1 /* 2 * Largely written by Julian Elischer (julian@tfs.com) 3 * for TRW Financial Systems. 4 * 5 * TRW Financial Systems, in accordance with their agreement with Carnegie 6 * Mellon University, makes this software available to CMU to distribute 7 * or use in any manner that they see fit as long as this message is kept with 8 * the software. For this reason TFS also grants any other persons or 9 * organisations permission to use or modify this software. 10 * 11 * TFS supplies this software to be publicly redistributed 12 * on the understanding that TFS is not responsible for the correct 13 * functioning of this software in any circumstances. 14 * 15 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 16 * 17 * $Id: scsi_all.h,v 1.13 1995/05/30 08:13:25 rgrimes Exp $ 18 */ 19 20 /* 21 * SCSI general interface description 22 */ 23 24 #ifndef _SCSI_SCSI_ALL_H 25 #define _SCSI_SCSI_ALL_H 1 26 27 #include <sys/cdefs.h> 28 29 /* 30 * SCSI command format 31 */ 32 33 /* 34 * Define dome bits that are in ALL (or a lot of) scsi commands 35 */ 36 #define SCSI_CTL_LINK 0x01 37 #define SCSI_CTL_FLAG 0x02 38 #define SCSI_CTL_VENDOR 0xC0 39 #define SCSI_CMD_LUN 0xA0 /* these two should not be needed */ 40 #define SCSI_CMD_LUN_SHIFT 5 /* LUN in the cmd is no longer SCSI */ 41 42 #define SCSI_MAX_CDBLEN 16 /* 43 * 16 byte commands are in the 44 * SCSI-3 spec 45 */ 46 #if defined(CAM_MAX_CDBLEN) && (CAM_MAX_CDBLEN < SCSI_MAX_CDBLEN) 47 #error "CAM_MAX_CDBLEN cannot be less than SCSI_MAX_CDBLEN" 48 #endif 49 50 /* 51 * This type defines actions to be taken when a particular sense code is 52 * received. Right now, these flags are only defined to take up 16 bits, 53 * but can be expanded in the future if necessary. 54 */ 55 typedef enum { 56 SS_NOP = 0x000000, /* Do nothing */ 57 SS_RETRY = 0x010000, /* Retry the command */ 58 SS_FAIL = 0x020000, /* Bail out */ 59 SS_START = 0x030000, /* Send a Start Unit command to the device, 60 * then retry the original command. 61 */ 62 SS_TUR = 0x040000, /* Send a Test Unit Ready command to the 63 * device, then retry the original command. 64 */ 65 SS_MANUAL = 0x050000, /* 66 * This error must be handled manually, 67 * i.e. the code must look at the asc and 68 * ascq values and determine the proper 69 * course of action. 70 */ 71 SS_TURSTART = 0x060000, /* 72 * Send a Test Unit Ready command to the 73 * device, and if that fails, send a start 74 * unit. 75 */ 76 SS_MASK = 0xff0000 77 } scsi_sense_action; 78 79 typedef enum { 80 SSQ_NONE = 0x0000, 81 SSQ_DECREMENT_COUNT = 0x0100, /* Decrement the retry count */ 82 SSQ_MANY = 0x0200, /* send lots of recovery commands */ 83 SSQ_RANGE = 0x0400, /* 84 * Yes, this is a hack. Basically, 85 * if this flag is set then it 86 * represents an ascq range. The 87 * "correct" way to implement the 88 * ranges might be to add a special 89 * field to the sense code table, 90 * but that would take up a lot of 91 * additional space. This solution 92 * isn't as elegant, but is more 93 * space efficient. 94 */ 95 SSQ_PRINT_SENSE = 0x0800, 96 SSQ_MASK = 0xff00 97 } scsi_sense_action_qualifier; 98 99 /* Mask for error status values */ 100 #define SS_ERRMASK 0xff 101 102 /* The default error action */ 103 #define SS_DEF SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE|EIO 104 105 /* Default error action, without an error return value */ 106 #define SS_NEDEF SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE 107 108 /* Default error action, without sense printing or an error return value */ 109 #define SS_NEPDEF SS_RETRY|SSQ_DECREMENT_COUNT 110 111 struct scsi_generic 112 { 113 u_int8_t opcode; 114 u_int8_t bytes[11]; 115 }; 116 117 struct scsi_request_sense 118 { 119 u_int8_t opcode; 120 u_int8_t byte2; 121 u_int8_t unused[2]; 122 u_int8_t length; 123 u_int8_t control; 124 }; 125 126 struct scsi_test_unit_ready 127 { 128 u_int8_t opcode; 129 u_int8_t byte2; 130 u_int8_t unused[3]; 131 u_int8_t control; 132 }; 133 134 struct scsi_send_diag 135 { 136 u_int8_t opcode; 137 u_int8_t byte2; 138 #define SSD_UOL 0x01 139 #define SSD_DOL 0x02 140 #define SSD_SELFTEST 0x04 141 #define SSD_PF 0x10 142 u_int8_t unused[1]; 143 u_int8_t paramlen[2]; 144 u_int8_t control; 145 }; 146 147 struct scsi_sense 148 { 149 u_int8_t opcode; 150 u_int8_t byte2; 151 u_int8_t unused[2]; 152 u_int8_t length; 153 u_int8_t control; 154 }; 155 156 struct scsi_inquiry 157 { 158 u_int8_t opcode; 159 u_int8_t byte2; 160 #define SI_EVPD 0x01 161 u_int8_t page_code; 162 u_int8_t reserved; 163 u_int8_t length; 164 u_int8_t control; 165 }; 166 167 struct scsi_mode_sense_6 168 { 169 u_int8_t opcode; 170 u_int8_t byte2; 171 #define SMS_DBD 0x08 172 u_int8_t page; 173 #define SMS_PAGE_CODE 0x3F 174 #define SMS_VENDOR_SPECIFIC_PAGE 0x00 175 #define SMS_DISCONNECT_RECONNECT_PAGE 0x02 176 #define SMS_PERIPHERAL_DEVICE_PAGE 0x09 177 #define SMS_CONTROL_MODE_PAGE 0x0A 178 #define SMS_ALL_PAGES_PAGE 0x3F 179 #define SMS_PAGE_CTRL_MASK 0xC0 180 #define SMS_PAGE_CTRL_CURRENT 0x00 181 #define SMS_PAGE_CTRL_CHANGEABLE 0x40 182 #define SMS_PAGE_CTRL_DEFAULT 0x80 183 #define SMS_PAGE_CTRL_SAVED 0xC0 184 u_int8_t unused; 185 u_int8_t length; 186 u_int8_t control; 187 }; 188 189 struct scsi_mode_sense_10 190 { 191 u_int8_t opcode; 192 u_int8_t byte2; /* same bits as small version */ 193 u_int8_t page; /* same bits as small version */ 194 u_int8_t unused[4]; 195 u_int8_t length[2]; 196 u_int8_t control; 197 }; 198 199 struct scsi_mode_select_6 200 { 201 u_int8_t opcode; 202 u_int8_t byte2; 203 #define SMS_SP 0x01 204 #define SMS_PF 0x10 205 u_int8_t unused[2]; 206 u_int8_t length; 207 u_int8_t control; 208 }; 209 210 struct scsi_mode_select_10 211 { 212 u_int8_t opcode; 213 u_int8_t byte2; /* same bits as small version */ 214 u_int8_t unused[5]; 215 u_int8_t length[2]; 216 u_int8_t control; 217 }; 218 219 /* 220 * When sending a mode select to a tape drive, the medium type must be 0. 221 */ 222 struct scsi_mode_hdr_6 223 { 224 u_int8_t datalen; 225 u_int8_t medium_type; 226 u_int8_t dev_specific; 227 u_int8_t block_descr_len; 228 }; 229 230 struct scsi_mode_hdr_10 231 { 232 u_int8_t datalen[2]; 233 u_int8_t medium_type; 234 u_int8_t dev_specific; 235 u_int8_t reserved[2]; 236 u_int8_t block_descr_len[2]; 237 }; 238 239 struct scsi_mode_block_descr 240 { 241 u_int8_t density_code; 242 u_int8_t num_blocks[3]; 243 u_int8_t reserved; 244 u_int8_t block_len[3]; 245 }; 246 247 struct scsi_control_page { 248 u_int8_t page_code; 249 u_int8_t page_length; 250 u_int8_t rlec; 251 #define SCB_RLEC 0x01 /*Report Log Exception Cond*/ 252 u_int8_t queue_flags; 253 #define SCP_QUEUE_ALG_MASK 0xF0 254 #define SCP_QUEUE_ALG_RESTRICTED 0x00 255 #define SCP_QUEUE_ALG_UNRESTRICTED 0x10 256 #define SCP_QUEUE_ERR 0x02 /*Queued I/O aborted for CACs*/ 257 #define SCP_QUEUE_DQUE 0x01 /*Queued I/O disabled*/ 258 u_int8_t eca_and_aen; 259 #define SCP_EECA 0x80 /*Enable Extended CA*/ 260 #define SCP_RAENP 0x04 /*Ready AEN Permission*/ 261 #define SCP_UAAENP 0x02 /*UA AEN Permission*/ 262 #define SCP_EAENP 0x01 /*Error AEN Permission*/ 263 u_int8_t reserved; 264 u_int8_t aen_holdoff_period[2]; 265 }; 266 267 struct scsi_reserve 268 { 269 u_int8_t opcode; 270 u_int8_t byte2; 271 u_int8_t unused[2]; 272 u_int8_t length; 273 u_int8_t control; 274 }; 275 276 struct scsi_release 277 { 278 u_int8_t opcode; 279 u_int8_t byte2; 280 u_int8_t unused[2]; 281 u_int8_t length; 282 u_int8_t control; 283 }; 284 285 struct scsi_prevent 286 { 287 u_int8_t opcode; 288 u_int8_t byte2; 289 u_int8_t unused[2]; 290 u_int8_t how; 291 u_int8_t control; 292 }; 293 #define PR_PREVENT 0x01 294 #define PR_ALLOW 0x00 295 296 struct scsi_sync_cache 297 { 298 u_int8_t opcode; 299 u_int8_t byte2; 300 u_int8_t begin_lba[4]; 301 u_int8_t reserved; 302 u_int8_t lb_count[2]; 303 u_int8_t control; 304 }; 305 306 307 struct scsi_changedef 308 { 309 u_int8_t opcode; 310 u_int8_t byte2; 311 u_int8_t unused1; 312 u_int8_t how; 313 u_int8_t unused[4]; 314 u_int8_t datalen; 315 u_int8_t control; 316 }; 317 318 struct scsi_read_buffer 319 { 320 u_int8_t opcode; 321 u_int8_t byte2; 322 #define RWB_MODE 0x07 323 #define RWB_MODE_HDR_DATA 0x00 324 #define RWB_MODE_DATA 0x02 325 #define RWB_MODE_DOWNLOAD 0x04 326 #define RWB_MODE_DOWNLOAD_SAVE 0x05 327 u_int8_t buffer_id; 328 u_int8_t offset[3]; 329 u_int8_t length[3]; 330 u_int8_t control; 331 }; 332 333 struct scsi_write_buffer 334 { 335 u_int8_t opcode; 336 u_int8_t byte2; 337 u_int8_t buffer_id; 338 u_int8_t offset[3]; 339 u_int8_t length[3]; 340 u_int8_t control; 341 }; 342 343 #define SC_SCSI_1 0x01 344 #define SC_SCSI_2 0x03 345 346 /* 347 * Opcodes 348 */ 349 350 #define TEST_UNIT_READY 0x00 351 #define REQUEST_SENSE 0x03 352 #define INQUIRY 0x12 353 #define MODE_SELECT_6 0x15 354 #define MODE_SENSE_6 0x1a 355 #define START_STOP 0x1b 356 #define RESERVE 0x16 357 #define RELEASE 0x17 358 #define PREVENT_ALLOW 0x1e 359 #define READ_CAPACITY 0x25 360 #define POSITION_TO_ELEMENT 0x2b 361 #define SYNCHRONIZE_CACHE 0x35 362 #define WRITE_BUFFER 0x3b 363 #define READ_BUFFER 0x3c 364 #define CHANGE_DEFINITION 0x40 365 #define MODE_SELECT_10 0x55 366 #define MODE_SENSE_10 0x5A 367 #define MOVE_MEDIUM 0xa5 368 #define READ_ELEMENT_STATUS 0xb8 369 370 371 /* 372 * Device Types 373 */ 374 #define T_DIRECT 0x00 375 #define T_SEQUENTIAL 0x01 376 #define T_PRINTER 0x02 377 #define T_PROCESSOR 0x03 378 #define T_WORM 0x04 379 #define T_CDROM 0x05 380 #define T_SCANNER 0x06 381 #define T_OPTICAL 0x07 382 #define T_CHANGER 0x08 383 #define T_COMM 0x09 384 #define T_ASC0 0x0a 385 #define T_ASC1 0x0b 386 #define T_STORARRAY 0x0c 387 #define T_ENCLOSURE 0x0d 388 #define T_NODEVICE 0x1F 389 #define T_ANY 0xFF /* Used in Quirk table matches */ 390 391 #define T_REMOV 1 392 #define T_FIXED 0 393 394 struct scsi_inquiry_data 395 { 396 u_int8_t device; 397 #define SID_TYPE(inq_data) ((inq_data)->device & 0x1f) 398 #define SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5) 399 #define SID_QUAL_LU_CONNECTED 0x00 /* The specified peripheral device 400 * type is currently connected to 401 * logical unit. If the target cannot 402 * determine whether or not a physical 403 * device is currently connected, it 404 * shall also use this peripheral 405 * qualifier when returning the INQUIRY 406 * data. This peripheral qualifier 407 * does not mean that the device is 408 * ready for access by the initiator. 409 */ 410 #define SID_QUAL_LU_OFFLINE 0x01 /* The target is capable of supporting 411 * the specified peripheral device type 412 * on this logical unit; however, the 413 * physical device is not currently 414 * connected to this logical unit. 415 */ 416 #define SID_QUAL_RSVD 0x02 417 #define SID_QUAL_BAD_LU 0x03 /* The target is not capable of 418 * supporting a physical device on 419 * this logical unit. For this 420 * peripheral qualifier the peripheral 421 * device type shall be set to 1Fh to 422 * provide compatibility with previous 423 * versions of SCSI. All other 424 * peripheral device type values are 425 * reserved for this peripheral 426 * qualifier. 427 */ 428 #define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0) 429 u_int8_t dev_qual2; 430 #define SID_QUAL2 0x7F 431 #define SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0) 432 u_int8_t version; 433 #define SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07) 434 #define SID_ECMA 0x38 435 #define SID_ISO 0xC0 436 u_int8_t response_format; 437 #define SID_AENC 0x80 438 #define SID_TrmIOP 0x40 439 u_int8_t additional_length; 440 u_int8_t reserved[2]; 441 u_int8_t flags; 442 #define SID_SftRe 0x01 443 #define SID_CmdQue 0x02 444 #define SID_Linked 0x08 445 #define SID_Sync 0x10 446 #define SID_WBus16 0x20 447 #define SID_WBus32 0x40 448 #define SID_RelAdr 0x80 449 #define SID_VENDOR_SIZE 8 450 char vendor[SID_VENDOR_SIZE]; 451 #define SID_PRODUCT_SIZE 16 452 char product[SID_PRODUCT_SIZE]; 453 #define SID_REVISION_SIZE 4 454 char revision[SID_REVISION_SIZE]; 455 }; 456 457 struct scsi_vpd_unit_serial_number 458 { 459 u_int8_t device; 460 u_int8_t page_code; 461 #define SVPD_UNIT_SERIAL_NUMBER 0x80 462 u_int8_t reserved; 463 u_int8_t length; /* serial number length */ 464 #define SVPD_SERIAL_NUM_SIZE 251 465 char serial_num[SVPD_SERIAL_NUM_SIZE]; 466 }; 467 468 struct scsi_read_capacity 469 { 470 u_int8_t opcode; 471 u_int8_t byte2; 472 u_int8_t addr[4]; 473 u_int8_t unused[3]; 474 u_int8_t control; 475 }; 476 477 struct scsi_read_capacity_data 478 { 479 u_int8_t addr[4]; 480 u_int8_t length[4]; 481 }; 482 483 struct scsi_sense_data 484 { 485 u_int8_t error_code; 486 #define SSD_ERRCODE 0x7F 487 #define SSD_CURRENT_ERROR 0x70 488 #define SSD_DEFERRED_ERROR 0x71 489 #define SSD_ERRCODE_VALID 0x80 490 u_int8_t segment; 491 u_int8_t flags; 492 #define SSD_KEY 0x0F 493 #define SSD_KEY_NO_SENSE 0x00 494 #define SSD_KEY_RECOVERED_ERROR 0x01 495 #define SSD_KEY_NOT_READY 0x02 496 #define SSD_KEY_MEDIUM_ERROR 0x03 497 #define SSD_KEY_HARDWARE_ERROR 0x04 498 #define SSD_KEY_ILLEGAL_REQUEST 0x05 499 #define SSD_KEY_UNIT_ATTENTION 0x06 500 #define SSD_KEY_DATA_PROTECT 0x07 501 #define SSD_KEY_BLANK_CHECK 0x08 502 #define SSD_KEY_Vendor_Specific 0x09 503 #define SSD_KEY_COPY_ABORTED 0x0a 504 #define SSD_KEY_ABORTED_COMMAND 0x0b 505 #define SSD_KEY_EQUAL 0x0c 506 #define SSD_KEY_VOLUME_OVERFLOW 0x0d 507 #define SSD_KEY_MISCOMPARE 0x0e 508 #define SSD_KEY_RESERVED 0x0f 509 #define SSD_ILI 0x20 510 #define SSD_EOM 0x40 511 #define SSD_FILEMARK 0x80 512 u_int8_t info[4]; 513 u_int8_t extra_len; 514 u_int8_t cmd_spec_info[4]; 515 u_int8_t add_sense_code; 516 u_int8_t add_sense_code_qual; 517 u_int8_t fru; 518 u_int8_t sense_key_spec[3]; 519 #define SSD_SCS_VALID 0x80 520 #define SSD_FIELDPTR_CMD 0x40 521 #define SSD_BITPTR_VALID 0x08 522 #define SSD_BITPTR_VALUE 0x07 523 #define SSD_MIN_SIZE 18 524 u_int8_t extra_bytes[14]; 525 #define SSD_FULL_SIZE sizeof(struct scsi_sense_data) 526 }; 527 528 struct scsi_mode_header_6 529 { 530 u_int8_t data_length; /* Sense data length */ 531 u_int8_t medium_type; 532 u_int8_t dev_spec; 533 u_int8_t blk_desc_len; 534 }; 535 536 struct scsi_mode_header_10 537 { 538 u_int8_t data_length[2];/* Sense data length */ 539 u_int8_t medium_type; 540 u_int8_t dev_spec; 541 u_int8_t unused[2]; 542 u_int8_t blk_desc_len[2]; 543 }; 544 545 struct scsi_mode_blk_desc 546 { 547 u_int8_t density; 548 u_int8_t nblocks[3]; 549 u_int8_t reserved; 550 u_int8_t blklen[3]; 551 }; 552 553 /* 554 * Status Byte 555 */ 556 #define SCSI_STATUS_OK 0x00 557 #define SCSI_STATUS_CHECK_COND 0x02 558 #define SCSI_STATUS_COND_MET 0x04 559 #define SCSI_STATUS_BUSY 0x08 560 #define SCSI_STATUS_INTERMED 0x10 561 #define SCSI_STATUS_INTERMED_COND_MET 0x14 562 #define SCSI_STATUS_RESERV_CONFLICT 0x18 563 #define SCSI_STATUS_CMD_TERMINATED 0x22 564 #define SCSI_STATUS_QUEUE_FULL 0x28 565 566 struct scsi_inquiry_pattern { 567 u_int8_t type; 568 u_int8_t media_type; 569 #define SIP_MEDIA_REMOVABLE 0x01 570 #define SIP_MEDIA_FIXED 0x02 571 const char *vendor; 572 const char *product; 573 const char *revision; 574 }; 575 576 struct scsi_static_inquiry_pattern { 577 u_int8_t type; 578 u_int8_t media_type; 579 char vendor[SID_VENDOR_SIZE+1]; 580 char product[SID_PRODUCT_SIZE+1]; 581 char revision[SID_REVISION_SIZE+1]; 582 }; 583 584 struct scsi_sense_quirk_entry { 585 struct scsi_inquiry_pattern inq_pat; 586 int num_ascs; 587 struct asc_table_entry *asc_info; 588 }; 589 590 struct asc_table_entry { 591 u_int8_t asc; 592 u_int8_t ascq; 593 u_int32_t action; 594 #if !defined(SCSI_NO_SENSE_STRINGS) 595 const char *desc; 596 #endif 597 }; 598 599 struct op_table_entry { 600 u_int8_t opcode; 601 u_int16_t opmask; 602 const char *desc; 603 }; 604 605 struct scsi_op_quirk_entry { 606 struct scsi_inquiry_pattern inq_pat; 607 int num_ops; 608 struct op_table_entry *op_table; 609 }; 610 611 612 struct ccb_scsiio; 613 struct cam_periph; 614 union ccb; 615 #ifndef KERNEL 616 struct cam_device; 617 #endif 618 619 extern const char *scsi_sense_key_text[]; 620 621 __BEGIN_DECLS 622 const char * scsi_sense_desc(int asc, int ascq, 623 struct scsi_inquiry_data *inq_data); 624 scsi_sense_action scsi_error_action(int asc, int ascq, 625 struct scsi_inquiry_data *inq_data); 626 #ifdef KERNEL 627 void scsi_sense_print(struct ccb_scsiio *csio); 628 int scsi_interpret_sense(union ccb *ccb, 629 u_int32_t sense_flags, 630 u_int32_t *relsim_flags, 631 u_int32_t *reduction, 632 u_int32_t *timeout, 633 scsi_sense_action error_action); 634 #else 635 char * scsi_sense_string(struct cam_device *device, 636 struct ccb_scsiio *csio, 637 char *str, int str_len); 638 void scsi_sense_print(struct cam_device *device, 639 struct ccb_scsiio *csio, FILE *ofile); 640 int scsi_interpret_sense(struct cam_device *device, 641 union ccb *ccb, 642 u_int32_t sense_flags, 643 u_int32_t *relsim_flags, 644 u_int32_t *reduction, 645 u_int32_t *timeout, 646 scsi_sense_action error_action); 647 #endif /* KERNEL */ 648 649 #define SF_RETRY_UA 0x01 650 #define SF_NO_PRINT 0x02 651 #define SF_QUIET_IR 0x04 /* Be quiet about Illegal Request reponses */ 652 653 654 const char * scsi_op_desc(u_int16_t opcode, 655 struct scsi_inquiry_data *inq_data); 656 char * scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string); 657 658 void scsi_print_inquiry(struct scsi_inquiry_data *inq_data); 659 660 u_int scsi_calc_syncsrate(u_int period_factor); 661 u_int scsi_calc_syncparam(u_int period); 662 663 void scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries, 664 void (*cbfcnp)(struct cam_periph *, 665 union ccb *), 666 u_int8_t tag_action, 667 u_int8_t sense_len, u_int32_t timeout); 668 669 void scsi_request_sense(struct ccb_scsiio *csio, u_int32_t retries, 670 void (*cbfcnp)(struct cam_periph *, 671 union ccb *), 672 void *data_ptr, u_int8_t dxfer_len, 673 u_int8_t tag_action, u_int8_t sense_len, 674 u_int32_t timeout); 675 676 void scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries, 677 void (*cbfcnp)(struct cam_periph *, union ccb *), 678 u_int8_t tag_action, u_int8_t *inq_buf, 679 u_int32_t inq_len, int evpd, u_int8_t page_code, 680 u_int8_t sense_len, u_int32_t timeout); 681 682 void scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries, 683 void (*cbfcnp)(struct cam_periph *, 684 union ccb *), 685 u_int8_t tag_action, int dbd, 686 u_int8_t page_code, u_int8_t page, 687 u_int8_t *param_buf, u_int32_t param_len, 688 u_int8_t sense_len, u_int32_t timeout); 689 690 void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries, 691 void (*cbfcnp)(struct cam_periph *, 692 union ccb *), 693 u_int8_t tag_action, int scsi_page_fmt, 694 int save_pages, u_int8_t *param_buf, 695 u_int32_t param_len, u_int8_t sense_len, 696 u_int32_t timeout); 697 698 void scsi_read_capacity(struct ccb_scsiio *csio, u_int32_t retries, 699 void (*cbfcnp)(struct cam_periph *, 700 union ccb *), u_int8_t tag_action, 701 struct scsi_read_capacity_data *rcap_buf, 702 u_int8_t sense_len, u_int32_t timeout); 703 704 void scsi_prevent(struct ccb_scsiio *csio, u_int32_t retries, 705 void (*cbfcnp)(struct cam_periph *, union ccb *), 706 u_int8_t tag_action, u_int8_t action, 707 u_int8_t sense_len, u_int32_t timeout); 708 709 void scsi_synchronize_cache(struct ccb_scsiio *csio, 710 u_int32_t retries, 711 void (*cbfcnp)(struct cam_periph *, 712 union ccb *), u_int8_t tag_action, 713 u_int32_t begin_lba, u_int16_t lb_count, 714 u_int8_t sense_len, u_int32_t timeout); 715 716 int scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry); 717 int scsi_static_inquiry_match(caddr_t inqbuffer, 718 caddr_t table_entry); 719 720 static __inline void scsi_extract_sense(struct scsi_sense_data *sense, 721 int *error_code, int *sense_key, 722 int *asc, int *ascq); 723 static __inline void scsi_ulto2b(u_int32_t val, u_int8_t *bytes); 724 static __inline void scsi_ulto3b(u_int32_t val, u_int8_t *bytes); 725 static __inline void scsi_ulto4b(u_int32_t val, u_int8_t *bytes); 726 static __inline u_int32_t scsi_2btoul(u_int8_t *bytes); 727 static __inline u_int32_t scsi_3btoul(u_int8_t *bytes); 728 static __inline int32_t scsi_3btol(u_int8_t *bytes); 729 static __inline u_int32_t scsi_4btoul(u_int8_t *bytes); 730 731 732 static __inline void scsi_extract_sense(struct scsi_sense_data *sense, 733 int *error_code, int *sense_key, 734 int *asc, int *ascq) 735 { 736 *error_code = sense->error_code & SSD_ERRCODE; 737 *sense_key = sense->flags & SSD_KEY; 738 *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0; 739 *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0; 740 } 741 742 static __inline void 743 scsi_ulto2b(u_int32_t val, u_int8_t *bytes) 744 { 745 746 bytes[0] = (val >> 8) & 0xff; 747 bytes[1] = val & 0xff; 748 } 749 750 static __inline void 751 scsi_ulto3b(u_int32_t val, u_int8_t *bytes) 752 { 753 754 bytes[0] = (val >> 16) & 0xff; 755 bytes[1] = (val >> 8) & 0xff; 756 bytes[2] = val & 0xff; 757 } 758 759 static __inline void 760 scsi_ulto4b(u_int32_t val, u_int8_t *bytes) 761 { 762 763 bytes[0] = (val >> 24) & 0xff; 764 bytes[1] = (val >> 16) & 0xff; 765 bytes[2] = (val >> 8) & 0xff; 766 bytes[3] = val & 0xff; 767 } 768 769 static __inline u_int32_t 770 scsi_2btoul(u_int8_t *bytes) 771 { 772 u_int32_t rv; 773 774 rv = (bytes[0] << 8) | 775 bytes[1]; 776 return (rv); 777 } 778 779 static __inline u_int32_t 780 scsi_3btoul(u_int8_t *bytes) 781 { 782 u_int32_t rv; 783 784 rv = (bytes[0] << 16) | 785 (bytes[1] << 8) | 786 bytes[2]; 787 return (rv); 788 } 789 790 static __inline int32_t 791 scsi_3btol(u_int8_t *bytes) 792 { 793 u_int32_t rc = scsi_3btoul(bytes); 794 795 if (rc & 0x00800000) 796 rc |= 0xff000000; 797 798 return (int32_t) rc; 799 } 800 801 static __inline u_int32_t 802 scsi_4btoul(u_int8_t *bytes) 803 { 804 u_int32_t rv; 805 806 rv = (bytes[0] << 24) | 807 (bytes[1] << 16) | 808 (bytes[2] << 8) | 809 bytes[3]; 810 return (rv); 811 } 812 __END_DECLS 813 814 #endif /*_SCSI_SCSI_ALL_H*/ 815