BSD 4_4 release
[unix-history] / usr / src / sys / vax / uba / up.c
index 95f4fdb..a4a5f25 100644 (file)
@@ -1,4 +1,10 @@
-/*     up.c    4.70    83/02/17        */
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)up.c        7.10 (Berkeley) 12/16/90
+ */
 
 #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 "../include/pte.h"
+
+#include "sys/param.h"
+#include "sys/systm.h"
+#include "sys/dkstat.h"
+#include "sys/dkbad.h"
+#include "sys/ioctl.h"
+#include "sys/disklabel.h"
+#include "sys/buf.h"
+#include "sys/conf.h"
+#include "sys/user.h"
+#include "sys/map.h"
+#include "sys/vm.h"
+#include "sys/cmap.h"
+#include "sys/uio.h"
+#include "sys/kernel.h"
+#include "sys/syslog.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/vm.h"
-#include "../h/cmap.h"
-#include "../h/uio.h"
-#include "../h/kernel.h"
-#include "../h/dkbad.h"
-#include "../vax/cpu.h"
+#include "../include/cpu.h"
 #include "../vax/nexus.h"
 #include "../vax/nexus.h"
-#include "../vaxuba/ubavar.h"
-#include "../vaxuba/ubareg.h"
-#include "../vaxuba/upreg.h"
+#include "ubavar.h"
+#include "ubareg.h"
+#include "upreg.h"
 
 struct up_softc {
        int     sc_softas;
 
 struct up_softc {
        int     sc_softas;
@@ -40,16 +48,14 @@ struct      up_softc {
        int     sc_recal;
 } up_softc[NSC];
 
        int     sc_recal;
 } up_softc[NSC];
 
+#define upunit(dev)    (minor(dev) >> 3)
+
 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
 struct size {
        daddr_t nblocks;
        int     cyloff;
 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
 struct size {
        daddr_t nblocks;
        int     cyloff;
-} up_sizes[8] = {
-#ifdef ERNIE
-       49324,  0,              /* A=cyl 0 thru 26 */
-#else
+} up9300_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 26 */
        15884,  0,              /* A=cyl 0 thru 26 */
-#endif
        33440,  27,             /* B=cyl 27 thru 81 */
        495520, 0,              /* C=cyl 0 thru 814 */
        15884,  562,            /* D=cyl 562 thru 588 */
        33440,  27,             /* B=cyl 27 thru 81 */
        495520, 0,              /* C=cyl 0 thru 814 */
        15884,  562,            /* D=cyl 562 thru 588 */
@@ -57,37 +63,54 @@ struct      size {
        81376,  681,            /* F=cyl 681 thru 814 */
        153728, 562,            /* G=cyl 562 thru 814 */
        291346, 82,             /* H=cyl 82 thru 561 */
        81376,  681,            /* F=cyl 681 thru 814 */
        153728, 562,            /* G=cyl 562 thru 814 */
        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,
-       213664, 155,            /* H=cyl 155 thru 822 */
 }, 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 */
        291346, 98,             /* H=cyl 98 thru 667 */
+}, up980_sizes[8] = {
+       15884,  0,              /* A=cyl 0 thru 99 */
+       33440,  100,            /* B=cyl 100 thru 308 */
+       131680, 0,              /* C=cyl 0 thru 822 */
+       15884,  309,            /* D=cyl 309 thru 408 */
+       55936,  409,            /* E=cyl 409 thru 758 */
+       10080,  759,            /* F=cyl 759 thru 822 */
+       82080,  309,            /* G=cyl 309 thru 822 */
+       0,      0,
+}, upeagle_sizes[8] = {
+       15884,  0,              /* A=cyl 0 thru 16 */
+       66880,  17,             /* B=cyl 17 thru 86 */
+       808320, 0,              /* C=cyl 0 thru 841 */
+       15884,  391,            /* D=cyl 391 thru 407 */
+       307200, 408,            /* E=cyl 408 thru 727 */
+       109296, 728,            /* F=cyl 728 thru 841 */
+       432816, 391,            /* G=cyl 391 thru 841 */
+       291346, 87,             /* H=cyl 87 thru 390 */
 };
 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
 
 };
 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
 
