1/*
2 * Copyright (c) 1998-2014 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 IOBlockStorageDevice
26 * @abstract
27 * This header contains the IOBlockStorageDevice class definition.
28 */
29
30#ifndef _IOBLOCKSTORAGEDEVICE_H
31#define _IOBLOCKSTORAGEDEVICE_H
32
33#include <IOKit/IOTypes.h>
34#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
35
36/*!
37 * @defined kIOBlockStorageDeviceClass
38 * @abstract
39 * The name of the IOBlockStorageDevice class.
40 */
41
42#define kIOBlockStorageDeviceClass "IOBlockStorageDevice"
43
44/*!
45 * @defined kIOBlockStorageDeviceWriteCacheStateKey
46 * @abstract
47 * The name of the property used to get or set the write cache state of the
48 * block storage device.
49 */
50#define kIOBlockStorageDeviceWriteCacheStateKey	"WriteCacheState"
51
52#ifdef KERNEL
53#ifdef __cplusplus
54
55/*
56 * Kernel
57 */
58
59#include <IOKit/IOMemoryDescriptor.h>
60#include <IOKit/IOMessage.h>
61#include <IOKit/IOService.h>
62#include <IOKit/storage/IOMedia.h>
63
64/*!
65 * @defined kIOMessageMediaParametersHaveChanged
66 * @abstract
67 * The message ID which indicates that the media parameters, such as the highest valid block
68 * for the device, have changed.
69 * @discussion
70 * The message is passed to all clients of the IOBlockStorageDevice via the message() method.
71 */
72#define kIOMessageMediaParametersHaveChanged iokit_family_msg(sub_iokit_block_storage, 2)
73
74/*!
75 * @defined kIOMessageMediaStateHasChanged
76 * @abstract
77 * The message ID which indicates that the media state has changed.
78 * @discussion
79 * The message is passed to all clients of the IOBlockStorageDevice via the message() method.
80 * The argument that is passed along with this message is an IOMediaState value.
81 */
82#define kIOMessageMediaStateHasChanged iokit_family_msg(sub_iokit_block_storage, 1)
83
84/* Property used for matching, so the generic driver gets the nub it wants. */
85/*!
86 * @defined kIOBlockStorageDeviceTypeKey
87 * @abstract The name of the property tested for nub type matching by the generic block
88 * storage driver.
89 */
90#define	kIOBlockStorageDeviceTypeKey	"device-type"
91/*!
92 * @defined kIOBlockStorageDeviceTypeGeneric
93 * @abstract A character string used for nub matching.
94 */
95#define	kIOBlockStorageDeviceTypeGeneric	"Generic"
96
97/*!
98 * @struct IOBlockStorageDeviceExtent
99 * @abstract
100 * Extent for unmap storage requests.
101 * @field blockStart
102 * The starting block number of the operation.
103 * @field blockCount
104 * The integral number of blocks to be deleted.
105 */
106
107struct IOBlockStorageDeviceExtent
108{
109    UInt64 blockStart;
110    UInt64 blockCount;
111};
112
113/*!
114 * @class
115 * IOBlockStorageDevice
116 * @abstract
117 * A generic block storage device abstraction.
118 * @discussion
119 * The IOBlockStorageDevice class exports the generic block storage protocol,
120 * independent of the physical connection protocol (e.g. SCSI, ATA, USB),
121 * forwarding all requests to its provider (the Transport Driver).
122 * Though the nub does no actual processing of requests, it is necessary
123 * in a C++ environment. The Transport Driver can be of any type, as
124 * long as it inherits from IOService. Because Transport Drivers needn't
125 * derive from a type known to IOBlockStorageDriver, it isn't possible for
126 * IOBlockStorageDriver to include the appropriate header file to allow direct
127 * communication with the Transport Driver. Thus we achieve polymorphism by
128 * having the Transport Driver instantiate a subclass of IOBlockStorageDevice.
129 * A typical implementation for a concrete subclass of IOBlockStorageDevice
130 * simply relays all methods to its provider (the Transport Driver), which
131 * implements the protocol- and device-specific behavior.
132 *
133 * All pure-virtual functions must be implemented by the Transport Driver, which
134 * is responsible for instantiating the Nub.
135 */
136
137class IOBlockStorageDevice : public IOService {
138
139    OSDeclareAbstractStructors(IOBlockStorageDevice)
140
141protected:
142
143    struct ExpansionData { /* */ };
144    ExpansionData * _expansionData;
145
146public:
147
148    /* Overrides from IORegistryEntry */
149
150    using IORegistryEntry::getProperty;
151
152    /*!
153     * @function init
154     * @discussion
155     * This function is overridden so that IOBlockStorageDevice can set a
156     * property, used by IOBlockStorageDriver for matching. Since the concrete
157     * subclass of IOBlockStorageDevice can be of any class type, the property
158     * is used for matching.
159     *
160     * This function is usually not overridden by developers.
161     */
162    virtual bool	init(OSDictionary * properties);
163
164    virtual OSObject *	getProperty(const OSSymbol * key) const;
165
166    virtual IOReturn	setProperties(OSObject * properties);
167
168    /* --- A subclass must implement the the following methods: --- */
169
170#ifndef __LP64__
171    virtual IOReturn	doAsyncReadWrite(IOMemoryDescriptor *buffer,
172                                            UInt32 block, UInt32 nblks,
173                                            IOStorageCompletion completion) __attribute__ ((deprecated));
174
175    virtual IOReturn	doSyncReadWrite(IOMemoryDescriptor *buffer,
176                                    UInt32 block,UInt32 nblks) __attribute__ ((deprecated));
177#endif /* !__LP64__ */
178
179    /*!
180     * @function doEjectMedia
181     * @abstract
182     * Eject the media.
183     */
184    virtual IOReturn	doEjectMedia(void)	= 0;
185
186    /*!
187     * @function doFormatMedia
188     * @abstract
189     * Format the media to the specified byte capacity.
190     * @discussion
191     * The specified byte capacity must be one supported by the device.
192     * Supported capacities can be obtained by calling doGetFormatCapacities.
193     * @param byteCapacity
194     * The byte capacity to which the device is to be formatted, if possible.
195     */
196    virtual IOReturn	doFormatMedia(UInt64 byteCapacity)	= 0;
197
198    /*!
199     * @function doGetFormatCapacities
200     * @abstract
201     * Return the allowable formatting byte capacities.
202     * @discussion
203     * This function returns the supported byte capacities for the device.
204     * @param capacities
205     * Pointer for returning the list of capacities.
206     * @param capacitiesMaxCount
207     * The number of capacity values returned in "capacities," or if no buffer
208     * is given, the total number of capacity values available.
209     */
210    virtual UInt32	doGetFormatCapacities(UInt64 * capacities,
211                                            UInt32   capacitiesMaxCount) const	= 0;
212
213    virtual IOReturn	doLockUnlockMedia(bool doLock) __attribute__ ((deprecated));
214
215    /*!
216     * @function doSynchronizeCache
217     * @abstract
218     * Force data blocks in the hardware's buffer to be flushed to the media.
219     * @discussion
220     * This method should only be called if the media is writable.
221     */
222    virtual IOReturn	doSynchronizeCache(void)	= 0;
223
224    /*!
225     * @function getVendorString
226     * @abstract
227     * Return Vendor Name string for the device.
228     * @result
229     * A pointer to a static character string.
230     */
231    virtual char *	getVendorString(void)	= 0;
232
233    /*!
234     * @function getProductString
235     * @abstract
236     * Return Product Name string for the device.
237     * @result
238     * A pointer to a static character string.
239     */
240    virtual char *	getProductString(void)	= 0;
241
242    /*!
243     * @function getRevisionString
244     * @abstract
245     * Return Product Revision string for the device.
246     * @result
247     * A pointer to a static character string.
248     */
249    virtual char *	getRevisionString(void)	= 0;
250
251    /*!
252     * @function getAdditionalDeviceInfoString
253     * @abstract
254     * Return additional informational string for the device.
255     * @result
256     * A pointer to a static character string.
257     */
258    virtual char *	getAdditionalDeviceInfoString(void)	= 0;
259
260    /*!
261     * @function reportBlockSize
262     * @abstract
263     * Report the block size for the device, in bytes.
264     * @param blockSize
265     * Pointer to returned block size value.
266     */
267    virtual IOReturn	reportBlockSize(UInt64 *blockSize)	= 0;
268
269    /*!
270     * @function reportEjectability
271     * @abstract
272     * Report if the media is ejectable under software control.
273     * @discussion
274     * This method should only be called if the media is known to be removable.
275     * @param isEjectable
276     * Pointer to returned result. True indicates the media is ejectable, False indicates
277     * the media cannot be ejected under software control.
278     */
279    virtual IOReturn	reportEjectability(bool *isEjectable)	= 0;
280
281    virtual IOReturn	reportLockability(bool *isLockable) __attribute__ ((deprecated));
282
283#ifndef __LP64__
284    virtual IOReturn	reportMaxReadTransfer(UInt64 blockSize,UInt64 *max) __attribute__ ((deprecated));
285
286    virtual IOReturn	reportMaxWriteTransfer(UInt64 blockSize,UInt64 *max) __attribute__ ((deprecated));
287#endif /* !__LP64__ */
288
289    /*!
290     * @function reportMaxValidBlock
291     * @abstract
292     * Report the highest valid block for the device.
293     * @param maxBlock
294     * Pointer to returned result
295     */
296    virtual IOReturn	reportMaxValidBlock(UInt64 *maxBlock)	= 0;
297
298    /*!
299     * @function reportMediaState
300     * @abstract
301     * Report the device's media state.
302     * @discussion
303     * This method reports whether we have media in the drive or not, and
304     * whether the state has changed from the previously reported state.
305     *
306     * A result of kIOReturnSuccess is always returned if the test for media is successful,
307     * regardless of media presence. The mediaPresent result should be used to determine
308     * whether media is present or not. A return other than kIOReturnSuccess indicates that
309     * the Transport Driver was unable to interrogate the device. In this error case, the
310     * outputs mediaState and changedState will *not* be stored.
311     * @param mediaPresent Pointer to returned media state. True indicates media is present
312     * in the device; False indicates no media is present.
313     */
314    virtual IOReturn	reportMediaState(bool *mediaPresent,bool *changedState = 0)	= 0;
315
316    virtual IOReturn	reportPollRequirements(bool *pollRequired,
317                                            bool *pollIsExpensive) __attribute__ ((deprecated));
318
319    /*!
320     * @function reportRemovability
321     * @abstract
322     * Report whether the media is removable or not.
323     * @discussion
324     * This method reports whether the media is removable, but it does not
325     * provide detailed information regarding software eject or lock/unlock capability.
326     * @param isRemovable
327     * Pointer to returned result. True indicates that the media is removable; False
328     * indicates the media is not removable.
329     */
330    virtual IOReturn	reportRemovability(bool *isRemovable)  	= 0;
331
332    /*!
333     * @function reportWriteProtection
334     * @abstract
335     * Report whether the media is write-protected or not.
336     * @param isWriteProtected
337     * Pointer to returned result. True indicates that the media is write-protected (it
338     * cannot be written); False indicates that the media is not write-protected (it
339     * is permissible to write).
340     */
341    virtual IOReturn	reportWriteProtection(bool *isWriteProtected)	= 0;
342
343#ifndef __LP64__
344    virtual IOReturn	doAsyncReadWrite(IOMemoryDescriptor *buffer,
345                                            UInt64 block, UInt64 nblks,
346                                            IOStorageCompletion completion) __attribute__ ((deprecated));
347#endif /* !__LP64__ */
348
349    /*!
350     * @function getWriteCacheState
351     * @abstract
352     * Reports the current write cache state of the device.
353     * @discussion
354     * Reports the current write cache state of the device.  The write cache
355     * state is not guaranteed to persist across reboots and detaches.
356     * @param enabled
357     * Pointer to returned result. True indicates the write cache is enabled;
358     * False indicates the write cache is disabled.
359     */
360#ifdef __LP64__
361    virtual IOReturn	getWriteCacheState(bool *enabled)	= 0;
362#else /* !__LP64__ */
363    virtual IOReturn	getWriteCacheState(bool *enabled); /* 10.3.0 */
364#endif /* !__LP64__ */
365
366    /*!
367     * @function setWriteCacheState
368     * @abstract
369     * Sets the write cache state of the device.
370     * @discussion
371     * Sets the write cache state of the device.  The write cache state
372     * is not guaranteed to persist across reboots and detaches.
373     * @param enabled
374     * True to enable the write cache; False to disable the write cache.
375     */
376#ifdef __LP64__
377    virtual IOReturn	setWriteCacheState(bool enabled)	= 0;
378#else /* !__LP64__ */
379    virtual IOReturn	setWriteCacheState(bool enabled); /* 10.3.0 */
380#endif /* !__LP64__ */
381
382    /*!
383     * @function doAsyncReadWrite
384     * @abstract
385     * Start an asynchronous read or write operation.
386     * @param buffer
387     * An IOMemoryDescriptor describing the data-transfer buffer. The data direction
388     * is contained in the IOMemoryDescriptor. Responsibility for releasing the descriptor
389     * rests with the caller.
390     * @param block
391     * The starting block number of the data transfer.
392     * @param nblks
393     * The integral number of blocks to be transferred.
394     * @param attributes
395     * Attributes of the data transfer.  See IOStorageAttributes.
396     * @param completion
397     * The completion routine to call once the data transfer is complete.
398     */
399#ifdef __LP64__
400    virtual IOReturn	doAsyncReadWrite(IOMemoryDescriptor *buffer,
401                                            UInt64 block, UInt64 nblks,
402                                            IOStorageAttributes *attributes,
403                                            IOStorageCompletion *completion)	= 0;
404#else /* !__LP64__ */
405    virtual IOReturn	doAsyncReadWrite(IOMemoryDescriptor *buffer,
406                                            UInt64 block, UInt64 nblks,
407                                            IOStorageAttributes *attributes,
408                                            IOStorageCompletion *completion); /* 10.5.0 */
409#endif /* !__LP64__ */
410
411    /*!
412     * @function requestIdle
413     * @abstract
414     * Request that the device enter an idle state.
415     * @discussion
416     * Request that the device enter an idle state.  The device will exit this state on the
417     * next read or write request, or as it sees necessary.  One example is for a DVD drive
418     * to spin down when it enters such an idle state, and spin up on the next read request
419     * from the system.
420     */
421    virtual IOReturn	requestIdle(void); /* 10.6.0 */
422
423    virtual IOReturn doDiscard(UInt64 block, UInt64 nblks) __attribute__ ((deprecated));
424
425    /*!
426     * @function doUnmap
427     * @abstract
428     * Delete unused data blocks from the media.
429     * @param extents
430     * List of extents.  See IOBlockStorageDeviceExtent.  It is legal for the callee to
431     * overwrite the contents of this buffer in order to satisfy the request.
432     * @param extentsCount
433     * Number of extents.
434     */
435    virtual IOReturn doUnmap(IOBlockStorageDeviceExtent * extents,
436                             UInt32                       extentsCount,
437                             UInt32                       options = 0); /* 10.6.6 */
438
439    /*!
440     * @function doSetPriority
441     * @abstract
442     * Reprioritize read or write operations.
443     * @param extents
444     * List of extents.  See IOBlockStorageDeviceExtent.  It is legal for the callee to
445     * overwrite the contents of this buffer in order to satisfy the request.
446     * @param extentsCount
447     * Number of extents.
448     * @param priority
449     * New priority.  See IOStoragePriority.
450     */
451    virtual IOReturn doSetPriority(IOBlockStorageDeviceExtent * extents,
452                                   UInt32                       extentsCount,
453                                   IOStoragePriority            priority); /* 10.10.0 */
454
455    OSMetaClassDeclareReservedUsed(IOBlockStorageDevice,  0);
456    OSMetaClassDeclareReservedUsed(IOBlockStorageDevice,  1);
457#ifdef __LP64__
458    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice,  2);
459    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice,  3);
460    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice,  4);
461    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice,  5);
462    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice,  6);
463    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice,  7);
464#else /* !__LP64__ */
465    OSMetaClassDeclareReservedUsed(IOBlockStorageDevice,  2);
466    OSMetaClassDeclareReservedUsed(IOBlockStorageDevice,  3);
467    OSMetaClassDeclareReservedUsed(IOBlockStorageDevice,  4);
468    OSMetaClassDeclareReservedUsed(IOBlockStorageDevice,  5);
469    OSMetaClassDeclareReservedUsed(IOBlockStorageDevice,  6);
470    OSMetaClassDeclareReservedUsed(IOBlockStorageDevice,  7);
471#endif /* !__LP64__ */
472    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice,  8);
473    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice,  9);
474    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 10);
475    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 11);
476    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 12);
477    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 13);
478    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 14);
479    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 15);
480    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 16);
481    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 17);
482    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 18);
483    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 19);
484    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 20);
485    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 21);
486    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 22);
487    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 23);
488    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 24);
489    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 25);
490    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 26);
491    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 27);
492    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 28);
493    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 29);
494    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 30);
495    OSMetaClassDeclareReservedUnused(IOBlockStorageDevice, 31);
496};
497
498#endif /* __cplusplus */
499#endif /* KERNEL */
500#endif /* !_IOBLOCKSTORAGEDEVICE_H */
501