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/IODVDBlockStorageDevice.h> 27#include <IOKit/storage/IODVDBlockStorageDriver.h> 28#include <IOKit/storage/IODVDMedia.h> 29 30#define super IOCDBlockStorageDriver 31OSDefineMetaClassAndStructors(IODVDBlockStorageDriver,IOCDBlockStorageDriver) 32 33OSCompileAssert(sizeof(DVDDiscInfo) == sizeof(CDDiscInfo)); 34OSCompileAssert(sizeof(DVDRZoneInfo) == sizeof(CDTrackInfo)); 35 36#define reportDiscInfo(x) reportDiscInfo((CDDiscInfo *)(x)) 37#define reportRZoneInfo(y,x) reportTrackInfo((y),(CDTrackInfo *)(x)) 38 39IODVDBlockStorageDevice * 40IODVDBlockStorageDriver::getProvider() const 41{ 42 return (IODVDBlockStorageDevice *) IOService::getProvider(); 43} 44 45/* Accept a new piece of media, doing whatever's necessary to make it 46 * show up properly to the system. 47 */ 48IOReturn 49IODVDBlockStorageDriver::acceptNewMedia(void) 50{ 51 IOReturn result; 52 53 if (getMediaType() < kDVDMediaTypeMin || getMediaType() > kDVDMediaTypeMax) { 54 return super::acceptNewMedia(); 55 } 56 57 /* Obtain disc status: */ 58 59 switch (getMediaType()) { 60 case kDVDMediaTypeR: 61 case kDVDMediaTypeRW: { 62 bool checkIsWritable = false; 63 DVDDiscInfo discInfo; 64 DVDRZoneInfo rzoneInfo; 65 66 result = reportDiscInfo(&discInfo); 67 if (result != kIOReturnSuccess) { 68 break; 69 } 70 71 switch (discInfo.discStatus) { 72 case 0x01: /* is disc incomplete? */ 73 checkIsWritable = true; 74 break; 75 case 0x02: /* is disc complete? */ 76 checkIsWritable = discInfo.erasable ? true : false; 77 break; 78 } 79 80 /* Obtain rzone status: */ 81 82 if (checkIsWritable) { 83 UInt16 rzoneLast = (discInfo.lastRZoneNumberInLastBorderMSB << 8) | 84 discInfo.lastRZoneNumberInLastBorderLSB; 85 86 result = reportRZoneInfo(rzoneLast,&rzoneInfo); 87 if (result != kIOReturnSuccess) { 88 break; 89 } 90 91 if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ 92 _maxBlockNumber = max( _maxBlockNumber, 93 max( OSSwapBigToHostInt32(rzoneInfo.rzoneStartAddress) + 94 OSSwapBigToHostInt32(rzoneInfo.rzoneSize), 1 ) - 1 ); 95 } 96 97 if (rzoneInfo.incremental) { /* is rzone incremental? */ 98 _writeProtected = false; 99 break; 100 } 101 102 if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ 103 if (rzoneInfo.blank) { /* is rzone invisible? */ 104 UInt16 rzoneFirst = (discInfo.firstRZoneNumberInLastBorderMSB << 8) | 105 discInfo.firstRZoneNumberInLastBorderLSB; 106 107 if (rzoneFirst < rzoneLast) { 108 result = reportRZoneInfo(rzoneLast - 1,&rzoneInfo); 109 if (result != kIOReturnSuccess) { 110 break; 111 } 112 113 if (rzoneInfo.incremental) { /* is rzone incremental? */ 114 _writeProtected = false; 115 break; 116 } 117 } 118 } 119 } 120 } 121 122 break; 123 } 124 case kDVDMediaTypePlusR: 125 case kDVDMediaTypeHDR: { 126 DVDDiscInfo discInfo; 127 DVDRZoneInfo rzoneInfo; 128 IOReturn result; 129 130 result = reportDiscInfo(&discInfo); 131 if (result != kIOReturnSuccess) { 132 break; 133 } 134 135 /* Obtain rzone status: */ 136 137 if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ 138 UInt16 rzoneLast = (discInfo.lastRZoneNumberInLastBorderMSB << 8) | 139 discInfo.lastRZoneNumberInLastBorderLSB; 140 141 _writeProtected = false; 142 143 result = reportRZoneInfo(rzoneLast,&rzoneInfo); 144 if (result != kIOReturnSuccess) { 145 break; 146 } 147 148 _maxBlockNumber = max( _maxBlockNumber, 149 max( OSSwapBigToHostInt32(rzoneInfo.rzoneStartAddress) + 150 OSSwapBigToHostInt32(rzoneInfo.rzoneSize), 1 ) - 1 ); 151 } 152 153 break; 154 } 155 } 156 157 return IOBlockStorageDriver::acceptNewMedia(); 158} 159 160const char * 161IODVDBlockStorageDriver::getDeviceTypeName(void) 162{ 163 return(kIOBlockStorageDeviceTypeDVD); 164} 165 166IOMedia * 167IODVDBlockStorageDriver::instantiateDesiredMediaObject(void) 168{ 169 if (getMediaType() < kDVDMediaTypeMin || getMediaType() > kDVDMediaTypeMax) { 170 return super::instantiateDesiredMediaObject(); 171 } 172 173 return(new IODVDMedia); 174} 175 176IOMedia * 177IODVDBlockStorageDriver::instantiateMediaObject(UInt64 base,UInt64 byteSize, 178 UInt32 blockSize,char *mediaName) 179{ 180 IOMedia *media = NULL; 181 182 if (getMediaType() < kDVDMediaTypeMin || getMediaType() > kDVDMediaTypeMax) { 183 return super::instantiateMediaObject(base,byteSize,blockSize,mediaName); 184 } 185 186 media = IOBlockStorageDriver::instantiateMediaObject( 187 base,byteSize,blockSize,mediaName); 188 189 if (media) { 190 const char *description = NULL; 191 const char *picture = NULL; 192 193 switch (getMediaType()) { 194 case kDVDMediaTypeROM: 195 description = kIODVDMediaTypeROM; 196 picture = "DVD.icns"; 197 break; 198 case kDVDMediaTypeRAM: 199 description = kIODVDMediaTypeRAM; 200 picture = "DVD-RAM.icns"; 201 break; 202 case kDVDMediaTypeR: 203 description = kIODVDMediaTypeR; 204 picture = "DVD-R.icns"; 205 break; 206 case kDVDMediaTypeRW: 207 description = kIODVDMediaTypeRW; 208 picture = "DVD-RW.icns"; 209 break; 210 case kDVDMediaTypePlusR: 211 description = kIODVDMediaTypePlusR; 212 picture = "DVD+R.icns"; 213 break; 214 case kDVDMediaTypePlusRW: 215 description = kIODVDMediaTypePlusRW; 216 picture = "DVD+RW.icns"; 217 break; 218 case kDVDMediaTypeHDROM: 219 description = kIODVDMediaTypeHDROM; 220 picture = "DVD.icns"; 221 break; 222 case kDVDMediaTypeHDRAM: 223 description = kIODVDMediaTypeHDRAM; 224 picture = "DVD-RAM.icns"; 225 break; 226 case kDVDMediaTypeHDR: 227 description = kIODVDMediaTypeHDR; 228 picture = "DVD-R.icns"; 229 break; 230 case kDVDMediaTypeHDRW: 231 description = kIODVDMediaTypeHDRW; 232 picture = "DVD-RW.icns"; 233 break; 234 } 235 236 if (description) { 237 media->setProperty(kIODVDMediaTypeKey, description); 238 } 239 240 if (picture) { 241 OSDictionary *dictionary = OSDictionary::withCapacity(2); 242 OSString *identifier = OSString::withCString("com.apple.iokit.IODVDStorageFamily"); 243 OSString *resourceFile = OSString::withCString(picture); 244 245 if (dictionary && identifier && resourceFile) { 246 dictionary->setObject("CFBundleIdentifier", identifier); 247 dictionary->setObject("IOBundleResourceFile", resourceFile); 248 } 249 250 media->setProperty(kIOMediaIconKey, dictionary); 251 252 if (resourceFile) { 253 resourceFile->release(); 254 } 255 if (identifier) { 256 identifier->release(); 257 } 258 if (dictionary) { 259 dictionary->release(); 260 } 261 } 262 } 263 264 return media; 265} 266 267IOReturn 268IODVDBlockStorageDriver::reportKey(IOMemoryDescriptor *buffer,const DVDKeyClass keyClass, 269 const UInt32 lba,const UInt8 agid,const DVDKeyFormat keyFormat) 270{ 271 return(getProvider()->reportKey(buffer,keyClass,lba,agid,keyFormat)); 272} 273 274IOReturn 275IODVDBlockStorageDriver::sendKey(IOMemoryDescriptor *buffer,const DVDKeyClass keyClass, 276 const UInt8 agid,const DVDKeyFormat keyFormat) 277{ 278 return(getProvider()->sendKey(buffer,keyClass,agid,keyFormat)); 279} 280 281IOReturn 282IODVDBlockStorageDriver::readStructure(IOMemoryDescriptor *buffer,const DVDStructureFormat format, 283 const UInt32 address,const UInt8 layer,const UInt8 agid) 284{ 285 return(getProvider()->readDVDStructure(buffer,format,address,layer,agid)); 286} 287 288#ifdef __LP64__ 289OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 0); 290#else /* !__LP64__ */ 291OSMetaClassDefineReservedUsed(IODVDBlockStorageDriver, 0); 292#endif /* !__LP64__ */ 293OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 1); 294OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 2); 295OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 3); 296OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 4); 297OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 5); 298OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 6); 299OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 7); 300OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 8); 301OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 9); 302OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 10); 303OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 11); 304OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 12); 305OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 13); 306OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 14); 307OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 15); 308OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 16); 309OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 17); 310OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 18); 311OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 19); 312OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 20); 313OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 21); 314OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 22); 315OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 23); 316OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 24); 317OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 25); 318OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 26); 319OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 27); 320OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 28); 321OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 29); 322OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 30); 323OSMetaClassDefineReservedUnused(IODVDBlockStorageDriver, 31); 324