-/*
- * On a 780 upSDIST could be 2, but
- * in the interest of 750's...
- */
-#define        _upSDIST        3               /* 1.5 msec */
-#define        _upRDIST        4               /* 2.0 msec */
-
-int    upSDIST = _upSDIST;
-int    upRDIST = _upRDIST;
-
 int    upprobe(), upslave(), upattach(), updgo(), upintr();
 struct uba_ctlr *upminfo[NSC];
 struct uba_device *updinfo[NUP];
 int    upprobe(), upslave(), upattach(), updgo(), upintr();
 struct uba_ctlr *upminfo[NSC];
 struct uba_device *updinfo[NUP];
@@ -99,20 +122,23 @@ 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 {
 
 struct upst {
-       short   nsect;
-       short   ntrak;
-       short   nspc;
-       short   ncyl;
-       struct  size *sizes;
+       short   nsect;          /* # sectors/track */
+       short   ntrak;          /* # tracks/cylinder */
+       short   nspc;           /* # sectors/cylinder */
+       short   ncyl;           /* # cylinders */
+       struct  size *sizes;    /* partition tables */
+       short   sdist;          /* seek distance metric */
+       short   rdist;          /* rotational distance metric */
 } upst[] = {
 } upst[] = {
-       32,     19,     32*19,  815,    up_sizes,       /* 9300 */
-       32,     10,     32*10,  823,    fj_sizes,       /* fujitsu 160m */
-       32,     16,     32*16,  1024,   upam_sizes,     /* ampex capricorn */
-/* should make a new partition table for cdc drives */
-       32,     19,     32*19,  823,    up_sizes,       /* cdc */
+       { 32,   19,     32*19,  815,    up9300_sizes,   3, 4 }, /* 9300 */
+       { 32,   19,     32*19,  823,    up9766_sizes,   3, 4 }, /* 9766 */
+       { 32,   10,     32*10,  823,    up160_sizes,    3, 4 }, /* fuji 160m */
+       { 32,   16,     32*16,  1024,   upam_sizes,     7, 8 }, /* Capricorn */
+       { 32,   5,      32*5,   823,    up980_sizes,    3, 4 }, /* DM980 */
+        { 48,  20,     48*20,  842,    upeagle_sizes, 15, 8 }, /* EAGLE */
+       { 0,    0,      0,      0,      0,              0, 0 }
 };
 
 u_char up_offset[16] = {
 };
 
 u_char up_offset[16] = {
@@ -122,20 +148,11 @@ u_char    up_offset[16] = {
        0, 0, 0, 0
 };
 
        0, 0, 0, 0
 };
 
-struct buf     rupbuf[NUP];
-struct         buf     bupbuf[NUP];
-struct dkbad   upbad[NUP];
-#ifndef NOBADSECT
 struct         buf     bupbuf[NUP];
 struct dkbad   upbad[NUP];
 struct         buf     bupbuf[NUP];
 struct dkbad   upbad[NUP];
-#endif
 
 #define        b_cylin b_resid
 
 
 #define        b_cylin b_resid
 
-#ifdef INTRLVE
-daddr_t dkblock();
-#endif
-
 int    upwstart, upwatch();            /* Have started guardian */
 int    upseek;
 int    upwaitdry;
 int    upwstart, upwatch();            /* Have started guardian */
 int    upseek;
 int    upwaitdry;
@@ -147,7 +164,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);
@@ -164,7 +181,6 @@ upslave(ui, reg)
        upaddr->upcs1 = 0;              /* conservative */
        upaddr->upcs2 = ui->ui_slave;
        upaddr->upcs1 = UP_NOP|UP_GO;
        upaddr->upcs1 = 0;              /* conservative */
        upaddr->upcs2 = ui->ui_slave;
        upaddr->upcs1 = UP_NOP|UP_GO;
-       upaddr->upcs1 = UP_NOP|UP_GO;
        if (upaddr->upcs2&UPCS2_NED) {
                upaddr->upcs1 = UP_DCLR|UP_GO;
                return (0);
        if (upaddr->upcs2&UPCS2_NED) {
                upaddr->upcs1 = UP_DCLR|UP_GO;
                return (0);
@@ -175,36 +191,48 @@ 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);
                upwstart++;
        }
        if (ui->ui_dk >= 0)
 
        if (upwstart == 0) {
                timeout(upwatch, (caddr_t)0, hz);
                upwstart++;
        }
        if (ui->ui_dk >= 0)
