uda50 and rl11 boot blocks; 730 crud
[unix-history] / usr / src / sys / vax / stand / hp.c
index 68084e4..770df11 100644 (file)
@@ -1,4 +1,4 @@
-/*     hp.c    4.3     83/01/18        */
+/*     hp.c    4.11    83/02/16        */
 
 /*
  * RP??/RM?? disk driver
 
 /*
  * RP??/RM?? disk driver
@@ -39,15 +39,17 @@ short       ml_off[8] =     { 0, -1, -1, -1, -1, -1, -1, -1 };
 short  si9775_off[8] = { 0, 13, 0, -1, -1, -1, 40, 441 };
 short  si9730_off[8] = { 0, 50, 0, -1, -1, -1, -1, 155 };
 short  hpam_off[8] =   { 0, 32, 0, 668, 723, 778, 668, 98 };
 short  si9775_off[8] = { 0, 13, 0, -1, -1, -1, 40, 441 };
 short  si9730_off[8] = { 0, 50, 0, -1, -1, -1, -1, 155 };
 short  hpam_off[8] =   { 0, 32, 0, 668, 723, 778, 668, 98 };
+short  hpfj_off[8] =   { 0, 19, 0, -1, -1, -1, 398, 59 };
 /* END SHOULD BE READ IN */
 
 short  hptypes[] =
     { MBDT_RM03, MBDT_RM05, MBDT_RP06, MBDT_RM80, MBDT_RP05, MBDT_RP07,
 /* END SHOULD BE READ IN */
 
 short  hptypes[] =
     { MBDT_RM03, MBDT_RM05, MBDT_RP06, MBDT_RM80, MBDT_RP05, MBDT_RP07,
-      MBDT_ML11A, MBDT_ML11B, -1/*9755*/, -1/*9730*/, -1/*Capr*/, MBDT_RM02, 0};
+      MBDT_ML11A, MBDT_ML11B, -1/*9755*/, -1/*9730*/, -1/*Capr*/,
+      -1/* eagle */, -1/* 48 sect eagle */, MBDT_RM02, 0};
 
 
-#define RP06 (hptypes[UNITTODRIVE(unit)] <= MBDT_RP06)
-#define ML11 (hptypes[UNITTODRIVE(unit)] <= MBDT_ML11A)
-#define RM80 (hptypes[UNITTODRIVE(unit)] <= MBDT_RM80)
+#define RP06 (hptypes[hp_type[unit]] <= MBDT_RP06)
+#define ML11 (hptypes[hp_type[unit]] == MBDT_ML11A)
+#define RM80 (hptypes[hp_type[unit]] == 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,
@@ -67,12 +69,22 @@ struct st hpst[] = {
        1,      1,      1,      1,      ml_off,         /* ML11B */
        32,     40,     32*40,  843,    si9775_off,     /* 9775 */
        32,     10,     32*10,  823,    si9730_off,     /* 9730 */
        1,      1,      1,      1,      ml_off,         /* ML11B */
        32,     40,     32*40,  843,    si9775_off,     /* 9775 */
        32,     10,     32*10,  823,    si9730_off,     /* 9730 */
-       32,     16,     32*16,  1024,   hpam_off,       /* AMPEX capricorn */
-       1,      1,      1,      1,      0,              /* rm02 - not used */
+       32,     16,     32*16,  1024,   hpam_off,       /* capricorn */
+       43,     20,     43*20,  842,    hpfj_off,       /* Eagle */
+       48,     20,     48*20,  842,    hpfj_off,       /* modif. eagle */
+       1,      1,      1,      1,      0,      /* rm02 - not used */
 };
 };
+
 struct dkbad hpbad[MAXNMBA*8];
 int sectsiz;
 
 struct dkbad hpbad[MAXNMBA*8];
 int sectsiz;
 
