xref: /csrg-svn/sys/vax/uba/rk.c (revision 2622)
1*2622Swnj /*	rk.c	4.8	02/23/81	*/
21899Swnj 
31942Swnj #include "rk.h"
42618Swnj #if NRK11 > 0
5*2622Swnj int	rkflags,rkerrs;		/* GROT */
61899Swnj /*
72618Swnj  * RK11/RK07 disk driver
8*2622Swnj  *
9*2622Swnj  * This driver mimics up.c; see it for an explanation of common code.
101899Swnj  */
112618Swnj #define	DELAY(i)		{ register int j; j = i; while (--j > 0); }
121899Swnj #include "../h/param.h"
131899Swnj #include "../h/systm.h"
141899Swnj #include "../h/buf.h"
151899Swnj #include "../h/conf.h"
161899Swnj #include "../h/dir.h"
171899Swnj #include "../h/user.h"
181899Swnj #include "../h/pte.h"
191899Swnj #include "../h/map.h"
202618Swnj #include "../h/vm.h"
211899Swnj #include "../h/uba.h"
221899Swnj #include "../h/dk.h"
232618Swnj #include "../h/cpu.h"
242618Swnj #include "../h/cmap.h"
251899Swnj 
262618Swnj #include "../h/rkreg.h"
271899Swnj 
282618Swnj struct	rk_softc {
292618Swnj 	int	sc_softas;
302618Swnj 	int	sc_ndrive;
312618Swnj 	int	sc_wticks;
322618Swnj 	int	sc_recal;
332618Swnj } rk_softc[NRK11];
341899Swnj 
352618Swnj /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
362618Swnj struct	size
372618Swnj {
382618Swnj 	daddr_t	nblocks;
392618Swnj 	int	cyloff;
402618Swnj } rk7_sizes[] ={
412618Swnj 	15884,	0,		/* A=cyl 0 thru 240 */
422618Swnj 	10032,	146,		/* B=cyl 241 thru 392 */
432618Swnj 	53790,	246,		/* C=cyl 0 thru 814 */
442618Swnj 	0,	0,
452618Swnj 	0,	0,
462618Swnj 	0,	0,
472618Swnj 	27786,	393,		/* G=cyl 393 thru 813 */
482618Swnj 	0,	0,
492618Swnj };
502618Swnj /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
511899Swnj 
522618Swnj int	rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr();
532618Swnj struct	uba_minfo *rkminfo[NRK11];
542618Swnj struct	uba_dinfo *rkdinfo[NRK07];
552618Swnj struct	uba_dinfo *rkip[NRK11][4];
561899Swnj 
572618Swnj u_short	rkstd[] = { 0777440, 0 };
582618Swnj struct	uba_driver hkdriver =
59*2622Swnj  { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 };
602618Swnj struct	buf rkutab[NRK07];
612618Swnj short	rkcyl[NRK07];
621899Swnj 
632618Swnj struct	rkst {
642618Swnj 	short	nsect;
652618Swnj 	short	ntrak;
662618Swnj 	short	nspc;
672618Swnj 	short	ncyl;
682618Swnj 	struct	size *sizes;
692618Swnj } rkst[] = {
702618Swnj 	NRKSECT, NRKTRK, NRKSECT*NRKTRK,	NRK7CYL,	rk7_sizes,
712618Swnj };
721899Swnj 
732618Swnj u_char 	rk_offset[16] =
742618Swnj   { P400,M400,P400,M400,P800,M800,P800,M800,P1200,M1200,P1200,M1200,0,0,0,0 };
751899Swnj 
762618Swnj struct	buf rrkbuf[NRK07];
772618Swnj 
782618Swnj #define	b_cylin	b_resid
792618Swnj 
802618Swnj #ifdef INTRLVE
812618Swnj daddr_t	dkblock();
822618Swnj #endif
832618Swnj 
842618Swnj int	rkwstart, rkwatch();
852618Swnj 
862618Swnj rkprobe(reg)
872618Swnj 	caddr_t reg;
881899Swnj {
892618Swnj 	register int br, cvec;
901899Swnj 
912618Swnj #ifdef lint
922618Swnj 	br = 0; cvec = br; br = cvec;
932618Swnj #endif
942618Swnj 	((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY;
952618Swnj 	DELAY(10);
962618Swnj 	((struct rkdevice *)reg)->rkcs1 = RK_CDT;
972618Swnj 	return (1);
982618Swnj }
991899Swnj 
1002618Swnj rkslave(ui, reg)
1012618Swnj 	struct uba_dinfo *ui;
1022618Swnj 	caddr_t reg;
1032618Swnj {
1042618Swnj 	register struct rkdevice *rkaddr = (struct rkdevice *)reg;
1051899Swnj 
1062618Swnj 	rkaddr->rkcs1 = RK_CDT;
1072618Swnj 	rkaddr->rkcs2 = ui->ui_slave;
108*2622Swnj 	rkwait(rkaddr);
109*2622Swnj /* SHOULD TRY THIS BY PULLING A PLUG */
110*2622Swnj /* A DELAY OR SOMETHING MAY BE NEEDED */
1112618Swnj 	if (rkaddr->rkcs2&RK_NED) {
1122618Swnj 		rkaddr->rkcs1 = RK_CDT|RK_CCLR;
1132618Swnj 		return (0);
1142618Swnj 	}
1152618Swnj 	return (1);
1162618Swnj }
1172618Swnj 
1182618Swnj rkattach(ui)
1192618Swnj 	register struct uba_dinfo *ui;
1202618Swnj {
1212618Swnj 
1222618Swnj 	if (rkwstart == 0) {
1232618Swnj 		timeout(rkwatch, (caddr_t)0, HZ);
1242618Swnj 		rkwstart++;
1252618Swnj 	}
1262618Swnj 	if (ui->ui_dk >= 0)
1272618Swnj 		dk_mspw[ui->ui_dk] = 1.0 / (HZ * NRKSECT * 256);
1282618Swnj 	rkip[ui->ui_ctlr][ui->ui_slave] = ui;
1292618Swnj 	rk_softc[ui->ui_ctlr].sc_ndrive++;
1302618Swnj 	rkcyl[ui->ui_unit] = -1;
1312618Swnj }
1322618Swnj 
1331899Swnj rkstrategy(bp)
1342618Swnj 	register struct buf *bp;
1351899Swnj {
1362618Swnj 	register struct uba_dinfo *ui;
1372618Swnj 	register struct rkst *st;
1382618Swnj 	register int unit;
1392618Swnj 	register struct buf *dp;
1402618Swnj 	int xunit = minor(bp->b_dev) & 07;
1412618Swnj 	long bn, sz;
1421899Swnj 
1432618Swnj 	sz = (bp->b_bcount+511) >> 9;
1442618Swnj 	unit = dkunit(bp);
1452618Swnj 	if (unit >= NRK07)
1462618Swnj 		goto bad;
1472618Swnj 	ui = rkdinfo[unit];
1482618Swnj 	if (ui == 0 || ui->ui_alive == 0)
1492618Swnj 		goto bad;
1502618Swnj 	st = &rkst[ui->ui_type];
1512618Swnj 	if (bp->b_blkno < 0 ||
1522618Swnj 	    (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks)
1532618Swnj 		goto bad;
1542618Swnj 	bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
1552618Swnj 	(void) spl5();
1562618Swnj 	dp = &rkutab[ui->ui_unit];
1572618Swnj 	disksort(dp, bp);
1582618Swnj 	if (dp->b_active == 0) {
1592618Swnj 		(void) rkustart(ui);
1602618Swnj 		bp = &ui->ui_mi->um_tab;
1612618Swnj 		if (bp->b_actf && bp->b_active == 0)
1622618Swnj 			(void) rkstart(ui->ui_mi);
1631899Swnj 	}
1642618Swnj 	(void) spl0();
1652618Swnj 	return;
1662618Swnj 
1672618Swnj bad:
1682618Swnj 	bp->b_flags |= B_ERROR;
1692618Swnj 	iodone(bp);
1702618Swnj 	return;
1711899Swnj }
1721899Swnj 
1732618Swnj rkustart(ui)
1742618Swnj 	register struct uba_dinfo *ui;
1752618Swnj {
1762618Swnj 	register struct buf *bp, *dp;
1772618Swnj 	register struct uba_minfo *um;
1782618Swnj 	register struct rkdevice *rkaddr;
1792618Swnj 	register struct rkst *st;
1802618Swnj 	daddr_t bn;
1812618Swnj 	int sn, csn;
1822618Swnj 	int didie = 0;
1831899Swnj 
1842618Swnj 	if (ui == 0)
1852618Swnj 		return (0);
1862618Swnj 	dk_busy &= ~(1<<ui->ui_dk);
1872618Swnj 	dp = &rkutab[ui->ui_unit];
1882618Swnj 	if ((bp = dp->b_actf) == NULL)
1892618Swnj 		goto out;
1902618Swnj 	um = ui->ui_mi;
1912618Swnj 	if (um->um_tab.b_active) {
1922618Swnj 		rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave;
1932618Swnj 		return (0);
1942618Swnj 	}
1952618Swnj 	rkaddr = (struct rkdevice *)um->um_addr;
1962618Swnj 	rkaddr->rkcs1 = RK_CDT|RK_CERR;
1972618Swnj 	rkaddr->rkcs2 = ui->ui_slave;
1982618Swnj 	rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO;
1992618Swnj 	rkwait(rkaddr);
2002618Swnj 	if (dp->b_active)
2012618Swnj 		goto done;
2022618Swnj 	dp->b_active = 1;
2032618Swnj 	if ((rkaddr->rkds & RK_VV) == 0) {
2042618Swnj 		/* SHOULD WARN SYSTEM THAT THIS HAPPENED */
2052618Swnj 		rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO;
2062618Swnj 		rkwait(rkaddr);
2072618Swnj 		didie = 1;
2082618Swnj 	}
2092618Swnj 	if (rk_softc[um->um_ctlr].sc_ndrive == 1)
2102618Swnj 		goto done;
2112618Swnj 	if (bp->b_cylin == rkcyl[ui->ui_unit])
2122618Swnj 		goto done;
2132618Swnj 	rkaddr->rkcyl = bp->b_cylin;
2142618Swnj 	rkcyl[ui->ui_unit] = bp->b_cylin;
2152618Swnj 	rkaddr->rkcs1 = RK_CDT|RK_IE|RK_SEEK|RK_GO;
2162618Swnj 	didie = 1;
2172618Swnj 	if (ui->ui_dk >= 0) {
2182618Swnj 		dk_busy |= 1<<ui->ui_dk;
2192618Swnj 		dk_seek[ui->ui_dk]++;
2202618Swnj 	}
2212618Swnj 	goto out;
2222618Swnj done:
2232618Swnj 	if (dp->b_active != 2) {
2242618Swnj 		dp->b_forw = NULL;
2252618Swnj 		if (um->um_tab.b_actf == NULL)
2262618Swnj 			um->um_tab.b_actf = dp;
2272618Swnj 		else
2282618Swnj 			um->um_tab.b_actl->b_forw = dp;
2292618Swnj 		um->um_tab.b_actl = dp;
2302618Swnj 		dp->b_active = 2;
2312618Swnj 	}
2322618Swnj out:
2332618Swnj 	return (didie);
2342618Swnj }
2352618Swnj 
2362618Swnj rkstart(um)
2372618Swnj 	register struct uba_minfo *um;
2381899Swnj {
2392618Swnj 	register struct buf *bp, *dp;
2402618Swnj 	register struct uba_dinfo *ui;
2412618Swnj 	register struct rkdevice *rkaddr;
2422618Swnj 	struct rkst *st;
2431899Swnj 	daddr_t bn;
2442618Swnj 	int sn, tn, cmd;
2451899Swnj 
2462618Swnj loop:
2472618Swnj 	if ((dp = um->um_tab.b_actf) == NULL)
2482618Swnj 		return (0);
2492618Swnj 	if ((bp = dp->b_actf) == NULL) {
2502618Swnj 		um->um_tab.b_actf = dp->b_forw;
2512618Swnj 		goto loop;
2521899Swnj 	}
2532618Swnj 	um->um_tab.b_active++;
2542618Swnj 	ui = rkdinfo[dkunit(bp)];
2552618Swnj 	bn = dkblock(bp);
2562618Swnj 	st = &rkst[ui->ui_type];
2572618Swnj 	sn = bn%st->nspc;
2582618Swnj 	tn = sn/st->nsect;
2592618Swnj 	sn %= st->nsect;
2602618Swnj 	rkaddr = (struct rkdevice *)ui->ui_addr;
2612618Swnj 	rkaddr->rkcs1 = RK_CDT|RK_CERR;
2622618Swnj 	rkaddr->rkcs2 = ui->ui_slave;
2632618Swnj 	rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO;
2642618Swnj 	rkwait(rkaddr);
2652618Swnj 	if (um->um_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) {
2662618Swnj 		rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017];
2672618Swnj 		rkaddr->rkcs1 = RK_CDT|RK_OFFSET|RK_GO;
2682618Swnj 		rkwait(rkaddr);
2691899Swnj 	}
2702618Swnj 	rkaddr->rkcyl = bp->b_cylin;
2712618Swnj 	rkcyl[ui->ui_unit] = bp->b_cylin;
2722618Swnj 	rkaddr->rkda = (tn << 8) + sn;
2732618Swnj 	rkaddr->rkwc = -bp->b_bcount / sizeof (short);
2742618Swnj 	if (bp->b_flags & B_READ)
2752618Swnj 		cmd = RK_CDT|RK_IE|RK_READ|RK_GO;
2762618Swnj 	else
2772618Swnj 		cmd = RK_CDT|RK_IE|RK_WRITE|RK_GO;
2782618Swnj 	um->um_cmd = cmd;
2792618Swnj 	ubago(ui);
2802618Swnj 	return (1);
2811899Swnj }
2821899Swnj 
2832618Swnj rkdgo(um)
2842618Swnj 	register struct uba_minfo *um;
2851899Swnj {
2862618Swnj 	register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr;
2871899Swnj 
2882618Swnj 	rkaddr->rkba = um->um_ubinfo;
2892618Swnj 	rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300);
2902618Swnj }
2912618Swnj 
2922618Swnj hkintr(rk11)
2932618Swnj 	int rk11;
2942618Swnj {
2952618Swnj 	register struct uba_minfo *um = rkminfo[rk11];
2962618Swnj 	register struct uba_dinfo *ui;
2972618Swnj 	register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr;
2982618Swnj 	register struct buf *bp, *dp;
2992618Swnj 	int unit;
3002618Swnj 	struct rk_softc *sc = &rk_softc[um->um_ctlr];
3012618Swnj 	int as = (rkaddr->rkatt >> 8) | sc->sc_softas;
3022618Swnj 	int needie = 1;
3032618Swnj 
3042618Swnj 	sc->sc_wticks = 0;
3052618Swnj 	sc->sc_softas = 0;
3062618Swnj 	if (um->um_tab.b_active) {
3072618Swnj 		dp = um->um_tab.b_actf;
3082618Swnj 		bp = dp->b_actf;
3092618Swnj 		ui = rkdinfo[dkunit(bp)];
3102618Swnj 		dk_busy &= ~(1 << ui->ui_dk);
3112618Swnj 		if (rkaddr->rkcs1 & RK_CERR) {
3122618Swnj 			int recal;
3132618Swnj 			u_short ds = rkaddr->rkds;
3142618Swnj 			u_short cs2 = rkaddr->rkcs2;
3152618Swnj 			u_short er = rkaddr->rker;
3162618Swnj 			if (sc->sc_recal)
3172618Swnj 				printf("recal CERR\n");
318*2622Swnj 			rkerrs++;				/* GROT */
319*2622Swnj 			if (rkflags&1)				/* GROT */
320*2622Swnj 			printf("%d ds %o cs2 %o er %o\n",	/* GROT */
321*2622Swnj 			    um->um_tab.b_errcnt, ds, cs2, er);	/* GROT */
3222618Swnj 			if (er & RK_WLE)
3232618Swnj 				printf("rk%d is write locked\n", dkunit(bp));
324*2622Swnj /* THIS DOESN'T SEEM TO HAPPEN */
325*2622Swnj /* OR WAS SOMETHING BROKEN WHEN WE TRIED */
326*2622Swnj /* SPINNING A DRIVE DOWN ? */
3272618Swnj 			if (ds & RKDS_HARD)
3282618Swnj 				printf("rk%d is down\n", dkunit(bp));
3292618Swnj 			if (++um->um_tab.b_errcnt > 28 ||
3302618Swnj 			    ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD)
3312618Swnj 				bp->b_flags |= B_ERROR;
3322618Swnj 			else
3332618Swnj 				um->um_tab.b_active = 0;
3342618Swnj 			if (um->um_tab.b_errcnt > 27)
335*2622Swnj 				deverror(bp, cs2, (ds<<16)|er);
3362618Swnj 			if (cs2&RK_MDS) {
3372618Swnj 				rkaddr->rkcs2 = RK_SCLR;
3382618Swnj 				goto retry;
3391899Swnj 			}
3402618Swnj 			recal = 0;
3412618Swnj 			if (ds&RK_DROT || er&(RK_OPI|RK_SKI|RK_UNS) ||
3422618Swnj 			    (um->um_tab.b_errcnt&07) == 4)
3432618Swnj 				recal = 1;
3442618Swnj 			if ((er & (RK_DCK|RK_ECH)) == RK_DCK)
3452618Swnj 				if (rkecc(ui))
3462618Swnj 					return;
3472618Swnj 			rkaddr->rkcs1 = RK_CDT|RK_CCLR;
3482618Swnj 			rkaddr->rkcs2 = ui->ui_slave;
3492618Swnj 			rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
3502618Swnj 			rkwait(rkaddr);
3512618Swnj 			if (recal && um->um_tab.b_active == 0) {
3522618Swnj 				rkaddr->rkcs1 = RK_CDT|RK_IE|RK_RECAL|RK_GO;
3532618Swnj 				rkcyl[ui->ui_unit] = -1;
3542618Swnj 				rkwait(rkaddr);
3552618Swnj 				um->um_tab.b_active = 1;
3562618Swnj 				sc->sc_recal = 1;
3572618Swnj 				return;
3582618Swnj 			}
3591899Swnj 		}
3602618Swnj retry:
3612618Swnj 		if (sc->sc_recal) {
3622618Swnj 			sc->sc_recal = 0;
3632618Swnj 			um->um_tab.b_active = 0;
3641899Swnj 		}
3652618Swnj 		ubadone(um);
3662618Swnj 		if (um->um_tab.b_active) {
3672618Swnj 			um->um_tab.b_active = 0;
3682618Swnj 			um->um_tab.b_errcnt = 0;
3692618Swnj 			um->um_tab.b_actf = dp->b_forw;
3702618Swnj 			dp->b_active = 0;
3712618Swnj 			dp->b_errcnt = 0;
3722618Swnj 			dp->b_actf = bp->av_forw;
3732618Swnj 			bp->b_resid = -rkaddr->rkwc * sizeof(short);
3742618Swnj 			iodone(bp);
3752618Swnj 			if (dp->b_actf)
3762618Swnj 				if (rkustart(ui))
3772618Swnj 					needie = 0;
3781899Swnj 		}
3792618Swnj 		as &= ~(1<<ui->ui_slave);
3801899Swnj 	}
3812618Swnj 	for (unit = 0; as; as >>= 1, unit++)
3822618Swnj 		if (as & 1)
3832618Swnj 			if (rkustart(rkip[rk11][unit]))
3842618Swnj 				needie = 0;
3852618Swnj 	if (um->um_tab.b_actf && um->um_tab.b_active == 0)
3862618Swnj 		if (rkstart(um))
3872618Swnj 			needie = 0;
3882618Swnj 	if (needie)
3892618Swnj 		rkaddr->rkcs1 = RK_CDT|RK_IE;
3901899Swnj }
3911899Swnj 
3922618Swnj rkwait(addr)
3932618Swnj 	register struct rkdevice *addr;
3942618Swnj {
3951899Swnj 
3962618Swnj 	while ((addr->rkcs1 & RK_CRDY) == 0)
3972618Swnj 		;
3982618Swnj }
3992618Swnj 
4002618Swnj rkread(dev)
4012618Swnj 	dev_t dev;
4021899Swnj {
4032618Swnj 	register int unit = minor(dev) >> 3;
4042618Swnj 
4052618Swnj 	if (unit >= NRK07)
4062618Swnj 		u.u_error = ENXIO;
4072618Swnj 	else
4082618Swnj 		physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys);
4091899Swnj }
4101899Swnj 
4112618Swnj rkwrite(dev)
4122618Swnj 	dev_t dev;
4131899Swnj {
4142618Swnj 	register int unit = minor(dev) >> 3;
4151899Swnj 
4162618Swnj 	if (unit >= NRK07)
4172618Swnj 		u.u_error = ENXIO;
4182618Swnj 	else
4192618Swnj 		physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys);
4201899Swnj }
4211899Swnj 
4222618Swnj rkecc(ui)
4232618Swnj 	register struct uba_dinfo *ui;
4241899Swnj {
4252618Swnj 	register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr;
4262618Swnj 	register struct buf *bp = rkutab[ui->ui_unit].b_actf;
4272618Swnj 	register struct uba_minfo *um = ui->ui_mi;
4282618Swnj 	register struct rkst *st;
4292618Swnj 	struct uba_regs *ubp = ui->ui_hd->uh_uba;
4302618Swnj 	register int i;
4312618Swnj 	caddr_t addr;
4322618Swnj 	int reg, bit, byte, npf, mask, o, cmd, ubaddr;
4332618Swnj 	int bn, cn, tn, sn;
4341899Swnj 
4352618Swnj 	npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount) - 1;
4362618Swnj 	reg = btop(um->um_ubinfo&0x3ffff) + npf;
4372618Swnj 	o = (int)bp->b_un.b_addr & PGOFSET;
4382618Swnj 	printf("%D ", bp->b_blkno+npf);
4392618Swnj 	prdev("ECC", bp->b_dev);
4402618Swnj 	mask = rk->rkec2;
4412618Swnj 	if (mask == 0) {
4422618Swnj 		rk->rkatt = 0;
4432618Swnj 		return (0);
4442618Swnj 	}
4452618Swnj 	ubp->uba_dpr[(um->um_ubinfo>>28)&0x0f] |= UBA_BNE;
4462618Swnj 	i = rk->rkec1 - 1;		/* -1 makes 0 origin */
4472618Swnj 	bit = i&07;
4482618Swnj 	i = (i&~07)>>3;
4492618Swnj 	byte = i + o;
4502618Swnj 	while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
4512618Swnj 		addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
4522618Swnj 		    (byte & PGOFSET);
4532618Swnj 		putmemc(addr, getmemc(addr)^(mask<<bit));
4542618Swnj 		byte++;
4552618Swnj 		i++;
4562618Swnj 		bit -= 8;
4572618Swnj 	}
4582618Swnj 	um->um_tab.b_active++;	/* Either complete or continuing... */
4592618Swnj 	if (rk->rkwc == 0)
4602618Swnj 		return (0);
461*2622Swnj #ifdef notdef
462*2622Swnj 	rk->rkcs1 |= RK_GO;
463*2622Swnj #else
4642618Swnj 	rk->rkcs1 = RK_CDT|RK_CCLR;
4652618Swnj 	rk->rkcs2 = ui->ui_slave;
4662618Swnj 	rk->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
4672618Swnj 	rkwait(rk);
4682618Swnj 	bn = dkblock(bp);
4692618Swnj 	st = &rkst[ui->ui_type];
4702618Swnj 	cn = bp->b_cylin;
4712618Swnj 	sn = bn%st->nspc + npf + 1;
4722618Swnj 	tn = sn/st->nsect;
4732618Swnj 	sn %= st->nsect;
4742618Swnj 	cn += tn/st->ntrak;
4752618Swnj 	tn %= st->ntrak;
4762618Swnj 	rk->rkcyl = cn;
4772618Swnj 	rk->rkda = (tn << 8) | sn;
4782618Swnj 	ubaddr = (int)ptob(reg+1) + o;
4792618Swnj 	rk->rkba = ubaddr;
4802618Swnj 	cmd = (ubaddr >> 8) & 0x300;
4812618Swnj 	cmd |= RK_CDT|RK_IE|RK_GO|RK_READ;
4822618Swnj 	rk->rkcs1 = cmd;
483*2622Swnj #endif
4842618Swnj 	return (1);
4851899Swnj }
4861899Swnj 
4872618Swnj rkreset(uban)
4881899Swnj {
4892618Swnj 	register struct uba_minfo *um;
4902618Swnj 	register struct uba_dinfo *ui;
4912618Swnj 	register rk11, unit;
4922618Swnj 	int any = 0;
4931899Swnj 
4942618Swnj 	for (rk11 = 0; rk11 < NRK11; rk11++) {
4952618Swnj 		if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban ||
4962618Swnj 		    um->um_alive == 0)
4972618Swnj 			continue;
4982618Swnj 		if (any == 0) {
4992618Swnj 			printf(" rk");
5002618Swnj 			any++;
5012618Swnj 		}
5022618Swnj 		um->um_tab.b_active = 0;
5032618Swnj 		um->um_tab.b_actf = um->um_tab.b_actl = 0;
5042618Swnj 		rk_softc[um->um_ctlr].sc_recal = 0;
5052618Swnj 		if (um->um_ubinfo) {
5062618Swnj 			printf("<%d>", (um->um_ubinfo>>28)&0xf);
5072618Swnj 			ubadone(um);
5082618Swnj 		}
5092618Swnj 		((struct rkdevice *)(um->um_addr))->rkcs1 = RK_CDT|RK_CCLR;
5102618Swnj 		rkwait((struct rkdevice *)(um->um_addr));
5112618Swnj 		for (unit = 0; unit < NRK11; unit++) {
5122618Swnj 			if ((ui = rkdinfo[unit]) == 0)
5132618Swnj 				continue;
5142618Swnj 			if (ui->ui_alive == 0)
5152618Swnj 				continue;
5162618Swnj 			rkutab[unit].b_active = 0;
5172618Swnj 			(void) rkustart(ui);
5182618Swnj 		}
5192618Swnj 		(void) rkstart(um);
5202618Swnj 	}
5211899Swnj }
5222380Swnj 
5232618Swnj rkwatch()
5242380Swnj {
5252618Swnj 	register struct uba_minfo *um;
5262618Swnj 	register rk11, unit;
5272618Swnj 	register struct rk_softc *sc;
5282380Swnj 
5292618Swnj 	timeout(rkwatch, (caddr_t)0, HZ);
5302618Swnj 	for (rk11 = 0; rk11 < NRK11; rk11++) {
5312618Swnj 		um = rkminfo[rk11];
5322618Swnj 		if (um == 0 || um->um_alive == 0)
5332618Swnj 			continue;
5342618Swnj 		sc = &rk_softc[rk11];
5352618Swnj 		if (um->um_tab.b_active == 0) {
5362618Swnj 			for (unit = 0; unit < NRK07; unit++)
537*2622Swnj 				if (rkutab[unit].b_active &&
538*2622Swnj 				    rkdinfo[unit]->ui_mi == um)
5392618Swnj 					goto active;
5402618Swnj 			sc->sc_wticks = 0;
5412618Swnj 			continue;
5422618Swnj 		}
5432618Swnj active:
5442618Swnj 		sc->sc_wticks++;
5452618Swnj 		if (sc->sc_wticks >= 20) {
5462618Swnj 			sc->sc_wticks = 0;
5472618Swnj 			printf("LOST INTERRUPT RESET");
5482618Swnj 			/* SHOULD JUST RESET ONE CTLR, NOT ALL ON UBA */
5492618Swnj 			rkreset(um->um_ubanum);
5502618Swnj 			printf("\n");
5512618Swnj 		}
5522618Swnj 	}
5532380Swnj }
5542618Swnj 
5552618Swnj #define	DBSIZE	20
5562618Swnj 
5572618Swnj rkdump(dev)
5582618Swnj 	dev_t dev;
5592618Swnj {
5602618Swnj 	struct rkdevice *rkaddr;
5612618Swnj 	char *start;
5622618Swnj 	int num, blk, unit;
5632618Swnj 	struct size *sizes;
5642618Swnj 	register struct uba_regs *uba;
5652618Swnj 	register struct uba_dinfo *ui;
5662618Swnj 	register short *rp;
5672618Swnj 	struct rkst *st;
5682618Swnj 
5692618Swnj 	unit = minor(dev) >> 3;
5702618Swnj 	if (unit >= NRK07) {
5712618Swnj 		printf("bad unit\n");
5722618Swnj 		return (-1);
5732618Swnj 	}
5742618Swnj #define	phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
5752618Swnj 	ui = phys(struct uba_dinfo *, rkdinfo[unit]);
5762618Swnj 	if (ui->ui_alive == 0) {
5772618Swnj 		printf("dna\n");
5782618Swnj 		return(-1);
5792618Swnj 	}
5802618Swnj 	uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
5812618Swnj #if VAX780
5822618Swnj 	if (cpu == VAX_780)
5832618Swnj 		ubainit(uba);
5841899Swnj #endif
5852618Swnj 	rkaddr = (struct rkdevice *)ui->ui_physaddr;
5862618Swnj 	num = maxfree;
5872618Swnj 	start = 0;
5882618Swnj 	rkaddr->rkcs1 = RK_CDT|RK_CERR;
5892618Swnj 	rkaddr->rkcs2 = unit;
5902618Swnj 	rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
5912618Swnj 	rkwait(rkaddr);
5922618Swnj 	if ((rkaddr->rkds & RK_VV) == 0) {
5932618Swnj 		rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO;
5942618Swnj 		rkwait(rkaddr);
5952618Swnj 	}
5962618Swnj 	st = &rkst[ui->ui_type];
5972618Swnj 	sizes = phys(struct size *, st->sizes);
5982618Swnj 	if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) {
5992618Swnj 		printf("oor\n");
6002618Swnj 		return (-1);
6012618Swnj 	}
6022618Swnj 	while (num > 0) {
6032618Swnj 		register struct pte *io;
6042618Swnj 		register int i;
6052618Swnj 		int cn, sn, tn;
6062618Swnj 		daddr_t bn;
6072618Swnj 
6082618Swnj 		blk = num > DBSIZE ? DBSIZE : num;
6092618Swnj 		io = uba->uba_map;
6102618Swnj 		for (i = 0; i < blk; i++)
6112618Swnj 			*(int *)io++ = (btop(start)+i) | (1<<21) | UBA_MRV;
6122618Swnj 		*(int *)io = 0;
6132618Swnj 		bn = dumplo + btop(start);
6142618Swnj 		cn = bn/st->nspc + sizes[minor(dev)&07].cyloff;
6152618Swnj 		sn = bn%st->nspc;
6162618Swnj 		tn = sn/st->nsect;
6172618Swnj 		sn = sn%st->nsect;
6182618Swnj 		rkaddr->rkcyl = cn;
6192618Swnj 		rp = (short *) &rkaddr->rkda;
6202618Swnj 		*rp = (tn << 8) + sn;
6212618Swnj 		*--rp = 0;
6222618Swnj 		*--rp = -blk*NBPG / sizeof (short);
6232618Swnj 		*--rp = RK_CDT|RK_GO|RK_WRITE;
6242618Swnj 		rkwait(rkaddr);
6252618Swnj 		if (rkaddr->rkcs1 & RK_CERR) {
6262618Swnj 	printf("rk dump dsk err: (%d,%d,%d) cs1=%x, ds=%x, er1=%x\n",
6272618Swnj 			    cn, tn, sn,
6282618Swnj 			    rkaddr->rkcs1&0xffff, rkaddr->rkds&0xffff,
6292618Swnj 			    rkaddr->rker&0xffff);
6302618Swnj 			return (-1);
6312618Swnj 		}
6322618Swnj 		start += blk*NBPG;
6332618Swnj 		num -= blk;
6342618Swnj 	}
6352618Swnj 	return (0);
6362618Swnj }
6372618Swnj #endif
638