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