+/*
+ * When awaiting command completion, don't
+ * hang on to the status register since
+ * this ties up the controller.
+ */
+#define        HPWAIT(addr)    while ((((addr)->hpds)&HPDS_DRY)==0) DELAY(500);
+
 hpopen(io)
        register struct iob *io;
 {
 hpopen(io)
        register struct iob *io;
 {
@@ -91,59 +103,25 @@ hpopen(io)
                                goto found;
                _stop("unknown drive type");
 found:
                                goto found;
                _stop("unknown drive type");
 found:
-               switch (i) {
-               case 0: case 1: {       /* rm03 or rm05 */
-                       register hpsn = hpaddr->hpsn;
-
-                       if ((hpsn & SIMB_LU) != unit)
-                               break;
-                       switch ((hpsn & SIMB_MB) &~ (SIMB_S6|SIRM03|SIRM05)) {
-                       case SI9775D:
-                               i = 8;  /* si9775 */
-                               break;
-                       case SI9730D:
-                               i = 9;  /* si9730 */
-                               break;
-                       case SI9766:
-                               i = 1;  /* rm05 */
-                               hpaddr->hpcs1 = HP_RECAL|HP_GO;
-                               DELAY(100000);
-                               break;
-                       case SI9762:
-                               i = 0;  /* rm03 */
-                               break;
-                       }
-                       break;
-               }
-
-               case 11:                /* rm02 */
-                       hpaddr->hpcs1 = HP_NOP;
-                       hpaddr->hphr = HPHR_MAXTRAK;
-                       if (MASKREG(hpaddr->hphr) == 15)
-                               i = 10;         /* ampex capricorn */
-                       else
-                               i = 0;          /* rm03 */
-                       break;
-               
-               case 6: case 7:         /* ml11a ml11b */
-                       i = 6;                  /* ml11a */
-                       break;
-               }
-               hp_type[unit] = i;
+               hp_type[unit] = hpmaptype(hpaddr, i, unit);
+               hpaddr->hpcs1 = HP_DCLR|HP_GO;          /* init drive */
+               hpaddr->hpcs1 = HP_PRESET|HP_GO;
+               if (!ML11)
+                       hpaddr->hpof = HPOF_FMT22;
                /*
                 * Read in the bad sector table:
                 *      copy the contents of the io structure
                 *      to tio for use during the bb pointer
                 *      read operation.
                 */
                /*
                 * Read in the bad sector table:
                 *      copy the contents of the io structure
                 *      to tio for use during the bb pointer
                 *      read operation.
                 */
-               st = &hpst[hp_type[unit]];
+               st = &hpst[i];
                tio = *io;
                tio.i_bn = st->nspc * st->ncyl - st->nsect;
                tio = *io;
                tio.i_bn = st->nspc * st->ncyl - st->nsect;
-               tio.i_ma = (char *)&hpbad[tio.i_unit];
-               tio.i_cc = sizeof (hpbad);
+               tio.i_ma = (char *)&hpbad[unit];
+               tio.i_cc = sizeof (struct dkbad);
                tio.i_flgs |= F_RDDATA;
                for (i = 0; i < 5; i++) {
                tio.i_flgs |= F_RDDATA;
                for (i = 0; i < 5; i++) {
-                       if (hpstrategy(&tio, READ) == sizeof (hpbad))
+                       if (hpstrategy(&tio, READ) == sizeof (struct dkbad))
                                break;
                        tio.i_bn += 2;
                }
                                break;
                        tio.i_bn += 2;
                }
@@ -161,6 +139,65 @@ found:
        io->i_boff = st->off[io->i_boff] * st->nspc;
 }
 
        io->i_boff = st->off[io->i_boff] * st->nspc;
 }
 
