conservative fix for increasing FIN
[unix-history] / usr / src / sys / vax / stand / hp.c
index fd07755..59fba1f 100644 (file)
@@ -1,4 +1,10 @@
-/*     hp.c    6.4     84/02/06        */
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)hp.c        6.8 (Berkeley) %G%
+ */
 
 /*
  * RP??/RM?? disk driver
 
 /*
  * RP??/RM?? disk driver
 #include "saio.h"
 #include "savax.h"
 
 #include "saio.h"
 #include "savax.h"
 
+#define        RETRIES         27
+
 #define        MASKREG(reg)    ((reg)&0xffff)
 
 #define        MAXBADDESC      126
 #define        SECTSIZ         512     /* sector size in bytes */
 #define        HDRSIZ          4       /* number of bytes in sector header */
 #define        MASKREG(reg)    ((reg)&0xffff)
 
 #define        MAXBADDESC      126
 #define        SECTSIZ         512     /* sector size in bytes */
 #define        HDRSIZ          4       /* number of bytes in sector header */
-#define        MAXECC          5       /* max # bits allow in ecc error w/ F_ECCLM */
 
 
-char   hp_type[MAXNMBA*8] = { 0 };
 extern struct st hpst[];
 extern struct st hpst[];
+extern short hptypes[];
 
 
-short  hptypes[] = {
-       MBDT_RM03,
-       MBDT_RM05,
-       MBDT_RP06,
-       MBDT_RM80,
-       MBDT_RP05,
-       MBDT_RP07,
-       MBDT_ML11A,
-       MBDT_ML11B,
-       -1,             /* 9755 */
-       -1,             /* 9730 */
-       -1,             /* Capricorn */
-       -1,             /* Eagle */
-       MBDT_RM02,      /* actually something else */
-       -1,             /* 9300 */
-       0
-};
-
-#define        RP06 (hptypes[hp_type[unit]] <= MBDT_RP06)
-#define        ML11 (hptypes[hp_type[unit]] == MBDT_ML11A)
-#define        RM80 (hptypes[hp_type[unit]] == MBDT_RM80)
+#define        RP06 (hptypes[sc->type] == MBDT_RP06 || hptypes[sc->type] == MBDT_RP05 \
+       || hptypes[sc->type] == MBDT_RP04)
+#define        ML11 (hptypes[sc->type] == MBDT_ML11A)
+#define        RM80 (hptypes[sc->type] == MBDT_RM80)
 
 u_char hp_offset[16] = {
     HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400,
 
 u_char hp_offset[16] = {
     HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400,
@@ -58,11 +48,17 @@ u_char      hp_offset[16] = {
 };
 
 struct dkbad hpbad[MAXNMBA*8];
 };
 
 struct dkbad hpbad[MAXNMBA*8];
-int    ssect[MAXNMBA*8];               /* 1 when on track w/skip sector */
 
 
-int    hpdebug[MAXNMBA*8];
-#define        HPF_BSEDEBUG    01      /* debugging bad sector forwarding */
-#define        HPF_ECCDEBUG    02      /* debugging ecc correction */
+struct hp_softc {
+       char    type;
+       char    gottype;
+       char    ssect;          /* 1 when on track w/skip sector */
+       char    debug;
+#      define  HPF_BSEDEBUG    01      /* debugging bad sector forwarding */
+#      define  HPF_ECCDEBUG    02      /* debugging ecc correction */
+       int     ecclim;
+       int     retries;
+} hp_softc[MAXNMBA * 8];
 
 int    sectsiz;
 
 
 int    sectsiz;
 
@@ -80,9 +76,10 @@ hpopen(io)
        register unit = io->i_unit;
        struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit);
        register struct st *st;
        register unit = io->i_unit;
        struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit);
        register struct st *st;
+       register struct hp_softc *sc = &hp_softc[unit];
 
        mbainit(UNITTOMBA(unit));
 
        mbainit(UNITTOMBA(unit));
