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