You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
745 lines
19 KiB
745 lines
19 KiB
/*++
|
|
|
|
Copyright (c) 2002 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
fdopower.c
|
|
|
|
Abstract:
|
|
|
|
This module contains code to handle
|
|
IRP_MJ_POWER dispatches for SD controllers
|
|
|
|
Authors:
|
|
|
|
Neil Sandlin (neilsa) Jan 1, 2002
|
|
|
|
Environment:
|
|
|
|
Kernel mode only
|
|
|
|
Notes:
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
|
|
//
|
|
// Internal References
|
|
//
|
|
|
|
|
|
NTSTATUS
|
|
SdbusFdoSetSystemPowerState(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN OUT PIRP Irp
|
|
);
|
|
|
|
VOID
|
|
SdbusFdoSetSystemPowerStateCompletion(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN PVOID Context
|
|
);
|
|
|
|
NTSTATUS
|
|
SdbusFdoRequestDevicePowerState(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN DEVICE_POWER_STATE DevicePowerState,
|
|
IN PSDBUS_COMPLETION_ROUTINE CompletionRoutine,
|
|
IN PVOID Context,
|
|
IN BOOLEAN WaitForRequestComplete
|
|
);
|
|
|
|
VOID
|
|
SdbusFdoSystemPowerDeviceIrpComplete(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN UCHAR MinorFunction,
|
|
IN POWER_STATE PowerState,
|
|
IN PVOID Context,
|
|
IN PIO_STATUS_BLOCK IoStatus
|
|
);
|
|
|
|
NTSTATUS
|
|
SdbusFdoSetDevicePowerState(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN OUT PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
SdbusFdoSetDevicePowerStateCompletion(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN PIRP Irp,
|
|
IN PVOID Context
|
|
);
|
|
|
|
VOID
|
|
SdbusFdoSetDevicePowerStateActivateComplete(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN PVOID Context,
|
|
IN NTSTATUS status
|
|
);
|
|
|
|
NTSTATUS
|
|
SdbusSetPdoDevicePowerState(
|
|
IN PDEVICE_OBJECT Pdo,
|
|
IN OUT PIRP Irp
|
|
);
|
|
|
|
VOID
|
|
SdbusPdoInitializeFunctionComplete(
|
|
IN PSD_WORK_PACKET WorkPacket,
|
|
IN NTSTATUS status
|
|
);
|
|
|
|
NTSTATUS
|
|
SdbusPdoCompletePowerIrp(
|
|
IN PPDO_EXTENSION pdoExtension,
|
|
IN PIRP Irp,
|
|
IN NTSTATUS status
|
|
);
|
|
|
|
|
|
//************************************************
|
|
//
|
|
// FDO Routines
|
|
//
|
|
//************************************************
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SdbusSetFdoPowerState(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN OUT PIRP Irp
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Dispatches the IRP based on whether a system power state
|
|
or device power state transition is requested
|
|
|
|
Arguments
|
|
|
|
DeviceObject - Pointer to the functional device object for the sd controller
|
|
Irp - Pointer to the Irp for the power dispatch
|
|
|
|
Return value
|
|
|
|
status
|
|
|
|
--*/
|
|
{
|
|
PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
|
|
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
NTSTATUS status;
|
|
|
|
if (irpStack->Parameters.Power.Type == DevicePowerState) {
|
|
status = SdbusFdoSetDevicePowerState(Fdo, Irp);
|
|
} else if (irpStack->Parameters.Power.Type == SystemPowerState) {
|
|
status = SdbusFdoSetSystemPowerState(Fdo, Irp);
|
|
|
|
} else {
|
|
status = Irp->IoStatus.Status;
|
|
PoStartNextPowerIrp (Irp);
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SdbusFdoSetSystemPowerState(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN OUT PIRP Irp
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Handles system power state IRPs for the host controller.
|
|
|
|
Arguments
|
|
|
|
DeviceObject - Pointer to the functional device object for the sd controller
|
|
Irp - Pointer to the Irp for the power dispatch
|
|
|
|
Return value
|
|
|
|
status
|
|
|
|
--*/
|
|
{
|
|
PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
|
|
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
SYSTEM_POWER_STATE newSystemState = irpStack->Parameters.Power.State.SystemState;
|
|
DEVICE_POWER_STATE devicePowerState;
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
BOOLEAN waitForCompletion = TRUE;
|
|
|
|
try{
|
|
|
|
//
|
|
// Validate new system state
|
|
//
|
|
if (newSystemState >= POWER_SYSTEM_MAXIMUM) {
|
|
status = STATUS_UNSUCCESSFUL;
|
|
leave;
|
|
}
|
|
|
|
//
|
|
// Switch to the appropriate device power state
|
|
//
|
|
|
|
devicePowerState = fdoExtension->DeviceCapabilities.DeviceState[newSystemState];
|
|
|
|
if (devicePowerState == PowerDeviceUnspecified) {
|
|
status = STATUS_UNSUCCESSFUL;
|
|
leave;
|
|
}
|
|
|
|
//
|
|
// Transitioned to system state
|
|
//
|
|
DebugPrint((SDBUS_DEBUG_POWER, "fdo %08x irp %08x transition S state %d => %d, sending D%d\n",
|
|
Fdo, Irp, fdoExtension->SystemPowerState-1, newSystemState-1, devicePowerState-1));
|
|
|
|
fdoExtension->SystemPowerState = newSystemState;
|
|
|
|
//
|
|
// Don't wait for completion if we are coming out of standby/hibernate
|
|
//
|
|
waitForCompletion = (newSystemState != PowerSystemWorking);
|
|
|
|
if (!waitForCompletion) {
|
|
IoMarkIrpPending(Irp);
|
|
}
|
|
|
|
status = SdbusFdoRequestDevicePowerState(fdoExtension->DeviceObject,
|
|
devicePowerState,
|
|
SdbusFdoSetSystemPowerStateCompletion,
|
|
Irp,
|
|
waitForCompletion);
|
|
|
|
|
|
} finally {
|
|
if (!NT_SUCCESS(status)) {
|
|
PoStartNextPowerIrp (Irp);
|
|
Irp->IoStatus.Status = status;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
}
|
|
|
|
if (!waitForCompletion && (status != STATUS_PENDING)) {
|
|
//
|
|
// We've already marked the IRP pending, so we must return STATUS_PENDING
|
|
// (ie fail it asynchronously)
|
|
//
|
|
status = STATUS_PENDING;
|
|
}
|
|
}
|
|
|
|
DebugPrint((SDBUS_DEBUG_POWER, "fdo %08x irp %08x <-- %08x\n", Fdo, Irp, status));
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
VOID
|
|
SdbusFdoSetSystemPowerStateCompletion(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN PVOID Context
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Handles system power state IRPs for the host controller.
|
|
|
|
Arguments
|
|
|
|
DeviceObject - Pointer to the functional device object for the sd controller
|
|
Irp - Pointer to the Irp for the power dispatch
|
|
|
|
Return value
|
|
|
|
status
|
|
|
|
--*/
|
|
{
|
|
PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
|
|
PIRP Irp = Context;
|
|
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
PoSetPowerState (Fdo, SystemPowerState, irpStack->Parameters.Power.State);
|
|
PoStartNextPowerIrp (Irp);
|
|
IoSkipCurrentIrpStackLocation(Irp);
|
|
PoCallDriver(fdoExtension->LowerDevice, Irp);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SdbusFdoRequestDevicePowerState(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN DEVICE_POWER_STATE DevicePowerState,
|
|
IN PSDBUS_COMPLETION_ROUTINE CompletionRoutine,
|
|
IN PVOID Context,
|
|
IN BOOLEAN WaitForRequestComplete
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
This routine is called to request a new device power state for the FDO
|
|
|
|
Parameters
|
|
|
|
DeviceObject - Pointer to the Fdo for the SDBUS controller
|
|
PowerState - Power state requested
|
|
CompletionRoutine - Routine to be called when finished
|
|
Context - Context passed in to the completion routine
|
|
|
|
Return Value
|
|
|
|
Status
|
|
|
|
--*/
|
|
{
|
|
PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
|
|
POWER_STATE powerState;
|
|
NTSTATUS status;
|
|
|
|
powerState.DeviceState = DevicePowerState;
|
|
|
|
if (!WaitForRequestComplete) {
|
|
//
|
|
// Call the completion routine immediately
|
|
//
|
|
(*CompletionRoutine)(Fdo, Context);
|
|
//
|
|
// Request the device power irp to be completed later
|
|
//
|
|
PoRequestPowerIrp(fdoExtension->DeviceObject, IRP_MN_SET_POWER, powerState, NULL, NULL, NULL);
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
} else {
|
|
PSD_POWER_CONTEXT powerContext;
|
|
|
|
powerContext = ExAllocatePool(NonPagedPool, sizeof(SD_POWER_CONTEXT));
|
|
|
|
if (!powerContext) {
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
powerContext->CompletionRoutine = CompletionRoutine;
|
|
powerContext->Context = Context;
|
|
|
|
status = PoRequestPowerIrp(fdoExtension->DeviceObject,
|
|
IRP_MN_SET_POWER,
|
|
powerState,
|
|
SdbusFdoSystemPowerDeviceIrpComplete,
|
|
powerContext,
|
|
NULL
|
|
);
|
|
|
|
}
|
|
return status;
|
|
}
|
|
|
|
|
|
VOID
|
|
SdbusFdoSystemPowerDeviceIrpComplete(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN UCHAR MinorFunction,
|
|
IN POWER_STATE PowerState,
|
|
IN PVOID Context,
|
|
IN PIO_STATUS_BLOCK IoStatus
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
This routine is called on completion of a D irp generated by an S irp.
|
|
|
|
Parameters
|
|
|
|
DeviceObject - Pointer to the Fdo for the SDBUS controller
|
|
MinorFunction - Minor function of the IRP_MJ_POWER request
|
|
PowerState - Power state requested
|
|
Context - Context passed in to the completion routine
|
|
IoStatus - Pointer to the status block which will contain
|
|
the returned status
|
|
Return Value
|
|
|
|
Status
|
|
|
|
--*/
|
|
{
|
|
PSD_POWER_CONTEXT powerContext = Context;
|
|
|
|
// DebugPrint((SDBUS_DEBUG_POWER, "fdo %08x irp %08x request for D%d complete, passing S irp down\n",
|
|
// Fdo, Irp, PowerState.DeviceState-1));
|
|
|
|
(*powerContext->CompletionRoutine)(Fdo, powerContext->Context);
|
|
|
|
ExFreePool(powerContext);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SdbusFdoSetDevicePowerState(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN OUT PIRP Irp
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Handles device power state IRPs for the pccard controller.
|
|
|
|
Arguments
|
|
|
|
DeviceObject - Pointer to the functional device object for the sd controller
|
|
Irp - Pointer to the Irp for the power dispatch
|
|
|
|
Return value
|
|
|
|
status
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS status;
|
|
PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
|
|
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
DEVICE_POWER_STATE devicePowerState = irpStack->Parameters.Power.State.DeviceState;
|
|
|
|
status = IoAcquireRemoveLock(&fdoExtension->RemoveLock, "Sdbu");
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
PoStartNextPowerIrp (Irp);
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return status;
|
|
}
|
|
|
|
if (devicePowerState != PowerDeviceD0) {
|
|
|
|
(*(fdoExtension->FunctionBlock->DisableEvent))(fdoExtension, SDBUS_EVENT_ALL);
|
|
|
|
//
|
|
// Turn card off
|
|
//
|
|
(*(fdoExtension->FunctionBlock->SetPower))(fdoExtension, FALSE, NULL);
|
|
}
|
|
|
|
// anything to do here?
|
|
|
|
// Perform any device-specific tasks that must be done before device power is removed,
|
|
// such as closing the device, completing or flushing any pending I/O, disabling interrupts,
|
|
// queuing subsequent incoming IRPs, and saving device context from which to restore or
|
|
// reinitialize the device.
|
|
|
|
// The driver should not cause a long delay (for example, a delay that a user might find
|
|
// unreasonable for this type of device) while handling the IRP.
|
|
|
|
// The driver should queue any incoming I/O requests until the device has returned to the working state.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IoMarkIrpPending(Irp);
|
|
IoCopyCurrentIrpStackLocationToNext (Irp);
|
|
//
|
|
// Set our completion routine in the Irp..
|
|
//
|
|
IoSetCompletionRoutine(Irp,
|
|
SdbusFdoSetDevicePowerStateCompletion,
|
|
Fdo,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE);
|
|
|
|
PoCallDriver(fdoExtension->LowerDevice, Irp);
|
|
|
|
|
|
return STATUS_PENDING;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SdbusFdoSetDevicePowerStateCompletion(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN PIRP Irp,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
|
|
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
DEVICE_POWER_STATE devicePowerState = irpStack->Parameters.Power.State.DeviceState;
|
|
PSD_WORK_PACKET workPacket;
|
|
BOOLEAN cardInSlot;
|
|
BOOLEAN completeDeviceIrp;
|
|
|
|
try{
|
|
|
|
if (devicePowerState != PowerDeviceD0) {
|
|
completeDeviceIrp = TRUE;
|
|
status = Irp->IoStatus.Status;
|
|
leave;
|
|
}
|
|
|
|
//
|
|
// powering up
|
|
//
|
|
(*(fdoExtension->FunctionBlock->InitController))(fdoExtension);
|
|
|
|
(*(fdoExtension->FunctionBlock->EnableEvent))(fdoExtension, (SDBUS_EVENT_INSERTION | SDBUS_EVENT_REMOVAL));
|
|
|
|
SdbusActivateSocket(Fdo, SdbusFdoSetDevicePowerStateActivateComplete, Irp);
|
|
|
|
completeDeviceIrp = FALSE;
|
|
status = STATUS_MORE_PROCESSING_REQUIRED;
|
|
|
|
} finally {
|
|
if (completeDeviceIrp) {
|
|
PoSetPowerState(Fdo, DevicePowerState, irpStack->Parameters.Power.State);
|
|
PoStartNextPowerIrp (Irp);
|
|
IoReleaseRemoveLock(&fdoExtension->RemoveLock, "Sdbu");
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
SdbusFdoSetDevicePowerStateActivateComplete(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN PVOID Context,
|
|
IN NTSTATUS status
|
|
)
|
|
{
|
|
PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
|
|
PIRP Irp = Context;
|
|
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
PoSetPowerState(Fdo, DevicePowerState, irpStack->Parameters.Power.State);
|
|
PoStartNextPowerIrp(Irp);
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
}
|
|
|
|
|
|
|
|
|
|
//************************************************
|
|
//
|
|
// PDO Routines
|
|
//
|
|
//************************************************
|
|
|
|
|
|
NTSTATUS
|
|
SdbusSetPdoPowerState(
|
|
IN PDEVICE_OBJECT Pdo,
|
|
IN OUT PIRP Irp
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Dispatches the IRP based on whether a system power state
|
|
or device power state transition is requested
|
|
|
|
Arguments
|
|
|
|
Pdo - Pointer to the physical device object for the pc-card
|
|
Irp - Pointer to the Irp for the power dispatch
|
|
|
|
Return value
|
|
|
|
status
|
|
|
|
--*/
|
|
{
|
|
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
PPDO_EXTENSION pdoExtension = Pdo->DeviceExtension;
|
|
PFDO_EXTENSION fdoExtension = pdoExtension->FdoExtension;
|
|
NTSTATUS status;
|
|
|
|
switch (irpStack->Parameters.Power.Type) {
|
|
|
|
|
|
case DevicePowerState:
|
|
status = SdbusSetPdoDevicePowerState(Pdo, Irp);
|
|
break;
|
|
|
|
|
|
case SystemPowerState:
|
|
|
|
pdoExtension->SystemPowerState = irpStack->Parameters.Power.State.SystemState;
|
|
status = SdbusPdoCompletePowerIrp(pdoExtension, Irp, STATUS_SUCCESS);
|
|
break;
|
|
|
|
|
|
default:
|
|
status = SdbusPdoCompletePowerIrp(pdoExtension, Irp, Irp->IoStatus.Status);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SdbusSetPdoDevicePowerState(
|
|
IN PDEVICE_OBJECT Pdo,
|
|
IN OUT PIRP Irp
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Handles the device power state transition for the given SD function.
|
|
|
|
Arguments
|
|
|
|
Pdo - Pointer to the physical device object for the SD function
|
|
Irp - Irp for the system state transition
|
|
|
|
Return value
|
|
|
|
status
|
|
|
|
--*/
|
|
{
|
|
PPDO_EXTENSION pdoExtension = Pdo->DeviceExtension;
|
|
PFDO_EXTENSION fdoExtension = pdoExtension->FdoExtension;
|
|
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
DEVICE_POWER_STATE newDevicePowerState;
|
|
POWER_STATE newPowerState;
|
|
NTSTATUS status;
|
|
|
|
newDevicePowerState = irpStack->Parameters.Power.State.DeviceState;
|
|
|
|
DebugPrint((SDBUS_DEBUG_POWER, "pdo %08x transitioning D state %d => %d\n",
|
|
Pdo, pdoExtension->DevicePowerState, newDevicePowerState));
|
|
|
|
if (newDevicePowerState == pdoExtension->DevicePowerState) {
|
|
status = SdbusPdoCompletePowerIrp(pdoExtension, Irp, STATUS_SUCCESS);
|
|
return status;
|
|
}
|
|
|
|
if (newDevicePowerState == PowerDeviceD0) {
|
|
PSD_WORK_PACKET workPacket;
|
|
//
|
|
// Power up, initialize function
|
|
//
|
|
|
|
status = SdbusBuildWorkPacket(fdoExtension,
|
|
SDWP_INITIALIZE_FUNCTION,
|
|
SdbusPdoInitializeFunctionComplete,
|
|
Irp,
|
|
&workPacket);
|
|
if (!NT_SUCCESS(status)) {
|
|
status = SdbusPdoCompletePowerIrp(pdoExtension, Irp, status);
|
|
} else {
|
|
|
|
IoMarkIrpPending(Irp);
|
|
|
|
workPacket->PdoExtension = pdoExtension;
|
|
|
|
SdbusQueueWorkPacket(fdoExtension, workPacket, WP_TYPE_SYSTEM);
|
|
status = STATUS_PENDING;
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// moving to a low power state
|
|
//
|
|
|
|
newPowerState.DeviceState = newDevicePowerState;
|
|
|
|
PoSetPowerState(Pdo, DevicePowerState, newPowerState);
|
|
pdoExtension->DevicePowerState = newDevicePowerState;
|
|
|
|
status = SdbusPdoCompletePowerIrp(pdoExtension, Irp, STATUS_SUCCESS);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
SdbusPdoInitializeFunctionComplete(
|
|
IN PSD_WORK_PACKET WorkPacket,
|
|
IN NTSTATUS status
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
PPDO_EXTENSION pdoExtension = WorkPacket->PdoExtension;
|
|
PIRP Irp = WorkPacket->CompletionContext;
|
|
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
DEVICE_POWER_STATE newDevicePowerState;
|
|
POWER_STATE newPowerState;
|
|
|
|
newDevicePowerState = irpStack->Parameters.Power.State.DeviceState;
|
|
newPowerState.DeviceState = newDevicePowerState;
|
|
PoSetPowerState(pdoExtension->DeviceObject, DevicePowerState, newPowerState);
|
|
|
|
pdoExtension->DevicePowerState = newDevicePowerState;
|
|
|
|
SdbusPdoCompletePowerIrp(pdoExtension, Irp, status);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SdbusPdoCompletePowerIrp(
|
|
IN PPDO_EXTENSION pdoExtension,
|
|
IN PIRP Irp,
|
|
IN NTSTATUS status
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Completion routine for the Power Irp directed to the PDO of the
|
|
SD function.
|
|
|
|
|
|
Arguments
|
|
|
|
DeviceObject - Pointer to the PDO for the SD function
|
|
Irp - Irp that needs to be completed
|
|
|
|
Return Value
|
|
|
|
status
|
|
|
|
--*/
|
|
{
|
|
InterlockedDecrement(&pdoExtension->DeletionLock);
|
|
Irp->IoStatus.Status = status;
|
|
PoStartNextPowerIrp(Irp);
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return status;
|
|
}
|