consolidate random data structures
[unix-history] / usr / src / sys / vax / mba / hp.c
index ceecab5..83c57d3 100644 (file)
@@ -1,4 +1,4 @@
-/*     hp.c    4.55    82/10/10        */
+/*     hp.c    4.65    83/02/10        */
 
 #ifdef HPDEBUG
 int    hpdebug;
 
 #ifdef HPDEBUG
 int    hpdebug;
@@ -18,6 +18,7 @@ int   hpbdebug;
  *     see if DCLR and/or RELEASE set attention status
  *     print bits of mr && mr2 symbolically
  */
  *     see if DCLR and/or RELEASE set attention status
  *     print bits of mr && mr2 symbolically
  */
+#include "../machine/pte.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -27,15 +28,14 @@ int hpbdebug;
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/map.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/map.h"
-#include "../h/pte.h"
 #include "../vax/mtpr.h"
 #include "../h/vm.h"
 #include "../h/cmap.h"
 #include "../h/dkbad.h"
 #include "../h/ioctl.h"
 #include "../vax/mtpr.h"
 #include "../h/vm.h"
 #include "../h/cmap.h"
 #include "../h/dkbad.h"
 #include "../h/ioctl.h"
-#include "../h/dkio.h"
 #include "../h/uio.h"
 
 #include "../h/uio.h"
 
+#include "../vax/dkio.h"
 #include "../vaxmba/mbareg.h"
 #include "../vaxmba/mbavar.h"
 #include "../vaxmba/hpreg.h"
 #include "../vaxmba/mbareg.h"
 #include "../vaxmba/mbavar.h"
 #include "../vaxmba/hpreg.h"
@@ -51,11 +51,7 @@ struct       size {
        0,      0,
        0,      0,
        0,      0,
        0,      0,
        0,      0,
        0,      0,
-#ifndef NOBADSECT
        291280, 118,            /* G=cyl 118 thru 814 */
        291280, 118,            /* G=cyl 118 thru 814 */
-#else
-       291346, 118,
-#endif
        0,      0,
 }, rm3_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 99 */
        0,      0,
 }, rm3_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 99 */
@@ -64,42 +60,17 @@ struct      size {
        0,      0,
        0,      0,
        0,      0,
        0,      0,
        0,      0,
        0,      0,
-#ifndef NOBADSECT
        81984,  310,            /* G=cyl 310 thru 822 */
        81984,  310,            /* G=cyl 310 thru 822 */
-#else
-       82080,  310,
-#endif
        0,      0,
 }, rm5_sizes[8] = {
        0,      0,
 }, rm5_sizes[8] = {
-#ifndef CAD
        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 */
        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 */
-#ifndef NOBADSECT
        86240,  681,            /* F=cyl 681 thru 822 */
        158592, 562,            /* G=cyl 562 thru 822 */
        86240,  681,            /* F=cyl 681 thru 822 */
        158592, 562,            /* G=cyl 562 thru 822 */
-#else
-       86336,  681,
-       158688, 562,
-#endif
-       291346, 82,             /* H=cyl 82 thru 561 */
-#else
-       15884,  0,              /* A=cyl 0 thru 26 */
-       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 */
-#else
-       81472,  681,
-       153824, 562,
-#endif
        291346, 82,             /* H=cyl 82 thru 561 */
        291346, 82,             /* H=cyl 82 thru 561 */
-#endif
 }, rm80_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 36 */
        33440,  37,             /* B=cyl 37 thru 114 */
 }, rm80_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 36 */
        33440,  37,             /* B=cyl 37 thru 114 */
@@ -119,13 +90,13 @@ struct     size {
        479850, 330,            /* G=cyl 330 thru 629 */
        448000, 50,             /* H=cyl 50 thru 329 */
 }, si9775_sizes[8] = {
        479850, 330,            /* G=cyl 330 thru 629 */
        448000, 50,             /* H=cyl 50 thru 329 */
 }, si9775_sizes[8] = {
-       16640,    0,            /* A=cyl   0 thru  12 */
-       34560,   13,            /* B=cyl  13 thru  39 */
-       1079040,  0,            /* C=cyl   0 thru 842 - whole disk */
-       0,        0,            /* D unused */
-       0,        0,            /* E unused */
-       0,        0,            /* F unused */
-       513280,  40,            /* G=cyl  40 thru 440 */
+       16640,    0,            /* A=cyl 0 thru 12 */
+       34560,   13,            /* B=cyl 13 thru 39 */
+       1079040,  0,            /* C=cyl 0 thru 842 */
+       0,        0,
+       0,        0,
+       0,        0,
+       513280,  40,            /* G=cyl 40 thru 440 */
        513280, 441,            /* H=cyl 441 thru 841 */
 }, si9730_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 49 */
        513280, 441,            /* H=cyl 441 thru 841 */
 }, si9730_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 49 */