-       if (hp_type[unit] == 0) {
+       if (sc->gottype == 0) {
                register i, type = hpaddr->hpdt & MBDT_TYPE;
                struct iob tio;
 
                register i, type = hpaddr->hpdt & MBDT_TYPE;
                struct iob tio;
 
@@ -91,15 +88,18 @@ hpopen(io)
                                goto found;
                _stop("unknown drive type");
 found:
                                goto found;
                _stop("unknown drive type");
 found:
+               sc->retries = RETRIES;
+               sc->ecclim = 11;
+               sc->debug = 0;
                hpaddr->hpcs1 = HP_DCLR|HP_GO;          /* init drive */
                hpaddr->hpcs1 = HP_PRESET|HP_GO;
                if (!ML11)
                        hpaddr->hpof = HPOF_FMT22;
                hpaddr->hpcs1 = HP_DCLR|HP_GO;          /* init drive */
                hpaddr->hpcs1 = HP_PRESET|HP_GO;
                if (!ML11)
                        hpaddr->hpof = HPOF_FMT22;
-               hp_type[unit] = hpmaptype(hpaddr, i, unit);
+               sc->type = hpmaptype(hpaddr, i, UNITTODRIVE(unit));
                /*
                 * Read in the bad sector table.
                 */
                /*
                 * Read in the bad sector table.
                 */
-               st = &hpst[hp_type[unit]];
+               st = &hpst[sc->type];
                tio = *io;
                tio.i_bn = st->nspc * st->ncyl - st->nsect;
                tio.i_ma = (char *)&hpbad[unit];
                tio = *io;
                tio.i_bn = st->nspc * st->ncyl - st->nsect;
                tio.i_ma = (char *)&hpbad[unit];
@@ -116,9 +116,10 @@ found:
                                hpbad[unit].bt_bad[i].bt_cyl = -1;
                                hpbad[unit].bt_bad[i].bt_trksec = -1;
                        }
                                hpbad[unit].bt_bad[i].bt_cyl = -1;
                                hpbad[unit].bt_bad[i].bt_trksec = -1;
                        }
-               }       
+               }
+               sc->gottype = 1;
        }
        }
-       st = &hpst[hp_type[unit]];
+       st = &hpst[sc->type];
        if (io->i_boff < 0 || io->i_boff > 7 ||
            st->off[io->i_boff]== -1)
                _stop("hp bad minor");
        if (io->i_boff < 0 || io->i_boff > 7 ||
            st->off[io->i_boff]== -1)
                _stop("hp bad minor");
@@ -132,8 +133,9 @@ hpstrategy(io, func)
        struct mba_regs *mba = mbamba(unit);
        daddr_t bn, startblock;
        struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit);
        struct mba_regs *mba = mbamba(unit);
        daddr_t bn, startblock;
        struct hpdevice *hpaddr = (struct hpdevice *)mbadrv(unit);
-       struct st *st = &hpst[hp_type[unit]];
-       int cn, tn, sn, bytecnt, bytesleft; 
+       register struct hp_softc *sc = &hp_softc[unit];
+       struct st *st = &hpst[sc->type];
+       int cn, tn, sn, bytecnt, bytesleft, rv; 
        char *membase;
        int er1, er2, hprecal;
 
        char *membase;
        int er1, er2, hprecal;
 
@@ -147,8 +149,8 @@ hpstrategy(io, func)
                        hpaddr->hpof = HPOF_FMT22;
        }
        io->i_errcnt = 0;
                        hpaddr->hpof = HPOF_FMT22;
        }
        io->i_errcnt = 0;
-       ssect[unit] = 0;
-       bytecnt = io->i_cc;
+       sc->ssect = 0;
+       rv = bytecnt = io->i_cc;
        membase = io->i_ma;
        startblock = io->i_bn;
        hprecal = 0;
        membase = io->i_ma;
        startblock = io->i_bn;
        hprecal = 0;
