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