compilable first uba autoconf version
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Wed, 11 Feb 1981 05:20:01 +0000 (21:20 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Wed, 11 Feb 1981 05:20:01 +0000 (21:20 -0800)
SCCS-vsn: sys/vax/mba/hp.c 4.8
SCCS-vsn: sys/vax/uba/dh.c 4.13
SCCS-vsn: sys/vax/uba/dz.c 4.10
SCCS-vsn: sys/vax/uba/uba.c 4.7
SCCS-vsn: sys/vax/uba/up.c 4.13
SCCS-vsn: sys/vax/vax/autoconf.c 4.2
SCCS-vsn: sys/vax/uba/tm.c 4.9

usr/src/sys/vax/mba/hp.c
usr/src/sys/vax/uba/dh.c
usr/src/sys/vax/uba/dz.c
usr/src/sys/vax/uba/tm.c
usr/src/sys/vax/uba/uba.c
usr/src/sys/vax/uba/up.c
usr/src/sys/vax/vax/autoconf.c

index bde97e3..9e25ff1 100644 (file)
@@ -1,4 +1,4 @@
-/*     hp.c    4.7     81/02/08        */
+/*     hp.c    4.8     81/02/10        */
 
 #include "hp.h"
 #if NHP > 0
 
 #include "hp.h"
 #if NHP > 0
@@ -121,7 +121,7 @@ hpstrategy(bp)
        if (unit >= NHP)
                goto bad;
        mi = hpinfo[unit];
        if (unit >= NHP)
                goto bad;
        mi = hpinfo[unit];
-       if (mi->mi_alive == 0)
+       if (mi == 0 || mi->mi_alive == 0)
                goto bad;
        st = &hpst[mi->mi_type];
        if (bp->b_blkno < 0 ||
                goto bad;
        st = &hpst[mi->mi_type];
        if (bp->b_blkno < 0 ||
@@ -161,17 +161,17 @@ hpustart(mi)
                return (MBU_DODATA);
        if ((hpaddr->hpds & (DPR|MOL)) != (DPR|MOL))
                return (MBU_DODATA);
                return (MBU_DODATA);
        if ((hpaddr->hpds & (DPR|MOL)) != (DPR|MOL))
                return (MBU_DODATA);
-       hpaddr->hpdc = bp->b_cylin;
-       flags = mi->mi_hd->mh_flags;
        if (flags&MH_NOSEEK)
                return (MBU_DODATA);
        if (flags&MH_NOSEEK)
                return (MBU_DODATA);
+       hpaddr->hpdc = bp->b_cylin;
+       st = &hpst[mi->mi_type];
+       bn = dkblock(bp);
+       sn = bn%st->nspc;
+       sn = (sn+st->nsect-hpSDIST)%st->nsect;
+       flags = mi->mi_hd->mh_flags;
        if (bp->b_cylin == (hpaddr->hpdc & 0xffff)) {
                if (flags&MH_NOSEARCH)
                        return (MBU_DODATA);
        if (bp->b_cylin == (hpaddr->hpdc & 0xffff)) {
                if (flags&MH_NOSEARCH)
                        return (MBU_DODATA);
-               bn = dkblock(bp);
-               st = &hpst[mi->mi_type];
-               sn = bn%st->nspc;
-               sn = (sn+st->nsect-hpSDIST)%st->nsect;
                dist = ((hpaddr->hpla & 0xffff)>>6) - st->nsect + 1;
                if (dist < 0)
                        dist += st->nsect;
                dist = ((hpaddr->hpla & 0xffff)>>6) - st->nsect + 1;
                if (dist < 0)
                        dist += st->nsect;
@@ -199,7 +199,7 @@ hpstart(mi)
        bn = dkblock(bp);
        sn = bn%st->nspc;
        tn = sn/st->nsect;
        bn = dkblock(bp);
        sn = bn%st->nspc;
        tn = sn/st->nsect;
-       sn = sn%st->nsect;
+       sn %= st->nsect;
        if (mi->mi_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) {
                hpaddr->hpof = hp_offset[mi->mi_tab.b_errcnt & 017] | FMT22;
                hpaddr->hpcs1 = OFFSET|GO;
        if (mi->mi_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) {
                hpaddr->hpof = hp_offset[mi->mi_tab.b_errcnt & 017] | FMT22;
                hpaddr->hpcs1 = OFFSET|GO;
index 0d53c8c..dc48fdc 100644 (file)
@@ -1,4 +1,4 @@
-/*     dh.c    4.12    %G%     */
+/*     dh.c    4.13    81/02/10        */
 
 #include "dh.h"
 #if NDH11 > 0
 
 #include "dh.h"
 #if NDH11 > 0
 #include "../h/tty.h"
 #include "../h/map.h"
 #include "../h/pte.h"
 #include "../h/tty.h"
 #include "../h/map.h"
 #include "../h/pte.h"
+#include "../h/buf.h"
 #include "../h/uba.h"
 #include "../h/bk.h"
 #include "../h/clist.h"
 #include "../h/mx.h"
 
 #include "../h/uba.h"
 #include "../h/bk.h"
 #include "../h/clist.h"
 #include "../h/mx.h"
 
-/*
- * When running dz's using only SAE (silo alarm) on input
- * it is necessary to call dzrint() at clock interrupt time.
- * This is unsafe unless spl5()s in tty code are changed to
- * spl6()s to block clock interrupts.  Note that the dh driver
- * currently in use works the same way as the dz, even though
- * we could try to more intelligently manage its silo.
- * Thus don't take this out if you have no dz's unless you
- * change clock.c and dhtimer().
- */
+/* This is to block the clock because we are using the silos */
+/* SHOULD RATHER QUEUE SOFTWARE INTERRUPT AT CLOCK TIME */
 #define        spl5    spl6
 
 #define        spl5    spl6
 
-#define        UBACVT(x) (cbase + (short)((x)-(char *)cfree))
+#define        UBACVT(x,uban) (cbase[uban] + (short)((x)-(char *)cfree))
 
 
-struct tty dh11[NDH11];
+int    dhcntrlr(), dhslave(), dhrint(), dhxint();
+struct uba_dinfo *dhinfo[NDH11];
+u_short        dhstd[] = { 0 };
+int    (*dhivec[])() = { dhrint, dhxint, 0 };  /* note: order matters */
+struct uba_driver dhdriver =
+       { dhcntrlr, dhslave, (int (*)())0, 0, 0, dhstd, dhinfo, dhivec };
+
+struct tty dh11[NDH11*16];
 int    dhact;
 int    dhisilo;
 int    dhact;
 int    dhisilo;
-int    ndh11   = NDH11;
+int    ndh11   = NDH11*16;
 int    dhstart();
 int    ttrstrt();
 int    dhstart();
 int    ttrstrt();
-int    dh_ubinfo;
-int    cbase;
-int    getcbase;
+int    dh_ubinfo[4];
+int    cbase[4];
 
 /*
  * Hardware control bits
 
 /*
  * Hardware control bits
@@ -78,7 +77,7 @@ int   getcbase;
 /*
  * Software copy of last dhbar
  */
 /*
  * Software copy of last dhbar
  */
-short  dhsar[(NDH11+15)/16];
+short  dhsar[NDH11];
 
 struct device
 {
 
 struct device
 {
@@ -95,39 +94,60 @@ struct device
        short   dhsilo;
 };
 
        short   dhsilo;
 };
 
+dhcntrlr(ui, reg)
+       struct uba_dinfo *ui;
+       caddr_t reg;
+{
+
+       ((struct device *)reg)->un.dhcsr |= IENABLE;
+       /* get it to interrupt */
+}
+
+dhslave(ui, reg, slaveno)
+       struct uba_dinfo *ui;
+       caddr_t reg;
+{
+
+       /* could fill in local tables for the dh here */
+}
+
 /*
  * Open a DH11 line.
  */
 /*ARGSUSED*/
 dhopen(dev, flag)
 /*
  * Open a DH11 line.
  */
 /*ARGSUSED*/
 dhopen(dev, flag)
+       dev_t dev;
 {
        register struct tty *tp;
 {
        register struct tty *tp;
-       register d;
+       register int unit, dh;
        register struct device *addr;
        register struct device *addr;
+       register struct uba_dinfo *ui;
        int s;
 
        int s;
 
-       d = minor(dev) & 0177;
-       if (d >= NDH11) {
+       unit = minor(dev);
+       dh = unit >> 4;
+       if (unit >= NDH11*16 || (ui = dhinfo[dh])->ui_alive == 0) {
                u.u_error = ENXIO;
                return;
        }
                u.u_error = ENXIO;
                return;
        }
-       tp = &dh11[d];
-       addr = DHADDR;
-       addr += d>>4;
+       tp = &dh11[unit];
+       ui = dhinfo[dh];
+       addr = (struct device *)ui->ui_addr;
        tp->t_addr = (caddr_t)addr;
        tp->t_oproc = dhstart;
        tp->t_iproc = NULL;
        tp->t_state |= WOPEN;
        s = spl6();
        tp->t_addr = (caddr_t)addr;
        tp->t_oproc = dhstart;
        tp->t_iproc = NULL;
        tp->t_state |= WOPEN;
        s = spl6();
-       if (!getcbase) {
-               getcbase++;
+       if (dh_ubinfo[ui->ui_ubanum]) {
                /* 512+ is a kludge to try to get around a hardware problem */
                /* 512+ is a kludge to try to get around a hardware problem */
-               dh_ubinfo = uballoc((caddr_t)cfree, 512+NCLIST*sizeof(struct cblock), 0);
-               cbase = (short)dh_ubinfo;
+               dh_ubinfo[ui->ui_ubanum] =
+                   uballoc((caddr_t)cfree,
+                       512+NCLIST*sizeof(struct cblock), 0);
+               cbase[ui->ui_ubanum] = (short)dh_ubinfo[ui->ui_ubanum];
        }
        splx(s);
        addr->un.dhcsr |= IENAB;
        }
        splx(s);
        addr->un.dhcsr |= IENAB;
-       dhact |= (1<<(d>>4));
+       dhact |= (1<<dh);
        if ((tp->t_state&ISOPEN) == 0) {
                ttychars(tp);
                if (tp->t_ispeed == 0) {
        if ((tp->t_state&ISOPEN) == 0) {
                ttychars(tp);
                if (tp->t_ispeed == 0) {
@@ -135,14 +155,14 @@ dhopen(dev, flag)
                        tp->t_ospeed = SSPEED;
                        tp->t_flags = ODDP|EVENP|ECHO;
                }
                        tp->t_ospeed = SSPEED;
                        tp->t_flags = ODDP|EVENP|ECHO;
                }
-               dhparam(d);
+               dhparam(unit);
        }
        if (tp->t_state&XCLUDE && u.u_uid!=0) {
                u.u_error = EBUSY;
                return;
        }
        dmopen(dev);
        }
        if (tp->t_state&XCLUDE && u.u_uid!=0) {
                u.u_error = EBUSY;
                return;
        }
        dmopen(dev);
-       (*linesw[tp->t_line].l_open)(dev,tp);
+       (*linesw[tp->t_line].l_open)(dev, tp);
 }
 
 /*
 }
 
 /*
@@ -150,22 +170,22 @@ dhopen(dev, flag)
  */
 /*ARGSUSED*/
 dhclose(dev, flag)
  */
 /*ARGSUSED*/
 dhclose(dev, flag)
-dev_t dev;
-int  flag;
+       dev_t dev;
+       int flag;
 {
        register struct tty *tp;
 {
        register struct tty *tp;
-       register d;
+       register unit;
 
 
-       d = minor(dev) & 0177;
-       tp = &dh11[d];
+       unit = minor(dev);
+       tp = &dh11[unit];
        (*linesw[tp->t_line].l_close)(tp);
        /*
         * Turn of the break bit in case somebody did a TIOCSBRK without
         * a TIOCCBRK.
         */
        (*linesw[tp->t_line].l_close)(tp);
        /*
         * Turn of the break bit in case somebody did a TIOCSBRK without
         * a TIOCCBRK.
         */
-       ((struct device *)(tp->t_addr))->dhbreak &= ~(1<<(minor(dev)&017));
+       ((struct device *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
        if (tp->t_state&HUPCLS || (tp->t_state&ISOPEN)==0)
        if (tp->t_state&HUPCLS || (tp->t_state&ISOPEN)==0)
-               dmctl(d, TURNOFF, DMSET);
+               dmctl(unit, TURNOFF, DMSET);
        ttyclose(tp);
 }
 
        ttyclose(tp);
 }
 
@@ -173,10 +193,11 @@ int  flag;
  * Read from a DH11 line.
  */
 dhread(dev)
  * Read from a DH11 line.
  */
 dhread(dev)
+       dev_t dev;
 {
 {
-register struct tty *tp;
+       register struct tty *tp;
 
 
-       tp = &dh11[minor(dev) & 0177];
+       tp = &dh11[minor(dev)];
        (*linesw[tp->t_line].l_read)(tp);
 }
 
        (*linesw[tp->t_line].l_read)(tp);
 }
 
@@ -184,31 +205,34 @@ register struct tty *tp;
  * write on a DH11 line
  */
 dhwrite(dev)
  * write on a DH11 line
  */
 dhwrite(dev)
+       dev_t dev;
 {
 {
-register struct tty *tp;
+       register struct tty *tp;
 
 
-       tp = &dh11[minor(dev) & 0177];
+       tp = &dh11[minor(dev)];
        (*linesw[tp->t_line].l_write)(tp);
 }
 
 /*
  * DH11 receiver interrupt.
  */
        (*linesw[tp->t_line].l_write)(tp);
 }
 
 /*
  * DH11 receiver interrupt.
  */
-dhrint(dev)
+dhrint(dh)
+       int dh;
 {
        register struct tty *tp;
 {
        register struct tty *tp;
-       register short c;
+       register c;
        register struct device *addr;
        register struct tty *tp0;
        register struct device *addr;
        register struct tty *tp0;
+       register struct uba_dinfo *ui;
        int s;
 
        s = spl6();     /* see comment in clock.c */
        int s;
 
        s = spl6();     /* see comment in clock.c */
-       addr = DHADDR;
-       addr += minor(dev) & 0177;
-       tp0 = &dh11[((minor(dev)&0177)<<4)];
+       ui = dhinfo[dh];
+       addr = (struct device *)ui->ui_addr;
+       tp0 = &dh11[dh*16];
        while ((c = addr->dhnxch) < 0) {        /* char. present */
                tp = tp0 + ((c>>8)&017);
        while ((c = addr->dhnxch) < 0) {        /* char. present */
                tp = tp0 + ((c>>8)&017);
-               if (tp >= &dh11[NDH11])
+               if (tp >= &dh11[NDH11*16])
                        continue;
                if((tp->t_state&ISOPEN)==0) {
                        wakeup((caddr_t)tp);
                        continue;
                if((tp->t_state&ISOPEN)==0) {
                        wakeup((caddr_t)tp);
@@ -243,29 +267,30 @@ dhrint(dev)
  */
 /*ARGSUSED*/
 dhioctl(dev, cmd, addr, flag)
  */
 /*ARGSUSED*/
 dhioctl(dev, cmd, addr, flag)
-caddr_t addr;
+       caddr_t addr;
 {
        register struct tty *tp;
 {
        register struct tty *tp;
+       register unit = minor(dev);
 
 
-       tp = &dh11[minor(dev) & 0177];
+       tp = &dh11[unit];
        cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
        if (cmd==0)
                return;
        if (ttioctl(tp, cmd, addr, flag)) {
                if (cmd==TIOCSETP||cmd==TIOCSETN)
        cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
        if (cmd==0)
                return;
        if (ttioctl(tp, cmd, addr, flag)) {
                if (cmd==TIOCSETP||cmd==TIOCSETN)
-                       dhparam(dev);
+                       dhparam(unit);
        } else switch(cmd) {
        case TIOCSBRK:
        } else switch(cmd) {
        case TIOCSBRK:
-               ((struct device *)(tp->t_addr))->dhbreak |= 1<<(minor(dev)&017);
+               ((struct device *)(tp->t_addr))->dhbreak |= 1<<(unit&017);
                break;
        case TIOCCBRK:
                break;
        case TIOCCBRK:
-               ((struct device *)(tp->t_addr))->dhbreak &= ~(1<<(minor(dev)&017));
+               ((struct device *)(tp->t_addr))->dhbreak &= ~(1<<(unit&017));
                break;
        case TIOCSDTR:
                break;
        case TIOCSDTR:
-               dmctl(minor(dev), DTR|RQS, DMBIS);
+               dmctl(unit, DTR|RQS, DMBIS);
                break;
        case TIOCCDTR:
                break;
        case TIOCCDTR:
-               dmctl(minor(dev), DTR|RQS, DMBIC);
+               dmctl(unit, DTR|RQS, DMBIC);
                break;
        default:
                u.u_error = ENOTTY;
                break;
        default:
                u.u_error = ENOTTY;
@@ -276,38 +301,38 @@ caddr_t addr;
  * Set parameters from open or stty into the DH hardware
  * registers.
  */
  * Set parameters from open or stty into the DH hardware
  * registers.
  */
-dhparam(dev)
+dhparam(unit)
+       register int unit;
 {
        register struct tty *tp;
        register struct device *addr;
 {
        register struct tty *tp;
        register struct device *addr;
-       register d;
+       register int lpar;
        int s;
 
        int s;
 
-       d = minor(dev) & 0177;
-       tp = &dh11[d];
+       tp = &dh11[unit];
        addr = (struct device *)tp->t_addr;
        s = spl5();
        addr = (struct device *)tp->t_addr;
        s = spl5();
-       addr->un.dhcsrl = (d&017) | IENAB;
+       addr->un.dhcsrl = (unit&017) | IENAB;
        /*
         * Hang up line?
         */
        if ((tp->t_ispeed)==0) {
                tp->t_state |= HUPCLS;
        /*
         * Hang up line?
         */
        if ((tp->t_ispeed)==0) {
                tp->t_state |= HUPCLS;
-               dmctl(d, TURNOFF, DMSET);
+               dmctl(unit, TURNOFF, DMSET);
                return;
        }
                return;
        }
-       d = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);
+       lpar = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);
        if ((tp->t_ispeed) == 4)                /* 134.5 baud */
        if ((tp->t_ispeed) == 4)                /* 134.5 baud */
-               d |= BITS6|PENABLE|HDUPLX;
+               lpar |= BITS6|PENABLE|HDUPLX;
        else if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT))
        else if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT))
-               d |= BITS8;
+               lpar |= BITS8;
        else
        else
-               d |= BITS7|PENABLE;
+               lpar |= BITS7|PENABLE;
        if ((tp->t_flags&EVENP) == 0)
        if ((tp->t_flags&EVENP) == 0)
-               d |= OPAR;
+               lpar |= OPAR;
        if ((tp->t_ospeed) == 3)        /* 110 baud */
        if ((tp->t_ospeed) == 3)        /* 110 baud */
-               d |= TWOSB;
-       addr->dhlpr = d;
+               lpar |= TWOSB;
+       addr->dhlpr = lpar;
        splx(s);
 }
 
        splx(s);
 }
 
@@ -316,38 +341,40 @@ dhparam(dev)
  * Restart each line which used to be active but has
  * terminated transmission since the last interrupt.
  */
  * Restart each line which used to be active but has
  * terminated transmission since the last interrupt.
  */
-dhxint(dev)
+dhxint(dh)
+       int dh;
 {
        register struct tty *tp;
        register struct device *addr;
 {
        register struct tty *tp;
        register struct device *addr;
-       register d;
        short ttybit, bar, *sbar;
        short ttybit, bar, *sbar;
+       register struct uba_dinfo *ui;
+       register unit;
        int s;
 
        s = spl6();     /* block the clock */
        int s;
 
        s = spl6();     /* block the clock */
-       d = minor(dev) & 0177;
-       addr = DHADDR + d;
+       ui = dhinfo[dh];
+       addr = (struct device *)ui->ui_addr;
        addr->un.dhcsr &= (short)~XINT;
        if (addr->un.dhcsr & NXM) {
                addr->un.dhcsr |= CLRNXM;
                printf("dh clr NXM\n");
        }
        addr->un.dhcsr &= (short)~XINT;
        if (addr->un.dhcsr & NXM) {
                addr->un.dhcsr |= CLRNXM;
                printf("dh clr NXM\n");
        }
-       sbar = &dhsar[d];
+       sbar = &dhsar[dh];
        bar = *sbar & ~addr->dhbar;
        bar = *sbar & ~addr->dhbar;
-       d <<= 4; ttybit = 1;
-
-       for(; bar; d++, ttybit <<= 1) {
+       unit = dh * 16; ttybit = 1;
+       for(; bar; unit++, ttybit <<= 1) {
                if(bar&ttybit) {
                        *sbar &= ~ttybit;
                        bar &= ~ttybit;
                if(bar&ttybit) {
                        *sbar &= ~ttybit;
                        bar &= ~ttybit;
-                       tp = &dh11[d];
+                       tp = &dh11[unit];
                        tp->t_state &= ~BUSY;
                        if (tp->t_state&FLUSH)
                                tp->t_state &= ~FLUSH;
                        else {
                        tp->t_state &= ~BUSY;
                        if (tp->t_state&FLUSH)
                                tp->t_state &= ~FLUSH;
                        else {
-                               addr->un.dhcsrl = (d&017)|IENAB;
+                               addr->un.dhcsrl = (unit&017)|IENAB;
                                ndflush(&tp->t_outq,
                                ndflush(&tp->t_outq,
-                                   (int)(short)addr->dhcar-UBACVT(tp->t_outq.c_cf));
+                                   (int)(short)addr->dhcar-
+                                       UBACVT(tp->t_outq.c_cf,ui->ui_ubanum));
                        }
                        if (tp->t_line)
                                (*linesw[tp->t_line].l_start)(tp);
                        }
                        if (tp->t_line)
                                (*linesw[tp->t_line].l_start)(tp);
@@ -362,43 +389,34 @@ dhxint(dev)
  * Start (restart) transmission on the given DH11 line.
  */
 dhstart(tp)
  * Start (restart) transmission on the given DH11 line.
  */
 dhstart(tp)
-register struct tty *tp;
+       register struct tty *tp;
 {
        register struct device *addr;
 {
        register struct device *addr;
-       register short nch;
-       int s, d;
+       register int nch, dh, unit;
+       int s;
 
        /*
         * If it's currently active, or delaying,
         * no need to do anything.
         */
        s = spl5();
 
        /*
         * If it's currently active, or delaying,
         * no need to do anything.
         */
        s = spl5();
-       d = tp-dh11;
+       unit = minor(tp->t_dev);
+       dh = unit >> 4;
        addr = (struct device *)tp->t_addr;
        if (tp->t_state&(TIMEOUT|BUSY|TTSTOP))
                goto out;
        addr = (struct device *)tp->t_addr;
        if (tp->t_state&(TIMEOUT|BUSY|TTSTOP))
                goto out;
-
-       /*
-        * If the writer was sleeping on output overflow,
-        * wake him when low tide is reached.
-        */
-       if (tp->t_state&ASLEEP && tp->t_outq.c_cc<=TTLOWAT(tp)) {
+       if ((tp->t_state&ASLEEP) && tp->t_outq.c_cc<=TTLOWAT(tp)) {
                tp->t_state &= ~ASLEEP;
                if (tp->t_chan)
                        mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
                else
                        wakeup((caddr_t)&tp->t_outq);
        }
                tp->t_state &= ~ASLEEP;
                if (tp->t_chan)
                        mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
                else
                        wakeup((caddr_t)&tp->t_outq);
        }
-
        if (tp->t_outq.c_cc == 0)
                goto out;
        if (tp->t_outq.c_cc == 0)
                goto out;
-
-       /*
-        * Find number of characters to transfer.
-        */
-       if (tp->t_flags & RAW) {
+       if (tp->t_flags & RAW)
                nch = ndqb(&tp->t_outq, 0);
                nch = ndqb(&tp->t_outq, 0);
-       else {
+       else {
                nch = ndqb(&tp->t_outq, 0200);
                if (nch == 0) {
                        nch = getc(&tp->t_outq);
                nch = ndqb(&tp->t_outq, 0200);
                if (nch == 0) {
                        nch = getc(&tp->t_outq);
@@ -407,19 +425,17 @@ register struct tty *tp;
                        goto out;
                }
        }
                        goto out;
                }
        }
-       /*
-        * If any characters were set up, start transmission;
-        */
        if (nch) {
        if (nch) {
-               addr->un.dhcsrl = (d&017)|IENAB;
-               addr->dhcar = UBACVT(tp->t_outq.c_cf);
+               addr->un.dhcsrl = (unit&017)|IENAB;
+               addr->dhcar = UBACVT(tp->t_outq.c_cf, 
+                   dhinfo[dh]->ui_ubanum);
                addr->dhbcr = -nch;
                addr->dhbcr = -nch;
-               nch = 1<<(d&017);
+               nch = 1<<(unit&017);
                addr->dhbar |= nch;
                addr->dhbar |= nch;
-               dhsar[d>>4] |= nch;
+               dhsar[dh] |= nch;
                tp->t_state |= BUSY;
        }
                tp->t_state |= BUSY;
        }
-    out:
+out:
        splx(s);
 }
 
        splx(s);
 }
 
@@ -432,13 +448,13 @@ dhstop(tp, flag)
 register struct tty *tp;
 {
        register struct device *addr;
 register struct tty *tp;
 {
        register struct device *addr;
-       register d, s;
+       register int unit, s;
 
        addr = (struct device *)tp->t_addr;
        s = spl6();
        if (tp->t_state & BUSY) {
 
        addr = (struct device *)tp->t_addr;
        s = spl6();
        if (tp->t_state & BUSY) {
-               d = minor(tp->t_dev);
-               addr->un.dhcsrl = (d&017) | IENAB;
+               unit = minor(tp->t_dev);
+               addr->un.dhcsrl = (unit&017) | IENAB;
                if ((tp->t_state&TTSTOP)==0)
                        tp->t_state |= FLUSH;
                addr->dhbcr = -1;
                if ((tp->t_state&TTSTOP)==0)
                        tp->t_state |= FLUSH;
                addr->dhbcr = -1;
@@ -455,21 +471,23 @@ int       dhsilo = 16;
 /*ARGSUSED*/
 dhtimer()
 {
 /*ARGSUSED*/
 dhtimer()
 {
-       register d;
+       register int dh;
        register struct device *addr;
        register struct device *addr;
+       register struct uba_dinfo *ui;
 
 
-       addr = DHADDR; d = 0;
+       dh = 0;
        do {
        do {
-               if (dhact & (1<<d)) {
-                       if ((dhisilo & (1<<d)) == 0) {
+               ui = dhinfo[dh];
+               addr = (struct device *)ui->ui_addr;
+               if (dhact & (1<<dh)) {
+                       if ((dhisilo & (1<<dh)) == 0) {
                                addr->dhsilo = dhsilo;
                                addr->dhsilo = dhsilo;
-                               dhisilo |= 1<<d;
+                               dhisilo |= 1<<dh;
                        }
                        }
-                       dhrint(d);
+                       dhrint(dh);
                }
                }
-               d++;
-               addr++;
-       } while (d < (NDH11+15)/16);
+               dh++;
+       } while (dh < NDH11);
 }
 
 /*
 }
 
 /*
@@ -477,38 +495,45 @@ dhtimer()
  * Reset the csrl and lpr registers on open lines, and
  * restart transmitters.
  */
  * Reset the csrl and lpr registers on open lines, and
  * restart transmitters.
  */
-dhreset()
+dhreset(uban)
 {
 {
-       int d;
+       register int dh, unit;
        register struct tty *tp;
        register struct device *addr;
        register struct tty *tp;
        register struct device *addr;
+       register struct uba_dinfo *ui;
+       int uba;
+
+       /*** WE SHOULD LOOK TO SEE IF UBA BEING RESET IS INTERESTING ***/
 
 
-       if (getcbase == 0)
-               return;
        printf(" dh");
        dhisilo = 0;
        printf(" dh");
        dhisilo = 0;
-       ubarelse(&dh_ubinfo);
-       dh_ubinfo = uballoc((caddr_t)cfree, NCLIST*sizeof (struct cblock), 0);
-       cbase = (short)dh_ubinfo;
-       d = 0;
+       for (uba = 0; uba < numuba; uba++)
+               if (dh_ubinfo[uba]) {
+                       ubarelse(uba, &dh_ubinfo[uba]);
+                       dh_ubinfo[uba] = uballoc(uba, (caddr_t)cfree,
+                           512+NCLIST*sizeof (struct cblock), 0);
+                       cbase[uba] = (short)dh_ubinfo;
+               }
+       dh = 0;
        do {
        do {
-               addr = DHADDR + d;
-               if (dhact & (1<<d))
-                       addr->un.dhcsr |= IENAB;
-               d++;
-       } while (d < (NDH11+15)/16);
-       for (d = 0; d < NDH11; d++) {
-               tp = &dh11[d];
+               if (dhact & (1<<dh))
+                       ((struct device *)dhinfo[dh]->ui_addr)->un.dhcsr |=
+                           IENAB;
+               dh++;
+       } while (dh < NDH11);
+       for (unit = 0; unit < NDH11*16; unit++) {
+               tp = &dh11[unit];
                if (tp->t_state & (ISOPEN|WOPEN)) {
                if (tp->t_state & (ISOPEN|WOPEN)) {
-                       dhparam(d);
-                       dmctl(d, TURNON, DMSET);
+                       dhparam(unit);
+                       dmctl(unit, TURNON, DMSET);
                        tp->t_state &= ~BUSY;
                        dhstart(tp);
                }
        }
        dhtimer();
 }
                        tp->t_state &= ~BUSY;
                        dhstart(tp);
                }
        }
        dhtimer();
 }
-#if DHDM > 0
+
+#if DHDM
 #include "../dev/dhdm.c"
 #else
 #include "../dev/dhfdm.c"
 #include "../dev/dhdm.c"
 #else
 #include "../dev/dhfdm.c"
index ef66cce..5fb464c 100644 (file)
@@ -1,4 +1,4 @@
-/*     dz.c    4.    %G%     */
+/*     dz.c    4.10    %G%     */
 
 #include "dz.h"
 #if NDZ11 > 0
 
 #include "dz.h"
 #if NDZ11 > 0
@@ -12,6 +12,7 @@
 #include "../h/user.h"
 #include "../h/map.h"
 #include "../h/pte.h"
 #include "../h/user.h"
 #include "../h/map.h"
 #include "../h/pte.h"
+#include "../h/buf.h"
 #include "../h/uba.h"
 #include "../h/conf.h"
 #include "../h/pdma.h"
 #include "../h/uba.h"
 #include "../h/conf.h"
 #include "../h/pdma.h"
  * we could try to more intelligently manage its silo.
  * Thus don't take this out if you have no dz's unless you
  * change clock.c and dhtimer().
  * we could try to more intelligently manage its silo.
  * Thus don't take this out if you have no dz's unless you
  * change clock.c and dhtimer().
+ *
+ * SHOULD RATHER QUEUE SOFTWARE INTERRUPT AT CLOCK TIME.
  */
 #define        spl5    spl6
  
  */
 #define        spl5    spl6
  
+int    dzcntrlr(), dzslave(), dzrint();
+struct uba_dinfo *dzinfo[NDZ11];
+u_short        dzstd[] = { 0 };
+int    (*dzivec[])() = { dzrint, 0 }; /* omit dzxint so we can do it here */
+struct uba_driver dzdriver =
+       { dzcntrlr, dzslave, (int (*)())0, 0, 0, dzstd, dzinfo, dzivec };
+
 #define NDZ    (NDZ11*8)
  
 #define BITS7  020
 #define NDZ    (NDZ11*8)
  
 #define BITS7  020
@@ -48,7 +58,6 @@
 #define        OVERRUN 040000
 #define SSPEED 7               /* std speed = 300 baud */
 
 #define        OVERRUN 040000
 #define SSPEED 7               /* std speed = 300 baud */
 
 #define        dzlpr   dzrbuf
 #define dzmsr  dzbrk
 #define ON     1
 #define        dzlpr   dzrbuf
 #define dzmsr  dzbrk
 #define ON     1
@@ -56,6 +65,7 @@
  
 int    dzstart();
 int    dzxint();
  
 int    dzstart();
 int    dzxint();
+int    dzdma();
 int    ttrstrt();
 struct tty dz_tty[NDZ];
 int    dz_cnt = { NDZ };
 int    ttrstrt();
 struct tty dz_tty[NDZ];
 int    dz_cnt = { NDZ };
@@ -70,62 +80,60 @@ struct device {
        char    dzbrk;
 };
 
        char    dzbrk;
 };
 
-struct pdma dzpdma[] = {
-       (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[0], dzxint,
-       (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[1], dzxint,
-       (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[2], dzxint,
-       (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[3], dzxint,
-       (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[4], dzxint,
-       (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[5], dzxint,
-       (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[6], dzxint,
-       (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[7], dzxint,
-#if NDZ11 >= 2
-       (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[8], dzxint,
-       (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[9], dzxint,
-       (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[10], dzxint,
-       (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[11], dzxint,
-       (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[12], dzxint,
-       (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[13], dzxint,
-       (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[14], dzxint,
-       (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[15], dzxint,
-#endif
-#if NDZ11 >= 3
-       (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[16], dzxint,
-       (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[17], dzxint,
-       (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[18], dzxint,
-       (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[19], dzxint,
-       (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[20], dzxint,
-       (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[21], dzxint,
-       (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[22], dzxint,
-       (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[23], dzxint,
-#endif
-#if NDZ11 >= 4
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[24], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[25], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[26], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[27], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[28], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[29], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[30], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[31], dzxint,
-#endif
-};
+struct pdma dzpdma[NDZ];
 char   dz_timer;
 char   dz_timer;
-char   dz_speeds[] = {
-       0, 020 , 021 , 022 , 023 , 024 , 0, 025,
-       026 , 027 , 030 , 032 , 034 , 036 , 0 , 0,
-};
-char dz_brk[NDZ11];
+char   dz_speeds[] =
+       { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,0,0 };
+char   dz_brk[NDZ11];
  
  
+dzcntrlr(ui, reg)
+       struct uba_dinfo *ui;
+       caddr_t reg;
+{
+
+       ((struct device *)reg)->dzcsr |= IENABLE;
+       /* get it to interrupt */
+}
+
+dzslave(ui, reg, slaveno, uban)
+       register struct uba_dinfo *ui;
+       caddr_t reg;
+{
+       register struct pdma *pdp = &dzpdma[ui->ui_unit*8];
+       register struct tty *tp = &dz_tty[ui->ui_unit*8];
+       register int cnt;
+       register int *urk = (int *)(&reg - 24); /* white magic */
+       caddr_t cp;
+       int urk2;
+
+       for (cnt = 0; cnt < 8; cnt++) {
+               pdp->p_addr = (struct device *)reg;
+               pdp->p_arg = (int)tp;
+               pdp->p_fcn = dzxint;
+               pdp++, tp++;
+       }
+       if ((cp = calloc(12)) == 0)
+               panic("dz iv nm\n");
+       uba_hd[uban].uh_vec[*urk] = (int (*)())cp;      /* more white magic */
+       *cp++ = 0xbb; *cp++ = 0xff; *cp++ = 0xd0;       /* black magic */
+       *cp++ = ui->ui_unit&0x3f; *cp++ = 0x50;
+       *cp++ = 0x17; *cp++ = 0x9f;
+       urk2 = (int)dzdma;
+       for (cnt = 0; cnt < 4; cnt++)
+               *cp++ = urk2, urk2 >>= 4;               /* the spell ends */
+       return (1);
+}
+
 /*ARGSUSED*/
 /*ARGSUSED*/
-dzopen(d, flag)
+dzopen(dev, flag)
+       dev_t dev;
 {
        register struct tty *tp;
 {
        register struct tty *tp;
-       register dev;
+       register int unit;
        extern dzscan();
  
        extern dzscan();
  
-       dev = minor(d);
-       if (dev >= dz_cnt) {
+       unit = minor(dev);
+       if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) {
                u.u_error = ENXIO;
                return;
        }
                u.u_error = ENXIO;
                return;
        }
@@ -133,8 +141,8 @@ dzopen(d, flag)
                dz_timer++;
                timeout(dzscan, (caddr_t)0, 60);
        }
                dz_timer++;
                timeout(dzscan, (caddr_t)0, 60);
        }
-       tp = &dz_tty[dev];
-       tp->t_addr = (caddr_t)&dzpdma[dev];
+       tp = &dz_tty[unit];
+       tp->t_addr = (caddr_t)&dzpdma[unit];
        tp->t_oproc = dzstart;
        tp->t_iproc = NULL;
        tp->t_state |= WOPEN;
        tp->t_oproc = dzstart;
        tp->t_iproc = NULL;
        tp->t_state |= WOPEN;
@@ -143,72 +151,76 @@ dzopen(d, flag)
                tp->t_ospeed = tp->t_ispeed = SSPEED;
                tp->t_flags = ODDP|EVENP|ECHO;
                /*tp->t_state |= HUPCLS;*/
                tp->t_ospeed = tp->t_ispeed = SSPEED;
                tp->t_flags = ODDP|EVENP|ECHO;
                /*tp->t_state |= HUPCLS;*/
-               dzparam(dev);
+               dzparam(unit);
        } else if (tp->t_state&XCLUDE && u.u_uid != 0) {
                u.u_error = EBUSY;
                return;
        }
        } else if (tp->t_state&XCLUDE && u.u_uid != 0) {
                u.u_error = EBUSY;
                return;
        }
-       dzmodem(dev, ON);
+       dzmodem(unit, ON);
        (void) spl5();
        while ((tp->t_state & CARR_ON) == 0) {
                tp->t_state |= WOPEN;
                sleep((caddr_t)&tp->t_rawq, TTIPRI);
        }
        (void) spl0();
        (void) spl5();
        while ((tp->t_state & CARR_ON) == 0) {
                tp->t_state |= WOPEN;
                sleep((caddr_t)&tp->t_rawq, TTIPRI);
        }
        (void) spl0();
-       (*linesw[tp->t_line].l_open)(d, tp);
+       (*linesw[tp->t_line].l_open)(dev, tp);
 }
  
 }
  
-dzclose(d)
+/*ARGSUSED*/
+dzclose(dev, flag)
+       dev_t dev;
 {
        register struct tty *tp;
 {
        register struct tty *tp;
-       register dev;
+       register int unit;
+       int dz;
  
  
-       dev = minor(d);
-       tp = &dz_tty[dev];
+       unit = minor(dev);
+       dz = unit >> 3;
+       tp = &dz_tty[unit];
        (*linesw[tp->t_line].l_close)(tp);
        (*linesw[tp->t_line].l_close)(tp);
-       /*
-        * Turn the break bit off in case it was left on by a TIOCSBRK
-        * but not turned off by TIOCCBRK
-        */
        ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
        ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
-               (dz_brk[minor(dev)>>3] &= ~(1 << (dev&07)));
+           (dz_brk[dz] &= ~(1 << (unit&07)));
        if (tp->t_state & HUPCLS)
        if (tp->t_state & HUPCLS)
-               dzmodem(dev, OFF);
+               dzmodem(unit, OFF);
        ttyclose(tp);
 }
  
        ttyclose(tp);
 }
  
-dzread(d)
+dzread(dev)
+       dev_t dev;
 {
        register struct tty *tp;
  
 {
        register struct tty *tp;
  
-       tp = &dz_tty[minor(d)];
+       tp = &dz_tty[minor(dev)];
        (*linesw[tp->t_line].l_read)(tp);
 }
  
        (*linesw[tp->t_line].l_read)(tp);
 }
  
-dzwrite(d)
+dzwrite(dev)
+       dev_t dev;
 {
        register struct tty *tp;
  
 {
        register struct tty *tp;
  
-       tp = &dz_tty[minor(d)];
+       tp = &dz_tty[minor(dev)];
        (*linesw[tp->t_line].l_write)(tp);
 }
  
 /*ARGSUSED*/
        (*linesw[tp->t_line].l_write)(tp);
 }
  
 /*ARGSUSED*/
-dzrint(dev)
+dzrint(dz)
+       int dz;
 {
        register struct tty *tp;
        register int c;
        register struct device *dzaddr;
        register struct tty *tp0;
 {
        register struct tty *tp;
        register int c;
        register struct device *dzaddr;
        register struct tty *tp0;
+       register int unit;
        int s;
  
        s = spl6();     /* see comment in clock.c */
        /* as long as we are here, service them all */
        int s;
  
        s = spl6();     /* see comment in clock.c */
        /* as long as we are here, service them all */
-       for (dev = 0; dev < NDZ; dev += 8) {
-               if ((dzact & (1<<(dev>>3))) == 0)
+       for (unit = 0; unit < NDZ; unit += 8) {
+               if ((dzact & (1<<(unit>>3))) == 0)
                        continue;
                        continue;
-               dzaddr = dzpdma[dev].p_addr;
-               tp0 = &dz_tty[dev];
+               dzaddr = dzpdma[unit].p_addr;
+               tp0 = &dz_tty[unit];
                while ((c = dzaddr->dzrbuf) < 0) {      /* char present */
                        tp = tp0 + ((c>>8)&07);
                        if (tp >= &dz_tty[dz_cnt])
                while ((c = dzaddr->dzrbuf) < 0) {      /* char present */
                        tp = tp0 + ((c>>8)&07);
                        if (tp >= &dz_tty[dz_cnt])
@@ -246,53 +258,57 @@ dzrint(dev)
  
 /*ARGSUSED*/
 dzioctl(dev, cmd, addr, flag)
  
 /*ARGSUSED*/
 dzioctl(dev, cmd, addr, flag)
-caddr_t addr;
-dev_t dev;
+       dev_t dev;
+       caddr_t addr;
 {
        register struct tty *tp;
 {
        register struct tty *tp;
+       register int unit = minor(dev);
+       register int dz = unit >> 3;
  
  
-       tp = &dz_tty[minor(dev)];
+       tp = &dz_tty[unit];
        cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
        if (cmd == 0)
                return;
        if (ttioctl(tp, cmd, addr, flag)) {
                if (cmd==TIOCSETP || cmd==TIOCSETN)
        cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
        if (cmd == 0)
                return;
        if (ttioctl(tp, cmd, addr, flag)) {
                if (cmd==TIOCSETP || cmd==TIOCSETN)
-                       dzparam(minor(dev));
+                       dzparam(unit);
        } else switch(cmd) {
        } else switch(cmd) {
+
        case TIOCSBRK:
                ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
        case TIOCSBRK:
                ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
-                       (dz_brk[minor(dev)>>3] |= 1 << (dev&07));
+                       (dz_brk[dz] |= 1 << (unit&07));
                break;
        case TIOCCBRK:
                ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
                break;
        case TIOCCBRK:
                ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
-                       (dz_brk[minor(dev)>>3] &= ~(1 << (dev&07)));
+                       (dz_brk[dz] &= ~(1 << (unit&07)));
                break;
        case TIOCSDTR:
                break;
        case TIOCSDTR:
-               dzmodem(minor(dev), ON);
+               dzmodem(unit, ON);
                break;
        case TIOCCDTR:
                break;
        case TIOCCDTR:
-               dzmodem(minor(dev), OFF);
+               dzmodem(unit, OFF);
                break;
        default:
                u.u_error = ENOTTY;
        }
 }
  
                break;
        default:
                u.u_error = ENOTTY;
        }
 }
  
-dzparam(dev)
+dzparam(unit)
+       register int unit;
 {
        register struct tty *tp;
        register struct device *dzaddr;
 {
        register struct tty *tp;
        register struct device *dzaddr;
-       register short lpr;
+       register int lpr;
  
  
-       tp = &dz_tty[dev];
-       dzaddr = dzpdma[dev].p_addr;
+       tp = &dz_tty[unit];
+       dzaddr = dzpdma[unit].p_addr;
        dzaddr->dzcsr = DZ_IEN;
        dzaddr->dzcsr = DZ_IEN;
-       dzact |= (1<<(dev>>3));
+       dzact |= (1<<(unit>>3));
        if (tp->t_ispeed == 0) {
        if (tp->t_ispeed == 0) {
-               dzmodem(dev, OFF);              /* hang up line */
+               dzmodem(unit, OFF);             /* hang up line */
                return;
        }
                return;
        }
-       lpr = (dz_speeds[tp->t_ispeed]<<8) | (dev & 07);
+       lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07);
 #ifndef IIASA
        if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW))
                lpr |= BITS8;
 #ifndef IIASA
        if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW))
                lpr |= BITS8;
@@ -316,13 +332,13 @@ dzparam(dev)
 }
  
 dzxint(tp)
 }
  
 dzxint(tp)
-register struct tty *tp;
+       register struct tty *tp;
 {
        register struct pdma *dp;
        register s;
        s = spl6();     /* block the clock */
  
 {
        register struct pdma *dp;
        register s;
        s = spl6();     /* block the clock */
  
-       dp = &dzpdma[tp-dz_tty];
+       dp = (struct pdma *)tp->t_addr;
        tp->t_state &= ~BUSY;
        if (tp->t_state & FLUSH)
                tp->t_state &= ~FLUSH;
        tp->t_state &= ~BUSY;
        if (tp->t_state & FLUSH)
                tp->t_state &= ~FLUSH;
@@ -333,21 +349,21 @@ register struct tty *tp;
        else
                dzstart(tp);
        if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0)
        else
                dzstart(tp);
        if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0)
-               dp->p_addr->dztcr &= ~(1 << ((tp-dz_tty) % 8));
+               dp->p_addr->dztcr &= ~(1 << (minor(tp->t_dev)&07));
        splx(s);
 }
 
 dzstart(tp)
        splx(s);
 }
 
 dzstart(tp)
-register struct tty *tp;
+       register struct tty *tp;
 {
        register struct pdma *dp;
        register struct device *dzaddr;
 {
        register struct pdma *dp;
        register struct device *dzaddr;
-       register cc;
-       int sps;
+       register int cc;
+       int s;
  
  
-       dp = &dzpdma[tp-dz_tty];
+       dp = (struct pdma *)tp->t_addr;
        dzaddr = dp->p_addr;
        dzaddr = dp->p_addr;
-       sps = spl5();
+       s = spl5();
        if (tp->t_state & (TIMEOUT|BUSY|TTSTOP))
                goto out;
        if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) {
        if (tp->t_state & (TIMEOUT|BUSY|TTSTOP))
                goto out;
        if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) {
@@ -373,9 +389,9 @@ register struct tty *tp;
        tp->t_state |= BUSY;
        dp->p_end = dp->p_mem = tp->t_outq.c_cf;
        dp->p_end += cc;
        tp->t_state |= BUSY;
        dp->p_end = dp->p_mem = tp->t_outq.c_cf;
        dp->p_end += cc;
-       dzaddr->dztcr |= 1 << ((tp-dz_tty) % 8);
-   out:
-       splx(sps);
+       dzaddr->dztcr |= 1 << (minor(tp->t_dev) & 07);
+out:
+       splx(s);
 }
  
 /*
 }
  
 /*
@@ -384,30 +400,29 @@ register struct tty *tp;
  */
 /*ARGSUSED*/
 dzstop(tp, flag)
  */
 /*ARGSUSED*/
 dzstop(tp, flag)
-register struct tty *tp;
+       register struct tty *tp;
 {
        register struct pdma *dp;
        register int s;
 
 {
        register struct pdma *dp;
        register int s;
 
-       dp = &dzpdma[tp-dz_tty];
+       dp = (struct pdma *)tp->t_addr;
        s = spl6();
        if (tp->t_state & BUSY) {
                dp->p_end = dp->p_mem;
        s = spl6();
        if (tp->t_state & BUSY) {
                dp->p_end = dp->p_mem;
-               if ((tp->t_state&TTSTOP)==0) {
+               if ((tp->t_state&TTSTOP)==0)
                        tp->t_state |= FLUSH;
                        tp->t_state |= FLUSH;
-               }
        }
        splx(s);
 }
  
        }
        splx(s);
 }
  
-dzmodem(dev, flag)
-register int dev;
+dzmodem(unit, flag)
+       register int unit;
 {
        register struct device *dzaddr;
        register char bit;
  
 {
        register struct device *dzaddr;
        register char bit;
  
-       dzaddr = dzpdma[dev].p_addr;
-       bit = 1<<(dev&07);
+       dzaddr = dzpdma[unit].p_addr;
+       bit = 1<<(unit&07);
        if (flag == OFF)
                dzaddr->dzdtr &= ~bit;
        else
        if (flag == OFF)
                dzaddr->dzdtr &= ~bit;
        else
@@ -432,7 +447,7 @@ dzscan()
                                tp->t_state |= CARR_ON;
                        }
                } else {
                                tp->t_state |= CARR_ON;
                        }
                } else {
-                       if ((tp->t_state&CARR_ON) && (tp->t_local&LNOHANG) == 0) {
+                       if ((tp->t_state&CARR_ON) && (tp->t_local&LNOHANG)==0) {
                                /* carrier lost */
                                if (tp->t_state&ISOPEN) {
                                        gsignal(tp->t_pgrp, SIGHUP);
                                /* carrier lost */
                                if (tp->t_state&ISOPEN) {
                                        gsignal(tp->t_pgrp, SIGHUP);
@@ -457,17 +472,19 @@ dztimer()
  * Reset state of driver if UBA reset was necessary.
  * Reset parameters and restart transmission on open lines.
  */
  * Reset state of driver if UBA reset was necessary.
  * Reset parameters and restart transmission on open lines.
  */
-dzreset()
+dzreset(uban)
 {
 {
-       int d;
+       register int unit;
        register struct tty *tp;
 
        register struct tty *tp;
 
+       /*** WE SHOULD LOOK TO SEE IF WE CARE ABOUT UBA BEING RESET ***/
+
        printf(" dz");
        printf(" dz");
-       for (d = 0; d < NDZ; d++) {
-               tp = &dz_tty[d];
+       for (unit = 0; unit < NDZ; unit++) {
+               tp = &dz_tty[unit];
                if (tp->t_state & (ISOPEN|WOPEN)) {
                if (tp->t_state & (ISOPEN|WOPEN)) {
-                       dzparam(d);
-                       dzmodem(d, ON);
+                       dzparam(unit);
+                       dzmodem(unit, ON);
                        tp->t_state &= ~BUSY;
                        dzstart(tp);
                }
                        tp->t_state &= ~BUSY;
                        dzstart(tp);
                }
index 490b7a1..070e5dd 100644 (file)
@@ -1,4 +1,4 @@
-/*     tm.c    4.8     %G%     */
+/*     tm.c    4.9     %G%     */
 
 #include "tm.h"
 #if NTM > 0
 
 #include "tm.h"
 #if NTM > 0
 #include "../h/ioctl.h"
 #include "../h/vm.h"
 #include "../h/cmap.h"
 #include "../h/ioctl.h"
 #include "../h/vm.h"
 #include "../h/cmap.h"
+#include "../h/cpu.h"
 
 
-struct device {
-       u_short tmer;
-       u_short tmcs;
-       short   tmbc;
-       u_short tmba;
-       short   tmdb;
-       short   tmrd;
-};
-
-#define        b_repcnt  b_bcount
-#define        b_command b_resid
+#include "../h/tmreg.h"
 
 struct buf     tmtab;
 struct buf     ctmbuf;
 struct buf     rtmbuf;
 
 
 struct buf     tmtab;
 struct buf     ctmbuf;
 struct buf     rtmbuf;
 
+int    tmcntrlr(), tmslave(), tmdgo(), tmintr();
+struct uba_dinfo *tminfo[NTM];
+u_short        tmstd[] = { 0 };
+int    (*tmivec[])() = { tmintr, 0 };
+struct uba_driver tmdriver =
+       { tmcntrlr, tmslave, tmdgo, 0, 0, tmstd, tminfo, tmivec };
 int    tm_ubinfo;
 
 /* bits in minor device */
 int    tm_ubinfo;
 
 /* bits in minor device */
@@ -46,7 +43,8 @@ int   tm_ubinfo;
 
 /*
  * Really only handle one tape drive... if you have more than one,
 
 /*
  * Really only handle one tape drive... if you have more than one,
- * you can make all these arrays and change the obvious things, but
+ * you can put all these (and some of the above) in a structure,
+ * change the obvious things, and make tmslave smarter, but
  * it is not clear what happens when some drives are transferring while
  * others rewind, so we don't pretend that this driver handles multiple
  * tape drives.
  * it is not clear what happens when some drives are transferring while
  * others rewind, so we don't pretend that this driver handles multiple
  * tape drives.
@@ -59,43 +57,6 @@ u_short      t_erreg;
 u_short        t_dsreg;
 short  t_resid;
 
 u_short        t_dsreg;
 short  t_resid;
 
-/* bits in tmcs */
-#define        GO      01
-#define        OFFL    0
-#define        RCOM    02
-#define        WCOM    04
-#define        WEOF    06
-#define        SFORW   010
-#define        SREV    012
-#define        WIRG    014
-#define        REW     016
-#define        IENABLE 0100
-#define        CUR     0200
-#define        NOP     IENABLE
-#define        DCLR    010000
-#define        D800    060000
-#define        ERROR   0100000
-
-/* bits in tmer */
-#define        TUR     1
-#define        RWS     02
-#define        WRL     04
-#define        SDWN    010
-#define        BOT     040
-#define        SELR    0100
-#define        NXM     0200
-#define        TMBTE   0400
-#define        RLE     01000
-#define        EOT     02000
-#define        BGL     04000
-#define        PAE     010000
-#define        CRE     020000
-#define        EOF     040000
-#define        ILC     0100000
-
-#define        HARD    (ILC|EOT)
-#define        SOFT    (CRE|PAE|BGL|RLE|TMBTE|NXM)
-
 #define        SSEEK   1               /* seeking */
 #define        SIO     2               /* doing seq i/o */
 #define        SCOM    3               /* sending control command */
 #define        SSEEK   1               /* seeking */
 #define        SIO     2               /* doing seq i/o */
 #define        SCOM    3               /* sending control command */
@@ -103,15 +64,52 @@ short      t_resid;
 #define        LASTIOW 1               /* last op was a write */
 #define        WAITREW 2               /* someone is waiting for a rewind */
 
 #define        LASTIOW 1               /* last op was a write */
 #define        WAITREW 2               /* someone is waiting for a rewind */
 
+tmcntrlr(ui, reg)
+       struct uba_dinfo *ui;
+       caddr_t reg;
+{
+       ((struct device *)reg)->tmcs = IENABLE;
+       /*
+        * If this is a tm03/tc11, it ought to have interrupted
+        * by now, if it isn't (ie: it is a ts04) then we just
+        * pray that it didn't interrupt, so autoconf will ignore it
+        * - just in case out prayers fail, we will reference one
+        * of the more distant registers, and hope for a machine
+        * check, or similar disaster
+        */
+       if (badaddr(&((struct device *)reg)->tmrd, 2))
+               return(0);
+       return(1);
+}
+
+tmslave(ui, reg, slaveno)
+       struct uba_dinfo *ui;
+       caddr_t reg;
+{
+       /*
+        * Due to a design flaw, we cannot ascertain if the tape
+        * exists or not unless it is on line - ie: unless a tape is
+        * mounted. This is too servere a restriction to bear.
+        * As we can only handle one tape, we might just as well insist
+        * that it be slave #0, and just assume that it exists.
+        * Something better will have to be done if you have two
+        * tapes on one controller, or two controllers
+        */
+       if (slaveno != 0 || tminfo[0])
+               return(0);
+       return(1);
+}
+
 tmopen(dev, flag)
        dev_t dev;
        int flag;
 {
        register ds, unit;
 tmopen(dev, flag)
        dev_t dev;
        int flag;
 {
        register ds, unit;
+       register struct uba_dinfo *ui;
 
        tmtab.b_flags |= B_TAPE;
        unit = minor(dev)&03;
 
        tmtab.b_flags |= B_TAPE;
        unit = minor(dev)&03;
-       if (unit >= NTM || t_openf) {
+       if (unit>=NTM || t_openf || !(ui = tminfo[minor(dev)>>3])->ui_alive) {
                u.u_error = ENXIO;              /* out of range or open */
                return;
        }
                u.u_error = ENXIO;              /* out of range or open */
                return;
        }
@@ -127,7 +125,7 @@ tmopen(dev, flag)
                tcommand(dev, NOP, 1);          /* await settle down */
        if ((t_erreg&TUR)==0 ||
            ((flag&(FREAD|FWRITE)) == FWRITE && (t_erreg&WRL))) {
                tcommand(dev, NOP, 1);          /* await settle down */
        if ((t_erreg&TUR)==0 ||
            ((flag&(FREAD|FWRITE)) == FWRITE && (t_erreg&WRL))) {
-               TMADDR->tmcs = DCLR|GO;
+               ((struct device *)ui->ui_addr)->tmcs = DCLR|GO;
                u.u_error = EIO;                /* offline or write protect */
        }
        if (u.u_error != 0) {
                u.u_error = EIO;                /* offline or write protect */
        }
        if (u.u_error != 0) {
@@ -143,10 +141,12 @@ tmopen(dev, flag)
 tmwaitrws(dev)
        register dev;
 {
 tmwaitrws(dev)
        register dev;
 {
+       register struct device *addr =
+           (struct device *)tminfo[minor(dev)>>3]->ui_addr;
 
        spl5();
        for (;;) {
 
        spl5();
        for (;;) {
-               if ((TMADDR->tmer&RWS) == 0) {
+               if ((addr->tmer&RWS) == 0) {
                        spl0();         /* rewind complete */
                        return;
                }
                        spl0();         /* rewind complete */
                        return;
                }
@@ -231,6 +231,8 @@ tmstrategy(bp)
 tmstart()
 {
        register struct buf *bp;
 tmstart()
 {
        register struct buf *bp;
+       register struct uba_dinfo *ui;
+       register struct device *addr;
        register cmd;
        register daddr_t blkno;
        int s;
        register cmd;
        register daddr_t blkno;
        int s;
@@ -238,11 +240,13 @@ tmstart()
 loop:
        if ((bp = tmtab.b_actf) == 0)
                return;
 loop:
        if ((bp = tmtab.b_actf) == 0)
                return;
-       t_dsreg = TMADDR->tmcs;
-       t_erreg = TMADDR->tmer;
-       t_resid = TMADDR->tmbc;
+       ui = tminfo[minor(bp->b_dev)>>3];
+       addr = (struct device *)ui->ui_addr;
+       t_dsreg = addr->tmcs;
+       t_erreg = addr->tmer;
+       t_resid = addr->tmbc;
        t_flags &= ~LASTIOW;
        t_flags &= ~LASTIOW;
-       if (t_openf < 0 || (TMADDR->tmcs&CUR) == 0) {
+       if (t_openf < 0 || (addr->tmcs&CUR) == 0) {
                /* t_openf = -1; ??? */
                bp->b_flags |= B_ERROR;         /* hard error'ed or !SELR */
                goto next;
                /* t_openf = -1; ??? */
                bp->b_flags |= B_ERROR;         /* hard error'ed or !SELR */
                goto next;
@@ -257,16 +261,16 @@ loop:
                        cmd |= bp->b_command;
                        tmtab.b_active = SCOM;
                        if (bp->b_command == SFORW || bp->b_command == SREV)
                        cmd |= bp->b_command;
                        tmtab.b_active = SCOM;
                        if (bp->b_command == SFORW || bp->b_command == SREV)
-                               TMADDR->tmbc = bp->b_repcnt;
-                       TMADDR->tmcs = cmd;
+                               addr->tmbc = bp->b_repcnt;
+                       addr->tmcs = cmd;
                        return;
                }
        }
        if ((blkno = t_blkno) == dbtofsb(bp->b_blkno)) {
                        return;
                }
        }
        if ((blkno = t_blkno) == dbtofsb(bp->b_blkno)) {
-               TMADDR->tmbc = -bp->b_bcount;
+               addr->tmbc = -bp->b_bcount;
                s = spl6();
                if (tm_ubinfo == 0)
                s = spl6();
                if (tm_ubinfo == 0)
-                       tm_ubinfo = ubasetup(bp,1);
+                       tm_ubinfo = ubasetup(ui->ui_ubanum, bp, 1);
                splx(s);
                if ((bp->b_flags&B_READ) == 0) {
                        if (tmtab.b_errcnt)
                splx(s);
                if ((bp->b_flags&B_READ) == 0) {
                        if (tmtab.b_errcnt)
@@ -277,64 +281,69 @@ loop:
                        cmd |= RCOM;
                cmd |= (tm_ubinfo >> 12) & 0x30;
                tmtab.b_active = SIO;
                        cmd |= RCOM;
                cmd |= (tm_ubinfo >> 12) & 0x30;
                tmtab.b_active = SIO;
-               TMADDR->tmba = tm_ubinfo;
-               TMADDR->tmcs = cmd; 
+               addr->tmba = tm_ubinfo;
+               addr->tmcs = cmd; 
                return;
        }
        tmtab.b_active = SSEEK;
        if (blkno < dbtofsb(bp->b_blkno)) {
                cmd |= SFORW;
                return;
        }
        tmtab.b_active = SSEEK;
        if (blkno < dbtofsb(bp->b_blkno)) {
                cmd |= SFORW;
-               TMADDR->tmbc = blkno - dbtofsb(bp->b_blkno);
+               addr->tmbc = blkno - dbtofsb(bp->b_blkno);
        } else {
                cmd |= SREV;
        } else {
                cmd |= SREV;
-               TMADDR->tmbc = dbtofsb(bp->b_blkno) - blkno;
+               addr->tmbc = dbtofsb(bp->b_blkno) - blkno;
        }
        }
-       TMADDR->tmcs = cmd;
+       addr->tmcs = cmd;
        return;
 
 next:
        return;
 
 next:
-       ubarelse(&tm_ubinfo);
+       ubarelse(ui->ui_ubanum, &tm_ubinfo);
        tmtab.b_actf = bp->av_forw;
        iodone(bp);
        goto loop;
 }
 
        tmtab.b_actf = bp->av_forw;
        iodone(bp);
        goto loop;
 }
 
-tmintr()
+tmdgo()
+{
+}
+
+tmintr(d)
 {
        register struct buf *bp;
 {
        register struct buf *bp;
+       register struct device *addr = (struct device *)tminfo[d]->ui_addr;
        register state;
 
        register state;
 
-       if (t_flags&WAITREW && (TMADDR->tmer&RWS) == 0) {
+       if (t_flags&WAITREW && (addr->tmer&RWS) == 0) {
                t_flags &= ~WAITREW;
                wakeup((caddr_t)&t_flags);
        }
        if ((bp = tmtab.b_actf) == NULL)
                return;
                t_flags &= ~WAITREW;
                wakeup((caddr_t)&t_flags);
        }
        if ((bp = tmtab.b_actf) == NULL)
                return;
-       t_dsreg = TMADDR->tmcs;
-       t_erreg = TMADDR->tmer;
-       t_resid = TMADDR->tmbc;
+       t_dsreg = addr->tmcs;
+       t_erreg = addr->tmer;
+       t_resid = addr->tmbc;
        if ((bp->b_flags & B_READ) == 0)
                t_flags |= LASTIOW;
        state = tmtab.b_active;
        tmtab.b_active = 0;
        if ((bp->b_flags & B_READ) == 0)
                t_flags |= LASTIOW;
        state = tmtab.b_active;
        tmtab.b_active = 0;
-       if (TMADDR->tmcs&ERROR) {
-               while(TMADDR->tmer & SDWN)
+       if (addr->tmcs&ERROR) {
+               while(addr->tmer & SDWN)
                        ;                       /* await settle down */
                        ;                       /* await settle down */
-               if (TMADDR->tmer&EOF) {
+               if (addr->tmer&EOF) {
                        tmseteof(bp);   /* set blkno and nxrec */
                        state = SCOM;
                        tmseteof(bp);   /* set blkno and nxrec */
                        state = SCOM;
-                       TMADDR->tmbc = -bp->b_bcount;
+                       addr->tmbc = -bp->b_bcount;
                        goto errout;
                }
                        goto errout;
                }
-               if ((bp->b_flags&B_READ) && (TMADDR->tmer&(HARD|SOFT)) == RLE)
+               if ((bp->b_flags&B_READ) && (addr->tmer&(HARD|SOFT)) == RLE)
                        goto out;
                        goto out;
-               if ((TMADDR->tmer&HARD)==0 && state==SIO) {
+               if ((addr->tmer&HARD)==0 && state==SIO) {
                        if (++tmtab.b_errcnt < 7) {
                        if (++tmtab.b_errcnt < 7) {
-                               if((TMADDR->tmer&SOFT) == NXM)
+                               if((addr->tmer&SOFT) == NXM)
                                        printf("TM UBA late error\n");
                                else
                                        printf("TM UBA late error\n");
                                else
-                                       t_blkno += 2;           /* ???????? */
-                               ubarelse(&tm_ubinfo);
+                                       t_blkno++;
+                               ubarelse(tminfo[d]->ui_ubanum, &tm_ubinfo);
                                tmstart();
                                return;
                        }
                                tmstart();
                                return;
                        }
@@ -372,8 +381,8 @@ out:
 errout:
                tmtab.b_errcnt = 0;
                tmtab.b_actf = bp->av_forw;
 errout:
                tmtab.b_errcnt = 0;
                tmtab.b_actf = bp->av_forw;
-               bp->b_resid = -TMADDR->tmbc;
-               ubarelse(&tm_ubinfo);
+               bp->b_resid = -addr->tmbc;
+               ubarelse(tminfo[d]->ui_ubanum, &tm_ubinfo);
                iodone(bp);
                break;
 
                iodone(bp);
                break;
 
@@ -390,15 +399,17 @@ errout:
 tmseteof(bp)
        register struct buf *bp;
 {
 tmseteof(bp)
        register struct buf *bp;
 {
+       register struct device *addr = 
+           (struct device *)tminfo[minor(bp->b_dev)>>3]->ui_addr;
 
        if (bp == &ctmbuf) {
                if (t_blkno > dbtofsb(bp->b_blkno)) {
                        /* reversing */
 
        if (bp == &ctmbuf) {
                if (t_blkno > dbtofsb(bp->b_blkno)) {
                        /* reversing */
-                       t_nxrec = dbtofsb(bp->b_blkno) - TMADDR->tmbc;
+                       t_nxrec = dbtofsb(bp->b_blkno) - addr->tmbc;
                        t_blkno = t_nxrec;
                } else {
                        /* spacing forward */
                        t_blkno = t_nxrec;
                } else {
                        /* spacing forward */
-                       t_blkno = dbtofsb(bp->b_blkno) + TMADDR->tmbc;
+                       t_blkno = dbtofsb(bp->b_blkno) + addr->tmbc;
                        t_nxrec = t_blkno - 1;
                }
                return;
                        t_nxrec = t_blkno - 1;
                }
                return;
@@ -506,70 +517,83 @@ tmdump()
 tmwall(start, num)
        int start, num;
 {
 tmwall(start, num)
        int start, num;
 {
-#if VAX==780
-       register struct uba_regs *up = (struct uba_regs *)PHYSUBA0;
-#endif
+       register struct uba_dinfo *ui;
+       register struct uba_regs *up;
+       register struct device *addr;
        int blk, bdp;
 
        int blk, bdp;
 
-#if VAX==780
-       up->uba_cr = ADINIT;
-       up->uba_cr = IFS|BRIE|USEFIE|SUEFIE;
-       while ((up->uba_cnfgr & UBIC) == 0)
-               ;
+#define        phys1(a,b)      ((b)((int)(a)&0x7fffffff))
+#define        phys(a,b)       phys1(*phys1(&a, b*), b)
+       if (tminfo[0] == 0) {
+               printf("dna\n");
+               return (-1);
+       }
+       ui = phys(tminfo[0], struct uba_dinfo *);
+       up = phys(ui->ui_hd, struct uba_hd *)->uh_physuba;
+#if VAX780
+       if (cpu == VAX_780)
+               ubainit(up);
 #endif
        DELAY(1000000);
 #endif
        DELAY(1000000);
-       tmwait();
-       TMPHYS->tmcs = DCLR | GO;
+       addr = (struct device *)ui->ui_physaddr;
+       tmwait(addr);
+       addr->tmcs = DCLR | GO;
        while (num > 0) {
                blk = num > DBSIZE ? DBSIZE : num;
        while (num > 0) {
                blk = num > DBSIZE ? DBSIZE : num;
-               tmdwrite(start, blk);
+               tmdwrite(start, blk, addr, up);
                start += blk;
                num -= blk;
        }
        bdp = 1;                /* crud to fool c compiler */
                start += blk;
                num -= blk;
        }
        bdp = 1;                /* crud to fool c compiler */
-       ((struct uba_regs *)PHYSUBA0)->uba_dpr[bdp] |= BNE;
+       up->uba_dpr[bdp] |= UBA_BNE;
        return (0);
 }
 
        return (0);
 }
 
-tmdwrite(buf, num)
-register buf, num;
+tmdwrite(buf, num, addr, up)
+       register buf, num;
+       register struct device *addr;
+       struct uba_regs *up;
 {
 {
-       register int *io, npf;
+       register struct pte *io;
+       register int npf;
        int bdp;
 
        int bdp;
 
-       tmwait();
+       tmwait(addr);
        bdp = 1;                /* more dastardly tricks on pcc */
        bdp = 1;                /* more dastardly tricks on pcc */
-       ((struct uba_regs *)PHYSUBA0)->uba_dpr[bdp] |= BNE;
-       io = (int *)((struct uba_regs *)PHYSUBA0)->uba_map;
+       up->uba_dpr[bdp] |= UBA_BNE;
+       io = up->uba_map;
        npf = num+1;
        while (--npf != 0)
        npf = num+1;
        while (--npf != 0)
-                *io++ = (int)(buf++ | (1<<21) | MRV);
-       *io = 0;
-       TMPHYS->tmbc = -(num*NBPG);
-       TMPHYS->tmba = 0;
-       TMPHYS->tmcs = WCOM | GO;
+                *(int *)io++ = (buf++ | (1<<UBA_DPSHIFT) | UBA_MRV);
+       *(int *)io = 0;
+       addr->tmbc = -(num*NBPG);
+       addr->tmba = 0;
+       addr->tmcs = WCOM | GO;
 }
 
 }
 
-tmwait()
+tmwait(addr)
+       register struct device *addr;
 {
        register s;
 
        do
 {
        register s;
 
        do
-               s = TMPHYS->tmcs;
+               s = addr->tmcs;
        while ((s & CUR) == 0);
 }
 
        while ((s & CUR) == 0);
 }
 
-tmrewind()
+tmrewind(addr)
+       struct device *addr;
 {
 
 {
 
-       tmwait();
-       TMPHYS->tmcs = REW | GO;
+       tmwait(addr);
+       addr->tmcs = REW | GO;
 }
 
 }
 
-tmeof()
+tmeof(addr)
+       struct device *addr;
 {
 
 {
 
-       tmwait();
-       TMPHYS->tmcs = WEOF | GO;
+       tmwait(addr);
+       addr->tmcs = WEOF | GO;
 }
 #endif
 }
 #endif
index b58c689..f5bcf09 100644 (file)
@@ -1,33 +1,35 @@
-/*     uba.c   4.6     %G%     */
+/*     uba.c   4.7     %G%     */
 
 #include "../h/param.h"
 
 #include "../h/param.h"
+#include "../h/systm.h"
+#include "../h/cpu.h"
 #include "../h/map.h"
 #include "../h/pte.h"
 #include "../h/map.h"
 #include "../h/pte.h"
-#include "../h/uba.h"
 #include "../h/buf.h"
 #include "../h/buf.h"
+#include "../h/uba.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/proc.h"
 #include "../h/vm.h"
 #include "../h/conf.h"
 #include "../h/mtpr.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/proc.h"
 #include "../h/vm.h"
 #include "../h/conf.h"
 #include "../h/mtpr.h"
+#include "../h/nexus.h"
 
 /*
 
 /*
- * Allocate as many contiguous UBA mapping registers
- * as are necessary to do transfer of bcnt bytes
- * to/from location baddr.  Wait for enough map registers.
- *
- * Bdpflg is non-zero if a "buffered data path" (BDP) is
- * to be used, else 0 -> use direct data path (DDP).  Return
+ * Allocate and setup UBA map registers, and bdp's
+ * Flags says whether bdp is needed, whether the caller can't
+ * wait (e.g. if the caller is at interrupt level).
  *
  *
+ * Return value (cruft):
  *     Bits 0-8        Byte offset
  *     Bits 9-17       Start map reg. no.
  *     Bits 18-27      No. mapping reg's
  *     Bits 28-31      BDP no.
  */
  *     Bits 0-8        Byte offset
  *     Bits 9-17       Start map reg. no.
  *     Bits 18-27      No. mapping reg's
  *     Bits 28-31      BDP no.
  */
-ubasetup(bp, bdpflg)
-struct buf *bp;
+ubasetup(uban, bp, flags)
+       struct buf *bp;
 {
 {
+       register struct uba_hd *uh = &uba_hd[uban];
        register int temp, i;
        int npf, reg, bdp;
        unsigned v;
        register int temp, i;
        int npf, reg, bdp;
        unsigned v;
@@ -39,26 +41,32 @@ struct buf *bp;
        o = (int)bp->b_un.b_addr & PGOFSET;
        npf = btoc(bp->b_bcount + o) + 1;
        a = spl6();
        o = (int)bp->b_un.b_addr & PGOFSET;
        npf = btoc(bp->b_bcount + o) + 1;
        a = spl6();
-       while ((reg = malloc(ubamap, npf)) == 0) {
-               panic("ran out of uba map");
-               umrwant++;
-               sleep((caddr_t)ubamap, PSWP);
+       while ((reg = malloc(uh->uh_map, npf)) == 0) {
+               if (flags & UBA_CANTWAIT)
+                       return (0);
+               uh->uh_mrwant++;
+               sleep((caddr_t)uh->uh_map, PSWP);
        }
        reg--;
        bdp = 0;
        }
        reg--;
        bdp = 0;
-       if (bdpflg)
-               while ((bdp = malloc(bdpmap, 1)) == 0) {
-                       panic("ran out of bdp's");
-                       bdpwant++;
-                       sleep((caddr_t)bdpmap, PSWP);
+       if (flags & UBA_NEEDBDP) {
+               while ((bdp = ffs(uh->uh_bdpfree)) == 0) {
+                       if (flags & UBA_CANTWAIT) {
+                               mfree(uh->uh_map, npf, reg);
+                               return (0);
+                       }
+                       uh->uh_bdpwant++;
+                       sleep((caddr_t)uh->uh_map, PSWP);
                }
                }
+               uh->uh_bdpfree &= ~ (1<<bdp);
+       }
        splx(a);
        ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o;
        splx(a);
        ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o;
-       io = &(((struct uba_regs *)UBA0)->uba_map[reg]);
-       temp = (bdp << 21) | MRV;
+       io = &uh->uh_uba->uba_map[reg];
+       temp = (bdp << 21) | UBA_MRV;
        rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
        if (bdp && (o & 01))
        rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
        if (bdp && (o & 01))
-               temp |= BO;
+               temp |= UBA_BO;
        if (bp->b_flags & B_UAREA) {
                for (i = UPAGES - bp->b_bcount / NBPG; i < UPAGES; i++) {
                        if (rp->p_addr[i].pg_pfnum == 0)
        if (bp->b_flags & B_UAREA) {
                for (i = UPAGES - bp->b_bcount / NBPG; i < UPAGES; i++) {
                        if (rp->p_addr[i].pg_pfnum == 0)
@@ -87,7 +95,7 @@ struct buf *bp;
 /*
  * Non buffer unibus interface... set up a buffer and call ubasetup.
  */
 /*
  * Non buffer unibus interface... set up a buffer and call ubasetup.
  */
-uballoc(addr, bcnt, bdpflg)
+uballoc(uban, addr, bcnt, flags)
        caddr_t addr;
        unsigned short bcnt;
 {
        caddr_t addr;
        unsigned short bcnt;
 {
@@ -97,15 +105,16 @@ uballoc(addr, bcnt, bdpflg)
        ubabuf.b_flags = B_BUSY;
        ubabuf.b_bcount = bcnt;
        /* that's all the fields ubasetup() needs */
        ubabuf.b_flags = B_BUSY;
        ubabuf.b_bcount = bcnt;
        /* that's all the fields ubasetup() needs */
-       return (ubasetup(&ubabuf, bdpflg));
+       return (ubasetup(uban, &ubabuf, flags));
 }
  
 /*
  * Old ubafree(info) is now ubarelse(&info) to avoid races.
  */
 }
  
 /*
  * Old ubafree(info) is now ubarelse(&info) to avoid races.
  */
-ubarelse(amr)
+ubarelse(uban, amr)
        int *amr;
 {
        int *amr;
 {
+       register struct uba_hd *uh = &uba_hd[uban];
        register int bdp, reg, npf, a;
        int mr;
  
        register int bdp, reg, npf, a;
        int mr;
  
@@ -118,53 +127,130 @@ ubarelse(amr)
        *amr = 0;
        bdp = (mr >> 28) & 0x0f;
        if (bdp) {
        *amr = 0;
        bdp = (mr >> 28) & 0x0f;
        if (bdp) {
-               ((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE; /* purge */
-               mfree(bdpmap, 1, bdp);
-               if (bdpwant) {
-                       bdpwant = 0;
-                       wakeup((caddr_t)bdpmap);
+               uh->uh_uba->uba_dpr[bdp] |= UBA_BNE;
+               uh->uh_bdpfree |= 1 << bdp;
+               if (uh->uh_bdpwant) {
+                       uh->uh_bdpwant = 0;
+                       wakeup((caddr_t)uh->uh_map);
                }
        }
        npf = (mr >> 18) & 0x3ff;
        reg = ((mr >> 9) & 0x1ff) + 1;
                }
        }
        npf = (mr >> 18) & 0x3ff;
        reg = ((mr >> 9) & 0x1ff) + 1;
-       mfree(ubamap, npf, reg);
-       if (umrwant) {
-               umrwant = 0;
-               wakeup((caddr_t)ubamap);
+       mfree(uh->uh_map, npf, reg);
+       if (uh->uh_mrwant) {
+               uh->uh_mrwant = 0;
+               wakeup((caddr_t)uh->uh_map);
        }
        splx(a);
 }
 
        }
        splx(a);
 }
 
-ubainit()
-{
-
-       mfree(ubamap, 496, 1);
-       mfree(bdpmap, NUBABDP, 1);
-}
-
 #define        DELAY(N)        { register int d; d = N; while (--d > 0); }
 
 #define        DELAY(N)        { register int d; d = N; while (--d > 0); }
 
-ubareset()
+ubareset(uban)
 {
 {
-       struct uba_regs *up = (struct uba_regs *)UBA0;
+       struct uba_regs *up;
        register struct cdevsw *cdp;
        int s;
 
        s = spl6();
        register struct cdevsw *cdp;
        int s;
 
        s = spl6();
+       switch (cpu) {
 #if VAX==780
 #if VAX==780
-       printf("UBA RESET:");
-       up->uba_cr = ADINIT;
-       up->uba_cr = IFS|BRIE|USEFIE|SUEFIE;
-       while ((up->uba_cnfgr & UBIC) == 0)
-               ;
+       case VAX_780:
+               printf("UBA RESET %d:", uban);
+               ubainit(uba_hd[uban].uh_uba);
+               break;
 #endif
 #if VAX==750
 #endif
 #if VAX==750
-       printf("UNIBUS INIT:");
-       mtpr(IUR, 1);
-       DELAY(100000);
+       case VAX_750:
+               printf("UNIBUS INIT:");
+               mtpr(IUR, 1);
+               DELAY(100000);
+               break;
 #endif
 #endif
+       }
        for (cdp = cdevsw; cdp->d_open; cdp++)
        for (cdp = cdevsw; cdp->d_open; cdp++)
-               (*cdp->d_reset)();
+               (*cdp->d_reset)(uban);
        printf("\n");
        splx(s);
 }
        printf("\n");
        splx(s);
 }
+
+/* pointer rather than number so we can be called with virt and phys addrs */
+ubainit(up)
+       register struct uba_regs *up;
+{
+
+       up->uba_cr = UBA_ADINIT;
+       up->uba_cr = UBA_IFS|UBA_BRIE|UBA_USEFIE|UBA_SUEFIE;
+       while ((up->uba_cnfgr & UBA_UBIC) == 0)
+               ;
+}
+
+#if VAX780
+unhang()
+{
+       register int uban;
+
+       for (uban = 0; uban < numuba; uban++) {
+               register struct uba_hd *uh = &uba_hd[uban];
+               register struct uba_regs *up = uh->uh_uba;
+
+               if (up->uba_sr == 0)
+                       return;
+               uh->uh_hangcnt++;
+               if (uh->uh_hangcnt > 5*HZ) {
+                       uh->uh_hangcnt = 0;
+                       printf("HANG ");
+                       ubareset(uban);
+               }
+       }
+}
+
+/* timeout routine to decrement ``i forgot to interrupt counts */
+/* this prevents the counts from growing slowly, which isn't interesting */
+ubawatch()
+{
+       register struct uba_hd *uh;
+       register int uban;
+
+       for (uban = 0; uban < numuba; uban++) {
+               uh = &uba_hd[uban];
+               if (uh->uh_hangcnt)
+                       uh->uh_hangcnt--;
+       }
+}
+
+/* called from locore.s; parameters here (i.e. uvec) are value-result! */
+ubaerror(uban, uh, xx, uvec, uba)
+       register int uban;
+       register struct uba_hd *uh;
+       int uvec;
+       register struct uba_regs *uba;
+{
+       register sr, s;
+
+       if (uvec == 0) {
+               uh->uh_zvcnt++;
+               if (uh->uh_zvcnt > 250000) {
+                       printf("ZERO VECTOR ");
+                       ubareset(uban);
+               }
+               uvec = 0;
+               return;
+       }
+       if (uba->uba_cnfgr & NEX_CFGFLT) {
+               printf("UBA%d SBI FAULT sr %x cnfgr %x\n",
+                   uban, uba->uba_sr, uba->uba_cnfgr);
+               ubareset(uban);
+               uvec = 0;
+               return;
+       }
+       sr = uba->uba_sr;
+       s = spl7();
+       printf("UBA%d ERROR SR %x FMER %x FUBAR %o\n",
+           uba->uba_sr, uba->uba_fmer, uba->uba_fubar);
+       splx(s);
+       uba->uba_sr = sr;
+       uvec &= UBA_DIV;
+       return;
+}
+#endif
index 519fb16..71a6be0 100644 (file)
@@ -1,7 +1,7 @@
-/*     up.c    4.12    %G%     */
+/*     up.c    4.13    81/02/10        */
 
 #include "up.h"
 
 #include "up.h"
-#if NUP > 0
+#if NSC21 > 0
 /*
  * UNIBUS disk driver with overlapped seeks and ECC recovery.
  */
 /*
  * UNIBUS disk driver with overlapped seeks and ECC recovery.
  */
@@ -9,6 +9,8 @@
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
+#include "../h/cpu.h"
+#include "../h/nexus.h"
 #include "../h/dk.h"
 #include "../h/buf.h"
 #include "../h/conf.h"
 #include "../h/dk.h"
 #include "../h/buf.h"
 #include "../h/conf.h"
 
 #include "../h/upreg.h"
 
 
 #include "../h/upreg.h"
 
-/*
- * Software extension to the upas register, so we can
- * postpone starting SEARCH commands until the controller
- * is not transferring.
- */
-int    upsoftas;
-
-/*
- * If upseek then we don't issue SEARCH commands but rather just
- * settle for a SEEK to the correct cylinder.
- */
-int    upseek;
-
-#define        NSECT   32
-#define        NTRAC   19
-
-/*
- * Constants controlling on-cylinder SEARCH usage.
- *
- *     upSDIST/2 msec          time needed to start transfer
- *     upRDIST/2 msec          tolerable rotational latency when on-cylinder
- *
- * If we are no closer than upSDIST sectors and no further than upSDIST+upRDIST
- * and in the driver then we take it as it is.  Otherwise we do a SEARCH
- * requesting an interrupt upSDIST sectors in advance.
- */
-#define        _upSDIST        2               /* 1.0 msec */
-#define        _upRDIST        4               /* 2.0 msec */
-
-int    upSDIST = _upSDIST;
-int    upRDIST = _upRDIST;
+struct up_softc {
+       int     sc_softas;
+       int     sc_seek;
+       int     sc_info;
+       int     sc_wticks;
+} up_softc[NSC21];
 
 
-/*
- * To fill a 300M drive:
- *     A is designed to be used as a root.
- *     B is suitable for a swap area.
- *     H is the primary storage area.
- * On systems with RP06'es, we normally use only 291346 blocks of the H
- * area, and use DEF or G to cover the rest of the drive.  The C system
- * covers the whole drive and can be used for pack-pack copying.
- *
- * Note: sizes here are for AMPEX drives with 815 cylinders.
- * CDC drives can make the F,G, and H areas larger as they have 823 cylinders.
- */
+/* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
 struct size
 {
        daddr_t nblocks;
 struct size
 {
        daddr_t nblocks;
@@ -81,23 +47,52 @@ struct      size
        81472,  681,            /* F=cyl 681 thru 814 */
        153824, 562,            /* G=cyl 562 thru 814 */
        291346, 82,             /* H=cyl 82 thru 561 */
        81472,  681,            /* F=cyl 681 thru 814 */
        153824, 562,            /* G=cyl 562 thru 814 */
        291346, 82,             /* H=cyl 82 thru 561 */
+}, fj_sizes[8] = {
+       15884,  0,              /* A=cyl 0 thru 49 */
+       33440,  50,             /* B=cyl 50 thru 154 */
+       263360, 0,              /* C=cyl 0 thru 822 */
+       0,      0,
+       0,      0,
+       0,      0,
+       0,      0,
+       213760, 155,            /* H=cyl 155 thru 822 */
 };
 };
+/* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
 
 
-/*
- * The following defines are used in offset positioning
- * when trying to recover disk errors, with the constants being
- * +/- microinches.  Note that header compare inhibit (HCI) is not
- * tried (this makes sense only during read, in any case.)
- *
- * NB: Not all drives/controllers emulate all of these.
- */
-#define        P400    020
-#define        M400    0220
-#define        P800    040
-#define        M800    0240
-#define        P1200   060
-#define        M1200   0260
-#define        HCI     020000
+#define        _upSDIST        2               /* 1.0 msec */
+#define        _upRDIST        4               /* 2.0 msec */
+
+int    upSDIST = _upSDIST;
+int    upRDIST = _upRDIST;
+
+int    upcntrlr(), upslave(), updgo(), upintr();
+struct uba_minfo *upminfo[NSC21];
+struct uba_dinfo *updinfo[NUP];
+struct uba_minfo up_minfo[NSC21];
+       /* there is no reason for this to be a global structure, it
+          is only known/used locally, it would be better combined
+          with up_softc - but that would mean I would have to alter
+          more than I want to just now. Similarly, there is no longer
+          any real need for upminfo, but the code still uses it so ...
+       */
+
+u_short        upstd[] = { 0 };
+int    (*upivec[])() = { upintr, 0 };
+struct uba_driver updriver =
+       { upcntrlr, upslave, updgo, 4, 0, upstd, updinfo, upivec };
+struct buf     uputab[NUP];
+
+struct upst {
+       short   nsect;
+       short   ntrak;
+       short   nspc;
+       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,     10,     32*10,  823,    fj_sizes,       /* fujitsu 160m */
+};
 
 int    up_offset[16] =
 {
 
 int    up_offset[16] =
 {
@@ -107,133 +102,143 @@ int     up_offset[16] =
        0, 0, 0, 0,
 };
 
        0, 0, 0, 0,
 };
 
-/*
- * Each drive has a table uputab[i].  On this table are sorted the
- * pending requests implementing an elevator algorithm (see dsort.c.)
- * In the upustart() routine, each drive is independently advanced
- * until it is on the desired cylinder for the next transfer and near
- * the desired sector.  The drive is then chained onto the uptab
- * table, and the transfer is initiated by the upstart() routine.
- * When the transfer is completed the driver reinvokes the upustart()
- * routine to set up the next transfer.
- */
-struct buf     uptab;
-struct buf     uputab[NUP];
-
-struct buf     rupbuf;                 /* Buffer for raw i/o */
+struct buf     rupbuf;                 /* GROT */
 
 #define        b_cylin b_resid
 
 
 #define        b_cylin b_resid
 
-int    up_ubinfo;              /* Information about UBA usage saved here */
-
-int    up_wticks;              /* Ticks waiting for interrupt */
-int    upwstart;               /* Have started guardian */
-int    upwatch();
-
 #ifdef INTRLVE
 daddr_t dkblock();
 #endif
 #ifdef INTRLVE
 daddr_t dkblock();
 #endif
-/*
- * Queue an i/o request for a drive, checking first that it is in range.
- *
- * A unit start is issued if the drive is inactive, causing
- * a SEARCH for the correct cylinder/sector.  If the drive is
- * already nearly on the money and the controller is not transferring
- * we kick it to start the transfer.
- */
-upstrategy(bp)
-register struct buf *bp;
+
+int    upwstart, upwatch();            /* Have started guardian */
+
+/*ARGSUSED*/
+upcntrlr(um, reg)
+       struct uba_minfo *um;
+       caddr_t reg;
 {
 {
-       register struct buf *dp;
-       register unit, xunit;
-       long sz, bn;
+       ((struct device *)reg)->upcs1 |= (IE|RDY);
+       return(1);                      /* just assume it is us (for now) */
+}
+
+upslave(ui, reg, slaveno, uban)
+       struct uba_dinfo *ui;
+       caddr_t reg;
+{
+       register struct device *upaddr = (struct device *)reg;
+       register struct uba_minfo *um;
+       register int sc21;
+
+       upaddr->upcs1 = 0;              /* conservative */
+       upaddr->upcs2 = slaveno;
+       if (upaddr->upcs2&NED) {
+               upaddr->upcs1 = DCLR|GO;
+               return (0);
+       }
+       /*** we should check device type (return 0 if we don't like it) ***/
+       /*** and set type index in ui->ui_type, but we KNOW all we are  ***/
+       /*** going to see at the minute is a 9300, and the index for a  ***/
+       /*** 9300 is 0, which is the value already in ui->ui_type, so ..***/
+
+       um = &up_minfo[0];
+       for (sc21 = 0; sc21 < NSC21; sc21++) {
+               if (um->um_alive == 0) {        /* this is a new ctrlr */
+                       um->um_addr = reg;
+                       um->um_ubanum = uban;
+                       um->um_num = sc21;      /* not needed after up_softc
+                                                  combined with um ???  */
+                       um->um_alive = 1;
+                       upminfo[sc21] = um;     /* just till upminfo vanishes */
+                       goto found;
+               }
+               if (um->um_addr == reg && um->um_ubanum == uban)
+                       goto found;
+               um++;
+       }
+       return(0);                              /* too many sc21's */
+
+    found:
+       ui->ui_mi = um;
 
        if (upwstart == 0) {
                timeout(upwatch, (caddr_t)0, HZ);
                upwstart++;
        }
 
        if (upwstart == 0) {
                timeout(upwatch, (caddr_t)0, HZ);
                upwstart++;
        }
-       xunit = minor(bp->b_dev) & 077;
+       return (1);
+}
+/*
+       dk_mspw[UPDK_N+unit] = .0000020345;
+*/
+
+upstrategy(bp)
+       register struct buf *bp;
+{
+       register struct uba_dinfo *ui;
+       register struct uba_minfo *um;
+       register struct upst *st;
+       register int unit;
+       int xunit = minor(bp->b_dev) & 07;
+       long sz, bn;
+
        sz = bp->b_bcount;
        sz = (sz+511) >> 9;             /* transfer size in 512 byte sectors */
        unit = dkunit(bp);
        sz = bp->b_bcount;
        sz = (sz+511) >> 9;             /* transfer size in 512 byte sectors */
        unit = dkunit(bp);
-       if (unit >= NUP ||
-           bp->b_blkno < 0 ||
-           (bn = dkblock(bp))+sz > up_sizes[xunit&07].nblocks) {
-               bp->b_flags |= B_ERROR;
-               iodone(bp);
-               return;
-       }
-       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];
+       if (unit >= NUP)
+               goto bad;
+       ui = updinfo[unit];
+       if (ui == 0 || ui->ui_alive == 0)
+               goto bad;
+       st = &upst[ui->ui_type];
+       if (bp->b_blkno < 0 ||
+           (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks)
+               goto bad;
+       bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
        (void) spl5();
        (void) spl5();
-       disksort(dp, bp);
-       if (dp->b_active == 0) {
-               (void) upustart(unit);
-               if (uptab.b_actf && uptab.b_active == 0)
-                       (void) upstart();
+       disksort(&uputab[ui->ui_unit], bp);
+       if (uputab[ui->ui_unit].b_active == 0) {
+               (void) upustart(ui);
+               bp = &ui->ui_mi->um_tab;
+               if (bp->b_actf && bp->b_active == 0)
+                       (void) upstart(ui->ui_mi);
        }
        (void) spl0();
        }
        (void) spl0();
+       return;
+
+bad:
+       bp->b_flags |= B_ERROR;
+       iodone(bp);
+       return;
 }
 
 }
 
-/*
- * Start activity on specified drive; called when drive is inactive
- * and new transfer request arrives and also when upas indicates that
- * a SEARCH command is complete.
- */
-upustart(unit)
-register unit;
+upustart(ui)
+       register struct uba_dinfo *ui;
 {
        register struct buf *bp, *dp;
 {
        register struct buf *bp, *dp;
-       register struct device *upaddr = UPADDR;
+       register struct uba_minfo *um;
+       register struct device *upaddr;
+       register struct upst *st;
        daddr_t bn;
        int sn, cn, csn;
        int didie = 0;
 
        daddr_t bn;
        int sn, cn, csn;
        int didie = 0;
 
-       /*
-        * Other drivers tend to say something like
-        *      upaddr->upcs1 = IE;
-        *      upaddr->upas = 1<<unit;
-        * here, but some controllers will cancel a command
-        * happens to be sitting in the cs1 if you clear the go
-        * bit by storing there (so the first is not safe).
-        *
-        * Thus we keep careful track of when we re-enable IE
-        * after an interrupt and do it only if we didn't issue
-        * a command which re-enabled it as a matter of course.
-        * We clear bits in upas in the interrupt routine, when
-        * no transfers are active.
-        */
-       if (unit >= NUP)
-               goto out;
-       if (unit+UPDK_N <= UPDK_NMAX)
-               dk_busy &= ~(1<<(unit+UPDK_N));
-       dp = &uputab[unit];
+       /* SC21 cancels commands if you say cs1 = IE, so dont */
+       /* being ultra-cautious, we clear as bits only in upintr() */
+       dk_busy &= ~(1<<ui->ui_dk);
+       dp = &uputab[ui->ui_unit];
        if ((bp = dp->b_actf) == NULL)
                goto out;
        if ((bp = dp->b_actf) == NULL)
                goto out;
-       /*
-        * Most controllers don't start SEARCH commands when transfers are
-        * in progress.  In fact, some tend to get confused when given
-        * SEARCH'es during transfers, generating interrupts with neither
-        * RDY nor a bit in the upas register.  Thus we defer
-        * until an interrupt when a transfer is pending.
-        */
-       if (uptab.b_active) {
-               upsoftas |= 1<<unit;
+       /* dont confuse controller by giving SEARCH while dt in progress */
+       um = ui->ui_mi;
+       if (um->um_tab.b_active) {
+               up_softc[um->um_num].sc_softas |= 1<<ui->ui_slave;
                return (0);
        }
        if (dp->b_active)
                goto done;
        dp->b_active = 1;
                return (0);
        }
        if (dp->b_active)
                goto done;
        dp->b_active = 1;
-       if ((upaddr->upcs2 & 07) != unit)
-               upaddr->upcs2 = unit;
-       /*
-        * If we have changed packs or just initialized,
-        * then the volume will not be valid; if so, clear
-        * the drive, preset it and put in 16bit/word mode.
-        */
+       upaddr = (struct device *)um->um_addr;
+       upaddr->upcs2 = ui->ui_slave;
        if ((upaddr->upds & VV) == 0) {
                upaddr->upcs1 = IE|DCLR|GO;
                upaddr->upcs1 = IE|PRESET|GO;
        if ((upaddr->upds & VV) == 0) {
                upaddr->upcs1 = IE|DCLR|GO;
                upaddr->upcs1 = IE|PRESET|GO;
@@ -242,110 +247,82 @@ 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.
-        * If we are on the correct cylinder and the desired sector
-        * lies between upSDIST and upSDIST+upRDIST sectors ahead of us, then
-        * we don't bother to SEARCH but just begin the transfer asap.
-        * Otherwise ask for a interrupt upSDIST sectors ahead.
-        */
+       st = &upst[ui->ui_type];
        bn = dkblock(bp);
        cn = bp->b_cylin;
        bn = dkblock(bp);
        cn = bp->b_cylin;
-       sn = bn%(NSECT*NTRAC);
-       sn = (sn+NSECT-upSDIST)%NSECT;
-
+       sn = bn%st->nspc;
+       sn = (sn + st->nsect - upSDIST) % st->nsect;
        if (cn - upaddr->updc)
                goto search;            /* Not on-cylinder */
        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;
        if (csn < 0)
        else if (upseek)
                goto done;              /* Ok just to be on-cylinder */
        csn = (upaddr->upla>>6) - sn - 1;
        if (csn < 0)
-               csn += NSECT;
-       if (csn > NSECT-upRDIST)
+               csn += st->nsect;
+       if (csn > st->nsect - upRDIST)
                goto done;
                goto done;
-
 search:
        upaddr->updc = cn;
 search:
        upaddr->updc = cn;
+/***                           ANOTHER OCCURRENCE
        if (upseek)
                upaddr->upcs1 = IE|SEEK|GO;
        if (upseek)
                upaddr->upcs1 = IE|SEEK|GO;
-       else {
+       else  ****/   {
                upaddr->upda = sn;
                upaddr->upcs1 = IE|SEARCH|GO;
        }
        didie = 1;
                upaddr->upda = sn;
                upaddr->upcs1 = IE|SEARCH|GO;
        }
        didie = 1;
-       /*
-        * Mark this unit busy.
-        */
-       unit += UPDK_N;
-       if (unit <= UPDK_NMAX) {
-               dk_busy |= 1<<unit;
-               dk_seek[unit]++;
+       if (ui->ui_dk >= 0) {
+               dk_busy |= 1<<ui->ui_dk;
+               dk_seek[ui->ui_dk]++;
        }
        goto out;
        }
        goto out;
-#endif
-
 done:
 done:
-       /*
-        * This unit is ready to go so
-        * link it onto the chain of ready disks.
-        */
        dp->b_forw = NULL;
        dp->b_forw = NULL;
-       if (uptab.b_actf == NULL)
-               uptab.b_actf = dp;
+       if (um->um_tab.b_actf == NULL)
+               um->um_tab.b_actf = dp;
        else
        else
-               uptab.b_actl->b_forw = dp;
-       uptab.b_actl = dp;
-
+               um->um_tab.b_actl->b_forw = dp;
+       um->um_tab.b_actl = dp;
 out:
        return (didie);
 }
 
 out:
        return (didie);
 }
 
-/*
- * Start a transfer; call from top level at spl5() or on interrupt.
- */
-upstart()
+upstart(um)
+       register struct uba_minfo *um;
 {
        register struct buf *bp, *dp;
 {
        register struct buf *bp, *dp;
+       register struct uba_dinfo *ui;
        register unit;
        register struct device *upaddr;
        register unit;
        register struct device *upaddr;
+       register struct upst *st;
        daddr_t bn;
        int dn, sn, tn, cn, cmd;
 
 loop:
        daddr_t bn;
        int dn, sn, tn, cn, cmd;
 
 loop:
-       /*
-        * Pick a drive off the queue of ready drives, and
-        * perform the first transfer on its queue.
-        *
-        * Looping here is completely for the sake of drives which
-        * are not present and on-line, for which we completely clear the
-        * request queue.
-        */
-       if ((dp = uptab.b_actf) == NULL)
+       if ((dp = um->um_tab.b_actf) == NULL)
                return (0);
        if ((bp = dp->b_actf) == NULL) {
                return (0);
        if ((bp = dp->b_actf) == NULL) {
-               uptab.b_actf = dp->b_forw;
+               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.
         */
                goto loop;
        }
        /*
         * Mark the controller busy, and multi-part disk address.
         * Select the unit on which the i/o is to take place.
         */
-       uptab.b_active++;
-       unit = minor(bp->b_dev) & 077;
-       dn = dkunit(bp);
+       um->um_tab.b_active++;
+       ui = updinfo[dkunit(bp)];
        bn = dkblock(bp);
        bn = dkblock(bp);
-       cn = up_sizes[unit&07].cyloff;
-       cn += bn/(NSECT*NTRAC);
-       sn = bn%(NSECT*NTRAC);
-       tn = sn/NSECT;
-       sn %= NSECT;
-       upaddr = UPADDR;
+       dn = ui->ui_slave;
+       st = &upst[ui->ui_type];
+       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;
        if ((upaddr->upcs2 & 07) != dn)
                upaddr->upcs2 = dn;
-       up_ubinfo = ubasetup(bp, 1);
+       up_softc[um->um_num].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
        /*
         * If drive is not present and on-line, then
         * get rid of this with an error and loop to get
@@ -356,14 +333,14 @@ loop:
                printf("!DPR || !MOL, unit %d, ds %o", dn, upaddr->upds);
                if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) {
                        printf("-- hard\n");
                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;
+                       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 ... */
                        dp->b_actf = bp->av_forw;
                        dp->b_active = 0;
                        bp->b_flags |= B_ERROR;
                        iodone(bp);
                        /* A funny place to do this ... */
-                       ubarelse(&up_ubinfo);
+                       ubarelse(&up_softc[um->um_num].sc_info);
                        goto loop;
                }
                printf("-- came back\n");
                        goto loop;
                }
                printf("-- came back\n");
@@ -372,8 +349,8 @@ 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_READ) != 0) {
-               upaddr->upof = up_offset[uptab.b_errcnt & 017] | FMT22;
+       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)
                        DELAY(25);
                upaddr->upcs1 = IE|OFFSET|GO;
                while (upaddr->upds & PIP)
                        DELAY(25);
@@ -385,9 +362,9 @@ loop:
         */
        upaddr->updc = cn;
        upaddr->upda = (tn << 8) + sn;
         */
        upaddr->updc = cn;
        upaddr->upda = (tn << 8) + sn;
-       upaddr->upba = up_ubinfo;
+       upaddr->upba = up_softc[um->um_num].sc_info;
        upaddr->upwc = -bp->b_bcount / sizeof (short);
        upaddr->upwc = -bp->b_bcount / sizeof (short);
-       cmd = (up_ubinfo >> 8) & 0x300;
+       cmd = (up_softc[um->um_num].sc_info >> 8) & 0x300;
        if (bp->b_flags & B_READ)
                cmd |= IE|RCOM|GO;
        else
        if (bp->b_flags & B_READ)
                cmd |= IE|RCOM|GO;
        else
@@ -400,130 +377,88 @@ loop:
         * us in which case we record this as a drive busy
         * (if there is room for that).
         */
         * us in which case we record this as a drive busy
         * (if there is room for that).
         */
-       unit = dn+UPDK_N;
-       if (unit <= UPDK_NMAX) {
-               dk_busy |= 1<<unit;
-               dk_xfer[unit]++;
-               dk_wds[unit] += bp->b_bcount>>6;
-       }
+       unit = ui->ui_dk;
+       dk_busy |= 1<<unit;
+       dk_xfer[unit]++;
+       dk_wds[unit] += bp->b_bcount>>6;
        return (1);
 }
 
        return (1);
 }
 
+updgo()
+{
+}
+
 /*
  * 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
 /*
  * 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 uptab, and then restart
+ * their blocks to the ready queue in um->um_tab, and then restart
  * the controller if there is anything to do.
  */
  * the controller if there is anything to do.
  */
-upintr()
+upintr(sc21)
+       register sc21;
 {
        register struct buf *bp, *dp;
 {
        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 unit;
        register unit;
-       register struct device *upaddr = UPADDR;
        int as = upaddr->upas & 0377;
        int as = upaddr->upas & 0377;
-       int oupsoftas;
        int needie = 1;
 
        (void) spl6();
        int needie = 1;
 
        (void) spl6();
-       up_wticks = 0;
-       if (uptab.b_active) {
-               /*
-                * The drive is transferring, thus the hardware
-                * (say the designers) will only interrupt when the transfer
-                * completes; check for it anyways.
-                */
+       up_softc[um->um_num].sc_wticks = 0;
+       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);
                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, uptab.b_active,
+                       printf("as=%d act %d %d %d\n", as, um->um_tab.b_active,
                            uputab[0].b_active, uputab[1].b_active);
                }
                            uputab[0].b_active, uputab[1].b_active);
                }
-               /*
-                * Mark drive not busy, and check for an
-                * error condition which may have resulted from the transfer.
-                */
-               dp = uptab.b_actf;
+               dp = um->um_tab.b_actf;
                bp = dp->b_actf;
                bp = dp->b_actf;
-               unit = dkunit(bp);
-               if (UPDK_N+unit <= UPDK_NMAX)
-                       dk_busy &= ~(1<<(UPDK_N+unit));
-               if ((upaddr->upcs2 & 07) != unit)
-                       upaddr->upcs2 = unit;
+               ui = updinfo[dkunit(bp)];
+               dk_busy &= ~(1 << ui->ui_dk);
+               upaddr->upcs2 = ui->ui_slave;
                if ((upaddr->upds&ERR) || (upaddr->upcs1&TRE)) {
                        int cs2;
                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
-                        * intervened to change the selected unit), and
-                        * wait for the command which caused the interrupt
-                        * to complete (DRY).
-                        */
                        while ((upaddr->upds & DRY) == 0)
                                DELAY(25);
                        while ((upaddr->upds & DRY) == 0)
                                DELAY(25);
-                       /*
-                        * After 28 retries (16 w/o servo offsets, and then
-                        * 12 with servo offsets), or if we encountered
-                        * an error because the drive is write-protected,
-                        * give up.  Print an error message on the last 2
-                        * retries before a hard failure.
-                        */
-                       if (++uptab.b_errcnt > 28 || upaddr->uper1&WLE)
+                       if (++um->um_tab.b_errcnt > 28 || upaddr->uper1&WLE)
                                bp->b_flags |= B_ERROR;
                        else
                                bp->b_flags |= B_ERROR;
                        else
-                               uptab.b_active = 0;     /* To force retry */
-                       if (uptab.b_errcnt > 27)
+                               um->um_tab.b_active = 0; /* force retry */
+                       if (um->um_tab.b_errcnt > 27) {
                                cs2 = (int)upaddr->upcs2;
                                cs2 = (int)upaddr->upcs2;
-                               deverror(bp, (int)upaddr->upcs2,
-                                   (int)upaddr->uper1);
-                       /*
-                        * If this was a correctible ECC error, let upecc
-                        * do the dirty work to correct it.  If upecc
-                        * starts another READ for the rest of the data
-                        * then it returns 1 (having set uptab.b_active).
-                        * Otherwise we are done and fall through to
-                        * finish up.
-                        */
-                       if ((upaddr->uper1&(DCK|ECH))==DCK && upecc(upaddr, bp))
+                               deverror(bp, cs2, (int)upaddr->uper1);
+                       }
+                       if ((upaddr->uper1&(DCK|ECH))==DCK && upecc(ui))
                                return;
                                return;
-                       /*
-                        * Clear the drive and, every 4 retries, recalibrate
-                        * to hopefully help clear up seek positioning problems.
-                        */
                        upaddr->upcs1 = TRE|IE|DCLR|GO;
                        needie = 0;
                        upaddr->upcs1 = TRE|IE|DCLR|GO;
                        needie = 0;
-                       if ((uptab.b_errcnt&07) == 4) {
+                       if ((um->um_tab.b_errcnt&07) == 4) {
                                upaddr->upcs1 = RECAL|GO|IE;
                                while(upaddr->upds & PIP)
                                        DELAY(25);
                        }
                                upaddr->upcs1 = RECAL|GO|IE;
                                while(upaddr->upds & PIP)
                                        DELAY(25);
                        }
-                       if (uptab.b_errcnt == 28 && cs2&(NEM|MXF)) {
+                       if (um->um_tab.b_errcnt == 28 && cs2&(NEM|MXF)) {
                                printf("FLAKEY UP ");
                                printf("FLAKEY UP ");
-                               ubareset();
+                               ubareset(um->um_ubanum);
                                return;
                        }
                }
                                return;
                        }
                }
-               /*
-                * If we are still noted as active, then no
-                * (further) retries are necessary.  
-                *
-                * Make sure the correct unit is selected,
-                * return it to centerline if necessary, and mark
-                * this i/o complete, starting the next transfer
-                * on this drive with the upustart routine (if any).
-                */
-               if (uptab.b_active) {
-                       if (uptab.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)
                                        DELAY(25);
                                needie = 0;
                        }
                                upaddr->upcs1 = RTC|GO|IE;
                                while (upaddr->upds & PIP)
                                        DELAY(25);
                                needie = 0;
                        }
-                       uptab.b_active = 0;
-                       uptab.b_errcnt = 0;
-                       uptab.b_actf = dp->b_forw;
+                       um->um_tab.b_active = 0;
+                       um->um_tab.b_errcnt = 0;
+                       um->um_tab.b_actf = dp->b_forw;
                        dp->b_active = 0;
                        dp->b_errcnt = 0;
                        dp->b_actf = bp->av_forw;
                        dp->b_active = 0;
                        dp->b_errcnt = 0;
                        dp->b_actf = bp->av_forw;
@@ -533,36 +468,29 @@ upintr()
                                    bp->b_resid, upaddr->upds,
                                    upaddr->uper1, upaddr->uper2, upaddr->uper3);
                        iodone(bp);
                                    bp->b_resid, upaddr->upds,
                                    upaddr->uper1, upaddr->uper2, upaddr->uper3);
                        iodone(bp);
-                       if(dp->b_actf)
-                               if (upustart(unit))
+                       if (dp->b_actf)
+                               if (upustart(ui))
                                        needie = 0;
                }
                                        needie = 0;
                }
-               as &= ~(1<<unit);
-               upsoftas &= ~(1<<unit);
-               ubarelse(&up_ubinfo);
+               up_softc[um->um_num].sc_softas &= ~(1<<ui->ui_slave);
+               ubarelse(&up_softc[um->um_num].sc_info);
        } else {
                if (upaddr->upcs1 & TRE)
                        upaddr->upcs1 = TRE;
        }
        } else {
                if (upaddr->upcs1 & TRE)
                        upaddr->upcs1 = TRE;
        }
-       /*
-        * If we have a unit with an outstanding SEARCH,
-        * and the hardware indicates the unit requires attention,
-        * the bring the drive to the ready queue.
-        * Finally, if the controller is not transferring
-        * start it if any drives are now ready to transfer.
-        */
-       as |= upsoftas;
-       oupsoftas = upsoftas;
-       upsoftas = 0;
-       for (unit = 0; unit < NUP; unit++)
-               if ((as|oupsoftas) & (1<<unit)) {
+       as |= up_softc[um->um_num].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 (as & (1<<unit))
                                upaddr->upas = 1<<unit;
-                       if (upustart(unit))
+                       if (upustart(ui))
                                needie = 0;
                }
                                needie = 0;
                }
-       if (uptab.b_actf && uptab.b_active == 0)
-               if (upstart())
+       }
+       if (um->um_tab.b_actf && um->um_tab.b_active == 0)
+               if (upstart(um))
                        needie = 0;
        if (needie)
                upaddr->upcs1 = IE;
                        needie = 0;
        if (needie)
                upaddr->upcs1 = IE;
@@ -570,13 +498,11 @@ upintr()
 
 upread(dev)
 {
 
 upread(dev)
 {
-
        physio(upstrategy, &rupbuf, dev, B_READ, minphys);
 }
 
 upwrite(dev)
 {
        physio(upstrategy, &rupbuf, dev, B_READ, minphys);
 }
 
 upwrite(dev)
 {
-
        physio(upstrategy, &rupbuf, dev, B_WRITE, minphys);
 }
 
        physio(upstrategy, &rupbuf, dev, B_WRITE, minphys);
 }
 
@@ -586,11 +512,14 @@ upwrite(dev)
  * the transfer may be going to an odd memory address base and/or
  * across a page boundary.
  */
  * the transfer may be going to an odd memory address base and/or
  * across a page boundary.
  */
-upecc(up, bp)
-register struct device *up;
-register struct buf *bp;
+upecc(ui)
+       register struct uba_dinfo *ui;
 {
 {
-       struct uba_regs *ubp = (struct uba_regs *)UBA0;
+       register struct device *up = (struct device *)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;
+       struct uba_regs *ubp = ui->ui_hd->uh_uba;
        register int i;
        caddr_t addr;
        int reg, bit, byte, npf, mask, o, cmd, ubaddr;
        register int i;
        caddr_t addr;
        int reg, bit, byte, npf, mask, o, cmd, ubaddr;
@@ -603,7 +532,7 @@ register struct buf *bp;
         * 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_ubinfo&0x3ffff) + npf;
+       reg = btop(up_softc[um->um_num].sc_info&0x3ffff) + npf;
        o = (int)bp->b_un.b_addr & PGOFSET;
        printf("%D ", bp->b_blkno+npf);
        prdev("ECC", bp->b_dev);
        o = (int)bp->b_un.b_addr & PGOFSET;
        printf("%D ", bp->b_blkno+npf);
        prdev("ECC", bp->b_dev);
@@ -618,7 +547,7 @@ register struct buf *bp;
         * 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_ubinfo>>28)&0x0f] |= BNE;
+       ubp->uba_dpr[(up_softc[um->um_num].sc_info>>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;
@@ -637,7 +566,7 @@ register struct buf *bp;
                i++;
                bit -= 8;
        }
                i++;
                bit -= 8;
        }
-       uptab.b_active++;       /* Either complete or continuing... */
+       um->um_tab.b_active++;  /* Either complete or continuing... */
        if (up->upwc == 0)
                return (0);
        /*
        if (up->upwc == 0)
                return (0);
        /*
@@ -648,12 +577,13 @@ register struct buf *bp;
         */
        up->upcs1 = TRE|IE|DCLR|GO;
        bn = dkblock(bp);
         */
        up->upcs1 = TRE|IE|DCLR|GO;
        bn = dkblock(bp);
+       st = &upst[ui->ui_type];
        cn = bp->b_cylin;
        cn = bp->b_cylin;
-       sn = bn%(NSECT*NTRAC) + npf + 1;
-       tn = sn/NSECT;
-       sn %= NSECT;
-       cn += tn/NTRAC;
-       tn %= NTRAC;
+       sn = bn%st->nspc + npf + 1;
+       tn = sn/st->nsect;
+       sn %= st->nsect;
+       cn += tn/st->ntrak;
+       tn %= st->ntrak;
        up->updc = cn;
        up->upda = (tn << 8) | sn;
        ubaddr = (int)ptob(reg+1) + o;
        up->updc = cn;
        up->upda = (tn << 8) | sn;
        ubaddr = (int)ptob(reg+1) + o;
@@ -669,24 +599,45 @@ register struct buf *bp;
  * Cancel software state of all pending transfers
  * and restart all units and the controller.
  */
  * Cancel software state of all pending transfers
  * and restart all units and the controller.
  */
-upreset()
+upreset(uban)
 {
 {
-       int unit;
-
+       register struct uba_minfo *um;
+       register struct uba_dinfo *ui;
+       register sc21, unit;
+
+       /* we should really delay the printf & DELAY till we know
+        * that there is at least one sc21 on this UBA, but then
+        * we would have to remember we had done it before, or the
+        * msg would come twice(or whatever) - but perhaps that
+        * wouldn't be such a bad thing - too many delays would
+        * be annoying however
+        */
        printf(" up");
        DELAY(15000000);                /* give it time to self-test */
        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);
-               ubarelse(&up_ubinfo);
-       }
-       UPADDR->upcs2 = CLR;            /* clear controller */
-       for (unit = 0; unit < NUP; unit++) {
-               uputab[unit].b_active = 0;
-               (void) upustart(unit);
+       for (sc21 = 0; sc21 < NSC21; sc21++) {
+               if ((um = upminfo[sc21]) == 0)
+                       continue;
+               if (um->um_ubanum != uban)
+                       continue;
+               if (!um->um_alive)
+                       continue;
+               um->um_tab.b_active = 0;
+               um->um_tab.b_actf = um->um_tab.b_actl = 0;
+               if (up_softc[um->um_num].sc_info) {
+                       printf("<%d>", (up_softc[um->um_num].sc_info>>28)&0xf);
+                       ubarelse(&up_softc[um->um_num].sc_info);
+               }
+               ((struct device *)(um->um_addr))->upcs2 = CLR;
+               for (unit = 0; unit < NUP; unit++) {
+                       if ((ui = updinfo[unit]) == 0)
+                               continue;
+                       if (ui->ui_alive == 0)
+                               continue;
+                       uputab[unit].b_active = 0;
+                       (void) upustart(ui);
+               }
+               (void) upstart(um);
        }
        }
-       (void) upstart();
 }
 
 /*
 }
 
 /*
@@ -697,23 +648,28 @@ upreset()
  */
 upwatch()
 {
  */
 upwatch()
 {
-       int i;
+       register struct uba_minfo *um;
+       register sc21, unit;
 
        timeout(upwatch, (caddr_t)0, HZ);
 
        timeout(upwatch, (caddr_t)0, HZ);
-       if (uptab.b_active == 0) {
-               for (i = 0; i < NUP; i++)
-                       if (uputab[i].b_active)
-                               goto active;
-               up_wticks = 0;          /* idling */
-               return;
-       }
-active:
-       up_wticks++;
-       if (up_wticks >= 20) {
-               up_wticks = 0;
-               printf("LOST INTERRUPT RESET");
-               upreset();
-               printf("\n");
+       for (sc21 = 0; sc21 < NSC21; sc21++) {
+               um = upminfo[sc21];
+               if (um->um_tab.b_active == 0) {
+                       for (unit = 0; unit < NUP; unit++)
+                               if (updinfo[unit]->ui_mi == um &&
+                                   uputab[unit].b_active)
+                                       goto active;
+                       up_softc[sc21].sc_wticks = 0;
+                       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");
+               }
        }
 }
 
        }
 }
 
@@ -726,27 +682,39 @@ updump(dev)
        char *start;
        int num, blk, unit, nsect, ntrak, nspc;
        struct size *sizes;
        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 struct uba_regs *uba;
+       register struct uba_dinfo *ui;
        register short *rp;
        register short *rp;
+       struct upst *st;
        int bdp;
 
        int bdp;
 
-       up->uba_cr = ADINIT;
-       up->uba_cr = IFS|BRIE|USEFIE|SUEFIE;
-       while ((up->uba_cnfgr & UBIC) == 0)
-               ;
-#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);
        }
        unit = minor(dev) >> 3;
        if (unit >= NUP) {
                printf("bad unit\n");
                return (-1);
        }
-       upaddr = UPPHYS;
+#define        phys1(cast, addr) ((cast)((int)addr & 0x7fffffff))
+#define        phys(cast, addr) phys1(cast, phys1(cast *, &addr))
+       ui = phys(struct uba_dinfo *, updinfo[unit]);
+       if (ui->ui_alive == 0) {
+               printf("dna\n");
+               return(-1);
+       }
+       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)
+                       ;
+       }
+#endif
+       DELAY(1000000);
+       upaddr = (struct device *)ui->ui_physaddr;
+       while ((upaddr->upcs1&DVA) == 0)
+               ;
+       num = maxfree;
+       start = 0;
        upaddr->upcs2 = unit;
        if ((upaddr->upds & VV) == 0) {
                upaddr->upcs1 = DCLR|GO;
        upaddr->upcs2 = unit;
        if ((upaddr->upds & VV) == 0) {
                upaddr->upcs1 = DCLR|GO;
@@ -757,12 +725,15 @@ updump(dev)
                printf("up !DPR || !MOL\n");
                return (-1);
        }
                printf("up !DPR || !MOL\n");
                return (-1);
        }
-       nsect = NSECT; ntrak = NTRAC; sizes = up_sizes;
+       st = phys1(struct upst *, &upst[ui->ui_type]);
+       nsect = st->nsect;
+       ntrak = st->ntrak;
+       sizes = phys(struct size *, st->sizes);
        if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) {
        if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) {
-               printf("dumplo+num, sizes %d %d\n", dumplo+num, sizes[minor(dev)&07].nblocks);
+               printf("oor\n");
                return (-1);
        }
                return (-1);
        }
-       nspc = nsect * ntrak;
+       nspc = st->nspc;
        while (num > 0) {
                register struct pte *io;
                register int i;
        while (num > 0) {
                register struct pte *io;
                register int i;
@@ -771,10 +742,10 @@ updump(dev)
 
                blk = num > DBSIZE ? DBSIZE : num;
                bdp = 1;                /* trick pcc */
 
                blk = num > DBSIZE ? DBSIZE : num;
                bdp = 1;                /* trick pcc */
-               ((struct uba_regs *)PHYSUBA0)->uba_dpr[bdp] |= BNE;
-               io = ((struct uba_regs *)PHYSUBA0)->uba_map;
+               uba->uba_dpr[bdp] |= UBA_BNE;
+               io = uba->uba_map;
                for (i = 0; i < blk; i++)
                for (i = 0; i < blk; i++)
-                       *(int *)io++ = (btop(start)+i) | (1<<21) | MRV;
+                       *(int *)io++ = (btop(start)+i) | (1<<21) | UBA_MRV;
                *(int *)io = 0;
                bn = dumplo + btop(start);
                cn = bn/nspc + sizes[minor(dev)&07].cyloff;
                *(int *)io = 0;
                bn = dumplo + btop(start);
                cn = bn/nspc + sizes[minor(dev)&07].cyloff;
@@ -799,7 +770,7 @@ updump(dev)
                num -= blk;
        }
        bdp = 1;                /* crud to fool c compiler */
                num -= blk;
        }
        bdp = 1;                /* crud to fool c compiler */
-       ((struct uba_regs *)PHYSUBA0)->uba_dpr[bdp] |= BNE;
+       uba->uba_dpr[bdp] |= UBA_BNE;
        return (0);
 }
 #endif
        return (0);
 }
 #endif
index 6643507..86e1bb4 100644 (file)
@@ -1,8 +1,13 @@
-/*     autoconf.c      4.1     81/02/08        */
+/*     autoconf.c      4.2     81/02/10        */
+
+#define        dprintf printf
 
 
-#define        dprintf printf
 /*
 /*
- * discover whatever we can about the machine we are running on
+ * Configure the system for your own VAX.
+ * Mostly used for distribution systems,
+ * but parts of this run always.
+ *
+ *     kre/wnj         Berkeley, February 1981
  */
 
  /*** NOT DONE YET 
  */
 
  /*** NOT DONE YET 
        - unibus intr vec setup
        - (probably) lots more wrt UBA's
        - 750 main loop
        - unibus intr vec setup
        - (probably) lots more wrt UBA's
        - 750 main loop
-       - arrange permission to write SCB & give it back
+       - arrange permission to write SCB & give it back  (KLUDGED)
        - set up dk fields in structs
        - make locore.s compatible (incl Scbbase -> _Scbbase)
   ***/
 
 #include "../h/param.h"
        - set up dk fields in structs
        - make locore.s compatible (incl Scbbase -> _Scbbase)
   ***/
 
 #include "../h/param.h"
-#include "../h/ino.h"
-#include "../h/inode.h"
+#include "../h/systm.h"
 #include "../h/map.h"
 #include "../h/nexus.h"
 #include "../h/pte.h"
 #include "../h/buf.h"
 #include "../h/mba.h"
 #include "../h/map.h"
 #include "../h/nexus.h"
 #include "../h/pte.h"
 #include "../h/buf.h"
 #include "../h/mba.h"
-#include "../bert/uba.h"                       /*** TEMPORARY ***/
+#include "../h/uba.h"
 #include "../h/mtpr.h"
 #include "../h/cpu.h"
 #include "../h/scb.h"
 #include "../h/vmparam.h"
 #include "../h/vmmac.h"
 #include "../h/mtpr.h"
 #include "../h/cpu.h"
 #include "../h/scb.h"
 #include "../h/vmparam.h"
 #include "../h/vmmac.h"
+#include "../h/mem.h"
 
 int    mbanum;         /* counts MBA's as we see them */
 
 int    mbanum;         /* counts MBA's as we see them */
-#if    VAX==780 || VAX==ANY
-int    ubanum;         /* same for UBA's */
-#endif
-int    memctl;         /* and memory controllers */
+int    numuba;         /* same for UBA's */
 int    nexnum;         /* current nexus number */
 
 int    nexnum;         /* current nexus number */
 
-extern cpu;
-struct nexus *nxtemp();
-extern struct scb Scbbase;
-struct uba_regs *curuba;
-extern struct pte Nexmap[16][16];
-extern struct nexus nexus[16];
+struct uba_regs *curuba;
 int    catcher[129];
 int    catcher[129];
+extern caddr_t umaddr[];
+extern struct pte UMEMmap[4][16];
+extern char    umem[4][16*128*512];
+
+/* I somehow don't think this will work on a 750 */
+#define        C (caddr_t)
+caddr_t        umaddr[4] = {
+       C 0x2013e000, C 0x2017e000, C 0x201be000, C 0x201fe000
+};
 
 
-extern mba0int(), mba1int(), mba2int(), mba3int();
-extern ua0int(),  ua1int(),  ua2int(),  ua3int();
+extern Xmba0int(), Xmba1int(), Xmba2int(), Xmba3int();
+extern Xua0int(),  Xua1int(),  Xua2int(),  Xua3int();
 
 int    (*mbaintv[4])() = {
 
 int    (*mbaintv[4])() = {
-       mba0int, mba1int, mba2int
-#if    VAX==780 || VAX==ANY
-           mba3int
+       Xmba0int, Xmba1int, Xmba2int,
+#if VAX780
+                                  Xmba3int
 #endif
 };
 
 #endif
 };
 
-#if    VAX==780 || VAX == ANY
+#if VAX780
 int    (*ubaintv[4])() = {
 int    (*ubaintv[4])() = {
-       ua0int, ua1int, ua2int, ua3int
+       Xua0int, Xua1int, Xua2int, Xua3int
 };
 
 extern int     (*UNIvec[])();
 #endif
 
 };
 
 extern int     (*UNIvec[])();
 #endif
 
+int    c780();
+int    c750();
+int    c7ZZ();
+int    c8ZZ();
+
+struct percpu percpu[] = {
+#if VAX780
+       c780,   VAX_780,        4,      1,      4,
+#endif
+#if VAX750
+       c750,   VAX_750,        3,      0,      1,
+#endif
+#if VAX7ZZ
+       c7ZZ,   VAX_7ZZ,        0,      0,      1,
+#endif
+#if VAX8ZZ
+       c8ZZ,   VAX_8ZZ,        4,      4,      4,
+#endif
+};
+#define        NCPU    (sizeof(percpu)/sizeof(struct percpu))
+
 /*
  * Determine mass storage and memory configuration for a machine.
  * Get cpu type, and then switch out to machine specific procedures
 /*
  * Determine mass storage and memory configuration for a machine.
  * Get cpu type, and then switch out to machine specific procedures
@@ -75,39 +102,39 @@ extern     int     (*UNIvec[])();
 configure()
 {
        union cpusid cpusid;
 configure()
 {
        union cpusid cpusid;
+       register struct percpu *ocp;
 
        cpusid.cpusid = mfpr(SID);
 
        cpusid.cpusid = mfpr(SID);
-       switch (cpusid.cpuany.cp_type) {
-
-#if    VAX==780 || VAX==ANY
-       case VAX_780: cpu = 780; c780(); break;
-#endif
-#if    VAX==750 || VAX==ANY
-       case VAX_750: cpu = 750; c750(); break;
-#endif
-
-       default:
-               printf("cpu type %d unsupported\n", cpusid.cpuany.cp_type);
-               panic("config");
-       }
+       for (ocp = percpu; ocp < &percpu[NCPU]; ocp++)
+               if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
+                       cpu = ocp->pc_cputype;
+                       (*ocp->pc_config)(ocp);
+                       /*** SET CATCHER FOR STRAY INTERRUPTS HERE ***/
+                       /*** NB: NOT VECTORS: JUST HANDLER CODE ***/
+                       panic("config done\n");
+                       return;
+               }
+       printf("cpu type %d unsupported\n", cpusid.cpuany.cp_type);
        asm("halt");
 }
 
        asm("halt");
 }
 
-#if    VAX==750 || VAX==ANY
-c750()
+#if VAX750
+c750(ocp)
+       register struct percpu *ocp;
 {
        printf("not yet, sad to say\n");
        asm("halt");
 }
 #endif
 
 {
        printf("not yet, sad to say\n");
        asm("halt");
 }
 #endif
 
-#if    VAX==780 || VAX==ANY
+#if VAX780
 /*
  * Build configuration table for a 780, by looking
  * at the things (mbas and ubas) in the nexus slots
  * and initialzing each appropriately.
  */
 /*
  * Build configuration table for a 780, by looking
  * at the things (mbas and ubas) in the nexus slots
  * and initialzing each appropriately.
  */
-c780()
+c780(pcpu)
+       register struct percpu *pcpu;
 {
        register struct nexus *nxv;
        struct nexus *nxp = NEXBASE;
 {
        register struct nexus *nxv;
        struct nexus *nxp = NEXBASE;
@@ -121,16 +148,14 @@ c780()
                nexcsr = nxv->nexcsr;
                if (nexcsr.nex_csr&NEX_APD)
                        continue;
                nexcsr = nxv->nexcsr;
                if (nexcsr.nex_csr&NEX_APD)
                        continue;
-               dprintf("nexus %d\n", nexnum);
                switch (nexcsr.nex_type) {
 
                case NEX_MBA:
                switch (nexcsr.nex_type) {
 
                case NEX_MBA:
-                       mba_hd[mbanum].mh_mba = (struct mba_regs *)nxv;
-                       mba_hd[mbanum].mh_physmba = (struct mba_regs *)nxp;
-                       mbafind(nxv);
-                       setscbnex(nexnum, mbaintv[mbanum]);
-                       ((struct mba_regs *)nxv)->mba_cr = MBAINIT;
-                       ((struct mba_regs *)nxv)->mba_cr = MBAIE;
+                       if (mbanum >= pcpu->pc_maxmba) {
+                               printf("%d mba's", pcpu->pc_maxmba+1);
+                               goto unsupp;
+                       }
+                       mbafind(nxv, nxp);
                        mbanum++;
                        break;
 
                        mbanum++;
                        break;
 
@@ -138,21 +163,25 @@ c780()
                case NEX_UBA1:
                case NEX_UBA2:
                case NEX_UBA3:
                case NEX_UBA1:
                case NEX_UBA2:
                case NEX_UBA3:
-                       uba_hd[ubanum].uh_uba = (struct uba_regs *)nxv;
-                       uba_hd[ubanum].uh_physuba = (struct uba_regs *)nxp;
-                       ubafind(nxv, nexcsr.nex_type - NEX_UBA0);
-                       setscbnex(nexnum, ubaintv[ubanum]);
-                       if (ubanum == 0)
+                       if (numuba >= pcpu->pc_maxuba) {
+                               printf("%d uba's", pcpu->pc_maxuba+1);
+                               goto unsupp;
+                       }
+                       uba_hd[numuba].uh_bdpfree = 0x7fff;     /* 15 bdp's */
+                       uba_hd[numuba].uh_uba = (struct uba_regs *)nxv;
+                       uba_hd[numuba].uh_physuba = (struct uba_regs *)nxp;
+                       if (numuba == 0)
                                uba_hd[0].uh_vec = UNIvec;
                                uba_hd[0].uh_vec = UNIvec;
-#ifdef notyet
                        else {
                        else {
-                               uba_hd[ubanum].uh_vec =
-                                   (int (**)())memall(NBPG);   /*?????*/
-               /*** FILL IN uh_vec with something useful !!! */
+                               /** WE JUST KNOW THIS WON'T HAPPEN **/
+                               uba_hd[numuba].uh_vec = 0;
+                               /* mapinit() */
                        }
                        }
-                       mapinit(/* some parameters I suppose*/);
-#endif
-                       ubanum++;
+                       i = nexcsr.nex_type - NEX_UBA0;
+                       nxaccess(umaddr[i], UMEMmap[numuba]);
+                       unifind((struct uba_regs *)nxv, umaddr[i], umem[i]);
+                       setscbnex(nexnum, ubaintv[numuba]);
+                       numuba++;
                        break;
 
                case NEX_DR32:
                        break;
 
                case NEX_DR32:
@@ -163,10 +192,11 @@ c780()
                case NEX_MEM4I:
                case NEX_MEM16:
                case NEX_MEM16I:
                case NEX_MEM4I:
                case NEX_MEM16:
                case NEX_MEM16I:
-                               /* What is memfind supposed to do ???? */
-#ifdef notyet
-                       memfind(memctl++);
-#endif
+                       if (nmcr >= pcpu->pc_maxmcr) {
+                               printf("%d mcr's", pcpu->pc_maxmcr+1);
+                               goto unsupp;
+                       }
+                       mcraddr[nmcr++] = (struct mcr *)nxv;
                        break;
 
                case NEX_MPM0:
                        break;
 
                case NEX_MPM0:
@@ -179,7 +209,7 @@ c780()
                default:
                        printf("nexus type %x", nexcsr.nex_type);
     unsupp:
                default:
                        printf("nexus type %x", nexcsr.nex_type);
     unsupp:
-                       printf(" at tr %d unsupported\n", nexnum);
+                       printf(" unsupported (at tr %d)\n", nexnum);
                        continue;
                }
        }
                        continue;
                }
        }
@@ -191,7 +221,8 @@ c780()
  * and look for each device found in the massbus
  * initialization tables.
  */
  * and look for each device found in the massbus
  * initialization tables.
  */
-mbafind(nxp)
+mbafind(nxv, nxp)
+       struct nexus *nxv;
        struct nexus *nxp;
 {
        register struct mba_regs *mdp;
        struct nexus *nxp;
 {
        register struct mba_regs *mdp;
@@ -199,7 +230,10 @@ mbafind(nxp)
        int dn, dt, sn, ds;
        struct mba_info fnd;
 
        int dn, dt, sn, ds;
        struct mba_info fnd;
 
-       mdp = (struct mba_regs *)nxp;
+       mdp = (struct mba_regs *)nxv;
+       mba_hd[mbanum].mh_mba = mdp;
+       mba_hd[mbanum].mh_physmba = (struct mba_regs *)nxp;
+       setscbnex(nexnum, mbaintv[mbanum]);
        fnd.mi_mba = mdp;
        fnd.mi_mbanum = mbanum;
        for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
        fnd.mi_mba = mdp;
        fnd.mi_mbanum = mbanum;
        for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
@@ -229,6 +263,8 @@ mbafind(nxp)
                        mbaconfig(&fnd, dt&MBDT_TYPE);
                }
        }
                        mbaconfig(&fnd, dt&MBDT_TYPE);
                }
        }
+       mdp->mba_cr = MBAINIT;
+       mdp->mba_cr = MBAIE;
 }
 
 /*
 }
 
 /*
@@ -243,7 +279,6 @@ mbaconfig(ni, type)
        register struct mba_info *mi;
        register short *tp;
 
        register struct mba_info *mi;
        register short *tp;
 
-       dprintf("mbaconfig %x\n", type);
        for (mi = mbinit; mi->mi_driver; mi++) {
                if (mi->mi_alive)
                        continue;
        for (mi = mbinit; mi->mi_driver; mi++) {
                if (mi->mi_alive)
                        continue;
@@ -268,39 +303,46 @@ found:
        }
 }
 
        }
 }
 
-ubafind(nxp, i)
-       struct nexus *nxp;
+/*
+ * Find mass storage devices on a UNIBUS.
+ */
+unifind(ubp, puba, vuba)
+       struct uba_regs *ubp;
+       caddr_t puba;
+       caddr_t vuba;
 {
        register br, cvec;                      /* MUST BE r11, r10 */
 {
        register br, cvec;                      /* MUST BE r11, r10 */
-       register struct uba_regs *ubp = (struct uba_regs *)nxp;
-       register short *uba;
-       register struct uba_info *ui;
-       register u_short *sp;
+       register struct uba_dinfo *ui;
+       register u_short *uba = (u_short *)vuba, *sp;
        struct uba_driver *udp;
        struct uba_driver *udp;
-       short *reg;
-       int i;
+       u_short *reg;
+       register i;
+       u_short addr;
 
 
-       uba = (short *)(PHYSUDEV0 + i * PHYSUDEVSZ - 0160000);
-       return;                 /******** ZZZZZZZZZZZ *******/
-#if    VAX==ANY || VAX==780
-       if (cpu == 780) {
+#if VAX780
+       if (ubp) {
                ubp->uba_sr = ubp->uba_sr;
                curuba = ubp;
        }
 #endif
                ubp->uba_sr = ubp->uba_sr;
                curuba = ubp;
        }
 #endif
-#if    VAX==ANY || VAX==750
-       setvecs();
+#if VAX750
+       if (ubp == 0)
+               setvecs();
 #endif
 #endif
-       for (ui = ubinit; udp = ui->ui_driver; ui++) {
-               if (ui->ui_ubanum != ubanum && ui->ui_ubanum != '?')
+       for (ui = ubdinit; udp = ui->ui_driver; ui++) {
+               if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?')
                        continue;
                        continue;
-               for (sp = udp->ud_addr; *sp; sp++) {
-#define        ubaddr(i)       (short *)((int)uba + (i))
-                       reg = ubaddr(*sp);
+               addr = (u_short)ui->ui_addr;
+               sp = udp->ud_addr;
+               for (; addr || *sp; addr = 0) {
+#define        ubaddr(off)     (u_short *)((int)uba + ((off)&0x1fff))
+                       if (addr == 0)
+                               addr = *sp++;
+                       reg = ubaddr(addr);
                        if (badaddr((caddr_t)reg, 2))
                                continue;
                        if (badaddr((caddr_t)reg, 2))
                                continue;
-#if    VAX==780 || VAX==ANY
-                       if (cpu == 780) {
+#if VAX780
+                       if (ubp) {
                                if (ubp->uba_sr) {
                                        ubp->uba_sr = ubp->uba_sr;
                                        continue;
                                if (ubp->uba_sr) {
                                        ubp->uba_sr = ubp->uba_sr;
                                        continue;
@@ -310,8 +352,8 @@ ubafind(nxp, i)
 #endif
                        cvec = 0x200;
                        i = (*udp->ud_cntrlr)(ui, reg);
 #endif
                        cvec = 0x200;
                        i = (*udp->ud_cntrlr)(ui, reg);
-#if    VAX==780 || VAX==ANY
-                       if (cpu == 780) {
+#if VAX780
+                       if (ubp) {
                                ubp->uba_cr = 0;
                                if (ubp->uba_sr) {
                                        ubp->uba_sr = ubp->uba_sr;
                                ubp->uba_cr = 0;
                                if (ubp->uba_sr) {
                                        ubp->uba_sr = ubp->uba_sr;
@@ -321,18 +363,17 @@ ubafind(nxp, i)
 #endif
                        if (i == 0)
                                continue;
 #endif
                        if (i == 0)
                                continue;
-                       printf("\tLocated %c at %o ", ui->ui_name, *sp);
+                       dprintf("\tLocated %c at %o ",
+                           ui->ui_name, addr);
                        if (cvec == 0) {
                        if (cvec == 0) {
-                               printf("zero uba vector\n");
+                               dprintf("zero uba vector\n");
                                continue;
                        }
                        if (cvec == 0x200) {
                                continue;
                        }
                        if (cvec == 0x200) {
-                               printf("didn't interrupt\n");
+                               dprintf("didn't interrupt\n");
                                continue;
                        }
                                continue;
                        }
-                       printf("vector %o, ipl %x\n", cvec, br);
-                       if (ui->ui_slave == -1)
-                               goto ubdevfnd;
+                       dprintf("vector %o, ipl %x\n", cvec, br);
                        if (ui->ui_slave != '?') {
                                if ((*udp->ud_slave)(ui, reg, ui->ui_slave))
                                        goto ubdevfnd;
                        if (ui->ui_slave != '?') {
                                if ((*udp->ud_slave)(ui, reg, ui->ui_slave))
                                        goto ubdevfnd;
@@ -340,15 +381,37 @@ ubafind(nxp, i)
                        }
                        for (i = 0; i < udp->ud_maxslave; i++) {
                                if ((*udp->ud_slave)(ui, reg, i)) {
                        }
                        for (i = 0; i < udp->ud_maxslave; i++) {
                                if ((*udp->ud_slave)(ui, reg, i)) {
+                                       int     (**ivec)();
+
                                        ui->ui_slave = i;
     ubdevfnd:
                                        ui->ui_alive = 1;
                                        ui->ui_slave = i;
     ubdevfnd:
                                        ui->ui_alive = 1;
-                                       ui->ui_ubanum = ubanum;
-                                       ui->ui_hd = &uba_hd[ubanum];
+                                       ui->ui_ubanum = numuba;
+                                       ui->ui_hd = &uba_hd[numuba];
                                        ui->ui_addr = (caddr_t)reg;
                                        ui->ui_addr = (caddr_t)reg;
-                                       /* there must be more, surely !!! */
-                                       /* NB: it is drivers responsibility  */
-                                       /* to fill in ui_type if it wants it */
+                                       ui->ui_physaddr = puba + (addr&0x1fff);
+                                       ui->ui_dk = 0;
+                                       /* ui_type comes from driver */
+                                       udp->ud_info[ui->ui_unit] = ui;
+                                       dprintf("\tslave %d\n", ui->ui_slave);
+                                       for (ivec=udp->ud_intr; *ivec; ivec++) {
+                                               caddr_t cp;
+                                               int fn;
+
+                                               if ((cp = calloc(12)) == 0)
+                                                       panic("nm/iv\n");
+                                               ui->ui_hd->uh_vec[cvec] =
+                                                   scbentry((int (*)()) cp,
+                                                       SCB_ISTACK);
+                                               *cp++ = 0xbb; *cp++ = 0xff;
+                                               *cp++ = 0xdd;
+                                               *cp++ = ui->ui_unit&0x3f;
+                                               *cp++ = 1; *cp++ = 0x9f;
+                                               fn = (int)*ivec;
+                                               for (i=0; i<4; i++)
+                                                       *cp++ = fn, fn >>= 4;
+                                               *cp = 0x02;
+                                       }
                                        break;
                                }
                        }
                                        break;
                                }
                        }
@@ -356,7 +419,7 @@ ubafind(nxp, i)
        }
 }
 
        }
 }
 
-#if    VAX==750 || VAX==ANY
+#if VAX750
 /*
  * For machines which vector unibus interrupts directly,
  * we must spray the unibus vector with pointers to distinct
 /*
  * For machines which vector unibus interrupts directly,
  * we must spray the unibus vector with pointers to distinct
@@ -369,51 +432,30 @@ setvecs()
 {
        register int i;
 
 {
        register int i;
 
-       if (cpu == 780)
-               return;
        for (i = 0; i < 128; i++) {
                catcher[i] = 0x015a04c2;        /* subl2 $4,r10; nop */
                Scbbase.scb_ubaint[i] = 
                    scbentry((int (*)())&catcher[i], SCB_ISTACK);
        for (i = 0; i < 128; i++) {
                catcher[i] = 0x015a04c2;        /* subl2 $4,r10; nop */
                Scbbase.scb_ubaint[i] = 
                    scbentry((int (*)())&catcher[i], SCB_ISTACK);
-                   /**** WHAT IS scbentry() ???? ****/
        }
        catcher[i] = 0x025b12db;                /* mfpr $IPL,r11; rei */
 }
 #endif
 
        }
        catcher[i] = 0x025b12db;                /* mfpr $IPL,r11; rei */
 }
 #endif
 
-#if    VAX==780 || VAX==ANY
-/*
- * The routine used to catch br 4/5/6/7 interrupts
- * on vaxen with unibus adaptors.  This looks at the
- * resulting vector register to tell where the interrupt
- * occurred.
- */
-ubaintr()
-{
-       register int br, cvec;          /* MUST BE r11, r10 */
-       int ubaintr0();
-
-asm(".align 2");
-asm(".globl _ubaintr0");
-asm("_ubaintr0:");
-       br = mfpr(IPL);
-       cvec = curuba->uba_brrvr[br-0x14] & 0xffff;
-       { asm("rei"); }
-}
-
+#if VAX780
 /*
  * Init for testing vector addresses on a
 /*
  * Init for testing vector addresses on a
- * machine where interrupts are vectored through a uba.
+ * machine that has a UNIBUS adaptor to recieve interrupts
  */
 ubatstvec(ubp)
        register struct uba_regs *ubp;
 {
        register struct scb *sp = &Scbbase;
  */
 ubatstvec(ubp)
        register struct uba_regs *ubp;
 {
        register struct scb *sp = &Scbbase;
+       extern int Xconfuaint();
        
        sp->scb_ipl14[nexnum] = sp->scb_ipl15[nexnum] =
            sp->scb_ipl16[nexnum] = sp->scb_ipl17[nexnum] =
        
        sp->scb_ipl14[nexnum] = sp->scb_ipl15[nexnum] =
            sp->scb_ipl16[nexnum] = sp->scb_ipl17[nexnum] =
-               scbentry(ubaintr0, SCB_ISTACK);
-       ubp->uba_cr = IFS|BRIE;
+               scbentry(Xconfuaint, SCB_ISTACK);
+       ubp->uba_cr = UBA_IFS|UBA_BRIE;
 }
 #endif
 
 }
 #endif