new formats... new !RDY code... no more FLAKEY up
[unix-history] / usr / src / sys / vax / uba / up.c
index 38548bd..4e88914 100644 (file)
@@ -1,9 +1,17 @@
-/*     up.c    4.26    81/02/27        */
+/*     up.c    4.29    81/03/06        */
 
 #include "up.h"
 #if NSC > 0
 /*
  * UNIBUS disk driver with overlapped seeks and ECC recovery.
 
 #include "up.h"
 #if NSC > 0
 /*
  * UNIBUS disk driver with overlapped seeks and ECC recovery.
+ *
+ * TODO:
+ *     Check out handling of spun-down drives and write lock
+ *     Add reading of bad sector information and disk layout from sector 1
+ *     Add bad sector forwarding code
+ *     Check multiple drive handling
+ *     Check dump code
+ *     Check unibus reset code
  */
 #define        DELAY(N)                { register int d; d = N; while (--d > 0); }
 
  */
 #define        DELAY(N)                { register int d; d = N; while (--d > 0); }
 
@@ -382,7 +390,7 @@ loop:
                upwaitdry++;
        }
        if ((upaddr->upds & UP_DREADY) != UP_DREADY) {
                upwaitdry++;
        }
        if ((upaddr->upds & UP_DREADY) != UP_DREADY) {
-               printf("up%d not ready", dkunit(bp));
+               printf("up%d: not ready", dkunit(bp));
                if ((upaddr->upds & UP_DREADY) != UP_DREADY) {
                        printf("\n");
                        um->um_tab.b_active = 0;
                if ((upaddr->upds & UP_DREADY) != UP_DREADY) {
                        printf("\n");
                        um->um_tab.b_active = 0;
@@ -463,8 +471,6 @@ upintr(sc21)
                        upaddr->upcs1 = UP_TRE;
                goto doattn;
        }
                        upaddr->upcs1 = UP_TRE;
                goto doattn;
        }
-       if ((upaddr->upcs1 & UP_RDY) == 0)
-               printf("upintr !RDY\n");                /* shouldn't happen */
        /*
         * Get device and block structures, and a pointer
         * to the uba_dinfo for the drive.  Select the drive.
        /*
         * Get device and block structures, and a pointer
         * to the uba_dinfo for the drive.  Select the drive.
@@ -486,30 +492,23 @@ upintr(sc21)
                                break;
                        upwaitdry++;
                }
                                break;
                        upwaitdry++;
                }
-               if ((upaddr->upds&UP_DREADY) != UP_DREADY) {
-                       printf("up%d not ready", dkunit(bp));
-                       bp->b_flags |= B_ERROR;
-               } else if (upaddr->uper1&UP_WLE) {
+               if (upaddr->uper1&UP_WLE) {
                        /*
                         * Give up on write locked devices
                         * immediately.
                         */
                        /*
                         * Give up on write locked devices
                         * immediately.
                         */
-                       printf("up%d is write locked\n", dkunit(bp));
+                       printf("up%d: write locked\n", dkunit(bp));
                        bp->b_flags |= B_ERROR;
                } else if (++um->um_tab.b_errcnt > 27) {
                        /*
                         * After 28 retries (16 without offset, and
                         * 12 with offset positioning) give up.
                         */
                        bp->b_flags |= B_ERROR;
                } else if (++um->um_tab.b_errcnt > 27) {
                        /*
                         * After 28 retries (16 without offset, and
                         * 12 with offset positioning) give up.
                         */
-                       if (upaddr->upcs2&(UP_NEM|UP_MXF)) {
-                               printf("FLAKEY UP ");
-                               ubareset(um->um_ubanum);
-                               return;
-                       }
-                       harderr(bp);
-                       printf("up%d cs2 %b er1 %b er2 %b\n",
-                           dkunit(bp), upaddr->upcs2, UPCS2_BITS, upaddr->uper1,
-                           UPER1_BITS, upaddr->uper2, UPER2_BITS);
+                       harderr(bp, "up");
+                       printf("cs2=%b er1=%b er2=%b\n",
+                           upaddr->upcs2, UPCS2_BITS,
+                           upaddr->uper1, UPER1_BITS,
+                           upaddr->uper2, UPER2_BITS);
                        bp->b_flags |= B_ERROR;
                } else {
                        /*
                        bp->b_flags |= B_ERROR;
                } else {
                        /*
@@ -655,13 +654,9 @@ upecc(ui)
        npf = btop((up->upwc * sizeof(short)) + bp->b_bcount) - 1;
        reg = btop(um->um_ubinfo&0x3ffff) + npf;
        o = (int)bp->b_un.b_addr & PGOFSET;
        npf = btop((up->upwc * 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("up%d%c: soft ecc bn%d\n", dkunit(bp),
+           'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
        mask = up->upec2;
        mask = up->upec2;
-       if (mask == 0) {
-               up->upof = UP_FMT22;            /* == RTC ???? */
-               return (0);
-       }
        /*
         * Flush the buffered data path, and compute the
         * byte and bit position of the error.  The variable i
        /*
         * Flush the buffered data path, and compute the
         * byte and bit position of the error.  The variable i
@@ -726,23 +721,20 @@ upecc(ui)
  * and restart all units and the controller.
  */
 upreset(uban)
  * and restart all units and the controller.
  */
 upreset(uban)
