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#include <IOKit/IOBufferMemoryDescriptor.h> 24#include <IOKit/IOKitKeys.h> 25#include <IOKit/IOLib.h> 26#include <IOKit/storage/IOCDBlockStorageDriver.h> 27#include <IOKit/storage/IOCDMedia.h> 28#include <IOKit/storage/IOCDBlockStorageDevice.h> 29#include <libkern/OSByteOrder.h> 30 31#define super IOBlockStorageDriver 32OSDefineMetaClassAndStructors(IOCDBlockStorageDriver,IOBlockStorageDriver) 33 34#ifdef __LP64__ 35#define original request 36#endif /* __LP64__ */ 37 38IOCDBlockStorageDevice * 39IOCDBlockStorageDriver::getProvider() const 40{ 41 return (IOCDBlockStorageDevice *) IOService::getProvider(); 42} 43 44 45/* Accept a new piece of media, doing whatever's necessary to make it 46 * show up properly to the system. The arbitration lock is assumed to 47 * be held during the call. 48 */ 49IOReturn 50IOCDBlockStorageDriver::acceptNewMedia(void) 51{ 52 IOReturn result; 53 int i; 54 int nentries; 55 int nAudioTracks; 56 57 /* First, we cache information about the tracks on the disc: */ 58 59 result = cacheTocInfo(); 60 if (result != kIOReturnSuccess) { 61 assert(_toc == NULL); 62 } 63 64 /* Scan thru the track list, counting up the number of Data and Audio tracks. */ 65 66 nAudioTracks = 0; 67 68 _minBlockNumberAudio = 0xFFFFFFFF; 69 _maxBlockNumberAudio = 0xFFFFFFFF; 70 71 if (_toc) { 72 nentries = CDTOCGetDescriptorCount(_toc); 73 74 for (i = 0; i < nentries; i++) { 75 UInt32 lba = CDConvertMSFToClippedLBA(_toc->descriptors[i].p); 76 /* tracks 1-99, not leadout or skip intervals */ 77 if (_toc->descriptors[i].point <= 99 && _toc->descriptors[i].adr == 1) { 78 if ((_toc->descriptors[i].control & 0x04)) { 79 /* it's a data track */ 80 _maxBlockNumberAudio = min(_maxBlockNumberAudio, lba ? (lba - 1) : 0); 81 } else { 82 nAudioTracks++; 83 _minBlockNumberAudio = min(_minBlockNumberAudio, lba); 84 } 85 /* leadout */ 86 } else if (_toc->descriptors[i].point == 0xA2 && _toc->descriptors[i].adr == 1) { 87 _maxBlockNumber = max(_maxBlockNumber, lba ? (lba - 1) : 0); 88 _maxBlockNumberAudio = min(_maxBlockNumberAudio, lba ? (lba - 1) : 0); 89 } 90 } 91 92 if (_maxBlockNumberAudio < _minBlockNumberAudio) { 93 _maxBlockNumberAudio = 0xFFFFFFFF; 94 95 /* find first data track or leadout after the audio tracks */ 96 for (i = 0; i < nentries; i++) { 97 UInt32 lba = CDConvertMSFToClippedLBA(_toc->descriptors[i].p); 98 /* tracks 1-99, not leadout or skip intervals */ 99 if (_toc->descriptors[i].point <= 99 && _toc->descriptors[i].adr == 1) { 100 if ((_toc->descriptors[i].control & 0x04)) { 101 /* it's a data track */ 102 if (lba > _minBlockNumberAudio) { 103 _maxBlockNumberAudio = min(_maxBlockNumberAudio, lba - 1); 104 } 105 } 106 /* leadout */ 107 } else if (_toc->descriptors[i].point == 0xA2 && _toc->descriptors[i].adr == 1) { 108 if (lba > _minBlockNumberAudio) { 109 _maxBlockNumberAudio = min(_maxBlockNumberAudio, lba - 1); 110 } 111 } 112 } 113 } 114 } 115 116 /* Obtain disc status: */ 117 118 switch (getMediaType()) { 119 case kCDMediaTypeR: 120 case kCDMediaTypeRW: { 121 bool checkIsWritable = false; 122 CDDiscInfo discInfo; 123 CDTrackInfo trackInfo; 124 125 result = reportDiscInfo(&discInfo); 126 if (result != kIOReturnSuccess) { 127 break; 128 } 129 130 switch (discInfo.discStatus) { 131 case 0x01: /* is disc incomplete? */ 132 checkIsWritable = true; 133 break; 134 case 0x02: /* is disc complete? */ 135 checkIsWritable = discInfo.erasable ? true : false; 136 break; 137 } 138 139 /* Obtain track status: */ 140 141 if (checkIsWritable) { 142 UInt16 trackLast = discInfo.lastTrackNumberInLastSessionLSB; 143 144 result = reportTrackInfo(trackLast,&trackInfo); 145 if (result != kIOReturnSuccess) { 146 break; 147 } 148 149 if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ 150 _maxBlockNumber = CDConvertMSFToClippedLBA(discInfo.lastPossibleStartTimeOfLeadOut); 151 } 152 153 if (trackInfo.packet) { /* is track incremental? */ 154 _writeProtected = false; 155 break; 156 } 157 158 if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ 159 if (trackInfo.blank) { /* is track invisible? */ 160 UInt16 trackFirst = discInfo.firstTrackNumberInLastSessionLSB; 161 162 if (trackFirst < trackLast) { 163 result = reportTrackInfo(trackLast - 1,&trackInfo); 164 if (result != kIOReturnSuccess) { 165 break; 166 } 167 168 if (trackInfo.packet) { /* is track incremental? */ 169 _writeProtected = false; 170 break; 171 } 172 } 173 } 174 } 175 } 176 177 break; 178 } 179 } 180 181 /* Instantiate a media object and attach it to ourselves. */ 182 183 result = super::acceptNewMedia(); 184 if (result != kIOReturnSuccess) { 185 return(result); /* give up now */ 186 } 187 188 return(result); 189} 190 191#ifndef __LP64__ 192IOReturn 193IOCDBlockStorageDriver::audioPause(bool pause) 194{ 195 return(getProvider()->audioPause(pause)); 196} 197 198IOReturn 199IOCDBlockStorageDriver::audioPlay(CDMSF timeStart,CDMSF timeStop) 200{ 201 return(getProvider()->audioPlay(timeStart,timeStop)); 202} 203 204IOReturn 205IOCDBlockStorageDriver::audioScan(CDMSF timeStart,bool reverse) 206{ 207 return(getProvider()->audioScan(timeStart,reverse)); 208} 209 210IOReturn 211IOCDBlockStorageDriver::audioStop() 212{ 213 return(getProvider()->audioStop()); 214} 215#endif /* !__LP64__ */ 216 217IOReturn 218IOCDBlockStorageDriver::cacheTocInfo(void) 219{ 220 IOBufferMemoryDescriptor *buffer; 221 IOReturn result; 222 CDTOC *toc; 223 UInt16 tocSize; 224 225 assert(sizeof(CDTOC) == 4); /* (compiler/platform check) */ 226 assert(sizeof(CDTOCDescriptor) == 11); /* (compiler/platform check) */ 227 228 assert(_toc == NULL); 229 230 /* Read the TOC header: */ 231 232 buffer = IOBufferMemoryDescriptor::withCapacity(sizeof(CDTOC),kIODirectionIn); 233 if (buffer == NULL) { 234 return(kIOReturnNoMemory); 235 } 236 237 result = getProvider()->readTOC(buffer); 238 if (result != kIOReturnSuccess) { 239 buffer->release(); 240 return(result); 241 } 242 243 toc = (CDTOC *) buffer->getBytesNoCopy(); 244 tocSize = OSSwapBigToHostInt16(toc->length) + sizeof(toc->length); 245 246 buffer->release(); 247 248 /* Reject the TOC if its size is too small: */ 249 250 if (tocSize <= sizeof(CDTOC)) { 251 return(kIOReturnNotFound); 252 } 253 254 /* Read the TOC in full: */ 255 256 buffer = IOBufferMemoryDescriptor::withCapacity(tocSize,kIODirectionIn); 257 if (buffer == NULL) { 258 return(kIOReturnNoMemory); 259 } 260 261 result = getProvider()->readTOC(buffer); 262 if (result != kIOReturnSuccess) { 263 buffer->release(); 264 return(result); 265 } 266 267 toc = (CDTOC *) IOMalloc(tocSize); 268 if (toc == NULL) { 269 buffer->release(); 270 return(kIOReturnNoMemory); 271 } 272 273 if (buffer->readBytes(0,toc,tocSize) != tocSize) { 274 buffer->release(); 275 IOFree(toc,tocSize); 276 return(kIOReturnNoMemory); 277 } 278 279 _toc = toc; 280 _tocSize = tocSize; 281 282 buffer->release(); 283 284 return(result); 285} 286 287/* Decommission all nubs. The arbitration lock is assumed to 288 * be held during the call. 289 */ 290IOReturn 291IOCDBlockStorageDriver::decommissionMedia(bool forcible) 292{ 293 IOReturn result; 294 295 result = super::decommissionMedia(forcible); 296 297 if (result == kIOReturnSuccess) { 298 if (_toc) { 299 IOFree(_toc,_tocSize); 300 _toc = NULL; 301 _tocSize = 0; 302 } 303 304 _minBlockNumberAudio = 0; 305 _maxBlockNumberAudio = 0; 306 } 307 308 return(result); 309} 310 311/* We should check with other clients using the other nubs before we allow 312 * the client of the IOCDMedia to eject the media. 313 */ 314IOReturn 315IOCDBlockStorageDriver::ejectMedia(void) 316{ 317 /* For now, we don't check with the other clients. */ 318 319 return(super::ejectMedia()); 320} 321 322void 323IOCDBlockStorageDriver::executeRequest(UInt64 byteStart, 324 IOMemoryDescriptor *buffer, 325#ifdef __LP64__ 326 IOStorageAttributes *attributes, 327 IOStorageCompletion *completion, 328#else /* !__LP64__ */ 329 IOStorageCompletion completion, 330#endif /* !__LP64__ */ 331 IOBlockStorageDriver::Context *context) 332{ 333 UInt32 block; 334 UInt32 nblks; 335 IOReturn result; 336 337 if (!_mediaObject) { /* no media? you lose */ 338 complete(completion, kIOReturnNoMedia,0); 339 return; 340 } 341 342 /* We know that we are never called with a request too large, 343 * nor one that is misaligned with a block. 344 */ 345 assert((byteStart % context->block.size) == 0); 346 assert((buffer->getLength() % context->block.size) == 0); 347 348 block = byteStart / context->block.size; 349 nblks = buffer->getLength() / context->block.size; 350 351/* Now the protocol-specific provider implements the actual 352 * start of the data transfer: */ 353 354 if (context->block.type == kBlockTypeCD) { 355 /* Some drives have firmware that performs better at audio reads when 356 * the block type is specifically set to CDDA, rather than "unknown"; 357 * this is a temporary measure until all clients cut over to the CDDA 358 * based APIs; this measure should not be depended upon in the future. 359 */ 360 if (context->block.typeSub[1] == kCDSectorTypeUnknown && 361 block >= _minBlockNumberAudio && 362 block + nblks - 1 <= _maxBlockNumberAudio) { 363 context->block.typeSub[1] = kCDSectorTypeCDDA; 364 365 if (context->block.typeSub[0] & 0xF8) { 366 context->block.typeSub[0] &= ~(0xF8); 367 context->block.typeSub[0] |= kCDSectorAreaUser; 368 } 369 } 370 371 if (buffer->getDirection() == kIODirectionIn) { 372 result = getProvider()->doAsyncReadCD(buffer,block,nblks, 373 (CDSectorArea)context->block.typeSub[0], 374 (CDSectorType)context->block.typeSub[1], 375#ifdef __LP64__ 376 completion ? *completion : (IOStorageCompletion) { 0 }); 377#else /* !__LP64__ */ 378 completion); 379#endif /* !__LP64__ */ 380 } else { 381 complete(completion,kIOReturnUnsupported); 382 return; 383 } 384 } else { 385#ifdef __LP64__ 386 result = getProvider()->doAsyncReadWrite(buffer,block,nblks,attributes,completion); 387#else /* !__LP64__ */ 388 result = getProvider()->doAsyncReadWrite(buffer,block,nblks,&context->request.attributes,&completion); 389#endif /* !__LP64__ */ 390 } 391 392 if (result != kIOReturnSuccess) { /* it failed to start */ 393 complete(completion,result); 394 return; 395 } 396} 397 398void 399IOCDBlockStorageDriver::free(void) 400{ 401 if (_expansionData) { 402 IODelete(_expansionData, ExpansionData, 1); 403 } 404 405 super::free(); 406} 407 408#ifndef __LP64__ 409IOReturn 410IOCDBlockStorageDriver::getAudioStatus(CDAudioStatus *status) 411{ 412 return(getProvider()->getAudioStatus(status)); 413} 414 415IOReturn 416IOCDBlockStorageDriver::getAudioVolume(UInt8 *leftVolume,UInt8 *rightVolume) 417{ 418 return(getProvider()->getAudioVolume(leftVolume,rightVolume)); 419} 420#endif /* !__LP64__ */ 421 422const char * 423IOCDBlockStorageDriver::getDeviceTypeName(void) 424{ 425 return(kIOBlockStorageDeviceTypeCDROM); 426} 427 428UInt64 429IOCDBlockStorageDriver::getMediaBlockSize(CDSectorArea area,CDSectorType type) 430{ 431 UInt64 blockSize = 0; 432 433 const SInt16 areaSize[kCDSectorTypeCount][8] = 434 { /* 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 */ 435 /* Unknown */ { 96, 294, 16, 280, 2048, 4, 8, 12 }, 436 /* CDDA */ { 96, 294, 16, 0, 2352, 0, 0, 0 }, 437 /* Mode1 */ { 96, 294, 16, 288, 2048, 4, 0, 12 }, 438 /* Mode2 */ { 96, 294, 16, 0, 2336, 4, 0, 12 }, 439 /* Mode2Form1 */ { 96, 294, 16, 280, 2048, 4, 8, 12 }, 440 /* Mode2Form2 */ { 96, 294, 16, 0, 2328, 4, 8, 12 }, 441 }; 442 443 if ( type >= kCDSectorTypeCount ) return 0; 444 445 for ( UInt32 index = 0; index < 8; index++ ) 446 { 447 if ( ((area >> index) & 0x01) ) 448 { 449 if ( areaSize[type][index] == -1 ) return 0; 450 blockSize += areaSize[type][index]; 451 } 452 } 453 454 return blockSize; 455} 456 457UInt32 458IOCDBlockStorageDriver::getMediaType(void) 459{ 460 return(_mediaType); 461} 462 463CDTOC * 464IOCDBlockStorageDriver::getTOC(void) 465{ 466 return(_toc); 467} 468 469bool 470IOCDBlockStorageDriver::init(OSDictionary * properties) 471{ 472 if (super::init(properties) == false) { 473 return false; 474 } 475 476 _expansionData = IONew(ExpansionData, 1); 477 478 if (_expansionData == NULL) { 479 return false; 480 } 481 482 _minBlockNumberAudio = 0; 483 _maxBlockNumberAudio = 0; 484#ifndef __LP64__ 485 _maxReadByteTransfer = 196608; 486 _maxWriteByteTransfer = 196608; 487#endif /* !__LP64__ */ 488 _toc = NULL; 489 _tocSize = 0; 490 491 return(true); 492} 493 494IOMedia * 495IOCDBlockStorageDriver::instantiateDesiredMediaObject(void) 496{ 497 return(new IOCDMedia); 498} 499 500IOMedia * 501IOCDBlockStorageDriver::instantiateMediaObject(UInt64 base,UInt64 byteSize, 502 UInt32 blockSize,char *mediaName) 503{ 504 IOMedia *media; 505 506 if (blockSize) { 507 byteSize /= blockSize; 508 byteSize *= kBlockSizeCD; 509 blockSize = kBlockSizeCD; 510 } 511 512 media = super::instantiateMediaObject(base,byteSize,blockSize,mediaName); 513 514 if (media) { 515 const char *description = NULL; 516 const char *picture = NULL; 517 518 switch (getMediaType()) { 519 case kCDMediaTypeROM: 520 description = kIOCDMediaTypeROM; 521 picture = "CD.icns"; 522 break; 523 case kCDMediaTypeR: 524 description = kIOCDMediaTypeR; 525 picture = "CD-R.icns"; 526 break; 527 case kCDMediaTypeRW: 528 description = kIOCDMediaTypeRW; 529 picture = "CD-RW.icns"; 530 break; 531 } 532 533 if (description) { 534 media->setProperty(kIOCDMediaTypeKey, description); 535 } 536 537 if (picture) { 538 OSDictionary *dictionary = OSDictionary::withCapacity(2); 539 OSString *identifier = OSString::withCString("com.apple.iokit.IOCDStorageFamily"); 540 OSString *resourceFile = OSString::withCString(picture); 541 542 if (dictionary && identifier && resourceFile) { 543 dictionary->setObject("CFBundleIdentifier", identifier); 544 dictionary->setObject("IOBundleResourceFile", resourceFile); 545 } 546 547 media->setProperty(kIOMediaIconKey, dictionary); 548 549 if (resourceFile) { 550 resourceFile->release(); 551 } 552 if (identifier) { 553 identifier->release(); 554 } 555 if (dictionary) { 556 dictionary->release(); 557 } 558 } 559 560 if (_toc) { 561 media->setProperty(kIOCDMediaTOCKey,(void*)_toc,_tocSize); 562 } 563 } 564 565 return media; 566} 567 568void 569IOCDBlockStorageDriver::readCD(IOService *client, 570 UInt64 byteStart, 571 IOMemoryDescriptor *buffer, 572 CDSectorArea sectorArea, 573 CDSectorType sectorType, 574#ifdef __LP64__ 575 IOStorageAttributes *attributes, 576 IOStorageCompletion *completion) 577#else /* !__LP64__ */ 578 IOStorageCompletion completion) 579#endif /* !__LP64__ */ 580{ 581 assert(buffer->getDirection() == kIODirectionIn); 582 583#ifdef __LP64__ 584 prepareRequest(byteStart, buffer, sectorArea, sectorType, attributes, completion); 585#else /* !__LP64__ */ 586 prepareRequest(byteStart, buffer, sectorArea, sectorType, completion); 587#endif /* !__LP64__ */ 588} 589 590IOReturn 591IOCDBlockStorageDriver::reportDiscInfo(CDDiscInfo *discInfo) 592{ 593 IOMemoryDescriptor *buffer; 594 IOReturn result; 595 UInt16 discInfoSize; 596 597 bzero(discInfo,sizeof(CDDiscInfo)); 598 599 /* Read the Disc Information in full: */ 600 601 buffer = IOMemoryDescriptor::withAddress(discInfo,sizeof(CDDiscInfo),kIODirectionIn); 602 if (buffer == NULL) { 603 return(kIOReturnNoMemory); 604 } 605 606 result = getProvider()->readDiscInfo(buffer,&discInfoSize); 607 if (result != kIOReturnSuccess) { 608 buffer->release(); 609 return(result); 610 } 611 612 buffer->release(); 613 614 /* Reject the Disc Information if its size is too small: */ 615 616 if (discInfoSize < sizeof(CDDiscInfo)) { 617 return(kIOReturnNotFound); 618 } 619 620 discInfoSize = OSSwapBigToHostInt16(discInfo->dataLength) + sizeof(discInfo->dataLength); 621 622 if (discInfoSize < sizeof(CDDiscInfo)) { 623 return(kIOReturnNotFound); 624 } 625 626 return(result); 627} 628 629IOReturn 630IOCDBlockStorageDriver::reportTrackInfo(UInt16 track,CDTrackInfo *trackInfo) 631{ 632 IOMemoryDescriptor *buffer; 633 IOReturn result; 634 UInt16 trackInfoSize; 635 636 bzero(trackInfo,sizeof(CDTrackInfo)); 637 638 /* Read the Track Information in full: */ 639 640 buffer = IOMemoryDescriptor::withAddress(trackInfo,sizeof(CDTrackInfo),kIODirectionIn); 641 if (buffer == NULL) { 642 return(kIOReturnNoMemory); 643 } 644 645 result = getProvider()->readTrackInfo(buffer,track,kCDTrackInfoAddressTypeTrackNumber,&trackInfoSize); 646 if (result != kIOReturnSuccess) { 647 buffer->release(); 648 return(result); 649 } 650 651 buffer->release(); 652 653 /* Reject the Track Information if its size is too small: */ 654 655 if (trackInfoSize < offsetof(CDTrackInfo, lastRecordedAddress)) { 656 return(kIOReturnNotFound); 657 } 658 659 trackInfoSize = OSSwapBigToHostInt16(trackInfo->dataLength) + sizeof(trackInfo->dataLength); 660 661 if (trackInfoSize < offsetof(CDTrackInfo, lastRecordedAddress)) { 662 return(kIOReturnNotFound); 663 } 664 665 return(result); 666} 667 668void 669IOCDBlockStorageDriver::prepareRequest(UInt64 byteStart, 670 IOMemoryDescriptor *buffer, 671 CDSectorArea sectorArea, 672 CDSectorType sectorType, 673#ifdef __LP64__ 674 IOStorageAttributes *attributes, 675 IOStorageCompletion *completion) 676#else /* !__LP64__ */ 677 IOStorageCompletion completion) 678#endif /* !__LP64__ */ 679{ 680 IOStorageCompletion completionOut; 681 Context * context; 682 683 // Determine whether an undefined sector area was specified. 684 685 if ((sectorArea & 0xFF) == 0x00 || (sectorArea & 0x05) == 0x05) 686 { 687 complete(completion, kIOReturnBadArgument); 688 return; 689 } 690 691 // Determine whether an undefined sector type was specified. 692 693 if (sectorType >= kCDSectorTypeCount) 694 { 695 complete(completion, kIOReturnBadArgument); 696 return; 697 } 698 699 // For a transfer that involves an unknown sector type, the sector area must 700 // not describe a vague sector size (and hence, a vague transfer size). The 701 // SYNC, HEADER, SUBHEADER, USER and AUXILIARY sector areas differ in length 702 // from one sector type to the next. All together, however, the same sector 703 // areas describe a consistent sector size from one sector type to the next, 704 // hence we permit either all the above sector areas to be specified at once 705 // or none to be specified at all. The other sector areas are consistent in 706 // size from one sector type to the next, hence need not be considered here. 707 708 if (sectorType == kCDSectorTypeUnknown) 709 { 710 if ((sectorArea & 0xF8) != 0x00 && (sectorArea & 0xF8) != 0xF8) 711 { 712 complete(completion, kIOReturnBadArgument); 713 return; 714 } 715 } 716 717 // Allocate a context structure to hold some of our state. 718 719 context = allocateContext(); 720 721 if (context == 0) 722 { 723 complete(completion, kIOReturnNoMemory); 724 return; 725 } 726 727 // Fill in the context structure with some of our state. 728 729 if ( ( sectorArea == kCDSectorAreaUser ) && 730 ( sectorType == kCDSectorTypeMode1 || 731 sectorType == kCDSectorTypeMode2Form1 ) ) 732 { 733 context->block.size = getMediaBlockSize(); 734 context->block.type = kBlockTypeStandard; 735 } 736 else 737 { 738 context->block.size = getMediaBlockSize(sectorArea, sectorType); 739 context->block.type = kBlockTypeCD; 740 context->block.typeSub[0] = sectorArea; 741 context->block.typeSub[1] = sectorType; 742 } 743 744 context->original.byteStart = byteStart; 745 context->original.buffer = buffer; 746 context->original.buffer->retain(); 747 748#ifdef __LP64__ 749 if (attributes) context->request.attributes = *attributes; 750 if (completion) context->request.completion = *completion; 751#else /* !__LP64__ */ 752 context->original.completion = completion; 753#endif /* !__LP64__ */ 754 755 clock_get_uptime(&context->timeStart); 756 757 completionOut.target = this; 758 completionOut.action = prepareRequestCompletion; 759 completionOut.parameter = context; 760 761 // Deblock the transfer. 762 763#ifdef __LP64__ 764 deblockRequest(byteStart, buffer, attributes, &completionOut, context); 765#else /* !__LP64__ */ 766 deblockRequest(byteStart, buffer, completionOut, context); 767#endif /* !__LP64__ */ 768} 769 770IOReturn 771IOCDBlockStorageDriver::readISRC(UInt8 track,CDISRC isrc) 772{ 773 return(getProvider()->readISRC(track,isrc)); 774} 775 776IOReturn 777IOCDBlockStorageDriver::readMCN(CDMCN mcn) 778{ 779 return(getProvider()->readMCN(mcn)); 780} 781 782IOReturn 783IOCDBlockStorageDriver::recordMediaParameters(void) 784{ 785 IOReturn result; 786 787 result = super::recordMediaParameters(); 788 if (result != kIOReturnSuccess) { 789 return(result); 790 } 791 792 _mediaType = getProvider()->getMediaType(); 793 794 return(kIOReturnSuccess); 795} 796 797#ifndef __LP64__ 798IOReturn 799IOCDBlockStorageDriver::setAudioVolume(UInt8 leftVolume,UInt8 rightVolume) 800{ 801 return(getProvider()->setAudioVolume(leftVolume,rightVolume)); 802} 803#endif /* !__LP64__ */ 804 805IOReturn 806IOCDBlockStorageDriver::getSpeed(UInt16 * kilobytesPerSecond) 807{ 808 return(getProvider()->getSpeed(kilobytesPerSecond)); 809} 810 811IOReturn 812IOCDBlockStorageDriver::setSpeed(UInt16 kilobytesPerSecond) 813{ 814 return(getProvider()->setSpeed(kilobytesPerSecond)); 815} 816 817IOReturn 818IOCDBlockStorageDriver::readTOC(IOMemoryDescriptor *buffer,CDTOCFormat format, 819 UInt8 formatAsTime,UInt8 trackOrSessionNumber, 820 UInt16 *actualByteCount) 821{ 822 return(getProvider()->readTOC(buffer,format,formatAsTime,trackOrSessionNumber,actualByteCount)); 823} 824 825IOReturn 826IOCDBlockStorageDriver::readDiscInfo(IOMemoryDescriptor *buffer, 827 UInt16 *actualByteCount) 828{ 829 return(getProvider()->readDiscInfo(buffer,actualByteCount)); 830} 831 832IOReturn 833IOCDBlockStorageDriver::readTrackInfo(IOMemoryDescriptor *buffer,UInt32 address, 834 CDTrackInfoAddressType addressType, 835 UInt16 *actualByteCount) 836{ 837 return(getProvider()->readTrackInfo(buffer,address,addressType,actualByteCount)); 838} 839 840void 841IOCDBlockStorageDriver::writeCD(IOService *client, 842 UInt64 byteStart, 843 IOMemoryDescriptor *buffer, 844 CDSectorArea sectorArea, 845 CDSectorType sectorType, 846#ifdef __LP64__ 847 IOStorageAttributes *attributes, 848 IOStorageCompletion *completion) 849#else /* !__LP64__ */ 850 IOStorageCompletion completion) 851#endif /* !__LP64__ */ 852{ 853 assert(buffer->getDirection() == kIODirectionOut); 854 855#ifdef __LP64__ 856 prepareRequest(byteStart, buffer, sectorArea, sectorType, attributes, completion); 857#else /* !__LP64__ */ 858 prepareRequest(byteStart, buffer, sectorArea, sectorType, completion); 859#endif /* !__LP64__ */ 860} 861 862#ifdef __LP64__ 863OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 0); 864OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 1); 865OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 2); 866OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 3); 867OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 4); 868OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 5); 869#else /* !__LP64__ */ 870OSMetaClassDefineReservedUsed(IOCDBlockStorageDriver, 0); 871OSMetaClassDefineReservedUsed(IOCDBlockStorageDriver, 1); 872OSMetaClassDefineReservedUsed(IOCDBlockStorageDriver, 2); 873OSMetaClassDefineReservedUsed(IOCDBlockStorageDriver, 3); 874OSMetaClassDefineReservedUsed(IOCDBlockStorageDriver, 4); 875OSMetaClassDefineReservedUsed(IOCDBlockStorageDriver, 5); 876#endif /* !__LP64__ */ 877OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 6); 878OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 7); 879OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 8); 880OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 9); 881OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 10); 882OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 11); 883OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 12); 884OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 13); 885OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 14); 886OSMetaClassDefineReservedUnused(IOCDBlockStorageDriver, 15); 887