with tracing, it works!?!
[unix-history] / usr / src / sys / vax / uba / up.c
index a6933a4..eb22040 100644 (file)
@@ -1,6 +1,7 @@
-int    cs1del;
-int    printsw;
-/*     %H%     3.2     %G%     */
+#define        UTRACE
+int    asdel = 500;
+int    csdel3 = 100;
+/*     %H%     3.5     %G%     */
 
 /*
  * Emulex UNIBUS disk driver with overlapped seeks and ECC recovery.
 
 /*
  * Emulex UNIBUS disk driver with overlapped seeks and ECC recovery.
@@ -212,11 +213,7 @@ int        up_ubinfo;              /* Information about UBA usage saved here */
  * variables control the delay, DELAY(n) is approximately n usec.
  */
 int    idelay = 500;           /* Delay after PRESET or DCLR */
  * variables control the delay, DELAY(n) is approximately n usec.
  */
 int    idelay = 500;           /* Delay after PRESET or DCLR */
-int    sdelay = 500;           /* Delay after selecting drive in upcs2 */
-int    iedel1 = 500;
-int    iedel2 = 500;
-int    iedel3 = 0;
-int    iedel4 = 500;
+int    sdelay = 150;           /* Delay after selecting drive in upcs2 */
 
 #define        DELAY(N)                { register int d; d = N; while (--d > 0); }
  
 
 #define        DELAY(N)                { register int d; d = N; while (--d > 0); }
  
@@ -257,10 +254,14 @@ register struct buf *bp;
        dp = &uputab[unit];
        (void) spl5();
        disksort(dp, bp);
        dp = &uputab[unit];
        (void) spl5();
        disksort(dp, bp);
+#ifdef UTRACE
+       ttime();
+       trace("upstrat bn %d unit %d\n", bp->b_blkno, unit);
+#endif
        if (dp->b_active == 0) {
        if (dp->b_active == 0) {
-               upustart(unit);
+               (void) upustart(unit);
                if (uptab.b_actf && uptab.b_active == 0)
                if (uptab.b_actf && uptab.b_active == 0)
-                       upstart();
+                       (void) upstart();
        }
        (void) spl0();
 }
        }
        (void) spl0();
 }
@@ -277,10 +278,14 @@ register unit;
        register struct device *upaddr = UPADDR;
        daddr_t bn;
        int sn, cn, csn;
        register struct device *upaddr = UPADDR;
        daddr_t bn;
        int sn, cn, csn;
+       int didie = 0;
 
 
-       if (printsw&1) printf("upustart\n");
        if (unit >= NUP)
        if (unit >= NUP)
