]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Families/IOStorage/IOBlockStorageDriver.cpp
xnu-201.tar.gz
[apple/xnu.git] / iokit / Families / IOStorage / IOBlockStorageDriver.cpp
diff --git a/iokit/Families/IOStorage/IOBlockStorageDriver.cpp b/iokit/Families/IOStorage/IOBlockStorageDriver.cpp
deleted file mode 100644 (file)
index 345e55b..0000000
+++ /dev/null
@@ -1,2338 +0,0 @@
-/*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <IOKit/assert.h>
-#include <IOKit/IOLib.h>
-#include <IOKit/IOMemoryDescriptor.h>
-#include <IOKit/storage/IOBlockStorageDevice.h>
-#include <IOKit/storage/IOBlockStorageDriver.h>
-#include <IOKit/storage/IOMedia.h>
-
-#define super IOStorage
-OSDefineMetaClassAndStructors(IOBlockStorageDriver, IOStorage)
-
-// Hack for Cheetah to prevent sleep if there's disk activity.
-static IOService * gIORootPowerDomain = NULL;
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-const UInt32 kPollerInterval = 1000;                           // (ms, 1 second)
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-IOBlockStorageDevice * IOBlockStorageDriver::getProvider() const
-{
-    //
-    // Obtain this object's provider.  We override the superclass's method to
-    // return a more specific subclass of IOService -- IOBlockStorageDevice.  
-    // This method serves simply as a convenience to subclass developers.
-    //
-
-    return (IOBlockStorageDevice *) IOService::getProvider();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IOBlockStorageDriver::init(OSDictionary * properties = 0)
-{
-    //
-    // Initialize this object's minimal state.
-    //
-
-    if (super::init(properties) == false)  return false;
-
-    initMediaState();
-    
-    _ejectable               = false;
-    _lockable                = false;
-    _pollIsExpensive         = false;
-    _pollIsRequired          = false;
-    _removable               = false;
-    
-    _mediaBlockSize          = 0;
-    _maxBlockNumber          = 0;
-    _maxReadByteTransfer     = 0;
-    _maxWriteByteTransfer    = 0;
-
-    _mediaStateLock          = IOLockAlloc();
-
-    if (_mediaStateLock == 0)
-        return false;
-
-    _deblockRequestWriteLock = IOLockAlloc();
-    _openClients             = OSSet::withCapacity(2);
-    _pollerCall              = thread_call_allocate(poller, this);
-
-    for (unsigned index = 0; index < kStatisticsCount; index++)
-        _statistics[index] = OSNumber::withNumber(0ULL, 64);
-
-    if (_deblockRequestWriteLock == 0 || _openClients == 0 || _pollerCall == 0)
-        return false;
-
-    for (unsigned index = 0; index < kStatisticsCount; index++)
-        if (_statistics[index] == 0)  return false;
-
-    //
-    // Create the standard block storage driver registry properties.
-    //
-
-    OSDictionary * statistics = OSDictionary::withCapacity(kStatisticsCount);
-
-    if (statistics == 0)  return false;
-
-    statistics->setObject( kIOBlockStorageDriverStatisticsBytesReadKey,
-                           _statistics[kStatisticsBytesRead] );
-    statistics->setObject( kIOBlockStorageDriverStatisticsBytesWrittenKey,
-                           _statistics[kStatisticsBytesWritten] );
-    statistics->setObject( kIOBlockStorageDriverStatisticsReadErrorsKey,
-                           _statistics[kStatisticsReadErrors] );
-    statistics->setObject( kIOBlockStorageDriverStatisticsWriteErrorsKey,
-                           _statistics[kStatisticsWriteErrors] );
-    statistics->setObject( kIOBlockStorageDriverStatisticsLatentReadTimeKey,
-                           _statistics[kStatisticsLatentReadTime] );
-    statistics->setObject( kIOBlockStorageDriverStatisticsLatentWriteTimeKey,
-                           _statistics[kStatisticsLatentWriteTime] );
-    statistics->setObject( kIOBlockStorageDriverStatisticsReadsKey,
-                           _statistics[kStatisticsReads] );
-    statistics->setObject( kIOBlockStorageDriverStatisticsWritesKey,
-                           _statistics[kStatisticsWrites] );
-    statistics->setObject( kIOBlockStorageDriverStatisticsReadRetriesKey,
-                           _statistics[kStatisticsReadRetries] );
-    statistics->setObject( kIOBlockStorageDriverStatisticsWriteRetriesKey,
-                           _statistics[kStatisticsWriteRetries] );
-    statistics->setObject( kIOBlockStorageDriverStatisticsTotalReadTimeKey,
-                           _statistics[kStatisticsTotalReadTime] );
-    statistics->setObject( kIOBlockStorageDriverStatisticsTotalWriteTimeKey,
-                           _statistics[kStatisticsTotalWriteTime] );
-    
-    setProperty(kIOBlockStorageDriverStatisticsKey, statistics);
-
-    // Hack for Cheetah to prevent sleep if there's disk activity.
-    if (!gIORootPowerDomain) {
-        // No danger of race here as we're ultimately just setting
-        // the gIORootPowerDomain variable.
-
-        do {
-            IOService * root = NULL;
-            OSIterator * iterator = NULL;
-            OSDictionary * pmDict = NULL;
-
-            root = IOService::getServiceRoot();
-            if (!root) break;
-
-            pmDict = root->serviceMatching("IOPMrootDomain");
-            if (!pmDict) break;
-
-            iterator = root->getMatchingServices(pmDict);
-            pmDict->release();
-            if (!iterator) break;
-
-            if (iterator) {
-                gIORootPowerDomain = OSDynamicCast(IOService, iterator->getNextObject());
-                iterator->release();
-            }
-        } while (false);
-    }
-
-    return true;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IOBlockStorageDriver::start(IOService * provider)
-{
-    //
-    // This method is called once we have been attached to the provider object.
-    //
-
-    // Open the block storage device.
-
-    if (provider->open(this) == false)  return false;
-
-    // Prepare the block storage driver for operation.
-
-    if (handleStart(provider) == false)
-    {
-        provider->close(this);
-        return false;
-    }
-
-    // Initiate the poller mechanism if it is required.
-
-    if (isMediaEjectable() && isMediaPollRequired() && !isMediaPollExpensive())
-    {
-        lockForArbitration();        // (disable opens/closes; a recursive lock)
-
-        if (!isOpen() && !isInactive())
-            schedulePoller();        // (schedule the poller, increments retain)
-
-        unlockForArbitration();       // (enable opens/closes; a recursive lock)
-    }
-
-    // Register this object so it can be found via notification requests. It is
-    // not being registered to have I/O Kit attempt to have drivers match on it,
-    // which is the reason most other services are registered -- that's not the
-    // intention of this registerService call.
-
-    registerService();
-
-    return true;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IOBlockStorageDriver::yield(IOService *  provider,
-                                 IOOptionBits options,
-                                 void *       argument)
-{
-    //
-    // This method is called as a result of the kIOMessageServiceIsTerminated
-    // or kIOMessageServiceIsRequestingClose provider messages.  The argument
-    // is passed in as-is from the message.  The kIOServiceRequired option is
-    // set for the kIOMessageServiceIsTerminated message to indicate that the
-    // yield must succeed.
-    //
-
-    bool success = false;
-
-    lockForArbitration();
-
-    // Yield the block storage device.
-
-    success = handleYield(provider, options, argument);
-
-    if (success)
-    {
-        // Close the block storage device.
-
-        provider->close(this);
-    }
-
-    unlockForArbitration();
-
-    return success;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::free()
-{
-    //
-    // Free all of this object's outstanding resources.
-    //
-
-    if (_mediaStateLock)  IOLockFree(_mediaStateLock);
-
-    if (_deblockRequestWriteLock)  IOLockFree(_deblockRequestWriteLock);
-    if (_openClients)  _openClients->release();
-    if (_pollerCall)  thread_call_free(_pollerCall);
-
-    for (unsigned index = 0; index < kStatisticsCount; index++)
-        if (_statistics[index])  _statistics[index]->release();
-
-    super::free();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IOBlockStorageDriver::handleOpen(IOService *  client,
-                                      IOOptionBits options,
-                                      void *       argument)
-{
-    //
-    // The handleOpen method grants or denies permission to access this object
-    // to an interested client.  The argument is an IOStorageAccess value that
-    // specifies the level of access desired -- reader or reader-writer.
-    //
-    // This method can be invoked to upgrade or downgrade the access level for
-    // an existing client as well.  The previous access level will prevail for
-    // upgrades that fail, of course.   A downgrade should never fail.  If the
-    // new access level should be the same as the old for a given client, this
-    // method will do nothing and return success.  In all cases, one, singular
-    // close-per-client is expected for all opens-per-client received.
-    //
-    // This method assumes that the arbitration lock is held.
-    //
-
-    assert(client);
-
-    // Ensure there is media in the block storage device.
-
-    if (getMediaState() == kIOMediaStateOffline)  return false;
-
-    // Handle the first open on removable media in a special case.
-
-    if (isMediaEjectable() && _openClients->getCount() == 0)
-    {
-        // Halt the poller if it is active and this is the first open.
-
-        if (isMediaPollRequired() && !isMediaPollExpensive())
-            unschedulePoller();                       // (unschedule the poller)
-
-        // Lock down the media while we have opens on this driver object.
-
-        if (lockMedia(true) != kIOReturnSuccess)
-            IOLog("%s: Unable to lock down removable media.\n", getName());
-    }
-
-    // Process the open.
-
-    _openClients->setObject(client);            // (works for up/downgrade case)
-
-    return true;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IOBlockStorageDriver::handleIsOpen(const IOService * client) const
-{
-    //
-    // The handleIsOpen method determines whether the specified client, or any
-    // client if none is specificed, presently has an open on this object.
-    //
-    // This method assumes that the arbitration lock is held.
-    //
-
-    if (client)
-        return _openClients->containsObject(client);
-    else
-        return (_openClients->getCount() != 0);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::handleClose(IOService * client, IOOptionBits options)
-{
-    //
-    // The handleClose method drops the incoming client's access to this object.
-    //
-    // This method assumes that the arbitration lock is held.
-    //
-
-    assert(client);
-
-    // Process the close.
-
-    _openClients->removeObject(client);
-
-    // Handle the last close in a special case.
-
-    if (!isInactive() && _openClients->getCount() == 0)
-    {
-        if (isMediaWritable())
-        {
-            if (getMediaState() == kIOMediaStateOnline)
-            {
-                // Synchronize the cache on writeable media.
-
-                if (synchronizeCache(this) != kIOReturnSuccess)
-                    IOLog("%s: Unable to flush cache on media.\n", getName());
-            }
-        }
-
-        if (isMediaEjectable())
-        {
-            // Unlock the removable media.
-
-            if (getMediaState() == kIOMediaStateOnline)
-            {
-                if (lockMedia(false) != kIOReturnSuccess)
-                    IOLog("%s: Unable to unlock removable media.\n", getName());
-            }
-
-            // Reactivate the poller.
-
-            if (isMediaPollRequired() && !isMediaPollExpensive())
-                schedulePoller();    // (schedule the poller, increments retain)
-          }
-    }
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::read(IOService *          /* client */,
-                                UInt64               byteStart,
-                                IOMemoryDescriptor * buffer,
-                                IOStorageCompletion  completion)
-{
-    //
-    // The read method is the receiving end for all read requests from the
-    // storage framework, ie. via the media object created by this driver.
-    //
-    // This method kicks off a sequence of three methods for each read or write
-    // request.  The first is prepareRequest, which allocates and prepares some
-    // context for the transfer; the second is deblockRequest, which aligns the
-    // transfer at the media block boundaries; and the third is executeRequest,
-    // which implements the actual transfer from the block storage device.
-    //
-
-    // State our assumptions.
-
-    assert(buffer->getDirection() == kIODirectionIn);
-
-    // Prepare the transfer.
-
-    prepareRequest(byteStart, buffer, completion);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::write(IOService *          /* client */,
-                                 UInt64               byteStart,
-                                 IOMemoryDescriptor * buffer,
-                                 IOStorageCompletion  completion)
-{
-    //
-    // The write method is the receiving end for all write requests from the
-    // storage framework, ie. via the media object created by this driver.
-    //
-    // This method kicks off a sequence of three methods for each read or write
-    // request.  The first is prepareRequest, which allocates and prepares some
-    // context for the transfer; the second is deblockRequest, which aligns the
-    // transfer at the media block boundaries; and the third is executeRequest,
-    // which implements the actual transfer from the block storage driver.
-    //
-
-    // State our assumptions.
-
-    assert(buffer->getDirection() == kIODirectionOut);
-
-    // Prepare the transfer.
-
-    prepareRequest(byteStart, buffer, completion);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::addToBytesTransferred(UInt64 bytesTransferred,
-                                                 UInt64 totalTime,       // (ns)
-                                                 UInt64 latentTime,      // (ns)
-                                                 bool   isWrite)
-{
-    //
-    // Update the total number of bytes transferred, the total transfer time,
-    // and the total latency time -- used for statistics.
-    //
-
-    if (isWrite)
-    {
-        _statistics[kStatisticsWrites]->addValue(1);
-        _statistics[kStatisticsBytesWritten]->addValue(bytesTransferred);
-        _statistics[kStatisticsTotalWriteTime]->addValue(totalTime);
-        _statistics[kStatisticsLatentWriteTime]->addValue(latentTime);
-        if (bytesTransferred <= getMediaBlockSize())
-            _statistics[kStatisticsSingleBlockWrites]->addValue(1);
-    }
-    else
-    {
-        _statistics[kStatisticsReads]->addValue(1);
-        _statistics[kStatisticsBytesRead]->addValue(bytesTransferred);
-        _statistics[kStatisticsTotalReadTime]->addValue(totalTime);
-        _statistics[kStatisticsLatentReadTime]->addValue(latentTime);
-    }
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::incrementRetries(bool isWrite)
-{
-    //
-    // Update the total retry count -- used for statistics.
-    //
-
-    if (isWrite)
-        _statistics[kStatisticsWriteRetries]->addValue(1);
-    else
-        _statistics[kStatisticsReadRetries]->addValue(1);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::incrementErrors(bool isWrite)
-{
-    //
-    // Update the total error count -- used for statistics.
-    //
-
-    if (isWrite)
-        _statistics[kStatisticsWriteErrors]->addValue(1);
-    else
-        _statistics[kStatisticsReadErrors]->addValue(1);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-UInt32 IOBlockStorageDriver::getStatistics(UInt64 * statistics,
-                                           UInt32   statisticsMaxCount) const
-{
-    //
-    // Ask the driver to report its operating statistics.
-    //
-    // The statistics are each indexed by IOBlockStorageDriver::Statistics
-    // indices.  This routine fills the caller's buffer, up to the maximum
-    // count specified if the real number of statistics would overflow the
-    // buffer.  The return value indicates the actual number of statistics
-    // copied to the buffer.
-    //
-    // If the statistics buffer is not supplied or if the maximum count is
-    // zero, the routine returns the proposed count of statistics instead.
-    //
-
-    if (statistics == 0)
-        return kStatisticsCount;
-
-    UInt32 statisticsCount = min(kStatisticsCount, statisticsMaxCount);
-
-    for (unsigned index = 0; index < statisticsCount; index++)
-        statistics[index] = _statistics[index]->unsigned64BitValue();
-
-    return statisticsCount;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-UInt64 IOBlockStorageDriver::getStatistic(Statistics statistic) const
-{
-    //
-    // Ask the driver to report one of its operating statistics.
-    //
-
-    if ((UInt32) statistic >= kStatisticsCount)  return 0;
-
-    return _statistics[statistic]->unsigned64BitValue();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-IOBlockStorageDriver::Context * IOBlockStorageDriver::allocateContext()
-{
-    //
-    // Allocate a context structure for a read/write operation.
-    //
-
-    Context * context = IONew(Context, 1);
-
-    if (context)
-    {
-        bzero(context, sizeof(Context));
-    }
-
-    return context;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::deleteContext(
-                                        IOBlockStorageDriver::Context * context)
-{
-    //
-    // Delete a context structure from a read/write operation.
-    //
-
-    IODelete(context, Context, 1);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::prepareRequest(UInt64               byteStart,
-                                          IOMemoryDescriptor * buffer,
-                                          IOStorageCompletion  completion)
-{
-    //
-    // The prepareRequest method allocates and prepares state for the transfer.
-    //
-    // This method is part of a sequence of methods invoked for each read/write
-    // request.  The first is prepareRequest, which allocates and prepares some
-    // context for the transfer; the second is deblockRequest, which aligns the
-    // transfer at the media block boundaries; and the third is executeRequest,
-    // which implements the actual transfer from the block storage device.
-    //
-
-    Context * context;
-    IOReturn  status;
-
-    // Allocate a context structure to hold some of our state.
-
-    context = allocateContext();
-
-    if (context == 0)
-    {
-        complete(completion, kIOReturnNoMemory);
-        return;
-    }
-    
-    // Prepare the transfer buffer.
-
-    status = buffer->prepare();
-
-    if (status != kIOReturnSuccess)
-    {
-        deleteContext(context);
-        complete(completion, status);
-        return;
-    }
-
-    // Fill in the context structure with some of our state.
-
-    context->block.size = getMediaBlockSize();
-    context->block.type = kBlockTypeStandard;
-
-    context->original.byteStart  = byteStart;
-    context->original.buffer     = buffer;
-    context->original.buffer->retain();
-    context->original.completion = completion;
-
-    completion.target    = this;
-    completion.action    = prepareRequestCompletion;
-    completion.parameter = context;
-
-    // Deblock the transfer.
-
-    deblockRequest(byteStart, buffer, completion, context);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::prepareRequestCompletion(void *   target,
-                                                    void *   parameter,
-                                                    IOReturn status,
-                                                    UInt64   actualByteCount)
-{
-    //
-    // This is the completion routine for the prepared request.  It updates
-    // the driver's statistics, performs some clean up work, then calls the
-    // original request's completion routine.
-    //
-
-    Context *              context = (Context              *) parameter;
-    IOBlockStorageDriver * driver  = (IOBlockStorageDriver *) target;
-    bool                   isWrite;
-    
-    isWrite = (context->original.buffer->getDirection() == kIODirectionOut);
-
-    // State our assumptions.
-
-    assert(status                                != kIOReturnSuccess ||
-           context->original.buffer->getLength() == actualByteCount);
-
-    // Update the total number of bytes transferred.
-
-    driver->addToBytesTransferred(actualByteCount, 0, 0, isWrite);
-
-    // Update the total error count.
-
-    if (status != kIOReturnSuccess)
-    {
-        driver->incrementErrors(isWrite);
-    }
-
-    // Complete the transfer buffer.
-
-    context->original.buffer->complete();
-
-    // Complete the transfer request.
-
-    IOStorage::complete(context->original.completion, status, actualByteCount);
-
-    // Release our resources.
-
-    context->original.buffer->release();
-
-    driver->deleteContext(context);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::schedulePoller()
-{
-    //
-    // Schedule the poller mechanism.
-    //
-    // This method assumes that the arbitration lock is held.
-    //
-
-    AbsoluteTime deadline;
-
-    retain();
-
-    clock_interval_to_deadline(kPollerInterval, kMillisecondScale, &deadline);
-    thread_call_enter_delayed(_pollerCall, deadline);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::unschedulePoller()
-{
-    //
-    // Unschedule the poller mechanism.
-    //
-    // This method assumes that the arbitration lock is held.
-    //
-
-    if (thread_call_cancel(_pollerCall))  release();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::poller(void * target, void *)
-{
-    //
-    // This method is the timeout handler for the poller mechanism.  It polls
-    // for media and reschedules another timeout if there are still no opens.
-    //
-
-    IOBlockStorageDriver * driver = (IOBlockStorageDriver *) target;
-
-    driver->pollMedia();
-
-    driver->lockForArbitration();    // (disable opens/closes; a recursive lock)
-
-    if (!driver->isOpen() && !driver->isInactive())
-        driver->schedulePoller();    // (schedule the poller, increments retain)
-
-    driver->unlockForArbitration();   // (enable opens/closes; a recursive lock)
-
-    driver->release();            // (drop the retain associated with this poll)
-}
-
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-IOReturn IOBlockStorageDriver::message(UInt32      type,
-                                       IOService * provider,
-                                       void *      argument)
-{
-    //
-    // Generic entry point for calls from the provider.  A return value of
-    // kIOReturnSuccess indicates that the message was received, and where
-    // applicable, that it was successful.
-    //
-
-    switch (type)
-    {
-        case kIOMessageMediaStateHasChanged:
-        {
-            IOReturn status;
-            IOLockLock(_mediaStateLock);    
-            status = mediaStateHasChanged((IOMediaState) argument);
-            IOLockUnlock(_mediaStateLock);    
-            return status;
-        }
-        case kIOMessageServiceIsRequestingClose:
-        {
-            bool success;
-            success = yield(provider, 0, argument);
-            return success ? kIOReturnSuccess : kIOReturnBusy;
-        }
-        case kIOMessageServiceIsTerminated:
-        {
-            bool success;
-            success = yield(provider, kIOServiceRequired, argument);
-            return success ? kIOReturnSuccess : kIOReturnError;
-        }
-        default:
-        {
-            return super::message(type, provider, argument);
-        }
-    }
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-/* Accept a new piece of media, doing whatever's necessary to make it
- * show up properly to the system. The arbitration lock is assumed to
- * be held during the call.
- */
-IOReturn
-IOBlockStorageDriver::acceptNewMedia(void)
-{
-    IOReturn result;
-    bool ok;
-    UInt64 nbytes;
-    char name[128];
-    bool nameSep;
-
-    /* Since the kernel printf doesn't handle 64-bit integers, we
-     * simply make an assumption that the block count and size
-     * will be 32-bit values max.
-     */
-
-#ifdef moreDebug
-    IOLog("%s[IOBlockStorageDriver]::%s media: %ld blocks, %ld bytes each, write-%s.\n",
-            getName(),
-            getDeviceTypeName(),
-            (UInt32)_maxBlockNumber + 1,(UInt32)getMediaBlockSize(),
-            (_writeProtected ? "protected" : "enabled"));
-#endif
-
-    if (_maxBlockNumber) {
-        nbytes = _mediaBlockSize * (_maxBlockNumber + 1);  
-    } else {
-        nbytes = 0;
-    }
-
-    /* Instantiate a media object and attach it to ourselves. */
-
-    name[0] = 0;
-    nameSep = false;
-    if (getProvider()->getVendorString()) {
-        strcat(name, getProvider()->getVendorString());
-        nameSep = true;
-    }
-    if (getProvider()->getProductString()) {
-        if (nameSep == true)  strcat(name, " ");
-        strcat(name, getProvider()->getProductString());
-        nameSep = true;
-    }
-    if (nameSep == true)  strcat(name, " ");
-    strcat(name, "Media");
-
-    _mediaObject = instantiateMediaObject(0,nbytes,_mediaBlockSize,name);
-    result = (_mediaObject) ? kIOReturnSuccess : kIOReturnBadArgument;
-    
-    if (result == kIOReturnSuccess) {
-        ok = _mediaObject->attach(this);                       /* attach media object above us */
-        if (ok) {
-            _mediaPresent = true;
-            _mediaObject->registerService();           /* enable matching */
-        } else {
-            _mediaObject->release();
-            _mediaObject = 0;
-            return(kIOReturnNoMemory); /* give up now */
-        }
-    }
-    
-    return(result);
-}
-
-IOReturn
-IOBlockStorageDriver::checkForMedia(void)
-{
-    IOReturn result;
-    bool currentState;
-    bool changed;
-    
-    IOLockLock(_mediaStateLock);    
-
-    result = getProvider()->reportMediaState(&currentState,&changed);
-    if (result != kIOReturnSuccess) {          /* the poll operation failed */
-        IOLog("%s[IOBlockStorageDriver]::checkForMedia; err '%s' from reportMediaState\n",
-              getName(),stringFromReturn(result));
-    } else if (changed) {      /* the poll succeeded, media state has changed */
-        result = mediaStateHasChanged(currentState ? kIOMediaStateOnline
-                                                   : kIOMediaStateOffline);
-    }
-
-    IOLockUnlock(_mediaStateLock);
-    return(result);
-}
-
-IOReturn
-IOBlockStorageDriver::mediaStateHasChanged(IOMediaState state)
-{
-    IOReturn result;
-
-    /* The media has changed state. See if it's just inserted or removed. */
-
-    if (state == kIOMediaStateOnline) {                /* media is now present */
-
-        /* Allow a subclass to decide whether we accept the media. Such a
-         * decision might be based on things like password-protection, etc.
-         */
-
-        if (validateNewMedia() == false) {     /* we're told to reject it */
-            rejectMedia();                     /* so let subclass do whatever it wants */
-            return(kIOReturnSuccess);          /* pretend nothing happened */
-        }
-
-        result = recordMediaParameters();      /* learn about media */
-        if (result != kIOReturnSuccess) {      /* couldn't record params */
-            initMediaState();          /* deny existence of new media */
-           IOLog("%s[IOBlockStorageDriver]::checkForMedia: err '%s' from recordMediaParameters\n",
-                       getName(),stringFromReturn(result));
-            return(result);
-        }
-
-        /* Now we do what's necessary to make the new media
-         * show up properly in the system.
-         */
-
-        lockForArbitration();    
-        result = acceptNewMedia();
-
-        if (result != kIOReturnSuccess) {
-            initMediaState();          /* deny existence of new media */
-           IOLog("%s[IOBlockStorageDriver]::checkForMedia; err '%s' from acceptNewMedia\n",
-            getName(),stringFromReturn(result));
-        }
-
-        unlockForArbitration();    
-        return(result);                /* all done, new media is ready */
-
-    } else {                           /* media is now absent */
-
-        lockForArbitration();
-        result = decommissionMedia(true);      /* force a teardown */
-        unlockForArbitration();
-
-        if (result != kIOReturnSuccess && result != kIOReturnNoMedia) {
-           IOLog("%s[IOBlockStorageDriver]::checkForMedia; err '%s' from decommissionNewMedia\n",
-                       getName(),stringFromReturn(result));
-            return(result);
-        }
-
-        return(kIOReturnSuccess);              /* all done; media is gone */
-    }
-}
-
-UInt64
-IOBlockStorageDriver::constrainByteCount(UInt64 /* requestedCount */ ,bool isWrite)
-{
-    if (isWrite) {
-        return(_maxWriteByteTransfer);
-    } else {
-        return(_maxReadByteTransfer);
-    }
-}
-
-/* Decommission a piece of media that has become unavailable either due to
- * ejection or some outside force (e.g. the Giant Hand of the User).
- * (I prefer the term "decommission" rather than "abandon." The former implies
- * a well-determined procedure, whereas the latter implies leaving the media
- * in an orphaned state.)
- */
-/* Tear down the stack above the specified object. Usually these objects will
- * be of type IOMedia, but they could be any IOService. The arbitration lock is
- * assumed to be held during the call.
- */
-IOReturn
-IOBlockStorageDriver::decommissionMedia(bool forcible)
-{
-    IOReturn result;
-
-    if (_mediaObject) {
-        /* If this is a forcible decommission (i.e. media is gone), we don't
-         * care whether the teardown worked; we forget about the media.
-         */
-        if (_mediaObject->terminate(forcible ? kIOServiceRequired : 0) || forcible) {
-            _mediaObject->release();
-            _mediaObject = 0;
-
-            initMediaState();        /* clear all knowledge of the media */
-            result = kIOReturnSuccess;
-
-        } else {
-            result = kIOReturnBusy;
-        }
-    } else {
-        result = kIOReturnNoMedia;
-    }
-
-    return(result);
-}
-
-IOReturn
-IOBlockStorageDriver::ejectMedia(void)
-{
-    IOReturn result;
-
-    if (_removable) {
-        
-        IOLockLock(_mediaStateLock);
-
-        lockForArbitration();
-        result = decommissionMedia(false);     /* try to teardown */
-        unlockForArbitration();
-
-        if (result == kIOReturnSuccess) {      /* eject */
-            if (lockMedia(false) != kIOReturnSuccess)
-                IOLog("%s: Unable to unlock removable media.\n", getName());
-
-            (void)getProvider()->doEjectMedia();       /* ignore any error */
-        }
-
-        IOLockUnlock(_mediaStateLock);
-
-        return(result);
-            
-    } else {
-        return(kIOReturnUnsupported);        
-    }
-}
-
-void
-IOBlockStorageDriver::executeRequest(UInt64                          byteStart,
-                                     IOMemoryDescriptor *            buffer,
-                                     IOStorageCompletion             completion,
-                                     IOBlockStorageDriver::Context * context)
-{
-    UInt32 block;
-    UInt32 nblks;
-    IOReturn result;
-
-    if (!_mediaPresent) {              /* no media? you lose */
-        complete(completion, kIOReturnNoMedia,0);
-        return;
-    }
-
-    /* We know that we are never called with a request too large,
-     * nor one that is misaligned with a block.
-     */
-    assert((byteStart           % _mediaBlockSize) == 0);
-    assert((buffer->getLength() % _mediaBlockSize) == 0);
-    
-    block = byteStart           / _mediaBlockSize;
-    nblks = buffer->getLength() / _mediaBlockSize;
-
-/* Now the protocol-specific provider implements the actual
-     * start of the data transfer: */
-
-    // Tickle the root power domain to reset the sleep countdown.
-    if (gIORootPowerDomain) {
-        gIORootPowerDomain->activityTickle(kIOPMSubclassPolicy);
-    }
-
-    result = getProvider()->doAsyncReadWrite(buffer,block,nblks,completion);
-    
-    if (result != kIOReturnSuccess) {          /* it failed to start */
-        IOLog("%s[IOBlockStorageDriver]; executeRequest: request failed to start!\n",getName());
-        complete(completion,result);
-        return;
-    }
-}
-
-IOReturn
-IOBlockStorageDriver::formatMedia(UInt64 byteCapacity)
-{
-    if (!_mediaPresent) {
-        return(kIOReturnNoMedia);
-    }
-
-    return(getProvider()->doFormatMedia(byteCapacity));
-}
-
-const char *
-IOBlockStorageDriver::getDeviceTypeName(void)
-{
-    return(kIOBlockStorageDeviceTypeGeneric);
-}
-
-UInt32
-IOBlockStorageDriver::getFormatCapacities(UInt64 * capacities,
-                                            UInt32   capacitiesMaxCount) const
-{
-    return(getProvider()->doGetFormatCapacities(capacities,capacitiesMaxCount));
-}
-
-UInt64
-IOBlockStorageDriver::getMediaBlockSize() const
-{
-    return(_mediaBlockSize);
-}
-
-IOMediaState
-IOBlockStorageDriver::getMediaState() const
-{
-    if (_mediaPresent) {
-        return(kIOMediaStateOnline);
-    } else {
-        return(kIOMediaStateOffline);
-    }
-}
-
-bool
-IOBlockStorageDriver::handleStart(IOService * provider)
-{
-    IOReturn result;
-
-    /* Print device name/type information on the console: */
-    
-    /*The protocol-specific provider determines whether the media is removable. */
-
-    result = getProvider()->reportRemovability(&_removable);
-    if (result != kIOReturnSuccess) {
-       IOLog("%s[IOBlockStorageDriver]::handleStart; err '%s' from reportRemovability\n",
-                       getName(),stringFromReturn(result));
-        return(false);
-    }
-
-    if (_removable) {
-
-        /* The protocol-specific provider determines whether we must poll to detect
-         * media insertion. Nonremovable devices never need polling.
-         */
-        
-        result = getProvider()->reportPollRequirements(&_pollIsRequired,&_pollIsExpensive);
-
-            if (result != kIOReturnSuccess) {
-           IOLog("%s[IOBlockStorageDriver]::handleStart; err '%s' from reportPollRequirements\n",
-                       getName(),stringFromReturn(result));
-            return(false);
-        }
-        
-        /* The protocol-specific provider determines whether the media is ejectable
-         * under software control.
-         */
-        result = getProvider()->reportEjectability(&_ejectable);
-        if (result != kIOReturnSuccess) {
-           IOLog("%s[IOBlockStorageDriver]::handleStart; err '%s' from reportEjectability\n",
-                       getName(),stringFromReturn(result));
-            return(false);
-        }
-
-        /* The protocol-specific provider determines whether the media is lockable
-         * under software control.
-         */
-        result = getProvider()->reportLockability(&_lockable);
-        if (result != kIOReturnSuccess) {
-           IOLog("%s[IOBlockStorageDriver]::handleStart; err '%s' from reportLockability\n",
-                       getName(),stringFromReturn(result));
-            return(false);
-        }
-
-    } else {           /* fixed disk: not ejectable, not lockable */
-        _ejectable     = false;
-        _lockable      = false;
-        _pollIsRequired        = true;         /* polling detects device disappearance */
-    }
-    
-    /* Check for the device being ready with media inserted: */
-
-    result = checkForMedia();
-
-    /* The poll should never fail for nonremovable media: */
-    
-    if (result != kIOReturnSuccess && !_removable) {
-       IOLog("%s[IOBlockStorageDriver]::handleStart: err '%s' from checkForMedia\n",
-                       getName(),stringFromReturn(result));
-        return(false);
-    }
-
-    return(true);
-}
-
-/* The driver has been instructed to yield. The arbitration lock is assumed to
- * be held during the call.
- */
-bool
-IOBlockStorageDriver::handleYield(IOService *  provider,
-                                  IOOptionBits options,
-                                  void *       argument)
-{
-    // Determine whether we can yield (for non-required yield requests).
-
-    if ( (options & kIOServiceRequired) == 0 && isOpen() != false )
-    {
-        return false;
-    }
-
-    // Halt the poller mechanism.
-
-    if ( isMediaEjectable()     != false &&
-         isMediaPollRequired()  != false &&
-         isMediaPollExpensive() == false )
-    {
-        unschedulePoller();                           // (unschedule the poller)
-    }
-
-    // Force a teardown.
-
-    decommissionMedia(true);
-
-    return true;
-}
-
-void
-IOBlockStorageDriver::initMediaState(void)
-{
-    _mediaPresent      = false;
-    _writeProtected            = false;
-}
-
-IOMedia *
-IOBlockStorageDriver::instantiateDesiredMediaObject(void)
-{
-    return(new IOMedia);
-}
-
-IOMedia *
-IOBlockStorageDriver::instantiateMediaObject(UInt64 base,UInt64 byteSize,
-                                        UInt32 blockSize,char *mediaName)
-{
-    IOMedia *m;
-    bool result;
-
-    m = instantiateDesiredMediaObject();
-    if (m == NULL) {
-        return(NULL);
-    }
-
-    result = m->init(   base,                  /* base byte offset */
-                        byteSize,              /* byte size */
-                        blockSize,             /* preferred block size */
-                       _ejectable,             /* TRUE if ejectable */
-                        true,                  /* TRUE if whole physical media */
-                        !_writeProtected,      /* TRUE if writable */
-                       "");                    /* content hint */
-
-    if (result) {
-        m->setName(mediaName);
-        return(m);
-        
-    } else {                                   /* some init error */
-        m->release();
-        return(NULL);          /* beats me...call it this error */
-    }
-}
-
-bool
-IOBlockStorageDriver::isMediaEjectable(void) const
-{
-    return(_ejectable);
-}
-
-bool
-IOBlockStorageDriver::isMediaPollExpensive(void) const
-{
-    return(_pollIsExpensive);
-}
-
-bool
-IOBlockStorageDriver::isMediaPollRequired(void) const
-{
-    return(_pollIsRequired);
-}
-
-bool
-IOBlockStorageDriver::isMediaWritable(void) const
-{
-    return(!_writeProtected);
-}
-
-IOReturn
-IOBlockStorageDriver::lockMedia(bool locked)
-{
-    if (_lockable) {
-        return(getProvider()->doLockUnlockMedia(locked));
-    } else {
-        return(kIOReturnUnsupported);        
-    }
-}
-
-IOReturn
-IOBlockStorageDriver::pollMedia(void)
-{
-    if (!_pollIsRequired) {                    /* shouldn't poll; it's an error */
-        
-        return(kIOReturnUnsupported);
-        
-    } else {                                   /* poll is required...do it */
-
-        return(checkForMedia());
-        
-    }
-}
-
-IOReturn
-IOBlockStorageDriver::recordMediaParameters(void)
-{
-    IOReturn result;
-
-    /* Determine the device's block size and max block number.
-     * What should an unformatted device report? All zeroes, or an error?
-     */
-
-    result = getProvider()->reportBlockSize(&_mediaBlockSize);    
-    if (result != kIOReturnSuccess) {
-        goto err;
-    }
-
-    result = getProvider()->reportMaxValidBlock(&_maxBlockNumber);    
-    if (result != kIOReturnSuccess) {
-        goto err;
-    }
-
-    /* Calculate the maximum allowed byte transfers for reads and writes. */
-
-    result = getProvider()->reportMaxReadTransfer(_mediaBlockSize,&_maxReadByteTransfer);
-    if (result != kIOReturnSuccess) {
-        goto err;
-    }
-
-    result = getProvider()->reportMaxWriteTransfer(_mediaBlockSize,&_maxWriteByteTransfer);
-    if (result != kIOReturnSuccess) {
-        goto err;
-    }
-
-    /* Is the media write-protected? */
-
-    result = getProvider()->reportWriteProtection(&_writeProtected);
-    if (result != kIOReturnSuccess) {
-        goto err;
-    }
-
-    return(kIOReturnSuccess);          /* everything was successful */
-
-    /* If we fall thru to here, we had some kind of error. Set everything to
-     * a reasonable state since we haven't got any real information.
-     */
-
-err:
-    _mediaPresent = false;
-    _writeProtected = true;
-
-    return(result);
-}
-
-void
-IOBlockStorageDriver::rejectMedia(void)
-{
-    (void)getProvider()->doEjectMedia();       /* eject it, ignoring any error */
-    initMediaState();                  /* deny existence of new media */
-}
-
-IOReturn
-IOBlockStorageDriver::synchronizeCache(IOService *client)
-{
-    return(getProvider()->doSynchronizeCache());
-}
-
-bool
-IOBlockStorageDriver::validateNewMedia(void)
-{
-    return(true);
-}
-
-// -----------------------------------------------------------------------------
-// Deblocker Implementation
-
-#include <IOKit/IOBufferMemoryDescriptor.h>
-
-class IODeblocker : public IOMemoryDescriptor
-{
-    OSDeclareDefaultStructors(IODeblocker);
-
-protected:
-
-    UInt64                     _blockSize;
-
-    struct
-    {
-        IOMemoryDescriptor * buffer;
-        UInt32               offset;
-        UInt32               length;
-    }                          _chunks[3];
-    UInt32                     _chunksCount;
-
-    IOBufferMemoryDescriptor * _excessBuffer;
-    UInt64                     _excessCountFinal;
-    UInt64                     _excessCountStart;
-
-    IOMemoryDescriptor *       _requestBuffer;
-    IOStorageCompletion        _requestCompletion;
-    void *                     _requestContext;
-    UInt64                     _requestCount;
-    bool                       _requestIsOneBlock;
-    UInt64                     _requestStart;
-
-    enum
-    {
-        kStageInit,
-        kStagePrepareExcessStart,
-        kStagePrepareExcessFinal,
-        kStageLast,
-        kStageDone
-    } _stage;
-
-    virtual void free();
-
-    virtual bool initWithAddress( void *      address,       /* not supported */
-                                  IOByteCount withLength,
-                                  IODirection withDirection );
-
-    virtual bool initWithAddress( vm_address_t address,      /* not supported */
-                                  IOByteCount  withLength,
-                                  IODirection  withDirection,
-                                  task_t       withTask );
-
-    virtual bool initWithPhysicalAddress( 
-                                  IOPhysicalAddress address, /* not supported */
-                                  IOByteCount       withLength,
-                                  IODirection       withDirection );
-
-    virtual bool initWithPhysicalRanges( 
-                                  IOPhysicalRange * ranges,  /* not supproted */
-                                  UInt32            withCount,
-                                  IODirection       withDirection,
-                                  bool              asReference = false );
-
-    virtual bool initWithRanges(  IOVirtualRange * ranges,   /* not supported */
-                                  UInt32           withCount,
-                                  IODirection      withDirection,
-                                  task_t           withTask,
-                                  bool             asReference = false );
-
-    virtual void * getVirtualSegment( IOByteCount   offset,  /* not supported */
-                                      IOByteCount * length );
-
-    IOMemoryDescriptor::withAddress;                         /* not supported */
-    IOMemoryDescriptor::withPhysicalAddress;                 /* not supported */
-    IOMemoryDescriptor::withPhysicalRanges;                  /* not supported */
-    IOMemoryDescriptor::withRanges;                          /* not supported */
-    IOMemoryDescriptor::withSubRange;                        /* not supported */
-
-public:
-
-    static IODeblocker * withBlockSize(
-                                  UInt64               blockSize,
-                                  UInt64               withRequestStart,
-                                  IOMemoryDescriptor * withRequestBuffer,
-                                  IOStorageCompletion  withRequestCompletion,
-                                  void *               withRequestContext );
-
-    virtual bool initWithBlockSize(
-                                  UInt64               blockSize,
-                                  UInt64               withRequestStart,
-                                  IOMemoryDescriptor * withRequestBuffer,
-                                  IOStorageCompletion  withRequestCompletion,
-                                  void *               withRequestContext );
-
-    virtual IOPhysicalAddress getPhysicalSegment( IOByteCount   offset,
-                                                  IOByteCount * length );
-
-    virtual IOReturn prepare(IODirection forDirection = kIODirectionNone);
-
-    virtual IOReturn complete(IODirection forDirection = kIODirectionNone);
-
-    virtual IOByteCount readBytes( IOByteCount offset,
-                                   void *      bytes,
-                                   IOByteCount withLength );
-
-    virtual IOByteCount writeBytes( IOByteCount  offset,
-                                    const void * bytes,
-                                    IOByteCount  withLength );
-
-    virtual bool getNextStage(UInt64 * byteStart);
-
-    virtual void getRequestCompletion( IOStorageCompletion * completion,
-                                       IOReturn *            status,
-                                       UInt64 *              actualByteCount );
-
-    virtual IOMemoryDescriptor * getRequestBuffer();
-
-    virtual void * getRequestContext();
-};
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-#undef  super
-#define super IOMemoryDescriptor
-OSDefineMetaClassAndStructors(IODeblocker, IOMemoryDescriptor)
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IODeblocker::initWithAddress( void *      /* address       */ ,
-                                   IOByteCount /* withLength    */ ,
-                                   IODirection /* withDirection */ )
-{
-    return false;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IODeblocker::initWithAddress( vm_address_t /* address       */ ,
-                                   IOByteCount  /* withLength    */ ,
-                                   IODirection  /* withDirection */ ,
-                                   task_t       /* withTask      */ )
-{
-    return false;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IODeblocker::initWithPhysicalAddress(
-                                   IOPhysicalAddress /* address       */ ,
-                                   IOByteCount       /* withLength    */ ,
-                                   IODirection       /* withDirection */ )
-{
-    return false;
-}
-
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IODeblocker::initWithPhysicalRanges(
-                                   IOPhysicalRange * /* ranges        */ ,
-                                   UInt32            /* withCount     */ ,
-                                   IODirection       /* withDirection */ ,
-                                   bool              /* asReference   */ )
-{
-    return false;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IODeblocker::initWithRanges( IOVirtualRange * /* ranges        */ ,
-                                  UInt32           /* withCount     */ ,
-                                  IODirection      /* withDirection */ ,
-                                  task_t           /* withTask      */ ,
-                                  bool             /* asReference   */ )
-{
-    return false;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-IODeblocker * IODeblocker::withBlockSize(
-                                  UInt64               blockSize,
-                                  UInt64               withRequestStart,
-                                  IOMemoryDescriptor * withRequestBuffer,
-                                  IOStorageCompletion  withRequestCompletion,
-                                  void *               withRequestContext )
-{
-    //
-    // Create a new IODeblocker.
-    //
-
-    IODeblocker * me = new IODeblocker;
-    
-    if ( me && me->initWithBlockSize(
-                /* blockSize               */ blockSize,
-                /* withRequestStart        */ withRequestStart,
-                /* withRequestBuffer       */ withRequestBuffer,
-                /* withRequestCompletion   */ withRequestCompletion,
-                /* withRequestContext      */ withRequestContext ) == false )
-    {
-           me->release();
-           me = 0;
-    }
-
-    return me;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IODeblocker::initWithBlockSize(
-                                  UInt64               blockSize,
-                                  UInt64               withRequestStart,
-                                  IOMemoryDescriptor * withRequestBuffer,
-                                  IOStorageCompletion  withRequestCompletion,
-                                  void *               withRequestContext )
-{
-    //
-    // Initialize an IODeblocker.
-    //
-    // _excessCountStart = byte count from media boundary to start of request
-    // _excessCountFinal = byte count from end of request to a media boundary
-    //
-
-    UInt32 excessBufferSize = 0;
-
-    // Ask our superclass' opinion.
-
-    if ( super::init() == false )  return false;
-
-    // Initialize our minimal state.
-
-    _blockSize         = blockSize;
-    _chunksCount       = 0;
-    _direction         = kIODirectionNone;
-    _length            = 0;
-
-    _requestBuffer     = withRequestBuffer;
-    _requestBuffer->retain();
-    _requestCompletion = withRequestCompletion;
-    _requestContext    = withRequestContext;
-    _requestCount      = withRequestBuffer->getLength();
-    _requestStart      = withRequestStart;
-
-    _excessCountStart  = (withRequestStart                ) % blockSize;
-    _excessCountFinal  = (withRequestStart + _requestCount) % blockSize;
-    if ( _excessCountFinal )  _excessCountFinal = blockSize - _excessCountFinal;
-
-    _requestIsOneBlock = (_excessCountStart + _requestCount <= blockSize);
-
-    // Determine the necessary size for our scratch buffer.
-
-    switch ( _requestBuffer->getDirection() )
-    {
-        case kIODirectionIn:                                           // (read)
-        {
-            excessBufferSize = max(_excessCountStart, _excessCountFinal);
-        } break;
-
-        case kIODirectionOut:                                         // (write)
-        {
-            if ( _excessCountStart )  excessBufferSize += blockSize;
-            if ( _excessCountFinal )  excessBufferSize += blockSize;
-
-            // If there is excess both ends of the original request, but both
-            // ends reside within the same media block, then we could shorten
-            // our buffer size to just one block.
-
-            if ( _excessCountStart && _excessCountFinal && _requestIsOneBlock )
-            {
-                excessBufferSize -= blockSize;
-            }
-        } break;
-
-        default:
-        {
-            assert(0);
-        } break;
-    }
-
-    // Allocate our scratch buffer.
-
-    if ( excessBufferSize )
-    {
-        _excessBuffer = IOBufferMemoryDescriptor::withCapacity(
-                                         /* capacity      */ excessBufferSize,
-                                         /* withDirection */ kIODirectionNone );
-        if ( _excessBuffer == 0 )  return false;
-    }
-
-    return true;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IODeblocker::free()
-{
-    //
-    // Free all of this object's outstanding resources.
-    //
-
-    if ( _requestBuffer )  _requestBuffer->release();
-    if ( _excessBuffer )  _excessBuffer->release();
-
-    super::free();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-IOReturn IODeblocker::prepare(IODirection forDirection)
-{
-    //
-    // Prepare the memory for an I/O transfer.
-    //
-    // This involves paging in the memory and wiring it down for the duration
-    // of the transfer.  The complete() method finishes the processing of the
-    // memory after the I/O transfer finishes.
-    //
-
-    unsigned index;
-    IOReturn status = kIOReturnInternalError;
-    IOReturn statusUndo;
-
-    if ( forDirection == kIODirectionNone )
-    {
-        forDirection = _direction;
-    }
-
-    for ( index = 0; index < _chunksCount; index++ ) 
-    {
-        status = _chunks[index].buffer->prepare(forDirection);
-        if ( status != kIOReturnSuccess )  break;
-    }
-
-    if ( status != kIOReturnSuccess )
-    {
-        for ( unsigned indexUndo = 0; indexUndo <= index; indexUndo++ )
-        {
-            statusUndo = _chunks[index].buffer->complete(forDirection);
-            assert(statusUndo == kIOReturnSuccess);
-        }
-    }
-
-    return status;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-IOReturn IODeblocker::complete(IODirection forDirection)
-{
-    //
-    // Complete processing of the memory after an I/O transfer finishes.
-    //
-    // This method shouldn't be called unless a prepare() was previously issued;
-    // the prepare() and complete() must occur in pairs, before and after an I/O
-    // transfer.
-    //
-
-    IOReturn status;
-    IOReturn statusFinal = kIOReturnSuccess;
-
-    if ( forDirection == kIODirectionNone )
-    {
-        forDirection = _direction;
-    }
-
-    for ( unsigned index = 0; index < _chunksCount; index++ ) 
-    {
-        status = _chunks[index].buffer->complete(forDirection);
-        if ( status != kIOReturnSuccess )  statusFinal = status;
-        assert(status == kIOReturnSuccess);
-    }
-
-    return statusFinal;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-IOPhysicalAddress IODeblocker::getPhysicalSegment( IOByteCount   offset,
-                                                   IOByteCount * length )
-{
-    //
-    // This method returns the physical address of the byte at the given offset
-    // into the memory,  and optionally the length of the physically contiguous
-    // segment from that offset.
-    //
-
-    assert(offset <= _length);
-
-    for ( unsigned index = 0; index < _chunksCount; index++ ) 
-    {
-        if ( offset < _chunks[index].length )
-        {
-            IOPhysicalAddress address;
-            address = _chunks[index].buffer->getPhysicalSegment(
-                                    /* offset */ offset + _chunks[index].offset,
-                                    /* length */ length );
-            if ( length )  *length = min(*length, _chunks[index].length);
-            return address;
-        }
-        offset -= _chunks[index].length;
-    }
-
-    if ( length )  *length = 0;
-
-    return 0;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void * IODeblocker::getVirtualSegment( IOByteCount   /* offset */ ,
-                                       IOByteCount * /* length */ )
-{
-    return 0;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-IOByteCount IODeblocker::readBytes( IOByteCount offset,
-                                    void *      bytes,
-                                    IOByteCount withLength )
-{
-    //
-    // Copies data from the memory descriptor's buffer at the given offset, to
-    // the specified buffer.  Returns the number of bytes copied.
-    //
-
-    IOByteCount bytesCopied = 0;
-    unsigned    index;
-
-    for ( index = 0; index < _chunksCount; index++ ) 
-    {
-        if ( offset < _chunks[index].length )  break;
-        offset -= _chunks[index].length;
-    }
-
-    for ( ; index < _chunksCount && withLength; index++)
-    {
-        IOByteCount copy   = min(_chunks[index].length - offset, withLength);
-        IOByteCount copied = _chunks[index].buffer->readBytes(
-                                    /* offset */ offset + _chunks[index].offset,
-                                    /* bytes  */ bytes,
-                                    /* length */ copy );
-
-        bytesCopied += copied;
-        if ( copied != copy )  break;
-
-        bytes = ((UInt8 *) bytes) + copied;
-        withLength -= copied;
-        offset = 0;
-    }
-
-    return bytesCopied;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-IOByteCount IODeblocker::writeBytes( IOByteCount  offset,
-                                     const void * bytes,
-                                     IOByteCount  withLength )
-{
-    //
-    // Copies data to the memory descriptor's buffer at the given offset, from
-    // the specified buffer.  Returns the number of bytes copied.
-    //
-
-    IOByteCount bytesCopied = 0;
-    unsigned    index;
-
-    for ( index = 0; index < _chunksCount; index++ ) 
-    {
-        if ( offset < _chunks[index].length )  break;
-        offset -= _chunks[index].length;
-    }
-
-    for ( ; index < _chunksCount && withLength; index++)
-    {
-        IOByteCount copy   = min(_chunks[index].length - offset, withLength);
-        IOByteCount copied = _chunks[index].buffer->writeBytes(
-                                    /* offset */ offset + _chunks[index].offset,
-                                    /* bytes  */ bytes,
-                                    /* length */ copy );
-
-        bytesCopied += copied;
-        if ( copied != copy )  break;
-
-        bytes = ((UInt8 *) bytes) + copied;
-        withLength -= copied;
-        offset = 0;
-    }
-
-    return bytesCopied;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool IODeblocker::getNextStage(UInt64 * byteStart)
-{
-    //
-    // Obtain the next stage of the transfer.   The transfer buffer will be the
-    // deblocker object itself and the byte start will be returned in byteStart.
-    //
-    // This method must not be called if the current stage failed with an error
-    // or a short byte count, but instead getRequestCompletion() must be called
-    // to adjust the status and actual byte count (with respect to the original
-    // request) and return the original request's completion routine.  The same
-    // call to getRequestCompletion() should also be done if the getNextStage()
-    // method returns false.
-    //
-
-    _chunksCount = 0;
-    _direction   = kIODirectionNone;
-    _length      = 0;
-
-    switch ( _requestBuffer->getDirection() )
-    {
-        case kIODirectionIn:                                           // (read)
-        {
-            switch ( _stage )
-            {
-                case kStageInit:
-                {
-                    _stage     = kStageLast;
-                    _excessBuffer->setDirection(kIODirectionIn);
-                    _direction = kIODirectionIn;
-                    *byteStart = _requestStart - _excessCountStart;
-
-                    if ( _excessCountStart )
-                    {
-                        _chunks[_chunksCount].buffer = _excessBuffer;
-                        _chunks[_chunksCount].offset = 0;
-                        _chunks[_chunksCount].length = _excessCountStart;
-                        _chunksCount++;
-                    }
-
-                    _chunks[_chunksCount].buffer = _requestBuffer;
-                    _chunks[_chunksCount].offset = 0;
-                    _chunks[_chunksCount].length = _requestBuffer->getLength();
-                    _chunksCount++;
-
-                    if ( _excessCountFinal )
-                    {
-                        _chunks[_chunksCount].buffer = _excessBuffer;
-                        _chunks[_chunksCount].offset = 0;
-                        _chunks[_chunksCount].length = _excessCountFinal;
-                        _chunksCount++;
-                    }
-                } break;
-
-                case kStageLast:
-                {
-                    _stage = kStageDone;
-                } break;
-
-                default:
-                {
-                    assert(0);
-                } break;
-            } // (switch)
-        } break;
-
-        case kIODirectionOut:                                         // (write)
-        {
-            switch ( _stage )
-            {
-                case kStageInit:
-                {
-                    if ( _excessCountStart )
-                    {
-                        _stage = kStagePrepareExcessStart;
-                        _excessBuffer->setDirection(kIODirectionIn);
-                        _direction = kIODirectionIn;
-                        *byteStart = _requestStart - _excessCountStart;
-
-                        _chunks[_chunksCount].buffer = _excessBuffer;
-                        _chunks[_chunksCount].offset = 0;
-                        _chunks[_chunksCount].length = _blockSize;
-                        _chunksCount++;
-                        break;
-                    } 
-                } // (fall thru)
-
-                case kStagePrepareExcessStart:
-                {
-                    if ( _excessCountFinal )
-                    {
-                        // We do not issue this stage if the original transfer
-                        // resides within one media block, and we already read
-                        // that block into our buffer in the previous stage.
-
-                        if ( !_excessCountStart || !_requestIsOneBlock )
-                        {
-                            _stage = kStagePrepareExcessFinal;
-                            _excessBuffer->setDirection(kIODirectionIn);
-                            _direction = kIODirectionIn;
-                            *byteStart = _requestStart + _requestCount +
-                                         _excessCountFinal - _blockSize;
-
-                            _chunks[_chunksCount].buffer = _excessBuffer;
-                            _chunks[_chunksCount].offset = (_requestIsOneBlock)
-                                                           ? 0
-                                                           : (_excessCountStart)
-                                                             ? _blockSize
-                                                             : 0;
-                            _chunks[_chunksCount].length = _blockSize;
-                            _chunksCount++;
-                            break;
-                        }
-                    }
-                } // (fall thru)
-
-                case kStagePrepareExcessFinal:
-                {
-                    _stage     = kStageLast;
-                    _excessBuffer->setDirection(kIODirectionOut);
-                    _direction = kIODirectionOut;
-                    *byteStart = _requestStart - _excessCountStart;
-
-                    if ( _excessCountStart )
-                    {
-                        _chunks[_chunksCount].buffer = _excessBuffer;
-                        _chunks[_chunksCount].offset = 0;
-                        _chunks[_chunksCount].length = _excessCountStart;
-                        _chunksCount++;
-                    }
-
-                    _chunks[_chunksCount].buffer = _requestBuffer;
-                    _chunks[_chunksCount].offset = 0;
-                    _chunks[_chunksCount].length = _requestBuffer->getLength();
-                    _chunksCount++;
-
-                    if ( _excessCountFinal )
-                    {
-                        _chunks[_chunksCount].buffer = _excessBuffer;
-                        _chunks[_chunksCount].offset = (_requestIsOneBlock)
-                                                       ? 0
-                                                       : (_excessCountStart)
-                                                         ? _blockSize
-                                                         : 0;
-                        _chunks[_chunksCount].offset += ( _blockSize -
-                                                          _excessCountFinal );
-                        _chunks[_chunksCount].length = _excessCountFinal;
-                        _chunksCount++;
-                    }
-                } break;
-
-                case kStageLast:
-                {
-                    _stage = kStageDone;
-                } break;
-
-                default:
-                {
-                    assert(0);
-                } break;
-            } // (switch)
-        } break;
-
-        default:
-        {
-            assert(0);
-        } break;
-    } // (switch)
-
-    // Determine whether we have an abort or completion condition.
-
-    if ( _chunksCount == 0 )  return false;
-
-    // Compute the total length of the descriptor over all chunks.
-
-    for ( unsigned index = 0; index < _chunksCount; index++ )
-    {
-        _length += _chunks[index].length;
-    }
-
-    return true;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IODeblocker::getRequestCompletion( IOStorageCompletion * completion,
-                                        IOReturn *            status,
-                                        UInt64 *              actualByteCount )
-{
-    //
-    // Obtain the completion information for the original request, taking
-    // into account the status and actual byte count of the current stage. 
-    //
-
-    *completion = _requestCompletion;
-
-    switch ( _stage )
-    {
-        case kStageInit:                                       // (inital stage)
-        {
-            *status = kIOReturnInternalError;
-            *actualByteCount = 0;
-        } break;
-
-        case kStagePrepareExcessStart:              // (write preparation stage)
-        case kStagePrepareExcessFinal:
-        {
-            *actualByteCount = 0;
-        } break;
-
-        case kStageLast:                                         // (last stage)
-        case kStageDone:
-        {
-            if ( *actualByteCount > _excessCountStart )
-                *actualByteCount -= _excessCountStart;
-            else
-                *actualByteCount = 0;
-
-            if ( *actualByteCount > _requestBuffer->getLength() )
-                *actualByteCount = _requestBuffer->getLength();
-        } break;
-
-        default:
-        {
-            assert(0);
-        } break;
-    }
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-IOMemoryDescriptor * IODeblocker::getRequestBuffer()
-{
-    //
-    // Obtain the buffer for the original request. 
-    //
-
-    return _requestBuffer;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void * IODeblocker::getRequestContext()
-{
-    //
-    // Obtain the context for the original request. 
-    //
-
-    return _requestContext;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::deblockRequest(
-                                     UInt64                          byteStart,
-                                     IOMemoryDescriptor *            buffer,
-                                     IOStorageCompletion             completion,
-                                     IOBlockStorageDriver::Context * context )
-{
-    //
-    // The deblockRequest method checks to see if the incoming request rests
-    // on the media's block boundaries, and if not, deblocks it.  Deblocking
-    // involves rounding out the request to the nearest block boundaries and
-    // transferring the excess bytes into a scratch buffer.
-    //
-    // This method is part of a sequence of methods invoked for each read/write
-    // request.  The first is prepareRequest, which allocates and prepares some
-    // context for the transfer; the second is deblockRequest, which aligns the
-    // transfer at the media block boundaries; and the third is executeRequest,
-    // which implements the actual transfer from the block storage device.
-    //
-    // The current implementation of deblockRequest is asynchronous.
-    //
-
-    IODeblocker * deblocker;
-
-    // If the request is aligned with the media's block boundaries, we
-    // do short-circuit the deblocker and call executeRequest directly.
-
-    if ( (byteStart           % context->block.size) == 0 &&
-         (buffer->getLength() % context->block.size) == 0 )
-    {
-        executeRequest(byteStart, buffer, completion, context);
-        return;
-    }
-
-    // Build a deblocker object.
-
-    deblocker = IODeblocker::withBlockSize(
-                                /* blockSize             */ context->block.size,
-                                /* withRequestStart      */ byteStart,
-                                /* withRequestBuffer     */ buffer,
-                                /* withRequestCompletion */ completion,
-                                /* withRequestContext    */ context );
-
-    if ( deblocker == 0 )
-    {
-        complete(completion, kIOReturnNoMemory);
-        return;
-    }
-
-    // This implementation of the deblocker permits only one read-modify-write
-    // at any given time.  Note that other write requests can, and do, proceed
-    // simultaneously so long as they do not require the deblocker -- refer to
-    // the read() and the write() routines for the short-cut logic.
-    //
-    // Note that the original buffer during a read-modify-write operation must
-    // be prepared on the client's thread, that is, right now, or else it will
-    // happen on the controller's thread after the read stage(s) complete, and
-    // this is bad (causes deadlock if that controller was the swap device).
-
-    if ( buffer->getDirection() == kIODirectionOut )
-    {
-        if ( buffer->prepare() != kIOReturnSuccess )
-        {
-            deblocker->release();
-            complete(completion, kIOReturnNoMemory);
-            return;
-        }
-
-        IOLockLock(_deblockRequestWriteLock);
-    }
-
-    // Execute the transfer (for the next stage).
-
-    deblockRequestCompletion(this, deblocker, kIOReturnSuccess, 0);
-
-    return;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void IOBlockStorageDriver::deblockRequestCompletion( void *   target,
-                                                     void *   parameter,
-                                                     IOReturn status,
-                                                     UInt64   actualByteCount )
-{
-    //
-    // This is the completion routine for the aligned deblocker subrequests.
-    // It verifies the success of the just-completed stage,  transitions to
-    // the next stage, then builds and issues a transfer for the next stage.
-    //
-
-    UInt64                 byteStart;
-    IOStorageCompletion    completion;
-    Context *              context;
-    IODeblocker *          deblocker = (IODeblocker          *) parameter;
-    IOBlockStorageDriver * driver    = (IOBlockStorageDriver *) target;
-
-    // Determine whether an error occurred or whether there are no more stages.
-
-    if ( actualByteCount                      < deblocker->getLength() ||
-         status                              != kIOReturnSuccess       ||
-         deblocker->getNextStage(&byteStart) == false                  )
-    {
-        // Unlock the write-lock in order to allow the next write to proceed.
-
-        if ( deblocker->getRequestBuffer()->getDirection() == kIODirectionOut )
-        {
-            IOLockUnlock(driver->_deblockRequestWriteLock);
-
-            deblocker->getRequestBuffer()->complete();
-        }
-
-        // Obtain the completion information for the original request, taking
-        // into account the status and actual byte count of the current stage. 
-
-        deblocker->getRequestCompletion(&completion, &status, &actualByteCount);
-
-        // Complete the original request.
-
-        IOStorage::complete(completion, status, actualByteCount);
-
-        // Release our resources.
-
-        deblocker->release();
-
-        return;
-    }
-
-    // Execute the transfer (for the next stage).
-
-    completion.target    = driver;
-    completion.action    = deblockRequestCompletion;
-    completion.parameter = deblocker;
-
-    context = (Context *) deblocker->getRequestContext();
-
-    driver->executeRequest(byteStart, deblocker, completion, context);
-
-    return;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver,  0);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver,  1);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver,  2);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver,  3);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver,  4);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver,  5);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver,  6);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver,  7);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver,  8);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver,  9);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 10);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 11);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 12);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 13);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 14);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 15);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 16);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 17);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 18);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 19);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 20);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 21);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 22);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 23);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 24);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 25);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 26);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 27);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 28);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 29);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 30);
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-OSMetaClassDefineReservedUnused(IOBlockStorageDriver, 31);