@@ -135,11 +106,7 @@ struct     size {
        0,      0,
        0,      0,
        0,      0,
        0,      0,
        0,      0,
        0,      0,
-#ifndef NOBADSECT
        213664, 155,            /* H=cyl 155 thru 822 */
        213664, 155,            /* H=cyl 155 thru 822 */
-#else
-       213760, 155,
-#endif
 }, hpam_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 31 */
        33440,  32,             /* B=cyl 32 thru 97 */
 }, hpam_sizes[8] = {
        15884,  0,              /* A=cyl 0 thru 31 */
        33440,  32,             /* B=cyl 32 thru 97 */
@@ -149,6 +116,24 @@ struct     size {
        125440, 778,
        181760, 668,            /* G=cyl 668 thru 1022 */
        291346, 98,             /* H=cyl 98 thru 667 */
        125440, 778,
        181760, 668,            /* G=cyl 668 thru 1022 */
        291346, 98,             /* H=cyl 98 thru 667 */
+}, hpfj_sizes[8] = {
+       15884,  0,              /* A=cyl 0 thru 18 */
+       33440,  19,             /* B=cyl 19 thru 58 */
+       724120, 0,              /* C=cyl 0 thru 841 */
+       0, 0,
+       0, 0,
+       0, 0,
+       381711, 398,            /* G=cyl 398 thru 841 */
+       291346, 59,             /* H=cyl 59 thru 397 */
+}, hpfj48_sizes[8] = {
+       15884,  0,              /* A=cyl 0 thru 16 */
+       33440,  17,             /* B=cyl 17 thru 52 */
+       808176, 0,              /* C=cyl 0 thru 841 */
+       0, 0,
+       0, 0,
+       0, 0,
+       465456, 357,            /* G=cyl 357 thru 841 */
+       291346, 53,             /* H=cyl 52 thru 356 */
 };
 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
 
 };
 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
 
@@ -187,8 +172,12 @@ short      hptypes[] = {
        -1,
 #define        HPDT_CAPRICORN  10
        -1,
        -1,
 #define        HPDT_CAPRICORN  10
        -1,
-#define        HPDT_RM02       11
-       MBDT_RM02,              /* beware, actually capricorn */
+#define HPDT_EAGLE     11
+       -1,
+#define        HPDT_EAGLE48    12
+       -1,
+#define HPDT_RM02      13
+       MBDT_RM02,              /* beware, actually capricorn or eagle */
        0
 };
 struct mba_device *hpinfo[NHP];
        0
 };
 struct mba_device *hpinfo[NHP];
@@ -215,6 +204,8 @@ struct hpst {
        32,     40,     32*40,  843,    si9775_sizes,   /* 9775 */
        32,     10,     32*10,  823,    si9730_sizes,   /* 9730 */
        32,     16,     32*16,  1024,   hpam_sizes,     /* AMPEX capricorn */
        32,     40,     32*40,  843,    si9775_sizes,   /* 9775 */
        32,     10,     32*10,  823,    si9730_sizes,   /* 9730 */
        32,     16,     32*16,  1024,   hpam_sizes,     /* AMPEX capricorn */
+       43,     20,     43*20,  842,    hpfj_sizes,     /* Fujitsu EAGLE */
+       48,     20,     48*20,  842,    hpfj48_sizes,   /* 48 sector EAGLE */
 };
 
 u_char hp_offset[16] = {
 };
 
 u_char hp_offset[16] = {
@@ -225,15 +216,16 @@ u_char    hp_offset[16] = {
 };
 
 struct buf     rhpbuf[NHP];
 };
 
 struct buf     rhpbuf[NHP];
-#ifndef NOBADSECT
 struct buf     bhpbuf[NHP];
 struct dkbad   hpbad[NHP];
 struct buf     bhpbuf[NHP];
 struct dkbad   hpbad[NHP];
