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