-               dk_mspw[ui->ui_dk] = .0000020345;
+               dk_wpms[ui->ui_dk] = 491521;
        upip[ui->ui_ctlr][ui->ui_slave] = ui;
        up_softc[ui->ui_ctlr].sc_ndrive++;
        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 */
-       else {
+       for (st = upst; st->nsect != 0; st++)
+               if (upaddr->uphr == st->ntrak - 1) {
+                       type = st - upst;
+                       break;
+               }
+       if (st->nsect == 0)
+               printf(": uphr=%x", upaddr->uphr);
+       if (type == 0) {
                upaddr->uphr = UPHR_MAXCYL;
                if (upaddr->uphr == 822)
                upaddr->uphr = UPHR_MAXCYL;
                if (upaddr->uphr == 822)
-                       ui->ui_type = 3;        /* cdc hack */
+                       type++;
        }
        upaddr->upcs2 = UPCS2_CLR;
        }
        upaddr->upcs2 = UPCS2_CLR;
+       return (type);
 }
  
 upopen(dev)
        dev_t dev;
 {
 }
  
 upopen(dev)
        dev_t dev;
 {
-       register int unit = minor(dev) >> 3;
+       register int unit = upunit(dev);
        register struct uba_device *ui;
 
        if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0)
        register struct uba_device *ui;
 
        if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0)
@@ -221,20 +249,31 @@ upstrategy(bp)
        register struct buf *dp;
        int xunit = minor(bp->b_dev) & 07;
        long bn, sz;
        register struct buf *dp;
        int xunit = minor(bp->b_dev) & 07;
        long bn, sz;
+       int s;
 
        sz = (bp->b_bcount+511) >> 9;
 
        sz = (bp->b_bcount+511) >> 9;
-       unit = dkunit(bp);
-       if (unit >= NUP)
+       unit = upunit(bp->b_dev);
+       if (unit >= NUP) {
+               bp->b_error = ENXIO;
                goto bad;
                goto bad;
+       }
        ui = updinfo[unit];
        ui = updinfo[unit];
-       if (ui == 0 || ui->ui_alive == 0)
+       if (ui == 0 || ui->ui_alive == 0) {
+               bp->b_error = ENXIO;
                goto bad;
                goto bad;
+       }
        st = &upst[ui->ui_type];
        if (bp->b_blkno < 0 ||
        st = &upst[ui->ui_type];
        if (bp->b_blkno < 0 ||
-           (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks)
+           (bn = bp->b_blkno)+sz > st->sizes[xunit].nblocks) {
+               if (bp->b_blkno == st->sizes[xunit].nblocks) {
+                       bp->b_resid = bp->b_bcount;
+                       goto done;
+               }
+               bp->b_error = EINVAL;
                goto bad;
                goto bad;
+       }
        bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
        bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
-       (void) spl5();
+       s = spl5();
        dp = &uputab[ui->ui_unit];
        disksort(dp, bp);
        if (dp->b_active == 0) {
        dp = &uputab[ui->ui_unit];
        disksort(dp, bp);
        if (dp->b_active == 0) {
@@ -243,11 +282,12 @@ upstrategy(bp)
                if (bp->b_actf && bp->b_active == 0)
                        (void) upstart(ui->ui_mi);
        }
                if (bp->b_actf && bp->b_active == 0)
                        (void) upstart(ui->ui_mi);
        }
-       (void) spl0();
+       splx(s);
        return;
 
 bad:
        bp->b_flags |= B_ERROR;
        return;
 
 bad:
        bp->b_flags |= B_ERROR;
+done:
        iodone(bp);
        return;
 }
        iodone(bp);
        return;
 }