@@ -158,7 +160,7 @@ restart:
        cn = bn/st->nspc;
        sn = bn%st->nspc;
        tn = sn/st->nsect;
        cn = bn/st->nspc;
        sn = bn%st->nspc;
        tn = sn/st->nsect;
-       sn = sn%st->nsect + ssect[unit];
+       sn = sn%st->nsect + sc->ssect;
 
        HPWAIT(hpaddr);
        mba->mba_sr = -1;
 
        HPWAIT(hpaddr);
        mba->mba_sr = -1;
@@ -168,8 +170,10 @@ restart:
                hpaddr->hpdc = cn;
                hpaddr->hpda = (tn << 8) + sn;
        }
                hpaddr->hpdc = cn;
                hpaddr->hpda = (tn << 8) + sn;
        }
-       if (mbastart(io, func) != 0)            /* start transfer */
-               return (-1);
+       if (mbastart(io, func) != 0) {          /* start transfer */
+               rv = -1;
+               goto done;
+       }
        HPWAIT(hpaddr);
        /*
         * Successful data transfer, return.
        HPWAIT(hpaddr);
        /*
         * Successful data transfer, return.
@@ -192,9 +196,9 @@ restart:
        sn = bn%st->nspc;
        tn = sn/st->nsect;
        sn = sn%st->nsect;
        sn = bn%st->nspc;
        tn = sn/st->nsect;
        sn = sn%st->nsect;
-       if (hpdebug[unit] & (HPF_ECCDEBUG|HPF_BSEDEBUG)) {
-               printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b\n",
-                       cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS);
+       if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG)) {
+               printf("hp error: sn%d (cyl,trk,sec)=(%d,%d,%d) ds=%b\n",
+                       bn, cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS);
                printf("er1=%b er2=%b\n", er1, HPER1_BITS, er2, HPER2_BITS);
                printf("bytes left: %d, of 0x%x, da 0x%x\n",-bytesleft,
                        hpaddr->hpof, hpaddr->hpda);
                printf("er1=%b er2=%b\n", er1, HPER1_BITS, er2, HPER2_BITS);
                printf("bytes left: %d, of 0x%x, da 0x%x\n",-bytesleft,
                        hpaddr->hpof, hpaddr->hpda);
@@ -202,75 +206,31 @@ restart:
        if (er1 & HPER1_HCRC) {
                er1 &= ~(HPER1_HCE|HPER1_FER);
                er2 &= ~HPER2_BSE;
        if (er1 & HPER1_HCRC) {
                er1 &= ~(HPER1_HCE|HPER1_FER);
                er2 &= ~HPER2_BSE;
+               if ((io->i_flgs&F_NBSF) == 0 && hpecc(io, BSE) == 0)
+                       goto success;
        }
        /*
         * Give up early if drive write locked.
         */
        if (er1&HPER1_WLE) {
                printf("hp%d: write locked\n", unit);
        }
        /*
         * Give up early if drive write locked.
         */
        if (er1&HPER1_WLE) {
                printf("hp%d: write locked\n", unit);
-               return (-1);
+               rv = -1;
+               goto done;
        }
        /*
        }
        /*
-        * Interpret format error bit as a bad block on RP06's.
-        */
-       if (MASKREG(er1) == HPER1_FER && RP06)
-               goto badsect;
-
-       /*
-        * If a hard error, or maximum retry count
-        * exceeded, clear controller state and
-        * pass back error to caller.
+        * Skip sector handling.
         */
         */
