BSD 4_4 release
[unix-history] / usr / src / sys / vax / mba / mba.c
index f908daa..0a4d48c 100644 (file)
@@ -1,24 +1,37 @@
-/*     mba.c   4.20    81/05/09        */
+/*-
+ * Copyright (c) 1982 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This module is believed to contain source code proprietary to AT&T.
+ * Use and redistribution is subject to the Berkeley Software License
+ * Agreement and your Software Agreement with AT&T (Western Electric).
+ *
+ *     @(#)mba.c       7.6 (Berkeley) 5/8/91
+ */
 
 #include "mba.h"
 #if NMBA > 0
 /*
  * Massbus driver, arbitrates a massbus among attached devices.
  */
 
 #include "mba.h"
 #if NMBA > 0
 /*
  * Massbus driver, arbitrates a massbus among attached devices.
  */
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/dk.h"
-#include "../h/buf.h"
-#include "../h/conf.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/proc.h"
-#include "../h/map.h"
-#include "../h/pte.h"
-#include "../h/mbareg.h"
-#include "../h/mbavar.h"
-#include "../h/mtpr.h"
-#include "../h/vm.h"
+#include "../include/pte.h"
+
+#include "sys/param.h"
+#include "sys/systm.h"
+#include "sys/dkstat.h"
+#include "sys/buf.h"
+#include "sys/conf.h"
+#include "sys/user.h"
+#include "sys/proc.h"
+#include "sys/map.h"
+#include "../include/mtpr.h"
+#include "sys/vm.h"
+
+#include "mbareg.h"
+#include "mbavar.h"
+
+/* mbunit should be the same as hpunit, etc.! */
+#define mbunit(dev)    (minor(dev) >> 3)
 
 char   mbsr_bits[] = MBSR_BITS;
 /*
 
 char   mbsr_bits[] = MBSR_BITS;
 /*
@@ -54,7 +67,7 @@ loop:
                mi->mi_tab.b_active = 0;
                mi->mi_tab.b_errcnt = 0;
                mi->mi_tab.b_actf = bp->av_forw;
                mi->mi_tab.b_active = 0;
                mi->mi_tab.b_errcnt = 0;
                mi->mi_tab.b_actf = bp->av_forw;
-               iodone(bp);
+               biodone(bp);
                goto loop;
 
        case MBU_DODATA:        /* all ready to do data transfer */
                goto loop;
 
        case MBU_DODATA:        /* all ready to do data transfer */
@@ -119,6 +132,7 @@ mbstart(mhp)
        struct buf *bp;
        register struct mba_regs *mbp;
        register int com;
        struct buf *bp;
        register struct mba_regs *mbp;
        register int com;
+       extern int cold;
 
 loop:
        /*
 
 loop:
        /*
@@ -134,15 +148,28 @@ loop:
        /*
         * If this device isn't present and on-line, then
         * we screwed up, and can't really do the operation.
        /*
         * If this device isn't present and on-line, then
         * we screwed up, and can't really do the operation.
+        * Only check for non-tapes because tape drivers check
+        * ONLINE themselves and because TU78 registers are
+        * different.
+        * No complaints during autoconfiguration,
+        * when we try to read disk labels from anything on line.
         */
         */
+       if (((com = mi->mi_drv->mbd_dt) & MBDT_TAP) == 0)
        if ((mi->mi_drv->mbd_ds & MBDS_DREADY) != MBDS_DREADY) {
        if ((mi->mi_drv->mbd_ds & MBDS_DREADY) != MBDS_DREADY) {
-               printf("%s%d: not ready\n", mi->mi_driver->md_dname,
-                   dkunit(bp));
+               if (!cold) {
+                   if ((com & MBDT_TYPE) == 0) {
+                       mi->mi_alive = 0;
+                       printf("%s%d: nonexistent\n", mi->mi_driver->md_dname,
+                           mbunit(bp->b_dev));
+                   } else
+                       printf("%s%d: not ready\n", mi->mi_driver->md_dname,
+                           mbunit(bp->b_dev));
+               }
                mi->mi_tab.b_actf = bp->av_forw;
                mi->mi_tab.b_errcnt = 0;
                mi->mi_tab.b_active = 0;
                bp->b_flags |= B_ERROR;
                mi->mi_tab.b_actf = bp->av_forw;
                mi->mi_tab.b_errcnt = 0;
                mi->mi_tab.b_active = 0;
                bp->b_flags |= B_ERROR;
-               iodone(bp);
+               biodone(bp);
                goto loop;
        }
        /*
                goto loop;
        }
        /*
@@ -152,11 +179,8 @@ loop:
         * on disks).
         */
        mhp->mh_active = 1;
         * on disks).
         */
        mhp->mh_active = 1;