-#endif
-/* SHOULD CONSOLIDATE ALL THIS STUFF INTO A STRUCTURE */
-char   hpinit[NHP];
-char   hprecal[NHP];
-char   hphdr[NHP];
-daddr_t        mlsize[NHP];
+
+struct hpsoftc {
+       u_char  sc_hpinit;      /* drive initialized */
+       u_char  sc_recal;       /* recalibrate state */
+       u_char  sc_hdr;         /* next i/o includes header */
+       u_char  sc_doseeks;     /* perform explicit seeks */
+       daddr_t sc_mlsize;      /* ML11 size */
+} hpsoftc[NHP];
 
 #define        b_cylin b_resid
  
 
 #define        b_cylin b_resid
  
@@ -245,99 +237,138 @@ daddr_t  mlsize[NHP];
 #ifdef INTRLVE
 daddr_t dkblock();
 #endif
 #ifdef INTRLVE
 daddr_t dkblock();
 #endif
-int    hpseek;
 
 /*ARGSUSED*/
 hpattach(mi, slave)
 
 /*ARGSUSED*/
 hpattach(mi, slave)
-       struct mba_device *mi;
+       register struct mba_device *mi;
 {
 {
-       register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
 
 
-       switch (mi->mi_type) {
+       mi->mi_type = hpmaptype(mi);
+       if (!ML11 && mi->mi_dk >= 0) {
+               struct hpst *st = &hpst[mi->mi_type];
+
+               dk_mspw[mi->mi_dk] = 1.0 / 60 / (st->nsect * 256);
+       }
+}
+
+/*
+ * Map apparent MASSBUS drive type into manufacturer
+ * specific configuration.  For SI controllers this is done
+ * based on codes in the serial number register.  For
+ * EMULEX controllers, the track and sector attributes are
+ * used when the drive type is an RM02 (not supported by DEC).
+ */
+hpmaptype(mi)
+       register struct mba_device *mi;
+{
+       register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
+       register int type = mi->mi_type;
 
        /*
         * Model-byte processing for SI 9400 controllers.
         * NB:  Only deals with RM03 and RM05 emulations.
         */
 
        /*
         * Model-byte processing for SI 9400 controllers.
         * NB:  Only deals with RM03 and RM05 emulations.
         */
-       case HPDT_RM03:
-       case HPDT_RM05: {
-               register int hpsn;
+       if (type == HPDT_RM03 || type == HPDT_RM05) {
+               int hpsn = hpaddr->hpsn;
 
 
-               hpsn = hpaddr->hpsn;
                if ((hpsn & SIMB_LU) != mi->mi_drive)
                if ((hpsn & SIMB_LU) != mi->mi_drive)
-                       break;
+                       return (type);
                switch ((hpsn & SIMB_MB) & ~(SIMB_S6|SIRM03|SIRM05)) {
 
                case SI9775D:
                        printf("hp%d: si 9775 (direct)\n", mi->mi_unit);
                switch ((hpsn & SIMB_MB) & ~(SIMB_S6|SIRM03|SIRM05)) {
 
                case SI9775D:
                        printf("hp%d: si 9775 (direct)\n", mi->mi_unit);
-                       mi->mi_type = HPDT_9775;
+                       type = HPDT_9775;
                        break;
 
                case SI9730D:
                        printf("hp%d: si 9730 (direct)\n", mi->mi_unit);
                        break;
 
                case SI9730D:
                        printf("hp%d: si 9730 (direct)\n", mi->mi_unit);
-                       mi->mi_type = HPDT_9730;
+                       type = HPDT_9730;
                        break;
 
                        break;
 
-#ifdef CAD
                /*
                /*
-                * AMPEX 9300, SI Combination needs a have the drive cleared
-                * before we start.  We do not know why, but tests show
-                * that the recalibrate fixes the problem.
+                * AMPEX 9300, SI Combination needs a have the
+                * drive cleared before we start.  We do not know
+                * why, but tests show that the recalibrate fixes
+                * the problem.
                 */
                case SI9766:
                        printf("hp%d: 9776/9300\n", mi->mi_unit);
                 */
                case SI9766:
                        printf("hp%d: 9776/9300\n", mi->mi_unit);
-                       mi->mi_type = HPDT_RM05;
+                       type = HPDT_RM05;
                        hpaddr->hpcs1 = HP_RECAL|HP_GO;
                        DELAY(100000);
                        break;
 
                case SI9762:
                        printf("hp%d: 9762\n", mi->mi_unit);
                        hpaddr->hpcs1 = HP_RECAL|HP_GO;
                        DELAY(100000);
                        break;
 
                case SI9762:
                        printf("hp%d: 9762\n", mi->mi_unit);
-                       mi->mi_type = HPDT_RM03;
+                       type = HPDT_RM03;
                        break;
                        break;
-#endif
-               }
-               break;
                }
                }
+               return (type);
+       }
 
        /*
 
        /*
-        * CAPRICORN KLUDGE...poke the holding register
-        * to find out the number of tracks.  If it's 15
-        * we believe it's a Capricorn.
+        * EMULEX SC750 or SC780.  Poke the holding register.
         */
         */
-       case HPDT_RM02:
+       if (type == HPDT_RM02) {
+               int ntracks, nsectors;
+
                hpaddr->hpcs1 = HP_NOP;
                hpaddr->hphr = HPHR_MAXTRAK;
                hpaddr->hpcs1 = HP_NOP;
                hpaddr->hphr = HPHR_MAXTRAK;
-               if ((hpaddr->hphr&0xffff) == 15) {
+               ntracks = (hpaddr->hphr & 0xffff) + 1;
+               if (ntracks == 16) {
                        printf("hp%d: capricorn\n", mi->mi_unit);
                        printf("hp%d: capricorn\n", mi->mi_unit);
-                       mi->mi_type = HPDT_CAPRICORN;
+                       type = HPDT_CAPRICORN;
+                       goto done;
+               }
+               if (ntracks != 20) {
+                       printf("hp%d: ntracks %d: unknown device\n", ntracks);
+                       goto done;
+               }
+               hpaddr->hpcs1 = HP_NOP;
+               hpaddr->hphr = HPHR_MAXSECT;
+               nsectors = (hpaddr->hphr & 0xffff) + 1;
+               printf("hp%d: ", mi->mi_unit);
+               if (nsectors == 43)
+                       type = HPDT_EAGLE;
+               else {
+                       type = HPDT_EAGLE48;
+                       printf("modified ");
                }
                }
+               printf("eagle\n");
+done:
                hpaddr->hpcs1 = HP_DCLR|HP_GO;
                hpaddr->hpcs1 = HP_DCLR|HP_GO;
-               break;
+               return (type);
+       } 
 
 
-       case HPDT_ML11A:
-       case HPDT_ML11B: {
-               register int trt, sz;
+       /*
+        * Map all ML11's to the same type.  Also calculate
+        * transfer rates based on device characteristics.
+        */
+       if (type == HPDT_ML11A || type == HPDT_ML11B) {
+               register struct hpsoftc *sc = &hpsoftc[mi->mi_unit];
+               register int trt;
 
 
-               sz = hpaddr->hpmr & HPMR_SZ;
+               sc->sc_mlsize = hpaddr->hpmr & HPMR_SZ;
                if ((hpaddr->hpmr & HPMR_ARRTYP) == 0)
                if ((hpaddr->hpmr & HPMR_ARRTYP) == 0)
-                       sz >>= 2;
-               mlsize[mi->mi_unit] = sz;
+                       sc->sc_mlsize >>= 2;
                if (mi->mi_dk >= 0) {
                        trt = (hpaddr->hpmr & HPMR_TRT) >> 8;
                        dk_mspw[mi->mi_dk] = 1.0 / (1<<(20-trt));
                }
                if (mi->mi_dk >= 0) {
                        trt = (hpaddr->hpmr & HPMR_TRT) >> 8;
                        dk_mspw[mi->mi_dk] = 1.0 / (1<<(20-trt));
                }
-               /* A CHEAT - ML11B D.T. SHOULD == ML11A */
-               mi->mi_type = HPDT_ML11A;
-               break;
-               }
+               type = HPDT_ML11A;
        }
        }
-       if (!ML11 && mi->mi_dk >= 0) {
-               register struct hpst *st = &hpst[mi->mi_type];
+       return (type);
+}
 
 
-               dk_mspw[mi->mi_dk] = 1.0 / 60 / (st->nsect * 256);
-       }
+hpopen(dev)
+       dev_t dev;
+{
+       register int unit = minor(dev) >> 3;
+       register struct mba_device *mi;
+
+       if (unit >= NHP || (mi = hpinfo[unit]) == 0 || mi->mi_alive == 0)
+               return (ENXIO);
+       return (0);
 }
 
 hpstrategy(bp)
 }
 
 hpstrategy(bp)
