|
|
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.