📄 hp.c
字号:
case 2: if (mi->mi_tab.b_errcnt < 16 || (bp->b_flags & B_READ) == 0) goto donerecal; hpaddr->hpof = hp_offset[mi->mi_tab.b_errcnt & 017]|HPOF_FMT22; hpaddr->hpcs1 = HP_OFFSET|HP_GO; sc->sc_recal++; return (MBD_RESTARTED); donerecal: case 3: sc->sc_recal = 0; sc->sc_flags |= DEV_RETRY; return (MBD_RETRY); } sc->sc_hdr = 0; bp->b_resid = MASKREG(-mi->mi_mba->mba_bcr); if (mi->mi_tab.b_errcnt >= 16) { /* * This is fast and occurs rarely; we don't * bother with interrupts. */ hpaddr->hpcs1 = HP_RTC|HP_GO; while (hpaddr->hpds & HPDS_PIP) ; mbclrattn(mi); } if (!ML11) { hpaddr->hpof = HPOF_FMT22; hpaddr->hpcs1 = HP_RELEASE|HP_GO; } sc->sc_flags |= DEV_DONE; return (MBD_DONE);}hpread(dev, uio) register dev_t dev; register struct uio *uio;{ register int unit = minor(dev) >> 3; return (physio(hpstrategy, &rhpbuf[unit], dev, B_READ, minphys, uio));}hpwrite(dev, uio) register dev_t dev; register struct uio *uio;{ register int unit = minor(dev) >> 3; return (physio(hpstrategy, &rhpbuf[unit], dev, B_WRITE, minphys, uio));}/*ARGSUSED*/hpioctl(dev, cmd, data, flag) dev_t dev; register int cmd; caddr_t data; int flag;{ register int unit = minor(dev) >> 3; register struct mba_device *mi = hpinfo[unit]; register struct pt *pt = (struct pt *)data; register struct hp_softc *sc = &hp_softc[unit]; struct dkop *dkop; struct dkget *dkget; struct devget *devget; register int i; int nspc; int error; switch (cmd) { case DKIOCHDR: /* do header read/write */ sc->sc_hdr = 1; break; case DIOCGETPT: /* 001 get partition table info */ /* * Do a structure copy into the user's data area */ *pt = hp_part[unit]; break; case DIOCDGTPT: /* Get default partition table */ /* * Get number of sectors per cylinder */ nspc = hpst[mi->mi_type].nspc; /* * Get the partition size and offset */ for ( i = 0; i <= 7; i++) { pt->pt_part[i].pi_nblocks = hpst[mi->mi_type].sizes[i].nblocks; pt->pt_part[i].pi_blkoff = hpst[mi->mi_type].sizes[i].cyloff * nspc; } break; case DIOCSETPT: /* 001 set the driver partition tables */ /* * Only super users can set the pack's partition * table */ if ( !suser() ) return(EACCES); /* * Before we set the new partition tables make sure * that it will no corrupt any of the kernel data * structures */ if ( ( error = ptcmp( dev, &hp_part[unit], pt ) ) != 0 ) return(error); /* * Using the user's data to set the partition table * for the pack */ hp_part[unit] = *pt; /* * See if we need to update the superblock of the * "a" partition of this disk */ ssblk(dev,pt); /* * Just make sure that we set the valid bit */ hp_part[unit].pt_valid = PT_VALID; break; case DKIOCDOP: /* Disk operation */ if ( !suser() ) return(EACCES); break; case DKIOCGET: /* Get disk status */ break; case DEVIOCGET: /* Device status */ devget = (struct devget *)data; bzero(devget,sizeof(struct devget)); devget->category = DEV_DISK; /* Disk */ devget->bus = DEV_MB; /* Massbus */ bcopy(DEV_RH,devget->interface, strlen(DEV_RH)); /* RH??? */ bcopy(sc->sc_device,devget->device, strlen(sc->sc_device)); /* R[MP]?? */ devget->adpt_num = mi->mi_adpt; /* which adapter*/ devget->nexus_num = mi->mi_nexus; /* which nexus */ devget->bus_num = mi->mi_mbanum; /* which MBA */ devget->ctlr_num = mi->mi_mbanum; /* which RH */ devget->slave_num = mi->mi_drive; /* which plug */ bcopy(mi->mi_driver->md_dname, devget->dev_name, strlen(mi->mi_driver->md_dname)); /* Ultrix "hp" */ devget->unit_num = unit; /* which hp?? */ devget->soft_count = sc->sc_softcnt; /* soft er. cnt.*/ devget->hard_count = sc->sc_hardcnt; /* hard er. cnt.*/ devget->stat = sc->sc_flags; /* status */ devget->category_stat = DEV_DISKPART; /* which prtn. */ break; default: return (ENXIO); } return(0);}hpecc(mi, flag) register struct mba_device *mi; int flag;{ register struct mba_regs *mbp = mi->mi_mba; register struct hpdevice *rp = (struct hpdevice *)mi->mi_drv; register struct buf *bp = mi->mi_tab.b_actf; register struct hpst *st = &hpst[mi->mi_type]; int npf, o; int bn, cn, tn, sn; int bcr;#ifdef HPDEBUG if(hpdebug) { printf("b_flags = 0x%x ", bp->b_flags); printf("mba_bcr = 0x%x ", mbp->mba_bcr); }#endif HPDEBUG bcr = (mbp->mba_bcr); /* * On a read, the most conservative half of the byte count * register is the SBI transfer half (lower 16 bits). * On a write, the most conservative half of the byte count * register is the Massbus half (upper 16 bits). * * If the transfer is not a read, it is most likely * a write. */ if ((bp->b_flags & B_READ) != B_READ) bcr = (bcr >> 16); bcr = MASKREG(bcr); if (bcr) bcr |= 0xffff0000; /* sxt */ if (flag == CONT) npf = bp->b_error; else npf = btop(bcr + bp->b_bcount);#ifdef HPDEBUG if(hpdebug) printf("npf = %d\n", npf);#endif HPDEBUG o = (int)bp->b_un.b_addr & PGOFSET; bn = dkblock(bp); cn = bp->b_cylin; sn = bn%(st->nspc) + npf; tn = sn/st->nsect; sn %= st->nsect; cn += tn/st->ntrak; tn %= st->ntrak; switch (flag) { case ECC: { register int i; caddr_t addr; struct pte mpte; int bit, byte, mask; npf--; /* error was in the previous block*/ mprintf("hp%d%c: soft ecc sn:%d cyl:%d trk:%d sect:%d\n", dkunit(bp), 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf, MASKREG(rp->hpdc), ((MASKREG(rp->hpda) >> 8) & 0xff), (MASKREG(rp->hpda) & 0xff)); mask = MASKREG(rp->hpec2); i = MASKREG(rp->hpec1) - 1; /* -1 makes 0 origin */ bit = i&07; i = (i&~07)>>3; byte = i + o; while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { mpte = mbp->mba_map[npf+btop(byte)]; addr = ptob(mpte.pg_pfnum) + (byte & PGOFSET); putmemc(addr, getmemc(addr)^(mask<<bit)); byte++; i++; bit -= 8; } if (bcr == 0) return (0); npf++; break; } case SSE: rp->hpof |= HPOF_SSEI; mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf)); break; case BSE:#ifdef HPBDEBUG if (hpbdebug) printf("hpecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);#endif if (rp->hpof&HPOF_SSEI) sn++; if ((bn = isbad(&hpbad[mi->mi_unit], cn, tn, sn)) < 0) return (0); bp->b_flags |= B_BAD; bp->b_error = npf + 1; bn = st->ncyl*st->nspc - st->nsect - 1 - bn; cn = bn/st->nspc; sn = bn%st->nspc; tn = sn/st->nsect; sn %= st->nsect; mbp->mba_bcr = -MIN(512, bp->b_bcount - (int)ptob(npf)); rp->hpof &= ~HPOF_SSEI;#ifdef HPBDEBUG if (hpbdebug) printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);#endif break; case CONT:#ifdef HPBDEBUG if (hpbdebug) printf("hpecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn);#endif npf = bp->b_error; bp->b_flags &= ~B_BAD; mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf)); if (MASKREG(mbp->mba_bcr) == 0) return (0); break; } rp->hpcs1 = HP_DCLR|HP_GO; if (rp->hpof&HPOF_SSEI) sn++; rp->hpdc = cn; rp->hpda = (tn<<8) + sn; mbp->mba_sr = -1; mbp->mba_var = (int)ptob(npf) + o; rp->hpcs1 = bp->b_flags&B_READ ? HP_RCOM|HP_GO : HP_WCOM|HP_GO; mi->mi_tab.b_errcnt = 0; /* error has been corrected */ return (1);}#define DBSIZE 20hpdump(dev, dumpinfo) dev_t dev; /* dump device */ struct dumpinfo dumpinfo; /* dump info */{#ifdef notdef register struct mba_device *mi; register struct mba_regs *mba; struct hpdevice *hpaddr; char *start; char *start_tmp; int unit; register struct hpst *st; start = start_tmp = 0; unit = minor(dev) >> 3; if (unit >= nNHP) return (ENXIO);#define phys(a,b) ((b)((int)(a)&0x7fffffff)) mi = phys(hpinfo[unit],struct mba_device *); if (mi == 0 || mi->mi_alive == 0) return (ENXIO); mba = phys(mi->mi_hd, struct mba_hd *)->mh_physmba; mba->mba_cr = MBCR_INIT; hpaddr = (struct hpdevice *)&mba->mba_drv[mi->mi_drive]; if ((hpaddr->hpds & HPDS_VV) == 0) { hpaddr->hpcs1 = HP_DCLR|HP_GO; hpaddr->hpcs1 = HP_PRESET|HP_GO; hpaddr->hpof = HPOF_FMT22; } st = &hpst[mi->mi_type]; /* * If a full dump is being performed, then this loop * will dump all of core. If a partial dump is being * performed, then as much of core as possible will be * dumped, leaving room for the u_area and error logger * buffer. Please note that dumpsys predetermined what * type of dump will be performed. */ while ((dumpinfo.size_to_dump > 0) || (dumpinfo.partial_dump)) { register struct pte *hpte = mba->mba_map; register int i; int blk, cn, sn, tn; daddr_t bn; blk = dumpinfo.size_to_dump > DBSIZE ? DBSIZE : dumpinfo.size_to_dump; bn = dumplo + btop(start_tmp); cn = bn/st->nspc + dumpinfo.blkoffs / st->nspc; sn = bn%st->nspc; tn = sn/st->nsect; sn = sn%st->nsect; hpaddr->hpdc = cn; hpaddr->hpda = (tn << 8) + sn; for (i = 0; i < blk; i++) *(int *)hpte++ = (btop(start)+i) | PG_V; mba->mba_sr = -1; mba->mba_bcr = -(blk*NBPG); mba->mba_var = 0; hpaddr->hpcs1 = HP_WCOM | HP_GO; while ((hpaddr->hpds & HPDS_DRY) == 0) ; if (hpaddr->hpds&HPDS_ERR) return (EIO); start += blk*NBPG; start_tmp += blk*NBPG; dumpinfo.size_to_dump -= blk; if ((dumpinfo.size_to_dump <= 0) && (dumpinfo.partial_dump)) { /* * If a partial dump is being performed.... */ /* Set size_to_dump to the number of pages to dump */ dumpinfo.size_to_dump = dumpinfo.pdump[NUM_TO_DUMP-dumpinfo.partial_dump].num_blks; /* Set start to starting address */ start = 0; start += dumpinfo.pdump[NUM_TO_DUMP-dumpinfo.partial_dump].start_addr; dumpinfo.partial_dump--; } } return (0);#endif notdef}hpsize(dev) register dev_t dev;{ register int unit = minor(dev) >> 3; register struct mba_device *mi; if (unit >= nNHP || (mi = hpinfo[unit]) == 0 || mi->mi_alive == 0) return (-1); /* * Sanity check 001 */ if ( hp_part[unit].pt_valid != PT_VALID ) panic("hpsize: invalid partition table "); return ((int)hp_part[unit].pt_part[minor(dev) & 07].pi_nblocks);/*001*/}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -