xref: /freebsd/sys/cam/scsi/scsi_cd.h (revision 41466b50c1d5bfd1cf6adaae547a579a75d7c04e)
1 /*-
2  * Copyright (c) 2000 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_pause
60 {
61 	u_int8_t op_code;
62 	u_int8_t byte2;
63 	u_int8_t unused[6];
64 	u_int8_t resume;
65 	u_int8_t control;
66 };
67 #define	PA_PAUSE	1
68 #define PA_RESUME	0
69 
70 struct scsi_play_msf
71 {
72 	u_int8_t op_code;
73 	u_int8_t byte2;
74 	u_int8_t unused;
75 	u_int8_t start_m;
76 	u_int8_t start_s;
77 	u_int8_t start_f;
78 	u_int8_t end_m;
79 	u_int8_t end_s;
80 	u_int8_t end_f;
81 	u_int8_t control;
82 };
83 
84 struct scsi_play_track
85 {
86 	u_int8_t op_code;
87 	u_int8_t byte2;
88 	u_int8_t unused[2];
89 	u_int8_t start_track;
90 	u_int8_t start_index;
91 	u_int8_t unused1;
92 	u_int8_t end_track;
93 	u_int8_t end_index;
94 	u_int8_t control;
95 };
96 
97 struct scsi_play_10
98 {
99 	u_int8_t op_code;
100 	u_int8_t byte2;
101 	u_int8_t blk_addr[4];
102 	u_int8_t unused;
103 	u_int8_t xfer_len[2];
104 	u_int8_t control;
105 };
106 
107 struct scsi_play_12
108 {
109 	u_int8_t op_code;
110 	u_int8_t byte2;	/* same as above */
111 	u_int8_t blk_addr[4];
112 	u_int8_t xfer_len[4];
113 	u_int8_t unused;
114 	u_int8_t control;
115 };
116 
117 struct scsi_play_rel_12
118 {
119 	u_int8_t op_code;
120 	u_int8_t byte2;	/* same as above */
121 	u_int8_t blk_addr[4];
122 	u_int8_t xfer_len[4];
123 	u_int8_t track;
124 	u_int8_t control;
125 };
126 
127 struct scsi_read_header
128 {
129 	u_int8_t op_code;
130 	u_int8_t byte2;
131 	u_int8_t blk_addr[4];
132 	u_int8_t unused;
133 	u_int8_t data_len[2];
134 	u_int8_t control;
135 };
136 
137 struct scsi_read_subchannel
138 {
139 	u_int8_t op_code;
140 	u_int8_t byte1;
141 	u_int8_t byte2;
142 #define	SRS_SUBQ	0x40
143 	u_int8_t subchan_format;
144 	u_int8_t unused[2];
145 	u_int8_t track;
146 	u_int8_t data_len[2];
147 	u_int8_t control;
148 };
149 
150 struct scsi_read_toc
151 {
152 	u_int8_t op_code;
153 	u_int8_t byte2;
154 	u_int8_t unused[4];
155 	u_int8_t from_track;
156 	u_int8_t data_len[2];
157 	u_int8_t control;
158 };
159 ;
160 
161 struct scsi_read_cd_capacity
162 {
163 	u_int8_t op_code;
164 	u_int8_t byte2;
165 	u_int8_t addr_3;	/* Most Significant */
166 	u_int8_t addr_2;
167 	u_int8_t addr_1;
168 	u_int8_t addr_0;	/* Least Significant */
169 	u_int8_t unused[3];
170 	u_int8_t control;
171 };
172 
173 struct scsi_report_key
174 {
175 	u_int8_t opcode;
176 	u_int8_t reserved0;
177 	u_int8_t lba[4];
178 	u_int8_t reserved1[2];
179 	u_int8_t alloc_len[2];
180 	u_int8_t agid_keyformat;
181 #define RK_KF_AGID_MASK		0xc0
182 #define RK_KF_AGID_SHIFT	6
183 #define RK_KF_KEYFORMAT_MASK	0x3f
184 #define RK_KF_AGID		0x00
185 #define RK_KF_CHALLENGE		0x01
186 #define RF_KF_KEY1		0x02
187 #define RK_KF_KEY2		0x03
188 #define RF_KF_TITLE		0x04
189 #define RF_KF_ASF		0x05
190 #define RK_KF_RPC_SET		0x06
191 #define RF_KF_RPC_REPORT	0x08
192 #define RF_KF_INV_AGID		0x3f
193 	u_int8_t control;
194 };
195 
196 /*
197  * See the report key structure for key format and AGID definitions.
198  */
199 struct scsi_send_key
200 {
201 	u_int8_t opcode;
202 	u_int8_t reserved[7];
203 	u_int8_t param_len[2];
204 	u_int8_t agid_keyformat;
205 	u_int8_t control;
206 };
207 
208 struct scsi_read_dvd_structure
209 {
210 	u_int8_t opcode;
211 	u_int8_t reserved;
212 	u_int8_t address[4];
213 	u_int8_t layer_number;
214 	u_int8_t format;
215 #define RDS_FORMAT_PHYSICAL		0x00
216 #define RDS_FORMAT_COPYRIGHT		0x01
217 #define RDS_FORMAT_DISC_KEY		0x02
218 #define RDS_FORMAT_BCA			0x03
219 #define RDS_FORMAT_MANUFACTURER		0x04
220 #define RDS_FORMAT_CMGS_CPM		0x05
221 #define RDS_FORMAT_PROT_DISCID		0x06
222 #define RDS_FORMAT_DISC_KEY_BLOCK	0x07
223 #define RDS_FORMAT_DDS			0x08
224 #define RDS_FORMAT_DVDRAM_MEDIA_STAT	0x09
225 #define RDS_FORMAT_SPARE_AREA		0x0a
226 #define RDS_FORMAT_RMD_BORDEROUT	0x0c
227 #define RDS_FORMAT_RMD			0x0d
228 #define RDS_FORMAT_LEADIN		0x0e
229 #define RDS_FORMAT_DISC_ID		0x0f
230 #define RDS_FORMAT_DCB			0x30
231 #define RDS_FORMAT_WRITE_PROT		0xc0
232 #define RDS_FORMAT_STRUCTURE_LIST	0xff
233 	u_int8_t alloc_len[2];
234 	u_int8_t agid;
235 	u_int8_t control;
236 };
237 
238 /*
239  * Opcodes
240  */
241 #define READ_CD_CAPACITY	0x25	/* slightly different from disk */
242 #define READ_SUBCHANNEL		0x42	/* cdrom read Subchannel */
243 #define READ_TOC		0x43	/* cdrom read TOC */
244 #define READ_HEADER		0x44	/* cdrom read header */
245 #define PLAY_10			0x45	/* cdrom play  'play audio' mode */
246 #define PLAY_MSF		0x47	/* cdrom play Min,Sec,Frames mode */
247 #define PLAY_TRACK		0x48	/* cdrom play track/index mode */
248 #define PLAY_TRACK_REL		0x49	/* cdrom play track/index mode */
249 #define PAUSE			0x4b	/* cdrom pause in 'play audio' mode */
250 #define SEND_KEY		0xa3	/* dvd send key command */
251 #define REPORT_KEY		0xa4	/* dvd report key command */
252 #define PLAY_12			0xa5	/* cdrom pause in 'play audio' mode */
253 #define PLAY_TRACK_REL_BIG	0xa9	/* cdrom play track/index mode */
254 #define READ_DVD_STRUCTURE	0xad	/* read dvd structure */
255 
256 struct scsi_report_key_data_header
257 {
258 	u_int8_t data_len[2];
259 	u_int8_t reserved[2];
260 };
261 
262 struct scsi_report_key_data_agid
263 {
264 	u_int8_t data_len[2];
265 	u_int8_t reserved[5];
266 	u_int8_t agid;
267 #define RKD_AGID_MASK	0xc0
268 #define RKD_AGID_SHIFT	6
269 };
270 
271 struct scsi_report_key_data_challenge
272 {
273 	u_int8_t data_len[2];
274 	u_int8_t reserved0[2];
275 	u_int8_t challenge_key[10];
276 	u_int8_t reserved1[2];
277 };
278 
279 struct scsi_report_key_data_key1_key2
280 {
281 	u_int8_t data_len[2];
282 	u_int8_t reserved0[2];
283 	u_int8_t key1[5];
284 	u_int8_t reserved1[3];
285 };
286 
287 struct scsi_report_key_data_title
288 {
289 	u_int8_t data_len[2];
290 	u_int8_t reserved0[2];
291 	u_int8_t byte0;
292 #define RKD_TITLE_CPM		0x80
293 #define RKD_TITLE_CPM_SHIFT	7
294 #define RKD_TITLE_CP_SEC	0x40
295 #define RKD_TITLE_CP_SEC_SHIFT	6
296 #define RKD_TITLE_CMGS_MASK	0x30
297 #define RKD_TITLE_CMGS_SHIFT	4
298 #define RKD_TITLE_CMGS_NO_RST	0x00
299 #define RKD_TITLE_CMGS_RSVD	0x10
300 #define RKD_TITLE_CMGS_1_GEN	0x20
301 #define RKD_TITLE_CMGS_NO_COPY	0x30
302 	u_int8_t title_key[5];
303 	u_int8_t reserved1[2];
304 };
305 
306 struct scsi_report_key_data_asf
307 {
308 	u_int8_t data_len[2];
309 	u_int8_t reserved[5];
310 	u_int8_t success;
311 #define RKD_ASF_SUCCESS	0x01
312 };
313 
314 struct scsi_report_key_data_rpc
315 {
316 	u_int8_t data_len[2];
317 	u_int8_t rpc_scheme0;
318 #define RKD_RPC_SCHEME_UNKNOWN		0x00
319 #define RKD_RPC_SCHEME_PHASE_II		0x01
320 	u_int8_t reserved0;
321 	u_int8_t byte4;
322 #define RKD_RPC_TYPE_MASK		0xC0
323 #define RKD_RPC_TYPE_SHIFT		6
324 #define RKD_RPC_TYPE_NONE		0x00
325 #define RKD_RPC_TYPE_SET		0x40
326 #define RKD_RPC_TYPE_LAST_CHANCE	0x80
327 #define RKD_RPC_TYPE_PERM		0xC0
328 #define RKD_RPC_VENDOR_RESET_MASK	0x38
329 #define RKD_RPC_VENDOR_RESET_SHIFT	3
330 #define RKD_RPC_USER_RESET_MASK		0x07
331 #define RKD_RPC_USER_RESET_SHIFT	0
332 	u_int8_t region_mask;
333 	u_int8_t rpc_scheme1;
334 	u_int8_t reserved1;
335 };
336 
337 struct scsi_send_key_data_rpc
338 {
339 	u_int8_t data_len[2];
340 	u_int8_t reserved0[2];
341 	u_int8_t region_code;
342 	u_int8_t reserved1[3];
343 };
344 
345 /*
346  * Common header for the return data from the READ DVD STRUCTURE command.
347  */
348 struct scsi_read_dvd_struct_data_header
349 {
350 	u_int8_t data_len[2];
351 	u_int8_t reserved[2];
352 };
353 
354 struct scsi_read_dvd_struct_data_layer_desc
355 {
356 	u_int8_t book_type_version;
357 #define RDSD_BOOK_TYPE_DVD_ROM	0x00
358 #define RDSD_BOOK_TYPE_DVD_RAM	0x10
359 #define RDSD_BOOK_TYPE_DVD_R	0x20
360 #define RDSD_BOOK_TYPE_DVD_RW	0x30
361 #define RDSD_BOOK_TYPE_DVD_PRW	0x90
362 #define RDSD_BOOK_TYPE_MASK	0xf0
363 #define RDSD_BOOK_TYPE_SHIFT	4
364 #define RDSD_BOOK_VERSION_MASK	0x0f
365 	/*
366 	 * The lower 4 bits of this field is referred to as the "minimum
367 	 * rate" field in MMC2, and the "maximum rate" field in MMC3.  Ugh.
368 	 */
369 	u_int8_t disc_size_max_rate;
370 #define RDSD_DISC_SIZE_120MM	0x00
371 #define RDSD_DISC_SIZE_80MM	0x10
372 #define RDSD_DISC_SIZE_MASK	0xf0
373 #define RDSD_DISC_SIZE_SHIFT	4
374 #define RDSD_MAX_RATE_0252	0x00
375 #define RDSD_MAX_RATE_0504	0x01
376 #define RDSD_MAX_RATE_1008	0x02
377 #define RDSD_MAX_RATE_NOT_SPEC	0x0f
378 #define RDSD_MAX_RATE_MASK	0x0f
379 	u_int8_t layer_info;
380 #define RDSD_NUM_LAYERS_MASK	0x60
381 #define RDSD_NUM_LAYERS_SHIFT	5
382 #define RDSD_NL_ONE_LAYER	0x00
383 #define RDSD_NL_TWO_LAYERS	0x20
384 #define RDSD_TRACK_PATH_MASK	0x10
385 #define RDSD_TRACK_PATH_SHIFT	4
386 #define RDSD_TP_PTP		0x00
387 #define RDSD_TP_OTP		0x10
388 #define RDSD_LAYER_TYPE_RO	0x01
389 #define RDSD_LAYER_TYPE_RECORD	0x02
390 #define RDSD_LAYER_TYPE_RW	0x04
391 #define RDSD_LAYER_TYPE_MASK	0x0f
392 	u_int8_t density;
393 #define RDSD_LIN_DENSITY_0267		0x00
394 #define RDSD_LIN_DENSITY_0293		0x10
395 #define RDSD_LIN_DENSITY_0409_0435	0x20
396 #define RDSD_LIN_DENSITY_0280_0291	0x40
397 /* XXX MMC2 uses 0.176um/bit instead of 0.353 as in MMC3 */
398 #define RDSD_LIN_DENSITY_0353		0x80
399 #define RDSD_LIN_DENSITY_MASK		0xf0
400 #define RDSD_LIN_DENSITY_SHIFT		4
401 #define RDSD_TRACK_DENSITY_074		0x00
402 #define RDSD_TRACK_DENSITY_080		0x01
403 #define RDSD_TRACK_DENSITY_0615		0x02
404 #define RDSD_TRACK_DENSITY_MASK		0x0f
405 	u_int8_t zeros0;
406 	u_int8_t main_data_start[3];
407 #define RDSD_MAIN_DATA_START_DVD_RO	0x30000
408 #define RDSD_MAIN_DATA_START_DVD_RW	0x31000
409 	u_int8_t zeros1;
410 	u_int8_t main_data_end[3];
411 	u_int8_t zeros2;
412 	u_int8_t end_sector_layer0[3];
413 	u_int8_t bca;
414 #define RDSD_BCA	0x80
415 #define RDSD_BCA_MASK	0x80
416 #define RDSD_BCA_SHIFT	7
417 	u_int8_t media_specific[2031];
418 };
419 
420 struct scsi_read_dvd_struct_data_physical
421 {
422 	u_int8_t data_len[2];
423 	u_int8_t reserved[2];
424 	struct scsi_read_dvd_struct_data_layer_desc layer_desc;
425 };
426 
427 struct scsi_read_dvd_struct_data_copyright
428 {
429 	u_int8_t data_len[2];
430 	u_int8_t reserved0[2];
431 	u_int8_t cps_type;
432 #define RDSD_CPS_NOT_PRESENT	0x00
433 #define RDSD_CPS_DATA_EXISTS	0x01
434 	u_int8_t region_info;
435 	u_int8_t reserved1[2];
436 };
437 
438 struct scsi_read_dvd_struct_data_disc_key
439 {
440 	u_int8_t data_len[2];
441 	u_int8_t reserved[2];
442 	u_int8_t disc_key[2048];
443 };
444 
445 struct scsi_read_dvd_struct_data_bca
446 {
447 	u_int8_t data_len[2];
448 	u_int8_t reserved[2];
449 	u_int8_t bca_info[188]; /* XXX 12-188 bytes */
450 };
451 
452 struct scsi_read_dvd_struct_data_manufacturer
453 {
454 	u_int8_t data_len[2];
455 	u_int8_t reserved[2];
456 	u_int8_t manuf_info[2048];
457 };
458 
459 struct scsi_read_dvd_struct_data_copy_manage
460 {
461 	u_int8_t data_len[2];
462 	u_int8_t reserved0[2];
463 	u_int8_t byte4;
464 #define RDSD_CPM_NO_COPYRIGHT	0x00
465 #define RDSD_CPM_HAS_COPYRIGHT	0x80
466 #define RDSD_CPM_MASK		0x80
467 #define RDSD_CMGS_COPY_ALLOWED	0x00
468 #define RDSD_CMGS_ONE_COPY	0x20
469 #define RDSD_CMGS_NO_COPIES	0x30
470 #define RDSD_CMGS_MASK		0x30
471 	u_int8_t reserved1[3];
472 };
473 
474 struct scsi_read_dvd_struct_data_prot_discid
475 {
476 	u_int8_t data_len[2];
477 	u_int8_t reserved[2];
478 	u_int8_t prot_discid_data[16];
479 };
480 
481 struct scsi_read_dvd_struct_data_disc_key_blk
482 {
483 	/*
484 	 * Length is 0x6ffe == 28670 for CPRM, 0x3002 == 12990 for CSS2.
485 	 */
486 	u_int8_t data_len[2];
487 	u_int8_t reserved;
488 	u_int8_t total_packs;
489 	u_int8_t disc_key_pack_data[28668];
490 };
491 struct scsi_read_dvd_struct_data_dds
492 {
493 	u_int8_t data_len[2];
494 	u_int8_t reserved[2];
495 	u_int8_t dds_info[2048];
496 };
497 
498 struct scsi_read_dvd_struct_data_medium_status
499 {
500 	u_int8_t data_len[2];
501 	u_int8_t reserved0[2];
502 	u_int8_t byte4;
503 #define RDSD_MS_CARTRIDGE	0x80
504 #define RDSD_MS_OUT		0x40
505 #define RDSD_MS_MSWI		0x08
506 #define RDSD_MS_CWP		0x04
507 #define RDSD_MS_PWP		0x02
508 	u_int8_t disc_type_id;
509 #define RDSD_DT_NEED_CARTRIDGE	0x00
510 #define RDSD_DT_NO_CART_NEEDED	0x01
511 	u_int8_t reserved1;
512 	u_int8_t ram_swi_info;
513 #define RDSD_SWI_NO_BARE	0x01
514 #define RDSD_SWI_UNSPEC		0xff
515 };
516 
517 struct scsi_read_dvd_struct_data_spare_area
518 {
519 	u_int8_t data_len[2];
520 	u_int8_t reserved[2];
521 	u_int8_t unused_primary[4];
522 	u_int8_t unused_supl[4];
523 	u_int8_t allocated_supl[4];
524 };
525 
526 struct scsi_read_dvd_struct_data_rmd_borderout
527 {
528 	u_int8_t data_len[2];
529 	u_int8_t reserved[2];
530 	u_int8_t rmd[30720]; 	/* maximum is 30720 bytes */
531 };
532 
533 struct scsi_read_dvd_struct_data_rmd
534 {
535 	u_int8_t data_len[2];
536 	u_int8_t reserved[2];
537 	u_int8_t last_sector_num[4];
538 	u_int8_t rmd_bytes[32768];  /* This is the maximum */
539 };
540 
541 /*
542  * XXX KDM this is the MMC2 version of the structure.
543  * The variable positions have changed (in a semi-conflicting way) in the
544  * MMC3 spec, although the overall length of the structure is the same.
545  */
546 struct scsi_read_dvd_struct_data_leadin
547 {
548 	u_int8_t data_len[2];
549 	u_int8_t reserved0[2];
550 	u_int8_t field_id_1;
551 	u_int8_t app_code;
552 	u_int8_t disc_physical_data;
553 	u_int8_t last_addr[3];
554 	u_int8_t reserved1[2];
555 	u_int8_t field_id_2;
556 	u_int8_t rwp;
557 	u_int8_t rwp_wavelength;
558 	u_int8_t optimum_write_strategy;
559 	u_int8_t reserved2[4];
560 	u_int8_t field_id_3;
561 	u_int8_t manuf_id_17_12[6];
562 	u_int8_t reserved3;
563 	u_int8_t field_id_4;
564 	u_int8_t manuf_id_11_6[6];
565 	u_int8_t reserved4;
566 	u_int8_t field_id_5;
567 	u_int8_t manuf_id_5_0[6];
568 	u_int8_t reserved5[25];
569 };
570 
571 struct scsi_read_dvd_struct_data_disc_id
572 {
573 	u_int8_t data_len[2];
574 	u_int8_t reserved[4];
575 	u_int8_t random_num[2];
576 	u_int8_t year[4];
577 	u_int8_t month[2];
578 	u_int8_t day[2];
579 	u_int8_t hour[2];
580 	u_int8_t minute[2];
581 	u_int8_t second[2];
582 };
583 
584 struct scsi_read_dvd_struct_data_generic_dcb
585 {
586 	u_int8_t content_desc[4];
587 #define SCSI_RCB
588 	u_int8_t unknown_desc_actions[4];
589 #define RDSD_ACTION_RECORDING	0x0001
590 #define RDSD_ACTION_READING	0x0002
591 #define RDSD_ACTION_FORMAT	0x0004
592 #define RDSD_ACTION_MODIFY_DCB	0x0008
593 	u_int8_t vendor_id[32];
594 	u_int8_t dcb_data[32728];
595 };
596 
597 struct scsi_read_dvd_struct_data_dcb
598 {
599 	u_int8_t data_len[2];
600 	u_int8_t reserved[2];
601 	struct scsi_read_dvd_struct_data_generic_dcb dcb;
602 };
603 
604 struct read_dvd_struct_write_prot
605 {
606 	u_int8_t data_len[2];
607 	u_int8_t reserved0[2];
608 	u_int8_t write_prot_status;
609 #define RDSD_WPS_MSWI		0x08
610 #define RDSD_WPS_CWP		0x04
611 #define RDSD_WPS_PWP		0x02
612 #define RDSD_WPS_SWPP		0x01
613 	u_int8_t reserved[3];
614 };
615 
616 struct read_dvd_struct_list_entry
617 {
618 	u_int8_t format_code;
619 	u_int8_t sds_rds;
620 #define RDSD_SDS_NOT_WRITEABLE	0x00
621 #define RDSD_SDS_WRITEABLE	0x80
622 #define RDSD_SDS_MASK		0x80
623 #define RDSD_RDS_NOT_READABLE	0x00
624 #define RDSD_RDS_READABLE	0x40
625 #define RDSD_RDS_MASK		0x40
626 	u_int8_t struct_len[2];
627 };
628 
629 struct read_dvd_struct_data_list
630 {
631 	u_int8_t data_len[2];
632 	u_int8_t reserved[2];
633 	struct read_dvd_struct_list_entry entries[0];
634 };
635 
636 struct scsi_read_cd_cap_data
637 {
638 	u_int8_t addr_3;	/* Most significant */
639 	u_int8_t addr_2;
640 	u_int8_t addr_1;
641 	u_int8_t addr_0;	/* Least significant */
642 	u_int8_t length_3;	/* Most significant */
643 	u_int8_t length_2;
644 	u_int8_t length_1;
645 	u_int8_t length_0;	/* Least significant */
646 };
647 
648 union	cd_pages
649 {
650 	struct	audio_page
651 	{
652 		u_int8_t page_code;
653 #define	CD_PAGE_CODE	0x3F
654 #define	AUDIO_PAGE	0x0e
655 #define	CD_PAGE_PS	0x80
656 		u_int8_t param_len;
657 		u_int8_t flags;
658 #define		CD_PA_SOTC	0x02
659 #define		CD_PA_IMMED	0x04
660 		u_int8_t unused[2];
661 		u_int8_t format_lba;
662 #define		CD_PA_FORMAT_LBA	0x0F
663 #define		CD_PA_APR_VALID	0x80
664 		u_int8_t lb_per_sec[2];
665 		struct	port_control
666 		{
667 			u_int8_t channels;
668 #define	CHANNEL 0x0F
669 #define	CHANNEL_0 1
670 #define	CHANNEL_1 2
671 #define	CHANNEL_2 4
672 #define	CHANNEL_3 8
673 #define	LEFT_CHANNEL	CHANNEL_0
674 #define	RIGHT_CHANNEL	CHANNEL_1
675 			u_int8_t volume;
676 		} port[4];
677 #define	LEFT_PORT	0
678 #define	RIGHT_PORT	1
679 	}audio;
680 };
681 
682 struct cd_mode_data
683 {
684 	struct scsi_mode_header_6 header;
685 	struct scsi_mode_blk_desc blk_desc;
686 	union cd_pages page;
687 };
688 
689 __BEGIN_DECLS
690 void scsi_report_key(struct ccb_scsiio *csio, u_int32_t retries,
691 		     void (*cbfcnp)(struct cam_periph *, union ccb *),
692 		     u_int8_t tag_action, u_int32_t lba, u_int8_t agid,
693 		     u_int8_t key_format, u_int8_t *data_ptr,
694 		     u_int32_t dxfer_len, u_int8_t sense_len,
695 		     u_int32_t timeout);
696 
697 void scsi_send_key(struct ccb_scsiio *csio, u_int32_t retries,
698 		   void (*cbfcnp)(struct cam_periph *, union ccb *),
699 		   u_int8_t tag_action, u_int8_t agid, u_int8_t key_format,
700 		   u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
701 		   u_int32_t timeout);
702 
703 void scsi_read_dvd_structure(struct ccb_scsiio *csio, u_int32_t retries,
704 			     void (*cbfcnp)(struct cam_periph *, union ccb *),
705 			     u_int8_t tag_action, u_int32_t address,
706 			     u_int8_t layer_number, u_int8_t format,
707 			     u_int8_t agid, u_int8_t *data_ptr,
708 			     u_int32_t dxfer_len, u_int8_t sense_len,
709 			     u_int32_t timeout);
710 
711 __END_DECLS
712 
713 #endif /*_SCSI_SCSI_CD_H*/
714 
715