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