@@ -311,12 +351,10 @@ upustart(ui)
         * setup the pack.
         */
        if ((upaddr->upds & UPDS_VV) == 0 || upinit[ui->ui_unit] == 0) {
         * setup the pack.
         */
        if ((upaddr->upds & UPDS_VV) == 0 || upinit[ui->ui_unit] == 0) {
-#ifndef NOBADSECT
                struct buf *bbp = &bupbuf[ui->ui_unit];
                struct buf *bbp = &bupbuf[ui->ui_unit];
-#endif
+
                /* SHOULD WARN SYSTEM THAT THIS HAPPENED */
                upinit[ui->ui_unit] = 1;
                /* 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;
                upaddr->upcs1 = UP_IE|UP_DCLR|UP_GO;
                upaddr->upcs1 = UP_IE|UP_PRESET|UP_GO;
                upaddr->upof = UPOF_FMT22;
@@ -331,18 +369,6 @@ upustart(ui)
                dp->b_actf = bbp;
                bbp->av_forw = bp;
                bp = bbp;
                dp->b_actf = bbp;
                bbp->av_forw = bp;
                bp = bbp;
-#ifndef NOBADSECT
-               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;
-#endif
        }
        /*
         * If drive is offline, forget about positioning.
        }
        /*
         * If drive is offline, forget about positioning.
@@ -360,9 +386,9 @@ upustart(ui)
         * and see if we are close enough to justify not searching.
         */
        st = &upst[ui->ui_type];
         * and see if we are close enough to justify not searching.
         */
        st = &upst[ui->ui_type];
-       bn = dkblock(bp);
+       bn = bp->b_blkno;
        sn = bn%st->nspc;
        sn = bn%st->nspc;
-       sn = (sn + st->nsect - upSDIST) % st->nsect;
+       sn = (sn + st->nsect - st->sdist) % st->nsect;
        if (bp->b_cylin - upaddr->updc)
                goto search;            /* Not on-cylinder */
        else if (upseek)
        if (bp->b_cylin - upaddr->updc)
                goto search;            /* Not on-cylinder */
        else if (upseek)
@@ -370,7 +396,7 @@ upustart(ui)
        csn = (upaddr->upla>>6) - sn - 1;
        if (csn < 0)
                csn += st->nsect;
        csn = (upaddr->upla>>6) - sn - 1;
        if (csn < 0)
                csn += st->nsect;
-       if (csn > st->nsect - upRDIST)
+       if (csn > st->nsect - st->rdist)
                goto done;
 search:
        upaddr->updc = bp->b_cylin;
                goto done;
 search:
        upaddr->updc = bp->b_cylin;
@@ -440,8 +466,8 @@ loop:
         * determine destination of this request.
         */
        um->um_tab.b_active++;
         * determine destination of this request.
         */
        um->um_tab.b_active++;
-       ui = updinfo[dkunit(bp)];
-       bn = dkblock(bp);
+       ui = updinfo[upunit(bp->b_dev)];
+       bn = bp->b_blkno;
        dn = ui->ui_slave;
        st = &upst[ui->ui_type];
        sn = bn%st->nspc;
        dn = ui->ui_slave;
        st = &upst[ui->ui_type];
        sn = bn%st->nspc;
@@ -458,14 +484,13 @@ loop:
         */
        waitdry = 0;
        while ((upaddr->upds&UPDS_DRY) == 0) {
         */
        waitdry = 0;
        while ((upaddr->upds&UPDS_DRY) == 0) {
-               printf("up%d: ds wait ds=%o\n",dkunit(bp),upaddr->upds);
-               printf("up%d: ds wait ds=%o\n",dkunit(bp),upaddr->upds);
+               printf("up%d: ds wait ds=%o\n",upunit(bp->b_dev),upaddr->upds);
                if (++waitdry > 512)
                        break;
                upwaitdry++;
        }
        if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
                if (++waitdry > 512)
                        break;
                upwaitdry++;
        }
        if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
-               printf("up%d: not ready", dkunit(bp));
+               printf("up%d: not ready", upunit(bp->b_dev));
                if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
                        printf("\n");
                        um->um_tab.b_active = 0;
                if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
                        printf("\n");
                        um->um_tab.b_active = 0;
@@ -539,14 +564,13 @@ upintr(sc21)
                goto doattn;
        }
        um->um_tab.b_active = 1;
                goto doattn;
        }
        um->um_tab.b_active = 1;