-       if (mi->mi_driver->md_start) {
-               if ((com = (*mi->mi_driver->md_start)(mi)) == 0)
-                       com = (bp->b_flags & B_READ) ?
-                           MB_RCOM|MB_GO : MB_WCOM|MB_GO;
-       } else
+       if (mi->mi_driver->md_start == (int (*)())0 ||
+           (com = (*mi->mi_driver->md_start)(mi)) == 0)
                com = (bp->b_flags & B_READ) ? MB_RCOM|MB_GO : MB_WCOM|MB_GO;
 
        /*
                com = (bp->b_flags & B_READ) ? MB_RCOM|MB_GO : MB_WCOM|MB_GO;
 
        /*
@@ -165,13 +189,21 @@ loop:
         */
        mbp = mi->mi_mba;
        mbp->mba_sr = -1;       /* conservative */
         */
        mbp = mi->mi_mba;
        mbp->mba_sr = -1;       /* conservative */
-       mbp->mba_var = mbasetup(mi);
-       mbp->mba_bcr = -bp->b_bcount;
+       if (bp->b_bcount >= 0) {
+               mbp->mba_var = mbasetup(mi) + mi->mi_tab.b_bdone;
+               mbp->mba_bcr = -(bp->b_bcount - mi->mi_tab.b_bdone);
+       } else {
+               mbp->mba_var = mbasetup(mi) - bp->b_bcount - mi->mi_tab.b_bdone - 1;
+               mbp->mba_bcr = bp->b_bcount + mi->mi_tab.b_bdone;
+       }
        mi->mi_drv->mbd_cs1 = com;
        if (mi->mi_dk >= 0) {
                dk_busy |= 1 << mi->mi_dk;
                dk_xfer[mi->mi_dk]++;
        mi->mi_drv->mbd_cs1 = com;
        if (mi->mi_dk >= 0) {
                dk_busy |= 1 << mi->mi_dk;
                dk_xfer[mi->mi_dk]++;
-               dk_wds[mi->mi_dk] += bp->b_bcount >> 6;
+               if (bp->b_bcount >= 0)
+                       dk_wds[mi->mi_dk] += bp->b_bcount >> 6;
+               else
+                       dk_wds[mi->mi_dk] += -(bp->b_bcount) >> 6;
        }
 }
 
        }
 }
 
@@ -188,6 +220,7 @@ mbintr(mbanum)
        register struct buf *bp;
        register int drive;
        int mbasr, as;
        register struct buf *bp;
        register int drive;
        int mbasr, as;
+       extern struct mba_device *mbaconfig();
        
        /*
         * Read out the massbus status register
        
        /*
         * Read out the massbus status register
@@ -230,7 +263,7 @@ mbintr(mbanum)
                         */
                        mi->mi_tab.b_errcnt = 0;
                        mi->mi_tab.b_actf = bp->av_forw;
                         */
                        mi->mi_tab.b_errcnt = 0;
                        mi->mi_tab.b_actf = bp->av_forw;
