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