(no message)
[unix-history] / usr / src / sys / vax / uba / up.c
index a63873b..519fb16 100644 (file)
@@ -1,10 +1,7 @@
-/*     up.c    4.    %G%     */
+/*     up.c    4.12    %G%     */
 
 
-#include "../conf/up.h"
+#include "up.h"
 #if NUP > 0
 #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.
  */
 #include "../h/mtpr.h"
 #include "../h/uba.h"
 #include "../h/vm.h"
 #include "../h/mtpr.h"
 #include "../h/uba.h"
 #include "../h/vm.h"
+#include "../h/cmap.h"
 
 
-#define        ushort  unsigned short
-
-struct device
-{
-       ushort  upcs1;          /* control and status register 1 */
-       short   upwc;           /* word count register */
-       ushort  upba;           /* UNIBUS address register */
-       ushort  upda;           /* desired address register */
-       ushort  upcs2;          /* control and status register 2 */
-       ushort  upds;           /* drive Status */
-       ushort  uper1;          /* error register 1 */
-       ushort  upas;           /* attention summary */
-       ushort  upla;           /* look ahead */
-       ushort  updb;           /* data buffer */
-       ushort  upmr;           /* maintenance */ 
-       ushort  updt;           /* drive type */
-       ushort  upsn;           /* serial number */
-       ushort  upof;           /* offset register */
-       ushort  updc;           /* desired cylinder address register */
-       ushort  upcc;           /* current cylinder */
-       ushort  uper2;          /* error register 2 */
-       ushort  uper3;          /* error register 3 */
-       ushort  upec1;          /* burst error bit position */
-       ushort  upec2;          /* burst error bit pattern */
-};
+#include "../h/upreg.h"
 
 /*
  * Software extension to the upas register, so we can
 
 /*
  * Software extension to the upas register, so we can
@@ -148,44 +122,6 @@ struct     buf     uputab[NUP];
 
 struct buf     rupbuf;                 /* Buffer for raw i/o */
 
 
 struct buf     rupbuf;                 /* Buffer for raw i/o */
 
-/* Drive commands, placed in upcs1 */
-#define        GO      01              /* Go bit, set in all commands */
-#define        PRESET  020             /* Preset drive at init or after errors */
-#define        OFFSET  014             /* Offset heads to try to recover error */
-#define        RTC     016             /* Return to center-line after OFFSET */
-#define        SEARCH  030             /* Search for cylinder+sector */
-#define        SEEK    04              /* Seek to cylinder */
-#define        RECAL   06              /* Recalibrate, needed after seek error */
-#define        DCLR    010             /* Drive clear, after error */
-#define        WCOM    060             /* Write */
-#define        RCOM    070             /* Read */
-
-/* Other bits of upcs1 */
-#define        IE      0100            /* Controller wide interrupt enable */
-#define        TRE     040000          /* Transfer error */
-#define        RDY     0200            /* Transfer terminated */
-
-/* Drive status bits of upds */
-#define        PIP     020000          /* Positioning in progress */
-#define        ERR     040000          /* Error has occurred, DCLR necessary */
-#define        VV      0100            /* Volume is valid, set by PRESET */
-#define        DPR     0400            /* Drive has been preset */
-#define        MOL     010000          /* Drive is online, heads loaded, etc */
-#define        DRY     0200            /* Drive ready */
-
-/* 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 */
-#define        WLE     04000           /* Attempt to write read-only drive */
-
-/* Bits of upof; the offset bits above are also in this register */
-#define        FMT22   010000          /* 16 bits/word, must be always set */
-
 #define        b_cylin b_resid
 
 int    up_ubinfo;              /* Information about UBA usage saved here */
 #define        b_cylin b_resid
 
 int    up_ubinfo;              /* Information about UBA usage saved here */
@@ -228,8 +164,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();
@@ -272,8 +208,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;
@@ -306,6 +242,8 @@ register unit;
        }
        if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL))
                goto done;
        }
        if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL))
                goto done;
