1 /*
2 
3     SPDX-FileCopyrightText: 2003-2009 Sebastian Trueg <trueg@k3b.org>
4     SPDX-FileCopyrightText: 1998-2009 Sebastian Trueg <trueg@k3b.org>
5 
6     SPDX-License-Identifier: GPL-2.0-or-later
7 */
8 
9 
10 #ifndef _K3B_MMC_H_
11 #define _K3B_MMC_H_
12 
13 #include <config-k3b.h>
14 
15 
16 namespace K3b {
17     namespace Device
18     {
19         /*
20          * struct disc_info taken from cdrwtool.h
21          *
22          *
23          * disc status (status):
24          *     00b - empty disc
25          *     01b - incomplete disc (appendable)
26          *     10b - Complete disc
27          *     11b - Others
28          *
29          * State of last session (border)
30          *     00b - Empty session
31          *     01b - Incomplete session
32          *     10b - Reserved
33          *     11b - Complete session (only possible when disc status is complete)
34          */
35         typedef struct disc_info {
36             quint16 length;
37 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
38             unsigned char reserved1 : 3;
39             unsigned char erasable  : 1;
40             unsigned char border    : 2;
41             unsigned char status    : 2;
42 #else
43             unsigned char status    : 2;
44             unsigned char border    : 2;
45             unsigned char erasable  : 1;
46             unsigned char reserved1 : 3;
47 #endif
48             unsigned char n_first_track;
49             unsigned char n_sessions_l;
50             unsigned char first_track_l;
51             unsigned char last_track_l;
52 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
53             unsigned char did_v     : 1;
54             unsigned char dbc_v     : 1;
55             unsigned char uru       : 1;
56             unsigned char reserved2 : 2;
57             unsigned char dbit      : 1;
58             unsigned char bg_f_status : 1;
59 #else
60             unsigned char bg_f_status : 1;
61             unsigned char dbit      : 1;
62             unsigned char reserved2 : 2;
63             unsigned char uru       : 1;
64             unsigned char dbc_v     : 1;
65             unsigned char did_v     : 1;
66 #endif
67 
68             /*
69              * disc type
70              *    00h - CD-DA of CDROM
71              *    10h - CD-I
72              *    20h - CD-ROM XA
73              *    FFh - Undefined
74              *    All other values are reserved
75              */
76             unsigned char disc_type;
77             unsigned char n_sessions_m;
78             unsigned char first_track_m;
79             unsigned char last_track_m;
80             quint32 disc_id;
81 
82             /*
83              * Last session lead-in start time
84              * if the disc is complete this shall be FF/FF/FF
85              */
86             unsigned char lead_in_r;
87             unsigned char lead_in_m;
88             unsigned char lead_in_s;
89             unsigned char lead_in_f;
90 
91             /*
92              * Last possible start time for start of lead-in
93              * if the disc is complete this shall be FF/FF/FF
94              */
95             unsigned char lead_out_r;
96             unsigned char lead_out_m;
97             unsigned char lead_out_s;
98             unsigned char lead_out_f;
99 
100             unsigned char disc_bar_code[8];
101 
102             //
103             // We need to make sure the structure has a proper size
104             // I think it needs to be a power of 2.
105             // With ide-scsi there is no problem. But without the
106             // GPCMD_READ_DISC_INFO command failes if the size is 34
107             //
108 
109 /*     unsigned char reserved3; */
110 /*     unsigned char opc_entries; */
111         } disc_info_t;
112 
113 
114 
115         /*
116          * struct track_info taken from cdrwtool.h
117          */
118         typedef struct track_info {
119             unsigned char data_length[2];
120             unsigned char track_number_l;
121             unsigned char session_number_l;
122             unsigned char reserved1;
123 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
124             unsigned char reserved2       : 2;
125             unsigned char damage          : 1;
126             unsigned char copy            : 1;
127             unsigned char track_mode      : 4;
128             unsigned char rt              : 1;
129             unsigned char blank           : 1;
130             unsigned char packet          : 1;
131             unsigned char fp              : 1;
132             unsigned char data_mode       : 4;
133             unsigned char reserved3       : 6;
134             unsigned char lra_v           : 1;
135             unsigned char nwa_v           : 1;
136 #else
137             unsigned char track_mode      : 4;
138             unsigned char copy            : 1;
139             unsigned char damage          : 1;
140             unsigned char reserved2       : 2;
141             unsigned char data_mode       : 4;
142             unsigned char fp              : 1;
143             unsigned char packet          : 1;
144             unsigned char blank           : 1;
145             unsigned char rt              : 1;
146             unsigned char nwa_v           : 1;
147             unsigned char lra_v           : 1;
148             unsigned char reserved3       : 6;
149 #endif
150             unsigned char track_start[4];
151             unsigned char next_writable[4];
152             unsigned char free_blocks[4];
153             unsigned char packet_size[4];
154             unsigned char track_size[4];
155             unsigned char last_recorded[4];
156             unsigned char track_number_m;
157             unsigned char session_number_m;
158             unsigned char reserved4;
159             unsigned char reserved5;
160             unsigned char read_compatibility[4];
161         } track_info_t;
162 
163 
164         /*
165          * Use this with the GPCMD_READ_TOC_PMA_ATIP command
166          * where format is set to 2 (Full TOC)
167          */
168         struct toc_raw_track_descriptor {
169             unsigned char session_number;
170 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
171             unsigned char adr     : 4;
172             unsigned char control : 4;
173 #else
174             unsigned char control : 4;
175             unsigned char adr     : 4;
176 #endif
177             unsigned char tno;
178             unsigned char point;
179             unsigned char min;
180             unsigned char sec;
181             unsigned char frame;
182             unsigned char zero;
183             unsigned char p_min;
184             unsigned char p_sec;
185             unsigned char p_frame;
186         };
187 
188 
189 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
190         struct cd_wr_speed_performance {
191             unsigned char res0;                   /* Reserved                          */
192             unsigned char res_1_27        : 6;    /* Reserved                          */
193             unsigned char rot_ctl_sel     : 2;    /* Rotational control selected       */
194             unsigned char wr_speed_supp[2];       /* Supported write speed             */
195         };
196 #else
197         struct cd_wr_speed_performance {
198             unsigned char res0;                   /* Reserved                          */
199             unsigned char rot_ctl_sel     : 2;    /* Rotational control selected       */
200             unsigned char res_1_27        : 6;    /* Reserved                          */
201             unsigned char wr_speed_supp[2];       /* Supported write speed             */
202         };
203 #endif
204 
205 
206         /**
207          * Based on the cdrecord struct cd_mode_page_2A
208          * MM Capabilities and Mechanical Status Page
209          */
210 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
211 
212         struct mm_cap_page_2A {
213             unsigned char PS               : 1;
214             unsigned char res_1            : 1;
215             unsigned char page_code        : 6;
216             unsigned char page_len;             /* 0x14 = 20 Bytes (MMC) */
217             /* 0x18 = 24 Bytes (MMC-2) */
218             /* 0x1C >= 28 Bytes (MMC-3) */
219             unsigned char res_2_67         : 2; /* Reserved        */
220             unsigned char dvd_ram_read     : 1; /* Reads DVD-RAM media       */
221             unsigned char dvd_r_read       : 1; /* Reads DVD-R media       */
222             unsigned char dvd_rom_read     : 1; /* Reads DVD ROM media       */
223             unsigned char method2          : 1; /* Reads fixed packet method2 media  */
224             unsigned char cd_rw_read       : 1; /* Reads CD-RW media       */
225             unsigned char cd_r_read        : 1; /* Reads CD-R  media       */
226             unsigned char res_3_67         : 2; /* Reserved        */
227             unsigned char dvd_ram_write    : 1; /* Supports writing DVD-RAM media    */
228             unsigned char dvd_r_write      : 1; /* Supports writing DVD-R media      */
229             unsigned char res_3_3          : 1; /* Reserved        */
230             unsigned char test_write       : 1; /* Supports emulation write      */
231             unsigned char cd_rw_write      : 1; /* Supports writing CD-RW media      */
232             unsigned char cd_r_write       : 1; /* Supports writing CD-R  media      */
233             unsigned char BUF              : 1; /* Supports Buffer under. free rec.  */
234             unsigned char multi_session    : 1; /* Reads multi-session media      */
235             unsigned char mode_2_form_2    : 1; /* Reads Mode-2 form 2 media      */
236             unsigned char mode_2_form_1    : 1; /* Reads Mode-2 form 1 media (XA)    */
237             unsigned char digital_port_1   : 1; /* Supports digital output on port 1 */
238             unsigned char digital_port_2   : 1; /* Supports digital output on port 2 */
239             unsigned char composite        : 1; /* Deliveres composite A/V stream    */
240             unsigned char audio_play       : 1; /* Supports Audio play operation     */
241             unsigned char read_bar_code    : 1; /* Supports reading bar codes      */
242             unsigned char UPC              : 1; /* Reads media catalog number (UPC)  */
243             unsigned char ISRC             : 1; /* Reads ISRC information      */
244             unsigned char c2_pointers      : 1; /* Supports C2 error pointers      */
245             unsigned char rw_deint_corr    : 1; /* Reads de-interleved R-W sub chan  */
246             unsigned char rw_supported     : 1; /* Reads R-W sub channel information */
247             unsigned char cd_da_accurate   : 1; /* READ CD data stream is accurate   */
248             unsigned char cd_da_supported  : 1; /* Reads audio data with READ CD cmd */
249             unsigned char loading_type     : 3; /* Loading mechanism type      */
250             unsigned char res_6_4          : 1; /* Reserved        */
251             unsigned char eject            : 1; /* Ejects disc/cartr with STOP LoEj  */
252             unsigned char prevent_jumper   : 1; /* State of prev/allow jumper 0=pres */
253             unsigned char lock_state       : 1; /* Lock state 0=unlocked 1=locked    */
254             unsigned char lock             : 1; /* PREVENT/ALLOW may lock media      */
255             unsigned char res_7            : 2; /* Reserved        */
256             unsigned char rw_in_lead_in    : 1; /* Reads raw R-W subcode from lead in */
257             unsigned char side_change      : 1; /* Side change capable       */
258             unsigned char sw_slot_sel      : 1; /* Load empty slot in changer      */
259             unsigned char disk_present_rep : 1; /* Changer supports disk present rep */
260             unsigned char sep_chan_mute    : 1; /* Mute controls each channel separately */
261             unsigned char sep_chan_vol     : 1; /* Vol controls each channel separately */
262             unsigned char max_read_speed[2];    /* Max. read speed in KB/s      */
263             /* obsolete in MMC-4 */
264             unsigned char num_vol_levels[2];    /* # of supported volume levels      */
265             unsigned char buffer_size[2];       /* Buffer size for the data in KB    */
266             unsigned char cur_read_speed[2];    /* Current read speed in KB/s      */
267             /* obsolete in MMC-4 */
268             unsigned char res_16;               /* Reserved        */
269             unsigned char res_17           : 2; /* Reserved        */
270             unsigned char length           : 2; /* 0=32BCKs 1=16BCKs 2=24BCKs 3=24I2c*/
271             unsigned char LSBF             : 1; /* Set: LSB first Clear: MSB first   */
272             unsigned char RCK              : 1; /* Set: HIGH high LRCK=left channel  */
273             unsigned char BCK              : 1; /* Data valid on falling edge of BCK */
274             unsigned char res_17_0         : 1; /* Reserved        */
275             unsigned char max_write_speed[2];   /* Max. write speed supported in KB/s*/
276             /* obsolete in MMC-4 */
277             unsigned char cur_write_speed[2];   /* Current write speed in KB/s      */
278             /* obsolete in MMC-4 */
279 
280             /* Byte 22 ... Only in MMC-2      */
281             unsigned char copy_man_rev[2];      /* Copy management revision supported*/
282             unsigned char res_24;               /* Reserved        */
283             unsigned char res_25;               /* Reserved        */
284 
285             /* Byte 26 ... Only in MMC-3      */
286             unsigned char res_26;               /* Reserved        */
287             unsigned char res_27_27        : 6; /* Reserved        */
288             unsigned char rot_ctl_sel      : 2; /* Rotational control selected      */
289             unsigned char v3_cur_write_speed[2]; /* Current write speed in KB/s      */
290             unsigned char num_wr_speed_des[2];  /* # of wr speed perf descr. tables  */
291             struct cd_wr_speed_performance
292             wr_speed_des[1];                    /* wr speed performance descriptor   */
293             /* Actually more (num_wr_speed_des)  */
294         };
295 
296 #else  // LITTLE_ENDIAN
297 
298         struct mm_cap_page_2A {
299             unsigned char page_code        : 6;
300             unsigned char res_1            : 1;
301             unsigned char PS               : 1;
302             unsigned char page_len;             /* 0x14 = 20 Bytes (MMC) */
303             /* 0x18 = 24 Bytes (MMC-2) */
304             /* 0x1C >= 28 Bytes (MMC-3) */
305             unsigned char cd_r_read        : 1; /* Reads CD-R  media       */
306             unsigned char cd_rw_read       : 1; /* Reads CD-RW media       */
307             unsigned char method2          : 1; /* Reads fixed packet method2 media  */
308             unsigned char dvd_rom_read     : 1; /* Reads DVD ROM media       */
309             unsigned char dvd_r_read       : 1; /* Reads DVD-R media       */
310             unsigned char dvd_ram_read     : 1; /* Reads DVD-RAM media       */
311             unsigned char res_2_67         : 2; /* Reserved        */
312             unsigned char cd_r_write       : 1; /* Supports writing CD-R  media      */
313             unsigned char cd_rw_write      : 1; /* Supports writing CD-RW media      */
314             unsigned char test_write       : 1; /* Supports emulation write      */
315             unsigned char res_3_3          : 1; /* Reserved        */
316             unsigned char dvd_r_write      : 1; /* Supports writing DVD-R media      */
317             unsigned char dvd_ram_write    : 1; /* Supports writing DVD-RAM media    */
318             unsigned char res_3_67         : 2; /* Reserved        */
319             unsigned char audio_play       : 1; /* Supports Audio play operation     */
320             unsigned char composite        : 1; /* Deliveres composite A/V stream    */
321             unsigned char digital_port_2   : 1; /* Supports digital output on port 2 */
322             unsigned char digital_port_1   : 1; /* Supports digital output on port 1 */
323             unsigned char mode_2_form_1    : 1; /* Reads Mode-2 form 1 media (XA)    */
324             unsigned char mode_2_form_2    : 1; /* Reads Mode-2 form 2 media      */
325             unsigned char multi_session    : 1; /* Reads multi-session media      */
326             unsigned char BUF              : 1; /* Supports Buffer under. free rec.  */
327             unsigned char cd_da_supported  : 1; /* Reads audio data with READ CD cmd */
328             unsigned char cd_da_accurate   : 1; /* READ CD data stream is accurate   */
329             unsigned char rw_supported     : 1; /* Reads R-W sub channel information */
330             unsigned char rw_deint_corr    : 1; /* Reads de-interleved R-W sub chan  */
331             unsigned char c2_pointers      : 1; /* Supports C2 error pointers      */
332             unsigned char ISRC             : 1; /* Reads ISRC information      */
333             unsigned char UPC              : 1; /* Reads media catalog number (UPC)  */
334             unsigned char read_bar_code    : 1; /* Supports reading bar codes      */
335             unsigned char lock             : 1; /* PREVENT/ALLOW may lock media      */
336             unsigned char lock_state       : 1; /* Lock state 0=unlocked 1=locked    */
337             unsigned char prevent_jumper   : 1; /* State of prev/allow jumper 0=pres */
338             unsigned char eject            : 1; /* Ejects disc/cartr with STOP LoEj  */
339             unsigned char res_6_4          : 1; /* Reserved        */
340             unsigned char loading_type     : 3; /* Loading mechanism type      */
341             unsigned char sep_chan_vol     : 1; /* Vol controls each channel separately */
342             unsigned char sep_chan_mute    : 1; /* Mute controls each channel separately */
343             unsigned char disk_present_rep : 1; /* Changer supports disk present rep */
344             unsigned char sw_slot_sel      : 1; /* Load empty slot in changer      */
345             unsigned char side_change      : 1; /* Side change capable       */
346             unsigned char rw_in_lead_in    : 1; /* Reads raw R-W subcode from lead in */
347             unsigned char res_7            : 2; /* Reserved        */
348             unsigned char max_read_speed[2];    /* Max. read speed in KB/s      */
349             /* obsolete in MMC-4 */
350             unsigned char num_vol_levels[2];    /* # of supported volume levels      */
351             unsigned char buffer_size[2];       /* Buffer size for the data in KB    */
352             unsigned char cur_read_speed[2];    /* Current read speed in KB/s      */
353             /* obsolete in MMC-4 */
354             unsigned char res_16;               /* Reserved        */
355             unsigned char res_17_0         : 1; /* Reserved        */
356             unsigned char BCK              : 1; /* Data valid on falling edge of BCK */
357             unsigned char RCK              : 1; /* Set: HIGH high LRCK=left channel  */
358             unsigned char LSBF             : 1; /* Set: LSB first Clear: MSB first   */
359             unsigned char length           : 2; /* 0=32BCKs 1=16BCKs 2=24BCKs 3=24I2c*/
360             unsigned char res_17           : 2; /* Reserved        */
361             unsigned char max_write_speed[2];   /* Max. write speed supported in KB/s*/
362             /* obsolete in MMC-4 */
363             unsigned char cur_write_speed[2];   /* Current write speed in KB/s      */
364             /* obsolete in MMC-4 */
365 
366             /* Byte 22 ... Only in MMC-2      */
367             unsigned char copy_man_rev[2];      /* Copy management revision supported*/
368             unsigned char res_24;               /* Reserved        */
369             unsigned char res_25;               /* Reserved        */
370 
371             /* Byte 26 ... Only in MMC-3      */
372             unsigned char res_26;               /* Reserved        */
373             unsigned char rot_ctl_sel      : 2; /* Rotational control selected      */
374             unsigned char res_27_27        : 6; /* Reserved        */
375             unsigned char v3_cur_write_speed[2]; /* Current write speed in KB/s      */
376             unsigned char num_wr_speed_des[2];  /* # of wr speed perf descr. tables  */
377             struct cd_wr_speed_performance
378             wr_speed_des[1];                    /* wr speed performance descriptor   */
379             /* Actually more (num_wr_speed_des)  */
380         };
381 #endif
382 
383         /**
384          * Based on the cdrecord struct cd_mode_page_05
385          * Write Parameters Mode Page
386          */
387 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
388         struct wr_param_page_05 {                /* write parameters */
389             unsigned char PS               : 1;
390             unsigned char res_1            : 1;
391             unsigned char page_code        : 6;
392             unsigned char page_len;                /* 0x32 = 50 Bytes */
393             unsigned char res_2_7          : 1;
394             unsigned char BUFE             : 1;    /* Enable Bufunderrun free rec.      */
395             unsigned char LS_V             : 1;    /* Link size valid                   */
396             unsigned char test_write       : 1;    /* Do not actually write data        */
397             unsigned char write_type       : 4;    /* Session write type (PACKET/TAO...)*/
398             unsigned char multi_session    : 2;    /* Multi session write type          */
399             unsigned char fp               : 1;    /* Fixed packed (if in packet mode)  */
400             unsigned char copy             : 1;    /* 1st higher gen of copy prot track */
401             unsigned char track_mode       : 4;    /* Track mode (Q-sub control nibble) */
402             unsigned char res_4            : 4;    /* Reserved                          */
403             unsigned char dbtype           : 4;    /* Data block type                   */
404             unsigned char link_size;               /* Link Size (default is 7)          */
405             unsigned char res_6;                   /* Reserved                          */
406             unsigned char res_7            : 2;    /* Reserved                          */
407             unsigned char host_appl_code   : 6;    /* Host application code of disk     */
408             unsigned char session_format;          /* Session format (DA/CDI/XA)        */
409             unsigned char res_9;                   /* Reserved                          */
410             unsigned char packet_size[4];          /* # of user datablocks/fixed packet */
411             unsigned char audio_pause_len[2];      /* # of blocks where index is zero   */
412             unsigned char media_cat_number[16];    /* Media catalog Number (MCN)        */
413             unsigned char ISRC[14];                /* ISRC for this track               */
414             unsigned char sub_header[4];
415             unsigned char vendor_uniq[4];
416         };
417 
418 #else // __LITTLE_ENDIAN
419         struct wr_param_page_05 {		/* write parameters */
420             unsigned char page_code        : 6;
421             unsigned char res_1            : 1;
422             unsigned char PS               : 1;
423             unsigned char p_len;		/* 0x32 = 50 Bytes */
424             unsigned char write_type	   : 4;	/* Session write type (PACKET/TAO...)*/
425             unsigned char test_write	   : 1;	/* Do not actually write data	     */
426             unsigned char LS_V		   : 1;	/* Link size valid		     */
427             unsigned char BUFE		   : 1;	/* Enable Bufunderrun free rec.	     */
428             unsigned char res_2_7	   : 1;
429             unsigned char track_mode	   : 4;	/* Track mode (Q-sub control nibble) */
430             unsigned char copy		   : 1;	/* 1st higher gen of copy prot track ~*/
431             unsigned char fp		   : 1;	/* Fixed packed (if in packet mode)  */
432             unsigned char multi_session	   : 2;	/* Multi session write type	     */
433             unsigned char dbtype	   : 4;	/* Data block type		     */
434             unsigned char res_4		   : 4;	/* Reserved			     */
435             unsigned char link_size;		/* Link Size (default is 7)	     */
436             unsigned char res_6;	       	/* Reserved			     */
437             unsigned char host_appl_code   : 6;	/* Host application code of disk     */
438             unsigned char res_7		   : 2;	/* Reserved			     */
439             unsigned char session_format;	/* Session format (DA/CDI/XA)	     */
440             unsigned char res_9;		/* Reserved			     */
441             unsigned char packet_size[4];	/* # of user datablocks/fixed packet */
442             unsigned char audio_pause_len[2];	/* # of blocks where index is zero   */
443             unsigned char media_cat_number[16];	/* Media catalog Number (MCN)	     */
444             unsigned char ISRC[14];		/* ISRC for this track		     */
445             unsigned char sub_header[4];
446             unsigned char vendor_uniq[4];
447         };
448 #endif
449 
450 
451         struct toc_track_descriptor {
452             unsigned char res1;
453 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
454             unsigned char adr     : 4;
455             unsigned char control : 4;
456 #else
457             unsigned char control : 4;
458             unsigned char adr     : 4;
459 #endif
460             unsigned char track_no;
461             unsigned char res2;
462             unsigned char start_adr[4];
463         };
464 
465 
466         struct atip_descriptor {
467             unsigned char dataLength[2];
468             unsigned char res1;
469             unsigned char res2;
470 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
471             unsigned char ind_wr_power : 4;  // indicated writing power
472             unsigned char ddcd         : 1;  // DDCD
473             unsigned char ref_speed    : 3;  // reference Speed
474             unsigned char zero         : 1;  // 0
475             unsigned char uru          : 1;  // Uru
476             unsigned char res3         : 6;
477             unsigned char one          : 1;  // 1
478             unsigned char disc_type    : 1;  // Disc Type
479             unsigned char disc_subtype : 3;  // Disc Sub-Type
480             unsigned char a1_valid     : 1;
481             unsigned char a2_valid     : 1;
482             unsigned char a3_valid     : 1;
483 #else
484             unsigned char ref_speed    : 3;  // reference Speed
485             unsigned char ddcd         : 1;  // DDCD
486             unsigned char ind_wr_power : 4;  // indicated writing power
487             unsigned char res3         : 6;
488             unsigned char uru          : 1;  // Uru
489             unsigned char zero         : 1;  // 0
490             unsigned char a3_valid     : 1;
491             unsigned char a2_valid     : 1;
492             unsigned char a1_valid     : 1;
493             unsigned char disc_subtype : 3;  // Disc Sub-Type
494             unsigned char disc_type    : 1;  // Disc Type
495             unsigned char one          : 1;  // 1
496 #endif
497             unsigned char res4;
498             unsigned char lead_in_m;
499             unsigned char lead_in_s;
500             unsigned char lead_in_f;
501             unsigned char res5;
502             unsigned char lead_out_m;
503             unsigned char lead_out_s;
504             unsigned char lead_out_f;
505             unsigned char res6;
506             unsigned char a1[3];
507             unsigned char res7;
508             unsigned char a2[3];
509             unsigned char res8;
510             unsigned char a3[3];
511             unsigned char res9;
512             unsigned char s4[3];
513             unsigned char res10;
514         };
515 
516 
517         struct mechanism_status_header {
518 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
519             unsigned char fault         : 1;
520             unsigned char changer_state : 2;
521             unsigned char slot_low      : 5;
522 #else
523             unsigned char slot_low      : 5;
524             unsigned char changer_state : 2;
525             unsigned char fault         : 1;
526 #endif
527 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
528             unsigned char mech_state    : 3;
529             unsigned char door_open     : 1;
530             unsigned char res1          : 1;
531             unsigned char slot_high     : 3;
532 #else
533             unsigned char slot_high     : 3;
534             unsigned char res1          : 1;
535             unsigned char door_open     : 1;
536             unsigned char mech_state    : 3;
537 #endif
538             unsigned char current_lba[3];
539             unsigned char num_slots;
540             unsigned char slot_len[2];
541         };
542 
543         struct mechanism_status_slot {
544 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
545             unsigned char disc_present  : 1;
546             unsigned char res1          : 6;
547             unsigned char change        : 1;
548 #else
549             unsigned char change        : 1;
550             unsigned char res1          : 6;
551             unsigned char disc_present  : 1;
552 #endif
553 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
554             unsigned char res2          : 6;
555             unsigned char cwp_v         : 1;
556             unsigned char cwp           : 1;
557 #else
558             unsigned char cwp           : 1;
559             unsigned char cwp_v         : 1;
560             unsigned char res2          : 6;
561 #endif
562             unsigned char res3;
563             unsigned char res4;
564         };
565 
566 
567         struct inquiry {
568 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
569             unsigned char p_qualifier   : 3;
570             unsigned char p_device_type : 5;
571             unsigned char rmb           : 1;
572             unsigned char reserved1     : 7;
573 #else
574             unsigned char p_device_type : 5;
575             unsigned char p_qualifier   : 3;
576             unsigned char reserved1     : 7;
577             unsigned char rmb           : 1;
578 #endif
579             unsigned char version;
580 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
581             unsigned char interface_dep : 4;
582             unsigned char data_format   : 4;
583 #else
584             unsigned char data_format   : 4;
585             unsigned char interface_dep : 4;
586 #endif
587             unsigned char add_length;
588             unsigned char reserved2;
589 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
590             unsigned char bque          : 1;
591             unsigned char enc_serv      : 1;
592             unsigned char vs1           : 1;
593             unsigned char multi_p       : 1;
594             unsigned char m_chngr       : 1;
595             unsigned char reserved3     : 1;
596             unsigned char reserved4     : 1;
597             unsigned char addr_16       : 1;
598             unsigned char rel_adr       : 1;
599             unsigned char reserved5     : 1;
600             unsigned char w_bus_16      : 1;
601             unsigned char sync          : 1;
602             unsigned char linked        : 1;
603             unsigned char reserved6     : 1;
604             unsigned char cmd_que       : 1;
605             unsigned char vs2           : 1;
606 #else
607             unsigned char addr_16       : 1;
608             unsigned char reserved4     : 1;
609             unsigned char reserved3     : 1;
610             unsigned char m_chngr       : 1;
611             unsigned char multi_p       : 1;
612             unsigned char vs1           : 1;
613             unsigned char enc_serv      : 1;
614             unsigned char bque          : 1;
615             unsigned char vs2           : 1;
616             unsigned char cmd_que       : 1;
617             unsigned char reserved6     : 1;
618             unsigned char linked        : 1;
619             unsigned char sync          : 1;
620             unsigned char w_bus_16      : 1;
621             unsigned char reserved5     : 1;
622             unsigned char rel_adr       : 1;
623 #endif
624             unsigned char vendor[8];
625             unsigned char product[16];
626             unsigned char revision[4];
627             unsigned char vendor_specific[20];
628             unsigned char reserved7[2];
629             unsigned char version1[2];
630             unsigned char version2[2];
631             unsigned char version3[2];
632             unsigned char version4[2];
633             unsigned char version5[2];
634             unsigned char version6[2];
635             unsigned char version7[2];
636             unsigned char version8[2];
637 
638             // bytes 74-95: reserved
639             // bytes 96-n: vendor specific
640         };
641 
642 
643         struct ricoh_mode_page_30 {
644 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
645             unsigned char PS               : 1;
646             unsigned char res_1            : 1;
647             unsigned char page_code        : 6;
648 #else
649             unsigned char page_code        : 6;
650             unsigned char res_1            : 1;
651             unsigned char PS               : 1;
652 #endif
653             unsigned char page_len;                  /* 0xE = 14 Bytes */
654 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
655             unsigned char res_2_67        :2;
656             unsigned char AWSCS           :1;     /* Auto write speed control supp. */
657             unsigned char ARSCS           :1;     /* Auto read speed control supp. */
658             unsigned char res_2_23        :2;
659             unsigned char TWBFS           :1;     /* Test Burn-Free sup.  */
660             unsigned char BUEFS           :1;     /* Burn-Free supported  */
661 #else
662             unsigned char BUEFS           :1;     /* Burn-Free supported  */
663             unsigned char TWBFS           :1;     /* Test Burn-Free sup.  */
664             unsigned char res_2_23        :2;
665             unsigned char ARSCS           :1;     /* Auto read speed control supp. */
666             unsigned char AWSCS           :1;     /* Auto write speed control supp. */
667             unsigned char res_2_67        :2;
668 #endif
669 #ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
670             unsigned char res_3_67        :2;
671             unsigned char AWSCD           :1;     /* Auto write speed control disabled */
672             unsigned char ARSCE           :1;     /* Auto read speed control enabled */
673             unsigned char res_2_13        :3;
674             unsigned char BUEFE           :1;     /* Burn-Free enabled    */
675 #else
676             unsigned char BUEFE           :1;     /* Burn-Free enabled    */
677             unsigned char res_2_13        :3;
678             unsigned char ARSCE           :1;     /* Auto read speed control enabled */
679             unsigned char AWSCD           :1;     /* Auto write speed control disabled */
680             unsigned char res_3_67        :2;
681 #endif
682             unsigned char link_counter[2];        /* Burn-Free link counter */
683             unsigned char res[10];                /* Padding up to 16 bytes */
684         };
685     }
686 }
687 
688 #endif
689