-       um->um_tab.b_active = 1;
        /*
         * Get device and block structures, and a pointer
         * to the uba_device for the drive.  Select the drive.
         */
        dp = um->um_tab.b_actf;
        bp = dp->b_actf;
        /*
         * Get device and block structures, and a pointer
         * to the uba_device for the drive.  Select the drive.
         */
        dp = um->um_tab.b_actf;
        bp = dp->b_actf;
-       ui = updinfo[dkunit(bp)];
+       ui = updinfo[upunit(bp->b_dev)];
        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;
@@ -554,12 +578,6 @@ upintr(sc21)
                if (upecc(ui, CONT))
                        return;
        }
                if (upecc(ui, CONT))
                        return;
        }
-#ifndef NOBADSECT
-       if (bp->b_flags&B_BAD) {
-               if (upecc(ui, CONT))
-                       return;
-       }
-#endif
        /*
         * Check for and process errors on
         * either the drive or the controller.
        /*
         * Check for and process errors on
         * either the drive or the controller.
@@ -576,7 +594,7 @@ upintr(sc21)
                         * Give up on write locked devices
                         * immediately.
                         */
                         * Give up on write locked devices
                         * immediately.
                         */
-                       printf("up%d: write locked\n", dkunit(bp));
+                       printf("up%d: write locked\n", upunit(bp->b_dev));
                        bp->b_flags |= B_ERROR;
                } else if (++um->um_tab.b_errcnt > 27) {
                        /*
                        bp->b_flags |= B_ERROR;
                } else if (++um->um_tab.b_errcnt > 27) {
                        /*
@@ -591,9 +609,9 @@ upintr(sc21)
                                        return;
                        }
        hard:
                                        return;
                        }
        hard:
-       hard:
-                       harderr(bp, "up");
-                       printf("cn=%d tn=%d sn=%d cs2=%b er1=%b er2=%b\n",
+                       diskerr(bp, "up", "hard error", LOG_PRINTF, -1,
+                           (struct disklabel *)0);
+                       printf(" cn=%d tn=%d sn=%d cs2=%b er1=%b er2=%b\n",
                                upaddr->updc, ((upaddr->upda)>>8)&077,
                                (upaddr->upda)&037,
                                upaddr->upcs2, UPCS2_BITS,
                                upaddr->updc, ((upaddr->upda)>>8)&077,
                                (upaddr->upda)&037,
                                upaddr->upcs2, UPCS2_BITS,
@@ -605,13 +623,6 @@ upintr(sc21)
                                return;
                        else
                                goto hard;
                                return;
                        else
                                goto hard;
-               } else if (upaddr->uper2 & UPER2_BSE) {
-#ifndef NOBADSECT
-                       if (upecc(ui, BSE))
-                               return;
-                       else
-#endif
-                               goto hard;
                } else {
                        /*
                         * Retriable error.
                } else {
                        /*
                         * Retriable error.
@@ -624,8 +635,6 @@ upintr(sc21)
                                        return;
                        } else
                                um->um_tab.b_active = 0; /* force retry */
                                        return;
                        } else
                                um->um_tab.b_active = 0; /* force retry */
-                       } else
-                               um->um_tab.b_active = 0; /* force retry */
                }
                /*
                 * Clear drive error and, every eight attempts,
                }
                /*
                 * Clear drive error and, every eight attempts,
@@ -713,7 +722,7 @@ doattn:
         * the unit start routine to place the slave
         * on the controller device queue.
         */
         * the unit start routine to place the slave
         * on the controller device queue.
         */
-       while (unit = ffs(as)) {
+       while (unit = ffs((long)as)) {
                unit--;         /* was 1 origin */
                as &= ~(1<<unit);
                upaddr->upas = 1<<unit;
                unit--;         /* was 1 origin */
                as &= ~(1<<unit);
                upaddr->upas = 1<<unit;
@@ -732,28 +741,6 @@ doattn:
                upaddr->upcs1 = UP_IE;
 }
 
                upaddr->upcs1 = UP_IE;
 }
 
