Annotation of Gnu-Mach/scsi/scsi_alldevs.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
                     11:  * 
                     12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     File: scsi_alldevs.c
                     28:  *     Author: Alessandro Forin, Carnegie Mellon University
                     29:  *     Date:   10/90
                     30:  *
                     31:  *     Middle layer of the SCSI driver: SCSI protocol implementation
                     32:  *     This file contains code for SCSI commands defined for all device types.
                     33:  */
                     34: 
                     35: #include <mach/std_types.h>
                     36: #include <sys/types.h>
                     37: #include <scsi/compat_30.h>
                     38: 
                     39: #include <scsi/scsi.h>
                     40: #include <scsi/scsi2.h>
                     41: #include <scsi/scsi_defs.h>
                     42: 
                     43: #if  (NSCSI > 0)
                     44: 
                     45: void scsi_print_add_sense_keys(); /* forward */
                     46: 
                     47: /*
                     48:  * Utilities
                     49:  */
                     50: void scsi_go_and_wait(tgt, insize, outsize, ior)
                     51:        target_info_t   *tgt;
                     52:        int insize, outsize;
                     53:        io_req_t        ior;
                     54: {
                     55:        register scsi_softc_t   *sc = scsi_softc[(unsigned char)tgt->masterno];
                     56: 
                     57:        tgt->ior = ior;
                     58: 
                     59:        (*sc->go)(tgt, insize, outsize, ior==0);
                     60: 
                     61:        if (ior)
                     62:                iowait(ior);
                     63:        else
                     64:                while (tgt->done == SCSI_RET_IN_PROGRESS);
                     65: }
                     66: 
                     67: void scsi_go(tgt, insize, outsize, cmd_only)
                     68:        target_info_t   *tgt;
                     69:        int insize, outsize, cmd_only;
                     70: {
                     71:        register scsi_softc_t   *sc = scsi_softc[(unsigned char)tgt->masterno];
                     72: 
                     73:        (*sc->go)(tgt, insize, outsize, cmd_only);
                     74: }
                     75: 
                     76: int sizeof_scsi_command(
                     77:        unsigned char   cmd)
                     78: {
                     79:        switch ((cmd & SCSI_CODE_GROUP) >> 5) {
                     80:            case 0: return sizeof(scsi_command_group_0);
                     81:            case 1: return sizeof(scsi_command_group_1);
                     82:            case 2: return sizeof(scsi_command_group_2);
                     83:            /* 3,4 reserved */
                     84:            case 5: return sizeof(scsi_command_group_5);
                     85:            /* 6,7 vendor specific (!!) */
                     86:            case 6: return sizeof(scsi_command_group_2);
                     87:        }
                     88: }
                     89: 
                     90: /*
                     91:  * INQUIRY (Almost mandatory)
                     92:  */
                     93: int scsi_inquiry( tgt, pagecode)
                     94:        register target_info_t  *tgt;
                     95:        int                     pagecode;
                     96: {
                     97:        scsi_cmd_inquiry_t      *cmd;
                     98:        boolean_t               no_ify = TRUE;
                     99: 
                    100: retry:
                    101:        cmd = (scsi_cmd_inquiry_t*) (tgt->cmd_ptr);
                    102:        cmd->scsi_cmd_code = SCSI_CMD_INQUIRY;
                    103:        cmd->scsi_cmd_lun_and_lba1 = 0;
                    104:        cmd->scsi_cmd_lba3 = 0;
                    105:        cmd->scsi_cmd_xfer_len = 0xff;  /* max len always */
                    106:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
                    107: /*#ifdef       SCSI2*/
                    108:        if (pagecode != SCSI_INQ_STD_DATA) {
                    109:                cmd->scsi_cmd_lun_and_lba1 |= SCSI_CMD_INQ_EVPD;
                    110:                cmd->scsi_cmd_page_code = pagecode;
                    111:        } else
                    112: /*#endif       SCSI2*/
                    113:                cmd->scsi_cmd_page_code = 0;
                    114: 
                    115:        tgt->cur_cmd = SCSI_CMD_INQUIRY;
                    116: 
                    117:        /*
                    118:         * Note: this is sent when we do not know much about the
                    119:         * target, so we might not put an identify message upfront
                    120:         */
                    121:        scsi_go(tgt, sizeof(*cmd), 0xff, no_ify);
                    122: 
                    123:        /*
                    124:         * This spin loop is because we are called at autoconf
                    125:         * time where we cannot thread_block(). Sigh.
                    126:         */
                    127:        while (tgt->done == SCSI_RET_IN_PROGRESS) ;
                    128:        if (tgt->done == SCSI_RET_RETRY)        /* sync negotiation ? */
                    129:                goto retry;
                    130:        if ((tgt->done != SCSI_RET_SUCCESS) && no_ify) {
                    131:                no_ify = FALSE;
                    132:                goto retry;
                    133:        }
                    134:        return tgt->done;
                    135: }
                    136: 
                    137: void scsi_print_inquiry( inq, pagecode, result)
                    138:        scsi2_inquiry_data_t    *inq;
                    139:        int                     pagecode;
                    140:        char                    *result;
                    141: {
                    142:        static char *periph_names[10] = {
                    143:                "disk", "tape", "printer", "processor", "WORM-disk",
                    144:                "CD-ROM", "scanner", "memory", "jukebox", "communication"
                    145:        };
                    146:        static char *periph_state[4] = {
                    147:                "online", "offline", "?", "absent"
                    148:        };
                    149: 
                    150:        char dev[SCSI_TARGET_NAME_LEN], *devname;
                    151:        register int i, j = 0;
                    152: 
                    153:        if (pagecode != SCSI_INQ_STD_DATA)
                    154:                return;
                    155: 
                    156:        devname = result ? result : dev;
                    157: 
                    158:        if (!result) {
                    159:                printf("\n\t%s%s %s (%s %x)",
                    160:                        (inq->rmb) ? "" : "non-", "removable SCSI",
                    161:                        (inq->periph_type > 10) ?
                    162:                                "?device?" : periph_names[inq->periph_type],
                    163:                        periph_state[inq->periph_qual & 0x3],
                    164:                        inq->device_type);
                    165:                printf("\n\t%s%s%s",
                    166:                        inq->iso ? "ISO-compliant, " : "",
                    167:                        inq->ecma ? "ECMA-compliant, " : "",
                    168:                        inq->ansi ? "ANSI-compliant, " : "");
                    169:                if (inq->ansi)
                    170:                        printf("%s%d, ", "SCSI-", inq->ansi);
                    171:                if (inq->response_fmt == 2)
                    172:                        printf("%s%s%s%s%s%s%s%s%s%s%s", "Supports: ",
                    173:                        inq->aenc ? "AENC, " : "",
                    174:                        inq->trmIOP ? "TrmIOP, " : "",
                    175:                        inq->RelAdr ? "RelAdr, " : "",
                    176:                        inq->Wbus32 ? "32 bit xfers, " : "",
                    177:                        inq->Wbus16 ? "16 bis xfers, " : "",
                    178:                        inq->Sync ? "Sync xfers, " : "",
                    179:                        inq->Linked ? "Linked cmds, " : "",
                    180:                        inq->CmdQue ? "Tagged cmd queues, " : "",
                    181:                        inq->SftRe ? "Soft" : "Hard", " RESET, ");
                    182:        }
                    183: 
                    184:        for (i = 0; i < 8; i++)
                    185:                if (inq->vendor_id[i] != ' ')
                    186:                        devname[j++] = inq->vendor_id[i];
                    187:        devname[j++] = ' ';
                    188:        for (i = 0; i < 16; i++)
                    189:                if (inq->product_id[i] != ' ')
                    190:                        devname[j++] = inq->product_id[i];
                    191:        devname[j++] = ' ';
                    192:        for (i = 0; i < 4; i++)
                    193:                if (inq->product_rev[i] != ' ')
                    194:                        devname[j++] = inq->product_rev[i];
                    195: #if unsafe
                    196:        devname[j++] = ' ';
                    197:        for (i = 0; i < 8; i++)
                    198:                if (inq->vendor_uqe[i] != ' ')
                    199:                        devname[j++] = inq->vendor_uqe[i];
                    200: #endif
                    201:        devname[j] = 0;
                    202: 
                    203:        if (!result)
                    204:                printf("(%s, %s%s)\n", devname, "SCSI ",
                    205:                        (inq->periph_type > 10) ?
                    206:                                "?device?" : periph_names[inq->periph_type]);
                    207: }
                    208: 
                    209: /*
                    210:  * REQUESTE SENSE (Mandatory, All)
                    211:  */
                    212: 
                    213: int scsi_request_sense(tgt, ior, data)
                    214:        register target_info_t  *tgt;
                    215:        io_req_t                ior;
                    216:        char                    **data;
                    217: {
                    218:        scsi_cmd_request_sense_t *cmd;
                    219: 
                    220:        cmd = (scsi_cmd_request_sense_t *) (tgt->cmd_ptr);
                    221:        cmd->scsi_cmd_code = SCSI_CMD_REQUEST_SENSE;
                    222:        cmd->scsi_cmd_lun_and_lba1 = 0;
                    223:        cmd->scsi_cmd_lba2 = 0;
                    224:        cmd->scsi_cmd_lba3 = 0;
                    225:        cmd->scsi_cmd_allocation_length = 0xff; /* max len always */
                    226:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
                    227: 
                    228:        tgt->cur_cmd = SCSI_CMD_REQUEST_SENSE;
                    229: 
                    230:        if (ior==0)
                    231:                scsi_go_and_wait (tgt, sizeof(*cmd), 0xff, ior);
                    232:        else {
                    233:                scsi_go(tgt, sizeof(*cmd), 0xff, FALSE);
                    234:                return tgt->done;
                    235:        }
                    236: 
                    237:        if (data)
                    238:                *data = tgt->cmd_ptr;
                    239: 
                    240:        (void) scsi_check_sense_data(tgt, tgt->cmd_ptr);
                    241: 
                    242:        return tgt->done;
                    243: }
                    244: 
                    245: boolean_t
                    246: scsi_check_sense_data(tgt, sns)
                    247:        register target_info_t  *tgt;
                    248:        scsi_sense_data_t       *sns;
                    249: {
                    250:        unsigned char   code;
                    251: 
                    252:        if (sns->error_class != SCSI_SNS_XTENDED_SENSE_DATA) {
                    253:                printf("Bad sense data, vuqe class x%x code x%x\n",
                    254:                        sns->error_class, sns->error_code);
                    255:                return FALSE;   /* and good luck */
                    256:        } else {
                    257:                code = sns->u.xtended.sense_key;
                    258: 
                    259:                switch (code) {
                    260:                case SCSI_SNS_NOSENSE:
                    261:                case SCSI_SNS_EQUAL:
                    262:                        return TRUE;
                    263:                        break;
                    264:                case SCSI_SNS_RECOVERED:
                    265:                        scsi_error(tgt, SCSI_ERR_BAD | SCSI_ERR_SENSE,
                    266:                                   code, sns->u.xtended.add_bytes);
                    267:                        return TRUE;
                    268:                        break;
                    269:                case SCSI_SNS_UNIT_ATN:
                    270:                        scsi_error(tgt, SCSI_ERR_SENSE,
                    271:                                   code, sns->u.xtended.add_bytes);
                    272:                        return TRUE;
                    273:                        break;
                    274:                case SCSI_SNS_NOTREADY:
                    275:                        tgt->done = SCSI_RET_RETRY;
                    276:                        return TRUE;
                    277:                case SCSI_SNS_ILLEGAL_REQ:
                    278:                        if (tgt->flags & TGT_OPTIONAL_CMD)
                    279:                                return TRUE;
                    280:                        /* fall through */
                    281:                default:
                    282: /* e.g.
                    283:                case SCSI_SNS_MEDIUM_ERR:
                    284:                case SCSI_SNS_HW_ERR:
                    285:                case SCSI_SNS_PROTECT:
                    286:                case SCSI_SNS_BLANK_CHK:
                    287:                case SCSI_SNS_VUQE:
                    288:                case SCSI_SNS_COPY_ABRT:
                    289:                case SCSI_SNS_ABORTED:
                    290:                case SCSI_SNS_VOLUME_OVFL:
                    291:                case SCSI_SNS_MISCOMPARE:
                    292:                case SCSI_SNS_RESERVED:
                    293: */
                    294:                        scsi_error(tgt, SCSI_ERR_GRAVE|SCSI_ERR_SENSE,
                    295:                                   code, sns->u.xtended.add_bytes);
                    296:                        return FALSE;
                    297:                        break;
                    298:                }
                    299:        }
                    300: }
                    301: 
                    302: /*
                    303:  * START STOP UNIT (Optional, disk prin work rom tape[load/unload])
                    304:  */
                    305: int scsi_start_unit( tgt, ss, ior)
                    306:        register target_info_t  *tgt;
                    307:        int                     ss;
                    308:        io_req_t                ior;
                    309: {
                    310:        scsi_cmd_start_t        *cmd;
                    311: 
                    312:        cmd = (scsi_cmd_start_t*) (tgt->cmd_ptr);
                    313:        cmd->scsi_cmd_code = SCSI_CMD_START_STOP_UNIT;
                    314:        cmd->scsi_cmd_lun_and_lba1 = SCSI_CMD_SS_IMMED;/* 0 won't work ? */
                    315:        cmd->scsi_cmd_lba2 = 0;
                    316:        cmd->scsi_cmd_lba3 = 0;
                    317:        cmd->scsi_cmd_ss_flags = ss;
                    318:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
                    319:        
                    320:        tgt->cur_cmd = SCSI_CMD_START_STOP_UNIT;
                    321: 
                    322:        scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
                    323:        return tgt->done;
                    324: }
                    325: 
                    326: /*
                    327:  * TEST UNIT READY (Optional, All)
                    328:  * Note: this is where we do the synch negotiation at autoconf
                    329:  */
                    330: int scsi_test_unit_ready( tgt, ior)
                    331:        register target_info_t  *tgt;
                    332:        io_req_t                ior;
                    333: {
                    334:        scsi_cmd_test_unit_ready_t      *cmd;
                    335: 
                    336:        cmd = (scsi_cmd_test_unit_ready_t*) (tgt->cmd_ptr);
                    337: 
                    338:        cmd->scsi_cmd_code = SCSI_CMD_TEST_UNIT_READY;
                    339:        cmd->scsi_cmd_lun_and_lba1 = 0;
                    340:        cmd->scsi_cmd_lba2 = 0;
                    341:        cmd->scsi_cmd_lba3 = 0;
                    342:        cmd->scsi_cmd_ss_flags = 0;
                    343:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
                    344:        
                    345:        tgt->cur_cmd = SCSI_CMD_TEST_UNIT_READY;
                    346: 
                    347:        scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
                    348: 
                    349:        return tgt->done;
                    350: }
                    351: 
                    352: /*
                    353:  * RECEIVE DIAGNOSTIC RESULTS (Optional, All)
                    354:  */
                    355: int scsi_receive_diag( tgt, result, result_len, ior)
                    356:        register target_info_t  *tgt;
                    357:        char                    *result;
                    358:        int                     result_len;
                    359:        io_req_t                ior;
                    360: {
                    361:        scsi_cmd_receive_diag_t *cmd;
                    362: 
                    363:        cmd = (scsi_cmd_receive_diag_t*) (tgt->cmd_ptr);
                    364:        cmd->scsi_cmd_code = SCSI_CMD_RECEIVE_DIAG_RESULTS;
                    365:        cmd->scsi_cmd_lun_and_lba1 = 0;
                    366:        cmd->scsi_cmd_lba2 = 0;
                    367:        cmd->scsi_cmd_lba3 = result_len >> 8 & 0xff;
                    368:        cmd->scsi_cmd_xfer_len = result_len & 0xff;
                    369:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
                    370:        
                    371:        tgt->cur_cmd = SCSI_CMD_RECEIVE_DIAG_RESULTS;
                    372: 
                    373:        scsi_go_and_wait(tgt, sizeof(*cmd), result_len, ior);
                    374: 
                    375:        bcopy(tgt->cmd_ptr, (char*)result, result_len);
                    376: 
                    377:        return tgt->done;
                    378: }
                    379: 
                    380: 
                    381: int scsi_mode_sense( tgt, pagecode, len, ior)
                    382:        register target_info_t  *tgt;
                    383:        int                     pagecode;
                    384:        int                     len;
                    385:        io_req_t                ior;
                    386: {
                    387:        scsi_cmd_mode_sense_t   *cmd;
                    388: 
                    389:        cmd = (scsi_cmd_mode_sense_t*) (tgt->cmd_ptr);
                    390:        cmd->scsi_cmd_code = SCSI_CMD_MODE_SENSE;
                    391:        cmd->scsi_cmd_lun_and_lba1 = 0;
                    392:        cmd->scsi_cmd_ms_pagecode = pagecode;
                    393:        cmd->scsi_cmd_lba3 = 0;
                    394:        cmd->scsi_cmd_xfer_len = len;
                    395:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
                    396:        
                    397:        tgt->cur_cmd = SCSI_CMD_MODE_SENSE;
                    398: 
                    399:        scsi_go_and_wait(tgt, sizeof(*cmd), len, ior);
                    400: 
                    401:        return tgt->done;
                    402: }
                    403: 
                    404: #if    0 /* unused */
                    405: 
                    406: /*
                    407:  * COPY (Optional, All)
                    408:  */
                    409: void scsi_copy( tgt, params, params_len, ior)
                    410:        register target_info_t  *tgt;
                    411:        char                    *params;
                    412:        io_req_t                ior;
                    413: {
                    414:        scsi_cmd_copy_t *cmd;
                    415: 
                    416:        cmd = (scsi_cmd_copy_t*) (tgt->cmd_ptr;
                    417:        cmd->scsi_cmd_code = SCSI_CMD_COPY;
                    418:        cmd->scsi_cmd_lun_and_lba1 = 0;
                    419:        cmd->scsi_cmd_lba2 = params_len>>16 & 0xff;
                    420:        cmd->scsi_cmd_lba3 = params_len >> 8 & 0xff;
                    421:        cmd->scsi_cmd_xfer_len = params_len & 0xff;
                    422:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
                    423:        
                    424:        bcopy(params, cmd + 1, params_len);
                    425: 
                    426:        tgt->cur_cmd = SCSI_CMD_COPY;
                    427: 
                    428:        scsi_go_and_wait(tgt, sizeof(*cmd) + params_len, 0, ior);
                    429: }
                    430: 
                    431: /*
                    432:  * SEND DIAGNOSTIC (Optional, All)
                    433:  */
                    434: void scsi_send_diag( tgt, flags, params, params_len, ior)
                    435:        register target_info_t  *tgt;
                    436:        char                    *params;
                    437:        io_req_t                ior;
                    438: {
                    439:        scsi_cmd_send_diag_t    *cmd;
                    440: 
                    441:        cmd = (scsi_cmd_send_diag_t*) (tgt->cmd_ptr);
                    442:        cmd->scsi_cmd_code = SCSI_CMD_SEND_DIAGNOSTICS;
                    443:        cmd->scsi_cmd_lun_and_lba1 = flags & 0x7;
                    444:        cmd->scsi_cmd_lba2 = 0;
                    445:        cmd->scsi_cmd_lba3 = params_len >> 8 & 0xff;
                    446:        cmd->scsi_cmd_xfer_len = params_len & 0xff;
                    447:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
                    448:        
                    449:        bcopy(params, cmd + 1, params_len);
                    450: 
                    451:        tgt->cur_cmd = SCSI_CMD_SEND_DIAGNOSTICS;
                    452: 
                    453:        scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
                    454: }
                    455: 
                    456: /*
                    457:  * COMPARE (Optional, All)
                    458:  */
                    459: void scsi_compare( tgt, params, params_len, ior)
                    460:        register target_info_t  *tgt;
                    461:        char                    *params;
                    462:        io_req_t                ior;
                    463: {
                    464:        scsi_cmd_compare_t      *cmd;
                    465: 
                    466:        cmd = (scsi_cmd_compare_t*) (tgt->cmd_ptr);
                    467:        cmd->scsi_cmd_code = SCSI_CMD_COMPARE;
                    468:        cmd->scsi_cmd_lun_and_relbit = 0;
                    469:        cmd->scsi_cmd_lba1 = 0;
                    470:        cmd->scsi_cmd_1_paraml1 = params_len >> 16 & 0xff;
                    471:        cmd->scsi_cmd_1_paraml2 = params_len >> 8 & 0xff;
                    472:        cmd->scsi_cmd_1_paraml3 = params_len & 0xff;
                    473:        cmd->scsi_cmd_xxx = 0;
                    474:        cmd->scsi_cmd_xfer_len_1 = 0;
                    475:        cmd->scsi_cmd_xfer_len_2 = 0;
                    476:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
                    477:        
                    478:        bcopy(params, cmd + 1, params_len);
                    479: 
                    480:        tgt->cur_cmd = SCSI_CMD_COMPARE;
                    481: 
                    482:        scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
                    483: }
                    484: 
                    485: /*
                    486:  * COPY AND VERIFY (Optional, All)
                    487:  */
                    488: void scsi_copy_and_verify( tgt, params, params_len, bytchk, ior)
                    489:        register target_info_t  *tgt;
                    490:        char                    *params;
                    491:        io_req_t                ior;
                    492: {
                    493:        scsi_cmd_compare_t      *cmd;
                    494: 
                    495:        cmd = (scsi_cmd_compare_t*) (tgt->cmd_ptr);
                    496:        cmd->scsi_cmd_code = SCSI_CMD_COMPARE;
                    497:        cmd->scsi_cmd_lun_and_relbit = bytchk ? SCSI_CMD_CPY_BYTCHK : 0;
                    498:        cmd->scsi_cmd_lba1 = 0;
                    499:        cmd->scsi_cmd_1_paraml1 = params_len >> 16 & 0xff;
                    500:        cmd->scsi_cmd_1_paraml2 = params_len >> 8 & 0xff;
                    501:        cmd->scsi_cmd_1_paraml3 = params_len & 0xff;
                    502:        cmd->scsi_cmd_xxx = 0;
                    503:        cmd->scsi_cmd_xfer_len_1 = 0;
                    504:        cmd->scsi_cmd_xfer_len_2 = 0;
                    505:        cmd->scsi_cmd_ctrl_byte = 0;    /* not linked */
                    506:        
                    507:        bcopy(params, cmd + 1, params_len);
                    508: 
                    509:        tgt->cur_cmd = SCSI_CMD_COMPARE;
                    510: 
                    511:        scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
                    512: }
                    513: 
                    514: #endif
                    515: 
                    516: #ifdef SCSI2
                    517: scsi_change_definition
                    518: scsi_log_select
                    519: scsi_log_sense
                    520: scsi_long_mode_select
                    521: scsi_read_buffer
                    522: scsi_write_buffer
                    523: #endif SCSI2
                    524: 
                    525: /*
                    526:  * Warn user of some device error
                    527:  */
                    528: int    scsi_debug = 0;
                    529: 
                    530: static char *sns_msg[SCSI_SNS_RESERVED+1] = {
                    531:        "No Sense Data",/* shouldn't happen */
                    532:        "Recovered",
                    533:        "Unit not ready",
                    534:        "Medium",
                    535:        "Hardware failure",
                    536:        "Illegal request",
                    537:        "Unit Attention Condition",
                    538:        "Protection",
                    539:        "Blank Check",
                    540:        "Vendor Unique",
                    541:        "Copy Operation Aborted",
                    542:        "Aborted Command",
                    543:        "Equal Comparison",
                    544:        "Volume Overflow",
                    545:        "Miscompare",
                    546:        "Reserved"
                    547: };
                    548: 
                    549: void
                    550: scsi_error( tgt, code, info, addtl)
                    551:        target_info_t   *tgt;
                    552:        unsigned        code;
                    553:        unsigned        info;
                    554:        char            *addtl;
                    555: {
                    556:        char            unit;
                    557:        char            *msg, *cmd;
                    558:        scsi2_status_byte_t     status;
                    559:        if (scsi_debug)
                    560:                code |= SCSI_ERR_GRAVE;
                    561: 
                    562:        if (tgt)
                    563:                unit = tgt->unit_no + '0';
                    564:        else
                    565:                unit = '?';
                    566: 
                    567: 
                    568:        switch (SCSI_ERR_CLASS(code)) {
                    569:        case SCSI_ERR_STATUS:
                    570:                cmd = "Bad status return";
                    571:                status.bits = info;
                    572:                switch (status.st.scsi_status_code) {
                    573:                case SCSI_ST_GOOD:
                    574:                case SCSI_ST_CONDITION_MET:
                    575:                case SCSI_ST_INT_GOOD:
                    576:                case SCSI_ST_INT_MET:
                    577:                        return; /* all is fine */
                    578:                case SCSI_ST_CHECK_CONDITION:
                    579:                        msg = "Check condition"; break;
                    580:                case SCSI_ST_RES_CONFLICT:
                    581:                        msg = "Reservation conflict"; break;
                    582:                case SCSI_ST_BUSY:
                    583:                        msg = "Target busy"; break;
                    584:                case SCSI_ST2_QUEUE_FULL:
                    585:                        msg = "Queue full"; break;
                    586:                case SCSI_ST2_CMD_TERMINATED:
                    587:                        msg = "Command terminated"; break;
                    588:                default:
                    589:                        msg = "Strange"; break;
                    590:                }
                    591:                break;
                    592:        case SCSI_ERR_SENSE:
                    593:                cmd = "Sensed a";
                    594:                msg = sns_msg[info & 0xf];
                    595:                break;
                    596:        case SCSI_ERR_MSEL:
                    597:                cmd = "Mode select broken"; msg = ""; break;
                    598:        default:
                    599:                cmd = "Generic"; msg = "";
                    600:        }
                    601:        if (SCSI_ERR_GRAVITY(code)) {
                    602:                printf("\n%s%c: %s %s %sx%x", "target ", unit, cmd, msg,
                    603:                        "error, code ", info);
                    604:                if (addtl) {
                    605:                        unsigned int    add[3];
                    606:                        bcopy(addtl, (char*)add, 3*sizeof(int));
                    607:                        printf("%s x%x x%x x%x", ", additional info ",
                    608:                                add[0], add[1], add[2]);
                    609:                }
                    610:                printf("\n");
                    611:        }
                    612: }
                    613: 
                    614: void scsi_print_sense_data(sns)
                    615:        scsi_sense_data_t       *sns;
                    616: {
                    617:        printf("Sense data: %s%s, segment %d", 
                    618:                sns_msg[sns->u.xtended.sense_key], " error",
                    619:                sns->u.xtended.segment_number);
                    620:        if (sns->u.xtended.ili) printf(", IncorrectLengthIndicator");
                    621:        if (sns->u.xtended.eom) printf(", EndOfMedium");
                    622:        if (sns->u.xtended.fm) printf(", FileMark");
                    623: 
                    624:        if (sns->addr_valid) {
                    625:                unsigned int info;
                    626:                info =  (sns->u.xtended.info0 << 24) |
                    627:                        (sns->u.xtended.info1 << 16) |
                    628:                        (sns->u.xtended.info2 <<  8) |
                    629:                         sns->u.xtended.info3;
                    630:                printf(", Info x%x", info);
                    631:        }
                    632: 
                    633:        if (sns->u.xtended.add_len > 6)
                    634:                scsi_print_add_sense_keys(sns->u.xtended.add_bytes[4],
                    635:                                          sns->u.xtended.add_bytes[5]);
                    636: }
                    637: 
                    638: /*
                    639:  * Table of the official SCSI-2 error messages
                    640:  * Last update:
                    641:  *     X3T9.2/86-109, Revision 10c, March 9, 1990
                    642:  */
                    643: static struct addtl_sns_keys_msg {
                    644:        unsigned char   byte12;
                    645:        unsigned char   byte13;
                    646:        char            *means;
                    647: } addtl_sns_msgs[] = {
                    648:        { 0x00, 0x00, "No additional sense information" },
                    649:        { 0x00, 0x01, "Filemark detected" },
                    650:        { 0x00, 0x02, "End-of-partition/medium detected" },
                    651:        { 0x00, 0x03, "Setmark detected" },
                    652:        { 0x00, 0x04, "Beginning of partition/medium detected" },
                    653:        { 0x00, 0x05, "End-of-data detected" },
                    654:        { 0x00, 0x06, "I/O process terminated" },
                    655:        { 0x00, 0x11, "Audio play operation in progress" },
                    656:        { 0x00, 0x12, "Audio play operation paused" },
                    657:        { 0x00, 0x13, "Audio play operation successfully completed" },
                    658:        { 0x00, 0x14, "Audio play operation stopped due to error" },
                    659:        { 0x00, 0x15, "No current audio status to return" },
                    660:        { 0x01, 0x00, "No index/sector signal" },
                    661:        { 0x02, 0x00, "No seek complete" },
                    662:        { 0x03, 0x00, "Peripheral device write fault" },
                    663:        { 0x03, 0x01, "No write current" },
                    664:        { 0x03, 0x02, "Excessive write errors" },
                    665:        { 0x04, 0x00, "Logical unit not ready, cause not reportable" },
                    666:        { 0x04, 0x01, "Logical unit is in process of becoming ready" },
                    667:        { 0x04, 0x02, "Logical unit not ready, initializing command required" },
                    668:        { 0x04, 0x03, "Logical unit not ready, manual intervention required" },
                    669:        { 0x04, 0x04, "Logical unit not ready, format in progress" },
                    670:        { 0x05, 0x00, "Logical unit does not respond to selection" },
                    671:        { 0x06, 0x00, "No reference position found" },
                    672:        { 0x07, 0x00, "Multiple peripheral devices selected" },
                    673:        { 0x08, 0x00, "Logical unit communication failure" },
                    674:        { 0x08, 0x01, "Logical unit communication time-out" },
                    675:        { 0x08, 0x02, "Logical unit communication parity error" },
                    676:        { 0x09, 0x00, "Track following error" },
                    677:        { 0x09, 0x01, "Tracking servo failure" },
                    678:        { 0x09, 0x02, "Focus servo failure" },
                    679:        { 0x09, 0x03, "Spindle servo failure" },
                    680:        { 0x0a, 0x00, "Error log overflow" },
                    681:        { 0x0c, 0x00, "Write error" },
                    682:        { 0x0c, 0x01, "Write error recovered with auto-reallocation" },
                    683:        { 0x0c, 0x02, "Write error - auto-reallocation failed" },
                    684:        { 0x10, 0x00, "Id CRC or ECC error" },
                    685:        { 0x10, 0x04, "Recovered data with LEC" },
                    686:        { 0x11, 0x00, "Unrecovered read error" },
                    687:        { 0x11, 0x01, "Read retries exhausted" },
                    688:        { 0x11, 0x02, "Error too long to correct" },
                    689:        { 0x11, 0x03, "Multiple read errors" },
                    690:        { 0x11, 0x04, "Unrecovered read error - auto-reallocate failed" },
                    691:        { 0x11, 0x05, "L-EC uncorrectable error" },
                    692:        { 0x11, 0x06, "CIRC unrecovered error" },
                    693:        { 0x11, 0x07, "Data resynchronization error" },
                    694:        { 0x11, 0x08, "Incomplete block read" },
                    695:        { 0x11, 0x09, "No gap found" },
                    696:        { 0x11, 0x0a, "Miscorrected error" },
                    697:        { 0x11, 0x0b, "Unrecovered read error - recommend reassignment" },
                    698:        { 0x11, 0x0c, "Unrecovered read error - recommend rewrite the data" },
                    699:        { 0x12, 0x00, "Address mark not found for id field" },
                    700:        { 0x13, 0x00, "Address mark not found for data field" },
                    701:        { 0x14, 0x00, "Recorded entity not found" },
                    702:        { 0x14, 0x01, "Record not found" },
                    703:        { 0x14, 0x02, "Filemark or setmark not found" },
                    704:        { 0x14, 0x03, "End-of-data not found" },
                    705:        { 0x14, 0x04, "Block sequence error" },
                    706:        { 0x15, 0x00, "Random positioning error" },
                    707:        { 0x15, 0x01, "Mechanical positioning error" },
                    708:        { 0x15, 0x02, "Positioning error detected by read of medium" },
                    709:        { 0x16, 0x00, "Data synchronization mark error" },
                    710:        { 0x17, 0x00, "Recovered data with no error correction applied" },
                    711:        { 0x17, 0x01, "Recovered data with retries" },
                    712:        { 0x17, 0x02, "Recovered data with positive head offset" },
                    713:        { 0x17, 0x03, "Recovered data with negative head offset" },
                    714:        { 0x17, 0x04, "Recovered data with retries and/or CIRC applied" },
                    715:        { 0x17, 0x05, "Recovered data using previous sector id" },
                    716:        { 0x17, 0x06, "Recovered data without ECC - data auto-reallocated" },
                    717:        { 0x17, 0x07, "Recovered data without ECC - recommend reassignment" },
                    718:        { 0x18, 0x00, "Recovered data with error correction applied" },
                    719:        { 0x18, 0x01, "Recovered data with error correction and retries applied" },
                    720:        { 0x18, 0x02, "Recovered data - data auto-reallocated" },
                    721:        { 0x18, 0x03, "Recovered data with CIRC" },
                    722:        { 0x18, 0x05, "Recovered data - recommended reassignment" },
                    723:        { 0x19, 0x00, "Defect list error" },
                    724:        { 0x19, 0x01, "Defect list not available" },
                    725:        { 0x19, 0x02, "Defect list error in primary list" },
                    726:        { 0x19, 0x03, "Defect list error in grown list" },
                    727:        { 0x1a, 0x00, "Parameter list length error" },
                    728:        { 0x1b, 0x00, "Synchronous data transfer error" },
                    729:        { 0x1c, 0x00, "Defect list not found" },
                    730:        { 0x1c, 0x01, "Primary defect list not found" },
                    731:        { 0x1c, 0x02, "Grown defect list not found" },
                    732:        { 0x1d, 0x00, "Miscompare during verify operation" },
                    733:        { 0x1e, 0x00, "Recovered id with ECC correction" },
                    734:        { 0x20, 0x00, "Invalid command operation code" },
                    735:        { 0x21, 0x00, "Logical block address out of range" },
                    736:        { 0x21, 0x01, "Invalid element address" },
                    737:        { 0x22, 0x00, "Illegal function" },
                    738:        { 0x24, 0x00, "Invalid field in CDB" },
                    739:        { 0x24, 0x02, "Log parameters changed" },
                    740:        { 0x25, 0x00, "Logical unit not supported" },
                    741:        { 0x26, 0x00, "Invalid field in parameter list" },
                    742:        { 0x26, 0x01, "Parameter not supported" },
                    743:        { 0x26, 0x02, "Parameter value invalid" },
                    744:        { 0x26, 0x03, "Threshold parameters not supported" },
                    745:        { 0x27, 0x00, "Write protected" },
                    746:        { 0x28, 0x00, "Not ready to ready transition (medium may have changed)" },
                    747:        { 0x28, 0x01, "Import or export element accessed" },
                    748:        { 0x29, 0x00, "Power on, reset, or bus device reset occurred" },
                    749:        { 0x2a, 0x00, "Parameters changed" },
                    750:        { 0x2a, 0x01, "Mode parameters changed" },
                    751:        { 0x2b, 0x00, "Copy cannot execute since host cannot disconnect" },
                    752:        { 0x2c, 0x00, "Command sequence error" },
                    753:        { 0x2c, 0x01, "Too many windows specified" },
                    754:        { 0x2c, 0x02, "Invalid combination of windows specified" },
                    755:        { 0x2d, 0x00, "Overwrite error on update in place" },
                    756:        { 0x2f, 0x00, "Commands cleared by another initiator" },
                    757:        { 0x30, 0x00, "Incompatible medium installed" },
                    758:        { 0x30, 0x01, "Cannot read medium - unknown format" },
                    759:        { 0x30, 0x02, "Cannot read medium - incompatible format" },
                    760:        { 0x30, 0x03, "Cleaning cartridge installed" },
                    761:        { 0x31, 0x00, "Medium format corrupted" },
                    762:        { 0x31, 0x01, "Format command failed" },
                    763:        { 0x32, 0x00, "No defect spare location available" },
                    764:        { 0x32, 0x01, "Defect list update failure" },
                    765:        { 0x33, 0x00, "Tape length error" },
                    766:        { 0x36, 0x00, "Ribbon, ink, or toner failure" },
                    767:        { 0x37, 0x00, "Rounded parameter" },
                    768:        { 0x39, 0x00, "Saving parameters not supported" },
                    769:        { 0x3a, 0x00, "Medium not present" },
                    770:        { 0x3b, 0x00, "Sequential positioning error" },
                    771:        { 0x3b, 0x01, "Tape position error at beginning of medium" },
                    772:        { 0x3b, 0x02, "Tape position error at end of medium" },
                    773:        { 0x3b, 0x03, "Tape or electronic vertical forms unit not ready" },
                    774:        { 0x3b, 0x04, "Slew failure" },
                    775:        { 0x3b, 0x05, "Paper jam" },
                    776:        { 0x3b, 0x06, "Failed to sense top-of-form" },
                    777:        { 0x3b, 0x07, "Failed to sense bottom-of-form" },
                    778:        { 0x3b, 0x08, "Reposition error" },
                    779:        { 0x3b, 0x09, "Read past end of medium" },
                    780:        { 0x3b, 0x0a, "Read past beginning of medium" },
                    781:        { 0x3b, 0x0b, "Position past end of medium" },
                    782:        { 0x3b, 0x0c, "Position past beginning of medium" },
                    783:        { 0x3b, 0x0d, "Medium destination element full" },
                    784:        { 0x3b, 0x0e, "Medium source element empty" },
                    785:        { 0x3d, 0x00, "Invalid bits in identify message" },
                    786:        { 0x3e, 0x00, "Logical unit has not self-configured yet" },
                    787:        { 0x3f, 0x00, "Target operating conditions have changed" },
                    788:        { 0x3f, 0x01, "Microcode has been changed" },
                    789:        { 0x3f, 0x02, "Changed operating definition" },
                    790:        { 0x3f, 0x03, "Inquiry data has changed" },
                    791:        { 0x40, 0x00, "RAM failure" },
                    792:        { 0x40, 0xff, "Diagnostic failure on component <NN>" },
                    793:        { 0x41, 0x00, "Data path failure" },
                    794:        { 0x42, 0x00, "Power on or self-test failure" },
                    795:        { 0x43, 0x00, "Message error" },
                    796:        { 0x44, 0x00, "Internal target failure" },
                    797:        { 0x45, 0x00, "Select or reselect failure" },
                    798:        { 0x46, 0x00, "Unsuccessful soft reset" },
                    799:        { 0x47, 0x00, "SCSI parity error" },
                    800:        { 0x48, 0x00, "Initiator detected message received" },
                    801:        { 0x49, 0x00, "Invalid message error" },
                    802:        { 0x4a, 0x00, "Command phase error" },
                    803:        { 0x4b, 0x00, "Data phase error" },
                    804:        { 0x4c, 0x00, "Logical unit failed self-configuration" },
                    805:        { 0x4e, 0x00, "Overlapped commands attempted" },
                    806:        { 0x50, 0x00, "Write append error" },
                    807:        { 0x50, 0x01, "Write append position error" },
                    808:        { 0x50, 0x02, "Position error related to timing" },
                    809:        { 0x51, 0x00, "Erase failure" },
                    810:        { 0x52, 0x00, "Cartridge fault" },
                    811:        { 0x53, 0x00, "Media load or eject failed" },
                    812:        { 0x53, 0x01, "Unload tape failure" },
                    813:        { 0x53, 0x02, "Medium removal prevented" },
                    814:        { 0x54, 0x00, "SCSI to host system interface failure" },
                    815:        { 0x55, 0x00, "System resource failure" },
                    816:        { 0x57, 0x00, "Unable to recover table-of-contents" },
                    817:        { 0x58, 0x00, "Generation does not exist" },
                    818:        { 0x59, 0x00, "Updated block read" },
                    819:        { 0x5a, 0x00, "Operator request or state change input (unspecified)" },
                    820:        { 0x5a, 0x01, "Operator medium removal request" },
                    821:        { 0x5a, 0x02, "Operator selected write protect" },
                    822:        { 0x5a, 0x03, "Operator selected write permit" },
                    823:        { 0x5b, 0x00, "Log exception" },
                    824:        { 0x5b, 0x01, "Threshold condition met" },
                    825:        { 0x5b, 0x02, "Log counter at maximum" },
                    826:        { 0x5b, 0x03, "Log list codes exhausted" },
                    827:        { 0x5c, 0x00, "RPL status change" },
                    828:        { 0x5c, 0x01, "Spindles synchronized" },
                    829:        { 0x5c, 0x02, "Spindles not synchronized" },
                    830:        { 0x60, 0x00, "Lamp failure" },
                    831:        { 0x61, 0x00, "Video acquisition error" },
                    832:        { 0x61, 0x01, "Unable to acquire video" },
                    833:        { 0x61, 0x02, "Out of focus" },
                    834:        { 0x62, 0x00, "Scan head positioning error" },
                    835:        { 0x63, 0x00, "End of user area encountered on this track" },
                    836:        { 0x64, 0x00, "Illegal mode for this track" },
                    837:        { 0, 0, 0}
                    838: };
                    839: 
                    840: void scsi_print_add_sense_keys(key, qualif)
                    841:        register unsigned key, qualif;
                    842: {
                    843:        register struct addtl_sns_keys_msg      *msg;
                    844: 
                    845:        for (msg = addtl_sns_msgs; msg->means; msg++) {
                    846:                if (msg->byte12 != key) continue;
                    847:                if ((msg->byte12 == 0x40) && qualif) {
                    848:                        printf(", %s, NN=x%x", msg->means, qualif);
                    849:                        return;
                    850:                }
                    851:                if (msg->byte13 == qualif) {
                    852:                        printf(" %s", msg->means);
                    853:                        return;
                    854:                }
                    855:        };
                    856:        printf(", Unknown additional sense keys: 0x%x 0x%x\n", key, qualif);
                    857: }
                    858: #endif  /* NSCSI > 0 */

unix.superglobalmegacorp.com

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