|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: ! 23: /*! ! 24: * @header IODrive ! 25: * @abstract ! 26: * This header contains the IODrive class definition. ! 27: */ ! 28: ! 29: #ifndef _IODRIVE_H ! 30: #define _IODRIVE_H ! 31: ! 32: /*! ! 33: * @defined kIODriveStatistics ! 34: * @abstract ! 35: * kIODriveStatistics is a property of IODrive objects. It is an OSDictionary. ! 36: * @discussion ! 37: * The kIODirectionStatistics property contains a table of statistics describing ! 38: * drive operations. All the different statistics are grouped under this table. ! 39: */ ! 40: ! 41: #define kIODriveStatistics "Statistics" ! 42: ! 43: /*! ! 44: * @defined kIODriveStatisticsBytesRead ! 45: * @abstract ! 46: * kIODriveStatisticsBytesRead is one of the statistic entries listed ! 47: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 48: * @discussion ! 49: * The kIODriveStatisticsBytesRead property describes the number of ! 50: * bytes read since the drive object was instantiated. ! 51: */ ! 52: ! 53: #define kIODriveStatisticsBytesRead "Bytes (Read)" ! 54: ! 55: /*! ! 56: * @defined kIODriveStatisticsBytesWritten ! 57: * @abstract ! 58: * kIODriveStatisticsBytesWritten is one of the statistic entries listed ! 59: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 60: * @discussion ! 61: * The kIODriveStatisticsBytesWritten property describes the number of ! 62: * bytes written since the drive object was instantiated. ! 63: */ ! 64: ! 65: #define kIODriveStatisticsBytesWritten "Bytes (Write)" ! 66: ! 67: /*! ! 68: * @defined kIODriveStatisticsReadErrors ! 69: * @abstract ! 70: * kIODriveStatisticsReadErrors is one of the statistic entries listed ! 71: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 72: * @discussion ! 73: * The kIODriveStatisticsReadErrors property describes the number of ! 74: * read errors encountered since the drive object was instantiated. ! 75: */ ! 76: ! 77: #define kIODriveStatisticsReadErrors "Errors (Read)" ! 78: ! 79: /*! ! 80: * @defined kIODriveStatisticsWriteErrors ! 81: * @abstract ! 82: * kIODriveStatisticsWriteErrors is one of the statistic entries listed ! 83: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 84: * @discussion ! 85: * The kIODriveStatisticsWriteErrors property describes the number of ! 86: * write errors encountered since the drive object was instantiated. ! 87: */ ! 88: ! 89: #define kIODriveStatisticsWriteErrors "Errors (Write)" ! 90: ! 91: /*! ! 92: * @defined kIODriveStatisticsLatentReadTime ! 93: * @abstract ! 94: * kIODriveStatisticsLatentReadTime is one of the statistic entries listed ! 95: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 96: * @discussion ! 97: * The kIODriveStatisticsLatentReadTime property describes the number of ! 98: * nanoseconds of latency during reads since the drive object was instantiated. ! 99: */ ! 100: ! 101: #define kIODriveStatisticsLatentReadTime "Latency Time (Read)" ! 102: ! 103: /*! ! 104: * @defined kIODriveStatisticsLatentWriteTime ! 105: * @abstract ! 106: * kIODriveStatisticsLatentWriteTime is one of the statistic entries listed ! 107: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 108: * @discussion ! 109: * The kIODriveStatisticsLatentWriteTime property describes the number of ! 110: * nanoseconds of latency during writes since the drive object was instantiated. ! 111: */ ! 112: ! 113: #define kIODriveStatisticsLatentWriteTime "Latency Time (Write)" ! 114: ! 115: /*! ! 116: * @defined kIODriveStatisticsReads ! 117: * @abstract ! 118: * kIODriveStatisticsReads is one of the statistic entries listed ! 119: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 120: * @discussion ! 121: * The kIODriveStatisticsReads property describes the number of ! 122: * read operations processed since the drive object was instantiated. ! 123: */ ! 124: ! 125: #define kIODriveStatisticsReads "Operations (Read)" ! 126: ! 127: /*! ! 128: * @defined kIODriveStatisticsWrites ! 129: * @abstract ! 130: * kIODriveStatisticsWrites is one of the statistic entries listed ! 131: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 132: * @discussion ! 133: * The kIODriveStatisticsWrites property describes the number of ! 134: * write operations processed since the drive object was instantiated. ! 135: */ ! 136: ! 137: #define kIODriveStatisticsWrites "Operations (Write)" ! 138: ! 139: /*! ! 140: * @defined kIODriveStatisticsReadRetries ! 141: * @abstract ! 142: * kIODriveStatisticsReadRetries is one of the statistic entries listed ! 143: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 144: * @discussion ! 145: * The kIODriveStatisticsReadRetries property describes the number of ! 146: * read retries required since the drive object was instantiated. ! 147: */ ! 148: ! 149: #define kIODriveStatisticsReadRetries "Retries (Read)" ! 150: ! 151: /*! ! 152: * @defined kIODriveStatisticsWriteRetries ! 153: * @abstract ! 154: * kIODriveStatisticsWriteRetries is one of the statistic entries listed ! 155: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 156: * @discussion ! 157: * The kIODriveStatisticsWriteRetries property describes the number of ! 158: * write retries required since the drive object was instantiated. ! 159: */ ! 160: ! 161: #define kIODriveStatisticsWriteRetries "Retries (Write)" ! 162: ! 163: /*! ! 164: * @defined kIODriveStatisticsTotalReadTime ! 165: * @abstract ! 166: * kIODriveStatisticsTotalReadTime is one of the statistic entries listed ! 167: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 168: * @discussion ! 169: * The kIODriveStatisticsTotalReadTime property describes the number of ! 170: * nanoseconds spent performing reads since the drive object was instantiated. ! 171: */ ! 172: ! 173: #define kIODriveStatisticsTotalReadTime "Total Time (Read)" ! 174: ! 175: /*! ! 176: * @defined kIODriveStatisticsTotalWriteTime ! 177: * @abstract ! 178: * kIODriveStatisticsTotalWriteTime is one of the statistic entries listed ! 179: * under the kIODriveStatistics property of IODrive objects. It is an OSNumber. ! 180: * @discussion ! 181: * The kIODriveStatisticsTotalWriteTime property describes the number of ! 182: * nanoseconds spent performing writes since the drive object was instantiated. ! 183: */ ! 184: ! 185: #define kIODriveStatisticsTotalWriteTime "Total Time (Write)" ! 186: ! 187: /* ! 188: * Kernel ! 189: */ ! 190: ! 191: #if defined(KERNEL) && defined(__cplusplus) ! 192: ! 193: #include <IOKit/storage/IOStorage.h> ! 194: ! 195: /*! ! 196: * @class IODrive ! 197: * @abstract ! 198: * The IODrive class is the common base class for all disk drive objects. ! 199: * @discussion ! 200: * The IODrive class is the common base class for all disk drive objects. It ! 201: * extends the IOStorage class by implementing the appropriate open and close ! 202: * semantics for drive objects, deblocking for unaligned transfers, automatic ! 203: * polling for removable media, statistics gathering and reporting functions, ! 204: * and declaring the abstract APIs for media formatting, ejection and locking ! 205: * (removal prevention). ! 206: * ! 207: * There are more specific subclasses of IODrive which further implement the ! 208: * general semantics of hard disk drives (IOHDDrive), CD drives (IOCDDrive), ! 209: * and so on. ! 210: */ ! 211: ! 212: class IODrive : public IOStorage ! 213: { ! 214: OSDeclareAbstractStructors(IODrive); ! 215: ! 216: public: ! 217: ! 218: /*! ! 219: * @enum Statistics ! 220: * @discussion ! 221: * Indices for the different statistics that getStatistics() can report. ! 222: * @constant kStatisticsReads ! 223: * Number of read operations thus far. ! 224: * @constant kStatisticsSingleBlockReads ! 225: * Number of read operations for a single block thus far. ! 226: * @constant kStatisticsBytesRead ! 227: * Number of bytes read thus far. ! 228: * @constant kStatisticsTotalReadTime ! 229: * Nanoseconds spent performing reads thus far. ! 230: * @constant kStatisticsLatentReadTime ! 231: * Nanoseconds of latency during reads thus far. ! 232: * @constant kStatisticsReadRetries ! 233: * Number of read retries thus far. ! 234: * @constant kStatisticsReadErrors ! 235: * Number of read errors thus far. ! 236: * @constant kStatisticsWrites ! 237: * Number of write operations thus far. ! 238: * @constant kStatisticsSingleBlockWrites ! 239: * Number of write operations for a single block thus far. ! 240: * @constant kStatisticsBytesWritten ! 241: * Number of bytes written thus far. ! 242: * @constant kStatisticsTotalWriteTime ! 243: * Nanoseconds spent performing writes thus far. ! 244: * @constant kStatisticsLatentWriteTime ! 245: * Nanoseconds of latency during writes thus far. ! 246: * @constant kStatisticsWriteRetries ! 247: * Number of write retries thus far. ! 248: * @constant kStatisticsWriteErrors ! 249: * Number of write errors thus far. ! 250: */ ! 251: ! 252: enum Statistics ! 253: { ! 254: kStatisticsReads, ! 255: kStatisticsSingleBlockReads, ! 256: kStatisticsBytesRead, ! 257: kStatisticsTotalReadTime, ! 258: kStatisticsLatentReadTime, ! 259: kStatisticsReadRetries, ! 260: kStatisticsReadErrors, ! 261: ! 262: kStatisticsWrites, ! 263: kStatisticsSingleBlockWrites, ! 264: kStatisticsBytesWritten, ! 265: kStatisticsTotalWriteTime, ! 266: kStatisticsLatentWriteTime, ! 267: kStatisticsWriteRetries, ! 268: kStatisticsWriteErrors ! 269: }; ! 270: ! 271: static const UInt32 kStatisticsCount = kStatisticsWriteErrors + 1; ! 272: ! 273: /*! ! 274: * @enum IOMediaState ! 275: * @discussion ! 276: * The different states that getMediaState() can report. ! 277: * @constant kMediaOffline ! 278: * Media is not available. ! 279: * @constant kMediaOnline ! 280: * Media is available and ready for operations. ! 281: * @constant kMediaBusy ! 282: * Media is available, but not ready for operations. ! 283: */ ! 284: ! 285: enum IOMediaState ! 286: { ! 287: kMediaOffline, ! 288: kMediaOnline, ! 289: kMediaBusy ! 290: }; ! 291: ! 292: protected: ! 293: ! 294: OSSet * _openClients; ! 295: OSNumber * _statistics[kStatisticsCount]; ! 296: ! 297: /* ! 298: * Free all of this object's outstanding resources. ! 299: * ! 300: * This method's implementation is not typically overidden. ! 301: */ ! 302: ! 303: void free(); ! 304: ! 305: /*! ! 306: * @function handleOpen ! 307: * @discussion ! 308: * The handleOpen method grants or denies permission to access this object ! 309: * to an interested client. The argument is an IOStorageAccess value that ! 310: * specifies the level of access desired -- reader or reader-writer. ! 311: * ! 312: * This method can be invoked to upgrade or downgrade the access level for ! 313: * an existing client as well. The previous access level will prevail for ! 314: * upgrades that fail, of course. A downgrade should never fail. If the ! 315: * new access level should be the same as the old for a given client, this ! 316: * method will do nothing and return success. In all cases, one, singular ! 317: * close-per-client is expected for all opens-per-client received. ! 318: * ! 319: * This implementation replaces the IOService definition of handleIsOpen(). ! 320: * @param client ! 321: * Client requesting the open. ! 322: * @param options ! 323: * Options for the open. Set to zero. ! 324: * @param access ! 325: * Access level for the open. Set to kAccessReader or kAccessReaderWriter. ! 326: * @result ! 327: * Returns true if the open was successful, false otherwise. ! 328: */ ! 329: ! 330: virtual bool handleOpen(IOService * client, ! 331: IOOptionBits options, ! 332: void * access); ! 333: ! 334: /*! ! 335: * @function handleIsOpen ! 336: * @discussion ! 337: * The handleIsOpen method determines whether the specified client, or any ! 338: * client if none is specificed, presently has an open on this object. ! 339: * ! 340: * This implementation replaces the IOService definition of handleIsOpen(). ! 341: * @param client ! 342: * Client to check the open state of. Set to zero to check the open state ! 343: * of all clients. ! 344: * @result ! 345: * Returns true if the client was (or clients were) open, false otherwise. ! 346: */ ! 347: ! 348: virtual bool handleIsOpen(const IOService * client) const; ! 349: ! 350: /*! ! 351: * @function handleClose ! 352: * @discussion ! 353: * The handleClose method closes the client's access to this object. ! 354: * ! 355: * This implementation replaces the IOService definition of handleIsOpen(). ! 356: * @param client ! 357: * Client requesting the close. ! 358: * @param options ! 359: * Options for the close. Set to zero. ! 360: */ ! 361: ! 362: virtual void handleClose(IOService * client, IOOptionBits options); ! 363: ! 364: /*! ! 365: * @function addToBytesTransferred ! 366: * @discussion ! 367: * Update the total number of bytes transferred, the total transfer time, ! 368: * and the total latency time for this drive -- used for statistics. ! 369: * ! 370: * This method's implementation is not typically overidden. ! 371: * @param bytesTransferred ! 372: * Number of bytes transferred in this operation. ! 373: * @param totalTime ! 374: * Nanoseconds spent performing this operation. ! 375: * @param latentTime ! 376: * Nanoseconds of latency during this operation. ! 377: * @param isWrite ! 378: * Indicates whether this operation was a write, otherwise is was a read. ! 379: */ ! 380: ! 381: virtual void addToBytesTransferred(UInt64 bytesTransferred, ! 382: UInt64 totalTime, ! 383: UInt64 latentTime, ! 384: bool isWrite); ! 385: ! 386: /*! ! 387: * @function incrementErrors ! 388: * @discussion ! 389: * Update the total error count -- used for statistics. ! 390: * ! 391: * This method's implementation is not typically overidden. ! 392: * @param isWrite ! 393: * Indicates whether this operation was a write, otherwise is was a read. ! 394: */ ! 395: ! 396: virtual void incrementErrors(bool isWrite); ! 397: ! 398: /*! ! 399: * @function incrementRetries ! 400: * @discussion ! 401: * Update the total retry count -- used for statistics. ! 402: * ! 403: * This method's implementation is not typically overidden. ! 404: * @param isWrite ! 405: * Indicates whether this operation was a write, otherwise is was a read. ! 406: */ ! 407: ! 408: virtual void incrementRetries(bool isWrite); ! 409: ! 410: /*! ! 411: * @function deblockRequest ! 412: * @discussion ! 413: * The deblockRequest method checks to see if the incoming request rests ! 414: * on the media's block boundaries, and if not, deblocks it. Deblocking ! 415: * involves breaking up the request into sub-requests that rest on block ! 416: * boundaries, and performing the appropriate unaligned byte copies from ! 417: * the scratch buffer into into the client's request buffer. ! 418: * ! 419: * This method is part of a sequence of methods that are called for each ! 420: * read or write request. The first is deblockRequest, which aligns the ! 421: * request at the media's block boundaries; the second is prepareRequest, ! 422: * which prepares the memory involved in the transfer; and the third is ! 423: * executeRequest, which implements the actual transfer from the drive. ! 424: * ! 425: * This method's implementation is not typically overidden. ! 426: * @param byteStart ! 427: * Starting byte offset for the data transfer. ! 428: * @param buffer ! 429: * Buffer for the data transfer. The size of the buffer implies the size of ! 430: * the data transfer. ! 431: * @param completion ! 432: * Completion routine to call once the data transfer is complete. ! 433: */ ! 434: ! 435: virtual void deblockRequest(UInt64 byteStart, ! 436: IOMemoryDescriptor * buffer, ! 437: IOStorageCompletion completion); ! 438: ! 439: /*! ! 440: * @function prepareRequest ! 441: * @discussion ! 442: * The prepareRequest method prepares the memory involved in the transfer. ! 443: * The memory will be wired down, physically mapped, and broken up based ! 444: * on the controller's and drive's constraints. ! 445: * ! 446: * This method is part of a sequence of methods that are called for each ! 447: * read or write request. The first is deblockRequest, which aligns the ! 448: * request at the media's block boundaries; the second is prepareRequest, ! 449: * which prepares the buffer involved in the transfer; and the third is ! 450: * executeRequest, which implements the actual transfer from the drive. ! 451: * ! 452: * This method's implementation is not typically overidden. ! 453: * @param byteStart ! 454: * Starting byte offset for the data transfer. ! 455: * @param buffer ! 456: * Buffer for the data transfer. The size of the buffer implies the size of ! 457: * the data transfer. ! 458: * @param completion ! 459: * Completion routine to call once the data transfer is complete. ! 460: */ ! 461: ! 462: virtual void prepareRequest(UInt64 byteStart, ! 463: IOMemoryDescriptor * buffer, ! 464: IOStorageCompletion completion); ! 465: ! 466: /*! ! 467: * @function executeRequest ! 468: * @discussion ! 469: * Execute the specified storage request. The request is guaranteed to ! 470: * be block-aligned, and to have a memory buffer that is wired, mapped, ! 471: * and is constrained according to the controller's and drive's limits. ! 472: * ! 473: * This method is part of a sequence of methods that are called for each ! 474: * read or write request. The first is deblockRequest, which aligns the ! 475: * request at the media's block boundaries; the second is prepareRequest, ! 476: * which prepares the buffer involved in the transfer; and the third is ! 477: * executeRequest, which implements the actual transfer from the drive. ! 478: * ! 479: * When implementing this abstract method, it is important to remember ! 480: * that the buffer must be retained while the asynchronous operation is ! 481: * being processed, as per regular I/O Kit object-passing semantics. ! 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 completion ! 488: * Completion routine to call once the data transfer is complete. ! 489: */ ! 490: ! 491: virtual void executeRequest(UInt64 byteStart, ! 492: IOMemoryDescriptor * buffer, ! 493: IOStorageCompletion completion) = 0; ! 494: ! 495: /*! ! 496: * @function handleStart ! 497: * @discussion ! 498: * Prepare the drive for operation. ! 499: * ! 500: * This is where a media object needs to be created for fixed media, and ! 501: * optionally for removable media. For removable media, the poller will ! 502: * issue handlePoll() once a second, so the creation of the media object ! 503: * could be delayed until then if you wish. ! 504: * ! 505: * Note that this method is called from the superclass' start() routine; ! 506: * if this method returns successfully, it should be prepared to accept ! 507: * any of IODrive's abstract methods. ! 508: * @param provider ! 509: * This object's provider. ! 510: * @result ! 511: * Returns true on success, false otherwise. ! 512: */ ! 513: ! 514: virtual bool handleStart(IOService * provider) = 0; ! 515: ! 516: /*! ! 517: * @function handleStop ! 518: * @discussion ! 519: * Stop the drive. ! 520: * ! 521: * This is where the driver should clean up its state in preparation for ! 522: * removal from the system. ! 523: * ! 524: * Note that this method is called from the superclass' stop() routine. ! 525: * @param provider ! 526: * This object's provider. ! 527: */ ! 528: ! 529: virtual void handleStop(IOService * provider) = 0; ! 530: ! 531: /*! ! 532: * @function getMediaBlockSize ! 533: * @discussion ! 534: * Ask the drive about the media's actual block size. ! 535: * @result ! 536: * Natural block size, in bytes. ! 537: */ ! 538: ! 539: virtual inline UInt64 getMediaBlockSize() const = 0; ! 540: ! 541: public: ! 542: ! 543: ///m:2333367:workaround:commented:start ! 544: // IOStorage::open; ! 545: // IOStorage::close; ! 546: // IOStorage::read; ! 547: // IOStorage::write; ! 548: ///m:2333367:workaround:commented:stop ! 549: ! 550: /* ! 551: * Initialize this object's minimal state. ! 552: * ! 553: * This method's implementation is not typically overidden. ! 554: */ ! 555: ! 556: virtual bool init(OSDictionary * properties = 0); ! 557: ! 558: /* ! 559: * This method is called once we have been attached to the provider object. ! 560: * ! 561: * This method's implementation is not typically overidden. ! 562: */ ! 563: ! 564: virtual bool start(IOService * provider); ! 565: ! 566: /* ! 567: * This method is called before we are detached from the provider object. ! 568: * ! 569: * This method's implementation is not typically overidden. ! 570: */ ! 571: ! 572: virtual void stop(IOService * provider); ! 573: ! 574: /*! ! 575: * @function read ! 576: * @discussion ! 577: * The read method is the receiving end for all read requests from the ! 578: * storage framework, that is, the child storage objects of this drive. ! 579: * ! 580: * This method kicks off a sequence of methods which are called for each ! 581: * read or write request. The first is deblockRequest, which aligns the ! 582: * request at the media's block boundaries; the second is prepareRequest, ! 583: * which prepares the buffer involved in the transfer; and the third is ! 584: * executeRequest, which implements the actual transfer from the drive. ! 585: * ! 586: * This method's implementation is not typically overidden. ! 587: * @param client ! 588: * Client requesting the read. ! 589: * @param byteStart ! 590: * Starting byte offset for the data transfer. ! 591: * @param buffer ! 592: * Buffer for the data transfer. The size of the buffer implies the size of ! 593: * the data transfer. ! 594: * @param completion ! 595: * Completion routine to call once the data transfer is complete. ! 596: */ ! 597: ! 598: virtual void read(IOService * client, ! 599: UInt64 byteStart, ! 600: IOMemoryDescriptor * buffer, ! 601: IOStorageCompletion completion); ! 602: ! 603: /*! ! 604: * @function write ! 605: * @discussion ! 606: * The write method is the receiving end for all write requests from the ! 607: * storage framework, that is, the child storage objects of this drive. ! 608: * ! 609: * This method kicks off a sequence of methods which are called for each ! 610: * read or write request. The first is deblockRequest, which aligns the ! 611: * request at the media's block boundaries; the second is prepareRequest, ! 612: * which prepares the buffer involved in the transfer; and the third is ! 613: * executeRequest, which implements the actual transfer from the drive. ! 614: * ! 615: * This method's implementation is not typically overidden. ! 616: * @param client ! 617: * Client requesting the write. ! 618: * @param byteStart ! 619: * Starting byte offset for the data transfer. ! 620: * @param buffer ! 621: * Buffer for the data transfer. The size of the buffer implies the size of ! 622: * the data transfer. ! 623: * @param completion ! 624: * Completion routine to call once the data transfer is complete. ! 625: */ ! 626: ! 627: virtual void write(IOService * client, ! 628: UInt64 byteStart, ! 629: IOMemoryDescriptor * buffer, ! 630: IOStorageCompletion completion); ! 631: ! 632: /*! ! 633: * @function ejectMedia ! 634: * @discussion ! 635: * Eject the media from the drive. The drive object is responsible for ! 636: * tearing down the child storage objects it created before proceeding ! 637: * with the eject. If the teardown fails, an error should be returned. ! 638: * @result ! 639: * An IOReturn code. ! 640: */ ! 641: ! 642: virtual IOReturn ejectMedia() = 0; ! 643: ! 644: /*! ! 645: * @function formatMedia ! 646: * @discussion ! 647: * Format the media in the drive with the specified byte capacity. The ! 648: * drive object is responsible for tearing down the child storage objects ! 649: * and recreating them, if applicable. ! 650: * @param byteCapacity ! 651: * Number of bytes to format media to. ! 652: * @result ! 653: * An IOReturn code. ! 654: */ ! 655: ! 656: virtual IOReturn formatMedia(UInt64 byteCapacity) = 0; ! 657: ! 658: /*! ! 659: * @function lockMedia ! 660: * @discussion ! 661: * Lock or unlock the ejectable media in the drive, that is, prevent ! 662: * it from manual ejection or allow its manual ejection. ! 663: * @param lock ! 664: * Pass true to lock the media, otherwise pass false to unlock the media. ! 665: * @result ! 666: * An IOReturn code. ! 667: */ ! 668: ! 669: virtual IOReturn lockMedia(bool lock) = 0; ! 670: ! 671: /*! ! 672: * @function pollMedia ! 673: * @discussion ! 674: * Poll for the presence of media in the drive. The drive object is ! 675: * responsible for tearing down the child storage objects it created ! 676: * should the media have been removed since the last poll, and vice- ! 677: * versa, creating the child storage objects should new media have ! 678: * arrived since the last poll. ! 679: * @result ! 680: * An IOReturn code. ! 681: */ ! 682: ! 683: virtual IOReturn pollMedia() = 0; ! 684: ! 685: /*! ! 686: * @function isMediaEjectable ! 687: * @discussion ! 688: * Ask the drive whether it contains ejectable media. ! 689: * @result ! 690: * Returns true if the media is ejectable, false otherwise. ! 691: */ ! 692: ! 693: virtual bool isMediaEjectable() const = 0; ! 694: ! 695: /*! ! 696: * @function isMediaPollExpensive ! 697: * @discussion ! 698: * Ask the drive whether it a pollMedia would be an expensive operation, ! 699: * that is, one that requires the drive to spin up or delay for a while. ! 700: * @result ! 701: * Returns true if polling the media is expensive, false otherwise. ! 702: */ ! 703: ! 704: virtual bool isMediaPollExpensive() const = 0; ! 705: ! 706: /*! ! 707: * @function isMediaPollRequired ! 708: * @discussion ! 709: * Ask the drive whether it requires polling, which is typically required ! 710: * for drives with ejectable media without the ability to asynchronously ! 711: * detect the arrival or departure of the media. ! 712: * @result ! 713: * Returns true if polling the media is required, false otherwise. ! 714: */ ! 715: ! 716: virtual bool isMediaPollRequired() const = 0; ! 717: ! 718: /*! ! 719: * @function getMediaState ! 720: * @discussion ! 721: * Ask the drive about the media's current state. ! 722: * @result ! 723: * An IOMediaState value. ! 724: */ ! 725: ! 726: virtual IOMediaState getMediaState() const = 0; ! 727: ! 728: /*! ! 729: * @function getFormatCapacities ! 730: * @discussion ! 731: * Ask the drive to report the feasible formatting capacities for the ! 732: * inserted media (in bytes). This routine fills the caller's buffer, ! 733: * up to the maximum count specified if the real number of capacities ! 734: * would overflow the buffer. The return value indicates the actual ! 735: * number of capacities copied to the buffer. ! 736: * ! 737: * If the capacities buffer is not supplied or if the maximum count is ! 738: * zero, the routine returns the proposed count of capacities instead. ! 739: * @param capacities ! 740: * Buffer that will receive the UInt64 capacity values. ! 741: * @param capacitiesMaxCount ! 742: * Maximum number of capacity values that can be held in the buffer. ! 743: * @result ! 744: * Actual number of capacity values copied to the buffer, or if no buffer ! 745: * is given, the total number of capacity values available. ! 746: */ ! 747: ! 748: virtual UInt32 getFormatCapacities(UInt64 * capacities, ! 749: UInt32 capacitiesMaxCount) const = 0; ! 750: ! 751: /*! ! 752: * @function getStatistics ! 753: * @discussion ! 754: * Ask the drive to report its operating statistics. The statistics are ! 755: * described by the IODrive::Statistics indices. This routine fills the ! 756: * caller's buffer, up to the maximum count specified if the real number ! 757: * of statistics would overflow the buffer. The return value indicates ! 758: * the actual number of statistics copied to the buffer. ! 759: * ! 760: * If the statistics buffer is not supplied or if the maximum count is ! 761: * zero, the routine returns the proposed count of statistics instead. ! 762: * @param statistics ! 763: * Buffer that will receive the UInt64 statistic values. ! 764: * @param statisticsMaxCount ! 765: * Maximum number of statistic values that can be held in the buffer. ! 766: * @result ! 767: * Actual number of statistic values copied to the buffer, or if no buffer ! 768: * is given, the total number of statistic values available. ! 769: */ ! 770: ! 771: virtual UInt32 getStatistics(UInt64 * statistics, ! 772: UInt32 statisticsMaxCount) const; ! 773: ! 774: /*! ! 775: * @function getStatistic ! 776: * @discussion ! 777: * Ask the drive to report one of its operating statistics. ! 778: * @param statistic ! 779: * Statistic index (an IODrive::Statistics index). ! 780: * @result ! 781: * Statistic value. ! 782: */ ! 783: ! 784: virtual UInt64 getStatistic(Statistics statistic) const; ! 785: ! 786: protected: ! 787: ! 788: /* ! 789: * Definitions for the default deblocker implementation. ! 790: */ ! 791: ! 792: enum DeblockerPhase ! 793: { ! 794: kPhaseBegin, ! 795: kPhaseStart, ! 796: kPhaseMiddle, ! 797: kPhaseFinal, ! 798: kPhaseDone, ! 799: ! 800: kPhaseBeginRMW, ! 801: kPhaseStartRM, ! 802: kPhaseStartW, ! 803: kPhaseMiddleW, ! 804: kPhaseFinalRM, ! 805: kPhaseFinalW ! 806: }; ! 807: ! 808: struct DeblockerContext ! 809: { ! 810: struct ! 811: { ! 812: UInt64 byteStart; ! 813: IOMemoryDescriptor * buffer; ! 814: IOStorageCompletion completion; ! 815: } subrequest; ! 816: ! 817: UInt64 offsetStart; ! 818: UInt64 bytesStart; ! 819: UInt64 bytesMiddle; ! 820: UInt64 bytesFinal; ! 821: ! 822: IOMemoryDescriptor * blockBuffer; ! 823: UInt8 * blockBufferPtr; ! 824: ! 825: IOMemoryDescriptor * middleBuffer; ! 826: ! 827: UInt64 bytesTransferred; ! 828: ! 829: struct ! 830: { ! 831: UInt64 byteStart; ! 832: IOMemoryDescriptor * buffer; ! 833: IOStorageCompletion completion; ! 834: } originalRequest; ! 835: ! 836: DeblockerPhase phase; ! 837: }; ! 838: ! 839: IOLock * _deblockerLockForRMWs; ! 840: ! 841: /* ! 842: * Allocate a deblocker context structure. It comes preinitialized with ! 843: * a block-sized scratch buffer and an associated memory descriptor, but ! 844: * is otherwise uninitialized. ! 845: */ ! 846: ! 847: DeblockerContext * deblockerContextAllocate(); ! 848: ! 849: /* ! 850: * Deallocate a deblocker context structure. The block-sized scratch ! 851: * buffer and memory descriptor is automatically deallocated as well. ! 852: */ ! 853: ! 854: void deblockerContextFree(DeblockerContext * deblockContext); ! 855: ! 856: /* ! 857: * This is the completion routine for the aligned deblocker subrequests. ! 858: * It performs work on the just-completed phase, if any, transitions to ! 859: * the next phase, then builds and issues a transfer for the next phase. ! 860: */ ! 861: ! 862: static void deblockerCompletion(void * target, ! 863: void * parameter, ! 864: IOReturn status, ! 865: UInt64 actualByteCount); ! 866: ! 867: /* ! 868: * Schedule the poller mechanism. ! 869: */ ! 870: ! 871: void schedulePoller(); ! 872: ! 873: /* ! 874: * Unschedule the poller mechanism. ! 875: */ ! 876: ! 877: void unschedulePoller(); ! 878: ! 879: /* ! 880: * This method is the timeout handler for the poller mechanism. It polls ! 881: * for media and reschedules another timeout if the drive is still closed. ! 882: */ ! 883: ! 884: static void poller(void *, void *); ! 885: }; ! 886: ! 887: #endif /* defined(KERNEL) && defined(__cplusplus) */ ! 888: ! 889: #endif /* !_IODRIVE_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.