Annotation of Net2/scsi/st.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Written by Julian Elischer ([email protected])
                      3:  * for TRW Financial Systems for use under the MACH(2.5) operating system.
                      4:  *
                      5:  * TRW Financial Systems, in accordance with their agreement with Carnegie
                      6:  * Mellon University, makes this software available to CMU to distribute
                      7:  * or use in any manner that they see fit as long as this message is kept with
                      8:  * the software. For this reason TFS also grants any other persons or
                      9:  * organisations permission to use or modify this software.
                     10:  *
                     11:  * TFS supplies this software to be publicly redistributed
                     12:  * on the understanding that TFS is not responsible for the correct
                     13:  * functioning of this software in any circumstances.
                     14:  *
                     15:  *
                     16:  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
                     17:  * --------------------         -----   ----------------------
                     18:  * CURRENT PATCH LEVEL:         1       00098
                     19:  * --------------------         -----   ----------------------
                     20:  *
                     21:  * 16 Feb 93   Julian Elischer         ADDED for SCSI system
                     22:  */
                     23: 
                     24: /*
                     25:  * Ported to run under 386BSD by Julian Elischer ([email protected]) Sept 1992
                     26:  */
                     27: 
                     28: 
                     29: /*
                     30:  * To do:
                     31:  * work out some better way of guessing what a good timeout is going
                     32:  * to be depending on whether we expect to retension or not.
                     33:  *
                     34:  */
                     35: 
                     36: #include       <sys/types.h>
                     37: #include       <st.h>
                     38: 
                     39: #include <sys/param.h>
                     40: #include <sys/systm.h>
                     41: 
                     42: #include <sys/errno.h>
                     43: #include <sys/ioctl.h>
                     44: #include <sys/buf.h>
                     45: #include <sys/proc.h>
                     46: #include <sys/user.h>
                     47: #include <sys/mtio.h>
                     48: 
                     49: #if defined(OSF)
                     50: #define SECSIZE        512
                     51: #endif /* defined(OSF) */
                     52: 
                     53: #include <scsi/scsi_all.h>
                     54: #include <scsi/scsi_tape.h>
                     55: #include <scsi/scsiconf.h>
                     56: 
                     57: 
                     58: long int ststrats,stqueues;
                     59: 
                     60: 
                     61: #define PAGESIZ        4096
                     62: #define STQSIZE                4
                     63: #define        ST_RETRIES      4
                     64: 
                     65: 
                     66: #define MODE(z)                (  (minor(z)       & 0x03) )
                     67: #define DSTY(z)         ( ((minor(z) >> 2) & 0x03) )
                     68: #define UNIT(z)                (  (minor(z) >> 4) )
                     69: 
                     70: #define DSTY_QIC120  3
                     71: #define DSTY_QIC150  2
                     72: #define DSTY_QIC525  1
                     73: 
                     74: #define QIC120     0x0f
                     75: #define QIC150     0x10
                     76: #define QIC525     0x11
                     77: 
                     78: 
                     79: 
                     80: 
                     81: #ifndef        __386BSD__
                     82: struct buf stbuf[NST][STQSIZE];        /* buffer for raw io (one per device) */
                     83: struct buf *stbuf_free[NST];   /* queue of free buffers for raw io */
                     84: #endif __386BSD__
                     85: struct buf st_buf_queue[NST];
                     86: int    ststrategy();
                     87: void   stminphys();
                     88: struct scsi_xfer st_scsi_xfer[NST];
                     89: int    st_xfer_block_wait[NST];
                     90: 
                     91: #if defined(OSF)
                     92: caddr_t                st_window[NST];
                     93: #endif /* defined(OSF) */
                     94: #ifndef        MACH
                     95: #define ESUCCESS 0
                     96: #endif MACH
                     97: 
                     98: int    st_info_valid[NST];     /* the info about the device is valid */
                     99: int    st_initialized[NST] ;
                    100: int    st_debug = 0;
                    101: 
                    102: int stattach();
                    103: int st_done();
                    104: struct st_data
                    105: {
                    106:        int     flags;
                    107:        struct  scsi_switch *sc_sw;     /* address of scsi low level switch */
                    108:        int     ctlr;                   /* so they know which one we want */
                    109:        int     targ;                   /* our scsi target ID */
                    110:        int     lu;                     /* out scsi lu */
                    111:        int     blkmin;                 /* min blk size */
                    112:        int     blkmax;                 /* max blk size */
                    113:        int     numblks;                /* nominal blocks capacity */
                    114:        int     blksiz;                 /* nominal block size */
                    115: }st_data[NST];
                    116: #define ST_OPEN                0x01
                    117: #define        ST_NOREWIND     0x02
                    118: #define        ST_WRITTEN      0x04
                    119: #define        ST_FIXEDBLOCKS  0x10
                    120: #define        ST_AT_FILEMARK  0x20
                    121: #define        ST_AT_EOM       0x40
                    122: 
                    123: #define        ST_PER_ACTION   (ST_AT_FILEMARK | ST_AT_EOM)
                    124: #define        ST_PER_OPEN     (ST_OPEN | ST_NOREWIND | ST_WRITTEN | ST_PER_ACTION)
                    125: #define        ST_PER_MEDIA    ST_FIXEDBLOCKS
                    126: 
                    127: static int     next_st_unit = 0;
                    128: /***********************************************************************\
                    129: * The routine called by the low level scsi routine when it discovers   *
                    130: * A device suitable for this driver                                    *
                    131: \***********************************************************************/
                    132: 
                    133: int    stattach(ctlr,targ,lu,scsi_switch)
                    134: struct scsi_switch *scsi_switch;
                    135: {
                    136:        int     unit,i;
                    137:        unsigned char *tbl;
                    138:        struct st_data *st;
                    139: 
                    140:        if(scsi_debug & PRINTROUTINES) printf("stattach: ");
                    141:        /*******************************************************\
                    142:        * Check we have the resources for another drive         *
                    143:        \*******************************************************/
                    144:        unit = next_st_unit++;
                    145:        if( unit >= NST)
                    146:        {
                    147:                printf("Too many scsi tapes..(%d > %d) reconfigure kernel",(unit + 1),NST);
                    148:                return(0);
                    149:        }
                    150:        st = st_data + unit;
                    151:        /*******************************************************\
                    152:        * Store information needed to contact our base driver   *
                    153:        \*******************************************************/
                    154:        st->sc_sw       =       scsi_switch;
                    155:        st->ctlr        =       ctlr;
                    156:        st->targ        =       targ;
                    157:        st->lu  =       lu;
                    158: 
                    159:        /*******************************************************\
                    160:        * Use the subdriver to request information regarding    *
                    161:        * the drive. We cannot use interrupts yet, so the       *
                    162:        * request must specify this.                            *
                    163:        \*******************************************************/
                    164:        if((st_mode_sense(unit,  SCSI_NOSLEEP |  SCSI_NOMASK | SCSI_SILENT)))
                    165:        {
                    166:                printf("        st%d: scsi tape drive, %d blocks of %d bytes\n",
                    167:                        unit, st->numblks, st->blksiz);
                    168:        }
                    169:        else
                    170:        {
                    171:                printf("        st%d: scsi tape drive :- offline\n", unit);
                    172:        }
                    173:        /*******************************************************\
                    174:        * Set up the bufs for this device                       *
                    175:        \*******************************************************/
                    176: #ifndef        __386BSD__
                    177:        stbuf_free[unit] = (struct buf *)0;
                    178:        for (i = 1; i < STQSIZE; i++)
                    179:        {
                    180:                stbuf[unit][i].b_forw = stbuf_free[unit];
                    181:                stbuf_free[unit]=&stbuf[unit][i];
                    182:        }
                    183: #endif __386BSD__
                    184:        st_buf_queue[unit].b_active     =       0;
                    185:        st_buf_queue[unit].b_actf       =       st_buf_queue[unit].b_actl = 0;
                    186:        st_initialized[unit] = 1;
                    187: 
                    188: #if defined(OSF)
                    189:        st_window[unit] = (caddr_t)alloc_kva(SECSIZE*256+PAGESIZ);
                    190: #endif /* defined(OSF) */
                    191: 
                    192:        return;
                    193: 
                    194: }
                    195: 
                    196: 
                    197: 
                    198: /*******************************************************\
                    199: *      open the device.                                *
                    200: \*******************************************************/
                    201: stopen(dev)
                    202: {
                    203:        int errcode = 0;
                    204:        int unit,mode,dsty;
                    205:         int dsty_code;
                    206:        struct st_data *st;
                    207:        unit = UNIT(dev);
                    208:        mode = MODE(dev);
                    209:        dsty = DSTY(dev);
                    210:        st = st_data + unit;
                    211: 
                    212:        /*******************************************************\
                    213:        * Check the unit is legal                               *
                    214:        \*******************************************************/
                    215:        if ( unit >= NST )
                    216:        {
                    217:                errcode = ENXIO;
                    218:                return(errcode);
                    219:        }
                    220:        /*******************************************************\
                    221:        * Only allow one at a time                              *
                    222:        \*******************************************************/
                    223:        if(st->flags & ST_OPEN)
                    224:        {
                    225:                errcode = EBUSY;
                    226:                goto bad;
                    227:        }
                    228:        /*******************************************************\
                    229:        * Set up the mode flags according to the minor number   *
                    230:        * ensure all open flags are in a known state            *
                    231:        \*******************************************************/
                    232:        st->flags &= ~ST_PER_OPEN;
                    233:        switch(mode)
                    234:        {
                    235:        case    2:
                    236:        case    0:
                    237:                st->flags &= ~ST_NOREWIND;
                    238:                break;
                    239:        case    3:
                    240:        case    1:
                    241:                st->flags |= ST_NOREWIND;
                    242:                break;
                    243:        default:
                    244:                printf("st%d: Bad mode (minor number)%d\n",unit,mode);
                    245:                return(EINVAL);
                    246:        }
                    247:         /*******************************************************\
                    248:         * Check density code: 0 is drive default               *
                    249:         \*******************************************************/
                    250:         switch(dsty)
                    251:        {
                    252:        case    0:              dsty_code = 0;          break;
                    253:        case    DSTY_QIC120:    dsty_code = QIC120;     break;
                    254:        case    DSTY_QIC150:    dsty_code = QIC150;     break;
                    255:        case    DSTY_QIC525:    dsty_code = QIC525;     break;
                    256:        default:
                    257:                printf("st%d: Bad density (minor number)%d\n",unit,dsty);
                    258:                return(EINVAL);
                    259:        }
                    260:        if(scsi_debug & (PRINTROUTINES | TRACEOPENS))
                    261:                printf("stopen: dev=0x%x (unit %d (of %d))\n"
                    262:                                ,   dev,      unit,   NST);
                    263:        /*******************************************************\
                    264:        * Make sure the device has been initialised             *
                    265:        \*******************************************************/
                    266: 
                    267:        if (!st_initialized[unit])
                    268:                return(ENXIO);
                    269:        /*******************************************************\
                    270:        * Check that it is still responding and ok.             *
                    271:        \*******************************************************/
                    272: 
                    273:        if(scsi_debug & TRACEOPENS)
                    274:                printf("device is ");
                    275:        if (!(st_req_sense(unit, 0)))
                    276:        {
                    277:                errcode = ENXIO;
                    278:                if(scsi_debug & TRACEOPENS)
                    279:                        printf("not responding\n");
                    280:                goto bad;
                    281:        }
                    282:        if(scsi_debug & TRACEOPENS)
                    283:                printf("ok\n");
                    284: 
                    285:        if(!(st_test_ready(unit,0)))
                    286:        {
                    287:                printf("st%d not ready\n",unit);
                    288:                return(EIO);
                    289:        }
                    290: 
                    291:        if(!st_info_valid[unit])                /* is media new? */
                    292:                if(!st_load(unit,LD_LOAD,0))
                    293:                {
                    294:                        return(EIO);
                    295:                }
                    296: 
                    297:        if(!st_rd_blk_lim(unit,0))
                    298:        {
                    299:                return(EIO);
                    300:        }
                    301: 
                    302:        if(!st_mode_sense(unit,0))
                    303:        {
                    304:                return(EIO);
                    305:        }
                    306: 
                    307:        if(!st_mode_select(unit,0,dsty_code))
                    308:        {
                    309:                return(EIO);
                    310:        }
                    311: 
                    312:        st_info_valid[unit] = TRUE;
                    313: 
                    314:        st_prevent(unit,PR_PREVENT,0); /* who cares if it fails? */
                    315: 
                    316:        /*******************************************************\
                    317:        * Load the physical device parameters                   *
                    318:        \*******************************************************/
                    319:        if(scsi_debug & TRACEOPENS)
                    320:                printf("Params loaded ");
                    321: 
                    322: 
                    323:        st->flags |= ST_OPEN;
                    324: 
                    325: bad:
                    326:        return(errcode);
                    327: }
                    328: 
                    329: /*******************************************************\
                    330: * close the device.. only called if we are the LAST    *
                    331: * occurence of an open device                          *
                    332: \*******************************************************/
                    333: stclose(dev)
                    334: {
                    335:        unsigned char unit,mode;
                    336:        struct  st_data *st;
                    337: 
                    338:        unit = UNIT(dev);
                    339:        mode = MODE(dev);
                    340:        st = st_data + unit;
                    341: 
                    342:        if(scsi_debug & TRACEOPENS)
                    343:                printf("Closing device");
                    344:        if(st->flags & ST_WRITTEN)
                    345:        {
                    346:                st_write_filemarks(unit,1,0);
                    347:        }
                    348:        st->flags &= ~ST_WRITTEN;
                    349:        switch(mode)
                    350:        {
                    351:        case    0:
                    352:                st_rewind(unit,FALSE,SCSI_SILENT);
                    353:                st_prevent(unit,PR_ALLOW,SCSI_SILENT);
                    354:                break;
                    355:        case    1:
                    356:                st_prevent(unit,PR_ALLOW,SCSI_SILENT);
                    357:                break;
                    358:        case    2:
                    359:                st_rewind(unit,FALSE,SCSI_SILENT);
                    360:                st_prevent(unit,PR_ALLOW,SCSI_SILENT);
                    361:                st_load(unit,LD_UNLOAD,SCSI_SILENT);
                    362:                break;
                    363:        case    3:
                    364:                st_prevent(unit,PR_ALLOW,SCSI_SILENT);
                    365:                st_load(unit,LD_UNLOAD,SCSI_SILENT);
                    366:                break;
                    367:        default:
                    368:                printf("st%d:close: Bad mode (minor number)%d how's it open?\n"
                    369:                                ,unit,mode);
                    370:                return(EINVAL);
                    371:        }
                    372:        st->flags &= ~ST_PER_OPEN;
                    373:        return(0);
                    374: }
                    375: 
                    376: #ifndef        __386BSD__
                    377: /*******************************************************\
                    378: * Get ownership of this unit's buf                     *
                    379: * If need be, sleep on it, until it comes free         *
                    380: \*******************************************************/
                    381: struct buf *
                    382: st_get_buf(unit) {
                    383:        struct buf *rc;
                    384: 
                    385:        while (!(rc = stbuf_free[unit]))
                    386:                sleep((caddr_t)&stbuf_free[unit], PRIBIO+1);
                    387:        stbuf_free[unit] = stbuf_free[unit]->b_forw;
                    388:        rc->b_error = 0;
                    389:        rc->b_resid = 0;
                    390:        rc->b_flags = 0;
                    391:        return(rc);
                    392: }
                    393: 
                    394: /*******************************************************\
                    395: * Free this unit's buf, wake processes waiting for it  *
                    396: \*******************************************************/
                    397: st_free_buf(unit,bp)
                    398: struct buf *bp;
                    399: {
                    400:        if (!stbuf_free[unit])
                    401:                wakeup((caddr_t)&stbuf_free[unit]);
                    402:        bp->b_forw = stbuf_free[unit];
                    403:        stbuf_free[unit] = bp;
                    404: }
                    405:        
                    406: 
                    407: /*******************************************************\
                    408: * Get the buf for this unit and use physio to do it    *
                    409: \*******************************************************/
                    410: stread(dev,uio)
                    411: register short  dev;
                    412: struct uio     *uio;
                    413: {
                    414:        int     unit = UNIT(dev);
                    415:        struct buf *bp = st_get_buf(unit);
                    416:        int rc;
                    417:        rc = physio(ststrategy, bp, dev, B_READ, stminphys, uio);
                    418:        st_free_buf(unit,bp);
                    419:        return(rc);
                    420: }
                    421: 
                    422: /*******************************************************\
                    423: * Get the buf for this unit and use physio to do it    *
                    424: \*******************************************************/
                    425: stwrite(dev,uio)
                    426: dev_t          dev;
                    427: struct uio     *uio;
                    428: {
                    429:        int     unit = UNIT(dev);
                    430:        struct buf *bp = st_get_buf(unit);
                    431:        int rc;
                    432: 
                    433:        rc = physio(ststrategy, bp, dev, B_WRITE, stminphys, uio);
                    434:        st_free_buf(unit,bp);
                    435:        return(rc);
                    436: }
                    437: 
                    438: 
                    439: #endif __386BSD__
                    440: /*******************************************************\
                    441: * trim the size of the transfer if needed,             *
                    442: * called by physio                                     *
                    443: * basically the smaller of our min and the scsi driver's*
                    444: * minphys                                              *
                    445: \*******************************************************/
                    446: void   stminphys(bp)
                    447: struct buf     *bp;
                    448: {
                    449:        (*(st_data[UNIT(bp->b_dev)].sc_sw->scsi_minphys))(bp);
                    450: }
                    451: 
                    452: /*******************************************************\
                    453: * Actually translate the requested transfer into       *
                    454: * one the physical driver can understand               *
                    455: * The transfer is described by a buf and will include  *
                    456: * only one physical transfer.                          *
                    457: \*******************************************************/
                    458: 
                    459: int    ststrategy(bp)
                    460: struct buf     *bp;
                    461: {
                    462:        struct  buf     *dp;
                    463:        unsigned char unit;
                    464:        unsigned int opri;
                    465: 
                    466:        ststrats++;
                    467:        unit = UNIT((bp->b_dev));
                    468:        if(scsi_debug & PRINTROUTINES) printf("\nststrategy ");
                    469:        if(scsi_debug & SHOWREQUESTS) printf("st%d: %d bytes @ blk%d\n",
                    470:                                        unit,bp->b_bcount,bp->b_blkno);
                    471:        /*******************************************************\
                    472:        * If it's a null transfer, return immediatly            *
                    473:        \*******************************************************/
                    474:        if (bp->b_bcount == 0) {
                    475:                goto done;
                    476:        }
                    477: 
                    478:        /*******************************************************\
                    479:        * Odd sized request on fixed drives are verboten        *
                    480:        \*******************************************************/
                    481:        if((st_data[unit].flags & ST_FIXEDBLOCKS)
                    482:                && bp->b_bcount % st_data[unit].blkmin)
                    483:        {
                    484:                printf("st%d: bad request, must be multiple of %d\n",
                    485:                        unit, st_data[unit].blkmin);
                    486:                bp->b_error = EIO;
                    487:                goto bad;
                    488:        }
                    489: 
                    490: #ifdef __386BSD__
                    491:        stminphys(bp);
                    492: #endif __386BSD__
                    493:        opri = splbio();
                    494:        dp = &st_buf_queue[unit];
                    495: 
                    496:        /*******************************************************\
                    497:        * Place it in the queue of disk activities for this tape*
                    498:        * at the end                                            *
                    499:        \*******************************************************/
                    500:        while ( dp->b_actf) 
                    501:        {
                    502:                dp = dp->b_actf;
                    503:        }       
                    504:        dp->b_actf = bp;
                    505:        bp->b_actf = NULL;
                    506: 
                    507:        /*******************************************************\
                    508:        * Tell the device to get going on the transfer if it's  *
                    509:        * not doing anything, otherwise just wait for completion*
                    510:        \*******************************************************/
                    511:        ststart(unit);
                    512: 
                    513:        splx(opri);
                    514:        return;
                    515: bad:
                    516:        bp->b_flags |= B_ERROR;
                    517: done:
                    518:        /*******************************************************\
                    519:        * Correctly set the buf to indicate a completed xfer    *
                    520:        \*******************************************************/
                    521:        iodone(bp);
                    522:        return;
                    523: }
                    524: 
                    525: 
                    526: /***************************************************************\
                    527: * ststart looks to see if there is a buf waiting for the device        *
                    528: * and that the device is not already busy. If both are true,   *
                    529: * It deques the buf and creates a scsi command to perform the  *
                    530: * transfer in the buf. The transfer request will call st_done  *
                    531: * on completion, which will in turn call this routine again    *
                    532: * so that the next queued transfer is performed.               *
                    533: * The bufs are queued by the strategy routine (ststrategy)     *
                    534: *                                                              *
                    535: * This routine is also called after other non-queued requests  *
                    536: * have been made of the scsi driver, to ensure that the queue  *
                    537: * continues to be drained.                                     *
                    538: \***************************************************************/
                    539: /* ststart() is called at splbio */
                    540: ststart(unit)
                    541: {
                    542:        int                     drivecount;
                    543:        register struct buf     *bp = 0;
                    544:        register struct buf     *dp;
                    545:        struct  scsi_xfer       *xs;
                    546:        struct  scsi_rw_tape    cmd;
                    547:        int                     blkno, nblk;
                    548:        struct  st_data *st;
                    549: 
                    550: 
                    551:        st = st_data + unit;
                    552: 
                    553:        if(scsi_debug & PRINTROUTINES) printf("ststart%d ",unit);
                    554:        /*******************************************************\
                    555:        * See if there is a buf to do and we are not already    *
                    556:        * doing one                                             *
                    557:        \*******************************************************/
                    558:        xs=&st_scsi_xfer[unit];
                    559:        if(xs->flags & INUSE)
                    560:        {
                    561:                return;    /* unit already underway */
                    562:        }
                    563: trynext:
                    564:        if(st_xfer_block_wait[unit]) /* a special awaits, let it proceed first */
                    565:        {
                    566:                wakeup(&st_xfer_block_wait[unit]);
                    567:                return;
                    568:        }
                    569: 
                    570:        dp = &st_buf_queue[unit];
                    571:        if ((bp = dp->b_actf) != NULL)
                    572:        {
                    573:                dp->b_actf = bp->b_actf;
                    574:        }
                    575:        else /* no work to do */
                    576:        {
                    577:                return;
                    578:        }
                    579:        xs->flags = INUSE;    /* Now ours */
                    580: 
                    581: 
                    582:        /*******************************************************\
                    583:        * We have a buf, now we should move the data into       *
                    584:        * a scsi_xfer definition and try start it               *
                    585:        \*******************************************************/
                    586: 
                    587:        /*******************************************************\
                    588:        *  If we are at a filemark but have not reported it yet *
                    589:        * then we should report it now                          *
                    590:        \*******************************************************/
                    591:        if(st->flags & ST_AT_FILEMARK)
                    592:        {
                    593:                bp->b_error = 0;
                    594:                bp->b_flags |= B_ERROR; /* EOF*/
                    595:                st->flags &= ~ST_AT_FILEMARK;
                    596:                biodone(bp);
                    597:                xs->flags = 0; /* won't need it now */
                    598:                goto trynext;
                    599:        }
                    600:        /*******************************************************\
                    601:        *  If we are at EOM but have not reported it yet        *
                    602:        * then we should report it now                          *
                    603:        \*******************************************************/
                    604:        if(st->flags & ST_AT_EOM)
                    605:        {
                    606:                bp->b_error = EIO;
                    607:                bp->b_flags |= B_ERROR;
                    608:                st->flags &= ~ST_AT_EOM;
                    609:                biodone(bp);
                    610:                xs->flags = 0; /* won't need it now */
                    611:                goto trynext;
                    612:        }
                    613:        /*******************************************************\
                    614:        *  Fill out the scsi command                            *
                    615:        \*******************************************************/
                    616:        bzero(&cmd, sizeof(cmd));
                    617:        if((bp->b_flags & B_READ) == B_WRITE)
                    618:        {
                    619:                st->flags |= ST_WRITTEN;
                    620:                xs->flags |= SCSI_DATA_OUT;
                    621:        }
                    622:        else
                    623:        {
                    624:                xs->flags |= SCSI_DATA_IN;
                    625:        }
                    626:        cmd.op_code = (bp->b_flags & B_READ) 
                    627:                                        ? READ_COMMAND_TAPE
                    628:                                        : WRITE_COMMAND_TAPE;
                    629: 
                    630:        /*******************************************************\
                    631:        * Handle "fixed-block-mode" tape drives by using the    *
                    632:        * block count instead of the length.                    *
                    633:        \*******************************************************/
                    634:        if(st->flags & ST_FIXEDBLOCKS)
                    635:        {
                    636:                cmd.fixed = 1;
                    637:                lto3b(bp->b_bcount/st->blkmin,cmd.len);
                    638:        }
                    639:        else
                    640:        {
                    641:                lto3b(bp->b_bcount,cmd.len);
                    642:        }
                    643: 
                    644:        /*******************************************************\
                    645:        * Fill out the scsi_xfer structure                      *
                    646:        *       Note: we cannot sleep as we may be an interrupt *
                    647:        \*******************************************************/
                    648:        xs->flags       |=      SCSI_NOSLEEP;
                    649:        xs->adapter     =       st->ctlr;
                    650:        xs->targ        =       st->targ;
                    651:        xs->lu          =       st->lu;
                    652:        xs->retries     =       1;      /* can't retry on tape*/
                    653:        xs->timeout     =       100000; /* allow 100 secs for retension */
                    654:        xs->cmd         =       (struct scsi_generic *)&cmd;
                    655:        xs->cmdlen      =       sizeof(cmd);
                    656:        xs->data        =       (u_char *)bp->b_un.b_addr;
                    657:        xs->datalen     =       bp->b_bcount;
                    658:        xs->resid       =       bp->b_bcount;
                    659:        xs->when_done   =       st_done;
                    660:        xs->done_arg    =       unit;
                    661:        xs->done_arg2   =       (int)xs;
                    662:        xs->error       =       XS_NOERROR;
                    663:        xs->bp          =       bp;
                    664:        /*******************************************************\
                    665:        * Pass all this info to the scsi driver.                *
                    666:        \*******************************************************/
                    667: 
                    668: 
                    669: #if defined(OSF)||defined(FIX_ME)
                    670:        if (bp->b_flags & B_PHYS) {
                    671:                xs->data = (u_char*)map_pva_kva(bp->b_proc, bp->b_un.b_addr,
                    672:                        bp->b_bcount, st_window[unit],
                    673:                        (bp->b_flags&B_READ)?B_WRITE:B_READ);
                    674:        } else {
                    675:                xs->data = (u_char*)bp->b_un.b_addr;
                    676:        }
                    677: #endif /* defined(OSF) */
                    678: 
                    679:        if ( (*(st->sc_sw->scsi_cmd))(xs) != SUCCESSFULLY_QUEUED)
                    680:        {
                    681:                printf("st%d: oops not queued",unit);
                    682:                xs->error = XS_DRIVER_STUFFUP;
                    683:                st_done(unit,xs);
                    684:        }
                    685:        stqueues++;
                    686: }
                    687: 
                    688: /*******************************************************\
                    689: * This routine is called by the scsi interrupt when    *
                    690: * the transfer is complete.
                    691: \*******************************************************/
                    692: int    st_done(unit,xs)
                    693: int    unit;
                    694: struct scsi_xfer       *xs;
                    695: {
                    696:        struct  buf             *bp;
                    697:        int     retval;
                    698: 
                    699:        if(scsi_debug & PRINTROUTINES) printf("st_done%d ",unit);
                    700:        if (! (xs->flags & INUSE))
                    701:                panic("scsi_xfer not in use!");
                    702:        if(bp = xs->bp)
                    703:        {
                    704:                switch(xs->error)
                    705:                {
                    706:                case    XS_NOERROR:
                    707:                        bp->b_flags &= ~B_ERROR;
                    708:                        bp->b_error = 0;
                    709:                        bp->b_resid = 0;
                    710:                        break;
                    711:                case    XS_SENSE:
                    712:                        retval = (st_interpret_sense(unit,xs));
                    713:                        if(retval)
                    714:                        {
                    715:                                /***************************************\
                    716:                                * We have a real error, the bit should  *
                    717:                                * be set to indicate this. The return   *
                    718:                                * value will contain the unix error code*
                    719:                                * that the error interpretation routine *
                    720:                                * thought was suitable, so pass this    *
                    721:                                * value back in the buf structure.      *
                    722:                                * Furthermore we return information     *
                    723:                                * saying that no data was transferred   *
                    724:                                \***************************************/
                    725:                                bp->b_flags |= B_ERROR;
                    726:                                bp->b_error = retval;
                    727:                                bp->b_resid =  bp->b_bcount;
                    728:                                st_data[unit].flags 
                    729:                                        &= ~(ST_AT_FILEMARK|ST_AT_EOM);
                    730:                        }
                    731:                        else
                    732:                        {
                    733:                        /***********************************************\
                    734:                        * The error interpretation code has declared    *
                    735:                        * that it wasn't a real error, or at least that *
                    736:                        * we should be ignoring it if it was.           *
                    737:                        \***********************************************/
                    738:                            if(xs->resid && ( xs->resid != xs->datalen ))
                    739:                            {
                    740:                                /***************************************\
                    741:                                * Here we have the tricky part..        *
                    742:                                * We successfully read less data than   *
                    743:                                * we requested. (but not 0)             *
                    744:                                *------for variable blocksize tapes:----*
                    745:                                * UNDER 386BSD:                         *
                    746:                                * We should legitimatly have the error  *
                    747:                                * bit set, with the error value set to  *
                    748:                                * zero.. This is to indicate to the     *
                    749:                                * physio code that while we didn't get  *
                    750:                                * as much information as was requested, *
                    751:                                * we did reach the end of the record    *
                    752:                                * and so physio should not call us      *
                    753:                                * again for more data... we have it all *
                    754:                                * SO SET THE ERROR BIT!                 *
                    755:                                *                                       *
                    756:                                * UNDER MACH:(CMU)                      *
                    757:                                * To indicate the same as above, we     *
                    758:                                * need only have a non 0 resid that is  *
                    759:                                * less than the b_bcount, but the       *
                    760:                                * ERROR BIT MUST BE CLEAR! (sigh)       *
                    761:                                *                                       *
                    762:                                * UNDER OSF1:                           *
                    763:                                * To indicate the same as above, we     *
                    764:                                * need to have a non 0 resid that is    *
                    765:                                * less than the b_bcount, but the       *
                    766:                                * ERROR BIT MUST BE SET! (gasp)(sigh)   *
                    767:                                *                                       *
                    768:                                *-------for fixed blocksize device------*
                    769:                                * We could have read some successful    *
                    770:                                * records before hitting                *
                    771:                                * the EOF or EOT. These must be passed  *
                    772:                                * to the user, before we report the     *
                    773:                                * EOx. Only if there is no data for the *
                    774:                                * user do we report it now. (via an EIO *
                    775:                                * for EOM and resid == count for EOF).  *
                    776:                                * We will report the EOx NEXT time..    *
                    777:                                \***************************************/
                    778: #ifdef MACH /*osf and cmu varieties */
                    779: #ifdef OSF
                    780:                                bp->b_flags |= B_ERROR;
                    781: #else  OSF
                    782:                                bp->b_flags &= ~B_ERROR;
                    783: #endif OSF
                    784: #endif MACH
                    785: #ifdef __386BSD__
                    786:                                bp->b_flags |= B_ERROR;
                    787: #endif __386BSD__
                    788:                                bp->b_error = 0;
                    789:                                bp->b_resid = xs->resid;
                    790:                                if((st_data[unit].flags & ST_FIXEDBLOCKS))
                    791:                                {
                    792:                                        bp->b_resid *= st_data[unit].blkmin;
                    793:                                        if(  (st_data[unit].flags & ST_AT_EOM)
                    794:                                          && (bp->b_resid == bp->b_bcount))
                    795:                                        {
                    796:                                                bp->b_error = EIO;
                    797:                                                st_data[unit].flags
                    798:                                                        &= ~ST_AT_EOM;
                    799:                                        }
                    800:                                }
                    801:                                xs->error = XS_NOERROR;
                    802:                                break;
                    803:                            }
                    804:                            else
                    805:                            {
                    806:                                /***************************************\
                    807:                                * We have come out of the error handler *
                    808:                                * with no error code.. we have also     *
                    809:                                * not had an ili (would have gone to    *
                    810:                                * the previous clause). Now we need to  *
                    811:                                * distiguish between succesful read of  *
                    812:                                * no data (EOF or EOM) and successfull  *
                    813:                                * read of all requested data.           *
                    814:                                * At least all o/s agree that:          *
                    815:                                * 0 bytes read with no error is EOF     *
                    816:                                * 0 bytes read with an EIO is EOM       *
                    817:                                \***************************************/
                    818: 
                    819:                                bp->b_resid = bp->b_bcount;
                    820:                                if(st_data[unit].flags & ST_AT_FILEMARK)
                    821:                                {
                    822:                                        st_data[unit].flags &= ~ST_AT_FILEMARK;
                    823:                                        bp->b_flags &= ~B_ERROR;
                    824:                                        bp->b_error = 0;
                    825:                                        break;
                    826:                                }
                    827:                                if(st_data[unit].flags & ST_AT_EOM)
                    828:                                {
                    829:                                        bp->b_flags |= B_ERROR;
                    830:                                        bp->b_error = EIO;
                    831:                                        st_data[unit].flags &= ~ST_AT_EOM;
                    832:                                        break;
                    833:                                }
                    834:                                printf("st%d:error ignored\n" ,unit);
                    835:                            }
                    836:                        }
                    837:                        break;
                    838: 
                    839:                case    XS_TIMEOUT:
                    840:                        printf("st%d timeout\n",unit);
                    841:                        break;
                    842: 
                    843:                case    XS_BUSY:        /* should retry */ /* how? */
                    844:                        /************************************************/
                    845:                        /* SHOULD put buf back at head of queue         */
                    846:                        /* and decrement retry count in (*xs)           */
                    847:                        /* HOWEVER, this should work as a kludge        */
                    848:                        /************************************************/
                    849:                        if(xs->retries--)
                    850:                        {
                    851:                                xs->flags &= ~ITSDONE;
                    852:                                xs->error = XS_NOERROR;
                    853:                                if ( (*(st_data[unit].sc_sw->scsi_cmd))(xs)
                    854:                                        == SUCCESSFULLY_QUEUED)
                    855:                                {       /* don't wake the job, ok? */
                    856:                                        return;
                    857:                                }
                    858:                                printf("device busy");
                    859:                                xs->flags |= ITSDONE;
                    860:                        }
                    861: 
                    862:                case    XS_DRIVER_STUFFUP:
                    863:                        bp->b_flags |= B_ERROR;
                    864:                        bp->b_error = EIO;
                    865:                        break;
                    866:                default:
                    867:                        printf("st%d: unknown error category from scsi driver\n"
                    868:                                ,unit);
                    869:                }       
                    870:                biodone(bp);
                    871:                xs->flags = 0;  /* no longer in use */
                    872:                ststart(unit);          /* If there's another waiting.. do it */
                    873:        }
                    874:        else
                    875:        {
                    876:                wakeup(xs);
                    877:        }
                    878: }
                    879: /*******************************************************\
                    880: * Perform special action on behalf of the user         *
                    881: * Knows about the internals of this device             *
                    882: \*******************************************************/
                    883: stioctl(dev, cmd, arg, mode)
                    884: dev_t dev;
                    885: int cmd;
                    886: caddr_t arg;
                    887: {
                    888:        register i,j;
                    889:        unsigned int opri;
                    890:        int errcode = 0;
                    891:        unsigned char unit;
                    892:        int number,flags,ret;
                    893: 
                    894:        /*******************************************************\
                    895:        * Find the device that the user is talking about        *
                    896:        \*******************************************************/
                    897:        flags = 0;      /* give error messages, act on errors etc. */
                    898:        unit = UNIT(dev);
                    899: 
                    900:        switch(cmd)
                    901:        {
                    902: 
                    903:        case MTIOCGET:
                    904:            {
                    905:                struct mtget *g = (struct mtget *) arg;
                    906: 
                    907:                bzero(g, sizeof(struct mtget));
                    908:                g->mt_type = 0x7;       /* Ultrix compat */ /*?*/
                    909:                ret=TRUE;
                    910:                break;
                    911:            }
                    912: 
                    913: 
                    914:        case MTIOCTOP:
                    915:            {
                    916:                struct mtop *mt = (struct mtop *) arg;
                    917: 
                    918:                if (st_debug)
                    919:                        printf("[sctape_sstatus: %x %x]\n",
                    920:                                 mt->mt_op, mt->mt_count);
                    921: 
                    922: 
                    923: 
                    924:                /* compat: in U*x it is a short */
                    925:                number = mt->mt_count;
                    926:                switch ((short)(mt->mt_op))
                    927:                {
                    928:                case MTWEOF:    /* write an end-of-file record */
                    929:                        ret = st_write_filemarks(unit,number,flags);
                    930:                        st_data[unit].flags &= ~ST_WRITTEN;
                    931:                        break;
                    932:                case MTFSF:     /* forward space file */
                    933:                        ret = st_space(unit,number,SP_FILEMARKS,flags);
                    934:                        break;
                    935:                case MTBSF:     /* backward space file */
                    936:                        ret = st_space(unit,-number,SP_FILEMARKS,flags);
                    937:                        break;
                    938:                case MTFSR:     /* forward space record */
                    939:                        ret = st_space(unit,number,SP_BLKS,flags);
                    940:                        break;
                    941:                case MTBSR:     /* backward space record */
                    942:                        ret = st_space(unit,-number,SP_BLKS,flags);
                    943:                        break;
                    944:                case MTREW:     /* rewind */
                    945:                        ret = st_rewind(unit,FALSE,flags);
                    946:                        break;
                    947:                case MTOFFL:    /* rewind and put the drive offline */
                    948:                        if((ret = st_rewind(unit,FALSE,flags)))
                    949:                        {
                    950:                                st_prevent(unit,PR_ALLOW,0);
                    951:                                ret = st_load(unit,LD_UNLOAD,flags);
                    952:                        }
                    953:                        else
                    954:                        {
                    955:                                printf("rewind failed, unit still loaded\n");
                    956:                        }
                    957:                        break;
                    958:                case MTNOP:     /* no operation, sets status only */
                    959:                case MTCACHE:   /* enable controller cache */
                    960:                case MTNOCACHE: /* disable controller cache */
                    961:                        ret = TRUE;;
                    962:                        break;
                    963:                default:
                    964:                        return EINVAL;
                    965:                }
                    966:                break;
                    967:            }
                    968:        case MTIOCIEOT:
                    969:        case MTIOCEEOT:
                    970:                ret=TRUE;
                    971:                break;
                    972:        }
                    973: 
                    974:        return(ret?ESUCCESS:EIO);
                    975: }
                    976: 
                    977: 
                    978: /*******************************************************\
                    979: * Check with the device that it is ok, (via scsi driver)*
                    980: \*******************************************************/
                    981: st_req_sense(unit, flags)
                    982: int    flags;
                    983: {
                    984:        struct  scsi_sense_data sense;
                    985:        struct  scsi_sense      scsi_cmd;
                    986: 
                    987:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                    988:        scsi_cmd.op_code = REQUEST_SENSE;
                    989:        scsi_cmd.length = sizeof(sense);
                    990: 
                    991:        if (st_scsi_cmd(unit,
                    992:                        &scsi_cmd,
                    993:                        sizeof(scsi_cmd),
                    994:                        &sense,
                    995:                        sizeof(sense),
                    996:                        100000,
                    997:                        flags | SCSI_DATA_IN) != 0)
                    998:        {
                    999:                return(FALSE);
                   1000:        }
                   1001:        else 
                   1002:                return(TRUE);
                   1003: }
                   1004: 
                   1005: /*******************************************************\
                   1006: * Get scsi driver to send a "are you ready" command    *
                   1007: \*******************************************************/
                   1008: st_test_ready(unit,flags)
                   1009: int    unit,flags;
                   1010: {
                   1011:        struct  scsi_test_unit_ready scsi_cmd;
                   1012: 
                   1013:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                   1014:        scsi_cmd.op_code = TEST_UNIT_READY;
                   1015: 
                   1016:        if (st_scsi_cmd(unit,
                   1017:                        &scsi_cmd,
                   1018:                        sizeof(scsi_cmd),
                   1019:                        0,
                   1020:                        0,
                   1021:                        100000,
                   1022:                        flags) != 0) {
                   1023:                return(FALSE);
                   1024:        } else 
                   1025:                return(TRUE);
                   1026: }
                   1027: 
                   1028: 
                   1029: #ifdef __STDC__
                   1030: #define b2tol(a)       (((unsigned)(a##_1) << 8) + (unsigned)a##_0 )
                   1031: #else
                   1032: #define b2tol(a)       (((unsigned)(a/**/_1) << 8) + (unsigned)a/**/_0 )
                   1033: #endif
                   1034: 
                   1035: /*******************************************************\
                   1036: * Ask the drive what it's min and max blk sizes are.   *
                   1037: \*******************************************************/
                   1038: st_rd_blk_lim(unit, flags)
                   1039: int    unit,flags;
                   1040: {
                   1041:        struct  scsi_blk_limits scsi_cmd;
                   1042:        struct scsi_blk_limits_data scsi_blkl;
                   1043:        struct st_data *st = st_data + unit;
                   1044:        /*******************************************************\
                   1045:        * First check if we have it all loaded                  *
                   1046:        \*******************************************************/
                   1047:        if (st_info_valid[unit]) goto done;
                   1048: 
                   1049:        /*******************************************************\
                   1050:        * do a 'Read Block Limits'                              *
                   1051:        \*******************************************************/
                   1052:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                   1053:        scsi_cmd.op_code = READ_BLK_LIMITS;
                   1054: 
                   1055:        /*******************************************************\
                   1056:        * do the command,       update the global values        *
                   1057:        \*******************************************************/
                   1058:        if (st_scsi_cmd(unit,
                   1059:                        &scsi_cmd,
                   1060:                        sizeof(scsi_cmd),
                   1061:                        &scsi_blkl,
                   1062:                        sizeof(scsi_blkl),
                   1063:                        5000,
                   1064:                        flags | SCSI_DATA_IN) != 0)
                   1065:        {
                   1066:                if(!(flags & SCSI_SILENT))
                   1067:                        printf("could not get blk limits for unit %d\n", unit);
                   1068:                st_info_valid[unit] = FALSE;
                   1069:                return(FALSE);
                   1070:        } 
                   1071:        if (st_debug)
                   1072:        {
                   1073:                printf(" (%d <= blksiz <= %d\n) ",
                   1074:                        b2tol(scsi_blkl.min_length),
                   1075:                        _3btol(&scsi_blkl.max_length_2));
                   1076:        }
                   1077:        st->blkmin = b2tol(scsi_blkl.min_length);
                   1078:        st->blkmax = _3btol(&scsi_blkl.max_length_2);
                   1079: 
                   1080: done:
                   1081:        if(st->blkmin && (st->blkmin == st->blkmax))
                   1082:        {
                   1083:                st->flags |= ST_FIXEDBLOCKS;
                   1084:        }
                   1085:        return(TRUE);
                   1086: }
                   1087: /*******************************************************\
                   1088: * Get the scsi driver to send a full inquiry to the    *
                   1089: * device and use the results to fill out the global    *
                   1090: * parameter structure.                                 *
                   1091: \*******************************************************/
                   1092: st_mode_sense(unit, flags)
                   1093: int    unit,flags;
                   1094: {
                   1095:        struct scsi_mode_sense          scsi_cmd;
                   1096:        struct 
                   1097:        {
                   1098:                struct  scsi_mode_header_tape header;
                   1099:                struct  blk_desc        blk_desc;
                   1100:        }scsi_sense;
                   1101:        struct  st_data *st = st_data + unit;
                   1102: 
                   1103:        /*******************************************************\
                   1104:        * First check if we have it all loaded                  *
                   1105:        \*******************************************************/
                   1106:        if (st_info_valid[unit]) return(TRUE);
                   1107:        /*******************************************************\
                   1108:        * First do a mode sense                                 *
                   1109:        \*******************************************************/
                   1110:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                   1111:        scsi_cmd.op_code = MODE_SENSE;
                   1112:        scsi_cmd.length = sizeof(scsi_sense);
                   1113:        /*******************************************************\
                   1114:        * do the command, but we don't need the results         *
                   1115:        * just print them for our interest's sake               *
                   1116:        \*******************************************************/
                   1117:        if (st_scsi_cmd(unit,
                   1118:                        &scsi_cmd,
                   1119:                        sizeof(scsi_cmd),
                   1120:                        &scsi_sense,
                   1121:                        sizeof(scsi_sense),
                   1122:                        5000,
                   1123:                        flags | SCSI_DATA_IN) != 0)
                   1124:        {
                   1125:                if(!(flags & SCSI_SILENT))
                   1126:                        printf("could not mode sense for unit %d\n", unit);
                   1127:                st_info_valid[unit] = FALSE;
                   1128:                return(FALSE);
                   1129:        } 
                   1130:        if (st_debug)
                   1131:        {
                   1132:                printf("unit %d: %d blocks of %d bytes, write %s, %sbuffered",
                   1133:                        unit,
                   1134:                        _3btol(&scsi_sense.blk_desc.nblocks),
                   1135:                        _3btol(&scsi_sense.blk_desc.blklen),
                   1136:                        (scsi_sense.header.write_protected ?
                   1137:                                "protected" : "enabled"),
                   1138:                        (scsi_sense.header.buf_mode ?
                   1139:                                "" : "un")
                   1140:                        );
                   1141:        }
                   1142:        st->numblks = _3btol(&scsi_sense.blk_desc.nblocks);
                   1143:        st->blksiz = _3btol(&scsi_sense.blk_desc.blklen);
                   1144:        return(TRUE);
                   1145: }
                   1146: 
                   1147: /*******************************************************\
                   1148: * Get the scsi driver to send a full inquiry to the    *
                   1149: * device and use the results to fill out the global    *
                   1150: * parameter structure.                                 *
                   1151: \*******************************************************/
                   1152: st_mode_select(unit, flags, dsty_code)
                   1153: int    unit,flags,dsty_code;
                   1154: {
                   1155:        struct scsi_mode_select scsi_cmd;
                   1156:        struct
                   1157:        {
                   1158:                struct  scsi_mode_header_tape header;
                   1159:                struct  blk_desc        blk_desc;
                   1160:        }dat;
                   1161:        struct  st_data *st = st_data + unit;
                   1162: 
                   1163:        /*******************************************************\
                   1164:        * Set up for a mode select                              *
                   1165:        \*******************************************************/
                   1166:        bzero(&dat, sizeof(dat));
                   1167:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                   1168:        scsi_cmd.op_code = MODE_SELECT;
                   1169:        scsi_cmd.length = sizeof(dat);
                   1170:        dat.header.blk_desc_len = sizeof(struct  blk_desc);
                   1171:        dat.header.buf_mode = 1;
                   1172:         dat.blk_desc.density = dsty_code;
                   1173:        if(st->flags & ST_FIXEDBLOCKS)
                   1174:        {
                   1175:                lto3b( st->blkmin , dat.blk_desc.blklen);
                   1176:        }
                   1177: /*     lto3b( st->numblks , dat.blk_desc.nblocks); use defaults!!!!
                   1178:        lto3b( st->blksiz , dat.blk_desc.blklen);
                   1179: */
                   1180:        /*******************************************************\
                   1181:        * do the command                                        *
                   1182:        \*******************************************************/
                   1183:        if (st_scsi_cmd(unit,
                   1184:                        &scsi_cmd,
                   1185:                        sizeof(scsi_cmd),
                   1186:                        &dat,
                   1187:                        sizeof(dat),
                   1188:                        5000,
                   1189:                        flags | SCSI_DATA_OUT) != 0)
                   1190:        {
                   1191:                if(!(flags & SCSI_SILENT))
                   1192:                        printf("could not mode select for unit %d\n", unit);
                   1193:                st_info_valid[unit] = FALSE;
                   1194:                return(FALSE);
                   1195:        } 
                   1196:        return(TRUE);
                   1197: }
                   1198: 
                   1199: /*******************************************************\
                   1200: * skip N blocks/filemarks/seq filemarks/eom            *
                   1201: \*******************************************************/
                   1202: st_space(unit,number,what,flags)
                   1203: int    unit,number,what,flags;
                   1204: {
                   1205:        struct scsi_space scsi_cmd;
                   1206: 
                   1207:        /* if we are at a filemark now, we soon won't be*/
                   1208:        st_data[unit].flags &= ~(ST_AT_FILEMARK | ST_AT_EOM);
                   1209:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                   1210:        scsi_cmd.op_code = SPACE;
                   1211:        scsi_cmd.code = what;
                   1212:        lto3b(number,scsi_cmd.number);
                   1213:        if (st_scsi_cmd(unit,
                   1214:                        &scsi_cmd,
                   1215:                        sizeof(scsi_cmd),
                   1216:                        0,
                   1217:                        0,
                   1218:                        600000, /* 10 mins enough? */
                   1219:                        flags) != 0)
                   1220:        {
                   1221:                if(!(flags & SCSI_SILENT))
                   1222:                        printf("could not space st%d\n", unit);
                   1223:                st_info_valid[unit] = FALSE;
                   1224:                return(FALSE);
                   1225:        }
                   1226:        return(TRUE);
                   1227: }
                   1228: /*******************************************************\
                   1229: * write N filemarks                                    *
                   1230: \*******************************************************/
                   1231: st_write_filemarks(unit,number,flags)
                   1232: int    unit,number,flags;
                   1233: {
                   1234:        struct scsi_write_filemarks scsi_cmd;
                   1235: 
                   1236:        st_data[unit].flags &= ~(ST_AT_FILEMARK);
                   1237:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                   1238:        scsi_cmd.op_code = WRITE_FILEMARKS;
                   1239:        lto3b(number,scsi_cmd.number);
                   1240:        if (st_scsi_cmd(unit,
                   1241:                        &scsi_cmd,
                   1242:                        sizeof(scsi_cmd),
                   1243:                        0,
                   1244:                        0,
                   1245:                        100000, /* 10 secs.. (may need to repos head )*/
                   1246:                        flags) != 0)
                   1247:        {
                   1248:                if(!(flags & SCSI_SILENT))
                   1249:                        printf("could not write_filemarks st%d\n", unit);
                   1250:                st_info_valid[unit] = FALSE;
                   1251:                return(FALSE);
                   1252:        }
                   1253:        return(TRUE);
                   1254: }
                   1255: /*******************************************************\
                   1256: * load /unload (with retension if true)                        *
                   1257: \*******************************************************/
                   1258: st_load(unit,type,flags)
                   1259: int    unit,type,flags;
                   1260: {
                   1261:        struct  scsi_load  scsi_cmd;
                   1262: 
                   1263:        st_data[unit].flags &= ~(ST_AT_FILEMARK | ST_AT_EOM);
                   1264:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                   1265:        scsi_cmd.op_code = LOAD_UNLOAD;
                   1266:        scsi_cmd.load=type;
                   1267:        if (type == LD_LOAD)
                   1268:        {
                   1269:                /*scsi_cmd.reten=TRUE;*/
                   1270:                scsi_cmd.reten=FALSE;
                   1271:        }
                   1272:        else
                   1273:        {
                   1274:                scsi_cmd.reten=FALSE;
                   1275:        }
                   1276:        if (st_scsi_cmd(unit,
                   1277:                        &scsi_cmd,
                   1278:                        sizeof(scsi_cmd),
                   1279:                        0,
                   1280:                        0,
                   1281:                        30000, /* 30 secs */
                   1282:                        flags) != 0)
                   1283:        {
                   1284:                if(!(flags & SCSI_SILENT))
                   1285:                        printf("cannot load/unload  st%d\n", unit);
                   1286:                st_info_valid[unit] = FALSE;
                   1287:                return(FALSE);
                   1288:        }
                   1289:        return(TRUE);
                   1290: }
                   1291: /*******************************************************\
                   1292: * Prevent or allow the user to remove the tape         *
                   1293: \*******************************************************/
                   1294: st_prevent(unit,type,flags)
                   1295: int    unit,type,flags;
                   1296: {
                   1297:        struct  scsi_prevent    scsi_cmd;
                   1298: 
                   1299:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                   1300:        scsi_cmd.op_code = PREVENT_ALLOW;
                   1301:        scsi_cmd.prevent=type;
                   1302:        if (st_scsi_cmd(unit,
                   1303:                        &scsi_cmd,
                   1304:                        sizeof(scsi_cmd),
                   1305:                        0,
                   1306:                        0,
                   1307:                        5000,
                   1308:                        flags) != 0)
                   1309:        {
                   1310:                if(!(flags & SCSI_SILENT))
                   1311:                        printf("cannot prevent/allow on st%d\n", unit);
                   1312:                st_info_valid[unit] = FALSE;
                   1313:                return(FALSE);
                   1314:        }
                   1315:        return(TRUE);
                   1316: }
                   1317: /*******************************************************\
                   1318: *  Rewind the device                                   *
                   1319: \*******************************************************/
                   1320: st_rewind(unit,immed,flags)
                   1321: int    unit,immed,flags;
                   1322: {
                   1323:        struct  scsi_rewind     scsi_cmd;
                   1324: 
                   1325:        st_data[unit].flags &= ~(ST_AT_FILEMARK | ST_AT_EOM);
                   1326:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                   1327:        scsi_cmd.op_code = REWIND;
                   1328:        scsi_cmd.immed=immed;
                   1329:        if (st_scsi_cmd(unit,
                   1330:                        &scsi_cmd,
                   1331:                        sizeof(scsi_cmd),
                   1332:                        0,
                   1333:                        0,
                   1334:                        immed?5000:300000, /* 5 sec or 5 min */
                   1335:                        flags) != 0)
                   1336:        {
                   1337:                if(!(flags & SCSI_SILENT))
                   1338:                        printf("could not rewind st%d\n", unit);
                   1339:                st_info_valid[unit] = FALSE;
                   1340:                return(FALSE);
                   1341:        }
                   1342:        return(TRUE);
                   1343: }
                   1344: /*******************************************************\
                   1345: * ask the scsi driver to perform a command for us.     *
                   1346: * Call it through the switch table, and tell it which  *
                   1347: * sub-unit we want, and what target and lu we wish to  *
                   1348: * talk to. Also tell it where to find the command      *
                   1349: * how long int is.                                     *
                   1350: * Also tell it where to read/write the data, and how   *
                   1351: * long the data is supposed to be                      *
                   1352: \*******************************************************/
                   1353: int    st_scsi_cmd(unit,scsi_cmd,cmdlen,data_addr,datalen,timeout,flags)
                   1354: 
                   1355: int    unit,flags;
                   1356: struct scsi_generic *scsi_cmd;
                   1357: int    cmdlen;
                   1358: int    timeout;
                   1359: u_char *data_addr;
                   1360: int    datalen;
                   1361: {
                   1362:        struct  scsi_xfer *xs;
                   1363:        int     retval;
                   1364:        int     s;
                   1365:        struct  st_data *st = st_data + unit;
                   1366: 
                   1367:        if(scsi_debug & PRINTROUTINES) printf("\nst_scsi_cmd%d ",unit);
                   1368:        if(st->sc_sw)   /* If we have a scsi driver */
                   1369:        {
                   1370: 
                   1371:                xs = &(st_scsi_xfer[unit]);
                   1372:                if(!(flags & SCSI_NOMASK))
                   1373:                        s = splbio();
                   1374:                st_xfer_block_wait[unit]++;     /* there is someone waiting */
                   1375:                while (xs->flags & INUSE)
                   1376:                {
                   1377:                        sleep(&st_xfer_block_wait[unit],PRIBIO+1);
                   1378:                }
                   1379:                st_xfer_block_wait[unit]--;
                   1380:                xs->flags = INUSE;
                   1381:                if(!(flags & SCSI_NOMASK))
                   1382:                        splx(s);
                   1383: 
                   1384:                /*******************************************************\
                   1385:                * Fill out the scsi_xfer structure                      *
                   1386:                \*******************************************************/
                   1387:                xs->flags       |=      flags;
                   1388:                xs->adapter     =       st->ctlr;
                   1389:                xs->targ        =       st->targ;
                   1390:                xs->lu          =       st->lu;
                   1391:                xs->retries     =       ST_RETRIES;
                   1392:                xs->timeout     =       timeout;
                   1393:                xs->cmd         =       scsi_cmd;
                   1394:                xs->cmdlen      =       cmdlen;
                   1395:                xs->data        =       data_addr;
                   1396:                xs->datalen     =       datalen;
                   1397:                xs->resid       =       datalen;
                   1398:                xs->when_done   =       (flags & SCSI_NOMASK)
                   1399:                                        ?(int (*)())0
                   1400:                                        :st_done;
                   1401:                xs->done_arg    =       unit;
                   1402:                xs->done_arg2   =       (int)xs;
                   1403: retry:         xs->error       =       XS_NOERROR;
                   1404:                xs->bp          =       0;
                   1405:                retval = (*(st->sc_sw->scsi_cmd))(xs);
                   1406:                switch(retval)
                   1407:                {
                   1408:                case    SUCCESSFULLY_QUEUED:
                   1409:                        s = splbio();
                   1410:                        while(!(xs->flags & ITSDONE))
                   1411:                                sleep(xs,PRIBIO+1);
                   1412:                        splx(s);
                   1413: 
                   1414:                case    HAD_ERROR:
                   1415:                case    COMPLETE:
                   1416:                        switch(xs->error)
                   1417:                        {
                   1418:                        case    XS_NOERROR:
                   1419:                                retval = ESUCCESS;
                   1420:                                break;
                   1421:                        case    XS_SENSE:
                   1422:                                retval = (st_interpret_sense(unit,xs));
                   1423:                                /* only useful for reads */
                   1424:                                if (retval)
                   1425:                                { /* error... don't care about filemarks */
                   1426:                                        st->flags &= ~(ST_AT_FILEMARK
                   1427:                                                        | ST_AT_EOM);
                   1428:                                }
                   1429:                                else
                   1430:                                {
                   1431:                                        xs->error = XS_NOERROR;
                   1432:                                        retval = ESUCCESS;
                   1433:                                }
                   1434:                                break;
                   1435:                        case    XS_DRIVER_STUFFUP:
                   1436:                                retval = EIO;
                   1437:                                break;
                   1438:                        case    XS_TIMEOUT:
                   1439:                                if(xs->retries-- )
                   1440:                                {
                   1441:                                        xs->flags &= ~ITSDONE;
                   1442:                                        goto retry;
                   1443:                                }
                   1444:                                retval = EIO;
                   1445:                                break;
                   1446:                        case    XS_BUSY:
                   1447:                                if(xs->retries-- )
                   1448:                                {
                   1449:                                        xs->flags &= ~ITSDONE;
                   1450:                                        goto retry;
                   1451:                                }
                   1452:                                retval = EIO;
                   1453:                                break;
                   1454:                        default:
                   1455:                                retval = EIO;
                   1456:                                printf("st%d: unknown error category from scsi driver\n"
                   1457:                                        ,unit);
                   1458:                                break;
                   1459:                        }       
                   1460:                        break;
                   1461:                case    TRY_AGAIN_LATER:
                   1462:                        if(xs->retries-- )
                   1463:                        {
                   1464:                                xs->flags &= ~ITSDONE;
                   1465:                                goto retry;
                   1466:                        }
                   1467:                        retval = EIO;
                   1468:                        break;
                   1469:                default:
                   1470:                        retval = EIO;
                   1471:                }
                   1472:                xs->flags = 0;  /* it's free! */
                   1473:                ststart(unit);
                   1474:        }
                   1475:        else
                   1476:        {
                   1477:                printf("st%d: not set up\n",unit);
                   1478:                return(EINVAL);
                   1479:        }
                   1480:        return(retval);
                   1481: }
                   1482: /***************************************************************\
                   1483: * Look at the returned sense and act on the error and detirmine        *
                   1484: * The unix error number to pass back... (0 = report no error)  *
                   1485: \***************************************************************/
                   1486: 
                   1487: int    st_interpret_sense(unit,xs)
                   1488: int    unit;
                   1489: struct scsi_xfer       *xs;
                   1490: {
                   1491:        struct  scsi_sense_data *sense;
                   1492:        int     key;
                   1493:        int     silent = xs->flags & SCSI_SILENT;
                   1494: 
                   1495:        /***************************************************************\
                   1496:        * If errors are ok, report a success                            *
                   1497:        \***************************************************************/
                   1498:        if(xs->flags & SCSI_ERR_OK) return(ESUCCESS);
                   1499: 
                   1500:        /***************************************************************\
                   1501:        * Get the sense fields and work out what CLASS                  *
                   1502:        \***************************************************************/
                   1503:        sense = &(xs->sense);
                   1504:        if(st_debug)
                   1505:        {
                   1506:                int count = 0;
                   1507:                printf("code%x class%x valid%x\n"
                   1508:                                ,sense->error_code
                   1509:                                ,sense->error_class
                   1510:                                ,sense->valid);
                   1511:                printf("seg%x key%x ili%x eom%x fmark%x\n"
                   1512:                                ,sense->ext.extended.segment
                   1513:                                ,sense->ext.extended.sense_key
                   1514:                                ,sense->ext.extended.ili
                   1515:                                ,sense->ext.extended.eom
                   1516:                                ,sense->ext.extended.filemark);
                   1517:                printf("info: %x %x %x %x followed by %d extra bytes\n"
                   1518:                                ,sense->ext.extended.info[0]
                   1519:                                ,sense->ext.extended.info[1]
                   1520:                                ,sense->ext.extended.info[2]
                   1521:                                ,sense->ext.extended.info[3]
                   1522:                                ,sense->ext.extended.extra_len);
                   1523:                printf("extra: ");
                   1524:                while(count < sense->ext.extended.extra_len)
                   1525:                {
                   1526:                        printf ("%x ",sense->ext.extended.extra_bytes[count++]);
                   1527:                }
                   1528:                printf("\n");
                   1529:        }
                   1530:        switch(sense->error_class)
                   1531:        {
                   1532:        /***************************************************************\
                   1533:        * If it's class 7, use the extended stuff and interpret the key *
                   1534:        \***************************************************************/
                   1535:        case 7:
                   1536:        {
                   1537:                if(sense->ext.extended.eom)
                   1538:                {
                   1539:                        st_data[unit].flags |= ST_AT_EOM;
                   1540:                }
                   1541: 
                   1542:                if(sense->ext.extended.filemark)
                   1543:                {
                   1544:                        st_data[unit].flags |= ST_AT_FILEMARK;
                   1545:                }
                   1546: 
                   1547:                if(sense->ext.extended.ili)
                   1548:                {
                   1549:                        if(sense->valid)
                   1550:                        {
                   1551:                                /*******************************\
                   1552:                                * In all ili cases, note that   *
                   1553:                                * the resid is non-0 AND not    *
                   1554:                                * unchanged.                    *
                   1555:                                \*******************************/
                   1556:                                xs->resid
                   1557:                                   = ntohl(*((long *)sense->ext.extended.info));
                   1558:                                if(xs->bp)
                   1559:                                {
                   1560:                                        if(xs->resid < 0)
                   1561:                                        { /* never on block devices */
                   1562:                                                /***********************\
                   1563:                                                * it's only really bad  *
                   1564:                                                * if we have lost data  *
                   1565:                                                * (the record was       *
                   1566:                                                * bigger than the read) *
                   1567:                                                \***********************/
                   1568:                                                return(EIO);
                   1569:                                        }
                   1570:                                }       
                   1571:                        }
                   1572:                        else
                   1573:                        { /* makes no sense.. complain */
                   1574:                                printf("BAD length error?");
                   1575:                        }
                   1576:                }/* there may be some other error. check the rest */
                   1577: 
                   1578:                key=sense->ext.extended.sense_key;
                   1579:                switch(key)
                   1580:                {
                   1581:                case    0x0:
                   1582:                        return(ESUCCESS);
                   1583:                case    0x1:
                   1584:                        if(!silent)
                   1585:                        {
                   1586:                                printf("st%d: soft error(corrected) ", unit); 
                   1587:                                if(sense->valid)
                   1588:                                {
                   1589:                                        printf("block no. %d (decimal)\n",
                   1590:                                        (sense->ext.extended.info[0] <<24)|
                   1591:                                        (sense->ext.extended.info[1] <<16)|
                   1592:                                        (sense->ext.extended.info[2] <<8)|
                   1593:                                        (sense->ext.extended.info[3] ));
                   1594:                                }
                   1595:                                else
                   1596:                                {
                   1597:                                        printf("\n");
                   1598:                                }
                   1599:                        }
                   1600:                        return(ESUCCESS);
                   1601:                case    0x2:
                   1602:                        if(!silent) printf("st%d: not ready\n ", unit); 
                   1603:                        return(ENODEV);
                   1604:                case    0x3:
                   1605:                        if(!silent)
                   1606:                        {
                   1607:                                printf("st%d: medium error ", unit); 
                   1608:                                if(sense->valid)
                   1609:                                {
                   1610:                                        printf("block no. %d (decimal)\n",
                   1611:                                        (sense->ext.extended.info[0] <<24)|
                   1612:                                        (sense->ext.extended.info[1] <<16)|
                   1613:                                        (sense->ext.extended.info[2] <<8)|
                   1614:                                        (sense->ext.extended.info[3] ));
                   1615:                                }
                   1616:                                else
                   1617:                                {
                   1618:                                        printf("\n");
                   1619:                                }
                   1620:                        }
                   1621:                        return(EIO);
                   1622:                case    0x4:
                   1623:                        if(!silent) printf("st%d: non-media hardware failure\n ",
                   1624:                                unit); 
                   1625:                        return(EIO);
                   1626:                case    0x5:
                   1627:                        if(!silent) printf("st%d: illegal request\n ", unit); 
                   1628:                        return(EINVAL);
                   1629:                case    0x6:
                   1630:                        if(!silent) printf("st%d: Unit attention.\n ", unit); 
                   1631:                        st_data[unit].flags &= ~(ST_AT_FILEMARK|ST_AT_EOM);
                   1632:                        st_info_valid[unit] = FALSE;
                   1633:                        if (st_data[unit].flags & ST_OPEN) /* TEMP!!!! */
                   1634:                                return(EIO);
                   1635:                        else
                   1636:                                return(ESUCCESS);
                   1637:                case    0x7:
                   1638:                        if(!silent)
                   1639:                        {
                   1640:                                printf("st%d: attempted protection violation "
                   1641:                                                                , unit); 
                   1642:                                if(sense->valid)
                   1643:                                {
                   1644:                                        printf("block no. %d (decimal)\n",
                   1645:                                        (sense->ext.extended.info[0] <<24)|
                   1646:                                        (sense->ext.extended.info[1] <<16)|
                   1647:                                        (sense->ext.extended.info[2] <<8)|
                   1648:                                        (sense->ext.extended.info[3] ));
                   1649:                                }
                   1650:                                else
                   1651:                                {
                   1652:                                        printf("\n");
                   1653:                                }
                   1654:                        }
                   1655:                        return(EACCES);
                   1656:                case    0x8:
                   1657:                        if(!silent)
                   1658:                        {
                   1659:                                printf("st%d: block wrong state (worm)\n "
                   1660:                                                        , unit); 
                   1661:                                if(sense->valid)
                   1662:                                {
                   1663:                                        printf("block no. %d (decimal)\n",
                   1664:                                        (sense->ext.extended.info[0] <<24)|
                   1665:                                        (sense->ext.extended.info[1] <<16)|
                   1666:                                        (sense->ext.extended.info[2] <<8)|
                   1667:                                        (sense->ext.extended.info[3] ));
                   1668:                                }
                   1669:                                else
                   1670:                                {
                   1671:                                        printf("\n");
                   1672:                                }
                   1673:                        }
                   1674:                        return(EIO);
                   1675:                case    0x9:
                   1676:                        if(!silent) printf("st%d: vendor unique\n",
                   1677:                                unit); 
                   1678:                        return(EIO);
                   1679:                case    0xa:
                   1680:                        if(!silent) printf("st%d: copy aborted\n ",
                   1681:                                unit); 
                   1682:                        return(EIO);
                   1683:                case    0xb:
                   1684:                        if(!silent) printf("st%d: command aborted\n ",
                   1685:                                unit); 
                   1686:                        return(EIO);
                   1687:                case    0xc:
                   1688:                        if(!silent)
                   1689:                        {
                   1690:                                printf("st%d: search returned\n ", unit); 
                   1691:                                if(sense->valid)
                   1692:                                {
                   1693:                                        printf("block no. %d (decimal)\n",
                   1694:                                        (sense->ext.extended.info[0] <<24)|
                   1695:                                        (sense->ext.extended.info[1] <<16)|
                   1696:                                        (sense->ext.extended.info[2] <<8)|
                   1697:                                        (sense->ext.extended.info[3] ));
                   1698:                                }
                   1699:                                else
                   1700:                                {
                   1701:                                        printf("\n");
                   1702:                                }
                   1703:                        }
                   1704:                        return(ESUCCESS);
                   1705:                case    0xd:
                   1706:                        if(!silent) printf("st%d: volume overflow\n ",
                   1707:                                unit); 
                   1708:                        return(ENOSPC);
                   1709:                case    0xe:
                   1710:                        if(!silent)
                   1711:                        {
                   1712:                                printf("st%d: verify miscompare\n ", unit); 
                   1713:                                if(sense->valid)
                   1714:                                {
                   1715:                                        printf("block no. %d (decimal)\n",
                   1716:                                        (sense->ext.extended.info[0] <<24)|
                   1717:                                        (sense->ext.extended.info[1] <<16)|
                   1718:                                        (sense->ext.extended.info[2] <<8)|
                   1719:                                        (sense->ext.extended.info[3] ));
                   1720:                                }
                   1721:                                else
                   1722:                                {
                   1723:                                        printf("\n");
                   1724:                                }
                   1725:                        }
                   1726:                        return(EIO);
                   1727:                case    0xf:
                   1728:                        if(!silent) printf("st%d: unknown error key\n ",
                   1729:                                unit); 
                   1730:                        return(EIO);
                   1731:                }
                   1732:                break;
                   1733:        }
                   1734:        /***************************************************************\
                   1735:        * If it's NOT class 7, just report it.                          *
                   1736:        \***************************************************************/
                   1737:        case 0:
                   1738:        case 1:
                   1739:        case 2:
                   1740:        case 3:
                   1741:        case 4:
                   1742:        case 5:
                   1743:        case 6:
                   1744:                {
                   1745:                        if(!silent) printf("st%d: error class %d code %d\n",
                   1746:                                unit,
                   1747:                                sense->error_class,
                   1748:                                sense->error_code);
                   1749:                if(sense->valid)
                   1750:                        if(!silent) printf("block no. %d (decimal)\n",
                   1751:                        (sense->ext.unextended.blockhi <<16),
                   1752:                        + (sense->ext.unextended.blockmed <<8),
                   1753:                        + (sense->ext.unextended.blocklow ));
                   1754:                }
                   1755:                return(EIO);
                   1756:        }
                   1757: }
                   1758: 
                   1759: #if defined(OSF)
                   1760: 
                   1761: stsize(dev_t dev)
                   1762: {
                   1763:     printf("stsize()        -- not implemented\n");
                   1764:     return(0);
                   1765: }
                   1766: 
                   1767: stdump()
                   1768: {
                   1769:     printf("stdump()        -- not implemented\n");
                   1770:     return(-1);
                   1771: }
                   1772: 
                   1773: #endif /* defined(OSF) */
                   1774: 

unix.superglobalmegacorp.com

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