@@ -360,8 +391,10 @@ hpstrategy(bp)
                goto bad;
        st = &hpst[mi->mi_type];
        if (ML11) {
                goto bad;
        st = &hpst[mi->mi_type];
        if (ML11) {
+               struct hpsoftc *sc = &hpsoftc[unit];
+
                if (bp->b_blkno < 0 ||
                if (bp->b_blkno < 0 ||
-                   dkblock(bp)+sz > mlsize[mi->mi_unit])
+                   dkblock(bp)+sz > sc->sc_mlsize)
                        goto bad;
                bp->b_cylin = 0;
        } else {
                        goto bad;
                bp->b_cylin = 0;
        } else {
@@ -389,18 +422,17 @@ hpustart(mi)
        register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
        register struct buf *bp = mi->mi_tab.b_actf;
        register struct hpst *st = &hpst[mi->mi_type];
        register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
        register struct buf *bp = mi->mi_tab.b_actf;
        register struct hpst *st = &hpst[mi->mi_type];
+       struct hpsoftc *sc = &hpsoftc[mi->mi_unit];
        daddr_t bn;
        int sn, dist;
 
        hpaddr->hpcs1 = 0;
        if ((hpaddr->hpcs1&HP_DVA) == 0)
                return (MBU_BUSY);
        daddr_t bn;
        int sn, dist;
 
        hpaddr->hpcs1 = 0;
        if ((hpaddr->hpcs1&HP_DVA) == 0)
                return (MBU_BUSY);
-       if ((hpaddr->hpds & HPDS_VV) == 0 || hpinit[mi->mi_unit] == 0) {
-#ifndef NOBADSECT
+       if ((hpaddr->hpds & HPDS_VV) == 0 || !sc->sc_hpinit) {
                struct buf *bbp = &bhpbuf[mi->mi_unit];
                struct buf *bbp = &bhpbuf[mi->mi_unit];
-#endif
 
 
-               hpinit[mi->mi_unit] = 1;
+               sc->sc_hpinit = 1;
                hpaddr->hpcs1 = HP_DCLR|HP_GO;
                if (mi->mi_mba->mba_drv[0].mbd_as & (1<<mi->mi_drive))
                        printf("DCLR attn\n");
                hpaddr->hpcs1 = HP_DCLR|HP_GO;
                if (mi->mi_mba->mba_drv[0].mbd_as & (1<<mi->mi_drive))
                        printf("DCLR attn\n");
@@ -408,7 +440,6 @@ hpustart(mi)
                if (!ML11)
                        hpaddr->hpof = HPOF_FMT22;
                mbclrattn(mi);
                if (!ML11)
                        hpaddr->hpof = HPOF_FMT22;
                mbclrattn(mi);
-#ifndef NOBADSECT
                if (!ML11) {
                        bbp->b_flags = B_READ|B_BUSY;
                        bbp->b_dev = bp->b_dev;
                if (!ML11) {
                        bbp->b_flags = B_READ|B_BUSY;
                        bbp->b_dev = bp->b_dev;
@@ -420,7 +451,6 @@ hpustart(mi)
                        bbp->av_forw = bp;
                        bp = bbp;
                }
                        bbp->av_forw = bp;
                        bp = bbp;
                }
-#endif
        }
        if (mi->mi_tab.b_active || mi->mi_hd->mh_ndrive == 1)
                return (MBU_DODATA);
        }
        if (mi->mi_tab.b_active || mi->mi_hd->mh_ndrive == 1)
                return (MBU_DODATA);
@@ -432,7 +462,7 @@ hpustart(mi)
        sn = bn%st->nspc;
        sn = (sn+st->nsect-hpSDIST)%st->nsect;
        if (bp->b_cylin == (hpaddr->hpdc & 0xffff)) {
        sn = bn%st->nspc;
        sn = (sn+st->nsect-hpSDIST)%st->nsect;
        if (bp->b_cylin == (hpaddr->hpdc & 0xffff)) {
-               if (hpseek)
+               if (sc->sc_seek)
                        return (MBU_DODATA);
                dist = ((hpaddr->hpla & 0xffff)>>6) - st->nsect + 1;
                if (dist < 0)
                        return (MBU_DODATA);
                dist = ((hpaddr->hpla & 0xffff)>>6) - st->nsect + 1;
                if (dist < 0)
@@ -441,7 +471,7 @@ hpustart(mi)
                        return (MBU_DODATA);
        } else
                hpaddr->hpdc = bp->b_cylin;
                        return (MBU_DODATA);
        } else
                hpaddr->hpdc = bp->b_cylin;
-       if (hpseek)
+       if (sc->sc_seek)
                hpaddr->hpcs1 = HP_SEEK|HP_GO;
        else {
                hpaddr->hpda = sn;
                hpaddr->hpcs1 = HP_SEEK|HP_GO;
        else {
                hpaddr->hpda = sn;
@@ -456,6 +486,7 @@ hpstart(mi)
        register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
        register struct buf *bp = mi->mi_tab.b_actf;
        register struct hpst *st = &hpst[mi->mi_type];
        register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
        register struct buf *bp = mi->mi_tab.b_actf;
        register struct hpst *st = &hpst[mi->mi_type];
+       struct hpsoftc *sc = &hpsoftc[mi->mi_unit];
        daddr_t bn;
        int sn, tn;
 
        daddr_t bn;
        int sn, tn;
 
@@ -469,7 +500,7 @@ hpstart(mi)
                hpaddr->hpdc = bp->b_cylin;
                hpaddr->hpda = (tn << 8) + sn;
        }
                hpaddr->hpdc = bp->b_cylin;
                hpaddr->hpda = (tn << 8) + sn;
        }
-       if (hphdr[mi->mi_unit]) {
+       if (sc->sc_hdr) {
                if (bp->b_flags & B_READ)
                        return (HP_RHDR|HP_GO);
                else
                if (bp->b_flags & B_READ)
                        return (HP_RHDR|HP_GO);
                else
@@ -484,15 +515,15 @@ hpdtint(mi, mbsr)
 {
        register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
        register struct buf *bp = mi->mi_tab.b_actf;
 {
        register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
        register struct buf *bp = mi->mi_tab.b_actf;
+       register struct hpst *st = &hpst[mi->mi_type];
        register int er1, er2;
        register int er1, er2;
+       struct hpsoftc *sc = &hpsoftc[mi->mi_unit];
        int retry = 0;
 
        int retry = 0;
 
-#ifndef NOBADSECT
        if (bp->b_flags&B_BAD) {
                if (hpecc(mi, CONT))
                        return(MBD_RESTARTED);
        }
        if (bp->b_flags&B_BAD) {
                if (hpecc(mi, CONT))
                        return(MBD_RESTARTED);
        }
-#endif
        if (hpaddr->hpds&HPDS_ERR || mbsr&MBSR_EBITS) {
 #ifdef HPDEBUG
                if (hpdebug) {
        if (hpaddr->hpds&HPDS_ERR || mbsr&MBSR_EBITS) {
 #ifdef HPDEBUG
                if (hpdebug) {
@@ -519,20 +550,23 @@ hpdtint(mi, mbsr)
                if (er1&HPER1_WLE) {
                        printf("hp%d: write locked\n", dkunit(bp));
                        bp->b_flags |= B_ERROR;
                if (er1&HPER1_WLE) {
                        printf("hp%d: write locked\n", dkunit(bp));
                        bp->b_flags |= B_ERROR;
-               } else if ((er1&0xffff) == HPER1_FER && RP06 &&
-                   hphdr[mi->mi_unit] == 0) {
-#ifndef NOBADSECT
+               } else if ((er1&0xffff) == HPER1_FER && RP06 && !sc->sc_hdr) {
                        if (hpecc(mi, BSE))
                                return(MBD_RESTARTED);
                        else
                        if (hpecc(mi, BSE))
                                return(MBD_RESTARTED);
                        else
-#endif
                                goto hard;
                } else if (++mi->mi_tab.b_errcnt > 27 ||
                    mbsr & MBSR_HARD ||
                    er1 & HPER1_HARD ||
                                goto hard;
                } else if (++mi->mi_tab.b_errcnt > 27 ||
                    mbsr & MBSR_HARD ||
                    er1 & HPER1_HARD ||
-                   hphdr[mi->mi_unit] ||
+                   sc->sc_hdr ||
                    (!ML11 && (er2 & HPER2_HARD))) {
 hard:
                    (!ML11 && (er2 & HPER2_HARD))) {
 hard:
+                       if (ML11)
+                               bp->b_blkno = hpaddr->hpda&0xffff;
+                       else
+                               bp->b_blkno = (hpaddr->hpdc*st->nspc)&0xffff +
+                                         ((hpaddr->hpda>>8)&0xffff)*st->nsect +
+                                               (hpaddr->hpda&0x1f);
                        harderr(bp, "hp");
                        if (mbsr & (MBSR_EBITS &~ (MBSR_DTABT|MBSR_MBEXC)))
                                printf("mbsr=%b ", mbsr, mbsr_bits);
                        harderr(bp, "hp");
                        if (mbsr & (MBSR_EBITS &~ (MBSR_DTABT|MBSR_MBEXC)))
                                printf("mbsr=%b ", mbsr, mbsr_bits);
@@ -545,13 +579,12 @@ hard:
                                printf(" mr2=%o", hpaddr->hpmr2&0xffff);
                        printf("\n");
                        bp->b_flags |= B_ERROR;
                                printf(" mr2=%o", hpaddr->hpmr2&0xffff);
                        printf("\n");
                        bp->b_flags |= B_ERROR;
-                       hprecal[mi->mi_unit] = 0;
+                       retry = 0;
+                       sc->sc_recal = 0;
                } else if ((er2 & HPER2_BSE) && !ML11) {
                } else if ((er2 & HPER2_BSE) && !ML11) {
-#ifndef NOBADSECT
                        if (hpecc(mi, BSE))
                                return(MBD_RESTARTED);
                        else
                        if (hpecc(mi, BSE))
                                return(MBD_RESTARTED);
                        else
-#endif
                                goto hard;
                } else if (RM80 && er2&HPER2_SSE) {
                        (void) hpecc(mi, SSE);
                                goto hard;
                } else if (RM80 && er2&HPER2_SSE) {
                        (void) hpecc(mi, SSE);
@@ -568,7 +601,7 @@ hard:
                                goto hard;
                } else if ((mi->mi_tab.b_errcnt&07) == 4) {
                        hpaddr->hpcs1 = HP_RECAL|HP_GO;
                                goto hard;
                } else if ((mi->mi_tab.b_errcnt&07) == 4) {
                        hpaddr->hpcs1 = HP_RECAL|HP_GO;
-                       hprecal[mi->mi_unit] = 1;
+                       sc->sc_recal = 1;
                        return(MBD_RESTARTED);
                }
                if (retry)
                        return(MBD_RESTARTED);
                }
                if (retry)
@@ -576,8 +609,8 @@ hard:
        }
 #ifdef HPDEBUG
        else
        }
 #ifdef HPDEBUG
        else
-               if (hpdebug && hprecal[mi->mi_unit]) {
-                       printf("recal %d ", hprecal[mi->mi_unit]);
+               if (hpdebug && sc->sc_recal) {
+                       printf("recal %d ", sc->sc_recal);
                        printf("errcnt %d\n", mi->mi_tab.b_errcnt);
                        printf("mbsr=%b ", mbsr, mbsr_bits);
                        printf("er1=%b er2=%b\n",
                        printf("errcnt %d\n", mi->mi_tab.b_errcnt);
                        printf("mbsr=%b ", mbsr, mbsr_bits);
                        printf("er1=%b er2=%b\n",
@@ -585,12 +618,12 @@ hard:
                            hpaddr->hper2, HPER2_BITS);
                }
 #endif
                            hpaddr->hper2, HPER2_BITS);
                }
 #endif
-       switch (hprecal[mi->mi_unit]) {
+       switch (sc->sc_recal) {
 
        case 1:
                hpaddr->hpdc = bp->b_cylin;
                hpaddr->hpcs1 = HP_SEEK|HP_GO;
 
        case 1:
                hpaddr->hpdc = bp->b_cylin;
                hpaddr->hpcs1 = HP_SEEK|HP_GO;
-               hprecal[mi->mi_unit]++;
+               sc->sc_recal++;
                return (MBD_RESTARTED);
        case 2:
                if (mi->mi_tab.b_errcnt < 16 ||
                return (MBD_RESTARTED);
        case 2:
                if (mi->mi_tab.b_errcnt < 16 ||
@@ -598,14 +631,14 @@ hard:
                        goto donerecal;
                hpaddr->hpof = hp_offset[mi->mi_tab.b_errcnt & 017]|HPOF_FMT22;
                hpaddr->hpcs1 = HP_OFFSET|HP_GO;
                        goto donerecal;
                hpaddr->hpof = hp_offset[mi->mi_tab.b_errcnt & 017]|HPOF_FMT22;
                hpaddr->hpcs1 = HP_OFFSET|HP_GO;
-               hprecal[mi->mi_unit]++;
+               sc->sc_recal++;
                return (MBD_RESTARTED);
        donerecal:
        case 3:
                return (MBD_RESTARTED);
        donerecal:
        case 3:
-               hprecal[mi->mi_unit] = 0;
+               sc->sc_recal = 0;
                return (MBD_RETRY);
        }
                return (MBD_RETRY);
        }
-       hphdr[mi->mi_unit] = 0;
+       sc->sc_hdr = 0;
        bp->b_resid = -(mi->mi_mba->mba_bcr) & 0xffff;
        if (mi->mi_tab.b_errcnt >= 16) {
                /*
        bp->b_resid = -(mi->mi_mba->mba_bcr) & 0xffff;
        if (mi->mi_tab.b_errcnt >= 16) {
                /*
@@ -657,11 +690,11 @@ hpioctl(dev, cmd, data, flag)
        switch (cmd) {
 
        case DKIOCHDR:  /* do header read/write */
        switch (cmd) {
 
        case DKIOCHDR:  /* do header read/write */
-               hphdr[minor(dev)>>3] = 1;
-               return;
+               hpsoftc[minor(dev) >> 3].sc_hdr = 1;
+               return (0);
 
        default:
 
        default:
-               u.u_error = ENXIO;
+               return (ENXIO);
        }
 }
 
        }
 }
 
@@ -680,11 +713,9 @@ hpecc(mi, flag)
        bcr = mbp->mba_bcr & 0xffff;
        if (bcr)
                bcr |= 0xffff0000;              /* sxt */
        bcr = mbp->mba_bcr & 0xffff;
        if (bcr)
                bcr |= 0xffff0000;              /* sxt */
-#ifndef NOBADSECT
        if (flag == CONT)
                npf = bp->b_error;
        else
        if (flag == CONT)
                npf = bp->b_error;
        else
-#endif
                npf = btop(bcr + bp->b_bcount);
        o = (int)bp->b_un.b_addr & PGOFSET;
        bn = dkblock(bp);
                npf = btop(bcr + bp->b_bcount);
        o = (int)bp->b_un.b_addr & PGOFSET;
        bn = dkblock(bp);
@@ -695,8 +726,7 @@ hpecc(mi, flag)
        cn += tn/st->ntrak;
        tn %= st->ntrak;
        switch (flag) {
        cn += tn/st->ntrak;
        tn %= st->ntrak;
        switch (flag) {
-       case ECC:
-               {
+       case ECC: {
                register int i;
                caddr_t addr;
                struct pte mpte;
                register int i;
                caddr_t addr;
                struct pte mpte;
@@ -729,7 +759,6 @@ hpecc(mi, flag)
                mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf));
                break;
 
                mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf));
                break;
 
-#ifndef NOBADSECT
        case BSE:
 #ifdef HPBDEBUG
                if (hpbdebug)
        case BSE:
 #ifdef HPBDEBUG
                if (hpbdebug)
@@ -762,7 +791,6 @@ hpecc(mi, flag)
                if ((mbp->mba_bcr & 0xffff) == 0)
                        return(0);
                break;
                if ((mbp->mba_bcr & 0xffff) == 0)
                        return(0);
                break;
-#endif
        }
        rp->hpcs1 = HP_DCLR|HP_GO;
        if (rp->hpof&HPOF_SSEI)
        }
        rp->hpcs1 = HP_DCLR|HP_GO;
        if (rp->hpof&HPOF_SSEI)