Example #1
0
NTSTATUS NTAPI HandleSystemQueryPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS           ntStatus;
    PDEVICE_EXTENSION  deviceExtension;
    SYSTEM_POWER_STATE systemState;
    PIO_STACK_LOCATION irpStack;

    FreeBT_DbgPrint(3, ("FBTUSB: HandleSystemQueryPower: Entered\n"));

    // initialize variables
    deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    systemState = irpStack->Parameters.Power.State.SystemState;

    FreeBT_DbgPrint(3, ("FBTUSB: HandleSystemQueryPower: Query for system power state S%X\n"
                        "FBTUSB: HandleSystemQueryPower: Current system power state S%X\n",
                         systemState - 1,
                         deviceExtension->SysPower - 1));

    // Fail a query for a power state incompatible with waking up the system
    if ((deviceExtension->WaitWakeEnable) && (systemState > deviceExtension->DeviceCapabilities.SystemWake))
    {
        FreeBT_DbgPrint(1, ("FBTUSB: HandleSystemQueryPower: Query for an incompatible system power state\n"));

        PoStartNextPowerIrp(Irp);
        Irp->IoStatus.Status = ntStatus = STATUS_INVALID_DEVICE_STATE;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        FreeBT_DbgPrint(3, ("FBTUSB: HandleSystemQueryPower::"));
        FreeBT_IoDecrement(deviceExtension);

        return ntStatus;

    }

    // if querying for a lower S-state, issue a wait-wake
    if((systemState > deviceExtension->SysPower) && (deviceExtension->WaitWakeEnable))
    {
        IssueWaitWake(deviceExtension);

    }

    IoCopyCurrentIrpStackLocationToNext(Irp);
    IoSetCompletionRoutine(
            Irp,
            (PIO_COMPLETION_ROUTINE)SysPoCompletionRoutine,
            deviceExtension,
            TRUE,
            TRUE,
            TRUE);

    ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
    FreeBT_DbgPrint(3, ("FBTUSB: HandleSystemQueryPower: Leaving\n"));

    return STATUS_PENDING;

}
Example #2
0
VOID NTAPI WaitWakeCallback(
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PVOID Context,
    IN PIO_STATUS_BLOCK IoStatus)
{
    NTSTATUS               ntStatus;
    POWER_STATE            powerState;
    PDEVICE_EXTENSION      deviceExtension;

    FreeBT_DbgPrint(3, ("FBTUSB: WaitWakeCallback: Entered\n"));

    deviceExtension = (PDEVICE_EXTENSION) Context;

    InterlockedExchange(&deviceExtension->FlagWWOutstanding, 0);

    if(!NT_SUCCESS(IoStatus->Status))
    {
        return;

    }

    // wake up the device
    if(deviceExtension->DevPower == PowerDeviceD0)
    {
        FreeBT_DbgPrint(3, ("FBTUSB: WaitWakeCallback: Device already powered up...\n"));

        return;

    }

    FreeBT_DbgPrint(3, ("FBTUSB: WaitWakeCallback::"));
    FreeBT_IoIncrement(deviceExtension);

    powerState.DeviceState = PowerDeviceD0;
    ntStatus = PoRequestPowerIrp(deviceExtension->PhysicalDeviceObject,
                                 IRP_MN_SET_POWER,
                                 powerState,
                                 (PREQUEST_POWER_COMPLETE) WWIrpCompletionFunc,
                                 deviceExtension,
                                 NULL);

    if(deviceExtension->WaitWakeEnable)
    {
        IssueWaitWake(deviceExtension);

    }

    FreeBT_DbgPrint(3, ("FBTUSB: WaitWakeCallback: Leaving\n"));

    return;

}
Example #3
0
static VOID IdleNotificationCallback(IN PTDeviceExtension DeviceExtension)
{
	NTSTATUS                ntStatus;
	POWER_STATE             powerState;
	KEVENT                  irpCompletionEvent;
	PTIrpCompletionContext	irpContext;

	BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationCallback - process\n"));
	if(DeviceExtension->DeviceState != WORKING) 
		return;

	if(DeviceExtension->WaitWakeEnable) 
		IssueWaitWake(DeviceExtension);
	irpContext = (PTIrpCompletionContext)ExAllocatePool(NonPagedPool, sizeof(TIrpCompletionContext));
	if(!irpContext) 
	{
		BulkUsb_DbgPrint(1, ("file bulkdev: Failed to alloc memory for irpContext\n"));
		//ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		return;
	}
	BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationCallback::"));
	BulkUsb_IoIncrement(DeviceExtension);
	powerState.DeviceState = DeviceExtension->PowerDownLevel;
	KeInitializeEvent(&irpCompletionEvent, NotificationEvent, FALSE);
	irpContext->DeviceExtension = DeviceExtension;
	irpContext->Event = &irpCompletionEvent;
	ntStatus = PoRequestPowerIrp(
				DeviceExtension->PhysicalDeviceObject, 
				IRP_MN_SET_POWER, 
				powerState, 
				(PREQUEST_POWER_COMPLETE) PoIrpCompletionFunc,
				irpContext, 
				NULL);

	if(STATUS_PENDING == ntStatus) 
	{
		BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationCallback::"
						"waiting for the power irp to complete\n"));
		KeWaitForSingleObject(&irpCompletionEvent,
					Executive,
					KernelMode,
					FALSE,
					NULL);
	}
	ExFreePool(irpContext);
	BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationCallback - ends\n"));
}
Example #4
0
NTSTATUS
HandleSystemQueryPower(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++
 
Routine Description:

    This routine handles the irp with minor function of type IRP_MN_QUERY_POWER
    for the system power states.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet sent by the power manager.

Return Value:

    NT status value

--*/
{
    NTSTATUS           ntStatus;
    PDEVICE_EXTENSION  deviceExtension;
    SYSTEM_POWER_STATE systemState;
    PIO_STACK_LOCATION irpStack;
    
    MobiUsb_DbgPrint(3, ("file mobipwr: HandleSystemQueryPower - begins\n"));

    //
    // initialize variables
    //

    deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    systemState = irpStack->Parameters.Power.State.SystemState;

    MobiUsb_DbgPrint(3, ("file mobipwr: Query for system power state S%X\n"
                         "Current system power state S%X\n",
                         systemState - 1,
                         deviceExtension->SysPower - 1));

    //
    // if querying for a lower S-state, issue a wait-wake
    //

    if((systemState > deviceExtension->SysPower) &&
       (deviceExtension->WaitWakeEnable)) {

        IssueWaitWake(deviceExtension);
    }

    IoCopyCurrentIrpStackLocationToNext(Irp);

    IoSetCompletionRoutine(
            Irp, 
            (PIO_COMPLETION_ROUTINE)SysPoCompletionRoutine,
            deviceExtension, 
            TRUE, 
            TRUE, 
            TRUE);

    ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

    MobiUsb_DbgPrint(3, ("file mobipwr: HandleSystemQueryPower - ends\n"));

    return STATUS_PENDING;
}
Example #5
0
VOID
WaitWakeCallback( 
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PVOID Context,
    IN PIO_STATUS_BLOCK IoStatus
    )
/*++
 
Routine Description:

    This is the PoRequest completion routine for the wait wake irp.

Arguments:

    DeviceObject - pointer to device object
    MinorFunction - irp minor function
    PowerState - power state of the irp.
    Context - context passed to the completion routine.
    IoStatus - status block.

Return Value:

    None

--*/
{
    NTSTATUS               ntStatus;
    POWER_STATE            powerState;
    PDEVICE_EXTENSION      deviceExtension;

    MobiUsb_DbgPrint(3, ("file mobipwr: WaitWakeCallback - begins\n"));

    deviceExtension = (PDEVICE_EXTENSION) Context;

    InterlockedExchange(&deviceExtension->FlagWWOutstanding, 0);

    if(!NT_SUCCESS(IoStatus->Status)) {

        return;
    }

    //
    // wake up the device
    //

    if(deviceExtension->DevPower == PowerDeviceD0) {

        MobiUsb_DbgPrint(3, ("file mobipwr: device already powered up...\n"));

        return;
    }

    MobiUsb_DbgPrint(3, ("file mobipwr: WaitWakeCallback::"));
    MobiUsb_IoIncrement(deviceExtension);

    powerState.DeviceState = PowerDeviceD0;

    ntStatus = PoRequestPowerIrp(deviceExtension->PhysicalDeviceObject, 
                                 IRP_MN_SET_POWER, 
                                 powerState, 
                                 (PREQUEST_POWER_COMPLETE) WWIrpCompletionFunc,
                                 deviceExtension, 
                                 NULL);

    if(deviceExtension->WaitWakeEnable) {

        IssueWaitWake(deviceExtension);
    }

    MobiUsb_DbgPrint(3, ("file mobipwr: WaitWakeCallback - ends\n"));

    return;
}
Example #6
0
NTSTATUS
HandleSystemQueryPower(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++
 
Routine Description:

    This routine handles the irp with minor function of type IRP_MN_QUERY_POWER
    for the system power states.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet sent by the power manager.

Return Value:

    NT status value

--*/
{
    NTSTATUS           ntStatus;
    PDEVICE_EXTENSION  deviceExtension;
    SYSTEM_POWER_STATE systemState;
    PIO_STACK_LOCATION irpStack;
    
    BulkUsb_DbgPrint(3, ("HandleSystemQueryPower - begins\n"));

    //
    // initialize variables
    //

    deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    systemState = irpStack->Parameters.Power.State.SystemState;

    BulkUsb_DbgPrint(3, ("Query for system power state S%X\n"
                         "Current system power state S%X\n",
                         systemState - 1,
                         deviceExtension->SysPower - 1));

    //
    // Fail a query for a power state incompatible with waking up the system
    //

    if((deviceExtension->WaitWakeEnable) &&
       (systemState > deviceExtension->DeviceCapabilities.SystemWake)) {

        BulkUsb_DbgPrint(1, ("Query for an incompatible system power state\n"));

        PoStartNextPowerIrp(Irp);

        Irp->IoStatus.Status = ntStatus = STATUS_INVALID_DEVICE_STATE;
        Irp->IoStatus.Information = 0;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        BulkUsb_DbgPrint(3, ("HandleSystemQueryPower::"));
        BulkUsb_IoDecrement(deviceExtension);

        return ntStatus;
    }

    //
    // if querying for a lower S-state, issue a wait-wake
    //

    if((systemState > deviceExtension->SysPower) &&
       (deviceExtension->WaitWakeEnable)) {

        IssueWaitWake(deviceExtension);
    }

    IoCopyCurrentIrpStackLocationToNext(Irp);

    IoSetCompletionRoutine(
            Irp, 
            (PIO_COMPLETION_ROUTINE)SysPoCompletionRoutine,
            deviceExtension, 
            TRUE, 
            TRUE, 
            TRUE);

    ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

    BulkUsb_DbgPrint(3, ("HandleSystemQueryPower - ends\n"));

    return STATUS_PENDING;
}
Example #7
0
VOID
IdleNotificationCallback(
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:

  "A pointer to a callback function in your driver is passed down the stack with
   this IOCTL, and it is this callback function that is called by USBHUB when it
   safe for your device to power down."

  "When the callback in your driver is called, all you really need to do is to
   to first ensure that a WaitWake Irp has been submitted for your device, if 
   remote wake is possible for your device and then request a SetD2 (or DeviceWake)"

Arguments:

    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/
{
    NTSTATUS                ntStatus;
    POWER_STATE             powerState;
    KEVENT                  irpCompletionEvent;
    PIRP_COMPLETION_CONTEXT irpContext;

    BulkUsb_DbgPrint(3, ("IdleNotificationCallback - begins\n"));

    //
    // Dont idle, if the device was just disconnected or being stopped
    // i.e. return for the following DeviceState(s)
    // NotStarted, Stopped, PendingStop, PendingRemove, SurpriseRemoved, Removed
    //

    if(DeviceExtension->DeviceState != Working) {

        return;
    }

    //
    // If there is not already a WW IRP pending, submit one now
    //
    if(DeviceExtension->WaitWakeEnable) {

        IssueWaitWake(DeviceExtension);
    }


    //
    // power down the device
    //

    irpContext = (PIRP_COMPLETION_CONTEXT) 
                 ExAllocatePool(NonPagedPool,
                                sizeof(IRP_COMPLETION_CONTEXT));

    if(!irpContext) {

        BulkUsb_DbgPrint(1, ("Failed to alloc memory for irpContext\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }
    else {

        //
        // increment the count. In the HoldIoRequestWorkerRoutine, the
        // count is decremented twice (one for the system Irp and the 
        // other for the device Irp. An increment here compensates for 
        // the sytem irp..The decrement corresponding to this increment 
        // is in the completion function
        //

        BulkUsb_DbgPrint(3, ("IdleNotificationCallback::"));
        BulkUsb_IoIncrement(DeviceExtension);

        powerState.DeviceState = DeviceExtension->PowerDownLevel;

        KeInitializeEvent(&irpCompletionEvent, NotificationEvent, FALSE);

        irpContext->DeviceExtension = DeviceExtension;
        irpContext->Event = &irpCompletionEvent;

        ntStatus = PoRequestPowerIrp(
                          DeviceExtension->PhysicalDeviceObject, 
                          IRP_MN_SET_POWER, 
                          powerState, 
                          (PREQUEST_POWER_COMPLETE) PoIrpCompletionFunc,
                          irpContext, 
                          NULL);

        if(STATUS_PENDING == ntStatus) {

            BulkUsb_DbgPrint(3, ("IdleNotificationCallback::"
                           "waiting for the power irp to complete\n"));

            KeWaitForSingleObject(&irpCompletionEvent,
                                  Executive,
                                  KernelMode,
                                  FALSE,
                                  NULL);
        }
    }
    
    if(!NT_SUCCESS(ntStatus)) {

        if(irpContext) {

            ExFreePool(irpContext);
        }
    }

    BulkUsb_DbgPrint(3, ("IdleNotificationCallback - ends\n"));
}