-       if (++io->i_errcnt > 27 || (er1 & HPER1_HARD) ||
-           (!ML11 && (er2 & HPER2_HARD))) {
-               /*
-                * The last ditch effort to bad sector forward
-                * below will probably fail since mba byte ctr
-                * (bcr) is different for BSE and ECC errors and
-                * the wrong block will be revectored to if one
-                * has 2 contiguous bad blocks and reads the second.
-                * For now, we can probably just let a header CRC
-                * error be handled like a BSE since no data will
-                * have been transferred and the bcr should the same
-                * as it would with a BSE error.
-                * --ghg.
-                */
-               if (er1 & HPER1_HCRC) 
-                       if ((io->i_flgs&F_NBSF) == 0 && hpecc(io, BSE) == 0)
-                               goto success;
-hard0:
-               io->i_error = EHER;
-               if (mba->mba_sr & (MBSR_WCKUP|MBSR_WCKLWR))
-                       io->i_error = EWCK;
-hard:
-               io->i_errblk = bn + ssect[unit];
-               printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b \n",
-                          cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS);
-               printf("er1=%b er2=%b", er1, HPER1_BITS, er2, HPER2_BITS);
-               if (hpaddr->hpmr)
-                       printf(" mr1=%o", MASKREG(hpaddr->hpmr));
-               if (hpaddr->hpmr2)
-                       printf(" mr2=%o", MASKREG(hpaddr->hpmr2));
-               if (hpdebug[unit] & (HPF_BSEDEBUG|HPF_ECCDEBUG))
-                       printf(" dc=%d, da=0x%x",MASKREG(hpaddr->hpdc),
-                         MASKREG(hpaddr->hpda));
-               hpaddr->hpcs1 = HP_DCLR|HP_GO;
-               printf("\n");
-               bytecnt = -1;
-               goto done;
-
+       if (RM80 && (er2 & HPER2_SSE)) {
+               (void) hpecc(io, SSE);
+               sc->ssect = 1;
+               goto restart;
        }
        /*
        }
        /*
-        * Attempt to forward bad sectors on
-        * anything but an ML11.  If drive
-        * supports skip sector handling, try to
-        * use it first; otherwise try the
-        * bad sector table.
+        * Attempt to forward bad sectors on anything but an ML11.
+        * Interpret format error bit as a bad block on RP06's.
         */
         */
-       if ((er2 & HPER2_BSE) && !ML11) {
-badsect:
-               if (!ssect[unit] && (er2&HPER2_SSE))
-                       goto skipsect;
+       if (((er2 & HPER2_BSE) && !ML11) ||
+           (MASKREG(er1) == HPER1_FER && RP06)) {
                if (io->i_flgs & F_NBSF) {
                        io->i_error = EBSE;     
                        goto hard;
                if (io->i_flgs & F_NBSF) {
                        io->i_error = EBSE;     
                        goto hard;
@@ -280,16 +240,6 @@ badsect:
                io->i_error = EBSE;
                goto hard;
        }
                io->i_error = EBSE;
                goto hard;
        }
-
-       /*
-        * Skip sector handling.
-        */
-       if (RM80 && (er2 & HPER2_SSE)) {
-skipsect:
-               (void) hpecc(io, SSE);
-               ssect[unit] = 1;
-               goto success;
-       }
        /*
         * ECC correction?
         */
        /*
         * ECC correction?
         */
@@ -297,15 +247,35 @@ skipsect:
                if (hpecc(io, ECC) == 0)
                        goto success;
                io->i_error = EECC;
                if (hpecc(io, ECC) == 0)
                        goto success;
                io->i_error = EECC;
-               io->i_errblk = bn + ssect[unit];
-               return (-1);    
-       } 
-#ifdef F_SEVRE
-       if (io->i_flgs & F_SEVRE)
                goto hard;
                goto hard;
-#endif
-       if (ML11 && (io->i_errcnt >= 16))
-               goto hard0;
+       } 
+
+       /*
+        * If a hard error, or maximum retry count
+        * exceeded, clear controller state and
+        * pass back error to caller.
+        */
+       if (++io->i_errcnt > sc->retries || (er1 & HPER1_HARD) ||
+           (!ML11 && (er2 & HPER2_HARD)) || (ML11 && (io->i_errcnt >= 16))) {
+               io->i_error = EHER;
+               if (mba->mba_sr & (MBSR_WCKUP|MBSR_WCKLWR))
+                       io->i_error = EWCK;
+hard:
+               io->i_errblk = bn + sc->ssect;
+               if (sc->debug & (HPF_BSEDEBUG|HPF_ECCDEBUG))
+                   printf(" dc=%d, da=0x%x",MASKREG(hpaddr->hpdc),
+                         MASKREG(hpaddr->hpda));
+               else {
+                   printf("hp error: sn%d (cyl,trk,sec)=(%d,%d,%d) ds=%b \n",
+                          bn, cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS);
+                   printf("er1=%b er2=%b", er1, HPER1_BITS, er2, HPER2_BITS);
+               }
+               hpaddr->hpcs1 = HP_DCLR|HP_GO;
+               printf("\n");
+               rv = -1;
+               goto done;
+
+       }
        /* fall thru to retry */
        hpaddr->hpcs1 = HP_DCLR|HP_GO;
        HPWAIT(hpaddr);
        /* fall thru to retry */
        hpaddr->hpcs1 = HP_DCLR|HP_GO;
        HPWAIT(hpaddr);