+       int uban;
 {
        register struct uba_minfo *um;
        register struct uba_dinfo *ui;
        register sc21, unit;
 {
        register struct uba_minfo *um;
        register struct uba_dinfo *ui;
        register sc21, unit;
-       int any = 0;
 
        for (sc21 = 0; sc21 < NSC; sc21++) {
                if ((um = upminfo[sc21]) == 0 || um->um_ubanum != uban ||
                    um->um_alive == 0)
                        continue;
 
        for (sc21 = 0; sc21 < NSC; sc21++) {
                if ((um = upminfo[sc21]) == 0 || um->um_ubanum != uban ||
                    um->um_alive == 0)
                        continue;
-               if (any == 0) {
-                       printf(" up");
-                       DELAY(10000000);        /* give it time to self-test */
-                       any++;
-               }
+               printf(" sc%d", sc21);
                um->um_tab.b_active = 0;
                um->um_tab.b_actf = um->um_tab.b_actl = 0;
                um->um_tab.b_active = 0;
                um->um_tab.b_actf = um->um_tab.b_actl = 0;
+               up_softc[sc21].sc_recal = 0;
                if (um->um_ubinfo) {
                        printf("<%d>", (um->um_ubinfo>>28)&0xf);
                        ubadone(um);
                if (um->um_ubinfo) {
                        printf("<%d>", (um->um_ubinfo>>28)&0xf);
                        ubadone(um);
@@ -751,7 +743,7 @@ upreset(uban)
                for (unit = 0; unit < NUP; unit++) {
                        if ((ui = updinfo[unit]) == 0)
                                continue;
                for (unit = 0; unit < NUP; unit++) {
                        if ((ui = updinfo[unit]) == 0)
                                continue;
-                       if (ui->ui_alive == 0)
+                       if (ui->ui_alive == 0 || ui->ui_mi != um)
                                continue;
                        uputab[unit].b_active = 0;
                        (void) upustart(ui);
                                continue;
                        uputab[unit].b_active = 0;
                        (void) upustart(ui);
@@ -763,7 +755,7 @@ upreset(uban)
 /*
  * Wake up every second and if an interrupt is pending
  * but nothing has happened increment a counter.
 /*
  * Wake up every second and if an interrupt is pending
  * but nothing has happened increment a counter.
- * If nothing happens for 20 seconds, reset the controller
+ * If nothing happens for 20 seconds, reset the UNIBUS
  * and begin anew.
  */
 upwatch()
  * and begin anew.
  */
 upwatch()
@@ -786,11 +778,11 @@ upwatch()
                        sc->sc_wticks = 0;
                        continue;
                }
                        sc->sc_wticks = 0;
                        continue;
                }
-    active:
+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 upintr ");
+                       printf("sc%d: lost interrupt\n", sc21);
                        ubareset(um->um_ubanum);
                }
        }
                        ubareset(um->um_ubanum);
                }
        }
@@ -803,7 +795,7 @@ updump(dev)
 {
        struct updevice *upaddr;
        char *start;
 {
        struct updevice *upaddr;
        char *start;
-       int num, blk, unit;
+       int num, blk, unit, i;
        struct size *sizes;
        register struct uba_regs *uba;
        register struct uba_dinfo *ui;
        struct size *sizes;
        register struct uba_regs *uba;
        register struct uba_dinfo *ui;
@@ -811,25 +803,20 @@ updump(dev)
        struct upst *st;
 
        unit = minor(dev) >> 3;
        struct upst *st;
 
        unit = minor(dev) >> 3;
-       if (unit >= NUP) {
-               printf("bad unit\n");
-               return (-1);
-       }
+       if (unit >= NUP)
+               return (ENXIO);
 #define        phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
        ui = phys(struct uba_dinfo *, updinfo[unit]);
 #define        phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
        ui = phys(struct uba_dinfo *, updinfo[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)
                ubainit(uba);
 #endif
        uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
 #if VAX780
        if (cpu == VAX_780)
                ubainit(uba);
 #endif
-       DELAY(1000000);
        upaddr = (struct updevice *)ui->ui_physaddr;
        upaddr = (struct updevice *)ui->ui_physaddr;
-       while ((upaddr->upcs1&UP_DVA) == 0)
-               ;
+       if ((upaddr->upcs1&UP_DVA) == 0)
+               return (EFAULT);
        num = maxfree;
        start = 0;
        upaddr->upcs2 = unit;
        num = maxfree;
        start = 0;
        upaddr->upcs2 = unit;
@@ -838,16 +825,12 @@ updump(dev)
                upaddr->upcs1 = UP_PRESET|UP_GO;
                upaddr->upof = UP_FMT22;
        }
                upaddr->upcs1 = UP_PRESET|UP_GO;
                upaddr->upof = UP_FMT22;
        }
-       if ((upaddr->upds & (UP_DPR|UP_MOL)) != (UP_DPR|UP_MOL)) {
-               printf("dna\n");
-               return (-1);
-       }
+       if ((upaddr->upds & UP_DREADY) != UP_DREADY)
+               return (EFAULT);
        st = &upst[ui->ui_type];
        sizes = phys(struct size *, st->sizes);
        st = &upst[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;
@@ -873,11 +856,8 @@ updump(dev)
                do {
                        DELAY(25);
                } while ((upaddr->upcs1 & UP_RDY) == 0);
                do {
                        DELAY(25);
                } while ((upaddr->upcs1 & UP_RDY) == 0);
-               if (upaddr->upcs1&UP_ERR) {
-                       printf("up dump dsk err: (%d,%d,%d) cs1=%x, er1=%x\n",
-                           cn, tn, sn, upaddr->upcs1, upaddr->uper1);
-                       return (-1);
-               }
+               if (upaddr->upcs1&UP_ERR)
+                       return (EIO);
                start += blk*NBPG;
                num -= blk;
        }
                start += blk*NBPG;
                num -= blk;
        }