+hpmaptype(hpaddr, type, unit)
+       register struct hpdevice *hpaddr;
+       unsigned type;
+       int unit;
+{
+       int ntracks, hpsn;
+
+       /*
+        * Handle SI model byte stuff when
+        * we think it's an RM03 or RM05.
+        */
+       if (type == 0 || type == 1) {
+               hpsn = hpaddr->hpsn;
+               if ((hpsn & SIMB_LU) != unit)
+                       return (type);
+               switch ((hpsn & SIMB_MB) &~ (SIMB_S6|SIRM03|SIRM05)) {
+               case SI9775D:
+                       return (8);
+               case SI9730D:
+                       return (9);
+               case SI9766:
+                       hpaddr->hpcs1 = HP_RECAL|HP_GO;
+                       DELAY(100000);
+                       return (1);
+
+               case SI9762:
+                       return (0);
+               }
+               return (type);
+       }
+       /*
+        * RM03: EMULEX controller.  Map to correct
+        * drive type by checking the holding
+        * register for the disk geometry.
+        */
+       if (type == 13) {
+               hpaddr->hpcs1 = HP_NOP;
+               hpaddr->hphr = HPHR_MAXTRAK;
+               ntracks = MASKREG(hpaddr->hphr) + 1;
+               if (ntracks == 16)
+                       return (10);    /* AMPEX capricorn */
+               hpaddr->hphr = HPHR_MAXSECT;
+               if (ntracks == 48)
+                       return (12);    /* 48 sector Eagle */
+               if (ntracks == 43)
+                       return (11);    /* 43 sector Eagle */
+               printf("RM02 with %d tracks?\n", ntracks);
+               return (type);
+       }
+       /*
+        * ML11's all map to the same type.
+        */
+       if (type == 6 || type == 7)
+               return (6);
+       return (type);
+}
+
+int    ssect;          /* set to 1 if we are on a track with skip sectors */
+
 hpstrategy(io, func)
        register struct iob *io;
 {
 hpstrategy(io, func)
        register struct iob *io;
 {
@@ -180,24 +217,25 @@ hpstrategy(io, func)
        if ((hpaddr->hpds & HPDS_VV) == 0) {
                hpaddr->hpcs1 = HP_DCLR|HP_GO;
                hpaddr->hpcs1 = HP_PRESET|HP_GO;
        if ((hpaddr->hpds & HPDS_VV) == 0) {
                hpaddr->hpcs1 = HP_DCLR|HP_GO;
                hpaddr->hpcs1 = HP_PRESET|HP_GO;
-               if (hp_type[unit] != 6)         /* any but ml11 */
+               if (!ML11)
                        hpaddr->hpof = HPOF_FMT22;
        }
        io->i_errcnt = 0;
                        hpaddr->hpof = HPOF_FMT22;
        }
        io->i_errcnt = 0;
+       ssect = 0;
        bytecnt = io->i_cc;
        membase = io->i_ma;
        startblock = io->i_bn;
        bytecnt = io->i_cc;
        membase = io->i_ma;
        startblock = io->i_bn;
-       hprecal = 1;
-readmore:
+       hprecal = 0;
+restart:
        bn = io->i_bn;
        cn = bn/st->nspc;
        sn = bn%st->nspc;
        tn = sn/st->nsect;
        bn = io->i_bn;
        cn = bn/st->nspc;
        sn = bn%st->nspc;
        tn = sn/st->nsect;
-       sn = sn%st->nsect;
+       sn = sn%st->nsect + ssect;
 
 
-       while ((hpaddr->hpds & HPDS_DRY) == 0)
-               ;
-       if (hp_type[unit] == 6)         /* ml11 */
+       HPWAIT(hpaddr);
+       mba->mba_sr = -1;
+       if (ML11)
                hpaddr->hpda = bn;
        else {
                hpaddr->hpdc = cn;
                hpaddr->hpda = bn;
        else {
                hpaddr->hpdc = cn;
@@ -205,11 +243,9 @@ readmore:
        }
        if (mbastart(io, func) != 0)            /* start transfer */
                return (-1);
        }
        if (mbastart(io, func) != 0)            /* start transfer */
                return (-1);
-
-       while ((hpaddr->hpds & HPDS_DRY) == 0)
-               ;
-       if (((hpaddr->hpds&HPDS_ERR) | (mba->mba_sr&MBSR_EBITS)) == 0 )
-               return(bytecnt);
+       HPWAIT(hpaddr);
+       if ((hpaddr->hpds&HPDS_ERR) == 0 && (mba->mba_sr&MBSR_EBITS) == 0)
+               return (bytecnt);
 
        /* ------- error handling ------- */
 
 
        /* ------- error handling ------- */
 
@@ -225,9 +261,9 @@ readmore:
 #ifdef HPDEBUG
        printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b \n",
                cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS);
 #ifdef HPDEBUG
        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);
