1/*
2 * Copyright (c) 1998-2012 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#ifndef	_IOCDTYPES_H
25#define	_IOCDTYPES_H
26
27#include <IOKit/IOTypes.h>
28#include <libkern/OSByteOrder.h>
29
30#pragma pack(push, 1)                        /* (enable 8-bit struct packing) */
31
32/*
33 * Minutes, Seconds, Frames (M:S:F)
34 *
35 * All M:S:F values passed across I/O Kit APIs are guaranteed to be
36 * binary-encoded numbers (no BCD-encoded numbers are ever passed).
37 */
38
39typedef struct
40{
41    UInt8 minute;
42    UInt8 second;
43    UInt8 frame;
44} CDMSF;
45
46/*
47 * Media Catalogue Numbers (MCN), International Standard Recording Codes (ISRC)
48 *
49 * All MCN and ISRC values passed across I/O Kit APIs are guaranteed
50 * to have a zero-terminating byte, for convenient use as C strings.
51 */
52
53#define kCDMCNMaxLength  13
54#define kCDISRCMaxLength 12
55
56typedef char CDMCN [kCDMCNMaxLength  + 1];
57typedef char CDISRC[kCDISRCMaxLength + 1];
58
59/*
60 * Audio Status
61 *
62 * All CDAudioStatus fields passed across I/O Kit APIs are guaranteed to
63 * be binary-encoded numbers (no BCD-encoded numbers are ever passed).
64 */
65
66#define kCDAudioStatusUnsupported 0x00
67#define kCDAudioStatusActive      0x11
68#define kCDAudioStatusPaused      0x12
69#define kCDAudioStatusSuccess     0x13
70#define kCDAudioStatusFailure     0x14
71#define kCDAudioStatusNone        0x15
72
73typedef struct
74{
75    UInt8 status;
76    struct
77    {
78        CDMSF time;
79        struct
80        {
81            UInt8 index;
82            UInt8 number;
83            CDMSF time;
84        } track;
85    } position;
86} CDAudioStatus;
87
88/*
89 * Table Of Contents
90 *
91 * All CDTOC fields passed across I/O Kit APIs are guaranteed to be
92 * binary-encoded numbers (no BCD-encoded numbers are ever passed).
93 */
94
95typedef struct
96{
97    UInt8 session;
98#ifdef __LITTLE_ENDIAN__
99    UInt8 control:4, adr:4;
100#else /* !__LITTLE_ENDIAN__ */
101    UInt8 adr:4, control:4;
102#endif /* !__LITTLE_ENDIAN__ */
103    UInt8 tno;
104    UInt8 point;
105    CDMSF address;
106    UInt8 zero;
107    CDMSF p;
108} CDTOCDescriptor;
109
110typedef struct
111{
112    UInt16          length;
113    UInt8           sessionFirst;
114    UInt8           sessionLast;
115    CDTOCDescriptor descriptors[0];
116} CDTOC;
117
118/*
119 * Table Of Contents Descriptor Count Convenience Function
120 */
121
122static inline UInt32 CDTOCGetDescriptorCount(CDTOC * toc)
123{
124    UInt32 tocSize = OSSwapBigToHostInt16(toc->length) + (UInt32) sizeof(toc->length);
125
126    return (tocSize < (UInt32) sizeof(CDTOC)) ? 0 :
127           (tocSize - (UInt32) sizeof(CDTOC)) / (UInt32) sizeof(CDTOCDescriptor);
128}
129
130/*
131 * M:S:F To LBA Convenience Function
132 */
133
134static inline UInt32 CDConvertMSFToLBA(CDMSF msf)
135{
136    return (((msf.minute * 60U) + msf.second) * 75U) + msf.frame - 150U;
137}
138
139/*
140 * M:S:F To Clipped LBA Convenience Function
141 */
142
143static inline UInt32 CDConvertMSFToClippedLBA(CDMSF msf)
144{
145    return (msf.minute == 0 && msf.second <= 1) ? 0 : CDConvertMSFToLBA(msf);
146}
147
148/*
149 * LBA To M:S:F Convenience Function
150 */
151
152static inline CDMSF CDConvertLBAToMSF(UInt32 lba)
153{
154    CDMSF msf;
155
156    lba += 150;
157    msf.minute = (lba / (75 * 60));
158    msf.second = (lba % (75 * 60)) / 75;
159    msf.frame  = (lba % (75     ));
160
161    return msf;
162}
163
164/*
165 * Track Number To M:S:F Convenience Function
166 *
167 * The CDTOC structure is assumed to be complete, that is, none of
168 * the descriptors are missing or clipped due to an insufficiently
169 * sized buffer holding the CDTOC contents.
170 */
171
172static inline CDMSF CDConvertTrackNumberToMSF(UInt8 track, CDTOC * toc)
173{
174    UInt32 count = CDTOCGetDescriptorCount(toc);
175    UInt32 i;
176    CDMSF  msf   = { 0xFF, 0xFF, 0xFF };
177
178    for (i = 0; i < count; i++)
179    {
180        if (toc->descriptors[i].point == track && toc->descriptors[i].adr == 1)
181        {
182            msf = toc->descriptors[i].p;
183            break;
184        }
185    }
186
187    return msf;
188}
189
190/*
191 * Sector Areas, Sector Types
192 *
193 * Bytes Per Type      CDDA       Mode1      Mode2   Mode2Form1 Mode2Form2
194 *       Per Area  +----------+----------+----------+----------+----------+
195 * Sync            | 0        | 12       | 12       | 12       | 12       |
196 * Header          | 0        | 4        | 4        | 4        | 4        |
197 * SubHeader       | 0        | 0        | 0        | 8        | 8        |
198 * User            | 2352     | 2048     | 2336     | 2048     | 2328     |
199 * Auxiliary       | 0        | 288      | 0        | 280      | 0        |
200 * ErrorFlags      | 294      | 294      | 294      | 294      | 294      |
201 * SubChannel      | 96       | 96       | 96       | 96       | 96       |
202 * SubChannelQ     | 16       | 16       | 16       | 16       | 16       |
203 *                 +----------+----------+----------+----------+----------+
204 */
205
206typedef enum
207{
208    kCDSectorAreaSync        = 0x80,
209    kCDSectorAreaHeader      = 0x20,
210    kCDSectorAreaSubHeader   = 0x40,
211    kCDSectorAreaUser        = 0x10,
212    kCDSectorAreaAuxiliary   = 0x08,
213    kCDSectorAreaErrorFlags  = 0x02,
214    kCDSectorAreaSubChannel  = 0x01,
215    kCDSectorAreaSubChannelQ = 0x04
216} CDSectorArea;
217
218typedef enum
219{
220    kCDSectorTypeUnknown     = 0x00,
221    kCDSectorTypeCDDA        = 0x01,
222    kCDSectorTypeMode1       = 0x02,
223    kCDSectorTypeMode2       = 0x03,
224    kCDSectorTypeMode2Form1  = 0x04,
225    kCDSectorTypeMode2Form2  = 0x05,
226    kCDSectorTypeCount       = 0x06
227} CDSectorType;
228
229typedef enum
230{
231    kCDSectorSizeCDDA        = 2352,
232    kCDSectorSizeMode1       = 2048,
233    kCDSectorSizeMode2       = 2336,
234    kCDSectorSizeMode2Form1  = 2048,
235    kCDSectorSizeMode2Form2  = 2328,
236    kCDSectorSizeWhole       = 2352
237} CDSectorSize;
238
239/*
240 * Media Types
241 */
242
243enum
244{
245    kCDMediaTypeUnknown      = 0x0100,
246    kCDMediaTypeROM          = 0x0102, /* CD-ROM */
247    kCDMediaTypeR            = 0x0104, /* CD-R   */
248    kCDMediaTypeRW           = 0x0105, /* CD-RW  */
249
250    kCDMediaTypeMin          = 0x0100,
251    kCDMediaTypeMax          = 0x01FF
252};
253
254typedef UInt32 CDMediaType;
255
256/*
257 * Media Speed (kB/s)
258 */
259
260#define kCDSpeedMin 0x00B0
261#define kCDSpeedMax 0xFFFF
262
263/*
264 * MMC Formats
265 */
266
267// Read Table Of Contents Format Types
268typedef UInt8 CDTOCFormat;
269enum
270{
271    kCDTOCFormatTOC  = 0x02, // CDTOC
272    kCDTOCFormatPMA  = 0x03, // CDPMA
273    kCDTOCFormatATIP = 0x04, // CDATIP
274    kCDTOCFormatTEXT = 0x05  // CDTEXT
275};
276
277// Read Table Of Contents Format 0x03
278struct CDPMADescriptor
279{
280    UInt8 reserved;
281#ifdef __LITTLE_ENDIAN__
282    UInt8 control:4, adr:4;
283#else /* !__LITTLE_ENDIAN__ */
284    UInt8 adr:4, control:4;
285#endif /* !__LITTLE_ENDIAN__ */
286    UInt8 tno;
287    UInt8 point;
288    CDMSF address;
289    UInt8 zero;
290    CDMSF p;
291};
292typedef struct CDPMADescriptor CDPMADescriptor;
293
294struct CDPMA
295{
296    UInt16          dataLength;
297    UInt8           reserved;
298    UInt8           reserved2;
299    CDPMADescriptor descriptors[0];
300};
301typedef struct CDPMA CDPMA;
302
303// Read Table Of Contents Format 0x04
304struct CDATIP
305{
306    UInt16 dataLength;
307    UInt8  reserved[2];
308#ifdef __LITTLE_ENDIAN__
309    UInt8  referenceSpeed:3;
310    UInt8  reserved3:1;
311    UInt8  indicativeTargetWritingPower:3;
312    UInt8  reserved2:1;
313
314    UInt8  reserved5:6;
315    UInt8  unrestrictedUse:1;
316    UInt8  reserved4:1;
317
318    UInt8  a3Valid:1;
319    UInt8  a2Valid:1;
320    UInt8  a1Valid:1;
321    UInt8  discSubType:3;
322    UInt8  discType:1;
323    UInt8  reserved6:1;
324#else /* !__LITTLE_ENDIAN__ */
325    UInt8  reserved2:1;
326    UInt8  indicativeTargetWritingPower:3;
327    UInt8  reserved3:1;
328    UInt8  referenceSpeed:3;
329
330    UInt8  reserved4:1;
331    UInt8  unrestrictedUse:1;
332    UInt8  reserved5:6;
333
334    UInt8  reserved6:1;
335    UInt8  discType:1;
336    UInt8  discSubType:3;
337    UInt8  a1Valid:1;
338    UInt8  a2Valid:1;
339    UInt8  a3Valid:1;
340#endif /* !__LITTLE_ENDIAN__ */
341    UInt8  reserved7;
342    CDMSF  startTimeOfLeadIn;
343    UInt8  reserved8;
344    CDMSF  lastPossibleStartTimeOfLeadOut;
345    UInt8  reserved9;
346    UInt8  a1[3];
347    UInt8  reserved10;
348    UInt8  a2[3];
349    UInt8  reserved11;
350    UInt8  a3[3];
351    UInt8  reserved12;
352};
353typedef struct CDATIP CDATIP;
354
355// Read Table Of Contents Format 0x05
356struct CDTEXTDescriptor
357{
358    UInt8 packType;
359    UInt8 trackNumber;
360    UInt8 sequenceNumber;
361#ifdef __LITTLE_ENDIAN__
362    UInt8 characterPosition:4;
363    UInt8 blockNumber:3;
364    UInt8 doubleByteCharacterCode:1;
365#else /* !__LITTLE_ENDIAN__ */
366    UInt8 doubleByteCharacterCode:1;
367    UInt8 blockNumber:3;
368    UInt8 characterPosition:4;
369#endif /* !__LITTLE_ENDIAN__ */
370    UInt8 textData[12];
371    UInt8 reserved[2];
372};
373typedef struct CDTEXTDescriptor CDTEXTDescriptor;
374
375struct CDTEXT
376{
377    UInt16           dataLength;
378    UInt8            reserved;
379    UInt8            reserved2;
380    CDTEXTDescriptor descriptors[0];
381};
382typedef struct CDTEXT CDTEXT;
383
384// Read Disc Information Format
385struct CDDiscInfo
386{
387    UInt16 dataLength;
388#ifdef __LITTLE_ENDIAN__
389    UInt8  discStatus:2;
390    UInt8  stateOfLastSession:2;
391    UInt8  erasable:1;
392    UInt8  reserved:3;
393#else /* !__LITTLE_ENDIAN__ */
394    UInt8  reserved:3;
395    UInt8  erasable:1;
396    UInt8  stateOfLastSession:2;
397    UInt8  discStatus:2;
398#endif /* !__LITTLE_ENDIAN__ */
399    UInt8  numberOfFirstTrack;
400    UInt8  numberOfSessionsLSB;
401    UInt8  firstTrackNumberInLastSessionLSB;
402    UInt8  lastTrackNumberInLastSessionLSB;
403#ifdef __LITTLE_ENDIAN__
404    UInt8  reserved3:5;
405    UInt8  unrestrictedUse:1;
406    UInt8  discBarCodeValid:1;
407    UInt8  discIdentificationValid:1;
408#else /* !__LITTLE_ENDIAN__ */
409    UInt8  discIdentificationValid:1;
410    UInt8  discBarCodeValid:1;
411    UInt8  unrestrictedUse:1;
412    UInt8  reserved3:5;
413#endif /* !__LITTLE_ENDIAN__ */
414    UInt8  discType;
415    UInt8  numberOfSessionsMSB;
416    UInt8  firstTrackNumberInLastSessionMSB;
417    UInt8  lastTrackNumberInLastSessionMSB;
418    UInt32 discIdentification;
419    UInt8  reserved7;
420    CDMSF  lastSessionLeadInStartTime;
421    UInt8  reserved8;
422    CDMSF  lastPossibleStartTimeOfLeadOut;
423    UInt8  discBarCode[8];
424    UInt8  reserved9;
425    UInt8  numberOfOPCTableEntries;
426    UInt8  opcTableEntries[0];
427};
428typedef struct CDDiscInfo CDDiscInfo;
429
430// Read Track Information Address Types
431typedef UInt8 CDTrackInfoAddressType;
432enum
433{
434    kCDTrackInfoAddressTypeLBA           = 0x00,
435    kCDTrackInfoAddressTypeTrackNumber   = 0x01,
436    kCDTrackInfoAddressTypeSessionNumber = 0x02,
437};
438
439// Read Track Information Format
440struct CDTrackInfo
441{
442    UInt16 dataLength;
443    UInt8  trackNumberLSB;
444    UInt8  sessionNumberLSB;
445    UInt8  reserved;
446#ifdef __LITTLE_ENDIAN__
447    UInt8  trackMode:4;
448    UInt8  copy:1;
449    UInt8  damage:1;
450    UInt8  reserved3:2;
451
452    UInt8  dataMode:4;
453    UInt8  fixedPacket:1;
454    UInt8  packet:1;
455    UInt8  blank:1;
456    UInt8  reservedTrack:1;
457
458    UInt8  nextWritableAddressValid:1;
459    UInt8  lastRecordedAddressValid:1;
460    UInt8  reserved5:6;
461#else /* !__LITTLE_ENDIAN__ */
462    UInt8  reserved3:2;
463    UInt8  damage:1;
464    UInt8  copy:1;
465    UInt8  trackMode:4;
466
467    UInt8  reservedTrack:1;
468    UInt8  blank:1;
469    UInt8  packet:1;
470    UInt8  fixedPacket:1;
471    UInt8  dataMode:4;
472
473    UInt8  reserved5:6;
474    UInt8  lastRecordedAddressValid:1;
475    UInt8  nextWritableAddressValid:1;
476#endif /* !__LITTLE_ENDIAN__ */
477    UInt32 trackStartAddress;
478    UInt32 nextWritableAddress;
479    UInt32 freeBlocks;
480    UInt32 fixedPacketSize;
481    UInt32 trackSize;
482    UInt32 lastRecordedAddress;
483    UInt8  trackNumberMSB;
484    UInt8  sessionNumberMSB;
485    UInt8  reserved6;
486    UInt8  reserved7;
487};
488typedef struct CDTrackInfo CDTrackInfo;
489
490#pragma pack(pop)                        /* (reset to default struct packing) */
491
492#endif /* _IOCDTYPES_H */
493