xref: /haiku/headers/private/drivers/scsi_cmds.h (revision 16d5c24e533eb14b7b8a99ee9f3ec9ba66335b1e)
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