📄 hp.c
字号:
* partition table valid bit has not been set or the volume is * in valid */ if (((hpaddr->hpds & HPDS_VV) == 0 ) || (hp_part[unit].pt_valid == 0)){ /* * Assume that the default values before trying to * see if the partition tables are on the pack. The * reason that we do this is that the strategy routine * is used to read in the superblock but uses the * partition info. So we must first set the default * values. * */ int nspc = hpst[mi->mi_type].nspc; int i, hpstrategy(); /* 001 */ for ( i = 0; i <= 7; i++) { hp_part[unit].pt_part[i].pi_nblocks = hpst[mi->mi_type].sizes[i].nblocks; hp_part[unit].pt_part[i].pi_blkoff = hpst[mi->mi_type].sizes[i].cyloff * nspc; hp_part[unit].pt_valid = PT_VALID; } /* * Go see if the partition tables are on the pack */ rsblk( hpstrategy, dev, &hp_part[unit]); } return (0);}hpstrategy(bp) register struct buf *bp;{ register struct mba_device *mi; register struct hpst *st; register int unit = dkunit(bp); register struct pt *pt; register struct hp_softc *sc = &hp_softc[unit]; long sz, bn; int xunit = minor(bp->b_dev) & 07; int s; sz = bp->b_bcount; sz = (sz+511) >> 9; if (unit >= nNHP) goto bad; mi = hpinfo[unit]; /* * Get the partition tables for the pack in question */ pt = &hp_part[unit]; if ( ( pt->pt_valid != PT_VALID ) ) panic("hpstrategy: invalid partition table "); if (mi == 0 || mi->mi_alive == 0) goto bad; st = &hpst[mi->mi_type]; if (ML11) { if (bp->b_blkno < 0 || dkblock(bp)+sz > sc->sc_mlsize) { sc->sc_flags |= DEV_EOM; goto bad; } bp->b_cylin = 0; } else { if (bp->b_blkno < 0 || (bn = dkblock(bp))+sz > pt->pt_part[xunit].pi_nblocks) { sc->sc_flags |= DEV_EOM; goto bad; } /* * Must convert blkoff to cylinder */ bp->b_cylin = bn/st->nspc + pt->pt_part[xunit].pi_blkoff / st->nspc; } s = spl5(); disksort(&mi->mi_tab, bp); if (mi->mi_tab.b_active == 0) mbustart(mi); splx(s); return;bad: bp->b_flags |= B_ERROR; if ((sc->sc_flags & DEV_EOM)) { bp->b_error = ENOSPC; } iodone(bp); return;}hpustart(mi) register struct mba_device *mi;{ register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv; register struct buf *bp = mi->mi_tab.b_actf; register struct hpst *st; register struct hp_softc *sc = &hp_softc[mi->mi_unit]; register daddr_t bn; int sn, dist; st = &hpst[mi->mi_type]; hpaddr->hpcs1 = 0; if ((hpaddr->hpcs1&HP_DVA) == 0) return (MBU_BUSY); if ((hpaddr->hpds & HPDS_VV) == 0 || !sc->sc_hpinit) { struct buf *bbp = &bhpbuf[mi->mi_unit]; sc->sc_hpinit = 1; hpaddr->hpcs1 = HP_DCLR|HP_GO; if (mi->mi_mba->mba_drv[0].mbd_as & (1<<mi->mi_drive)) printf("%s: unit# %d: DCLR attn\n",sc->sc_device, mi->mi_unit); hpaddr->hpcs1 = HP_PRESET|HP_GO; if (!ML11) hpaddr->hpof = HPOF_FMT22; mbclrattn(mi); if (!ML11) { bbp->b_flags = B_READ|B_BUSY; bbp->b_dev = bp->b_dev; bbp->b_bcount = 512; bbp->b_un.b_addr = (caddr_t)&hpbad[mi->mi_unit]; bbp->b_blkno = st->ncyl*st->nspc - st->nsect; bbp->b_cylin = st->ncyl - 1; mi->mi_tab.b_actf = bbp; bbp->av_forw = bp; bp = bbp; } } if (mi->mi_tab.b_active || mi->mi_hd->mh_ndrive == 1) return (MBU_DODATA); if (ML11) return (MBU_DODATA); if ((hpaddr->hpds & HPDS_DREADY) != HPDS_DREADY) return (MBU_DODATA); bn = dkblock(bp); sn = bn%st->nspc; sn = (sn + st->nsect - st->sdist) % st->nsect; if (bp->b_cylin == MASKREG(hpaddr->hpdc)) { if (sc->sc_doseeks) return (MBU_DODATA); dist = (MASKREG(hpaddr->hpla) >> 6) - st->nsect + 1; if (dist < 0) dist += st->nsect; if (dist > st->nsect - st->rdist) return (MBU_DODATA); } else hpaddr->hpdc = bp->b_cylin; if (sc->sc_doseeks) hpaddr->hpcs1 = HP_SEEK|HP_GO; else { hpaddr->hpda = sn; hpaddr->hpcs1 = HP_SEARCH|HP_GO; } return (MBU_STARTED);}hpstart(mi) register struct mba_device *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 hp_softc *sc = &hp_softc[mi->mi_unit]; register daddr_t bn; int sn, tn; bn = dkblock(bp); if (ML11) hpaddr->hpda = bn; else { sn = bn%st->nspc; tn = sn/st->nsect; sn %= st->nsect; hpaddr->hpdc = bp->b_cylin; hpaddr->hpda = (tn << 8) + sn; } if (sc->sc_hdr) { if (bp->b_flags & B_READ) return (HP_RHDR|HP_GO); else return (HP_WHDR|HP_GO); } return (0);}hpdtint(mi, mbsr) register struct mba_device *mi; int mbsr;{ register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv; register struct buf *bp = mi->mi_tab.b_actf; register struct hpst *st; register int er1, er2; register struct hp_softc *sc = &hp_softc[mi->mi_unit]; int retry = 0; st = &hpst[mi->mi_type]; if (bp->b_flags&B_BAD && hpecc(mi, CONT)) return (MBD_RESTARTED); if (hpaddr->hpds&HPDS_ERR || mbsr&MBSR_EBITS) { er1 = hpaddr->hper1; er2 = hpaddr->hper2;#ifdef HPDEBUG if (hpdebug) { int dc = hpaddr->hpdc, da = hpaddr->hpda; printf("hperr: bp %x cyl %d blk %d as %o ", bp, bp->b_cylin, bp->b_blkno, hpaddr->hpas&0xff); printf("dc %x da %x\n",MASKREG(dc), MASKREG(da)); printf("errcnt %d ", mi->mi_tab.b_errcnt); printf("mbsr=%b ", mbsr, mbsr_bits); printf("er1=%b er2=%b\n", MASKREG(er1), HPER1_BITS, MASKREG(er2), HPER2_BITS); DELAY(1000000); }#endif if (er1 & HPER1_HCRC) { er1 &= ~(HPER1_HCE|HPER1_FER); er2 &= ~HPER2_BSE; } if (er1&HPER1_WLE) { sc->sc_flags |= DEV_WRTLCK; bp->b_flags |= B_ERROR; } else if (MASKREG(er1) == HPER1_FER && RP06 && !sc->sc_hdr) { if (hpecc(mi, BSE)) return (MBD_RESTARTED); goto hard; } else if (++mi->mi_tab.b_errcnt > 27 || mbsr & MBSR_HARD || er1 & HPER1_HARD || sc->sc_hdr || (!ML11 && (er2 & HPER2_HARD))) { /* * HCRC means the header is screwed up and the sector * might well exist in the bad sector table, * better check.... */ if ((er1&HPER1_HCRC) && !ML11 && !sc->sc_hdr && hpecc(mi, BSE)) return (MBD_RESTARTED);hard: if (ML11) bp->b_blkno = MASKREG(hpaddr->hpda); else bp->b_blkno = MASKREG(hpaddr->hpdc) * st->nspc + (MASKREG(hpaddr->hpda) >> 8) * st->nsect + (hpaddr->hpda&0xff); /* * If we have a data check error or a hard * ecc error the bad sector has been read/written, * and the controller registers are pointing to * the next sector... */ if (er1&(HPER1_DCK|HPER1_ECH) || sc->sc_hdr) bp->b_blkno--; harderr(bp, "hp"); sc->sc_hardcnt++; sc->sc_flags |= DEV_HARDERR; /* Do an hex dump of interesting registers * for the hard disk error. First, print a row of * appropriate register names followed by a row of * register contents lined up below the header line * (Hopefully). Bit expansions are not practical for * this type of dump, using the Kernel printf. */ switch ((hpaddr -> hpdt) & 0x1ff) { case MBDT_RP04: case MBDT_RP05: case MBDT_RP06: case MBDT_RP07: mprintf("%s: unit#:%d hard err blk#:%d \ mbsr:%b rpcs1:%x rpds:%x rper1:%x rpmr:%x \ rpas:%x rpda:%x rpdt:%x rpla:%x rpsn:%x \ rpof:%x rpdc:%x rpcc:%x rper2:%x rper3:%x \ rpec1:%x rpec2:%x\n", sc->sc_device, mi->mi_unit, bp->b_blkno, mbsr, mbsr_bits, MASKREG(hpaddr->hpcs1), MASKREG(hpaddr->hpds), MASKREG(hpaddr->hper1), MASKREG(hpaddr->hpmr), MASKREG(hpaddr->hpas), MASKREG(hpaddr->hpda), MASKREG(hpaddr->hpdt), MASKREG(hpaddr->hpla), MASKREG(hpaddr->hpsn), MASKREG(hpaddr->hpof), MASKREG(hpaddr->hpdc), MASKREG(hpaddr->hpcc), MASKREG(hpaddr->hpmr2), MASKREG(hpaddr->hper2), MASKREG(hpaddr->hpec1), MASKREG(hpaddr->hpec2)); break; case MBDT_RM03: case MBDT_RM05: case MBDT_RM80: mprintf("%s: unit#:%d hard err blk#:%d \ mbsr:%b rmcs1:%x rmds:%x rmer1:%x rmmr1:%x \ rmas:%x rmda:%x rmdt:%x rmla:%x rmsn:%x \ rmof:%x rmdc:%x rmhr:%x rmmr2:%x rmer2:%x \ rmec1:%x rmec2:%x\n", sc->sc_device, mi->mi_unit, bp->b_blkno, mbsr, mbsr_bits, MASKREG(hpaddr->hpcs1), MASKREG(hpaddr->hpds), MASKREG(hpaddr->hper1), MASKREG(hpaddr->hpmr), MASKREG(hpaddr->hpas), MASKREG(hpaddr->hpda), MASKREG(hpaddr->hpdt), MASKREG(hpaddr->hpla), MASKREG(hpaddr->hpsn), MASKREG(hpaddr->hpof), MASKREG(hpaddr->hpdc), MASKREG(hpaddr->hpcc), MASKREG(hpaddr->hpmr2), MASKREG(hpaddr->hper2), MASKREG(hpaddr->hpec1), MASKREG(hpaddr->hpec2)); break; case MBDT_ML11A: case MBDT_ML11B: mprintf("%s: unit#:%d hard err blk#:%d \ mbsr:%b mlcs1:%x mlds:%x mler:%x mlmr:%x \ mlas:%x mlda:%x mldt:%x mlpa:%x mlsn:%x \ mle1:%x mle2:%x mld1:%x mld2:%x mlee:%x \ mlel:%x mlpd:%x\n", sc->sc_device, mi->mi_unit, bp->b_blkno, mbsr, mbsr_bits, MASKREG(hpaddr->hpcs1), MASKREG(hpaddr->hpds), MASKREG(hpaddr->hper1), MASKREG(hpaddr->hpmr), MASKREG(hpaddr->hpas), MASKREG(hpaddr->hpda), MASKREG(hpaddr->hpdt), MASKREG(hpaddr->hpla), MASKREG(hpaddr->hpsn), MASKREG(hpaddr->hpof), MASKREG(hpaddr->hpdc), MASKREG(hpaddr->hpcc), MASKREG(hpaddr->hpmr2), MASKREG(hpaddr->hper2), MASKREG(hpaddr->hpec1), MASKREG(hpaddr->hpec2)); break; default: /* * Original Error handler (Maintained for all * of the unsupported devices) modified to use * mprintf */ mprintf("%s: unit#:%d hard err blk#:%d \ mbsr:%b er1:%b er2:%b mr:%x mr2:%x\n", sc->sc_device, mi->mi_unit, bp->b_blkno, mbsr, mbsr_bits, MASKREG(hpaddr->hper1), HPER1_BITS, MASKREG(hpaddr->hper2), HPER2_BITS, MASKREG(hpaddr->hpmr), MASKREG(hpaddr->hpmr2)); if (sc->sc_hdr) mprintf("(hdr i/o)\n"); /* End of Original Error Handler */ break; } bp->b_flags |= B_ERROR; retry = 0; sc->sc_recal = 0; } else if ((er2 & HPER2_BSE) && !ML11) { if (hpecc(mi, BSE)) return (MBD_RESTARTED); goto hard; } else if (RM80 && er2&HPER2_SSE) { (void) hpecc(mi, SSE); return (MBD_RESTARTED); } else if ((er1&(HPER1_DCK|HPER1_ECH))==HPER1_DCK) { if (hpecc(mi, ECC)) return (MBD_RESTARTED); /* else done */ } else retry = 1; hpaddr->hpcs1 = HP_DCLR|HP_GO; if (ML11) { if (mi->mi_tab.b_errcnt >= 16) goto hard; } else if ((mi->mi_tab.b_errcnt&07) == 4) { hpaddr->hpcs1 = HP_RECAL|HP_GO; sc->sc_recal = 1; return (MBD_RESTARTED); } if (retry) { sc->sc_flags |= DEV_RETRY; return (MBD_RETRY); } }#ifdef HPDEBUG else 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", hpaddr->hper1, HPER1_BITS, hpaddr->hper2, HPER2_BITS); }#endif switch (sc->sc_recal) { case 1: hpaddr->hpdc = bp->b_cylin; hpaddr->hpcs1 = HP_SEEK|HP_GO; sc->sc_recal++; return (MBD_RESTARTED);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -