|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.