+       printf("er1=%b er2=%b", er1, HPER1_BITS, er2, HPER2_BITS);
+       printf("\nbytes left: %d, of 0x%x, da 0x%x",-bytesleft,
+       hpaddr->hpof, hpaddr->hpda);
        printf("\n");
 #endif
        if (er1 & HPER1_HCRC) {
        printf("\n");
 #endif
        if (er1 & HPER1_HCRC) {
@@ -236,113 +272,113 @@ readmore:
        }
        if (er1&HPER1_WLE) {
                printf("hp%d: write locked\n", unit);
        }
        if (er1&HPER1_WLE) {
                printf("hp%d: write locked\n", unit);
-               return(-1);
-       } else if ((er1&0xffff) == HPER1_FER && RP06) {
+               return (-1);
+       }
+       if (MASKREG(er1) == HPER1_FER && RP06)
                goto badsect;
                goto badsect;
-
-       } else if (++io->i_errcnt > 27 ||
-                  er1 & HPER1_HARD ||
-                  (!ML11 && (er2 & HPER2_HARD))) {
+       if (++io->i_errcnt > 27 || (er1 & HPER1_HARD) ||
+           (!ML11 && (er2 & HPER2_HARD))) {
+hard0:
                io->i_error = EHER;
                io->i_error = EHER;
-               if ((mba->mba_sr & (MBSR_WCKUP | MBSR_WCKLWR)) != 0)
+               if (mba->mba_sr & (MBSR_WCKUP|MBSR_WCKLWR))
                        io->i_error = EWCK;
 hard:
                        io->i_error = EWCK;
 hard:
-               io->i_errblk = bn;
+               io->i_errblk = bn + ssect;
                printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b \n",
                           cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS);
                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);
+               printf("er1=%b er2=%b", er1, HPER1_BITS, er2, HPER2_BITS);
                if (hpaddr->hpmr)
                if (hpaddr->hpmr)
-                       printf(" mr=%o", hpaddr->hpmr&0xffff);
+                       printf(" mr1=%o", MASKREG(hpaddr->hpmr));
                if (hpaddr->hpmr2)
                if (hpaddr->hpmr2)
-                       printf(" mr2=%o", hpaddr->hpmr2&0xffff);
+                       printf(" mr2=%o", MASKREG(hpaddr->hpmr2));
+#ifdef HPDEBUG
+               printf("dc: %d, da: 0x%x",MASKREG(hpaddr->hpdc),
+                 MASKREG(hpaddr->hpda));
+#endif
+               hpaddr->hpcs1 = HP_DCLR|HP_GO;
                printf("\n");
                printf("\n");
-               return(-1);
+               return (-1);
 
 
-       } else if ((er2 & HPER2_BSE) && !ML11) {
+       }
+       if ((er2 & HPER2_BSE) && !ML11) {
 badsect:
 badsect:
-               if ((io->i_flgs & F_NBSF) != 0) {
+               if (!ssect && (er2&HPER2_SSE))
+                       goto skipsect;
+               if (io->i_flgs & F_NBSF) {
                        io->i_error = EBSE;     
                        goto hard;
                }
                if (hpecc(io, BSE) == 0)
                        goto success;
                        io->i_error = EBSE;     
                        goto hard;
                }
                if (hpecc(io, BSE) == 0)
                        goto success;
-               else {
-                       io->i_error = EBSE;
-                       goto hard;
-               }
-       } else if (RM80 && er2&HPER2_SSE) {
-       /* skip sector error */
+               io->i_error = EBSE;
+               goto hard;
+       }
+       if (RM80 && er2&HPER2_SSE) {
+skipsect:
                (void) hpecc(io, SSE);
                (void) hpecc(io, SSE);
-               startblock++;           /* since one sector was skipped */
+               ssect = 1;
                goto success;
                goto success;
-       } else if ((er1&(HPER1_DCK|HPER1_ECH))==HPER1_DCK) {
-               if ( hpecc(io, ECC) == 0)
+       }
+       if ((er1 & (HPER1_DCK|HPER1_ECH)) == HPER1_DCK) {
+               if (hpecc(io, ECC) == 0)
                        goto success;
                        goto success;
-               else {
-                       io->i_error = EECC;
-                       return(1);      
-               }
-       } else
-               io->i_active = 0;               /* force retry */
-
+               io->i_error = EECC;
+               return (-1);    
+       } 
+       if (ML11 && (io->i_errcnt >= 16))
+               goto hard0;
+       /* fall thru to retry */
        hpaddr->hpcs1 = HP_DCLR|HP_GO;
        hpaddr->hpcs1 = HP_DCLR|HP_GO;
