📄 ct.c
字号:
case MTBSF: goto gotaddr; case MTOFFL: sc->sc_blkno = 0; sc->sc_ul.unit = C_SUNIT(sc->sc_punit); sc->sc_ul.cmd = C_UNLOAD; hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_CMD, &sc->sc_ul, sizeof(sc->sc_ul)); break; case MTWEOF: sc->sc_blkno++; sc->sc_flags |= CTF_WRT; sc->sc_wfm.unit = C_SUNIT(sc->sc_punit); sc->sc_wfm.cmd = C_WFM; hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_CMD, &sc->sc_wfm, sizeof(sc->sc_wfm)); ctaddeof(unit); break; case MTBSR: sc->sc_blkno--; goto gotaddr; case MTFSR: sc->sc_blkno++; goto gotaddr; case MTREW: sc->sc_blkno = 0;#ifdef DEBUG if(ctdebug & CT_BSF) printf("ct%d: clearing eofs\n", unit);#endif for (i=0; i<EOFS; i++) sc->sc_eofs[i] = 0; sc->sc_eofp = 0;gotaddr: sc->sc_ioc.saddr = C_SADDR; sc->sc_ioc.addr0 = 0; sc->sc_ioc.addr = sc->sc_blkno; sc->sc_ioc.unit = C_SUNIT(sc->sc_punit); sc->sc_ioc.nop2 = C_NOP; sc->sc_ioc.slen = C_SLEN; sc->sc_ioc.len = 0; sc->sc_ioc.nop3 = C_NOP; sc->sc_ioc.cmd = C_READ; hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_CMD, &sc->sc_ioc, sizeof(sc->sc_ioc)); break; } } else {mustio: if ((bp->b_flags & B_READ) && sc->sc_flags & (CTF_BEOF|CTF_EOT)) {#ifdef DEBUG if (ctdebug & CDB_FILES) printf("ctstart: before flags %x\n", sc->sc_flags);#endif if (sc->sc_flags & CTF_BEOF) { sc->sc_flags &= ~CTF_BEOF; sc->sc_flags |= CTF_AEOF;#ifdef DEBUG if (ctdebug & CDB_FILES) printf("ctstart: after flags %x\n", sc->sc_flags);#endif } bp->b_resid = bp->b_bcount; iodone(bp); hpibfree(&sc->sc_dq); if (dp = bp->b_actf) dp->b_actb = bp->b_actb; else cttab[unit].b_actb = bp->b_actb; *bp->b_actb = dp; if ((bp = dp) == NULL) { cttab[unit].b_active = 0; return; } sc->sc_addr = bp->b_un.b_addr; sc->sc_resid = bp->b_bcount; if (hpibreq(&sc->sc_dq)) goto again; return; } sc->sc_flags |= CTF_IO; sc->sc_ioc.unit = C_SUNIT(sc->sc_punit); sc->sc_ioc.saddr = C_SADDR; sc->sc_ioc.addr0 = 0; sc->sc_ioc.addr = sc->sc_blkno; sc->sc_ioc.nop2 = C_NOP; sc->sc_ioc.slen = C_SLEN; sc->sc_ioc.len = sc->sc_resid; sc->sc_ioc.nop3 = C_NOP; if (bp->b_flags & B_READ) sc->sc_ioc.cmd = C_READ; else { sc->sc_ioc.cmd = C_WRITE; sc->sc_flags |= (CTF_WRT | CTF_WRTTN); } hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_CMD, &sc->sc_ioc, sizeof(sc->sc_ioc)); } hpibawait(sc->sc_hd->hp_ctlr);}ctgo(unit) register int unit;{ register struct ct_softc *sc = &ct_softc[unit]; register struct buf *bp; bp = cttab[unit].b_actf; hpibgo(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_EXEC, sc->sc_addr, sc->sc_resid, bp->b_flags & B_READ);}/* * Hideous grue to handle EOF/EOT (mostly for reads) */cteof(sc, bp) register struct ct_softc *sc; register struct buf *bp;{ long blks; /* * EOT on a write is an error. */ if ((bp->b_flags & B_READ) == 0) { bp->b_resid = bp->b_bcount; bp->b_flags |= B_ERROR; bp->b_error = ENOSPC; sc->sc_flags |= CTF_EOT; return; } /* * Use returned block position to determine how many blocks * we really read and update b_resid. */ blks = sc->sc_stat.c_blk - sc->sc_blkno - 1;#ifdef DEBUG if (ctdebug & CDB_FILES) printf("cteof: bc %d oblk %d nblk %d read %d, resid %d\n", bp->b_bcount, sc->sc_blkno, sc->sc_stat.c_blk, blks, bp->b_bcount - CTKTOB(blks));#endif if (blks == -1) { /* 9145 on EOF does not change sc_stat.c_blk */ blks = 0; sc->sc_blkno++; } else { sc->sc_blkno = sc->sc_stat.c_blk; } bp->b_resid = bp->b_bcount - CTKTOB(blks); /* * If we are at physical EOV or were after an EOF, * we are now at logical EOT. */ if ((sc->sc_stat.c_aef & AEF_EOV) || (sc->sc_flags & CTF_AEOF)) { sc->sc_flags |= CTF_EOT; sc->sc_flags &= ~(CTF_AEOF|CTF_BEOF); } /* * If we were before an EOF or we have just completed a FSF, * we are now after EOF. */ else if ((sc->sc_flags & CTF_BEOF) || (sc->sc_flags & CTF_CMD) && sc->sc_cmd == MTFSF) { sc->sc_flags |= CTF_AEOF; sc->sc_flags &= ~CTF_BEOF; } /* * Otherwise if we read something we are now before EOF * (and no longer after EOF). */ else if (blks) { sc->sc_flags |= CTF_BEOF; sc->sc_flags &= ~CTF_AEOF; } /* * Finally, if we didn't read anything we just passed an EOF */ else sc->sc_flags |= CTF_AEOF;#ifdef DEBUG if (ctdebug & CDB_FILES) printf("cteof: leaving flags %x\n", sc->sc_flags);#endif}ctintr(unit) register int unit;{ register struct ct_softc *sc = &ct_softc[unit]; register struct buf *bp, *dp; u_char stat; bp = cttab[unit].b_actf; if (bp == NULL) { printf("ct%d: bp == NULL\n", unit); return; } if (sc->sc_flags & CTF_IO) { sc->sc_flags &= ~CTF_IO; if (hpibustart(sc->sc_hd->hp_ctlr)) ctgo(unit); return; } if ((sc->sc_flags & CTF_STATWAIT) == 0) { if (hpibpptest(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave) == 0) { sc->sc_flags |= CTF_STATWAIT; hpibawait(sc->sc_hd->hp_ctlr); return; } } else sc->sc_flags &= ~CTF_STATWAIT; hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_QSTAT, &stat, 1);#ifdef DEBUG if (ctdebug & CDB_FILES) printf("ctintr: before flags %x\n", sc->sc_flags);#endif if (stat) { sc->sc_rsc.unit = C_SUNIT(sc->sc_punit); sc->sc_rsc.cmd = C_STATUS; hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_CMD, &sc->sc_rsc, sizeof(sc->sc_rsc)); hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_EXEC, &sc->sc_stat, sizeof(sc->sc_stat)); hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_QSTAT, &stat, 1);#ifdef DEBUG if (ctdebug & CDB_FILES) printf("ctintr: return stat 0x%x, A%x F%x blk %d\n", stat, sc->sc_stat.c_aef, sc->sc_stat.c_fef, sc->sc_stat.c_blk);#endif if (stat == 0) { if (sc->sc_stat.c_aef & (AEF_EOF | AEF_EOV)) { cteof(sc, bp); ctaddeof(unit); goto done; } if (sc->sc_stat.c_fef & FEF_PF) { ctreset(sc, sc->sc_hd); ctstart(unit); return; } if (sc->sc_stat.c_fef & FEF_REXMT) { ctstart(unit); return; } if (sc->sc_stat.c_aef & 0x5800) { if (sc->sc_stat.c_aef & 0x4000) tprintf(sc->sc_tpr, "ct%d: uninitialized media\n", unit); if (sc->sc_stat.c_aef & 0x1000) tprintf(sc->sc_tpr, "ct%d: not ready\n", unit); if (sc->sc_stat.c_aef & 0x0800) tprintf(sc->sc_tpr, "ct%d: write protect\n", unit); } else { printf("ct%d err: v%d u%d ru%d bn%d, ", unit, (sc->sc_stat.c_vu>>4)&0xF, sc->sc_stat.c_vu&0xF, sc->sc_stat.c_pend, sc->sc_stat.c_blk); printf("R0x%x F0x%x A0x%x I0x%x\n", sc->sc_stat.c_ref, sc->sc_stat.c_fef, sc->sc_stat.c_aef, sc->sc_stat.c_ief); } } else printf("ct%d: request status failed\n", unit); bp->b_flags |= B_ERROR; bp->b_error = EIO; goto done; } else bp->b_resid = 0; if (sc->sc_flags & CTF_CMD) { switch (sc->sc_cmd) { case MTFSF: sc->sc_flags &= ~(CTF_BEOF|CTF_AEOF); sc->sc_blkno += CTBTOK(sc->sc_resid); ctstart(unit); return; case MTBSF: sc->sc_flags &= ~(CTF_AEOF|CTF_BEOF|CTF_EOT); break; case MTBSR: sc->sc_flags &= ~CTF_BEOF; if (sc->sc_flags & CTF_EOT) { sc->sc_flags |= CTF_AEOF; sc->sc_flags &= ~CTF_EOT; } else if (sc->sc_flags & CTF_AEOF) { sc->sc_flags |= CTF_BEOF; sc->sc_flags &= ~CTF_AEOF; } break; case MTWEOF: sc->sc_flags &= ~CTF_BEOF; if (sc->sc_flags & (CTF_AEOF|CTF_EOT)) { sc->sc_flags |= CTF_EOT; sc->sc_flags &= ~CTF_AEOF; } else sc->sc_flags |= CTF_AEOF; break; case MTREW: case MTOFFL: sc->sc_flags &= ~(CTF_BEOF|CTF_AEOF|CTF_EOT); break; } } else { sc->sc_flags &= ~CTF_AEOF; sc->sc_blkno += CTBTOK(sc->sc_resid); }done:#ifdef DEBUG if (ctdebug & CDB_FILES) printf("ctintr: after flags %x\n", sc->sc_flags);#endif if (dp = bp->b_actf) dp->b_actb = bp->b_actb; else cttab[unit].b_actb = bp->b_actb; *bp->b_actb = dp; iodone(bp); hpibfree(&sc->sc_dq); if (cttab[unit].b_actf == NULL) { cttab[unit].b_active = 0; return; } ctustart(unit);}ctread(dev, uio) dev_t dev; struct uio *uio;{ register int unit = UNIT(dev); return(physio(ctstrategy, &ctbuf[unit], dev, B_READ, minphys, uio));}ctwrite(dev, uio) dev_t dev; struct uio *uio;{ register int unit = UNIT(dev); return(physio(ctstrategy, &ctbuf[unit], dev, B_WRITE, minphys, uio));}/*ARGSUSED*/ctioctl(dev, cmd, data, flag) dev_t dev; int cmd, flag; caddr_t data;{ register struct mtop *op; register int cnt; switch (cmd) { case MTIOCTOP: op = (struct mtop *)data; switch(op->mt_op) { case MTWEOF: case MTFSF: case MTBSR: case MTBSF: case MTFSR: cnt = op->mt_count; break; case MTREW: case MTOFFL: cnt = 1; break; default: return(EINVAL); } ctcommand(dev, op->mt_op, cnt); break; case MTIOCGET: break; default: return(EINVAL); } return(0);}/*ARGSUSED*/ctdump(dev) dev_t dev;{ return(ENXIO);}ctaddeof(unit) int unit;{ register struct ct_softc *sc = &ct_softc[unit]; if (sc->sc_eofp == EOFS - 1) sc->sc_eofs[EOFS - 1]++; else { sc->sc_eofp++; if (sc->sc_eofp == EOFS - 1) sc->sc_eofs[EOFS - 1] = EOFS; else /* save blkno */ sc->sc_eofs[sc->sc_eofp] = sc->sc_blkno - 1; }#ifdef DEBUG if (ctdebug & CT_BSF) printf("ct%d: add eof pos %d blk %d\n", unit, sc->sc_eofp, sc->sc_eofs[sc->sc_eofp]);#endif}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -