1 /* 2 * Copyright 2004-2007, Haiku, Inc. All RightsReserved. 3 * Copyright 2002/03, Thomas Kurschel. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 #ifndef _SCSI_CMDS_H 8 #define _SCSI_CMDS_H 9 10 // SCSI commands and their data structures and constants 11 12 13 #include <lendian_bitfield.h> 14 15 16 // always keep in mind that SCSI is big-endian !!! 17 18 #define SCSI_STD_TIMEOUT 10 19 20 // SCSI device status (as the result of a command) 21 #define SCSI_STATUS_GOOD (0 << 1) 22 #define SCSI_STATUS_CHECK_CONDITION (1 << 1) // error occured 23 #define SCSI_STATUS_CONDITION_MET (2 << 1) // "found" for SEARCH DATA and PREFETCH 24 #define SCSI_STATUS_BUSY (4 << 1) // try again later (??? == QUEUE_FULL ???) 25 #define SCSI_STATUS_INTERMEDIATE (8 << 1) // used by linked command only 26 #define SCSI_STATUS_INTERMEDIATE_COND_MET (10 << 1) // ditto 27 #define SCSI_STATUS_RESERVATION_CONFLICT (12 << 1) // only if RESERVE/RELEASE is used 28 #define SCSI_STATUS_COMMAND_TERMINATED (17 << 1) // aborted by TERMINATE I/O PROCESS 29 #define SCSI_STATUS_QUEUE_FULL (20 << 1) // queue full 30 31 #define SCSI_STATUS_MASK 0xfe 32 33 // SCSI sense key 34 #define SCSIS_KEY_NO_SENSE 0 35 #define SCSIS_KEY_RECOVERED_ERROR 1 36 #define SCSIS_KEY_NOT_READY 2 // operator intervention may be required 37 #define SCSIS_KEY_MEDIUM_ERROR 3 // can be set if source could be hardware error 38 #define SCSIS_KEY_HARDWARE_ERROR 4 39 #define SCSIS_KEY_ILLEGAL_REQUEST 5 // invalid command 40 #define SCSIS_KEY_UNIT_ATTENTION 6 // medium changed or target reset 41 #define SCSIS_KEY_DATA_PROTECT 7 // data access forbidden 42 #define SCSIS_KEY_BLANK_CHECK 8 // tried to read blank or to write non-blank medium 43 #define SCSIS_KEY_VENDOR_SPECIFIC 9 44 #define SCSIS_KEY_COPY_ABORTED 10 // error in COPY or COMPARE command 45 #define SCSIS_KEY_ABORTED_COMMAND 11 // aborted by target, retry *may* help 46 #define SCSIS_KEY_EQUAL 12 // during SEARCH: data found 47 #define SCSIS_KEY_VOLUME_OVERFLOW 13 // tried to write buffered data beyond end of medium 48 #define SCSIS_KEY_MISCOMPARE 14 49 #define SCSIS_KEY_RESERVED 15 50 51 // SCSI ASC and ASCQ data - (ASC << 8) | ASCQ 52 // all codes with bit 7 of ASC or ASCQ set are vendor-specific 53 #define SCSIS_ASC_NO_SENSE 0x0000 54 #define SCSIS_ASC_IO_PROC_TERMINATED 0x0006 55 #define SCSIS_ASC_AUDIO_PLAYING 0x0011 56 #define SCSIS_ASC_AUDIO_PAUSED 0x0012 57 #define SCSIS_ASC_AUDIO_COMPLETED 0x0013 58 #define SCSIS_ASC_AUDIO_ERROR 0x0014 // playing has stopped due to error 59 #define SCSIS_ASC_AUDIO_NO_STATUS 0x0015 60 #define SCSIS_ASC_NO_INDEX 0x0100 // no index/sector signal 61 #define SCSIS_ASC_NO_SEEK_CMP 0x0200 // ??? 62 #define SCSIS_ASC_WRITE_FAULT 0x0300 63 #define SCSIS_ASC_LUN_NOT_READY 0x0400 // LUN not ready, cause not reportable 64 #define SCSIS_ASC_LUN_BECOMING_READY 0x0401 // LUN in progress of becoming ready 65 #define SCSIS_ASC_LUN_NEED_INIT 0x0402 // LUN need initializing command 66 #define SCSIS_ASC_LUN_NEED_MANUAL_HELP 0x0403 // LUN needs manual intervention 67 #define SCSIS_ASC_LUN_FORMATTING 0x0404 // LUN format in progress 68 #define SCSIS_ASC_LUN_SEL_FAILED 0x0500 // LUN doesn't respond to selection 69 #define SCSIS_ASC_LUN_COM_FAILURE 0x0800 // LUN communication failure 70 #define SCSIS_ASC_LUN_TIMEOUT 0x0801 // LUN communication time-out 71 #define SCSIS_ASC_LUN_COM_PARITY 0x0802 // LUN communication parity failure 72 #define SCSIS_ASC_LUN_COM_CRC 0x0803 // LUN communication CRC failure (SCSI-3) 73 #define SCSIS_ASC_WRITE_ERR_AUTOREALLOC 0x0c01 // recovered by auto-reallocation 74 #define SCSIS_ASC_WRITE_ERR_AUTOREALLOC_FAILED 0x0c02 75 #define SCSIS_ASC_ECC_ERROR 0x1000 76 #define SCSIS_ASC_UNREC_READ_ERR 0x1100 // unrecovered read error 77 #define SCSIS_ASC_READ_RETRIES_EXH 0x1101 // read retries exhausted 78 #define SCSIS_ASC_UNREC_READ_ERR_AUTOREALLOC_FAILED 0x1104 // above + auto-reallocate failed 79 #define SCSIS_ASC_RECORD_NOT_FOUND 0x1401 80 #define SCSIS_ASC_RANDOM_POS_ERROR 0x1500 // random positioning error 81 #define SCSIS_ASC_POSITIONING_ERR 0x1501 // mechanical positioning error 82 #define SCSIS_ASC_POS_ERR_ON_READ 0x1502 // positioning error detected by reading 83 #define SCSIS_ASC_DATA_RECOV_NO_ERR_CORR 0x1700 // recovered with no error correction applied 84 #define SCSIS_ASC_DATA_RECOV_WITH_RETRIES 0x1701 85 #define SCSIS_ASC_DATA_RECOV_POS_HEAD_OFS 0x1702 // ?recovered with positive head offset 86 #define SCSIS_ASC_DATA_RECOV_NEG_HEAD_OFS 0x1703 // ?recovered with negative head offset 87 #define SCSIS_ASC_DATA_RECOV_WITH_RETRIES_CIRC 0x1704 // recovered with retries/CIRC 88 #define SCSIS_ASC_DATA_RECOV_PREV_SECT_ID 0x1705 // recovered using previous sector ID 89 #define SCSIS_ASC_DATA_RECOV_NO_ECC_AUTOREALLOC 0x1706 90 #define SCSIS_ASC_DATA_RECOV_NO_ECC_REASSIGN 0x1707 // reassign recommended 91 #define SCSIS_ASC_DATA_RECOV_NO_ECC_REWRITE 0x1708 // rewrite recommended 92 #define SCSIS_ASC_DATA_RECOV_WITH_CORR 0x1800 // recovered using error correction 93 #define SCSIS_ASC_DATA_RECOV_WITH_CORR_RETRIES 0x1801 // used error correction and retries 94 #define SCSIS_ASC_DATA_RECOV_AUTOREALLOC 0x1802 95 #define SCSIS_ASC_DATA_RECOV_CIRC 0x1803 // recovered using CIRC 96 #define SCSIS_ASC_DATA_RECOV_LEC 0x1804 // recovered using LEC 97 #define SCSIS_ASC_DATA_RECOV_REASSIGN 0x1805 // reassign recommended 98 #define SCSIS_ASC_DATA_RECOV_REWRITE 0x1806 // rewrite recommended 99 #define SCSIS_ASC_PARAM_LIST_LENGTH_ERR 0x1a00 // parameter list too short 100 #define SCSIS_ASC_ID_RECOV 0x1e00 // recoved ID with ECC 101 #define SCSIS_ASC_INV_OPCODE 0x2000 102 #define SCSIS_ASC_LBA_OOR 0x2100 // LBA out of range 103 #define SCSIS_ASC_ILL_FUNCTION 0x2200 // better use 0x2000/0x2400/0x2600 instead 104 #define SCSIS_ASC_INV_CDB_FIELD 0x2400 105 #define SCSIS_ASC_LUN_NOT_SUPPORTED 0x2500 106 #define SCSIS_ASC_INV_PARAM_LIST_FIELD 0x2600 107 #define SCSIS_ASC_PARAM_NOT_SUPPORTED 0x2601 108 #define SCSIS_ASC_PARAM_VALUE_INV 0x2602 109 #define SCSIS_ASC_WRITE_PROTECTED 0x2700 110 #define SCSIS_ASC_MEDIUM_CHANGED 0x2800 111 #define SCSIS_ASC_WAS_RESET 0x2900 // reset by power-on/bus reset/device reset 112 #define SCSIS_ASC_PARAMS_CHANGED 0x2a00 113 #define SCSIS_ASC_MEDIUM_FORMAT_CORRUPTED 0x3100 114 #define SCSIS_ASC_ROUNDED_PARAM 0x3700 // parameter got rounded 115 #define SCSIS_ASC_NO_MEDIUM 0x3a00 // medium not present 116 #define SCSIS_ASC_INTERNAL_FAILURE 0x4400 117 #define SCSIS_ASC_SEL_FAILURE 0x4500 // select/reselect failure 118 #define SCSIS_ASC_UNSUCC_SOFT_RESET 0x4600 // unsuccessful soft reset 119 #define SCSIS_ASC_SCSI_PARITY_ERR 0x4700 // SCSI parity error 120 #define SCSIS_ASC_LOAD_EJECT_FAILED 0x5300 // media load or eject failed 121 #define SCSIS_ASC_REMOVAL_PREVENTED 0x5302 // medium removal prevented 122 #define SCSIS_ASC_REMOVAL_REQUESTED 0x5a01 // operator requests medium removal 123 124 // some scsi op-codes 125 #define SCSI_OP_TEST_UNIT_READY 0x00 126 #define SCSI_OP_REQUEST_SENSE 0x03 127 #define SCSI_OP_FORMAT 0x04 128 #define SCSI_OP_READ_6 0x08 129 #define SCSI_OP_WRITE_6 0x0a 130 #define SCSI_OP_INQUIRY 0x12 131 #define SCSI_OP_MODE_SELECT_6 0x15 132 #define SCSI_OP_RESERVE 0x16 133 #define SCSI_OP_RELEASE 0x17 134 #define SCSI_OP_MODE_SENSE_6 0x1a 135 #define SCSI_OP_START_STOP 0x1b 136 #define SCSI_OP_RECEIVE_DIAGNOSTIC 0x1c 137 #define SCSI_OP_SEND_DIAGNOSTIC 0x1d 138 #define SCSI_OP_PREVENT_ALLOW 0x1e 139 #define SCSI_OP_READ_CAPACITY 0x25 140 #define SCSI_OP_READ_10 0x28 141 #define SCSI_OP_WRITE_10 0x2a 142 #define SCSI_OP_POSITION_TO_ELEMENT 0x2b 143 #define SCSI_OP_VERIFY 0x2f 144 #define SCSI_OP_SYNCHRONIZE_CACHE 0x35 145 #define SCSI_OP_WRITE_BUFFER 0x3b 146 #define SCSI_OP_READ_BUFFER 0x3c 147 #define SCSI_OP_CHANGE_DEFINITION 0x40 148 #define SCSI_OP_READ_SUB_CHANNEL 0x42 149 #define SCSI_OP_READ_TOC 0x43 150 #define SCSI_OP_PLAY_MSF 0x47 151 #define SCSI_OP_PLAY_AUDIO_TRACK_INDEX 0x48 // obsolete, spec missing 152 #define SCSI_OP_PAUSE_RESUME 0x4b 153 #define SCSI_OP_STOP_PLAY 0x4e 154 #define SCSI_OP_MODE_SELECT_10 0x55 155 #define SCSI_OP_MODE_SENSE_10 0x5A 156 #define SCSI_OP_MOVE_MEDIUM 0xa5 157 #define SCSI_OP_READ_12 0xa8 158 #define SCSI_OP_WRITE_12 0xaa 159 #define SCSI_OP_READ_ELEMENT_STATUS 0xb8 160 #define SCSI_OP_SCAN 0xba 161 #define SCSI_OP_READ_CD 0xbe 162 163 // INQUIRY 164 165 typedef struct scsi_cmd_inquiry { 166 uint8 opcode; 167 LBITFIELD8_3( 168 evpd : 1, // enhanced vital product data 169 _res1_1 : 4, 170 lun : 3 171 ); 172 uint8 page_code; 173 uint8 _res3; 174 uint8 allocation_length; 175 uint8 control; 176 } _PACKED scsi_cmd_inquiry; 177 178 typedef struct scsi_res_inquiry { 179 LBITFIELD8_2( 180 device_type : 5, 181 device_qualifier : 3 182 ); 183 LBITFIELD8_2( 184 device_type_modifier : 7, // obsolete, normally set to zero 185 removable_medium : 1 186 ); 187 LBITFIELD8_3( // 0 always means "not conforming" 188 ansi_version : 3, // 1 for SCSI-1, 2 for SCSI-2 etc. 189 ecma_version : 3, 190 iso_version : 2 191 ); 192 LBITFIELD8_4( 193 response_data_format : 4, // 2 = SCSI/2 compliant 194 _res3_4 : 2, 195 term_iop : 1, // 1 = supports TERMINATE I/O PROCESS 196 async_enc : 1 // processor devices only : 197 // Asynchronous Event Notification Capable 198 ); 199 uint8 additional_length; // total (whished) length = this + 4 200 uint8 _res5; 201 uint8 _res6; 202 LBITFIELD8_8( 203 soft_reset : 1, // 0 = soft reset leads to hard reset 204 cmd_queue : 1, // 1 = supports tagged command queuing 205 _res7_2 : 1, 206 linked : 1, // 1 = supports linked commands 207 sync : 1, // 1 = supports synchronous transfers 208 write_bus16 : 1, // 1 = supports 16 bit transfers 209 write_bus32 : 1, // 1 = supports 32 bit transfers 210 relative_address : 1 // 1 = supports relative addr. for linking 211 ); 212 char vendor_ident[8]; 213 char product_ident[16]; 214 char product_rev[4]; 215 216 // XPT doesn't return following data on XPT_GDEV_TYPE 217 uint8 vendor_spec[20]; 218 uint8 _res56[2]; 219 220 uint16 version_descriptor[8]; // array of supported standards, big endian 221 222 uint8 _res74[22]; 223 /* additional vendor specific data */ 224 } _PACKED scsi_res_inquiry; 225 226 enum scsi_peripheral_qualifier { 227 scsi_periph_qual_connected = 0, 228 scsi_periph_qual_not_connected = 2, 229 scsi_periph_qual_not_connectable = 3 230 // value 1 is reserved, values of 4 and above are vendor-specific 231 }; 232 233 enum scsi_device_type { 234 scsi_dev_direct_access = 0, 235 scsi_dev_sequential_access = 1, 236 scsi_dev_printer = 2, 237 scsi_dev_processor = 3, 238 scsi_dev_WORM = 4, 239 scsi_dev_CDROM = 5, 240 scsi_dev_scanner = 6, 241 scsi_dev_optical = 7, 242 scsi_dev_medium_changer = 8, 243 scsi_dev_communication = 9, 244 // 0xa - 0xb are graphics arts pre-press devices 245 // 0xc - 0x1e reserved 246 scsi_dev_storage_array = 0xc, 247 scsi_dev_enclosure_services = 0xd, 248 scsi_dev_simplified_direct_access = 0xe, 249 scsi_dev_optical_card = 0xf, 250 scsi_dev_unknown = 0x1f // used for scsi_periph_qual_not_connectable 251 }; 252 253 254 // vital product data: unit serial number page 255 256 #define SCSI_PAGE_USN 0x80 257 258 typedef struct scsi_page_usn { 259 LBITFIELD8_2( 260 device_type : 5, 261 device_qualifier : 3 262 ); 263 uint8 page_code; 264 uint8 _res2; 265 266 uint8 _page_length; // total size = this + 3 267 char psn[1]; // size according to page_length 268 } _PACKED scsi_page_usn; 269 270 // READ CAPACITY 271 272 typedef struct scsi_cmd_read_capacity { 273 uint8 opcode; 274 LBITFIELD8_3( 275 relative_address : 1, // relative address 276 _res1_1 : 4, 277 lun : 3 278 ); 279 uint32 lba; 280 uint8 _res6[2]; 281 LBITFIELD8_2( 282 pmi : 1, // partial medium indicator 283 _res8_1 : 7 284 ); 285 uint8 control; 286 } _PACKED scsi_cmd_read_capacity; 287 288 typedef struct scsi_res_read_capacity { 289 uint32 lba; // big endian 290 uint32 block_size; // in bytes 291 } _PACKED scsi_res_read_capacity; 292 293 294 // READ (6), WRITE (6) 295 296 typedef struct scsi_cmd_rw_6 { 297 uint8 opcode; 298 LBITFIELD8_2( 299 high_lba : 5, 300 lun : 3 301 ); 302 uint8 mid_lba; 303 uint8 low_lba; 304 uint8 length; // 0 = 256 blocks 305 uint8 control; 306 } _PACKED scsi_cmd_rw_6; 307 308 309 // READ (10), WRITE (10) 310 311 typedef struct scsi_cmd_rw_10 { 312 uint8 opcode; 313 LBITFIELD8_5( 314 relative_address : 1, // relative address 315 _res1_1 : 2, 316 force_unit_access : 1, // force unit access (1 = safe, cacheless access) 317 disable_page_out : 1, // disable page out (1 = not worth caching) 318 lun : 3 319 ); 320 uint32 lba; // big endian 321 uint8 _res6; 322 uint16 length; // 0 = no block 323 uint8 control; 324 } _PACKED scsi_cmd_rw_10; 325 326 327 // READ (12), WRITE (12) 328 329 typedef struct scsi_cmd_rw_12 { 330 uint8 opcode; 331 LBITFIELD8_5( 332 relative_address : 1, // relative address 333 _res1_1 : 2, 334 force_unit_access : 1, // force unit access (1 = safe, cacheless access) 335 disable_page_out : 1, // disable page out (1 = not worth caching) 336 lun : 3 337 ); 338 uint32 lba; // big endian 339 uint32 length; // 0 = no block 340 uint8 _res10; 341 uint8 control; 342 } _PACKED scsi_cmd_rw_12; 343 344 345 // REQUEST SENSE 346 347 typedef struct scsi_cmd_request_sense { 348 uint8 opcode; 349 LBITFIELD8_2( 350 _res1_0 : 5, 351 lun : 3 352 ); 353 uint8 _res2[2]; 354 uint8 allocation_length; 355 uint8 control; 356 } _PACKED scsi_cmd_request_sense; 357 358 359 // sense data structures 360 361 #define SCSIS_CURR_ERROR 0x70 362 #define SCSIS_DEFERRED_ERROR 0x71 363 364 typedef struct scsi_sense { 365 LBITFIELD8_2( 366 error_code : 7, 367 valid : 1 // 0 = not conforming to standard 368 ); 369 uint8 segment_number; // for COPY/COPY AND VERIFY/COMPARE 370 LBITFIELD8_5( 371 sense_key : 4, 372 res2_4 : 1, 373 ILI : 1, // incorrect length indicator - req. block 374 // length doesn't match physical block length 375 EOM : 1, // serial devices only 376 Filemark : 1 // optional for random access 377 ); 378 379 uint8 highest_inf; // device-type or command specific 380 uint8 high_inf; // device-type 0, 4, 5, 7: block address 381 uint8 mid_inf; // device-type 1, 2, 3: req length - act. length 382 uint8 low_inf; // (and others for sequential dev. and COPY cmds 383 384 uint8 add_sense_length; // total length = this + 7 385 386 uint8 highest_cmd_inf; 387 uint8 high_cmd_inf; 388 uint8 mid_cmd_inf; 389 uint8 low_cmd_inf; 390 uint8 asc; 391 uint8 ascq; // this can be zero if unsupported 392 uint8 unit_code; // != 0 to specify internal device unit 393 394 union { 395 struct { 396 LBITFIELD8_2( 397 high_key_spec : 7, 398 SKSV : 1 // 1 = sense key specific (byte 15-17) valid 399 ); 400 uint8 mid_key_spec; 401 uint8 low_key_spec; 402 } raw; 403 404 // ILLEGAL REQUEST 405 struct { 406 LBITFIELD8_5( 407 bit_pointer : 3, // points to (highest) invalid bit of parameter 408 BPV : 1, // 1 = bit_pointer is valid 409 res15_4 : 2, 410 c_d : 2, // 1 = error command, 0 = error in data 411 SKSV : 1 // s.a. 412 ); 413 uint8 high_field_pointer; // points to (highest) invalid byte of parameter 414 uint8 low_field_pointer; // (!using big endian, this means the first byte!) 415 } ill_request; 416 417 // access error (RECOVERED, HARDWARE or MEDIUM ERROR) 418 struct { 419 LBITFIELD8_2( 420 res15_0 : 7, 421 SKSV : 1 422 ); 423 uint8 high_retry_cnt; 424 uint8 low_retry_cnt; 425 } acc_error; 426 427 // format progress (if sense key = NOT READY) 428 struct { 429 LBITFIELD8_2( 430 res15_0 : 7, 431 SKSV : 1 432 ); 433 uint16 progress; // 0 = start, 0xffff = almost finished 434 } format_progress; 435 } sense_key_spec; 436 437 // starting with offset 18 there are additional sense byte 438 } _PACKED scsi_sense; 439 440 441 // PREVENT ALLOW 442 443 typedef struct scsi_cmd_prevent_allow { 444 uint8 opcode; 445 LBITFIELD8_2( 446 _res1_0 : 5, 447 lun : 3 448 ); 449 uint8 _res2[2]; 450 LBITFIELD8_2( 451 prevent : 1, // 1 - prevent medium removal, 0 - allow removal 452 _res4_1 : 7 453 ); 454 uint8 control; 455 } _PACKED scsi_cmd_prevent_allow; 456 457 // START STOP UNIT 458 459 typedef struct scsi_cmd_ssu { 460 uint8 opcode; 461 LBITFIELD8_3( 462 immediately : 1, // 1 - return immediately, 0 - return on completion 463 _res1_1 : 4, 464 lun : 3 465 ); 466 uint8 res2[2]; 467 LBITFIELD8_3( 468 start : 1, // 1 - load+start, i.e. allow, 0 - eject+stop, i.e. deny 469 load_eject : 1, // 1 - include loading/ejecting, 0 - only to allow/deny 470 _res4_2 : 6 471 ); 472 uint8 control; 473 } _PACKED scsi_cmd_ssu; 474 475 476 // MODE SELECT (6) 477 478 typedef struct scsi_cmd_mode_select_6 { 479 uint8 opcode; 480 LBITFIELD8_4( 481 save_pages : 1, // 1 = save pages to non-volatile memory 482 _res1_1 : 3, 483 pf : 1, // 0 = old SCSI-1; 1 = new SCSI-2 format 484 lun : 3 485 ); 486 uint8 _res2[2]; 487 uint8 param_list_length; // data size 488 uint8 control; 489 } _PACKED scsi_cmd_mode_select_6; 490 491 492 // MODE SENSE (6) 493 494 typedef struct scsi_cmd_mode_sense_6 { 495 uint8 opcode; 496 LBITFIELD8_4( 497 _res1_0 : 3, 498 disable_block_desc : 1, // disable block descriptors 499 _res1_4 : 1, 500 lun : 3 501 ); 502 LBITFIELD8_2( 503 page_code : 6, 504 page_control : 2 // page control field 505 ); 506 uint8 _res3; 507 uint8 allocation_length; // maximum amount of data 508 uint8 control; 509 } _PACKED scsi_cmd_mode_sense_6; 510 511 512 // MODE SELECT (10) 513 514 typedef struct scsi_cmd_mode_select_10 { 515 uint8 opcode; 516 LBITFIELD8_4( 517 save_pages : 1, // 1 = save pages to non-volatile memory 518 _res1_1 : 3, 519 pf : 1, // 0 = old SCSI-1; 1 = new SCSI-2 format 520 lun : 3 521 ); 522 uint8 _res2[5]; 523 uint16 param_list_length; // data size, big endian 524 uint8 control; 525 } _PACKED scsi_cmd_mode_select_10; 526 527 528 // MODE SENSE (10) 529 530 typedef struct scsi_cmd_mode_sense_10 { 531 uint8 opcode; 532 LBITFIELD8_4( 533 _res1_0 : 3, 534 disable_block_desc : 1, // disable block descriptors 535 _res1_4 : 1, 536 lun : 3 537 ); 538 LBITFIELD8_2( 539 page_code : 6, 540 page_control : 2 // page control field 541 ); 542 uint8 _res3[4]; 543 uint16 allocation_length; // maximum amount of data, big endian 544 uint8 control; 545 } _PACKED scsi_cmd_mode_sense_10; 546 547 // possible contents of page control (PC) 548 #define SCSI_MODE_SENSE_PC_CURRENT 0 549 #define SCSI_MODE_SENSE_PC_CHANGABLE 1 550 // changable field are filled with "1" 551 #define SCSI_MODE_SENSE_PC_DEFAULT 2 552 #define SCSI_MODE_SENSE_PC_SAVED 3 553 554 // special mode page indicating to return all mode pages 555 #define SCSI_MODEPAGE_ALL 0x3f 556 557 // header of mode data; followed by block descriptors and mode pages 558 typedef struct scsi_mode_param_header_6 { 559 uint8 mode_data_length; // total length excluding this byte 560 uint8 medium_type; 561 uint8 dev_spec_parameter; 562 uint8 block_desc_length; // total length of all transmitted block descriptors 563 } _PACKED scsi_mode_param_header_6; 564 565 typedef struct scsi_mode_param_header_10 { 566 uint16 mode_data_length; // total length excluding these two bytes 567 uint8 medium_type; 568 uint8 dev_spec_parameter; 569 uint8 _res4[2]; 570 uint16 block_desc_length; // total length of all transmitted block descriptors 571 } _PACKED scsi_mode_param_header_10; 572 573 574 // content of dev_spec_parameter for direct access devices 575 typedef struct scsi_mode_param_dev_spec_da { 576 LBITFIELD8_4( 577 _res0_0 : 4, 578 dpo_fua : 1, // 1 = supports DPO and FUA, see READ (10) (sense only) 579 _res0_6 : 1, 580 write_protected : 1 // write protected (sense only) 581 ); 582 } _PACKED scsi_mode_param_dev_spec_da; 583 584 typedef struct scsi_mode_param_block_desc { 585 uint8 density; // density code of area 586 uint8 high_numblocks; // size of this area in blocks 587 uint8 med_numblocks; // 0 = all remaining blocks 588 uint8 low_numblocks; 589 uint8 _res4; 590 uint8 high_blocklen; // block size 591 uint8 med_blocklen; 592 uint8 low_blocklen; 593 } _PACKED scsi_mode_param_block_desc; 594 595 596 // header of a mode pages 597 typedef struct scsi_modepage_header { 598 LBITFIELD8_3( 599 page_code : 6, 600 _res0_6 : 1, 601 PS : 1 // 1 = page can be saved (only valid for MODE SENSE) 602 ); 603 uint8 page_length; // size of page excluding this common header 604 } _PACKED scsi_modepage_header; 605 606 607 // control mode page 608 #define SCSI_MODEPAGE_CONTROL 0xa 609 610 typedef struct scsi_modepage_control { 611 scsi_modepage_header header; 612 LBITFIELD8_2( 613 RLEC : 1, // Report Log Exception Condition 614 res2_1 : 7 615 ); 616 LBITFIELD8_4( 617 DQue : 1, // disable Queuing 618 QErr : 1, // abort queued commands on contingent allegiance condition 619 res3_2 : 2, 620 QAM : 4 // Queue Algorithm Modifier 621 ); 622 LBITFIELD8_5( 623 EAENP : 1, // error AEN permission; true = send AEN on deferred error 624 // false = generate UA condition after deferred error 625 UAAENP : 1, // unit attention AEN permission; true = send AEN, 626 // false = generate UA condition (for everything but init.) 627 RAENP : 1, // ready AEN permission; true = send async event notification 628 // (AEN) instead of generating an Unit Attention (UA) Condition 629 // after initialization 630 res4_3 : 4, 631 EECA : 1 // enable Extended Contingent Allegiance 632 ); 633 uint8 res5; 634 uint8 high_AEN_holdoff; // ready AEN hold off period - delay in ms between 635 uint8 low_AEN_holdoff; // initialization and AEN 636 } scsi_modepage_control; 637 638 // values for QAM 639 #define SCSI_QAM_RESTRICTED 0 640 #define SCSI_QAM_UNRESTRICTED 1 641 // 2 - 7 reserved, 8 - 0xf vendor-specific 642 643 644 // CD audio control page 645 #define SCSI_MODEPAGE_AUDIO 0xe 646 647 typedef struct scsi_modepage_audio { 648 scsi_modepage_header header; 649 LBITFIELD8_4( 650 _res2_0 : 1, 651 stop_on_track_crossing : 1, // Stop On Track Crossing 652 // 0 - stop according transfer length, 1 - stop at end of track 653 immediately : 1, // must be one 654 _res2_3 : 5 655 ); 656 uint8 _res3[3]; 657 uint8 _obsolete6[2]; 658 struct { 659 LBITFIELD8_2( 660 channel : 4, // select channel to connect to this port 661 _res0_4 : 4 662 ); 663 uint8 volume; 664 } ports[4]; 665 } _PACKED scsi_modepage_audio; 666 667 // connection between output port and audio channel 668 #define SCSI_CHANNEL_SEL_MUTED 0 // mute port 669 #define SCSI_CHANNEL_SEL_CHANNEL0 1 // connect to channel 0 670 #define SCSI_CHANNEL_SEL_CHANNEL1 2 // connect to channel 1 671 #define SCSI_CHANNEL_SEL_CHANNEL0_1 3 // connect to channel 0 and channel 1 672 #define SCSI_CHANNEL_SEL_CHANNEL2 4 // connect to channel 2 673 #define SCSI_CHANNEL_SEL_CHANNEL3 8 // connect to channel 3 674 675 // TUR 676 677 typedef struct scsi_cmd_tur { 678 uint8 opcode; 679 LBITFIELD8_2( 680 _res1_0 : 5, 681 lun : 3 682 ); 683 uint8 _res3[3]; 684 uint8 control; 685 } _PACKED scsi_cmd_tur; 686 687 688 // READ_TOC 689 690 typedef struct scsi_cmd_read_toc { 691 uint8 opcode; 692 LBITFIELD8_4( 693 _res1_0 : 1, 694 time : 1, // true, to use MSF format, false for LBA format 695 _res1_2 : 3, 696 lun : 3 697 ); 698 LBITFIELD8_2( 699 format : 4, // see below 700 _res2_4 : 4 701 ); 702 uint8 _res3[3]; 703 uint8 track; // (starting) track 704 uint16 allocation_length; // maximum amount of data (big endian) 705 uint8 control; 706 } _PACKED scsi_cmd_read_toc; 707 708 // values of <format> in TOC command 709 #define SCSI_TOC_FORMAT_TOC 0 // all TOCs starting with <track> (0xaa for lead-out) 710 #define SCSI_TOC_FORMAT_SESSION_INFO 1 // Session info 711 #define SCSI_TOC_FORMAT_FULL_TOC 2 // all Q-channel data in TOC 712 #define SCSI_TOC_FORMAT_PMA 3 // Q-channel data in PMA area 713 #define SCSI_TOC_FORMAT_ATIP 4 // get ATIP data 714 #define SCSI_TOC_FORMAT_CD_TEXT 5 // get CD-Text from R/W-channel in lead-in 715 716 // general structure of response 717 typedef struct scsi_toc_general { 718 uint16 data_length; // big endian, total length - 2 719 uint8 first; // first track/session/reserved 720 uint8 last; // last one 721 // remainder are parameter list descriptors 722 } _PACKED scsi_toc_general; 723 724 // definition of CD-ROM LBA 725 typedef uint32 scsi_cd_lba; // big endian 726 727 // definition of CD-ROM MSF time 728 typedef struct scsi_cd_msf { 729 uint8 _reserved; 730 uint8 minute; 731 uint8 second; 732 uint8 frame; 733 } _PACKED scsi_cd_msf; 734 735 // definition of Track Number address format 736 typedef struct scsi_cd_track_number { 737 uint8 _res0[3]; 738 uint8 track; 739 } _PACKED scsi_cd_track_number; 740 741 // one track for SCSI_TOC_FORMAT_TOC 742 typedef struct scsi_toc_track { 743 uint8 _res0; 744 LBITFIELD8_2( 745 control : 4, 746 adr : 4 747 ); 748 uint8 track_number; // track number (hex) 749 uint8 _res3; 750 union { // start of track (time or LBA, see TIME of command) 751 scsi_cd_lba lba; 752 scsi_cd_msf time; 753 } start; 754 } _PACKED scsi_toc_track; 755 756 // possible value of ADR-field (described Q-channel content) 757 enum scsi_adr { 758 scsi_adr_none = 0, // no Q-channel mode info 759 scsi_adr_position = 1, // Q-channel encodes current position data 760 scsi_adr_mcn = 2, // Q-channel encodes Media Catalog Number 761 scsi_adr_isrc = 3 // Q-channel encodes ISRC 762 }; 763 764 // value of Q-channel control field (CONTROL) 765 enum scsi_q_control { 766 scsi_q_control_2audio = 0, // stereo audio 767 scsi_q_control_2audio_preemp = 1, // stereo audio with 50/15µs pre-emphasis 768 scsi_q_control_1audio = 8, // audio (reserved in CD-R/W) 769 scsi_q_control_1audio_preemp = 9, // audio with pre-emphasis (reserved in CD-R/W) 770 scsi_q_control_data_un_intr = 4, // data, recorded un-interrupted 771 scsi_q_control_data_incr = 5, // data, recorded incremental 772 scsi_q_control_ddcd = 4, // DDCD data 773 scsi_q_control_copy_perm = 2 // copy permitted (or-ed with value above) 774 }; 775 776 // format SCSI_TOC_FORMAT_TOC 777 typedef struct scsi_toc_toc { 778 uint16 data_length; // big endian, total length - 2 779 uint8 first_track; // first track 780 uint8 last_track; // last track 781 782 scsi_toc_track tracks[1]; // one entry per track 783 } _PACKED scsi_toc_toc; 784 785 786 // READ SUB-CHANNEL 787 788 typedef struct scsi_cmd_read_subchannel { 789 uint8 opcode; 790 LBITFIELD8_4( 791 _res1_0 : 1, 792 time : 1, // true, to use MSF format, false for LBA format 793 _res1_2 : 3, 794 lun : 3 795 ); 796 LBITFIELD8_3( 797 _res2_0 : 6, 798 subq : 1, // 1 - return Q sub-channel data 799 _res2_7 : 1 800 ); 801 uint8 parameter_list; // see below 802 uint8 _res4[2]; 803 uint8 track; // track number (hex) 804 uint16 allocation_length; // maximum amount of data, big endian 805 uint8 control; 806 } _PACKED scsi_cmd_read_subchannel; 807 808 // values of parameter_list 809 enum scsi_sub_channel_parameter_list { 810 scsi_sub_channel_parameter_list_cd_pos = 1, // CD current position 811 scsi_sub_channel_parameter_list_mcn = 2, // Media Catalog Number 812 scsi_sub_channel_parameter_list_isrc = 3 // Track International Standard Recording Code 813 }; 814 815 // header of response 816 typedef struct scsi_subchannel_data_header { 817 uint8 _res0; 818 uint8 audio_status; // see below 819 uint16 data_length; // total length - 4, big endian 820 } _PACKED scsi_subchannel_data_header; 821 822 // possible audio_status 823 enum scsi_audio_status { 824 scsi_audio_status_not_supported = 0, 825 scsi_audio_status_playing = 0x11, 826 scsi_audio_status_paused = 0x12, 827 scsi_audio_status_completed = 0x13, 828 scsi_audio_status_error_stop = 0x14, 829 scsi_audio_status_no_status = 0x15 830 }; 831 832 typedef struct scsi_cd_current_position { 833 uint8 format_code; // always 1 834 LBITFIELD8_2( 835 control : 4, // see scsi_q_control 836 adr : 4 // see scsi_adr 837 ); 838 uint8 track; 839 uint8 index; 840 union { // current position, relative to logical beginning 841 scsi_cd_lba lba; 842 scsi_cd_msf time; 843 } absolute_address; 844 union { // current position, relative to track 845 scsi_cd_lba lba; 846 scsi_cd_msf time; 847 } track_relative_address; 848 } _PACKED scsi_cd_current_position; 849 850 851 // PLAY AUDIO MSF 852 853 typedef struct scsi_cmd_play_msf { 854 uint8 opcode; 855 LBITFIELD8_2( 856 _res1_0 : 5, 857 lun : 3 858 ); 859 uint8 _res2; 860 uint8 start_minute; // start time 861 uint8 start_second; 862 uint8 start_frame; 863 uint8 end_minute; // end time (excluding) 864 uint8 end_second; 865 uint8 end_frame; 866 uint8 control; 867 } _PACKED scsi_cmd_play_msf; 868 869 870 // STOP AUDIO 871 872 typedef struct scsi_cmd_stop_play { 873 uint8 opcode; 874 LBITFIELD8_2( 875 _res1_0 : 5, 876 lun : 3 877 ); 878 uint8 _res2[7]; 879 uint8 control; 880 } _PACKED scsi_cmd_stop_play; 881 882 883 // PAUSE/RESUME 884 885 typedef struct scsi_cmd_pause_resume { 886 uint8 opcode; 887 LBITFIELD8_2( 888 _res1_0 : 5, 889 lun : 3 890 ); 891 uint8 _res2[6]; 892 LBITFIELD8_2( 893 resume : 1, // 1 for resume, 0 for pause 894 _res8_2 : 7 895 ); 896 uint8 control; 897 } _PACKED scsi_cmd_pause_resume; 898 899 900 // SCAN 901 902 typedef struct scsi_cmd_scan { 903 uint8 opcode; 904 LBITFIELD8_4( 905 relative_address : 1, // must be zero 906 _res1_1 : 3, 907 direct : 1, // direction: 0 forward, 1 backward 908 lun : 3 909 ); 910 union { // start of track (depends on <type>) 911 scsi_cd_lba lba; 912 scsi_cd_msf time; 913 scsi_cd_track_number track_number; 914 } start; 915 uint8 _res6[3]; 916 LBITFIELD8_2( 917 res9_0 : 6, 918 type : 2 // actual type of <start> (see below) 919 ); 920 uint8 _res10; 921 uint8 control; 922 } _PACKED scsi_cmd_scan; 923 924 // possible values for type 925 enum scsi_scan_type { 926 scsi_scan_lba = 0, 927 scsi_scan_msf = 1, 928 scsi_scan_tno = 2 929 }; 930 931 932 // READ_CD 933 934 typedef struct scsi_cmd_read_cd { 935 uint8 opcode; 936 LBITFIELD8_4( 937 relative_address : 1, // must be zero 938 _res1_1 : 1, 939 sector_type : 3, // required sector type (1=CDDA) 940 lun : 3 941 ); 942 scsi_cd_lba lba; 943 uint8 high_length; 944 uint8 mid_length; 945 uint8 low_length; 946 LBITFIELD8_6( 947 _res9_0 : 1, 948 error_field : 2, 949 edc_ecc : 1, // include EDC/ECC; includes 8 byte padding for Mode 1 format 950 user_data : 1, // if 1, include user data 951 // (mode select block size is ignored) 952 header_code : 2, 953 sync : 1 // if 1, include sync field from sector 954 ); 955 LBITFIELD8_2( 956 sub_channel_selection : 4, 957 _res10_4 : 4 958 ); 959 uint8 control; 960 } _PACKED scsi_cmd_read_cd; 961 962 // possible values for header_code 963 enum scsi_read_cd_header_code { 964 scsi_read_cd_header_none = 0, 965 scsi_read_cd_header_hdr_only = 1, 966 scsi_read_cd_header_sub_header_only = 2, 967 scsi_read_cd_header_all_headers = 3, 968 }; 969 970 // possible values for error_field 971 enum scsi_read_cd_error_field { 972 scsi_read_cd_error_none = 0, 973 scsi_read_cd_error_c2_error = 1, // include 2352 bits indicating error in byte 974 scsi_read_cd_error_c2_and_block_error = 2, // include or of C2 data plus pad byte 975 }; 976 977 // possible values for sub_channel_selection 978 enum scsi_read_cd_sub_channel_selection { 979 scsi_read_cd_sub_channel_none = 0, 980 scsi_read_cd_sub_channel_RAW = 1, 981 scsi_read_cd_sub_channel_Q = 2, 982 scsi_read_cd_sub_channel_P_W = 4 // R/W data, depending on CD capabilities 983 // and Mechanism status page 984 }; 985 986 // SYNCHRONIZE CACHE (10) 987 988 typedef struct scsi_cmd_sync_cache { 989 uint8 opcode; 990 LBITFIELD8_4( 991 relative_address : 1, // must be zero 992 immediately : 1, // 1 - return immediately, 0 - return on completion 993 _res1_1 : 3, 994 lun : 3 995 ); 996 scsi_cd_lba lba; 997 uint8 _res2; 998 uint16 block_count; // big endian 999 uint8 control; 1000 } _PACKED scsi_cmd_sync_cache; 1001 1002 #endif /* _SCSI_CMDS_H */ 1003