|
|
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: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 24: * ! 25: * IOHDDrive.h ! 26: * ! 27: * This class implements generic Hard Disk functionality, independent of ! 28: * the physical connection protocol (e.g. SCSI, ATA, USB). ! 29: * ! 30: * A protocol-specific provider implements the functionality using an appropriate ! 31: * protocol and commands. ! 32: */ ! 33: ! 34: #ifndef _IOHDDRIVE_H ! 35: #define _IOHDDRIVE_H ! 36: ! 37: #include <IOKit/IOTypes.h> ! 38: #include <IOKit/storage/IOStorage.h> ! 39: #include <IOKit/storage/IODrive.h> ! 40: #include <IOKit/IOMemoryDescriptor.h> ! 41: ! 42: class IOHDDriveNub; ! 43: class IOMedia; ! 44: ! 45: /*! ! 46: * @class ! 47: * IOHDDrive : public IODrive ! 48: * @abstract ! 49: * Generic Hard Disk Driver. ! 50: * @discussion ! 51: * Storage drivers are split into two parts: the Generic Driver handles ! 52: * all generic device issues, independent of the lower-level transport ! 53: * mechanism (e.g. SCSI, ATA, USB, FireWire). All storage operations ! 54: * at the Generic Driver level are translated into a series of generic ! 55: * device operations. These operations are passed via the Device Nub ! 56: * to a Transport Driver, which implements the appropriate ! 57: * transport-dependent protocol to execute these operations. ! 58: * ! 59: * To determine the write-protect state of a device (or media), for ! 60: * example, the generic driver would issue a call to the ! 61: * Transport Driver's reportWriteProtection method. If this were a SCSI ! 62: * device, its Transport Driver would issue a Mode Sense command to ! 63: * extract the write-protection status bit. The Transport Driver then ! 64: * reports true or false to the generic driver. ! 65: * ! 66: * The generic driver therefore has no knowledge of, or involvement ! 67: * with, the actual commands and mechanisms used to communicate with ! 68: * the device. It is expected that the generic driver will rarely, if ! 69: * ever, need to be subclassed to handle device idiosyncrasies; rather, ! 70: * the Transport Driver should be changed via overrides. ! 71: * ! 72: * A generic driver could be subclassed to create a different type of ! 73: * generic device. The generic driver IOCDDrive class is a subclass ! 74: * of IOHDDrive, adding CD functions. Similarly, the Transport Driver ! 75: * IOSCSICDDrive is a subclass of IOSCSIHDDrive, adding CD functions. ! 76: */ ! 77: ! 78: class IOHDDrive : public IODrive { ! 79: ! 80: OSDeclareDefaultStructors(IOHDDrive) ! 81: ! 82: public: ! 83: ! 84: struct context { ! 85: IOStorageCompletion completion; ! 86: IOMemoryDescriptor * buffer; ! 87: UInt64 byteStart; ! 88: UInt64 byteCount; ! 89: ! 90: IOReturn result; ! 91: UInt64 actualTransferCount; ! 92: }; ! 93: ! 94: /* Overrides from IORegistryEntry */ ! 95: ! 96: virtual void free(void); ! 97: virtual bool init(OSDictionary * properties); ! 98: ! 99: /* Overrides from IOService */ ! 100: ! 101: /*! ! 102: * @function probe ! 103: * @abstract ! 104: * Probe for proper client Transport Driver. ! 105: * @discussion ! 106: * This method first verifies that our provider is of class IOHDDriveNub, then ! 107: * checks that the provider's property "kDeviceTypeProperty" matches what we expect. ! 108: * Failure of either test causes a return of NULL. ! 109: */ ! 110: virtual IOService * probe(IOService * provider,SInt32 * score); ! 111: ! 112: /* Mandatory overrides from IODrive: */ ! 113: ! 114: /*! ! 115: * @function constrainByteCount ! 116: * @abstract ! 117: * Constrain the byte count for this IO to device limits. ! 118: * @discussion ! 119: * This function should be called prior to each read or write operation, so that ! 120: * the driver can constrain the requested byte count, as necessary, to meet ! 121: * current device limits. Such limits could be imposed by the device depending ! 122: * on operating modes, media types, or transport prototol (e.g. ATA, SCSI). ! 123: * ! 124: * At present, this method is not used. ! 125: * @param requestedCount ! 126: * The requested byte count for the next read or write operation. ! 127: * @param isWrite ! 128: * True if the operation will be a write; False if the operation will be a read. ! 129: */ ! 130: virtual UInt64 constrainByteCount(UInt64 requestedCount,bool isWrite); ! 131: ! 132: /*! ! 133: * @function ejectMedia ! 134: * @abstract ! 135: * Eject the media. ! 136: */ ! 137: virtual IOReturn ejectMedia(void); ! 138: ! 139: /*! ! 140: * @function formatMedia ! 141: * @abstract ! 142: * Format the media to the specified byte capacity. ! 143: * @param byteCapacity ! 144: * The requested final byte capacity for the formatted media. ! 145: */ ! 146: virtual IOReturn formatMedia(UInt64 byteCapacity); ! 147: ! 148: /*! ! 149: * @function getFormatCapacities ! 150: * @abstract ! 151: * Return the allowable formatting byte capacities. ! 152: * @discussion ! 153: * This function returns the supported byte capacities for the device. ! 154: * @param capacities ! 155: * Pointer for returning the list of capacities. ! 156: * @param capacitiesMaxCount ! 157: * The number of capacity values returned in "capacities." ! 158: */ ! 159: virtual UInt32 getFormatCapacities(UInt64 * capacities, ! 160: UInt32 capacitiesMaxCount) const; ! 161: ! 162: /*! ! 163: * @function getMediaBlockSize ! 164: * @abstract ! 165: * Return the block size for the device, in bytes. ! 166: */ ! 167: virtual UInt64 getMediaBlockSize(void) const; ! 168: ! 169: /*! ! 170: * @function getMediaState ! 171: * @abstract ! 172: * Return the state of media in the device. ! 173: */ ! 174: virtual IODrive::IOMediaState getMediaState(void) const; ! 175: ! 176: /*! ! 177: * @function handleStart ! 178: * @abstract ! 179: * Handle startup functionality after superclass is ready. ! 180: * @discussion ! 181: * This function obtains device description strings (e.g. Vendor name), prints ! 182: * a message describing the device, and then obtains all removable-media information ! 183: * (if the device is removable.) Finally, a check for media is performed. ! 184: * @param provider ! 185: * A pointer to our provider. ! 186: */ ! 187: virtual bool handleStart(IOService * provider); ! 188: ! 189: /*! ! 190: * @function handleStop ! 191: * @abstract ! 192: * Handle clean up functionality before driver is unloaded. ! 193: * @discussion ! 194: * If the media is writable, this method issues a Synchronize Cache operation. ! 195: * Then the media is ejected. ! 196: * @param provider ! 197: * A pointer to our provider. ! 198: */ ! 199: virtual void handleStop(IOService * provider); ! 200: ! 201: /*! ! 202: * @function isMediaEjectable ! 203: * @abstract ! 204: * Report whether the media is removable or not. ! 205: * @result ! 206: * True indicates the media can be ejected by software; False indicates it cannot. ! 207: */ ! 208: virtual bool isMediaEjectable(void) const; ! 209: ! 210: /*! ! 211: * @function isMediaPollExpensive ! 212: * @abstract ! 213: * Report whether polling for media is expensive. ! 214: * @result ! 215: * True indicates the media poll is expensive; False indicates polling is cheap. ! 216: */ ! 217: virtual bool isMediaPollExpensive(void) const; ! 218: ! 219: /*! ! 220: * @function isMediaPollRequired ! 221: * @abstract ! 222: * Report whether device must be polled to determine media state. ! 223: * @discussion ! 224: * @result ! 225: * True indicates that polling is required; False indicates that no polling is needed. ! 226: */ ! 227: virtual bool isMediaPollRequired(void) const; ! 228: ! 229: /*! ! 230: * @function lockMedia ! 231: * @abstract ! 232: * Lock or unlock the media in the device. ! 233: * @discussion ! 234: * This method may be used to lock the media in the device, thus preventing the user ! 235: * from removing the media manually. ! 236: * ! 237: * This method only makes sense if it is known that the device supports locking. ! 238: * @param lock ! 239: * True indicates the media should be locked in the device; ! 240: * False indicates the media should be unlocked. ! 241: */ ! 242: virtual IOReturn lockMedia(bool lock); ! 243: ! 244: /*! ! 245: * @function pollMedia ! 246: * @abstract ! 247: * Poll for media insertion/removal. ! 248: * @discussion ! 249: * This method is called periodically by the superclass, if isMediaPollRequired has ! 250: * previously reported True. We are responsible for reacting to new media insertion, ! 251: * or to existing media being removed. ! 252: */ ! 253: virtual IOReturn pollMedia(void); ! 254: ! 255: protected: ! 256: ! 257: /*! ! 258: * @function executeRequest ! 259: * @abstract ! 260: * Start an asynchronous read or write operation. ! 261: * @discussion ! 262: * This method is the main entry to start an asynchronous read or ! 263: * write operation. All IO operations must be block aligned and a ! 264: * multiple of the device block size. After some validations, the ! 265: * request is passed to the Transport Driver's doAsyncReadWrite method. ! 266: * The completion from the operation is set to call RWCompletion, by ! 267: * way of the gc_glue C function. ! 268: * @param byteStart ! 269: * The starting byte offset of the data transfer. ! 270: * @param buffer ! 271: * The data buffer for the operation. A pointer to an IOMemoryDescriptor. ! 272: * @param completion ! 273: * The completion information for an asynchronous read or write operation. ! 274: */ ! 275: virtual void executeRequest(UInt64 byteStart, ! 276: IOMemoryDescriptor * buffer, ! 277: IOStorageCompletion completion); ! 278: ! 279: /*! ! 280: * @function acceptNewMedia ! 281: * @abstract ! 282: * React to new media insertion. ! 283: * @discussion ! 284: * This method logs the media block size and block count, then calls ! 285: * instantiateMediaObject to get a media object instantiated. The ! 286: * media object is then attached above us and registered. ! 287: * ! 288: * This method can be overridden to control what happens when new media ! 289: * is inserted. The default implementation deals with one IOMedia object. ! 290: */ ! 291: virtual IOReturn acceptNewMedia(void); ! 292: ! 293: /*! ! 294: * @function decommissionMedia ! 295: * @abstract ! 296: * Decommission an existing piece of media that has gone away. ! 297: * @discussion ! 298: * This method wraps a call to tearDown, to tear down the stack and ! 299: * the IOMedia object for the media. If "forcible" is true, the media ! 300: * object will be forgotten, and initMediaStates will be called. A ! 301: * forcible decommission would occur when an unrecoverable error ! 302: * happens during teardown (e.g. perhaps a client is still open), but ! 303: * we must still forget about the media. ! 304: * @param forcible ! 305: * True to force forgetting of the media object even if tearDown reports ! 306: * that there was an active client. ! 307: */ ! 308: virtual IOReturn decommissionMedia(bool forcible); ! 309: ! 310: /*! ! 311: * @function instantiateDesiredMediaObject ! 312: * @abstract ! 313: * Create an IOMedia object for media. ! 314: * @discussion ! 315: * This method creates the exact type of IOMedia object desired. It is called by ! 316: * instantiateMediaObject. A subclass may override this one-line method to change ! 317: * the type of media object actually instantiated. ! 318: */ ! 319: virtual IOMedia * instantiateDesiredMediaObject(void); ! 320: ! 321: /*! ! 322: * @function instantiateMediaObject ! 323: * @abstract ! 324: * Create an IOMedia object for media. ! 325: * @discussion ! 326: * This method creates an IOMedia object from the supplied parameters. It is a ! 327: * convenience method to wrap the handful of steps to do the job. ! 328: * @param media ! 329: * A pointer to the created IOMedia object. ! 330: * @param base ! 331: * Byte number of beginning of active data area of the media. Usually zero. ! 332: * @param byteSize ! 333: * Size of the data area of the media, in bytes. ! 334: * @param blockSize ! 335: * Block size of the media, in bytes. ! 336: * @param isWholeMedia ! 337: * True indicates the IOMedia object represents the entire media; False indicates ! 338: * the IOMedia object represents a portion of the entire media. ! 339: * @param mediaName ! 340: * Name of the IOMedia object. ! 341: */ ! 342: virtual IOReturn instantiateMediaObject(IOMedia **media,UInt64 base,UInt64 byteSize,UInt32 blockSize, ! 343: bool isWholeMedia,char *mediaName); ! 344: ! 345: /*! ! 346: * @function recordAdditionalMediaParameters ! 347: * @abstract ! 348: * Record any additional media parameters as necessary. ! 349: * @discussion ! 350: * This method is called by recordMediaParameters() when media is detected. ! 351: * The default implementation does nothing and returns kIOReturnSuccess. A ! 352: * subclass may override this method to record additional parameters. ! 353: */ ! 354: virtual IOReturn recordAdditionalMediaParameters(void); ! 355: ! 356: /* --- Internally used methods. --- */ ! 357: ! 358: /* ! 359: * @group ! 360: * Internally Used Methods ! 361: * @discussion ! 362: * These methods are used internally, and will not generally be modified. ! 363: */ ! 364: ! 365: /*! ! 366: * @function allocateContext ! 367: * @abstract ! 368: * Allocate a context structure for use with the current async operation. ! 369: * @discussion ! 370: * A context structure is only needed for asynchronous read or write operations, ! 371: * to contain information used to complete the request with the client. ! 372: */ ! 373: virtual struct IOHDDrive::context *allocateContext(void); ! 374: ! 375: /*! ! 376: * @function checkForMedia ! 377: * @abstract ! 378: * Check if media has newly arrived or disappeared. ! 379: * @discussion ! 380: * This method does most of the work in polling for media, first ! 381: * calling the Transport Driver's reportMediaState method. If ! 382: * reportMediaState reports no change in the media state, kIOReturnSuccess ! 383: * is returned. If media has just become available, calls are made to ! 384: * recordMediaParameters and acceptNewMedia. If media has just gone ! 385: * away, a call is made to decommissionMedia, with the forcible ! 386: * parameter set to true. The forcible teardown is needed to enforce ! 387: * the disappearance of media, regardless of interested clients. ! 388: */ ! 389: virtual IOReturn checkForMedia(void); ! 390: ! 391: /*! ! 392: * @function constructMediaProperties ! 393: * @abstract ! 394: * Create properties related to the media. ! 395: * @discussion ! 396: * This function creates a set of properties to express media properties. ! 397: * ! 398: * This function is presently called by recordMediaParameters, but it does nothing. ! 399: */ ! 400: virtual OSDictionary *constructMediaProperties(void); ! 401: ! 402: /*! ! 403: * @function deleteContext ! 404: * @abstract ! 405: * Delete a context structure. ! 406: * @discussion ! 407: * This method also issues a "release" for the IO buffer, if any. ! 408: * @param cx ! 409: * A pointer to the context structure to be deleted. ! 410: */ ! 411: virtual void deleteContext(struct IOHDDrive::context *cx); ! 412: ! 413: /*! ! 414: * @function getDeviceTypeName ! 415: * @abstract ! 416: * Return the desired device name. ! 417: * @discussion ! 418: * This method returns a string, used to compare the kDeviceTypeProperty of ! 419: * our provider. This method is called from probe. ! 420: * ! 421: * The default implementation of this method returns kDeviceTypeHardDisk. ! 422: */ ! 423: virtual const char * getDeviceTypeName(void); ! 424: ! 425: /*! ! 426: * @function initMediaStates ! 427: * @abstract ! 428: * Initialize media-related instance variables. ! 429: * @discussion ! 430: * Called when media is not present, this method marks the drive state ! 431: * as not having media present, not spun up, and write-enabled. ! 432: */ ! 433: virtual void initMediaStates(void); ! 434: ! 435: /*! ! 436: * @function recordMediaParameters ! 437: * @abstract ! 438: * Obtain media-related parameters on media insertion. ! 439: * @discussion ! 440: * This method obtains media-related parameters via calls to the ! 441: * Transport Driver's reportBlockSize, reportMaxValidBlock, ! 442: * reportMaxReadTransfer, reportMaxWriteTransfer, and reportWriteProtection ! 443: * methods. ! 444: */ ! 445: virtual IOReturn recordMediaParameters(void); ! 446: ! 447: /*! ! 448: * @function setProvider ! 449: * @abstract ! 450: * Store the provider pointer. ! 451: * @discussion ! 452: * This method uses IODynamicCast to verify that the provider is of ! 453: * the proper class type. The default implementation checks for a nub ! 454: * of type IOHDDriveNub. ! 455: * ! 456: * This method would be overridden for a new generic driver subclass. For ! 457: * example, a generic CD driver would need to accept a different provider ! 458: * class (e.g. IOCDDriveNub instead of IOHDDriveNub). ! 459: * @param provider ! 460: * A pointer to our provider. ! 461: */ ! 462: virtual bool setProvider(IOService * provider); ! 463: ! 464: /*! ! 465: * @function showStats ! 466: * @abstract ! 467: * Print debugging statistics. ! 468: * @discussion ! 469: * This method prints debugging statistics maintained by the class. ! 470: * ! 471: * Present statistics include counts of up and down calls. ! 472: * @result ! 473: * True indicates statistics should be printed; False indicates no printing desired. ! 474: */ ! 475: virtual bool showStats(void); ! 476: ! 477: /*! ! 478: * @function tearDown ! 479: * @abstract ! 480: * Tear down the stack above this object when media goes away. ! 481: * @discussion ! 482: * This method calls media->terminate, and if that succeeds, issues ! 483: * a release on the media object, followed by a call to initMediaStates. ! 484: * @param media ! 485: * A pointer to the IOMedia object from which to initiate teardown. ! 486: */ ! 487: virtual IOReturn tearDown(IOService *media); ! 488: ! 489: /* ! 490: * @endgroup ! 491: */ ! 492: ! 493: /*! ! 494: * @function validateNewMedia ! 495: * @abstract ! 496: * Verify that new media is acceptable. ! 497: * @discussion ! 498: * This method will be called whenever new media is detected. Return true to accept ! 499: * the media, or false to reject it (andcall rejectMedia). Vendors might override ! 500: * this method to handle password-protection for new media. ! 501: * ! 502: * The default implementation always returns True, indicating media is accepted. ! 503: */ ! 504: virtual bool validateNewMedia(void); ! 505: ! 506: /*! ! 507: * @function rejectMedia ! 508: * @abstract ! 509: * Reject new media. ! 510: * @discussion ! 511: * This method will be called if validateNewMedia returns False (thus rejecting ! 512: * the new media. A vendor may choose to override this method to control behavior ! 513: * when media is rejected. ! 514: * ! 515: * The default implementation simply calls ejectMedia. ! 516: */ ! 517: virtual void rejectMedia(void); /* default ejects */ ! 518: ! 519: public: ! 520: ! 521: /*! ! 522: * @function RWCompletion ! 523: * @abstract ! 524: * Handle a C callback for an IO completion. ! 525: * @discussion ! 526: * This method must be public so we can reach it from the C-language callback ! 527: * "glue" routine. It should not be called from outside this class. ! 528: */ ! 529: virtual void RWCompletion(struct IOHDDrive::context *cx); ! 530: ! 531: protected: ! 532: ! 533: /* -------------*/ ! 534: ! 535: /*! ! 536: * @var _provider ! 537: * A pointer to our provider. ! 538: */ ! 539: IOHDDriveNub * _provider; ! 540: ! 541: /* Device info: */ ! 542: ! 543: /*! ! 544: * @var _removable ! 545: * True if the media is removable; False if it is fixed (not removable). ! 546: */ ! 547: bool _removable; ! 548: ! 549: /*! ! 550: * @var _ejectable ! 551: * True if the media is ejectable under software control. ! 552: */ ! 553: bool _ejectable; /* software-ejectable */ ! 554: ! 555: /*! ! 556: * @var _lockable ! 557: * True if the media can be locked in the device under software control. ! 558: */ ! 559: bool _lockable; /* software lockable in drive */ ! 560: /*! ! 561: * @var _pollIsRequired ! 562: * True if we must poll to detect media insertion or removal. ! 563: */ ! 564: bool _pollIsRequired; ! 565: /*! ! 566: * @var _pollIsExpensive ! 567: * True if polling is expensive; False if not. ! 568: */ ! 569: bool _pollIsExpensive; ! 570: ! 571: /* Async IO statistics, usually only useful for debugging. These counters show ! 572: * outstanding IO operations and completions. ! 573: */ ! 574: ! 575: /*! ! 576: * @struct stats ! 577: * A data structure to contain debugging statistics. Each field is a count. ! 578: * @field clientReceived ! 579: * Requests received from our client. ! 580: * @field providerSent ! 581: * Requests sent to our provider. ! 582: * @field providerReject ! 583: * Client requests we rejected without sending to our provider. ! 584: * @field providerCompletionsRcvd ! 585: * Completion calls that have arrived from our provider. ! 586: * @field clientCompletionsSent ! 587: * Completion calls that have been made to our client. ! 588: * @field clientCompletionsDone ! 589: * Completion calls to the client that have come back to us. ! 590: * This count MUST match clientCompletionsSent! ! 591: */ ! 592: /*! ! 593: * @var stats ! 594: * The stats structure. ! 595: */ ! 596: struct stats { /* executeRequest & completion counts */ ! 597: int clientReceived; /* requests received from client */ ! 598: int providerSent; /* requests sent to provider */ ! 599: int providerReject; /* provider requests rejected */ ! 600: int providerCompletionsRcvd; /* completions received from provider */ ! 601: int clientCompletionsSent; /* completions sent to client */ ! 602: int clientCompletionsDone; /* client completions made it back to us */ ! 603: } _stats; ! 604: ! 605: /* Media info and states: */ ! 606: ! 607: /*! ! 608: * @var _mediaObject ! 609: * A pointer to the media object we have instantiated (if any). ! 610: */ ! 611: IOMedia * _mediaObject; ! 612: /*! ! 613: * @var _mediaPresent ! 614: * True if media is present in the device; False if not. ! 615: */ ! 616: bool _mediaPresent; /* media is present and ready */ ! 617: /*! ! 618: * @var _writeProtected ! 619: * True if the media is write-protected; False if not. ! 620: */ ! 621: bool _writeProtected; ! 622: ! 623: /*! ! 624: * @var _mediaStateLock ! 625: * A lock used to protect during media checks. ! 626: */ ! 627: IOLock * _mediaStateLock; ! 628: ! 629: /*! ! 630: * @var _mediaBlockSize ! 631: * The block size of the media, in bytes. ! 632: */ ! 633: UInt64 _mediaBlockSize; ! 634: /*! ! 635: * @var _maxBlockNumber ! 636: * The maximum allowable block number for the media, zero-based. ! 637: */ ! 638: UInt64 _maxBlockNumber; ! 639: ! 640: /*! ! 641: * @var _maxReadByteTransfer ! 642: * The maximum byte transfer allowed for read operations. ! 643: */ ! 644: UInt64 _maxReadByteTransfer; ! 645: ! 646: /*! ! 647: * @var _maxWriteByteTransfer ! 648: * The maximum byte transfer allowed for write operations. ! 649: */ ! 650: UInt64 _maxWriteByteTransfer; ! 651: }; ! 652: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.