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