xref: /csrg-svn/sys/vax/uba/rk.c (revision 2380)
1 /*	rk.c	4.6	02/08/81	*/
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 	53790,	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+511)>>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("rkintr: DI\n");
200 		}
201 		if (rkaddr->rkds&CDA)
202 			printf("rkintr: CDA\n");
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 		} else {
208 			if ((rkaddr->rkds&SVAL)==0) {
209 				x = 0x8000 - rkselect(rkaddr, d);
210 				printf("rkintr: no SVAL, delay %d\n", x);
211 			}
212 			er = (unsigned short)rkaddr->rker;
213 			ds = (unsigned short)rkaddr->rkds;
214 		}
215 		if (rkaddr->rkds&dsabort) {
216 			printf("rk %d is down\n", d);
217 			rktab.b_errcnt = 10;
218 		}
219 		if (rkaddr->rkcs2&cs2abort) {
220 			printf("cs2 abort %o\n", rkaddr->rkcs2);
221 			rktab.b_errcnt = 10;
222 		}
223 		if (rktab.b_errcnt >= 10) {
224 			deverror(bp, er, ds);
225 			printf("cn %d tn %d sn %d\n", tcn, ttn, tsn);
226 		}
227 		rkaddr->rkcs1 = CDT | DCLR | GO;
228 		while ((rkaddr->rkcs1&RDY)==0)
229 			;
230 		rkaddr->rkcs2 = SCLR;
231 		while ((rkaddr->rkcs1&RDY)==0)
232 			;
233 		if ((x=rkselect(rkaddr, d)) == 0) {
234 			printf("after clears\n");
235 			goto bad;
236 		}
237 		rkaddr->rkcs1 = CDT | RESET | GO;
238 		while (rkaddr->rkds & PIP)
239 			;
240 		if (++rktab.b_errcnt <= 10) {
241 			ubarelse(&rk_info);
242 			rkstart();
243 			return;
244 		}
245 bad:
246 		bp->b_flags |= B_ERROR;
247 	}
248 	rktab.b_errcnt = 0;
249 	rktab.b_actf = bp->av_forw;
250 	bp->b_resid = 0;
251 	ubarelse(&rk_info);
252 	iodone(bp);
253 	rkstart();
254 }
255 
256 
257 rkselect(rkaddr, d)
258 register struct device *rkaddr;
259 {
260 	rkaddr->rkcs2 = d;
261 	rkaddr->rkcs1 = CDT|GO;
262 	return(rkwait(rkaddr));
263 }
264 
265 rkwait(rkaddr)
266 register struct device *rkaddr;
267 {
268 register t;
269 
270 	for(t=0x8000; t && ((rkaddr->rkds&DRDY)==0); t--)
271 		;
272 	if (t==0)
273 		printf("rk not ready\n");
274 	return(t);
275 }
276 
277 rkread(dev)
278 dev_t dev;
279 {
280 
281 	physio(rkstrategy, &rrkbuf, dev, B_READ, minphys);
282 }
283 
284 rkwrite(dev)
285 dev_t dev;
286 {
287 
288 	physio(rkstrategy, &rrkbuf, dev, B_WRITE, minphys);
289 }
290 
291 rkdump()
292 {
293 
294 	printf("don't know how to dump to rk (yet)\n");
295 }
296 #endif
297