X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/7780575aa004e44c438fd3ac0918cfe92b550c37..68347e63b710dbb11755702f87e7d27669d05020:/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 56e9b9cda9..bc02a08d7c 100644 --- a/usr/src/sys/vax/uba/rk.c +++ b/usr/src/sys/vax/uba/rk.c @@ -1,14 +1,17 @@ -/* rk.c 4.16 %G% */ +/* rk.c 4.21 %G% */ #include "rk.h" #if NHK > 0 -int rkflags,rkerrs; /* GROT */ +int rkwaitdry; /* * RK11/RK07 disk driver * * This driver mimics up.c; see it for an explanation of common code. * - * THIS DRIVER DOESN'T DEAL WITH DRIVES SPINNING DOWN AND UP + * TODO: + * Add reading of bad sector information and disk layout from sector 1 + * Add bad sector forwarding code + * Why do we lose an interrupt sometime when spinning drives down? */ #define DELAY(i) { register int j; j = i; while (--j > 0); } #include "../h/param.h" @@ -35,8 +38,7 @@ struct rk_softc { } rk_softc[NHK]; /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ -struct size -{ +struct size { daddr_t nblocks; int cyloff; } rk7_sizes[] ={ @@ -105,12 +107,12 @@ rkslave(ui, reg) { register struct rkdevice *rkaddr = (struct rkdevice *)reg; - rkaddr->rkcs1 = RK_CDT; + rkaddr->rkcs1 = RK_CDT|RK_CCLR; rkaddr->rkcs2 = ui->ui_slave; + rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; rkwait(rkaddr); -/* SHOULD TRY THIS BY PULLING A PLUG */ -/* A DELAY OR SOMETHING MAY BE NEEDED */ - if (rkaddr->rkcs2&RK_NED) { + DELAY(50); + if (rkaddr->rkcs2&RK_NED || (rkaddr->rkds&RK_SVAL) == 0) { rkaddr->rkcs1 = RK_CDT|RK_CCLR; return (0); } @@ -187,27 +189,31 @@ rkustart(ui) return (0); 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); } - rkaddr = (struct rkdevice *)um->um_addr; rkaddr->rkcs1 = RK_CDT|RK_CERR; rkaddr->rkcs2 = ui->ui_slave; rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; rkwait(rkaddr); - if (dp->b_active) - goto done; - dp->b_active = 1; + if ((bp = dp->b_actf) == NULL) { + rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; + rkwait(rkaddr); + return (0); + } if ((rkaddr->rkds & RK_VV) == 0) { /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ - rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO; + rkaddr->rkcs1 = RK_CDT|RK_PACK|RK_GO; rkwait(rkaddr); - didie = 1; } + if (dp->b_active) + goto done; + dp->b_active = 1; + if ((rkaddr->rkds & RK_DREADY) != RK_DREADY) + goto done; if (rk_softc[um->um_ctlr].sc_ndrive == 1) goto done; if (bp->b_cylin == rkcyl[ui->ui_unit]) @@ -244,6 +250,7 @@ rkstart(um) struct rkst *st; daddr_t bn; int sn, tn, cmd; + int waitdry; loop: if ((dp = um->um_tab.b_actf) == NULL) @@ -264,6 +271,30 @@ loop: rkaddr->rkcs2 = ui->ui_slave; rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; rkwait(rkaddr); + waitdry = 0; + while ((rkaddr->rkds&RK_SVAL) == 0) { + if (++waitdry > 32) + break; + rkwaitdry++; + } + if ((rkaddr->rkds&RK_DREADY) != RK_DREADY) { + printf("rk%d: not ready", dkunit(bp)); + if ((rkaddr->rkds&RK_DREADY) != RK_DREADY) { + printf("\n"); + rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; + rkwait(rkaddr); + rkaddr->rkcs1 = RK_CDT|RK_CERR; + 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"); + } 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; @@ -312,43 +343,18 @@ rkintr(rk11) dk_busy &= ~(1 << ui->ui_dk); 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"); - rkerrs++; -#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; - } - 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)); + 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, + 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; @@ -397,6 +403,7 @@ retry: } as &= ~(1<ui_slave); } +att: for (unit = 0; as; as >>= 1, unit++) if (as & 1) if (rkustart(rkip[rk11][unit])) @@ -454,13 +461,9 @@ rkecc(ui) npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount) - 1; 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); + printf("rk%d%c: soft ecc bn%d\n", dkunit(bp), + 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); mask = rk->rkec2; - if (mask == 0) { - rk->rkatt = 0; - return (0); - } ubapurge(um); i = rk->rkec1 - 1; /* -1 makes 0 origin */ bit = i&07; @@ -504,20 +507,17 @@ rkecc(ui) } rkreset(uban) + int uban; { register struct uba_minfo *um; register struct uba_dinfo *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; @@ -561,7 +561,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); } } @@ -582,16 +582,12 @@ rkdump(dev) struct rkst *st; unit = minor(dev) >> 3; - if (unit >= NRK) { - 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); - } + if (ui->ui_alive == 0) + return (ENXIO); uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; #if VAX780 if (cpu == VAX_780) @@ -610,10 +606,8 @@ rkdump(dev) } 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; @@ -637,13 +631,8 @@ rkdump(dev) *--rp = -blk*NBPG / sizeof (short); *--rp = RK_CDT|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; }