cleanup, time is a struct timeval you know
[unix-history] / usr / src / sys / vax / uba / up.c
index 9fd5c8f..7d544e8 100644 (file)
@@ -1,5 +1,4 @@
-/*     up.c    4.61    82/11/26        */
-.f
+/*     up.c    4.74    83/05/27        */
 
 #include "up.h"
 #if NSC > 0
 
 #include "up.h"
 #if NSC > 0
  * TODO:
  *     Check that offset recovery code works
  */
  * TODO:
  *     Check that offset recovery code works
  */
+#include "../machine/pte.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/dk.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/dk.h"
+#include "../h/dkbad.h"
 #include "../h/buf.h"
 #include "../h/conf.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/map.h"
 #include "../h/buf.h"
 #include "../h/conf.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/map.h"
-#include "../h/pte.h"
 #include "../h/vm.h"
 #include "../h/cmap.h"
 #include "../h/uio.h"
 #include "../h/vm.h"
 #include "../h/cmap.h"
 #include "../h/uio.h"
+#include "../h/kernel.h"
 #include "../h/dkbad.h"
 #include "../vax/cpu.h"
 #include "../vax/nexus.h"
 #include "../h/dkbad.h"
 #include "../vax/cpu.h"
 #include "../vax/nexus.h"
@@ -40,53 +41,48 @@ struct      up_softc {
 } up_softc[NSC];
 
 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
 } up_softc[NSC];
 
 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
-struct size
-{
+struct size {
        daddr_t nblocks;
        int     cyloff;
        daddr_t nblocks;
        int     cyloff;
-} up_sizes[8] = {
-#ifdef ERNIE
-       49324,  0,              /* A=cyl 0 thru 26 */
-#else
+} up9300_sizes[8] = {
 #ifdef ERNIE
        49324,  0,              /* A=cyl 0 thru 26 */
 #else
        15884,  0,              /* A=cyl 0 thru 26 */
 #ifdef ERNIE
        49324,  0,              /* A=cyl 0 thru 26 */
 #else
        15884,  0,              /* A=cyl 0 thru 26 */
-#endif
 #endif
        33440,  27,             /* B=cyl 27 thru 81 */
        495520, 0,              /* C=cyl 0 thru 814 */
        15884,  562,            /* D=cyl 562 thru 588 */
        55936,  589,            /* E=cyl 589 thru 680 */
 #endif
        33440,  27,             /* B=cyl 27 thru 81 */
        495520, 0,              /* C=cyl 0 thru 814 */
        15884,  562,            /* D=cyl 562 thru 588 */
        55936,  589,            /* E=cyl 589 thru 680 */
-#ifndef NOBADSECT
        81376,  681,            /* F=cyl 681 thru 814 */
        153728, 562,            /* G=cyl 562 thru 814 */
        81376,  681,            /* F=cyl 681 thru 814 */
        153728, 562,            /* G=cyl 562 thru 814 */
-#else
-       81472,  681,
-       153824, 562,
-#endif
        291346, 82,             /* H=cyl 82 thru 561 */
        291346, 82,             /* H=cyl 82 thru 561 */
-}, fj_sizes[8] = {
+}, up9766_sizes[8] = {
+       15884,  0,              /* A=cyl 0 thru 26 */
+       33440,  27,             /* B=cyl 27 thru 81 */
+       500384, 0,              /* C=cyl 0 thru 822 */
+       15884,  562,            /* D=cyl 562 thru 588 */
+       55936,  589,            /* E=cyl 589 thru 680 */
+       86240,  681,            /* F=cyl 681 thru 822 */
+       158592, 562,            /* G=cyl 562 thru 822 */
+       291346, 82,             /* H=cyl 82 thru 561 */
+}, up160_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 49 */
        33440,  50,             /* B=cyl 50 thru 154 */
        263360, 0,              /* C=cyl 0 thru 822 */
        15884,  0,              /* A=cyl 0 thru 49 */
        33440,  50,             /* B=cyl 50 thru 154 */
        263360, 0,              /* C=cyl 0 thru 822 */
+       15884,  155,            /* D=cyl 155 thru 204 */
+       55936,  205,            /* E=cyl 205 thru 379 */
+       141664, 380,            /* F=cyl 380 thru 822 */
+       213664, 155,            /* G=cyl 155 thru 822 */
        0,      0,
        0,      0,
-       0,      0,
-       0,      0,
-       0,      0,
-#ifndef NOBADSECT
-       213664, 155,            /* H=cyl 155 thru 822 */
-#else
-       213760, 155,
-#endif
 }, upam_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 31 */
        33440,  32,             /* B=cyl 32 thru 97 */
        524288, 0,              /* C=cyl 0 thru 1023 */
 }, upam_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 31 */
        33440,  32,             /* B=cyl 32 thru 97 */
        524288, 0,              /* C=cyl 0 thru 1023 */
