xref: /freebsd-11-stable/sys/cam/scsi/scsi_cd.h (revision c0be1933121ce001ef383ed6284b3a4331aee451)
1 /*-
2  * Copyright (c) 2000, 2002 Kenneth D. Merry
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions, and the following disclaimer,
10  *    without modification, immediately at the beginning of the file.
11  * 2. The name of the author may not be used to endorse or promote products
12  *    derived from this software without specific prior written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
18  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  */
27 /*
28  * Written by Julian Elischer (julian@tfs.com)
29  * for TRW Financial Systems.
30  *
31  * TRW Financial Systems, in accordance with their agreement with Carnegie
32  * Mellon University, makes this software available to CMU to distribute
33  * or use in any manner that they see fit as long as this message is kept with
34  * the software. For this reason TFS also grants any other persons or
35  * organisations permission to use or modify this software.
36  *
37  * TFS supplies this software to be publicly redistributed
38  * on the understanding that TFS is not responsible for the correct
39  * functioning of this software in any circumstances.
40  *
41  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
42  *
43  *	from: scsi_cd.h,v 1.10 1997/02/22 09:44:28 peter Exp $
44  * $FreeBSD$
45  */
46 #ifndef	_SCSI_SCSI_CD_H
47 #define _SCSI_SCSI_CD_H 1
48 
49 /*
50  *	Define two bits always in the same place in byte 2 (flag byte)
51  */
52 #define	CD_RELADDR	0x01
53 #define	CD_MSF		0x02
54 
55 /*
56  * SCSI command format
57  */
58 
59 struct scsi_get_config
60 {
61 	uint8_t opcode;
62 	uint8_t rt;
63 #define	SGC_RT_ALL		0x00
64 #define	SGC_RT_CURRENT		0x01
65 #define	SGC_RT_SPECIFIC		0x02
66 #define	SGC_RT_MASK		0x03
67 	uint8_t starting_feature[2];
68 	uint8_t reserved[3];
69 	uint8_t length[2];
70 	uint8_t control;
71 };
72 
73 struct scsi_get_config_header
74 {
75 	uint8_t data_length[4];
76 	uint8_t reserved[2];
77 	uint8_t current_profile[2];
78 };
79 
80 struct scsi_get_config_feature
81 {
82 	uint8_t feature_code[2];
83 	uint8_t flags;
84 #define	SGC_F_CURRENT		0x01
85 #define	SGC_F_PERSISTENT	0x02
86 #define	SGC_F_VERSION_MASK	0x2C
87 #define	SGC_F_VERSION_SHIFT	2
88 	uint8_t add_length;
89 	uint8_t feature_data[];
90 };
91 
92 struct scsi_get_event_status
93 {
94 	uint8_t opcode;
95 	uint8_t byte2;
96 #define	SGESN_POLLED		1
97 	uint8_t reserved[2];
98 	uint8_t notif_class;
99 	uint8_t reserved2[2];
100 	uint8_t length[2];
101 	uint8_t control;
102 };
103 
104 struct scsi_get_event_status_header
105 {
106 	uint8_t descr_length[4];
107 	uint8_t nea_class;
108 #define	SGESN_NEA		0x80
109 	uint8_t supported_class;
110 };
111 
112 struct scsi_get_event_status_descr
113 {
114 	uint8_t event_code;
115 	uint8_t event_info[];
116 };
117 
118 struct scsi_mechanism_status
119 {
120 	uint8_t opcode;
121 	uint8_t reserved[7];
122 	uint8_t length[2];
123 	uint8_t reserved2;
124 	uint8_t control;
125 };
126 
127 struct scsi_mechanism_status_header
128 {
129 	uint8_t state1;
130 	uint8_t state2;
131 	uint8_t lba[3];
132 	uint8_t slots_num;
133 	uint8_t slots_length[2];
134 };
135 
136 struct scsi_pause
137 {
138 	u_int8_t op_code;
139 	u_int8_t byte2;
140 	u_int8_t unused[6];
141 	u_int8_t resume;
142 	u_int8_t control;
143 };
144 #define	PA_PAUSE	1
145 #define PA_RESUME	0
146 
147 struct scsi_play_msf
148 {
149 	u_int8_t op_code;
150 	u_int8_t byte2;
151 	u_int8_t unused;
152 	u_int8_t start_m;
153 	u_int8_t start_s;
154 	u_int8_t start_f;
155 	u_int8_t end_m;
156 	u_int8_t end_s;
157 	u_int8_t end_f;
158 	u_int8_t control;
159 };
160 
161 struct scsi_play_track
162 {
163 	u_int8_t op_code;
164 	u_int8_t byte2;
165 	u_int8_t unused[2];
166 	u_int8_t start_track;
167 	u_int8_t start_index;
168 	u_int8_t unused1;
169 	u_int8_t end_track;
170 	u_int8_t end_index;
171 	u_int8_t control;
172 };
173 
174 struct scsi_play_10
175 {
176 	u_int8_t op_code;
177 	u_int8_t byte2;
178 	u_int8_t blk_addr[4];
179 	u_int8_t unused;
180 	u_int8_t xfer_len[2];
181 	u_int8_t control;
182 };
183 
184 struct scsi_play_12
185 {
186 	u_int8_t op_code;
187 	u_int8_t byte2;	/* same as above */
188 	u_int8_t blk_addr[4];
189 	u_int8_t xfer_len[4];
190 	u_int8_t unused;
191 	u_int8_t control;
192 };
193 
194 struct scsi_play_rel_12
195 {
196 	u_int8_t op_code;
197 	u_int8_t byte2;	/* same as above */
198 	u_int8_t blk_addr[4];
199 	u_int8_t xfer_len[4];
200 	u_int8_t track;
201 	u_int8_t control;
202 };
203 
204 struct scsi_read_header
205 {
206 	u_int8_t op_code;
207 	u_int8_t byte2;
208 	u_int8_t blk_addr[4];
209 	u_int8_t unused;
210 	u_int8_t data_len[2];
211 	u_int8_t control;
212 };
213 
214 struct scsi_read_subchannel
215 {
216 	u_int8_t op_code;
217 	u_int8_t byte1;
218 	u_int8_t byte2;
219 #define	SRS_SUBQ	0x40
220 	u_int8_t subchan_format;
221 	u_int8_t unused[2];
222 	u_int8_t track;
223 	u_int8_t data_len[2];
224 	u_int8_t control;
225 };
226 
227 struct scsi_read_toc
228 {
229 	u_int8_t op_code;
230 	u_int8_t byte2;
231 	u_int8_t format;
232 #define	SRTOC_FORMAT_TOC	0x00
233 #define	SRTOC_FORMAT_LAST_ADDR	0x01
234 #define	SRTOC_FORMAT_QSUB_TOC	0x02
235 #define	SRTOC_FORMAT_QSUB_PMA	0x03
236 #define	SRTOC_FORMAT_ATIP	0x04
237 #define	SRTOC_FORMAT_CD_TEXT	0x05
238 	u_int8_t unused[3];
239 	u_int8_t from_track;
240 	u_int8_t data_len[2];
241 	u_int8_t control;
242 };
243 
244 struct scsi_read_toc_hdr
245 {
246 	uint8_t data_length[2];
247 	uint8_t first;
248 	uint8_t last;
249 };
250 
251 struct scsi_read_toc_type01_descr
252 {
253 	uint8_t reserved;
254 	uint8_t addr_ctl;
255 	uint8_t track_number;
256 	uint8_t reserved2;
257 	uint8_t track_start[4];
258 };
259 
260 struct scsi_read_cd_capacity
261 {
262 	u_int8_t op_code;
263 	u_int8_t byte2;
264 	u_int8_t addr_3;	/* Most Significant */
265 	u_int8_t addr_2;
266 	u_int8_t addr_1;
267 	u_int8_t addr_0;	/* Least Significant */
268 	u_int8_t unused[3];
269 	u_int8_t control;
270 };
271 
272 struct scsi_set_speed
273 {
274 	u_int8_t opcode;
275 	u_int8_t byte2;
276 	u_int8_t readspeed[2];
277 	u_int8_t writespeed[2];
278 	u_int8_t reserved[5];
279 	u_int8_t control;
280 };
281 
282 struct scsi_report_key
283 {
284 	u_int8_t opcode;
285 	u_int8_t reserved0;
286 	u_int8_t lba[4];
287 	u_int8_t reserved1[2];
288 	u_int8_t alloc_len[2];
289 	u_int8_t agid_keyformat;
290 #define RK_KF_AGID_MASK		0xc0
291 #define RK_KF_AGID_SHIFT	6
292 #define RK_KF_KEYFORMAT_MASK	0x3f
293 #define RK_KF_AGID		0x00
294 #define RK_KF_CHALLENGE		0x01
295 #define RF_KF_KEY1		0x02
296 #define RK_KF_KEY2		0x03
297 #define RF_KF_TITLE		0x04
298 #define RF_KF_ASF		0x05
299 #define RK_KF_RPC_SET		0x06
300 #define RF_KF_RPC_REPORT	0x08
301 #define RF_KF_INV_AGID		0x3f
302 	u_int8_t control;
303 };
304 
305 /*
306  * See the report key structure for key format and AGID definitions.
307  */
308 struct scsi_send_key
309 {
310 	u_int8_t opcode;
311 	u_int8_t reserved[7];
312 	u_int8_t param_len[2];
313 	u_int8_t agid_keyformat;
314 	u_int8_t control;
315 };
316 
317 struct scsi_read_dvd_structure
318 {
319 	u_int8_t opcode;
320 	u_int8_t reserved;
321 	u_int8_t address[4];
322 	u_int8_t layer_number;
323 	u_int8_t format;
324 #define RDS_FORMAT_PHYSICAL		0x00
325 #define RDS_FORMAT_COPYRIGHT		0x01
326 #define RDS_FORMAT_DISC_KEY		0x02
327 #define RDS_FORMAT_BCA			0x03
328 #define RDS_FORMAT_MANUFACTURER		0x04
329 #define RDS_FORMAT_CMGS_CPM		0x05
330 #define RDS_FORMAT_PROT_DISCID		0x06
331 #define RDS_FORMAT_DISC_KEY_BLOCK	0x07
332 #define RDS_FORMAT_DDS			0x08
333 #define RDS_FORMAT_DVDRAM_MEDIA_STAT	0x09
334 #define RDS_FORMAT_SPARE_AREA		0x0a
335 #define RDS_FORMAT_RMD_BORDEROUT	0x0c
336 #define RDS_FORMAT_RMD			0x0d
337 #define RDS_FORMAT_LEADIN		0x0e
338 #define RDS_FORMAT_DISC_ID		0x0f
339 #define RDS_FORMAT_DCB			0x30
340 #define RDS_FORMAT_WRITE_PROT		0xc0
341 #define RDS_FORMAT_STRUCTURE_LIST	0xff
342 	u_int8_t alloc_len[2];
343 	u_int8_t agid;
344 	u_int8_t control;
345 };
346 
347 /*
348  * Opcodes
349  */
350 #define READ_CD_CAPACITY	0x25	/* slightly different from disk */
351 #define READ_SUBCHANNEL		0x42	/* cdrom read Subchannel */
352 #define READ_TOC		0x43	/* cdrom read TOC */
353 #define READ_HEADER		0x44	/* cdrom read header */
354 #define PLAY_10			0x45	/* cdrom play  'play audio' mode */
355 #define GET_CONFIGURATION	0x46	/* Get device configuration */
356 #define PLAY_MSF		0x47	/* cdrom play Min,Sec,Frames mode */
357 #define PLAY_TRACK		0x48	/* cdrom play track/index mode */
358 #define PLAY_TRACK_REL		0x49	/* cdrom play track/index mode */
359 #define GET_EVENT_STATUS	0x4a	/* Get event status notification */
360 #define PAUSE			0x4b	/* cdrom pause in 'play audio' mode */
361 #define SEND_KEY		0xa3	/* dvd send key command */
362 #define REPORT_KEY		0xa4	/* dvd report key command */
363 #define PLAY_12			0xa5	/* cdrom pause in 'play audio' mode */
364 #define PLAY_TRACK_REL_BIG	0xa9	/* cdrom play track/index mode */
365 #define READ_DVD_STRUCTURE	0xad	/* read dvd structure */
366 #define SET_CD_SPEED		0xbb	/* set c/dvd speed */
367 #define MECHANISM_STATUS	0xbd	/* get status of c/dvd mechanics */
368 
369 struct scsi_report_key_data_header
370 {
371 	u_int8_t data_len[2];
372 	u_int8_t reserved[2];
373 };
374 
375 struct scsi_report_key_data_agid
376 {
377 	u_int8_t data_len[2];
378 	u_int8_t reserved[5];
379 	u_int8_t agid;
380 #define RKD_AGID_MASK	0xc0
381 #define RKD_AGID_SHIFT	6
382 };
383 
384 struct scsi_report_key_data_challenge
385 {
386 	u_int8_t data_len[2];
387 	u_int8_t reserved0[2];
388 	u_int8_t challenge_key[10];
389 	u_int8_t reserved1[2];
390 };
391 
392 struct scsi_report_key_data_key1_key2
393 {
394 	u_int8_t data_len[2];
395 	u_int8_t reserved0[2];
396 	u_int8_t key1[5];
397 	u_int8_t reserved1[3];
398 };
399 
400 struct scsi_report_key_data_title
401 {
402 	u_int8_t data_len[2];
403 	u_int8_t reserved0[2];
404 	u_int8_t byte0;
405 #define RKD_TITLE_CPM		0x80
406 #define RKD_TITLE_CPM_SHIFT	7
407 #define RKD_TITLE_CP_SEC	0x40
408 #define RKD_TITLE_CP_SEC_SHIFT	6
409 #define RKD_TITLE_CMGS_MASK	0x30
410 #define RKD_TITLE_CMGS_SHIFT	4
411 #define RKD_TITLE_CMGS_NO_RST	0x00
412 #define RKD_TITLE_CMGS_RSVD	0x10
413 #define RKD_TITLE_CMGS_1_GEN	0x20
414 #define RKD_TITLE_CMGS_NO_COPY	0x30
415 	u_int8_t title_key[5];
416 	u_int8_t reserved1[2];
417 };
418 
419 struct scsi_report_key_data_asf
420 {
421 	u_int8_t data_len[2];
422 	u_int8_t reserved[5];
423 	u_int8_t success;
424 #define RKD_ASF_SUCCESS	0x01
425 };
426 
427 struct scsi_report_key_data_rpc
428 {
429 	u_int8_t data_len[2];
430 	u_int8_t rpc_scheme0;
431 #define RKD_RPC_SCHEME_UNKNOWN		0x00
432 #define RKD_RPC_SCHEME_PHASE_II		0x01
433 	u_int8_t reserved0;
434 	u_int8_t byte4;
435 #define RKD_RPC_TYPE_MASK		0xC0
436 #define RKD_RPC_TYPE_SHIFT		6
437 #define RKD_RPC_TYPE_NONE		0x00
438 #define RKD_RPC_TYPE_SET		0x40
439 #define RKD_RPC_TYPE_LAST_CHANCE	0x80
440 #define RKD_RPC_TYPE_PERM		0xC0
441 #define RKD_RPC_VENDOR_RESET_MASK	0x38
442 #define RKD_RPC_VENDOR_RESET_SHIFT	3
443 #define RKD_RPC_USER_RESET_MASK		0x07
444 #define RKD_RPC_USER_RESET_SHIFT	0
445 	u_int8_t region_mask;
446 	u_int8_t rpc_scheme1;
447 	u_int8_t reserved1;
448 };
449 
450 struct scsi_send_key_data_rpc
451 {
452 	u_int8_t data_len[2];
453 	u_int8_t reserved0[2];
454 	u_int8_t region_code;
455 	u_int8_t reserved1[3];
456 };
457 
458 /*
459  * Common header for the return data from the READ DVD STRUCTURE command.
460  */
461 struct scsi_read_dvd_struct_data_header
462 {
463 	u_int8_t data_len[2];
464 	u_int8_t reserved[2];
465 };
466 
467 struct scsi_read_dvd_struct_data_layer_desc
468 {
469 	u_int8_t book_type_version;
470 #define RDSD_BOOK_TYPE_DVD_ROM	0x00
471 #define RDSD_BOOK_TYPE_DVD_RAM	0x10
472 #define RDSD_BOOK_TYPE_DVD_R	0x20
473 #define RDSD_BOOK_TYPE_DVD_RW	0x30
474 #define RDSD_BOOK_TYPE_DVD_PRW	0x90
475 #define RDSD_BOOK_TYPE_MASK	0xf0
476 #define RDSD_BOOK_TYPE_SHIFT	4
477 #define RDSD_BOOK_VERSION_MASK	0x0f
478 	/*
479 	 * The lower 4 bits of this field is referred to as the "minimum
480 	 * rate" field in MMC2, and the "maximum rate" field in MMC3.  Ugh.
481 	 */
482 	u_int8_t disc_size_max_rate;
483 #define RDSD_DISC_SIZE_120MM	0x00
484 #define RDSD_DISC_SIZE_80MM	0x10
485 #define RDSD_DISC_SIZE_MASK	0xf0
486 #define RDSD_DISC_SIZE_SHIFT	4
487 #define RDSD_MAX_RATE_0252	0x00
488 #define RDSD_MAX_RATE_0504	0x01
489 #define RDSD_MAX_RATE_1008	0x02
490 #define RDSD_MAX_RATE_NOT_SPEC	0x0f
491 #define RDSD_MAX_RATE_MASK	0x0f
492 	u_int8_t layer_info;
493 #define RDSD_NUM_LAYERS_MASK	0x60
494 #define RDSD_NUM_LAYERS_SHIFT	5
495 #define RDSD_NL_ONE_LAYER	0x00
496 #define RDSD_NL_TWO_LAYERS	0x20
497 #define RDSD_TRACK_PATH_MASK	0x10
498 #define RDSD_TRACK_PATH_SHIFT	4
499 #define RDSD_TP_PTP		0x00
500 #define RDSD_TP_OTP		0x10
501 #define RDSD_LAYER_TYPE_RO	0x01
502 #define RDSD_LAYER_TYPE_RECORD	0x02
503 #define RDSD_LAYER_TYPE_RW	0x04
504 #define RDSD_LAYER_TYPE_MASK	0x0f
505 	u_int8_t density;
506 #define RDSD_LIN_DENSITY_0267		0x00
507 #define RDSD_LIN_DENSITY_0293		0x10
508 #define RDSD_LIN_DENSITY_0409_0435	0x20
509 #define RDSD_LIN_DENSITY_0280_0291	0x40
510 /* XXX MMC2 uses 0.176um/bit instead of 0.353 as in MMC3 */
511 #define RDSD_LIN_DENSITY_0353		0x80
512 #define RDSD_LIN_DENSITY_MASK		0xf0
513 #define RDSD_LIN_DENSITY_SHIFT		4
514 #define RDSD_TRACK_DENSITY_074		0x00
515 #define RDSD_TRACK_DENSITY_080		0x01
516 #define RDSD_TRACK_DENSITY_0615		0x02
517 #define RDSD_TRACK_DENSITY_MASK		0x0f
518 	u_int8_t zeros0;
519 	u_int8_t main_data_start[3];
520 #define RDSD_MAIN_DATA_START_DVD_RO	0x30000
521 #define RDSD_MAIN_DATA_START_DVD_RW	0x31000
522 	u_int8_t zeros1;
523 	u_int8_t main_data_end[3];
524 	u_int8_t zeros2;
525 	u_int8_t end_sector_layer0[3];
526 	u_int8_t bca;
527 #define RDSD_BCA	0x80
528 #define RDSD_BCA_MASK	0x80
529 #define RDSD_BCA_SHIFT	7
530 	u_int8_t media_specific[2031];
531 };
532 
533 struct scsi_read_dvd_struct_data_physical
534 {
535 	u_int8_t data_len[2];
536 	u_int8_t reserved[2];
537 	struct scsi_read_dvd_struct_data_layer_desc layer_desc;
538 };
539 
540 struct scsi_read_dvd_struct_data_copyright
541 {
542 	u_int8_t data_len[2];
543 	u_int8_t reserved0[2];
544 	u_int8_t cps_type;
545 #define RDSD_CPS_NOT_PRESENT	0x00
546 #define RDSD_CPS_DATA_EXISTS	0x01
547 	u_int8_t region_info;
548 	u_int8_t reserved1[2];
549 };
550 
551 struct scsi_read_dvd_struct_data_disc_key
552 {
553 	u_int8_t data_len[2];
554 	u_int8_t reserved[2];
555 	u_int8_t disc_key[2048];
556 };
557 
558 struct scsi_read_dvd_struct_data_bca
559 {
560 	u_int8_t data_len[2];
561 	u_int8_t reserved[2];
562 	u_int8_t bca_info[188]; /* XXX 12-188 bytes */
563 };
564 
565 struct scsi_read_dvd_struct_data_manufacturer
566 {
567 	u_int8_t data_len[2];
568 	u_int8_t reserved[2];
569 	u_int8_t manuf_info[2048];
570 };
571 
572 struct scsi_read_dvd_struct_data_copy_manage
573 {
574 	u_int8_t data_len[2];
575 	u_int8_t reserved0[2];
576 	u_int8_t byte4;
577 #define RDSD_CPM_NO_COPYRIGHT	0x00
578 #define RDSD_CPM_HAS_COPYRIGHT	0x80
579 #define RDSD_CPM_MASK		0x80
580 #define RDSD_CMGS_COPY_ALLOWED	0x00
581 #define RDSD_CMGS_ONE_COPY	0x20
582 #define RDSD_CMGS_NO_COPIES	0x30
583 #define RDSD_CMGS_MASK		0x30
584 	u_int8_t reserved1[3];
585 };
586 
587 struct scsi_read_dvd_struct_data_prot_discid
588 {
589 	u_int8_t data_len[2];
590 	u_int8_t reserved[2];
591 	u_int8_t prot_discid_data[16];
592 };
593 
594 struct scsi_read_dvd_struct_data_disc_key_blk
595 {
596 	/*
597 	 * Length is 0x6ffe == 28670 for CPRM, 0x3002 == 12990 for CSS2.
598 	 */
599 	u_int8_t data_len[2];
600 	u_int8_t reserved;
601 	u_int8_t total_packs;
602 	u_int8_t disc_key_pack_data[28668];
603 };
604 struct scsi_read_dvd_struct_data_dds
605 {
606 	u_int8_t data_len[2];
607 	u_int8_t reserved[2];
608 	u_int8_t dds_info[2048];
609 };
610 
611 struct scsi_read_dvd_struct_data_medium_status
612 {
613 	u_int8_t data_len[2];
614 	u_int8_t reserved0[2];
615 	u_int8_t byte4;
616 #define RDSD_MS_CARTRIDGE	0x80
617 #define RDSD_MS_OUT		0x40
618 #define RDSD_MS_MSWI		0x08
619 #define RDSD_MS_CWP		0x04
620 #define RDSD_MS_PWP		0x02
621 	u_int8_t disc_type_id;
622 #define RDSD_DT_NEED_CARTRIDGE	0x00
623 #define RDSD_DT_NO_CART_NEEDED	0x01
624 	u_int8_t reserved1;
625 	u_int8_t ram_swi_info;
626 #define RDSD_SWI_NO_BARE	0x01
627 #define RDSD_SWI_UNSPEC		0xff
628 };
629 
630 struct scsi_read_dvd_struct_data_spare_area
631 {
632 	u_int8_t data_len[2];
633 	u_int8_t reserved[2];
634 	u_int8_t unused_primary[4];
635 	u_int8_t unused_supl[4];
636 	u_int8_t allocated_supl[4];
637 };
638 
639 struct scsi_read_dvd_struct_data_rmd_borderout
640 {
641 	u_int8_t data_len[2];
642 	u_int8_t reserved[2];
643 	u_int8_t rmd[30720]; 	/* maximum is 30720 bytes */
644 };
645 
646 struct scsi_read_dvd_struct_data_rmd
647 {
648 	u_int8_t data_len[2];
649 	u_int8_t reserved[2];
650 	u_int8_t last_sector_num[4];
651 	u_int8_t rmd_bytes[32768];  /* This is the maximum */
652 };
653 
654 /*
655  * XXX KDM this is the MMC2 version of the structure.
656  * The variable positions have changed (in a semi-conflicting way) in the
657  * MMC3 spec, although the overall length of the structure is the same.
658  */
659 struct scsi_read_dvd_struct_data_leadin
660 {
661 	u_int8_t data_len[2];
662 	u_int8_t reserved0[2];
663 	u_int8_t field_id_1;
664 	u_int8_t app_code;
665 	u_int8_t disc_physical_data;
666 	u_int8_t last_addr[3];
667 	u_int8_t reserved1[2];
668 	u_int8_t field_id_2;
669 	u_int8_t rwp;
670 	u_int8_t rwp_wavelength;
671 	u_int8_t optimum_write_strategy;
672 	u_int8_t reserved2[4];
673 	u_int8_t field_id_3;
674 	u_int8_t manuf_id_17_12[6];
675 	u_int8_t reserved3;
676 	u_int8_t field_id_4;
677 	u_int8_t manuf_id_11_6[6];
678 	u_int8_t reserved4;
679 	u_int8_t field_id_5;
680 	u_int8_t manuf_id_5_0[6];
681 	u_int8_t reserved5[25];
682 };
683 
684 struct scsi_read_dvd_struct_data_disc_id
685 {
686 	u_int8_t data_len[2];
687 	u_int8_t reserved[4];
688 	u_int8_t random_num[2];
689 	u_int8_t year[4];
690 	u_int8_t month[2];
691 	u_int8_t day[2];
692 	u_int8_t hour[2];
693 	u_int8_t minute[2];
694 	u_int8_t second[2];
695 };
696 
697 struct scsi_read_dvd_struct_data_generic_dcb
698 {
699 	u_int8_t content_desc[4];
700 #define SCSI_RCB
701 	u_int8_t unknown_desc_actions[4];
702 #define RDSD_ACTION_RECORDING	0x0001
703 #define RDSD_ACTION_READING	0x0002
704 #define RDSD_ACTION_FORMAT	0x0004
705 #define RDSD_ACTION_MODIFY_DCB	0x0008
706 	u_int8_t vendor_id[32];
707 	u_int8_t dcb_data[32728];
708 };
709 
710 struct scsi_read_dvd_struct_data_dcb
711 {
712 	u_int8_t data_len[2];
713 	u_int8_t reserved[2];
714 	struct scsi_read_dvd_struct_data_generic_dcb dcb;
715 };
716 
717 struct read_dvd_struct_write_prot
718 {
719 	u_int8_t data_len[2];
720 	u_int8_t reserved0[2];
721 	u_int8_t write_prot_status;
722 #define RDSD_WPS_MSWI		0x08
723 #define RDSD_WPS_CWP		0x04
724 #define RDSD_WPS_PWP		0x02
725 #define RDSD_WPS_SWPP		0x01
726 	u_int8_t reserved[3];
727 };
728 
729 struct read_dvd_struct_list_entry
730 {
731 	u_int8_t format_code;
732 	u_int8_t sds_rds;
733 #define RDSD_SDS_NOT_WRITEABLE	0x00
734 #define RDSD_SDS_WRITEABLE	0x80
735 #define RDSD_SDS_MASK		0x80
736 #define RDSD_RDS_NOT_READABLE	0x00
737 #define RDSD_RDS_READABLE	0x40
738 #define RDSD_RDS_MASK		0x40
739 	u_int8_t struct_len[2];
740 };
741 
742 struct read_dvd_struct_data_list
743 {
744 	u_int8_t data_len[2];
745 	u_int8_t reserved[2];
746 	struct read_dvd_struct_list_entry entries[0];
747 };
748 
749 struct scsi_read_cd_cap_data
750 {
751 	u_int8_t addr_3;	/* Most significant */
752 	u_int8_t addr_2;
753 	u_int8_t addr_1;
754 	u_int8_t addr_0;	/* Least significant */
755 	u_int8_t length_3;	/* Most significant */
756 	u_int8_t length_2;
757 	u_int8_t length_1;
758 	u_int8_t length_0;	/* Least significant */
759 };
760 
761 struct cd_audio_page
762 {
763 	u_int8_t page_code;
764 #define	CD_PAGE_CODE		0x3F
765 #define	AUDIO_PAGE		0x0e
766 #define	CD_PAGE_PS		0x80
767 	u_int8_t param_len;
768 	u_int8_t flags;
769 #define	CD_PA_SOTC		0x02
770 #define	CD_PA_IMMED		0x04
771 	u_int8_t unused[2];
772 	u_int8_t format_lba;
773 #define	CD_PA_FORMAT_LBA	0x0F
774 #define	CD_PA_APR_VALID		0x80
775 	u_int8_t lb_per_sec[2];
776 	struct	port_control
777 	{
778 		u_int8_t channels;
779 #define	CHANNEL			0x0F
780 #define	CHANNEL_0		1
781 #define	CHANNEL_1		2
782 #define	CHANNEL_2		4
783 #define	CHANNEL_3		8
784 #define	LEFT_CHANNEL		CHANNEL_0
785 #define	RIGHT_CHANNEL		CHANNEL_1
786 		u_int8_t volume;
787 	} port[4];
788 #define	LEFT_PORT		0
789 #define	RIGHT_PORT		1
790 };
791 
792 struct scsi_cddvd_capabilities_page_sd {
793 	uint8_t reserved;
794 	uint8_t rotation_control;
795 	uint8_t write_speed_supported[2];
796 };
797 
798 struct scsi_cddvd_capabilities_page {
799 	uint8_t page_code;
800 #define	SMS_CDDVD_CAPS_PAGE		0x2a
801 	uint8_t page_length;
802 	uint8_t caps1;
803 	uint8_t caps2;
804 	uint8_t caps3;
805 	uint8_t caps4;
806 	uint8_t caps5;
807 	uint8_t caps6;
808 	uint8_t obsolete[2];
809 	uint8_t nvol_levels[2];
810 	uint8_t buffer_size[2];
811 	uint8_t obsolete2[2];
812 	uint8_t reserved;
813 	uint8_t digital;
814 	uint8_t obsolete3;
815 	uint8_t copy_management;
816 	uint8_t reserved2;
817 	uint8_t rotation_control;
818 	uint8_t cur_write_speed;
819 	uint8_t num_speed_descr;
820 	struct scsi_cddvd_capabilities_page_sd speed_descr[];
821 };
822 
823 union cd_pages
824 {
825 	struct cd_audio_page audio;
826 };
827 
828 struct cd_mode_data_10
829 {
830 	struct scsi_mode_header_10 header;
831 	struct scsi_mode_blk_desc  blk_desc;
832 	union cd_pages page;
833 };
834 
835 struct cd_mode_data
836 {
837 	struct scsi_mode_header_6 header;
838 	struct scsi_mode_blk_desc blk_desc;
839 	union cd_pages page;
840 };
841 
842 union cd_mode_data_6_10
843 {
844 	struct cd_mode_data mode_data_6;
845 	struct cd_mode_data_10 mode_data_10;
846 };
847 
848 struct cd_mode_params
849 {
850 	STAILQ_ENTRY(cd_mode_params)	links;
851 	int				cdb_size;
852 	int				alloc_len;
853 	u_int8_t			*mode_buf;
854 };
855 
856 __BEGIN_DECLS
857 void scsi_report_key(struct ccb_scsiio *csio, u_int32_t retries,
858 		     void (*cbfcnp)(struct cam_periph *, union ccb *),
859 		     u_int8_t tag_action, u_int32_t lba, u_int8_t agid,
860 		     u_int8_t key_format, u_int8_t *data_ptr,
861 		     u_int32_t dxfer_len, u_int8_t sense_len,
862 		     u_int32_t timeout);
863 
864 void scsi_send_key(struct ccb_scsiio *csio, u_int32_t retries,
865 		   void (*cbfcnp)(struct cam_periph *, union ccb *),
866 		   u_int8_t tag_action, u_int8_t agid, u_int8_t key_format,
867 		   u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
868 		   u_int32_t timeout);
869 
870 void scsi_read_dvd_structure(struct ccb_scsiio *csio, u_int32_t retries,
871 			     void (*cbfcnp)(struct cam_periph *, union ccb *),
872 			     u_int8_t tag_action, u_int32_t address,
873 			     u_int8_t layer_number, u_int8_t format,
874 			     u_int8_t agid, u_int8_t *data_ptr,
875 			     u_int32_t dxfer_len, u_int8_t sense_len,
876 			     u_int32_t timeout);
877 
878 void scsi_read_toc(struct ccb_scsiio *csio, uint32_t retries,
879 		   void (*cbfcnp)(struct cam_periph *, union ccb *),
880 		   uint8_t tag_action, uint8_t byte1_flags, uint8_t format,
881 		   uint8_t track, uint8_t *data_ptr, uint32_t dxfer_len,
882 		   int sense_len, int timeout);
883 
884 __END_DECLS
885 
886 #endif /*_SCSI_SCSI_CD_H*/
887 
888