spelling sn%d not bn%d
[unix-history] / usr / src / sys / vax / mba / hp.c
index e769d1f..8fd8113 100644 (file)
@@ -1,9 +1,16 @@
-/*     hp.c    4.18    81/03/01        */
+/*     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
  
@@ -226,30 +234,26 @@ hpdtint(mi, mbasr)
        int retry = 0;
 
        if (hpaddr->hpds&HP_ERR || mbasr&MBAEBITS) {
        int retry = 0;
 
        if (hpaddr->hpds&HP_ERR || mbasr&MBAEBITS) {
-               int dready = 0;
-
-               while ((hpaddr->hpds & HP_DRY) == 0) {
-                       if (++dready > 32)
-                               break;
-               }
-               if ((hpaddr->hpds&HP_DREADY) != HP_DREADY) {
-                       printf("hp%d not ready\n", dkunit(bp));
-                       bp->b_flags |= B_ERROR;
-               } else if (hpaddr->hper1&HP_WLE) {
-                       printf("hp%d is write locked\n", dkunit(bp));
+               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) {
                        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);
-                       printf("hp%d mbasr=%b er1=%b er2=%b\n",
-                           dkunit(bp), mbasr, mbasr_bits,
+                       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;
                            hpaddr->hper1, HPER1_BITS,
                            hpaddr->hper2, HPER2_BITS);
                        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) {
                } else if ((hpaddr->hper1&(HP_DCK|HP_ECH)) == HP_DCK) {
-                       if (hpecc(mi))
+                       if (hpecc(mi, 0))
                                return (MBD_RESTARTED);
                        /* else done */
                } else
                                return (MBD_RESTARTED);
                        /* else done */
                } else
@@ -257,15 +261,16 @@ hpdtint(mi, mbasr)
                hpaddr->hpcs1 = HP_DCLR|HP_GO;
                if ((mi->mi_tab.b_errcnt&07) == 4) {
                        hpaddr->hpcs1 = HP_RECAL|HP_GO;
                hpaddr->hpcs1 = HP_DCLR|HP_GO;
                if ((mi->mi_tab.b_errcnt&07) == 4) {
                        hpaddr->hpcs1 = HP_RECAL|HP_GO;
-                       /* SHOULD SET AN INTERRUPT AND RETURN */
-                       /* AND HANDLE ALA rk.c OR up.c */
-                       while (hpaddr->hpds & HP_PIP)
-                               ;
-                       mbclrattn(mi);
+                       hprecal[mi->mi_unit] = 1;
+                       return (MBD_RESTARTED);
                }
                if (retry)
                        return (MBD_RETRY);
        }
                }
                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;
        if (mi->mi_tab.b_errcnt > 16) {
                hpaddr->hpcs1 = HP_RTC|HP_GO;
        bp->b_resid = -(mi->mi_mba->mba_bcr) & 0xffff;
        if (mi->mi_tab.b_errcnt > 16) {
                hpaddr->hpcs1 = HP_RTC|HP_GO;
@@ -299,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;
@@ -318,8 +324,15 @@ 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("SOFT ECC hp%d%c bn%d\n", dkunit(bp),
+       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;
        i = (rp->hpec1&0xffff) - 1;             /* -1 makes 0 origin */
            'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
        mask = rp->hpec2&0xffff;
        i = (rp->hpec1&0xffff) - 1;             /* -1 makes 0 origin */
@@ -337,9 +350,13 @@ hpecc(mi)
        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];
@@ -349,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;
@@ -373,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];
@@ -392,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;
@@ -418,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;
        }