Ejemplo n.º 1
0
NTSTATUS UsbDev::SendDeviceSetPower(
	DEVICE_POWER_STATE devpower, 
	BOOL bWait)
{ 
	POWER_STATE poState;
	NTSTATUS ntStatus;

	poState.DeviceState = devpower;

	if (bWait)
	{
		KEVENT Event;
		USB_SDSP_CONTEXT context;
		
		KeInitializeEvent(&Event, NotificationEvent, FALSE);
		context.pEvent = &Event;
		ntStatus = PoRequestPowerIrp(m_pLdo, IRP_MN_SET_POWER, poState,
			(PREQUEST_POWER_COMPLETE) SendDeviceSetPowerComplete, &context, NULL);

		if (ntStatus == STATUS_PENDING)
		{
			KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
			ntStatus = context.ntStatus;
		}
	}
	else
		ntStatus = PoRequestPowerIrp(m_pLdo, IRP_MN_SET_POWER, poState, NULL, NULL, NULL);

	DBGU_WARNING("SendDeviceSetPower D%d return %X\n", (devpower-1), ntStatus);
	return ntStatus;
}
Ejemplo n.º 2
0
void power_set_device_state(libusb_device_t *dev,
                            DEVICE_POWER_STATE device_state, bool_t block)
{
    NTSTATUS status;
    KEVENT event;
    POWER_STATE power_state;

    power_state.DeviceState = device_state;

	USBMSG("setting device power state to D%d %s\n", 
		power_state.DeviceState - PowerDeviceD0, dev->device_id);

    if (block) /* wait for IRP to complete */
    {
        KeInitializeEvent(&event, NotificationEvent, FALSE);

        /* set the device power state and wait for completion */
        status = PoRequestPowerIrp(dev->physical_device_object,
                                   IRP_MN_SET_POWER,
                                   power_state,
                                   on_power_set_device_state_complete,
                                   &event, NULL);

        if (status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
        }
    }
    else
    {
        PoRequestPowerIrp(dev->physical_device_object, IRP_MN_SET_POWER,
                          power_state, NULL, NULL, NULL);
    }
}
Ejemplo n.º 3
0
NTSTATUS
NTAPI
PcRequestNewPowerState(
    IN  PDEVICE_OBJECT DeviceObject,
    IN  DEVICE_POWER_STATE RequestedNewState)
{
    KEVENT Event;
    NTSTATUS Status;
    POWER_STATE PowerState;
    PPCLASS_DEVICE_EXTENSION DeviceExt;

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!DeviceObject || !RequestedNewState)
        return STATUS_INVALID_PARAMETER;

    DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);

    PowerState.DeviceState = RequestedNewState;
    PowerState.SystemState = PowerSystemUnspecified;

    Status = PoRequestPowerIrp(DeviceExt->PhysicalDeviceObject, IRP_MN_SET_POWER, PowerState, PwrCompletionCallback, (PVOID)&Event, NULL);
    if (NT_SUCCESS(Status))
    {
        KeWaitForSingleObject((PVOID)&Event, Executive, KernelMode, FALSE, NULL);
    }


    return Status;
}
Ejemplo n.º 4
0
static NTSTATUS vboxUsbPwrIoRequestDev(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp)
{
    PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
    POWER_STATE PwrState;
    PwrState.SystemState = pSl->Parameters.Power.State.SystemState;
    PwrState.DeviceState = pDevExt->DdiState.DevCaps.DeviceState[PwrState.SystemState];

    NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
    PVBOXUSB_PWRDEV_CTX pDevCtx = (PVBOXUSB_PWRDEV_CTX)vboxUsbMemAlloc(sizeof (*pDevCtx));
    Assert(pDevCtx);
    if (pDevCtx)
    {
        pDevCtx->pDevExt = pDevExt;
        pDevCtx->pIrp = pIrp;

        Status = PoRequestPowerIrp(pDevExt->pPDO, pSl->MinorFunction, PwrState,
                        vboxUsbPwrIoDeviceCompletion, pDevCtx, NULL);
        Assert(NT_SUCCESS(Status));
        if (NT_SUCCESS(Status))
        {
            return STATUS_MORE_PROCESSING_REQUIRED;
        }

        vboxUsbMemFree(pDevCtx);
    }

    PoStartNextPowerIrp(pIrp);
    pIrp->IoStatus.Status = Status;
    pIrp->IoStatus.Information = 0;
    vboxUsbDdiStateRelease(pDevExt);

    /* the "real" Status is stored in pIrp->IoStatus.Status,
     * return success here to complete the Io */
    return STATUS_SUCCESS;
}
Ejemplo n.º 5
0
NTSTATUS NTAPI IssueWaitWake(IN PDEVICE_EXTENSION DeviceExtension)
{
    POWER_STATE poState;
    NTSTATUS    ntStatus;

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

    if(InterlockedExchange(&DeviceExtension->FlagWWOutstanding, 1))
    {
        return STATUS_DEVICE_BUSY;

    }

    InterlockedExchange(&DeviceExtension->FlagWWCancel, 0);

    // lowest state from which this Irp will wake the system
    poState.SystemState = DeviceExtension->DeviceCapabilities.SystemWake;
    ntStatus = PoRequestPowerIrp(DeviceExtension->PhysicalDeviceObject,
                                 IRP_MN_WAIT_WAKE,
                                 poState,
                                 (PREQUEST_POWER_COMPLETE) WaitWakeCallback,
                                 DeviceExtension,
                                 &DeviceExtension->WaitWakeIrp);

    if(!NT_SUCCESS(ntStatus))
    {
        InterlockedExchange(&DeviceExtension->FlagWWOutstanding, 0);

    }

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

    return ntStatus;

}
Ejemplo n.º 6
0
NTSTATUS
NTAPI
USBH_HubSetD0(IN PUSBHUB_FDO_EXTENSION HubExtension)
{
    PUSBHUB_FDO_EXTENSION RootHubDevExt;
    NTSTATUS Status;
    KEVENT Event;
    POWER_STATE PowerState;

    DPRINT("USBH_HubSetD0: HubExtension - %p\n", HubExtension);

    RootHubDevExt = USBH_GetRootHubExtension(HubExtension);

    if (RootHubDevExt->SystemPowerState.SystemState != PowerSystemWorking)
    {
        Status = STATUS_INVALID_DEVICE_STATE;
        return Status;
    }

    if (HubExtension->HubFlags & USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST)
    {
        DPRINT("USBH_HubSetD0: HubFlags - %lX\n", HubExtension->HubFlags);

        KeWaitForSingleObject(&HubExtension->IdleEvent,
                              Suspended,
                              KernelMode,
                              FALSE,
                              NULL);
    }

    KeInitializeEvent(&Event, NotificationEvent, FALSE);

    PowerState.DeviceState = PowerDeviceD0;

    Status = PoRequestPowerIrp(HubExtension->LowerPDO,
                               IRP_MN_SET_POWER,
                               PowerState,
                               USBH_HubESDRecoverySetD3Completion,
                               &Event,
                               NULL);

    if (Status == STATUS_PENDING)
    {
       Status = KeWaitForSingleObject(&Event,
                                      Suspended,
                                      KernelMode,
                                      FALSE,
                                      NULL);
    }

    while (HubExtension->HubFlags & USBHUB_FDO_FLAG_WAKEUP_START)
    {
        USBH_Wait(10);
    }

    return Status;
}
Ejemplo n.º 7
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;

}
Ejemplo n.º 8
0
NTSTATUS
IssueWaitWake(
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:

    This routine will PoRequest a WAIT WAKE irp for the device

Arguments:

    DeviceExtension - pointer to device extension

Return Value:

    NT status value.

--*/
{
    POWER_STATE poState;
    NTSTATUS    ntStatus;

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

    if(InterlockedExchange(&DeviceExtension->FlagWWOutstanding, 1)) {

        return STATUS_DEVICE_BUSY;
    }

    InterlockedExchange(&DeviceExtension->FlagWWCancel, 0);

    //
    // lowest state from which this Irp will wake the system
    //

    poState.SystemState = DeviceExtension->DeviceCapabilities.SystemWake;

    ntStatus = PoRequestPowerIrp(DeviceExtension->PhysicalDeviceObject, 
                                 IRP_MN_WAIT_WAKE,
                                 poState, 
                                 (PREQUEST_POWER_COMPLETE) WaitWakeCallback,
                                 DeviceExtension, 
                                 &DeviceExtension->WaitWakeIrp);

    if(!NT_SUCCESS(ntStatus)) {

        InterlockedExchange(&DeviceExtension->FlagWWOutstanding, 0);
    }

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

    return ntStatus;
}
Ejemplo n.º 9
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"));
}
Ejemplo n.º 10
0
_Must_inspect_result_
FORCEINLINE
NTSTATUS
FxIrp::RequestPowerIrp(
    __in MdDeviceObject  DeviceObject,
    __in UCHAR  MinorFunction,
    __in POWER_STATE  PowerState,
    __in MdRequestPowerComplete  CompletionFunction,
    __in PVOID  Context
    )
{
    //
    // Prefast enforces that NULL is passed for IRP parameter (last parameter)  
    // since the IRP might complete before the function returns.
    //
    return PoRequestPowerIrp(
        DeviceObject,
        MinorFunction,
        PowerState,
        CompletionFunction,
        Context,
        NULL); 
}
Ejemplo n.º 11
0
VOID NTAPI SendDeviceIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP SIrp )
{
    NTSTATUS                  ntStatus;
    POWER_STATE               powState;
    PDEVICE_EXTENSION         deviceExtension;
    PIO_STACK_LOCATION        irpStack;
    SYSTEM_POWER_STATE        systemState;
    DEVICE_POWER_STATE        devState;
    PPOWER_COMPLETION_CONTEXT powerContext;

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

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

    // Read out the D-IRP out of the S->D mapping array captured in QueryCap's.
    // we can choose deeper sleep states than our mapping but never choose
    // lighter ones.
    devState = deviceExtension->DeviceCapabilities.DeviceState[systemState];
    powState.DeviceState = devState;

    powerContext = (PPOWER_COMPLETION_CONTEXT) ExAllocatePool(NonPagedPool, sizeof(POWER_COMPLETION_CONTEXT));
    if (!powerContext)
    {
        FreeBT_DbgPrint(1, ("FBTUSB: SendDeviceIrp: Failed to alloc memory for powerContext\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;

    }

    else
    {
        powerContext->DeviceObject = DeviceObject;
        powerContext->SIrp = SIrp;

        // in win2k PoRequestPowerIrp can take fdo or pdo.
        ntStatus = PoRequestPowerIrp(
                            deviceExtension->PhysicalDeviceObject,
                            irpStack->MinorFunction,
                            powState,
                            (PREQUEST_POWER_COMPLETE)DevPoCompletionRoutine,
                            powerContext,
                            NULL);

    }

    if (!NT_SUCCESS(ntStatus))
    {
        if (powerContext)
        {
            ExFreePool(powerContext);

        }

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

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

    }

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

}
Ejemplo n.º 12
0
NTSTATUS
NTAPI
USBH_FdoPower(IN PUSBHUB_FDO_EXTENSION HubExtension,
              IN PIRP Irp,
              IN UCHAR Minor)
{
    NTSTATUS Status;
    PIO_STACK_LOCATION IoStack;
    POWER_STATE PowerState;
    POWER_STATE DevicePwrState;
    BOOLEAN IsAllPortsD3;
    PUSBHUB_PORT_DATA PortData;
    PDEVICE_OBJECT PdoDevice;
    PUSBHUB_PORT_PDO_EXTENSION PortExtension;
    ULONG Port;

    DPRINT_PWR("USBH_FdoPower: HubExtension - %p, Irp - %p, Minor - %X\n",
               HubExtension,
               Irp,
               Minor);

    switch (Minor)
    {
        case IRP_MN_WAIT_WAKE:
            DPRINT_PWR("USBH_FdoPower: IRP_MN_WAIT_WAKE\n");

            IoCopyCurrentIrpStackLocationToNext(Irp);

            IoSetCompletionRoutine(Irp,
                                   USBH_FdoWWIrpIoCompletion,
                                   HubExtension,
                                   TRUE,
                                   TRUE,
                                   TRUE);

            PoStartNextPowerIrp(Irp);
            IoMarkIrpPending(Irp);
            PoCallDriver(HubExtension->LowerDevice, Irp);

            return STATUS_PENDING;

        case IRP_MN_POWER_SEQUENCE:
            DPRINT_PWR("USBH_FdoPower: IRP_MN_POWER_SEQUENCE\n");
            break;

        case IRP_MN_SET_POWER:
            DPRINT_PWR("USBH_FdoPower: IRP_MN_SET_POWER\n");

            IoStack = IoGetCurrentIrpStackLocation(Irp);
            DPRINT_PWR("USBH_FdoPower: IRP_MN_SET_POWER/DevicePowerState\n");
            PowerState = IoStack->Parameters.Power.State;

            if (IoStack->Parameters.Power.Type == DevicePowerState)
            {
                DPRINT_PWR("USBH_FdoPower: PowerState - %x\n",
                           PowerState.DeviceState);

                if (HubExtension->CurrentPowerState.DeviceState == PowerState.DeviceState)
                {
                    IoCopyCurrentIrpStackLocationToNext(Irp);

                    PoStartNextPowerIrp(Irp);
                    IoMarkIrpPending(Irp);
                    PoCallDriver(HubExtension->LowerDevice, Irp);

                    return STATUS_PENDING;
                }

                switch (PowerState.DeviceState)
                {
                    case PowerDeviceD0:
                        if (!(HubExtension->HubFlags & USBHUB_FDO_FLAG_SET_D0_STATE))
                        {
                            HubExtension->HubFlags &= ~(USBHUB_FDO_FLAG_NOT_D0_STATE |
                                                        USBHUB_FDO_FLAG_DEVICE_STOPPING);

                            HubExtension->HubFlags |= USBHUB_FDO_FLAG_SET_D0_STATE;

                            IoCopyCurrentIrpStackLocationToNext(Irp);

                            IoSetCompletionRoutine(Irp,
                                                   USBH_PowerIrpCompletion,
                                                   HubExtension,
                                                   TRUE,
                                                   TRUE,
                                                   TRUE);
                        }
                        else
                        {
                            IoCopyCurrentIrpStackLocationToNext(Irp);
                            PoStartNextPowerIrp(Irp);
                        }

                        IoMarkIrpPending(Irp);
                        PoCallDriver(HubExtension->LowerDevice, Irp);
                        return STATUS_PENDING;

                    case PowerDeviceD1:
                    case PowerDeviceD2:
                    case PowerDeviceD3:
                        if (HubExtension->ResetRequestCount)
                        {
                            IoCancelIrp(HubExtension->ResetPortIrp);

                            KeWaitForSingleObject(&HubExtension->ResetEvent,
                                                  Executive,
                                                  KernelMode,
                                                  FALSE,
                                                  NULL);
                        }

                        if (!(HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_STOPPED))
                        {
                            HubExtension->HubFlags |= (USBHUB_FDO_FLAG_NOT_D0_STATE |
                                                       USBHUB_FDO_FLAG_DEVICE_STOPPING);

                            IoCancelIrp(HubExtension->SCEIrp);

                            KeWaitForSingleObject(&HubExtension->StatusChangeEvent,
                                                  Executive,
                                                  KernelMode,
                                                  FALSE,
                                                  NULL);
                        }

                        HubExtension->CurrentPowerState.DeviceState = PowerState.DeviceState;

                        if (HubExtension->HubFlags & USBHUB_FDO_FLAG_DO_SUSPENSE &&
                            USBH_CheckIdleAbort(HubExtension, TRUE, TRUE) == TRUE)
                        {
                            HubExtension->HubFlags &= ~(USBHUB_FDO_FLAG_NOT_D0_STATE |
                                                        USBHUB_FDO_FLAG_DEVICE_STOPPING);

                            HubExtension->CurrentPowerState.DeviceState = PowerDeviceD0;

                            USBH_SubmitStatusChangeTransfer(HubExtension);

                            PoStartNextPowerIrp(Irp);

                            Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
                            IoCompleteRequest(Irp, IO_NO_INCREMENT);

                            HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_DO_SUSPENSE;

                            KeReleaseSemaphore(&HubExtension->IdleSemaphore,
                                               LOW_REALTIME_PRIORITY,
                                               1,
                                               FALSE);

                            return STATUS_UNSUCCESSFUL;
                        }

                        IoCopyCurrentIrpStackLocationToNext(Irp);

                        IoSetCompletionRoutine(Irp,
                                               USBH_PowerIrpCompletion,
                                               HubExtension,
                                               TRUE,
                                               TRUE,
                                               TRUE);

                        PoStartNextPowerIrp(Irp);
                        IoMarkIrpPending(Irp);
                        PoCallDriver(HubExtension->LowerDevice, Irp);

                        if (HubExtension->HubFlags & USBHUB_FDO_FLAG_DO_SUSPENSE)
                        {
                            HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_DO_SUSPENSE;

                            KeReleaseSemaphore(&HubExtension->IdleSemaphore,
                                               LOW_REALTIME_PRIORITY,
                                               1,
                                               FALSE);
                        }

                        return STATUS_PENDING;

                    default:
                        DPRINT1("USBH_FdoPower: Unsupported PowerState.DeviceState\n");
                        DbgBreakPoint();
                        break;
                }
            }
            else
            {
                if (PowerState.SystemState != PowerSystemWorking)
                {
                    USBH_GetRootHubExtension(HubExtension)->SystemPowerState.SystemState =
                                                            PowerState.SystemState;
                }

                if (PowerState.SystemState == PowerSystemHibernate)
                {
                    HubExtension->HubFlags |= USBHUB_FDO_FLAG_HIBERNATE_STATE;
                }

                PortData = HubExtension->PortData;

                IsAllPortsD3 = TRUE;

                if (PortData && HubExtension->HubDescriptor)
                {
                    for (Port = 0;
                         Port < HubExtension->HubDescriptor->bNumberOfPorts;
                         Port++)
                    {
                        PdoDevice = PortData[Port].DeviceObject;

                        if (PdoDevice)
                        {
                            PortExtension = PdoDevice->DeviceExtension;

                            if (PortExtension->CurrentPowerState.DeviceState != PowerDeviceD3)
                            {
                                IsAllPortsD3 = FALSE;
                                break;
                            }
                        }
                    }
                }

                if (PowerState.SystemState == PowerSystemWorking)
                {
                    DevicePwrState.DeviceState = PowerDeviceD0;
                }
                else if (HubExtension->HubFlags & USBHUB_FDO_FLAG_PENDING_WAKE_IRP ||
                         !IsAllPortsD3)
                {
                    DevicePwrState.DeviceState = HubExtension->DeviceState[PowerState.SystemState];

                    if (DevicePwrState.DeviceState == PowerDeviceUnspecified)
                    {
                        goto Exit;
                    }
                }
                else
                {
                    DevicePwrState.DeviceState = PowerDeviceD3;
                }

                if (DevicePwrState.DeviceState != HubExtension->CurrentPowerState.DeviceState &&
                    HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_STARTED)
                {
                    HubExtension->PowerIrp = Irp;

                    IoMarkIrpPending(Irp);

                    if (PoRequestPowerIrp(HubExtension->LowerPDO,
                                          IRP_MN_SET_POWER,
                                          DevicePwrState,
                                          USBH_FdoDeferPoRequestCompletion,
                                          (PVOID)HubExtension,
                                          NULL) == STATUS_PENDING)
                    {
                        return STATUS_PENDING;
                    }

                    IoCopyCurrentIrpStackLocationToNext(Irp);
                    PoStartNextPowerIrp(Irp);
                    PoCallDriver(HubExtension->LowerDevice, Irp);

                    return STATUS_PENDING;
                }

            Exit:

                HubExtension->SystemPowerState.SystemState = PowerState.SystemState;

                if (PowerState.SystemState == PowerSystemWorking)
                {
                    USBH_CheckIdleDeferred(HubExtension);
                }

                IoCopyCurrentIrpStackLocationToNext(Irp);
                PoStartNextPowerIrp(Irp);

                return PoCallDriver(HubExtension->LowerDevice, Irp);
            }

            break;

        case IRP_MN_QUERY_POWER:
            DPRINT_PWR("USBH_FdoPower: IRP_MN_QUERY_POWER\n");
            break;

        default:
            DPRINT1("USBH_FdoPower: unknown IRP_MN_POWER!\n");
            break;
    }

    IoCopyCurrentIrpStackLocationToNext(Irp);
    PoStartNextPowerIrp(Irp);
    Status = PoCallDriver(HubExtension->LowerDevice, Irp);

    return Status;
}
Ejemplo n.º 13
0
NTSTATUS
NTAPI
USBH_FdoWWIrpIoCompletion(IN PDEVICE_OBJECT DeviceObject,
                          IN PIRP Irp,
                          IN PVOID Context)
{
    PUSBHUB_FDO_EXTENSION HubExtension;
    NTSTATUS Status;
    KIRQL OldIrql;
    POWER_STATE PowerState;
    PIRP WakeIrp;

    DPRINT("USBH_FdoWWIrpIoCompletion: DeviceObject - %p, Irp - %p\n",
            DeviceObject,
            Irp);

    HubExtension = Context;

    Status = Irp->IoStatus.Status;

    IoAcquireCancelSpinLock(&OldIrql);

    HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_PENDING_WAKE_IRP;

    WakeIrp = InterlockedExchangePointer((PVOID *)&HubExtension->PendingWakeIrp,
                                         NULL);

    if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
    {
        KeSetEvent(&HubExtension->PendingRequestEvent,
                   EVENT_INCREMENT,
                   FALSE);
    }

    IoReleaseCancelSpinLock(OldIrql);

    DPRINT("USBH_FdoWWIrpIoCompletion: Status - %lX\n", Status);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("USBH_FdoWWIrpIoCompletion: DbgBreakPoint() \n");
        DbgBreakPoint();
    }
    else
    {
        PowerState.DeviceState = PowerDeviceD0;

        HubExtension->HubFlags |= USBHUB_FDO_FLAG_WAKEUP_START;
        InterlockedIncrement(&HubExtension->PendingRequestCount);

        Status = STATUS_SUCCESS;

        PoRequestPowerIrp(HubExtension->LowerPDO,
                          IRP_MN_SET_POWER,
                          PowerState,
                          USBH_FdoPoRequestD0Completion,
                          (PVOID)HubExtension,
                          NULL);
    }

    if (!WakeIrp)
    {
        if (!InterlockedExchange(&HubExtension->FdoWaitWakeLock, 1))
        {
            Status = STATUS_MORE_PROCESSING_REQUIRED;
        }
    }

    DPRINT("USBH_FdoWWIrpIoCompletion: Status - %lX\n", Status);

    if (Status != STATUS_MORE_PROCESSING_REQUIRED)
    {
        PoStartNextPowerIrp(Irp);
    }

    return Status;
}
Ejemplo n.º 14
0
NTSTATUS
IdleNotificationRequestComplete(
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP              Irp,
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:

  Completion routine for idle notification irp

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/
{
    NTSTATUS                ntStatus;
    POWER_STATE             powerState;
    KIRQL                   oldIrql;
    LARGE_INTEGER           dueTime;
    PIRP                    idleIrp;
    PUSB_IDLE_CALLBACK_INFO idleCallbackInfo;

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

    idleIrp = NULL;

    //
    // check the Irp status
    //

    ntStatus = Irp->IoStatus.Status;

    if(!NT_SUCCESS(ntStatus) && ntStatus != STATUS_NOT_SUPPORTED) {

        BulkUsb_DbgPrint(1, ("Idle irp completes with error::"));

        switch(ntStatus) {
            
        case STATUS_INVALID_DEVICE_REQUEST:

            BulkUsb_DbgPrint(1, ("STATUS_INVALID_DEVICE_REQUEST\n"));

            break;

        case STATUS_CANCELLED:

            BulkUsb_DbgPrint(1, ("STATUS_CANCELLED\n"));

            break;

        case STATUS_POWER_STATE_INVALID:

            BulkUsb_DbgPrint(1, ("STATUS_POWER_STATE_INVALID\n"));

            goto IdleNotificationRequestComplete_Exit;

        case STATUS_DEVICE_BUSY:

            BulkUsb_DbgPrint(1, ("STATUS_DEVICE_BUSY\n"));

            break;

        default:

            BulkUsb_DbgPrint(1, ("default: status = %X\n", ntStatus));

            break;
        }

        //
        // if in error, issue a SetD0
        //

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

        powerState.DeviceState = PowerDeviceD0;

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

        if(!NT_SUCCESS(ntStatus)) {
    
            BulkUsb_DbgPrint(1, ("PoRequestPowerIrp failed\n"));
        }

    }

IdleNotificationRequestComplete_Exit:

    KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);

    idleCallbackInfo = DeviceExtension->IdleCallbackInfo;

    DeviceExtension->IdleCallbackInfo = NULL;

    idleIrp = (PIRP) InterlockedExchangePointer(
                                        &DeviceExtension->PendingIdleIrp,
                                        NULL);

    InterlockedExchange(&DeviceExtension->IdleReqPend, 0);

    KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);

    if(idleCallbackInfo) {

        ExFreePool(idleCallbackInfo);
    }

    //
    // since the irp was created using IoAllocateIrp, 
    // the Irp needs to be freed using IoFreeIrp.
    // Also return STATUS_MORE_PROCESSING_REQUIRED so that 
    // the kernel does not reference this in the near future.
    //

    if(idleIrp) {

        BulkUsb_DbgPrint(3, ("completion routine has a valid irp and frees it\n"));
        IoFreeIrp(Irp);
        KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
                   IO_NO_INCREMENT,
                   FALSE);
    }
    else {

        //
        // The CancelSelectiveSuspend routine has grabbed the Irp from the device 
        // extension. Now the last one to decrement the FreeIdleIrpCount should
        // free the irp.
        //
        if(0 == InterlockedDecrement(&DeviceExtension->FreeIdleIrpCount)) {

            BulkUsb_DbgPrint(3, ("completion routine frees the irp\n"));
            IoFreeIrp(Irp);

            KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
                       IO_NO_INCREMENT,
                       FALSE);
        }
    }

    if(DeviceExtension->SSEnable) {

        BulkUsb_DbgPrint(3, ("Set the timer to fire DPCs\n"));

        dueTime.QuadPart = -10000 * IDLE_INTERVAL;               // 5000 ms

        KeSetTimerEx(&DeviceExtension->Timer, 
                     dueTime,
                     IDLE_INTERVAL,                              // 5000 ms
                     &DeviceExtension->DeferredProcCall);

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

    return STATUS_MORE_PROCESSING_REQUIRED;
}
Ejemplo n.º 15
0
static NTSTATUS IdleNotificationRequestComplete(IN PDEVICE_OBJECT DeviceObject,
												IN PIRP Irp, IN PTDeviceExtension DeviceExtension)
{
	NTSTATUS                ntStatus;
	POWER_STATE             powerState;
	KIRQL                   oldIrql;
	LARGE_INTEGER           dueTime;
	PIRP                    idleIrp;
	PUSB_IDLE_CALLBACK_INFO idleCallbackInfo;

	BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationRequestCompete - begins\n"));
	idleIrp = NULL;
	ntStatus = Irp->IoStatus.Status;
	if(!NT_SUCCESS(ntStatus) && ntStatus != STATUS_NOT_SUPPORTED) 
	{
		BulkUsb_DbgPrint(1, ("file bulkdev: Idle irp completes with error::"));
		switch(ntStatus) 
		{
		case STATUS_INVALID_DEVICE_REQUEST:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_INVALID_DEVICE_REQUEST\n"));
			break;

		case STATUS_CANCELLED:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_CANCELLED\n"));
			break;

		case STATUS_POWER_STATE_INVALID:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_POWER_STATE_INVALID\n"));
			goto IdleNotificationRequestComplete_Exit;

		case STATUS_DEVICE_BUSY:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_DEVICE_BUSY\n"));
			break;

		default:
			BulkUsb_DbgPrint(1, ("file bulkdev: default: status = %X\n", ntStatus));
			break;
		}

		if(PowerDeviceD0 != DeviceExtension->DevPower) 
		{
			BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationRequestComplete::"));
			BulkUsb_IoIncrement(DeviceExtension);
			powerState.DeviceState = PowerDeviceD0;
			ntStatus = PoRequestPowerIrp(
						DeviceExtension->PhysicalDeviceObject, 
						IRP_MN_SET_POWER, 
						powerState, 
						(PREQUEST_POWER_COMPLETE) PoIrpAsyncCompletionFunc, 
						DeviceExtension, 
						NULL);

			if(!NT_SUCCESS(ntStatus)) 
			{
				BulkUsb_DbgPrint(1, ("file bulkdev: PoRequestPowerIrp failed\n"));
			}
		}
	}

IdleNotificationRequestComplete_Exit:

	KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
	idleCallbackInfo = DeviceExtension->IdleCallbackInfo;
	DeviceExtension->IdleCallbackInfo = NULL;
	idleIrp = (PIRP) InterlockedExchangePointer(&DeviceExtension->PendingIdleIrp, NULL);
	InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
	KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
	if(idleCallbackInfo) 
	{
		ExFreePool(idleCallbackInfo);
	}
	if(idleIrp) 
	{
		BulkUsb_DbgPrint(3, ("file bulkdev: completion routine has a valid irp and frees it\n"));
		IoFreeIrp(Irp);
		KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
	}
	else 
	{
		if(0 == InterlockedDecrement(&DeviceExtension->FreeIdleIrpCount)) 
		{
			BulkUsb_DbgPrint(3, ("file bulkdev: completion routine frees the irp\n"));
			IoFreeIrp(Irp);
			KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
		}
	}
	if(DeviceExtension->SSEnable) 
	{
		BulkUsb_DbgPrint(3, ("file bulkdev: Set the timer to fire DPCs\n"));
		dueTime.QuadPart = -10000 * IDLE_INTERVAL;               // 5000 ms
		KeSetTimerEx(&DeviceExtension->Timer, 
			dueTime,
			IDLE_INTERVAL,                              // 5000 ms
			&DeviceExtension->DeferredProcCall);

		BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationRequestCompete - ends\n"));
	}
	return STATUS_MORE_PROCESSING_REQUIRED;
}
Ejemplo n.º 16
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"));
}
Ejemplo n.º 17
0
NTSTATUS
NTAPI
PortClsPower(
    IN  PDEVICE_OBJECT DeviceObject,
    IN  PIRP Irp)
{
    PIO_STACK_LOCATION IoStack;
    PPCLASS_DEVICE_EXTENSION DeviceExtension;
    PQUERY_POWER_CONTEXT PwrContext;
    POWER_STATE PowerState;
    NTSTATUS Status = STATUS_SUCCESS;

    DPRINT("PortClsPower called\n");

    // get currrent stack location
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    if (IoStack->MinorFunction != IRP_MN_SET_POWER && IoStack->MinorFunction != IRP_MN_QUERY_POWER)
    {
        // just forward the request
        Status = PcForwardIrpSynchronous(DeviceObject, Irp);

        // start next power irp
        PoStartNextPowerIrp(Irp);

        // complete request
        Irp->IoStatus.Status = Status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        // done
        return Status;
    }


    // get device extension
    DeviceExtension = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension;

    // get current request type
    if (IoStack->Parameters.Power.Type == DevicePowerState)
    {
        // request for device power state
        if (DeviceExtension->DevicePowerState == IoStack->Parameters.Power.State.DeviceState)
        {
            // nothing has changed
            if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
            {
                // only forward query requests
                Status = PcForwardIrpSynchronous(DeviceObject, Irp);
            }

            // start next power irp
            PoStartNextPowerIrp(Irp);

            // complete request
            Irp->IoStatus.Status = Status;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);

            // done
            return Status;
        }

        if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
        {
            // check if there is a registered adapter power management
            if (DeviceExtension->AdapterPowerManagement)
            {
                // it is query if the change can be changed
                PowerState = *((POWER_STATE*)&IoStack->Parameters.Power.State.DeviceState);
                Status = DeviceExtension->AdapterPowerManagement->QueryPowerChangeState(PowerState);

                // sanity check
                PC_ASSERT(Status == STATUS_SUCCESS);
            }

            // only forward query requests
            PcForwardIrpSynchronous(DeviceObject, Irp);

            // start next power irp
            PoStartNextPowerIrp(Irp);

            // complete request
            Irp->IoStatus.Status = Status;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);

            // done
            return Status;
        }
        else
        {
            // set power state
            PowerState = *((POWER_STATE*)&IoStack->Parameters.Power.State.DeviceState);
            PoSetPowerState(DeviceObject, DevicePowerState, PowerState);

            // check if there is a registered adapter power management
            if (DeviceExtension->AdapterPowerManagement)
            {
                // notify of a power change state
                DeviceExtension->AdapterPowerManagement->PowerChangeState(PowerState);
            }

            // FIXME call all registered IPowerNotify interfaces via ISubdevice interface

            // store new power state
           DeviceExtension->DevicePowerState = IoStack->Parameters.Power.State.DeviceState;

            // complete request
            Irp->IoStatus.Status = Status;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);

            // done
            return Status;
        }
    }
    else
    {
        // sanity check
        PC_ASSERT(IoStack->Parameters.Power.Type == SystemPowerState);

        if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
        {
            // mark irp as pending
            IoMarkIrpPending(Irp);

            // allocate power completion context
            PwrContext = (PQUERY_POWER_CONTEXT)AllocateItem(NonPagedPool, sizeof(QUERY_POWER_CONTEXT), TAG_PORTCLASS);

            if (!PwrContext)
            {
                // no memory
                PoStartNextPowerIrp(Irp);

                // complete and forget
                Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);

                // done
                return Status;
            }

            // setup power context
            PwrContext->Irp = Irp;
            PwrContext->DeviceObject = DeviceObject;

            // pass the irp down
            PowerState = *((POWER_STATE*)IoStack->Parameters.Power.State.SystemState);
            Status = PoRequestPowerIrp(DeviceExtension->PhysicalDeviceObject, IoStack->MinorFunction, PowerState, PwrCompletionFunction, (PVOID)PwrContext, NULL);

            // check for success
            if (!NT_SUCCESS(Status))
            {
                // failed
                Irp->IoStatus.Status = Status;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);

                // done
                return Status;
            }

            // done
            return STATUS_PENDING;
        }
        else
        {
            // set power request
            DeviceExtension->SystemPowerState = IoStack->Parameters.Power.State.SystemState;

            // only forward query requests
            Status = PcForwardIrpSynchronous(DeviceObject, Irp);

            // start next power irp
            PoStartNextPowerIrp(Irp);

            // complete request
            Irp->IoStatus.Status = Status;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);

            // done
            return Status;
        }
    }
}
Ejemplo n.º 18
0
VOID
SendDeviceIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP SIrp
    )
