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
60struct 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
74struct scsi_get_config_header
75{
76	uint8_t data_length[4];
77	uint8_t reserved[2];
78	uint8_t current_profile[2];
79};
80
81struct 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
93struct 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
105struct 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
113struct scsi_get_event_status_descr
114{
115	uint8_t event_code;
116	uint8_t event_info[];
117};
118
119struct 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
128struct 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
137struct 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
148struct 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
162struct 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
175struct 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
185struct 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
195struct 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
205struct 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
215struct 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
228struct 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
245struct scsi_read_toc_hdr
246{
247	uint8_t data_length[2];
248	uint8_t first;
249	uint8_t last;
250};
251
252struct 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
261struct 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
273struct 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
283struct 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 */
309struct 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
318struct 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
370struct scsi_report_key_data_header
371{
372	uint8_t data_len[2];
373	uint8_t reserved[2];
374};
375
376struct 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
385struct 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
393struct 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
401struct 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
420struct 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
428struct 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
451struct 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 */
462struct scsi_read_dvd_struct_data_header
463{
464	uint8_t data_len[2];
465	uint8_t reserved[2];
466};
467
468struct 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
534struct 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
541struct 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
552struct 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
559struct 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
566struct 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
573struct 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
588struct 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
595struct 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};
605struct 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
612struct 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
631struct 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
640struct 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
647struct 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 */
660struct 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
685struct 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
698struct 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
711struct 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
718struct 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
730struct 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
743struct 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
750struct 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
762struct 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
793struct scsi_cddvd_capabilities_page_sd {
794	uint8_t reserved;
795	uint8_t rotation_control;
796	uint8_t write_speed_supported[2];
797};
798
799struct 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
824union cd_pages
825{
826	struct cd_audio_page audio;
827};
828
829struct 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
836struct 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
843union 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
849struct 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
858void 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
865void 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
871void 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
879void 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