-       27786,  668,
-       27786,  723,
-       125440, 778,
-       181760, 668,            /* G=cyl 668 thru 1022 */
+       15884,  668,            /* D=cyl 668 thru 699 */
+       55936,  700,            /* E=cyl 700 thru 809 */
+       109472, 810,            /* F=cyl 810 thru 1023 */
+       182176, 668,            /* G=cyl 668 thru 1023 */
        291346, 98,             /* H=cyl 98 thru 667 */
 };
 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
        291346, 98,             /* H=cyl 98 thru 667 */
 };
 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
@@ -112,6 +108,7 @@ struct      uba_driver scdriver =
     { upprobe, upslave, upattach, updgo, upstd, "up", updinfo, "sc", upminfo };
 struct buf     uputab[NUP];
 char upinit[NUP];
     { upprobe, upslave, upattach, updgo, upstd, "up", updinfo, "sc", upminfo };
 struct buf     uputab[NUP];
 char upinit[NUP];
+char upinit[NUP];
 
 struct upst {
        short   nsect;
 
 struct upst {
        short   nsect;
@@ -120,10 +117,11 @@ struct    upst {
        short   ncyl;
        struct  size *sizes;
 } upst[] = {
        short   ncyl;
        struct  size *sizes;
 } upst[] = {
-       32,     19,     32*19,  823,    up_sizes,       /* 9300/cdc */
-/* 9300 actually has 815 cylinders... */
-       32,     10,     32*10,  823,    fj_sizes,       /* fujitsu 160m */
+       32,     19,     32*19,  815,    up9300_sizes,   /* 9300 */
+       32,     19,     32*19,  823,    up9766_sizes,   /* 9766 */
+       32,     10,     32*10,  823,    up160_sizes,    /* fujitsu 160m */
        32,     16,     32*16,  1024,   upam_sizes,     /* ampex capricorn */
        32,     16,     32*16,  1024,   upam_sizes,     /* ampex capricorn */
+       0,      0,      0,      0,      0
 };
 
 u_char up_offset[16] = {
 };
 
 u_char up_offset[16] = {
@@ -134,6 +132,8 @@ u_char      up_offset[16] = {
 };
 
 struct buf     rupbuf[NUP];
 };
 
 struct buf     rupbuf[NUP];
+struct         buf     bupbuf[NUP];
+struct dkbad   upbad[NUP];
 #ifndef NOBADSECT
 struct         buf     bupbuf[NUP];
 struct dkbad   upbad[NUP];
 #ifndef NOBADSECT
 struct         buf     bupbuf[NUP];
 struct dkbad   upbad[NUP];
@@ -156,7 +156,7 @@ upprobe(reg)
        register int br, cvec;
 
 #ifdef lint    
        register int br, cvec;
 
 #ifdef lint    
-       br = 0; cvec = br; br = cvec;
+       br = 0; cvec = br; br = cvec; upintr(0);
 #endif
        ((struct updevice *)reg)->upcs1 = UP_IE|UP_RDY;
        DELAY(10);
 #endif
        ((struct updevice *)reg)->upcs1 = UP_IE|UP_RDY;
        DELAY(10);
@@ -184,7 +184,6 @@ upslave(ui, reg)
 upattach(ui)
        register struct uba_device *ui;
 {
 upattach(ui)
        register struct uba_device *ui;
 {
-       register struct updevice *upaddr;
 
        if (upwstart == 0) {
                timeout(upwatch, (caddr_t)0, hz);
 
        if (upwstart == 0) {
                timeout(upwatch, (caddr_t)0, hz);
@@ -194,17 +193,46 @@ upattach(ui)
                dk_mspw[ui->ui_dk] = .0000020345;
        upip[ui->ui_ctlr][ui->ui_slave] = ui;
        up_softc[ui->ui_ctlr].sc_ndrive++;
                dk_mspw[ui->ui_dk] = .0000020345;
        upip[ui->ui_ctlr][ui->ui_slave] = ui;
        up_softc[ui->ui_ctlr].sc_ndrive++;
-       upaddr = (struct updevice *)ui->ui_addr;
+       ui->ui_type = upmaptype(ui);
+}
+
+upmaptype(ui)
+       register struct uba_device *ui;
+{
+       register struct updevice *upaddr = (struct updevice *)ui->ui_addr;
+       int type = ui->ui_type;
+       register struct upst *st;
+
        upaddr->upcs1 = 0;
        upaddr->upcs2 = ui->ui_slave;
        upaddr->uphr = UPHR_MAXTRAK;
        upaddr->upcs1 = 0;
        upaddr->upcs2 = ui->ui_slave;
        upaddr->uphr = UPHR_MAXTRAK;
-       if (upaddr->uphr == 9)
-               ui->ui_type = 1;                /* fujitsu hack */
-       else if (upaddr->uphr == 15)
-               ui->ui_type = 2;                /* ampex hack */
+       for (st = upst; st->nsect != 0; st++)
+               if (upaddr->uphr == st->ntrak - 1) {
+                       type = st - upst;
+                       break;
+               }
+       if (st->nsect == 0)
+               printf("up%d: uphr=%x\n", ui->ui_slave, upaddr->uphr);
+       if (type == 0) {
+               upaddr->uphr = UPHR_MAXCYL;
+               if (upaddr->uphr == 822)
+                       type++;
+       }
        upaddr->upcs2 = UPCS2_CLR;
        upaddr->upcs2 = UPCS2_CLR;
+       return (type);
 }
  
 }
  
+upopen(dev)
+       dev_t dev;
+{
+       register int unit = minor(dev) >> 3;
+       register struct uba_device *ui;
+
+       if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0)
+               return (ENXIO);
+       return (0);
+}
+
 upstrategy(bp)
        register struct buf *bp;
 {
 upstrategy(bp)
        register struct buf *bp;
 {
@@ -309,10 +337,21 @@ upustart(ui)
 #endif
                /* SHOULD WARN SYSTEM THAT THIS HAPPENED */
                upinit[ui->ui_unit] = 1;
 #endif
                /* SHOULD WARN SYSTEM THAT THIS HAPPENED */
                upinit[ui->ui_unit] = 1;
+               upinit[ui->ui_unit] = 1;
                upaddr->upcs1 = UP_IE|UP_DCLR|UP_GO;
                upaddr->upcs1 = UP_IE|UP_PRESET|UP_GO;
                upaddr->upof = UPOF_FMT22;
                didie = 1;
                upaddr->upcs1 = UP_IE|UP_DCLR|UP_GO;
                upaddr->upcs1 = UP_IE|UP_PRESET|UP_GO;
                upaddr->upof = UPOF_FMT22;
                didie = 1;
+               st = &upst[ui->ui_type];
+               bbp->b_flags = B_READ|B_BUSY;
+               bbp->b_dev = bp->b_dev;
+               bbp->b_bcount = 512;
+               bbp->b_un.b_addr = (caddr_t)&upbad[ui->ui_unit];
+               bbp->b_blkno = st->ncyl * st->nspc - st->nsect;
+               bbp->b_cylin = st->ncyl - 1;
+               dp->b_actf = bbp;
+               bbp->av_forw = bp;
+               bp = bbp;
 #ifndef NOBADSECT
                st = &upst[ui->ui_type];
                bbp->b_flags = B_READ|B_BUSY;
 #ifndef NOBADSECT
                st = &upst[ui->ui_type];
                bbp->b_flags = B_READ|B_BUSY;
@@ -532,6 +571,10 @@ upintr(sc21)
        dk_busy &= ~(1 << ui->ui_dk);
        if ((upaddr->upcs2&07) != ui->ui_slave)
                upaddr->upcs2 = ui->ui_slave;
        dk_busy &= ~(1 << ui->ui_dk);
        if ((upaddr->upcs2&07) != ui->ui_slave)
                upaddr->upcs2 = ui->ui_slave;
+       if (bp->b_flags&B_BAD) {
+               if (upecc(ui, CONT))
+                       return;
+       }
 #ifndef NOBADSECT
        if (bp->b_flags&B_BAD) {
                if (upecc(ui, CONT))
 #ifndef NOBADSECT
        if (bp->b_flags&B_BAD) {
                if (upecc(ui, CONT))
@@ -560,7 +603,15 @@ upintr(sc21)
                        /*
                         * After 28 retries (16 without offset, and
                         * 12 with offset positioning) give up.
                        /*
                         * After 28 retries (16 without offset, and
                         * 12 with offset positioning) give up.
+                        * If the error was header CRC, the header is 
+                        * screwed up, and the sector may in fact exist
+                        * in the bad sector table, better check...
                         */
                         */
+                       if (upaddr->uper1&UPER1_HCRC) {
+                               if (upecc(ui, BSE))
+                                       return;
+                       }
+       hard:
        hard:
                        harderr(bp, "up");
                        printf("cn=%d tn=%d sn=%d cs2=%b er1=%b er2=%b\n",
        hard:
                        harderr(bp, "up");
                        printf("cn=%d tn=%d sn=%d cs2=%b er1=%b er2=%b\n",
@@ -571,6 +622,11 @@ upintr(sc21)
                                upaddr->uper2, UPER2_BITS);
                        bp->b_flags |= B_ERROR;
                } else if (upaddr->uper2 & UPER2_BSE) {
                                upaddr->uper2, UPER2_BITS);
                        bp->b_flags |= B_ERROR;
                } else if (upaddr->uper2 & UPER2_BSE) {
+                       if (upecc(ui, BSE))
+                               return;
+                       else
+                               goto hard;
+               } else if (upaddr->uper2 & UPER2_BSE) {
 #ifndef NOBADSECT
                        if (upecc(ui, BSE))
                                return;
 #ifndef NOBADSECT
                        if (upecc(ui, BSE))
                                return;
@@ -728,6 +784,7 @@ upwrite(dev, uio)
 upecc(ui, flag)
        register struct uba_device *ui;
        int flag;
 upecc(ui, flag)
        register struct uba_device *ui;
        int flag;
+       int flag;
 {
        register struct updevice *up = (struct updevice *)ui->ui_addr;
        register struct buf *bp = uputab[ui->ui_unit].b_actf;
 {
        register struct updevice *up = (struct updevice *)ui->ui_addr;
        register struct buf *bp = uputab[ui->ui_unit].b_actf;
@@ -753,8 +810,6 @@ upecc(ui, flag)
        npf = btop((up->upwc * sizeof(short)) + bp->b_bcount);
        reg = btop(um->um_ubinfo&0x3ffff) + npf;
        o = (int)bp->b_un.b_addr & PGOFSET;
        npf = btop((up->upwc * sizeof(short)) + bp->b_bcount);
        reg = btop(um->um_ubinfo&0x3ffff) + npf;
        o = (int)bp->b_un.b_addr & PGOFSET;
-       printf("up%d%c: soft ecc sn%d\n", dkunit(bp),
-           'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
        mask = up->upec2;
 #ifdef UPECCDEBUG
        printf("npf %d reg %x o %d mask %o pos %d\n", npf, reg, o, mask,
        mask = up->upec2;
 #ifdef UPECCDEBUG
        printf("npf %d reg %x o %d mask %o pos %d\n", npf, reg, o, mask,
@@ -875,7 +930,6 @@ upecc(ui, flag)
        cmd = (ubaddr >> 8) & 0x300;
        cmd |= ((bp->b_flags&B_READ)?UP_RCOM:UP_WCOM)|UP_IE|UP_GO;
        um->um_tab.b_errcnt = 0;
        cmd = (ubaddr >> 8) & 0x300;
        cmd |= ((bp->b_flags&B_READ)?UP_RCOM:UP_WCOM)|UP_IE|UP_GO;
        um->um_tab.b_errcnt = 0;
-       um->um_tab.b_active = 2;        /* continuing transfer ... */
        up->upcs1 = cmd;
 #endif
        return (1);
        up->upcs1 = cmd;
 #endif
        return (1);
@@ -1056,4 +1110,17 @@ updump(dev)
        }
        return (0);
 }
        }
        return (0);
 }
+
+upsize(dev)
+       dev_t dev;
+{
+       int unit = minor(dev) >> 3;
+       struct uba_device *ui;
+       struct upst *st;
+
+       if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0)
+               return (-1);
+       st = &upst[ui->ui_type];
+       return (st->sizes[minor(dev) & 07].nblocks);
+}
 #endif
 #endif