minor typos
[unix-history] / usr / src / sys / vax / uba / up.c
index 5ac11b0..8d4c658 100644 (file)
@@ -1,7 +1,7 @@
-/*     up.c    4.15    81/02/16        */
+/*     up.c    4.21    81/02/23        */
 
 #include "up.h"
 
 #include "up.h"
-#if NSC21 > 0
+#if NSC > 0
 /*
  * UNIBUS disk driver with overlapped seeks and ECC recovery.
  */
 /*
  * UNIBUS disk driver with overlapped seeks and ECC recovery.
  */
 #include "../h/pte.h"
 #include "../h/mba.h"
 #include "../h/mtpr.h"
 #include "../h/pte.h"
 #include "../h/mba.h"
 #include "../h/mtpr.h"
-#include "../h/uba.h"
 #include "../h/vm.h"
 #include "../h/vm.h"
+#include "../h/uba.h"
 #include "../h/cmap.h"
 
 #include "../h/upreg.h"
 
 struct up_softc {
        int     sc_softas;
 #include "../h/cmap.h"
 
 #include "../h/upreg.h"
 
 struct up_softc {
        int     sc_softas;
-       int     sc_seek;
-       int     sc_info;
+       int     sc_ndrive;
        int     sc_wticks;
        int     sc_wticks;
-       /* struct uba_minfo sc_minfo; */
-} up_softc[NSC21];
+} up_softc[NSC];
 
 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
 struct size
 
 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
 struct size
@@ -66,13 +64,14 @@ struct      size
 int    upSDIST = _upSDIST;
 int    upRDIST = _upRDIST;
 
 int    upSDIST = _upSDIST;
 int    upRDIST = _upRDIST;
 
-int    upcntrlr(), upslave(), updgo(), upintr();
-struct uba_minfo *upminfo[NSC21];
+int    upprobe(), upslave(), upattach(), updgo(), upintr();
+struct uba_minfo *upminfo[NSC];
 struct uba_dinfo *updinfo[NUP];
 struct uba_dinfo *updinfo[NUP];
+struct uba_dinfo *upip[NSC][4];
 
 
-u_short        upstd[] = { 0776700, 0774400, 0776300 };
-struct uba_driver updriver =
-       { upcntrlr, upslave, updgo, 0, upstd, "up", updinfo, upminfo };
+u_short        upstd[] = { 0776700, 0774400, 0776300, 0 };
+struct uba_driver scdriver =
+    { upprobe, upslave, upattach, updgo, upstd, "up", updinfo, "sc", upminfo };
 struct buf     uputab[NUP];
 
 struct upst {
 struct buf     uputab[NUP];
 
 struct upst {
@@ -82,20 +81,17 @@ struct      upst {
        short   ncyl;
        struct  size *sizes;
 } upst[] = {
        short   ncyl;
        struct  size *sizes;
 } upst[] = {
-       32,     19,     32*19,  815,    up_sizes,       /* 9300 */
-       32,     19,     32*19,  823,    up_sizes,       /* so cdc will boot */
+       32,     19,     32*19,  823,    up_sizes,       /* 9300/cdc */
+/* 9300 actually has 815 cylinders... */
        32,     10,     32*10,  823,    fj_sizes,       /* fujitsu 160m */
 };
 
        32,     10,     32*10,  823,    fj_sizes,       /* fujitsu 160m */
 };
 
-int    up_offset[16] =
-{
-       P400, M400, P400, M400,
-       P800, M800, P800, M800,
-       P1200, M1200, P1200, M1200,
-       0, 0, 0, 0,
+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
 };
 
 };
 
-struct buf     rupbuf;                 /* GROT */
+struct buf     rupbuf[NUP];
 
 #define        b_cylin b_resid
 
 
 #define        b_cylin b_resid
 
@@ -104,53 +100,75 @@ daddr_t dkblock();
 #endif
 
 int    upwstart, upwatch();            /* Have started guardian */
 #endif
 
 int    upwstart, upwatch();            /* Have started guardian */
+int    upseek;
 
 /*ARGSUSED*/
 
 /*ARGSUSED*/
-upcntrlr(um, reg)
-       struct uba_minfo *um;
+upprobe(reg)
        caddr_t reg;
 {
        register int br, cvec;
 
        caddr_t reg;
 {
        register int br, cvec;
 
-       ((struct device *)reg)->upcs1 |= (IE|RDY);
+#ifdef lint    
+       br = 0; cvec = br; br = cvec;
+#endif
+       ((struct updevice *)reg)->upcs1 = UP_IE|UP_RDY;
+       DELAY(10);
+       ((struct updevice *)reg)->upcs1 = 0;
        return (1);
 }
 
        return (1);
 }
 
