Annotation of Gnu-Mach/scsi/scsi_alldevs.c, revision 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.