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 IOPartitionScheme
26 * @abstract
27 * This header contains the IOPartitionScheme class definition.
28 */
29
30#ifndef _IOPARTITIONSCHEME_H
31#define _IOPARTITIONSCHEME_H
32
33/*!
34 * @defined kIOPartitionSchemeClass
35 * @abstract
36 * The name of the IOPartitionScheme class.
37 * @discussion
38 * kIOPartitionSchemeClass is the name of the IOPartitionScheme class.
39 */
40
41#define kIOPartitionSchemeClass "IOPartitionScheme"
42
43/*!
44 * @defined kIOMediaBaseKey
45 * @abstract
46 * A property of IOMedia objects.
47 * @discussion
48 * The kIOMediaBaseKey property has an OSNumber value and is placed into an
49 * IOMedia instance created via the partition scheme. It describes the byte
50 * offset of the partition relative to the provider media.
51 */
52
53#define kIOMediaBaseKey "Base"
54
55/*!
56 * @defined kIOMediaLiveKey
57 * @abstract
58 * A property of IOMedia objects.
59 * @discussion
60 * The kIOMediaLiveKey property has an OSBoolean
61 * value and is placed into an IOMedia instance
62 * created via the partition scheme.  It describes whether the
63 * partition is live, that is, it is up-to-date with respect
64 * to the on-disk partition table.
65 */
66
67#define kIOMediaLiveKey "Live"
68
69/*!
70 * @defined kIOMediaPartitionIDKey
71 * @abstract
72 * A property of IOMedia objects.
73 * @discussion
74 * The kIOMediaPartitionIDKey property has an OSNumber
75 * value and is placed into an IOMedia instance
76 * created via the partition scheme.  It is an ID that differentiates one
77 * partition from the other (within a given scheme).  It is typically an index
78 * into the on-disk partition table.
79 */
80
81#define kIOMediaPartitionIDKey "Partition ID"
82
83#ifdef KERNEL
84#ifdef __cplusplus
85
86/*
87 * Kernel
88 */
89
90#include <IOKit/storage/IOMedia.h>
91#include <IOKit/storage/IOStorage.h>
92
93/*!
94 * @class IOPartitionScheme
95 * @abstract
96 * The common base class for all partition scheme
97 * objects.
98 * @discussion
99 * The IOPartitionScheme class is the common base class for all partition scheme
100 * objects.  It extends the IOStorage class by implementing the appropriate open
101 * and close semantics for partition objects (standard semantics are to act as a
102 * multiplexor for incoming opens,  producing one outgoing open with the correct
103 * access).  It also implements the default read and write semantics, which pass
104 * all reads and writes through to the provider media unprocessed.    For simple
105 * schemes, the default behavior is sufficient.   More complex partition schemes
106 * such as RAID will want to do extra processing for reads and writes.
107 */
108
109class IOPartitionScheme : public IOStorage
110{
111    OSDeclareDefaultStructors(IOPartitionScheme);
112
113protected:
114
115    struct ExpansionData { /* */ };
116    ExpansionData * _expansionData;
117
118    IOStorageAccess _openLevel;
119    OSSet *         _openReaders;
120    OSSet *         _openReaderWriters;
121
122    /*
123     * Free all of this object's outstanding resources.
124     */
125
126    virtual void free();
127
128    /*!
129     * @function handleOpen
130     * @discussion
131     * The handleOpen method grants or denies permission to access this object
132     * to an interested client.  The argument is an IOStorageAccess value that
133     * specifies the level of access desired -- reader or reader-writer.
134     *
135     * This method can be invoked to upgrade or downgrade the access level for
136     * an existing client as well.  The previous access level will prevail for
137     * upgrades that fail, of course.   A downgrade should never fail.  If the
138     * new access level should be the same as the old for a given client, this
139     * method will do nothing and return success.  In all cases, one, singular
140     * close-per-client is expected for all opens-per-client received.
141     *
142     * This implementation replaces the IOService definition of handleOpen().
143     * @param client
144     * Client requesting the open.
145     * @param options
146     * Options for the open.  Set to zero.
147     * @param access
148     * Access level for the open.  Set to kIOStorageAccessReader or
149     * kIOStorageAccessReaderWriter.
150     * @result
151     * Returns true if the open was successful, false otherwise.
152     */
153
154    virtual bool handleOpen(IOService *  client,
155                            IOOptionBits options,
156                            void *       access);
157
158    /*!
159     * @function handleIsOpen
160     * @discussion
161     * The handleIsOpen method determines whether the specified client, or any
162     * client if none is specified, presently has an open on this object.
163     *
164     * This implementation replaces the IOService definition of handleIsOpen().
165     * @param client
166     * Client to check the open state of.  Set to zero to check the open state
167     * of all clients.
168     * @result
169     * Returns true if the client was (or clients were) open, false otherwise.
170     */
171
172    virtual bool handleIsOpen(const IOService * client) const;
173
174    /*!
175     * @function handleClose
176     * @discussion
177     * The handleClose method closes the client's access to this object.
178     *
179     * This implementation replaces the IOService definition of handleClose().
180     * @param client
181     * Client requesting the close.
182     * @param options
183     * Options for the close.  Set to zero.
184     */
185
186    virtual void handleClose(IOService * client, IOOptionBits options);
187
188    /*
189     * Attach the given media object to the device tree plane.
190     */
191
192#ifdef __LP64__
193    virtual bool attachMediaObjectToDeviceTree(IOMedia * media);
194#else /* !__LP64__ */
195    virtual bool attachMediaObjectToDeviceTree(IOMedia *    media,
196                                               IOOptionBits options = 0); /* 10.5.0 */
197#endif /* !__LP64__ */
198
199    /*
200     * Detach the given media object from the device tree plane.
201     */
202
203#ifdef __LP64__
204    virtual void detachMediaObjectFromDeviceTree(IOMedia * media);
205#else /* !__LP64__ */
206    virtual void detachMediaObjectFromDeviceTree(IOMedia *    media,
207                                                 IOOptionBits options = 0); /* 10.5.0 */
208#endif /* !__LP64__ */
209
210    /*
211     * Updates a set of existing partitions, represented by partitionsOld,
212     * with possible updates from a rescan of the disk, represented by
213     * partitionsNew.  It returns a new set of partitions with the results,
214     * removing partitions from partitionsOld where applicable, adding
215     * partitions from partitionsNew where applicable, and folding in property
216     * changes to partitions from partitionsNew into partitionsOld where
217     * applicable.
218     */
219
220    virtual OSSet * juxtaposeMediaObjects(OSSet * partitionsOld,
221                                          OSSet * partitionsNew); /* 10.5.0 */
222
223public:
224
225    using IOStorage::read;
226    using IOStorage::write;
227
228    /*
229     * Initialize this object's minimal state.
230     */
231
232    virtual bool init(OSDictionary * properties = 0);
233
234    /*!
235     * @function read
236     * @discussion
237     * Read data from the storage object at the specified byte offset into the
238     * specified buffer, asynchronously.   When the read completes, the caller
239     * will be notified via the specified completion action.
240     *
241     * The buffer will be retained for the duration of the read.
242     *
243     * For simple partition schemes, the default behavior is to simply pass the
244     * read through to the provider media.  More complex partition schemes such
245     * as RAID will need to do extra processing here.
246     * @param client
247     * Client requesting the read.
248     * @param byteStart
249     * Starting byte offset for the data transfer.
250     * @param buffer
251     * Buffer for the data transfer.  The size of the buffer implies the size of
252     * the data transfer.
253     * @param attributes
254     * Attributes of the data transfer.  See IOStorageAttributes.  It is the
255     * responsibility of the callee to maintain the information for the duration
256     * of the data transfer, as necessary.
257     * @param completion
258     * Completion routine to call once the data transfer is complete.  It is the
259     * responsibility of the callee to maintain the information for the duration
260     * of the data transfer, as necessary.
261     */
262
263    virtual void read(IOService *           client,
264                      UInt64                byteStart,
265                      IOMemoryDescriptor *  buffer,
266                      IOStorageAttributes * attributes,
267                      IOStorageCompletion * completion);
268
269    /*!
270     * @function write
271     * @discussion
272     * Write data into the storage object at the specified byte offset from the
273     * specified buffer, asynchronously.   When the write completes, the caller
274     * will be notified via the specified completion action.
275     *
276     * The buffer will be retained for the duration of the write.
277     *
278     * For simple partition schemes, the default behavior is to simply pass the
279     * write through to the provider media. More complex partition schemes such
280     * as RAID will need to do extra processing here.
281     * @param client
282     * Client requesting the write.
283     * @param byteStart
284     * Starting byte offset for the data transfer.
285     * @param buffer
286     * Buffer for the data transfer.  The size of the buffer implies the size of
287     * the data transfer.
288     * @param attributes
289     * Attributes of the data transfer.  See IOStorageAttributes.  It is the
290     * responsibility of the callee to maintain the information for the duration
291     * of the data transfer, as necessary.
292     * @param completion
293     * Completion routine to call once the data transfer is complete.  It is the
294     * responsibility of the callee to maintain the information for the duration
295     * of the data transfer, as necessary.
296     */
297
298    virtual void write(IOService *           client,
299                       UInt64                byteStart,
300                       IOMemoryDescriptor *  buffer,
301                       IOStorageAttributes * attributes,
302                       IOStorageCompletion * completion);
303
304    /*!
305     * @function synchronizeCache
306     * @discussion
307     * Flush the cached data in the storage object, if any, synchronously.
308     * @param client
309     * Client requesting the cache synchronization.
310     * @result
311     * Returns the status of the cache synchronization.
312     */
313
314    virtual IOReturn synchronizeCache(IOService * client);
315
316    /*!
317     * @function unmap
318     * @discussion
319     * Delete unused data from the storage object at the specified byte offsets,
320     * synchronously.
321     * @param client
322     * Client requesting the operation.
323     * @param extents
324     * List of extents.  See IOStorageExtent.  It is legal for the callee to
325     * overwrite the contents of this buffer in order to satisfy the request.
326     * @param extentsCount
327     * Number of extents.
328     * @result
329     * Returns the status of the operation.
330     */
331
332    virtual IOReturn unmap(IOService *       client,
333                           IOStorageExtent * extents,
334                           UInt32            extentsCount,
335                           UInt32            options = 0);
336
337    /*!
338     * @function lockPhysicalExtents
339     * @discussion
340     * Lock the contents of the storage object against relocation temporarily,
341     * for the purpose of getting physical extents.
342     * @param client
343     * Client requesting the operation.
344     * @result
345     * Returns true if the lock was successful, false otherwise.
346     */
347
348    virtual bool lockPhysicalExtents(IOService * client);
349
350    /*!
351     * @function copyPhysicalExtent
352     * @discussion
353     * Convert the specified byte offset into a physical byte offset, relative
354     * to a physical storage object.  This call should only be made within the
355     * context of lockPhysicalExtents().
356     * @param client
357     * Client requesting the operation.
358     * @param byteStart
359     * Starting byte offset for the operation.  Returns a physical byte offset,
360     * relative to the physical storage object, on success.
361     * @param byteCount
362     * Size of the operation.  Returns the actual number of bytes which can be
363     * transferred, relative to the physical storage object, on success.
364     * @result
365     * A reference to the physical storage object, which should be released by
366     * the caller, or a null on error.
367     */
368
369    virtual IOStorage * copyPhysicalExtent(IOService * client,
370                                           UInt64 *    byteStart,
371                                           UInt64 *    byteCount);
372
373    /*!
374     * @function unlockPhysicalExtents
375     * @discussion
376     * Unlock the contents of the storage object for relocation again.  This
377     * call must balance a successful call to lockPhysicalExtents().
378     * @param client
379     * Client requesting the operation.
380     */
381
382    virtual void unlockPhysicalExtents(IOService * client);
383
384    /*!
385     * @function setPriority
386     * @discussion
387     * Reprioritize read or write requests at the specified byte offsets.
388     * @param client
389     * Client requesting the operation.
390     * @param extents
391     * List of extents.  See IOStorageExtent.  It is legal for the callee to
392     * overwrite the contents of this buffer in order to satisfy the request.
393     * @param extentsCount
394     * Number of extents.
395     * @param priority
396     * New priority.  See IOStoragePriority.
397     * @result
398     * Returns the status of the operation.
399     */
400
401    virtual IOReturn setPriority(IOService *       client,
402                                 IOStorageExtent * extents,
403                                 UInt32            extentsCount,
404                                 IOStoragePriority priority);
405
406    /*
407     * Obtain this object's provider.  We override the superclass's method
408     * to return a more specific subclass of OSObject -- an IOMedia.  This
409     * method serves simply as a convenience to subclass developers.
410     */
411
412    virtual IOMedia * getProvider() const;
413
414#ifdef __LP64__
415    OSMetaClassDeclareReservedUnused(IOPartitionScheme,  0);
416    OSMetaClassDeclareReservedUnused(IOPartitionScheme,  1);
417    OSMetaClassDeclareReservedUnused(IOPartitionScheme,  2);
418#else /* !__LP64__ */
419    OSMetaClassDeclareReservedUsed(IOPartitionScheme,  0);
420    OSMetaClassDeclareReservedUsed(IOPartitionScheme,  1);
421    OSMetaClassDeclareReservedUsed(IOPartitionScheme,  2);
422#endif /* !__LP64__ */
423    OSMetaClassDeclareReservedUnused(IOPartitionScheme,  3);
424    OSMetaClassDeclareReservedUnused(IOPartitionScheme,  4);
425    OSMetaClassDeclareReservedUnused(IOPartitionScheme,  5);
426    OSMetaClassDeclareReservedUnused(IOPartitionScheme,  6);
427    OSMetaClassDeclareReservedUnused(IOPartitionScheme,  7);
428    OSMetaClassDeclareReservedUnused(IOPartitionScheme,  8);
429    OSMetaClassDeclareReservedUnused(IOPartitionScheme,  9);
430    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 10);
431    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 11);
432    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 12);
433    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 13);
434    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 14);
435    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 15);
436    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 16);
437    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 17);
438    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 18);
439    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 19);
440    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 20);
441    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 21);
442    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 22);
443    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 23);
444    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 24);
445    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 25);
446    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 26);
447    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 27);
448    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 28);
449    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 29);
450    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 30);
451    OSMetaClassDeclareReservedUnused(IOPartitionScheme, 31);
452};
453
454#endif /* __cplusplus */
455#endif /* KERNEL */
456#endif /* !_IOPARTITIONSCHEME_H */
457