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