-       while ((hpaddr->hpds & HPDS_DRY) == 0)
-               ;
-       if (ML11) {
-               if (io->i_errcnt >= 16)
-                       goto hard;
-       } else if (((io->i_errcnt&07) == 4) && (io->i_active == 0)) {
+       HPWAIT(hpaddr);
+       if (((io->i_errcnt&07) == 4) ) {
                hpaddr->hpcs1 = HP_RECAL|HP_GO;
                hpaddr->hpcs1 = HP_RECAL|HP_GO;
-               hprecal = 0;
-               goto nextrecal;
+               hprecal = 1;
+               goto again;
        }
        switch (hprecal) {
 
        case 1:
                hpaddr->hpdc = cn;
                hpaddr->hpcs1 = HP_SEEK|HP_GO;
        }
        switch (hprecal) {
 
        case 1:
                hpaddr->hpdc = cn;
                hpaddr->hpcs1 = HP_SEEK|HP_GO;
-               goto nextrecal;
+               hprecal = 2;
+               goto again;
+
        case 2:
        case 2:
-               if (io->i_errcnt < 16 || (func & READ) == 0)
+               if (io->i_errcnt < 16 || (io->i_flgs & F_READ) == 0)
                        goto donerecal;
                hpaddr->hpof = hp_offset[io->i_errcnt & 017]|HPOF_FMT22;
                hpaddr->hpcs1 = HP_OFFSET|HP_GO;
                        goto donerecal;
                hpaddr->hpof = hp_offset[io->i_errcnt & 017]|HPOF_FMT22;
                hpaddr->hpcs1 = HP_OFFSET|HP_GO;
-nextrecal:
-               hprecal++;
-               io->i_active = 1;
-               goto try_again;
-       donerecal:
+               hprecal = 3;
+               goto again;
+
        case 3:
        case 3:
+       donerecal:
                hprecal = 0;
                hprecal = 0;
-               io->i_active = 0;
-               goto try_again;
+               goto again;
        }
        }
-       if (io->i_active) {
-               if (io->i_errcnt >= 16) {
-                       hpaddr->hpcs1 = HP_RTC|HP_GO;
-                       while (hpaddr->hpds & HPDS_PIP)
-                               ;
-               }
+       if (io->i_errcnt >= 16) {
+               hpaddr->hpcs1 = HP_RTC|HP_GO;
+               while (hpaddr->hpds & HPDS_PIP)
+                       ;
        }
        }
-success:                /* continue with the next block */
+       goto again;
+
+success:                               /* continue with the next block */
        bn++;
        if ((bn-startblock) * sectsiz < bytecnt) {
        bn++;
        if ((bn-startblock) * sectsiz < bytecnt) {
-
-try_again:             /* re-read same block */
+again:                                 /* re-read same block */
                io->i_bn = bn;
                io->i_bn = bn;
-               mba->mba_sr = -1;
                io->i_ma = membase + (io->i_bn - startblock)*sectsiz;
                io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz;
 #ifdef HPDEBUG
                io->i_ma = membase + (io->i_bn - startblock)*sectsiz;
                io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz;
 #ifdef HPDEBUG
-               printf("restart: bl %d, byte %d, mem 0x%x %d\n",
-                       io->i_bn, io->i_cc, io->i_ma, io->i_ma);
+               printf("restart: bl %d, byte %d, mem 0x%x hprecal %d\n",
+                       io->i_bn, io->i_cc, io->i_ma, hprecal);
 #endif
 #endif
-               goto readmore;
+               goto restart;
        }
        return (bytecnt);
 }
        }
        return (bytecnt);
 }
