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: stable/11/sys/cam/scsi/scsi_cd.h 352715 2019-09-25 19:46:52Z avg $
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_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
73struct scsi_get_config_header
74{
75	uint8_t data_length[4];
76	uint8_t reserved[2];
77	uint8_t current_profile[2];
78};
79
80struct 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
92struct 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
104struct 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
112struct scsi_get_event_status_descr
113{
114	uint8_t event_code;
115	uint8_t event_info[];
116};
117
118struct 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
127struct 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
136struct 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
147struct 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
161struct 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
174struct 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
184struct 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
194struct 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
204struct 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
214struct 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
227struct 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
244struct scsi_read_toc_hdr
245{
246	uint8_t data_length[2];
247	uint8_t first;
248	uint8_t last;
249};
250
251struct 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
260struct 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
272struct 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
282struct 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 */
308struct 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
317struct 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
369struct scsi_report_key_data_header
370{
371	u_int8_t data_len[2];
372	u_int8_t reserved[2];
373};
374
375struct 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
384struct 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
392struct 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
400struct 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
419struct 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
427struct 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
450struct 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 */
461struct scsi_read_dvd_struct_data_header
462{
463	u_int8_t data_len[2];
464	u_int8_t reserved[2];
465};
466
467struct 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
533struct 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
540struct 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
551struct 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
558struct 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
565struct 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
572struct 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
587struct 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
594struct 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};
604struct 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
611struct 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
630struct 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
639struct 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
646struct 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 */
659struct 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
684struct 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
697struct 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
710struct 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
717struct 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
729struct 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
742struct 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
749struct 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
761struct 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
792struct scsi_cddvd_capabilities_page_sd {
793	uint8_t reserved;
794	uint8_t rotation_control;
795	uint8_t write_speed_supported[2];
796};
797
798struct 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
823union cd_pages
824{
825	struct cd_audio_page audio;
826};
827
828struct 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
835struct 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
842union 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
848struct 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
857void 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
864void 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
870void 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
878void 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