xref: /csrg-svn/sys/vax/stand/rk.c (revision 35052)
123237Smckusick /*
2*35052Skarels  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
323237Smckusick  * All rights reserved.  The Berkeley software License Agreement
423237Smckusick  * specifies the terms and conditions for redistribution.
523237Smckusick  *
6*35052Skarels  *	@(#)rk.c	7.7 (Berkeley) 07/09/88
723237Smckusick  */
81915Swnj 
91915Swnj /*
103263Swnj  * RK611/RK07
111915Swnj  */
1233408Skarels #include "param.h"
1333408Skarels #include "inode.h"
1433408Skarels #include "fs.h"
1533408Skarels #include "disklabel.h"
161915Swnj 
1733408Skarels #include "../vax/pte.h"
189186Ssam 
199186Ssam #include "../vaxuba/ubareg.h"
209186Ssam #include "../vaxuba/rkreg.h"
219186Ssam 
221915Swnj #include "saio.h"
233263Swnj #include "savax.h"
241915Swnj 
2533541Sbostic #define	SECTSIZ		512		/* sector size in bytes */
2630547Skarels 
2733541Sbostic #define	MAXCTLR		1		/* all addresses must be specified */
28*35052Skarels #define	MAXUNIT		8
2933541Sbostic u_short	rkstd[MAXCTLR] = { 0777440 };
30*35052Skarels struct	disklabel rklabel[MAXNUBA][MAXCTLR][MAXUNIT];
3130547Skarels char	lbuf[SECTSIZ];
321915Swnj 
331915Swnj rkopen(io)
343263Swnj 	register struct iob *io;
351915Swnj {
3633541Sbostic 	register struct rkdevice *rkaddr;
3733541Sbostic 	register struct disklabel *lp;
3830547Skarels 	struct iob tio;
391915Swnj 
40*35052Skarels 	if ((u_int)io->i_adapt >= nuba)
41*35052Skarels 		return (EADAPT);
4233541Sbostic 	if ((u_int)io->i_ctlr >= MAXCTLR)
4333541Sbostic 		return (ECTLR);
44*35052Skarels 	if ((u_int)io->i_unit >= MAXUNIT)
45*35052Skarels 		return (EUNIT);
4633541Sbostic 	rkaddr = (struct rkdevice *)ubamem(io->i_adapt, rkstd[io->i_ctlr]);
4733548Sbostic 	if (badaddr((char *)rkaddr, sizeof(short)))
4830547Skarels 		return (ENXIO);
493349Swnj 	rkaddr->rkcs2 = RKCS2_SCLR;
503349Swnj 	rkwait(rkaddr);
5130547Skarels 	/*
5230547Skarels 	 * Read in the pack label.
5330547Skarels 	 */
5433541Sbostic 	lp = &rklabel[io->i_adapt][io->i_ctlr][io->i_unit];
5530547Skarels 	lp->d_nsectors = NRKSECT;
5630547Skarels 	lp->d_secpercyl = NRKTRK*NRKSECT;
5730547Skarels 	tio = *io;
5830547Skarels 	tio.i_bn = LABELSECTOR;
5930547Skarels 	tio.i_ma = lbuf;
6030547Skarels 	tio.i_cc = SECTSIZ;
6130547Skarels 	tio.i_flgs |= F_RDDATA;
6233636Sbostic 	if (rkstrategy(&tio, READ) != SECTSIZ)
6333636Sbostic 		return (ERDLAB);
6430547Skarels 	*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
6533636Sbostic 	if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC)
6633636Sbostic #ifdef COMPAT_42
6733636Sbostic 	{
6833541Sbostic 		printf("rk%d: unlabeled\n", io->i_unit);
6930547Skarels 		rkmaptype(io, lp);
7033636Sbostic 	}
7130547Skarels #else
7233636Sbostic 		return (EUNLAB);
7330547Skarels #endif
7433541Sbostic 	if ((u_int)io->i_part >= lp->d_npartitions ||
7533541Sbostic 	    (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
7633541Sbostic 		return (EPART);
7730547Skarels 	return (0);
781915Swnj }
791915Swnj 
8030547Skarels #ifdef COMPAT_42
8130547Skarels u_long	rk_off[] = { 0, 241, 0, -1, -1, -1, 393, -1 };
8230547Skarels 
8330547Skarels rkmaptype(io, lp)
8433408Skarels 	struct iob *io;
8530547Skarels 	register struct disklabel *lp;
8630547Skarels {
8730547Skarels 	register struct partition *pp;
8830547Skarels 	register u_long *off = rk_off;
8933541Sbostic 	register int i;
9030547Skarels 
9130547Skarels 	lp->d_npartitions = 8;
9230547Skarels 	pp = lp->d_partitions;
9330547Skarels 	for (i = 0; i < 8; i++, pp++)
9430547Skarels 		pp->p_offset = *off++;
9530547Skarels }
9630547Skarels #endif
9730547Skarels 
981915Swnj rkstrategy(io, func)
993263Swnj 	register struct iob *io;
1001915Swnj {
10133541Sbostic 	register struct rkdevice *rkaddr;
10233408Skarels 	register daddr_t bn;
10333541Sbostic 	int com, ubinfo, errcnt = 0;
10433408Skarels 	short cn, sn, tn;
1051915Swnj 
10633541Sbostic 	rkaddr = (struct rkdevice *)ubamem(io->i_adapt, rkstd[io->i_ctlr]);
1073349Swnj retry:
1081915Swnj 	ubinfo = ubasetup(io, 1);
1091915Swnj 	bn = io->i_bn;
11033408Skarels 	cn = bn / (NRKSECT*NRKTRK);
11133408Skarels 	sn = bn % NRKSECT;
1123263Swnj 	tn = (bn / NRKSECT) % NRKTRK;
11333541Sbostic 	rkaddr->rkcs2 = io->i_unit;
1143263Swnj 	rkaddr->rkcs1 = RK_CDT|RK_PACK|RK_GO;
1153263Swnj 	rkwait(rkaddr);
1163349Swnj 	rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
1173349Swnj 	rkwait(rkaddr);
1183263Swnj 	rkaddr->rkda = sn | (tn << 8);
1193263Swnj 	rkaddr->rkcyl = cn;
1203263Swnj 	rkaddr->rkba = ubinfo;
1213263Swnj 	rkaddr->rkwc = -(io->i_cc >> 1);
1224038Swnj 	com = RK_CDT|((ubinfo>>8)&0x300)|RK_GO;
1233263Swnj 	if (func == READ)
1243263Swnj 		com |= RK_READ;
1253263Swnj 	else
1263263Swnj 		com |= RK_WRITE;
1273263Swnj 	rkaddr->rkcs1 = com;
1283263Swnj 	rkwait(rkaddr);
1293349Swnj 	while ((rkaddr->rkds & RKDS_SVAL) == 0)
1301915Swnj 		;
1313263Swnj 	ubafree(io, ubinfo);
1323263Swnj 	if (rkaddr->rkcs1 & RK_CERR) {
1333349Swnj 		printf("rk error: (cyl,trk,sec)=(%d,%d,%d) cs2=%b er=%b\n",
1343349Swnj 		    cn, tn, sn, rkaddr->rkcs2, RKCS2_BITS,
1353349Swnj 		    rkaddr->rker, RKER_BITS);
1363349Swnj 		rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
1373263Swnj 		rkwait(rkaddr);
13833541Sbostic 		if (errcnt++ == 10) {
1393349Swnj 			printf("rk: unrecovered error\n");
1403349Swnj 			return (-1);
1413349Swnj 		}
1423349Swnj 		goto retry;
1431915Swnj 	}
1443349Swnj 	if (errcnt)
1453349Swnj 		printf("rk: recovered by retry\n");
1461915Swnj 	return (io->i_cc);
1471915Swnj }
1483263Swnj 
1493263Swnj rkwait(rkaddr)
1503263Swnj 	register struct rkdevice *rkaddr;
1513263Swnj {
15233541Sbostic 	while ((rkaddr->rkcs1 & RK_CRDY) == 0);
1533263Swnj }
154