+
 hpecc(io, flag)
        register struct iob *io;
        int flag;
 hpecc(io, flag)
        register struct iob *io;
        int flag;
@@ -351,24 +387,22 @@ hpecc(io, flag)
        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 mba_regs *mbp = mbamba(unit);
        register struct hpdevice *rp = (struct hpdevice *)mbadrv(unit);
        register struct st *st = &hpst[hp_type[unit]];
-       int npf;
-       int bn, cn, tn, sn;
-       int bcr, tad;
+       int npf, bn, cn, tn, sn, bcr;
 
        if (bcr = MASKREG(mbp->mba_bcr>>16))
                bcr |= 0xffff0000;              /* sxt */
 
        if (bcr = MASKREG(mbp->mba_bcr>>16))
                bcr |= 0xffff0000;              /* sxt */
-       npf = (bcr + io->i_cc)/sectsiz;         /* number of sectors read */
-       bn = io->i_bn + npf;
+       npf = (bcr + io->i_cc) / sectsiz;       /* # sectors read */
+       bn = io->i_bn + npf + ssect;            /* physical block #*/
        switch (flag) {
        switch (flag) {
-       case ECC:
-               {
+
+       case ECC: {
                register int i;
                caddr_t addr;
                int bit, byte, mask, ecccnt = 0;
 
                printf("hp%d: soft ecc sn%d\n", unit, bn);
                mask = MASKREG(rp->hpec2);
                register int i;
                caddr_t addr;
                int bit, byte, mask, ecccnt = 0;
 
                printf("hp%d: soft ecc sn%d\n", unit, bn);
                mask = MASKREG(rp->hpec2);
-               i = MASKREG(rp->hpec1) - 1;             /* -1 makes 0 origin */
+               i = MASKREG(rp->hpec1) - 1;     /* -1 makes 0 origin */
                bit = i&07;
                i = (i&~07)>>3;
                byte = i;
                bit = i&07;
                i = (i&~07)>>3;
                byte = i;
@@ -387,50 +421,60 @@ hpecc(io, flag)
                        byte++;
                        i++;
                        bit -= 8;
                        byte++;
                        i++;
                        bit -= 8;
-                       if ((ecccnt++>=MAXECC) && ((io->i_flgs&F_ECCLM) != 0))
-                               return(1);
+                       if ((io->i_flgs & F_ECCLM) && ecccnt++ >= MAXECC)
+                               return (1);
                }
                return(0);
                }
                return(0);
-               }
+       }
 
 
-       case SSE:       /* skip sector error */
-                       /* set skip-sector-inhibit and read next sector */
+       /*
+        * Skip sector error.
+        * Set skip-sector-inhibit and
+        * read next sector
+        */
+       case SSE:
                rp->hpcs1 = HP_DCLR | HP_GO;
                rp->hpcs1 = HP_DCLR | HP_GO;
-               while(rp->hpds & HPDS_DRY == 0)
-                       ;                       /* avoid RMR error */
+               HPWAIT(rp);
                rp->hpof |= HPOF_SSEI;
                rp->hpof |= HPOF_SSEI;