@@ -326,10 +296,10 @@ skipsect:
                hpaddr->hpcs1 = HP_OFFSET|HP_GO;
                HPWAIT(hpaddr);
        }
                hpaddr->hpcs1 = HP_OFFSET|HP_GO;
                HPWAIT(hpaddr);
        }
-       if (hpdebug[unit] & (HPF_ECCDEBUG|HPF_BSEDEBUG))
+       if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG))
                printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n",
                  io->i_bn, io->i_cc, io->i_ma, hprecal);
                printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n",
                  io->i_bn, io->i_cc, io->i_ma, hprecal);
-       goto restart;   /* retry whole transfer  --ghg */
+       goto restart;
 
 success:
        /*
 
 success:
        /*
@@ -342,7 +312,7 @@ success:
                io->i_bn = bn;
                io->i_ma = membase + (io->i_bn - startblock)*sectsiz;
                io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz;
                io->i_bn = bn;
                io->i_ma = membase + (io->i_bn - startblock)*sectsiz;
                io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz;
-               if (hpdebug[unit] & (HPF_ECCDEBUG|HPF_BSEDEBUG))
+               if (sc->debug & (HPF_ECCDEBUG|HPF_BSEDEBUG))
                        printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n",
                          io->i_bn, io->i_cc, io->i_ma, hprecal);
                goto restart;
                        printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n",
                          io->i_bn, io->i_cc, io->i_ma, hprecal);
                goto restart;
@@ -353,7 +323,10 @@ done:
                while (hpaddr->hpds & HPDS_PIP)
                        ;
        }
                while (hpaddr->hpds & HPDS_PIP)
                        ;
        }
-       return (bytecnt);
+       io->i_bn = startblock;          /*reset i_bn to original */
+       io->i_cc = bytecnt;             /*reset i_cc to total count xfered*/
+       io->i_ma = membase;             /*reset i_ma to original */
+       return (rv);
 }
 
 hpecc(io, flag)
 }
 
 hpecc(io, flag)
@@ -363,7 +336,8 @@ hpecc(io, flag)
        register unit = io->i_unit;
        register struct mba_regs *mbp = mbamba(unit);
        register struct hpdevice *rp = (struct hpdevice *)mbadrv(unit);
        register unit = io->i_unit;
        register struct mba_regs *mbp = mbamba(unit);
        register struct hpdevice *rp = (struct hpdevice *)mbadrv(unit);
-       register struct st *st = &hpst[hp_type[unit]];
+       register struct hp_softc *sc = &hp_softc[unit];
+       register struct st *st = &hpst[sc->type];
        int npf, bn, cn, tn, sn, bcr;
 
        bcr = MASKREG(mbp->mba_bcr);
        int npf, bn, cn, tn, sn, bcr;
 
        bcr = MASKREG(mbp->mba_bcr);
