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

1.1       root        1: /*
                      2:  * Written by Julian Elischer ([email protected])
                      3:  * for TRW Financial Systems for use under the MACH(2.5) operating system.
                      4:  *
                      5:  * TRW Financial Systems, in accordance with their agreement with Carnegie
                      6:  * Mellon University, makes this software available to CMU to distribute
                      7:  * or use in any manner that they see fit as long as this message is kept with
                      8:  * the software. For this reason TFS also grants any other persons or
                      9:  * organisations permission to use or modify this software.
                     10:  *
                     11:  * TFS supplies this software to be publicly redistributed
                     12:  * on the understanding that TFS is not responsible for the correct
                     13:  * functioning of this software in any circumstances.
                     14:  *
                     15:  *
                     16:  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
                     17:  * --------------------         -----   ----------------------
                     18:  * CURRENT PATCH LEVEL:         1       00098
                     19:  * --------------------         -----   ----------------------
                     20:  *
                     21:  * 16 Feb 93   Julian Elischer         ADDED for SCSI system
                     22:  */
                     23: 
                     24: /*
                     25:  * Ported to run under 386BSD by Julian Elischer ([email protected]) Sept 1992
                     26:  */
                     27: 
                     28: /*
                     29: $Log:
                     30: *
                     31: */
                     32: #include <sys/types.h>
                     33: #include "st.h"
                     34: #include "sd.h"
                     35: #include "ch.h"
                     36: #include "cd.h"
                     37: 
                     38: #ifdef MACH
                     39: #include <i386/machparam.h>
                     40: #endif MACH
                     41: #include <scsi/scsi_all.h>
                     42: #include <scsi/scsiconf.h>
                     43: 
                     44: #if !defined(OSF) && !defined(__386BSD__)
                     45: #include "bll.h"
                     46: #include "cals.h"
                     47: #include "kil.h"
                     48: #else
                     49: #define        NBLL 0
                     50: #define        NCALS 0
                     51: #define        NKIL 0
                     52: #endif /* !defined(OSF) && !defined(__386BSD__) */
                     53: 
                     54: #if NSD > 0
                     55: extern sdattach();
                     56: #endif NSD
                     57: #if NST > 0
                     58: extern stattach();
                     59: #endif NST
                     60: #if NCH > 0
                     61: extern chattach();
                     62: #endif NCH
                     63: #if NCD > 0
                     64: extern cdattach();
                     65: #endif NCD
                     66: #if NBLL > 0
                     67: extern bllattach();
                     68: #endif NBLL
                     69: #if NCALS > 0
                     70: extern calsattach();
                     71: #endif NCALS
                     72: #if NKIL > 0
                     73: extern kil_attach();
                     74: #endif NKIL
                     75: 
                     76: /***************************************************************\
                     77: * The structure of pre-configured devices that might be turned *
                     78: * off and therefore may not show up                            *
                     79: \***************************************************************/
                     80: struct predefined
                     81: {
                     82:        u_char  scsibus;
                     83:        u_char  dev;
                     84:        u_char  lu;
                     85:        int     (*attach_rtn)();
                     86:        char    *devname;
                     87:        char    flags;
                     88: }
                     89: pd[] = 
                     90: {
                     91: #ifdef EXAMPLE_PREDEFINE
                     92: #if NSD > 0
                     93:        {0,0,0,sdattach,"sd",0},/* define a disk at scsibus=0 dev=0 lu=0 */
                     94: #endif NSD
                     95: #endif EXAMPLE_PREDEFINE
                     96:        {0,9,9}                 /*illegal dummy end entry */
                     97: };
                     98: 
                     99: 
                    100: /***************************************************************\
                    101: * The structure of known drivers for autoconfiguration         *
                    102: \***************************************************************/
                    103: static struct scsidevs 
                    104: {
                    105:        int type;
                    106:        int removable;
                    107:        char    *manufacturer;
                    108:        char    *model;
                    109:        char    *version;
                    110:        int     (*attach_rtn)();
                    111:        char    *devname;
                    112:        char    flags;          /* 1 show my comparisons during boot(debug) */
                    113: }
                    114: #define SC_SHOWME      0x01
                    115: #define        SC_ONE_LU       0x00
                    116: #define        SC_MORE_LUS     0x02
                    117: knowndevs[] = {
                    118: #if NSD > 0
                    119:        { T_DIRECT,T_FIXED,"standard","any"
                    120:                        ,"any",sdattach,"sd",SC_ONE_LU },
                    121:        { T_DIRECT,T_FIXED,"MAXTOR  ","XT-4170S        "
                    122:                        ,"B5A ",sdattach,"mx1",SC_ONE_LU },
                    123: #endif NSD
                    124: #if NST > 0
                    125:        { T_SEQUENTIAL,T_REMOV,"standard","any"
                    126:                        ,"any",stattach,"st",SC_ONE_LU },
                    127: #endif NST
                    128: #if NCALS > 0
                    129:        { T_PROCESSOR,T_FIXED,"standard","any"
                    130:                        ,"any",calsattach,"cals",SC_MORE_LUS },
                    131: #endif NCALS
                    132: #if NCH > 0
                    133:        { T_CHANGER,T_REMOV,"standard","any"
                    134:                        ,"any",chattach,"ch",SC_ONE_LU },
                    135: #endif NCH
                    136: #if NCD > 0
                    137:        { T_READONLY,T_REMOV,"SONY    ","CD-ROM CDU-8012 "
                    138:                        ,"3.1a",cdattach,"cd",SC_ONE_LU },
                    139: #endif NCD
                    140: #if NBLL > 0
                    141:        { T_PROCESSOR,T_FIXED,"AEG     ","READER          "
                    142:                        ,"V1.0",bllattach,"bll",SC_MORE_LUS },
                    143: #endif NBLL
                    144: #if NKIL > 0
                    145:        { T_SCANNER,T_FIXED,"KODAK   ","IL Scanner 900  "
                    146:                        ,"any",kil_attach,"kil",SC_ONE_LU },
                    147: #endif NKIL
                    148: 
                    149: {0}
                    150: };
                    151: /***************************************************************\
                    152: * Declarations                                                 *
                    153: \***************************************************************/
                    154: struct predefined      *scsi_get_predef();
                    155: struct scsidevs        *scsi_probedev();
                    156: struct scsidevs        *selectdev();
                    157: 
                    158: /* controls debug level within the scsi subsystem */
                    159: /* see scsiconf.h for values                     */
                    160: int    scsi_debug      =       0x0;
                    161: int    scsibus         =       0x0; /* This is the Nth scsibus */
                    162: 
                    163: /***************************************************************\
                    164: * The routine called by the adapter boards to get all their    *
                    165: * devices configured in.                                       *
                    166: \***************************************************************/
                    167: scsi_attachdevs( unit, scsi_addr, scsi_switch)
                    168: int    unit,scsi_addr;
                    169: struct scsi_switch     *scsi_switch;
                    170: {
                    171:        int     targ,lun;
                    172:        struct  scsidevs        *bestmatch = (struct scsidevs *)0;
                    173:        struct  predefined *predef;
                    174:        int maybe_more;
                    175: 
                    176: #ifdef SCSI_DELAY
                    177: #if    SCSI_DELAY > 2
                    178:        printf("waiting for scsi devices to settle\n");
                    179: #else  SCSI_DELAY > 2
                    180: #define        SCSI_DELAY 15
                    181: #endif SCSI_DELAY > 2
                    182: #else
                    183: #define SCSI_DELAY 2
                    184: #endif SCSI_DELAY
                    185:        spinwait(1000 * SCSI_DELAY);
                    186:        targ = 0;
                    187:        while(targ < 8)
                    188:        {
                    189:                maybe_more = 0; /* by default only check 1 lun */
                    190:                if (targ == scsi_addr) 
                    191:                {
                    192:                        targ++;
                    193:                        continue;
                    194:                }
                    195:                lun = 0;
                    196:                while(lun < 8)
                    197:                {
                    198:                        predef = scsi_get_predef(scsibus
                    199:                                                ,targ
                    200:                                                ,lun
                    201:                                                ,&maybe_more);
                    202:                        bestmatch = scsi_probedev(unit
                    203:                                                ,targ
                    204:                                                ,lun 
                    205:                                                ,scsi_switch
                    206:                                                ,&maybe_more);
                    207:                        if((bestmatch) && (predef)) /* both exist */
                    208:                        {
                    209:                                if(bestmatch->attach_rtn 
                    210:                                    != predef->attach_rtn)
                    211:                                {
                    212:                                    printf("Clash in found/expected devices\n");
                    213:                                    printf("will link in FOUND\n");
                    214:                                }
                    215:                                (*(bestmatch->attach_rtn))(unit,
                    216:                                                targ,
                    217:                                                lun,
                    218:                                                scsi_switch);
                    219:                        }
                    220:                        if((bestmatch) && (!predef)) /* just FOUND */
                    221:                        {
                    222:                                (*(bestmatch->attach_rtn))(unit,
                    223:                                                targ,
                    224:                                                lun,
                    225:                                                scsi_switch);
                    226:                        }
                    227:                        if((!bestmatch) && (predef)) /* just predef */
                    228:                        {
                    229:                                (*(predef->attach_rtn))(unit,
                    230:                                                targ,
                    231:                                                lun,
                    232:                                                scsi_switch);
                    233:                        }
                    234:                        if(!(maybe_more)) /* nothing suggests we'll find more */
                    235:                        {
                    236:                                break;  /* nothing here, skip to next targ */
                    237:                        }
                    238:                        /* otherwise something says we should look further*/
                    239:                        lun++;
                    240:                }
                    241:                targ++;
                    242:        }
                    243: #if NGENSCSI > 0
                    244:        /***************************************************************\
                    245:        * If available hook up the generic scsi driver, letting it      *
                    246:        * know which target is US. (i.e. illegal or at least special)   *
                    247:        \***************************************************************/
                    248:        genscsi_attach(unit,scsi_addr,0,scsi_switch);
                    249: #endif
                    250:        scsibus++;      /* next time we are on the NEXT scsi bus */
                    251: }
                    252: 
                    253: /***********************************************\
                    254: * given a target and lu, check if there is a   *
                    255: * predefined device for that address           *
                    256: \***********************************************/
                    257: struct predefined      *scsi_get_predef(unit,target,lu,maybe_more)
                    258: int    unit,target,lu,*maybe_more;
                    259: {
                    260:        int upto,numents;
                    261: 
                    262:        numents = (sizeof(pd)/sizeof(struct predefined)) - 1;
                    263:        
                    264:        for(upto = 0;upto < numents;upto++)
                    265:        {
                    266:                if(pd[upto].scsibus != unit)
                    267:                        continue;
                    268:                if(pd[upto].dev != target)
                    269:                        continue;
                    270:                if(pd[upto].lu != lu)
                    271:                        continue;
                    272:                
                    273:                printf("  dev%d,lu%d: %s - PRECONFIGURED -\n"
                    274:                        ,target
                    275:                        ,lu
                    276:                        ,pd[upto].devname);
                    277:                *maybe_more = pd[upto].flags & SC_MORE_LUS;
                    278:                return(&(pd[upto]));
                    279:        }
                    280:        return((struct predefined *)0);
                    281: }
                    282: 
                    283: /***********************************************\
                    284: * given a target and lu, ask the device what   *
                    285: * it is, and find the correct driver table     *
                    286: * entry.                                       *
                    287: \***********************************************/
                    288: struct scsidevs        *scsi_probedev(unit,target,lu,scsi_switch, maybe_more)
                    289: 
                    290: struct scsi_switch *scsi_switch;
                    291: int    unit,target,lu;
                    292: int *maybe_more;
                    293: {
                    294:        struct  scsidevs        *bestmatch = (struct scsidevs *)0;
                    295:        char    *dtype=(char *)0,*desc;
                    296:        char    *qtype;
                    297:        static  struct scsi_inquiry_data        inqbuf; 
                    298:        int     len,qualifier,type,remov;
                    299:        char    manu[32];
                    300:        char    model[32];
                    301:        char    version[32];
                    302: 
                    303: 
                    304:        bzero(&inqbuf,sizeof(inqbuf));
                    305:        /***********************************************\
                    306:        * Ask the device what it is                     *
                    307:        \***********************************************/
                    308: #ifdef DEBUG
                    309:        if((target == 0) && (lu == 0))
                    310:                scsi_debug = 0xfff;
                    311:        else
                    312:                scsi_debug = 0;
                    313: #endif DEBUG
                    314:        if(scsi_ready(  unit,
                    315:                        target,
                    316:                        lu,
                    317:                        scsi_switch,
                    318:                        SCSI_NOSLEEP | SCSI_NOMASK) != COMPLETE)
                    319:        {
                    320:                return(struct scsidevs *)0;
                    321:        }
                    322:        if(scsi_inquire(unit,
                    323:                        target,
                    324:                        lu,
                    325:                        scsi_switch,
                    326:                        &inqbuf,
                    327:                        SCSI_NOSLEEP | SCSI_NOMASK) != COMPLETE)
                    328:        {
                    329:                return(struct scsidevs *)0;
                    330:        }
                    331: 
                    332:        /***********************************************\
                    333:        * note what BASIC type of device it is          *
                    334:        \***********************************************/
                    335:        if(scsi_debug & SHOWINQUIRY)
                    336:        {
                    337:                desc=(char *)&inqbuf;
                    338:                printf("inq: %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
                    339:                desc[0], desc[1], desc[2], desc[3],
                    340:                desc[4], desc[5], desc[6], desc[7],
                    341:                desc[8], desc[9], desc[10], desc[11],
                    342:                desc[12]);
                    343:        }
                    344: 
                    345:        type = inqbuf.device_type;
                    346:        qualifier = inqbuf.device_qualifier;
                    347:        remov = inqbuf.removable;
                    348: 
                    349:        /* Check for a non-existent unit.  If the device is returning
                    350:         * this much, then we must set the flag that has
                    351:         * the searcher keep looking on other luns.
                    352:         */
                    353:        if (qualifier == 3 && type == T_NODEVICE)
                    354:        {
                    355:                *maybe_more = 1;
                    356:                return (struct scsidevs *)0;
                    357:        }
                    358: 
                    359:        /* Any device qualifier that has
                    360:         * the top bit set (qualifier&4 != 0) is vendor specific and
                    361:         * won't match in this switch.
                    362:         */
                    363: 
                    364:        switch(qualifier)
                    365:        {
                    366:                case 0:
                    367:                qtype="";
                    368:                break;
                    369:                case 1:
                    370:                qtype=", Unit not Connected!";
                    371:                break;
                    372:                case 2:
                    373:                qtype=", Reserved Peripheral Qualifier!";
                    374:                break;
                    375:                case 3:
                    376:                qtype=", The Target can't support this Unit!";
                    377:                break;
                    378: 
                    379:                default:
                    380:                dtype="vendor specific";
                    381:                qtype="";
                    382:                *maybe_more = 1;
                    383:                break;
                    384:        }
                    385: 
                    386:        if (dtype == 0)
                    387:                switch(type)
                    388:                {
                    389:                        case T_DIRECT:
                    390:                                dtype="direct";
                    391:                                break;
                    392:                        case T_SEQUENTIAL:
                    393:                                dtype="sequential";
                    394:                                break;
                    395:                        case T_PRINTER:
                    396:                                dtype="printer";
                    397:                                break;
                    398:                        case T_PROCESSOR:
                    399:                                dtype="processor";
                    400:                                break;
                    401:                        case T_READONLY:
                    402:                                dtype="readonly";
                    403:                                break;
                    404:                        case T_WORM:
                    405:                                dtype="worm";
                    406:                                break;
                    407:                        case T_SCANNER:
                    408:                                dtype="scanner";
                    409:                                break;
                    410:                        case T_OPTICAL:
                    411:                                dtype="optical";
                    412:                                break;
                    413:                        case T_CHANGER:
                    414:                                dtype="changer";
                    415:                                break;
                    416:                        case T_COMM:
                    417:                                dtype="communication";
                    418:                                break;
                    419:                        default:
                    420:                                dtype="unknown";
                    421:                                break;
                    422:                }
                    423: 
                    424:        /***********************************************\
                    425:        * Then if it's advanced enough, more detailed   *
                    426:        * information                                   *
                    427:        \***********************************************/
                    428:        if(inqbuf.ansii_version > 0) 
                    429:        {
                    430:                if ((len = inqbuf.additional_length 
                    431:                                + ( (char *)inqbuf.unused
                    432:                                  - (char *)&inqbuf))
                    433:                        > (sizeof(struct scsi_inquiry_data) - 1))
                    434:                        len = sizeof(struct scsi_inquiry_data) - 1;
                    435:                desc=inqbuf.vendor;
                    436:                desc[len-(desc - (char *)&inqbuf)] = 0;
                    437:                strncpy(manu,inqbuf.vendor,8);manu[8]=0;
                    438:                strncpy(model,inqbuf.product,16);model[16]=0;
                    439:                strncpy(version,inqbuf.revision,4);version[4]=0;
                    440:        }
                    441:        else
                    442:        /***********************************************\
                    443:        * If not advanced enough, use default values    *
                    444:        \***********************************************/
                    445:        {
                    446:                desc="early protocol device";
                    447:                strncpy(manu,"unknown",8);
                    448:                strncpy(model,"unknown",16);
                    449:                strncpy(version,"????",4);
                    450:        }
                    451:        printf("  dev%d,lu%d: type %d:%d(%s%s),%s '%s%s%s' scsi%d\n"
                    452:                ,target
                    453:                ,lu
                    454:                ,qualifier,type
                    455:                ,dtype,qtype
                    456:                ,remov?"removable":"fixed"
                    457:                ,manu
                    458:                ,model
                    459:                ,version
                    460:                ,inqbuf.ansii_version
                    461:        );
                    462:        /***********************************************\
                    463:        * Try make as good a match as possible with     *
                    464:        * available sub drivers                         *
                    465:        \***********************************************/
                    466:        bestmatch = (selectdev(unit,target,lu,&scsi_switch,
                    467:                qualifier,type,remov,manu,model,version));
                    468:        if((bestmatch) && (bestmatch->flags & SC_MORE_LUS))
                    469:        {
                    470:                *maybe_more = 1;
                    471:        }
                    472:        return(bestmatch);
                    473: }
                    474: 
                    475: /***********************************************\
                    476: * Try make as good a match as possible with    *
                    477: * available sub drivers                                *
                    478: \***********************************************/
                    479: struct scsidevs        
                    480: *selectdev(unit,target,lu,dvr_switch,qualifier,type,remov,manu,model,rev)
                    481: int    unit,target,lu;
                    482: struct scsi_switch *dvr_switch;
                    483: int    qualifier,type,remov;
                    484: char   *manu,*model,*rev;
                    485: {
                    486:        int     numents = (sizeof(knowndevs)/sizeof(struct scsidevs)) - 1;
                    487:        int     count = 0;
                    488:        int                     bestmatches = 0;
                    489:        struct  scsidevs        *bestmatch = (struct scsidevs *)0;
                    490:        struct  scsidevs        *thisentry = knowndevs;
                    491: 
                    492:        type |= (qualifier << 5);
                    493: 
                    494:        thisentry--;
                    495:        while( count++ < numents)
                    496:        {
                    497:                thisentry++;
                    498:                if(type != thisentry->type)
                    499:                {
                    500:                        continue;
                    501:                }
                    502:                if(bestmatches < 1)
                    503:                {
                    504:                        bestmatches = 1;
                    505:                        bestmatch = thisentry;
                    506:                }
                    507:                if(remov != thisentry->removable)
                    508:                {
                    509:                        continue;
                    510:                }
                    511:                if(bestmatches < 2)
                    512:                {
                    513:                        bestmatches = 2;
                    514:                        bestmatch = thisentry;
                    515:                }
                    516:                if(thisentry->flags & SC_SHOWME)
                    517:                        printf("\n%s-\n%s-",thisentry->manufacturer, manu);
                    518:                if(strcmp(thisentry->manufacturer, manu))
                    519:                {
                    520:                        continue;
                    521:                }
                    522:                if(bestmatches < 3)
                    523:                {
                    524:                        bestmatches = 3;
                    525:                        bestmatch = thisentry;
                    526:                }
                    527:                if(thisentry->flags & SC_SHOWME)
                    528:                        printf("\n%s-\n%s-",thisentry->model, model);
                    529:                if(strcmp(thisentry->model, model))
                    530:                {
                    531:                        continue;
                    532:                }
                    533:                if(bestmatches < 4)
                    534:                {
                    535:                        bestmatches = 4;
                    536:                        bestmatch = thisentry;
                    537:                }
                    538:                if(thisentry->flags & SC_SHOWME)
                    539:                        printf("\n%s-\n%s-",thisentry->version, rev);
                    540:                if(strcmp(thisentry->version, rev))
                    541:                {
                    542:                        continue;
                    543:                }
                    544:                if(bestmatches < 5)
                    545:                {
                    546:                        bestmatches = 5;
                    547:                        bestmatch = thisentry;
                    548:                        break;
                    549:                }
                    550:        }
                    551: 
                    552:        if (bestmatch == (struct scsidevs *)0)
                    553:                printf("        No explicit device driver match for \"%s %s\".\n",
                    554:                manu, model);
                    555: 
                    556:        return(bestmatch);
                    557: }
                    558: 
                    559: static int recurse = 0;
                    560: /***********************************************\
                    561: * Do a scsi operation asking a device if it is *
                    562: * ready. Use the scsi_cmd routine in the switch *
                    563: * table.                                       *
                    564: \***********************************************/
                    565: scsi_ready(unit,target,lu,scsi_switch, flags)
                    566: struct scsi_switch *scsi_switch;
                    567: {
                    568:        struct  scsi_test_unit_ready scsi_cmd;
                    569:        struct  scsi_xfer scsi_xfer;
                    570:        volatile int rval;
                    571:        int     key;
                    572: 
                    573:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                    574:        bzero(&scsi_xfer, sizeof(scsi_xfer));
                    575:        scsi_cmd.op_code = TEST_UNIT_READY;
                    576: 
                    577:        scsi_xfer.flags=flags | INUSE;
                    578:        scsi_xfer.adapter=unit;
                    579:        scsi_xfer.targ=target;
                    580:        scsi_xfer.lu=lu;
                    581:        scsi_xfer.cmd=(struct scsi_generic *)&scsi_cmd;
                    582:        scsi_xfer.retries=8;
                    583:        scsi_xfer.timeout=10000;
                    584:        scsi_xfer.cmdlen=sizeof(scsi_cmd);
                    585:        scsi_xfer.data=0;
                    586:        scsi_xfer.datalen=0;
                    587:        scsi_xfer.resid=0;
                    588:        scsi_xfer.when_done=0;
                    589:        scsi_xfer.done_arg=0;
                    590: retry: scsi_xfer.error=0;
                    591:        /*******************************************************\
                    592:        * do not use interrupts                                 *
                    593:        \*******************************************************/
                    594:        rval = (*(scsi_switch->scsi_cmd))(&scsi_xfer);
                    595:        if (rval != COMPLETE)
                    596:        {
                    597:                if(scsi_debug)
                    598:                {
                    599:                        printf("scsi error, rval = 0x%x\n",rval);
                    600:                        printf("code from driver: 0x%x\n",scsi_xfer.error);
                    601:                }
                    602:                switch(scsi_xfer.error)
                    603:                {
                    604:                case    XS_SENSE:
                    605:                /*******************************************************\
                    606:                * Any sense value is illegal except UNIT ATTENTION      *
                    607:                * In which case we need to check again to get the       *
                    608:                * correct response.                                     *
                    609:                *( especially exabytes)                                 *
                    610:                \*******************************************************/
                    611:                        if(scsi_xfer.sense.error_class == 7 )
                    612:                        {
                    613:                                key = scsi_xfer.sense.ext.extended.sense_key ;
                    614:                                switch(key)
                    615:                                { 
                    616:                                case    2:      /* not ready BUT PRESENT! */
                    617:                                                return(COMPLETE);
                    618:                                case    6:
                    619:                                        spinwait(1000);
                    620:                                        if(scsi_xfer.retries--)
                    621:                                        {
                    622:                                                scsi_xfer.flags &= ~ITSDONE;
                    623:                                                goto retry;
                    624:                                        }
                    625:                                        return(COMPLETE);
                    626:                                default:
                    627:                                        if(scsi_debug)
                    628:                                                printf("%d:%d,key=%x.",
                    629:                                                target,lu,key);
                    630:                                }
                    631:                        }
                    632:                        return(HAD_ERROR);
                    633:                case    XS_BUSY:
                    634:                        spinwait(1000);
                    635:                        if(scsi_xfer.retries--)
                    636:                        {
                    637:                                scsi_xfer.flags &= ~ITSDONE;
                    638:                                goto retry;
                    639:                        }
                    640:                        return(COMPLETE);       /* it's busy so it's there */
                    641:                case    XS_TIMEOUT:
                    642:                default:
                    643:                        return(HAD_ERROR);
                    644:                }
                    645:        }
                    646:        return(COMPLETE);
                    647: }
                    648: /***********************************************\
                    649: * Do a scsi operation asking a device what it is*
                    650: * Use the scsi_cmd routine in the switch table.        *
                    651: \***********************************************/
                    652: scsi_inquire(unit,target,lu,scsi_switch,inqbuf, flags)
                    653: struct scsi_switch *scsi_switch;
                    654: u_char *inqbuf;
                    655: {
                    656:        struct  scsi_inquiry scsi_cmd;
                    657:        struct  scsi_xfer scsi_xfer;
                    658:        volatile int rval;
                    659: 
                    660:        bzero(&scsi_cmd, sizeof(scsi_cmd));
                    661:        bzero(&scsi_xfer, sizeof(scsi_xfer));
                    662:        scsi_cmd.op_code = INQUIRY;
                    663:        scsi_cmd.length = sizeof(struct scsi_inquiry_data);
                    664: 
                    665:        scsi_xfer.flags=flags | SCSI_DATA_IN | INUSE;
                    666:        scsi_xfer.adapter=unit;
                    667:        scsi_xfer.targ=target;
                    668:        scsi_xfer.lu=lu;
                    669:        scsi_xfer.retries=8;
                    670:        scsi_xfer.timeout=10000;
                    671:        scsi_xfer.cmd=(struct scsi_generic *)&scsi_cmd;
                    672:        scsi_xfer.cmdlen= sizeof(struct scsi_inquiry);
                    673:        scsi_xfer.data=inqbuf;
                    674:        scsi_xfer.datalen=sizeof(struct scsi_inquiry_data);
                    675:        scsi_xfer.resid=sizeof(struct scsi_inquiry_data);
                    676:        scsi_xfer.when_done=0;
                    677:        scsi_xfer.done_arg=0;
                    678: retry: scsi_xfer.error=0;
                    679:        /*******************************************************\
                    680:        * do not use interrupts                                 *
                    681:        \*******************************************************/
                    682:        if ((*(scsi_switch->scsi_cmd))(&scsi_xfer) != COMPLETE)
                    683:        {
                    684:                if(scsi_debug) printf("inquiry had error(0x%x) ",scsi_xfer.error);
                    685:                switch(scsi_xfer.error)
                    686:                {
                    687:                case    XS_NOERROR:
                    688:                        break;
                    689:                case    XS_SENSE:
                    690:                /*******************************************************\
                    691:                * Any sense value is illegal except UNIT ATTENTION      *
                    692:                * In which case we need to check again to get the       *
                    693:                * correct response.                                     *
                    694:                *( especially exabytes)                                 *
                    695:                \*******************************************************/
                    696:                        if((scsi_xfer.sense.error_class == 7 )
                    697:                         && (scsi_xfer.sense.ext.extended.sense_key == 6))
                    698:                        { /* it's changed so it's there */
                    699:                                spinwait(1000);
                    700:                                {
                    701:                                        if(scsi_xfer.retries--)
                    702:                                        {
                    703:                                                scsi_xfer.flags &= ~ITSDONE;
                    704:                                                goto retry;
                    705:                                        }
                    706:                                }
                    707:                                return( COMPLETE);
                    708:                        }
                    709:                        return(HAD_ERROR);
                    710:                case    XS_BUSY:
                    711:                        spinwait(1000);
                    712:                        if(scsi_xfer.retries--)
                    713:                        {
                    714:                                scsi_xfer.flags &= ~ITSDONE;
                    715:                                goto retry;
                    716:                        }
                    717:                case    XS_TIMEOUT:
                    718:                default:
                    719:                        return(HAD_ERROR);
                    720:                }
                    721:        }
                    722:        return(COMPLETE);
                    723: }
                    724: 
                    725: 
                    726: 
                    727: 
                    728: /***********************************************\
                    729: * Utility routines often used in SCSI stuff    *
                    730: \***********************************************/
                    731: 
                    732: /***********************************************\
                    733: * convert a physical address to 3 bytes,       *
                    734: * MSB at the lowest address,                   *
                    735: * LSB at the highest.                          *
                    736: \***********************************************/
                    737: 
                    738: lto3b(val, bytes)
                    739: u_char *bytes;
                    740: {
                    741:        *bytes++ = (val&0xff0000)>>16;
                    742:        *bytes++ = (val&0xff00)>>8;
                    743:        *bytes = val&0xff;
                    744: }
                    745: 
                    746: /***********************************************\
                    747: * The reverse of lto3b                         *
                    748: \***********************************************/
                    749: _3btol(bytes)
                    750: u_char *bytes;
                    751: {
                    752:        int rc;
                    753:        rc = (*bytes++ << 16);
                    754:        rc += (*bytes++ << 8);
                    755:        rc += *bytes;
                    756:        return(rc);
                    757: }
                    758: 

unix.superglobalmegacorp.com

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