2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 #include <IOKit/assert.h>
24 #include <IOKit/IOLib.h>
25 #include <IOKit/IOMemoryDescriptor.h>
26 #include <IOKit/storage/IOBlockStorageDevice.h>
27 #include <IOKit/storage/IOBlockStorageDriver.h>
28 #include <IOKit/storage/IOMedia.h>
30 #define super IOStorage
31 OSDefineMetaClassAndStructors(IOBlockStorageDriver
, IOStorage
)
33 // Hack for Cheetah to prevent sleep if there's disk activity.
34 static IOService
* gIORootPowerDomain
= NULL
;
36 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
38 const UInt32 kPollerInterval
= 1000; // (ms, 1 second)
40 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
42 IOBlockStorageDevice
* IOBlockStorageDriver::getProvider() const
45 // Obtain this object's provider. We override the superclass's method to
46 // return a more specific subclass of IOService -- IOBlockStorageDevice.
47 // This method serves simply as a convenience to subclass developers.
50 return (IOBlockStorageDevice
*) IOService::getProvider();
53 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
55 bool IOBlockStorageDriver::init(OSDictionary
* properties
= 0)
58 // Initialize this object's minimal state.
61 if (super::init(properties
) == false) return false;
67 _pollIsExpensive
= false;
68 _pollIsRequired
= false;
73 _maxReadByteTransfer
= 0;
74 _maxWriteByteTransfer
= 0;
76 _mediaStateLock
= IOLockAlloc();
78 if (_mediaStateLock
== 0)
81 _deblockRequestWriteLock
= IOLockAlloc();
82 _openClients
= OSSet::withCapacity(2);
83 _pollerCall
= thread_call_allocate(poller
, this);
85 for (unsigned index
= 0; index
< kStatisticsCount
; index
++)
86 _statistics
[index
] = OSNumber::withNumber(0ULL, 64);
88 if (_deblockRequestWriteLock
== 0 || _openClients
== 0 || _pollerCall
== 0)
91 for (unsigned index
= 0; index
< kStatisticsCount
; index
++)
92 if (_statistics
[index
] == 0) return false;
95 // Create the standard block storage driver registry properties.
98 OSDictionary
* statistics
= OSDictionary::withCapacity(kStatisticsCount
);
100 if (statistics
== 0) return false;
102 statistics
->setObject( kIOBlockStorageDriverStatisticsBytesReadKey
,
103 _statistics
[kStatisticsBytesRead
] );
104 statistics
->setObject( kIOBlockStorageDriverStatisticsBytesWrittenKey
,
105 _statistics
[kStatisticsBytesWritten
] );
106 statistics
->setObject( kIOBlockStorageDriverStatisticsReadErrorsKey
,
107 _statistics
[kStatisticsReadErrors
] );
108 statistics
->setObject( kIOBlockStorageDriverStatisticsWriteErrorsKey
,
109 _statistics
[kStatisticsWriteErrors
] );
110 statistics
->setObject( kIOBlockStorageDriverStatisticsLatentReadTimeKey
,
111 _statistics
[kStatisticsLatentReadTime
] );
112 statistics
->setObject( kIOBlockStorageDriverStatisticsLatentWriteTimeKey
,
113 _statistics
[kStatisticsLatentWriteTime
] );
114 statistics
->setObject( kIOBlockStorageDriverStatisticsReadsKey
,
115 _statistics
[kStatisticsReads
] );
116 statistics
->setObject( kIOBlockStorageDriverStatisticsWritesKey
,
117 _statistics
[kStatisticsWrites
] );
118 statistics
->setObject( kIOBlockStorageDriverStatisticsReadRetriesKey
,
119 _statistics
[kStatisticsReadRetries
] );
120 statistics
->setObject( kIOBlockStorageDriverStatisticsWriteRetriesKey
,
121 _statistics
[kStatisticsWriteRetries
] );
122 statistics
->setObject( kIOBlockStorageDriverStatisticsTotalReadTimeKey
,
123 _statistics
[kStatisticsTotalReadTime
] );
124 statistics
->setObject( kIOBlockStorageDriverStatisticsTotalWriteTimeKey
,
125 _statistics
[kStatisticsTotalWriteTime
] );
127 setProperty(kIOBlockStorageDriverStatisticsKey
, statistics
);
129 // Hack for Cheetah to prevent sleep if there's disk activity.
130 if (!gIORootPowerDomain
) {
131 // No danger of race here as we're ultimately just setting
132 // the gIORootPowerDomain variable.
135 IOService
* root
= NULL
;
136 OSIterator
* iterator
= NULL
;
137 OSDictionary
* pmDict
= NULL
;
139 root
= IOService::getServiceRoot();
142 pmDict
= root
->serviceMatching("IOPMrootDomain");
145 iterator
= root
->getMatchingServices(pmDict
);
147 if (!iterator
) break;
150 gIORootPowerDomain
= OSDynamicCast(IOService
, iterator
->getNextObject());
159 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
161 bool IOBlockStorageDriver::start(IOService
* provider
)
164 // This method is called once we have been attached to the provider object.
167 // Open the block storage device.
169 if (provider
->open(this) == false) return false;
171 // Prepare the block storage driver for operation.
173 if (handleStart(provider
) == false)
175 provider
->close(this);
179 // Initiate the poller mechanism if it is required.
181 if (isMediaEjectable() && isMediaPollRequired() && !isMediaPollExpensive())
183 lockForArbitration(); // (disable opens/closes; a recursive lock)
185 if (!isOpen() && !isInactive())
186 schedulePoller(); // (schedule the poller, increments retain)
188 unlockForArbitration(); // (enable opens/closes; a recursive lock)
191 // Register this object so it can be found via notification requests. It is
192 // not being registered to have I/O Kit attempt to have drivers match on it,
193 // which is the reason most other services are registered -- that's not the
194 // intention of this registerService call.
201 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
203 bool IOBlockStorageDriver::yield(IOService
* provider
,
204 IOOptionBits options
,
208 // This method is called as a result of the kIOMessageServiceIsTerminated
209 // or kIOMessageServiceIsRequestingClose provider messages. The argument
210 // is passed in as-is from the message. The kIOServiceRequired option is
211 // set for the kIOMessageServiceIsTerminated message to indicate that the
212 // yield must succeed.
215 bool success
= false;
217 lockForArbitration();
219 // Yield the block storage device.
221 success
= handleYield(provider
, options
, argument
);
225 // Close the block storage device.
227 provider
->close(this);
230 unlockForArbitration();
235 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
237 void IOBlockStorageDriver::free()
240 // Free all of this object's outstanding resources.
243 if (_mediaStateLock
) IOLockFree(_mediaStateLock
);
245 if (_deblockRequestWriteLock
) IOLockFree(_deblockRequestWriteLock
);
246 if (_openClients
) _openClients
->release();
247 if (_pollerCall
) thread_call_free(_pollerCall
);
249 for (unsigned index
= 0; index
< kStatisticsCount
; index
++)
250 if (_statistics
[index
]) _statistics
[index
]->release();
255 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
257 bool IOBlockStorageDriver::handleOpen(IOService
* client
,
258 IOOptionBits options
,
262 // The handleOpen method grants or denies permission to access this object
263 // to an interested client. The argument is an IOStorageAccess value that
264 // specifies the level of access desired -- reader or reader-writer.
266 // This method can be invoked to upgrade or downgrade the access level for
267 // an existing client as well. The previous access level will prevail for
268 // upgrades that fail, of course. A downgrade should never fail. If the
269 // new access level should be the same as the old for a given client, this
270 // method will do nothing and return success. In all cases, one, singular
271 // close-per-client is expected for all opens-per-client received.
273 // This method assumes that the arbitration lock is held.
278 // Ensure there is media in the block storage device.
280 if (getMediaState() == kIOMediaStateOffline
) return false;
282 // Handle the first open on removable media in a special case.
284 if (isMediaEjectable() && _openClients
->getCount() == 0)
286 // Halt the poller if it is active and this is the first open.
288 if (isMediaPollRequired() && !isMediaPollExpensive())
289 unschedulePoller(); // (unschedule the poller)
291 // Lock down the media while we have opens on this driver object.
293 if (lockMedia(true) != kIOReturnSuccess
)
294 IOLog("%s: Unable to lock down removable media.\n", getName());
299 _openClients
->setObject(client
); // (works for up/downgrade case)
304 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
306 bool IOBlockStorageDriver::handleIsOpen(const IOService
* client
) const
309 // The handleIsOpen method determines whether the specified client, or any
310 // client if none is specificed, presently has an open on this object.
312 // This method assumes that the arbitration lock is held.
316 return _openClients
->containsObject(client
);
318 return (_openClients
->getCount() != 0);
321 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
323 void IOBlockStorageDriver::handleClose(IOService
* client
, IOOptionBits options
)
326 // The handleClose method drops the incoming client's access to this object.
328 // This method assumes that the arbitration lock is held.
333 // Process the close.
335 _openClients
->removeObject(client
);
337 // Handle the last close in a special case.
339 if (!isInactive() && _openClients
->getCount() == 0)
341 if (isMediaWritable())
343 if (getMediaState() == kIOMediaStateOnline
)
345 // Synchronize the cache on writeable media.
347 if (synchronizeCache(this) != kIOReturnSuccess
)
348 IOLog("%s: Unable to flush cache on media.\n", getName());
352 if (isMediaEjectable())
354 // Unlock the removable media.
356 if (getMediaState() == kIOMediaStateOnline
)
358 if (lockMedia(false) != kIOReturnSuccess
)
359 IOLog("%s: Unable to unlock removable media.\n", getName());
362 // Reactivate the poller.
364 if (isMediaPollRequired() && !isMediaPollExpensive())
365 schedulePoller(); // (schedule the poller, increments retain)
370 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
372 void IOBlockStorageDriver::read(IOService
* /* client */,
374 IOMemoryDescriptor
* buffer
,
375 IOStorageCompletion completion
)
378 // The read method is the receiving end for all read requests from the
379 // storage framework, ie. via the media object created by this driver.
381 // This method kicks off a sequence of three methods for each read or write
382 // request. The first is prepareRequest, which allocates and prepares some
383 // context for the transfer; the second is deblockRequest, which aligns the
384 // transfer at the media block boundaries; and the third is executeRequest,
385 // which implements the actual transfer from the block storage device.
388 // State our assumptions.
390 assert(buffer
->getDirection() == kIODirectionIn
);
392 // Prepare the transfer.
394 prepareRequest(byteStart
, buffer
, completion
);
397 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
399 void IOBlockStorageDriver::write(IOService
* /* client */,
401 IOMemoryDescriptor
* buffer
,
402 IOStorageCompletion completion
)
405 // The write method is the receiving end for all write requests from the
406 // storage framework, ie. via the media object created by this driver.
408 // This method kicks off a sequence of three methods for each read or write
409 // request. The first is prepareRequest, which allocates and prepares some
410 // context for the transfer; the second is deblockRequest, which aligns the
411 // transfer at the media block boundaries; and the third is executeRequest,
412 // which implements the actual transfer from the block storage driver.
415 // State our assumptions.
417 assert(buffer
->getDirection() == kIODirectionOut
);
419 // Prepare the transfer.
421 prepareRequest(byteStart
, buffer
, completion
);
424 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
426 void IOBlockStorageDriver::addToBytesTransferred(UInt64 bytesTransferred
,
427 UInt64 totalTime
, // (ns)
428 UInt64 latentTime
, // (ns)
432 // Update the total number of bytes transferred, the total transfer time,
433 // and the total latency time -- used for statistics.
438 _statistics
[kStatisticsWrites
]->addValue(1);
439 _statistics
[kStatisticsBytesWritten
]->addValue(bytesTransferred
);
440 _statistics
[kStatisticsTotalWriteTime
]->addValue(totalTime
);
441 _statistics
[kStatisticsLatentWriteTime
]->addValue(latentTime
);
442 if (bytesTransferred
<= getMediaBlockSize())
443 _statistics
[kStatisticsSingleBlockWrites
]->addValue(1);
447 _statistics
[kStatisticsReads
]->addValue(1);
448 _statistics
[kStatisticsBytesRead
]->addValue(bytesTransferred
);
449 _statistics
[kStatisticsTotalReadTime
]->addValue(totalTime
);
450 _statistics
[kStatisticsLatentReadTime
]->addValue(latentTime
);
454 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
456 void IOBlockStorageDriver::incrementRetries(bool isWrite
)
459 // Update the total retry count -- used for statistics.
463 _statistics
[kStatisticsWriteRetries
]->addValue(1);
465 _statistics
[kStatisticsReadRetries
]->addValue(1);
468 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
470 void IOBlockStorageDriver::incrementErrors(bool isWrite
)
473 // Update the total error count -- used for statistics.
477 _statistics
[kStatisticsWriteErrors
]->addValue(1);
479 _statistics
[kStatisticsReadErrors
]->addValue(1);
482 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
484 UInt32
IOBlockStorageDriver::getStatistics(UInt64
* statistics
,
485 UInt32 statisticsMaxCount
) const
488 // Ask the driver to report its operating statistics.
490 // The statistics are each indexed by IOBlockStorageDriver::Statistics
491 // indices. This routine fills the caller's buffer, up to the maximum
492 // count specified if the real number of statistics would overflow the
493 // buffer. The return value indicates the actual number of statistics
494 // copied to the buffer.
496 // If the statistics buffer is not supplied or if the maximum count is
497 // zero, the routine returns the proposed count of statistics instead.
501 return kStatisticsCount
;
503 UInt32 statisticsCount
= min(kStatisticsCount
, statisticsMaxCount
);
505 for (unsigned index
= 0; index
< statisticsCount
; index
++)
506 statistics
[index
] = _statistics
[index
]->unsigned64BitValue();
508 return statisticsCount
;
511 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
513 UInt64
IOBlockStorageDriver::getStatistic(Statistics statistic
) const
516 // Ask the driver to report one of its operating statistics.
519 if ((UInt32
) statistic
>= kStatisticsCount
) return 0;
521 return _statistics
[statistic
]->unsigned64BitValue();
524 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
526 IOBlockStorageDriver::Context
* IOBlockStorageDriver::allocateContext()
529 // Allocate a context structure for a read/write operation.
532 Context
* context
= IONew(Context
, 1);
536 bzero(context
, sizeof(Context
));
542 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
544 void IOBlockStorageDriver::deleteContext(
545 IOBlockStorageDriver::Context
* context
)
548 // Delete a context structure from a read/write operation.
551 IODelete(context
, Context
, 1);
554 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
556 void IOBlockStorageDriver::prepareRequest(UInt64 byteStart
,
557 IOMemoryDescriptor
* buffer
,
558 IOStorageCompletion completion
)
561 // The prepareRequest method allocates and prepares state for the transfer.
563 // This method is part of a sequence of methods invoked for each read/write
564 // request. The first is prepareRequest, which allocates and prepares some
565 // context for the transfer; the second is deblockRequest, which aligns the
566 // transfer at the media block boundaries; and the third is executeRequest,
567 // which implements the actual transfer from the block storage device.
573 // Allocate a context structure to hold some of our state.
575 context
= allocateContext();
579 complete(completion
, kIOReturnNoMemory
);
583 // Prepare the transfer buffer.
585 status
= buffer
->prepare();
587 if (status
!= kIOReturnSuccess
)
589 deleteContext(context
);
590 complete(completion
, status
);
594 // Fill in the context structure with some of our state.
596 context
->block
.size
= getMediaBlockSize();
597 context
->block
.type
= kBlockTypeStandard
;
599 context
->original
.byteStart
= byteStart
;
600 context
->original
.buffer
= buffer
;
601 context
->original
.buffer
->retain();
602 context
->original
.completion
= completion
;
604 completion
.target
= this;
605 completion
.action
= prepareRequestCompletion
;
606 completion
.parameter
= context
;
608 // Deblock the transfer.
610 deblockRequest(byteStart
, buffer
, completion
, context
);
613 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
615 void IOBlockStorageDriver::prepareRequestCompletion(void * target
,
618 UInt64 actualByteCount
)
621 // This is the completion routine for the prepared request. It updates
622 // the driver's statistics, performs some clean up work, then calls the
623 // original request's completion routine.
626 Context
* context
= (Context
*) parameter
;
627 IOBlockStorageDriver
* driver
= (IOBlockStorageDriver
*) target
;
630 isWrite
= (context
->original
.buffer
->getDirection() == kIODirectionOut
);
632 // State our assumptions.
634 assert(status
!= kIOReturnSuccess
||
635 context
->original
.buffer
->getLength() == actualByteCount
);
637 // Update the total number of bytes transferred.
639 driver
->addToBytesTransferred(actualByteCount
, 0, 0, isWrite
);
641 // Update the total error count.
643 if (status
!= kIOReturnSuccess
)
645 driver
->incrementErrors(isWrite
);
648 // Complete the transfer buffer.
650 context
->original
.buffer
->complete();
652 // Complete the transfer request.
654 IOStorage::complete(context
->original
.completion
, status
, actualByteCount
);
656 // Release our resources.
658 context
->original
.buffer
->release();
660 driver
->deleteContext(context
);
663 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
665 void IOBlockStorageDriver::schedulePoller()
668 // Schedule the poller mechanism.
670 // This method assumes that the arbitration lock is held.
673 AbsoluteTime deadline
;
677 clock_interval_to_deadline(kPollerInterval
, kMillisecondScale
, &deadline
);
678 thread_call_enter_delayed(_pollerCall
, deadline
);
681 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
683 void IOBlockStorageDriver::unschedulePoller()
686 // Unschedule the poller mechanism.
688 // This method assumes that the arbitration lock is held.
691 if (thread_call_cancel(_pollerCall
)) release();
694 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
696 void IOBlockStorageDriver::poller(void * target
, void *)
699 // This method is the timeout handler for the poller mechanism. It polls
700 // for media and reschedules another timeout if there are still no opens.
703 IOBlockStorageDriver
* driver
= (IOBlockStorageDriver
*) target
;
707 driver
->lockForArbitration(); // (disable opens/closes; a recursive lock)
709 if (!driver
->isOpen() && !driver
->isInactive())
710 driver
->schedulePoller(); // (schedule the poller, increments retain)
712 driver
->unlockForArbitration(); // (enable opens/closes; a recursive lock)
714 driver
->release(); // (drop the retain associated with this poll)
718 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
720 IOReturn
IOBlockStorageDriver::message(UInt32 type
,
721 IOService
* provider
,
725 // Generic entry point for calls from the provider. A return value of
726 // kIOReturnSuccess indicates that the message was received, and where
727 // applicable, that it was successful.
732 case kIOMessageMediaStateHasChanged
:
735 IOLockLock(_mediaStateLock
);
736 status
= mediaStateHasChanged((IOMediaState
) argument
);
737 IOLockUnlock(_mediaStateLock
);
740 case kIOMessageServiceIsRequestingClose
:
743 success
= yield(provider
, 0, argument
);
744 return success
? kIOReturnSuccess
: kIOReturnBusy
;
746 case kIOMessageServiceIsTerminated
:
749 success
= yield(provider
, kIOServiceRequired
, argument
);
750 return success
? kIOReturnSuccess
: kIOReturnError
;
754 return super::message(type
, provider
, argument
);
759 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
761 /* Accept a new piece of media, doing whatever's necessary to make it
762 * show up properly to the system. The arbitration lock is assumed to
763 * be held during the call.
766 IOBlockStorageDriver::acceptNewMedia(void)
774 /* Since the kernel printf doesn't handle 64-bit integers, we
775 * simply make an assumption that the block count and size
776 * will be 32-bit values max.
780 IOLog("%s[IOBlockStorageDriver]::%s media: %ld blocks, %ld bytes each, write-%s.\n",
783 (UInt32
)_maxBlockNumber
+ 1,(UInt32
)getMediaBlockSize(),
784 (_writeProtected
? "protected" : "enabled"));
787 if (_maxBlockNumber
) {
788 nbytes
= _mediaBlockSize
* (_maxBlockNumber
+ 1);
793 /* Instantiate a media object and attach it to ourselves. */
797 if (getProvider()->getVendorString()) {
798 strcat(name
, getProvider()->getVendorString());
801 if (getProvider()->getProductString()) {
802 if (nameSep
== true) strcat(name
, " ");
803 strcat(name
, getProvider()->getProductString());
806 if (nameSep
== true) strcat(name
, " ");
807 strcat(name
, "Media");
809 _mediaObject
= instantiateMediaObject(0,nbytes
,_mediaBlockSize
,name
);
810 result
= (_mediaObject
) ? kIOReturnSuccess
: kIOReturnBadArgument
;
812 if (result
== kIOReturnSuccess
) {
813 ok
= _mediaObject
->attach(this); /* attach media object above us */
815 _mediaPresent
= true;
816 _mediaObject
->registerService(); /* enable matching */
818 _mediaObject
->release();
820 return(kIOReturnNoMemory
); /* give up now */
828 IOBlockStorageDriver::checkForMedia(void)
834 IOLockLock(_mediaStateLock
);
836 result
= getProvider()->reportMediaState(¤tState
,&changed
);
837 if (result
!= kIOReturnSuccess
) { /* the poll operation failed */
838 IOLog("%s[IOBlockStorageDriver]::checkForMedia; err '%s' from reportMediaState\n",
839 getName(),stringFromReturn(result
));
840 } else if (changed
) { /* the poll succeeded, media state has changed */
841 result
= mediaStateHasChanged(currentState
? kIOMediaStateOnline
842 : kIOMediaStateOffline
);
845 IOLockUnlock(_mediaStateLock
);
850 IOBlockStorageDriver::mediaStateHasChanged(IOMediaState state
)
854 /* The media has changed state. See if it's just inserted or removed. */
856 if (state
== kIOMediaStateOnline
) { /* media is now present */
858 /* Allow a subclass to decide whether we accept the media. Such a
859 * decision might be based on things like password-protection, etc.
862 if (validateNewMedia() == false) { /* we're told to reject it */
863 rejectMedia(); /* so let subclass do whatever it wants */
864 return(kIOReturnSuccess
); /* pretend nothing happened */
867 result
= recordMediaParameters(); /* learn about media */
868 if (result
!= kIOReturnSuccess
) { /* couldn't record params */
869 initMediaState(); /* deny existence of new media */
870 IOLog("%s[IOBlockStorageDriver]::checkForMedia: err '%s' from recordMediaParameters\n",
871 getName(),stringFromReturn(result
));
875 /* Now we do what's necessary to make the new media
876 * show up properly in the system.
879 lockForArbitration();
880 result
= acceptNewMedia();
882 if (result
!= kIOReturnSuccess
) {
883 initMediaState(); /* deny existence of new media */
884 IOLog("%s[IOBlockStorageDriver]::checkForMedia; err '%s' from acceptNewMedia\n",
885 getName(),stringFromReturn(result
));
888 unlockForArbitration();
889 return(result
); /* all done, new media is ready */
891 } else { /* media is now absent */
893 lockForArbitration();
894 result
= decommissionMedia(true); /* force a teardown */
895 unlockForArbitration();
897 if (result
!= kIOReturnSuccess
&& result
!= kIOReturnNoMedia
) {
898 IOLog("%s[IOBlockStorageDriver]::checkForMedia; err '%s' from decommissionNewMedia\n",
899 getName(),stringFromReturn(result
));
903 return(kIOReturnSuccess
); /* all done; media is gone */
908 IOBlockStorageDriver::constrainByteCount(UInt64
/* requestedCount */ ,bool isWrite
)
911 return(_maxWriteByteTransfer
);
913 return(_maxReadByteTransfer
);
917 /* Decommission a piece of media that has become unavailable either due to
918 * ejection or some outside force (e.g. the Giant Hand of the User).
919 * (I prefer the term "decommission" rather than "abandon." The former implies
920 * a well-determined procedure, whereas the latter implies leaving the media
921 * in an orphaned state.)
923 /* Tear down the stack above the specified object. Usually these objects will
924 * be of type IOMedia, but they could be any IOService. The arbitration lock is
925 * assumed to be held during the call.
928 IOBlockStorageDriver::decommissionMedia(bool forcible
)
933 /* If this is a forcible decommission (i.e. media is gone), we don't
934 * care whether the teardown worked; we forget about the media.
936 if (_mediaObject
->terminate(forcible
? kIOServiceRequired
: 0) || forcible
) {
937 _mediaObject
->release();
940 initMediaState(); /* clear all knowledge of the media */
941 result
= kIOReturnSuccess
;
944 result
= kIOReturnBusy
;
947 result
= kIOReturnNoMedia
;
954 IOBlockStorageDriver::ejectMedia(void)
960 IOLockLock(_mediaStateLock
);
962 lockForArbitration();
963 result
= decommissionMedia(false); /* try to teardown */
964 unlockForArbitration();
966 if (result
== kIOReturnSuccess
) { /* eject */
967 if (lockMedia(false) != kIOReturnSuccess
)
968 IOLog("%s: Unable to unlock removable media.\n", getName());
970 (void)getProvider()->doEjectMedia(); /* ignore any error */
973 IOLockUnlock(_mediaStateLock
);
978 return(kIOReturnUnsupported
);
983 IOBlockStorageDriver::executeRequest(UInt64 byteStart
,
984 IOMemoryDescriptor
* buffer
,
985 IOStorageCompletion completion
,
986 IOBlockStorageDriver::Context
* context
)
992 if (!_mediaPresent
) { /* no media? you lose */
993 complete(completion
, kIOReturnNoMedia
,0);
997 /* We know that we are never called with a request too large,
998 * nor one that is misaligned with a block.
1000 assert((byteStart
% _mediaBlockSize
) == 0);
1001 assert((buffer
->getLength() % _mediaBlockSize
) == 0);
1003 block
= byteStart
/ _mediaBlockSize
;
1004 nblks
= buffer
->getLength() / _mediaBlockSize
;
1006 /* Now the protocol-specific provider implements the actual
1007 * start of the data transfer: */
1009 // Tickle the root power domain to reset the sleep countdown.
1010 if (gIORootPowerDomain
) {
1011 gIORootPowerDomain
->activityTickle(kIOPMSubclassPolicy
);
1014 result
= getProvider()->doAsyncReadWrite(buffer
,block
,nblks
,completion
);
1016 if (result
!= kIOReturnSuccess
) { /* it failed to start */
1017 IOLog("%s[IOBlockStorageDriver]; executeRequest: request failed to start!\n",getName());
1018 complete(completion
,result
);
1024 IOBlockStorageDriver::formatMedia(UInt64 byteCapacity
)
1026 if (!_mediaPresent
) {
1027 return(kIOReturnNoMedia
);
1030 return(getProvider()->doFormatMedia(byteCapacity
));
1034 IOBlockStorageDriver::getDeviceTypeName(void)
1036 return(kIOBlockStorageDeviceTypeGeneric
);
1040 IOBlockStorageDriver::getFormatCapacities(UInt64
* capacities
,
1041 UInt32 capacitiesMaxCount
) const
1043 return(getProvider()->doGetFormatCapacities(capacities
,capacitiesMaxCount
));
1047 IOBlockStorageDriver::getMediaBlockSize() const
1049 return(_mediaBlockSize
);
1053 IOBlockStorageDriver::getMediaState() const
1055 if (_mediaPresent
) {
1056 return(kIOMediaStateOnline
);
1058 return(kIOMediaStateOffline
);
1063 IOBlockStorageDriver::handleStart(IOService
* provider
)
1067 /* Print device name/type information on the console: */
1069 /*The protocol-specific provider determines whether the media is removable. */
1071 result
= getProvider()->reportRemovability(&_removable
);
1072 if (result
!= kIOReturnSuccess
) {
1073 IOLog("%s[IOBlockStorageDriver]::handleStart; err '%s' from reportRemovability\n",
1074 getName(),stringFromReturn(result
));
1080 /* The protocol-specific provider determines whether we must poll to detect
1081 * media insertion. Nonremovable devices never need polling.
1084 result
= getProvider()->reportPollRequirements(&_pollIsRequired
,&_pollIsExpensive
);
1086 if (result
!= kIOReturnSuccess
) {
1087 IOLog("%s[IOBlockStorageDriver]::handleStart; err '%s' from reportPollRequirements\n",
1088 getName(),stringFromReturn(result
));
1092 /* The protocol-specific provider determines whether the media is ejectable
1093 * under software control.
1095 result
= getProvider()->reportEjectability(&_ejectable
);
1096 if (result
!= kIOReturnSuccess
) {
1097 IOLog("%s[IOBlockStorageDriver]::handleStart; err '%s' from reportEjectability\n",
1098 getName(),stringFromReturn(result
));
1102 /* The protocol-specific provider determines whether the media is lockable
1103 * under software control.
1105 result
= getProvider()->reportLockability(&_lockable
);
1106 if (result
!= kIOReturnSuccess
) {
1107 IOLog("%s[IOBlockStorageDriver]::handleStart; err '%s' from reportLockability\n",
1108 getName(),stringFromReturn(result
));
1112 } else { /* fixed disk: not ejectable, not lockable */
1115 _pollIsRequired
= true; /* polling detects device disappearance */
1118 /* Check for the device being ready with media inserted: */
1120 result
= checkForMedia();
1122 /* The poll should never fail for nonremovable media: */
1124 if (result
!= kIOReturnSuccess
&& !_removable
) {
1125 IOLog("%s[IOBlockStorageDriver]::handleStart: err '%s' from checkForMedia\n",
1126 getName(),stringFromReturn(result
));
1133 /* The driver has been instructed to yield. The arbitration lock is assumed to
1134 * be held during the call.
1137 IOBlockStorageDriver::handleYield(IOService
* provider
,
1138 IOOptionBits options
,
1141 // Determine whether we can yield (for non-required yield requests).
1143 if ( (options
& kIOServiceRequired
) == 0 && isOpen() != false )
1148 // Halt the poller mechanism.
1150 if ( isMediaEjectable() != false &&
1151 isMediaPollRequired() != false &&
1152 isMediaPollExpensive() == false )
1154 unschedulePoller(); // (unschedule the poller)
1157 // Force a teardown.
1159 decommissionMedia(true);
1165 IOBlockStorageDriver::initMediaState(void)
1167 _mediaPresent
= false;
1168 _writeProtected
= false;
1172 IOBlockStorageDriver::instantiateDesiredMediaObject(void)
1174 return(new IOMedia
);
1178 IOBlockStorageDriver::instantiateMediaObject(UInt64 base
,UInt64 byteSize
,
1179 UInt32 blockSize
,char *mediaName
)
1184 m
= instantiateDesiredMediaObject();
1189 result
= m
->init( base
, /* base byte offset */
1190 byteSize
, /* byte size */
1191 blockSize
, /* preferred block size */
1192 _ejectable
, /* TRUE if ejectable */
1193 true, /* TRUE if whole physical media */
1194 !_writeProtected
, /* TRUE if writable */
1195 ""); /* content hint */
1198 m
->setName(mediaName
);
1201 } else { /* some init error */
1203 return(NULL
); /* beats me...call it this error */
1208 IOBlockStorageDriver::isMediaEjectable(void) const
1214 IOBlockStorageDriver::isMediaPollExpensive(void) const
1216 return(_pollIsExpensive
);
1220 IOBlockStorageDriver::isMediaPollRequired(void) const
1222 return(_pollIsRequired
);
1226 IOBlockStorageDriver::isMediaWritable(void) const
1228 return(!_writeProtected
);
1232 IOBlockStorageDriver::lockMedia(bool locked
)
1235 return(getProvider()->doLockUnlockMedia(locked
));
1237 return(kIOReturnUnsupported
);
1242 IOBlockStorageDriver::pollMedia(void)
1244 if (!_pollIsRequired
) { /* shouldn't poll; it's an error */
1246 return(kIOReturnUnsupported
);
1248 } else { /* poll is required...do it */
1250 return(checkForMedia());
1256 IOBlockStorageDriver::recordMediaParameters(void)
1260 /* Determine the device's block size and max block number.
1261 * What should an unformatted device report? All zeroes, or an error?
1264 result
= getProvider()->reportBlockSize(&_mediaBlockSize
);
1265 if (result
!= kIOReturnSuccess
) {
1269 result
= getProvider()->reportMaxValidBlock(&_maxBlockNumber
);
1270 if (result
!= kIOReturnSuccess
) {
1274 /* Calculate the maximum allowed byte transfers for reads and writes. */
1276 result
= getProvider()->reportMaxReadTransfer(_mediaBlockSize
,&_maxReadByteTransfer
);
1277 if (result
!= kIOReturnSuccess
) {
1281 result
= getProvider()->reportMaxWriteTransfer(_mediaBlockSize
,&_maxWriteByteTransfer
);
1282 if (result
!= kIOReturnSuccess
) {
1286 /* Is the media write-protected? */
1288 result
= getProvider()->reportWriteProtection(&_writeProtected
);
1289 if (result
!= kIOReturnSuccess
) {
1293 return(kIOReturnSuccess
); /* everything was successful */
1295 /* If we fall thru to here, we had some kind of error. Set everything to
1296 * a reasonable state since we haven't got any real information.
1300 _mediaPresent
= false;
1301 _writeProtected
= true;
1307 IOBlockStorageDriver::rejectMedia(void)
1309 (void)getProvider()->doEjectMedia(); /* eject it, ignoring any error */
1310 initMediaState(); /* deny existence of new media */
1314 IOBlockStorageDriver::synchronizeCache(IOService
*client
)
1316 return(getProvider()->doSynchronizeCache());
1320 IOBlockStorageDriver::validateNewMedia(void)
1325 // -----------------------------------------------------------------------------
1326 // Deblocker Implementation
1328 #include <IOKit/IOBufferMemoryDescriptor.h>
1330 class IODeblocker
: public IOMemoryDescriptor
1332 OSDeclareDefaultStructors(IODeblocker
);
1340 IOMemoryDescriptor
* buffer
;
1344 UInt32 _chunksCount
;
1346 IOBufferMemoryDescriptor
* _excessBuffer
;
1347 UInt64 _excessCountFinal
;
1348 UInt64 _excessCountStart
;
1350 IOMemoryDescriptor
* _requestBuffer
;
1351 IOStorageCompletion _requestCompletion
;
1352 void * _requestContext
;
1353 UInt64 _requestCount
;
1354 bool _requestIsOneBlock
;
1355 UInt64 _requestStart
;
1360 kStagePrepareExcessStart
,
1361 kStagePrepareExcessFinal
,
1366 virtual void free();
1368 virtual bool initWithAddress( void * address
, /* not supported */
1369 IOByteCount withLength
,
1370 IODirection withDirection
);
1372 virtual bool initWithAddress( vm_address_t address
, /* not supported */
1373 IOByteCount withLength
,
1374 IODirection withDirection
,
1377 virtual bool initWithPhysicalAddress(
1378 IOPhysicalAddress address
, /* not supported */
1379 IOByteCount withLength
,
1380 IODirection withDirection
);
1382 virtual bool initWithPhysicalRanges(
1383 IOPhysicalRange
* ranges
, /* not supproted */
1385 IODirection withDirection
,
1386 bool asReference
= false );
1388 virtual bool initWithRanges( IOVirtualRange
* ranges
, /* not supported */
1390 IODirection withDirection
,
1392 bool asReference
= false );
1394 virtual void * getVirtualSegment( IOByteCount offset
, /* not supported */
1395 IOByteCount
* length
);
1397 IOMemoryDescriptor::withAddress
; /* not supported */
1398 IOMemoryDescriptor::withPhysicalAddress
; /* not supported */
1399 IOMemoryDescriptor::withPhysicalRanges
; /* not supported */
1400 IOMemoryDescriptor::withRanges
; /* not supported */
1401 IOMemoryDescriptor::withSubRange
; /* not supported */
1405 static IODeblocker
* withBlockSize(
1407 UInt64 withRequestStart
,
1408 IOMemoryDescriptor
* withRequestBuffer
,
1409 IOStorageCompletion withRequestCompletion
,
1410 void * withRequestContext
);
1412 virtual bool initWithBlockSize(
1414 UInt64 withRequestStart
,
1415 IOMemoryDescriptor
* withRequestBuffer
,
1416 IOStorageCompletion withRequestCompletion
,
1417 void * withRequestContext
);
1419 virtual IOPhysicalAddress
getPhysicalSegment( IOByteCount offset
,
1420 IOByteCount
* length
);
1422 virtual IOReturn
prepare(IODirection forDirection
= kIODirectionNone
);
1424 virtual IOReturn
complete(IODirection forDirection
= kIODirectionNone
);
1426 virtual IOByteCount
readBytes( IOByteCount offset
,
1428 IOByteCount withLength
);
1430 virtual IOByteCount
writeBytes( IOByteCount offset
,
1432 IOByteCount withLength
);
1434 virtual bool getNextStage(UInt64
* byteStart
);
1436 virtual void getRequestCompletion( IOStorageCompletion
* completion
,
1438 UInt64
* actualByteCount
);
1440 virtual IOMemoryDescriptor
* getRequestBuffer();
1442 virtual void * getRequestContext();
1445 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1448 #define super IOMemoryDescriptor
1449 OSDefineMetaClassAndStructors(IODeblocker
, IOMemoryDescriptor
)
1451 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1453 bool IODeblocker::initWithAddress( void * /* address */ ,
1454 IOByteCount
/* withLength */ ,
1455 IODirection
/* withDirection */ )
1460 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1462 bool IODeblocker::initWithAddress( vm_address_t
/* address */ ,
1463 IOByteCount
/* withLength */ ,
1464 IODirection
/* withDirection */ ,
1465 task_t
/* withTask */ )
1470 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1472 bool IODeblocker::initWithPhysicalAddress(
1473 IOPhysicalAddress
/* address */ ,
1474 IOByteCount
/* withLength */ ,
1475 IODirection
/* withDirection */ )
1481 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1483 bool IODeblocker::initWithPhysicalRanges(
1484 IOPhysicalRange
* /* ranges */ ,
1485 UInt32
/* withCount */ ,
1486 IODirection
/* withDirection */ ,
1487 bool /* asReference */ )
1492 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1494 bool IODeblocker::initWithRanges( IOVirtualRange
* /* ranges */ ,
1495 UInt32
/* withCount */ ,
1496 IODirection
/* withDirection */ ,
1497 task_t
/* withTask */ ,
1498 bool /* asReference */ )
1503 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1505 IODeblocker
* IODeblocker::withBlockSize(
1507 UInt64 withRequestStart
,
1508 IOMemoryDescriptor
* withRequestBuffer
,
1509 IOStorageCompletion withRequestCompletion
,
1510 void * withRequestContext
)
1513 // Create a new IODeblocker.
1516 IODeblocker
* me
= new IODeblocker
;
1518 if ( me
&& me
->initWithBlockSize(
1519 /* blockSize */ blockSize
,
1520 /* withRequestStart */ withRequestStart
,
1521 /* withRequestBuffer */ withRequestBuffer
,
1522 /* withRequestCompletion */ withRequestCompletion
,
1523 /* withRequestContext */ withRequestContext
) == false )
1532 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1534 bool IODeblocker::initWithBlockSize(
1536 UInt64 withRequestStart
,
1537 IOMemoryDescriptor
* withRequestBuffer
,
1538 IOStorageCompletion withRequestCompletion
,
1539 void * withRequestContext
)
1542 // Initialize an IODeblocker.
1544 // _excessCountStart = byte count from media boundary to start of request
1545 // _excessCountFinal = byte count from end of request to a media boundary
1548 UInt32 excessBufferSize
= 0;
1550 // Ask our superclass' opinion.
1552 if ( super::init() == false ) return false;
1554 // Initialize our minimal state.
1556 _blockSize
= blockSize
;
1558 _direction
= kIODirectionNone
;
1561 _requestBuffer
= withRequestBuffer
;
1562 _requestBuffer
->retain();
1563 _requestCompletion
= withRequestCompletion
;
1564 _requestContext
= withRequestContext
;
1565 _requestCount
= withRequestBuffer
->getLength();
1566 _requestStart
= withRequestStart
;
1568 _excessCountStart
= (withRequestStart
) % blockSize
;
1569 _excessCountFinal
= (withRequestStart
+ _requestCount
) % blockSize
;
1570 if ( _excessCountFinal
) _excessCountFinal
= blockSize
- _excessCountFinal
;
1572 _requestIsOneBlock
= (_excessCountStart
+ _requestCount
<= blockSize
);
1574 // Determine the necessary size for our scratch buffer.
1576 switch ( _requestBuffer
->getDirection() )
1578 case kIODirectionIn
: // (read)
1580 excessBufferSize
= max(_excessCountStart
, _excessCountFinal
);
1583 case kIODirectionOut
: // (write)
1585 if ( _excessCountStart
) excessBufferSize
+= blockSize
;
1586 if ( _excessCountFinal
) excessBufferSize
+= blockSize
;
1588 // If there is excess both ends of the original request, but both
1589 // ends reside within the same media block, then we could shorten
1590 // our buffer size to just one block.
1592 if ( _excessCountStart
&& _excessCountFinal
&& _requestIsOneBlock
)
1594 excessBufferSize
-= blockSize
;
1604 // Allocate our scratch buffer.
1606 if ( excessBufferSize
)
1608 _excessBuffer
= IOBufferMemoryDescriptor::withCapacity(
1609 /* capacity */ excessBufferSize
,
1610 /* withDirection */ kIODirectionNone
);
1611 if ( _excessBuffer
== 0 ) return false;
1617 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1619 void IODeblocker::free()
1622 // Free all of this object's outstanding resources.
1625 if ( _requestBuffer
) _requestBuffer
->release();
1626 if ( _excessBuffer
) _excessBuffer
->release();
1631 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1633 IOReturn
IODeblocker::prepare(IODirection forDirection
)
1636 // Prepare the memory for an I/O transfer.
1638 // This involves paging in the memory and wiring it down for the duration
1639 // of the transfer. The complete() method finishes the processing of the
1640 // memory after the I/O transfer finishes.
1644 IOReturn status
= kIOReturnInternalError
;
1645 IOReturn statusUndo
;
1647 if ( forDirection
== kIODirectionNone
)
1649 forDirection
= _direction
;
1652 for ( index
= 0; index
< _chunksCount
; index
++ )
1654 status
= _chunks
[index
].buffer
->prepare(forDirection
);
1655 if ( status
!= kIOReturnSuccess
) break;
1658 if ( status
!= kIOReturnSuccess
)
1660 for ( unsigned indexUndo
= 0; indexUndo
<= index
; indexUndo
++ )
1662 statusUndo
= _chunks
[index
].buffer
->complete(forDirection
);
1663 assert(statusUndo
== kIOReturnSuccess
);
1670 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 IOReturn
IODeblocker::complete(IODirection forDirection
)
1675 // Complete processing of the memory after an I/O transfer finishes.
1677 // This method shouldn't be called unless a prepare() was previously issued;
1678 // the prepare() and complete() must occur in pairs, before and after an I/O
1683 IOReturn statusFinal
= kIOReturnSuccess
;
1685 if ( forDirection
== kIODirectionNone
)
1687 forDirection
= _direction
;
1690 for ( unsigned index
= 0; index
< _chunksCount
; index
++ )
1692 status
= _chunks
[index
].buffer
->complete(forDirection
);
1693 if ( status
!= kIOReturnSuccess
) statusFinal
= status
;
1694 assert(status
== kIOReturnSuccess
);
1700 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1702 IOPhysicalAddress
IODeblocker::getPhysicalSegment( IOByteCount offset
,
1703 IOByteCount
* length
)
1706 // This method returns the physical address of the byte at the given offset
1707 // into the memory, and optionally the length of the physically contiguous
1708 // segment from that offset.
1711 assert(offset
<= _length
);
1713 for ( unsigned index
= 0; index
< _chunksCount
; index
++ )
1715 if ( offset
< _chunks
[index
].length
)
1717 IOPhysicalAddress address
;
1718 address
= _chunks
[index
].buffer
->getPhysicalSegment(
1719 /* offset */ offset
+ _chunks
[index
].offset
,
1720 /* length */ length
);
1721 if ( length
) *length
= min(*length
, _chunks
[index
].length
);
1724 offset
-= _chunks
[index
].length
;
1727 if ( length
) *length
= 0;
1732 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1734 void * IODeblocker::getVirtualSegment( IOByteCount
/* offset */ ,
1735 IOByteCount
* /* length */ )
1740 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1742 IOByteCount
IODeblocker::readBytes( IOByteCount offset
,
1744 IOByteCount withLength
)
1747 // Copies data from the memory descriptor's buffer at the given offset, to
1748 // the specified buffer. Returns the number of bytes copied.
1751 IOByteCount bytesCopied
= 0;
1754 for ( index
= 0; index
< _chunksCount
; index
++ )
1756 if ( offset
< _chunks
[index
].length
) break;
1757 offset
-= _chunks
[index
].length
;
1760 for ( ; index
< _chunksCount
&& withLength
; index
++)
1762 IOByteCount copy
= min(_chunks
[index
].length
- offset
, withLength
);
1763 IOByteCount copied
= _chunks
[index
].buffer
->readBytes(
1764 /* offset */ offset
+ _chunks
[index
].offset
,
1766 /* length */ copy
);
1768 bytesCopied
+= copied
;
1769 if ( copied
!= copy
) break;
1771 bytes
= ((UInt8
*) bytes
) + copied
;
1772 withLength
-= copied
;
1779 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1781 IOByteCount
IODeblocker::writeBytes( IOByteCount offset
,
1783 IOByteCount withLength
)
1786 // Copies data to the memory descriptor's buffer at the given offset, from
1787 // the specified buffer. Returns the number of bytes copied.
1790 IOByteCount bytesCopied
= 0;
1793 for ( index
= 0; index
< _chunksCount
; index
++ )
1795 if ( offset
< _chunks
[index
].length
) break;
1796 offset
-= _chunks
[index
].length
;
1799 for ( ; index
< _chunksCount
&& withLength
; index
++)
1801 IOByteCount copy
= min(_chunks
[index
].length
- offset
, withLength
);
1802 IOByteCount copied
= _chunks
[index
].buffer
->writeBytes(
1803 /* offset */ offset
+ _chunks
[index
].offset
,
1805 /* length */ copy
);
1807 bytesCopied
+= copied
;
1808 if ( copied
!= copy
) break;
1810 bytes
= ((UInt8
*) bytes
) + copied
;
1811 withLength
-= copied
;
1818 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1820 bool IODeblocker::getNextStage(UInt64
* byteStart
)
1823 // Obtain the next stage of the transfer. The transfer buffer will be the
1824 // deblocker object itself and the byte start will be returned in byteStart.
1826 // This method must not be called if the current stage failed with an error
1827 // or a short byte count, but instead getRequestCompletion() must be called
1828 // to adjust the status and actual byte count (with respect to the original
1829 // request) and return the original request's completion routine. The same
1830 // call to getRequestCompletion() should also be done if the getNextStage()
1831 // method returns false.
1835 _direction
= kIODirectionNone
;
1838 switch ( _requestBuffer
->getDirection() )
1840 case kIODirectionIn
: // (read)
1846 _stage
= kStageLast
;
1847 _excessBuffer
->setDirection(kIODirectionIn
);
1848 _direction
= kIODirectionIn
;
1849 *byteStart
= _requestStart
- _excessCountStart
;
1851 if ( _excessCountStart
)
1853 _chunks
[_chunksCount
].buffer
= _excessBuffer
;
1854 _chunks
[_chunksCount
].offset
= 0;
1855 _chunks
[_chunksCount
].length
= _excessCountStart
;
1859 _chunks
[_chunksCount
].buffer
= _requestBuffer
;
1860 _chunks
[_chunksCount
].offset
= 0;
1861 _chunks
[_chunksCount
].length
= _requestBuffer
->getLength();
1864 if ( _excessCountFinal
)
1866 _chunks
[_chunksCount
].buffer
= _excessBuffer
;
1867 _chunks
[_chunksCount
].offset
= 0;
1868 _chunks
[_chunksCount
].length
= _excessCountFinal
;
1875 _stage
= kStageDone
;
1885 case kIODirectionOut
: // (write)
1891 if ( _excessCountStart
)
1893 _stage
= kStagePrepareExcessStart
;
1894 _excessBuffer
->setDirection(kIODirectionIn
);
1895 _direction
= kIODirectionIn
;
1896 *byteStart
= _requestStart
- _excessCountStart
;
1898 _chunks
[_chunksCount
].buffer
= _excessBuffer
;
1899 _chunks
[_chunksCount
].offset
= 0;
1900 _chunks
[_chunksCount
].length
= _blockSize
;
1906 case kStagePrepareExcessStart
:
1908 if ( _excessCountFinal
)
1910 // We do not issue this stage if the original transfer
1911 // resides within one media block, and we already read
1912 // that block into our buffer in the previous stage.
1914 if ( !_excessCountStart
|| !_requestIsOneBlock
)
1916 _stage
= kStagePrepareExcessFinal
;
1917 _excessBuffer
->setDirection(kIODirectionIn
);
1918 _direction
= kIODirectionIn
;
1919 *byteStart
= _requestStart
+ _requestCount
+
1920 _excessCountFinal
- _blockSize
;
1922 _chunks
[_chunksCount
].buffer
= _excessBuffer
;
1923 _chunks
[_chunksCount
].offset
= (_requestIsOneBlock
)
1925 : (_excessCountStart
)
1928 _chunks
[_chunksCount
].length
= _blockSize
;
1935 case kStagePrepareExcessFinal
:
1937 _stage
= kStageLast
;
1938 _excessBuffer
->setDirection(kIODirectionOut
);
1939 _direction
= kIODirectionOut
;
1940 *byteStart
= _requestStart
- _excessCountStart
;
1942 if ( _excessCountStart
)
1944 _chunks
[_chunksCount
].buffer
= _excessBuffer
;
1945 _chunks
[_chunksCount
].offset
= 0;
1946 _chunks
[_chunksCount
].length
= _excessCountStart
;
1950 _chunks
[_chunksCount
].buffer
= _requestBuffer
;
1951 _chunks
[_chunksCount
].offset
= 0;
1952 _chunks
[_chunksCount
].length
= _requestBuffer
->getLength();
1955 if ( _excessCountFinal
)
1957 _chunks
[_chunksCount
].buffer
= _excessBuffer
;
1958 _chunks
[_chunksCount
].offset
= (_requestIsOneBlock
)
1960 : (_excessCountStart
)
1963 _chunks
[_chunksCount
].offset
+= ( _blockSize
-
1964 _excessCountFinal
);
1965 _chunks
[_chunksCount
].length
= _excessCountFinal
;
1972 _stage
= kStageDone
;
1988 // Determine whether we have an abort or completion condition.
1990 if ( _chunksCount
== 0 ) return false;
1992 // Compute the total length of the descriptor over all chunks.
1994 for ( unsigned index
= 0; index
< _chunksCount
; index
++ )
1996 _length
+= _chunks
[index
].length
;
2002 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2004 void IODeblocker::getRequestCompletion( IOStorageCompletion
* completion
,
2006 UInt64
* actualByteCount
)
2009 // Obtain the completion information for the original request, taking
2010 // into account the status and actual byte count of the current stage.
2013 *completion
= _requestCompletion
;
2017 case kStageInit
: // (inital stage)
2019 *status
= kIOReturnInternalError
;
2020 *actualByteCount
= 0;
2023 case kStagePrepareExcessStart
: // (write preparation stage)
2024 case kStagePrepareExcessFinal
:
2026 *actualByteCount
= 0;
2029 case kStageLast
: // (last stage)
2032 if ( *actualByteCount
> _excessCountStart
)
2033 *actualByteCount
-= _excessCountStart
;
2035 *actualByteCount
= 0;
2037 if ( *actualByteCount
> _requestBuffer
->getLength() )
2038 *actualByteCount
= _requestBuffer
->getLength();
2048 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2050 IOMemoryDescriptor
* IODeblocker::getRequestBuffer()
2053 // Obtain the buffer for the original request.
2056 return _requestBuffer
;
2059 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2061 void * IODeblocker::getRequestContext()
2064 // Obtain the context for the original request.
2067 return _requestContext
;
2070 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2072 void IOBlockStorageDriver::deblockRequest(
2074 IOMemoryDescriptor
* buffer
,
2075 IOStorageCompletion completion
,
2076 IOBlockStorageDriver::Context
* context
)
2079 // The deblockRequest method checks to see if the incoming request rests
2080 // on the media's block boundaries, and if not, deblocks it. Deblocking
2081 // involves rounding out the request to the nearest block boundaries and
2082 // transferring the excess bytes into a scratch buffer.
2084 // This method is part of a sequence of methods invoked for each read/write
2085 // request. The first is prepareRequest, which allocates and prepares some
2086 // context for the transfer; the second is deblockRequest, which aligns the
2087 // transfer at the media block boundaries; and the third is executeRequest,
2088 // which implements the actual transfer from the block storage device.
2090 // The current implementation of deblockRequest is asynchronous.
2093 IODeblocker
* deblocker
;
2095 // If the request is aligned with the media's block boundaries, we
2096 // do short-circuit the deblocker and call executeRequest directly.
2098 if ( (byteStart
% context
->block
.size
) == 0 &&
2099 (buffer
->getLength() % context
->block
.size
) == 0 )
2101 executeRequest(byteStart
, buffer
, completion
, context
);
2105 // Build a deblocker object.
2107 deblocker
= IODeblocker::withBlockSize(
2108 /* blockSize */ context
->block
.size
,
2109 /* withRequestStart */ byteStart
,
2110 /* withRequestBuffer */ buffer
,
2111 /* withRequestCompletion */ completion
,
2112 /* withRequestContext */ context
);
2114 if ( deblocker
== 0 )
2116 complete(completion
, kIOReturnNoMemory
);
2120 // This implementation of the deblocker permits only one read-modify-write
2121 // at any given time. Note that other write requests can, and do, proceed
2122 // simultaneously so long as they do not require the deblocker -- refer to
2123 // the read() and the write() routines for the short-cut logic.
2125 // Note that the original buffer during a read-modify-write operation must
2126 // be prepared on the client's thread, that is, right now, or else it will
2127 // happen on the controller's thread after the read stage(s) complete, and
2128 // this is bad (causes deadlock if that controller was the swap device).
2130 if ( buffer
->getDirection() == kIODirectionOut
)
2132 if ( buffer
->prepare() != kIOReturnSuccess
)
2134 deblocker
->release();
2135 complete(completion
, kIOReturnNoMemory
);
2139 IOLockLock(_deblockRequestWriteLock
);
2142 // Execute the transfer (for the next stage).
2144 deblockRequestCompletion(this, deblocker
, kIOReturnSuccess
, 0);
2149 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2151 void IOBlockStorageDriver::deblockRequestCompletion( void * target
,
2154 UInt64 actualByteCount
)
2157 // This is the completion routine for the aligned deblocker subrequests.
2158 // It verifies the success of the just-completed stage, transitions to
2159 // the next stage, then builds and issues a transfer for the next stage.
2163 IOStorageCompletion completion
;
2165 IODeblocker
* deblocker
= (IODeblocker
*) parameter
;
2166 IOBlockStorageDriver
* driver
= (IOBlockStorageDriver
*) target
;
2168 // Determine whether an error occurred or whether there are no more stages.
2170 if ( actualByteCount
< deblocker
->getLength() ||
2171 status
!= kIOReturnSuccess
||
2172 deblocker
->getNextStage(&byteStart
) == false )
2174 // Unlock the write-lock in order to allow the next write to proceed.
2176 if ( deblocker
->getRequestBuffer()->getDirection() == kIODirectionOut
)
2178 IOLockUnlock(driver
->_deblockRequestWriteLock
);
2180 deblocker
->getRequestBuffer()->complete();
2183 // Obtain the completion information for the original request, taking
2184 // into account the status and actual byte count of the current stage.
2186 deblocker
->getRequestCompletion(&completion
, &status
, &actualByteCount
);
2188 // Complete the original request.
2190 IOStorage::complete(completion
, status
, actualByteCount
);
2192 // Release our resources.
2194 deblocker
->release();
2199 // Execute the transfer (for the next stage).
2201 completion
.target
= driver
;
2202 completion
.action
= deblockRequestCompletion
;
2203 completion
.parameter
= deblocker
;
2205 context
= (Context
*) deblocker
->getRequestContext();
2207 driver
->executeRequest(byteStart
, deblocker
, completion
, context
);
2212 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2214 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 0);
2216 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2218 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 1);
2220 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2222 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 2);
2224 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2226 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 3);
2228 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2230 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 4);
2232 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2234 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 5);
2236 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2238 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 6);
2240 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2242 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 7);
2244 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2246 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 8);
2248 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2250 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 9);
2252 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2254 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 10);
2256 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2258 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 11);
2260 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2262 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 12);
2264 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2266 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 13);
2268 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2270 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 14);
2272 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2274 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 15);
2276 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2278 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 16);
2280 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2282 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 17);
2284 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2286 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 18);
2288 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2290 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 19);
2292 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2294 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 20);
2296 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2298 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 21);
2300 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2302 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 22);
2304 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2306 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 23);
2308 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2310 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 24);
2312 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2314 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 25);
2316 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2318 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 26);
2320 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2322 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 27);
2324 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2326 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 28);
2328 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2330 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 29);
2332 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2334 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 30);
2336 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2338 OSMetaClassDefineReservedUnused(IOBlockStorageDriver
, 31);