-upread(dev, uio)
-       dev_t dev;
-       struct uio *uio;
-{
-       register int unit = minor(dev) >> 3;
-
-       if (unit >= NUP)
-               return (ENXIO);
-       return (physio(upstrategy, &rupbuf[unit], dev, B_READ, minphys, uio));
-}
-
-upwrite(dev, uio)
-       dev_t dev;
-       struct uio *uio;
-{
-       register int unit = minor(dev) >> 3;
-
-       if (unit >= NUP)
-               return (ENXIO);
-       return (physio(upstrategy, &rupbuf[unit], dev, B_WRITE, minphys, uio));
-}
-
 /*
  * Correct an ECC error, and restart the i/o to complete
  * the transfer if necessary.  This is quite complicated because
 /*
  * Correct an ECC error, and restart the i/o to complete
  * the transfer if necessary.  This is quite complicated because
@@ -763,7 +750,6 @@ 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;
@@ -781,20 +767,18 @@ upecc(ui, flag)
         * mapping (the first part of) the transfer.
         * O is offset within a memory page of the first byte transferred.
         */
         * mapping (the first part of) the transfer.
         * O is offset within a memory page of the first byte transferred.
         */
-#ifndef NOBADSECT
        if (flag == CONT)
                npf = bp->b_error;
        else
        if (flag == CONT)
                npf = bp->b_error;
        else
-#endif
-       npf = btop((up->upwc * sizeof(short)) + bp->b_bcount);
-       reg = btop(um->um_ubinfo&0x3ffff) + npf;
+               npf = btodb(bp->b_bcount + (up->upwc * sizeof(short)) + 511);
+       reg = btop(UBAI_ADDR(um->um_ubinfo)) + npf;
        o = (int)bp->b_un.b_addr & PGOFSET;
        mask = up->upec2;
 #ifdef UPECCDEBUG
        printf("npf %d reg %x o %d mask %o pos %d\n", npf, reg, o, mask,
            up->upec1);
 #endif
        o = (int)bp->b_un.b_addr & PGOFSET;
        mask = up->upec2;
 #ifdef UPECCDEBUG
        printf("npf %d reg %x o %d mask %o pos %d\n", npf, reg, o, mask,
            up->upec1);
 #endif
-       bn = dkblock(bp);
+       bn = bp->b_blkno;
        st = &upst[ui->ui_type];
        cn = bp->b_cylin;
        sn = bn%st->nspc + npf;
        st = &upst[ui->ui_type];
        cn = bp->b_cylin;
        sn = bn%st->nspc + npf;
@@ -812,8 +796,9 @@ upecc(ui, flag)
                npf--;
                reg--;
                mask = up->upec2;
                npf--;
                reg--;
                mask = up->upec2;
-               printf("up%d%c: soft ecc sn%d\n", dkunit(bp),
-                       'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
+               diskerr(bp, "up", "soft ecc", LOG_WARNING, npf,
+                   (struct disklabel *)0);
+               addlog("\n");
                /*
                 * Flush the buffered data path, and compute the
                 * byte and bit position of the error.  The variable i
                /*
                 * Flush the buffered data path, and compute the
                 * byte and bit position of the error.  The variable i
@@ -830,9 +815,11 @@ upecc(ui, flag)
                 * Also watch out for end of this block and the end of the whole
                 * transfer.
                 */
                 * Also watch out for end of this block and the end of the whole
                 * transfer.
                 */
-               while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
-                       addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
-                               (byte & PGOFSET);
+               while (i < 512 && (int)dbtob(npf)+i < bp->b_bcount && bit > -11) {
+                       struct pte pte;
+
+                       pte = ubp->uba_map[reg + btop(byte)];
+                       addr = ptob(pte.pg_pfnum) + (byte & PGOFSET);
 #ifdef UPECCDEBUG
                        printf("addr %x map reg %x\n",
                                addr, *(int *)(&ubp->uba_map[reg+btop(byte)]));
 #ifdef UPECCDEBUG
                        printf("addr %x map reg %x\n",
                                addr, *(int *)(&ubp->uba_map[reg+btop(byte)]));
@@ -844,13 +831,13 @@ upecc(ui, flag)
 #endif
                        byte++;
                        i++;
 #endif
                        byte++;
                        i++;
+                       bit -= 8;
                }
                if (up->upwc == 0)
                        return (0);
                npf++;
                reg++;
                break;
                }
                if (up->upwc == 0)
                        return (0);
                npf++;
                reg++;
                break;