-upslave(ui, reg, slaveno)
+upslave(ui, reg)
        struct uba_dinfo *ui;
        caddr_t reg;
 {
        struct uba_dinfo *ui;
        caddr_t reg;
 {
-       register struct device *upaddr = (struct device *)reg;
+       register struct updevice *upaddr = (struct updevice *)reg;
 
        upaddr->upcs1 = 0;              /* conservative */
 
        upaddr->upcs1 = 0;              /* conservative */
-       upaddr->upcs2 = slaveno;
-       if (upaddr->upcs2&NED) {
-               upaddr->upcs1 = DCLR|GO;
+       upaddr->upcs2 = ui->ui_slave;
+       if (upaddr->upcs2&UP_NED) {
+               upaddr->upcs1 = UP_DCLR|UP_GO;
                return (0);
        }
                return (0);
        }
+       return (1);
+}
+
+upattach(ui)
+       register struct uba_dinfo *ui;
+{
+#ifdef notdef
+       register struct updevice *upaddr;
+#endif
+
        if (upwstart == 0) {
                timeout(upwatch, (caddr_t)0, HZ);
                upwstart++;
        }
        if (upwstart == 0) {
                timeout(upwatch, (caddr_t)0, HZ);
                upwstart++;
        }
-       return (1);
+       if (ui->ui_dk >= 0)
+               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->uphr = -1;
+       /* ... */
+       if (upaddr-> ... == 10)
+               ui->ui_type = 1;
+#endif
 }
  
 }
  
