../conf/*.h
[unix-history] / usr / src / sys / vax / uba / up.c
index 5c49853..c244ef0 100644 (file)
@@ -1,15 +1,19 @@
-/*     up.c    3.19    %G%     */
+/*     up.c    3.26    %G%     */
 
 
+#include "../conf/up.h"
 /*
 /*
- * Emulex UNIBUS disk driver with overlapped seeks and ECC recovery.
+ * UNIBUS disk driver with overlapped seeks and ECC recovery.
  *
  *
- * NB: This driver works reliably only on an SC-11B controller with
- *     rev. level at least J (in particular rev. level H will not work well).
- *     If you have an newer controller you should change olducode below to:
- *             int     olducode = 0;
- *     which saves time by stalling less in the system.
+ * This driver works marginally on an Emulex SC-11B controller with rev
+ * level J microcode, defining:
+ *     int     olducode = 1;
+ * to force CPU stalling delays.
  *
  *
- * Controller switch settings:
+ * It has worked with no delays and no problems on a prototype
+ * SC-21 controller.  Emulex intends to upgrade all SC-11s on VAXes to SC-21s.
+ * You should get a SC-21 to replace any SC-11 on a VAX.
+ *
+ * SC-11B Controller switch settings:
  *     SW1-1   5/19 surfaces   (off, 19 surfaces on Ampex 9300)
  *     SW1-2   chksum enable   (off, checksum disabled)
  *     SW1-3   volume select   (off, 815 cylinders)
  *     SW1-1   5/19 surfaces   (off, 19 surfaces on Ampex 9300)
  *     SW1-2   chksum enable   (off, checksum disabled)
  *     SW1-3   volume select   (off, 815 cylinders)
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/map.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/map.h"
+#include "../h/pte.h"
 #include "../h/mba.h"
 #include "../h/mtpr.h"
 #include "../h/mba.h"
 #include "../h/mtpr.h"
-#include "../h/pte.h"
 #include "../h/uba.h"
 #include "../h/vm.h"
 
 #include "../h/uba.h"
 #include "../h/vm.h"
 
-/*
- * Define number of drives, and range of sampling information to be used.
- *
- * Normally, DK_N .. DK_N+NUP-1 gather individual drive stats,
- * and DK_N+NUP gathers controller transferring stats.
- *
- * If DK_N+NUP > DK_NMAX, then transfer stats are divided per drive.
- * If DK_NMAX is yet smaller, some drives are not monitored.
- */
-#define        DK_N    2
-#define        DK_NMAX 3
-
 #define        ushort  unsigned short
 
 struct device
 #define        ushort  unsigned short
 
 struct device
@@ -90,10 +82,6 @@ int  upsoftas;
  */
 int    upseek;
 
  */
 int    upseek;
 
-#define        UPADDR  ((struct device *)(UBA0_DEV + 0176700))
-
-#define        NUP     2               /* Number of drives this installation */
-
 #define        NSECT   32
 #define        NTRAC   19
 
 #define        NSECT   32
 #define        NTRAC   19
 
@@ -273,6 +261,8 @@ register struct buf *bp;
                iodone(bp);
                return;
        }
                iodone(bp);
                return;
        }