-#ifndef NOBADSECT
        case BSE:
                /*
                 * if not in bad sector table, return 0
        case BSE:
                /*
                 * if not in bad sector table, return 0
@@ -880,17 +867,15 @@ upecc(ui, flag)
                printf("upecc, CONT: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);
 #endif
                bp->b_flags &= ~B_BAD;
                printf("upecc, CONT: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);
 #endif
                bp->b_flags &= ~B_BAD;
-               up->upwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof(short));
-               if (up->upwc == 0)
-                       return(0);
+               if ((int)dbtob(npf) >= bp->b_bcount)
+                       return (0);
+               up->upwc = -((bp->b_bcount - (int)dbtob(npf)) / sizeof(short));
                break;
                break;
-#endif
        }
        if (up->upwc == 0) {
                um->um_tab.b_active = 0;
                return (0);
        }
        }
        if (up->upwc == 0) {
                um->um_tab.b_active = 0;
                return (0);
        }
-       }
        /*
         * Have to continue the transfer... clear the drive,
         * and compute the position where the transfer is to continue.
        /*
         * Have to continue the transfer... clear the drive,
         * and compute the position where the transfer is to continue.
@@ -1002,9 +987,8 @@ updump(dev)
        register short *rp;
        struct upst *st;
        register int retry;
        register short *rp;
        struct upst *st;
        register int retry;
-       register int retry;
 
 
-       unit = minor(dev) >> 3;
+       unit = upunit(dev);
        if (unit >= NUP)
                return (ENXIO);
 #define        phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
        if (unit >= NUP)
                return (ENXIO);
 #define        phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
@@ -1031,10 +1015,11 @@ updump(dev)
                return (EFAULT);
        start = 0;
        st = &upst[ui->ui_type];
                return (EFAULT);
        start = 0;
        st = &upst[ui->ui_type];
-       start = 0;
        sizes = phys(struct size *, st->sizes);
        sizes = phys(struct size *, st->sizes);
-       if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks)
+       if (dumplo < 0)
                return (EINVAL);
                return (EINVAL);
+       if (dumplo + num >= sizes[minor(dev)&07].nblocks)
+               num = sizes[minor(dev)&07].nblocks - dumplo;
        while (num > 0) {
                register struct pte *io;
                register int i;
        while (num > 0) {
                register struct pte *io;
                register int i;
@@ -1058,13 +1043,10 @@ updump(dev)
                *--rp = -blk*NBPG / sizeof (short);
                *--rp = UP_GO|UP_WCOM;
                retry = 0;
                *--rp = -blk*NBPG / sizeof (short);
                *--rp = UP_GO|UP_WCOM;
                retry = 0;
-               retry = 0;
                do {
                        DELAY(25);
                        if (++retry > 527)
                                break;
                do {
                        DELAY(25);
                        if (++retry > 527)
                                break;
-                       if (++retry > 527)
-                               break;
                } while ((upaddr->upcs1 & UP_RDY) == 0);
                if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
                        printf("up%d: not ready", unit);
                } while ((upaddr->upcs1 & UP_RDY) == 0);
                if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
                        printf("up%d: not ready", unit);
@@ -1074,14 +1056,6 @@ updump(dev)
                        }
                        printf(" (flakey)\n");
                }
                        }
                        printf(" (flakey)\n");
                }
-               if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
-                       printf("up%d: not ready", unit);
-                       if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
-                               printf("\n");
-                               return (EIO);
-                       }
-                       printf(" (flakey)\n");
-               }
                if (upaddr->upds&UPDS_ERR)
                        return (EIO);
                start += blk*NBPG;
                if (upaddr->upds&UPDS_ERR)
                        return (EIO);
                start += blk*NBPG;
@@ -1089,4 +1063,17 @@ updump(dev)
        }
        return (0);
 }
        }
        return (0);
 }
+
+upsize(dev)
+       dev_t dev;
+{
+       int unit = upunit(dev);
+       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