spelling sn%d not bn%d
[unix-history] / usr / src / sys / vax / mba / hp.c
index fdafe8c..8fd8113 100644 (file)
@@ -1,9 +1,16 @@
-/*     hp.c    4.12    81/02/23        */
+/*     hp.c    4.23    81/03/06        */
 
 #include "hp.h"
 #if NHP > 0
 /*
  * HP disk driver for RP0x+RM0x
 
 #include "hp.h"
 #if NHP > 0
 /*
  * HP disk driver for RP0x+RM0x
+ *
+ * TODO:
+ *     Check RM80 skip sector handling, esp when ECC's occur later
+ *     Add reading of bad sector information and disk layout from sector 1
+ *     Add bad sector forwarding code
+ *     Check interaction with tape driver on same mba
+ *     Check multiple drive handling
  */
 
 #include "../h/param.h"
  */
 
 #include "../h/param.h"
@@ -97,6 +104,7 @@ u_char       hp_offset[16] = {
 };
 
 struct buf     rhpbuf[NHP];
 };
 
 struct buf     rhpbuf[NHP];
+char   hprecal[NHP];
 
 #define        b_cylin b_resid
  
 
 #define        b_cylin b_resid
  
@@ -112,7 +120,7 @@ hpdkinit(mi)
        register struct hpst *st = &hpst[mi->mi_type];
 
        if (mi->mi_dk >= 0)
        register struct hpst *st = &hpst[mi->mi_type];
 
        if (mi->mi_dk >= 0)
-               dk_mspw[mi->mi_dk] = 1.0 / HZ / (st->nsect * 256);
+               dk_mspw[mi->mi_dk] = 1.0 / 60 / (st->nsect * 256);
 }
 
 hpstrategy(bp)
 }
 
 hpstrategy(bp)
@@ -217,34 +225,54 @@ hpstart(mi)
        hpaddr->hpda = (tn << 8) + sn;
 }
 
        hpaddr->hpda = (tn << 8) + sn;
 }
 
-hpdtint(mi, mbastat)
+hpdtint(mi, mbasr)
        register struct mba_info *mi;
        register struct mba_info *mi;
