1*2957Swnj /* rk.c 4.23 03/06/81 */ 21899Swnj 3*2957Swnj int rkpip; 4*2957Swnj int rknosval; 51942Swnj #include "rk.h" 62648Swnj #if NHK > 0 71899Swnj /* 82618Swnj * RK11/RK07 disk driver 92622Swnj * 102622Swnj * This driver mimics up.c; see it for an explanation of common code. 112685Swnj * 122885Swnj * TODO: 132885Swnj * Add reading of bad sector information and disk layout from sector 1 142885Swnj * Add bad sector forwarding code 152903Swnj * Why do we lose an interrupt sometime when spinning drives down? 161899Swnj */ 172618Swnj #define DELAY(i) { register int j; j = i; while (--j > 0); } 181899Swnj #include "../h/param.h" 191899Swnj #include "../h/systm.h" 201899Swnj #include "../h/buf.h" 211899Swnj #include "../h/conf.h" 221899Swnj #include "../h/dir.h" 231899Swnj #include "../h/user.h" 241899Swnj #include "../h/pte.h" 251899Swnj #include "../h/map.h" 262618Swnj #include "../h/vm.h" 271899Swnj #include "../h/uba.h" 281899Swnj #include "../h/dk.h" 292618Swnj #include "../h/cpu.h" 302618Swnj #include "../h/cmap.h" 311899Swnj 322618Swnj #include "../h/rkreg.h" 331899Swnj 342618Swnj struct rk_softc { 352618Swnj int sc_softas; 362618Swnj int sc_ndrive; 372618Swnj int sc_wticks; 382618Swnj int sc_recal; 392648Swnj } rk_softc[NHK]; 401899Swnj 412618Swnj /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 422787Swnj struct size { 432618Swnj daddr_t nblocks; 442618Swnj int cyloff; 452618Swnj } rk7_sizes[] ={ 462618Swnj 15884, 0, /* A=cyl 0 thru 240 */ 472665Swnj 10032, 241, /* B=cyl 241 thru 392 */ 482665Swnj 53790, 0, /* C=cyl 0 thru 814 */ 492618Swnj 0, 0, 502618Swnj 0, 0, 512618Swnj 0, 0, 522618Swnj 27786, 393, /* G=cyl 393 thru 813 */ 532618Swnj 0, 0, 542618Swnj }; 552618Swnj /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 561899Swnj 572618Swnj int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr(); 582648Swnj struct uba_minfo *rkminfo[NHK]; 592648Swnj struct uba_dinfo *rkdinfo[NRK]; 602648Swnj struct uba_dinfo *rkip[NHK][4]; 611899Swnj 622618Swnj u_short rkstd[] = { 0777440, 0 }; 632618Swnj struct uba_driver hkdriver = 642622Swnj { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 }; 652648Swnj struct buf rkutab[NRK]; 662648Swnj short rkcyl[NRK]; 671899Swnj 682618Swnj struct rkst { 692618Swnj short nsect; 702618Swnj short ntrak; 712618Swnj short nspc; 722618Swnj short ncyl; 732618Swnj struct size *sizes; 742618Swnj } rkst[] = { 752618Swnj NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes, 762618Swnj }; 771899Swnj 782618Swnj u_char rk_offset[16] = 792618Swnj { P400,M400,P400,M400,P800,M800,P800,M800,P1200,M1200,P1200,M1200,0,0,0,0 }; 801899Swnj 812648Swnj struct buf rrkbuf[NRK]; 822618Swnj 832618Swnj #define b_cylin b_resid 842618Swnj 852618Swnj #ifdef INTRLVE 862618Swnj daddr_t dkblock(); 872618Swnj #endif 882618Swnj 892618Swnj int rkwstart, rkwatch(); 902618Swnj 912618Swnj rkprobe(reg) 922618Swnj caddr_t reg; 931899Swnj { 942618Swnj register int br, cvec; 951899Swnj 962618Swnj #ifdef lint 972618Swnj br = 0; cvec = br; br = cvec; 982618Swnj #endif 992618Swnj ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY; 1002618Swnj DELAY(10); 1012618Swnj ((struct rkdevice *)reg)->rkcs1 = RK_CDT; 1022618Swnj return (1); 1032618Swnj } 1041899Swnj 1052618Swnj rkslave(ui, reg) 1062618Swnj struct uba_dinfo *ui; 1072618Swnj caddr_t reg; 1082618Swnj { 1092618Swnj register struct rkdevice *rkaddr = (struct rkdevice *)reg; 1101899Swnj 1112894Swnj rkaddr->rkcs1 = RK_CDT|RK_CCLR; 1122618Swnj rkaddr->rkcs2 = ui->ui_slave; 113*2957Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 1142622Swnj rkwait(rkaddr); 1152894Swnj DELAY(50); 1162894Swnj if (rkaddr->rkcs2&RK_NED || (rkaddr->rkds&RK_SVAL) == 0) { 1172618Swnj rkaddr->rkcs1 = RK_CDT|RK_CCLR; 1182618Swnj return (0); 1192618Swnj } 1202618Swnj return (1); 1212618Swnj } 1222618Swnj 1232618Swnj rkattach(ui) 1242618Swnj register struct uba_dinfo *ui; 1252618Swnj { 1262618Swnj 1272618Swnj if (rkwstart == 0) { 1282758Swnj timeout(rkwatch, (caddr_t)0, hz); 1292618Swnj rkwstart++; 1302618Swnj } 1312618Swnj if (ui->ui_dk >= 0) 1322758Swnj dk_mspw[ui->ui_dk] = 1.0 / (60 * NRKSECT * 256); 1332618Swnj rkip[ui->ui_ctlr][ui->ui_slave] = ui; 1342618Swnj rk_softc[ui->ui_ctlr].sc_ndrive++; 1352618Swnj rkcyl[ui->ui_unit] = -1; 1362618Swnj } 1372618Swnj 1381899Swnj rkstrategy(bp) 1392618Swnj register struct buf *bp; 1401899Swnj { 1412618Swnj register struct uba_dinfo *ui; 1422618Swnj register struct rkst *st; 1432618Swnj register int unit; 1442618Swnj register struct buf *dp; 1452618Swnj int xunit = minor(bp->b_dev) & 07; 1462618Swnj long bn, sz; 1471899Swnj 1482618Swnj sz = (bp->b_bcount+511) >> 9; 1492618Swnj unit = dkunit(bp); 1502648Swnj if (unit >= NRK) 1512618Swnj goto bad; 1522618Swnj ui = rkdinfo[unit]; 1532618Swnj if (ui == 0 || ui->ui_alive == 0) 1542618Swnj goto bad; 1552618Swnj st = &rkst[ui->ui_type]; 1562618Swnj if (bp->b_blkno < 0 || 1572618Swnj (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) 1582618Swnj goto bad; 1592618Swnj bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; 1602618Swnj (void) spl5(); 1612618Swnj dp = &rkutab[ui->ui_unit]; 1622618Swnj disksort(dp, bp); 1632618Swnj if (dp->b_active == 0) { 1642618Swnj (void) rkustart(ui); 1652618Swnj bp = &ui->ui_mi->um_tab; 1662618Swnj if (bp->b_actf && bp->b_active == 0) 1672618Swnj (void) rkstart(ui->ui_mi); 1681899Swnj } 1692618Swnj (void) spl0(); 1702618Swnj return; 1712618Swnj 1722618Swnj bad: 1732618Swnj bp->b_flags |= B_ERROR; 1742618Swnj iodone(bp); 1752618Swnj return; 1761899Swnj } 1771899Swnj 1782618Swnj rkustart(ui) 1792618Swnj register struct uba_dinfo *ui; 1802618Swnj { 1812618Swnj register struct buf *bp, *dp; 1822618Swnj register struct uba_minfo *um; 1832618Swnj register struct rkdevice *rkaddr; 1842618Swnj register struct rkst *st; 1852618Swnj daddr_t bn; 1862618Swnj int sn, csn; 1872618Swnj int didie = 0; 1881899Swnj 1892618Swnj if (ui == 0) 1902618Swnj return (0); 1912618Swnj dk_busy &= ~(1<<ui->ui_dk); 1922618Swnj dp = &rkutab[ui->ui_unit]; 1932618Swnj um = ui->ui_mi; 1942894Swnj rkaddr = (struct rkdevice *)um->um_addr; 1952618Swnj if (um->um_tab.b_active) { 1962618Swnj rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 1972618Swnj return (0); 1982618Swnj } 1992618Swnj rkaddr->rkcs1 = RK_CDT|RK_CERR; 2002618Swnj rkaddr->rkcs2 = ui->ui_slave; 201*2957Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 2022618Swnj rkwait(rkaddr); 2032903Swnj if ((bp = dp->b_actf) == NULL) { 2042903Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 2052903Swnj rkwait(rkaddr); 2062903Swnj return (0); 2072903Swnj } 2082618Swnj if ((rkaddr->rkds & RK_VV) == 0) { 2092618Swnj /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ 2102894Swnj rkaddr->rkcs1 = RK_CDT|RK_PACK|RK_GO; 2112618Swnj rkwait(rkaddr); 2122618Swnj } 2132903Swnj if (dp->b_active) 2142903Swnj goto done; 2152903Swnj dp->b_active = 1; 2162894Swnj if ((rkaddr->rkds & RK_DREADY) != RK_DREADY) 2172894Swnj goto done; 2182618Swnj if (rk_softc[um->um_ctlr].sc_ndrive == 1) 2192618Swnj goto done; 2202618Swnj if (bp->b_cylin == rkcyl[ui->ui_unit]) 2212618Swnj goto done; 2222618Swnj rkaddr->rkcyl = bp->b_cylin; 2232618Swnj rkcyl[ui->ui_unit] = bp->b_cylin; 2242618Swnj rkaddr->rkcs1 = RK_CDT|RK_IE|RK_SEEK|RK_GO; 2252618Swnj didie = 1; 2262618Swnj if (ui->ui_dk >= 0) { 2272618Swnj dk_busy |= 1<<ui->ui_dk; 2282618Swnj dk_seek[ui->ui_dk]++; 2292618Swnj } 2302618Swnj goto out; 2312618Swnj done: 2322618Swnj if (dp->b_active != 2) { 2332618Swnj dp->b_forw = NULL; 2342618Swnj if (um->um_tab.b_actf == NULL) 2352618Swnj um->um_tab.b_actf = dp; 2362618Swnj else 2372618Swnj um->um_tab.b_actl->b_forw = dp; 2382618Swnj um->um_tab.b_actl = dp; 2392618Swnj dp->b_active = 2; 2402618Swnj } 2412618Swnj out: 2422618Swnj return (didie); 2432618Swnj } 2442618Swnj 2452618Swnj rkstart(um) 2462618Swnj register struct uba_minfo *um; 2471899Swnj { 2482618Swnj register struct buf *bp, *dp; 2492618Swnj register struct uba_dinfo *ui; 2502618Swnj register struct rkdevice *rkaddr; 2512618Swnj struct rkst *st; 2521899Swnj daddr_t bn; 2532618Swnj int sn, tn, cmd; 2541899Swnj 2552618Swnj loop: 2562618Swnj if ((dp = um->um_tab.b_actf) == NULL) 2572618Swnj return (0); 2582618Swnj if ((bp = dp->b_actf) == NULL) { 2592618Swnj um->um_tab.b_actf = dp->b_forw; 2602618Swnj goto loop; 2611899Swnj } 2622618Swnj um->um_tab.b_active++; 2632618Swnj ui = rkdinfo[dkunit(bp)]; 2642618Swnj bn = dkblock(bp); 2652618Swnj st = &rkst[ui->ui_type]; 2662618Swnj sn = bn%st->nspc; 2672618Swnj tn = sn/st->nsect; 2682618Swnj sn %= st->nsect; 2692618Swnj rkaddr = (struct rkdevice *)ui->ui_addr; 270*2957Swnj retry: 2712618Swnj rkaddr->rkcs1 = RK_CDT|RK_CERR; 2722618Swnj rkaddr->rkcs2 = ui->ui_slave; 273*2957Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 2742618Swnj rkwait(rkaddr); 275*2957Swnj if ((rkaddr->rkds&RK_SVAL) == 0) { 276*2957Swnj rknosval++; 277*2957Swnj goto nosval; 2782894Swnj } 279*2957Swnj if (rkaddr->rkds&RK_PIP) { 280*2957Swnj rkpip++; 281*2957Swnj goto retry; 282*2957Swnj } 2832894Swnj if ((rkaddr->rkds&RK_DREADY) != RK_DREADY) { 2842927Swnj printf("rk%d: not ready", dkunit(bp)); 2852894Swnj if ((rkaddr->rkds&RK_DREADY) != RK_DREADY) { 2862894Swnj printf("\n"); 2872894Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 2882894Swnj rkwait(rkaddr); 2892894Swnj rkaddr->rkcs1 = RK_CDT|RK_CERR; 2902894Swnj rkwait(rkaddr); 2912894Swnj um->um_tab.b_active = 0; 2922894Swnj um->um_tab.b_errcnt = 0; 2932894Swnj dp->b_actf = bp->av_forw; 2942894Swnj dp->b_active = 0; 2952894Swnj bp->b_flags |= B_ERROR; 2962894Swnj iodone(bp); 2972894Swnj goto loop; 2982894Swnj } 2992894Swnj printf(" (came back!)\n"); 3002894Swnj } 301*2957Swnj nosval: 3022618Swnj rkaddr->rkcyl = bp->b_cylin; 3032618Swnj rkcyl[ui->ui_unit] = bp->b_cylin; 3042618Swnj rkaddr->rkda = (tn << 8) + sn; 3052618Swnj rkaddr->rkwc = -bp->b_bcount / sizeof (short); 3062618Swnj if (bp->b_flags & B_READ) 3072618Swnj cmd = RK_CDT|RK_IE|RK_READ|RK_GO; 3082618Swnj else 3092618Swnj cmd = RK_CDT|RK_IE|RK_WRITE|RK_GO; 3102618Swnj um->um_cmd = cmd; 3112618Swnj ubago(ui); 3122618Swnj return (1); 3131899Swnj } 3141899Swnj 3152618Swnj rkdgo(um) 3162618Swnj register struct uba_minfo *um; 3171899Swnj { 3182618Swnj register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 3191899Swnj 3202618Swnj rkaddr->rkba = um->um_ubinfo; 3212618Swnj rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 3222618Swnj } 3232618Swnj 3242710Swnj rkintr(rk11) 3252618Swnj int rk11; 3262618Swnj { 3272618Swnj register struct uba_minfo *um = rkminfo[rk11]; 3282618Swnj register struct uba_dinfo *ui; 3292618Swnj register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 3302618Swnj register struct buf *bp, *dp; 3312618Swnj int unit; 3322618Swnj struct rk_softc *sc = &rk_softc[um->um_ctlr]; 3332618Swnj int as = (rkaddr->rkatt >> 8) | sc->sc_softas; 3342618Swnj int needie = 1; 3352618Swnj 3362618Swnj sc->sc_wticks = 0; 3372618Swnj sc->sc_softas = 0; 3382618Swnj if (um->um_tab.b_active) { 339*2957Swnj ubadone(um); 3402618Swnj dp = um->um_tab.b_actf; 3412618Swnj bp = dp->b_actf; 3422618Swnj ui = rkdinfo[dkunit(bp)]; 3432618Swnj dk_busy &= ~(1 << ui->ui_dk); 3442618Swnj if (rkaddr->rkcs1 & RK_CERR) { 3452618Swnj int recal; 3462618Swnj u_short ds = rkaddr->rkds; 3472618Swnj u_short cs2 = rkaddr->rkcs2; 3482618Swnj u_short er = rkaddr->rker; 3492685Swnj if (ds & RK_WLE) { 3502927Swnj printf("rk%d: write locked\n", dkunit(bp)); 3512685Swnj bp->b_flags |= B_ERROR; 3522685Swnj } else if (++um->um_tab.b_errcnt > 28 || 3532676Swnj ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { 3542618Swnj bp->b_flags |= B_ERROR; 3552927Swnj harderr(bp, "rk"); 3562927Swnj printf("cs2=%b ds=%b er=%b\n", 3572894Swnj cs2, RKCS2_BITS, ds, 3582676Swnj RKDS_BITS, er, RKER_BITS); 3592676Swnj } else 3602618Swnj um->um_tab.b_active = 0; 3612618Swnj if (cs2&RK_MDS) { 3622618Swnj rkaddr->rkcs2 = RK_SCLR; 3632618Swnj goto retry; 3641899Swnj } 3652618Swnj recal = 0; 3662618Swnj if (ds&RK_DROT || er&(RK_OPI|RK_SKI|RK_UNS) || 3672618Swnj (um->um_tab.b_errcnt&07) == 4) 3682618Swnj recal = 1; 3692618Swnj if ((er & (RK_DCK|RK_ECH)) == RK_DCK) 3702618Swnj if (rkecc(ui)) 3712618Swnj return; 3722618Swnj rkaddr->rkcs1 = RK_CDT|RK_CCLR; 3732618Swnj rkaddr->rkcs2 = ui->ui_slave; 3742618Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 3752618Swnj rkwait(rkaddr); 3762618Swnj if (recal && um->um_tab.b_active == 0) { 3772618Swnj rkaddr->rkcs1 = RK_CDT|RK_IE|RK_RECAL|RK_GO; 3782618Swnj rkcyl[ui->ui_unit] = -1; 379*2957Swnj sc->sc_recal = 0; 380*2957Swnj goto nextrecal; 3812618Swnj } 3821899Swnj } 3832618Swnj retry: 384*2957Swnj switch (sc->sc_recal) { 385*2957Swnj 386*2957Swnj case 1: 387*2957Swnj rkaddr->rkcyl = bp->b_cylin; 388*2957Swnj rkcyl[ui->ui_unit] = bp->b_cylin; 389*2957Swnj rkaddr->rkcs1 = RK_CDT|RK_IE|RK_SEEK|RK_GO; 390*2957Swnj goto nextrecal; 391*2957Swnj 392*2957Swnj case 2: 393*2957Swnj if (um->um_tab.b_errcnt < 16 || 394*2957Swnj (bp->b_flags&B_READ) != 0) 395*2957Swnj break; 396*2957Swnj rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; 397*2957Swnj rkaddr->rkcs1 = RK_CDT|RK_IE|RK_OFFSET|RK_GO; 398*2957Swnj /* fall into ... */ 399*2957Swnj nextrecal: 400*2957Swnj sc->sc_recal++; 401*2957Swnj rkwait(rkaddr); 402*2957Swnj um->um_tab.b_active = 1; 403*2957Swnj return; 404*2957Swnj 405*2957Swnj case 3: 4062618Swnj sc->sc_recal = 0; 4072618Swnj um->um_tab.b_active = 0; 408*2957Swnj break; 4091899Swnj } 4102618Swnj if (um->um_tab.b_active) { 4112618Swnj um->um_tab.b_active = 0; 4122618Swnj um->um_tab.b_errcnt = 0; 4132618Swnj um->um_tab.b_actf = dp->b_forw; 4142618Swnj dp->b_active = 0; 4152618Swnj dp->b_errcnt = 0; 4162618Swnj dp->b_actf = bp->av_forw; 4172618Swnj bp->b_resid = -rkaddr->rkwc * sizeof(short); 4182618Swnj iodone(bp); 4192618Swnj if (dp->b_actf) 4202618Swnj if (rkustart(ui)) 4212618Swnj needie = 0; 4221899Swnj } 4232618Swnj as &= ~(1<<ui->ui_slave); 4241899Swnj } 4252618Swnj for (unit = 0; as; as >>= 1, unit++) 4262618Swnj if (as & 1) 4272618Swnj if (rkustart(rkip[rk11][unit])) 4282618Swnj needie = 0; 4292618Swnj if (um->um_tab.b_actf && um->um_tab.b_active == 0) 4302618Swnj if (rkstart(um)) 4312618Swnj needie = 0; 4322618Swnj if (needie) 4332618Swnj rkaddr->rkcs1 = RK_CDT|RK_IE; 4341899Swnj } 4351899Swnj 4362618Swnj rkwait(addr) 4372618Swnj register struct rkdevice *addr; 4382618Swnj { 4391899Swnj 4402618Swnj while ((addr->rkcs1 & RK_CRDY) == 0) 4412618Swnj ; 4422618Swnj } 4432618Swnj 4442618Swnj rkread(dev) 4452618Swnj dev_t dev; 4461899Swnj { 4472618Swnj register int unit = minor(dev) >> 3; 4482618Swnj 4492648Swnj if (unit >= NRK) 4502618Swnj u.u_error = ENXIO; 4512618Swnj else 4522618Swnj physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys); 4531899Swnj } 4541899Swnj 4552618Swnj rkwrite(dev) 4562618Swnj dev_t dev; 4571899Swnj { 4582618Swnj register int unit = minor(dev) >> 3; 4591899Swnj 4602648Swnj if (unit >= NRK) 4612618Swnj u.u_error = ENXIO; 4622618Swnj else 4632618Swnj physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys); 4641899Swnj } 4651899Swnj 4662618Swnj rkecc(ui) 4672618Swnj register struct uba_dinfo *ui; 4681899Swnj { 4692618Swnj register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr; 4702618Swnj register struct buf *bp = rkutab[ui->ui_unit].b_actf; 4712618Swnj register struct uba_minfo *um = ui->ui_mi; 4722618Swnj register struct rkst *st; 4732618Swnj struct uba_regs *ubp = ui->ui_hd->uh_uba; 4742618Swnj register int i; 4752618Swnj caddr_t addr; 4762618Swnj int reg, bit, byte, npf, mask, o, cmd, ubaddr; 4772618Swnj int bn, cn, tn, sn; 4781899Swnj 4792618Swnj npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount) - 1; 4802618Swnj reg = btop(um->um_ubinfo&0x3ffff) + npf; 4812618Swnj o = (int)bp->b_un.b_addr & PGOFSET; 4822940Swnj printf("rk%d%c: soft ecc sn%d\n", dkunit(bp), 4832885Swnj 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); 4842618Swnj mask = rk->rkec2; 4852724Swnj ubapurge(um); 4862618Swnj i = rk->rkec1 - 1; /* -1 makes 0 origin */ 4872618Swnj bit = i&07; 4882618Swnj i = (i&~07)>>3; 4892618Swnj byte = i + o; 4902618Swnj while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { 4912618Swnj addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 4922618Swnj (byte & PGOFSET); 4932618Swnj putmemc(addr, getmemc(addr)^(mask<<bit)); 4942618Swnj byte++; 4952618Swnj i++; 4962618Swnj bit -= 8; 4972618Swnj } 4982618Swnj um->um_tab.b_active++; /* Either complete or continuing... */ 4992618Swnj if (rk->rkwc == 0) 5002618Swnj return (0); 5012622Swnj #ifdef notdef 5022622Swnj rk->rkcs1 |= RK_GO; 5032622Swnj #else 5042618Swnj rk->rkcs1 = RK_CDT|RK_CCLR; 5052618Swnj rk->rkcs2 = ui->ui_slave; 5062618Swnj rk->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 5072618Swnj rkwait(rk); 5082618Swnj bn = dkblock(bp); 5092618Swnj st = &rkst[ui->ui_type]; 5102618Swnj cn = bp->b_cylin; 5112618Swnj sn = bn%st->nspc + npf + 1; 5122618Swnj tn = sn/st->nsect; 5132618Swnj sn %= st->nsect; 5142618Swnj cn += tn/st->ntrak; 5152618Swnj tn %= st->ntrak; 5162618Swnj rk->rkcyl = cn; 5172618Swnj rk->rkda = (tn << 8) | sn; 5182618Swnj ubaddr = (int)ptob(reg+1) + o; 5192618Swnj rk->rkba = ubaddr; 5202618Swnj cmd = (ubaddr >> 8) & 0x300; 5212618Swnj cmd |= RK_CDT|RK_IE|RK_GO|RK_READ; 5222618Swnj rk->rkcs1 = cmd; 5232622Swnj #endif 5242618Swnj return (1); 5251899Swnj } 5261899Swnj 5272618Swnj rkreset(uban) 5282927Swnj int uban; 5291899Swnj { 5302618Swnj register struct uba_minfo *um; 5312618Swnj register struct uba_dinfo *ui; 5322618Swnj register rk11, unit; 5331899Swnj 5342648Swnj for (rk11 = 0; rk11 < NHK; rk11++) { 5352618Swnj if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || 5362618Swnj um->um_alive == 0) 5372618Swnj continue; 5382927Swnj printf(" hk%d", rk11); 5392618Swnj um->um_tab.b_active = 0; 5402618Swnj um->um_tab.b_actf = um->um_tab.b_actl = 0; 5412618Swnj rk_softc[um->um_ctlr].sc_recal = 0; 5422618Swnj if (um->um_ubinfo) { 5432618Swnj printf("<%d>", (um->um_ubinfo>>28)&0xf); 5442618Swnj ubadone(um); 5452618Swnj } 5462648Swnj for (unit = 0; unit < NHK; unit++) { 5472618Swnj if ((ui = rkdinfo[unit]) == 0) 5482618Swnj continue; 5492618Swnj if (ui->ui_alive == 0) 5502618Swnj continue; 5512618Swnj rkutab[unit].b_active = 0; 5522618Swnj (void) rkustart(ui); 5532618Swnj } 5542618Swnj (void) rkstart(um); 5552618Swnj } 5561899Swnj } 5572380Swnj 5582618Swnj rkwatch() 5592380Swnj { 5602618Swnj register struct uba_minfo *um; 5612618Swnj register rk11, unit; 5622618Swnj register struct rk_softc *sc; 5632380Swnj 5642758Swnj timeout(rkwatch, (caddr_t)0, hz); 5652648Swnj for (rk11 = 0; rk11 < NHK; rk11++) { 5662618Swnj um = rkminfo[rk11]; 5672618Swnj if (um == 0 || um->um_alive == 0) 5682618Swnj continue; 5692618Swnj sc = &rk_softc[rk11]; 5702618Swnj if (um->um_tab.b_active == 0) { 5712648Swnj for (unit = 0; unit < NRK; unit++) 5722622Swnj if (rkutab[unit].b_active && 5732622Swnj rkdinfo[unit]->ui_mi == um) 5742618Swnj goto active; 5752618Swnj sc->sc_wticks = 0; 5762618Swnj continue; 5772618Swnj } 5782618Swnj active: 5792618Swnj sc->sc_wticks++; 5802618Swnj if (sc->sc_wticks >= 20) { 5812618Swnj sc->sc_wticks = 0; 5822927Swnj printf("hk%d: lost interrupt\n", rk11); 5832648Swnj ubareset(um->um_ubanum); 5842618Swnj } 5852618Swnj } 5862380Swnj } 5872618Swnj 5882618Swnj #define DBSIZE 20 5892618Swnj 5902618Swnj rkdump(dev) 5912618Swnj dev_t dev; 5922618Swnj { 5932618Swnj struct rkdevice *rkaddr; 5942618Swnj char *start; 5952618Swnj int num, blk, unit; 5962618Swnj struct size *sizes; 5972618Swnj register struct uba_regs *uba; 5982618Swnj register struct uba_dinfo *ui; 5992618Swnj register short *rp; 6002618Swnj struct rkst *st; 6012618Swnj 6022618Swnj unit = minor(dev) >> 3; 6032885Swnj if (unit >= NRK) 6042885Swnj return (ENXIO); 6052618Swnj #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 6062618Swnj ui = phys(struct uba_dinfo *, rkdinfo[unit]); 6072885Swnj if (ui->ui_alive == 0) 6082885Swnj return (ENXIO); 6092618Swnj uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 6102618Swnj #if VAX780 6112618Swnj if (cpu == VAX_780) 6122618Swnj ubainit(uba); 6131899Swnj #endif 6142618Swnj rkaddr = (struct rkdevice *)ui->ui_physaddr; 6152618Swnj num = maxfree; 6162618Swnj start = 0; 6172618Swnj rkaddr->rkcs1 = RK_CDT|RK_CERR; 6182618Swnj rkaddr->rkcs2 = unit; 6192618Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 6202618Swnj rkwait(rkaddr); 6212618Swnj if ((rkaddr->rkds & RK_VV) == 0) { 6222618Swnj rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO; 6232618Swnj rkwait(rkaddr); 6242618Swnj } 6252618Swnj st = &rkst[ui->ui_type]; 6262618Swnj sizes = phys(struct size *, st->sizes); 6272885Swnj if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) 6282885Swnj return (EINVAL); 6292618Swnj while (num > 0) { 6302618Swnj register struct pte *io; 6312618Swnj register int i; 6322618Swnj int cn, sn, tn; 6332618Swnj daddr_t bn; 6342618Swnj 6352618Swnj blk = num > DBSIZE ? DBSIZE : num; 6362618Swnj io = uba->uba_map; 6372618Swnj for (i = 0; i < blk; i++) 6382618Swnj *(int *)io++ = (btop(start)+i) | (1<<21) | UBA_MRV; 6392618Swnj *(int *)io = 0; 6402618Swnj bn = dumplo + btop(start); 6412618Swnj cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 6422618Swnj sn = bn%st->nspc; 6432618Swnj tn = sn/st->nsect; 6442618Swnj sn = sn%st->nsect; 6452618Swnj rkaddr->rkcyl = cn; 6462618Swnj rp = (short *) &rkaddr->rkda; 6472618Swnj *rp = (tn << 8) + sn; 6482618Swnj *--rp = 0; 6492618Swnj *--rp = -blk*NBPG / sizeof (short); 6502618Swnj *--rp = RK_CDT|RK_GO|RK_WRITE; 6512618Swnj rkwait(rkaddr); 6522885Swnj if (rkaddr->rkcs1 & RK_CERR) 6532885Swnj return (EIO); 6542618Swnj start += blk*NBPG; 6552618Swnj num -= blk; 6562618Swnj } 6572618Swnj return (0); 6582618Swnj } 6592618Swnj #endif 660