+       if (DK_N+unit <= DK_NMAX)
+               dk_mspw[DK_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();
@@ -394,9 +384,9 @@ search:
         * Mark this unit busy.
         */
        unit += DK_N;
         * Mark this unit busy.
         */
        unit += DK_N;
-       if (unit <= DK_NMAX && DK_N+NUP <= DK_NMAX) {
+       if (unit <= DK_NMAX) {
                dk_busy |= 1<<unit;
                dk_busy |= 1<<unit;
-               dk_numb[unit]++;
+               dk_seek[unit]++;
        }
        if (olducode)
                DELAY(ordelay);
        }
        if (olducode)
                DELAY(ordelay);
@@ -472,21 +462,26 @@ 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)) {
-               printf("!DPR || !MOL, unit %d, ds %o\n", dn, upaddr->upds);
-               uptab.b_active = 0;
-               uptab.b_errcnt = 0;
-               dp->b_actf = bp->av_forw;
-               dp->b_active = 0;
-               bp->b_flags |= B_ERROR;
-               iodone(bp);
-               ubafree(up_ubinfo), up_ubinfo = 0;      /* A funny place ... */
-               goto loop;
+               printf("!DPR || !MOL, unit %d, ds %o", dn, upaddr->upds);
+               if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) {
+                       printf("-- hard\n");
+                       uptab.b_active = 0;
+                       uptab.b_errcnt = 0;
+                       dp->b_actf = bp->av_forw;
+                       dp->b_active = 0;
+                       bp->b_flags |= B_ERROR;
+                       iodone(bp);
+                       /* A funny place to do this ... */
+                       ubafree(up_ubinfo), up_ubinfo = 0;
+                       goto loop;
+               }
+               printf("-- came back\n");
        }
        /*
         * If this is a retry, then with the 16'th retry we
         * begin to try offsetting the heads to recover the data.
         */
        }
        /*
         * If this is a retry, then with the 16'th retry we
         * begin to try offsetting the heads to recover the data.
         */
-       if (uptab.b_errcnt >= 16) {
+       if (uptab.b_errcnt >= 16 && (bp->b_flags&B_WRITE) == 0) {
                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);
@@ -516,11 +511,9 @@ loop:
         * (if there is room for that).
         */
        unit = dn+DK_N;
         * (if there is room for that).
         */
        unit = dn+DK_N;
-       if (NUP+DK_N == DK_NMAX)
-               unit = NUP+DK_N;
        if (unit <= DK_NMAX) {
                dk_busy |= 1<<unit;
        if (unit <= DK_NMAX) {
                dk_busy |= 1<<unit;
-               dk_numb[unit]++;
+               dk_xfer[unit]++;
                dk_wds[unit] += bp->b_bcount>>6;
        }
        return (1);
                dk_wds[unit] += bp->b_bcount>>6;
        }
        return (1);
@@ -559,15 +552,13 @@ upintr()
                            uputab[0].b_active, uputab[1].b_active);
                }
                /*
                            uputab[0].b_active, uputab[1].b_active);
                }
                /*
-                * Mark controller or drive not busy, and check for an
+                * Mark drive not busy, and check for an
                 * error condition which may have resulted from the transfer.
                 */
                dp = uptab.b_actf;
                bp = dp->b_actf;
                unit = dkunit(bp);
                 * error condition which may have resulted from the transfer.
                 */
                dp = uptab.b_actf;
                bp = dp->b_actf;
                unit = dkunit(bp);
-               if (DK_N+NUP == DK_NMAX)
-                       dk_busy &= ~(1<<(DK_N+NUP));
-               else if (DK_N+unit <= DK_NMAX)
+               if (DK_N+unit <= DK_NMAX)
                        dk_busy &= ~(1<<(DK_N+unit));
                if ((upaddr->upcs2 & 07) != unit) {
                        upaddr->upcs2 = unit;
                        dk_busy &= ~(1<<(DK_N+unit));
                if ((upaddr->upcs2 & 07) != unit) {
                        upaddr->upcs2 = unit;
@@ -575,7 +566,7 @@ upintr()
                        nwaitcs2++;
                } else
                        neasycs2++;
                        nwaitcs2++;
                } else
                        neasycs2++;
-               if (upaddr->upds & ERR) {
+               if ((upaddr->upds&ERR) || (upaddr->upcs1&TRE)) {
                        /*
                         * 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
@@ -802,8 +793,6 @@ upreset()
        printf(" up");
        uptab.b_active = 0;
        uptab.b_actf = uptab.b_actl = 0;
        printf(" up");
        uptab.b_active = 0;
        uptab.b_actf = uptab.b_actl = 0;
-       if (DK_N+NUP == DK_NMAX)
-               dk_busy &= ~(1<<(DK_N+NUP));
        if (up_ubinfo) {
                printf("<%d>", (up_ubinfo>>28)&0xf);
                ubafree(up_ubinfo), up_ubinfo = 0;
        if (up_ubinfo) {
                printf("<%d>", (up_ubinfo>>28)&0xf);
                ubafree(up_ubinfo), up_ubinfo = 0;