-       int mbastat;
+       int mbasr;
 {
        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;
+       int retry = 0;
 
 
-       while ((hpaddr->hpds & HP_DRY) == 0)    /* shouldn't happen */
-               printf("hp dry not set\n");
-       if (hpaddr->hpds & HP_ERR || mbastat & MBAEBITS)
-               if (++mi->mi_tab.b_errcnt < 28 && (hpaddr->hper1&HP_WLE) == 0) {
-                       if ((hpaddr->hper1&0xffff) != HP_DCK) {
-                               hpaddr->hpcs1 = HP_DCLR|HP_GO;
-                               if ((mi->mi_tab.b_errcnt&07) == 4) {
-                                       hpaddr->hpcs1 = HP_RECAL|HP_GO;
-                                       while (hpaddr->hpds & HP_PIP)
-                                               ;
-                                       mbclrattn(mi);
-                               }
-                               return (MBD_RETRY);
-                       } else if (hpecc(mi))
-                               return (MBD_RESTARTED);
-               } else {
-                       deverror(bp, mbastat, hpaddr->hper1);
+       if (hpaddr->hpds&HP_ERR || mbasr&MBAEBITS) {
+               if (hpaddr->hper1&HP_WLE) {
+                       printf("hp%d: write locked\n", dkunit(bp));
+                       bp->b_flags |= B_ERROR;
+               } else if (++mi->mi_tab.b_errcnt > 27 ||
+                   mbasr & MBASR_HARD ||
+                   hpaddr->hper1 & HPER1_HARD ||
+                   hpaddr->hper2 & HPER2_HARD) {
+                       harderr(bp, "hp");
+                       printf("mbasr=%b er1=%b er2=%b\n",
+                           mbasr, mbasr_bits,
+                           hpaddr->hper1, HPER1_BITS,
+                           hpaddr->hper2, HPER2_BITS);
                        bp->b_flags |= B_ERROR;
                        bp->b_flags |= B_ERROR;
+#ifdef notdef
+               } else if (hpaddr->hper2&HP_SSE) {
+                       hpecc(mi, 1);
+                       return (MBD_RESTARTED);
+#endif
+               } else if ((hpaddr->hper1&(HP_DCK|HP_ECH)) == HP_DCK) {
+                       if (hpecc(mi, 0))
+                               return (MBD_RESTARTED);
+                       /* else done */
+               } else
+                       retry = 1;
+               hpaddr->hpcs1 = HP_DCLR|HP_GO;
+               if ((mi->mi_tab.b_errcnt&07) == 4) {
+                       hpaddr->hpcs1 = HP_RECAL|HP_GO;
+                       hprecal[mi->mi_unit] = 1;
+                       return (MBD_RESTARTED);
                }
                }
+               if (retry)
+                       return (MBD_RETRY);
+       }
+       if (hprecal[mi->mi_unit]) {
+               hprecal[mi->mi_unit] = 0;
+               return (MBD_RETRY);
+       }
        bp->b_resid = -(mi->mi_mba->mba_bcr) & 0xffff;
        bp->b_resid = -(mi->mi_mba->mba_bcr) & 0xffff;
-       if (mi->mi_tab.b_errcnt) {
+       if (mi->mi_tab.b_errcnt > 16) {
                hpaddr->hpcs1 = HP_RTC|HP_GO;
                while (hpaddr->hpds & HP_PIP)
                        ;
                hpaddr->hpcs1 = HP_RTC|HP_GO;
                while (hpaddr->hpds & HP_PIP)
                        ;
@@ -276,8 +304,9 @@ hpwrite(dev)
                physio(hpstrategy, &rhpbuf[unit], dev, B_WRITE, minphys);
 }
 
                physio(hpstrategy, &rhpbuf[unit], dev, B_WRITE, minphys);
 }
 
-hpecc(mi)
+hpecc(mi, rm80sse)
        register struct mba_info *mi;
        register struct mba_info *mi;
+       int rm80sse;
 {
        register struct mba_regs *mbp = mi->mi_mba;
        register struct hpdevice *rp = (struct hpdevice *)mi->mi_drv;
 {
        register struct mba_regs *mbp = mi->mi_mba;
        register struct hpdevice *rp = (struct hpdevice *)mi->mi_drv;
@@ -295,15 +324,17 @@ hpecc(mi)
                bcr |= 0xffff0000;              /* sxt */
        npf = btop(bcr + bp->b_bcount) - 1;
        reg = npf;
                bcr |= 0xffff0000;              /* sxt */
        npf = btop(bcr + bp->b_bcount) - 1;
        reg = npf;
+#ifdef notdef
+       if (rm80sse) {
+               rp->hpof |= HP_SSEI;
+               reg--;          /* compensate in advance for reg-- below */
+               goto sse;
+       }
+#endif
        o = (int)bp->b_un.b_addr & PGOFSET;
        o = (int)bp->b_un.b_addr & PGOFSET;
-       printf("%D ", bp->b_blkno + npf);
-       prdev("ECC", bp->b_dev);
+       printf("hp%d%c: soft ecc sn%d\n", dkunit(bp),
+           'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
        mask = rp->hpec2&0xffff;
        mask = rp->hpec2&0xffff;
-       if (mask == 0) {
-               rp->hpof = HP_FMT22;
-               return (0);
-       }
-
        i = (rp->hpec1&0xffff) - 1;             /* -1 makes 0 origin */
        bit = i&07;
        i = (i&~07)>>3;
        i = (rp->hpec1&0xffff) - 1;             /* -1 makes 0 origin */
        bit = i&07;
        i = (i&~07)>>3;
@@ -316,13 +347,16 @@ hpecc(mi)
                i++;
                bit -= 8;
        }
                i++;
                bit -= 8;
        }
-       mi->mi_hd->mh_active++;         /* Either complete or continuing */
        if (bcr == 0)
                return (0);
 #ifdef notdef
        if (bcr == 0)
                return (0);
 #ifdef notdef
+sse:
+       if (rpof&HP_SSEI)
+               rp->hpda = rp->hpda + 1;
        rp->hper1 = 0;
        rp->hpcs1 = HP_RCOM|HP_GO;
 #else
        rp->hper1 = 0;
        rp->hpcs1 = HP_RCOM|HP_GO;
 #else
+sse:
        rp->hpcs1 = HP_DCLR|HP_GO;
        bn = dkblock(bp);
        st = &hpst[mi->mi_type];
        rp->hpcs1 = HP_DCLR|HP_GO;
        bn = dkblock(bp);
        st = &hpst[mi->mi_type];
@@ -332,6 +366,10 @@ hpecc(mi)
        sn %= st->nsect;
        cn += tn/st->ntrak;
        tn %= st->ntrak;
        sn %= st->nsect;
        cn += tn/st->ntrak;
        tn %= st->ntrak;
+#ifdef notdef
+       if (rp->hpof&SSEI)
+               sn++;
+#endif
        rp->hpdc = cn;
        rp->hpda = (tn<<8) + sn;
        mbp->mba_sr = -1;
        rp->hpdc = cn;
        rp->hpda = (tn<<8) + sn;
        mbp->mba_sr = -1;
@@ -356,16 +394,12 @@ hpdump(dev)
        num = maxfree;
        start = 0;
        unit = minor(dev) >> 3;
        num = maxfree;
        start = 0;
        unit = minor(dev) >> 3;
-       if (unit >= NHP) {
-               printf("bad unit\n");
-               return (-1);
-       }
+       if (unit >= NHP)
+               return (ENXIO);
 #define        phys(a,b)       ((b)((int)(a)&0x7fffffff))
        mi = phys(hpinfo[unit],struct mba_info *);
 #define        phys(a,b)       ((b)((int)(a)&0x7fffffff))
        mi = phys(hpinfo[unit],struct mba_info *);
-       if (mi == 0 || mi->mi_alive == 0) {
-               printf("dna\n");
-               return (-1);
-       }
+       if (mi == 0 || mi->mi_alive == 0)
+               return (ENXIO);
        mba = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;
        mba->mba_cr = MBAINIT;
        hpaddr = (struct hpdevice *)&mba->mba_drv[mi->mi_drive];
        mba = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;
        mba->mba_cr = MBAINIT;
        hpaddr = (struct hpdevice *)&mba->mba_drv[mi->mi_drive];
@@ -375,10 +409,8 @@ hpdump(dev)
                hpaddr->hpof = HP_FMT22;
        }
        st = &hpst[mi->mi_type];
                hpaddr->hpof = HP_FMT22;
        }
        st = &hpst[mi->mi_type];
