ubafree() becomes ubarelse() to fix race conditions
[unix-history] / usr / src / sys / vax / uba / up.c
index 7646672..fe6fed6 100644 (file)
@@ -1,6 +1,10 @@
-/*     up.c    4.    %G%     */
+/*     up.c    4.10    %G%     */
 
 
-#include "../conf/up.h"
+#include "up.h"
+#if NUP > 0
+#if SC11 > 0
+#include "../dev/up.c.SC11"
+#else
 /*
  * UNIBUS disk driver with overlapped seeks and ECC recovery.
  */
 /*
  * UNIBUS disk driver with overlapped seeks and ECC recovery.
  */
@@ -171,6 +175,9 @@ struct      buf     rupbuf;                 /* Buffer for raw i/o */
 
 /* Bits of upcs2 */
 #define        CLR     040             /* Controller clear */
 
 /* Bits of upcs2 */
 #define        CLR     040             /* Controller clear */
+#define        MXF     01000
+#define        NEM     04000
+
 /* Bits of uper1 */
 #define        DCK     0100000         /* Ecc error occurred */
 #define        ECH     0100            /* Ecc error was unrecoverable */
 /* Bits of uper1 */
 #define        DCK     0100000         /* Ecc error occurred */
 #define        ECH     0100            /* Ecc error was unrecoverable */
@@ -221,8 +228,8 @@ register struct buf *bp;
                iodone(bp);
                return;
        }
                iodone(bp);
                return;
        }
-       if (DK_N+unit <= DK_NMAX)
-               dk_mspw[DK_N+unit] = .0000020345;
+       if (UPDK_N+unit <= UPDK_NMAX)
+               dk_mspw[UPDK_N+unit] = .0000020345;
        bp->b_cylin = bn/(NSECT*NTRAC) + up_sizes[xunit&07].cyloff;
        dp = &uputab[unit];
        (void) spl5();
        bp->b_cylin = bn/(NSECT*NTRAC) + up_sizes[xunit&07].cyloff;
        dp = &uputab[unit];
        (void) spl5();
@@ -265,8 +272,8 @@ register unit;
         */
        if (unit >= NUP)
                goto out;
         */
        if (unit >= NUP)
                goto out;
-       if (unit+DK_N <= DK_NMAX)
-               dk_busy &= ~(1<<(unit+DK_N));
+       if (unit+UPDK_N <= UPDK_NMAX)
+               dk_busy &= ~(1<<(unit+UPDK_N));
        dp = &uputab[unit];
        if ((bp = dp->b_actf) == NULL)
                goto out;
        dp = &uputab[unit];
        if ((bp = dp->b_actf) == NULL)
                goto out;
@@ -334,8 +341,8 @@ search:
        /*
         * Mark this unit busy.
         */
        /*
         * Mark this unit busy.
         */
-       unit += DK_N;
-       if (unit <= DK_NMAX) {
+       unit += UPDK_N;
+       if (unit <= UPDK_NMAX) {
                dk_busy |= 1<<unit;
                dk_seek[unit]++;
        }
                dk_busy |= 1<<unit;
                dk_seek[unit]++;
        }
@@ -417,7 +424,7 @@ loop:
                        bp->b_flags |= B_ERROR;
                        iodone(bp);
                        /* A funny place to do this ... */
                        bp->b_flags |= B_ERROR;
                        iodone(bp);
                        /* A funny place to do this ... */
-                       ubafree(up_ubinfo), up_ubinfo = 0;
+                       ubarelse(&up_ubinfo);
                        goto loop;
                }
                printf("-- came back\n");
                        goto loop;
                }
                printf("-- came back\n");
@@ -449,13 +456,13 @@ loop:
        upaddr->upcs1 = cmd;
        /*
         * This is a controller busy situation.
        upaddr->upcs1 = cmd;
        /*
         * This is a controller busy situation.
-        * Record in dk slot NUP+DK_N (after last drive)
+        * Record in dk slot NUP+UPDK_N (after last drive)
         * unless there aren't that many slots reserved for
         * us in which case we record this as a drive busy
         * (if there is room for that).
         */
         * unless there aren't that many slots reserved for
         * us in which case we record this as a drive busy
         * (if there is room for that).
         */
