Annotation of Net2/scsi/ch.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  */
        !             3: /*
        !             4:  * HISTORY
        !             5:  * 
        !             6:  *
        !             7:  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
        !             8:  * --------------------         -----   ----------------------
        !             9:  * CURRENT PATCH LEVEL:         1       00098
        !            10:  * --------------------         -----   ----------------------
        !            11:  *
        !            12:  * 16 Feb 93   Julian Elischer         ADDED for SCSI system
        !            13:  * 
        !            14:  */
        !            15: 
        !            16: #include       <sys/types.h>
        !            17: #include       <ch.h>
        !            18: 
        !            19: #include <sys/param.h>
        !            20: #include <sys/systm.h>
        !            21: 
        !            22: #include <sys/errno.h>
        !            23: #include <sys/ioctl.h>
        !            24: #include <sys/buf.h>
        !            25: #include <sys/proc.h>
        !            26: #include <sys/user.h>
        !            27: #include <sys/chio.h>
        !            28: 
        !            29: #if defined(OSF)
        !            30: #define SECSIZE        512
        !            31: #endif /* defined(OSF) */
        !            32: 
        !            33: #include <scsi/scsi_all.h>
        !            34: #include <scsi/scsi_changer.h>
        !            35: #include <scsi/scsiconf.h>
        !            36: 
        !            37: 
        !            38: struct  scsi_xfer ch_scsi_xfer[NCH];
        !            39: int     ch_xfer_block_wait[NCH];
        !            40: 
        !            41: 
        !            42: #define PAGESIZ        4096
        !            43: #define STQSIZE                4
        !            44: #define        CH_RETRIES      4
        !            45: 
        !            46: 
        !            47: #define MODE(z)                (  (minor(z) & 0x0F) )
        !            48: #define UNIT(z)                (  (minor(z) >> 4) )
        !            49: 
        !            50: #ifndef        MACH
        !            51: #define ESUCCESS 0
        !            52: #endif MACH
        !            53: 
        !            54: int    ch_info_valid[NCH];     /* the info about the device is valid */
        !            55: int    ch_initialized[NCH] ;
        !            56: int    ch_debug = 1;
        !            57: 
        !            58: int chattach();
        !            59: int ch_done();
        !            60: struct ch_data
        !            61: {
        !            62:        int     flags;
        !            63:        struct  scsi_switch *sc_sw;     /* address of scsi low level switch */
        !            64:        int     ctlr;                   /* so they know which one we want */
        !            65:        int     targ;                   /* our scsi target ID */
        !            66:        int     lu;                     /* out scsi lu */
        !            67:        short   chmo;                   /* Offset of first CHM */
        !            68:        short   chms;                   /* No. of CHM */
        !            69:        short   slots;                  /* No. of Storage Elements */
        !            70:        short   sloto;                  /* Offset of first SE */
        !            71:        short   imexs;                  /* No. of Import/Export Slots */
        !            72:        short   imexo;                  /* Offset of first IM/EX */
        !            73:        short   drives;                 /* No. of CTS */
        !            74:        short   driveo;                 /* Offset of first CTS */
        !            75:        short   rot;                    /* CHM can rotate */
        !            76:        u_long  op_matrix;              /* possible opertaions */
        !            77:        u_short lsterr;         /* details of lasterror */
        !            78:        u_char  stor;                   /* posible Storage locations */
        !            79: }ch_data[NCH];
        !            80: 
        !            81: #define CH_OPEN                0x01
        !            82: #define CH_KNOWN       0x02
        !            83: 
        !            84: static int     next_ch_unit = 0;
        !            85: /***********************************************************************\
        !            86: * The routine called by the low level scsi routine when it discovers   *
        !            87: * A device suitable for this driver                                    *
        !            88: \***********************************************************************/
        !            89: 
        !            90: int    chattach(ctlr,targ,lu,scsi_switch)
        !            91: struct scsi_switch *scsi_switch;
        !            92: {
        !            93:        int     unit,i,stat;
        !            94:        unsigned char *tbl;
        !            95: 
        !            96:        if(scsi_debug & PRINTROUTINES) printf("chattach: ");
        !            97:        /*******************************************************\
        !            98:        * Check we have the resources for another drive         *
        !            99:        \*******************************************************/
        !           100:        unit = next_ch_unit++;
        !           101:        if( unit >= NCH)
        !           102:        {
        !           103:                printf("Too many scsi changers..(%d > %d) reconfigure kernel",(unit + 1),NCH);
        !           104:                return(0);
        !           105:        }
        !           106:        /*******************************************************\
        !           107:        * Store information needed to contact our base driver   *
        !           108:        \*******************************************************/
        !           109:        ch_data[unit].sc_sw     =       scsi_switch;
        !           110:        ch_data[unit].ctlr      =       ctlr;
        !           111:        ch_data[unit].targ      =       targ;
        !           112:        ch_data[unit].lu        =       lu;
        !           113: 
        !           114:        /*******************************************************\
        !           115:        * Use the subdriver to request information regarding    *
        !           116:        * the drive. We cannot use interrupts yet, so the       *
        !           117:        * request must specify this.                            *
        !           118:        \*******************************************************/
        !           119:        if((ch_mode_sense(unit,  SCSI_NOSLEEP |  SCSI_NOMASK /*| SCSI_SILENT*/)))
        !           120:        {
        !           121:                printf("        ch%d: scsi changer, %d slot(s) %d drive(s) %d arm(s) %d i/e-slot(s) \n",
        !           122:                        unit, ch_data[unit].slots, ch_data[unit].drives, ch_data[unit].chms, ch_data[unit].imexs);
        !           123:                stat=CH_KNOWN;
        !           124:        }
        !           125:        else
        !           126:        {
        !           127:                printf("        ch%d: scsi changer :- offline\n", unit);
        !           128:                stat=CH_OPEN;
        !           129:        }
        !           130:        ch_initialized[unit] = stat;
        !           131: 
        !           132:        return;
        !           133: 
        !           134: }
        !           135: 
        !           136: 
        !           137: 
        !           138: /*******************************************************\
        !           139: *      open the device.                                *
        !           140: \*******************************************************/
        !           141: chopen(dev)
        !           142: {
        !           143:        int errcode = 0;
        !           144:        int unit,mode;
        !           145: 
        !           146:        unit = UNIT(dev);
        !           147:        mode = MODE(dev);
        !           148: 
        !           149:        /*******************************************************\
        !           150:        * Check the unit is legal                               *
        !           151:        \*******************************************************/
        !           152:        if ( unit >= NCH )
        !           153:        {
        !           154:                printf("ch %d  > %d\n",unit,NCH);
        !           155:                errcode = ENXIO;
        !           156:                return(errcode);
        !           157:        }
        !           158:        /*******************************************************\
        !           159:        * Only allow one at a time                              *
        !           160:        \*******************************************************/
        !           161:        if(ch_data[unit].flags & CH_OPEN)
        !           162:        {
        !           163:                printf("CH%d already open\n",unit);
        !           164:                errcode = ENXIO;
        !           165:                goto bad;
        !           166:        }
        !           167:        
        !           168:        if(ch_debug||(scsi_debug & (PRINTROUTINES | TRACEOPENS)))
        !           169:                printf("chopen: dev=0x%x (unit %d (of %d))\n"
        !           170:                                ,   dev,      unit,   NCH);
        !           171:        /*******************************************************\
        !           172:        * Make sure the device has been initialised             *
        !           173:        \*******************************************************/
        !           174: 
        !           175:        if (!ch_initialized[unit])
        !           176:                return(ENXIO);
        !           177:        if (ch_initialized[unit]!=CH_KNOWN) {
        !           178:                if((ch_mode_sense(unit,  SCSI_NOSLEEP |  SCSI_NOMASK /*| SCSI_SILENT*/)))
        !           179:                {
        !           180:                        ch_initialized[unit]=CH_KNOWN;
        !           181:                }
        !           182:          else
        !           183:                {
        !           184:                        printf("  ch%d: scsi changer :- offline\n", unit);
        !           185:                        return(ENXIO);
        !           186:                }
        !           187:        }
        !           188:        /*******************************************************\
        !           189:        * Check that it is still responding and ok.             *
        !           190:        \*******************************************************/
        !           191: 
        !           192:        if(ch_debug || (scsi_debug & TRACEOPENS))
        !           193:                printf("device is ");
        !           194:        if (!(ch_req_sense(unit, 0)))
        !           195:        {
        !           196:                errcode = ENXIO;
        !           197:                if(ch_debug || (scsi_debug & TRACEOPENS))
        !           198:                        printf("not responding\n");
        !           199:                goto bad;
        !           200:        }
        !           201:        if(ch_debug || (scsi_debug & TRACEOPENS))
        !           202:                printf("ok\n");
        !           203: 
        !           204:        if(!(ch_test_ready(unit,0)))
        !           205:        {
        !           206:                printf("ch%d not ready\n",unit);
        !           207:                return(EIO);
        !           208:        }
        !           209: 
        !           210:        ch_info_valid[unit] = TRUE;
        !           211: 
        !           212:        /*******************************************************\
        !           213:        * Load the physical device parameters                   *
        !           214:        \*******************************************************/
        !           215: 
        !           216:        ch_data[unit].flags = CH_OPEN;
        !           217:        return(errcode);
        !           218: bad:
        !           219:        return(errcode);
        !           220: }
        !           221: 
        !           222: /*******************************************************\
        !           223: * close the device.. only called if we are the LAST    *
        !           224: * occurence of an open device                          *
        !           225: \*******************************************************/
        !           226: chclose(dev)
        !           227: {
        !           228:        unsigned char unit,mode;
        !           229: 
        !           230:        unit = UNIT(dev);
        !           231:        mode = MODE(dev);
        !           232: 
        !           233:        if(scsi_debug & TRACEOPENS)
        !           234:                printf("Closing device");
        !           235:        ch_data[unit].flags = 0;
        !           236:        return(0);
        !           237: }
        !           238: 
        !           239: 
        !           240: 
        !           241: /***************************************************************\
        !           242: * chstart                                                       *
        !           243: * This routine is also called after other non-queued requests  *
        !           244: * have been made of the scsi driver, to ensure that the queue  *
        !           245: * continues to be drained.                                     *
        !           246: \***************************************************************/
        !           247: /* chstart() is called at splbio */
        !           248: chstart(unit)
        !           249: {
        !           250:        int                     drivecount;
        !           251:        register struct buf     *bp = 0;
        !           252:        register struct buf     *dp;
        !           253:        struct  scsi_xfer       *xs;
        !           254:        int                     blkno, nblk;
        !           255: 
        !           256: 
        !           257:        if(scsi_debug & PRINTROUTINES) printf("chstart%d ",unit);
        !           258:        /*******************************************************\
        !           259:        * See if there is a buf to do and we are not already    *
        !           260:        * doing one                                             *
        !           261:        \*******************************************************/
        !           262:        xs=&ch_scsi_xfer[unit];
        !           263:        if(xs->flags & INUSE)
        !           264:        {
        !           265:                return;    /* unit already underway */
        !           266:        }
        !           267:        if(ch_xfer_block_wait[unit]) /* a special awaits, let it proceed first */
        !           268:        {
        !           269:                wakeup(&ch_xfer_block_wait[unit]);
        !           270:                return;
        !           271:        }
        !           272: 
        !           273:        return;
        !           274: 
        !           275: }
        !           276: 
        !           277: 
        !           278: /*******************************************************\
        !           279: * This routine is called by the scsi interrupt when    *
        !           280: * the transfer is complete.
        !           281: \*******************************************************/
        !           282: int    ch_done(unit,xs)
        !           283: int    unit;
        !           284: struct scsi_xfer       *xs;
        !           285: {
        !           286:        struct  buf             *bp;
        !           287:        int     retval;
        !           288: 
        !           289:        if(ch_debug||(scsi_debug & PRINTROUTINES)) printf("ch_done%d ",unit);
        !           290:        if (! (xs->flags & INUSE))
        !           291:                panic("scsi_xfer not in use!");
        !           292:        wakeup(xs);
        !           293: }
        !           294: /*******************************************************\
        !           295: * Perform special action on behalf of the user         *
        !           296: * Knows about the internals of this device             *
        !           297: \*******************************************************/
        !           298: chioctl(dev, cmd, arg, mode)
        !           299: dev_t dev;
        !           300: int cmd;
        !           301: caddr_t arg;
        !           302: {
        !           303:        /* struct ch_cmd_buf *args;*/
        !           304:        union scsi_cmd *scsi_cmd;
        !           305:        register i,j;
        !           306:        unsigned int opri;
        !           307:        int errcode = 0;
        !           308:        unsigned char unit;
        !           309:        int number,flags,ret;
        !           310: 
        !           311:        /*******************************************************\
        !           312:        * Find the device that the user is talking about        *
        !           313:        \*******************************************************/
        !           314:        flags = 0;      /* give error messages, act on errors etc. */
        !           315:        unit = UNIT(dev);
        !           316: 
        !           317:        switch(cmd)
        !           318:        {
        !           319:                case CHIOOP: {
        !           320:                        struct chop *ch=(struct chop *) arg;
        !           321:                        if (ch_debug)
        !           322:                                printf("[chtape_chop: %x]\n", ch->ch_op);
        !           323: 
        !           324:                         switch ((short)(ch->ch_op)) {
        !           325:                                case CHGETPARAM:
        !           326:                                        ch->u.getparam.chmo=     ch_data[unit].chmo;
        !           327:                                        ch->u.getparam.chms=   ch_data[unit].chms;
        !           328:                                        ch->u.getparam.sloto=  ch_data[unit].sloto;
        !           329:                                        ch->u.getparam.slots=  ch_data[unit].slots;
        !           330:                                        ch->u.getparam.imexo=  ch_data[unit].imexo;
        !           331:                                        ch->u.getparam.imexs=  ch_data[unit].imexs;
        !           332:                                        ch->u.getparam.driveo= ch_data[unit].driveo;
        !           333:                                        ch->u.getparam.drives= ch_data[unit].drives;
        !           334:                                        ch->u.getparam.rot=    ch_data[unit].rot;
        !           335:                                        ch->result=0;
        !           336:                                        return 0;
        !           337:                                        break;
        !           338:                                case CHPOSITION: 
        !           339:                                 return ch_position(unit,&ch->result,ch->u.position.chm,
        !           340:                                                ch->u.position.to,
        !           341:                                                flags);
        !           342:                                case CHMOVE: 
        !           343:                                 return ch_move(unit,&ch->result, ch->u.position.chm,
        !           344:                                        ch->u.move.from, ch->u.move.to,
        !           345:                                                                flags);
        !           346:                                case CHGETELEM:
        !           347:                                 return ch_getelem(unit,&ch->result, ch->u.get_elem_stat.type,
        !           348:                                        ch->u.get_elem_stat.from, &ch->u.get_elem_stat.elem_data,
        !           349:                                                                        flags);
        !           350:                                default:
        !           351:                                 return EINVAL;
        !           352:                }
        !           353: 
        !           354:         }
        !           355:        default:
        !           356:                return EINVAL;
        !           357:        }
        !           358: 
        !           359:        return(ret?ESUCCESS:EIO);
        !           360: }
        !           361: 
        !           362: ch_getelem(unit,stat,type,from,data,flags)
        !           363: int unit,from,flags;
        !           364: short *stat;
        !           365: char *data;
        !           366: {
        !           367:        struct scsi_read_element_status scsi_cmd;
        !           368:        char elbuf[32];
        !           369:        int ret;
        !           370: 
        !           371:        bzero(&scsi_cmd, sizeof(scsi_cmd));
        !           372:        scsi_cmd.op_code = READ_ELEMENT_STATUS;
        !           373:        scsi_cmd.element_type_code=type;
        !           374:        scsi_cmd.starting_element_addr[0]=(from>>8)&0xff;
        !           375:        scsi_cmd.starting_element_addr[1]=from&0xff;
        !           376:        scsi_cmd.number_of_elements[1]=1;
        !           377:        scsi_cmd.allocation_length[2]=32;
        !           378:        
        !           379:        if ((ret=ch_scsi_cmd(unit,
        !           380:                        &scsi_cmd,
        !           381:                        sizeof(scsi_cmd),
        !           382:                        elbuf,
        !           383:                        32,
        !           384:                        100000,
        !           385:                        flags) !=ESUCCESS)) {
        !           386:                        *stat=ch_data[unit].lsterr;
        !           387:                        bcopy(elbuf+16,data,16);
        !           388:                        return ret;
        !           389:                        }
        !           390:        bcopy(elbuf+16,data,16); /*Just a hack sh */
        !           391:        return ret;
        !           392: }
        !           393: 
        !           394: ch_move(unit,stat,chm,from,to,flags)
        !           395: int unit,chm,from,to,flags;
        !           396: short *stat;
        !           397: {
        !           398:        struct scsi_move_medium scsi_cmd;
        !           399:        int ret;
        !           400: 
        !           401:        bzero(&scsi_cmd, sizeof(scsi_cmd));
        !           402:        scsi_cmd.op_code = MOVE_MEDIUM;
        !           403:        scsi_cmd.transport_element_address[0]=(chm>>8)&0xff;
        !           404:        scsi_cmd.transport_element_address[1]=chm&0xff;
        !           405:        scsi_cmd.source_address[0]=(from>>8)&0xff;
        !           406:        scsi_cmd.source_address[1]=from&0xff;
        !           407:        scsi_cmd.destination_address[0]=(to>>8)&0xff;
        !           408:        scsi_cmd.destination_address[1]=to&0xff;
        !           409:        scsi_cmd.invert=(chm&CH_INVERT)?1:0;
        !           410:        if ((ret=ch_scsi_cmd(unit,
        !           411:                        &scsi_cmd,
        !           412:                        sizeof(scsi_cmd),
        !           413:                        NULL,
        !           414:                        0,
        !           415:                        100000,
        !           416:                        flags) !=ESUCCESS)) {
        !           417:                        *stat=ch_data[unit].lsterr;
        !           418:                        return ret;
        !           419:                        }
        !           420:        return ret;
        !           421: }
        !           422: 
        !           423: ch_position(unit,stat,chm,to,flags)
        !           424: int unit,chm,to,flags;
        !           425: short *stat;
        !           426: {
        !           427:        struct scsi_position_to_element scsi_cmd;
        !           428:        int ret;
        !           429: 
        !           430:        bzero(&scsi_cmd, sizeof(scsi_cmd));
        !           431:        scsi_cmd.op_code = POSITION_TO_ELEMENT;
        !           432:        scsi_cmd.transport_element_address[0]=(chm>>8)&0xff;
        !           433:        scsi_cmd.transport_element_address[1]=chm&0xff;
        !           434:        scsi_cmd.source_address[0]=(to>>8)&0xff;
        !           435:        scsi_cmd.source_address[1]=to&0xff;
        !           436:        scsi_cmd.invert=(chm&CH_INVERT)?1:0;
        !           437:        if ((ret=ch_scsi_cmd(unit,
        !           438:                        &scsi_cmd,
        !           439:                        sizeof(scsi_cmd),
        !           440:                        NULL,
        !           441:                        0,
        !           442:                        100000,
        !           443:                        flags) !=ESUCCESS)) {
        !           444:                        *stat=ch_data[unit].lsterr;
        !           445:                        return ret;
        !           446:                        }
        !           447:        return ret;
        !           448: }
        !           449: 
        !           450: /*******************************************************\
        !           451: * Check with the device that it is ok, (via scsi driver)*
        !           452: \*******************************************************/
        !           453: ch_req_sense(unit, flags)
        !           454: int    flags;
        !           455: {
        !           456:        struct  scsi_sense_data sense;
        !           457:        struct scsi_sense scsi_cmd;
        !           458: 
        !           459:        bzero(&scsi_cmd, sizeof(scsi_cmd));
        !           460:        scsi_cmd.op_code = REQUEST_SENSE;
        !           461:        scsi_cmd.length = sizeof(sense);
        !           462: 
        !           463:        if (ch_scsi_cmd(unit,
        !           464:                        &scsi_cmd,
        !           465:                        sizeof(struct   scsi_sense),
        !           466:                        &sense,
        !           467:                        sizeof(sense),
        !           468:                        100000,
        !           469:                        flags | SCSI_DATA_IN) != 0)
        !           470:        {
        !           471:                return(FALSE);
        !           472:        }
        !           473:        else 
        !           474:                return(TRUE);
        !           475: }
        !           476: 
        !           477: /*******************************************************\
        !           478: * Get scsi driver to send a "are you ready" command    *
        !           479: \*******************************************************/
        !           480: ch_test_ready(unit,flags)
        !           481: int    unit,flags;
        !           482: {
        !           483:        struct scsi_test_unit_ready scsi_cmd;
        !           484: 
        !           485:        bzero(&scsi_cmd, sizeof(scsi_cmd));
        !           486:        scsi_cmd.op_code = TEST_UNIT_READY;
        !           487: 
        !           488:        if (ch_scsi_cmd(unit,
        !           489:                        &scsi_cmd,
        !           490:                        sizeof(struct   scsi_test_unit_ready),
        !           491:                        0,
        !           492:                        0,
        !           493:                        100000,
        !           494:                        flags) != 0) {
        !           495:                return(FALSE);
        !           496:        } else 
        !           497:                return(TRUE);
        !           498: }
        !           499: 
        !           500: 
        !           501: #ifdef __STDC__
        !           502: #define b2tol(a)       (((unsigned)(a##_1) << 8) + (unsigned)a##_0 )
        !           503: #else
        !           504: #define b2tol(a)       (((unsigned)(a/**/_1) << 8) + (unsigned)a/**/_0 )
        !           505: #endif
        !           506: 
        !           507: /*******************************************************\
        !           508: * Get the scsi driver to send a full inquiry to the    *
        !           509: * device and use the results to fill out the global    *
        !           510: * parameter structure.                                 *
        !           511: \*******************************************************/
        !           512: ch_mode_sense(unit, flags)
        !           513: int    unit,flags;
        !           514: {
        !           515:        struct scsi_mode_sense scsi_cmd;
        !           516:        u_char scsi_sense[128]; /* Can't use scsi_mode_sense_data because of */
        !           517:                                /* missing block descriptor                  */
        !           518:        u_char *b;
        !           519:        int i,l;
        !           520: 
        !           521:        /*******************************************************\
        !           522:        * First check if we have it all loaded                  *
        !           523:        \*******************************************************/
        !           524:        if (ch_info_valid[unit]==CH_KNOWN) return(TRUE);
        !           525:        /*******************************************************\
        !           526:        * First do a mode sense                                 *
        !           527:        \*******************************************************/
        !           528:        ch_info_valid[unit] &= ~CH_KNOWN;
        !           529:        for(l=1;l>=0;l--) {
        !           530:                bzero(&scsi_cmd, sizeof(scsi_cmd));
        !           531:                scsi_cmd.op_code = MODE_SENSE;
        !           532:                scsi_cmd.dbd = l;
        !           533:                scsi_cmd.page_code = 0x3f;      /* All Pages */
        !           534:                scsi_cmd.length = sizeof(scsi_sense);
        !           535:        /*******************************************************\
        !           536:        * do the command, but we don't need the results         *
        !           537:        * just print them for our interest's sake               *
        !           538:        \*******************************************************/
        !           539:                if (ch_scsi_cmd(unit,
        !           540:                        &scsi_cmd,
        !           541:                        sizeof(struct   scsi_mode_sense),
        !           542:                        &scsi_sense,
        !           543:                        sizeof(scsi_sense),
        !           544:                        5000,
        !           545:                        flags | SCSI_DATA_IN) == 0) {
        !           546:                                ch_info_valid[unit] = CH_KNOWN;
        !           547:                                break;
        !           548:                        }
        !           549:        }
        !           550:        if (ch_info_valid[unit]!=CH_KNOWN)   {
        !           551:                if(!(flags & SCSI_SILENT))
        !           552:                        printf("could not mode sense for unit %d\n", unit);
        !           553:                return(FALSE);
        !           554:        }
        !           555:        l=scsi_sense[0]-3;
        !           556:        b=&scsi_sense[4];
        !           557:        /*****************************\
        !           558:        * To avoid alignment problems *
        !           559:        \*****************************/
        !           560: /*FIX THIS FOR MSB */
        !           561: #define p2copy(valp)    (valp[1]+ (valp[0]<<8));valp+=2
        !           562: #define p4copy(valp)    (valp[3]+ (valp[2]<<8) + (valp[1]<<16) + (valp[0]<<24));valp+=4
        !           563: #if 0
        !           564:        printf("\nmode_sense %d\n",l);
        !           565:        for(i=0;i<l+4;i++) {
        !           566:                printf("%x%c",scsi_sense[i],i%8==7?'\n':':');
        !           567:        }
        !           568:        printf("\n");
        !           569: #endif
        !           570:        for(i=0;i<l;) {
        !           571:                int pc=(*b++)&0x3f;
        !           572:                int pl=*b++;
        !           573:                u_char *bb=b;
        !           574:                switch(pc) {
        !           575:                        case 0x1d:
        !           576:                                ch_data[unit].chmo  =p2copy(bb);
        !           577:                                ch_data[unit].chms  =p2copy(bb);
        !           578:                                ch_data[unit].sloto =p2copy(bb);
        !           579:                                ch_data[unit].slots =p2copy(bb);
        !           580:                                ch_data[unit].imexo =p2copy(bb);
        !           581:                                ch_data[unit].imexs =p2copy(bb);
        !           582:                                ch_data[unit].driveo =p2copy(bb);
        !           583:                                ch_data[unit].drives =p2copy(bb);
        !           584:                                break;
        !           585:                        case 0x1e:
        !           586:                                ch_data[unit].rot = (*b)&1;
        !           587:                                break;
        !           588:                        case 0x1f:
        !           589:                                ch_data[unit].stor = *b&0xf;
        !           590:                                bb+=2;
        !           591:                                ch_data[unit].stor =p4copy(bb);
        !           592:                                break;
        !           593:                        default:
        !           594:                                break;
        !           595:                }
        !           596:                b+=pl;
        !           597:                i+=pl+2;
        !           598:        }
        !           599:        if (ch_debug)
        !           600:        {
        !           601:                printf("unit %d: cht(%d-%d)slot(%d-%d)imex(%d-%d)cts(%d-%d) %s rotate\n",
        !           602:                                unit,
        !           603:                                ch_data[unit].chmo,
        !           604:                                ch_data[unit].chms,
        !           605:                                ch_data[unit].sloto,
        !           606:                                ch_data[unit].slots,
        !           607:                                ch_data[unit].imexo,
        !           608:                                ch_data[unit].imexs,
        !           609:                                ch_data[unit].driveo,
        !           610:                                ch_data[unit].drives,
        !           611:                                ch_data[unit].rot?"can":"can't");
        !           612:        }
        !           613:        return(TRUE);
        !           614: }
        !           615: 
        !           616: /*******************************************************\
        !           617: * ask the scsi driver to perform a command for us.     *
        !           618: * Call it through the switch table, and tell it which  *
        !           619: * sub-unit we want, and what target and lu we wish to  *
        !           620: * talk to. Also tell it where to find the command      *
        !           621: * how long int is.                                     *
        !           622: * Also tell it where to read/write the data, and how   *
        !           623: * long the data is supposed to be                      *
        !           624: \*******************************************************/
        !           625: int    ch_scsi_cmd(unit,scsi_cmd,cmdlen,data_addr,datalen,timeout,flags)
        !           626: 
        !           627: int    unit,flags;
        !           628: struct scsi_generic *scsi_cmd;
        !           629: int    cmdlen;
        !           630: int    timeout;
        !           631: u_char *data_addr;
        !           632: int    datalen;
        !           633: {
        !           634:        struct  scsi_xfer *xs;
        !           635:        int     retval;
        !           636:        int     s;
        !           637: 
        !           638:        if(ch_debug||(scsi_debug & PRINTROUTINES)) printf("\nch_scsi_cmd%d %x",
        !           639:                                unit,scsi_cmd->opcode);
        !           640:        if(ch_data[unit].sc_sw) /* If we have a scsi driver */
        !           641:        {
        !           642: 
        !           643:                xs = &(ch_scsi_xfer[unit]);
        !           644:                if(!(flags & SCSI_NOMASK))
        !           645:                        s = splbio();
        !           646:                ch_xfer_block_wait[unit]++;     /* there is someone waiting */
        !           647:                while (xs->flags & INUSE)
        !           648:                {
        !           649:                        sleep(&ch_xfer_block_wait[unit],PRIBIO+1);
        !           650:                }
        !           651:                ch_xfer_block_wait[unit]--;
        !           652:                xs->flags = INUSE;
        !           653:                if(!(flags & SCSI_NOMASK))
        !           654:                        splx(s);
        !           655: 
        !           656:                /*******************************************************\
        !           657:                * Fill out the scsi_xfer structure                      *
        !           658:                \*******************************************************/
        !           659:                xs->flags       |=      flags;
        !           660:                xs->adapter     =       ch_data[unit].ctlr;
        !           661:                xs->targ        =       ch_data[unit].targ;
        !           662:                xs->lu          =       ch_data[unit].lu;
        !           663:                xs->retries     =       CH_RETRIES;
        !           664:                xs->timeout     =       timeout;
        !           665:                xs->cmd         =       scsi_cmd;
        !           666:                xs->cmdlen      =       cmdlen;
        !           667:                xs->data        =       data_addr;
        !           668:                xs->datalen     =       datalen;
        !           669:                xs->resid       =       datalen;
        !           670:                xs->when_done   =       (flags & SCSI_NOMASK)
        !           671:                                        ?(int (*)())0
        !           672:                                        :ch_done;
        !           673:                xs->done_arg    =       unit;
        !           674:                xs->done_arg2   =       (int)xs;
        !           675: retry:         xs->error       =       XS_NOERROR;
        !           676:                xs->bp          =       0;
        !           677:                ch_data[unit].lsterr=0;
        !           678:                retval = (*(ch_data[unit].sc_sw->scsi_cmd))(xs);
        !           679:                switch(retval)
        !           680:                {
        !           681:                case    SUCCESSFULLY_QUEUED:
        !           682:                        while(!(xs->flags & ITSDONE))
        !           683:                                sleep(xs,PRIBIO+1);
        !           684: 
        !           685:                case    HAD_ERROR:
        !           686:                case    COMPLETE:
        !           687:                        switch(xs->error)
        !           688:                        {
        !           689:                        case    XS_NOERROR:
        !           690:                                retval = ESUCCESS;
        !           691:                                break;
        !           692:                        case    XS_SENSE:
        !           693:                                retval = (ch_interpret_sense(unit,xs));
        !           694:                                break;
        !           695:                        case    XS_DRIVER_STUFFUP:
        !           696:                                retval = EIO;
        !           697:                                break;
        !           698:                        case    XS_TIMEOUT:
        !           699:                                if(xs->retries-- )
        !           700:                                {
        !           701:                                        xs->flags &= ~ITSDONE;
        !           702:                                        goto retry;
        !           703:                                }
        !           704:                                retval = EIO;
        !           705:                                break;
        !           706:                        case    XS_BUSY:
        !           707:                                if(xs->retries-- )
        !           708:                                {
        !           709:                                        xs->flags &= ~ITSDONE;
        !           710:                                        goto retry;
        !           711:                                }
        !           712:                                retval = EIO;
        !           713:                                break;
        !           714:                        default:
        !           715:                                retval = EIO;
        !           716:                                printf("st%d: unknown error category from scsi driver\n"
        !           717:                                        ,unit);
        !           718:                                break;
        !           719:                        }       
        !           720:                        break;
        !           721:                case    TRY_AGAIN_LATER:
        !           722:                        if(xs->retries-- )
        !           723:                        {
        !           724:                                xs->flags &= ~ITSDONE;
        !           725:                                goto retry;
        !           726:                        }
        !           727:                        retval = EIO;
        !           728:                        break;
        !           729:                default:
        !           730:                        retval = EIO;
        !           731:                }
        !           732:                xs->flags = 0;  /* it's free! */
        !           733:                chstart(unit);
        !           734:        }
        !           735:        else
        !           736:        {
        !           737:                printf("chd: not set up\n",unit);
        !           738:                return(EINVAL);
        !           739:        }
        !           740:        return(retval);
        !           741: }
        !           742: /***************************************************************\
        !           743: * Look at the returned sense and act on the error and detirmine        *
        !           744: * The unix error number to pass back... (0 = report no error)  *
        !           745: \***************************************************************/
        !           746: 
        !           747: int    ch_interpret_sense(unit,xs)
        !           748: int    unit;
        !           749: struct scsi_xfer       *xs;
        !           750: {
        !           751:        struct  scsi_sense_data *sense;
        !           752:        int     key;
        !           753:        int     silent = xs->flags & SCSI_SILENT;
        !           754: 
        !           755:        /***************************************************************\
        !           756:        * If errors are ok, report a success                            *
        !           757:        \***************************************************************/
        !           758:        if(xs->flags & SCSI_ERR_OK) return(ESUCCESS);
        !           759: 
        !           760:        /***************************************************************\
        !           761:        * Get the sense fields and work out what CLASS                  *
        !           762:        \***************************************************************/
        !           763:        sense = &(xs->sense);
        !           764:        switch(sense->error_class)
        !           765:        {
        !           766:        /***************************************************************\
        !           767:        * If it's class 7, use the extended stuff and interpret the key *
        !           768:        \***************************************************************/
        !           769:        case 7:
        !           770:                {
        !           771:                key=sense->ext.extended.sense_key;
        !           772:                if(sense->ext.extended.ili)
        !           773:                        if(!silent)
        !           774:                        {
        !           775:                                printf("length error ");
        !           776:                        }
        !           777:                        if(sense->valid)
        !           778:                                xs->resid = ntohl(*((long *)sense->ext.extended.info));
        !           779:                                if(xs->bp)
        !           780:                                {
        !           781:                                        xs->bp->b_flags |= B_ERROR;
        !           782:                                        return(ESUCCESS);
        !           783:                                }
        !           784:                if(sense->ext.extended.eom)
        !           785:                        if(!silent) printf("end of medium ");
        !           786:                if(sense->ext.extended.filemark)
        !           787:                        if(!silent) printf("filemark ");
        !           788:                if(ch_debug)
        !           789:                {
        !           790:                        printf("code%x class%x valid%x\n"
        !           791:                                        ,sense->error_code
        !           792:                                        ,sense->error_class
        !           793:                                        ,sense->valid);
        !           794:                        printf("seg%x key%x ili%x eom%x fmark%x\n"
        !           795:                                        ,sense->ext.extended.segment
        !           796:                                        ,sense->ext.extended.sense_key
        !           797:                                        ,sense->ext.extended.ili
        !           798:                                        ,sense->ext.extended.eom
        !           799:                                        ,sense->ext.extended.filemark);
        !           800:                        printf("info: %x %x %x %x followed by %d extra bytes\n"
        !           801:                                        ,sense->ext.extended.info[0]
        !           802:                                        ,sense->ext.extended.info[1]
        !           803:                                        ,sense->ext.extended.info[2]
        !           804:                                        ,sense->ext.extended.info[3]
        !           805:                                        ,sense->ext.extended.extra_len);
        !           806:                        printf("extra: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n"
        !           807:                                        ,sense->ext.extended.extra_bytes[0]
        !           808:                                        ,sense->ext.extended.extra_bytes[1]
        !           809:                                        ,sense->ext.extended.extra_bytes[2]
        !           810:                                        ,sense->ext.extended.extra_bytes[3]
        !           811:                                        ,sense->ext.extended.extra_bytes[4]
        !           812:                                        ,sense->ext.extended.extra_bytes[5]
        !           813:                                        ,sense->ext.extended.extra_bytes[6]
        !           814:                                        ,sense->ext.extended.extra_bytes[7]
        !           815:                                        ,sense->ext.extended.extra_bytes[8]
        !           816:                                        ,sense->ext.extended.extra_bytes[9]
        !           817:                                        ,sense->ext.extended.extra_bytes[10]
        !           818:                                        ,sense->ext.extended.extra_bytes[11]
        !           819:                                        ,sense->ext.extended.extra_bytes[12]
        !           820:                                        ,sense->ext.extended.extra_bytes[13]
        !           821:                                        ,sense->ext.extended.extra_bytes[14]
        !           822:                                        ,sense->ext.extended.extra_bytes[15]);
        !           823:                                    
        !           824:                }
        !           825:                switch(key)
        !           826:                {
        !           827:                case    0x0:
        !           828:                        return(ESUCCESS);
        !           829:                case    0x1:
        !           830:                        if(!silent)
        !           831:                        {
        !           832:                                printf("st%d: soft error(corrected) ", unit); 
        !           833:                                if(sense->valid)
        !           834:                                {
        !           835:                                        printf("block no. %d (decimal)\n",
        !           836:                                        (sense->ext.extended.info[0] <<24)|
        !           837:                                        (sense->ext.extended.info[1] <<16)|
        !           838:                                        (sense->ext.extended.info[2] <<8)|
        !           839:                                        (sense->ext.extended.info[3] ));
        !           840:                                }
        !           841:                                else
        !           842:                                {
        !           843:                                        printf("\n");
        !           844:                                }
        !           845:                        }
        !           846:                        return(ESUCCESS);
        !           847:                case    0x2:
        !           848:                        if(!silent) printf("st%d: not ready\n ", unit); 
        !           849:                        ch_data[unit].lsterr=(sense->ext.extended.info[12]<<8)|
        !           850:                                                                sense->ext.extended.info[13] ;
        !           851:                        return(ENODEV);
        !           852:                case    0x3:
        !           853:                        if(!silent)
        !           854:                        {
        !           855:                                printf("st%d: medium error ", unit); 
        !           856:                                if(sense->valid)
        !           857:                                {
        !           858:                                        printf("block no. %d (decimal)\n",
        !           859:                                        (sense->ext.extended.info[0] <<24)|
        !           860:                                        (sense->ext.extended.info[1] <<16)|
        !           861:                                        (sense->ext.extended.info[2] <<8)|
        !           862:                                        (sense->ext.extended.info[3] ));
        !           863:                                }
        !           864:                                else
        !           865:                                {
        !           866:                                        printf("\n");
        !           867:                                }
        !           868:                        }
        !           869:                        return(EIO);
        !           870:                case    0x4:
        !           871:                        if(!silent) printf("st%d: non-media hardware failure\n ",
        !           872:                                unit); 
        !           873:                        ch_data[unit].lsterr=(sense->ext.extended.info[12]<<8)|
        !           874:                                                                sense->ext.extended.info[13] ;
        !           875:                        return(EIO);
        !           876:                case    0x5:
        !           877:                        if(!silent) printf("st%d: illegal request\n ", unit); 
        !           878:                        ch_data[unit].lsterr=(sense->ext.extended.info[12]<<8)|
        !           879:                                                                sense->ext.extended.info[13] ;
        !           880:                        return(EINVAL);
        !           881:                case    0x6:
        !           882:                        if(!silent) printf("st%d: Unit attention.\n ", unit); 
        !           883:                        ch_data[unit].lsterr=(sense->ext.extended.info[12]<<8)|
        !           884:                                                                sense->ext.extended.info[13] ;
        !           885:                        ch_info_valid[unit] = FALSE;
        !           886:                        if (ch_data[unit].flags & CH_OPEN) /* TEMP!!!! */
        !           887:                                return(EIO);
        !           888:                        else
        !           889:                                return(ESUCCESS);
        !           890:                case    0x7:
        !           891:                        if(!silent)
        !           892:                        {
        !           893:                                printf("st%d: attempted protection violation "
        !           894:                                                                , unit); 
        !           895:                                if(sense->valid)
        !           896:                                {
        !           897:                                        printf("block no. %d (decimal)\n",
        !           898:                                        (sense->ext.extended.info[0] <<24)|
        !           899:                                        (sense->ext.extended.info[1] <<16)|
        !           900:                                        (sense->ext.extended.info[2] <<8)|
        !           901:                                        (sense->ext.extended.info[3] ));
        !           902:                                }
        !           903:                                else
        !           904:                                {
        !           905:                                        printf("\n");
        !           906:                                }
        !           907:                        }
        !           908:                        return(EACCES);
        !           909:                case    0x8:
        !           910:                        if(!silent)
        !           911:                        {
        !           912:                                printf("st%d: block wrong state (worm)\n "
        !           913:                                                        , unit); 
        !           914:                                if(sense->valid)
        !           915:                                {
        !           916:                                        printf("block no. %d (decimal)\n",
        !           917:                                        (sense->ext.extended.info[0] <<24)|
        !           918:                                        (sense->ext.extended.info[1] <<16)|
        !           919:                                        (sense->ext.extended.info[2] <<8)|
        !           920:                                        (sense->ext.extended.info[3] ));
        !           921:                                }
        !           922:                                else
        !           923:                                {
        !           924:                                        printf("\n");
        !           925:                                }
        !           926:                        }
        !           927:                        return(EIO);
        !           928:                case    0x9:
        !           929:                        if(!silent) printf("st%d: vendor unique\n",
        !           930:                                unit); 
        !           931:                        return(EIO);
        !           932:                case    0xa:
        !           933:                        if(!silent) printf("st%d: copy aborted\n ",
        !           934:                                unit); 
        !           935:                        return(EIO);
        !           936:                case    0xb:
        !           937:                        if(!silent) printf("st%d: command aborted\n ",
        !           938:                                unit); 
        !           939:                        ch_data[unit].lsterr=(sense->ext.extended.info[12]<<8)|
        !           940:                                                                sense->ext.extended.info[13] ;
        !           941:                        return(EIO);
        !           942:                case    0xc:
        !           943:                        if(!silent)
        !           944:                        {
        !           945:                                printf("st%d: search returned\n ", unit); 
        !           946:                                if(sense->valid)
        !           947:                                {
        !           948:                                        printf("block no. %d (decimal)\n",
        !           949:                                        (sense->ext.extended.info[0] <<24)|
        !           950:                                        (sense->ext.extended.info[1] <<16)|
        !           951:                                        (sense->ext.extended.info[2] <<8)|
        !           952:                                        (sense->ext.extended.info[3] ));
        !           953:                                }
        !           954:                                else
        !           955:                                {
        !           956:                                        printf("\n");
        !           957:                                }
        !           958:                        }
        !           959:                        return(ESUCCESS);
        !           960:                case    0xd:
        !           961:                        if(!silent) printf("st%d: volume overflow\n ",
        !           962:                                unit); 
        !           963:                        return(ENOSPC);
        !           964:                case    0xe:
        !           965:                        if(!silent)
        !           966:                        {
        !           967:                                printf("st%d: verify miscompare\n ", unit); 
        !           968:                                if(sense->valid)
        !           969:                                {
        !           970:                                        printf("block no. %d (decimal)\n",
        !           971:                                        (sense->ext.extended.info[0] <<24)|
        !           972:                                        (sense->ext.extended.info[1] <<16)|
        !           973:                                        (sense->ext.extended.info[2] <<8)|
        !           974:                                        (sense->ext.extended.info[3] ));
        !           975:                                }
        !           976:                                else
        !           977:                                {
        !           978:                                        printf("\n");
        !           979:                                }
        !           980:                        }
        !           981:                        return(EIO);
        !           982:                case    0xf:
        !           983:                        if(!silent) printf("st%d: unknown error key\n ",
        !           984:                                unit); 
        !           985:                        return(EIO);
        !           986:                }
        !           987:                break;
        !           988:        }
        !           989:        /***************************************************************\
        !           990:        * If it's NOT class 7, just report it.                          *
        !           991:        \***************************************************************/
        !           992:        case 0:
        !           993:        case 1:
        !           994:        case 2:
        !           995:        case 3:
        !           996:        case 4:
        !           997:        case 5:
        !           998:        case 6:
        !           999:                {
        !          1000:                        if(!silent) printf("st%d: error class %d code %d\n",
        !          1001:                                unit,
        !          1002:                                sense->error_class,
        !          1003:                                sense->error_code);
        !          1004:                if(sense->valid)
        !          1005:                        if(!silent) printf("block no. %d (decimal)\n",
        !          1006:                        (sense->ext.unextended.blockhi <<16),
        !          1007:                        + (sense->ext.unextended.blockmed <<8),
        !          1008:                        + (sense->ext.unextended.blocklow ));
        !          1009:                }
        !          1010:                return(EIO);
        !          1011:        }
        !          1012: }
        !          1013: 
        !          1014: 
        !          1015: 

unix.superglobalmegacorp.com

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