-/*
-       dk_mspw[UPDK_N+unit] = .0000020345;
-*/
-
 upstrategy(bp)
        register struct buf *bp;
 {
        register struct uba_dinfo *ui;
 upstrategy(bp)
        register struct buf *bp;
 {
        register struct uba_dinfo *ui;
-       register struct uba_minfo *um;
        register struct upst *st;
        register int unit;
        register struct upst *st;
        register int unit;
+       register struct buf *dp;
        int xunit = minor(bp->b_dev) & 07;
        int xunit = minor(bp->b_dev) & 07;
-       long sz, bn;
+       long bn, sz;
 
 
-       sz = bp->b_bcount;
-       sz = (sz+511) >> 9;             /* transfer size in 512 byte sectors */
+       sz = (bp->b_bcount+511) >> 9;
        unit = dkunit(bp);
        if (unit >= NUP)
                goto bad;
        unit = dkunit(bp);
        if (unit >= NUP)
                goto bad;
@@ -163,8 +181,9 @@ upstrategy(bp)
                goto bad;
        bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
        (void) spl5();
                goto bad;
        bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
        (void) spl5();
-       disksort(&uputab[ui->ui_unit], bp);
-       if (uputab[ui->ui_unit].b_active == 0) {
+       dp = &uputab[ui->ui_unit];
+       disksort(dp, bp);
+       if (dp->b_active == 0) {
                (void) upustart(ui);
                bp = &ui->ui_mi->um_tab;
                if (bp->b_actf && bp->b_active == 0)
                (void) upustart(ui);
                bp = &ui->ui_mi->um_tab;
                if (bp->b_actf && bp->b_active == 0)
@@ -184,14 +203,20 @@ upustart(ui)
 {
        register struct buf *bp, *dp;
        register struct uba_minfo *um;
 {
        register struct buf *bp, *dp;
        register struct uba_minfo *um;
-       register struct device *upaddr;
+       register struct updevice *upaddr;
        register struct upst *st;
        daddr_t bn;
        int sn, cn, csn;
        int didie = 0;
 
        register struct upst *st;
        daddr_t bn;
        int sn, cn, csn;
        int didie = 0;
 
-       /* SC21 cancels commands if you say cs1 = IE, so dont */
-       /* being ultra-cautious, we clear as bits only in upintr() */
+       if (ui == 0)
+               return (0);
+       /*
+        * The SC21 cancels commands if you just say
+        *      cs1 = UP_IE
+        * so we are cautious about handling of cs1.
+        * Also don't bother to clear as bits other than in upintr().
+        */
        dk_busy &= ~(1<<ui->ui_dk);
        dp = &uputab[ui->ui_unit];
        if ((bp = dp->b_actf) == NULL)
        dk_busy &= ~(1<<ui->ui_dk);
        dp = &uputab[ui->ui_unit];
        if ((bp = dp->b_actf) == NULL)
@@ -205,15 +230,18 @@ upustart(ui)
        if (dp->b_active)
                goto done;
        dp->b_active = 1;
        if (dp->b_active)
                goto done;
        dp->b_active = 1;
-       upaddr = (struct device *)um->um_addr;
+       upaddr = (struct updevice *)um->um_addr;
        upaddr->upcs2 = ui->ui_slave;
        upaddr->upcs2 = ui->ui_slave;
-       if ((upaddr->upds & VV) == 0) {
-               upaddr->upcs1 = IE|DCLR|GO;
-               upaddr->upcs1 = IE|PRESET|GO;
-               upaddr->upof = FMT22;
+       if ((upaddr->upds & UP_VV) == 0) {
+               /* 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;
                didie = 1;
        }
                didie = 1;
        }
-       if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL))
+       if ((upaddr->upds & (UP_DPR|UP_MOL)) != (UP_DPR|UP_MOL))
+               goto done;
+       if (up_softc[um->um_ctlr].sc_ndrive == 1)
                goto done;
        st = &upst[ui->ui_type];
        bn = dkblock(bp);
                goto done;
        st = &upst[ui->ui_type];
        bn = dkblock(bp);
@@ -222,7 +250,6 @@ upustart(ui)
        sn = (sn + st->nsect - upSDIST) % st->nsect;
        if (cn - upaddr->updc)
                goto search;            /* Not on-cylinder */
        sn = (sn + st->nsect - upSDIST) % st->nsect;
        if (cn - upaddr->updc)
                goto search;            /* Not on-cylinder */
-/****                          WHAT SHOULD THIS BE NOW ???
        else if (upseek)
                goto done;              /* Ok just to be on-cylinder */
        csn = (upaddr->upla>>6) - sn - 1;
        else if (upseek)
                goto done;              /* Ok just to be on-cylinder */
        csn = (upaddr->upla>>6) - sn - 1;
@@ -232,12 +259,11 @@ upustart(ui)
                goto done;
 search:
        upaddr->updc = cn;
                goto done;
 search:
        upaddr->updc = cn;
-/***                           ANOTHER OCCURRENCE
        if (upseek)
        if (upseek)
-               upaddr->upcs1 = IE|SEEK|GO;
-       else  ****/   {
+               upaddr->upcs1 = UP_IE|UP_SEEK|UP_GO;
+       else {
                upaddr->upda = sn;
                upaddr->upda = sn;
-               upaddr->upcs1 = IE|SEARCH|GO;
+               upaddr->upcs1 = UP_IE|UP_SEARCH|UP_GO;
        }
        didie = 1;
        if (ui->ui_dk >= 0) {
        }
        didie = 1;
        if (ui->ui_dk >= 0) {
@@ -246,12 +272,15 @@ search:
        }
        goto out;
 done:
        }
        goto out;
 done:
-       dp->b_forw = NULL;
-       if (um->um_tab.b_actf == NULL)
-               um->um_tab.b_actf = dp;
-       else
-               um->um_tab.b_actl->b_forw = dp;
-       um->um_tab.b_actl = dp;
+       if (dp->b_active != 2) {
+               dp->b_forw = NULL;
+               if (um->um_tab.b_actf == NULL)
+                       um->um_tab.b_actf = dp;
+               else
+                       um->um_tab.b_actl->b_forw = dp;
+               um->um_tab.b_actl = dp;
+               dp->b_active = 2;
+       }
 out:
        return (didie);
 }
 out:
        return (didie);
 }
@@ -261,9 +290,8 @@ upstart(um)
 {
        register struct buf *bp, *dp;
        register struct uba_dinfo *ui;
 {
        register struct buf *bp, *dp;
        register struct uba_dinfo *ui;
-       register unit;
-       register struct device *upaddr;
-       register struct upst *st;
+       register struct updevice *upaddr;
+       struct upst *st;
        daddr_t bn;
        int dn, sn, tn, cmd;
 
        daddr_t bn;
        int dn, sn, tn, cmd;
 
@@ -274,10 +302,6 @@ loop:
                um->um_tab.b_actf = dp->b_forw;
                goto loop;
        }
                um->um_tab.b_actf = dp->b_forw;
                goto loop;
        }
-       /*
-        * Mark the controller busy, and multi-part disk address.
-        * Select the unit on which the i/o is to take place.
-        */
        um->um_tab.b_active++;
        ui = updinfo[dkunit(bp)];
        bn = dkblock(bp);
        um->um_tab.b_active++;
        ui = updinfo[dkunit(bp)];
        bn = dkblock(bp);
@@ -286,115 +310,78 @@ loop:
        sn = bn%st->nspc;
        tn = sn/st->nsect;
        sn %= st->nsect;
        sn = bn%st->nspc;
        tn = sn/st->nsect;
        sn %= st->nsect;
-       upaddr = (struct device *)ui->ui_addr;
-       if ((upaddr->upcs2 & 07) != dn)
-               upaddr->upcs2 = dn;
-       up_softc[um->um_ctlr].sc_info =
-           ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP|UBA_CANTWAIT);
-       /*
-        * If drive is not present and on-line, then
-        * get rid of this with an error and loop to get
-        * rid of the rest of its queued requests.
-        * (Then on to any other ready drives.)
-        */
-       if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) {
-               printf("!DPR || !MOL, unit %d, ds %o", dn, upaddr->upds);
-               if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) {
-                       printf("-- hard\n");
+       upaddr = (struct updevice *)ui->ui_addr;
+       upaddr->upcs2 = dn;
+       if ((upaddr->upds & (UP_DPR|UP_MOL)) != (UP_DPR|UP_MOL)) {
+               printf("up%d not ready", dkunit(bp));
+               if ((upaddr->upds & (UP_DPR|UP_MOL)) != (UP_DPR|UP_MOL)) {
+                       printf("\n");
                        um->um_tab.b_active = 0;
                        um->um_tab.b_errcnt = 0;
                        dp->b_actf = bp->av_forw;
                        dp->b_active = 0;
                        bp->b_flags |= B_ERROR;
                        iodone(bp);
                        um->um_tab.b_active = 0;
                        um->um_tab.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 ... */
-                       ubarelse(ui->ui_ubanum, &up_softc[um->um_ctlr].sc_info);
                        goto loop;
                }
                        goto loop;
                }
-               printf("-- came back\n");
+               printf(" (flakey)\n");
        }
        }
-       /*
-        * If this is a retry, then with the 16'th retry we
-        * begin to try offsetting the heads to recover the data.
-        */
        if (um->um_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) {
        if (um->um_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) {
-               upaddr->upof = up_offset[um->um_tab.b_errcnt & 017] | FMT22;
-               upaddr->upcs1 = IE|OFFSET|GO;
-               while (upaddr->upds & PIP)
+               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);
        }
                        DELAY(25);
        }
-       /*
-        * Now set up the transfer, retrieving the high
-        * 2 bits of the UNIBUS address from the information
-        * returned by ubasetup() for the cs1 register bits 8 and 9.
-        */
        upaddr->updc = bp->b_cylin;
        upaddr->upda = (tn << 8) + sn;
        upaddr->updc = bp->b_cylin;
        upaddr->upda = (tn << 8) + sn;
-       upaddr->upba = up_softc[um->um_ctlr].sc_info;
        upaddr->upwc = -bp->b_bcount / sizeof (short);
        upaddr->upwc = -bp->b_bcount / sizeof (short);
-       cmd = (up_softc[um->um_ctlr].sc_info >> 8) & 0x300;
        if (bp->b_flags & B_READ)
        if (bp->b_flags & B_READ)
-               cmd |= IE|RCOM|GO;
+               cmd = UP_IE|UP_RCOM|UP_GO;
        else
        else
-               cmd |= IE|WCOM|GO;
-       upaddr->upcs1 = cmd;
-       /*
-        * This is a controller busy situation.
-        * 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).
-        */
-       unit = ui->ui_dk;
-       dk_busy |= 1<<unit;
-       dk_xfer[unit]++;
-       dk_wds[unit] += bp->b_bcount>>6;
+               cmd = UP_IE|UP_WCOM|UP_GO;
+       um->um_cmd = cmd;
+       ubago(ui);
        return (1);
 }
 
        return (1);
 }
 