-       unit = dn+DK_N;
-       if (unit <= DK_NMAX) {
+       unit = dn+UPDK_N;
+       if (unit <= UPDK_NMAX) {
                dk_busy |= 1<<unit;
                dk_xfer[unit]++;
                dk_wds[unit] += bp->b_bcount>>6;
                dk_busy |= 1<<unit;
                dk_xfer[unit]++;
                dk_wds[unit] += bp->b_bcount>>6;
@@ -502,11 +509,12 @@ upintr()
                dp = uptab.b_actf;
                bp = dp->b_actf;
                unit = dkunit(bp);
                dp = uptab.b_actf;
                bp = dp->b_actf;
                unit = dkunit(bp);
-               if (DK_N+unit <= DK_NMAX)
-                       dk_busy &= ~(1<<(DK_N+unit));
+               if (UPDK_N+unit <= UPDK_NMAX)
+                       dk_busy &= ~(1<<(UPDK_N+unit));
                if ((upaddr->upcs2 & 07) != unit)
                        upaddr->upcs2 = unit;
                if ((upaddr->upds&ERR) || (upaddr->upcs1&TRE)) {
                if ((upaddr->upcs2 & 07) != unit)
                        upaddr->upcs2 = unit;
                if ((upaddr->upds&ERR) || (upaddr->upcs1&TRE)) {
+                       int cs2;
                        /*
                         * 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
@@ -528,6 +536,7 @@ upintr()
                        else
                                uptab.b_active = 0;     /* To force retry */
                        if (uptab.b_errcnt > 27)
                        else
                                uptab.b_active = 0;     /* To force retry */
                        if (uptab.b_errcnt > 27)
+                               cs2 = (int)upaddr->upcs2;
                                deverror(bp, (int)upaddr->upcs2,
                                    (int)upaddr->uper1);
                        /*
                                deverror(bp, (int)upaddr->upcs2,
                                    (int)upaddr->uper1);
                        /*
@@ -551,6 +560,11 @@ upintr()
                                while(upaddr->upds & PIP)
                                        DELAY(25);
                        }
                                while(upaddr->upds & PIP)
                                        DELAY(25);
                        }
+                       if (uptab.b_errcnt == 28 && cs2&(NEM|MXF)) {
+                               printf("FLAKEY UP ");
+                               ubareset();
+                               return;
+                       }
                }
                /*
                 * If we are still noted as active, then no
                }
                /*
                 * If we are still noted as active, then no
@@ -586,7 +600,7 @@ upintr()
                }
                as &= ~(1<<unit);
                upsoftas &= ~(1<<unit);
                }
                as &= ~(1<<unit);
                upsoftas &= ~(1<<unit);
-               ubafree(up_ubinfo), up_ubinfo = 0;
+               ubarelse(&up_ubinfo);
        } else {
                if (upaddr->upcs1 & TRE)
                        upaddr->upcs1 = TRE;
        } else {
                if (upaddr->upcs1 & TRE)
                        upaddr->upcs1 = TRE;
@@ -721,11 +735,12 @@ upreset()
        int unit;
 
        printf(" up");
        int unit;
 
        printf(" up");
+       DELAY(15000000);                /* give it time to self-test */
        uptab.b_active = 0;
        uptab.b_actf = uptab.b_actl = 0;
        if (up_ubinfo) {
                printf("<%d>", (up_ubinfo>>28)&0xf);
        uptab.b_active = 0;
        uptab.b_actf = uptab.b_actl = 0;
        if (up_ubinfo) {
                printf("<%d>", (up_ubinfo>>28)&0xf);
-               ubafree(up_ubinfo), up_ubinfo = 0;
+               ubarelse(&up_ubinfo);
        }
        UPADDR->upcs2 = CLR;            /* clear controller */
        for (unit = 0; unit < NUP; unit++) {
        }
        UPADDR->upcs2 = CLR;            /* clear controller */
        for (unit = 0; unit < NUP; unit++) {
@@ -762,3 +777,5 @@ active:
                printf("\n");
        }
 }
                printf("\n");
        }
 }
+#endif
+#endif