?? usblspwr.c
字號(hào):
// Trigger Self-requested power irp completed event;
// The caller is waiting for completion
KeSetEvent(&deviceExtension->SelfRequestedPowerIrpEvent, 1, FALSE);
}
USBLS120_DecrementIoCount(deviceObject);
USBLS120_KdPrintCond( DBGLVL_HIGH, !NT_SUCCESS(ntStatus),("Exit USBLS120_PoSelfRequestCompletion() FAILED, ntStatus = 0x%x\n", ntStatus ));
return ntStatus;
}
BOOLEAN
USBLS120_SetDevicePowerState(
IN PDEVICE_OBJECT DeviceObject,
IN DEVICE_POWER_STATE DeviceState
)
/*++
Routine Description:
This routine is called when An IRP_MN_SET_POWER of type 'DevicePowerState'
has been received by USBLS120_ProcessPowerIrp().
Arguments:
DeviceObject - Pointer to the device object for the class device.
DeviceState - Device specific power state to set the device in to.
Return Value:
For requests to DeviceState D0 ( fully on ), returns TRUE to signal caller
that we must set a completion routine and finish there.
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension;
BOOLEAN fRes = FALSE;
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
switch (DeviceState) {
case PowerDeviceD3:
//
// Device will be going OFF,
// TODO: add any needed device-dependent code to save state here.
// ( We have nothing to do in this sample )
//
USBLS120_KdPrint( DBGLVL_MEDIUM,("USBLS120_SetDevicePowerState() PowerDeviceD3 (OFF)\n"));
deviceExtension->CurrentDevicePowerState = DeviceState;
break;
case PowerDeviceD1:
case PowerDeviceD2:
//
// power states D1,D2 translate to USB suspend
USBLS120_KdPrint( DBGLVL_MEDIUM,("USBLS120_SetDevicePowerState() %s\n",
USBLS120_StringForDevState(DeviceState) ));
deviceExtension->CurrentDevicePowerState = DeviceState;
break;
case PowerDeviceD0:
USBLS120_KdPrint( DBGLVL_MEDIUM,("USBLS120_SetDevicePowerState() PowerDeviceD0 (ON)\n"));
// We'll need to finish the rest in the completion routine;
// signal caller we're going to D0 and will need to set a completion routine
fRes = TRUE;
// Caller will pass on to PDO ( Physical Device object )
break;
default:
USBLS120_KdPrint( DBGLVL_MEDIUM,(" Bogus DeviceState = %x\n", DeviceState));
}
return fRes;
}
NTSTATUS
USBLS120_QueryCapabilities(
IN PDEVICE_OBJECT PdoDeviceObject,
IN PDEVICE_CAPABILITIES DeviceCapabilities
)
/*++
Routine Description:
This routine generates an internal IRP from this driver to the PDO
to obtain information on the Physical Device Object's capabilities.
We are most interested in learning which system power states
are to be mapped to which device power states for honoring IRP_MJ_SET_POWER Irps.
This is a blocking call which waits for the IRP completion routine
to set an event on finishing.
Arguments:
DeviceObject - Physical DeviceObject for this USB controller.
Return Value:
NTSTATUS value from the IoCallDriver() call.
--*/
{
PIO_STACK_LOCATION nextStack;
PIRP irp;
NTSTATUS ntStatus;
KEVENT event;
// This is a DDK-defined DBG-only macro that ASSERTS we are not running pageable code
// at higher than APC_LEVEL.
PAGED_CODE();
// Build an IRP for us to generate an internal query request to the PDO
irp = IoAllocateIrp(PdoDeviceObject->StackSize, FALSE);
if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
// IoGetNextIrpStackLocation gives a higher level driver access to the next-lower
// driver's I/O stack location in an IRP so the caller can set it up for the lower driver.
nextStack = IoGetNextIrpStackLocation(irp);
USBLS120_ASSERT(nextStack != NULL);
nextStack->MajorFunction= IRP_MJ_PNP;
nextStack->MinorFunction= IRP_MN_QUERY_CAPABILITIES;
// init an event to tell us when the completion routine's been called
KeInitializeEvent(&event, NotificationEvent, FALSE);
// Set a completion routine so it can signal our event when
// the next lower driver is done with the Irp
IoSetCompletionRoutine(
irp,
USBLS120_IrpCompletionRoutine,
&event, // pass the event as Context to completion routine
TRUE, // invoke on success
TRUE, // invoke on error
TRUE // invoke on cancellation of the Irp
);
// set our pointer to the DEVICE_CAPABILITIES struct
nextStack->Parameters.DeviceCapabilities.Capabilities = DeviceCapabilities;
ntStatus = IoCallDriver(PdoDeviceObject, irp);
USBLS120_KdPrint( DBGLVL_MEDIUM,(" USBLS120_QueryCapabilities() ntStatus from IoCallDriver to PCI = 0x%x\n", ntStatus));
if (ntStatus == STATUS_PENDING) {
// wait for irp to complete
KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL
);
}
// failed? this is probably a bug
USBLS120_KdPrintCond( DBGLVL_DEFAULT,(!NT_SUCCESS(ntStatus)), ("USBLS120_QueryCapabilities() failed\n"));
IoFreeIrp(irp);
return ntStatus;
}
BOOLEAN
USBLS120_CanAcceptIoRequests(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Check device extension status flags;
Can't accept a new io request if device:
1) is removed,
2) has never been started,
3) is stopped,
4) has a remove request pending, or
5) has a stop device pending
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
device.
Return Value:
return TRUE if can accept new io requests, else FALSE
--*/
{
PDEVICE_EXTENSION deviceExtension;
BOOLEAN fCan = FALSE;
deviceExtension = DeviceObject->DeviceExtension;
//flag set when processing IRP_MN_REMOVE_DEVICE
if ( !deviceExtension->DeviceRemoved &&
// device must be started( enabled )
deviceExtension->DeviceStarted &&
// flag set when driver has answered success to IRP_MN_QUERY_REMOVE_DEVICE
!deviceExtension->RemoveDeviceRequested &&
// flag set when driver has answered success to IRP_MN_QUERY_STOP_DEVICE
!deviceExtension->StopDeviceRequested ){
fCan = TRUE;
}
USBLS120_KdPrintCond( DBGLVL_MAXIMUM, !fCan, ("**** FALSE return from USBLS120_CanAcceptIoRequests()!\n"));
return fCan;
}
NTSTATUS
USBLS120_PdoProcessPowerIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is our PDO's dispatch table function for IRP_MJ_POWER.
It processes the Power IRPs sent to the PDO for this device.
Arguments:
DeviceObject - pointer to our device object (FDO)
Irp - pointer to an I/O Request Packet
Return Value:
NT status code
--*/
{
PIO_STACK_LOCATION irpStack;
NTSTATUS NtStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension;
BOOLEAN fGoingToD0 = FALSE;
POWER_STATE sysPowerState, desiredDevicePowerState;
USBLS120_KdPrint( DBGLVL_DEFAULT,(" USBLS120_PdoProcessPowerIrp() IRP_MJ_POWER\n"));
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation (Irp);
USBLS120_IncrementIoCount(DeviceObject);
switch (irpStack->MinorFunction)
{
case IRP_MN_SET_POWER:
USBLS120_KdPrint(1, ("IRP_MN_SET_POWER pdo\n"));
NtStatus = Irp->IoStatus.Status = USBLS120_PdoSetPower(DeviceObject, Irp);
break;
case IRP_MN_WAIT_WAKE:
USBLS120_KdPrint(1,("IRP_MN_WAIT_WAKE pdo\n"));
NtStatus = Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
break;
case IRP_MN_QUERY_POWER:
USBLS120_KdPrint(1,("IRP_MN_QUERY_POWER pdo\n"));
NtStatus = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
default:
NtStatus = Irp->IoStatus.Status;
USBLS120_KdPrint(1,("POWER IRP IRP_MN_[%d] not handled\n", irpStack->MinorFunction));
}
PoStartNextPowerIrp(Irp);
USBLS120_DecrementIoCount(DeviceObject);
USBLS120_KdPrint( DBGLVL_MEDIUM, ( "Exit USBLS120_PdoProcessPowerIrp() NtStatus = 0x%x\n", NtStatus ) );
return NtStatus;
}
NTSTATUS
USBLS120_PdoSetPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/* ++
*
* Description:
*
* Handles a IRP_MN_SET_POWER for our child PDO
*
* Arguments:
*
* Return:
*
* NTSTATUS
*
* -- */
{
NTSTATUS ntStatus;
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation(Irp);
DeviceExtension = DeviceObject->DeviceExtension;
USBLS120_KdPrint(1,("USBLS120_PdoSetPower pdo\n"));
ntStatus = STATUS_SUCCESS;
switch (irpStack->Parameters.Power.Type)
{
case SystemPowerState:
USBLS120_KdPrint(1,("SystemPowerState pdo\n"));
break;
case DevicePowerState:
USBLS120_KdPrint(1,("DevicePowerState pdo\n"));
switch (irpStack->Parameters.Power.State.DeviceState)
{
case PowerDeviceD0:
case PowerDeviceD1:
case PowerDeviceD2:
case PowerDeviceD3:
break;
default:
USBLS120_KdPrint(1,("Bad Power State\n"));
break;
}
break;
default:
ntStatus = STATUS_INVALID_PARAMETER;
}
return ntStatus;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -