X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/c9e9b65b24ddfaa1e2a2f1c85eeaa579eddb11fc..961945a80c6f995f4567dbce8881af0bbdee211c:/usr/src/sys/vax/uba/rk.c diff --git a/usr/src/sys/vax/uba/rk.c b/usr/src/sys/vax/uba/rk.c index 801b52735f..7f170057ba 100644 --- a/usr/src/sys/vax/uba/rk.c +++ b/usr/src/sys/vax/uba/rk.c @@ -1,35 +1,42 @@ -/* rk.c 4.18 %G% */ +/* rk.c 4.51 82/12/17 */ #include "rk.h" #if NHK > 0 +int rkpip; /* DEBUG */ +int rknosval; /* DEBUG */ +#ifdef RKDEBUG +int rkdebug; +#endif +#ifdef RKBDEBUG +int rkbdebug; +#endif /* - * RK11/RK07 disk driver + * RK611/RK0[67] disk driver * * This driver mimics up.c; see it for an explanation of common code. * * TODO: - * Correct to handle spun-down drives - * Check write lock handling - * Add reading of bad sector information and disk layout from sector 1 - * Add bad sector forwarding code - * Fix drive recognition + * Learn why we lose an interrupt sometime when spinning drives down */ -#define DELAY(i) { register int j; j = i; while (--j > 0); } +#include "../machine/pte.h" + #include "../h/param.h" #include "../h/systm.h" #include "../h/buf.h" #include "../h/conf.h" #include "../h/dir.h" #include "../h/user.h" -#include "../h/pte.h" #include "../h/map.h" #include "../h/vm.h" -#include "../h/uba.h" #include "../h/dk.h" -#include "../h/cpu.h" #include "../h/cmap.h" +#include "../h/dkbad.h" +#include "../h/uio.h" -#include "../h/rkreg.h" +#include "../vax/cpu.h" +#include "../vaxuba/ubareg.h" +#include "../vaxuba/ubavar.h" +#include "../vaxuba/rkreg.h" struct rk_softc { int sc_softas; @@ -42,7 +49,7 @@ struct rk_softc { struct size { daddr_t nblocks; int cyloff; -} rk7_sizes[] ={ +} rk7_sizes[8] ={ 15884, 0, /* A=cyl 0 thru 240 */ 10032, 241, /* B=cyl 241 thru 392 */ 53790, 0, /* C=cyl 0 thru 814 */ @@ -51,19 +58,34 @@ struct size { 0, 0, 27786, 393, /* G=cyl 393 thru 813 */ 0, 0, +}, rk6_sizes[8] ={ + 15884, 0, /* A=cyl 0 thru 240 */ + 11154, 241, /* B=cyl 241 thru 409 */ + 27126, 0, /* C=cyl 0 thru 410 */ + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, }; /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ +short rktypes[] = { RK_CDT, 0 }; + int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr(); -struct uba_minfo *rkminfo[NHK]; -struct uba_dinfo *rkdinfo[NRK]; -struct uba_dinfo *rkip[NHK][4]; +struct uba_ctlr *rkminfo[NHK]; +struct uba_device *rkdinfo[NRK]; +struct uba_device *rkip[NHK][4]; u_short rkstd[] = { 0777440, 0 }; struct uba_driver hkdriver = { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 }; struct buf rkutab[NRK]; short rkcyl[NRK]; +#ifndef NOBADSECT +struct dkbad rkbad[NRK]; +struct buf brkbuf[NRK]; +#endif struct rkst { short nsect; @@ -73,10 +95,13 @@ struct rkst { struct size *sizes; } rkst[] = { NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes, + NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK6CYL, rk6_sizes, }; u_char rk_offset[16] = - { P400,M400,P400,M400,P800,M800,P800,M800,P1200,M1200,P1200,M1200,0,0,0,0 }; + { RKAS_P400,RKAS_M400,RKAS_P400,RKAS_M400,RKAS_P800,RKAS_M800,RKAS_P800, + RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0 + }; struct buf rrkbuf[NRK]; @@ -95,33 +120,39 @@ rkprobe(reg) #ifdef lint br = 0; cvec = br; br = cvec; + rkintr(0); #endif ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY; DELAY(10); ((struct rkdevice *)reg)->rkcs1 = RK_CDT; - return (1); + return (sizeof (struct rkdevice)); } rkslave(ui, reg) - struct uba_dinfo *ui; + struct uba_device *ui; caddr_t reg; { register struct rkdevice *rkaddr = (struct rkdevice *)reg; - rkaddr->rkcs1 = RK_CDT; + ui->ui_type = 0; + rkaddr->rkcs1 = RK_CCLR; rkaddr->rkcs2 = ui->ui_slave; + rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; rkwait(rkaddr); -/* SHOULD TRY THIS BY PULLING A PLUG */ -/* A DELAY OR SOMETHING MAY BE NEEDED */ - if (rkaddr->rkcs2&RK_NED) { - rkaddr->rkcs1 = RK_CDT|RK_CCLR; + DELAY(50); + if (rkaddr->rkcs2&RKCS2_NED || (rkaddr->rkds&RKDS_SVAL) == 0) { + rkaddr->rkcs1 = RK_CCLR; return (0); } + if (rkaddr->rkcs1&RK_CERR && rkaddr->rker&RKER_DTYE) { + ui->ui_type = 1; + rkaddr->rkcs1 = RK_CCLR; + } return (1); } rkattach(ui) - register struct uba_dinfo *ui; + register struct uba_device *ui; { if (rkwstart == 0) { @@ -133,17 +164,30 @@ rkattach(ui) rkip[ui->ui_ctlr][ui->ui_slave] = ui; rk_softc[ui->ui_ctlr].sc_ndrive++; rkcyl[ui->ui_unit] = -1; + ui->ui_flags = 0; } +rkopen(dev) + dev_t dev; +{ + register int unit = minor(dev) >> 3; + register struct uba_device *ui; + + if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0) + return (ENXIO); + return (0); +} + rkstrategy(bp) register struct buf *bp; { - register struct uba_dinfo *ui; + register struct uba_device *ui; register struct rkst *st; register int unit; register struct buf *dp; int xunit = minor(bp->b_dev) & 07; long bn, sz; + int s; sz = (bp->b_bcount+511) >> 9; unit = dkunit(bp); @@ -157,7 +201,7 @@ rkstrategy(bp) (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) goto bad; bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; - (void) spl5(); + s = spl5(); dp = &rkutab[ui->ui_unit]; disksort(dp, bp); if (dp->b_active == 0) { @@ -166,7 +210,7 @@ rkstrategy(bp) if (bp->b_actf && bp->b_active == 0) (void) rkstart(ui->ui_mi); } - (void) spl0(); + splx(s); return; bad: @@ -176,49 +220,62 @@ bad: } rkustart(ui) - register struct uba_dinfo *ui; + register struct uba_device *ui; { register struct buf *bp, *dp; - register struct uba_minfo *um; + register struct uba_ctlr *um; register struct rkdevice *rkaddr; - register struct rkst *st; - daddr_t bn; - int sn, csn; - int didie = 0; if (ui == 0) - return (0); + return; dk_busy &= ~(1<ui_dk); dp = &rkutab[ui->ui_unit]; - if ((bp = dp->b_actf) == NULL) - goto out; um = ui->ui_mi; + rkaddr = (struct rkdevice *)um->um_addr; if (um->um_tab.b_active) { rk_softc[um->um_ctlr].sc_softas |= 1<ui_slave; - return (0); + return; } - rkaddr = (struct rkdevice *)um->um_addr; - rkaddr->rkcs1 = RK_CDT|RK_CERR; + if ((bp = dp->b_actf) == NULL) + return; + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_CERR; rkaddr->rkcs2 = ui->ui_slave; - rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; rkwait(rkaddr); - if (dp->b_active) - goto done; - dp->b_active = 1; - if ((rkaddr->rkds & RK_VV) == 0) { + if ((rkaddr->rkds & RKDS_VV) == 0 || ui->ui_flags == 0) { /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ - rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO; +#ifndef NOBADSECT + struct rkst *st = &rkst[ui->ui_type]; + struct buf *bbp = &brkbuf[ui->ui_unit]; +#endif + + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_PACK|RK_GO; + ui->ui_flags = 1; +#ifndef NOBADSECT + bbp->b_flags = B_READ|B_BUSY; + bbp->b_dev = bp->b_dev; + bbp->b_bcount = 512; + bbp->b_un.b_addr = (caddr_t)&rkbad[ui->ui_unit]; + bbp->b_blkno = st->ncyl*st->nspc - st->nsect; + bbp->b_cylin = st->ncyl - 1; + dp->b_actf = bbp; + bbp->av_forw = bp; + bp = bbp; +#endif rkwait(rkaddr); - didie = 1; } + if (dp->b_active) + goto done; + dp->b_active = 1; + if ((rkaddr->rkds & RKDS_DREADY) != RKDS_DREADY) + goto done; if (rk_softc[um->um_ctlr].sc_ndrive == 1) goto done; if (bp->b_cylin == rkcyl[ui->ui_unit]) goto done; rkaddr->rkcyl = bp->b_cylin; rkcyl[ui->ui_unit] = bp->b_cylin; - rkaddr->rkcs1 = RK_CDT|RK_IE|RK_SEEK|RK_GO; - didie = 1; + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; if (ui->ui_dk >= 0) { dk_busy |= 1<ui_dk; dk_seek[ui->ui_dk]++; @@ -235,14 +292,14 @@ done: dp->b_active = 2; } out: - return (didie); + return; } rkstart(um) - register struct uba_minfo *um; + register struct uba_ctlr *um; { register struct buf *bp, *dp; - register struct uba_dinfo *ui; + register struct uba_device *ui; register struct rkdevice *rkaddr; struct rkst *st; daddr_t bn; @@ -250,7 +307,7 @@ rkstart(um) loop: if ((dp = um->um_tab.b_actf) == NULL) - return (0); + return; if ((bp = dp->b_actf) == NULL) { um->um_tab.b_actf = dp->b_forw; goto loop; @@ -263,33 +320,56 @@ loop: tn = sn/st->nsect; sn %= st->nsect; rkaddr = (struct rkdevice *)ui->ui_addr; - rkaddr->rkcs1 = RK_CDT|RK_CERR; +retry: + rkaddr->rkcs1 = RK_CCLR; rkaddr->rkcs2 = ui->ui_slave; - rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; rkwait(rkaddr); - if (um->um_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) { - rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; - rkaddr->rkcs1 = RK_CDT|RK_OFFSET|RK_GO; - rkwait(rkaddr); + if ((rkaddr->rkds&RKDS_SVAL) == 0) { + rknosval++; + goto nosval; + } + if (rkaddr->rkds&RKDS_PIP) { + rkpip++; + goto retry; + } + if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { + printf("rk%d: not ready", dkunit(bp)); + if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { + printf("\n"); + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; + rkwait(rkaddr); + rkaddr->rkcs1 = RK_CCLR; + rkwait(rkaddr); + um->um_tab.b_active = 0; + um->um_tab.b_errcnt = 0; + dp->b_actf = bp->av_forw; + dp->b_active = 0; + bp->b_flags |= B_ERROR; + iodone(bp); + goto loop; + } + printf(" (came back!)\n"); } +nosval: rkaddr->rkcyl = bp->b_cylin; rkcyl[ui->ui_unit] = bp->b_cylin; rkaddr->rkda = (tn << 8) + sn; rkaddr->rkwc = -bp->b_bcount / sizeof (short); if (bp->b_flags & B_READ) - cmd = RK_CDT|RK_IE|RK_READ|RK_GO; + cmd = rktypes[ui->ui_type]|RK_IE|RK_READ|RK_GO; else - cmd = RK_CDT|RK_IE|RK_WRITE|RK_GO; + cmd = rktypes[ui->ui_type]|RK_IE|RK_WRITE|RK_GO; um->um_cmd = cmd; - ubago(ui); - return (1); + (void) ubago(ui); } rkdgo(um) - register struct uba_minfo *um; + register struct uba_ctlr *um; { register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; + um->um_tab.b_active = 2; /* should now be 2 */ rkaddr->rkba = um->um_ubinfo; rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); } @@ -297,91 +377,109 @@ rkdgo(um) rkintr(rk11) int rk11; { - register struct uba_minfo *um = rkminfo[rk11]; - register struct uba_dinfo *ui; + register struct uba_ctlr *um = rkminfo[rk11]; + register struct uba_device *ui; register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; register struct buf *bp, *dp; int unit; struct rk_softc *sc = &rk_softc[um->um_ctlr]; int as = (rkaddr->rkatt >> 8) | sc->sc_softas; - int needie = 1; sc->sc_wticks = 0; sc->sc_softas = 0; - if (um->um_tab.b_active) { + if (um->um_tab.b_active == 2 || sc->sc_recal) { + um->um_tab.b_active = 1; dp = um->um_tab.b_actf; bp = dp->b_actf; ui = rkdinfo[dkunit(bp)]; dk_busy &= ~(1 << ui->ui_dk); +#ifndef NOBADSECT + if (bp->b_flags&B_BAD) + if (rkecc(ui, CONT)) + return; +#endif if (rkaddr->rkcs1 & RK_CERR) { int recal; -#ifdef notdef - int del = 0; -#endif u_short ds = rkaddr->rkds; u_short cs2 = rkaddr->rkcs2; u_short er = rkaddr->rker; - if (sc->sc_recal) - printf("recal CERR\n"); -#ifdef notdef -/* THIS ATTEMPTED TO FIND OUT IF THE DRIVE IS SPUN */ -/* DOWN BUT IT DOESN'T SEEM TO WORK... THE DRIVE SEEMS TO */ -/* TELL PAINFULLY LITTLE WHEN IT IS SPUN DOWN (I.E. NOTHING CHANGES) */ -/* THE DRIVE JUST KEEPS SAYING IT WANTS ATTENTION AND BLOWING ALL COMMANDS */ - if (ds & RK_CDA) { - rkaddr->rkcs1 = RK_CDT|RK_CERR; - rkaddr->rkcs2 = ui->ui_slave; - rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; - rkwait(rkaddr); - while ((rkaddr->rkds & RK_SVAL) == 0) - if (++del > 512) - break; +#ifdef RKDEBUG + if (rkdebug) { + printf("cs2=%b ds=%b er=%b\n", + cs2, RKCS2_BITS, ds, + RKDS_BITS, er, RKER_BITS); } - if (del > 512) { - printf("rk%d is down\n", dkunit(bp)); - bp->b_flags |= B_ERROR; - } else #endif - if (ds & RK_WLE) { - printf("rk%d is write locked\n", dkunit(bp)); + if (er & RKER_WLE) { + printf("rk%d: write locked\n", dkunit(bp)); bp->b_flags |= B_ERROR; } else if (++um->um_tab.b_errcnt > 28 || ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { - bp->b_flags |= B_ERROR; - harderr(bp); - printf("rk%d cs2=%b ds=%b er=%b\n", - dkunit(bp), cs2, RKCS2_BITS, ds, +hard: + harderr(bp, "rk"); + printf("cs2=%b ds=%b er=%b\n", + cs2, RKCS2_BITS, ds, RKDS_BITS, er, RKER_BITS); - } else - um->um_tab.b_active = 0; - if (cs2&RK_MDS) { - rkaddr->rkcs2 = RK_SCLR; + bp->b_flags |= B_ERROR; + sc->sc_recal = 0; + } else if (er & RKER_BSE) { +#ifndef NOBADSECT + if (rkecc(ui, BSE)) + return; + else +#endif + goto hard; + } else { + if ((er & (RKER_DCK|RKER_ECH)) == RKER_DCK) { + if (rkecc(ui, ECC)) + return; + } else + um->um_tab.b_active = 0; + } + if (cs2&RKCS2_MDS) { + rkaddr->rkcs2 = RKCS2_SCLR; goto retry; } recal = 0; - if (ds&RK_DROT || er&(RK_OPI|RK_SKI|RK_UNS) || + if (ds&RKDS_DROT || er&(RKER_OPI|RKER_SKI|RKER_UNS) || (um->um_tab.b_errcnt&07) == 4) recal = 1; - if ((er & (RK_DCK|RK_ECH)) == RK_DCK) - if (rkecc(ui)) - return; - rkaddr->rkcs1 = RK_CDT|RK_CCLR; + rkaddr->rkcs1 = RK_CCLR; rkaddr->rkcs2 = ui->ui_slave; - rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; rkwait(rkaddr); if (recal && um->um_tab.b_active == 0) { - rkaddr->rkcs1 = RK_CDT|RK_IE|RK_RECAL|RK_GO; + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_RECAL|RK_GO; rkcyl[ui->ui_unit] = -1; - rkwait(rkaddr); - um->um_tab.b_active = 1; - sc->sc_recal = 1; - return; + sc->sc_recal = 0; + goto nextrecal; } } retry: - if (sc->sc_recal) { + switch (sc->sc_recal) { + + case 1: + rkaddr->rkcyl = bp->b_cylin; + rkcyl[ui->ui_unit] = bp->b_cylin; + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; + goto nextrecal; + case 2: + if (um->um_tab.b_errcnt < 16 || + (bp->b_flags&B_READ) == 0) + goto donerecal; + rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_OFFSET|RK_GO; + /* fall into ... */ + nextrecal: + sc->sc_recal++; + rkwait(rkaddr); + um->um_tab.b_active = 1; + return; + donerecal: + case 3: sc->sc_recal = 0; um->um_tab.b_active = 0; + break; } ubadone(um); if (um->um_tab.b_active) { @@ -394,20 +492,27 @@ retry: bp->b_resid = -rkaddr->rkwc * sizeof(short); iodone(bp); if (dp->b_actf) - if (rkustart(ui)) - needie = 0; + rkustart(ui); } as &= ~(1<ui_slave); } for (unit = 0; as; as >>= 1, unit++) - if (as & 1) - if (rkustart(rkip[rk11][unit])) - needie = 0; + if (as & 1) { + ui = rkip[rk11][unit]; + if (ui) { + rkustart(rkip[rk11][unit]); + } else { + rkaddr->rkcs1 = RK_CCLR; + rkaddr->rkcs2 = unit; + rkaddr->rkcs1 = RK_DCLR|RK_GO; + rkwait(rkaddr); + rkaddr->rkcs1 = RK_CCLR; + } + } if (um->um_tab.b_actf && um->um_tab.b_active == 0) - if (rkstart(um)) - needie = 0; - if (needie) - rkaddr->rkcs1 = RK_CDT|RK_IE; + rkstart(um); + if (((rkaddr->rkcs1) & RK_IE) == 0) + rkaddr->rkcs1 = RK_IE; } rkwait(addr) @@ -418,115 +523,166 @@ rkwait(addr) ; } -rkread(dev) +rkread(dev, uio) dev_t dev; + struct uio *uio; { register int unit = minor(dev) >> 3; if (unit >= NRK) - u.u_error = ENXIO; - else - physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys); + return (ENXIO); + return (physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys, uio)); } -rkwrite(dev) +rkwrite(dev, uio) dev_t dev; + struct uio *uio; { register int unit = minor(dev) >> 3; if (unit >= NRK) - u.u_error = ENXIO; - else - physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys); + return (ENXIO); + return (physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys, uio)); } -rkecc(ui) - register struct uba_dinfo *ui; +rkecc(ui, flag) + register struct uba_device *ui; { register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr; register struct buf *bp = rkutab[ui->ui_unit].b_actf; - register struct uba_minfo *um = ui->ui_mi; + register struct uba_ctlr *um = ui->ui_mi; register struct rkst *st; struct uba_regs *ubp = ui->ui_hd->uh_uba; - register int i; caddr_t addr; - int reg, bit, byte, npf, mask, o, cmd, ubaddr; + int reg, npf, o, cmd, ubaddr; int bn, cn, tn, sn; - npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount) - 1; +#ifndef NOBADSECT + if (flag == CONT) + npf = bp->b_error; + else +#endif + npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount); reg = btop(um->um_ubinfo&0x3ffff) + npf; o = (int)bp->b_un.b_addr & PGOFSET; - printf("SOFT ECC rk%d%c bn%d\n", dkunit(bp), - 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); - mask = rk->rkec2; - ubapurge(um); - i = rk->rkec1 - 1; /* -1 makes 0 origin */ - bit = i&07; - i = (i&~07)>>3; - byte = i + o; - while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { - addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ - (byte & PGOFSET); - putmemc(addr, getmemc(addr)^(mask<um_tab.b_active++; /* Either complete or continuing... */ - if (rk->rkwc == 0) - return (0); -#ifdef notdef - rk->rkcs1 |= RK_GO; -#else - rk->rkcs1 = RK_CDT|RK_CCLR; - rk->rkcs2 = ui->ui_slave; - rk->rkcs1 = RK_CDT|RK_DCLR|RK_GO; - rkwait(rk); bn = dkblock(bp); st = &rkst[ui->ui_type]; cn = bp->b_cylin; - sn = bn%st->nspc + npf + 1; + sn = bn%st->nspc + npf; tn = sn/st->nsect; sn %= st->nsect; cn += tn/st->ntrak; tn %= st->ntrak; + ubapurge(um); + switch (flag) { + case ECC: + { + register int i; + int bit, byte, mask; + + npf--; + reg--; + printf("rk%d%c: soft ecc sn%d\n", dkunit(bp), + 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); + mask = rk->rkec2; + i = rk->rkec1 - 1; /* -1 makes 0 origin */ + bit = i&07; + i = (i&~07)>>3; + byte = i + o; + while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { + addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ + (byte & PGOFSET); + putmemc(addr, getmemc(addr)^(mask<rkwc == 0) { + um->um_tab.b_active = 0; + return (0); + } + npf++; + reg++; + break; + } + +#ifndef NOBADSECT + case BSE: +#ifdef RKBDEBUG + if (rkbdebug) + printf("rkecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); +#endif + if ((bn = isbad(&rkbad[ui->ui_unit], cn, tn, sn)) < 0) + return(0); + bp->b_flags |= B_BAD; + bp->b_error = npf + 1; + bn = st->ncyl*st->nspc - st->nsect - 1 - bn; + cn = bn/st->nspc; + sn = bn%st->nspc; + tn = sn/st->nsect; + sn %= st->nsect; +#ifdef RKBDEBUG + if (rkbdebug) + printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); +#endif + rk->rkwc = -(512 / sizeof (short)); + break; + + case CONT: +#ifdef RKBDEBUG + if (rkbdebug) + printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn); +#endif + bp->b_flags &= ~B_BAD; + rk->rkwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof (short)); + if (rk->rkwc == 0) { + um->um_tab.b_active = 0; + return (0); + } + break; +#endif + } + rk->rkcs1 = RK_CCLR; + rk->rkcs2 = ui->ui_slave; + rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; + rkwait(rk); rk->rkcyl = cn; rk->rkda = (tn << 8) | sn; - ubaddr = (int)ptob(reg+1) + o; + ubaddr = (int)ptob(reg) + o; rk->rkba = ubaddr; - cmd = (ubaddr >> 8) & 0x300; - cmd |= RK_CDT|RK_IE|RK_GO|RK_READ; + cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO; + cmd |= (ubaddr >> 8) & 0x300; + cmd |= rktypes[ui->ui_type]; rk->rkcs1 = cmd; -#endif + um->um_tab.b_active = 2; /* continuing */ + um->um_tab.b_errcnt = 0; /* error has been corrected */ return (1); } rkreset(uban) + int uban; { - register struct uba_minfo *um; - register struct uba_dinfo *ui; + register struct uba_ctlr *um; + register struct uba_device *ui; register rk11, unit; - int any = 0; for (rk11 = 0; rk11 < NHK; rk11++) { if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || um->um_alive == 0) continue; - if (any == 0) { - printf(" rk"); - any++; - } + printf(" hk%d", rk11); um->um_tab.b_active = 0; um->um_tab.b_actf = um->um_tab.b_actl = 0; rk_softc[um->um_ctlr].sc_recal = 0; + rk_softc[um->um_ctlr].sc_wticks = 0; if (um->um_ubinfo) { printf("<%d>", (um->um_ubinfo>>28)&0xf); - ubadone(um); + um->um_ubinfo = 0; } - for (unit = 0; unit < NHK; unit++) { + for (unit = 0; unit < NRK; unit++) { if ((ui = rkdinfo[unit]) == 0) continue; - if (ui->ui_alive == 0) + if (ui->ui_alive == 0 || ui->ui_mi != um) continue; rkutab[unit].b_active = 0; (void) rkustart(ui); @@ -537,7 +693,7 @@ rkreset(uban) rkwatch() { - register struct uba_minfo *um; + register struct uba_ctlr *um; register rk11, unit; register struct rk_softc *sc; @@ -559,7 +715,7 @@ active: sc->sc_wticks++; if (sc->sc_wticks >= 20) { sc->sc_wticks = 0; - printf("LOST rkintr "); + printf("hk%d: lost interrupt\n", rk11); ubareset(um->um_ubanum); } } @@ -575,7 +731,7 @@ rkdump(dev) int num, blk, unit; struct size *sizes; register struct uba_regs *uba; - register struct uba_dinfo *ui; + register struct uba_device *ui; register short *rp; struct rkst *st; @@ -583,23 +739,20 @@ rkdump(dev) if (unit >= NRK) return (ENXIO); #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) - ui = phys(struct uba_dinfo *, rkdinfo[unit]); + ui = phys(struct uba_device *, rkdinfo[unit]); if (ui->ui_alive == 0) return (ENXIO); uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; -#if VAX780 - if (cpu == VAX_780) - ubainit(uba); -#endif + ubainit(uba); rkaddr = (struct rkdevice *)ui->ui_physaddr; num = maxfree; start = 0; - rkaddr->rkcs1 = RK_CDT|RK_CERR; + rkaddr->rkcs1 = RK_CCLR; rkaddr->rkcs2 = unit; - rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; rkwait(rkaddr); - if ((rkaddr->rkds & RK_VV) == 0) { - rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO; + if ((rkaddr->rkds & RKDS_VV) == 0) { + rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO; rkwait(rkaddr); } st = &rkst[ui->ui_type]; @@ -615,7 +768,7 @@ rkdump(dev) blk = num > DBSIZE ? DBSIZE : num; io = uba->uba_map; for (i = 0; i < blk; i++) - *(int *)io++ = (btop(start)+i) | (1<<21) | UBA_MRV; + *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; *(int *)io = 0; bn = dumplo + btop(start); cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; @@ -627,7 +780,7 @@ rkdump(dev) *rp = (tn << 8) + sn; *--rp = 0; *--rp = -blk*NBPG / sizeof (short); - *--rp = RK_CDT|RK_GO|RK_WRITE; + *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE; rkwait(rkaddr); if (rkaddr->rkcs1 & RK_CERR) return (EIO);