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 IOBlockStorageDriver
26 * @abstract
27 * This header contains the IOBlockStorageDriver class definition.
28 */
29
30#ifndef _IOBLOCKSTORAGEDRIVER_H
31#define _IOBLOCKSTORAGEDRIVER_H
32
33#include <IOKit/IOTypes.h>
34
35/*!
36 * @defined kIOBlockStorageDriverClass
37 * @abstract
38 * The name of the IOBlockStorageDriver class.
39 */
40
41#define kIOBlockStorageDriverClass "IOBlockStorageDriver"
42
43/*!
44 * @defined kIOBlockStorageDriverStatisticsKey
45 * @abstract
46 * Holds a table of numeric values describing the driver's
47 * operating statistics.
48 * @discussion
49 * This property holds a table of numeric values describing the driver's
50 * operating statistics.  The table is an OSDictionary, where each entry
51 * describes one given statistic.
52 */
53
54#define kIOBlockStorageDriverStatisticsKey "Statistics"
55
56/*!
57 * @defined kIOBlockStorageDriverStatisticsBytesReadKey
58 * @abstract
59 * Describes the number of bytes read since the block storage
60 * driver was instantiated.
61 * @discussion
62 * This property describes the number of bytes read since the block storage
63 * driver was instantiated.  It is one of the statistic entries listed under
64 * the top-level kIOBlockStorageDriverStatisticsKey property table.  It has
65 * an OSNumber value.
66 */
67
68#define kIOBlockStorageDriverStatisticsBytesReadKey "Bytes (Read)"
69
70/*!
71 * @defined kIOBlockStorageDriverStatisticsBytesWrittenKey
72 * @abstract
73 * Describes the number of bytes written since the block storage
74 * driver was instantiated.
75 * @discussion
76 * This property describes the number of bytes written since the block storage
77 * driver was instantiated.  It is one of the statistic entries listed under the
78 * top-level kIOBlockStorageDriverStatisticsKey property table.  It has an
79 * OSNumber value.
80 */
81
82#define kIOBlockStorageDriverStatisticsBytesWrittenKey "Bytes (Write)"
83
84/*!
85 * @defined kIOBlockStorageDriverStatisticsReadErrorsKey
86 * @abstract
87 * Describes the number of read errors encountered since the block
88 * storage driver was instantiated.
89 * @discussion
90 * This property describes the number of read errors encountered since the block
91 * storage driver was instantiated.  It is one of the statistic entries listed
92 * under the top-level kIOBlockStorageDriverStatisticsKey property table.  It
93 * has an OSNumber value.
94 */
95
96#define kIOBlockStorageDriverStatisticsReadErrorsKey "Errors (Read)"
97
98/*!
99 * @defined kIOBlockStorageDriverStatisticsWriteErrorsKey
100 * @abstract
101 * Describes the number of write errors encountered since the
102 * block storage driver was instantiated.
103 * @discussion
104 * This property describes the number of write errors encountered since the
105 * block storage driver was instantiated.  It is one of the statistic entries
106 * listed under the top-level kIOBlockStorageDriverStatisticsKey property table.
107 * It has an OSNumber value.
108 */
109
110#define kIOBlockStorageDriverStatisticsWriteErrorsKey "Errors (Write)"
111
112/*!
113 * @defined kIOBlockStorageDriverStatisticsLatentReadTimeKey
114 * @abstract
115 * Describes the number of nanoseconds of latency during reads
116 * since the block storage driver was instantiated.
117 * @discussion
118 * This property describes the number of nanoseconds of latency during reads
119 * since the block storage driver was instantiated.  It is one of the statistic
120 * entries listed under the top-level kIOBlockStorageDriverStatisticsKey
121 * property table.  It has an OSNumber value.
122 */
123
124#define kIOBlockStorageDriverStatisticsLatentReadTimeKey "Latency Time (Read)"
125
126/*!
127 * @defined kIOBlockStorageDriverStatisticsLatentWriteTimeKey
128 * @abstract
129 * Describes the number of nanoseconds of latency during writes
130 * since the block storage driver was instantiated.
131 * @discussion
132 * This property describes the number of nanoseconds of latency during writes
133 * since the block storage driver was instantiated.  It is one of the statistic
134 * entries listed under the top-level kIOBlockStorageDriverStatisticsKey
135 * property table.  It has an OSNumber value.
136 */
137
138#define kIOBlockStorageDriverStatisticsLatentWriteTimeKey "Latency Time (Write)"
139
140/*!
141 * @defined kIOBlockStorageDriverStatisticsReadsKey
142 * @abstract
143 * Describes the number of read operations processed since the
144 * block storage driver was instantiated.
145 * @discussion
146 * This property describes the number of read operations processed since the
147 * block storage driver was instantiated.  It is one of the statistic entries
148 * listed under the top-level kIOBlockStorageDriverStatisticsKey property table.
149 * It has an OSNumber value.
150 */
151
152#define kIOBlockStorageDriverStatisticsReadsKey "Operations (Read)"
153
154/*!
155 * @defined kIOBlockStorageDriverStatisticsWritesKey
156 * @abstract
157 * Describes the number of write operations processed since the
158 * block storage driver was instantiated.
159 * @discussion
160 * This property describes the number of write operations processed since the
161 * block storage driver was instantiated.  It is one of the statistic entries
162 * listed under the top-level kIOBlockStorageDriverStatisticsKey property table.
163 * It has an OSNumber value.
164 */
165
166#define kIOBlockStorageDriverStatisticsWritesKey "Operations (Write)"
167
168/*!
169 * @defined kIOBlockStorageDriverStatisticsReadRetriesKey
170 * @abstract
171 * Describes the number of read retries required since the block
172 * storage driver was instantiated.
173 * @discussion
174 * This property describes the number of read retries required since the block
175 * storage driver was instantiated.  It is one of the statistic entries listed
176 * under the top-level kIOBlockStorageDriverStatisticsKey property table.  It
177 * has an OSNumber value.
178 */
179
180#define kIOBlockStorageDriverStatisticsReadRetriesKey "Retries (Read)"
181
182/*!
183 * @defined kIOBlockStorageDriverStatisticsWriteRetriesKey
184 * @abstract
185 * Describes the number of write retries required since the block
186 * storage driver was instantiated.
187 * @discussion
188 * This property describes the number of write retries required since the block
189 * storage driver was instantiated.  It is one of the statistic entries listed
190 * under the top-level kIOBlockStorageDriverStatisticsKey property table.  It
191 * has an OSNumber value.
192 */
193
194#define kIOBlockStorageDriverStatisticsWriteRetriesKey "Retries (Write)"
195
196/*!
197 * @defined kIOBlockStorageDriverStatisticsTotalReadTimeKey
198 * @abstract
199 * Describes the number of nanoseconds spent performing reads
200 * since the block storage driver was instantiated.
201 * @discussion
202 * This property describes the number of nanoseconds spent performing reads
203 * since the block storage driver was instantiated.  It is one of the statistic
204 * entries listed under the top-level kIOBlockStorageDriverStatisticsKey
205 * property table.  It has an OSNumber value.
206 */
207
208#define kIOBlockStorageDriverStatisticsTotalReadTimeKey "Total Time (Read)"
209
210/*!
211 * @defined kIOBlockStorageDriverStatisticsTotalWriteTimeKey
212 * @abstract
213 * Describes the number of nanoseconds spent performing writes
214 * since the block storage driver was instantiated.
215 * @discussion
216 * This property describes the number of nanoseconds spent performing writes
217 * since the block storage driver was instantiated.  It is one of the statistic
218 * entries listed under the top-level kIOBlockStorageDriverStatisticsKey
219 * property table.  It has an OSNumber value.
220 */
221
222#define kIOBlockStorageDriverStatisticsTotalWriteTimeKey "Total Time (Write)"
223
224/*!
225 * @enum IOMediaState
226 * @abstract
227 * The different states that getMediaState() can report.
228 * @constant kIOMediaStateOffline
229 * Media is not available.
230 * @constant kIOMediaStateOnline
231 * Media is available and ready for operations.
232 * @constant kIOMediaStateBusy
233 * Media is available, but not ready for operations.
234 */
235
236enum
237{
238    kIOMediaStateOffline = 0,
239    kIOMediaStateOnline  = 1,
240    kIOMediaStateBusy    = 2
241};
242
243typedef UInt32 IOMediaState;
244
245#ifdef KERNEL
246#ifdef __cplusplus
247
248/*
249 * Kernel
250 */
251
252#include <IOKit/storage/IOBlockStorageDevice.h>
253#include <IOKit/storage/IOMedia.h>
254#include <IOKit/storage/IOStorage.h>
255
256/*!
257 * @class IOBlockStorageDriver
258 * @abstract
259 * The common base class for generic block storage drivers.
260 * @discussion
261 * The IOBlockStorageDriver class is the common base class for generic block
262 * storage drivers.  It matches and communicates via an IOBlockStorageDevice
263 * interface, and connects to the remainder of the storage framework via the
264 * IOStorage protocol. It extends the IOStorage protocol by implementing the
265 * appropriate open and close semantics, deblocking for unaligned transfers,
266 * polling for ejectable media, locking and ejection policies, media object
267 * creation and tear-down, and statistics gathering and reporting.
268 *
269 * Block storage drivers are split into two parts: the generic driver handles
270 * all generic device issues, independent of the lower-level transport
271 * mechanism (e.g. SCSI, ATA, USB, FireWire). All storage operations
272 * at the generic driver level are translated into a series of generic
273 * device operations. These operations are passed via the IOBlockStorageDevice
274 * nub to a transport driver, which implements the appropriate
275 * transport-dependent protocol to execute these operations.
276 *
277 * To determine the write-protect state of a device (or media), for
278 * example, the generic driver would issue a call to the
279 * Transport Driver's reportWriteProtection method. If this were a SCSI
280 * device, its transport driver would issue a Mode Sense command to
281 * extract the write-protection status bit. The transport driver then
282 * reports true or false to the generic driver.
283 *
284 * The generic driver therefore has no knowledge of, or involvement
285 * with, the actual commands and mechanisms used to communicate with
286 * the device. It is expected that the generic driver will rarely, if
287 * ever, need to be subclassed to handle device idiosyncrasies; rather,
288 * the transport driver should be changed via overrides.
289 *
290 * A generic driver could be subclassed to create a different type of
291 * generic device. The generic driver IOCDBlockStorageDriver class is
292 * a subclass of IOBlockStorageDriver, adding CD functions.
293 */
294
295class IOBlockStorageDriver : public IOStorage
296{
297    OSDeclareDefaultStructors(IOBlockStorageDriver);
298
299public:
300
301    /*!
302     * @enum Statistics
303     * @abstract
304     * Indices for the different statistics that getStatistics() can report.
305     * @constant kStatisticsReads Number of read operations thus far.
306     * @constant kStatisticsBytesRead Number of bytes read thus far.
307     * @constant kStatisticsTotalReadTime Nanoseconds spent performing reads thus far.
308     * @constant kStatisticsLatentReadTime Nanoseconds of latency during reads thus far.
309     * @constant kStatisticsReadRetries Number of read retries thus far.
310     * @constant kStatisticsReadErrors Number of read errors thus far.
311     * @constant kStatisticsWrites Number of write operations thus far.
312     * @constant kStatisticsSingleBlockWrites Number of write operations for a single block thus far.
313     * @constant kStatisticsBytesWritten Number of bytes written thus far.
314     * @constant kStatisticsTotalWriteTime Nanoseconds spent performing writes thus far.
315     * @constant kStatisticsLatentWriteTime Nanoseconds of latency during writes thus far.
316     * @constant kStatisticsWriteRetries Number of write retries thus far.
317     * @constant kStatisticsWriteErrors Number of write errors thus far.
318     */
319
320    enum Statistics
321    {
322        kStatisticsReads,
323        kStatisticsBytesRead,
324        kStatisticsTotalReadTime,
325        kStatisticsLatentReadTime,
326        kStatisticsReadRetries,
327        kStatisticsReadErrors,
328
329        kStatisticsWrites,
330        kStatisticsSingleBlockWrites,
331        kStatisticsBytesWritten,
332        kStatisticsTotalWriteTime,
333        kStatisticsLatentWriteTime,
334        kStatisticsWriteRetries,
335        kStatisticsWriteErrors
336    };
337
338    static const UInt32 kStatisticsCount = kStatisticsWriteErrors + 1;
339
340protected:
341
342    struct Context;
343
344    struct ExpansionData
345    {
346#ifdef __LP64__
347        UInt64         reserved0000;
348#else /* !__LP64__ */
349        UInt32         reserved0000;
350#endif /* !__LP64__ */
351        UInt64         maxReadBlockTransfer;
352        UInt64         maxWriteBlockTransfer;
353        IONotifier *   powerEventNotifier;
354        UInt32         deblockRequestWriteLockCount;
355        UInt64         maxReadSegmentTransfer;
356        UInt64         maxWriteSegmentTransfer;
357        UInt64         maxReadSegmentByteTransfer;
358        UInt64         maxWriteSegmentByteTransfer;
359        UInt64         minSegmentAlignmentByteTransfer;
360        UInt64         maxSegmentWidthByteTransfer;
361        Context *      contexts;
362        IOSimpleLock * contextsLock;
363        UInt32         contextsCount;
364        UInt32         contextsMaxCount;
365    };
366    ExpansionData * _expansionData;
367
368    #define _maxReadBlockTransfer            \
369              IOBlockStorageDriver::_expansionData->maxReadBlockTransfer
370    #define _maxWriteBlockTransfer           \
371              IOBlockStorageDriver::_expansionData->maxWriteBlockTransfer
372    #define _powerEventNotifier              \
373              IOBlockStorageDriver::_expansionData->powerEventNotifier
374    #define _deblockRequestWriteLockCount    \
375              IOBlockStorageDriver::_expansionData->deblockRequestWriteLockCount
376    #define _maxReadSegmentTransfer          \
377              IOBlockStorageDriver::_expansionData->maxReadSegmentTransfer
378    #define _maxWriteSegmentTransfer         \
379              IOBlockStorageDriver::_expansionData->maxWriteSegmentTransfer
380    #define _maxReadSegmentByteTransfer      \
381              IOBlockStorageDriver::_expansionData->maxReadSegmentByteTransfer
382    #define _maxWriteSegmentByteTransfer     \
383              IOBlockStorageDriver::_expansionData->maxWriteSegmentByteTransfer
384    #define _minSegmentAlignmentByteTransfer \
385              IOBlockStorageDriver::_expansionData->minSegmentAlignmentByteTransfer
386    #define _maxSegmentWidthByteTransfer     \
387              IOBlockStorageDriver::_expansionData->maxSegmentWidthByteTransfer
388    #define _contexts                        \
389              IOBlockStorageDriver::_expansionData->contexts
390    #define _contextsLock                    \
391              IOBlockStorageDriver::_expansionData->contextsLock
392    #define _contextsCount                   \
393              IOBlockStorageDriver::_expansionData->contextsCount
394    #define _contextsMaxCount                \
395              IOBlockStorageDriver::_expansionData->contextsMaxCount
396
397    OSSet *         _openClients;
398    OSNumber *      _statistics[kStatisticsCount];
399
400    /*
401     * @struct Context
402     * @discussion
403     * Context structure for a read/write operation.  It describes the block size,
404     * and where applicable, a block type and block sub-type, for a data transfer,
405     * as well as the completion information for the original request.  Note that
406     * the block type field is unused in the IOBlockStorageDriver class.
407     * @field block.size
408     * Block size for the operation.
409     * @field block.type
410     * Block type for the operation.  Unused in IOBlockStorageDriver.  The default
411     * value for this field is IOBlockStorageDriver::kBlockTypeStandard.
412     * @field block.typeSub
413     * Block sub-type for the operation.  It's definition depends on block.type.
414     * Unused in IOBlockStorageDriver.
415     * @field request.byteStart
416     * Starting byte offset for the data transfer.
417     * @param request.buffer
418     * Buffer for the data transfer.  The size of the buffer implies the size of
419     * the data transfer.
420     * @param request.attributes
421     * Attributes of the data transfer.  See IOStorageAttributes.
422     * @param request.completion
423     * Completion routine to call once the data transfer is complete.
424     */
425
426    struct Context
427    {
428#ifdef __LP64__
429        struct
430        {
431            UInt64               byteStart;
432            IOMemoryDescriptor * buffer;
433            IOStorageAttributes  attributes;
434            IOStorageCompletion  completion;
435        } request;
436
437        struct
438        {
439            UInt32               size;
440            UInt8                type;
441            UInt8                typeSub[3];
442        } block;
443
444        AbsoluteTime timeStart;
445
446        UInt64 reserved0704;
447        UInt64 reserved0768;
448        UInt64 reserved0832;
449        UInt64 reserved0896;
450#else /* !__LP64__ */
451        struct
452        {
453            UInt32               size;
454            UInt8                type;
455            UInt8                typeSub[3];
456        } block;
457
458        struct
459        {
460            UInt64               byteStart;
461            IOMemoryDescriptor * buffer;
462            IOStorageCompletion  completion;
463        } original;
464
465        AbsoluteTime timeStart;
466
467        struct
468        {
469            IOStorageAttributes  attributes;
470        } request;
471
472        UInt32 reserved0448;
473#endif /* !__LP64__ */
474
475        Context * next;
476    };
477
478    static const UInt8 kBlockTypeStandard = 0x00;
479
480    using IOService::open;
481
482    /*
483     * Free all of this object's outstanding resources.
484     *
485     * This method's implementation is not typically overridden.
486     */
487
488    void free();
489
490    /*!
491     * @function handleOpen
492     * @discussion
493     * The handleOpen method grants or denies permission to access this object
494     * to an interested client.  The argument is an IOStorageAccess value that
495     * specifies the level of access desired -- reader or reader-writer.
496     *
497     * This method can be invoked to upgrade or downgrade the access level for
498     * an existing client as well.  The previous access level will prevail for
499     * upgrades that fail, of course.   A downgrade should never fail.  If the
500     * new access level should be the same as the old for a given client, this
501     * method will do nothing and return success.  In all cases, one, singular
502     * close-per-client is expected for all opens-per-client received.
503     *
504     * This implementation replaces the IOService definition of handleIsOpen().
505     * @param client
506     * Client requesting the open.
507     * @param options
508     * Options for the open.  Set to zero.
509     * @param access
510     * Access level for the open.  Set to kIOStorageAccessReader or
511     * kIOStorageAccessReaderWriter.
512     * @result
513     * Returns true if the open was successful, false otherwise.
514     */
515
516    virtual bool handleOpen(IOService *  client,
517                            IOOptionBits options,
518                            void *       access);
519
520    /*!
521     * @function handleIsOpen
522     * @discussion
523     * The handleIsOpen method determines whether the specified client, or any
524     * client if none is specified, presently has an open on this object.
525     *
526     * This implementation replaces the IOService definition of handleIsOpen().
527     * @param client
528     * Client to check the open state of.  Set to zero to check the open state
529     * of all clients.
530     * @result
531     * Returns true if the client was (or clients were) open, false otherwise.
532     */
533
534    virtual bool handleIsOpen(const IOService * client) const;
535
536    /*!
537     * @function handleClose
538     * @discussion
539     * The handleClose method closes the client's access to this object.
540     *
541     * This implementation replaces the IOService definition of handleIsOpen().
542     * @param client
543     * Client requesting the close.
544     * @param options
545     * Options for the close.  Set to zero.
546     */
547
548    virtual void handleClose(IOService * client, IOOptionBits options);
549
550    /*!
551     * @function addToBytesTransferred
552     * @discussion
553     * Update the total number of bytes transferred, the total transfer time,
554     * and the total latency time -- used for statistics.
555     *
556     * This method's implementation is not typically overridden.
557     * @param bytesTransferred
558     * Number of bytes transferred in this operation.
559     * @param totalTime
560     * Nanoseconds spent performing this operation.
561     * @param latentTime
562     * Nanoseconds of latency during this operation.
563     * @param isWrite
564     * Indicates whether this operation was a write, otherwise is was a read.
565     */
566
567    virtual void addToBytesTransferred(UInt64 bytesTransferred,
568                                       UInt64 totalTime,
569                                       UInt64 latentTime,
570                                       bool   isWrite);
571
572    /*!
573     * @function incrementErrors
574     * @discussion
575     * Update the total error count -- used for statistics.
576     *
577     * This method's implementation is not typically overridden.
578     * @param isWrite
579     * Indicates whether this operation was a write, otherwise is was a read.
580     */
581
582    virtual void incrementErrors(bool isWrite);
583
584    /*!
585     * @function incrementRetries
586     * @discussion
587     * Update the total retry count -- used for statistics.
588     *
589     * This method's implementation is not typically overridden.
590     * @param isWrite
591     * Indicates whether this operation was a write, otherwise is was a read.
592     */
593
594    virtual void incrementRetries(bool isWrite);
595
596    /*!
597     * @function allocateContext
598     * @discussion
599     * Allocate a context structure for a read/write operation.
600     * @result
601     * Context structure.
602     */
603
604    virtual Context * allocateContext();
605
606    /*!
607     * @function deleteContext
608     * @discussion
609     * Delete a context structure from a read/write operation.
610     * @param context
611     * Context structure to be deleted.
612     */
613
614    virtual void deleteContext(Context * context);
615
616#ifndef __LP64__
617    virtual void prepareRequest(UInt64               byteStart,
618                                IOMemoryDescriptor * buffer,
619                                IOStorageCompletion  completion) __attribute__ ((deprecated));
620#endif /* !__LP64__ */
621
622    /*!
623     * @function deblockRequest
624     * @discussion
625     * The deblockRequest method checks to see if the incoming request rests
626     * on the media's block boundaries, and if not, deblocks it.  Deblocking
627     * involves rounding out the request to the nearest block boundaries and
628     * transferring the excess bytes into a scratch buffer.
629     *
630     * This method is part of a sequence of methods invoked for each read/write
631     * request.  The first is prepareRequest, which allocates and prepares some
632     * context for the transfer; the second is deblockRequest, which aligns the
633     * transfer at the media's block boundaries; third is breakUpRequest, which
634     * breaks up the transfer into multiple sub-transfers when certain hardware
635     * constraints are exceeded; fourth is executeRequest, which implements the
636     * actual transfer from the block storage device.
637     *
638     * This method's implementation is not typically overridden.
639     * @param byteStart
640     * Starting byte offset for the data transfer.
641     * @param buffer
642     * Buffer for the data transfer.  The size of the buffer implies the size of
643     * the data transfer.
644     * @param attributes
645     * Attributes of the data transfer.  See IOStorageAttributes.  It is the
646     * responsibility of the callee to maintain the information for the duration
647     * of the data transfer, as necessary.
648     * @param completion
649     * Completion routine to call once the data transfer is complete.  It is the
650     * responsibility of the callee to maintain the information for the duration
651     * of the data transfer, as necessary.
652     * @param context
653     * Additional context information for the data transfer (e.g. block size).
654     */
655
656#ifdef __LP64__
657    virtual void deblockRequest(UInt64                byteStart,
658                                IOMemoryDescriptor *  buffer,
659                                IOStorageAttributes * attributes,
660                                IOStorageCompletion * completion,
661                                Context *             context);
662#else /* !__LP64__ */
663    virtual void deblockRequest(UInt64                byteStart,
664                                IOMemoryDescriptor *  buffer,
665                                IOStorageCompletion   completion,
666                                Context *             context);
667#endif /* !__LP64__ */
668
669    /*!
670     * @function executeRequest
671     * @discussion
672     * Execute an asynchronous storage request.  The request is guaranteed to be
673     * block-aligned.
674     *
675     * This method is part of a sequence of methods invoked for each read/write
676     * request.  The first is prepareRequest, which allocates and prepares some
677     * context for the transfer; the second is deblockRequest, which aligns the
678     * transfer at the media's block boundaries; third is breakUpRequest, which
679     * breaks up the transfer into multiple sub-transfers when certain hardware
680     * constraints are exceeded; fourth is executeRequest, which implements the
681     * actual transfer from the block storage device.
682     * @param byteStart
683     * Starting byte offset for the data transfer.
684     * @param buffer
685     * Buffer for the data transfer.  The size of the buffer implies the size of
686     * the data transfer.
687     * @param attributes
688     * Attributes of the data transfer.  See IOStorageAttributes.  It is the
689     * responsibility of the callee to maintain the information for the duration
690     * of the data transfer, as necessary.
691     * @param completion
692     * Completion routine to call once the data transfer is complete.  It is the
693     * responsibility of the callee to maintain the information for the duration
694     * of the data transfer, as necessary.
695     * @param context
696     * Additional context information for the data transfer (e.g. block size).
697     */
698
699#ifdef __LP64__
700    virtual void executeRequest(UInt64                byteStart,
701                                IOMemoryDescriptor *  buffer,
702                                IOStorageAttributes * attributes,
703                                IOStorageCompletion * completion,
704                                Context *             context);
705#else /* !__LP64__ */
706    virtual void executeRequest(UInt64                byteStart,
707                                IOMemoryDescriptor *  buffer,
708                                IOStorageCompletion   completion,
709                                Context *             context);
710#endif /* !__LP64__ */
711
712    /*!
713     * @function handleStart
714     * @discussion
715     * Prepare the block storage driver for operation.
716     *
717     * This is where a media object needs to be created for fixed media, and
718     * optionally for removable media.
719     *
720     * Note that this method is called from within the start() routine;
721     * if this method returns successfully,  it should be prepared to accept
722     * any of IOBlockStorageDriver's APIs.
723     * @param provider
724     * This object's provider.
725     * @result
726     * Returns true on success, false otherwise.
727     */
728
729    virtual bool handleStart(IOService * provider);
730
731    virtual bool handleYield(IOService *  provider,
732                             IOOptionBits options  = 0,
733                             void *       argument = 0) __attribute__ ((deprecated));
734
735    /*!
736     * @function getMediaBlockSize
737     * @discussion
738     * Ask the driver about the media's natural block size.
739     * @result
740     * Natural block size, in bytes.
741     */
742
743    virtual UInt64 getMediaBlockSize() const;
744
745public:
746
747    using IOStorage::open;
748    using IOStorage::read;
749    using IOStorage::write;
750
751    /*
752     * Initialize this object's minimal state.
753     *
754     * This method's implementation is not typically overridden.
755     */
756
757    virtual bool init(OSDictionary * properties = 0);
758
759    /*
760     * This method is called once we have been attached to the provider object.
761     *
762     * This method's implementation is not typically overridden.
763     */
764
765    virtual bool start(IOService * provider);
766
767    /*
768     * This method is called before we are detached from the provider object.
769     *
770     * This method's implementation is not typically overridden.
771     */
772
773    virtual void stop(IOService * provider);
774
775    virtual bool didTerminate(IOService *  provider,
776                              IOOptionBits options,
777                              bool *       defer);
778
779    virtual bool yield(IOService *  provider,
780                       IOOptionBits options  = 0,
781                       void *       argument = 0) __attribute__ ((deprecated));
782
783    /*!
784     * @function read
785     * @discussion
786     * The read method is the receiving end for all read requests from the
787     * storage framework (through the media object created by this driver).
788     *
789     * This method initiates a sequence of methods (stages) for each read/write
790     * request.  The first is prepareRequest, which allocates and prepares some
791     * context for the transfer; the second is deblockRequest, which aligns the
792     * transfer at the media's block boundaries; third is breakUpRequest, which
793     * breaks up the transfer into multiple sub-transfers when certain hardware
794     * constraints are exceeded; fourth is executeRequest, which implements the
795     * actual transfer from the block storage device.
796     *
797     * This method's implementation is not typically overridden.
798     * @param client
799     * Client requesting the read.
800     * @param byteStart
801     * Starting byte offset for the data transfer.
802     * @param buffer
803     * Buffer for the data transfer.  The size of the buffer implies the size of
804     * the data transfer.
805     * @param attributes
806     * Attributes of the data transfer.  See IOStorageAttributes.  It is the
807     * responsibility of the callee to maintain the information for the duration
808     * of the data transfer, as necessary.
809     * @param completion
810     * Completion routine to call once the data transfer is complete.  It is the
811     * responsibility of the callee to maintain the information for the duration
812     * of the data transfer, as necessary.
813     */
814
815    virtual void read(IOService *           client,
816                      UInt64                byteStart,
817                      IOMemoryDescriptor *  buffer,
818                      IOStorageAttributes * attributes,
819                      IOStorageCompletion * completion);
820
821    /*!
822     * @function write
823     * @discussion
824     * The write method is the receiving end for all write requests from the
825     * storage framework (through the media object created by this driver).
826     *
827     * This method initiates a sequence of methods (stages) for each read/write
828     * request.  The first is prepareRequest, which allocates and prepares some
829     * context for the transfer; the second is deblockRequest, which aligns the
830     * transfer at the media's block boundaries; third is breakUpRequest, which
831     * breaks up the transfer into multiple sub-transfers when certain hardware
832     * constraints are exceeded; fourth is executeRequest, which implements the
833     * actual transfer from the block storage device.
834     *
835     * This method's implementation is not typically overridden.
836     * @param client
837     * Client requesting the write.
838     * @param byteStart
839     * Starting byte offset for the data transfer.
840     * @param buffer
841     * Buffer for the data transfer.  The size of the buffer implies the size of
842     * the data transfer.
843     * @param attributes
844     * Attributes of the data transfer.  See IOStorageAttributes.  It is the
845     * responsibility of the callee to maintain the information for the duration
846     * of the data transfer, as necessary.
847     * @param completion
848     * Completion routine to call once the data transfer is complete.  It is the
849     * responsibility of the callee to maintain the information for the duration
850     * of the data transfer, as necessary.
851     */
852
853    virtual void write(IOService *           client,
854                       UInt64                byteStart,
855                       IOMemoryDescriptor *  buffer,
856                       IOStorageAttributes * attributes,
857                       IOStorageCompletion * completion);
858
859    /*!
860     * @function synchronizeCache
861     * @discussion
862     * Flush the cached data in the storage object, if any, synchronously.
863     * @param client
864     * Client requesting the cache synchronization.
865     * @result
866     * Returns the status of the cache synchronization.
867     */
868
869    virtual IOReturn synchronizeCache(IOService * client);
870
871    /*!
872     * @function unmap
873     * @discussion
874     * Delete unused data from the storage object at the specified byte offsets,
875     * synchronously.
876     * @param client
877     * Client requesting the operation.
878     * @param extents
879     * List of extents.  See IOStorageExtent.  It is legal for the callee to
880     * overwrite the contents of this buffer in order to satisfy the request.
881     * @param extentsCount
882     * Number of extents.
883     * @result
884     * Returns the status of the operation.
885     */
886
887    virtual IOReturn unmap(IOService *       client,
888                           IOStorageExtent * extents,
889                           UInt32            extentsCount,
890                           UInt32            options = 0);
891
892    /*!
893     * @function lockPhysicalExtents
894     * @discussion
895     * Lock the contents of the storage object against relocation temporarily,
896     * for the purpose of getting physical extents.
897     * @param client
898     * Client requesting the operation.
899     * @result
900     * Returns true if the lock was successful, false otherwise.
901     */
902
903    virtual bool lockPhysicalExtents(IOService * client);
904
905    /*!
906     * @function copyPhysicalExtent
907     * @discussion
908     * Convert the specified byte offset into a physical byte offset, relative
909     * to a physical storage object.  This call should only be made within the
910     * context of lockPhysicalExtents().
911     * @param client
912     * Client requesting the operation.
913     * @param byteStart
914     * Starting byte offset for the operation.  Returns a physical byte offset,
915     * relative to the physical storage object, on success.
916     * @param byteCount
917     * Size of the operation.  Returns the actual number of bytes which can be
918     * transferred, relative to the physical storage object, on success.
919     * @result
920     * A reference to the physical storage object, which should be released by
921     * the caller, or a null on error.
922     */
923
924    virtual IOStorage * copyPhysicalExtent(IOService * client,
925                                           UInt64 *    byteStart,
926                                           UInt64 *    byteCount);
927
928    /*!
929     * @function unlockPhysicalExtents
930     * @discussion
931     * Unlock the contents of the storage object for relocation again.  This
932     * call must balance a successful call to lockPhysicalExtents().
933     * @param client
934     * Client requesting the operation.
935     */
936
937    virtual void unlockPhysicalExtents(IOService * client);
938
939    /*!
940     * @function setPriority
941     * @discussion
942     * Reprioritize read or write requests at the specified byte offsets.
943     * @param client
944     * Client requesting the operation.
945     * @param extents
946     * List of extents.  See IOStorageExtent.  It is legal for the callee to
947     * overwrite the contents of this buffer in order to satisfy the request.
948     * @param extentsCount
949     * Number of extents.
950     * @param priority
951     * New priority.  See IOStoragePriority.
952     * @result
953     * Returns the status of the operation.
954     */
955
956    virtual IOReturn setPriority(IOService *       client,
957                                 IOStorageExtent * extents,
958                                 UInt32            extentsCount,
959                                 IOStoragePriority priority);
960
961    /*!
962     * @function ejectMedia
963     * @discussion
964     * Eject the media from the device.  The driver is responsible for tearing
965     * down the media object it created before proceeding with the eject.   If
966     * the tear-down fails, an error should be returned.
967     * @result
968     * An IOReturn code.
969     */
970
971    virtual IOReturn ejectMedia();
972
973    /*!
974     * @function formatMedia
975     * @discussion
976     * Format the media with the specified byte capacity.  The driver is
977     * responsible for tearing down the media object and recreating it.
978     * @param byteCapacity
979     * Number of bytes to format media to.
980     * @result
981     * An IOReturn code.
982     */
983
984    virtual IOReturn formatMedia(UInt64 byteCapacity);
985
986    virtual IOReturn lockMedia(bool lock) __attribute__ ((deprecated));
987
988    virtual IOReturn pollMedia() __attribute__ ((deprecated));
989
990    /*!
991     * @function isMediaEjectable
992     * @discussion
993     * Ask the driver whether the media is ejectable.
994     * @result
995     * Returns true if the media is ejectable, false otherwise.
996     */
997
998    virtual bool isMediaEjectable() const;
999
1000#ifdef __LP64__
1001    /*!
1002     * @function isMediaRemovable
1003     * @discussion
1004     * Ask the driver whether the media is ejectable.
1005     * @result
1006     * Returns true if the media is ejectable, false otherwise.
1007     */
1008
1009    virtual bool isMediaRemovable() const;
1010#endif /* __LP64__ */
1011
1012    virtual bool isMediaPollExpensive() const __attribute__ ((deprecated));
1013
1014    virtual bool isMediaPollRequired() const __attribute__ ((deprecated));
1015
1016    /*!
1017     * @function isMediaWritable
1018     * @discussion
1019     * Ask the driver whether the media is writable.
1020     * @result
1021     * Returns true if the media is writable, false otherwise.
1022     */
1023
1024    virtual bool isMediaWritable() const;
1025
1026    /*!
1027     * @function getMediaState
1028     * @discussion
1029     * Ask the driver about the media's current state.
1030     * @result
1031     * An IOMediaState value.
1032     */
1033
1034    virtual IOMediaState getMediaState() const;
1035
1036    /*!
1037     * @function getFormatCapacities
1038     * @discussion
1039     * Ask the driver to report the feasible formatting capacities for the
1040     * inserted media (in bytes).  This routine fills the caller's buffer,
1041     * up to the maximum count specified if the real number of capacities
1042     * would overflow the buffer.   The return value indicates the actual
1043     * number of capacities copied to the buffer.
1044     *
1045     * If the capacities buffer is not supplied or if the maximum count is
1046     * zero, the routine returns the proposed count of capacities instead.
1047     * @param capacities
1048     * Buffer that will receive the UInt64 capacity values.
1049     * @param capacitiesMaxCount
1050     * Maximum number of capacity values that can be held in the buffer.
1051     * @result
1052     * Actual number of capacity values copied to the buffer, or if no buffer
1053     * is given, the total number of capacity values available.
1054     */
1055
1056    virtual UInt32 getFormatCapacities(UInt64 * capacities,
1057                                       UInt32   capacitiesMaxCount) const;
1058
1059    /*!
1060     * @function getStatistics
1061     * @discussion
1062     * Ask the driver to report its operating statistics.
1063     *
1064     * The statistics are each indexed by IOBlockStorageDriver::Statistics
1065     * indices.  This routine fills the caller's buffer, up to the maximum
1066     * count specified if the real number of statistics would overflow the
1067     * buffer.  The return value indicates the actual number of statistics
1068     * copied to the buffer.
1069     *
1070     * If the statistics buffer is not supplied or if the maximum count is
1071     * zero, the routine returns the proposed count of statistics instead.
1072     * @param statistics
1073     * Buffer that will receive the UInt64 statistic values.
1074     * @param statisticsMaxCount
1075     * Maximum number of statistic values that can be held in the buffer.
1076     * @result
1077     * Actual number of statistic values copied to the buffer, or if no buffer
1078     * is given, the total number of statistic values available.
1079     */
1080
1081    virtual UInt32 getStatistics(UInt64 * statistics,
1082                                 UInt32   statisticsMaxCount) const;
1083
1084    /*!
1085     * @function getStatistic
1086     * @discussion
1087     * Ask the driver to report one of its operating statistics.
1088     * @param statistic
1089     * Statistic index (an IOBlockStorageDriver::Statistics index).
1090     * @result
1091     * Statistic value.
1092     */
1093
1094    virtual UInt64 getStatistic(Statistics statistic) const;
1095
1096    /*
1097     * Generic entry point for calls from the provider.  A return value of
1098     * kIOReturnSuccess indicates that the message was received, and where
1099     * applicable, that it was successful.
1100     */
1101
1102    virtual IOReturn message(UInt32 type, IOService * provider, void * argument);
1103
1104    /*
1105     * Obtain this object's provider.  We override the superclass's method to
1106     * return a more specific subclass of IOService -- IOBlockStorageDevice.
1107     * This method serves simply as a convenience to subclass developers.
1108     */
1109
1110    virtual IOBlockStorageDevice * getProvider() const;
1111
1112protected:
1113
1114    IOLock *      _deblockRequestWriteLock;
1115
1116#ifdef __LP64__
1117    UInt64        _reserved1024;
1118#else /* !__LP64__ */
1119    UInt32        _reserved1024;
1120#endif /* !__LP64__ */
1121
1122    static void breakUpRequestExecute(void * parameter, void * target);
1123
1124    static void deblockRequestExecute(void * parameter, void * target);
1125
1126    /*
1127     * This is the completion routine for the broken up breaker sub-requests.
1128     * It verifies the success of the just-completed stage,  transitions to
1129     * the next stage, then builds and issues a transfer for the next stage.
1130     */
1131
1132    static void breakUpRequestCompletion(void *   target,
1133                                         void *   parameter,
1134                                         IOReturn status,
1135                                         UInt64   actualByteCount);
1136
1137    /*
1138     * This is the completion routine for the aligned deblocker sub-requests.
1139     * It verifies the success of the just-completed stage,  transitions to
1140     * the next stage, then builds and issues a transfer for the next stage.
1141     */
1142
1143    static void deblockRequestCompletion(void *   target,
1144                                         void *   parameter,
1145                                         IOReturn status,
1146                                         UInt64   actualByteCount);
1147
1148    /*
1149     * This is the completion routine for the prepared request.  It updates
1150     * the driver's statistics, performs some clean up work, then calls the
1151     * original request's completion routine.
1152     */
1153
1154    static void prepareRequestCompletion(void *   target,
1155                                         void *   parameter,
1156                                         IOReturn status,
1157                                         UInt64   actualByteCount);
1158
1159    virtual void schedulePoller() __attribute__ ((deprecated));
1160
1161    virtual void unschedulePoller() __attribute__ ((deprecated));
1162
1163    /*
1164     * This method is the power event handler for restarts and shutdowns.
1165     */
1166
1167    static IOReturn handlePowerEvent(void *      target,
1168                                     void *      parameter,
1169                                     UInt32      messageType,
1170                                     IOService * provider,
1171                                     void *      messageArgument,
1172                                     vm_size_t   messageArgumentSize);
1173
1174protected:
1175
1176    /* Device info: */
1177
1178    /*!
1179     * @var _removable
1180     * True if the media is removable; False if it is fixed (not removable).
1181     */
1182    bool		_removable;
1183
1184    /*!
1185     * @var _ejectable
1186     * True if the media is ejectable under software control.
1187     */
1188    bool		_ejectable;		/* software-ejectable */
1189
1190    UInt16		_reserved1104;
1191
1192    UInt32		_openAssertions;
1193
1194    /* Media info and states: */
1195
1196    /*!
1197     * @var _mediaObject
1198     * A pointer to the media object we have instantiated (if any).
1199     */
1200    IOMedia *		_mediaObject;
1201
1202    /*!
1203     * @var _mediaType
1204     * Type of the media (can be used to differentiate between the
1205     * different types of CD media, DVD media, etc).
1206     */
1207    UInt32		_mediaType;
1208
1209    bool		_solidState;
1210
1211    /*!
1212     * @var _writeProtected
1213     * True if the media is write-protected; False if not.
1214     */
1215    bool		_writeProtected;
1216
1217    UInt16		_reserved1264;
1218#ifdef __LP64__
1219    UInt64		_reserved1280;
1220#else /* !__LP64__ */
1221    UInt32		_reserved1280;
1222#endif /* !__LP64__ */
1223
1224    /*!
1225     * @var _mediaBlockSize
1226     * The block size of the media, in bytes.
1227     */
1228    UInt64		_mediaBlockSize;
1229
1230    /*!
1231     * @var _maxBlockNumber
1232     * The maximum allowable block number for the media, zero-based.
1233     */
1234    UInt64		_maxBlockNumber;
1235
1236    /*!
1237     * @var _maxReadByteTransfer
1238     * The maximum byte transfer allowed for read operations.
1239     */
1240    UInt64		_maxReadByteTransfer;
1241
1242    /*!
1243     * @var _maxWriteByteTransfer
1244     * The maximum byte transfer allowed for write operations.
1245     */
1246    UInt64		_maxWriteByteTransfer;
1247
1248    /*!
1249     * @function acceptNewMedia
1250     * @abstract
1251     * React to new media insertion.
1252     * @discussion
1253     * This method logs the media block size and block count, then calls
1254     * instantiateMediaObject to get a media object instantiated. The
1255     * media object is then attached above us and registered.
1256     *
1257     * This method can be overridden to control what happens when new media
1258     * is inserted. The default implementation deals with one IOMedia object.
1259     */
1260    virtual IOReturn	acceptNewMedia(void);
1261
1262    /*!
1263     * @function constrainByteCount
1264     * @abstract
1265     * Constrain the byte count for this IO to device limits.
1266     * @discussion
1267     * This function should be called prior to each read or write operation, so that
1268     * the driver can constrain the requested byte count, as necessary, to meet
1269     * current device limits. Such limits could be imposed by the device depending
1270     * on operating modes, media types, or transport protocol (e.g. ATA, SCSI).
1271     *
1272     * At present, this method is not used.
1273     * @param requestedCount
1274     * The requested byte count for the next read or write operation.
1275     * @param isWrite
1276     * True if the operation will be a write; False if the operation will be a read.
1277     */
1278    virtual UInt64	constrainByteCount(UInt64 requestedCount,bool isWrite);
1279
1280    /*!
1281     * @function decommissionMedia
1282     * @abstract
1283     * Decommission an existing piece of media that has gone away.
1284     * @discussion
1285     * This method wraps a call to terminate, to tear down the stack and
1286     * the IOMedia object for the media. If "forcible" is true, the media
1287     * object will be forgotten, and initMediaState will be called. A
1288     * forcible decommission would occur when an unrecoverable error
1289     * happens during tear-down (e.g. perhaps a client is still open), but
1290     * we must still forget about the media.
1291     * @param forcible
1292     * True to force forgetting of the media object even if terminate reports
1293     * that there was an active client.
1294     */
1295    virtual IOReturn	decommissionMedia(bool forcible);
1296
1297    /*!
1298     * @function instantiateDesiredMediaObject
1299     * @abstract
1300     * Create an IOMedia object for media.
1301     * @discussion
1302     * This method creates the exact type of IOMedia object desired. It is called by
1303     * instantiateMediaObject. A subclass may override this one-line method to change
1304     * the type of media object actually instantiated.
1305     */
1306    virtual IOMedia *	instantiateDesiredMediaObject(void);
1307
1308    /*!
1309     * @function instantiateMediaObject
1310     * @abstract
1311     * Create an IOMedia object for media.
1312     * @discussion
1313     * This method creates an IOMedia object from the supplied parameters. It is a
1314     * convenience method to wrap the handful of steps to do the job.
1315     * @param base
1316     * Byte number of beginning of active data area of the media. Usually zero.
1317     * @param byteSize
1318     * Size of the data area of the media, in bytes.
1319     * @param blockSize
1320     * Block size of the media, in bytes.
1321     * @param mediaName
1322     * Name of the IOMedia object.
1323     * @result
1324     * A pointer to the created IOMedia object, or a null on error.
1325     */
1326    virtual IOMedia *	instantiateMediaObject(UInt64 base,UInt64 byteSize,
1327                                            UInt32 blockSize,char *mediaName);
1328
1329    /*!
1330     * @function recordMediaParameters
1331     * @abstract
1332     * Obtain media-related parameters on media insertion.
1333     * @discussion
1334     * This method obtains media-related parameters via calls to the
1335     * Transport Driver's reportBlockSize, reportMaxValidBlock,
1336     * and reportWriteProtection methods.
1337     */
1338    virtual IOReturn	recordMediaParameters(void);
1339
1340    /*!
1341     * @function rejectMedia
1342     * @abstract
1343     * Reject new media.
1344     * @discussion
1345     * This method will be called if validateNewMedia returns False (thus rejecting
1346     * the new media. A vendor may choose to override this method to control behavior
1347     * when media is rejected.
1348     *
1349     * The default implementation simply calls ejectMedia.
1350     */
1351    virtual void	rejectMedia(void);	/* default ejects */
1352
1353    /*!
1354     * @function validateNewMedia
1355     * @abstract
1356     * Verify that new media is acceptable.
1357     * @discussion
1358     * This method will be called whenever new media is detected. Return true to accept
1359     * the media, or false to reject it (and call rejectMedia). Vendors might override
1360     * this method to handle password-protection for new media.
1361     *
1362     * The default implementation always returns True, indicating media is accepted.
1363     */
1364    virtual bool	validateNewMedia(void);
1365
1366    /* --- Internally used methods. --- */
1367
1368    /*
1369     * @group
1370     * Internally Used Methods
1371     * @discussion
1372     * These methods are used internally, and will not generally be modified.
1373     */
1374
1375    /*!
1376     * @function checkForMedia
1377     * @abstract
1378     * Check if media has newly arrived or disappeared.
1379     * @discussion
1380     * This method does most of the work in polling for media, first
1381     * calling the block storage device's reportMediaState method. If
1382     * reportMediaState reports no change in the media state, kIOReturnSuccess
1383     * is returned. If the media state has indeed changed, a call is made to
1384     * mediaStateHasChanged to act on the event.
1385     */
1386    virtual IOReturn	checkForMedia(void);
1387
1388    /*!
1389     * @function getDeviceTypeName
1390     * @abstract
1391     * Return the desired device name.
1392     * @discussion
1393     * This method returns a string, used to compare the
1394     * kIOBlockStorageDeviceTypeKey of our provider. This method is called from
1395     * probe.
1396     *
1397     * The default implementation of this method returns
1398     * kIOBlockStorageDeviceTypeGeneric.
1399     */
1400    virtual const char * getDeviceTypeName(void);
1401
1402    /*!
1403     * @function initMediaState
1404     * @abstract
1405     * Initialize media-related instance variables.
1406     * @discussion
1407     * Called when media is not present, this method marks the device state
1408     * as not having media present, not spun up, and write-enabled.
1409     */
1410    virtual void	initMediaState(void);
1411
1412    /*!
1413     * @function mediaStateHasChanged
1414     * @abstract
1415     * React to a new media insertion or a media removal.
1416     * @discussion
1417     * This method is called on a media state change, that is, an arrival
1418     * or removal. If media has just become available, calls are made to
1419     * recordMediaParameters and acceptNewMedia. If media has just gone
1420     * away, a call is made to decommissionMedia, with the forcible
1421     * parameter set to true. The forcible tear-down is needed to enforce
1422     * the disappearance of media, regardless of interested clients.
1423     */
1424    virtual IOReturn	mediaStateHasChanged(IOMediaState state);
1425
1426    /*
1427     * @endgroup
1428     */
1429
1430protected:
1431
1432    /*!
1433     * @function breakUpRequest
1434     * @discussion
1435     * The breakUpRequest method checks to see if the incoming request exceeds
1436     * our transfer constraints, and if so, breaks up the request into smaller
1437     * sub-requests.
1438     *
1439     * This method is part of a sequence of methods invoked for each read/write
1440     * request.  The first is prepareRequest, which allocates and prepares some
1441     * context for the transfer; the second is deblockRequest, which aligns the
1442     * transfer at the media's block boundaries; third is breakUpRequest, which
1443     * breaks up the transfer into multiple sub-transfers when certain hardware
1444     * constraints are exceeded; fourth is executeRequest, which implements the
1445     * actual transfer from the block storage device.
1446     *
1447     * This method's implementation is not typically overridden.
1448     * @param byteStart
1449     * Starting byte offset for the data transfer.
1450     * @param buffer
1451     * Buffer for the data transfer.  The size of the buffer implies the size of
1452     * the data transfer.
1453     * @param attributes
1454     * Attributes of the data transfer.  See IOStorageAttributes.  It is the
1455     * responsibility of the callee to maintain the information for the duration
1456     * of the data transfer, as necessary.
1457     * @param completion
1458     * Completion routine to call once the data transfer is complete.  It is the
1459     * responsibility of the callee to maintain the information for the duration
1460     * of the data transfer, as necessary.
1461     * @param context
1462     * Additional context information for the data transfer (e.g. block size).
1463     */
1464
1465#ifdef __LP64__
1466    virtual void breakUpRequest(UInt64                byteStart,
1467                                IOMemoryDescriptor *  buffer,
1468                                IOStorageAttributes * attributes,
1469                                IOStorageCompletion * completion,
1470                                Context *             context);
1471#else /* !__LP64__ */
1472    virtual void breakUpRequest(UInt64                byteStart,
1473                                IOMemoryDescriptor *  buffer,
1474                                IOStorageCompletion   completion,
1475                                Context *             context); /* 10.1.2 */
1476#endif /* !__LP64__ */
1477
1478    /*!
1479     * @function prepareRequest
1480     * @discussion
1481     * The prepareRequest method allocates and prepares state for the transfer.
1482     *
1483     * This method is part of a sequence of methods invoked for each read/write
1484     * request.  The first is prepareRequest, which allocates and prepares some
1485     * context for the transfer; the second is deblockRequest, which aligns the
1486     * transfer at the media's block boundaries; third is breakUpRequest, which
1487     * breaks up the transfer into multiple sub-transfers when certain hardware
1488     * constraints are exceeded; fourth is executeRequest, which implements the
1489     * actual transfer from the block storage device.
1490     *
1491     * This method's implementation is not typically overridden.
1492     * @param byteStart
1493     * Starting byte offset for the data transfer.
1494     * @param buffer
1495     * Buffer for the data transfer.  The size of the buffer implies the size of
1496     * the data transfer.
1497     * @param attributes
1498     * Attributes of the data transfer.  See IOStorageAttributes.  It is the
1499     * responsibility of the callee to maintain the information for the duration
1500     * of the data transfer, as necessary.
1501     * @param completion
1502     * Completion routine to call once the data transfer is complete.  It is the
1503     * responsibility of the callee to maintain the information for the duration
1504     * of the data transfer, as necessary.
1505     */
1506
1507    virtual void prepareRequest(UInt64                byteStart,
1508                                IOMemoryDescriptor *  buffer,
1509                                IOStorageAttributes * attributes,
1510                                IOStorageCompletion * completion); /* 10.5.0 */
1511
1512public:
1513
1514    /*!
1515     * @function requestIdle
1516     * @abstract
1517     * Request that the device enter an idle state.
1518     * @discussion
1519     * Request that the device enter an idle state.  The device will exit this state on the
1520     * next read or write request, or as it sees necessary.  One example is for a DVD drive
1521     * to spin down when it enters such an idle state, and spin up on the next read request
1522     * from the system.
1523     */
1524    virtual IOReturn	requestIdle(void); /* 10.6.0 */
1525
1526#ifdef __LP64__
1527    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver,  0);
1528    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver,  1);
1529    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver,  2);
1530#else /* !__LP64__ */
1531    OSMetaClassDeclareReservedUsed(IOBlockStorageDriver,  0);
1532    OSMetaClassDeclareReservedUsed(IOBlockStorageDriver,  1);
1533    OSMetaClassDeclareReservedUsed(IOBlockStorageDriver,  2);
1534#endif /* !__LP64__ */
1535    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver,  3);
1536    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver,  4);
1537    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver,  5);
1538    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver,  6);
1539    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver,  7);
1540    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver,  8);
1541    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver,  9);
1542    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 10);
1543    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 11);
1544    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 12);
1545    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 13);
1546    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 14);
1547    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 15);
1548    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 16);
1549    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 17);
1550    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 18);
1551    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 19);
1552    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 20);
1553    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 21);
1554    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 22);
1555    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 23);
1556    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 24);
1557    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 25);
1558    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 26);
1559    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 27);
1560    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 28);
1561    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 29);
1562    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 30);
1563    OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 31);
1564};
1565
1566#endif /* __cplusplus */
1567#endif /* KERNEL */
1568#endif /* !_IOBLOCKSTORAGEDRIVER_H */
1569