xref: /csrg-svn/sys/vax/stand/rk.c (revision 30547)
123237Smckusick /*
229306Smckusick  * Copyright (c) 1982, 1986 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*30547Skarels  *	@(#)rk.c	7.2 (Berkeley) 02/21/87
723237Smckusick  */
81915Swnj 
91915Swnj /*
103263Swnj  * RK611/RK07
111915Swnj  */
129806Ssam #include "../machine/pte.h"
131915Swnj 
141915Swnj #include "../h/param.h"
151915Swnj #include "../h/inode.h"
167446Sroot #include "../h/fs.h"
17*30547Skarels #include "../h/disklabel.h"
189186Ssam 
199186Ssam #include "../vaxuba/ubareg.h"
209186Ssam #include "../vaxuba/rkreg.h"
219186Ssam 
221915Swnj #include "saio.h"
233263Swnj #include "savax.h"
241915Swnj 
25*30547Skarels #define	SECTSIZ 	512	/* sector size in bytes */
26*30547Skarels 
273263Swnj u_short	rkstd[] = { 0777440 };
28*30547Skarels struct	disklabel rklabel[MAXNUBA*8];
29*30547Skarels char	lbuf[SECTSIZ];
301915Swnj 
311915Swnj rkopen(io)
323263Swnj 	register struct iob *io;
331915Swnj {
343349Swnj 	register struct rkdevice *rkaddr = (struct rkdevice *)ubamem(io->i_unit, rkstd[0]);
35*30547Skarels 	register struct disklabel *lp = &rklabel[io->i_unit];
36*30547Skarels 	struct iob tio;
371915Swnj 
38*30547Skarels 	if (badaddr((char *)rkaddr, sizeof(short))) {
39*30547Skarels 		printf("nonexistent device");
40*30547Skarels 		return (ENXIO);
41*30547Skarels 	}
423349Swnj 	rkaddr->rkcs2 = RKCS2_SCLR;
433349Swnj 	rkwait(rkaddr);
44*30547Skarels 	/*
45*30547Skarels 	 * Read in the pack label.
46*30547Skarels 	 */
47*30547Skarels 	lp->d_nsectors = NRKSECT;
48*30547Skarels 	lp->d_secpercyl = NRKTRK*NRKSECT;
49*30547Skarels 	tio = *io;
50*30547Skarels 	tio.i_bn = LABELSECTOR;
51*30547Skarels 	tio.i_ma = lbuf;
52*30547Skarels 	tio.i_cc = SECTSIZ;
53*30547Skarels 	tio.i_flgs |= F_RDDATA;
54*30547Skarels 	if (rkstrategy(&tio, READ) != SECTSIZ) {
55*30547Skarels 		printf("can't read disk label");
56*30547Skarels 		return (EIO);
57*30547Skarels 	}
58*30547Skarels 	*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
59*30547Skarels 	if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
60*30547Skarels 		printf("hk%d: unlabeled\n", io->i_unit);
61*30547Skarels #ifdef COMPAT_42
62*30547Skarels 		rkmaptype(io, lp);
63*30547Skarels #else
64*30547Skarels 		return (ENXIO);
65*30547Skarels #endif
66*30547Skarels 	}
67*30547Skarels 	if ((unsigned)io->i_boff >= lp->d_npartitions ||
68*30547Skarels 	    (io->i_boff = lp->d_partitions[io->i_boff].p_offset) == -1) {
69*30547Skarels 		printf("rk: bad partition");
70*30547Skarels 		return (EUNIT);
71*30547Skarels 	}
72*30547Skarels 	return (0);
731915Swnj }
741915Swnj 
75*30547Skarels #ifdef COMPAT_42
76*30547Skarels u_long	rk_off[] = { 0, 241, 0, -1, -1, -1, 393, -1 };
77*30547Skarels 
78*30547Skarels rkmaptype(io, lp)
79*30547Skarels 	register struct iob *io;
80*30547Skarels 	register struct disklabel *lp;
81*30547Skarels {
82*30547Skarels 	register struct partition *pp;
83*30547Skarels 	register i;
84*30547Skarels 	register u_long *off = rk_off;
85*30547Skarels 
86*30547Skarels 	lp->d_npartitions = 8;
87*30547Skarels 	pp = lp->d_partitions;
88*30547Skarels 	for (i = 0; i < 8; i++, pp++)
89*30547Skarels 		pp->p_offset = *off++;
90*30547Skarels }
91*30547Skarels #endif
92*30547Skarels 
931915Swnj rkstrategy(io, func)
943263Swnj 	register struct iob *io;
951915Swnj {
963263Swnj 	register struct rkdevice *rkaddr = (struct rkdevice *)ubamem(io->i_unit, rkstd[0]);
973263Swnj 	int com;
981915Swnj 	daddr_t bn;
991915Swnj 	short dn, cn, sn, tn;
1003349Swnj 	int ubinfo, errcnt = 0;
1011915Swnj 
1023349Swnj retry:
1031915Swnj 	ubinfo = ubasetup(io, 1);
1041915Swnj 	bn = io->i_bn;
105*30547Skarels 	dn = UNITTODRIVE(io->i_unit);
1063263Swnj 	cn = bn/(NRKSECT*NRKTRK);
1073263Swnj 	sn = bn%NRKSECT;
1083263Swnj 	tn = (bn / NRKSECT) % NRKTRK;
1093263Swnj 	rkaddr->rkcs2 = dn;
1103263Swnj 	rkaddr->rkcs1 = RK_CDT|RK_PACK|RK_GO;
1113263Swnj 	rkwait(rkaddr);
1123349Swnj 	rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
1133349Swnj 	rkwait(rkaddr);
1143263Swnj 	rkaddr->rkda = sn | (tn << 8);
1153263Swnj 	rkaddr->rkcyl = cn;
1163263Swnj 	rkaddr->rkba = ubinfo;
1173263Swnj 	rkaddr->rkwc = -(io->i_cc >> 1);
1184038Swnj 	com = RK_CDT|((ubinfo>>8)&0x300)|RK_GO;
1193263Swnj 	if (func == READ)
1203263Swnj 		com |= RK_READ;
1213263Swnj 	else
1223263Swnj 		com |= RK_WRITE;
1233263Swnj 	rkaddr->rkcs1 = com;
1243263Swnj 	rkwait(rkaddr);
1253349Swnj 	while ((rkaddr->rkds & RKDS_SVAL) == 0)
1261915Swnj 		;
1273263Swnj 	ubafree(io, ubinfo);
1283263Swnj 	if (rkaddr->rkcs1 & RK_CERR) {
1293349Swnj 		printf("rk error: (cyl,trk,sec)=(%d,%d,%d) cs2=%b er=%b\n",
1303349Swnj 		    cn, tn, sn, rkaddr->rkcs2, RKCS2_BITS,
1313349Swnj 		    rkaddr->rker, RKER_BITS);
1323349Swnj 		rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
1333263Swnj 		rkwait(rkaddr);
1343349Swnj 		if (errcnt == 10) {
1353349Swnj 			printf("rk: unrecovered error\n");
1363349Swnj 			return (-1);
1373349Swnj 		}
1383349Swnj 		errcnt++;
1393349Swnj 		goto retry;
1401915Swnj 	}
1413349Swnj 	if (errcnt)
1423349Swnj 		printf("rk: recovered by retry\n");
1431915Swnj 	return (io->i_cc);
1441915Swnj }
1453263Swnj 
1463263Swnj rkwait(rkaddr)
1473263Swnj 	register struct rkdevice *rkaddr;
1483263Swnj {
1493263Swnj 
1503263Swnj 	while ((rkaddr->rkcs1 & RK_CRDY) == 0)
1513263Swnj 		;
1523263Swnj }
15310024Ssam 
15410024Ssam /*ARGSUSED*/
15510024Ssam rkioctl(io, cmd, arg)
15610024Ssam 	struct iob *io;
15710024Ssam 	int cmd;
15810024Ssam 	caddr_t arg;
15910024Ssam {
16010024Ssam 
16110024Ssam 	return (ECMD);
16210024Ssam }
163