Annotation of Net2/scsi/sd.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:  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
                     16:  * --------------------         -----   ----------------------
                     17:  * CURRENT PATCH LEVEL:         1       00098
                     18:  * --------------------         -----   ----------------------
                     19:  *
                     20:  * 16 Feb 93   Julian Elischer         ADDED for SCSI system
                     21:  *
                     22:  */
                     23: 
                     24: /*
                     25:  * Ported to run under 386BSD by Julian Elischer ([email protected]) Sept 1992
                     26:  */
                     27: 
                     28: #define SPLSD splbio
                     29: #define ESUCCESS 0
                     30: #include <sd.h>
                     31: #include <sys/types.h>
                     32: #include <sys/param.h>
                     33: #include <sys/dkbad.h>
                     34: #include <sys/systm.h>
                     35: #include <sys/conf.h>
                     36: #include <sys/file.h>
                     37: #include <sys/stat.h>
                     38: #include <sys/ioctl.h>
                     39: #include <sys/buf.h>
                     40: #include <sys/uio.h>
                     41: #include <sys/malloc.h>
                     42: #include <sys/errno.h>
                     43: #include <sys/disklabel.h>
                     44: #include <scsi/scsi_all.h>
                     45: #include <scsi/scsi_disk.h>
                     46: #include <scsi/scsiconf.h>
                     47: 
                     48: long int sdstrats,sdqueues;
                     49: 
                     50: 
                     51: #ifdef DDB
                     52: int    Debugger();
                     53: #else  
                     54: #define Debugger()
                     55: #endif
                     56: 
                     57: 
                     58: #define PAGESIZ        4096
                     59: #define SECSIZE 512
                     60: #define PDLOCATION     29      
                     61: #define BOOTRECORDSIGNATURE                    (0x55aa & 0x00ff)
                     62: #define        SDOUTSTANDING   2
                     63: #define SDQSIZE                4
                     64: #define        SD_RETRIES      4
                     65: 
                     66: #define MAKESDDEV(maj, unit, part)     (makedev(maj,((unit<<3)+part)))
                     67: #define        UNITSHIFT       3
                     68: #define PARTITION(z)   (minor(z) & 0x07)
                     69: #define        RAW_PART        3
                     70: #define UNIT(z)                (  (minor(z) >> UNITSHIFT) )
                     71: 
                     72: #define WHOLE_DISK(unit) ( (unit << UNITSHIFT) + RAW_PART )
                     73: 
                     74: struct buf sd_buf_queue[NSD];
                     75: int    sd_done();
                     76: int    sdstrategy();
                     77: 
                     78: int    sd_debug = 0;
                     79: 
                     80: struct scsi_xfer       *sd_free_xfer[NSD];
                     81: int                    sd_xfer_block_wait[NSD];
                     82: 
                     83: struct sd_data
                     84: {
                     85:        int     flags;
                     86: #define        SDVALID         0x02            /* PARAMS LOADED        */
                     87: #define        SDINIT          0x04            /* device has been init'd */
                     88: #define        SDWAIT          0x08            /* device has someone waiting */
                     89: #define SDHAVELABEL    0x10            /* have read the label */
                     90: #define SDDOSPART      0x20            /* Have read the DOS partition table */
                     91: #define SDWRITEPROT    0x40            /* Device in readonly mode (S/W)*/
                     92:        struct  scsi_switch *sc_sw;     /* address of scsi low level switch */
                     93:        int     ctlr;                   /* so they know which one we want */
                     94:        int     targ;                   /* our scsi target ID */
                     95:        int     lu;                     /* out scsi lu */
                     96:        long int        ad_info;        /* info about the adapter */
                     97:        int     cmdscount;              /* cmds allowed outstanding by board*/
                     98:        int     wlabel;                 /* label is writable */
                     99:        struct  disk_parms
                    100:        {
                    101:                u_char  heads;          /* Number of heads */
                    102:                u_short cyls;           /* Number of cylinders */
                    103:                u_char  sectors;/*dubious*/     /* Number of sectors/track */
                    104:                u_short secsiz;         /* Number of bytes/sector */
                    105:                u_long  disksize;               /* total number sectors */
                    106:        }params;
                    107:        struct  disklabel       disklabel;
                    108:        struct  dos_partition dosparts[NDOSPART]; /* DOS view of disk */
                    109:        int     partflags[MAXPARTITIONS];       /* per partition flags */
                    110: #define SDOPEN 0x01
                    111:        int             openparts;              /* one bit for each open partition */
                    112:        unsigned int    sd_start_of_unix;       /* unix vs dos partitions */
                    113: }sd_data[NSD];
                    114: 
                    115: 
                    116: static int     next_sd_unit = 0;
                    117: /***********************************************************************\
                    118: * The routine called by the low level scsi routine when it discovers   *
                    119: * A device suitable for this driver                                    *
                    120: \***********************************************************************/
                    121: 
                    122: int    sdattach(ctlr,targ,lu,scsi_switch)
                    123: struct scsi_switch *scsi_switch;
                    124: {
                    125:        int     unit,i;
                    126:        unsigned char *tbl;
                    127:        struct sd_data *sd;
                    128:        struct disk_parms *dp;
                    129:        long int        ad_info;
                    130:        struct  scsi_xfer       *sd_scsi_xfer;
                    131: 
                    132:        unit = next_sd_unit++;
                    133:        sd = sd_data + unit;
                    134:        dp  = &(sd->params);
                    135:        if(scsi_debug & PRINTROUTINES) printf("sdattach: "); 
                    136:        /*******************************************************\
                    137:        * Check we have the resources for another drive         *
                    138:        \*******************************************************/
                    139:        if( unit >= NSD)
                    140:        {
                    141:                printf("Too many scsi disks..(%d > %d) reconfigure kernel",(unit + 1),NSD);
                    142:                return(0);
                    143:        }
                    144:        /*******************************************************\
                    145:        * Store information needed to contact our base driver   *
                    146:        \*******************************************************/
                    147:        sd->sc_sw       =       scsi_switch;
                    148:        sd->ctlr        =       ctlr;
                    149:        sd->targ        =       targ;
                    150:        sd->lu          =       lu;
                    151:        if(sd->sc_sw->adapter_info)
                    152:        {
                    153:                sd->ad_info = ( (*(sd->sc_sw->adapter_info))(ctlr));
                    154:                sd->cmdscount = sd->ad_info & AD_INF_MAX_CMDS;
                    155:                if(sd->cmdscount > SDOUTSTANDING)
                    156:                {
                    157:                        sd->cmdscount = SDOUTSTANDING;
                    158:                }
                    159:        }
                    160:        else
                    161:        {
                    162:                sd->ad_info = 1;
                    163:                sd->cmdscount = 1;
                    164:        }
                    165: 
                    166:        i = sd->cmdscount;
                    167:        sd_scsi_xfer = (struct scsi_xfer *)malloc(sizeof(struct scsi_xfer) * i
                    168:                                ,M_TEMP, M_NOWAIT);
                    169:        while(i-- )
                    170:        {
                    171:                sd_scsi_xfer->next = sd_free_xfer[unit];
                    172:                sd_free_xfer[unit] = sd_scsi_xfer;
                    173:                sd_scsi_xfer++;
                    174:        }
                    175:        /*******************************************************\
                    176:        * Use the subdriver to request information regarding    *
                    177:        * the drive. We cannot use interrupts yet, so the       *
                    178:        * request must specify this.                            *
                    179:        \*******************************************************/
                    180:        sd_get_parms(unit,  SCSI_NOSLEEP |  SCSI_NOMASK);
                    181:        printf("        sd%d: %dMB, cyls %d, heads %d, secs %d, bytes/sec %d\n",
                    182:                unit,
                    183:                (         dp->cyls 
                    184:                        * dp->heads 
                    185:                        * dp->sectors
                    186:                        * dp->secsiz
                    187:                )
                    188:                / (1024 * 1024),
                    189:                dp->cyls,
                    190:                dp->heads,
                    191:                dp->sectors,
                    192:                dp->secsiz);
                    193:        /*******************************************************\
                    194:        * Set up the bufs for this device                       *
                    195:        \*******************************************************/
                    196:        sd->flags |= SDINIT;
                    197:        return;
                    198: 
                    199: }
                    200: 
                    201: 
                    202: 
                    203: /*******************************************************\
                    204: *      open the device. Make sure the partition info   *
                    205: * is a up-to-date as can be.                           *
                    206: \*******************************************************/
                    207: sdopen(dev)
                    208: {
                    209:        int errcode = 0;
                    210:        int unit, part;
                    211:        struct disk_parms disk_parms;
                    212:        struct sd_data *sd ;
                    213: 
                    214:        unit = UNIT(dev);
                    215:        part = PARTITION(dev);
                    216:        sd = sd_data + unit;
                    217:        if(scsi_debug & (PRINTROUTINES | TRACEOPENS))
                    218:                printf("sdopen: dev=0x%x (unit %d (of %d),partition %d)\n"
                    219:                                ,   dev,      unit,   NSD,         part);
                    220:        /*******************************************************\
                    221:        * Check the unit is legal                               *
                    222:        \*******************************************************/
                    223:        if ( unit >= NSD )
                    224:        {
                    225:                return(ENXIO);
                    226:        }
                    227:        /*******************************************************\
                    228:        * Make sure the disk has been initialised               *
                    229:        * At some point in the future, get the scsi driver      *
                    230:        * to look for a new device if we are not initted        *
                    231:        \*******************************************************/
                    232:        if (! (sd->flags & SDINIT))
                    233:        {
                    234:                return(ENXIO);
                    235:        }
                    236: 
                    237:        /*******************************************************\
                    238:        * If it's been invalidated, and not everybody has       *
                    239:        * closed it then forbid re-entry.                       *
                    240:        \*******************************************************/
                    241:        if ((! (sd->flags & SDVALID))
                    242:           && ( sd->openparts))
                    243:                return(ENXIO);
                    244:        /*******************************************************\
                    245:        * Check that it is still responding and ok.             *
                    246:        * "unit attention errors should occur here if the drive *
                    247:        * has been restarted or the pack changed                *
                    248:        \*******************************************************/
                    249: 
                    250:        if(scsi_debug & TRACEOPENS)
                    251:                printf("device is ");
                    252:        if (sd_test_unit_ready(unit,0))
                    253:        {
                    254:                if(scsi_debug & TRACEOPENS) printf("not reponding\n");
                    255:                return(ENXIO);
                    256:        }
                    257:        if(scsi_debug & TRACEOPENS)
                    258:                printf("ok\n");
                    259:        /*******************************************************\
                    260:        * In case it is a funny one, tell it to start           *
                    261:        * not needed for  most hard drives (ignore failure)     *
                    262:        \*******************************************************/
                    263:        sd_start_unit(unit,SCSI_ERR_OK|SCSI_SILENT);
                    264:        if(scsi_debug & TRACEOPENS)
                    265:                printf("started ");
                    266:        /*******************************************************\
                    267:        * Load the physical device parameters                   *
                    268:        \*******************************************************/
                    269:        sd_get_parms(unit, 0);  /* sets SDVALID */
                    270:        if (sd->params.secsiz != SECSIZE)
                    271:        {
                    272:                printf("sd%d: Can't deal with %d bytes logical blocks\n"
                    273:                        ,unit, sd->params.secsiz);
                    274:                Debugger();
                    275:                return(ENXIO);
                    276:        }
                    277:        if(scsi_debug & TRACEOPENS)
                    278:                printf("Params loaded ");
                    279:        /*******************************************************\
                    280:        * Load the partition info if not already loaded         *
                    281:        \*******************************************************/
                    282:        sd_prevent(unit,PR_PREVENT,SCSI_ERR_OK|SCSI_SILENT); /* who cares if it fails? */
                    283:        if((errcode = sdgetdisklabel(unit)) && (part != RAW_PART))
                    284:        {
                    285:                sd_prevent(unit,PR_ALLOW,SCSI_ERR_OK|SCSI_SILENT); /* who cares if it fails? */
                    286:                return(errcode);
                    287:        }
                    288:        if(scsi_debug & TRACEOPENS)
                    289:                printf("Disklabel loaded ");
                    290:        /*******************************************************\
                    291:        * Check the partition is legal                          *
                    292:        \*******************************************************/
                    293:        if ( part >= MAXPARTITIONS ) {
                    294:                sd_prevent(unit,PR_ALLOW,SCSI_ERR_OK|SCSI_SILENT); /* who cares if it fails? */
                    295:                return(ENXIO);
                    296:        }
                    297:        if(scsi_debug & TRACEOPENS)
                    298:                printf("ok");
                    299:        /*******************************************************\
                    300:        *  Check that the partition exists                      *
                    301:        \*******************************************************/
                    302:        if (( sd->disklabel.d_partitions[part].p_size == 0 )
                    303:                && (part != RAW_PART))
                    304:        {
                    305:                sd_prevent(unit,PR_ALLOW,SCSI_ERR_OK|SCSI_SILENT); /* who cares if it fails? */
                    306:                return(ENXIO);
                    307:        }
                    308:        sd->partflags[part] |= SDOPEN;
                    309:        sd->openparts |= (1 << part);
                    310:        if(scsi_debug & TRACEOPENS)
                    311:                printf("open %d %d\n",sdstrats,sdqueues);
                    312:        return(0);
                    313: }
                    314: 
                    315: /*******************************************************\
                    316: * Get ownership of a scsi_xfer                         *
                    317: * If need be, sleep on it, until it comes free         *
                    318: \*******************************************************/
                    319: struct scsi_xfer *sd_get_xs(unit,flags)
                    320: int    flags;
                    321: int    unit;
                    322: {
                    323:        struct scsi_xfer *xs;
                    324:        int     s;
                    325: 
                    326:        if(flags & (SCSI_NOSLEEP |  SCSI_NOMASK))
                    327:        {
                    328:                if (xs = sd_free_xfer[unit])
                    329:                {
                    330:                        sd_free_xfer[unit] = xs->next;
                    331:                        xs->flags = 0;
                    332:                }
                    333:        }
                    334:        else
                    335:        {
                    336:                s = SPLSD();
                    337:                while (!(xs = sd_free_xfer[unit]))
                    338:                {
                    339:                        sd_xfer_block_wait[unit]++;  /* someone waiting! */
                    340:                        sleep((caddr_t)&sd_free_xfer[unit], PRIBIO+1);
                    341:                        sd_xfer_block_wait[unit]--;
                    342:                }
                    343:                sd_free_xfer[unit] = xs->next;
                    344:                splx(s);
                    345:                xs->flags = 0;
                    346:        }
                    347:        return(xs);
                    348: }
                    349: 
                    350: /*******************************************************\
                    351: * Free a scsi_xfer, wake processes waiting for it      *
                    352: \*******************************************************/
                    353: sd_free_xs(unit,xs,flags)
                    354: struct scsi_xfer *xs;
                    355: int    unit;
                    356: int    flags;
                    357: {
                    358:        int     s;
                    359:        
                    360:        if(flags & SCSI_NOMASK)
                    361:        {
                    362:                if (sd_xfer_block_wait[unit])
                    363:                {
                    364:                        printf("doing a wakeup from NOMASK mode\n");
                    365:                        wakeup((caddr_t)&sd_free_xfer[unit]);
                    366:                }
                    367:                xs->next = sd_free_xfer[unit];
                    368:                sd_free_xfer[unit] = xs;
                    369:        }
                    370:        else
                    371:        {
                    372:                s = SPLSD();
                    373:                if (sd_xfer_block_wait[unit])
                    374:                        wakeup((caddr_t)&sd_free_xfer[unit]);
                    375:                xs->next = sd_free_xfer[unit];
                    376:                sd_free_xfer[unit] = xs;
                    377:                splx(s);
                    378:        }
                    379: }
                    380: 
                    381: /*******************************************************\
                    382: * trim the size of the transfer if needed,             *
                    383: * called by physio                                     *
                    384: * basically the smaller of our max and the scsi driver's*
                    385: * minphys (note we have no max)                                *
                    386: \*******************************************************/
                    387: /* Trim buffer length if buffer-size is bigger than page size */
                    388: void   sdminphys(bp)
                    389: struct buf     *bp;
                    390: {
                    391:        (*(sd_data[UNIT(bp->b_dev)].sc_sw->scsi_minphys))(bp);
                    392: }
                    393: 
                    394: /*******************************************************\
                    395: * Actually translate the requested transfer into       *
                    396: * one the physical driver can understand               *
                    397: * The transfer is described by a buf and will include  *
                    398: * only one physical transfer.                          *
                    399: \*******************************************************/
                    400: 
                    401: int    sdstrategy(bp)
                    402: struct buf     *bp;
                    403: {
                    404:        struct  buf     *dp;
                    405:        unsigned int opri;
                    406:        struct sd_data *sd ;
                    407:        int     unit;
                    408: 
                    409:        sdstrats++;
                    410:        unit = UNIT((bp->b_dev));
                    411:        sd = sd_data + unit;
                    412:        if(scsi_debug & PRINTROUTINES) printf("\nsdstrategy ");
                    413:        if(scsi_debug & SHOWREQUESTS) printf("sd%d: %d bytes @ blk%d\n",
                    414:                                        unit,bp->b_bcount,bp->b_blkno);
                    415:        sdminphys(bp);
                    416:        /*******************************************************\
                    417:        * If the device has been made invalid, error out        *
                    418:        \*******************************************************/
                    419:        if(!(sd->flags & SDVALID))
                    420:        {
                    421:                bp->b_error = EIO;
                    422:                goto bad;
                    423:        }
                    424:        /*******************************************************\
                    425:        * "soft" write protect check                            *
                    426:        \*******************************************************/
                    427:        if ((sd->flags & SDWRITEPROT) && (bp->b_flags & B_READ) == 0) {
                    428:                bp->b_error = EROFS;
                    429:                goto bad;
                    430:        }
                    431:        /*******************************************************\
                    432:        * If it's a null transfer, return immediatly            *
                    433:        \*******************************************************/
                    434:        if (bp->b_bcount == 0)
                    435:        {
                    436:                goto done;
                    437:        }
                    438: 
                    439:        /*******************************************************\
                    440:        * Decide which unit and partition we are talking about  *
                    441:        * only raw is ok if no label                            *
                    442:        \*******************************************************/
                    443:        if(PARTITION(bp->b_dev) != RAW_PART)
                    444:        {
                    445:                if (!(sd->flags & SDHAVELABEL))
                    446:                {
                    447:                        bp->b_error = EIO;
                    448:                        goto bad;
                    449:                }
                    450: 
                    451:                /*
                    452:                 * do bounds checking, adjust transfer. if error, process.
                    453:                 * if end of partition, just return
                    454:                 */
                    455:                if (bounds_check_with_label(bp,&sd->disklabel,sd->wlabel) <= 0)
                    456:                        goto done;
                    457:                /* otherwise, process transfer request */
                    458:        }
                    459: 
                    460:        opri = SPLSD();
                    461:        dp = &sd_buf_queue[unit];
                    462: 
                    463:        /*******************************************************\
                    464:        * Place it in the queue of disk activities for this disk*
                    465:        \*******************************************************/
                    466:        disksort(dp, bp);
                    467: 
                    468:        /*******************************************************\
                    469:        * Tell the device to get going on the transfer if it's  *
                    470:        * not doing anything, otherwise just wait for completion*
                    471:        \*******************************************************/
                    472:        sdstart(unit);
                    473: 
                    474:        splx(opri);
                    475:        return;
                    476: bad:
                    477:        bp->b_flags |= B_ERROR;
                    478: done:
                    479: 
                    480:        /*******************************************************\
                    481:        * Correctly set the buf to indicate a completed xfer    *
                    482:        \*******************************************************/
                    483:        bp->b_resid = bp->b_bcount;
                    484:        biodone(bp);
                    485:        return;
                    486: }
                    487: 
                    488: /***************************************************************\
                    489: * sdstart looks to see if there is a buf waiting for the device        *
                    490: * and that the device is not already busy. If both are true,   *
                    491: * It deques the buf and creates a scsi command to perform the  *
                    492: * transfer in the buf. The transfer request will call sd_done  *
                    493: * on completion, which will in turn call this routine again    *
                    494: * so that the next queued transfer is performed.               *
                    495: * The bufs are queued by the strategy routine (sdstrategy)     *
                    496: *                                                              *
                    497: * This routine is also called after other non-queued requests  *
                    498: * have been made of the scsi driver, to ensure that the queue  *
                    499: * continues to be drained.                                     *
                    500: *                                                              *
                    501: * must be called at the correct (highish) spl level            *
                    502: \***************************************************************/
                    503: /* sdstart() is called at SPLSD  from sdstrategy and sd_done*/
                    504: sdstart(unit)
                    505: int    unit;
                    506: {
                    507:        int                     drivecount;
                    508:        register struct buf     *bp = 0;
                    509:        register struct buf     *dp;
                    510:        struct  scsi_xfer       *xs;
                    511:        struct  scsi_rw_big     cmd;
                    512:        int                     blkno, nblk;
                    513:        struct sd_data *sd = sd_data + unit;
                    514:        struct partition *p ;
                    515: 
                    516:        if(scsi_debug & PRINTROUTINES) printf("sdstart%d ",unit);
                    517:        /*******************************************************\
                    518:        * See if there is a buf to do and we are not already    *
                    519:        * doing one                                             *
                    520:        \*******************************************************/
                    521:        if(!sd_free_xfer[unit])
                    522:        {
                    523:                return;    /* none for us, unit already underway */
                    524:        }
                    525: 
                    526:        if(sd_xfer_block_wait[unit])    /* there is one, but a special waits */
                    527:        {
                    528:                return; /* give the special that's waiting a chance to run */
                    529:        }
                    530: 
                    531: 
                    532:        dp = &sd_buf_queue[unit];
                    533:        if ((bp = dp->b_actf) != NULL)  /* yes, an assign */
                    534:        {
                    535:                dp->b_actf = bp->av_forw;
                    536:        }
                    537:        else
                    538:        { 
                    539:                return;
                    540:        }
                    541: 
                    542:        xs=sd_get_xs(unit,0);   /* ok we can grab it */
                    543:        xs->flags = INUSE;    /* Now ours */
                    544:        /*******************************************************\
                    545:        *  If the device has become invalid, abort all the      *
                    546:        * reads and writes until all files have been closed and *
                    547:        * re-openned                                            *
                    548:        \*******************************************************/
                    549:        if(!(sd->flags & SDVALID))
                    550:        {
                    551:                xs->error = XS_DRIVER_STUFFUP;
                    552:                sd_done(unit,xs);  /* clean up (calls sdstart) */
                    553:                return ;
                    554:        }
                    555:        /*******************************************************\
                    556:        * We have a buf, now we should move the data into       *
                    557:        * a scsi_xfer definition and try start it               *
                    558:        \*******************************************************/
                    559:        /*******************************************************\
                    560:        *  First, translate the block to absolute               *
                    561:        \*******************************************************/
                    562:        p = sd->disklabel.d_partitions + PARTITION(bp->b_dev);
                    563:        blkno = bp->b_blkno + p->p_offset;
                    564:        nblk = (bp->b_bcount + 511) >> 9;
                    565: 
                    566:        /*******************************************************\
                    567:        *  Fill out the scsi command                            *
                    568:        \*******************************************************/
                    569:        bzero(&cmd, sizeof(cmd));
                    570:        cmd.op_code             =       (bp->b_flags & B_READ) 
                    571:                                                ? READ_BIG : WRITE_BIG;
                    572:        cmd.addr_3      =       (blkno & 0xff000000) >> 24;
                    573:        cmd.addr_2      =       (blkno & 0xff0000) >> 16;
                    574:        cmd.addr_1      =       (blkno & 0xff00) >> 8;
                    575:        cmd.addr_0      =       blkno & 0xff;
                    576:        cmd.length2     =       (nblk & 0xff00) >> 8;
                    577:        cmd.length1     =       (nblk & 0xff);
                    578:        /*******************************************************\
                    579:        * Fill out the scsi_xfer structure                      *
                    580:        *       Note: we cannot sleep as we may be an interrupt *
                    581:        \*******************************************************/
                    582:        xs->flags       |=      SCSI_NOSLEEP;
                    583:        xs->adapter     =       sd->ctlr;
                    584:        xs->targ        =       sd->targ;
                    585:        xs->lu          =       sd->lu;
                    586:        xs->retries     =       SD_RETRIES;
                    587:        xs->timeout     =       10000;/* 10000 millisecs for a disk !*/
                    588:        xs->cmd         =       (struct scsi_generic *)&cmd;
                    589:        xs->cmdlen      =       sizeof(cmd);
                    590:        xs->resid       =       bp->b_bcount;
                    591:        xs->when_done   =       sd_done;
                    592:        xs->done_arg    =       unit;
                    593:        xs->done_arg2   =       (int)xs;
                    594:        xs->error       =       XS_NOERROR;
                    595:        xs->bp          =       bp;
                    596:        xs->data        =       (u_char *)bp->b_un.b_addr;
                    597:        xs->datalen     =       bp->b_bcount;
                    598:        /*******************************************************\
                    599:        * Pass all this info to the scsi driver.                *
                    600:        \*******************************************************/
                    601: 
                    602: 
                    603: 
                    604:        if ( (*(sd->sc_sw->scsi_cmd))(xs) != SUCCESSFULLY_QUEUED)
                    605:        {
                    606:                printf("sd%d: oops not queued",unit);
                    607:                xs->error = XS_DRIVER_STUFFUP;
                    608:                sd_done(unit,xs);  /* clean up (calls sdstart) */
                    609:        }
                    610:        sdqueues++;
                    611: }
                    612: 
                    613: /*******************************************************\
                    614: * This routine is called by the scsi interrupt when    *
                    615: * the transfer is complete.
                    616: \*******************************************************/
                    617: int    sd_done(unit,xs)
                    618: int    unit;
                    619: struct scsi_xfer       *xs;
                    620: {
                    621:        struct  buf             *bp;
                    622:        int     retval;
                    623:        int     retries = 0;
                    624: 
                    625:        if(scsi_debug & PRINTROUTINES) printf("sd_done%d ",unit);
                    626:        if (! (xs->flags & INUSE))
                    627:                panic("scsi_xfer not in use!");
                    628:        if(bp = xs->bp)
                    629:        {
                    630:                switch(xs->error)
                    631:                {
                    632:                case    XS_NOERROR:
                    633:                        bp->b_error = 0;
                    634:                        bp->b_resid = 0;
                    635:                        break;
                    636: 
                    637:                case    XS_SENSE:
                    638:                        retval = (sd_interpret_sense(unit,xs));
                    639:                        if(retval)
                    640:                        {
                    641:                                bp->b_flags |= B_ERROR;
                    642:                                bp->b_error = retval;
                    643:                        }
                    644:                        break;
                    645: 
                    646:                case    XS_TIMEOUT:
                    647:                        printf("sd%d timeout\n",unit);
                    648: 
                    649:                case    XS_BUSY:        /* should retry */ /* how? */
                    650:                        /************************************************/
                    651:                        /* SHOULD put buf back at head of queue         */
                    652:                        /* and decrement retry count in (*xs)           */
                    653:                        /* HOWEVER, this should work as a kludge        */
                    654:                        /************************************************/
                    655:                        if(xs->retries--)
                    656:                        {
                    657:                                xs->error = XS_NOERROR;
                    658:                                xs->flags &= ~ITSDONE;
                    659:                                if ( (*(sd_data[unit].sc_sw->scsi_cmd))(xs)
                    660:                                        == SUCCESSFULLY_QUEUED)
                    661:                                {       /* don't wake the job, ok? */
                    662:                                        return;
                    663:                                }
                    664:                                xs->flags |= ITSDONE;
                    665:                        } /* fall through */
                    666: 
                    667:                case    XS_DRIVER_STUFFUP:
                    668:                        bp->b_flags |= B_ERROR;
                    669:                        bp->b_error = EIO;
                    670:                        break;
                    671:                default:
                    672:                        printf("sd%d: unknown error category from scsi driver\n"
                    673:                                ,unit);
                    674:                }       
                    675:                biodone(bp);
                    676:                sd_free_xs(unit,xs,0);
                    677:                sdstart(unit);  /* If there's anything waiting.. do it */
                    678:        }
                    679:        else /* special has finished */
                    680:        {
                    681:                wakeup(xs);
                    682:        }
                    683: }
                    684: /*******************************************************\
                    685: * Perform special action on behalf of the user         *
                    686: * Knows about the internals of this device             *
                    687: \*******************************************************/
                    688: sdioctl(dev_t dev, int cmd, caddr_t addr, int flag)
                    689: {
                    690:        /* struct sd_cmd_buf *args;*/
                    691:        int error = 0;
                    692:        unsigned int opri;
                    693:        unsigned char unit, part;
                    694:        register struct sd_data *sd;
                    695: 
                    696: 
                    697:        /*******************************************************\
                    698:        * Find the device that the user is talking about        *
                    699:        \*******************************************************/
                    700:        unit = UNIT(dev);
                    701:        part = PARTITION(dev);
                    702:        sd = &sd_data[unit];
                    703:        if(scsi_debug & PRINTROUTINES) printf("sdioctl%d ",unit);
                    704: 
                    705:        /*******************************************************\
                    706:        * If the device is not valid.. abandon ship             *
                    707:        \*******************************************************/
                    708:        if (!(sd_data[unit].flags & SDVALID))
                    709:                return(EIO);
                    710:        switch(cmd)
                    711:        {
                    712: 
                    713:        case DIOCSBAD:
                    714:                         error = EINVAL;
                    715:                break;
                    716: 
                    717:        case DIOCGDINFO:
                    718:                *(struct disklabel *)addr = sd->disklabel;
                    719:                break;
                    720: 
                    721:         case DIOCGPART:
                    722:                 ((struct partinfo *)addr)->disklab = &sd->disklabel;
                    723:                 ((struct partinfo *)addr)->part =
                    724:                     &sd->disklabel.d_partitions[PARTITION(dev)];
                    725:                 break;
                    726: 
                    727:         case DIOCSDINFO:
                    728:                 if ((flag & FWRITE) == 0)
                    729:                         error = EBADF;
                    730:                 else
                    731:                         error = setdisklabel(&sd->disklabel,
                    732:                                        (struct disklabel *)addr,
                    733:                          /*(sd->flags & DKFL_BSDLABEL) ? sd->openparts : */0,
                    734:                                sd->dosparts);
                    735:                 if (error == 0) {
                    736:                        sd->flags |= SDHAVELABEL;
                    737:                }
                    738:                 break;
                    739: 
                    740:         case DIOCWLABEL:
                    741:                sd->flags &= ~SDWRITEPROT;
                    742:                 if ((flag & FWRITE) == 0)
                    743:                         error = EBADF;
                    744:                 else
                    745:                         sd->wlabel = *(int *)addr;
                    746:                 break;
                    747: 
                    748:         case DIOCWDINFO:
                    749:                sd->flags &= ~SDWRITEPROT;
                    750:                 if ((flag & FWRITE) == 0)
                    751:                         error = EBADF;
                    752:                 else
                    753:                {
                    754:                        if ((error = setdisklabel(&sd->disklabel
                    755:                                                , (struct disklabel *)addr
                    756:                        , /*(sd->flags & SDHAVELABEL) ? sd->openparts :*/ 0
                    757:                                                , sd->dosparts)) == 0)
                    758:                        {
                    759:                                int wlab;
                    760: 
                    761:                                sd->flags |= SDHAVELABEL; /* ok write will succeed */
                    762: 
                    763:                                /* simulate opening partition 0 so write succeeds */
                    764:                                sd->openparts |= (1 << 0);            /* XXX */
                    765:                                wlab = sd->wlabel;
                    766:                                sd->wlabel = 1;
                    767:                                error = writedisklabel(dev, sdstrategy,
                    768:                                        &sd->disklabel, sd->dosparts);
                    769:                                sd->wlabel = wlab;
                    770:                        }
                    771:                }
                    772:                 break;
                    773: 
                    774: 
                    775:        default:
                    776:                error = ENOTTY;
                    777:                break;
                    778:        }
                    779:        return (error);
                    780: }
                    781: 
                    782: 
                    783: /*******************************************************\
                    784: * Load the label information on the named device       *
                    785: \*******************************************************/
                    786: int sdgetdisklabel(unit)
                    787: unsigned char  unit;
                    788: {
                    789:        /*unsigned int n, m;*/
                    790:        char *errstring;
                    791:        struct dos_partition *dos_partition_p;
                    792:        struct sd_data *sd = sd_data + unit;
                    793: 
                    794:        /*******************************************************\
                    795:        * If the inflo is already loaded, use it                *
                    796:        \*******************************************************/
                    797:        if(sd->flags & SDHAVELABEL) return(ESUCCESS);
                    798: 
                    799:        bzero(&sd->disklabel,sizeof(struct disklabel));
                    800:        /*******************************************************\
                    801:        * make partition 3 the whole disk in case of failure    *
                    802:        *   then get pdinfo                                     *
                    803:        \*******************************************************/
                    804:        sd->disklabel.d_partitions[0].p_offset = 0;
                    805:        sd->disklabel.d_partitions[0].p_size = sd->params.disksize;
                    806:        sd->disklabel.d_partitions[RAW_PART].p_offset = 0;
                    807:        sd->disklabel.d_partitions[RAW_PART].p_size = sd->params.disksize;
                    808:        sd->disklabel.d_npartitions = MAXPARTITIONS;
                    809:        sd->disklabel.d_secsize = 512; /* as long as it's not 0 */
                    810:        sd->disklabel.d_ntracks = sd->params.heads;
                    811:        sd->disklabel.d_nsectors = sd->params.sectors;
                    812:        sd->disklabel.d_ncylinders = sd->params.cyls;
                    813:        sd->disklabel.d_secpercyl = sd->params.heads * sd->params.sectors;
                    814:        if (sd->disklabel.d_secpercyl == 0)
                    815:        {
                    816:                sd->disklabel.d_secpercyl = 100;
                    817:                                        /* as long as it's not 0 */
                    818:                                        /* readdisklabel divides by it */
                    819:        }
                    820: 
                    821:        /*******************************************************\
                    822:        * all the generic bisklabel extraction routine          *
                    823:        \*******************************************************/
                    824:        if(errstring = readdisklabel(makedev(0 ,(unit<<UNITSHIFT )+3)
                    825:                                        , sdstrategy
                    826:                                        , &sd->disklabel
                    827:                                        , sd->dosparts
                    828:                                        , 0
                    829:                                        , 0))
                    830:        {
                    831:                printf("sd%d: %s\n",unit, errstring);
                    832:                return(ENXIO);
                    833:        }
                    834:        /*******************************************************\
                    835:        * leave partition 2 "open" for raw I/O                  *
                    836:        \*******************************************************/
                    837: 
                    838:        sd->flags |= SDHAVELABEL; /* WE HAVE IT ALL NOW */
                    839:        return(ESUCCESS);
                    840: }
                    841: 
                    842: /*******************************************************\
                    843: * Find out from the device what it's capacity is       *
                    844: \*******************************************************/
                    845: sd_size(unit, flags)
                    846: {
                    847:        struct scsi_read_cap_data rdcap;
                    848:        struct scsi_read_capacity scsi_cmd;
                    849:        int size;
                    850: 
                    851:        /*******************************************************\
                    852:        * make up a scsi command and ask the scsi driver to do  *
                    853:        * it for you.                                           *
                    854:        \*******************************************************/
                    855:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                    856:        scsi_cmd.op_code = READ_CAPACITY;
                    857: 
                    858:        /*******************************************************\
                    859:        * If the command works, interpret the result as a 4 byte*
                    860:        * number of blocks                                      *
                    861:        \*******************************************************/
                    862:        if (sd_scsi_cmd(unit,
                    863:                        &scsi_cmd,
                    864:                        sizeof(scsi_cmd),
                    865:                        &rdcap,
                    866:                        sizeof(rdcap),  
                    867:                        2000,
                    868:                        flags) != 0)
                    869:        {
                    870:                printf("could not get size of unit %d\n", unit);
                    871:                return(0);
                    872:        } else {
                    873:                size = rdcap.addr_0 + 1 ;
                    874:                size += rdcap.addr_1 << 8;
                    875:                size += rdcap.addr_2 << 16;
                    876:                size += rdcap.addr_3 << 24;
                    877:        }
                    878:        return(size);
                    879: }
                    880:        
                    881: /*******************************************************\
                    882: * Get scsi driver to send a "are you ready?" command   *
                    883: \*******************************************************/
                    884: sd_test_unit_ready(unit,flags)
                    885: int    unit,flags;
                    886: {
                    887:        struct  scsi_test_unit_ready scsi_cmd;
                    888: 
                    889:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                    890:        scsi_cmd.op_code = TEST_UNIT_READY;
                    891: 
                    892:        return (sd_scsi_cmd(unit,
                    893:                        &scsi_cmd,
                    894:                        sizeof(scsi_cmd),
                    895:                        0,
                    896:                        0,
                    897:                        100000,
                    898:                        flags));
                    899: }
                    900: 
                    901: /*******************************************************\
                    902: * Prevent or allow the user to remove the tape         *
                    903: \*******************************************************/
                    904: sd_prevent(unit,type,flags)
                    905: int    unit,type,flags;
                    906: {
                    907:        struct  scsi_prevent    scsi_cmd;
                    908: 
                    909:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                    910:        scsi_cmd.op_code = PREVENT_ALLOW;
                    911:        scsi_cmd.prevent=type;
                    912:        return (sd_scsi_cmd(unit,
                    913:                        &scsi_cmd,
                    914:                        sizeof(scsi_cmd),
                    915:                        0,
                    916:                        0,
                    917:                        5000,
                    918:                        flags) );
                    919: }
                    920: /*******************************************************\
                    921: * Get scsi driver to send a "start up" command         *
                    922: \*******************************************************/
                    923: sd_start_unit(unit,flags)
                    924: int    unit,flags;
                    925: {
                    926:        struct scsi_start_stop scsi_cmd;
                    927: 
                    928:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                    929:        scsi_cmd.op_code = START_STOP;
                    930:        scsi_cmd.start = 1;
                    931: 
                    932:        return (sd_scsi_cmd(unit,
                    933:                        &scsi_cmd,
                    934:                        sizeof(scsi_cmd),
                    935:                        0,
                    936:                        0,
                    937:                        2000,
                    938:                        flags));
                    939: }
                    940: 
                    941: /*******************************************************\
                    942: * Tell the device to map out a defective block         *
                    943: \*******************************************************/
                    944: sd_reassign_blocks(unit,block)
                    945: {
                    946:        struct  scsi_reassign_blocks            scsi_cmd;
                    947:        struct  scsi_reassign_blocks_data       rbdata;
                    948: 
                    949: 
                    950:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                    951:        bzero(&rbdata, sizeof(rbdata));
                    952:        scsi_cmd.op_code = REASSIGN_BLOCKS;
                    953: 
                    954:        rbdata.length_msb = 0;
                    955:        rbdata.length_lsb = sizeof(rbdata.defect_descriptor[0]);
                    956:        rbdata.defect_descriptor[0].dlbaddr_3 = ((block >> 24) & 0xff);
                    957:        rbdata.defect_descriptor[0].dlbaddr_2 = ((block >> 16) & 0xff);
                    958:        rbdata.defect_descriptor[0].dlbaddr_1 = ((block >>  8) & 0xff);
                    959:        rbdata.defect_descriptor[0].dlbaddr_0 = ((block      ) & 0xff);
                    960: 
                    961:        return(sd_scsi_cmd(unit,
                    962:                        &scsi_cmd,
                    963:                        sizeof(scsi_cmd),
                    964:                        &rbdata,
                    965:                        sizeof(rbdata),
                    966:                        5000,
                    967:                        0));
                    968: }
                    969: 
                    970: #define b2tol(a)       (((unsigned)(a##_1) << 8) + (unsigned)a##_0 )
                    971: 
                    972: /*******************************************************\
                    973: * Get the scsi driver to send a full inquiry to the    *
                    974: * device and use the results to fill out the disk      *
                    975: * parameter structure.                                 *
                    976: \*******************************************************/
                    977: 
                    978: int    sd_get_parms(unit, flags)
                    979: {
                    980:        struct sd_data *sd = sd_data + unit;
                    981:        struct disk_parms *disk_parms = &sd->params;
                    982:        struct  scsi_mode_sense         scsi_cmd;
                    983:        struct  scsi_mode_sense_data
                    984:        {
                    985:                struct  scsi_mode_header        header;
                    986:                struct  blk_desc                blk_desc;
                    987:                union   disk_pages              pages;
                    988:        }scsi_sense;
                    989:        int sectors;
                    990: 
                    991:        /*******************************************************\
                    992:        * First check if we have it all loaded                  *
                    993:        \*******************************************************/
                    994:                if(sd->flags & SDVALID) return(0);
                    995:        /*******************************************************\
                    996:        * First do a mode sense page 3                          *
                    997:        \*******************************************************/
                    998:        if (sd_debug)
                    999:        {
                   1000:                bzero(&scsi_cmd, sizeof(scsi_cmd));
                   1001:                scsi_cmd.op_code = MODE_SENSE;
                   1002:                scsi_cmd.page_code = 3;
                   1003:                scsi_cmd.length = 0x24;
                   1004:                /*******************************************************\
                   1005:                * do the command, but we don't need the results         *
                   1006:                * just print them for our interest's sake               *
                   1007:                \*******************************************************/
                   1008:                if (sd_scsi_cmd(unit,
                   1009:                                &scsi_cmd,
                   1010:                                sizeof(scsi_cmd),
                   1011:                                &scsi_sense,
                   1012:                                sizeof(scsi_sense),
                   1013:                                2000,
                   1014:                                flags) != 0)
                   1015:                {
                   1016:                        printf("could not mode sense (3) for unit %d\n", unit);
                   1017:                        return(ENXIO);
                   1018:                } 
                   1019:                printf("unit %d: %d trk/zone, %d alt_sec/zone, %d alt_trk/zone, %d alt_trk/lun\n",
                   1020:                        unit,
                   1021:                        b2tol(scsi_sense.pages.disk_format.trk_z),
                   1022:                        b2tol(scsi_sense.pages.disk_format.alt_sec),
                   1023:                        b2tol(scsi_sense.pages.disk_format.alt_trk_z),
                   1024:                        b2tol(scsi_sense.pages.disk_format.alt_trk_v));
                   1025:                printf("         %d sec/trk, %d bytes/sec, %d interleave, %d %d bytes/log_blk\n",
                   1026:                        b2tol(scsi_sense.pages.disk_format.ph_sec_t),
                   1027:                        b2tol(scsi_sense.pages.disk_format.bytes_s),
                   1028:                        b2tol(scsi_sense.pages.disk_format.interleave),
                   1029:                        sd_size(unit, flags),
                   1030:                        _3btol(scsi_sense.blk_desc.blklen));
                   1031:        }
                   1032: 
                   1033: 
                   1034:        /*******************************************************\
                   1035:        * do a "mode sense page 4"                              *
                   1036:        \*******************************************************/
                   1037:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                   1038:        scsi_cmd.op_code = MODE_SENSE;
                   1039:        scsi_cmd.page_code = 4;
                   1040:        scsi_cmd.length = 0x20;
                   1041:        /*******************************************************\
                   1042:        * If the command worked, use the results to fill out    *
                   1043:        * the parameter structure                               *
                   1044:        \*******************************************************/
                   1045:        if (sd_scsi_cmd(unit,
                   1046:                        &scsi_cmd,
                   1047:                        sizeof(scsi_cmd),
                   1048:                        &scsi_sense,
                   1049:                        sizeof(scsi_sense),
                   1050:                        2000,
                   1051:                        flags) != 0)
                   1052:        {
                   1053:                printf("could not mode sense (4) for unit %d\n", unit);
                   1054:                printf(" using ficticious geometry\n");
                   1055:                /* use adaptec standard ficticious geometry */
                   1056:                sectors = sd_size(unit, flags);
                   1057:                disk_parms->heads = 64;
                   1058:                disk_parms->sectors = 32;
                   1059:                disk_parms->cyls = sectors/(64 * 32);
                   1060:                disk_parms->secsiz = SECSIZE;
                   1061:        } 
                   1062:        else
                   1063:        {
                   1064: 
                   1065:                if (sd_debug)
                   1066:                {
                   1067:                printf("         %d cyls, %d heads, %d precomp, %d red_write, %d land_zone\n",
                   1068:                        _3btol(&scsi_sense.pages.rigid_geometry.ncyl_2),
                   1069:                        scsi_sense.pages.rigid_geometry.nheads,
                   1070:                        b2tol(scsi_sense.pages.rigid_geometry.st_cyl_wp),
                   1071:                        b2tol(scsi_sense.pages.rigid_geometry.st_cyl_rwc),
                   1072:                        b2tol(scsi_sense.pages.rigid_geometry.land_zone));
                   1073:                }
                   1074: 
                   1075:                /*******************************************************\
                   1076:                * KLUDGE!!(for zone recorded disks)                     *
                   1077:                * give a number of sectors so that sec * trks * cyls    *
                   1078:                * is <= disk_size                                       *
                   1079:                \*******************************************************/
                   1080:                disk_parms->heads = scsi_sense.pages.rigid_geometry.nheads;
                   1081:                disk_parms->cyls = _3btol(&scsi_sense.pages.rigid_geometry.ncyl_2);
                   1082:                disk_parms->secsiz = _3btol(&scsi_sense.blk_desc.blklen);
                   1083: 
                   1084:                sectors = sd_size(unit, flags);
                   1085:                sectors /= disk_parms->cyls;
                   1086:                sectors /= disk_parms->heads;
                   1087:                disk_parms->sectors = sectors; /* dubious on SCSI*/
                   1088:        }
                   1089: 
                   1090:        sd->flags |= SDVALID;
                   1091:        return(0);
                   1092: }
                   1093: 
                   1094: /*******************************************************\
                   1095: * close the device.. only called if we are the LAST    *
                   1096: * occurence of an open device                          *
                   1097: \*******************************************************/
                   1098: sdclose(dev)
                   1099: dev_t dev;
                   1100: {
                   1101:        unsigned char unit, part;
                   1102:        unsigned int old_priority;
                   1103: 
                   1104:        unit = UNIT(dev);
                   1105:        part = PARTITION(dev);
                   1106:        sd_data[unit].partflags[part] &= ~SDOPEN;
                   1107:        sd_data[unit].openparts &= ~(1 << part);
                   1108:        if(sd_data[unit].openparts == 0) /* if all partitions closed */
                   1109:        {
                   1110:                sd_prevent(unit,PR_ALLOW,SCSI_SILENT|SCSI_ERR_OK);
                   1111:        }
                   1112:        return(0);
                   1113: }
                   1114: 
                   1115: /*******************************************************\
                   1116: * ask the scsi driver to perform a command for us.     *
                   1117: * Call it through the switch table, and tell it which  *
                   1118: * sub-unit we want, and what target and lu we wish to  *
                   1119: * talk to. Also tell it where to find the command      *
                   1120: * how long int is.                                     *
                   1121: * Also tell it where to read/write the data, and how   *
                   1122: * long the data is supposed to be                      *
                   1123: \*******************************************************/
                   1124: int    sd_scsi_cmd(unit,scsi_cmd,cmdlen,data_addr,datalen,timeout,flags)
                   1125: 
                   1126: int    unit,flags;
                   1127: struct scsi_generic *scsi_cmd;
                   1128: int    cmdlen;
                   1129: int    timeout;
                   1130: u_char *data_addr;
                   1131: int    datalen;
                   1132: {
                   1133:        struct  scsi_xfer *xs;
                   1134:        int     retval;
                   1135:        int     s;
                   1136:        struct sd_data *sd = sd_data + unit;
                   1137: 
                   1138:        if(scsi_debug & PRINTROUTINES) printf("\nsd_scsi_cmd%d ",unit);
                   1139:        if(sd->sc_sw)   /* If we have a scsi driver */
                   1140:        {
                   1141:                xs = sd_get_xs(unit,flags); /* should wait unless booting */
                   1142:                if(!xs)
                   1143:                {
                   1144:                        printf("sd_scsi_cmd%d: controller busy"
                   1145:                                        " (this should never happen)\n",unit); 
                   1146:                                return(EBUSY);
                   1147:                }
                   1148:                xs->flags |= INUSE;
                   1149:                /*******************************************************\
                   1150:                * Fill out the scsi_xfer structure                      *
                   1151:                \*******************************************************/
                   1152:                xs->flags       |=      flags;
                   1153:                xs->adapter     =       sd->ctlr;
                   1154:                xs->targ        =       sd->targ;
                   1155:                xs->lu          =       sd->lu;
                   1156:                xs->retries     =       SD_RETRIES;
                   1157:                xs->timeout     =       timeout;
                   1158:                xs->cmd         =       scsi_cmd;
                   1159:                xs->cmdlen      =       cmdlen;
                   1160:                xs->data        =       data_addr;
                   1161:                xs->datalen     =       datalen;
                   1162:                xs->resid       =       datalen;
                   1163:                xs->when_done   =       (flags & SCSI_NOMASK)
                   1164:                                        ?(int (*)())0
                   1165:                                        :sd_done;
                   1166:                xs->done_arg    =       unit;
                   1167:                xs->done_arg2   =       (int)xs;
                   1168: retry:         xs->error       =       XS_NOERROR;
                   1169:                xs->bp          =       0;
                   1170:                retval = (*(sd->sc_sw->scsi_cmd))(xs);
                   1171:                switch(retval)
                   1172:                {
                   1173:                case    SUCCESSFULLY_QUEUED:
                   1174:                        s = splbio();
                   1175:                        while(!(xs->flags & ITSDONE))
                   1176:                                sleep(xs,PRIBIO+1);
                   1177:                        splx(s);
                   1178: 
                   1179:                case    HAD_ERROR:
                   1180:                        /*printf("err = %d ",xs->error);*/
                   1181:                        switch(xs->error)
                   1182:                        {
                   1183:                        case    XS_NOERROR:
                   1184:                                retval = ESUCCESS;
                   1185:                                break;
                   1186:                        case    XS_SENSE:
                   1187:                                retval = (sd_interpret_sense(unit,xs));
                   1188:                                break;
                   1189:                        case    XS_DRIVER_STUFFUP:
                   1190:                                retval = EIO;
                   1191:                                break;
                   1192:                        case    XS_TIMEOUT:
                   1193:                                if(xs->retries-- )
                   1194:                                {
                   1195:                                        xs->flags &= ~ITSDONE;
                   1196:                                        goto retry;
                   1197:                                }
                   1198:                                retval = EIO;
                   1199:                                break;
                   1200:                        case    XS_BUSY:
                   1201:                                if(xs->retries-- )
                   1202:                                {
                   1203:                                        xs->flags &= ~ITSDONE;
                   1204:                                        goto retry;
                   1205:                                }
                   1206:                                retval = EIO;
                   1207:                                break;
                   1208:                        default:
                   1209:                                retval = EIO;
                   1210:                                printf("sd%d: unknown error category from scsi driver\n"
                   1211:                                        ,unit);
                   1212:                        }       
                   1213:                        break;
                   1214:                case    COMPLETE:
                   1215:                        retval = ESUCCESS;
                   1216:                        break;
                   1217:                case    TRY_AGAIN_LATER:
                   1218:                        if(xs->retries-- )
                   1219:                        {
                   1220:                                xs->flags &= ~ITSDONE;
                   1221:                                goto retry;
                   1222:                        }
                   1223:                        retval = EIO;
                   1224:                        break;
                   1225:                default:
                   1226:                        retval = EIO;
                   1227:                }
                   1228:                sd_free_xs(unit,xs,flags);
                   1229:                sdstart(unit);          /* check if anything is waiting fr the xs */
                   1230:        }
                   1231:        else
                   1232:        {
                   1233:                printf("sd%d: not set up\n",unit);
                   1234:                return(EINVAL);
                   1235:        }
                   1236:        return(retval);
                   1237: }
                   1238: /***************************************************************\
                   1239: * Look at the returned sense and act on the error and detirmine        *
                   1240: * The unix error number to pass back... (0 = report no error)  *
                   1241: \***************************************************************/
                   1242: 
                   1243: int    sd_interpret_sense(unit,xs)
                   1244: int    unit;
                   1245: struct scsi_xfer *xs;
                   1246: {
                   1247:        struct  scsi_sense_data *sense;
                   1248:        int     key;
                   1249:        int     silent;
                   1250: 
                   1251:        /***************************************************************\
                   1252:        * If the flags say errs are ok, then always return ok.          *
                   1253:        \***************************************************************/
                   1254:        if (xs->flags & SCSI_ERR_OK) return(ESUCCESS);
                   1255:        silent = (xs->flags & SCSI_SILENT);
                   1256: 
                   1257:        sense = &(xs->sense);
                   1258:        switch(sense->error_class)
                   1259:        {
                   1260:        case 7:
                   1261:                {
                   1262:                key=sense->ext.extended.sense_key;
                   1263:                switch(key)
                   1264:                {
                   1265:                case    0x0:
                   1266:                        return(ESUCCESS);
                   1267:                case    0x1:
                   1268:                        if(!silent)
                   1269:                        {
                   1270:                                printf("sd%d: soft error(corrected) ", unit); 
                   1271:                                if(sense->valid)
                   1272:                                {
                   1273:                                        printf("block no. %d (decimal)",
                   1274:                                        (sense->ext.extended.info[0] <<24),
                   1275:                                        (sense->ext.extended.info[1] <<16),
                   1276:                                        (sense->ext.extended.info[2] <<8),
                   1277:                                        (sense->ext.extended.info[3] ));
                   1278:                                }
                   1279:                                printf("\n");
                   1280:                        }
                   1281:                        return(ESUCCESS);
                   1282:                case    0x2:
                   1283:                        if(!silent)printf("sd%d: not ready\n ",
                   1284:                                unit); 
                   1285:                        return(ENODEV);
                   1286:                case    0x3:
                   1287:                        if(!silent)
                   1288:                        {
                   1289:                                printf("sd%d: medium error ", unit); 
                   1290:                                if(sense->valid)
                   1291:                                {
                   1292:                                        printf("block no. %d (decimal)",
                   1293:                                        (sense->ext.extended.info[0] <<24),
                   1294:                                        (sense->ext.extended.info[1] <<16),
                   1295:                                        (sense->ext.extended.info[2] <<8),
                   1296:                                        (sense->ext.extended.info[3] ));
                   1297:                                }
                   1298:                                printf("\n");
                   1299:                        }
                   1300:                        return(EIO);
                   1301:                case    0x4:
                   1302:                        if(!silent)printf("sd%d: non-media hardware failure\n ",
                   1303:                                unit); 
                   1304:                        return(EIO);
                   1305:                case    0x5:
                   1306:                        if(!silent)printf("sd%d: illegal request\n ",
                   1307:                                unit); 
                   1308:                        return(EINVAL);
                   1309:                case    0x6:
                   1310:                        /***********************************************\
                   1311:                        * If we are not open, then this is not an error *
                   1312:                        * as we don't have state yet. Either way, make  *
                   1313:                        * sure that we don't have any residual state    *
                   1314:                        \***********************************************/
                   1315:                        if(!silent)printf("sd%d: Unit attention.\n ", unit); 
                   1316:                        sd_data[unit].flags &= ~(SDVALID | SDHAVELABEL);
                   1317:                        if (sd_data[unit].openparts)
                   1318:                        {
                   1319:                                return(EIO);
                   1320:                        }
                   1321:                        return(ESUCCESS); /* not an error if nothing's open */
                   1322:                case    0x7:
                   1323:                        if(!silent)
                   1324:                        {
                   1325:                                printf("sd%d: attempted protection violation ",
                   1326:                                                unit); 
                   1327:                                if(sense->valid)
                   1328:                                {
                   1329:                                        printf("block no. %d (decimal)\n",
                   1330:                                        (sense->ext.extended.info[0] <<24),
                   1331:                                        (sense->ext.extended.info[1] <<16),
                   1332:                                        (sense->ext.extended.info[2] <<8),
                   1333:                                        (sense->ext.extended.info[3] ));
                   1334:                                }
                   1335:                                printf("\n");
                   1336:                        }
                   1337:                        return(EACCES);
                   1338:                case    0x8:
                   1339:                        if(!silent)
                   1340:                        {
                   1341:                                printf("sd%d: block wrong state (worm)\n ",
                   1342:                                unit); 
                   1343:                                if(sense->valid)
                   1344:                                {
                   1345:                                        printf("block no. %d (decimal)\n",
                   1346:                                        (sense->ext.extended.info[0] <<24),
                   1347:                                        (sense->ext.extended.info[1] <<16),
                   1348:                                        (sense->ext.extended.info[2] <<8),
                   1349:                                        (sense->ext.extended.info[3] ));
                   1350:                                }
                   1351:                                printf("\n");
                   1352:                        }
                   1353:                        return(EIO);
                   1354:                case    0x9:
                   1355:                        if(!silent)printf("sd%d: vendor unique\n",
                   1356:                                unit); 
                   1357:                        return(EIO);
                   1358:                case    0xa:
                   1359:                        if(!silent)printf("sd%d: copy aborted\n ",
                   1360:                                unit); 
                   1361:                        return(EIO);
                   1362:                case    0xb:
                   1363:                        if(!silent)printf("sd%d: command aborted\n ",
                   1364:                                unit); 
                   1365:                        return(EIO);
                   1366:                case    0xc:
                   1367:                        if(!silent)
                   1368:                        {
                   1369:                                printf("sd%d: search returned\n ",
                   1370:                                        unit); 
                   1371:                                if(sense->valid)
                   1372:                                {
                   1373:                                        printf("block no. %d (decimal)\n",
                   1374:                                        (sense->ext.extended.info[0] <<24),
                   1375:                                        (sense->ext.extended.info[1] <<16),
                   1376:                                        (sense->ext.extended.info[2] <<8),
                   1377:                                        (sense->ext.extended.info[3] ));
                   1378:                                }
                   1379:                                printf("\n");
                   1380:                        }
                   1381:                        return(ESUCCESS);
                   1382:                case    0xd:
                   1383:                        if(!silent)printf("sd%d: volume overflow\n ",
                   1384:                                unit); 
                   1385:                        return(ENOSPC);
                   1386:                case    0xe:
                   1387:                        if(!silent)
                   1388:                        {
                   1389:                                printf("sd%d: verify miscompare\n ",
                   1390:                                unit); 
                   1391:                                if(sense->valid)
                   1392:                                {
                   1393:                                        printf("block no. %d (decimal)\n",
                   1394:                                        (sense->ext.extended.info[0] <<24),
                   1395:                                        (sense->ext.extended.info[1] <<16),
                   1396:                                        (sense->ext.extended.info[2] <<8),
                   1397:                                        (sense->ext.extended.info[3] ));
                   1398:                                }
                   1399:                                printf("\n");
                   1400:                        }
                   1401:                        return(EIO);
                   1402:                case    0xf:
                   1403:                        if(!silent)printf("sd%d: unknown error key\n ",
                   1404:                                unit); 
                   1405:                        return(EIO);
                   1406:                }
                   1407:                break;
                   1408:        }
                   1409:        case 0:
                   1410:        case 1:
                   1411:        case 2:
                   1412:        case 3:
                   1413:        case 4:
                   1414:        case 5:
                   1415:        case 6:
                   1416:                {
                   1417:                        if(!silent)printf("sd%d: error class %d code %d\n",
                   1418:                                unit,
                   1419:                                sense->error_class,
                   1420:                                sense->error_code);
                   1421:                if(sense->valid)
                   1422:                        if(!silent)printf("block no. %d (decimal)\n",
                   1423:                        (sense->ext.unextended.blockhi <<16),
                   1424:                        + (sense->ext.unextended.blockmed <<8),
                   1425:                        + (sense->ext.unextended.blocklow ));
                   1426:                }
                   1427:                return(EIO);
                   1428:        }
                   1429: }
                   1430: 
                   1431: 
                   1432: 
                   1433: 
                   1434: int
                   1435: sdsize(dev_t dev)
                   1436: {
                   1437:        int unit = UNIT(dev), part = PARTITION(dev), val;
                   1438:        struct sd_data *sd;
                   1439: 
                   1440:        if (unit >= NSD)
                   1441:                return(-1);
                   1442: 
                   1443:        sd = &sd_data[unit];
                   1444:        if((sd->flags & SDINIT) == 0) return(-1);
                   1445:        if (sd == 0 || (sd->flags & SDHAVELABEL) == 0)
                   1446:                val = sdopen (MAKESDDEV(major(dev), unit, RAW_PART), FREAD, S_IFBLK, 0);
                   1447:        if ( val != 0 || sd->flags & SDWRITEPROT)
                   1448:                return (-1);
                   1449: 
                   1450:        return((int)sd->disklabel.d_partitions[part].p_size);
                   1451: }
                   1452: 
                   1453: sddump()
                   1454: {
                   1455:     printf("sddump()        -- not implemented\n");
                   1456:     return(-1);
                   1457: }
                   1458: 
                   1459: 
                   1460: 
                   1461: 
                   1462: 

unix.superglobalmegacorp.com

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