-updgo()
+updgo(um)
+       struct uba_minfo *um;
 {
 {
+       register struct updevice *upaddr = (struct updevice *)um->um_addr;
+
+       upaddr->upba = um->um_ubinfo;
+       upaddr->upcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300);
 }
 
 }
 
-/*
- * Handle a device interrupt.
- *
- * If the transferring drive needs attention, service it
- * retrying on error or beginning next transfer.
- * Service all other ready drives, calling ustart to transfer
- * their blocks to the ready queue in um->um_tab, and then restart
- * the controller if there is anything to do.
- */
-upintr(sc21)
+scintr(sc21)
        register sc21;
 {
        register struct buf *bp, *dp;
        register struct uba_minfo *um = upminfo[sc21];
        register struct uba_dinfo *ui;
        register sc21;
 {
        register struct buf *bp, *dp;
        register struct uba_minfo *um = upminfo[sc21];
        register struct uba_dinfo *ui;
-       register struct device *upaddr = (struct device *)um->um_addr;
+       register struct updevice *upaddr = (struct updevice *)um->um_addr;
        register unit;
        register unit;
-       int as = upaddr->upas & 0377;
+       struct up_softc *sc = &up_softc[um->um_ctlr];
+       int as = (upaddr->upas & 0377) | sc->sc_softas;
        int needie = 1;
 
        int needie = 1;
 
-       (void) spl6();
-       up_softc[um->um_ctlr].sc_wticks = 0;
+       sc->sc_wticks = 0;
+       sc->sc_softas = 0;
        if (um->um_tab.b_active) {
        if (um->um_tab.b_active) {
-               if ((upaddr->upcs1 & RDY) == 0) {
-                       printf("!RDY: cs1 %o, ds %o, wc %d\n", upaddr->upcs1,
-                           upaddr->upds, upaddr->upwc);
-                       printf("as=%d act %d %d %d\n", as, um->um_tab.b_active,
-                           uputab[0].b_active, uputab[1].b_active);
-               }
+               if ((upaddr->upcs1 & UP_RDY) == 0)
+                       printf("upintr !RDY\n");
                dp = um->um_tab.b_actf;
                bp = dp->b_actf;
                ui = updinfo[dkunit(bp)];
                dk_busy &= ~(1 << ui->ui_dk);
                upaddr->upcs2 = ui->ui_slave;
                dp = um->um_tab.b_actf;
                bp = dp->b_actf;
                ui = updinfo[dkunit(bp)];
                dk_busy &= ~(1 << ui->ui_dk);
                upaddr->upcs2 = ui->ui_slave;
-               if ((upaddr->upds&ERR) || (upaddr->upcs1&TRE)) {
+               if ((upaddr->upds&UP_ERR) || (upaddr->upcs1&UP_TRE)) {
                        int cs2;
                        int cs2;
-                       while ((upaddr->upds & DRY) == 0)
+                       while ((upaddr->upds & UP_DRY) == 0)
                                DELAY(25);
                                DELAY(25);
-                       if (++um->um_tab.b_errcnt > 28 || upaddr->uper1&WLE)
+                       if (upaddr->uper1&UP_WLE)       
+                               printf("up%d is write locked\n", dkunit(bp));
+                       if (++um->um_tab.b_errcnt > 28 || upaddr->uper1&UP_WLE)
                                bp->b_flags |= B_ERROR;
                        else
                                um->um_tab.b_active = 0; /* force retry */
                                bp->b_flags |= B_ERROR;
                        else
                                um->um_tab.b_active = 0; /* force retry */
@@ -402,25 +389,27 @@ upintr(sc21)
                                cs2 = (int)upaddr->upcs2;
                                deverror(bp, cs2, (int)upaddr->uper1);
                        }
                                cs2 = (int)upaddr->upcs2;
                                deverror(bp, cs2, (int)upaddr->uper1);
                        }
-                       if ((upaddr->uper1&(DCK|ECH))==DCK && upecc(ui))
-                               return;
-                       upaddr->upcs1 = TRE|IE|DCLR|GO;
+                       if ((upaddr->uper1&(UP_DCK|UP_ECH))==UP_DCK)
+                               if (upecc(ui))
+                                       return;
+                       upaddr->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO;
                        needie = 0;
                        if ((um->um_tab.b_errcnt&07) == 4) {
                        needie = 0;
                        if ((um->um_tab.b_errcnt&07) == 4) {
-                               upaddr->upcs1 = RECAL|GO|IE;
-                               while(upaddr->upds & PIP)
+                               upaddr->upcs1 = UP_RECAL|UP_IE|UP_GO;
+                               while(upaddr->upds & UP_PIP)
                                        DELAY(25);
                        }
                                        DELAY(25);
                        }
-                       if (um->um_tab.b_errcnt == 28 && cs2&(NEM|MXF)) {
+                       if (um->um_tab.b_errcnt == 28 && cs2&(UP_NEM|UP_MXF)) {
                                printf("FLAKEY UP ");
                                ubareset(um->um_ubanum);
                                return;
                        }
                }
                                printf("FLAKEY UP ");
                                ubareset(um->um_ubanum);
                                return;
                        }
                }
+               ubadone(um);
                if (um->um_tab.b_active) {
                        if (um->um_tab.b_errcnt >= 16) {
                if (um->um_tab.b_active) {
                        if (um->um_tab.b_errcnt >= 16) {
-                               upaddr->upcs1 = RTC|GO|IE;
-                               while (upaddr->upds & PIP)
+                               upaddr->upcs1 = UP_RTC|UP_GO|UP_IE;
+                               while (upaddr->upds & UP_PIP)
                                        DELAY(25);
                                needie = 0;
                        }
                                        DELAY(25);
                                needie = 0;
                        }
@@ -431,47 +420,49 @@ upintr(sc21)
                        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 (bp->b_resid)
-                               printf("resid %d ds %o er? %o %o %o\n",
-                                   bp->b_resid, upaddr->upds,
-                                   upaddr->uper1, upaddr->uper2, upaddr->uper3);
                        iodone(bp);
                        if (dp->b_actf)
                                if (upustart(ui))
                                        needie = 0;
                }
                        iodone(bp);
                        if (dp->b_actf)
                                if (upustart(ui))
                                        needie = 0;
                }
-               up_softc[um->um_ctlr].sc_softas &= ~(1<<ui->ui_slave);
-               ubarelse(ui->ui_ubanum, &up_softc[um->um_ctlr].sc_info);
+               as &= ~(1<<ui->ui_slave);
        } else {
        } else {
-               if (upaddr->upcs1 & TRE)
-                       upaddr->upcs1 = TRE;
+               if (upaddr->upcs1 & UP_TRE)
+                       upaddr->upcs1 = UP_TRE;
        }
        }
