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