📄 mt.c
字号:
bp->b_resid = 0; } break; case MTER_NOTCAP: sc->sc_flags |= DEV_BLANK; goto err; case MTER_EOT: if (dis_eot_mu[unit] != DISEOT) { sc->sc_flags |= DEV_EOM; if (mi->mi_tab.b_errcnt != 2) { sc->sc_blkno++; } bp->b_resid = 0; } break; case MTER_TM: sc->sc_category_flags |= DEV_TPMARK; sc->sc_blkno++; err: bp->b_resid = bp->b_bcount; sc->sc_nxrec = bdbtofsb(bp->b_blkno); break; case MTER_SHRTREC: sc->sc_category_flags |= DEV_SHRTREC; sc->sc_blkno++; if (bp == &cmtbuf[mtunit]) bp->b_flags |= B_ERROR; if (mi->mi_tab.b_errcnt == 2) bp->b_bcount = bp->b_resid; bp->b_resid = bp->b_bcount - mtaddr->mtbc; break; case MTER_RDOPP: sc->sc_flags |= DEV_DONE; sc->sc_category_flags |= DEV_RDOPP; mi->mi_tab.b_errcnt = 2; if ((bp->b_bcount = MASKREG(mtaddr->mtbc)) == 0) bp->b_bcount = 1; if (bp->b_bcount > bp->b_resid) bp->b_bcount = bp->b_resid; bp->b_bcount = -(bp->b_bcount); return(MBD_RETRY); case MTER_RETRY: sc->sc_flags |= DEV_RETRY; sc->sc_softcnt++; mi->mi_tab.b_errcnt = 1; return(MBD_RETRY); case MTER_OFFLINE: case MTER_NOTAVL: sc->sc_flags |= DEV_OFFLINE; if (sc->sc_openf > 0) { sc->sc_openf = -1; } bp->b_error |= ENXIO; bp->b_flags |= B_ERROR; sc->sc_flags |= DEV_DONE; return (MBD_DONE); case MTER_FPT: sc->sc_flags |= DEV_WRTLCK; bp->b_flags |= B_ERROR; break; case MTER_UNREAD: sc->sc_blkno++; bp->b_bcount = bp->b_resid; bp->b_resid -= MIN(MASKREG(mtaddr->mtbc), bp->b_bcount); default: sc->sc_flags |= DEV_HARDERR; sc->sc_hardcnt++; mprintf("%s: unit#:%d hard err blk#:%d mbsr:%b \ mtcs:%x mter:%x mtca:%x mtmr1:%x mtas:%x \ mtbc:%x mtdt:%x mtds:%x mtsn:%x mtmr2:%x \ mtmr3:%x mtner:%x mtncs0:%x mtncs1:%x mtncs2:%x \ mtncs3:%x mtia:%x mtid:%x\n", sc->sc_device, unit, bp->b_blkno, mbsr, mbsr_bits, MASKREG(mtaddr->mtcs), MASKREG(mtaddr->mter), MASKREG(mtaddr->mtca), MASKREG(mtaddr->mtmr1), MASKREG(mtaddr->mtas), MASKREG(mtaddr->mtbc), MASKREG(mtaddr->mtdt), MASKREG(mtaddr->mtds), MASKREG(mtaddr->mtsn), MASKREG(mtaddr->mtmr2), MASKREG(mtaddr->mtmr3), MASKREG(mtaddr->mtner), MASKREG(mtaddr->mtncs[0]), MASKREG(mtaddr->mtncs[1]), MASKREG(mtaddr->mtncs[2]), MASKREG(mtaddr->mtncs[3]), MASKREG(mtaddr->mtia), MASKREG(mtaddr->mtid)); bp->b_flags |= B_ERROR; mtaddr->mtid = MTID_CLR; /* reset the TM78 */ DELAY(100000); while ((mtaddr->mtid & MTID_RDY) == 0) /* wait for it */ ; break; } sc->sc_flags |= DEV_DONE; return (MBD_DONE);}mtndtint(mi) register struct mba_device *mi;{ register struct mtdevice *mtaddr = (struct mtdevice *)mi->mi_drv; register struct mu_softc *sc; register struct buf *bp = mi->mi_tab.b_actf; register int mtunit; register int unit; int er, ds, fc, ner; if (bp == 0) { ner = mtaddr->mtner; mtunit = MTUNIT((ner >> 8) & 0x3); unit = UNIT((ner >> 8) & 0x3); sc = &mu_softc[unit]; ds = MASKREG(mtaddr->mtds); if((ds & MTDS_EOT) && (dis_eot_mu[unit] != DISEOT)) { sc->sc_dsreg = ds; sc->sc_flags |= DEV_EOM; } return (MBN_SKIP); /* Just return if unexpected */ } mtunit = MTUNIT(bp->b_dev); unit = UNIT(bp->b_dev); sc = &mu_softc[unit]; sc->sc_erreg = er = MASKREG(mtaddr->mtner); sc->sc_dsreg = ds = MASKREG(mtaddr->mtds); sc->sc_resid = fc = (mtaddr->mtncs[unit] >> 8) & 0xff; if(sc->sc_savestate != sc->sc_dsreg) { sc->sc_changedstate = 1; } if((sc->sc_dsreg & MTDS_EOT) && (dis_eot_mu[unit] != DISEOT)) { sc->sc_flags |= DEV_EOM; } switch (er & MTER_INTCODE) { case MTER_DONE: if (bp == &cmtbuf[mtunit]) { done: if (bp->b_command == MT_SENSE) sc->sc_dsreg = MASKREG(mtaddr->mtds); bp->b_resid = fc; sc->sc_flags |= DEV_DONE; return (MBN_DONE); } if ((fc = bdbtofsb(bp->b_blkno) - sc->sc_blkno) < 0) sc->sc_blkno -= MIN(0377, -fc); else sc->sc_blkno += MIN(0377, fc); sc->sc_flags |= DEV_RETRY; return (MBN_RETRY); case MTER_RWDING: sc->sc_category_flags |= DEV_RWDING; return (MBN_SKIP); case MTER_NOTCAP: sc->sc_flags |= DEV_BLANK; return (MBN_SKIP); case MTER_EOT: case MTER_LEOT: if((ds & MTDS_EOT) && (dis_eot_mu[unit] != DISEOT)) { sc->sc_flags |= DEV_EOM; } sc->sc_flags |= DEV_DONE; return (MBN_DONE); case MTER_TM: sc->sc_category_flags |= DEV_TPMARK; if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { sc->sc_nxrec = bdbtofsb(bp->b_blkno) + fc; sc->sc_blkno = sc->sc_nxrec; } else { sc->sc_blkno = bdbtofsb(bp->b_blkno) - fc; sc->sc_nxrec = sc->sc_blkno - 1; } sc->sc_flags |= DEV_DONE; return (MBN_DONE); case MTER_FPT: sc->sc_flags |= DEV_WRTLCK; bp->b_flags |= B_ERROR; sc->sc_flags |= DEV_DONE; return (MBN_DONE); case MTER_OFFLINE: case MTER_NOTAVL: sc->sc_flags |= DEV_OFFLINE; if (sc->sc_openf > 0) { sc->sc_openf = -1; } bp->b_flags |= B_ERROR; sc->sc_flags |= DEV_DONE; return (MBN_DONE); case MTER_BOT: sc->sc_flags |= DEV_BOM; sc->sc_category_flags &= ~DEV_RWDING; if (bp == &cmtbuf[mtunit]) goto done; case MTER_ONLINE: sc->sc_flags &= ~DEV_OFFLINE; sc->sc_flags |= DEV_DONE; return (MBN_DONE); default: sc->sc_flags |= DEV_HARDERR; sc->sc_hardcnt++; mprintf("%s: unit#:%d hard err blk#:%d \ mtcs:%x mter:%x mtca:%x mtmr1:%x mtas:%x \ mtbc:%x mtdt:%x mtds:%x mtsn:%x mtmr2:%x \ mtmr3:%x mtner:%x mtncs0:%x mtncs1:%x mtncs2:%x \ mtncs3:%x mtia:%x mtid:%x\n", sc->sc_device, unit, bp->b_blkno, MASKREG(mtaddr->mtcs), MASKREG(mtaddr->mter), MASKREG(mtaddr->mtca), MASKREG(mtaddr->mtmr1), MASKREG(mtaddr->mtas), MASKREG(mtaddr->mtbc), MASKREG(mtaddr->mtdt), MASKREG(mtaddr->mtds), MASKREG(mtaddr->mtsn), MASKREG(mtaddr->mtmr2), MASKREG(mtaddr->mtmr3), MASKREG(mtaddr->mtner), MASKREG(mtaddr->mtncs[0]), MASKREG(mtaddr->mtncs[1]), MASKREG(mtaddr->mtncs[2]), MASKREG(mtaddr->mtncs[3]), MASKREG(mtaddr->mtia), MASKREG(mtaddr->mtid)); mtaddr->mtid = MTID_CLR; /* reset the TM78 */ DELAY(100000); while ((mtaddr->mtid & MTID_RDY) == 0) /* wait for it */ ; bp->b_flags |= B_ERROR; sc->sc_flags |= DEV_DONE; return (MBN_DONE); }}mtread(dev, uio) register dev_t dev; register struct uio *uio;{ register int mtunit = MTUNIT(dev); return (physio(mtstrategy, &rmtbuf[mtunit], dev, B_READ, minphys, uio));}mtwrite(dev, uio) register dev_t dev; register struct uio *uio;{ register int mtunit = MTUNIT(dev); return (physio(mtstrategy, &rmtbuf[mtunit], dev, B_WRITE, minphys, uio));}mtioctl(dev, cmd, data, flag) dev_t dev; register int cmd; caddr_t data; int flag;{ register struct mba_device *mi = mtinfo[MTUNIT(dev)]; register struct mu_softc *sc = &mu_softc[UNIT(dev)]; register struct buf *bp = &cmtbuf[MTUNIT(dev)]; register callcount; register int op; struct mtop *mtop; struct mtget *mtget; struct devget *devget; int unit = UNIT(dev); int fcount; /* we depend of the values and order of the MT codes here */ static mtops[] = { MT_WTM, MT_SFLEOT, MT_SREVF, MT_SFORW, MT_SREV, MT_REW, MT_UNLOAD, MT_SENSE }; switch (cmd) { case MTIOCTOP: /* tape operation */ mtop = (struct mtop *)data; switch (mtop->mt_op) { case MTWEOF: callcount = mtop->mt_count; fcount = 1; break; case MTFSF: case MTBSF: callcount = mtop->mt_count; fcount = 1; break; case MTFSR: case MTBSR: callcount = 1; fcount = mtop->mt_count; break; case MTREW: case MTOFFL: sc->sc_flags &= ~DEV_EOM; callcount = 1; fcount = 1; break; case MTNOP: case MTCACHE: case MTNOCACHE: return(0); case MTCSE: sc->sc_flags |= DEV_CSE; sc->sc_category_flags &= ~DEV_TPMARK; return(0); case MTCLX: case MTCLS: return(0); case MTENAEOT: dis_eot_mu[unit] = 0; return(0); case MTDISEOT: dis_eot_mu[unit] = DISEOT; sc->sc_flags &= ~DEV_EOM; return(0); case MTFLUSH: /* * Flush controller's write back cache. Since this * driver can not support this functionality, return * ENXIO to indicate the lack of support. */ return (ENXIO); default: return (ENXIO); } if (callcount <= 0 || fcount <= 0) return (EINVAL); op = mtops[mtop->mt_op]; if (op == MT_WTM) op |= sc->sc_dens; while (--callcount >= 0) { register int n; do { n = MIN(fcount, 0xff); mtcommand(dev, op, n); fcount -= n; } while (fcount); if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) && bp->b_resid) return (EIO); if (bp->b_flags & B_ERROR) break; } return (geterror(bp)); case MTIOCGET: /* tape status */ mtget = (struct mtget *)data; mtget->mt_erreg = sc->sc_erreg; mtget->mt_resid = sc->sc_resid; mtcommand(dev, MT_SENSE, 1); mtget->mt_dsreg = sc->sc_dsreg; mtget->mt_type = MT_ISMT; break; case DEVIOCGET: /* device status */ devget = (struct devget *)data; bzero(devget,sizeof(struct devget)); devget->category = DEV_TAPE; devget->bus = DEV_MB; bcopy(DEV_TM78,devget->interface, strlen(DEV_TM78)); bcopy(sc->sc_device,devget->device, strlen(sc->sc_device)); 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_drive; /* which TM78 */ devget->slave_num = sc->sc_slave; /* which plug */ bcopy(mi->mi_driver->md_sname, devget->dev_name, strlen(mi->mi_driver->md_sname)); /* Ult. "mu" */ devget->unit_num = unit; /* which mu?? */ mtcommand(dev, MT_SENSE, 1); /* TU78 hack */ 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 = sc->sc_category_flags; /* c.st.*/ break; default: return (ENXIO); } return (0);}mtdump(){ register struct mba_device *mi; register struct mba_regs *mp; register struct mtdevice *mtaddr; register int blk; register int num; register int start; start = 0; num = maxfree; if (mtinfo[0] == 0) return (ENXIO); mi = PHYS(mtinfo[0], struct mba_device *); mp = PHYS(mi->mi_hd, struct mba_hd *)->mh_physmba; mp->mba_cr = MBCR_IE; mtaddr = (struct mtdevice *)&mp->mba_drv[mi->mi_drive]; mtaddr->mtcs = MTID_CLR|MT_GO; while (num > 0) { blk = num > DBSIZE ? DBSIZE : num; mtdwrite(start, blk, mtaddr, mp); start += blk; num -= blk; } mteof(mtaddr); mteof(mtaddr); mtwait(mtaddr); mtaddr->mtcs = MT_REW|MT_GO; return (0);}mtdwrite(dbuf, num, mtaddr, mp) register int dbuf; register int num; register struct mtdevice *mtaddr; register struct mba_regs *mp;{ register struct pte *io; register int i; mtwait(mtaddr); io = mp->mba_map; for (i = 0; i < num; i++) *(int *)io++ = dbuf++ | PG_V; mtaddr->mtbc = -(num*NBPG); mp->mba_sr = -1; mp->mba_bcr = -(num*NBPG); mp->mba_var = 0; mtaddr->mtcs = MT_WRITE|MT_GCR|MT_GO;}mtwait(mtaddr) register struct mtdevice *mtaddr;{ register int s; do s = mtaddr->mtds; while ((s & MTDS_RDY) == 0);}mteof(mtaddr) register struct mtdevice *mtaddr;{ mtwait(mtaddr); mtaddr->mtcs = MT_CLS|MT_GCR|MT_GO;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -