new format of error prints
[unix-history] / usr / src / sys / vax / uba / rk.c
index bb4bf5c..bc02a08 100644 (file)
@@ -1,14 +1,17 @@
-/*     rk.c    4.12    %G%     */
+/*     rk.c    4.21    %G%     */
 
 #include "rk.h"
 #if NHK > 0
 
 #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.
  *
 /*
  * 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"
  */
 #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 */
 } rk_softc[NHK];
 
 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
-struct size
-{
+struct size {
        daddr_t nblocks;
        int     cyloff;
 } rk7_sizes[] ={
        daddr_t nblocks;
        int     cyloff;
 } rk7_sizes[] ={
@@ -105,12 +107,12 @@ rkslave(ui, reg)
 {
        register struct rkdevice *rkaddr = (struct rkdevice *)reg;
 
 {
        register struct rkdevice *rkaddr = (struct rkdevice *)reg;
 
-       rkaddr->rkcs1 = RK_CDT;
+       rkaddr->rkcs1 = RK_CDT|RK_CCLR;
        rkaddr->rkcs2 = ui->ui_slave;
        rkaddr->rkcs2 = ui->ui_slave;
+       rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO;
        rkwait(rkaddr);
        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);
        }
                rkaddr->rkcs1 = RK_CDT|RK_CCLR;
                return (0);
        }
@@ -122,11 +124,11 @@ rkattach(ui)
 {
 
        if (rkwstart == 0) {
 {
 
        if (rkwstart == 0) {
-               timeout(rkwatch, (caddr_t)0, HZ);
+               timeout(rkwatch, (caddr_t)0, hz);
                rkwstart++;
        }
        if (ui->ui_dk >= 0)
                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;
        rkip[ui->ui_ctlr][ui->ui_slave] = ui;
        rk_softc[ui->ui_ctlr].sc_ndrive++;
        rkcyl[ui->ui_unit] = -1;
@@ -187,27 +189,31 @@ rkustart(ui)
                return (0);
        dk_busy &= ~(1<<ui->ui_dk);
        dp = &rkutab[ui->ui_unit];
                return (0);
        dk_busy &= ~(1<<ui->ui_dk);
        dp = &rkutab[ui->ui_unit];
-       if ((bp = dp->b_actf) == NULL)
-               goto out;
        um = ui->ui_mi;
        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->ui_slave;
                return (0);
        }
        if (um->um_tab.b_active) {
                rk_softc[um->um_ctlr].sc_softas |= 1<<ui->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);
        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 */
        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);
                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])
        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;
        struct rkst *st;
        daddr_t bn;
        int sn, tn, cmd;
+       int waitdry;
 
 loop:
        if ((dp = um->um_tab.b_actf) == NULL)
 
 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);
        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;
        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;
@@ -291,7 +322,7 @@ rkdgo(um)
        rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300);
 }
 
        rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300);
 }
 
-hkintr(rk11)
+rkintr(rk11)
        int rk11;
 {
        register struct uba_minfo *um = rkminfo[rk11];
        int rk11;
 {
        register struct uba_minfo *um = rkminfo[rk11];
@@ -312,43 +343,18 @@ hkintr(rk11)
                dk_busy &= ~(1 << ui->ui_dk);
                if (rkaddr->rkcs1 & RK_CERR) {
                        int recal;
                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;
                        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) {
                        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;
                                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;
                                    RKDS_BITS, er, RKER_BITS);
                        } else
                                um->um_tab.b_active = 0;
@@ -397,6 +403,7 @@ retry:
                }
                as &= ~(1<<ui->ui_slave);
        }
                }
                as &= ~(1<<ui->ui_slave);
        }
+att:
        for (unit = 0; as; as >>= 1, unit++)
                if (as & 1)
                        if (rkustart(rkip[rk11][unit]))
        for (unit = 0; as; as >>= 1, unit++)
                if (as & 1)
                        if (rkustart(rkip[rk11][unit]))
@@ -454,16 +461,11 @@ 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;
        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;
        mask = rk->rkec2;
-       if (mask == 0) {
-               rk->rkatt = 0;
-               return (0);
-       }
-       ubp->uba_dpr[(um->um_ubinfo>>28)&0x0f] |= UBA_BNE;
+       ubapurge(um);
        i = rk->rkec1 - 1;              /* -1 makes 0 origin */
        i = rk->rkec1 - 1;              /* -1 makes 0 origin */
-       printf("mask %x pos %x\n", mask, i+1);
        bit = i&07;
        i = (i&~07)>>3;
        byte = i + o;
        bit = i&07;
        i = (i&~07)>>3;
        byte = i + o;
@@ -505,20 +507,17 @@ rkecc(ui)
 }
 
 rkreset(uban)
 }
 
 rkreset(uban)
+       int uban;
 {
        register struct uba_minfo *um;
        register struct uba_dinfo *ui;
        register rk11, unit;
 {
        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;
 
        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;
                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;
@@ -544,7 +543,7 @@ rkwatch()
        register rk11, unit;
        register struct rk_softc *sc;
 
        register rk11, unit;
        register struct rk_softc *sc;
 
-       timeout(rkwatch, (caddr_t)0, HZ);
+       timeout(rkwatch, (caddr_t)0, hz);
        for (rk11 = 0; rk11 < NHK; rk11++) {
                um = rkminfo[rk11];
                if (um == 0 || um->um_alive == 0)
        for (rk11 = 0; rk11 < NHK; rk11++) {
                um = rkminfo[rk11];
                if (um == 0 || um->um_alive == 0)
@@ -562,7 +561,7 @@ active:
                sc->sc_wticks++;
                if (sc->sc_wticks >= 20) {
                        sc->sc_wticks = 0;
                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);
                }
        }
                        ubareset(um->um_ubanum);
                }
        }
@@ -583,16 +582,12 @@ rkdump(dev)
        struct rkst *st;
 
        unit = minor(dev) >> 3;
        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]);
 #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)
        uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
 #if VAX780
        if (cpu == VAX_780)
@@ -611,10 +606,8 @@ rkdump(dev)
        }
        st = &rkst[ui->ui_type];
        sizes = phys(struct size *, st->sizes);
        }
        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;
        while (num > 0) {
                register struct pte *io;
                register int i;
@@ -638,13 +631,8 @@ rkdump(dev)
                *--rp = -blk*NBPG / sizeof (short);
                *--rp = RK_CDT|RK_GO|RK_WRITE;
                rkwait(rkaddr);
                *--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;
        }
                start += blk*NBPG;
                num -= blk;
        }