/*++
 
Routine Description:

    This routine is invoked from the completion routine of the system power
    irp. This routine will PoRequest a device power irp. The system irp is 
    passed as a context to the the device power irp.

Arguments:

    DeviceObject - pointer to device object
    SIrp - system power irp.

Return Value:

    None

--*/
{
    NTSTATUS                  ntStatus;
    POWER_STATE               powState;
    PDEVICE_EXTENSION         deviceExtension;
    PIO_STACK_LOCATION        irpStack;
    SYSTEM_POWER_STATE        systemState;
    DEVICE_POWER_STATE        devState;
    PPOWER_COMPLETION_CONTEXT powerContext;
    
    //
    // initialize variables
    //

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

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

    //
    // Read out the D-IRP out of the S->D mapping array captured in QueryCap's.
    // we can choose deeper sleep states than our mapping but never choose
    // lighter ones.
    //

    devState = deviceExtension->DeviceCapabilities.DeviceState[systemState];
    powState.DeviceState = devState;
    
    powerContext = (PPOWER_COMPLETION_CONTEXT) 
                   ExAllocatePool(NonPagedPool,
                                  sizeof(POWER_COMPLETION_CONTEXT));

    if(!powerContext) {

        MobiUsb_DbgPrint(1, ("file mobipwr: Failed to alloc memory for powerContext\n"));

        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }
    else {

        powerContext->DeviceObject = DeviceObject;
        powerContext->SIrp = SIrp;
   
        //
        // in win2k PoRequestPowerIrp can take fdo or pdo.
        //

        ntStatus = PoRequestPowerIrp(
                            deviceExtension->PhysicalDeviceObject, 
                            irpStack->MinorFunction,
                            powState,
                            (PREQUEST_POWER_COMPLETE)DevPoCompletionRoutine,
                            powerContext, 
                            NULL);
    }

    if(!NT_SUCCESS(ntStatus)) {

        if(powerContext) {

            ExFreePool(powerContext);
        }

        PoStartNextPowerIrp(SIrp);

        SIrp->IoStatus.Status = ntStatus;
        SIrp->IoStatus.Information = 0;
        
        IoCompleteRequest(SIrp, IO_NO_INCREMENT);

        MobiUsb_DbgPrint(3, ("file mobipwr: SendDeviceIrp::"));
        MobiUsb_IoDecrement(deviceExtension);

    }

    MobiUsb_DbgPrint(3, ("file mobipwr: SendDeviceIrp - ends\n"));
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
NTSTATUS
t1394Cmdr_SystemSetPowerIrpCompletion(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            NotUsed
    )
{

    PDEVICE_EXTENSION           deviceExtension     = DeviceObject->DeviceExtension;
    NTSTATUS                    ntStatus            = Irp->IoStatus.Status;
    PIO_STACK_LOCATION          stack               = IoGetCurrentIrpStackLocation(Irp);
    POWER_STATE                 state               = stack->Parameters.Power.State;
    POWER_COMPLETION_CONTEXT    *powerContext       = NULL;
    PIRP                        pDIrp               = NULL;

    ENTER("t1394Cmdr_SystemPowerIrpCompletion");

    if (!NT_SUCCESS(ntStatus)) {

        TRACE(TL_TRACE, ("Set System Power Irp failed, status = 0x%x\n", ntStatus));
        PoStartNextPowerIrp(Irp);
        ntStatus = STATUS_SUCCESS;
        goto Exit_SystemSetPowerIrpCompletion;
    }

    // allocate powerContext
    powerContext = (POWER_COMPLETION_CONTEXT*)
                ExAllocatePool(NonPagedPool, sizeof(POWER_COMPLETION_CONTEXT));

    if (!powerContext) {

        TRACE(TL_TRACE, ("Failed to allocate powerContext, status = 0x%x\n", ntStatus));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit_SystemSetPowerIrpCompletion;

    } else {

        if (state.SystemState == PowerSystemWorking) {

            state.DeviceState = PowerDeviceD0;
        }
        else {
                    
            state.DeviceState = PowerDeviceD3;
        }
        
        powerContext->DeviceObject = DeviceObject;
        powerContext->SIrp = Irp;
        
        ntStatus = PoRequestPowerIrp(deviceExtension->StackDeviceObject,
                                    IRP_MN_SET_POWER,
                                    state,
                                    t1394Cmdr_DeviceSetPowerIrpCompletion,
                                    powerContext,
                                    &pDIrp);
        
        TRACE(TL_TRACE, ("New Device Set Power Irp = 0x%x\n", pDIrp));
    }

Exit_SystemSetPowerIrpCompletion:

    if (!NT_SUCCESS(ntStatus)) {


        TRACE(TL_TRACE, ("System SetPowerIrp Completion routine failed = 0x%x\n", ntStatus));

        if (powerContext) {
            ExFreePool(powerContext);
        }

        PoStartNextPowerIrp(Irp);
        Irp->IoStatus.Status = ntStatus;
    }
    else
    {
        ntStatus = STATUS_MORE_PROCESSING_REQUIRED;
    }

    EXIT("t1394Cmdr_SystemPowerIrpCompletion", ntStatus);    
    return ntStatus;
}