-       as |= up_softc[um->um_ctlr].sc_softas;
-       for (unit = 0; unit < NUP; unit++) {
-               if ((ui = updinfo[unit]) == 0 || ui->ui_mi != um)
-                       continue;
-               if (as & (1<<unit)) {
-                       if (as & (1<<unit))
-                               upaddr->upas = 1<<unit;
-                       if (upustart(ui))
+       for (unit = 0; as; as >>= 1, unit++)
+               if (as & 1) {
+                       upaddr->upas = 1<<unit;
+                       if (upustart(upip[sc21][unit]))
                                needie = 0;
                }
                                needie = 0;
                }
-       }
        if (um->um_tab.b_actf && um->um_tab.b_active == 0)
                if (upstart(um))
                        needie = 0;
        if (needie)
        if (um->um_tab.b_actf && um->um_tab.b_active == 0)
                if (upstart(um))
                        needie = 0;
        if (needie)
-               upaddr->upcs1 = IE;
+               upaddr->upcs1 = UP_IE;
 }
 
 upread(dev)
 }
 
 upread(dev)
+       dev_t dev;
 {
 {
-       physio(upstrategy, &rupbuf, dev, B_READ, minphys);
+       register int unit = minor(dev) >> 3;
+
+       if (unit >= NUP)
+               u.u_error = ENXIO;
+       else
+               physio(upstrategy, &rupbuf[unit], dev, B_READ, minphys);
 }
 
 upwrite(dev)
 }
 
 upwrite(dev)
