lint
[unix-history] / usr / src / sys / vax / uba / up.c
index 7e23c1f..8f750b9 100644 (file)
@@ -1,4 +1,4 @@
-/*     up.c    4.31    81/03/09        */
+/*     up.c    4.40    81/11/18        */
 
 #include "up.h"
 #if NSC > 0
 
 #include "up.h"
 #if NSC > 0
@@ -6,11 +6,8 @@
  * UNIBUS disk driver with overlapped seeks and ECC recovery.
  *
  * TODO:
  * UNIBUS disk driver with overlapped seeks and ECC recovery.
  *
  * TODO:
- *     Add reading of bad sector information and disk layout from sector 1
  *     Add bad sector forwarding code
  *     Add bad sector forwarding code
- *     Check multiple drive handling
- *     Check unibus reset code
- *     Check that offset recovery code, etc works
+ *     Check that offset recovery code works
  */
 
 #include "../h/param.h"
  */
 
 #include "../h/param.h"
@@ -50,8 +47,13 @@ struct       size
        495520, 0,              /* C=cyl 0 thru 814 */
        15884,  562,            /* D=cyl 562 thru 588 */
        55936,  589,            /* E=cyl 589 thru 680 */
        495520, 0,              /* C=cyl 0 thru 814 */
        15884,  562,            /* D=cyl 562 thru 588 */
        55936,  589,            /* E=cyl 589 thru 680 */
-       81472,  681,            /* F=cyl 681 thru 814 */
-       153824, 562,            /* G=cyl 562 thru 814 */
+#ifndef NOBADSECT
+       81376,  681,            /* F=cyl 681 thru 814 */
+       153728, 562,            /* G=cyl 562 thru 814 */
+#else
+       81472,  681,
+       153824, 562,
+#endif
        291346, 82,             /* H=cyl 82 thru 561 */
 }, fj_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 49 */
        291346, 82,             /* H=cyl 82 thru 561 */
 }, fj_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 49 */
@@ -61,7 +63,11 @@ struct       size
        0,      0,
        0,      0,
        0,      0,
        0,      0,
        0,      0,
        0,      0,
-       213760, 155,            /* H=cyl 155 thru 822 */
+#ifndef NOBADSECT
+       213664, 155,            /* H=cyl 155 thru 822 */
+#else
+       213760, 155,
+#endif
 };
 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
 
 };
 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
 
@@ -94,8 +100,10 @@ struct      upst {
 };
 
 u_char up_offset[16] = {
 };
 
 u_char up_offset[16] = {
-    UP_P400, UP_M400, UP_P400, UP_M400, UP_P800, UP_M800, UP_P800, UP_M800, 
-    UP_P1200, UP_M1200, UP_P1200, UP_M1200, 0, 0, 0, 0
+    UPOF_P400, UPOF_M400, UPOF_P400, UPOF_M400,
+    UPOF_P800, UPOF_M800, UPOF_P800, UPOF_M800, 
+    UPOF_P1200, UPOF_M1200, UPOF_P1200, UPOF_M1200,
+    0, 0, 0, 0
 };
 
 struct buf     rupbuf[NUP];
 };
 
 struct buf     rupbuf[NUP];
@@ -118,6 +126,7 @@ upprobe(reg)
 
 #ifdef lint    
        br = 0; cvec = br; br = cvec;
 
 #ifdef lint    
        br = 0; cvec = br; br = cvec;
+       upintr(0);
 #endif
        ((struct updevice *)reg)->upcs1 = UP_IE|UP_RDY;
        DELAY(10);
 #endif
        ((struct updevice *)reg)->upcs1 = UP_IE|UP_RDY;
        DELAY(10);
@@ -133,7 +142,7 @@ upslave(ui, reg)
 
        upaddr->upcs1 = 0;              /* conservative */
        upaddr->upcs2 = ui->ui_slave;
 
        upaddr->upcs1 = 0;              /* conservative */
        upaddr->upcs2 = ui->ui_slave;
-       if (upaddr->upcs2&UP_NED) {
+       if (upaddr->upcs2&UPCS2_NED) {
                upaddr->upcs1 = UP_DCLR|UP_GO;
                return (0);
        }
                upaddr->upcs1 = UP_DCLR|UP_GO;
                return (0);
        }
