Annotation of researchv9/sys/sundev/st.c, revision 1.1.1.1

1.1       root        1: /*     @(#)st.c 1.1 86/02/03 SMI       */
                      2: 
                      3: /*
                      4:  * Copyright (c) 1985 by Sun Microsystems, Inc.
                      5:  */
                      6: 
                      7: #include "st.h"
                      8: #if NST > 0
                      9: 
                     10: /*
                     11:  * Driver for Sysgen SC400 and Emulex MT02 SCSI tape controller.
                     12:  */
                     13: 
                     14: #include "../h/param.h"
                     15: #include "../h/systm.h"
                     16: #include "../h/buf.h"
                     17: #include "../h/dir.h"
                     18: #include "../h/conf.h"
                     19: #include "../h/user.h"
                     20: #include "../h/file.h"
                     21: #include "../h/map.h"
                     22: #include "../h/vm.h"
                     23: #include "../h/mtio.h"
                     24: #include "../h/cmap.h"
                     25: 
                     26: #include "../sun/dklabel.h"
                     27: #include "../sun/dkio.h"
                     28: #include "../machine/psl.h"
                     29: #include "../machine/mmu.h"
                     30: #include "../machine/cpu.h"
                     31: #include "../sundev/mbvar.h"
                     32: #include "../sundev/screg.h"
                     33: #include "../sundev/sireg.h"
                     34: #include "../sundev/scsi.h"
                     35: #include "../sundev/streg.h"
                     36: 
                     37: #define        INF             1000000000
                     38: /*
                     39:  * Max # of buffers outstanding per unit.
                     40:  */
                     41: #define        MAXSTBUF        3
                     42: 
                     43: /*
                     44:  * Bits in minor device.
                     45:  */
                     46: #define        STUNIT(dev)     (minor(dev) & 03)
                     47: #define        T_NOREWIND      04
                     48: #define QIC_24         8
                     49: 
                     50: extern struct scsi_unit stunits[];
                     51: extern struct scsi_unit_subr scsi_unit_subr[];
                     52: extern struct scsi_tape stape[];
                     53: extern int nstape;
                     54: 
                     55: /*
                     56:  * Return a pointer to this unit's unit structure.
                     57:  */
                     58: stunitptr(md)
                     59:        register struct mb_device *md;
                     60: {
                     61:        return ((int)&stunits[md->md_unit]);
                     62: }
                     63: 
                     64: /*
                     65:  * Attach device (boot time).
                     66:  */
                     67: stattach(md)
                     68:        register struct mb_device *md;
                     69: {
                     70:        register struct scsi_unit *un;
                     71:        register struct scsi_tape *dsi;
                     72: 
                     73:        un = &stunits[md->md_unit];
                     74:        dsi = &stape[md->md_unit];
                     75:        un->un_md = md;
                     76:        un->un_mc = md->md_mc;
                     77:        un->un_unit = md->md_unit;
                     78:        un->un_target = TARGET(md->md_slave);
                     79:        un->un_lun = LUN(md->md_slave);
                     80:        un->un_ss = &scsi_unit_subr[TYPE(md->md_flags)];
                     81:        dsi->un_ctype = ST_TYPE_INVALID;
                     82:        dsi->un_openf = CLOSED;
                     83: }
                     84: 
                     85: stinit(dev)
                     86:        dev_t dev;
                     87: {
                     88:        register int unit;
                     89:        register struct scsi_tape *dsi;
                     90: 
                     91:        unit = STUNIT(dev);
                     92:        dsi = &stape[unit];
                     93: 
                     94:        dsi->un_ctype = 1;
                     95:        dsi->un_openf = OPENING;
                     96:        stcmd(dev, SC_TEST_UNIT_READY, 0);
                     97:        if (stcmd(dev, SC_REQUEST_SENSE, 0) == 0 || dsi->un_openf != OPEN) {
                     98:                dsi->un_openf = OPENING;
                     99:                if (stcmd(dev, SC_REQUEST_SENSE, 0) == 0 ||
                    100:                    dsi->un_openf != OPEN) {
                    101:                        if (stcmd(dev, SC_REQUEST_SENSE, 0) == 0 ||
                    102:                            dsi->un_openf != OPEN) {
                    103:                                if (dsi->un_openf == OPEN_FAILED) {
                    104:                                        uprintf("st%d: no cartridge loaded\n",
                    105:                                            unit);
                    106:                                } else {
                    107:                                        uprintf("st%d: tape not online \n", 
                    108:                                            unit);
                    109:                                }
                    110:                                dsi->un_openf = CLOSED;
                    111:                                dsi->un_ctype = ST_TYPE_INVALID;
                    112:                                return (0);
                    113:                        }
                    114:                }
                    115:        }
                    116:        dsi->un_openf = CLOSED;
                    117:        return (1);
                    118: }
                    119: 
                    120: sctopen(dev, flag)
                    121:        dev_t dev;
                    122:        int flag;
                    123: {
                    124:        register struct scsi_unit *un;
                    125:        register int unit, s;
                    126:        register struct scsi_tape *dsi;
                    127:        register int i;
                    128: 
                    129:        unit = STUNIT(dev);
                    130:        if (unit > nstape) {
                    131:                u.u_error = ENXIO;
                    132:                return;
                    133:        }
                    134:        un = &stunits[unit];
                    135:        dsi = &stape[unit];
                    136:        if (un->un_mc == 0) {   /* never attached */
                    137:                u.u_error = ENXIO;
                    138:                return;
                    139:        }
                    140: 
                    141:        /* determine type of tape controller */
                    142:        if (dsi->un_ctype == ST_TYPE_INVALID) {
                    143:                if (stinit(dev) == 0) {
                    144:                        u.u_error = EIO;
                    145:                        return;
                    146:                }
                    147:        }
                    148: 
                    149:        s = spl6();
                    150:        if (dsi->un_openf != CLOSED) {  /* already open */
                    151:                (void) splx(s);
                    152:                u.u_error = EBUSY;
                    153:                return;
                    154:        }
                    155:        dsi->un_openf = OPEN;
                    156:        (void) splx(s);
                    157:        dsi->un_read_only = 0;
                    158: 
                    159:        /* must be qic 24 format */
                    160:        if (!(minor(dev) & QIC_24)) {
                    161:                dsi->un_openf = CLOSED;
                    162:                u.u_error = EIO;
                    163:                return;
                    164:        }
                    165:        if ((flag & FWRITE) && dsi->un_read_only) {
                    166:                uprintf("st%d: cartridge is write protected \n", unit);
                    167:                dsi->un_openf = CLOSED;
                    168:                u.u_error = EIO;
                    169:                return;
                    170:        }
                    171:        dsi->un_lastiow = 0;
                    172:        dsi->un_lastior = 0;
                    173:        dsi->un_next_block = 0;
                    174:        dsi->un_last_block = INF;
                    175:        /* if we reset these here they will never be preserved for "mt status"
                    176:        dsi->un_retry_ct = 0;
                    177:        dsi->un_underruns = 0;
                    178:        */
                    179:        u.u_error = 0;
                    180:        return;
                    181: }
                    182: 
                    183: /*ARGSUSED*/
                    184: sctclose(dev, flag)
                    185:        register dev_t dev;
                    186:        int flag;
                    187: {
                    188:        register struct scsi_unit *un;
                    189:        register struct scsi_tape *dsi;
                    190: 
                    191:        un = &stunits[STUNIT(dev)];
                    192:        dsi = &stape[STUNIT(dev)];
                    193:        dsi->un_openf = CLOSING;
                    194:        if (dsi->un_lastiow) {
                    195:                if (stcmd(dev, SC_WRITE_FILE_MARK, 0) == 0) {
                    196:                        printf("st%d: stclose failed to write file mark\n",
                    197:                                un - stunits);
                    198:                }
                    199:        }
                    200:        if ((minor(dev) & T_NOREWIND) == 0) {
                    201:                (void) stcmd(dev, SC_REWIND, -1);
                    202:        } 
                    203:        dsi->un_openf = CLOSED;
                    204: }
                    205: 
                    206: stcmd(dev, cmd, count)
                    207:        dev_t dev;
                    208:        int cmd, count;
                    209: {
                    210:        register struct buf *bp;
                    211:        register int s, error;
                    212:        register struct scsi_unit *un;
                    213: 
                    214:        un = &stunits[STUNIT(dev)];
                    215:        bp = &un->un_sbuf;
                    216:        s = splx(pritospl(un->un_mc->mc_intpri));
                    217:        while (bp->b_flags & B_BUSY) {
                    218:                /*
                    219:                 * special test because B_BUSY never gets cleared in
                    220:                 * the non-waiting rewind case.
                    221:                 */
                    222:                if (bp->b_bcount == -1 && (bp->b_flags & B_DONE)) {
                    223:                        break;
                    224:                }
                    225:                bp->b_flags |= B_WANTED;
                    226:                sleep((caddr_t) bp, PRIBIO);
                    227:        }
                    228:        bp->b_flags = B_BUSY | B_READ;
                    229:        (void) splx(s);
                    230:        bp->b_dev = dev;
                    231:        bp->b_bcount = count;
                    232:        un->un_scmd = cmd;
                    233:        ststrategy(bp);
                    234:        /*
                    235:         * In case of rewind on close, don't wait.
                    236:         */
                    237:        if (cmd == SC_REWIND && count == -1) {
                    238:                return (1);
                    239:        }
                    240:        s = splx(pritospl(un->un_mc->mc_intpri));
                    241:        while ((bp->b_flags & B_DONE) == 0) {
                    242:                sleep((caddr_t) bp, PRIBIO);
                    243:        }
                    244:        (void) splx(s);
                    245:        error = geterror(bp);
                    246:        if (bp->b_flags & B_WANTED) {
                    247:                wakeup((caddr_t) bp);
                    248:        }
                    249:        bp->b_flags &= B_ERROR;         /* clears B_BUSY */
                    250:        return (error == 0);
                    251: }
                    252: 
                    253: ststrategy(bp)
                    254:        register struct buf *bp;
                    255: {
                    256:        register struct scsi_unit *un;
                    257:        register int unit, s;
                    258:        register struct buf *ap;
                    259:        register struct scsi_tape *dsi;
                    260: 
                    261:        unit = STUNIT(bp->b_dev);
                    262:        if (unit > nstape) {
                    263:                printf("st%d: ststrategy: invalid unit %x\n", unit, unit);
                    264:                bp->b_flags |= B_ERROR;
                    265:                iodone(bp);
                    266:                return;
                    267:        }
                    268:        un = &stunits[unit];
                    269:        dsi = &stape[unit];
                    270:        if (dsi->un_openf != OPEN && bp != &un->un_sbuf) {
                    271:                bp->b_flags |= B_ERROR;
                    272:                iodone(bp);
                    273:                return;
                    274:        }
                    275:        s = splx(pritospl(un->un_mc->mc_intpri));
                    276:        while (dsi->un_bufcnt >= MAXSTBUF) {
                    277:                sleep((caddr_t) &dsi->un_bufcnt, PRIBIO);
                    278:        }
                    279:        dsi->un_bufcnt++;
                    280: 
                    281:        /*
                    282:         * Put the block at the end of the queue.
                    283:         * Should probably have a pointer to the end of
                    284:         * the queue, but the queue can't get too long,
                    285:         * so the added code complexity probably isn't
                    286:         * worth it.
                    287:         */
                    288:        ap = &un->un_utab;
                    289:        while (ap->b_actf != NULL) {
                    290:                ap = ap->b_actf;
                    291:        }
                    292:        ap->b_actf = bp;
                    293:        bp->b_actf = NULL;
                    294:        if (un->un_utab.b_active == 0) {
                    295:                (*un->un_c->c_ss->scs_ustart)(un);
                    296:                bp = &un->un_mc->mc_tab;
                    297:                if (bp->b_actf && bp->b_active == 0) {
                    298:                        (*un->un_c->c_ss->scs_start)(un);
                    299:                }
                    300:        }
                    301:        (void) splx(s);
                    302: }
                    303: 
                    304: /*
                    305:  * Start the operation.
                    306:  */
                    307: /*ARGSUSED*/
                    308: ststart(bp, un)
                    309:        register struct buf *bp;
                    310:        register struct scsi_unit *un;
                    311: {
                    312:        register int bno;
                    313:        register struct scsi_tape *dsi;
                    314: 
                    315:        dsi = &stape[STUNIT(bp->b_dev)];
                    316:        /*
                    317:         * Default is that last command was NOT a read/write command;
                    318:         * if we issue a read/write command we will notice this in stintr().
                    319:         */
                    320:        dsi->un_lastiow = 0;
                    321:        dsi->un_lastior = 0;
                    322:        if (bp == &un->un_sbuf) {
                    323:                un->un_cmd = un->un_scmd;
                    324:                un->un_count = bp->b_bcount;
                    325:        } else if (bp == &un->un_rbuf) {
                    326:                if (bp->b_flags & B_READ) {
                    327:                        if (dsi->un_eof) {
                    328:                                bp->b_resid = bp->b_bcount;
                    329:                                iodone(bp);
                    330:                                if (dsi->un_bufcnt-- >= MAXSTBUF) {
                    331:                                        wakeup((caddr_t) &dsi->un_bufcnt);
                    332:                                }
                    333:                                return (0);
                    334:                        }
                    335:                        un->un_cmd = SC_READ;
                    336:                } else {
                    337:                        un->un_cmd = SC_WRITE;
                    338:                }
                    339:                un->un_count = howmany(bp->b_bcount, DEV_BSIZE);
                    340:                un->un_flags |= SC_UNF_DVMA;
                    341:        } else {
                    342:                bno = bp->b_blkno;
                    343:                if (bno > dsi->un_last_block && bp->b_flags & B_READ) {
                    344:                        /* 
                    345:                         * Can't read past EOF.
                    346:                         */
                    347:                        bp->b_flags |= B_ERROR;
                    348:                        bp->b_error = EIO;
                    349:                        iodone(bp);
                    350:                        if (dsi->un_bufcnt-- >= MAXSTBUF) {
                    351:                                wakeup((caddr_t) &dsi->un_bufcnt);
                    352:                        }
                    353:                        return (0);
                    354:                }
                    355:                if (bno == dsi->un_last_block && bp->b_flags & B_READ) {
                    356:                        /*
                    357:                         * Reading at EOF returns 0 bytes.
                    358:                         */
                    359:                        bp->b_resid = bp->b_bcount;
                    360:                        iodone(bp);
                    361:                        if (dsi->un_bufcnt-- >= MAXSTBUF) {
                    362:                                wakeup((caddr_t) &dsi->un_bufcnt);
                    363:                        }
                    364:                        return (0);
                    365:                }
                    366:                if ((bp->b_flags & B_READ) == 0) {
                    367:                        /*
                    368:                         * Writing sets EOF.
                    369:                         */
                    370:                        dsi->un_last_block = bno + 1;
                    371:                }
                    372:                if (bno != dsi->un_next_block) {
                    373:                        /*
                    374:                         * Not the next record.
                    375:                         * In theory we could space forward, or even rewind
                    376:                         * and space forward, and maybe someday we will.
                    377:                         * For now, no one really needs this capability.
                    378:                         */
                    379:                        bp->b_flags |= B_ERROR;
                    380:                        bp->b_error = ENXIO;
                    381:                        iodone(bp);
                    382:                        if (dsi->un_bufcnt-- >= MAXSTBUF) {
                    383:                                wakeup((caddr_t) &dsi->un_bufcnt);
                    384:                        }
                    385:                        return (0);
                    386:                }
                    387:                /*
                    388:                 * Position OK, we can do the read or write.
                    389:                 */
                    390:                if (bp->b_flags & B_READ) {
                    391:                        un->un_cmd = SC_READ;
                    392:                } else {
                    393:                        un->un_cmd = SC_WRITE;
                    394:                }
                    395:                un->un_count = howmany(bp->b_bcount, DEV_BSIZE);
                    396:                un->un_flags |= SC_UNF_DVMA;
                    397:        }
                    398:        bp->b_resid = 0;
                    399:        return (1);
                    400: }
                    401: 
                    402: /*
                    403:  * Make a command description block.
                    404:  */
                    405: stmkcdb(c, un)
                    406:        register struct scsi_ctlr *c;
                    407:        register struct scsi_unit *un;
                    408: {
                    409:        register struct scsi_cdb *cdb;
                    410:        register struct scsi_tape *dsi;
                    411:        int density = 0;
                    412: 
                    413:        cdb = &c->c_cdb;
                    414:        bzero((caddr_t)cdb, sizeof (*cdb));
                    415:        cdb->cmd = un->un_cmd;
                    416:        cdb->lun = un->un_lun;
                    417:        un->un_dma_addr = un->un_dma_count = 0;
                    418:        dsi = &stape[un->un_unit];
                    419: 
                    420:        switch (un->un_cmd) {
                    421: 
                    422:        case SC_WRITE_FILE_MARK:
                    423:        case SC_LOAD:
                    424:                cdb->count = 1;
                    425:                break;
                    426: 
                    427:        case SC_TEST_UNIT_READY:
                    428:                break;
                    429:                
                    430:        case SC_REWIND:
                    431:                break;
                    432: 
                    433:        case SC_ERASE_CARTRIDGE:
                    434:                cdb->t_code = 1;
                    435:                break;
                    436: 
                    437:        case SC_REQUEST_SENSE:
                    438:                un->un_dma_addr = (int)c->c_sense - (int)DVMA;
                    439:                un->un_dma_count = cdb->count = sizeof (struct st_archive_sense);               
                    440:                break;
                    441: 
                    442:        case SC_READ:
                    443:        case SC_WRITE:
                    444:                cdb->t_code = 1;
                    445:                cdb->high_count = un->un_count >> 16;
                    446:                cdb->mid_count = (un->un_count >> 8) & 0xFF;
                    447:                cdb->low_count = un->un_count & 0xFF;
                    448:                un->un_dma_addr = un->un_baddr;
                    449:                un->un_dma_count = un->un_count * DEV_BSIZE;
                    450:                break;
                    451: 
                    452:        case SC_SPACE_FILE:
                    453:                if (un->un_count == 0)
                    454:                        cdb->t_code = 3;        /* space to end */
                    455:                else
                    456:                        cdb->t_code = 1;        /* space files, not records */
                    457:                /* fall through ... */
                    458: 
                    459:        case SC_SPACE_REC:
                    460:                cdb->cmd = SC_SPACE;
                    461:                cdb->high_count = un->un_count >> 16;
                    462:                cdb->mid_count = (un->un_count >> 8) & 0xFF;
                    463:                cdb->low_count = un->un_count & 0xFF;
                    464:                un->un_dma_addr = un->un_dma_count = 0;
                    465:                break;
                    466: 
                    467:        default:
                    468:                printf("st%d: stmkcdb: invalid command %x\n", un - stunits,
                    469:                        un->un_cmd);
                    470:                break;  
                    471:        }
                    472: }
                    473: 
                    474: stintr(c, resid, error)
                    475:        register struct scsi_ctlr *c;
                    476:        register int resid, error;
                    477: {
                    478:        register struct scsi_unit *un;
                    479:        register struct buf *bp;
                    480:        register struct scsi_tape *dsi;
                    481:        struct st_archive_sense *ars;
                    482: 
                    483:        un = c->c_un;
                    484:        bp = un->un_mc->mc_tab.b_actf->b_actf;
                    485:        dsi = &stape[STUNIT(bp->b_dev)];
                    486:        ars = (struct st_archive_sense *)c->c_sense;
                    487: 
                    488:        /* 
                    489:         * We determine which tape controller we have by the number of
                    490:         * sense bytes we get back.
                    491:         */
                    492:        if (dsi->un_openf == OPENING && un->un_cmd == SC_REQUEST_SENSE) {
                    493:                if (resid || ST_NO_CART(dsi, c->c_sense)) {
                    494:                        dsi->un_openf = OPEN_FAILED;
                    495:                } else {
                    496:                        dsi->un_openf = OPEN;
                    497:                        if (ST_WRITE_PROT(dsi, c->c_sense))
                    498:                                dsi->un_read_only = 1;
                    499:                }
                    500:        }
                    501: 
                    502:        if (c->c_scb.busy)
                    503:                bp->b_flags |= B_ERROR;
                    504:        else if (error || c->c_scb.chk || resid > 0) {
                    505:                if (c->c_scb.chk && ST_RESET(dsi, c->c_sense)) {
                    506:                        /*
                    507:                         * Power on or reset occurred
                    508:                         */
                    509:                        dsi->un_reset_occurred = 1;
                    510:                        bp->b_flags |= B_ERROR;
                    511:                } else if (c->c_scb.chk && ST_NO_CART(dsi, c->c_sense)) {
                    512:                        printf("st%d: no cartridge loaded \n", 
                    513:                            un - stunits);
                    514:                        bp->b_flags |= B_ERROR;
                    515:                } else if (c->c_scb.chk && ST_FILE_MARK(dsi, c->c_sense)) {
                    516:                        /*
                    517:                         * File mark detected.
                    518:                         */
                    519:                        dsi->un_eof = 1;
                    520:                        switch (un->un_cmd) {
                    521:                        case SC_READ:
                    522:                                dsi->un_next_block += un->un_count -
                    523:                                        resid / DEV_BSIZE;
                    524:                                dsi->un_last_block = dsi->un_next_block;
                    525:                                break;
                    526:                        case SC_SPACE_REC:
                    527:                                dsi->un_last_block = dsi->un_next_block +=
                    528:                                        un->un_count;   /* a little high */
                    529:                                break;
                    530:                        default:
                    531:                                printf("st%d: scsi tape hit eof on cmd %x\n",
                    532:                                        un - stunits, un->un_cmd);
                    533:                                break;
                    534:                        }
                    535:                        bp->b_resid = resid;
                    536:                } else if ((un->un_cmd == SC_WRITE || 
                    537:                    un->un_cmd == SC_WRITE_FILE_MARK) &&
                    538:                    c->c_scb.chk && ST_WRITE_PROT(dsi, c->c_sense)) {
                    539:                        /*
                    540:                         * Write protected tape.
                    541:                         */
                    542:                        printf("st%d: tape is write protected \n, ",
                    543:                                un - stunits);
                    544:                        dsi->un_read_only = 1;
                    545:                        bp->b_flags |= B_ERROR;
                    546:                } else if (c->c_scb.chk && ST_EOT(dsi, c->c_sense)) {
                    547:                        /*
                    548:                         * End of tape.
                    549:                         */
                    550:                        bp->b_resid = bp->b_bcount;
                    551:                        if (un->un_cmd == SC_WRITE) {
                    552:                                /*
                    553:                                 * Setting this flag makes stclose()
                    554:                                 * write a file mark before closing.
                    555:                                 * Until a file mark is written, the 
                    556:                                 * tape will return invalid command
                    557:                                 * indications and not respond to 
                    558:                                 * rewinds.
                    559:                                 */
                    560:                                dsi->un_lastiow = 1;
                    561:                        }
                    562:                } else if (c->c_scb.chk && ST_ILLEGAL(dsi, c->c_sense)) {
                    563:                        printf("st%d: illegal command 0x%x\n", un-stunits, un->un_cmd);
                    564:                        bp->b_flags |= B_ERROR;
                    565:                } else if (ST_CORRECTABLE(dsi, c->c_sense))
                    566:                        goto success;
                    567:                else if (ST_EOD(dsi, c->c_sense))
                    568:                        bp->b_flags |= B_ERROR;
                    569:                else {
                    570:                        /*
                    571:                         * Some other error which we can't handle.
                    572:                         */
                    573:                        if ((c->c_scb.chk && dsi->un_openf == OPEN))
                    574:                                st_pr_sense(c, dsi);
                    575:                        bp->b_flags |= B_ERROR;
                    576:                }
                    577:        } else {
                    578: success:
                    579:                switch (un->un_cmd) {
                    580: 
                    581:                case SC_REWIND:
                    582:                case SC_ERASE_CARTRIDGE:
                    583:                case SC_MODE_SELECT:
                    584:                case SC_LOAD:
                    585:                        dsi->un_next_block = 0;
                    586:                        dsi->un_eof = 0;
                    587:                        break;
                    588: 
                    589:                case SC_WRITE:
                    590:                        dsi->un_lastiow = 1;
                    591:                        dsi->un_next_block += un->un_count;
                    592:                        break;
                    593: 
                    594:                case SC_READ:
                    595:                        dsi->un_lastior = 1;
                    596:                        dsi->un_next_block += un->un_count;
                    597:                        break;
                    598: 
                    599:                case SC_SPACE_FILE:
                    600:                        dsi->un_next_block = 0;
                    601:                        dsi->un_last_block = INF;
                    602:                        dsi->un_eof = 0;
                    603:                        break;
                    604: 
                    605:                case SC_SPACE_REC:
                    606:                        dsi->un_next_block += un->un_count;
                    607:                        break;
                    608: 
                    609:                case SC_REQUEST_SENSE:
                    610:                        dsi->un_status = ((char *)ars)[2];
                    611: /*
                    612:                        if (ars->ext_sense.add_len >= AR_ES_ADD_LEN) {
                    613:                                dsi->un_retry_ct += 
                    614:                                    (ars->retries_msb << 8) +
                    615:                                    ars->retries_lsb;
                    616:                        }
                    617: */
                    618:                        break;
                    619: 
                    620:                case SC_TEST_UNIT_READY:
                    621:                        break;
                    622: 
                    623:                case SC_WRITE_FILE_MARK:
                    624:                        dsi->un_next_block = 0;
                    625:                        dsi->un_last_block = 0; /* i.e. no reads allowed */
                    626:                        break;
                    627: 
                    628:                default:
                    629:                        printf("st%d: stintr: invalid command %x\n",
                    630:                            un - stunits, un->un_cmd);
                    631:                        break;
                    632:                }
                    633:        }
                    634:        if (bp == &un->un_sbuf && 
                    635:            ((un->un_flags & SC_UNF_DVMA) == 0)) {
                    636:                (*c->c_ss->scs_done)(un->un_mc);
                    637:        } else {
                    638:                mbdone(un->un_mc);
                    639:                un->un_flags &= ~SC_UNF_DVMA;
                    640:        }
                    641:        if (dsi->un_bufcnt-- >= MAXSTBUF) {
                    642:                wakeup((caddr_t) &dsi->un_bufcnt);
                    643:        }
                    644: }
                    645: 
                    646: st_pr_sense(c, dsi)
                    647:        register struct scsi_ctlr *c;
                    648:        register struct scsi_tape *dsi;
                    649: {
                    650:        register struct scsi_unit *un;
                    651:        register u_char *cp;
                    652:        register int i;
                    653: 
                    654:        un = c->c_un;
                    655:        cp = (u_char *)c->c_sense;
                    656:        printf("st%d: stintr: sense ", un - stunits);
                    657:        for (i=0; i < sizeof (struct st_archive_sense); i++)
                    658:                printf("%x ", *cp++);
                    659:        printf("\n");
                    660: }
                    661: 
                    662: sctread(dev)
                    663:        register dev_t dev;
                    664: {
                    665:        register struct scsi_unit *un;
                    666:        register int unit, r, resid;
                    667:        register struct scsi_tape *dsi;
                    668: 
                    669:        unit = STUNIT(dev);
                    670:        if (unit > nstape) {
                    671:                u.u_error = ENXIO;
                    672:                return;
                    673:        }
                    674:        un = &stunits[unit];
                    675:        dsi = &stape[unit];
                    676:        if (u.u_count % DEV_BSIZE) {
                    677:                u.u_error = ENXIO;
                    678:                return; /* drive can't do it */
                    679:        }
                    680:        resid = u.u_count;
                    681:        dsi->un_next_block = u.u_offset / DEV_BSIZE;
                    682:        dsi->un_last_block = INF;
                    683:        physio(ststrategy, &un->un_rbuf, dev, B_READ, minphys);
                    684:        if (dsi->un_eof && u.u_count == resid) {
                    685:                dsi->un_eof = 0;        /* the user is really getting it */
                    686:        }
                    687: }
                    688: 
                    689: sctwrite(dev)
                    690:        register dev_t dev;
                    691: {
                    692:        register struct scsi_unit *un;
                    693:        register int unit;
                    694:        register struct scsi_tape *dsi;
                    695: 
                    696:        unit = STUNIT(dev);
                    697:        if (unit > nstape) {
                    698:                u.u_error = ENXIO;
                    699:                return;
                    700:        }
                    701:        un = &stunits[unit];
                    702:        dsi = &stape[unit];
                    703:        dsi->un_next_block = u.u_offset / DEV_BSIZE;
                    704:        dsi->un_last_block = INF;
                    705:        physio(ststrategy, &un->un_rbuf, dev, B_WRITE, minphys);
                    706: }
                    707: 
                    708: /*ARGSUSED*/
                    709: sctioctl(dev, cmd, data, flag)
                    710:        register dev_t dev;
                    711:        register int cmd;
                    712:        register caddr_t data;
                    713:        int flag;
                    714: {
                    715:        register int fcount;
                    716:        struct mtop mtop;
                    717:        struct mtget mtget;
                    718:        register int unit;
                    719:        register struct scsi_tape *dsi;
                    720:        static int ops[] = {
                    721:                SC_WRITE_FILE_MARK,     /* write tape mark */
                    722:                SC_SPACE_FILE,          /* forward space file */
                    723:                SC_SPACE_FILE,          /* backspace file */
                    724:                SC_SPACE_REC,           /* forward space record */
                    725:                SC_SPACE_REC,           /* backspace record */
                    726:                SC_REWIND,              /* rewind tape */
                    727:                SC_REWIND,              /* unload - we just rewind */
                    728:                SC_REQUEST_SENSE,       /* get status */
                    729:                SC_REWIND,              /* retension - rewind + vu_57 */
                    730:                SC_ERASE_CARTRIDGE,     /* erase entire tape */
                    731:        };
                    732: 
                    733:        unit = STUNIT(dev);
                    734:        if (unit > nstape) {
                    735:                u.u_error = ENXIO;
                    736:                return;
                    737:        }
                    738:        dsi = &stape[unit];
                    739:        switch (cmd) {
                    740:        case MTIOCTOP:  /* tape operation */
                    741:                if (copyin((caddr_t)data, (caddr_t)&mtop, sizeof(mtop))) {
                    742:                        u.u_error = EFAULT;
                    743:                        return;
                    744:                }
                    745:                switch (mtop.mt_op) {
                    746:                case MTWEOF:
                    747:                case MTERASE:
                    748:                        if (dsi->un_read_only) {
                    749:                                u.u_error = ENXIO;
                    750:                                return;
                    751:                        }
                    752:                }
                    753: 
                    754:                switch (mtop.mt_op) {
                    755:                case MTBSF:
                    756:                case MTBSR:
                    757:                        fcount = -mtop.mt_count;
                    758:                        break;
                    759:                case MTRETEN:
                    760:                        dsi->un_reten_rewind = 1;
                    761:                        /* FALL THRU */
                    762:                case MTFSF:
                    763:                        fcount = mtop.mt_count;
                    764:                        if (fcount == -1)
                    765:                                fcount = 0;
                    766:                case MTWEOF:
                    767:                case MTREW:
                    768:                case MTOFFL:
                    769:                case MTNOP:
                    770:                case MTERASE:
                    771:                        fcount = mtop.mt_count;
                    772:                        break;
                    773:                default:
                    774:                        u.u_error = ENXIO;
                    775:                        return;
                    776:                }
                    777:                /*
                    778:                 * If eof_flag then we hit eof but didn't tell the user yet.
                    779:                 */
                    780:                if (ops[mtop.mt_op] == SC_SPACE_FILE && dsi->un_eof) {
                    781:                        dsi->un_eof = 0;
                    782:                        if (mtop.mt_op == MTFSF)
                    783:                                fcount--;
                    784:                }
                    785:                if (stcmd(dev, ops[mtop.mt_op], fcount) == 0)
                    786:                        u.u_error = EIO;
                    787:                return;
                    788: 
                    789:        case MTIOCGET:
                    790:                if (stcmd(dev, SC_REQUEST_SENSE, 0) == 0) {
                    791:                        u.u_error = EIO;
                    792:                        return;
                    793:                }
                    794:                mtget.mt_type = MT_ISSC;
                    795:                mtget.mt_erreg = dsi->un_status;
                    796:                mtget.mt_fileno = dsi->un_retry_ct;
                    797:                mtget.mt_blkno = dsi->un_underruns;
                    798:                dsi->un_retry_ct = dsi->un_underruns = 0;
                    799:                if (copyout((caddr_t)&mtget, data, sizeof(mtget)))
                    800:                        u.u_error = EFAULT;
                    801:                return;
                    802: 
                    803:        default:
                    804:                u.u_error = ENXIO;
                    805:                return;
                    806:        }
                    807: }
                    808: #endif NST > 0

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.