@@ -372,20 +346,27 @@ hpecc(io, flag)
        npf = (bcr + io->i_cc) / sectsiz;       /* # sectors read */
        if (flag == ECC)
                npf--;          /* Error is in prev block --ghg */
        npf = (bcr + io->i_cc) / sectsiz;       /* # sectors read */
        if (flag == ECC)
                npf--;          /* Error is in prev block --ghg */
-       bn = io->i_bn + npf + ssect[unit];      /* physical block #*/
-       if (hpdebug[unit]&HPF_ECCDEBUG)
+       bn = io->i_bn + npf + sc->ssect;        /* physical block #*/
+       if (sc->debug & HPF_ECCDEBUG)
                printf("bcr=%d npf=%d ssect=%d sectsiz=%d i_cc=%d\n",
                printf("bcr=%d npf=%d ssect=%d sectsiz=%d i_cc=%d\n",
-                       bcr, npf, ssect[unit], sectsiz, io->i_cc);
+                       bcr, npf, sc->ssect, sectsiz, io->i_cc);
        /*
         * ECC correction logic.
         */
        if (flag == ECC) {
                register int i;
                caddr_t addr;
        /*
         * ECC correction logic.
         */
        if (flag == ECC) {
                register int i;
                caddr_t addr;
-               int bit, o, mask, ecccnt = 0;
+               int bit, o, mask;
 
                printf("hp%d: soft ecc sn%d\n", unit, bn);
                mask = MASKREG(rp->hpec2);
 
                printf("hp%d: soft ecc sn%d\n", unit, bn);
                mask = MASKREG(rp->hpec2);
+               for (i = mask, bit = 0; i; i >>= 1)
+                       if (i & 1)
+                               bit++;
+               if (bit > sc->ecclim) {
+                       printf("%d-bit error\n", bit);
+                       return (1);
+               }
                i = MASKREG(rp->hpec1) - 1;     /* -1 makes 0 origin */
                bit = i&07;
                o = (i & ~07) >> 3;
                i = MASKREG(rp->hpec1) - 1;     /* -1 makes 0 origin */
                bit = i&07;
                o = (i & ~07) >> 3;
@@ -397,21 +378,15 @@ hpecc(io, flag)
                         * so don't correct the resident copy of data.
                         */
                        if ((io->i_flgs & (F_CHECK|F_HCHECK)) == 0) {
                         * so don't correct the resident copy of data.
                         */
                        if ((io->i_flgs & (F_CHECK|F_HCHECK)) == 0) {
-                               if (hpdebug[unit] & HPF_ECCDEBUG)
+                               if (sc->debug & HPF_ECCDEBUG)
                                        printf("addr=%x old=%x ", addr,
                                                (*addr & 0xff));
                                *addr ^= (mask << bit);
                                        printf("addr=%x old=%x ", addr,
                                                (*addr & 0xff));
                                *addr ^= (mask << bit);
-                               if (hpdebug[unit] & HPF_ECCDEBUG)
+                               if (sc->debug & HPF_ECCDEBUG)
                                        printf("new=%x\n",(*addr & 0xff));
                        }
                        o++, bit -= 8;
                                        printf("new=%x\n",(*addr & 0xff));
                        }
                        o++, bit -= 8;
-                       if ((io->i_flgs & F_ECCLM) && ecccnt++ >= MAXECC)
-                               return (1);
                }
                }
-#ifdef F_SEVRE
-               if (io->i_flgs & F_SEVRE)
-                       return(1);
-#endif
                return (0);
        }
 
                return (0);
        }
 
@@ -434,7 +409,7 @@ hpecc(io, flag)
                int bbn;
 
                rp->hpcs1 = HP_DCLR | HP_GO;
                int bbn;
 
                rp->hpcs1 = HP_DCLR | HP_GO;