-               return;
+               goto out;
+#ifdef UTRACE
+       ttime();
+       trace("upustart %d active %d", unit, uputab[unit].b_active);
+#endif
        /*
         * Whether or not it was before, this unit is no longer busy.
         * Check to see if there is (still or now) a request in this
        /*
         * Whether or not it was before, this unit is no longer busy.
         * Check to see if there is (still or now) a request in this
@@ -290,7 +295,7 @@ register unit;
                dk_busy &= ~(1<<(unit+DK_N));
        dp = &uputab[unit];
        if ((bp = dp->b_actf) == NULL)
                dk_busy &= ~(1<<(unit+DK_N));
        dp = &uputab[unit];
        if ((bp = dp->b_actf) == NULL)
-               return;
+               goto out;
        if ((upaddr->upcs2 & 07) != unit) {
                upaddr->upcs2 = unit;
                DELAY(sdelay);
        if ((upaddr->upcs2 & 07) != unit) {
                upaddr->upcs2 = unit;
                DELAY(sdelay);
@@ -303,11 +308,15 @@ register unit;
         * the drive, preset it and put in 16bit/word mode.
         */
        if ((upaddr->upds & VV) == 0) {
         * the drive, preset it and put in 16bit/word mode.
         */
        if ((upaddr->upds & VV) == 0) {
+#ifdef UTRACE
+               trace(" not VV");
+#endif
                upaddr->upcs1 = IE|DCLR|GO;
                DELAY(idelay);
                upaddr->upcs1 = IE|PRESET|GO;
                DELAY(idelay);
                upaddr->upof = FMT22;
                upaddr->upcs1 = IE|DCLR|GO;
                DELAY(idelay);
                upaddr->upcs1 = IE|PRESET|GO;
                DELAY(idelay);
                upaddr->upof = FMT22;
+               didie = 1;
        }
        /*
         * We are called from upstrategy when a new request arrives
        }
        /*
         * We are called from upstrategy when a new request arrives
@@ -361,11 +370,14 @@ register unit;
                goto done;
 
 search:
                goto done;
 
 search:
+#ifdef UTRACE
+       trace(" search %d@%d to %d@%d", upaddr->updc, (upaddr->upla>>6),
+           cn, sn);
+#endif
        upaddr->updc = cn;
        upaddr->upda = sn;
        upaddr->updc = cn;
        upaddr->upda = sn;
-       if (cs1del&8) DELAY(500);
        upaddr->upcs1 = IE|SEARCH|GO;
        upaddr->upcs1 = IE|SEARCH|GO;
-       if (cs1del&8) DELAY(500);
+       didie = 1;
        /*
         * Mark this unit busy.
         */
        /*
         * Mark this unit busy.
         */
@@ -374,7 +386,7 @@ search:
                dk_busy |= 1<<unit;
                dk_numb[unit]++;
        }
                dk_busy |= 1<<unit;
                dk_numb[unit]++;
        }
-       return;
+       goto out;
 
 done:
        /*
 
 done:
        /*
@@ -382,6 +394,9 @@ done:
         * we won't get called again (by upintr() because upas&(1<<unit))
         * and link us onto the chain of ready disks.
         */
         * we won't get called again (by upintr() because upas&(1<<unit))
         * and link us onto the chain of ready disks.
         */
+#ifdef UTRACE
+       trace(" done");
+#endif
        dp->b_active = 2;
        dp->b_forw = NULL;
        if (uptab.b_actf == NULL)
        dp->b_active = 2;
        dp->b_forw = NULL;
        if (uptab.b_actf == NULL)
@@ -389,6 +404,12 @@ done:
        else
                uptab.b_actl->b_forw = dp;
        uptab.b_actl = dp;
        else
                uptab.b_actl->b_forw = dp;
        uptab.b_actl = dp;
+
+out:
+#ifdef UTRACE
+       trace("\n");
+#endif
+       return (didie);
 }
 
 /*
 }
 
 /*
@@ -402,8 +423,11 @@ upstart()
        daddr_t bn;
        int dn, sn, tn, cn, cmd;
 
        daddr_t bn;
        int dn, sn, tn, cn, cmd;
 
-       if (printsw&2) printf("upstart\n");
 loop:
 loop:
+#ifdef UTRACE
+       ttime();
+       trace("upstart");
+#endif
        /*
         * Pick a drive off the queue of ready drives, and
         * perform the first transfer on its queue.
        /*
         * Pick a drive off the queue of ready drives, and
         * perform the first transfer on its queue.
@@ -412,8 +436,12 @@ loop:
         * are not present and on-line, for which we completely clear the
         * request queue.
         */
         * are not present and on-line, for which we completely clear the
         * request queue.
         */
