1/* 2 * Copyright (c) 1998-2013 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/*! 25 * @header IOStorage 26 * @abstract 27 * This header contains the IOStorage class definition. 28 */ 29 30#ifndef _IOSTORAGE_H 31#define _IOSTORAGE_H 32 33#include <sys/kernel_types.h> 34#include <IOKit/IOTypes.h> 35 36/*! 37 * @defined kIOStorageClass 38 * @abstract 39 * The name of the IOStorage class. 40 */ 41 42#define kIOStorageClass "IOStorage" 43 44/*! 45 * @defined kIOStorageCategory 46 * @abstract 47 * kIOStorageCategory is a value for IOService's kIOMatchCategoryKey property. 48 * @discussion 49 * The kIOStorageCategory value is the standard value for the IOService property 50 * kIOMatchCategoryKey ("IOMatchCategory") for all storage drivers. All storage 51 * objects that expect to drive new content (that is, produce new media objects) 52 * are expected to compete within the kIOStorageCategory namespace. 53 * 54 * See the IOService documentation for more information on match categories. 55 */ 56 57#define kIOStorageCategory "IOStorage" /* (as IOMatchCategory) */ 58 59/*! 60 * @defined kIOStorageFeaturesKey 61 * @abstract 62 * A property of any object in the storage stack. 63 * @discussion 64 * kIOStorageFeaturesKey is a property of any object in the storage stack that 65 * wishes to express support of additional features, such as Force Unit Access. 66 * It is typically defined in the device object below the block storage driver 67 * object. It has an OSDictionary value, where each entry describes one given 68 * feature. 69 */ 70 71#define kIOStorageFeaturesKey "IOStorageFeatures" 72 73/*! 74 * @defined kIOStorageFeatureUnmap 75 * @abstract 76 * Describes the presence of the Unmap feature. 77 * @discussion 78 * This property describes the ability of the storage stack to delete unused 79 * data from the media. It is one of the feature entries listed under the top- 80 * level kIOStorageFeaturesKey property table. It has an OSBoolean value. 81 */ 82 83#define kIOStorageFeatureUnmap "Unmap" 84 85/*! 86 * @defined kIOStorageFeatureForceUnitAccess 87 * @abstract 88 * Describes the presence of the Force Unit Access feature. 89 * @discussion 90 * This property describes the ability of the storage stack to force a request 91 * to access the media. It is one of the feature entries listed under the top- 92 * level kIOStorageFeaturesKey property table. It has an OSBoolean value. 93 */ 94 95#define kIOStorageFeatureForceUnitAccess "Force Unit Access" 96 97#ifdef KERNEL 98#ifdef __cplusplus 99 100/* 101 * Kernel 102 */ 103 104#include <IOKit/assert.h> 105#include <IOKit/IOMemoryDescriptor.h> 106#include <IOKit/IOService.h> 107 108/*! 109 * @enum IOStorageAccess 110 * @discussion 111 * The IOStorageAccess enumeration describes the possible access levels for open 112 * requests. 113 * @constant kIOStorageAccessNone 114 * No access is requested; should not be passed to open(). 115 * @constant kIOStorageAccessReader 116 * Read-only access is requested. 117 * @constant kIOStorageAccessReaderWriter 118 * Read and write access is requested. 119 * @constant kIOStorageAccessSharedLock 120 * Shared access is requested. 121 * @constant kIOStorageAccessExclusiveLock 122 * Exclusive access is requested. 123 */ 124 125enum 126{ 127 kIOStorageAccessNone = 0x00, 128 kIOStorageAccessReader = 0x01, 129 kIOStorageAccessReaderWriter = 0x03, 130 kIOStorageAccessSharedLock = 0x04, 131 kIOStorageAccessExclusiveLock = 0x08 132}; 133 134typedef UInt32 IOStorageAccess; 135 136/*! 137 * @enum IOStorageOptions 138 * @discussion 139 * Options for read and write storage requests. 140 * @constant kIOStorageOptionForceUnitAccess 141 * Force the request to access the media. 142 * @constant kIOStorageOptionIsEncrypted 143 * The data is already encrypted. 144 * @constant kIOStorageOptionIsStatic 145 * The data is likely to remain unaltered. 146 */ 147 148enum 149{ 150 kIOStorageOptionNone = 0x00000000, 151 kIOStorageOptionForceUnitAccess = 0x00000001, 152 kIOStorageOptionIsEncrypted = 0x00000010, 153 kIOStorageOptionIsStatic = 0x00000020, 154 kIOStorageOptionReserved = 0xFFFFFFCE 155}; 156 157typedef UInt32 IOStorageOptions; 158 159/*! 160 * @struct IOStorageAttributes 161 * @discussion 162 * Attributes of read and write storage requests. 163 * @field options 164 * Options for the request. See IOStorageOptions. 165 * @field bufattr 166 * Reserved for future use. Set to zero. 167 */ 168 169struct IOStorageAttributes 170{ 171 IOStorageOptions options; 172#ifdef __LP64__ 173 UInt32 reserved0032; 174 UInt64 reserved0064; 175 UInt64 reserved0128; 176 bufattr_t bufattr; 177#if TARGET_OS_EMBEDDED 178 UInt64 adjustedOffset; 179#endif /* TARGET_OS_EMBEDDED */ 180#else /* !__LP64__ */ 181 bufattr_t bufattr; 182#if TARGET_OS_EMBEDDED 183 UInt64 adjustedOffset; 184#else /* !TARGET_OS_EMBEDDED */ 185 UInt64 reserved0064; 186#endif /* !TARGET_OS_EMBEDDED */ 187#endif /* !__LP64__ */ 188}; 189 190/*! 191 * @struct IOStorageExtent 192 * @discussion 193 * Extent for unmap storage requests. 194 * @field byteStart 195 * Starting byte offset for the operation. 196 * @field byteCount 197 * Size of the operation. 198 */ 199 200struct IOStorageExtent 201{ 202 UInt64 byteStart; 203 UInt64 byteCount; 204}; 205 206/*! 207 * @typedef IOStorageCompletionAction 208 * @discussion 209 * The IOStorageCompletionAction declaration describes the C (or C++) completion 210 * routine that is called once an asynchronous storage operation completes. 211 * @param target 212 * Opaque client-supplied pointer (or an instance pointer for a C++ callback). 213 * @param parameter 214 * Opaque client-supplied pointer. 215 * @param status 216 * Status of the data transfer. 217 * @param actualByteCount 218 * Actual number of bytes transferred in the data transfer. 219 */ 220 221typedef void (*IOStorageCompletionAction)(void * target, 222 void * parameter, 223 IOReturn status, 224 UInt64 actualByteCount); 225 226/*! 227 * @struct IOStorageCompletion 228 * @discussion 229 * The IOStorageCompletion structure describes the C (or C++) completion routine 230 * that is called once an asynchronous storage operation completes. The values 231 * passed for the target and parameter fields will be passed to the routine when 232 * it is called. 233 * @field target 234 * Opaque client-supplied pointer (or an instance pointer for a C++ callback). 235 * @field action 236 * Completion routine to call on completion of the data transfer. 237 * @field parameter 238 * Opaque client-supplied pointer. 239 */ 240 241struct IOStorageCompletion 242{ 243 void * target; 244 IOStorageCompletionAction action; 245 void * parameter; 246}; 247 248/*! 249 * @class IOStorage 250 * @abstract 251 * The common base class for mass storage objects. 252 * @discussion 253 * The IOStorage class is the common base class for mass storage objects. It is 254 * an abstract class that defines the open/close/read/write APIs that need to be 255 * implemented in a given subclass. Synchronous versions of the read/write APIs 256 * are provided here -- they are coded in such a way as to wrap the asynchronous 257 * versions implemented in the subclass. 258 */ 259 260class IOStorage : public IOService 261{ 262 OSDeclareAbstractStructors(IOStorage); 263 264protected: 265 266 struct ExpansionData { /* */ }; 267 ExpansionData * _expansionData; 268 269 /*! 270 * @function handleOpen 271 * @discussion 272 * The handleOpen method grants or denies permission to access this object 273 * to an interested client. The argument is an IOStorageAccess value that 274 * specifies the level of access desired -- reader or reader-writer. 275 * 276 * This method can be invoked to upgrade or downgrade the access level for 277 * an existing client as well. The previous access level will prevail for 278 * upgrades that fail, of course. A downgrade should never fail. If the 279 * new access level should be the same as the old for a given client, this 280 * method will do nothing and return success. In all cases, one, singular 281 * close-per-client is expected for all opens-per-client received. 282 * @param client 283 * Client requesting the open. 284 * @param options 285 * Options for the open. Set to zero. 286 * @param access 287 * Access level for the open. Set to kIOStorageAccessReader or 288 * kIOStorageAccessReaderWriter. 289 * @result 290 * Returns true if the open was successful, false otherwise. 291 */ 292 293 virtual bool handleOpen(IOService * client, 294 IOOptionBits options, 295 void * access) = 0; 296 297 /*! 298 * @function handleIsOpen 299 * @discussion 300 * The handleIsOpen method determines whether the specified client, or any 301 * client if none is specified, presently has an open on this object. 302 * @param client 303 * Client to check the open state of. Set to zero to check the open state 304 * of all clients. 305 * @result 306 * Returns true if the client was (or clients were) open, false otherwise. 307 */ 308 309 virtual bool handleIsOpen(const IOService * client) const = 0; 310 311 /*! 312 * @function handleClose 313 * @discussion 314 * The handleClose method closes the client's access to this object. 315 * @param client 316 * Client requesting the close. 317 * @param options 318 * Options for the close. Set to zero. 319 */ 320 321 virtual void handleClose(IOService * client, IOOptionBits options) = 0; 322 323public: 324 325#ifndef __LP64__ 326 /* 327 * Initialize this object's minimal state. 328 */ 329 330 virtual bool init(OSDictionary * properties = 0); 331#endif /* !__LP64__ */ 332 333 /*! 334 * @function complete 335 * @discussion 336 * Invokes the specified completion action of the read/write request. If 337 * the completion action is unspecified, no action is taken. This method 338 * serves simply as a convenience to storage subclass developers. 339 * @param completion 340 * Completion information for the data transfer. 341 * @param status 342 * Status of the data transfer. 343 * @param actualByteCount 344 * Actual number of bytes transferred in the data transfer. 345 */ 346 347 static void complete(IOStorageCompletion * completion, 348 IOReturn status, 349 UInt64 actualByteCount = 0); 350 351#ifndef __LP64__ 352 static void complete(IOStorageCompletion completion, 353 IOReturn status, 354 UInt64 actualByteCount = 0); /* DEPRECATED */ 355#endif /* !__LP64__ */ 356 357 /*! 358 * @function open 359 * @discussion 360 * Ask the storage object for permission to access its contents; the method 361 * is equivalent to IOService::open(), but with the correct parameter types. 362 * 363 * This method may also be invoked to upgrade or downgrade the access of an 364 * existing open (if it fails, the existing open prevails). 365 * @param client 366 * Client requesting the open. 367 * @param options 368 * Options for the open. Set to zero. 369 * @param access 370 * Access level for the open. Set to kIOStorageAccessReader or 371 * kIOStorageAccessReaderWriter. 372 * @result 373 * Returns true if the open was successful, false otherwise. 374 */ 375 376 virtual bool open(IOService * client, 377 IOOptionBits options, 378 IOStorageAccess access); 379 380#ifndef __LP64__ 381 virtual void read(IOService * client, 382 UInt64 byteStart, 383 IOMemoryDescriptor * buffer, 384 IOStorageCompletion completion) __attribute__ ((deprecated)); 385 386 virtual void write(IOService * client, 387 UInt64 byteStart, 388 IOMemoryDescriptor * buffer, 389 IOStorageCompletion completion) __attribute__ ((deprecated)); 390#endif /* !__LP64__ */ 391 392 /*! 393 * @function read 394 * @discussion 395 * Read data from the storage object at the specified byte offset into the 396 * specified buffer, synchronously. When the read completes, this method 397 * will return to the caller. The actual byte count field is optional. 398 * @param client 399 * Client requesting the read. 400 * @param byteStart 401 * Starting byte offset for the data transfer. 402 * @param buffer 403 * Buffer for the data transfer. The size of the buffer implies the size of 404 * the data transfer. 405 * @param attributes 406 * Attributes of the data transfer. See IOStorageAttributes. 407 * @param actualByteCount 408 * Returns the actual number of bytes transferred in the data transfer. 409 * @result 410 * Returns the status of the data transfer. 411 */ 412 413#ifdef __LP64__ 414 virtual IOReturn read(IOService * client, 415 UInt64 byteStart, 416 IOMemoryDescriptor * buffer, 417 IOStorageAttributes * attributes = 0, 418 UInt64 * actualByteCount = 0); 419#else /* !__LP64__ */ 420 virtual IOReturn read(IOService * client, 421 UInt64 byteStart, 422 IOMemoryDescriptor * buffer, 423 UInt64 * actualByteCount = 0); 424#endif /* !__LP64__ */ 425 426 /*! 427 * @function write 428 * @discussion 429 * Write data into the storage object at the specified byte offset from the 430 * specified buffer, synchronously. When the write completes, this method 431 * will return to the caller. The actual byte count field is optional. 432 * @param client 433 * Client requesting the write. 434 * @param byteStart 435 * Starting byte offset for the data transfer. 436 * @param buffer 437 * Buffer for the data transfer. The size of the buffer implies the size of 438 * the data transfer. 439 * @param attributes 440 * Attributes of the data transfer. See IOStorageAttributes. 441 * @param actualByteCount 442 * Returns the actual number of bytes transferred in the data transfer. 443 * @result 444 * Returns the status of the data transfer. 445 */ 446 447#ifdef __LP64__ 448 virtual IOReturn write(IOService * client, 449 UInt64 byteStart, 450 IOMemoryDescriptor * buffer, 451 IOStorageAttributes * attributes = 0, 452 UInt64 * actualByteCount = 0); 453#else /* !__LP64__ */ 454 virtual IOReturn write(IOService * client, 455 UInt64 byteStart, 456 IOMemoryDescriptor * buffer, 457 UInt64 * actualByteCount = 0); 458#endif /* !__LP64__ */ 459 460 /*! 461 * @function synchronizeCache 462 * @discussion 463 * Flush the cached data in the storage object, if any, synchronously. 464 * @param client 465 * Client requesting the cache synchronization. 466 * @result 467 * Returns the status of the cache synchronization. 468 */ 469 470 virtual IOReturn synchronizeCache(IOService * client) = 0; 471 472 /*! 473 * @function read 474 * @discussion 475 * Read data from the storage object at the specified byte offset into the 476 * specified buffer, asynchronously. When the read completes, the caller 477 * will be notified via the specified completion action. 478 * 479 * The buffer will be retained for the duration of the read. 480 * @param client 481 * Client requesting the read. 482 * @param byteStart 483 * Starting byte offset for the data transfer. 484 * @param buffer 485 * Buffer for the data transfer. The size of the buffer implies the size of 486 * the data transfer. 487 * @param attributes 488 * Attributes of the data transfer. See IOStorageAttributes. It is the 489 * responsibility of the callee to maintain the information for the duration 490 * of the data transfer, as necessary. 491 * @param completion 492 * Completion routine to call once the data transfer is complete. It is the 493 * responsibility of the callee to maintain the information for the duration 494 * of the data transfer, as necessary. 495 */ 496 497#ifdef __LP64__ 498 virtual void read(IOService * client, 499 UInt64 byteStart, 500 IOMemoryDescriptor * buffer, 501 IOStorageAttributes * attributes, 502 IOStorageCompletion * completion) = 0; 503#else /* !__LP64__ */ 504 virtual void read(IOService * client, 505 UInt64 byteStart, 506 IOMemoryDescriptor * buffer, 507 IOStorageAttributes * attributes, 508 IOStorageCompletion * completion); /* 10.5.0 */ 509#endif /* !__LP64__ */ 510 511 /*! 512 * @function write 513 * @discussion 514 * Write data into the storage object at the specified byte offset from the 515 * specified buffer, asynchronously. When the write completes, the caller 516 * will be notified via the specified completion action. 517 * 518 * The buffer will be retained for the duration of the write. 519 * @param client 520 * Client requesting the write. 521 * @param byteStart 522 * Starting byte offset for the data transfer. 523 * @param buffer 524 * Buffer for the data transfer. The size of the buffer implies the size of 525 * the data transfer. 526 * @param attributes 527 * Attributes of the data transfer. See IOStorageAttributes. It is the 528 * responsibility of the callee to maintain the information for the duration 529 * of the data transfer, as necessary. 530 * @param completion 531 * Completion routine to call once the data transfer is complete. It is the 532 * responsibility of the callee to maintain the information for the duration 533 * of the data transfer, as necessary. 534 */ 535 536#ifdef __LP64__ 537 virtual void write(IOService * client, 538 UInt64 byteStart, 539 IOMemoryDescriptor * buffer, 540 IOStorageAttributes * attributes, 541 IOStorageCompletion * completion) = 0; 542#else /* !__LP64__ */ 543 virtual void write(IOService * client, 544 UInt64 byteStart, 545 IOMemoryDescriptor * buffer, 546 IOStorageAttributes * attributes, 547 IOStorageCompletion * completion); /* 10.5.0 */ 548#endif /* !__LP64__ */ 549 550 virtual IOReturn discard(IOService * client, 551 UInt64 byteStart, 552 UInt64 byteCount) __attribute__ ((deprecated)); 553 554 /*! 555 * @function unmap 556 * @discussion 557 * Delete unused data from the storage object at the specified byte offsets, 558 * synchronously. 559 * @param client 560 * Client requesting the operation. 561 * @param extents 562 * List of extents. See IOStorageExtent. It is legal for the callee to 563 * overwrite the contents of this buffer in order to satisfy the request. 564 * @param extentsCount 565 * Number of extents. 566 * @result 567 * Returns the status of the operation. 568 */ 569 570 virtual IOReturn unmap(IOService * client, 571 IOStorageExtent * extents, 572 UInt32 extentsCount, 573 UInt32 options = 0); /* 10.6.6 */ 574 575 /*! 576 * @function lockPhysicalExtents 577 * @discussion 578 * Lock the contents of the storage object against relocation temporarily, 579 * for the purpose of getting physical extents. 580 * @param client 581 * Client requesting the operation. 582 * @result 583 * Returns true if the lock was successful, false otherwise. 584 */ 585 586 virtual bool lockPhysicalExtents(IOService * client); /* 10.7.0 */ 587 588 /*! 589 * @function copyPhysicalExtent 590 * @discussion 591 * Convert the specified byte offset into a physical byte offset, relative 592 * to a physical storage object. This call should only be made within the 593 * context of lockPhysicalExtents(). 594 * @param client 595 * Client requesting the operation. 596 * @param byteStart 597 * Starting byte offset for the operation. Returns a physical byte offset, 598 * relative to the physical storage object, on success. 599 * @param byteCount 600 * Size of the operation. Returns the actual number of bytes which can be 601 * transferred, relative to the physical storage object, on success. 602 * @result 603 * A reference to the physical storage object, which should be released by 604 * the caller, or a null on error. 605 */ 606 607 virtual IOStorage * copyPhysicalExtent(IOService * client, 608 UInt64 * byteStart, 609 UInt64 * byteCount); /* 10.7.0 */ 610 611 /*! 612 * @function unlockPhysicalExtents 613 * @discussion 614 * Unlock the contents of the storage object for relocation again. This 615 * call must balance a successful call to lockPhysicalExtents(). 616 * @param client 617 * Client requesting the operation. 618 */ 619 620 virtual void unlockPhysicalExtents(IOService * client); /* 10.7.0 */ 621 622 OSMetaClassDeclareReservedUsed(IOStorage, 0); 623 OSMetaClassDeclareReservedUsed(IOStorage, 1); 624 OSMetaClassDeclareReservedUsed(IOStorage, 2); 625 OSMetaClassDeclareReservedUsed(IOStorage, 3); 626#ifdef __LP64__ 627 OSMetaClassDeclareReservedUnused(IOStorage, 4); 628 OSMetaClassDeclareReservedUnused(IOStorage, 5); 629 OSMetaClassDeclareReservedUnused(IOStorage, 6); 630#else /* !__LP64__ */ 631 OSMetaClassDeclareReservedUsed(IOStorage, 4); 632 OSMetaClassDeclareReservedUsed(IOStorage, 5); 633 OSMetaClassDeclareReservedUsed(IOStorage, 6); 634#endif /* !__LP64__ */ 635 OSMetaClassDeclareReservedUnused(IOStorage, 7); 636 OSMetaClassDeclareReservedUnused(IOStorage, 8); 637 OSMetaClassDeclareReservedUnused(IOStorage, 9); 638 OSMetaClassDeclareReservedUnused(IOStorage, 10); 639 OSMetaClassDeclareReservedUnused(IOStorage, 11); 640 OSMetaClassDeclareReservedUnused(IOStorage, 12); 641 OSMetaClassDeclareReservedUnused(IOStorage, 13); 642 OSMetaClassDeclareReservedUnused(IOStorage, 14); 643 OSMetaClassDeclareReservedUnused(IOStorage, 15); 644}; 645 646#endif /* __cplusplus */ 647#endif /* KERNEL */ 648#endif /* !_IOSTORAGE_H */ 649