-               return(0);      
+               return (0);     
 
 
-#ifndef NOBADSECT
-       case BSE:
+       case BSE: {
+               int bbn;
+
+               rp->hpcs1 = HP_DCLR | HP_GO;
 #ifdef HPDEBUG
                printf("hpecc: BSE @ bn %d\n", bn);
 #endif
 #ifdef HPDEBUG
                printf("hpecc: BSE @ bn %d\n", bn);
 #endif
-               rp->hpcs1 = HP_DCLR | HP_GO;
-               bcr += sectsiz;
-               tad = rp->hpda;
-               if ((bn = isbad(&hpbad[unit], bn/st->nspc,tad>>8,tad&0x7f)) < 0)
-                       return(1);
-               bn = st->ncyl*st->nspc - st->nsect - 1 - bn;
                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 %= st->nsect;
-               io->i_cc = -sectsiz;
-               io->i_ma += ((io->i_bn + npf -1)*sectsiz);
-#ifdef HPDEBUG
-               printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
-#endif
+               sn = sn%st->nsect;
+               bcr += sectsiz;
+               if ((bbn = isbad(&hpbad[unit], cn, tn, sn)) < 0)
+                       return (1);
+               bbn = st->ncyl*st->nspc - st->nsect - 1 - bbn;
+               cn = bbn/st->nspc;
+               sn = bbn%st->nspc;
+               tn = sn/st->nsect;
+               sn = sn%st->nsect;
+               io->i_cc = sectsiz;
+               io->i_ma += npf*sectsiz;
+#ifdef HPDEBUG 
+               printf("revector to cn %d tn %d sn %d mem: 0x%x\n", 
+                       cn, tn, sn, io->i_ma);
+#endif 
+               rp->hpof &= ~HPOF_SSEI; /* clear skip sector inhibit if set */
+               mbp->mba_sr = -1;
                rp->hpdc = cn;
                rp->hpda = (tn<<8) + sn;
                rp->hpdc = cn;
                rp->hpda = (tn<<8) + sn;
-               mbp->mba_sr = -1;
                mbastart(io,io->i_flgs);
                io->i_errcnt = 0;       /* error has been corrected */
                mbastart(io,io->i_flgs);
                io->i_errcnt = 0;       /* error has been corrected */
-               if (rp->hpds&HPDS_ERR)
-                       return(1);
-               else
-                       return(0);
+               HPWAIT(rp);
+               return (rp->hpds&HPDS_ERR);
+       }
        }
        }
+       printf("hpecc: flag=%d\n", flag);
+       return (1);
 }
 /*ARGSUSED*/
 hpioctl(io, cmd, arg)
 }
 /*ARGSUSED*/
 hpioctl(io, cmd, arg)
@@ -438,9 +482,9 @@ hpioctl(io, cmd, arg)
        int cmd;
        caddr_t arg;
 {
        int cmd;
        caddr_t arg;
 {
-
-       struct st *st = &hpst[hp_type[io->i_unit]], *tmp;
-       struct mba_drv *drv = mbadrv(io->i_unit);
+       register unit = io->i_unit;
+       struct st *st = &hpst[hp_type[unit]], *tmp;
+       struct mba_drv *drv = mbadrv(unit);
 
        switch(cmd) {
 
 
        switch(cmd) {
 
@@ -448,13 +492,32 @@ hpioctl(io, cmd, arg)
                if ((drv->mbd_dt&MBDT_TAP) == 0) {
                        tmp = (struct st *)arg;
                        *tmp = *st;
                if ((drv->mbd_dt&MBDT_TAP) == 0) {
                        tmp = (struct st *)arg;
                        *tmp = *st;
-                       return(0);
+                       return (0);
                }
                }
-               else 
-                       return(ECMD);
-
-       default:
                return (ECMD);
                return (ECMD);
+
+       case SAIOSSI:                   /* skip-sector-inhibit */
+               if (drv->mbd_dt&MBDT_TAP)
+                       return (ECMD);
+               if ((io->i_flgs&F_SSI) == 0) {
+                       /* make sure this is done once only */
+                       io->i_flgs |= F_SSI;
+                       st->nsect++;
+                       st->nspc += st->ntrak;
+               }
+               return (0);
+
+       case SAIONOSSI:                 /* remove skip-sector-inhibit */
+               if (io->i_flgs & F_SSI) {
+                       io->i_flgs &= ~F_SSI;
+                       drv->mbd_of &= ~HPOF_SSEI;
+                       st->nsect--;
+                       st->nspc -= st->ntrak;
+               }
+               return(0);
+
+       case SAIOSSDEV:                 /* drive have skip sector? */
+               return (RM80 ? 0 : ECMD);
        }
        }
+       return (ECMD);
 }
 }
-