compilable first uba autoconf version
[unix-history] / usr / src / sys / vax / uba / tm.c
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