+       dev_t dev;
 {
 {
-       physio(upstrategy, &rupbuf, dev, B_WRITE, minphys);
+       register int unit = minor(dev) >> 3;
+
+       if (unit >= NUP)
+               u.u_error = ENXIO;
+       else
+               physio(upstrategy, &rupbuf[unit], dev, B_WRITE, minphys);
 }
 
 /*
 }
 
 /*
@@ -483,7 +474,7 @@ upwrite(dev)
 upecc(ui)
        register struct uba_dinfo *ui;
 {
 upecc(ui)
        register struct uba_dinfo *ui;
 {
-       register struct device *up = (struct device *)ui->ui_addr;
+       register struct updevice *up = (struct updevice *)ui->ui_addr;
        register struct buf *bp = uputab[ui->ui_unit].b_actf;
        register struct uba_minfo *um = ui->ui_mi;
        register struct upst *st;
        register struct buf *bp = uputab[ui->ui_unit].b_actf;
        register struct uba_minfo *um = ui->ui_mi;
        register struct upst *st;
@@ -500,13 +491,13 @@ upecc(ui)
         * O is offset within a memory page of the first byte transferred.
         */
        npf = btop((up->upwc * sizeof(short)) + bp->b_bcount) - 1;
         * O is offset within a memory page of the first byte transferred.
         */
        npf = btop((up->upwc * sizeof(short)) + bp->b_bcount) - 1;
-       reg = btop(up_softc[um->um_ctlr].sc_info&0x3ffff) + npf;
+       reg = btop(um->um_ubinfo&0x3ffff) + npf;
        o = (int)bp->b_un.b_addr & PGOFSET;
        printf("%D ", bp->b_blkno+npf);
        prdev("ECC", bp->b_dev);
        mask = up->upec2;
        if (mask == 0) {
        o = (int)bp->b_un.b_addr & PGOFSET;
        printf("%D ", bp->b_blkno+npf);
        prdev("ECC", bp->b_dev);
        mask = up->upec2;
        if (mask == 0) {
-               up->upof = FMT22;               /* == RTC ???? */
+               up->upof = UP_FMT22;            /* == RTC ???? */
                return (0);
        }
        /*
                return (0);
        }
        /*
@@ -515,7 +506,7 @@ upecc(ui)
         * is the byte offset in the transfer, the variable byte
         * is the offset from a page boundary in main memory.
         */
         * is the byte offset in the transfer, the variable byte
         * is the offset from a page boundary in main memory.
         */
-       ubp->uba_dpr[(up_softc[um->um_ctlr].sc_info>>28)&0x0f] |= UBA_BNE;
+       ubp->uba_dpr[(um->um_ubinfo>>28)&0x0f] |= UBA_BNE;
        i = up->upec1 - 1;              /* -1 makes 0 origin */
        bit = i&07;
        i = (i&~07)>>3;
        i = up->upec1 - 1;              /* -1 makes 0 origin */
        bit = i&07;
        i = (i&~07)>>3;
@@ -543,7 +534,11 @@ upecc(ui)
         * We have completed npf+1 sectors of the transfer already;
         * restart at offset o of next sector (i.e. in UBA register reg+1).
         */
         * We have completed npf+1 sectors of the transfer already;
         * restart at offset o of next sector (i.e. in UBA register reg+1).
         */
-       up->upcs1 = TRE|IE|DCLR|GO;
+#ifdef notdef
+       up->uper1 = 0;
+       up->upcs1 |= UP_GO;
+#else
+       up->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO;
        bn = dkblock(bp);
        st = &upst[ui->ui_type];
        cn = bp->b_cylin;
        bn = dkblock(bp);
        st = &upst[ui->ui_type];
        cn = bp->b_cylin;
@@ -557,8 +552,9 @@ upecc(ui)
        ubaddr = (int)ptob(reg+1) + o;
        up->upba = ubaddr;
        cmd = (ubaddr >> 8) & 0x300;
        ubaddr = (int)ptob(reg+1) + o;
        up->upba = ubaddr;
        cmd = (ubaddr >> 8) & 0x300;
-       cmd |= IE|GO|RCOM;
+       cmd |= UP_IE|UP_GO|UP_RCOM;
        up->upcs1 = cmd;
        up->upcs1 = cmd;
+#endif
        return (1);
 }
 
        return (1);
 }
 
