X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/9037157b036f572f835f32cd3c46b537fe338086..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 012b903b20..7f170057ba 100644 --- a/usr/src/sys/vax/uba/rk.c +++ b/usr/src/sys/vax/uba/rk.c @@ -1,64 +1,91 @@ -/* rk.c 4.8 %G% */ +/* rk.c 4.51 82/12/17 */ #include "rk.h" -#if NRK11 > 0 -int rkflags,rkerrs; /* GROT */ +#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: + * 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; int sc_ndrive; int sc_wticks; int sc_recal; -} rk_softc[NRK11]; +} rk_softc[NHK]; /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ -struct size -{ +struct size { daddr_t nblocks; int cyloff; -} rk7_sizes[] ={ +} rk7_sizes[8] ={ 15884, 0, /* A=cyl 0 thru 240 */ - 10032, 146, /* B=cyl 241 thru 392 */ - 53790, 246, /* C=cyl 0 thru 814 */ + 10032, 241, /* B=cyl 241 thru 392 */ + 53790, 0, /* C=cyl 0 thru 814 */ 0, 0, 0, 0, 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[NRK11]; -struct uba_dinfo *rkdinfo[NRK07]; -struct uba_dinfo *rkip[NRK11][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[NRK07]; -short rkcyl[NRK07]; +struct buf rkutab[NRK]; +short rkcyl[NRK]; +#ifndef NOBADSECT +struct dkbad rkbad[NRK]; +struct buf brkbuf[NRK]; +#endif struct rkst { short nsect; @@ -68,12 +95,15 @@ 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[NRK07]; +struct buf rrkbuf[NRK]; #define b_cylin b_resid @@ -90,59 +120,78 @@ 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) { - timeout(rkwatch, (caddr_t)0, HZ); + timeout(rkwatch, (caddr_t)0, hz); rkwstart++; } if (ui->ui_dk >= 0) - dk_mspw[ui->ui_dk] = 1.0 / (HZ * NRKSECT * 256); + dk_mspw[ui->ui_dk] = 1.0 / (60 * NRKSECT * 256); 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); - if (unit >= NRK07) + if (unit >= NRK) goto bad; ui = rkdinfo[unit]; if (ui == 0 || ui->ui_alive == 0) @@ -152,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) { @@ -161,7 +210,7 @@ rkstrategy(bp) if (bp->b_actf && bp->b_active == 0) (void) rkstart(ui->ui_mi); } - (void) spl0(); + splx(s); return; bad: @@ -171,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]++; @@ -230,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; @@ -245,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; @@ -258,109 +320,166 @@ 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); } -hkintr(rk11) +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; u_short ds = rkaddr->rkds; u_short cs2 = rkaddr->rkcs2; u_short er = rkaddr->rker; - if (sc->sc_recal) - printf("recal CERR\n"); - rkerrs++; /* GROT */ - if (rkflags&1) /* GROT */ - printf("%d ds %o cs2 %o er %o\n", /* GROT */ - um->um_tab.b_errcnt, ds, cs2, er); /* GROT */ - if (er & RK_WLE) - printf("rk%d is write locked\n", dkunit(bp)); -/* THIS DOESN'T SEEM TO HAPPEN */ -/* OR WAS SOMETHING BROKEN WHEN WE TRIED */ -/* SPINNING A DRIVE DOWN ? */ - if (ds & RKDS_HARD) - printf("rk%d is down\n", dkunit(bp)); - if (++um->um_tab.b_errcnt > 28 || - ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) +#ifdef RKDEBUG + if (rkdebug) { + printf("cs2=%b ds=%b er=%b\n", + cs2, RKCS2_BITS, ds, + RKDS_BITS, er, RKER_BITS); + } +#endif + 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) { +hard: + harderr(bp, "rk"); + printf("cs2=%b ds=%b er=%b\n", + cs2, RKCS2_BITS, ds, + RKDS_BITS, er, RKER_BITS); bp->b_flags |= B_ERROR; - else - um->um_tab.b_active = 0; - if (um->um_tab.b_errcnt > 27) - deverror(bp, cs2, (ds<<16)|er); - if (cs2&RK_MDS) { - rkaddr->rkcs2 = RK_SCLR; + 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) { @@ -373,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) @@ -397,121 +523,166 @@ rkwait(addr) ; } -rkread(dev) +rkread(dev, uio) dev_t dev; + struct uio *uio; { register int unit = minor(dev) >> 3; - if (unit >= NRK07) - u.u_error = ENXIO; - else - physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys); + if (unit >= NRK) + 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 >= NRK07) - u.u_error = ENXIO; - else - physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys); + if (unit >= NRK) + 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("%D ", bp->b_blkno+npf); - prdev("ECC", bp->b_dev); - mask = rk->rkec2; - if (mask == 0) { - rk->rkatt = 0; - return (0); - } - ubp->uba_dpr[(um->um_ubinfo>>28)&0x0f] |= UBA_BNE; - 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 < NRK11; rk11++) { + 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; } - ((struct rkdevice *)(um->um_addr))->rkcs1 = RK_CDT|RK_CCLR; - rkwait((struct rkdevice *)(um->um_addr)); - for (unit = 0; unit < NRK11; 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); @@ -522,18 +693,18 @@ rkreset(uban) rkwatch() { - register struct uba_minfo *um; + register struct uba_ctlr *um; register rk11, unit; register struct rk_softc *sc; - timeout(rkwatch, (caddr_t)0, HZ); - for (rk11 = 0; rk11 < NRK11; rk11++) { + timeout(rkwatch, (caddr_t)0, hz); + for (rk11 = 0; rk11 < NHK; rk11++) { um = rkminfo[rk11]; if (um == 0 || um->um_alive == 0) continue; sc = &rk_softc[rk11]; if (um->um_tab.b_active == 0) { - for (unit = 0; unit < NRK07; unit++) + for (unit = 0; unit < NRK; unit++) if (rkutab[unit].b_active && rkdinfo[unit]->ui_mi == um) goto active; @@ -544,10 +715,8 @@ active: sc->sc_wticks++; if (sc->sc_wticks >= 20) { sc->sc_wticks = 0; - printf("LOST INTERRUPT RESET"); - /* SHOULD JUST RESET ONE CTLR, NOT ALL ON UBA */ - rkreset(um->um_ubanum); - printf("\n"); + printf("hk%d: lost interrupt\n", rk11); + ubareset(um->um_ubanum); } } } @@ -562,43 +731,34 @@ 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; unit = minor(dev) >> 3; - if (unit >= NRK07) { - printf("bad unit\n"); - return (-1); - } + if (unit >= NRK) + return (ENXIO); #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) - ui = phys(struct uba_dinfo *, rkdinfo[unit]); - if (ui->ui_alive == 0) { - printf("dna\n"); - return(-1); - } + 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]; sizes = phys(struct size *, st->sizes); - if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) { - printf("oor\n"); - return (-1); - } + if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) + return (EINVAL); while (num > 0) { register struct pte *io; register int i; @@ -608,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; @@ -620,15 +780,10 @@ 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) { - printf("rk dump dsk err: (%d,%d,%d) cs1=%x, ds=%x, er1=%x\n", - cn, tn, sn, - rkaddr->rkcs1&0xffff, rkaddr->rkds&0xffff, - rkaddr->rker&0xffff); - return (-1); - } + if (rkaddr->rkcs1 & RK_CERR) + return (EIO); start += blk*NBPG; num -= blk; }