Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / drivers / storage / classpnp / power.c
diff --git a/reactos/drivers/storage/classpnp/power.c b/reactos/drivers/storage/classpnp/power.c
deleted file mode 100644 (file)
index e1b5b32..0000000
+++ /dev/null
@@ -1,1614 +0,0 @@
-/*++
-
-Copyright (C) Microsoft Corporation, 1991 - 1999
-
-Module Name:
-
-    class.c
-
-Abstract:
-
-    SCSI class driver routines
-
-Environment:
-
-    kernel mode only
-
-Notes:
-
-
-Revision History:
-
---*/
-
-#include "classp.h"
-
-#define CLASS_TAG_POWER     'WLcS'
-
-NTSTATUS
-NTAPI
-ClasspPowerHandler(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN CLASS_POWER_OPTIONS Options
-    );
-
-IO_COMPLETION_ROUTINE ClasspPowerDownCompletion;
-
-IO_COMPLETION_ROUTINE ClasspPowerUpCompletion;
-
-VOID
-NTAPI
-RetryPowerRequest(
-    PDEVICE_OBJECT DeviceObject,
-    PIRP Irp,
-    PCLASS_POWER_CONTEXT Context
-    );
-
-NTSTATUS
-NTAPI
-ClasspStartNextPowerIrpCompletion(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Context
-    );
-
-
-/*++////////////////////////////////////////////////////////////////////////////
-
-ClassDispatchPower()
-
-Routine Description:
-
-    This routine acquires the removelock for the irp and then calls the
-    appropriate power callback.
-
-Arguments:
-
-    DeviceObject - 
-    Irp - 
-
-Return Value:
-
---*/
-NTSTATUS
-NTAPI
-ClassDispatchPower(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp
-    )
-{
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    ULONG isRemoved;
-
-    //
-    // NOTE: This code may be called at PASSIVE or DISPATCH, depending
-    //       upon the device object it is being called for.
-    //       don't do anything that would break under either circumstance.
-    //
-
-    isRemoved = ClassAcquireRemoveLock(DeviceObject, Irp);
-
-    if(isRemoved) {
-        ClassReleaseRemoveLock(DeviceObject, Irp);
-        Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
-        PoStartNextPowerIrp(Irp);
-        ClassCompleteRequest(DeviceObject, Irp, IO_NO_INCREMENT);
-        return STATUS_DEVICE_DOES_NOT_EXIST;
-    }
-
-    return commonExtension->DevInfo->ClassPowerDevice(DeviceObject, Irp);
-} // end ClassDispatchPower()
-
-/*++////////////////////////////////////////////////////////////////////////////
-
-ClasspPowerUpCompletion()
-
-Routine Description:
-
-    This routine is used for intermediate completion of a power up request.
-    PowerUp requires four requests to be sent to the lower driver in sequence.
-
-        * The queue is "power locked" to ensure that the class driver power-up
-          work can be done before request processing resumes.
-
-        * The power irp is sent down the stack for any filter drivers and the
-          port driver to return power and resume command processing for the
-          device.  Since the queue is locked, no queued irps will be sent
-          immediately.
-
-        * A start unit command is issued to the device with appropriate flags
-          to override the "power locked" queue.
-
-        * The queue is "power unlocked" to start processing requests again.
-
-    This routine uses the function in the srb which just completed to determine
-    which state it is in.
-
-Arguments:
-
-    DeviceObject - the device object being powered up
-
-    Irp - the IO_REQUEST_PACKET containing the power request
-
-    Srb - the SRB used to perform port/class operations.
-
-Return Value:
-
-    STATUS_MORE_PROCESSING_REQUIRED or
-    STATUS_SUCCESS
-    
---*/
-NTSTATUS
-NTAPI
-ClasspPowerUpCompletion(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID CompletionContext
-    )
-{
-    PCLASS_POWER_CONTEXT context = CompletionContext;
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
-
-    PIO_STACK_LOCATION currentStack = IoGetCurrentIrpStackLocation(Irp);
-    PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation(Irp);
-
-
-    NTSTATUS status = STATUS_MORE_PROCESSING_REQUIRED;
-
-    DebugPrint((1, "ClasspPowerUpCompletion: Device Object %p, Irp %p, "
-                   "Context %p\n",
-                DeviceObject, Irp, context));
-
-    ASSERT(!TEST_FLAG(context->Srb.SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER));
-    ASSERT(!TEST_FLAG(context->Srb.SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE));
-    ASSERT(context->Options.PowerDown == FALSE);
-    ASSERT(context->Options.HandleSpinUp);
-
-    if(Irp->PendingReturned) {
-        IoMarkIrpPending(Irp);
-    }
-
-    context->PowerChangeState.PowerUp++;
-
-    switch(context->PowerChangeState.PowerUp) {
-
-        case PowerUpDeviceLocked: {
-
-            DebugPrint((1, "(%p)\tPreviously sent power lock\n", Irp));
-
-            //
-            // Issue the actual power request to the lower driver.
-            //
-
-            IoCopyCurrentIrpStackLocationToNext(Irp);
-
-            //
-            // If the lock wasn't successful then just bail out on the power
-            // request unless we can ignore failed locks
-            //
-
-            if ((context->Options.LockQueue != FALSE) &&
-               (!NT_SUCCESS(Irp->IoStatus.Status))) {
-
-                DebugPrint((1, "(%p)\tIrp status was %lx\n",
-                            Irp, Irp->IoStatus.Status));
-                DebugPrint((1, "(%p)\tSrb status was %lx\n",
-                            Irp, context->Srb.SrbStatus));
-
-                //
-                // Lock was not successful - throw down the power IRP
-                // by itself and don't try to spin up the drive or unlock
-                // the queue.
-                //
-
-                context->InUse = FALSE;
-                context = NULL;
-
-                //
-                // Set the new power state
-                //
-
-                fdoExtension->DevicePowerState =
-                    currentStack->Parameters.Power.State.DeviceState;
-
-                Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
-
-                IoCopyCurrentIrpStackLocationToNext(Irp);
-
-                IoSetCompletionRoutine(Irp,
-                                       ClasspStartNextPowerIrpCompletion,
-                                       NULL,
-                                       TRUE,
-                                       TRUE,
-                                       TRUE);
-
-                //
-                // Indicate to Po that we've been successfully powered up so
-                // it can do it's notification stuff.
-                //
-
-                PoSetPowerState(DeviceObject,
-                                currentStack->Parameters.Power.Type,
-                                currentStack->Parameters.Power.State);
-
-                PoCallDriver(commonExtension->LowerDeviceObject, Irp);
-
-                ClassReleaseRemoveLock(commonExtension->DeviceObject,
-                                       Irp);
-
-                return STATUS_MORE_PROCESSING_REQUIRED;
-
-            } else {
-                context->QueueLocked = (UCHAR) context->Options.LockQueue;
-            }
-
-            Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
-
-            context->PowerChangeState.PowerUp = PowerUpDeviceLocked;
-
-            IoSetCompletionRoutine(Irp,
-                                   ClasspPowerUpCompletion,
-                                   context,
-                                   TRUE,
-                                   TRUE,
-                                   TRUE);
-
-            status = PoCallDriver(commonExtension->LowerDeviceObject, Irp);
-
-            DebugPrint((2, "(%p)\tPoCallDriver returned %lx\n", Irp, status));
-            break;
-        }
-
-        case PowerUpDeviceOn: {
-
-            PCDB cdb;
-
-            if(NT_SUCCESS(Irp->IoStatus.Status)) {
-
-                DebugPrint((1, "(%p)\tSending start unit to device\n", Irp));
-
-                //
-                // Issue the start unit command to the device.
-                //
-
-                context->Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
-                context->Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
-
-                context->Srb.SrbStatus = context->Srb.ScsiStatus = 0;
-                context->Srb.DataTransferLength = 0;
-
-                context->Srb.TimeOutValue = START_UNIT_TIMEOUT;
-
-                context->Srb.SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER |
-                                        SRB_FLAGS_DISABLE_AUTOSENSE |
-                                        SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
-                                        SRB_FLAGS_NO_QUEUE_FREEZE;
-
-                if(context->Options.LockQueue) {
-                    SET_FLAG(context->Srb.SrbFlags, SRB_FLAGS_BYPASS_LOCKED_QUEUE);
-                }
-
-                context->Srb.CdbLength = 6;
-
-                cdb = (PCDB) (context->Srb.Cdb);
-                RtlZeroMemory(cdb, sizeof(CDB));
-
-
-                cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
-                cdb->START_STOP.Start = 1;
-
-                context->PowerChangeState.PowerUp = PowerUpDeviceOn;
-
-                IoSetCompletionRoutine(Irp,
-                                       ClasspPowerUpCompletion,
-                                       context,
-                                       TRUE,
-                                       TRUE,
-                                       TRUE);
-
-                nextStack->Parameters.Scsi.Srb = &(context->Srb);
-                nextStack->MajorFunction = IRP_MJ_SCSI;
-
-                status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
-
-                DebugPrint((2, "(%p)\tIoCallDriver returned %lx\n", Irp, status));
-
-            } else {
-
-                //
-                // we're done.
-                //
-
-                context->FinalStatus = Irp->IoStatus.Status;
-                goto ClasspPowerUpCompletionFailure;
-            }
-
-            break;
-        }
-
-        case PowerUpDeviceStarted: { // 3
-
-            //
-            // First deal with an error if one occurred.
-            //
-
-            if(SRB_STATUS(context->Srb.SrbStatus) != SRB_STATUS_SUCCESS) {
-
-                BOOLEAN retry;
-
-                DebugPrint((1, "%p\tError occured when issuing START_UNIT "
-                            "command to device. Srb %p, Status %x\n",
-                            Irp,
-                            &context->Srb,
-                            context->Srb.SrbStatus));
-
-                ASSERT(!(TEST_FLAG(context->Srb.SrbStatus,
-                                   SRB_STATUS_QUEUE_FROZEN)));
-                ASSERT(context->Srb.Function == SRB_FUNCTION_EXECUTE_SCSI);
-
-                context->RetryInterval = 0;
-
-                retry = ClassInterpretSenseInfo(
-                            commonExtension->DeviceObject,
-                            &context->Srb,
-                            IRP_MJ_SCSI,
-                            IRP_MJ_POWER,
-                            MAXIMUM_RETRIES - context->RetryCount,
-                            &status,
-                            &context->RetryInterval);
-
-                if ((retry != FALSE) && (context->RetryCount-- != 0)) {
-
-                    DebugPrint((1, "(%p)\tRetrying failed request\n", Irp));
-
-                    //
-                    // Decrement the state so we come back through here the
-                    // next time.
-                    //
-
-                    context->PowerChangeState.PowerUp--;
-
-                    RetryPowerRequest(commonExtension->DeviceObject,
-                                      Irp,
-                                      context);
-
-                    break;
-
-                }
-
-                // reset retries
-                context->RetryCount = MAXIMUM_RETRIES;
-
-            }
-
-ClasspPowerUpCompletionFailure:
-
-            DebugPrint((1, "(%p)\tPreviously spun device up\n", Irp));
-
-            if (context->QueueLocked) {
-                DebugPrint((1, "(%p)\tUnlocking queue\n", Irp));
-
-                context->Srb.Function = SRB_FUNCTION_UNLOCK_QUEUE;
-                context->Srb.SrbFlags = SRB_FLAGS_BYPASS_LOCKED_QUEUE;
-                context->Srb.SrbStatus = context->Srb.ScsiStatus = 0;
-                context->Srb.DataTransferLength = 0;
-
-                nextStack->Parameters.Scsi.Srb = &(context->Srb);
-                nextStack->MajorFunction = IRP_MJ_SCSI;
-
-                context->PowerChangeState.PowerUp = PowerUpDeviceStarted;
-
-                IoSetCompletionRoutine(Irp,
-                                       ClasspPowerUpCompletion,
-                                       context,
-                                       TRUE,
-                                       TRUE,
-                                       TRUE);
-
-                status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
-                DebugPrint((1, "(%p)\tIoCallDriver returned %lx\n",
-                            Irp, status));
-                break;
-            }
-
-            // Fall-through to next case...
-
-        }
-
-        case PowerUpDeviceUnlocked: {
-
-            //
-            // This is the end of the dance.  Free the srb and complete the
-            // request finally.  We're ignoring possible intermediate
-            // error conditions ....
-            //
-
-            if (context->QueueLocked) {
-                DebugPrint((1, "(%p)\tPreviously unlocked queue\n", Irp));
-                ASSERT(NT_SUCCESS(Irp->IoStatus.Status));
-                ASSERT(context->Srb.SrbStatus == SRB_STATUS_SUCCESS);
-            } else {
-                DebugPrint((1, "(%p)\tFall-through (queue not locked)\n", Irp));
-            }
-
-            DebugPrint((1, "(%p)\tFreeing srb and completing\n", Irp));
-            context->InUse = FALSE;
-
-            status = context->FinalStatus;
-            Irp->IoStatus.Status = status;
-
-            context = NULL;
-
-            //
-            // Set the new power state
-            //
-
-            if(NT_SUCCESS(status)) {
-                fdoExtension->DevicePowerState =
-                    currentStack->Parameters.Power.State.DeviceState;
-            }
-
-            //
-            // Indicate to Po that we've been successfully powered up so
-            // it can do it's notification stuff.
-            //
-            
-            PoSetPowerState(DeviceObject,
-                            currentStack->Parameters.Power.Type,
-                            currentStack->Parameters.Power.State);
-
-            DebugPrint((1, "(%p)\tStarting next power irp\n", Irp));
-            ClassReleaseRemoveLock(DeviceObject, Irp);
-            PoStartNextPowerIrp(Irp);
-
-            return status;
-        }
-
-        case PowerUpDeviceInitial: {
-            NT_ASSERT(context->PowerChangeState.PowerUp != PowerUpDeviceInitial);
-            break;
-        }
-    }
-
-    return STATUS_MORE_PROCESSING_REQUIRED;
-} // end ClasspPowerUpCompletion()
-
-/*++////////////////////////////////////////////////////////////////////////////
-
-ClasspPowerDownCompletion()
-
-Routine Description:
-
-    This routine is used for intermediate completion of a power up request.
-    PowerUp requires four requests to be sent to the lower driver in sequence.
-
-        * The queue is "power locked" to ensure that the class driver power-up
-          work can be done before request processing resumes.
-
-        * The power irp is sent down the stack for any filter drivers and the
-          port driver to return power and resume command processing for the
-          device.  Since the queue is locked, no queued irps will be sent
-          immediately.
-
-        * A start unit command is issued to the device with appropriate flags
-          to override the "power locked" queue.
-
-        * The queue is "power unlocked" to start processing requests again.
-
-    This routine uses the function in the srb which just completed to determine
-    which state it is in.
-
-Arguments:
-
-    DeviceObject - the device object being powered up
-
-    Irp - the IO_REQUEST_PACKET containing the power request
-
-    Srb - the SRB used to perform port/class operations.
-
-Return Value:
-
-    STATUS_MORE_PROCESSING_REQUIRED or
-    STATUS_SUCCESS
-
---*/
-NTSTATUS
-NTAPI
-ClasspPowerDownCompletion(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID CompletionContext
-    )
-{
-    PCLASS_POWER_CONTEXT context = CompletionContext;
-    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-
-    PIO_STACK_LOCATION currentStack = IoGetCurrentIrpStackLocation(Irp);
-    PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation(Irp);
-
-    NTSTATUS status = STATUS_MORE_PROCESSING_REQUIRED;
-
-    DebugPrint((1, "ClasspPowerDownCompletion: Device Object %p, "
-                   "Irp %p, Context %p\n",
-                DeviceObject, Irp, context));
-
-    ASSERT(!TEST_FLAG(context->Srb.SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER));
-    ASSERT(!TEST_FLAG(context->Srb.SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE));
-    ASSERT(context->Options.PowerDown == TRUE);
-    ASSERT(context->Options.HandleSpinDown);
-
-    if(Irp->PendingReturned) {
-        IoMarkIrpPending(Irp);
-    }
-
-    context->PowerChangeState.PowerDown2++;
-
-    switch(context->PowerChangeState.PowerDown2) {
-
-        case PowerDownDeviceLocked2: {
-
-            PCDB cdb;
-
-            DebugPrint((1, "(%p)\tPreviously sent power lock\n", Irp));
-
-            if ((context->Options.LockQueue != FALSE) &&
-               (!NT_SUCCESS(Irp->IoStatus.Status))) {
-
-                DebugPrint((1, "(%p)\tIrp status was %lx\n",
-                            Irp,
-                            Irp->IoStatus.Status));
-                DebugPrint((1, "(%p)\tSrb status was %lx\n",
-                            Irp,
-                            context->Srb.SrbStatus));
-
-                Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
-
-                //
-                // Lock was not successful - throw down the power IRP
-                // by itself and don't try to spin down the drive or unlock
-                // the queue.
-                //
-
-                context->InUse = FALSE;
-                context = NULL;
-
-                //
-                // Set the new power state
-                //
-
-                fdoExtension->DevicePowerState =
-                    currentStack->Parameters.Power.State.DeviceState;
-
-                //
-                // Indicate to Po that we've been successfully powered down
-                // so it can do it's notification stuff.
-                //
-
-                IoCopyCurrentIrpStackLocationToNext(Irp);
-                IoSetCompletionRoutine(Irp,
-                                       ClasspStartNextPowerIrpCompletion,
-                                       NULL,
-                                       TRUE,
-                                       TRUE,
-                                       TRUE);
-
-                PoSetPowerState(DeviceObject,
-                                currentStack->Parameters.Power.Type,
-                                currentStack->Parameters.Power.State);
-
-                fdoExtension->PowerDownInProgress = FALSE;
-
-                PoCallDriver(commonExtension->LowerDeviceObject, Irp);
-
-                ClassReleaseRemoveLock(commonExtension->DeviceObject,
-                                       Irp);
-
-                return STATUS_MORE_PROCESSING_REQUIRED;
-
-            } else {
-                context->QueueLocked = (UCHAR) context->Options.LockQueue;
-            }
-
-            if (!TEST_FLAG(fdoExtension->PrivateFdoData->HackFlags,
-                           FDO_HACK_NO_SYNC_CACHE)) {
-
-                //
-                // send SCSIOP_SYNCHRONIZE_CACHE
-                //
-
-                context->Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
-                context->Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
-
-                context->Srb.TimeOutValue = fdoExtension->TimeOutValue;
-
-                context->Srb.SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER |
-                                        SRB_FLAGS_DISABLE_AUTOSENSE |
-                                        SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
-                                        SRB_FLAGS_NO_QUEUE_FREEZE |
-                                        SRB_FLAGS_BYPASS_LOCKED_QUEUE;
-
-                context->Srb.SrbStatus = context->Srb.ScsiStatus = 0;
-                context->Srb.DataTransferLength = 0;
-
-                context->Srb.CdbLength = 10;
-
-                cdb = (PCDB) context->Srb.Cdb;
-
-                RtlZeroMemory(cdb, sizeof(CDB));
-                cdb->SYNCHRONIZE_CACHE10.OperationCode = SCSIOP_SYNCHRONIZE_CACHE;
-
-                IoSetCompletionRoutine(Irp,
-                                       ClasspPowerDownCompletion,
-                                       context,
-                                       TRUE,
-                                       TRUE,
-                                       TRUE);
-
-                nextStack->Parameters.Scsi.Srb = &(context->Srb);
-                nextStack->MajorFunction = IRP_MJ_SCSI;
-
-                status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
-
-                DebugPrint((1, "(%p)\tIoCallDriver returned %lx\n", Irp, status));
-                break;
-
-            } else {
-
-                DebugPrint((1, "(%p)\tPower Down: not sending SYNCH_CACHE\n",
-                            DeviceObject));
-                context->PowerChangeState.PowerDown2++;
-                context->Srb.SrbStatus = SRB_STATUS_SUCCESS;
-                // and fall through....
-            }
-            // no break in case the device doesn't like synch_cache commands
-
-        }
-         
-        case PowerDownDeviceFlushed2: {
-
-            PCDB cdb;
-
-            DebugPrint((1, "(%p)\tPreviously send SCSIOP_SYNCHRONIZE_CACHE\n",
-                        Irp));
-
-            //
-            // SCSIOP_SYNCHRONIZE_CACHE was sent
-            //
-
-            if(SRB_STATUS(context->Srb.SrbStatus) != SRB_STATUS_SUCCESS) {
-
-                BOOLEAN retry;
-
-                DebugPrint((1, "(%p)\tError occured when issuing "
-                            "SYNCHRONIZE_CACHE command to device. "
-                            "Srb %p, Status %lx\n",
-                            Irp,
-                            &context->Srb,
-                            context->Srb.SrbStatus));
-
-                ASSERT(!(TEST_FLAG(context->Srb.SrbStatus,
-                                   SRB_STATUS_QUEUE_FROZEN)));
-                ASSERT(context->Srb.Function == SRB_FUNCTION_EXECUTE_SCSI);
-
-                context->RetryInterval = 0;
-                retry = ClassInterpretSenseInfo(
-                            commonExtension->DeviceObject,
-                            &context->Srb,
-                            IRP_MJ_SCSI,
-                            IRP_MJ_POWER,
-                            MAXIMUM_RETRIES - context->RetryCount,
-                            &status,
-                            &context->RetryInterval);
-
-                if ((retry != FALSE) && (context->RetryCount-- != 0)) {
-
-                        DebugPrint((1, "(%p)\tRetrying failed request\n", Irp));
-
-                        //
-                        // decrement the state so we come back through here
-                        // the next time.
-                        //
-
-                        context->PowerChangeState.PowerDown2--;
-                        RetryPowerRequest(commonExtension->DeviceObject,
-                                          Irp,
-                                          context);
-                        break;
-                }
-
-                DebugPrint((1, "(%p)\tSYNCHRONIZE_CACHE not retried\n", Irp));
-                context->RetryCount = MAXIMUM_RETRIES;
-
-            } // end !SRB_STATUS_SUCCESS
-
-            //
-            // note: we are purposefully ignoring any errors.  if the drive
-            //       doesn't support a synch_cache, then we're up a creek
-            //       anyways.
-            //
-
-            DebugPrint((1, "(%p)\tSending stop unit to device\n", Irp));
-
-            //
-            // Issue the start unit command to the device.
-            //
-
-            context->Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
-            context->Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
-
-            context->Srb.TimeOutValue = START_UNIT_TIMEOUT;
-
-            context->Srb.SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER |
-                                    SRB_FLAGS_DISABLE_AUTOSENSE |
-                                    SRB_FLAGS_DISABLE_SYNCH_TRANSFER |
-                                    SRB_FLAGS_NO_QUEUE_FREEZE |
-                                    SRB_FLAGS_BYPASS_LOCKED_QUEUE;
-
-            context->Srb.SrbStatus = context->Srb.ScsiStatus = 0;
-            context->Srb.DataTransferLength = 0;
-
-            context->Srb.CdbLength = 6;
-
-            cdb = (PCDB) context->Srb.Cdb;
-            RtlZeroMemory(cdb, sizeof(CDB));
-
-            cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
-            cdb->START_STOP.Start = 0;
-            cdb->START_STOP.Immediate = 1;
-
-            IoSetCompletionRoutine(Irp,
-                                   ClasspPowerDownCompletion,
-                                   context,
-                                   TRUE,
-                                   TRUE,
-                                   TRUE);
-
-            nextStack->Parameters.Scsi.Srb = &(context->Srb);
-            nextStack->MajorFunction = IRP_MJ_SCSI;
-
-            status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
-
-            DebugPrint((1, "(%p)\tIoCallDriver returned %lx\n", Irp, status));
-            break;
-
-        }
-
-        case PowerDownDeviceStopped2: {
-
-            BOOLEAN ignoreError = TRUE;
-
-            //
-            // stop was sent
-            //
-
-            if(SRB_STATUS(context->Srb.SrbStatus) != SRB_STATUS_SUCCESS) {
-
-                BOOLEAN retry;
-
-                DebugPrint((1, "(%p)\tError occured when issuing STOP_UNIT "
-                            "command to device. Srb %p, Status %lx\n",
-                            Irp,
-                            &context->Srb,
-                            context->Srb.SrbStatus));
-
-                ASSERT(!(TEST_FLAG(context->Srb.SrbStatus,
-                                   SRB_STATUS_QUEUE_FROZEN)));
-                ASSERT(context->Srb.Function == SRB_FUNCTION_EXECUTE_SCSI);
-
-                context->RetryInterval = 0;
-                retry = ClassInterpretSenseInfo(
-                            commonExtension->DeviceObject,
-                            &context->Srb,
-                            IRP_MJ_SCSI,
-                            IRP_MJ_POWER,
-                            MAXIMUM_RETRIES - context->RetryCount,
-                            &status,
-                            &context->RetryInterval);
-
-                if ((retry != FALSE) && (context->RetryCount-- != 0)) {
-
-                        DebugPrint((1, "(%p)\tRetrying failed request\n", Irp));
-
-                        //
-                        // decrement the state so we come back through here
-                        // the next time.
-                        //
-
-                        context->PowerChangeState.PowerDown2--;
-                        RetryPowerRequest(commonExtension->DeviceObject,
-                                          Irp,
-                                          context);
-                        break;
-                }
-
-                DebugPrint((1, "(%p)\tSTOP_UNIT not retried\n", Irp));
-                context->RetryCount = MAXIMUM_RETRIES;
-
-            } // end !SRB_STATUS_SUCCESS
-
-
-            DebugPrint((1, "(%p)\tPreviously sent stop unit\n", Irp));
-
-            //
-            // some operations, such as a physical format in progress,
-            // should not be ignored and should fail the power operation.
-            //
-
-            if (!NT_SUCCESS(status)) {
-
-                PSENSE_DATA senseBuffer = context->Srb.SenseInfoBuffer;
-
-                if (TEST_FLAG(context->Srb.SrbStatus,
-                              SRB_STATUS_AUTOSENSE_VALID) &&
-                    ((senseBuffer->SenseKey & 0xf) == SCSI_SENSE_NOT_READY) &&
-                    (senseBuffer->AdditionalSenseCode == SCSI_ADSENSE_LUN_NOT_READY) &&
-                    (senseBuffer->AdditionalSenseCodeQualifier == SCSI_SENSEQ_FORMAT_IN_PROGRESS)
-                    ) {
-                    ignoreError = FALSE;
-                    context->FinalStatus = STATUS_DEVICE_BUSY;
-                    status = context->FinalStatus;
-                }
-
-            }
-
-            if (NT_SUCCESS(status) || ignoreError) {
-
-                //
-                // Issue the actual power request to the lower driver.
-                //
-
-                Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
-
-                IoCopyCurrentIrpStackLocationToNext(Irp);
-
-                IoSetCompletionRoutine(Irp,
-                                       ClasspPowerDownCompletion,
-                                       context,
-                                       TRUE,
-                                       TRUE,
-                                       TRUE);
-
-                status = PoCallDriver(commonExtension->LowerDeviceObject, Irp);
-
-                DebugPrint((1, "(%p)\tPoCallDriver returned %lx\n", Irp, status));
-                break;
-            }
-            
-            // else fall through w/o sending the power irp, since the device
-            // is reporting an error that would be "really bad" to power down
-            // during.
-
-        }
-
-        case PowerDownDeviceOff2: {
-
-            //
-            // SpinDown request completed ... whether it succeeded or not is
-            // another matter entirely.
-            //
-
-            DebugPrint((1, "(%p)\tPreviously sent power irp\n", Irp));
-
-            if (context->QueueLocked) {
-
-                DebugPrint((1, "(%p)\tUnlocking queue\n", Irp));
-
-                context->Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
-
-                context->Srb.SrbStatus = context->Srb.ScsiStatus = 0;
-                context->Srb.DataTransferLength = 0;
-
-                context->Srb.Function = SRB_FUNCTION_UNLOCK_QUEUE;
-                context->Srb.SrbFlags = SRB_FLAGS_BYPASS_LOCKED_QUEUE;
-                nextStack->Parameters.Scsi.Srb = &(context->Srb);
-                nextStack->MajorFunction = IRP_MJ_SCSI;
-
-                IoSetCompletionRoutine(Irp,
-                                       ClasspPowerDownCompletion,
-                                       context,
-                                       TRUE,
-                                       TRUE,
-                                       TRUE);
-
-                status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
-                DebugPrint((1, "(%p)\tIoCallDriver returned %lx\n",
-                            Irp,
-                            status));
-                break;
-            }
-
-        }
-
-        case PowerDownDeviceUnlocked2: {
-
-            //
-            // This is the end of the dance.  Free the srb and complete the
-            // request finally.  We're ignoring possible intermediate
-            // error conditions ....
-            //
-
-            if (context->QueueLocked == FALSE) {
-                DebugPrint((1, "(%p)\tFall through (queue not locked)\n", Irp));
-            } else {
-                DebugPrint((1, "(%p)\tPreviously unlocked queue\n", Irp));
-                ASSERT(NT_SUCCESS(Irp->IoStatus.Status));
-                ASSERT(context->Srb.SrbStatus == SRB_STATUS_SUCCESS);
-            }
-
-            DebugPrint((1, "(%p)\tFreeing srb and completing\n", Irp));
-            context->InUse = FALSE;
-            status = context->FinalStatus; // allow failure to propagate
-            context = NULL;
-
-            if(Irp->PendingReturned) {
-                IoMarkIrpPending(Irp);
-            }
-
-            Irp->IoStatus.Status = status;
-            Irp->IoStatus.Information = 0;
-
-            if (NT_SUCCESS(status)) {
-                
-                //
-                // Set the new power state
-                //
-
-                fdoExtension->DevicePowerState =
-                    currentStack->Parameters.Power.State.DeviceState;
-
-            }
-
-
-            DebugPrint((1, "(%p)\tStarting next power irp\n", Irp));
-
-            ClassReleaseRemoveLock(DeviceObject, Irp);
-            PoStartNextPowerIrp(Irp);
-            fdoExtension->PowerDownInProgress = FALSE;
-
-            return status;
-        }
-
-        case PowerDownDeviceInitial2: {
-            NT_ASSERT(context->PowerChangeState.PowerDown2 != PowerDownDeviceInitial2);
-            break;
-        }
-    }
-
-    return STATUS_MORE_PROCESSING_REQUIRED;
-} // end ClasspPowerDownCompletion()
-
-/*++////////////////////////////////////////////////////////////////////////////
-
-ClasspPowerHandler()
-
-Routine Description:
-
-    This routine reduces the number of useless spinups and spindown requests
-    sent to a given device by ignoring transitions to power states we are
-    currently in.
-    
-    ISSUE-2000/02/20-henrygab - by ignoring spin-up requests, we may be
-          allowing the drive
-
-Arguments:
-
-    DeviceObject - the device object which is transitioning power states
-    Irp - the power irp
-    Options - a set of flags indicating what the device handles
-
-Return Value:
-
---*/
-NTSTATUS
-NTAPI
-ClasspPowerHandler(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN CLASS_POWER_OPTIONS Options  // ISSUE-2000/02/20-henrygab - pass pointer, not whole struct
-    )
-{
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    PDEVICE_OBJECT lowerDevice = commonExtension->LowerDeviceObject;
-    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
-    PIO_STACK_LOCATION nextIrpStack;
-    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
-    PCLASS_POWER_CONTEXT context;
-
-    if (!commonExtension->IsFdo) {
-
-        //
-        // certain assumptions are made here,
-        // particularly: having the fdoExtension
-        //
-
-        DebugPrint((0, "ClasspPowerHandler: Called for PDO %p???\n",
-                    DeviceObject));
-        ASSERT(!"PDO using ClasspPowerHandler");
-        return STATUS_NOT_SUPPORTED;
-    }
-
-    DebugPrint((1, "ClasspPowerHandler: Power irp %p to %s %p\n",
-                Irp, (commonExtension->IsFdo ? "fdo" : "pdo"), DeviceObject));
-
-    switch(irpStack->MinorFunction) {
-
-        case IRP_MN_SET_POWER: {
-            PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
-
-            DebugPrint((1, "(%p)\tIRP_MN_SET_POWER\n", Irp));
-
-            DebugPrint((1, "(%p)\tSetting %s state to %d\n",
-                        Irp,
-                        (irpStack->Parameters.Power.Type == SystemPowerState ?
-                            "System" : "Device"),
-                        irpStack->Parameters.Power.State.SystemState));
-
-                switch (irpStack->Parameters.Power.ShutdownType){
-                    
-                    case PowerActionSleep:
-                    case PowerActionHibernate:
-                        if (fdoData->HotplugInfo.MediaRemovable || fdoData->HotplugInfo.MediaHotplug){
-                            /*
-                             *  We are suspending and this drive is either hot-pluggable
-                             *  or contains removeable media.
-                             *  Set the media dirty bit, since the media may change while
-                             *  we are suspended.
-                             */
-                            SET_FLAG(DeviceObject->Flags, DO_VERIFY_VOLUME);
-                        }
-                        break;
-                    default:
-                        break;
-                }
-            
-            break;
-        }
-
-        default: {
-
-            DebugPrint((1, "(%p)\tIrp minor code = %#x\n",
-                        Irp, irpStack->MinorFunction));
-            break;
-        }
-    }
-
-    if (irpStack->Parameters.Power.Type != DevicePowerState ||
-        irpStack->MinorFunction != IRP_MN_SET_POWER) {
-
-        DebugPrint((1, "(%p)\tSending to lower device\n", Irp));
-
-        goto ClasspPowerHandlerCleanup;
-
-    }
-
-    nextIrpStack = IoGetNextIrpStackLocation(Irp);
-
-    //
-    // already in exact same state, don't work to transition to it.
-    //
-
-    if(irpStack->Parameters.Power.State.DeviceState ==
-       fdoExtension->DevicePowerState) {
-
-        DebugPrint((1, "(%p)\tAlready in device state %x\n",
-                    Irp, fdoExtension->DevicePowerState));
-        goto ClasspPowerHandlerCleanup;
-
-    }
-
-    //
-    // or powering down from non-d0 state (device already stopped)
-    // NOTE -- we're not sure whether this case can exist or not (the
-    // power system may never send this sort of request) but it's trivial
-    // to deal with.
-    //
-
-    if ((irpStack->Parameters.Power.State.DeviceState != PowerDeviceD0) &&
-        (fdoExtension->DevicePowerState != PowerDeviceD0)) {
-        DebugPrint((1, "(%p)\tAlready powered down to %x???\n",
-                    Irp, fdoExtension->DevicePowerState));
-        fdoExtension->DevicePowerState =
-            irpStack->Parameters.Power.State.DeviceState;
-        goto ClasspPowerHandlerCleanup;
-    }
-
-    //
-    // or going into a hibernation state when we're in the hibernation path.
-    // If the device is spinning then we should leave it spinning - if it's not
-    // then the dump driver will start it up for us.
-    //
-
-    if((irpStack->Parameters.Power.State.DeviceState == PowerDeviceD3) &&
-       (irpStack->Parameters.Power.ShutdownType == PowerActionHibernate) &&
-       (commonExtension->HibernationPathCount != 0)) {
-
-        DebugPrint((1, "(%p)\tdoing nothing for hibernation request for "
-                       "state %x???\n",
-                    Irp, fdoExtension->DevicePowerState));
-        fdoExtension->DevicePowerState =
-            irpStack->Parameters.Power.State.DeviceState;
-        goto ClasspPowerHandlerCleanup;
-    }
-    //
-    // or when not handling powering up and are powering up
-    //
-
-    if ((!Options.HandleSpinUp) &&
-        (irpStack->Parameters.Power.State.DeviceState == PowerDeviceD0)) {
-
-        DebugPrint((2, "(%p)\tNot handling spinup to state %x\n",
-                    Irp, fdoExtension->DevicePowerState));
-        fdoExtension->DevicePowerState =
-            irpStack->Parameters.Power.State.DeviceState;
-        goto ClasspPowerHandlerCleanup;
-
-    }
-
-    //
-    // or when not handling powering down and are powering down
-    //
-
-    if ((!Options.HandleSpinDown) &&
-        (irpStack->Parameters.Power.State.DeviceState != PowerDeviceD0)) {
-
-        DebugPrint((2, "(%p)\tNot handling spindown to state %x\n",
-                    Irp, fdoExtension->DevicePowerState));
-        fdoExtension->DevicePowerState =
-            irpStack->Parameters.Power.State.DeviceState;
-        goto ClasspPowerHandlerCleanup;
-
-    }
-
-    context = &(fdoExtension->PowerContext);
-
-#if DBG
-    //
-    // Mark the context as in use.  We should be synchronizing this but
-    // since it's just for debugging purposes we don't worry too much.
-    //
-
-    ASSERT(context->InUse == FALSE);
-#endif
-
-    RtlZeroMemory(context, sizeof(CLASS_POWER_CONTEXT));
-    context->InUse = TRUE;
-
-    nextIrpStack->Parameters.Scsi.Srb = &(context->Srb);
-    nextIrpStack->MajorFunction = IRP_MJ_SCSI;
-
-    context->FinalStatus = STATUS_SUCCESS;
-
-    context->Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
-    context->Srb.OriginalRequest = Irp;
-    context->Srb.SrbFlags |= SRB_FLAGS_BYPASS_LOCKED_QUEUE
-                          |  SRB_FLAGS_NO_QUEUE_FREEZE;
-    context->Srb.Function = SRB_FUNCTION_LOCK_QUEUE;
-
-    context->Srb.SenseInfoBuffer =
-        commonExtension->PartitionZeroExtension->SenseData;
-    context->Srb.SenseInfoBufferLength = SENSE_BUFFER_SIZE;
-    context->RetryCount = MAXIMUM_RETRIES;
-
-    context->Options = Options;
-    context->DeviceObject = DeviceObject;
-    context->Irp = Irp;
-
-    if(irpStack->Parameters.Power.State.DeviceState == PowerDeviceD0) {
-
-        ASSERT(Options.HandleSpinUp);
-
-        DebugPrint((2, "(%p)\tpower up - locking queue\n", Irp));
-
-        //
-        // We need to issue a queue lock request so that we
-        // can spin the drive back up after the power is restored
-        // but before any requests are processed.
-        //
-
-        context->Options.PowerDown = FALSE;
-        context->PowerChangeState.PowerUp = PowerUpDeviceInitial;
-        context->CompletionRoutine = ClasspPowerUpCompletion;
-
-    } else {
-
-        ASSERT(Options.HandleSpinDown);
-
-        fdoExtension->PowerDownInProgress = TRUE;
-
-        DebugPrint((2, "(%p)\tPowering down - locking queue\n", Irp));
-
-        PoSetPowerState(DeviceObject,
-                        irpStack->Parameters.Power.Type,
-                        irpStack->Parameters.Power.State);
-
-        context->Options.PowerDown = TRUE;
-        context->PowerChangeState.PowerDown2 = PowerDownDeviceInitial2;
-        context->CompletionRoutine = ClasspPowerDownCompletion;
-
-    }
-
-    //
-    // we are not dealing with port-allocated sense in these routines.
-    //
-
-    ASSERT(!TEST_FLAG(context->Srb.SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER));
-    ASSERT(!TEST_FLAG(context->Srb.SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE));
-
-    //
-    // we are always returning STATUS_PENDING, so we need to always
-    // set the irp as pending.
-    //
-
-    IoMarkIrpPending(Irp);
-
-    if(Options.LockQueue) {
-
-        //
-        // Send the lock irp down.
-        //
-
-        IoSetCompletionRoutine(Irp,
-                               context->CompletionRoutine,
-                               context,
-                               TRUE,
-                               TRUE,
-                               TRUE);
-
-        IoCallDriver(lowerDevice, Irp);
-
-    } else {
-
-        //
-        // Call the completion routine directly.  It won't care what the
-        // status of the "lock" was - it will just go and do the next
-        // step of the operation.
-        //
-
-        context->CompletionRoutine(DeviceObject, Irp, context);
-    }
-
-    return STATUS_PENDING;
-
-ClasspPowerHandlerCleanup:
-
-    ClassReleaseRemoveLock(DeviceObject, Irp);
-
-    DebugPrint((1, "(%p)\tStarting next power irp\n", Irp));
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           ClasspStartNextPowerIrpCompletion,
-                           NULL,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-    return PoCallDriver(lowerDevice, Irp);
-} // end ClasspPowerHandler()
-
-/*++////////////////////////////////////////////////////////////////////////////
-
-ClassMinimalPowerHandler()
-
-Routine Description:
-
-    This routine is the minimum power handler for a storage driver.  It does
-    the least amount of work possible.
-
---*/
-NTSTATUS
-NTAPI
-ClassMinimalPowerHandler(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp
-    )
-{
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
-    NTSTATUS status;
-
-    ClassReleaseRemoveLock(DeviceObject, Irp);
-    PoStartNextPowerIrp(Irp);
-
-    if(commonExtension->IsFdo) {
-
-        if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
-
-            PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = 
-                DeviceObject->DeviceExtension;
-
-            //
-            // Check if the system is going to hibernate or standby.
-            //
-            if (irpStack->MinorFunction == IRP_MN_SET_POWER){
-                PVPB vpb;
-                
-                switch (irpStack->Parameters.Power.ShutdownType){
-                    
-                    case PowerActionSleep:
-                    case PowerActionHibernate:
-                        //
-                        // If the volume is mounted, set the verify bit so that
-                        // the filesystem will be forced re-read the media
-                        // after coming out of hibernation or standby.
-                        //
-                        vpb = ClassGetVpb(fdoExtension->DeviceObject);
-                        if (vpb && (vpb->Flags & VPB_MOUNTED)){
-                            SET_FLAG(fdoExtension->DeviceObject->Flags, DO_VERIFY_VOLUME);  
-                        } 
-                        break;
-                    default:
-                        break;
-                }
-            } 
-        }
-
-        IoCopyCurrentIrpStackLocationToNext(Irp);
-        return PoCallDriver(commonExtension->LowerDeviceObject, Irp);
-
-    } else {
-
-        if (irpStack->MinorFunction != IRP_MN_SET_POWER &&
-            irpStack->MinorFunction != IRP_MN_QUERY_POWER) {
-           
-            NOTHING;
-
-        } else {
-
-            Irp->IoStatus.Status = STATUS_SUCCESS;
-            Irp->IoStatus.Information = 0;
-
-        }
-        status = Irp->IoStatus.Status;
-
-        ClassCompleteRequest(DeviceObject, Irp, IO_NO_INCREMENT);
-        return status;
-    }
-} // end ClassMinimalPowerHandler()
-
-/*++////////////////////////////////////////////////////////////////////////////
-
-ClassSpinDownPowerHandler()
-
-Routine Description:
-
-    This routine is a callback for disks and other things which require both
-    a start and a stop to be sent to the device.  (actually the starts are
-    almost always optional, since most device power themselves on to process
-    commands, but i digress).
-    
-    Determines proper use of spinup, spindown, and queue locking based upon
-    ScanForSpecialFlags in the FdoExtension.  This is the most common power
-    handler passed into classpnp.sys
-
-Arguments:
-
-    DeviceObject - Supplies the functional device object
-
-    Irp - Supplies the request to be retried.
-
-Return Value:
-
-    None
-
---*/
-NTSTATUS
-NTAPI
-ClassSpinDownPowerHandler(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp
-    )
-{
-    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
-    CLASS_POWER_OPTIONS options;
-
-    fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-    //
-    // this will set all options to FALSE
-    //
-
-    RtlZeroMemory(&options, sizeof(CLASS_POWER_OPTIONS));
-
-    //
-    // check the flags to see what options we need to worry about
-    //
-
-    if (!TEST_FLAG(fdoExtension->ScanForSpecialFlags,
-                  CLASS_SPECIAL_DISABLE_SPIN_DOWN)) {
-        options.HandleSpinDown = TRUE;
-    }
-
-    if (!TEST_FLAG(fdoExtension->ScanForSpecialFlags,
-                  CLASS_SPECIAL_DISABLE_SPIN_UP)) {
-        options.HandleSpinUp = TRUE;
-    }
-
-    if (!TEST_FLAG(fdoExtension->ScanForSpecialFlags,
-                  CLASS_SPECIAL_NO_QUEUE_LOCK)) {
-        options.LockQueue = TRUE;
-    }
-
-    DebugPrint((3, "ClasspPowerHandler: Devobj %p\n"
-                "\t%shandling spin down\n"
-                "\t%shandling spin up\n"
-                "\t%slocking queue\n",
-                DeviceObject,
-                (options.HandleSpinDown ? "" : "not "),
-                (options.HandleSpinUp   ? "" : "not "),
-                (options.LockQueue      ? "" : "not ")
-                ));
-
-    //
-    // do all the dirty work
-    //
-
-    return ClasspPowerHandler(DeviceObject, Irp, options);
-} // end ClassSpinDownPowerHandler()
-
-/*++////////////////////////////////////////////////////////////////////////////
-
-ClassStopUnitPowerHandler()
-
-Routine Description:
-
-    This routine is an outdated call.  To achieve equivalent functionality,
-    the driver should set the following flags in ScanForSpecialFlags in the
-    FdoExtension:
-        
-        CLASS_SPECIAL_DISABLE_SPIN_UP
-        CLASS_SPECIAL_NO_QUEUE_LOCK
-
---*/
-NTSTATUS
-NTAPI
-ClassStopUnitPowerHandler(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp
-    )
-{
-    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
-
-    DebugPrint((0, "ClassStopUnitPowerHandler - Devobj %p using outdated call\n"
-                "Drivers should set the following flags in ScanForSpecialFlags "
-                " in the FDO extension:\n"
-                "\tCLASS_SPECIAL_DISABLE_SPIN_UP\n"
-                "\tCLASS_SPECIAL_NO_QUEUE_LOCK\n"
-                "This will provide equivalent functionality if the power "
-                "routine is then set to ClassSpinDownPowerHandler\n\n",
-                DeviceObject));
-
-    fdoExtension = (PFUNCTIONAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-    SET_FLAG(fdoExtension->ScanForSpecialFlags,
-             CLASS_SPECIAL_DISABLE_SPIN_UP);
-    SET_FLAG(fdoExtension->ScanForSpecialFlags,
-             CLASS_SPECIAL_NO_QUEUE_LOCK);
-
-    return ClassSpinDownPowerHandler(DeviceObject, Irp);
-} // end ClassStopUnitPowerHandler()
-
-/*++////////////////////////////////////////////////////////////////////////////
-
-RetryPowerRequest()
-
-Routine Description:
-
-    This routine reinitializes the necessary fields, and sends the request
-    to the lower driver.
-
-Arguments:
-
-    DeviceObject - Supplies the device object associated with this request.
-
-    Irp - Supplies the request to be retried.
-
-    Context - Supplies a pointer to the power up context for this request.
-
-Return Value:
-
-    None
-
---*/
-VOID
-NTAPI
-RetryPowerRequest(
-    PDEVICE_OBJECT DeviceObject,
-    PIRP Irp,
-    PCLASS_POWER_CONTEXT Context
-    )
-{
-    PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
-    PSCSI_REQUEST_BLOCK srb = &(Context->Srb);
-    LARGE_INTEGER dueTime;
-
-    DebugPrint((1, "(%p)\tDelaying retry by queueing DPC\n", Irp));
-
-    ASSERT(Context->Irp == Irp);
-    ASSERT(Context->DeviceObject == DeviceObject);
-    ASSERT(!TEST_FLAG(Context->Srb.SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER));
-    ASSERT(!TEST_FLAG(Context->Srb.SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE));
-
-    //
-    // reset the retry interval
-    //
-
-    Context->RetryInterval = 0;
-
-    //
-    // Reset byte count of transfer in SRB Extension.
-    //
-
-    srb->DataTransferLength = 0;
-
-    //
-    // Zero SRB statuses.
-    //
-
-    srb->SrbStatus = srb->ScsiStatus = 0;
-
-    //
-    // Set up major SCSI function.
-    //
-
-    nextIrpStack->MajorFunction = IRP_MJ_SCSI;
-
-    //
-    // Save SRB address in next stack for port driver.
-    //
-
-    nextIrpStack->Parameters.Scsi.Srb = srb;
-
-    //
-    // Set the completion routine up again.
-    //
-
-    IoSetCompletionRoutine(Irp, Context->CompletionRoutine, Context,
-                           TRUE, TRUE, TRUE);
-
-
-    if (Context->RetryInterval == 0) {
-
-        DebugPrint((2, "(%p)\tDelaying minimum time (.2 sec)\n", Irp));
-        dueTime.QuadPart = (LONGLONG)1000000 * 2;
-
-    } else {
-
-        DebugPrint((2, "(%p)\tDelaying %x seconds\n",
-                    Irp, Context->RetryInterval));
-        dueTime.QuadPart = (LONGLONG)1000000 * 10 * Context->RetryInterval;
-
-    }
-
-    ClassRetryRequest(DeviceObject, Irp, dueTime);
-
-    return;
-
-} // end RetryRequest()
-
-/*++////////////////////////////////////////////////////////////////////////////
-
-ClasspStartNextPowerIrpCompletion()
-
-Routine Description:
-
-    This routine guarantees that the next power irp (power up or down) is not
-    sent until the previous one has fully completed.
-
---*/
-NTSTATUS
-NTAPI
-ClasspStartNextPowerIrpCompletion(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PVOID Context
-    )
-{
-    if(Irp->PendingReturned) {
-        IoMarkIrpPending(Irp);
-    }
-
-    PoStartNextPowerIrp(Irp);
-    return STATUS_SUCCESS;
-} // end ClasspStartNextPowerIrpCompletion()