xref: /csrg-svn/sys/vax/uba/rk.c (revision 2054)
1 /*	rk.c	4.4	12/30/80	*/
2 
3 #include "rk.h"
4 #if NRK > 0
5 /*
6  * RK disk driver
7  */
8 
9 #include "../h/param.h"
10 #include "../h/systm.h"
11 #include "../h/buf.h"
12 #include "../h/conf.h"
13 #include "../h/dir.h"
14 #include "../h/user.h"
15 #include "../h/pte.h"
16 #include "../h/map.h"
17 #include "../h/uba.h"
18 #include "../h/dk.h"
19 
20 #define NCYL 815
21 #define NSECT 22
22 #define NTRK 3
23 #define NBLK (NTRK*NSECT*NCYL)
24 
25 /* rkcs1 */
26 #define CCLR	0100000		/* controller clear */
27 #define	DI	040000		/* drive interrupt */
28 #define	CTO	04000		/* controller timeout */
29 #define	CDT	02000		/* drive type (rk07/rk06) */
30 #define	RDY	0200		/* controller ready */
31 #define	IEN	0100		/* interrupt enable */
32 
33 
34 /* rkcs2 */
35 #define	DLT	0100000		/* data late */
36 #define	WCE	040000		/* write check */
37 #define	UPE	020000		/* unibus parity */
38 #define	NED	010000		/* non-existant drive */
39 #define	NEM	04000		/* non-existant memory */
40 #define	PGE	02000		/* software error */
41 #define	MDS	01000		/* multiple drive select */
42 #define	UFE	0400		/* unit field error */
43 #define	SCLR	040		/* subsystem clear */
44 #define	cs2abort	(NED|NEM|PGE|UFE)
45 
46 /* rkds */
47 #define	SVAL	0100000		/* status valid */
48 #define	CDA	040000		/* current drive attention */
49 #define	PIP	020000		/* positioning in progress */
50 #define	WRL	04000		/* write lock */
51 #define	DDT	0400		/* disk drive type */
52 #define	DRDY	0200		/* drive ready */
53 #define	VV	0100		/* volume valid */
54 #define	DROT	040		/* drive off track */
55 #define	SPLS	020		/* speed loss */
56 #define	ACLO	010		/* ac low */
57 #define	OFFSET	04		/* offset mode */
58 #define	DRA	01		/* drive available */
59 #define	dsabort		(ACLO|SPLS)
60 
61 
62 /* commands */
63 #define SELECT 0
64 #define PACK 2
65 #define DCLR 4
66 #define	RESET	012
67 #define	WCOM	022
68 #define	RCOM	020
69 #define	GO	01
70 #define	DRESET	012
71 
72 struct	device
73 {
74 	short rkcs1;
75 	short rkwc;
76 	unsigned short rkba;
77 	short rkda;
78 	short rkcs2;
79 	short rkds;
80 	short rker;
81 	short rkatt;
82 	short rkcyl;
83 	short rkdb;
84 	short rkmr1;
85 	short rkecps;
86 	short rkecpt;
87 	short rkmr2;
88 	short rkmr3;
89 } ;
90 
91 struct	buf	rktab;
92 struct	buf	rrkbuf;
93 
94 struct	devsize {
95 	unsigned int nblocks;
96 	int	cyloff;
97 } rk_sizes [] ={
98 	9614, 0,	/* 0 - 145 */
99 	6600, 146,	/* 146 - 245 */
100 	37554, 246,	/* 246 - 815 */
101 	0,	0,
102 	0,	0,
103 	0,	0,
104 	0,	0,
105 	0,	0,
106 };
107 
108 rkstrategy(bp)
109 register struct buf *bp;
110 {
111 register dn, sz;
112 
113 	dn = minor(bp->b_dev);
114 	sz = (bp->b_bcount>>9);
115 	if (dn > (NRK<<3) || sz+bp->b_blkno >= rk_sizes[dn&07].nblocks) {
116 		bp->b_flags |= B_ERROR;
117 		iodone(bp);
118 		return;
119 	}
120 	bp->av_forw = (struct buf *)NULL;
121 	spl5();
122 	if(rktab.b_actf == NULL)
123 		rktab.b_actf = bp;
124 	else
125 		rktab.b_actl->av_forw = bp;
126 	rktab.b_actl = bp;
127 	if(rktab.b_active == NULL)
128 		rkstart();
129 	spl0();
130 }
131 
132 int rk_info;
133 int tcn, ttn, tsn;
134 
135 rkstart()
136 {
137 	register struct buf *bp;
138 	register com;
139 	register struct device *rkaddr = RKADDR;
140 	daddr_t bn;
141 	int dn, cn, sn, tn;
142 
143 	if ((bp = rktab.b_actf) == NULL)
144 		return;
145 	rktab.b_active++;
146 	rk_info = ubasetup(bp, 1);
147 	bn = bp->b_blkno;
148 	dn = minor(bp->b_dev);
149 	cn = bn/(NTRK*NSECT);
150 	cn += rk_sizes[dn&07].cyloff;
151 	dn >>= 3;
152 	if (dn != (rkaddr->rkcs2&07)) {
153 		rkaddr->rkcs2 = dn;
154 		rkaddr->rkcs1 = CDT | GO;
155 		while ((rkaddr->rkcs1&RDY)==0)
156 			;
157 	}
158 	if ((rkaddr->rkds & VV) == 0) {
159 		rkaddr->rkcs1 = PACK | CDT | GO;
160 		while ((rkaddr->rkcs1&RDY)==0)
161 			;
162 	}
163 	tn = bn%(NTRK*NSECT);
164 	tn = tn/NSECT;
165 	sn = bn%NSECT;
166 	rkaddr->rkcs2 = dn;
167 	rkaddr->rkcyl = cn;
168 	rkaddr->rkda = (tn << 8) | sn;
169 	ttn = tn; tcn = cn; tsn = sn;
170 	rkaddr->rkba = rk_info;
171 	rkaddr->rkwc = -(bp->b_bcount>>1);
172 	com = ((rk_info &0x30000) >> 8) | CDT | IEN | GO;
173 	if(bp->b_flags & B_READ)
174 		com |= RCOM; else
175 		com |= WCOM;
176 	rkaddr->rkcs1 = com;
177 	dk_busy |= 1<<RKDK_N;
178 	dk_xfer[RKDK_N] += 1;
179 	com = bp->b_bcount>>6;
180 	dk_wds[RKDK_N] += com;
181 }
182 
183 rkintr()
184 {
185 	register struct buf *bp;
186 	register d, x;
187 	register struct device *rkaddr = RKADDR;
188 	int ds, er;
189 
190 	if (rktab.b_active == NULL)
191 		return;
192 	dk_busy &= ~(1<<RKDK_N);
193 	bp = rktab.b_actf;
194 	rktab.b_active = NULL;
195 	if (rkaddr->rkcs1 < 0) {		/* error bit */
196 		d = (minor(bp->b_dev)>>3);
197 		x = 1;
198 		if (rkaddr->rkcs1&DI) {
199 			printf("DI");
200 		}
201 		if (rkaddr->rkds&CDA)
202 			printf("CDA ");
203 		if ((rkaddr->rkds&CDA) || (rkaddr->rkcs1&DI)) {
204 			er = (unsigned short)rkaddr->rker;
205 			ds = (unsigned short)rkaddr->rkds;
206 			rkaddr->rkcs1 = CDT | DCLR | GO;
207 			printf("DCLR");
208 		} else {
209 			if ((rkaddr->rkds&SVAL)==0) {
210 				printf("no SVAL\n");
211 				x = rkselect(rkaddr, d);
212 				printf("x = %d\n", x);
213 			}
214 			er = (unsigned short)rkaddr->rker;
215 			ds = (unsigned short)rkaddr->rkds;
216 		}
217 		if (rkaddr->rkds&dsabort) {
218 			printf("rk %d is down\n", d);
219 			rktab.b_errcnt = 10;
220 		}
221 		if (rkaddr->rkcs2&cs2abort) {
222 			printf("cs2 abort %o\n", rkaddr->rkcs2);
223 			rktab.b_errcnt = 10;
224 		}
225 		if (rktab.b_errcnt >= 10) {
226 			deverror(bp, er, ds);
227 			printf("cn %d tn %d sn %d\n", tcn, ttn, tsn);
228 		}
229 		rkaddr->rkcs1 = CDT | DCLR | GO;
230 		while ((rkaddr->rkcs1&RDY)==0)
231 			;
232 		rkaddr->rkcs2 = SCLR;
233 		while ((rkaddr->rkcs1&RDY)==0)
234 			;
235 		if ((x=rkselect(rkaddr, d)) == 0) {
236 			printf("after clears\n");
237 			goto bad;
238 		}
239 		printf("reset\n");
240 		rkaddr->rkcs1 = CDT | RESET | GO;
241 		while (rkaddr->rkds & PIP)
242 			;
243 		if (++rktab.b_errcnt <= 10) {
244 			ubarelse(&rk_info);
245 			rkstart();
246 			return;
247 		}
248 bad:
249 		bp->b_flags |= B_ERROR;
250 	}
251 	rktab.b_errcnt = 0;
252 	rktab.b_actf = bp->av_forw;
253 	bp->b_resid = 0;
254 	ubarelse(&rk_info);
255 	iodone(bp);
256 	rkstart();
257 }
258 
259 
260 rkselect(rkaddr, d)
261 register struct device *rkaddr;
262 {
263 	rkaddr->rkcs2 = d;
264 	rkaddr->rkcs1 = CDT|GO;
265 	return(rkwait(rkaddr));
266 }
267 
268 rkwait(rkaddr)
269 register struct device *rkaddr;
270 {
271 register t;
272 
273 	for(t=0x8000; t && ((rkaddr->rkds&DRDY)==0); t--)
274 		;
275 	if (t==0)
276 		printf("rk not ready\n");
277 	return(t);
278 }
279 
280 rkread(dev)
281 dev_t dev;
282 {
283 
284 	physio(rkstrategy, &rrkbuf, dev, B_READ, minphys);
285 }
286 
287 rkwrite(dev)
288 dev_t dev;
289 {
290 
291 	physio(rkstrategy, &rrkbuf, dev, B_WRITE, minphys);
292 }
293 #endif
294