1*2685Swnj /* rk.c 4.12 02/25/81 */ 21899Swnj 31942Swnj #include "rk.h" 42648Swnj #if NHK > 0 52622Swnj int rkflags,rkerrs; /* GROT */ 61899Swnj /* 72618Swnj * RK11/RK07 disk driver 82622Swnj * 92622Swnj * This driver mimics up.c; see it for an explanation of common code. 10*2685Swnj * 11*2685Swnj * THIS DRIVER DOESN'T DEAL WITH DRIVES SPINNING DOWN AND UP 121899Swnj */ 132618Swnj #define DELAY(i) { register int j; j = i; while (--j > 0); } 141899Swnj #include "../h/param.h" 151899Swnj #include "../h/systm.h" 161899Swnj #include "../h/buf.h" 171899Swnj #include "../h/conf.h" 181899Swnj #include "../h/dir.h" 191899Swnj #include "../h/user.h" 201899Swnj #include "../h/pte.h" 211899Swnj #include "../h/map.h" 222618Swnj #include "../h/vm.h" 231899Swnj #include "../h/uba.h" 241899Swnj #include "../h/dk.h" 252618Swnj #include "../h/cpu.h" 262618Swnj #include "../h/cmap.h" 271899Swnj 282618Swnj #include "../h/rkreg.h" 291899Swnj 302618Swnj struct rk_softc { 312618Swnj int sc_softas; 322618Swnj int sc_ndrive; 332618Swnj int sc_wticks; 342618Swnj int sc_recal; 352648Swnj } rk_softc[NHK]; 361899Swnj 372618Swnj /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 382618Swnj struct size 392618Swnj { 402618Swnj daddr_t nblocks; 412618Swnj int cyloff; 422618Swnj } rk7_sizes[] ={ 432618Swnj 15884, 0, /* A=cyl 0 thru 240 */ 442665Swnj 10032, 241, /* B=cyl 241 thru 392 */ 452665Swnj 53790, 0, /* C=cyl 0 thru 814 */ 462618Swnj 0, 0, 472618Swnj 0, 0, 482618Swnj 0, 0, 492618Swnj 27786, 393, /* G=cyl 393 thru 813 */ 502618Swnj 0, 0, 512618Swnj }; 522618Swnj /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 531899Swnj 542618Swnj int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr(); 552648Swnj struct uba_minfo *rkminfo[NHK]; 562648Swnj struct uba_dinfo *rkdinfo[NRK]; 572648Swnj struct uba_dinfo *rkip[NHK][4]; 581899Swnj 592618Swnj u_short rkstd[] = { 0777440, 0 }; 602618Swnj struct uba_driver hkdriver = 612622Swnj { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 }; 622648Swnj struct buf rkutab[NRK]; 632648Swnj short rkcyl[NRK]; 641899Swnj 652618Swnj struct rkst { 662618Swnj short nsect; 672618Swnj short ntrak; 682618Swnj short nspc; 692618Swnj short ncyl; 702618Swnj struct size *sizes; 712618Swnj } rkst[] = { 722618Swnj NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes, 732618Swnj }; 741899Swnj 752618Swnj u_char rk_offset[16] = 762618Swnj { P400,M400,P400,M400,P800,M800,P800,M800,P1200,M1200,P1200,M1200,0,0,0,0 }; 771899Swnj 782648Swnj struct buf rrkbuf[NRK]; 792618Swnj 802618Swnj #define b_cylin b_resid 812618Swnj 822618Swnj #ifdef INTRLVE 832618Swnj daddr_t dkblock(); 842618Swnj #endif 852618Swnj 862618Swnj int rkwstart, rkwatch(); 872618Swnj 882618Swnj rkprobe(reg) 892618Swnj caddr_t reg; 901899Swnj { 912618Swnj register int br, cvec; 921899Swnj 932618Swnj #ifdef lint 942618Swnj br = 0; cvec = br; br = cvec; 952618Swnj #endif 962618Swnj ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY; 972618Swnj DELAY(10); 982618Swnj ((struct rkdevice *)reg)->rkcs1 = RK_CDT; 992618Swnj return (1); 1002618Swnj } 1011899Swnj 1022618Swnj rkslave(ui, reg) 1032618Swnj struct uba_dinfo *ui; 1042618Swnj caddr_t reg; 1052618Swnj { 1062618Swnj register struct rkdevice *rkaddr = (struct rkdevice *)reg; 1071899Swnj 1082618Swnj rkaddr->rkcs1 = RK_CDT; 1092618Swnj rkaddr->rkcs2 = ui->ui_slave; 1102622Swnj rkwait(rkaddr); 1112622Swnj /* SHOULD TRY THIS BY PULLING A PLUG */ 1122622Swnj /* A DELAY OR SOMETHING MAY BE NEEDED */ 1132618Swnj if (rkaddr->rkcs2&RK_NED) { 1142618Swnj rkaddr->rkcs1 = RK_CDT|RK_CCLR; 1152618Swnj return (0); 1162618Swnj } 1172618Swnj return (1); 1182618Swnj } 1192618Swnj 1202618Swnj rkattach(ui) 1212618Swnj register struct uba_dinfo *ui; 1222618Swnj { 1232618Swnj 1242618Swnj if (rkwstart == 0) { 1252618Swnj timeout(rkwatch, (caddr_t)0, HZ); 1262618Swnj rkwstart++; 1272618Swnj } 1282618Swnj if (ui->ui_dk >= 0) 1292618Swnj dk_mspw[ui->ui_dk] = 1.0 / (HZ * NRKSECT * 256); 1302618Swnj rkip[ui->ui_ctlr][ui->ui_slave] = ui; 1312618Swnj rk_softc[ui->ui_ctlr].sc_ndrive++; 1322618Swnj rkcyl[ui->ui_unit] = -1; 1332618Swnj } 1342618Swnj 1351899Swnj rkstrategy(bp) 1362618Swnj register struct buf *bp; 1371899Swnj { 1382618Swnj register struct uba_dinfo *ui; 1392618Swnj register struct rkst *st; 1402618Swnj register int unit; 1412618Swnj register struct buf *dp; 1422618Swnj int xunit = minor(bp->b_dev) & 07; 1432618Swnj long bn, sz; 1441899Swnj 1452618Swnj sz = (bp->b_bcount+511) >> 9; 1462618Swnj unit = dkunit(bp); 1472648Swnj if (unit >= NRK) 1482618Swnj goto bad; 1492618Swnj ui = rkdinfo[unit]; 1502618Swnj if (ui == 0 || ui->ui_alive == 0) 1512618Swnj goto bad; 1522618Swnj st = &rkst[ui->ui_type]; 1532618Swnj if (bp->b_blkno < 0 || 1542618Swnj (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) 1552618Swnj goto bad; 1562618Swnj bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; 1572618Swnj (void) spl5(); 1582618Swnj dp = &rkutab[ui->ui_unit]; 1592618Swnj disksort(dp, bp); 1602618Swnj if (dp->b_active == 0) { 1612618Swnj (void) rkustart(ui); 1622618Swnj bp = &ui->ui_mi->um_tab; 1632618Swnj if (bp->b_actf && bp->b_active == 0) 1642618Swnj (void) rkstart(ui->ui_mi); 1651899Swnj } 1662618Swnj (void) spl0(); 1672618Swnj return; 1682618Swnj 1692618Swnj bad: 1702618Swnj bp->b_flags |= B_ERROR; 1712618Swnj iodone(bp); 1722618Swnj return; 1731899Swnj } 1741899Swnj 1752618Swnj rkustart(ui) 1762618Swnj register struct uba_dinfo *ui; 1772618Swnj { 1782618Swnj register struct buf *bp, *dp; 1792618Swnj register struct uba_minfo *um; 1802618Swnj register struct rkdevice *rkaddr; 1812618Swnj register struct rkst *st; 1822618Swnj daddr_t bn; 1832618Swnj int sn, csn; 1842618Swnj int didie = 0; 1851899Swnj 1862618Swnj if (ui == 0) 1872618Swnj return (0); 1882618Swnj dk_busy &= ~(1<<ui->ui_dk); 1892618Swnj dp = &rkutab[ui->ui_unit]; 1902618Swnj if ((bp = dp->b_actf) == NULL) 1912618Swnj goto out; 1922618Swnj um = ui->ui_mi; 1932618Swnj if (um->um_tab.b_active) { 1942618Swnj rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 1952618Swnj return (0); 1962618Swnj } 1972618Swnj rkaddr = (struct rkdevice *)um->um_addr; 1982618Swnj rkaddr->rkcs1 = RK_CDT|RK_CERR; 1992618Swnj rkaddr->rkcs2 = ui->ui_slave; 2002618Swnj rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; 2012618Swnj rkwait(rkaddr); 2022618Swnj if (dp->b_active) 2032618Swnj goto done; 2042618Swnj dp->b_active = 1; 2052618Swnj if ((rkaddr->rkds & RK_VV) == 0) { 2062618Swnj /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ 2072618Swnj rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO; 2082618Swnj rkwait(rkaddr); 2092618Swnj didie = 1; 2102618Swnj } 2112618Swnj if (rk_softc[um->um_ctlr].sc_ndrive == 1) 2122618Swnj goto done; 2132618Swnj if (bp->b_cylin == rkcyl[ui->ui_unit]) 2142618Swnj goto done; 2152618Swnj rkaddr->rkcyl = bp->b_cylin; 2162618Swnj rkcyl[ui->ui_unit] = bp->b_cylin; 2172618Swnj rkaddr->rkcs1 = RK_CDT|RK_IE|RK_SEEK|RK_GO; 2182618Swnj didie = 1; 2192618Swnj if (ui->ui_dk >= 0) { 2202618Swnj dk_busy |= 1<<ui->ui_dk; 2212618Swnj dk_seek[ui->ui_dk]++; 2222618Swnj } 2232618Swnj goto out; 2242618Swnj done: 2252618Swnj if (dp->b_active != 2) { 2262618Swnj dp->b_forw = NULL; 2272618Swnj if (um->um_tab.b_actf == NULL) 2282618Swnj um->um_tab.b_actf = dp; 2292618Swnj else 2302618Swnj um->um_tab.b_actl->b_forw = dp; 2312618Swnj um->um_tab.b_actl = dp; 2322618Swnj dp->b_active = 2; 2332618Swnj } 2342618Swnj out: 2352618Swnj return (didie); 2362618Swnj } 2372618Swnj 2382618Swnj rkstart(um) 2392618Swnj register struct uba_minfo *um; 2401899Swnj { 2412618Swnj register struct buf *bp, *dp; 2422618Swnj register struct uba_dinfo *ui; 2432618Swnj register struct rkdevice *rkaddr; 2442618Swnj struct rkst *st; 2451899Swnj daddr_t bn; 2462618Swnj int sn, tn, cmd; 2471899Swnj 2482618Swnj loop: 2492618Swnj if ((dp = um->um_tab.b_actf) == NULL) 2502618Swnj return (0); 2512618Swnj if ((bp = dp->b_actf) == NULL) { 2522618Swnj um->um_tab.b_actf = dp->b_forw; 2532618Swnj goto loop; 2541899Swnj } 2552618Swnj um->um_tab.b_active++; 2562618Swnj ui = rkdinfo[dkunit(bp)]; 2572618Swnj bn = dkblock(bp); 2582618Swnj st = &rkst[ui->ui_type]; 2592618Swnj sn = bn%st->nspc; 2602618Swnj tn = sn/st->nsect; 2612618Swnj sn %= st->nsect; 2622618Swnj rkaddr = (struct rkdevice *)ui->ui_addr; 2632618Swnj rkaddr->rkcs1 = RK_CDT|RK_CERR; 2642618Swnj rkaddr->rkcs2 = ui->ui_slave; 2652618Swnj rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; 2662618Swnj rkwait(rkaddr); 2672618Swnj if (um->um_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) { 2682618Swnj rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; 2692618Swnj rkaddr->rkcs1 = RK_CDT|RK_OFFSET|RK_GO; 2702618Swnj rkwait(rkaddr); 2711899Swnj } 2722618Swnj rkaddr->rkcyl = bp->b_cylin; 2732618Swnj rkcyl[ui->ui_unit] = bp->b_cylin; 2742618Swnj rkaddr->rkda = (tn << 8) + sn; 2752618Swnj rkaddr->rkwc = -bp->b_bcount / sizeof (short); 2762618Swnj if (bp->b_flags & B_READ) 2772618Swnj cmd = RK_CDT|RK_IE|RK_READ|RK_GO; 2782618Swnj else 2792618Swnj cmd = RK_CDT|RK_IE|RK_WRITE|RK_GO; 2802618Swnj um->um_cmd = cmd; 2812618Swnj ubago(ui); 2822618Swnj return (1); 2831899Swnj } 2841899Swnj 2852618Swnj rkdgo(um) 2862618Swnj register struct uba_minfo *um; 2871899Swnj { 2882618Swnj register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 2891899Swnj 2902618Swnj rkaddr->rkba = um->um_ubinfo; 2912618Swnj rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 2922618Swnj } 2932618Swnj 2942618Swnj hkintr(rk11) 2952618Swnj int rk11; 2962618Swnj { 2972618Swnj register struct uba_minfo *um = rkminfo[rk11]; 2982618Swnj register struct uba_dinfo *ui; 2992618Swnj register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 3002618Swnj register struct buf *bp, *dp; 3012618Swnj int unit; 3022618Swnj struct rk_softc *sc = &rk_softc[um->um_ctlr]; 3032618Swnj int as = (rkaddr->rkatt >> 8) | sc->sc_softas; 3042618Swnj int needie = 1; 3052618Swnj 3062618Swnj sc->sc_wticks = 0; 3072618Swnj sc->sc_softas = 0; 3082618Swnj if (um->um_tab.b_active) { 3092618Swnj dp = um->um_tab.b_actf; 3102618Swnj bp = dp->b_actf; 3112618Swnj ui = rkdinfo[dkunit(bp)]; 3122618Swnj dk_busy &= ~(1 << ui->ui_dk); 3132618Swnj if (rkaddr->rkcs1 & RK_CERR) { 3142618Swnj int recal; 315*2685Swnj #ifdef notdef 316*2685Swnj int del = 0; 317*2685Swnj #endif 3182618Swnj u_short ds = rkaddr->rkds; 3192618Swnj u_short cs2 = rkaddr->rkcs2; 3202618Swnj u_short er = rkaddr->rker; 3212618Swnj if (sc->sc_recal) 3222618Swnj printf("recal CERR\n"); 323*2685Swnj rkerrs++; 324*2685Swnj #ifdef notdef 325*2685Swnj /* THIS ATTEMPTED TO FIND OUT IF THE DRIVE IS SPUN */ 326*2685Swnj /* DOWN BUT IT DOESN'T SEEM TO WORK... THE DRIVE SEEMS TO */ 327*2685Swnj /* TELL PAINFULLY LITTLE WHEN IT IS SPUN DOWN (I.E. NOTHING CHANGES) */ 328*2685Swnj /* THE DRIVE JUST KEEPS SAYING IT WANTS ATTENTION AND BLOWING ALL COMMANDS */ 329*2685Swnj if (ds & RK_CDA) { 330*2685Swnj rkaddr->rkcs1 = RK_CDT|RK_CERR; 331*2685Swnj rkaddr->rkcs2 = ui->ui_slave; 332*2685Swnj rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; 333*2685Swnj rkwait(rkaddr); 334*2685Swnj while ((rkaddr->rkds & RK_SVAL) == 0) 335*2685Swnj if (++del > 512) 336*2685Swnj break; 337*2685Swnj } 338*2685Swnj if (del > 512) { 339*2685Swnj printf("rk%d is down\n", dkunit(bp)); 340*2685Swnj bp->b_flags |= B_ERROR; 341*2685Swnj } else 342*2685Swnj #endif 343*2685Swnj if (ds & RK_WLE) { 3442618Swnj printf("rk%d is write locked\n", dkunit(bp)); 345*2685Swnj bp->b_flags |= B_ERROR; 346*2685Swnj } else if (++um->um_tab.b_errcnt > 28 || 3472676Swnj ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { 3482618Swnj bp->b_flags |= B_ERROR; 3492676Swnj harderr(bp); 3502676Swnj printf("rk%d cs2 %b ds %b er %b\n", 3512676Swnj dkunit(bp), cs2, RKCS2_BITS, ds, 3522676Swnj RKDS_BITS, er, RKER_BITS); 3532676Swnj } else 3542618Swnj um->um_tab.b_active = 0; 3552618Swnj if (cs2&RK_MDS) { 3562618Swnj rkaddr->rkcs2 = RK_SCLR; 3572618Swnj goto retry; 3581899Swnj } 3592618Swnj recal = 0; 3602618Swnj if (ds&RK_DROT || er&(RK_OPI|RK_SKI|RK_UNS) || 3612618Swnj (um->um_tab.b_errcnt&07) == 4) 3622618Swnj recal = 1; 3632618Swnj if ((er & (RK_DCK|RK_ECH)) == RK_DCK) 3642618Swnj if (rkecc(ui)) 3652618Swnj return; 3662618Swnj rkaddr->rkcs1 = RK_CDT|RK_CCLR; 3672618Swnj rkaddr->rkcs2 = ui->ui_slave; 3682618Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 3692618Swnj rkwait(rkaddr); 3702618Swnj if (recal && um->um_tab.b_active == 0) { 3712618Swnj rkaddr->rkcs1 = RK_CDT|RK_IE|RK_RECAL|RK_GO; 3722618Swnj rkcyl[ui->ui_unit] = -1; 3732618Swnj rkwait(rkaddr); 3742618Swnj um->um_tab.b_active = 1; 3752618Swnj sc->sc_recal = 1; 3762618Swnj return; 3772618Swnj } 3781899Swnj } 3792618Swnj retry: 3802618Swnj if (sc->sc_recal) { 3812618Swnj sc->sc_recal = 0; 3822618Swnj um->um_tab.b_active = 0; 3831899Swnj } 3842618Swnj ubadone(um); 3852618Swnj if (um->um_tab.b_active) { 3862618Swnj um->um_tab.b_active = 0; 3872618Swnj um->um_tab.b_errcnt = 0; 3882618Swnj um->um_tab.b_actf = dp->b_forw; 3892618Swnj dp->b_active = 0; 3902618Swnj dp->b_errcnt = 0; 3912618Swnj dp->b_actf = bp->av_forw; 3922618Swnj bp->b_resid = -rkaddr->rkwc * sizeof(short); 3932618Swnj iodone(bp); 3942618Swnj if (dp->b_actf) 3952618Swnj if (rkustart(ui)) 3962618Swnj needie = 0; 3971899Swnj } 3982618Swnj as &= ~(1<<ui->ui_slave); 3991899Swnj } 4002618Swnj for (unit = 0; as; as >>= 1, unit++) 4012618Swnj if (as & 1) 4022618Swnj if (rkustart(rkip[rk11][unit])) 4032618Swnj needie = 0; 4042618Swnj if (um->um_tab.b_actf && um->um_tab.b_active == 0) 4052618Swnj if (rkstart(um)) 4062618Swnj needie = 0; 4072618Swnj if (needie) 4082618Swnj rkaddr->rkcs1 = RK_CDT|RK_IE; 4091899Swnj } 4101899Swnj 4112618Swnj rkwait(addr) 4122618Swnj register struct rkdevice *addr; 4132618Swnj { 4141899Swnj 4152618Swnj while ((addr->rkcs1 & RK_CRDY) == 0) 4162618Swnj ; 4172618Swnj } 4182618Swnj 4192618Swnj rkread(dev) 4202618Swnj dev_t dev; 4211899Swnj { 4222618Swnj register int unit = minor(dev) >> 3; 4232618Swnj 4242648Swnj if (unit >= NRK) 4252618Swnj u.u_error = ENXIO; 4262618Swnj else 4272618Swnj physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys); 4281899Swnj } 4291899Swnj 4302618Swnj rkwrite(dev) 4312618Swnj dev_t dev; 4321899Swnj { 4332618Swnj register int unit = minor(dev) >> 3; 4341899Swnj 4352648Swnj if (unit >= NRK) 4362618Swnj u.u_error = ENXIO; 4372618Swnj else 4382618Swnj physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys); 4391899Swnj } 4401899Swnj 4412618Swnj rkecc(ui) 4422618Swnj register struct uba_dinfo *ui; 4431899Swnj { 4442618Swnj register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr; 4452618Swnj register struct buf *bp = rkutab[ui->ui_unit].b_actf; 4462618Swnj register struct uba_minfo *um = ui->ui_mi; 4472618Swnj register struct rkst *st; 4482618Swnj struct uba_regs *ubp = ui->ui_hd->uh_uba; 4492618Swnj register int i; 4502618Swnj caddr_t addr; 4512618Swnj int reg, bit, byte, npf, mask, o, cmd, ubaddr; 4522618Swnj int bn, cn, tn, sn; 4531899Swnj 4542618Swnj npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount) - 1; 4552618Swnj reg = btop(um->um_ubinfo&0x3ffff) + npf; 4562618Swnj o = (int)bp->b_un.b_addr & PGOFSET; 4572618Swnj printf("%D ", bp->b_blkno+npf); 4582618Swnj prdev("ECC", bp->b_dev); 4592618Swnj mask = rk->rkec2; 4602618Swnj if (mask == 0) { 4612618Swnj rk->rkatt = 0; 4622618Swnj return (0); 4632618Swnj } 4642618Swnj ubp->uba_dpr[(um->um_ubinfo>>28)&0x0f] |= UBA_BNE; 4652618Swnj i = rk->rkec1 - 1; /* -1 makes 0 origin */ 4662665Swnj printf("mask %x pos %x\n", mask, i+1); 4672618Swnj bit = i&07; 4682618Swnj i = (i&~07)>>3; 4692618Swnj byte = i + o; 4702618Swnj while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { 4712618Swnj addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 4722618Swnj (byte & PGOFSET); 4732618Swnj putmemc(addr, getmemc(addr)^(mask<<bit)); 4742618Swnj byte++; 4752618Swnj i++; 4762618Swnj bit -= 8; 4772618Swnj } 4782618Swnj um->um_tab.b_active++; /* Either complete or continuing... */ 4792618Swnj if (rk->rkwc == 0) 4802618Swnj return (0); 4812622Swnj #ifdef notdef 4822622Swnj rk->rkcs1 |= RK_GO; 4832622Swnj #else 4842618Swnj rk->rkcs1 = RK_CDT|RK_CCLR; 4852618Swnj rk->rkcs2 = ui->ui_slave; 4862618Swnj rk->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 4872618Swnj rkwait(rk); 4882618Swnj bn = dkblock(bp); 4892618Swnj st = &rkst[ui->ui_type]; 4902618Swnj cn = bp->b_cylin; 4912618Swnj sn = bn%st->nspc + npf + 1; 4922618Swnj tn = sn/st->nsect; 4932618Swnj sn %= st->nsect; 4942618Swnj cn += tn/st->ntrak; 4952618Swnj tn %= st->ntrak; 4962618Swnj rk->rkcyl = cn; 4972618Swnj rk->rkda = (tn << 8) | sn; 4982618Swnj ubaddr = (int)ptob(reg+1) + o; 4992618Swnj rk->rkba = ubaddr; 5002618Swnj cmd = (ubaddr >> 8) & 0x300; 5012618Swnj cmd |= RK_CDT|RK_IE|RK_GO|RK_READ; 5022618Swnj rk->rkcs1 = cmd; 5032622Swnj #endif 5042618Swnj return (1); 5051899Swnj } 5061899Swnj 5072618Swnj rkreset(uban) 5081899Swnj { 5092618Swnj register struct uba_minfo *um; 5102618Swnj register struct uba_dinfo *ui; 5112618Swnj register rk11, unit; 5122618Swnj int any = 0; 5131899Swnj 5142648Swnj for (rk11 = 0; rk11 < NHK; rk11++) { 5152618Swnj if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || 5162618Swnj um->um_alive == 0) 5172618Swnj continue; 5182618Swnj if (any == 0) { 5192618Swnj printf(" rk"); 5202618Swnj any++; 5212618Swnj } 5222618Swnj um->um_tab.b_active = 0; 5232618Swnj um->um_tab.b_actf = um->um_tab.b_actl = 0; 5242618Swnj rk_softc[um->um_ctlr].sc_recal = 0; 5252618Swnj if (um->um_ubinfo) { 5262618Swnj printf("<%d>", (um->um_ubinfo>>28)&0xf); 5272618Swnj ubadone(um); 5282618Swnj } 5292648Swnj for (unit = 0; unit < NHK; unit++) { 5302618Swnj if ((ui = rkdinfo[unit]) == 0) 5312618Swnj continue; 5322618Swnj if (ui->ui_alive == 0) 5332618Swnj continue; 5342618Swnj rkutab[unit].b_active = 0; 5352618Swnj (void) rkustart(ui); 5362618Swnj } 5372618Swnj (void) rkstart(um); 5382618Swnj } 5391899Swnj } 5402380Swnj 5412618Swnj rkwatch() 5422380Swnj { 5432618Swnj register struct uba_minfo *um; 5442618Swnj register rk11, unit; 5452618Swnj register struct rk_softc *sc; 5462380Swnj 5472618Swnj timeout(rkwatch, (caddr_t)0, HZ); 5482648Swnj for (rk11 = 0; rk11 < NHK; rk11++) { 5492618Swnj um = rkminfo[rk11]; 5502618Swnj if (um == 0 || um->um_alive == 0) 5512618Swnj continue; 5522618Swnj sc = &rk_softc[rk11]; 5532618Swnj if (um->um_tab.b_active == 0) { 5542648Swnj for (unit = 0; unit < NRK; unit++) 5552622Swnj if (rkutab[unit].b_active && 5562622Swnj rkdinfo[unit]->ui_mi == um) 5572618Swnj goto active; 5582618Swnj sc->sc_wticks = 0; 5592618Swnj continue; 5602618Swnj } 5612618Swnj active: 5622618Swnj sc->sc_wticks++; 5632618Swnj if (sc->sc_wticks >= 20) { 5642618Swnj sc->sc_wticks = 0; 5652648Swnj printf("LOST rkintr "); 5662648Swnj ubareset(um->um_ubanum); 5672618Swnj } 5682618Swnj } 5692380Swnj } 5702618Swnj 5712618Swnj #define DBSIZE 20 5722618Swnj 5732618Swnj rkdump(dev) 5742618Swnj dev_t dev; 5752618Swnj { 5762618Swnj struct rkdevice *rkaddr; 5772618Swnj char *start; 5782618Swnj int num, blk, unit; 5792618Swnj struct size *sizes; 5802618Swnj register struct uba_regs *uba; 5812618Swnj register struct uba_dinfo *ui; 5822618Swnj register short *rp; 5832618Swnj struct rkst *st; 5842618Swnj 5852618Swnj unit = minor(dev) >> 3; 5862648Swnj if (unit >= NRK) { 5872618Swnj printf("bad unit\n"); 5882618Swnj return (-1); 5892618Swnj } 5902618Swnj #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 5912618Swnj ui = phys(struct uba_dinfo *, rkdinfo[unit]); 5922618Swnj if (ui->ui_alive == 0) { 5932618Swnj printf("dna\n"); 5942618Swnj return(-1); 5952618Swnj } 5962618Swnj uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 5972618Swnj #if VAX780 5982618Swnj if (cpu == VAX_780) 5992618Swnj ubainit(uba); 6001899Swnj #endif 6012618Swnj rkaddr = (struct rkdevice *)ui->ui_physaddr; 6022618Swnj num = maxfree; 6032618Swnj start = 0; 6042618Swnj rkaddr->rkcs1 = RK_CDT|RK_CERR; 6052618Swnj rkaddr->rkcs2 = unit; 6062618Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 6072618Swnj rkwait(rkaddr); 6082618Swnj if ((rkaddr->rkds & RK_VV) == 0) { 6092618Swnj rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO; 6102618Swnj rkwait(rkaddr); 6112618Swnj } 6122618Swnj st = &rkst[ui->ui_type]; 6132618Swnj sizes = phys(struct size *, st->sizes); 6142618Swnj if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) { 6152618Swnj printf("oor\n"); 6162618Swnj return (-1); 6172618Swnj } 6182618Swnj while (num > 0) { 6192618Swnj register struct pte *io; 6202618Swnj register int i; 6212618Swnj int cn, sn, tn; 6222618Swnj daddr_t bn; 6232618Swnj 6242618Swnj blk = num > DBSIZE ? DBSIZE : num; 6252618Swnj io = uba->uba_map; 6262618Swnj for (i = 0; i < blk; i++) 6272618Swnj *(int *)io++ = (btop(start)+i) | (1<<21) | UBA_MRV; 6282618Swnj *(int *)io = 0; 6292618Swnj bn = dumplo + btop(start); 6302618Swnj cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 6312618Swnj sn = bn%st->nspc; 6322618Swnj tn = sn/st->nsect; 6332618Swnj sn = sn%st->nsect; 6342618Swnj rkaddr->rkcyl = cn; 6352618Swnj rp = (short *) &rkaddr->rkda; 6362618Swnj *rp = (tn << 8) + sn; 6372618Swnj *--rp = 0; 6382618Swnj *--rp = -blk*NBPG / sizeof (short); 6392618Swnj *--rp = RK_CDT|RK_GO|RK_WRITE; 6402618Swnj rkwait(rkaddr); 6412618Swnj if (rkaddr->rkcs1 & RK_CERR) { 6422618Swnj printf("rk dump dsk err: (%d,%d,%d) cs1=%x, ds=%x, er1=%x\n", 6432618Swnj cn, tn, sn, 6442618Swnj rkaddr->rkcs1&0xffff, rkaddr->rkds&0xffff, 6452618Swnj rkaddr->rker&0xffff); 6462618Swnj return (-1); 6472618Swnj } 6482618Swnj start += blk*NBPG; 6492618Swnj num -= blk; 6502618Swnj } 6512618Swnj return (0); 6522618Swnj } 6532618Swnj #endif 654