]> git.saurik.com Git - apple/xnu.git/blame - iokit/IOKit/storage/IOBlockStorageDriver.h
xnu-124.13.tar.gz
[apple/xnu.git] / iokit / IOKit / storage / IOBlockStorageDriver.h
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23/*!
24 * @header IOBlockStorageDriver
25 * @abstract
26 * This header contains the IOBlockStorageDriver class definition.
27 */
28
29#ifndef _IOBLOCKSTORAGEDRIVER_H
30#define _IOBLOCKSTORAGEDRIVER_H
31
32/*!
33 * @defined kIOBlockStorageDriverClass
34 * @abstract
35 * kIOBlockStorageDriverClass is the name of the IOBlockStorageDriver class.
36 * @discussion
37 * kIOBlockStorageDriverClass is the name of the IOBlockStorageDriver class.
38 */
39
40#define kIOBlockStorageDriverClass "IOBlockStorageDriver"
41
42/*!
43 * @defined kIOBlockStorageDriverStatisticsKey
44 * @abstract
45 * This property holds a table of numeric values describing the driver's
46 * operating statistics.
47 * @discussion
48 * This property holds a table of numeric values describing the driver's
49 * operating statistics. The table is an OSDictionary, where each entry
50 * describes one given statistic.
51 */
52
53#define kIOBlockStorageDriverStatisticsKey "Statistics"
54
55/*!
56 * @defined kIOBlockStorageDriverStatisticsBytesReadKey
57 * @abstract
58 * This property describes the number of bytes read since the block storage
59 * driver was instantiated. It is one of the statistic entries listed under
60 * the top-level kIOBlockStorageDriverStatisticsKey property table.
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 * This property describes the number of bytes written since the block storage
74 * driver was instantiated. It is one of the statistic entries listed under the
75 * top-level kIOBlockStorageDriverStatisticsKey property table.
76 * @discussion
77 * This property describes the number of bytes written since the block storage
78 * driver was instantiated. It is one of the statistic entries listed under the
79 * top-level kIOBlockStorageDriverStatisticsKey property table. It has an
80 * OSNumber value.
81 */
82
83#define kIOBlockStorageDriverStatisticsBytesWrittenKey "Bytes (Write)"
84
85/*!
86 * @defined kIOBlockStorageDriverStatisticsReadErrorsKey
87 * @abstract
88 * This property describes the number of read errors encountered since the block
89 * storage driver was instantiated. It is one of the statistic entries listed
90 * under the top-level kIOBlockStorageDriverStatisticsKey property table.
91 * @discussion
92 * This property describes the number of read errors encountered since the block
93 * storage driver was instantiated. It is one of the statistic entries listed
94 * under the top-level kIOBlockStorageDriverStatisticsKey property table. It
95 * has an OSNumber value.
96 */
97
98#define kIOBlockStorageDriverStatisticsReadErrorsKey "Errors (Read)"
99
100/*!
101 * @defined kIOBlockStorageDriverStatisticsWriteErrorsKey
102 * @abstract
103 * This property describes the number of write errors encountered since the
104 * block storage driver was instantiated. It is one of the statistic entries
105 * listed under the top-level kIOBlockStorageDriverStatisticsKey property table.
106 * @discussion
107 * This property describes the number of write errors encountered since the
108 * block storage driver was instantiated. It is one of the statistic entries
109 * listed under the top-level kIOBlockStorageDriverStatisticsKey property table.
110 * It has an OSNumber value.
111 */
112
113#define kIOBlockStorageDriverStatisticsWriteErrorsKey "Errors (Write)"
114
115/*!
116 * @defined kIOBlockStorageDriverStatisticsLatentReadTimeKey
117 * @abstract
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.
122 * @discussion
123 * This property describes the number of nanoseconds of latency during reads
124 * since the block storage driver was instantiated. It is one of the statistic
125 * entries listed under the top-level kIOBlockStorageDriverStatisticsKey
126 * property table. It has an OSNumber value.
127 */
128
129#define kIOBlockStorageDriverStatisticsLatentReadTimeKey "Latency Time (Read)"
130
131/*!
132 * @defined kIOBlockStorageDriverStatisticsLatentWriteTimeKey
133 * @abstract
134 * This property describes the number of nanoseconds of latency during writes
135 * since the block storage driver was instantiated. It is one of the statistic
136 * entries listed under the top-level kIOBlockStorageDriverStatisticsKey
137 * property table.
138 * @discussion
139 * This property describes the number of nanoseconds of latency during writes
140 * since the block storage driver was instantiated. It is one of the statistic
141 * entries listed under the top-level kIOBlockStorageDriverStatisticsKey
142 * property table. It has an OSNumber value.
143 */
144
145#define kIOBlockStorageDriverStatisticsLatentWriteTimeKey "Latency Time (Write)"
146
147/*!
148 * @defined kIOBlockStorageDriverStatisticsReadsKey
149 * @abstract
150 * This property describes the number of read operations processed since the
151 * block storage driver was instantiated. It is one of the statistic entries
152 * listed under the top-level kIOBlockStorageDriverStatisticsKey property table.
153 * @discussion
154 * This property describes the number of read operations processed since the
155 * block storage driver was instantiated. It is one of the statistic entries
156 * listed under the top-level kIOBlockStorageDriverStatisticsKey property table.
157 * It has an OSNumber value.
158 */
159
160#define kIOBlockStorageDriverStatisticsReadsKey "Operations (Read)"
161
162/*!
163 * @defined kIOBlockStorageDriverStatisticsWritesKey
164 * @abstract
165 * This property describes the number of write operations processed since the
166 * block storage driver was instantiated. It is one of the statistic entries
167 * listed under the top-level kIOBlockStorageDriverStatisticsKey property table.
168 * @discussion
169 * This property describes the number of write operations processed since the
170 * block storage driver was instantiated. It is one of the statistic entries
171 * listed under the top-level kIOBlockStorageDriverStatisticsKey property table.
172 * It has an OSNumber value.
173 */
174
175#define kIOBlockStorageDriverStatisticsWritesKey "Operations (Write)"
176
177/*!
178 * @defined kIOBlockStorageDriverStatisticsReadRetriesKey
179 * @abstract
180 * This property describes the number of read retries required since the block
181 * storage driver was instantiated. It is one of the statistic entries listed
182 * under the top-level kIOBlockStorageDriverStatisticsKey property table.
183 * @discussion
184 * This property describes the number of read retries required since the block
185 * storage driver was instantiated. It is one of the statistic entries listed
186 * under the top-level kIOBlockStorageDriverStatisticsKey property table. It
187 * has an OSNumber value.
188 */
189
190#define kIOBlockStorageDriverStatisticsReadRetriesKey "Retries (Read)"
191
192/*!
193 * @defined kIOBlockStorageDriverStatisticsWriteRetriesKey
194 * @abstract
195 * This property describes the number of write retries required since the block
196 * storage driver was instantiated. It is one of the statistic entries listed
197 * under the top-level kIOBlockStorageDriverStatisticsKey property table. It
198 * has an OSNumber value.
199 * @discussion
200 * This property describes the number of write retries required since the block
201 * storage driver was instantiated. It is one of the statistic entries listed
202 * under the top-level kIOBlockStorageDriverStatisticsKey property table. It
203 * has an OSNumber value.
204 */
205
206#define kIOBlockStorageDriverStatisticsWriteRetriesKey "Retries (Write)"
207
208/*!
209 * @defined kIOBlockStorageDriverStatisticsTotalReadTimeKey
210 * @abstract
211 * This property describes the number of nanoseconds spent performing reads
212 * since the block storage driver was instantiated. It is one of the statistic
213 * entries listed under the top-level kIOBlockStorageDriverStatisticsKey
214 * property table.
215 * @discussion
216 * This property describes the number of nanoseconds spent performing reads
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 kIOBlockStorageDriverStatisticsTotalReadTimeKey "Total Time (Read)"
223
224/*!
225 * @defined kIOBlockStorageDriverStatisticsTotalWriteTimeKey
226 * @abstract
227 * This property describes the number of nanoseconds spent performing writes
228 * since the block storage driver was instantiated. It is one of the statistic
229 * entries listed under the top-level kIOBlockStorageDriverStatisticsKey
230 * property table.
231 * @discussion
232 * This property describes the number of nanoseconds spent performing writes
233 * since the block storage driver was instantiated. It is one of the statistic
234 * entries listed under the top-level kIOBlockStorageDriverStatisticsKey
235 * property table. It has an OSNumber value.
236 */
237
238#define kIOBlockStorageDriverStatisticsTotalWriteTimeKey "Total Time (Write)"
239
240/*!
241 * @enum IOMediaState
242 * @discussion
243 * The different states that getMediaState() can report.
244 * @constant kIOMediaStateOffline
245 * Media is not available.
246 * @constant kIOMediaStateOnline
247 * Media is available and ready for operations.
248 * @constant kIOMediaStateBusy
249 * Media is available, but not ready for operations.
250 */
251
252typedef UInt32 IOMediaState;
253
254#define kIOMediaStateOffline 0
255#define kIOMediaStateOnline 1
256#define kIOMediaStateBusy 2
257
258/*
259 * Kernel
260 */
261
262#if defined(KERNEL) && defined(__cplusplus)
263
264#include <IOKit/storage/IOBlockStorageDevice.h>
265#include <IOKit/storage/IOMedia.h>
266#include <IOKit/storage/IOStorage.h>
267#include <kern/thread_call.h>
268
269/*!
270 * @class IOBlockStorageDriver
271 * @abstract
272 * The IOBlockStorageDriver class is the common base class for generic block
273 * storage drivers. It matches and communicates via an IOBlockStorageDevice
274 * interface, and connects to the remainder of the storage framework via the
275 * IOStorage protocol.
276 * @discussion
277 * The IOBlockStorageDriver class is the common base class for generic block
278 * storage drivers. It matches and communicates via an IOBlockStorageDevice
279 * interface, and connects to the remainder of the storage framework via the
280 * IOStorage protocol. It extends the IOStorage protocol by implementing the
281 * appropriate open and close semantics, deblocking for unaligned transfers,
282 * polling for ejectable media, locking and ejection policies, media object
283 * creation and teardown, and statistics gathering and reporting.
284 *
285 * Block storage drivers are split into two parts: the generic driver handles
286 * all generic device issues, independent of the lower-level transport
287 * mechanism (e.g. SCSI, ATA, USB, FireWire). All storage operations
288 * at the generic driver level are translated into a series of generic
289 * device operations. These operations are passed via the IOBlockStorageDevice
290 * nub to a transport driver, which implements the appropriate
291 * transport-dependent protocol to execute these operations.
292 *
293 * To determine the write-protect state of a device (or media), for
294 * example, the generic driver would issue a call to the
295 * Transport Driver's reportWriteProtection method. If this were a SCSI
296 * device, its transport driver would issue a Mode Sense command to
297 * extract the write-protection status bit. The transport driver then
298 * reports true or false to the generic driver.
299 *
300 * The generic driver therefore has no knowledge of, or involvement
301 * with, the actual commands and mechanisms used to communicate with
302 * the device. It is expected that the generic driver will rarely, if
303 * ever, need to be subclassed to handle device idiosyncrasies; rather,
304 * the transport driver should be changed via overrides.
305 *
306 * A generic driver could be subclassed to create a different type of
307 * generic device. The generic driver IOCDBlockStorageDriver class is
308 * a subclass of IOBlockStorageDriver, adding CD functions.
309 */
310
311class IOBlockStorageDriver : public IOStorage
312{
313 OSDeclareDefaultStructors(IOBlockStorageDriver);
314
315public:
316
317 /*!
318 * @enum Statistics
319 * @discussion
320 * Indices for the different statistics that getStatistics() can report.
321 * @constant kStatisticsReads
322 * Number of read operations thus far.
323 * @constant kStatisticsBytesRead
324 * Number of bytes read thus far.
325 * @constant kStatisticsTotalReadTime
326 * Nanoseconds spent performing reads thus far.
327 * @constant kStatisticsLatentReadTime
328 * Nanoseconds of latency during reads thus far.
329 * @constant kStatisticsReadRetries
330 * Number of read retries thus far.
331 * @constant kStatisticsReadErrors
332 * Number of read errors thus far.
333 * @constant kStatisticsWrites
334 * Number of write operations thus far.
335 * @constant kStatisticsSingleBlockWrites
336 * Number of write operations for a single block thus far.
337 * @constant kStatisticsBytesWritten
338 * Number of bytes written thus far.
339 * @constant kStatisticsTotalWriteTime
340 * Nanoseconds spent performing writes thus far.
341 * @constant kStatisticsLatentWriteTime
342 * Nanoseconds of latency during writes thus far.
343 * @constant kStatisticsWriteRetries
344 * Number of write retries thus far.
345 * @constant kStatisticsWriteErrors
346 * Number of write errors thus far.
347 */
348
349 enum Statistics
350 {
351 kStatisticsReads,
352 kStatisticsBytesRead,
353 kStatisticsTotalReadTime,
354 kStatisticsLatentReadTime,
355 kStatisticsReadRetries,
356 kStatisticsReadErrors,
357
358 kStatisticsWrites,
359 kStatisticsSingleBlockWrites,
360 kStatisticsBytesWritten,
361 kStatisticsTotalWriteTime,
362 kStatisticsLatentWriteTime,
363 kStatisticsWriteRetries,
364 kStatisticsWriteErrors
365 };
366
367 static const UInt32 kStatisticsCount = kStatisticsWriteErrors + 1;
368
369protected:
370
371 struct ExpansionData { /* */ };
372 ExpansionData * _expansionData;
373
374 OSSet * _openClients;
375 OSNumber * _statistics[kStatisticsCount];
376
377 /*
378 * @struct Context
379 * @discussion
380 * Context structure for a read/write operation. It describes the block size,
381 * and where applicable, a block type and block sub-type, for a data transfer,
382 * as well as the completion information for the original request. Note that
383 * the block type field is unused in the IOBlockStorageDriver class.
384 * @field block.size
385 * Block size for the operation.
386 * @field block.type
387 * Block type for the operation. Unused in IOBlockStorageDriver. The default
388 * value for this field is IOBlockStorageDriver::kBlockTypeStandard.
389 * @field block.typeSub
390 * Block sub-type for the operation. It's definition depends on block.type.
391 * Unused in IOBlockStorageDriver.
392 * @field original.byteStart
393 * Starting byte offset for the data transfer.
394 * @param original.buffer
395 * Buffer for the data transfer. The size of the buffer implies the size of
396 * the data transfer.
397 * @param original.completion
398 * Completion routine to call once the data transfer is complete.
399 */
400
401 struct Context
402 {
403 struct
404 {
405 UInt32 size;
406 UInt8 type;
407 UInt8 typeSub[3];
408 } block;
409
410 struct
411 {
412 UInt64 byteStart;
413 IOMemoryDescriptor * buffer;
414 IOStorageCompletion completion;
415 } original;
416
417 UInt32 reserved[8];
418 };
419
420 static const UInt8 kBlockTypeStandard = 0x00;
421
422 /*
423 * Free all of this object's outstanding resources.
424 *
425 * This method's implementation is not typically overidden.
426 */
427
428 void free();
429
430 /*!
431 * @function handleOpen
432 * @discussion
433 * The handleOpen method grants or denies permission to access this object
434 * to an interested client. The argument is an IOStorageAccess value that
435 * specifies the level of access desired -- reader or reader-writer.
436 *
437 * This method can be invoked to upgrade or downgrade the access level for
438 * an existing client as well. The previous access level will prevail for
439 * upgrades that fail, of course. A downgrade should never fail. If the
440 * new access level should be the same as the old for a given client, this
441 * method will do nothing and return success. In all cases, one, singular
442 * close-per-client is expected for all opens-per-client received.
443 *
444 * This implementation replaces the IOService definition of handleIsOpen().
445 * @param client
446 * Client requesting the open.
447 * @param options
448 * Options for the open. Set to zero.
449 * @param access
450 * Access level for the open. Set to kIOStorageAccessReader or
451 * kIOStorageAccessReaderWriter.
452 * @result
453 * Returns true if the open was successful, false otherwise.
454 */
455
456 virtual bool handleOpen(IOService * client,
457 IOOptionBits options,
458 void * access);
459
460 /*!
461 * @function handleIsOpen
462 * @discussion
463 * The handleIsOpen method determines whether the specified client, or any
464 * client if none is specificed, presently has an open on this object.
465 *
466 * This implementation replaces the IOService definition of handleIsOpen().
467 * @param client
468 * Client to check the open state of. Set to zero to check the open state
469 * of all clients.
470 * @result
471 * Returns true if the client was (or clients were) open, false otherwise.
472 */
473
474 virtual bool handleIsOpen(const IOService * client) const;
475
476 /*!
477 * @function handleClose
478 * @discussion
479 * The handleClose method closes the client's access to this object.
480 *
481 * This implementation replaces the IOService definition of handleIsOpen().
482 * @param client
483 * Client requesting the close.
484 * @param options
485 * Options for the close. Set to zero.
486 */
487
488 virtual void handleClose(IOService * client, IOOptionBits options);
489
490 /*!
491 * @function addToBytesTransferred
492 * @discussion
493 * Update the total number of bytes transferred, the total transfer time,
494 * and the total latency time -- used for statistics.
495 *
496 * This method's implementation is not typically overidden.
497 * @param bytesTransferred
498 * Number of bytes transferred in this operation.
499 * @param totalTime
500 * Nanoseconds spent performing this operation.
501 * @param latentTime
502 * Nanoseconds of latency during this operation.
503 * @param isWrite
504 * Indicates whether this operation was a write, otherwise is was a read.
505 */
506
507 virtual void addToBytesTransferred(UInt64 bytesTransferred,
508 UInt64 totalTime,
509 UInt64 latentTime,
510 bool isWrite);
511
512 /*!
513 * @function incrementErrors
514 * @discussion
515 * Update the total error count -- used for statistics.
516 *
517 * This method's implementation is not typically overidden.
518 * @param isWrite
519 * Indicates whether this operation was a write, otherwise is was a read.
520 */
521
522 virtual void incrementErrors(bool isWrite);
523
524 /*!
525 * @function incrementRetries
526 * @discussion
527 * Update the total retry count -- used for statistics.
528 *
529 * This method's implementation is not typically overidden.
530 * @param isWrite
531 * Indicates whether this operation was a write, otherwise is was a read.
532 */
533
534 virtual void incrementRetries(bool isWrite);
535
536 /*!
537 * @function allocateContext
538 * @discussion
539 * Allocate a context structure for a read/write operation.
540 * @result
541 * Context structure.
542 */
543
544 virtual Context * allocateContext();
545
546 /*!
547 * @function deleteContext
548 * @discussion
549 * Delete a context structure from a read/write operation.
550 * @param context
551 * Context structure to be deleted.
552 */
553
554 virtual void deleteContext(Context * context);
555
556 /*!
557 * @function prepareRequest
558 * @discussion
559 * The prepareRequest method allocates and prepares state for the transfer.
560 *
561 * This method is part of a sequence of methods invoked for each read/write
562 * request. The first is prepareRequest, which allocates and prepares some
563 * context for the transfer; the second is deblockRequest, which aligns the
564 * transfer at the media block boundaries; and the third is executeRequest,
565 * which implements the actual transfer from the block storage device.
566 *
567 * This method's implementation is not typically overidden.
568 * @param byteStart
569 * Starting byte offset for the data transfer.
570 * @param buffer
571 * Buffer for the data transfer. The size of the buffer implies the size of
572 * the data transfer.
573 * @param completion
574 * Completion routine to call once the data transfer is complete.
575 */
576
577 virtual void prepareRequest(UInt64 byteStart,
578 IOMemoryDescriptor * buffer,
579 IOStorageCompletion completion);
580
581 /*!
582 * @function deblockRequest
583 * @discussion
584 * The deblockRequest method checks to see if the incoming request rests
585 * on the media's block boundaries, and if not, deblocks it. Deblocking
586 * involves rounding out the request to the nearest block boundaries and
587 * transferring the excess bytes into a scratch buffer.
588 *
589 * This method is part of a sequence of methods invoked for each read/write
590 * request. The first is prepareRequest, which allocates and prepares some
591 * context for the transfer; the second is deblockRequest, which aligns the
592 * transfer at the media block boundaries; and the third is executeRequest,
593 * which implements the actual transfer from the block storage device.
594 *
595 * This method's implementation is not typically overidden.
596 * @param byteStart
597 * Starting byte offset for the data transfer.
598 * @param buffer
599 * Buffer for the data transfer. The size of the buffer implies the size of
600 * the data transfer.
601 * @param completion
602 * Completion routine to call once the data transfer is complete.
603 * @param context
604 * Additional context information for the data transfer (eg. block size).
605 */
606
607 virtual void deblockRequest(UInt64 byteStart,
608 IOMemoryDescriptor * buffer,
609 IOStorageCompletion completion,
610 Context * context);
611
612 /*!
613 * @function executeRequest
614 * @discussion
615 * Execute an asynchrnous storage request. The request is guaranteed to be
616 * block-aligned.
617 *
618 * This method is part of a sequence of methods invoked for each read/write
619 * request. The first is prepareRequest, which allocates and prepares some
620 * context for the transfer; the second is deblockRequest, which aligns the
621 * transfer at the media block boundaries; and the third is executeRequest,
622 * which implements the actual transfer from the block storage device.
623 * @param byteStart
624 * Starting byte offset for the data transfer.
625 * @param buffer
626 * Buffer for the data transfer. The size of the buffer implies the size of
627 * the data transfer.
628 * @param completion
629 * Completion routine to call once the data transfer is complete.
630 * @param context
631 * Additional context information for the data transfer (eg. block size).
632 */
633
634 virtual void executeRequest(UInt64 byteStart,
635 IOMemoryDescriptor * buffer,
636 IOStorageCompletion completion,
637 Context * context);
638
639 /*!
640 * @function handleStart
641 * @discussion
642 * Prepare the block storage driver for operation.
643 *
644 * This is where a media object needs to be created for fixed media, and
645 * optionally for removable media.
646 *
647 * Note that this method is called from within the start() routine;
648 * if this method returns successfully, it should be prepared to accept
649 * any of IOBlockStorageDriver's APIs.
650 * @param provider
651 * This object's provider.
652 * @result
653 * Returns true on success, false otherwise.
654 */
655
656 virtual bool handleStart(IOService * provider);
657
658 /*!
659 * @function handleYield
660 * @discussion
661 * Stop the block storage driver.
662 *
663 * This method is called as a result of the kIOMessageServiceIsTerminated
664 * or kIOMessageServiceIsRequestingClose provider messages. The argument
665 * is passed in as-is from the message. The kIOServiceRequired option is
666 * set for the kIOMessageServiceIsTerminated message to indicate that the
667 * yield must succeed.
668 *
669 * This is where the driver should clean up its state in preparation for
670 * removal from the system. This implementation issues a synchronize cache
671 * operation, if the media is writable, and then ejects the media.
672 *
673 * Note that this method is called from within the yield() routine.
674 *
675 * This method is called with the arbitration lock held.
676 * @param provider
677 * This object's provider.
678 */
679
680 virtual bool handleYield(IOService * provider,
681 IOOptionBits options = 0,
682 void * argument = 0);
683
684
685 /*!
686 * @function getMediaBlockSize
687 * @discussion
688 * Ask the driver about the media's natural block size.
689 * @result
690 * Natural block size, in bytes.
691 */
692
693 virtual UInt64 getMediaBlockSize() const;
694
695public:
696
697///m:2333367:workaround:commented:start
698// using read;
699// using write;
700///m:2333367:workaround:commented:stop
701
702 /*
703 * Initialize this object's minimal state.
704 *
705 * This method's implementation is not typically overidden.
706 */
707
708 virtual bool init(OSDictionary * properties = 0);
709
710 /*
711 * This method is called once we have been attached to the provider object.
712 *
713 * This method's implementation is not typically overidden.
714 */
715
716 virtual bool start(IOService * provider);
717
718 /*
719 * This method is called as a result of the kIOMessageServiceIsTerminated
720 * or kIOMessageServiceIsRequestingClose provider messages. The argument
721 * is passed in as-is from the message. The kIOServiceRequired option is
722 * set for the kIOMessageServiceIsTerminated message to indicate that the
723 * yield must succeed.
724 *
725 * This method is called with the arbitration lock held.
726 *
727 * This method's implementation is not typically overidden.
728 */
729
730 virtual bool yield(IOService * provider,
731 IOOptionBits options = 0,
732 void * argument = 0);
733
734 /*!
735 * @function read
736 * @discussion
737 * The read method is the receiving end for all read requests from the
738 * storage framework (through the media object created by this driver).
739 *
740 * This method kicks off a sequence of three methods for each read or write
741 * request. The first is prepareRequest, which allocates and prepares some
742 * context for the transfer; the second is deblockRequest, which aligns the
743 * transfer at the media block boundaries; and the third is executeRequest,
744 * which implements the actual transfer from the block storage device.
745 *
746 * This method's implementation is not typically overidden.
747 * @param client
748 * Client requesting the read.
749 * @param byteStart
750 * Starting byte offset for the data transfer.
751 * @param buffer
752 * Buffer for the data transfer. The size of the buffer implies the size of
753 * the data transfer.
754 * @param completion
755 * Completion routine to call once the data transfer is complete.
756 */
757
758 virtual void read(IOService * client,
759 UInt64 byteStart,
760 IOMemoryDescriptor * buffer,
761 IOStorageCompletion completion);
762
763 /*!
764 * @function write
765 * @discussion
766 * The write method is the receiving end for all write requests from the
767 * storage framework (through the media object created by this driver).
768 *
769 * This method kicks off a sequence of three methods for each read or write
770 * request. The first is prepareRequest, which allocates and prepares some
771 * context for the transfer; the second is deblockRequest, which aligns the
772 * transfer at the media block boundaries; and the third is executeRequest,
773 * which implements the actual transfer from the block storage device.
774 *
775 * This method's implementation is not typically overidden.
776 * @param client
777 * Client requesting the write.
778 * @param byteStart
779 * Starting byte offset for the data transfer.
780 * @param buffer
781 * Buffer for the data transfer. The size of the buffer implies the size of
782 * the data transfer.
783 * @param completion
784 * Completion routine to call once the data transfer is complete.
785 */
786
787 virtual void write(IOService * client,
788 UInt64 byteStart,
789 IOMemoryDescriptor * buffer,
790 IOStorageCompletion completion);
791
792 virtual IOReturn synchronizeCache(IOService * client);
793
794 /*!
795 * @function ejectMedia
796 * @discussion
797 * Eject the media from the device. The driver is responsible for tearing
798 * down the media object it created before proceeding with the eject. If
799 * the teardown fails, an error should be returned.
800 * @result
801 * An IOReturn code.
802 */
803
804 virtual IOReturn ejectMedia();
805
806 /*!
807 * @function formatMedia
808 * @discussion
809 * Format the media with the specified byte capacity. The driver is
810 * responsible for tearing down the media object and recreating it.
811 * @param byteCapacity
812 * Number of bytes to format media to.
813 * @result
814 * An IOReturn code.
815 */
816
817 virtual IOReturn formatMedia(UInt64 byteCapacity);
818
819 /*!
820 * @function lockMedia
821 * @discussion
822 * Lock or unlock the ejectable media in the device, that is, prevent
823 * it from manual ejection or allow its manual ejection.
824 * @param lock
825 * Pass true to lock the media, otherwise pass false to unlock the media.
826 * @result
827 * An IOReturn code.
828 */
829
830 virtual IOReturn lockMedia(bool lock);
831
832 /*!
833 * @function pollMedia
834 * @discussion
835 * Poll for the presence of media in the device. The driver is responsible
836 * for tearing down the media object it created should the media have been
837 * removed since the last poll, and vice-versa, creating the media object
838 * should new media have arrived since the last poll.
839 * @result
840 * An IOReturn code.
841 */
842
843 virtual IOReturn pollMedia();
844
845 /*!
846 * @function isMediaEjectable
847 * @discussion
848 * Ask the driver whether the media is ejectable.
849 * @result
850 * Returns true if the media is ejectable, false otherwise.
851 */
852
853 virtual bool isMediaEjectable() const;
854
855 /*!
856 * @function isMediaPollExpensive
857 * @discussion
858 * Ask the driver whether a pollMedia() would be an expensive operation,
859 * that is, one that requires the device to spin up or delay for a while.
860 * @result
861 * Returns true if polling the media is expensive, false otherwise.
862 */
863
864 virtual bool isMediaPollExpensive() const;
865
866 /*!
867 * @function isMediaPollRequired
868 * @discussion
869 * Ask the driver whether the block storage device requires polling, which is
870 * typically required for devices without the ability to asynchronously detect
871 * the arrival or departure of the media.
872 * @result
873 * Returns true if polling the media is required, false otherwise.
874 */
875
876 virtual bool isMediaPollRequired() const;
877
878 virtual bool isMediaWritable() const;
879
880 /*!
881 * @function getMediaState
882 * @discussion
883 * Ask the driver about the media's current state.
884 * @result
885 * An IOMediaState value.
886 */
887
888 virtual IOMediaState getMediaState() const;
889
890 /*!
891 * @function getFormatCapacities
892 * @discussion
893 * Ask the driver to report the feasible formatting capacities for the
894 * inserted media (in bytes). This routine fills the caller's buffer,
895 * up to the maximum count specified if the real number of capacities
896 * would overflow the buffer. The return value indicates the actual
897 * number of capacities copied to the buffer.
898 *
899 * If the capacities buffer is not supplied or if the maximum count is
900 * zero, the routine returns the proposed count of capacities instead.
901 * @param capacities
902 * Buffer that will receive the UInt64 capacity values.
903 * @param capacitiesMaxCount
904 * Maximum number of capacity values that can be held in the buffer.
905 * @result
906 * Actual number of capacity values copied to the buffer, or if no buffer
907 * is given, the total number of capacity values available.
908 */
909
910 virtual UInt32 getFormatCapacities(UInt64 * capacities,
911 UInt32 capacitiesMaxCount) const;
912
913 /*!
914 * @function getStatistics
915 * @discussion
916 * Ask the driver to report its operating statistics.
917 *
918 * The statistics are each indexed by IOBlockStorageDriver::Statistics
919 * indices. This routine fills the caller's buffer, up to the maximum
920 * count specified if the real number of statistics would overflow the
921 * buffer. The return value indicates the actual number of statistics
922 * copied to the buffer.
923 *
924 * If the statistics buffer is not supplied or if the maximum count is
925 * zero, the routine returns the proposed count of statistics instead.
926 * @param statistics
927 * Buffer that will receive the UInt64 statistic values.
928 * @param statisticsMaxCount
929 * Maximum number of statistic values that can be held in the buffer.
930 * @result
931 * Actual number of statistic values copied to the buffer, or if no buffer
932 * is given, the total number of statistic values available.
933 */
934
935 virtual UInt32 getStatistics(UInt64 * statistics,
936 UInt32 statisticsMaxCount) const;
937
938 /*!
939 * @function getStatistic
940 * @discussion
941 * Ask the driver to report one of its operating statistics.
942 * @param statistic
943 * Statistic index (an IOBlockStorageDriver::Statistics index).
944 * @result
945 * Statistic value.
946 */
947
948 virtual UInt64 getStatistic(Statistics statistic) const;
949
950 /*
951 * Generic entry point for calls from the provider. A return value of
952 * kIOReturnSuccess indicates that the message was received, and where
953 * applicable, that it was successful.
954 */
955
956 virtual IOReturn message(UInt32 type, IOService * provider, void * argument);
957
958 /*
959 * Obtain this object's provider. We override the superclass's method to
960 * return a more specific subclass of IOService -- IOBlockStorageDevice.
961 * This method serves simply as a convenience to subclass developers.
962 */
963
964 virtual IOBlockStorageDevice * getProvider() const;
965
966protected:
967
968 IOLock * _deblockRequestWriteLock;
969 thread_call_t _pollerCall;
970
971 /*
972 * This is the completion routine for the aligned deblocker subrequests.
973 * It verifies the success of the just-completed stage, transitions to
974 * the next stage, then builds and issues a transfer for the next stage.
975 */
976
977 static void deblockRequestCompletion(void * target,
978 void * parameter,
979 IOReturn status,
980 UInt64 actualByteCount);
981
982 /*
983 * This is the completion routine for the prepared request. It updates
984 * the driver's statistics, performs some clean up work, then calls the
985 * original request's completion routine.
986 */
987
988 static void prepareRequestCompletion(void * target,
989 void * parameter,
990 IOReturn status,
991 UInt64 actualByteCount);
992
993 /*
994 * Schedule the poller mechanism.
995 */
996
997 virtual void schedulePoller();
998
999 /*
1000 * Unschedule the poller mechanism.
1001 */
1002
1003 virtual void unschedulePoller();
1004
1005 /*
1006 * This method is the timeout handler for the poller mechanism. It polls
1007 * for media and reschedules another timeout if there are still no opens.
1008 */
1009
1010 static void poller(void *, void *);
1011
1012protected:
1013
1014 /* Device info: */
1015
1016 /*!
1017 * @var _removable
1018 * True if the media is removable; False if it is fixed (not removable).
1019 */
1020 bool _removable;
1021
1022 /*!
1023 * @var _ejectable
1024 * True if the media is ejectable under software control.
1025 */
1026 bool _ejectable; /* software-ejectable */
1027
1028 /*!
1029 * @var _lockable
1030 * True if the media can be locked in the device under software control.
1031 */
1032 bool _lockable; /* software lockable in device */
1033 /*!
1034 * @var _pollIsRequired
1035 * True if we must poll to detect media insertion or removal.
1036 */
1037 bool _pollIsRequired;
1038 /*!
1039 * @var _pollIsExpensive
1040 * True if polling is expensive; False if not.
1041 */
1042 bool _pollIsExpensive;
1043
1044 /* Media info and states: */
1045
1046 /*!
1047 * @var _mediaObject
1048 * A pointer to the media object we have instantiated (if any).
1049 */
1050 IOMedia * _mediaObject;
1051 /*!
1052 * @var _mediaType
1053 * Type of the media (can be used to differentiate between the
1054 * different types of CD media, DVD media, etc).
1055 */
1056 UInt32 _mediaType;
1057 /*!
1058 * @var _mediaPresent
1059 * True if media is present in the device; False if not.
1060 */
1061 bool _mediaPresent; /* media is present and ready */
1062 /*!
1063 * @var _writeProtected
1064 * True if the media is write-protected; False if not.
1065 */
1066 bool _writeProtected;
1067
1068private:
1069
1070 /*!
1071 * @var _mediaStateLock
1072 * A lock used to protect during media checks.
1073 */
1074 IOLock * _mediaStateLock;
1075
1076protected:
1077
1078 /*!
1079 * @var _mediaBlockSize
1080 * The block size of the media, in bytes.
1081 */
1082 UInt64 _mediaBlockSize;
1083 /*!
1084 * @var _maxBlockNumber
1085 * The maximum allowable block number for the media, zero-based.
1086 */
1087 UInt64 _maxBlockNumber;
1088
1089 /*!
1090 * @var _maxReadByteTransfer
1091 * The maximum byte transfer allowed for read operations.
1092 */
1093 UInt64 _maxReadByteTransfer;
1094
1095 /*!
1096 * @var _maxWriteByteTransfer
1097 * The maximum byte transfer allowed for write operations.
1098 */
1099 UInt64 _maxWriteByteTransfer;
1100
1101 /*!
1102 * @function acceptNewMedia
1103 * @abstract
1104 * React to new media insertion.
1105 * @discussion
1106 * This method logs the media block size and block count, then calls
1107 * instantiateMediaObject to get a media object instantiated. The
1108 * media object is then attached above us and registered.
1109 *
1110 * This method can be overridden to control what happens when new media
1111 * is inserted. The default implementation deals with one IOMedia object.
1112 */
1113 virtual IOReturn acceptNewMedia(void);
1114
1115 /*!
1116 * @function constrainByteCount
1117 * @abstract
1118 * Constrain the byte count for this IO to device limits.
1119 * @discussion
1120 * This function should be called prior to each read or write operation, so that
1121 * the driver can constrain the requested byte count, as necessary, to meet
1122 * current device limits. Such limits could be imposed by the device depending
1123 * on operating modes, media types, or transport prototol (e.g. ATA, SCSI).
1124 *
1125 * At present, this method is not used.
1126 * @param requestedCount
1127 * The requested byte count for the next read or write operation.
1128 * @param isWrite
1129 * True if the operation will be a write; False if the operation will be a read.
1130 */
1131 virtual UInt64 constrainByteCount(UInt64 requestedCount,bool isWrite);
1132
1133 /*!
1134 * @function decommissionMedia
1135 * @abstract
1136 * Decommission an existing piece of media that has gone away.
1137 * @discussion
1138 * This method wraps a call to terminate, to tear down the stack and
1139 * the IOMedia object for the media. If "forcible" is true, the media
1140 * object will be forgotten, and initMediaState will be called. A
1141 * forcible decommission would occur when an unrecoverable error
1142 * happens during teardown (e.g. perhaps a client is still open), but
1143 * we must still forget about the media.
1144 * @param forcible
1145 * True to force forgetting of the media object even if terminate reports
1146 * that there was an active client.
1147 */
1148 virtual IOReturn decommissionMedia(bool forcible);
1149
1150 /*!
1151 * @function instantiateDesiredMediaObject
1152 * @abstract
1153 * Create an IOMedia object for media.
1154 * @discussion
1155 * This method creates the exact type of IOMedia object desired. It is called by
1156 * instantiateMediaObject. A subclass may override this one-line method to change
1157 * the type of media object actually instantiated.
1158 */
1159 virtual IOMedia * instantiateDesiredMediaObject(void);
1160
1161 /*!
1162 * @function instantiateMediaObject
1163 * @abstract
1164 * Create an IOMedia object for media.
1165 * @discussion
1166 * This method creates an IOMedia object from the supplied parameters. It is a
1167 * convenience method to wrap the handful of steps to do the job.
1168 * @param base
1169 * Byte number of beginning of active data area of the media. Usually zero.
1170 * @param byteSize
1171 * Size of the data area of the media, in bytes.
1172 * @param blockSize
1173 * Block size of the media, in bytes.
1174 * @param mediaName
1175 * Name of the IOMedia object.
1176 * @result
1177 * A pointer to the created IOMedia object, or a null on error.
1178 */
1179 virtual IOMedia * instantiateMediaObject(UInt64 base,UInt64 byteSize,
1180 UInt32 blockSize,char *mediaName);
1181
1182 /*!
1183 * @function recordMediaParameters
1184 * @abstract
1185 * Obtain media-related parameters on media insertion.
1186 * @discussion
1187 * This method obtains media-related parameters via calls to the
1188 * Transport Driver's reportBlockSize, reportMaxValidBlock,
1189 * reportMaxReadTransfer, reportMaxWriteTransfer, and reportWriteProtection
1190 * methods.
1191 */
1192 virtual IOReturn recordMediaParameters(void);
1193
1194 /*!
1195 * @function rejectMedia
1196 * @abstract
1197 * Reject new media.
1198 * @discussion
1199 * This method will be called if validateNewMedia returns False (thus rejecting
1200 * the new media. A vendor may choose to override this method to control behavior
1201 * when media is rejected.
1202 *
1203 * The default implementation simply calls ejectMedia.
1204 */
1205 virtual void rejectMedia(void); /* default ejects */
1206
1207 /*!
1208 * @function validateNewMedia
1209 * @abstract
1210 * Verify that new media is acceptable.
1211 * @discussion
1212 * This method will be called whenever new media is detected. Return true to accept
1213 * the media, or false to reject it (andcall rejectMedia). Vendors might override
1214 * this method to handle password-protection for new media.
1215 *
1216 * The default implementation always returns True, indicating media is accepted.
1217 */
1218 virtual bool validateNewMedia(void);
1219
1220 /* --- Internally used methods. --- */
1221
1222 /*
1223 * @group
1224 * Internally Used Methods
1225 * @discussion
1226 * These methods are used internally, and will not generally be modified.
1227 */
1228
1229 /*!
1230 * @function checkForMedia
1231 * @abstract
1232 * Check if media has newly arrived or disappeared.
1233 * @discussion
1234 * This method does most of the work in polling for media, first
1235 * calling the block storage device's reportMediaState method. If
1236 * reportMediaState reports no change in the media state, kIOReturnSuccess
1237 * is returned. If the media state has indeed changed, a call is made to
1238 * mediaStateHasChanged to act on the event.
1239 */
1240 virtual IOReturn checkForMedia(void);
1241
1242 /*!
1243 * @function getDeviceTypeName
1244 * @abstract
1245 * Return the desired device name.
1246 * @discussion
1247 * This method returns a string, used to compare the
1248 * kIOBlockStorageDeviceTypeKey of our provider. This method is called from
1249 * probe.
1250 *
1251 * The default implementation of this method returns
1252 * kIOBlockStorageDeviceTypeGeneric.
1253 */
1254 virtual const char * getDeviceTypeName(void);
1255
1256 /*!
1257 * @function initMediaState
1258 * @abstract
1259 * Initialize media-related instance variables.
1260 * @discussion
1261 * Called when media is not present, this method marks the device state
1262 * as not having media present, not spun up, and write-enabled.
1263 */
1264 virtual void initMediaState(void);
1265
1266 /*!
1267 * @function mediaStateHasChanged
1268 * @abstract
1269 * React to a new media insertion or a media removal.
1270 * @discussion
1271 * This method is called on a media state change, that is, an arrival
1272 * or removal. If media has just become available, calls are made to
1273 * recordMediaParameters and acceptNewMedia. If media has just gone
1274 * away, a call is made to decommissionMedia, with the forcible
1275 * parameter set to true. The forcible teardown is needed to enforce
1276 * the disappearance of media, regardless of interested clients.
1277 */
1278 virtual IOReturn mediaStateHasChanged(IOMediaState state);
1279
1280 /*
1281 * @endgroup
1282 */
1283
1284 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 0);
1285 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 1);
1286 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 2);
1287 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 3);
1288 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 4);
1289 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 5);
1290 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 6);
1291 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 7);
1292 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 8);
1293 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 9);
1294 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 10);
1295 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 11);
1296 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 12);
1297 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 13);
1298 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 14);
1299 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 15);
1300 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 16);
1301 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 17);
1302 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 18);
1303 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 19);
1304 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 20);
1305 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 21);
1306 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 22);
1307 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 23);
1308 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 24);
1309 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 25);
1310 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 26);
1311 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 27);
1312 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 28);
1313 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 29);
1314 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 30);
1315 OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 31);
1316};
1317
1318#endif /* defined(KERNEL) && defined(__cplusplus) */
1319
1320#endif /* !_IOBLOCKSTORAGEDRIVER_H */