@@ -574,25 +570,22 @@ upreset(uban)
        register sc21, unit;
        int any = 0;
 
        register sc21, unit;
        int any = 0;
 
-       for (sc21 = 0; sc21 < NSC21; sc21++) {
-               if ((um = upminfo[sc21]) == 0)
-                       continue;
-               if (um->um_ubanum != uban)
-                       continue;
-               if (!um->um_alive)
+       for (sc21 = 0; sc21 < NSC; sc21++) {
+               if ((um = upminfo[sc21]) == 0 || um->um_ubanum != uban ||
+                   um->um_alive == 0)
                        continue;
                if (any == 0) {
                        printf(" up");
                        continue;
                if (any == 0) {
                        printf(" up");
-                       DELAY(15000000);        /* give it time to self-test */
+                       DELAY(10000000);        /* give it time to self-test */
                        any++;
                }
                um->um_tab.b_active = 0;
                um->um_tab.b_actf = um->um_tab.b_actl = 0;
                        any++;
                }
                um->um_tab.b_active = 0;
                um->um_tab.b_actf = um->um_tab.b_actl = 0;
-               if (up_softc[um->um_ctlr].sc_info) {
-                       printf("<%d>", (up_softc[um->um_ctlr].sc_info>>28)&0xf);
-                       ubarelse(um->um_ubanum, &up_softc[um->um_ctlr].sc_info);
+               if (um->um_ubinfo) {
+                       printf("<%d>", (um->um_ubinfo>>28)&0xf);
+                       ubadone(um);
                }
                }
-               ((struct device *)(um->um_addr))->upcs2 = CLR;
+               ((struct updevice *)(um->um_addr))->upcs2 = UP_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;
@@ -615,25 +608,28 @@ upwatch()
 {
        register struct uba_minfo *um;
        register sc21, unit;
 {
        register struct uba_minfo *um;
        register sc21, unit;
+       register struct up_softc *sc;
 
        timeout(upwatch, (caddr_t)0, HZ);
 
        timeout(upwatch, (caddr_t)0, HZ);
-       for (sc21 = 0; sc21 < NSC21; sc21++) {
+       for (sc21 = 0; sc21 < NSC; sc21++) {
                um = upminfo[sc21];
                um = upminfo[sc21];
+               if (um == 0 || um->um_alive == 0)
+                       continue;
+               sc = &up_softc[sc21];
                if (um->um_tab.b_active == 0) {
                        for (unit = 0; unit < NUP; unit++)
                if (um->um_tab.b_active == 0) {
                        for (unit = 0; unit < NUP; unit++)
-                               if (updinfo[unit]->ui_mi == um &&
-                                   uputab[unit].b_active)
+                               if (uputab[unit].b_active &&
+                                   updinfo[unit]->ui_mi == um)
                                        goto active;
                                        goto active;
-                       up_softc[sc21].sc_wticks = 0;
+                       sc->sc_wticks = 0;
                        continue;
                }
     active:
                        continue;
                }
     active:
-               up_softc[sc21].sc_wticks++;
-               if (up_softc[sc21].sc_wticks >= 20) {
-                       up_softc[sc21].sc_wticks = 0;
-                       printf("LOST INTERRUPT RESET");
-                       upreset(um->um_ubanum);
-                       printf("\n");
+               sc->sc_wticks++;
+               if (sc->sc_wticks >= 20) {
+                       sc->sc_wticks = 0;
+                       printf("LOST upintr ");
+                       ubareset(um->um_ubanum);
                }
        }
 }
                }
        }
 }
@@ -643,9 +639,9 @@ upwatch()
 updump(dev)
        dev_t dev;
 {
 updump(dev)
        dev_t dev;
 {
-       struct device *upaddr;
+       struct updevice *upaddr;
        char *start;
        char *start;
-       int num, blk, unit, nsect, ntrak, nspc;
+       int num, blk, unit;
        struct size *sizes;
        register struct uba_regs *uba;
        register struct uba_dinfo *ui;
        struct size *sizes;
        register struct uba_regs *uba;
        register struct uba_dinfo *ui;
@@ -657,8 +653,7 @@ updump(dev)
                printf("bad unit\n");
                return (-1);
        }
                printf("bad unit\n");
                return (-1);
        }
-#define        phys1(cast, addr) ((cast)((int)addr & 0x7fffffff))
-#define        phys(cast, addr) phys1(cast, phys1(cast *, &addr))
+#define        phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
        ui = phys(struct uba_dinfo *, updinfo[unit]);
        if (ui->ui_alive == 0) {
                printf("dna\n");
        ui = phys(struct uba_dinfo *, updinfo[unit]);
        if (ui->ui_alive == 0) {
                printf("dna\n");
@@ -666,38 +661,31 @@ updump(dev)
        }
        uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
 #if VAX780
        }
        uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
 #if VAX780
-       if (cpu == VAX_780) {
-               uba->uba_cr = UBA_ADINIT;
-               uba->uba_cr = UBA_IFS|UBA_BRIE|UBA_USEFIE|UBA_SUEFIE;
-               while ((uba->uba_cnfgr & UBA_UBIC) == 0)
-                       ;
-       }
+       if (cpu == VAX_780)
+               ubainit(uba);
 #endif
        DELAY(1000000);
 #endif
        DELAY(1000000);
-       upaddr = (struct device *)ui->ui_physaddr;
-       while ((upaddr->upcs1&DVA) == 0)
+       upaddr = (struct updevice *)ui->ui_physaddr;
+       while ((upaddr->upcs1&UP_DVA) == 0)
                ;
        num = maxfree;
        start = 0;
        upaddr->upcs2 = unit;
                ;
        num = maxfree;
        start = 0;
        upaddr->upcs2 = unit;
-       if ((upaddr->upds & VV) == 0) {
-               upaddr->upcs1 = DCLR|GO;
-               upaddr->upcs1 = PRESET|GO;
-               upaddr->upof = FMT22;
+       if ((upaddr->upds & UP_VV) == 0) {
+               upaddr->upcs1 = UP_DCLR|UP_GO;
+               upaddr->upcs1 = UP_PRESET|UP_GO;
+               upaddr->upof = UP_FMT22;
        }
        }
-       if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) {
-               printf("up !DPR || !MOL\n");
+       if ((upaddr->upds & (UP_DPR|UP_MOL)) != (UP_DPR|UP_MOL)) {
+               printf("dna\n");
                return (-1);
        }
                return (-1);
        }
-       st = phys1(struct upst *, &upst[ui->ui_type]);
-       nsect = st->nsect;
-       ntrak = st->ntrak;
+       st = &upst[ui->ui_type];
        sizes = phys(struct size *, st->sizes);
        if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) {
                printf("oor\n");
                return (-1);
        }
        sizes = phys(struct size *, st->sizes);
        if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) {
                printf("oor\n");
                return (-1);
        }
