xref: /csrg-svn/sys/vax/stand/rk.c (revision 30547)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)rk.c	7.2 (Berkeley) 02/21/87
7  */
8 
9 /*
10  * RK611/RK07
11  */
12 #include "../machine/pte.h"
13 
14 #include "../h/param.h"
15 #include "../h/inode.h"
16 #include "../h/fs.h"
17 #include "../h/disklabel.h"
18 
19 #include "../vaxuba/ubareg.h"
20 #include "../vaxuba/rkreg.h"
21 
22 #include "saio.h"
23 #include "savax.h"
24 
25 #define	SECTSIZ 	512	/* sector size in bytes */
26 
27 u_short	rkstd[] = { 0777440 };
28 struct	disklabel rklabel[MAXNUBA*8];
29 char	lbuf[SECTSIZ];
30 
31 rkopen(io)
32 	register struct iob *io;
33 {
34 	register struct rkdevice *rkaddr = (struct rkdevice *)ubamem(io->i_unit, rkstd[0]);
35 	register struct disklabel *lp = &rklabel[io->i_unit];
36 	struct iob tio;
37 
38 	if (badaddr((char *)rkaddr, sizeof(short))) {
39 		printf("nonexistent device");
40 		return (ENXIO);
41 	}
42 	rkaddr->rkcs2 = RKCS2_SCLR;
43 	rkwait(rkaddr);
44 	/*
45 	 * Read in the pack label.
46 	 */
47 	lp->d_nsectors = NRKSECT;
48 	lp->d_secpercyl = NRKTRK*NRKSECT;
49 	tio = *io;
50 	tio.i_bn = LABELSECTOR;
51 	tio.i_ma = lbuf;
52 	tio.i_cc = SECTSIZ;
53 	tio.i_flgs |= F_RDDATA;
54 	if (rkstrategy(&tio, READ) != SECTSIZ) {
55 		printf("can't read disk label");
56 		return (EIO);
57 	}
58 	*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
59 	if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
60 		printf("hk%d: unlabeled\n", io->i_unit);
61 #ifdef COMPAT_42
62 		rkmaptype(io, lp);
63 #else
64 		return (ENXIO);
65 #endif
66 	}
67 	if ((unsigned)io->i_boff >= lp->d_npartitions ||
68 	    (io->i_boff = lp->d_partitions[io->i_boff].p_offset) == -1) {
69 		printf("rk: bad partition");
70 		return (EUNIT);
71 	}
72 	return (0);
73 }
74 
75 #ifdef COMPAT_42
76 u_long	rk_off[] = { 0, 241, 0, -1, -1, -1, 393, -1 };
77 
78 rkmaptype(io, lp)
79 	register struct iob *io;
80 	register struct disklabel *lp;
81 {
82 	register struct partition *pp;
83 	register i;
84 	register u_long *off = rk_off;
85 
86 	lp->d_npartitions = 8;
87 	pp = lp->d_partitions;
88 	for (i = 0; i < 8; i++, pp++)
89 		pp->p_offset = *off++;
90 }
91 #endif
92 
93 rkstrategy(io, func)
94 	register struct iob *io;
95 {
96 	register struct rkdevice *rkaddr = (struct rkdevice *)ubamem(io->i_unit, rkstd[0]);
97 	int com;
98 	daddr_t bn;
99 	short dn, cn, sn, tn;
100 	int ubinfo, errcnt = 0;
101 
102 retry:
103 	ubinfo = ubasetup(io, 1);
104 	bn = io->i_bn;
105 	dn = UNITTODRIVE(io->i_unit);
106 	cn = bn/(NRKSECT*NRKTRK);
107 	sn = bn%NRKSECT;
108 	tn = (bn / NRKSECT) % NRKTRK;
109 	rkaddr->rkcs2 = dn;
110 	rkaddr->rkcs1 = RK_CDT|RK_PACK|RK_GO;
111 	rkwait(rkaddr);
112 	rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
113 	rkwait(rkaddr);
114 	rkaddr->rkda = sn | (tn << 8);
115 	rkaddr->rkcyl = cn;
116 	rkaddr->rkba = ubinfo;
117 	rkaddr->rkwc = -(io->i_cc >> 1);
118 	com = RK_CDT|((ubinfo>>8)&0x300)|RK_GO;
119 	if (func == READ)
120 		com |= RK_READ;
121 	else
122 		com |= RK_WRITE;
123 	rkaddr->rkcs1 = com;
124 	rkwait(rkaddr);
125 	while ((rkaddr->rkds & RKDS_SVAL) == 0)
126 		;
127 	ubafree(io, ubinfo);
128 	if (rkaddr->rkcs1 & RK_CERR) {
129 		printf("rk error: (cyl,trk,sec)=(%d,%d,%d) cs2=%b er=%b\n",
130 		    cn, tn, sn, rkaddr->rkcs2, RKCS2_BITS,
131 		    rkaddr->rker, RKER_BITS);
132 		rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
133 		rkwait(rkaddr);
134 		if (errcnt == 10) {
135 			printf("rk: unrecovered error\n");
136 			return (-1);
137 		}
138 		errcnt++;
139 		goto retry;
140 	}
141 	if (errcnt)
142 		printf("rk: recovered by retry\n");
143 	return (io->i_cc);
144 }
145 
146 rkwait(rkaddr)
147 	register struct rkdevice *rkaddr;
148 {
149 
150 	while ((rkaddr->rkcs1 & RK_CRDY) == 0)
151 		;
152 }
153 
154 /*ARGSUSED*/
155 rkioctl(io, cmd, arg)
156 	struct iob *io;
157 	int cmd;
158 	caddr_t arg;
159 {
160 
161 	return (ECMD);
162 }
163