@@ -143,9 +152,7 @@ upslave(ui, reg)
 upattach(ui)
        register struct uba_device *ui;
 {
 upattach(ui)
        register struct uba_device *ui;
 {
-#ifdef notdef
        register struct updevice *upaddr;
        register struct updevice *upaddr;
-#endif
 
        if (upwstart == 0) {
                timeout(upwatch, (caddr_t)0, hz);
 
        if (upwstart == 0) {
                timeout(upwatch, (caddr_t)0, hz);
@@ -155,15 +162,21 @@ upattach(ui)
                dk_mspw[ui->ui_dk] = .0000020345;
        upip[ui->ui_ctlr][ui->ui_slave] = ui;
        up_softc[ui->ui_ctlr].sc_ndrive++;
                dk_mspw[ui->ui_dk] = .0000020345;
        upip[ui->ui_ctlr][ui->ui_slave] = ui;
        up_softc[ui->ui_ctlr].sc_ndrive++;
-#ifdef notdef
        upaddr = (struct updevice *)ui->ui_addr;
        upaddr->upcs1 = 0;
        upaddr->upcs2 = ui->ui_slave;
        upaddr = (struct updevice *)ui->ui_addr;
        upaddr->upcs1 = 0;
        upaddr->upcs2 = ui->ui_slave;
-       upaddr->uphr = -1;
-       /* ... */
-       if (upaddr-> ... == 10)
-               ui->ui_type = 1;
-#endif
+       upaddr->uphr = UPHR_MAXTRAK;
+       if (upaddr->uphr == 9)
+               ui->ui_type = 1;                /* fujitsu hack */
+       upaddr->upcs2 = UPCS2_CLR;
+/*
+       upaddr->uphr = UPHR_MAXCYL;
+       printf("maxcyl %d\n", upaddr->uphr);
+       upaddr->uphr = UPHR_MAXTRAK;
+       printf("maxtrak %d\n", upaddr->uphr);
+       upaddr->uphr = UPHR_MAXSECT;
+       printf("maxsect %d\n", upaddr->uphr);
+*/
 }
  
 upstrategy(bp)
 }
  
 upstrategy(bp)
@@ -264,17 +277,17 @@ upustart(ui)
         * If drive has just come up,
         * setup the pack.
         */
         * If drive has just come up,
         * setup the pack.
         */
-       if ((upaddr->upds & UP_VV) == 0) {
+       if ((upaddr->upds & UPDS_VV) == 0) {
                /* SHOULD WARN SYSTEM THAT THIS HAPPENED */
                upaddr->upcs1 = UP_IE|UP_DCLR|UP_GO;
                upaddr->upcs1 = UP_IE|UP_PRESET|UP_GO;
                /* SHOULD WARN SYSTEM THAT THIS HAPPENED */
                upaddr->upcs1 = UP_IE|UP_DCLR|UP_GO;
                upaddr->upcs1 = UP_IE|UP_PRESET|UP_GO;
-               upaddr->upof = UP_FMT22;
+               upaddr->upof = UPOF_FMT22;
                didie = 1;
        }
        /*
         * If drive is offline, forget about positioning.
         */
                didie = 1;
        }
        /*
         * If drive is offline, forget about positioning.
         */
-       if ((upaddr->upds & (UP_DPR|UP_MOL)) != (UP_DPR|UP_MOL))
+       if ((upaddr->upds & (UPDS_DPR|UPDS_MOL)) != (UPDS_DPR|UPDS_MOL))
                goto done;
        /*
         * If there is only one drive,
                goto done;
        /*
         * If there is only one drive,
@@ -384,14 +397,14 @@ loop:
         * Check that it is ready and online
         */
        waitdry = 0;
         * Check that it is ready and online
         */
        waitdry = 0;
-       while ((upaddr->upds&UP_DRY) == 0) {
+       while ((upaddr->upds&UPDS_DRY) == 0) {
                if (++waitdry > 512)
                        break;
                upwaitdry++;
        }
                if (++waitdry > 512)
                        break;
                upwaitdry++;
        }
-       if ((upaddr->upds & UP_DREADY) != UP_DREADY) {
+       if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
                printf("up%d: not ready", dkunit(bp));
                printf("up%d: not ready", dkunit(bp));
-               if ((upaddr->upds & UP_DREADY) != UP_DREADY) {
+               if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
                        printf("\n");
                        um->um_tab.b_active = 0;
                        um->um_tab.b_errcnt = 0;
                        printf("\n");
                        um->um_tab.b_active = 0;
                        um->um_tab.b_errcnt = 0;
@@ -407,15 +420,6 @@ loop:
                 */
                printf(" (flakey)\n");
        }
                 */
                printf(" (flakey)\n");
        }
-       /*
-        * After 16th retry, do offset positioning
-        */
-       if (um->um_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) {
-               upaddr->upof = up_offset[um->um_tab.b_errcnt & 017] | UP_FMT22;
-               upaddr->upcs1 = UP_IE|UP_OFFSET|UP_GO;
-               while (upaddr->upds & UP_PIP)
-                       DELAY(25);
-       }
        /*
         * Setup for the transfer, and get in the
         * UNIBUS adaptor queue.
        /*
         * Setup for the transfer, and get in the
         * UNIBUS adaptor queue.
@@ -485,14 +489,14 @@ upintr(sc21)
         * Check for and process errors on
         * either the drive or the controller.
         */
         * Check for and process errors on
         * either the drive or the controller.
         */
-       if ((upaddr->upds&UP_ERR) || (upaddr->upcs1&UP_TRE)) {
+       if ((upaddr->upds&UPDS_ERR) || (upaddr->upcs1&UP_TRE)) {
                waitdry = 0;
                waitdry = 0;
-               while ((upaddr->upds & UP_DRY) == 0) {
+               while ((upaddr->upds & UPDS_DRY) == 0) {
                        if (++waitdry > 512)
                                break;
                        upwaitdry++;
                }
                        if (++waitdry > 512)
                                break;
                        upwaitdry++;
                }
-               if (upaddr->uper1&UP_WLE) {
+               if (upaddr->uper1&UPER1_WLE) {
                        /*
                         * Give up on write locked devices
                         * immediately.
                        /*
                         * Give up on write locked devices
                         * immediately.
@@ -518,7 +522,7 @@ upintr(sc21)
                         * Otherwise fall through and retry the transfer
                         */
                        um->um_tab.b_active = 0;         /* force retry */
                         * Otherwise fall through and retry the transfer
                         */
                        um->um_tab.b_active = 0;         /* force retry */
-                       if ((upaddr->uper1&(UP_DCK|UP_ECH))==UP_DCK)
+                       if ((upaddr->uper1&(UPER1_DCK|UPER1_ECH))==UPER1_DCK)
                                if (upecc(ui))
                                        return;
                }
                                if (upecc(ui))
                                        return;
                }
@@ -529,23 +533,41 @@ upintr(sc21)
                 */
                upaddr->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO;
                needie = 0;
                 */
                upaddr->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO;
                needie = 0;
-               if ((um->um_tab.b_errcnt&07) == 4) {
+               if ((um->um_tab.b_errcnt&07) == 4 && um->um_tab.b_active == 0) {
                        upaddr->upcs1 = UP_RECAL|UP_IE|UP_GO;
                        upaddr->upcs1 = UP_RECAL|UP_IE|UP_GO;
-                       um->um_tab.b_active = 1;
-                       sc->sc_recal = 1;
-                       return;
+                       sc->sc_recal = 0;
+                       goto nextrecal;
                }
        }
        /*
                }
        }
        /*
-        * Done retrying transfer... release
-        * resources... if we were recalibrating,
-        * then retry the transfer.
-        * Mathematical note: 28%8 != 4.
+        * Advance recalibration finite state machine
+        * if recalibrate in progress, through
+        *      RECAL
+        *      SEEK
+        *      OFFSET (optional)
+        *      RETRY
         */
         */
-       ubadone(um);
-       if (sc->sc_recal) {
+       switch (sc->sc_recal) {
+
+       case 1:
+               upaddr->updc = bp->b_cylin;
+               upaddr->upcs1 = UP_SEEK|UP_IE|UP_GO;
+               goto nextrecal;
+       case 2:
+               if (um->um_tab.b_errcnt < 16 || (bp->b_flags&B_READ) == 0)
+                       goto donerecal;
+               upaddr->upof = up_offset[um->um_tab.b_errcnt & 017] | UPOF_FMT22;
+               upaddr->upcs1 = UP_IE|UP_OFFSET|UP_GO;
+               goto nextrecal;
+       nextrecal:
+               sc->sc_recal++;
+               um->um_tab.b_active = 1;
+               return;
+       donerecal:
+       case 3:
                sc->sc_recal = 0;
                sc->sc_recal = 0;
-               um->um_tab.b_active = 0;        /* force retry */
+               um->um_tab.b_active = 0;
+               break;
        }
        /*
         * If still ``active'', then don't need any more retries.
        }
        /*
         * If still ``active'', then don't need any more retries.
@@ -556,9 +578,9 @@ upintr(sc21)
                 * return to centerline.
                 */
                if (um->um_tab.b_errcnt >= 16) {
                 * return to centerline.
                 */
                if (um->um_tab.b_errcnt >= 16) {
-                       upaddr->upof = UP_FMT22;
+                       upaddr->upof = UPOF_FMT22;
                        upaddr->upcs1 = UP_RTC|UP_GO|UP_IE;
                        upaddr->upcs1 = UP_RTC|UP_GO|UP_IE;
-                       while (upaddr->upds & UP_PIP)
+                       while (upaddr->upds & UPDS_PIP)
                                DELAY(25);
                        needie = 0;
                }
                                DELAY(25);
                        needie = 0;
                }
@@ -579,6 +601,10 @@ upintr(sc21)
                                needie = 0;
        }
        as &= ~(1<<ui->ui_slave);
                                needie = 0;
        }
        as &= ~(1<<ui->ui_slave);
+       /*
+        * Release unibus resources and flush data paths.
+        */
+       ubadone(um);
 doattn:
        /*
         * Process other units which need attention.
 doattn:
        /*
         * Process other units which need attention.
@@ -586,12 +612,13 @@ doattn:
         * the unit start routine to place the slave
         * on the controller device queue.
         */
         * the unit start routine to place the slave
         * on the controller device queue.
         */
-       for (unit = 0; as; as >>= 1, unit++)
-               if (as & 1) {
-                       upaddr->upas = 1<<unit;
-                       if (upustart(upip[sc21][unit]))
-                               needie = 0;
-               }
+       while (unit = ffs(as)) {
+               unit--;         /* was 1 origin */
+               as &= ~(1<<unit);
+               upaddr->upas = 1<<unit;
+               if (upustart(upip[sc21][unit]))
+                       needie = 0;
+       }
        /*
         * If the controller is not transferring, but
         * there are devices ready to transfer, start
        /*
         * If the controller is not transferring, but
         * there are devices ready to transfer, start
@@ -657,6 +684,10 @@ upecc(ui)
        printf("up%d%c: soft ecc sn%d\n", dkunit(bp),
            'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
        mask = up->upec2;
        printf("up%d%c: soft ecc sn%d\n", dkunit(bp),
            'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
        mask = up->upec2;
+#ifdef UPECCDEBUG
+       printf("npf %d reg %x o %d mask %o pos %d\n", npf, reg, o, mask,
+           up->upec1);
+#endif
        /*
         * 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
@@ -677,7 +708,15 @@ upecc(ui)
        while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
                addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
                    (byte & PGOFSET);
        while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
                addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
                    (byte & PGOFSET);
+#ifdef UPECCDEBUG
+               printf("addr %x map reg %x\n",
+                   addr, *(int *)(&ubp->uba_map[reg+btop(byte)]));
+               printf("old: %x, ", getmemc(addr));
+#endif
                putmemc(addr, getmemc(addr)^(mask<<bit));
                putmemc(addr, getmemc(addr)^(mask<<bit));
+#ifdef UPECCDEBUG
+               printf("new: %x\n", getmemc(addr));
+#endif
                byte++;
                i++;
                bit -= 8;
                byte++;
                i++;
                bit -= 8;
@@ -739,7 +778,7 @@ upreset(uban)
                        printf("<%d>", (um->um_ubinfo>>28)&0xf);
                        ubadone(um);
                }
                        printf("<%d>", (um->um_ubinfo>>28)&0xf);
                        ubadone(um);
                }
-               ((struct updevice *)(um->um_addr))->upcs2 = UP_CLR;
+               ((struct updevice *)(um->um_addr))->upcs2 = UPCS2_CLR;
                for (unit = 0; unit < NUP; unit++) {
                        if ((ui = updinfo[unit]) == 0)
                                continue;
                for (unit = 0; unit < NUP; unit++) {
                        if ((ui = updinfo[unit]) == 0)
                                continue;
@@ -819,12 +858,12 @@ updump(dev)
        DELAY(100);
        if ((upaddr->upcs1&UP_DVA) == 0)
                return (EFAULT);
        DELAY(100);
        if ((upaddr->upcs1&UP_DVA) == 0)
                return (EFAULT);
-       if ((upaddr->upds & UP_VV) == 0) {
+       if ((upaddr->upds & UPDS_VV) == 0) {
                upaddr->upcs1 = UP_DCLR|UP_GO;
                upaddr->upcs1 = UP_PRESET|UP_GO;
                upaddr->upcs1 = UP_DCLR|UP_GO;
                upaddr->upcs1 = UP_PRESET|UP_GO;
-               upaddr->upof = UP_FMT22;
+               upaddr->upof = UPOF_FMT22;
        }
        }
-       if ((upaddr->upds & UP_DREADY) != UP_DREADY)
+       if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY)
                return (EFAULT);
        st = &upst[ui->ui_type];
        sizes = phys(struct size *, st->sizes);
                return (EFAULT);
        st = &upst[ui->ui_type];
        sizes = phys(struct size *, st->sizes);
@@ -855,7 +894,7 @@ 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)
+               if (upaddr->upds&UPDS_ERR)
                        return (EIO);
                start += blk*NBPG;
                num -= blk;
                        return (EIO);
                start += blk*NBPG;
                num -= blk;