-       nspc = st->nspc;
        while (num > 0) {
                register struct pte *io;
                register int i;
        while (num > 0) {
                register struct pte *io;
                register int i;
@@ -710,20 +698,20 @@ updump(dev)
                        *(int *)io++ = (btop(start)+i) | (1<<21) | UBA_MRV;
                *(int *)io = 0;
                bn = dumplo + btop(start);
                        *(int *)io++ = (btop(start)+i) | (1<<21) | UBA_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;
+               cn = bn/st->nspc + sizes[minor(dev)&07].cyloff;
+               sn = bn%st->nspc;
+               tn = sn/st->nsect;
+               sn = sn%st->nsect;
                upaddr->updc = cn;
                rp = (short *) &upaddr->upda;
                *rp = (tn << 8) + sn;
                *--rp = 0;
                *--rp = -blk*NBPG / sizeof (short);
                upaddr->updc = cn;
                rp = (short *) &upaddr->upda;
                *rp = (tn << 8) + sn;
                *--rp = 0;
                *--rp = -blk*NBPG / sizeof (short);
-               *--rp = GO|WCOM;
+               *--rp = UP_GO|UP_WCOM;
                do {
                        DELAY(25);
                do {
                        DELAY(25);
-               } while ((upaddr->upcs1 & RDY) == 0);
-               if (upaddr->upcs1&ERR) {
+               } while ((upaddr->upcs1 & UP_RDY) == 0);
+               if (upaddr->upcs1&UP_ERR) {
                        printf("up dump dsk err: (%d,%d,%d) cs1=%x, er1=%x\n",
                            cn, tn, sn, upaddr->upcs1, upaddr->uper1);
                        return (-1);
                        printf("up dump dsk err: (%d,%d,%d) cs1=%x, er1=%x\n",
                            cn, tn, sn, upaddr->upcs1, upaddr->uper1);
                        return (-1);