-       if ((dp = uptab.b_actf) == NULL)
-               return;
+       if ((dp = uptab.b_actf) == NULL) {
+#ifdef UTRACE
+               trace("\n");
+#endif
+               return (0);
+       }
        if ((bp = dp->b_actf) == NULL) {
                uptab.b_actf = dp->b_forw;
                goto loop;
        if ((bp = dp->b_actf) == NULL) {
                uptab.b_actf = dp->b_forw;
                goto loop;
@@ -432,7 +460,13 @@ loop:
        tn = sn/NSECT;
        sn %= NSECT;
        upaddr = UPADDR;
        tn = sn/NSECT;
        sn %= NSECT;
        upaddr = UPADDR;
+#ifdef UTRACE
+       trace(" unit %d", dn);
+#endif
        if ((upaddr->upcs2 & 07) != dn) {
        if ((upaddr->upcs2 & 07) != dn) {
+#ifdef UTRACE
+               trace(" select");
+#endif
                upaddr->upcs2 = dn;
                DELAY(sdelay);
                nwaitcs2++;
                upaddr->upcs2 = dn;
                DELAY(sdelay);
                nwaitcs2++;
@@ -446,6 +480,9 @@ loop:
         * (Then on to any other ready drives.)
         */
        if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) {
         * (Then on to any other ready drives.)
         */
        if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) {
+#ifdef UTRACE
+               trace(" !(DPR && MOL)");
+#endif
                uptab.b_active = 0;
                uptab.b_errcnt = 0;
                dp->b_actf = bp->av_forw;
                uptab.b_active = 0;
                uptab.b_errcnt = 0;
                dp->b_actf = bp->av_forw;
@@ -460,6 +497,9 @@ loop:
         * begin to try offsetting the heads to recover the data.
         */
        if (uptab.b_errcnt >= 16) {
         * begin to try offsetting the heads to recover the data.
         */
        if (uptab.b_errcnt >= 16) {
+#ifdef UTRACE
+               trace(" offset");
+#endif
                upaddr->upof = up_offset[uptab.b_errcnt & 017] | FMT22;
                upaddr->upcs1 = IE|OFFSET|GO;
                DELAY(idelay);
                upaddr->upof = up_offset[uptab.b_errcnt & 017] | FMT22;
                upaddr->upcs1 = IE|OFFSET|GO;
                DELAY(idelay);
@@ -471,19 +511,24 @@ loop:
         * 2 bits of the UNIBUS address from the information
         * returned by ubasetup() for the cs1 register bits 8 and 9.
         */
         * 2 bits of the UNIBUS address from the information
         * returned by ubasetup() for the cs1 register bits 8 and 9.
         */
+#ifdef UTRACE
+       trace(" %s %d.%d@%d cnt %d ba %x\n",
+           (bp->b_flags&B_READ) ? "read" : "write",
+           cn, tn, sn, bp->b_bcount, up_ubinfo & 0x3ffff);
+#endif
        upaddr->updc = cn;
        upaddr->upda = (tn << 8) + sn;
        upaddr->upba = up_ubinfo;
        upaddr->updc = cn;
        upaddr->upda = (tn << 8) + sn;
        upaddr->upba = up_ubinfo;
-       if (cs1del&1) DELAY(500);
        upaddr->upwc = -bp->b_bcount / sizeof (short);
        cmd = (up_ubinfo >> 8) & 0x300;
        if (bp->b_flags & B_READ)
                cmd |= IE|RCOM|GO;
        else
                cmd |= IE|WCOM|GO;
        upaddr->upwc = -bp->b_bcount / sizeof (short);
        cmd = (up_ubinfo >> 8) & 0x300;
        if (bp->b_flags & B_READ)
                cmd |= IE|RCOM|GO;
        else
                cmd |= IE|WCOM|GO;
-       if (cs1del&1) DELAY(500);
        upaddr->upcs1 = cmd;
        upaddr->upcs1 = cmd;
-       if (cs1del&1) DELAY(500);
+#ifdef notdef
+       if (csdel3) DELAY(csdel3);
+#endif
        /*
         * This is a controller busy situation.
         * Record in dk slot NUP+DK_N (after last drive)
        /*
         * This is a controller busy situation.
         * Record in dk slot NUP+DK_N (after last drive)
@@ -499,6 +544,7 @@ loop:
                dk_numb[unit]++;
                dk_wds[unit] += bp->b_bcount>>6;
        }
                dk_numb[unit]++;
                dk_wds[unit] += bp->b_bcount>>6;
        }
+       return (1);
 }
 
 /*
 }
 
 /*
@@ -516,8 +562,12 @@ upintr()
        register unit;
        register struct device *upaddr = UPADDR;
        int as = upaddr->upas & 0377;
        register unit;
        register struct device *upaddr = UPADDR;
        int as = upaddr->upas & 0377;
+       int needie = 1;
 
 
-       if (printsw&4) printf("upintr as=%d act %d %d %d\n", as, uptab.b_active, uputab[0].b_active, uputab[1].b_active);
+#ifdef UTRACE
+       ttime();
+       trace("upintr as %d act %d %d %d;", as, uptab.b_active, uputab[0].b_active, uputab[1].b_active);
+#endif
        if (uptab.b_active) {
                /*
                 * The drive is transferring, thus the hardware
        if (uptab.b_active) {
                /*
                 * The drive is transferring, thus the hardware
@@ -525,8 +575,11 @@ upintr()
                 * completes; check for it anyways.
                 */
                if ((upaddr->upcs1 & RDY) == 0) {
                 * completes; check for it anyways.
                 */
                if ((upaddr->upcs1 & RDY) == 0) {
-                       printf("upintr b_active && !RDY\n");
-                       goto out;
+#ifdef UTRACE
+                       trace(" !RDY");
+#endif
+                       printf("!RDY in upintr: cs1 %o\n", upaddr->upcs1);
+printf("as=%d act %d %d %d\n", as, uptab.b_active, uputab[0].b_active, uputab[1].b_active);
                }
                /*
                 * Mark controller or drive not busy, and check for an
                }
                /*
                 * Mark controller or drive not busy, and check for an
@@ -540,6 +593,9 @@ upintr()
                else if (DK_N+unit <= DK_NMAX)
                        dk_busy &= ~(1<<(DK_N+unit));
                if (upaddr->upcs1 & TRE) {
                else if (DK_N+unit <= DK_NMAX)
                        dk_busy &= ~(1<<(DK_N+unit));
                if (upaddr->upcs1 & TRE) {
+#ifdef UTRACE
+                       trace(" TRE");
+#endif
                        /*
                         * An error occurred, indeed.  Select this unit
                         * to get at the drive status (a SEARCH may have
                        /*
                         * An error occurred, indeed.  Select this unit
                         * to get at the drive status (a SEARCH may have
@@ -586,6 +642,7 @@ upintr()
                         */
                        upaddr->upcs1 = TRE|IE|DCLR|GO;
                        DELAY(idelay);
                         */
                        upaddr->upcs1 = TRE|IE|DCLR|GO;
                        DELAY(idelay);
+                       needie = 0;
                        if ((uptab.b_errcnt&07) == 4) {
                                upaddr->upcs1 = RECAL|GO|IE;
                                DELAY(idelay);
                        if ((uptab.b_errcnt&07) == 4) {
                                upaddr->upcs1 = RECAL|GO|IE;
                                DELAY(idelay);
@@ -603,17 +660,27 @@ upintr()
                 * on this drive with the upustart routine (if any).
                 */
                if (uptab.b_active) {
                 * on this drive with the upustart routine (if any).
                 */
                if (uptab.b_active) {
+#ifdef UTRACE
+                       trace(" unit %d", unit);
+#endif
                        if ((upaddr->upcs2 & 07) != unit) {
                        if ((upaddr->upcs2 & 07) != unit) {
+#ifdef UTRACE
+                               trace(" select");
+#endif
                                upaddr->upcs2 = unit;
                                DELAY(sdelay);
                                nwaitcs2++;
                        } else
                                neasycs2++;
                        if (uptab.b_errcnt >= 16) {
                                upaddr->upcs2 = unit;
                                DELAY(sdelay);
                                nwaitcs2++;
                        } else
                                neasycs2++;
                        if (uptab.b_errcnt >= 16) {
+#ifdef UTRACE
+                               trace(" rtc");
+#endif
                                upaddr->upcs1 = RTC|GO|IE;
                                DELAY(idelay);
                                while (upaddr->upds & PIP)
                                        DELAY(25);
                                upaddr->upcs1 = RTC|GO|IE;
                                DELAY(idelay);
                                while (upaddr->upds & PIP)
                                        DELAY(25);
+                               needie = 0;
                        }
                        uptab.b_active = 0;
                        uptab.b_errcnt = 0;
                        }
                        uptab.b_active = 0;
                        uptab.b_errcnt = 0;
@@ -622,23 +689,22 @@ upintr()
                        dp->b_errcnt = 0;
                        dp->b_actf = bp->av_forw;
                        bp->b_resid = (-upaddr->upwc * sizeof(short));
                        dp->b_errcnt = 0;
                        dp->b_actf = bp->av_forw;
                        bp->b_resid = (-upaddr->upwc * sizeof(short));
-                       if (cs1del&2) DELAY(500);
-                       upaddr->upcs1 = IE;
-                       if (cs1del&2) DELAY(500);
                        iodone(bp);
                        if(dp->b_actf)
                        iodone(bp);
                        if(dp->b_actf)
-                               upustart(unit);
+                               if (upustart(unit))
+                                       needie = 0;
                }
                as &= ~(1<<unit);
                ubafree(up_ubinfo), up_ubinfo = 0;
        }
 #ifndef notdef
        else {
                }
                as &= ~(1<<unit);
                ubafree(up_ubinfo), up_ubinfo = 0;
        }
 #ifndef notdef
        else {
-               if (printsw&64) printf("cs1 %o\n", upaddr->upcs1);
                if (upaddr->upcs1 & TRE) {
                if (upaddr->upcs1 & TRE) {
+#ifdef UTRACE
+                       trace(" TRE");
+#endif
                        upaddr->upcs1 = TRE;
                        DELAY(idelay);
                        upaddr->upcs1 = TRE;
                        DELAY(idelay);
-                       if (printsw&64) printf("after TRE cs1 %o\n", upaddr->upcs1);
                }
        }
 #endif
                }
        }
 #endif
@@ -649,22 +715,36 @@ upintr()
         * Finally, if the controller is not transferring
         * start it if any drives are now ready to transfer.
         */
         * Finally, if the controller is not transferring
         * start it if any drives are now ready to transfer.
         */
+#ifdef UTRACE
+       trace("\n");
+#endif
        for (unit = 0; unit < NUP; unit++)
                if (as & (1<<unit))
        for (unit = 0; unit < NUP; unit++)
                if (as & (1<<unit))
-                       if (uputab[unit].b_active == 1)
-                               upustart(unit);
-                       else {
+                       if (uputab[unit].b_active == 1) {
+                               upaddr->upas = 1<<unit;
+#ifdef UTRACE
+                               trace("as clear %d\n", unit);
+#endif
+                               if (asdel) DELAY(asdel);
+                               if (upustart(unit))
+                                       needie = 0;
+                       } else {
                                upaddr->upas = 1<<unit;
                                upaddr->upas = 1<<unit;
+#ifdef UTRACE
+                               trace("spurious as clear %d\n", unit);
+#endif
                                DELAY(1000);
                        }
        if (uptab.b_actf && uptab.b_active == 0)
                                DELAY(1000);
                        }
        if (uptab.b_actf && uptab.b_active == 0)
-               upstart();
+               if (upstart())
+                       needie = 0;
 out:
 out:
-       if (cs1del&4) DELAY(500);
-       if ((upaddr->upcs1&IE) == 0)
+       if (needie) {
+#ifdef UTRACE
+               trace("upintr set IE\n");
+#endif
                upaddr->upcs1 = IE;
                upaddr->upcs1 = IE;
-       if (cs1del&4) DELAY(500);
-       if (printsw&128) printf("exit cs1 %o\n", upaddr->upcs1);
+       }
 }
 
 upread(dev)
 }
 
 upread(dev)
@@ -695,7 +775,6 @@ register struct buf *bp;
        int reg, bit, byte, npf, mask, o, cmd, ubaddr;
        int bn, cn, tn, sn;
 
        int reg, bit, byte, npf, mask, o, cmd, ubaddr;
        int bn, cn, tn, sn;
 
-       if (printsw&8) printf("upecc\n");
        /*
         * Npf is the number of sectors transferred before the sector
         * containing the ECC error, and reg is the UBA register
        /*
         * Npf is the number of sectors transferred before the sector
         * containing the ECC error, and reg is the UBA register