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