-               if (hpdebug[unit] & HPF_BSEDEBUG)
+               if (sc->debug & HPF_BSEDEBUG)
                        printf("hpecc: BSE @ bn %d\n", bn);
                cn = bn/st->nspc;
                sn = bn%st->nspc;
                        printf("hpecc: BSE @ bn %d\n", bn);
                cn = bn/st->nspc;
                sn = bn%st->nspc;
@@ -450,7 +425,7 @@ hpecc(io, flag)
                sn = sn%st->nsect;
                io->i_cc = sectsiz;
                io->i_ma += npf*sectsiz;
                sn = sn%st->nsect;
                io->i_cc = sectsiz;
                io->i_ma += npf*sectsiz;
-               if (hpdebug[unit] & HPF_BSEDEBUG)
+               if (sc->debug & HPF_BSEDEBUG)
                        printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
                rp->hpof &= ~HPOF_SSEI;
                mbp->mba_sr = -1;
                        printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
                rp->hpof &= ~HPOF_SSEI;
                mbp->mba_sr = -1;
@@ -472,27 +447,35 @@ hpioctl(io, cmd, arg)
        caddr_t arg;
 {
        register unit = io->i_unit;
        caddr_t arg;
 {
        register unit = io->i_unit;
-       struct st *st = &hpst[hp_type[unit]], *tmp;
+       register struct hp_softc *sc = &hp_softc[unit];
+       struct st *st = &hpst[sc->type];
        struct mba_drv *drv = mbadrv(unit);
        struct mba_drv *drv = mbadrv(unit);
-       int flag;
 
        switch(cmd) {
 
        case SAIODEBUG:
 
        switch(cmd) {
 
        case SAIODEBUG:
-               flag = (int)arg;
-               if (flag > 0)
-                       hpdebug[unit] |= flag;
-               else
-                       hpdebug[unit] &= ~flag;
-               return (0);
+               sc->debug = (int)arg;
+               break;
 
        case SAIODEVDATA:
 
        case SAIODEVDATA:
-               if ((drv->mbd_dt&MBDT_TAP) == 0) {
-                       tmp = (struct st *)arg;
-                       *tmp = *st;
-                       return (0);
-               }
-               return (ECMD);
+               if (drv->mbd_dt&MBDT_TAP)
+                       return (ECMD);
+               *(struct st *)arg = *st;
+               break;
+
+       case SAIOGBADINFO:
+               if (drv->mbd_dt&MBDT_TAP)
+                       return (ECMD);
+               *(struct dkbad *)arg = hpbad[unit];
+               break;
+
+       case SAIOECCLIM:
+               sc->ecclim = (int)arg;
+               break;
+
+       case SAIORETRIES:
+               sc->retries = (int)arg;
+               break;
 
        case SAIOSSI:                   /* skip-sector-inhibit */
                if (drv->mbd_dt&MBDT_TAP)
 
        case SAIOSSI:                   /* skip-sector-inhibit */
                if (drv->mbd_dt&MBDT_TAP)
@@ -503,7 +486,7 @@ hpioctl(io, cmd, arg)
                        st->nsect++;
                        st->nspc += st->ntrak;
                }
                        st->nsect++;
                        st->nspc += st->ntrak;
                }
-               return (0);
+               break;
 
        case SAIONOSSI:                 /* remove skip-sector-inhibit */
                if (io->i_flgs & F_SSI) {
 
        case SAIONOSSI:                 /* remove skip-sector-inhibit */
                if (io->i_flgs & F_SSI) {
@@ -512,10 +495,13 @@ hpioctl(io, cmd, arg)
                        st->nsect--;
                        st->nspc -= st->ntrak;
                }
                        st->nsect--;
                        st->nspc -= st->ntrak;
                }
-               return(0);
+               break;
 
        case SAIOSSDEV:                 /* drive have skip sector? */
                return (RM80 ? 0 : ECMD);
 
        case SAIOSSDEV:                 /* drive have skip sector? */
                return (RM80 ? 0 : ECMD);
+
+       default:
+               return (ECMD);
        }
        }
-       return (ECMD);
+       return (0);
 }
 }