-       if (dumplo < 0 || dumplo + num >= st->sizes[minor(dev)&07].nblocks) {
-               printf("oor\n");
-               return (-1);
-       }
+       if (dumplo < 0 || dumplo + num >= st->sizes[minor(dev)&07].nblocks)
+               return (EINVAL);
        while (num > 0) {
                register struct pte *hpte = mba->mba_map;
                register int i;
        while (num > 0) {
                register struct pte *hpte = mba->mba_map;
                register int i;
@@ -401,11 +433,8 @@ hpdump(dev)
                hpaddr->hpcs1 = HP_WCOM | HP_GO;
                while ((hpaddr->hpds & HP_DRY) == 0)
                        ;
                hpaddr->hpcs1 = HP_WCOM | HP_GO;
                while ((hpaddr->hpds & HP_DRY) == 0)
                        ;
-               if (hpaddr->hpds&HP_ERR) {
-                       printf("dskerr: (%d,%d,%d) ds=%x er=%x\n",
-                           cn, tn, sn, hpaddr->hpds, hpaddr->hper1);
-                       return (-1);
-               }
+               if (hpaddr->hpds&HP_ERR)
+                       return (EIO);
                start += blk*NBPG;
                num -= blk;
        }
                start += blk*NBPG;
                num -= blk;
        }