xref: /csrg-svn/sys/vax/uba/rk.c (revision 1942)
1*1942Swnj /*	rk.c	4.2	12/19/80	*/
21899Swnj 
3*1942Swnj #include "rk.h"
41899Swnj #if NRK > 0
51899Swnj /*
61899Swnj  * RK disk driver
71899Swnj  */
81899Swnj 
91899Swnj #include "../h/param.h"
101899Swnj #include "../h/systm.h"
111899Swnj #include "../h/buf.h"
121899Swnj #include "../h/conf.h"
131899Swnj #include "../h/dir.h"
141899Swnj #include "../h/user.h"
151899Swnj #include "../h/pte.h"
161899Swnj #include "../h/map.h"
171899Swnj #include "../h/uba.h"
181899Swnj #include "../h/dk.h"
191899Swnj 
201899Swnj #define NCYL 815
211899Swnj #define NSECT 22
221899Swnj #define NTRK 3
231899Swnj #define NBLK (NTRK*NSECT*NCYL)
241899Swnj 
251899Swnj /* rkcs1 */
261899Swnj #define CCLR	0100000		/* controller clear */
271899Swnj #define	DI	040000		/* drive interrupt */
281899Swnj #define	CTO	04000		/* controller timeout */
291899Swnj #define	CDT	02000		/* drive type (rk07/rk06) */
301899Swnj #define	RDY	0200		/* controller ready */
311899Swnj #define	IEN	0100		/* interrupt enable */
321899Swnj 
331899Swnj 
341899Swnj /* rkcs2 */
351899Swnj #define	DLT	0100000		/* data late */
361899Swnj #define	WCE	040000		/* write check */
371899Swnj #define	UPE	020000		/* unibus parity */
381899Swnj #define	NED	010000		/* non-existant drive */
391899Swnj #define	NEM	04000		/* non-existant memory */
401899Swnj #define	PGE	02000		/* software error */
411899Swnj #define	MDS	01000		/* multiple drive select */
421899Swnj #define	UFE	0400		/* unit field error */
431899Swnj #define	SCLR	040		/* subsystem clear */
441899Swnj #define	cs2abort	(NED|NEM|PGE|UFE)
451899Swnj 
461899Swnj /* rkds */
471899Swnj #define	SVAL	0100000		/* status valid */
481899Swnj #define	CDA	040000		/* current drive attention */
491899Swnj #define	PIP	020000		/* positioning in progress */
501899Swnj #define	WRL	04000		/* write lock */
511899Swnj #define	DDT	0400		/* disk drive type */
521899Swnj #define	DRDY	0200		/* drive ready */
531899Swnj #define	VV	0100		/* volume valid */
541899Swnj #define	DROT	040		/* drive off track */
551899Swnj #define	SPLS	020		/* speed loss */
561899Swnj #define	ACLO	010		/* ac low */
571899Swnj #define	OFFSET	04		/* offset mode */
581899Swnj #define	DRA	01		/* drive available */
591899Swnj #define	dsabort		(ACLO|SPLS)
601899Swnj 
611899Swnj 
621899Swnj /* commands */
631899Swnj #define SELECT 0
641899Swnj #define PACK 2
651899Swnj #define DCLR 4
661899Swnj #define	RESET	012
671899Swnj #define	WCOM	022
681899Swnj #define	RCOM	020
691899Swnj #define	GO	01
701899Swnj #define	DRESET	012
711899Swnj 
721899Swnj struct	device
731899Swnj {
741899Swnj 	short rkcs1;
751899Swnj 	short rkwc;
761899Swnj 	unsigned short rkba;
771899Swnj 	short rkda;
781899Swnj 	short rkcs2;
791899Swnj 	short rkds;
801899Swnj 	short rker;
811899Swnj 	short rkatt;
821899Swnj 	short rkcyl;
831899Swnj 	short rkdb;
841899Swnj 	short rkmr1;
851899Swnj 	short rkecps;
861899Swnj 	short rkecpt;
871899Swnj 	short rkmr2;
881899Swnj 	short rkmr3;
891899Swnj } ;
901899Swnj 
911899Swnj struct	buf	rktab;
921899Swnj struct	buf	rrkbuf;
931899Swnj 
941899Swnj struct	devsize {
951899Swnj 	unsigned int nblocks;
961899Swnj 	int	cyloff;
971899Swnj } rk_sizes [] ={
981899Swnj 	9614, 0,	/* 0 - 145 */
991899Swnj 	6600, 146,	/* 146 - 245 */
1001899Swnj 	37554, 246,	/* 246 - 815 */
1011899Swnj 	0,	0,
1021899Swnj 	0,	0,
1031899Swnj 	0,	0,
1041899Swnj 	0,	0,
1051899Swnj 	0,	0,
1061899Swnj };
1071899Swnj 
1081899Swnj rkstrategy(bp)
1091899Swnj register struct buf *bp;
1101899Swnj {
1111899Swnj register dn, sz;
1121899Swnj 
1131899Swnj 	dn = minor(bp->b_dev);
1141899Swnj 	sz = (bp->b_bcount>>9);
1151899Swnj 	if (dn > (NRK<<3) || sz+bp->b_blkno >= rk_sizes[dn&07].nblocks) {
1161899Swnj 		bp->b_flags |= B_ERROR;
1171899Swnj 		iodone(bp);
1181899Swnj 		return;
1191899Swnj 	}
1201899Swnj 	bp->av_forw = (struct buf *)NULL;
1211899Swnj 	spl5();
1221899Swnj 	if(rktab.b_actf == NULL)
1231899Swnj 		rktab.b_actf = bp;
1241899Swnj 	else
1251899Swnj 		rktab.b_actl->av_forw = bp;
1261899Swnj 	rktab.b_actl = bp;
1271899Swnj 	if(rktab.b_active == NULL)
1281899Swnj 		rkstart();
1291899Swnj 	spl0();
1301899Swnj }
1311899Swnj 
1321899Swnj int rk_info;
1331899Swnj int tcn, ttn, tsn;
1341899Swnj 
1351899Swnj rkstart()
1361899Swnj {
1371899Swnj 	register struct buf *bp;
1381899Swnj 	register com;
1391899Swnj 	register struct device *rkaddr = RKADDR;
1401899Swnj 	daddr_t bn;
1411899Swnj 	int dn, cn, sn, tn;
1421899Swnj 
1431899Swnj 	if ((bp = rktab.b_actf) == NULL)
1441899Swnj 		return;
1451899Swnj 	rktab.b_active++;
1461899Swnj 	rk_info = ubasetup(bp, 1);
1471899Swnj 	bn = bp->b_blkno;
1481899Swnj 	dn = minor(bp->b_dev);
1491899Swnj 	cn = bn/(NTRK*NSECT);
1501899Swnj 	cn += rk_sizes[dn&07].cyloff;
1511899Swnj 	dn >>= 3;
1521899Swnj 	if (dn != (rkaddr->rkcs2&07)) {
1531899Swnj 		rkaddr->rkcs2 = dn;
1541899Swnj 		rkaddr->rkcs1 = CDT | GO;
1551899Swnj 		while ((rkaddr->rkcs1&RDY)==0)
1561899Swnj 			;
1571899Swnj 	}
1581899Swnj 	if ((rkaddr->rkds & VV) == 0) {
1591899Swnj 		rkaddr->rkcs1 = PACK | CDT | GO;
1601899Swnj 		while ((rkaddr->rkcs1&RDY)==0)
1611899Swnj 			;
1621899Swnj 	}
1631899Swnj 	tn = bn%(NTRK*NSECT);
1641899Swnj 	tn = tn/NSECT;
1651899Swnj 	sn = bn%NSECT;
1661899Swnj 	rkaddr->rkcs2 = dn;
1671899Swnj 	rkaddr->rkcyl = cn;
1681899Swnj 	rkaddr->rkda = (tn << 8) | sn;
1691899Swnj 	ttn = tn; tcn = cn; tsn = sn;
1701899Swnj 	rkaddr->rkba = rk_info;
1711899Swnj 	rkaddr->rkwc = -(bp->b_bcount>>1);
1721899Swnj 	com = ((rk_info &0x30000) >> 8) | CDT | IEN | GO;
1731899Swnj 	if(bp->b_flags & B_READ)
1741899Swnj 		com |= RCOM; else
1751899Swnj 		com |= WCOM;
1761899Swnj 	rkaddr->rkcs1 = com;
1771899Swnj 	dk_busy |= 1<<DK_N;
1781899Swnj 	dk_xfer[DK_N] += 1;
1791899Swnj 	com = bp->b_bcount>>6;
1801899Swnj 	dk_wds[DK_N] += com;
1811899Swnj }
1821899Swnj 
1831899Swnj rkintr()
1841899Swnj {
1851899Swnj 	register struct buf *bp;
1861899Swnj 	register d, x;
1871899Swnj 	register struct device *rkaddr = RKADDR;
1881899Swnj 	int ds, er;
1891899Swnj 
1901899Swnj 	if (rktab.b_active == NULL)
1911899Swnj 		return;
1921899Swnj 	dk_busy &= ~(1<<DK_N);
1931899Swnj 	bp = rktab.b_actf;
1941899Swnj 	rktab.b_active = NULL;
1951899Swnj 	if (rkaddr->rkcs1 < 0) {		/* error bit */
1961899Swnj 		d = (minor(bp->b_dev)>>3);
1971899Swnj 		x = 1;
1981899Swnj 		if (rkaddr->rkcs1&DI) {
1991899Swnj 			printf("DI");
2001899Swnj 		}
2011899Swnj 		if (rkaddr->rkds&CDA)
2021899Swnj 			printf("CDA ");
2031899Swnj 		if ((rkaddr->rkds&CDA) || (rkaddr->rkcs1&DI)) {
2041899Swnj 			er = (unsigned short)rkaddr->rker;
2051899Swnj 			ds = (unsigned short)rkaddr->rkds;
2061899Swnj 			rkaddr->rkcs1 = CDT | DCLR | GO;
2071899Swnj 			printf("DCLR");
2081899Swnj 		} else {
2091899Swnj 			if ((rkaddr->rkds&SVAL)==0) {
2101899Swnj 				printf("no SVAL\n");
2111899Swnj 				x = rkselect(rkaddr, d);
2121899Swnj 				printf("x = %d\n", x);
2131899Swnj 			}
2141899Swnj 			er = (unsigned short)rkaddr->rker;
2151899Swnj 			ds = (unsigned short)rkaddr->rkds;
2161899Swnj 		}
2171899Swnj 		if (rkaddr->rkds&dsabort) {
2181899Swnj 			printf("rk %d is down\n", d);
2191899Swnj 			rktab.b_errcnt = 10;
2201899Swnj 		}
2211899Swnj 		if (rkaddr->rkcs2&cs2abort) {
2221899Swnj 			printf("cs2 abort %o\n", rkaddr->rkcs2);
2231899Swnj 			rktab.b_errcnt = 10;
2241899Swnj 		}
2251899Swnj 		if (rktab.b_errcnt >= 10) {
2261899Swnj 			deverror(bp, er, ds);
2271899Swnj 			printf("cn %d tn %d sn %d\n", tcn, ttn, tsn);
2281899Swnj 		}
2291899Swnj 		rkaddr->rkcs1 = CDT | DCLR | GO;
2301899Swnj 		while ((rkaddr->rkcs1&RDY)==0)
2311899Swnj 			;
2321899Swnj 		rkaddr->rkcs2 = SCLR;
2331899Swnj 		while ((rkaddr->rkcs1&RDY)==0)
2341899Swnj 			;
2351899Swnj 		if ((x=rkselect(rkaddr, d)) == 0) {
2361899Swnj 			printf("after clears\n");
2371899Swnj 			goto bad;
2381899Swnj 		}
2391899Swnj 		printf("reset\n");
2401899Swnj 		rkaddr->rkcs1 = CDT | RESET | GO;
2411899Swnj 		while (rkaddr->rkds & PIP)
2421899Swnj 			;
2431899Swnj 		if (++rktab.b_errcnt <= 10) {
2441899Swnj 			ubafree(rk_info);
2451899Swnj 			rkstart();
2461899Swnj 			return;
2471899Swnj 		}
2481899Swnj bad:
2491899Swnj 		bp->b_flags |= B_ERROR;
2501899Swnj 	}
2511899Swnj 	rktab.b_errcnt = 0;
2521899Swnj 	rktab.b_actf = bp->av_forw;
2531899Swnj 	bp->b_resid = 0;
2541899Swnj 	ubafree(rk_info);
2551899Swnj 	iodone(bp);
2561899Swnj 	rkstart();
2571899Swnj }
2581899Swnj 
2591899Swnj 
2601899Swnj rkselect(rkaddr, d)
2611899Swnj register struct device *rkaddr;
2621899Swnj {
2631899Swnj 	rkaddr->rkcs2 = d;
2641899Swnj 	rkaddr->rkcs1 = CDT|GO;
2651899Swnj 	return(rkwait(rkaddr));
2661899Swnj }
2671899Swnj 
2681899Swnj rkwait(rkaddr)
2691899Swnj register struct device *rkaddr;
2701899Swnj {
2711899Swnj register t;
2721899Swnj 
2731899Swnj 	for(t=0x8000; t && ((rkaddr->rkds&DRDY)==0); t--)
2741899Swnj 		;
2751899Swnj 	if (t==0)
2761899Swnj 		printf("rk not ready\n");
2771899Swnj 	return(t);
2781899Swnj }
2791899Swnj 
2801899Swnj rkread(dev)
2811899Swnj dev_t dev;
2821899Swnj {
2831899Swnj 
2841899Swnj 	physio(rkstrategy, &rrkbuf, dev, B_READ, minphys);
2851899Swnj }
2861899Swnj 
2871899Swnj rkwrite(dev)
2881899Swnj dev_t dev;
2891899Swnj {
2901899Swnj 
2911899Swnj 	physio(rkstrategy, &rrkbuf, dev, B_WRITE, minphys);
2921899Swnj }
2931899Swnj #endif
294