-                       iodone(bp);
+                       biodone(bp);
                        /* fall into... */
                case MBD_RETRY:         /* attempt the operation again */
                        /*
                        /* fall into... */
                case MBD_RETRY:         /* attempt the operation again */
                        /*
@@ -246,7 +279,16 @@ mbintr(mbanum)
                                mbustart(mi);
                        break;
 
                                mbustart(mi);
                        break;
 
-               case MBD_RESTARTED:     /* driver restarted op (ecc, e.g.)
+               case MBD_REPOSITION:    /* driver started repositioning */
+                       /*
+                        * Drive is repositioning, not doing data transfer.
+                        * Free controller, but don't have to restart drive.
+                        */
+                       mhp->mh_active = 0;
+                       mhp->mh_actf = mi->mi_forw;
+                       break;
+
+               case MBD_RESTARTED:     /* driver restarted op (ecc, e.g.) */
                        /*
                         * Note that mhp->mh_active is still on.
                         */
                        /*
                         * Note that mhp->mh_active is still on.
                         */
@@ -260,25 +302,47 @@ mbintr(mbanum)
         * Service drives which require attention
         * after non-data-transfer operations.
         */
         * Service drives which require attention
         * after non-data-transfer operations.
         */
-       while (drive = ffs(as)) {
+       while (drive = ffs((long)as)) {
                drive--;                /* was 1 origin */
                as &= ~(1 << drive);
                mi = mhp->mh_mbip[drive];
                drive--;                /* was 1 origin */
                as &= ~(1 << drive);
                mi = mhp->mh_mbip[drive];
-               if (mi == NULL)
-                       continue;
+               if (mi == NULL || mi->mi_alive == 0) {
+                       struct mba_device fnd;
+                       struct mba_drv *mbd = &mhp->mh_mba->mba_drv[drive];
+                       int dt = mbd->mbd_dt & 0xffff;
+
+                       if (dt == 0 || dt == MBDT_MOH)
+                               continue;
+                       fnd.mi_mba = mhp->mh_mba;
+                       fnd.mi_mbanum = mbanum;
+                       fnd.mi_drive = drive;
+                       if ((mi = mbaconfig(&fnd, dt)) == NULL)
+                               continue;
+                       /*
+                        * If a tape, poke the slave attach routines.
+                        * Otherwise, could be a disk which we want
+                        * to swap on, so make a pass over the swap
+                        * configuration table in case the size of
+                        * the swap area must be determined by drive type.
+                        */
+                       if (dt & MBDT_TAP)
+                               mbaddtape(mi, drive);
+                       else
+                               swapconf();
+               }
                /*
                 * If driver has a handler for non-data transfer
                 * interrupts, give it a chance to tell us what to do.
                 */
                if (mi->mi_driver->md_ndint) {
                /*
                 * If driver has a handler for non-data transfer
                 * interrupts, give it a chance to tell us what to do.
                 */
                if (mi->mi_driver->md_ndint) {
-                       mi->mi_tab.b_active = 0;
                        switch ((*mi->mi_driver->md_ndint)(mi)) {
 
                        case MBN_DONE:          /* operation completed */
                        switch ((*mi->mi_driver->md_ndint)(mi)) {
 
                        case MBN_DONE:          /* operation completed */
+                               mi->mi_tab.b_active = 0;
                                mi->mi_tab.b_errcnt = 0;
                                bp = mi->mi_tab.b_actf;
                                mi->mi_tab.b_actf = bp->av_forw;
                                mi->mi_tab.b_errcnt = 0;
                                bp = mi->mi_tab.b_actf;
                                mi->mi_tab.b_actf = bp->av_forw;
-                               iodone(bp);
+                               biodone(bp);
                                /* fall into common code */
                        case MBN_RETRY:         /* operation continues */
                                if (mi->mi_tab.b_actf)
                                /* fall into common code */
                        case MBN_RETRY:         /* operation continues */
                                if (mi->mi_tab.b_actf)
@@ -306,6 +370,32 @@ mbintr(mbanum)
        /* THHHHATS all folks... */
 }
 
        /* THHHHATS all folks... */
 }
 
+/*
+ * For autoconfig'ng tape drives on the fly.
+ */
+mbaddtape(mi, drive)
+       struct mba_device *mi;
+       int drive;
+{
+       register struct mba_slave *ms;
+
+       for (ms = mbsinit; ms->ms_driver; ms++)
+               if (ms->ms_driver == mi->mi_driver && ms->ms_alive == 0 && 
+                   (ms->ms_ctlr == mi->mi_unit ||
+                    ms->ms_ctlr == '?')) {
+                       if ((*ms->ms_driver->md_slave)(mi, ms, drive)) {
+                               printf("%s%d at %s%d slave %d\n",
+                                   ms->ms_driver->md_sname,
+                                   ms->ms_unit,
+                                   mi->mi_driver->md_dname,
+                                   mi->mi_unit,
+                                   ms->ms_slave);
+                               ms->ms_alive = 1;
+                               ms->ms_ctlr = mi->mi_unit;
+                       }
+               }
+}
+
 /*
  * Setup the mapping registers for a transfer.
  */
 /*
  * Setup the mapping registers for a transfer.
  */
@@ -314,45 +404,38 @@ mbasetup(mi)
 {
        register struct mba_regs *mbap = mi->mi_mba;
        struct buf *bp = mi->mi_tab.b_actf;
 {
        register struct mba_regs *mbap = mi->mi_mba;
        struct buf *bp = mi->mi_tab.b_actf;
-       register int i;
-       int npf;
+       register int npf;
        unsigned v;
        register struct pte *pte, *io;
        int o;
        unsigned v;
        register struct pte *pte, *io;
        int o;
-       int vaddr;
        struct proc *rp;
 
        struct proc *rp;
 
-       io = mbap->mba_map;
        v = btop(bp->b_un.b_addr);
        v = btop(bp->b_un.b_addr);
-       o = (int)bp->b_un.b_addr & PGOFSET;
-       npf = btoc(bp->b_bcount + o);
+       o = (int)(bp->b_un.b_addr) & PGOFSET;
+       if (bp->b_bcount >= 0)
+               npf = btoc(bp->b_bcount + o);
+       else
+               npf = btoc(-(bp->b_bcount) + o);
        rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
        rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
-       vaddr = o;
-       if (bp->b_flags & B_UAREA) {
-               for (i = 0; i < UPAGES; i++) {
-                       if (rp->p_addr[i].pg_pfnum == 0)
-                               panic("mba: zero upage");
-                       *(int *)io++ = rp->p_addr[i].pg_pfnum | PG_V;
-               }
-       } else if ((bp->b_flags & B_PHYS) == 0) {
+       if ((bp->b_flags & B_PHYS) == 0)
                pte = &Sysmap[btop(((int)bp->b_un.b_addr)&0x7fffffff)];
                pte = &Sysmap[btop(((int)bp->b_un.b_addr)&0x7fffffff)];
-               while (--npf >= 0)
-                       *(int *)io++ = pte++->pg_pfnum | PG_V;
-       } else {
-               if (bp->b_flags & B_PAGET)
-                       pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
-               else
-                       pte = vtopte(rp, v);
-               while (--npf >= 0) {
-                       if (pte->pg_pfnum == 0)
-                               panic("mba, zero entry");
-                       *(int *)io++ = pte++->pg_pfnum | PG_V;
-               }
+       else if (bp->b_flags & B_UAREA)
+               pte = &rp->p_addr[v];
+       else if (bp->b_flags & B_PAGET)
+               pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
+       else
+               pte = vtopte(rp, v);
+       io = mbap->mba_map;
+       while (--npf >= 0) {
+               if (pte->pg_pfnum == 0)
+                       panic("mba, zero entry");
+               *(int *)io++ = pte++->pg_pfnum | PG_V;
        }
        *(int *)io++ = 0;
        }
        *(int *)io++ = 0;
-       return (vaddr);
+       return (o);
 }
 
 }
 
+#if notdef
 /*
  * Init and interrupt enable a massbus adapter.
  */
 /*
  * Init and interrupt enable a massbus adapter.
  */
@@ -364,3 +447,4 @@ mbainit(mp)
        mp->mba_cr = MBCR_IE;
 }
 #endif
        mp->mba_cr = MBCR_IE;
 }
 #endif
+#endif