+
+#if NUP > 1
        /*
         * Do enough of the disk address decoding to determine
         * which cylinder and sector the request is on.
        /*
         * Do enough of the disk address decoding to determine
         * which cylinder and sector the request is on.
@@ -341,12 +279,13 @@ 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]++;
        }
        goto out;
                dk_busy |= 1<<unit;
                dk_seek[unit]++;
        }
        goto out;
+#endif
 
 done:
        /*
 
 done:
        /*
@@ -424,7 +363,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");
@@ -433,7 +372,7 @@ loop:
         * 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 && (bp->b_flags&B_WRITE) == 0) {
+       if (uptab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) {
                upaddr->upof = up_offset[uptab.b_errcnt & 017] | FMT22;
                upaddr->upcs1 = IE|OFFSET|GO;
                while (upaddr->upds & PIP)
                upaddr->upof = up_offset[uptab.b_errcnt & 017] | FMT22;
                upaddr->upcs1 = IE|OFFSET|GO;
                while (upaddr->upds & PIP)
@@ -456,13 +395,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;
@@ -509,8 +448,8 @@ 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)) {
@@ -600,7 +539,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;
@@ -740,7 +679,7 @@ upreset()
        uptab.b_actf = uptab.b_actl = 0;
        if (up_ubinfo) {
                printf("<%d>", (up_ubinfo>>28)&0xf);
        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++) {
@@ -777,5 +716,90 @@ active:
                printf("\n");
        }
 }
                printf("\n");
        }
 }
+
+#define        DBSIZE  20
+
+updump(dev)
+       dev_t dev;
+{
+       struct device *upaddr;
+       char *start;
+       int num, blk, unit, nsect, ntrak, nspc;
+       struct size *sizes;
+#if VAX==780
+       register struct uba_regs *up = (struct uba_regs *)PHYSUBA0;
+       register short *rp;
+       int bdp;
+
+       up->uba_cr = ADINIT;
+       up->uba_cr = IFS|BRIE|USEFIE|SUEFIE;
+       while ((up->uba_cnfgr & UBIC) == 0)
+               ;
 #endif
 #endif
+       DELAY(1000000);
+       while ((UPADDR->upcs1&DVA) == 0)
+               ;
+       num = maxfree;
+       start = 0;
+       unit = minor(dev) >> 3;
+       if (unit >= NUP) {
+               printf("bad unit\n");
+               return (-1);
+       }
+       upaddr = UPPHYS;
+       upaddr->upcs2 = unit;
+       if ((upaddr->upds & VV) == 0) {
+               upaddr->upcs1 = DCLR|GO;
+               upaddr->upcs1 = PRESET|GO;
+               upaddr->upof = FMT22;
+       }
+       if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) {
+               printf("up !DPR || !MOL\n");
+               return (-1);
+       }
+       nsect = NSECT; ntrak = NTRAC; sizes = up_sizes;
+       if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) {
+               printf("dumplo+num, sizes %d %d\n", dumplo+num, sizes[minor(dev)&07].nblocks);
+               return (-1);
+       }
+       nspc = nsect * ntrak;
+       while (num > 0) {
+               register struct pte *io;
+               register int i;
+               int cn, sn, tn;
+               daddr_t bn;
+
+               blk = num > DBSIZE ? DBSIZE : num;
+               bdp = 1;                /* trick pcc */
+               ((struct uba_regs *)PHYSUBA0)->uba_dpr[bdp] |= BNE;
+               io = ((struct uba_regs *)PHYSUBA0)->uba_map;
+               for (i = 0; i < blk; i++)
+                       *(int *)io++ = (btop(start)+i) | (1<<21) | MRV;
+               *(int *)io = 0;
+               bn = dumplo + btop(start);
+               cn = bn/nspc + sizes[minor(dev)&07].cyloff;
+               sn = bn%nspc;
+               tn = sn/nsect;
+               sn = sn%nsect;
+               upaddr->updc = cn;
+               rp = (short *) &upaddr->upda;
+               *rp = (tn << 8) + sn;
+               *--rp = 0;
+               *--rp = -blk*NBPG / sizeof (short);
+               *--rp = GO|WCOM;
+               do {
+                       DELAY(25);
+               } while ((upaddr->upcs1 & RDY) == 0);
+               if (upaddr->upcs1&ERR) {
+                       printf("up dump dsk err: (%d,%d,%d) cs1=%x, er1=%x\n",
+                           cn, tn, sn, upaddr->upcs1, upaddr->uper1);
+                       return (-1);
+               }
+               start += blk*NBPG;
+               num -= blk;
+       }
+       bdp = 1;                /* crud to fool c compiler */
+       ((struct uba_regs *)PHYSUBA0)->uba_dpr[bdp] |= BNE;
+       return (0);
+}
 #endif
 #endif