Пример #1
0
NTSTATUS
SingleCompWdmEvtDeviceWdmPostPoFxRegisterDevice(
    _In_ WDFDEVICE Device,
    _In_ POHANDLE PoHandle
    )
/*++
Routine Description:

    KMDF calls this routine after it has registered with the Power Framework
    and supplies the registration handle that driver can use directly.

Arguments:

    Device - Handle to the framework device object

    PoHandle - Handle of registration with Power Framework.

Return Value:

    An NTSTATUS value representing success or failure of the function.
    
--*/
{
    FDO_DATA *fdoContext = NULL;

    PAGED_CODE();
    
    //
    // Get the device context
    //
    fdoContext = FdoGetContext(Device);

    //
    // Save the POHANDLE
    //
    fdoContext->PoHandle = PoHandle;

    //
    // Set latency and residency hints so that the power framework chooses lower
    // powered F-states when we are idle.
    // The values used here are for illustration purposes only. The driver 
    // should use values that are appropriate for its device.
    //
    PoFxSetComponentLatency(
        PoHandle,
        0, // Component
        (WDF_ABS_TIMEOUT_IN_MS(DEEPEST_FSTATE_LATENCY_IN_MS) + 1)
        );
    PoFxSetComponentResidency(
        PoHandle,
        0, // Component
        (WDF_ABS_TIMEOUT_IN_SEC(DEEPEST_FSTATE_RESIDENCY_IN_SEC) + 1)
        );

    return STATUS_SUCCESS;
}
Пример #2
0
VOID
SingleCompWdmEvtDeviceWdmPrePoFxUnregisterDevice(
    _In_ WDFDEVICE Device,
    _In_ POHANDLE PoHandle
    )
/*++
Routine Description:

    KMDF calls this routine when it is about to unregister with the Power
    Framework. After returning from this routine driver must not use the
    supplied registration handle anymore.

Arguments:

    Device - Handle to the framework device object

    PoHandle - Handle of registration with Power Framework.

Return Value:

    An NTSTATUS value representing success or failure of the function.
    
--*/
{
    FDO_DATA *fdoContext = NULL;

    PAGED_CODE();
    
    UNREFERENCED_PARAMETER(PoHandle);

    //
    // Get the device context
    //
    fdoContext = FdoGetContext(Device);

    //
    // Reset the POHANDLE
    //
    fdoContext->PoHandle = NULL;

    return;
}
Пример #3
0
VOID
SingleCompEvtIoDeviceControl(
    _In_ WDFQUEUE Queue,
    _In_ WDFREQUEST Request,
    _In_ size_t OutputBufferLength,
    _In_ size_t InputBufferLength,
    _In_ ULONG IoControlCode
    )
/*++
Routine Description:

    Callback invoked by WDFQUEUE for a Device Io Control request.

Arguments:

    Queue - Device I/O control queue
              
    Request - Device I/O control request

    OutputBufferLength - Output buffer length for the I/O control

    InputBufferLength - Input buffer length for the I/O control

    IoControlCode - I/O control code
                
--*/
{
    NTSTATUS status;
    PPOWERFX_READ_COMPONENT_OUTPUT outputBuffer = NULL;
    WDFDEVICE device = NULL;
    ULONG componentData;
    ULONG_PTR information = 0;
    FDO_DATA *fdoContext = NULL;
    
    //
    // When we complete the request, make sure we don't get the I/O manager to 
    // copy any more data to the client address space than what we write to the
    // output buffer. The only data that we write to the output buffer is the 
    // component data and the C_ASSERT below ensures that the output buffer does
    // not have room to contain anything other than that.
    //
    C_ASSERT(sizeof(componentData) == sizeof(*outputBuffer));

    UNREFERENCED_PARAMETER(OutputBufferLength);
    UNREFERENCED_PARAMETER(InputBufferLength);

    //
    // This is a power-managed queue. So our queue stop/start logic should have 
    // ensured that we are in the active condition when a request is dispatched
    // from this queue.
    //
    device = WdfIoQueueGetDevice(Queue);
    fdoContext = FdoGetContext(device);
    if (FALSE == fdoContext->IsActive) {
        Trace(TRACE_LEVEL_ERROR, 
              "%!FUNC! - IOCTL %d was dispatched from WDFQUEUE %p when the "
              "component was not in an active condition.",
              IOCTL_POWERFX_READ_COMPONENT,
              Queue);
        WdfVerifierDbgBreakPoint();
    }
    
    //
    // Validate Ioctl code
    //
    if (IOCTL_POWERFX_READ_COMPONENT != IoControlCode) {
        status = STATUS_NOT_SUPPORTED;
        Trace(TRACE_LEVEL_ERROR, 
              "%!FUNC! -Unsupported IoControlCode. Expected: %d. Actual: %d."
              " %!status!.", 
              IOCTL_POWERFX_READ_COMPONENT,
              IoControlCode,
              status);
        goto exit;
    }
    
    //
    // Get the output buffer
    //
    status = WdfRequestRetrieveOutputBuffer(Request,
                                            sizeof(*outputBuffer),
                                            (PVOID*) &outputBuffer,
                                            NULL // Length
                                            );
    if (FALSE == NT_SUCCESS(status)) {
        Trace(TRACE_LEVEL_ERROR, 
              "%!FUNC! - WdfRequestRetrieveOutputBuffer failed with %!status!.",
              status);
        goto exit;
    }
    
    //
    // Read the data from the component
    //
    componentData = HwSimReadComponent(device);
    outputBuffer->ComponentData = componentData;
    information = sizeof(*outputBuffer);
    
    status = STATUS_SUCCESS;
    
exit:
    //
    // Complete the request
    //
    WdfRequestCompleteWithInformation(Request, status, information);
    return;
}
Пример #4
0
NTSTATUS
SingleCompEvtDeviceAdd(
    _In_    WDFDRIVER       Driver,
    _Inout_ PWDFDEVICE_INIT DeviceInit
    )
/*++
Routine Description:

    EvtDeviceAdd is called by UMDF in response to AddDevice call from 
    the PnP manager. 

Arguments:

    Driver - Handle to the UMDF driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    An NTSTATUS value representing success or failure of the function.

--*/
{
    NTSTATUS status;
    WDFDEVICE device;
    WDFQUEUE queue;
    WDF_IO_QUEUE_CONFIG     queueConfig;
    FDO_DATA               *fdoContext = NULL;
    WDF_OBJECT_ATTRIBUTES   objectAttributes;
    WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks;

    UNREFERENCED_PARAMETER(Driver);

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&objectAttributes, FDO_DATA);

    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks);
    pnpCallbacks.EvtDeviceD0Entry = SingleCompEvtDeviceD0Entry;
    pnpCallbacks.EvtDeviceD0Exit = SingleCompEvtDeviceD0Exit;

    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks);
    
    status = WdfDeviceCreate(&DeviceInit, &objectAttributes, &device);
    if (!NT_SUCCESS(status)) {
        Trace(TRACE_LEVEL_ERROR,
              "%!FUNC! - WdfDeviceCreate failed with %!status!.", 
              status);
        goto exit;
    }

    fdoContext = FdoGetContext(device);

    //
    // Our initial state is active
    //
    fdoContext->IsActive = TRUE;

    //
    // Create a power-managed queue for IOCTL requests.
    //
    WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, 
                                           WdfIoQueueDispatchParallel);
    queueConfig.EvtIoDeviceControl = SingleCompEvtIoDeviceControl;

    //
    // By default, Static Driver Verifier (SDV) displays a warning if it 
    // doesn't find the EvtIoStop callback on a power-managed queue. 
    // The 'assume' below causes SDV to suppress this warning. If the driver 
    // has not explicitly set PowerManaged to WdfFalse, the framework creates
    // power-managed queues when the device is not a filter driver.  Normally 
    // the EvtIoStop is required for power-managed queues, but for this driver
    // it is not needed b/c the driver doesn't hold on to the requests or 
    // forward them to other drivers. This driver completes the requests 
    // directly in the queue's handlers. If the EvtIoStop callback is not 
    // implemented, the framework waits for all driver-owned requests to be
    // done before moving in the Dx/sleep states or before removing the 
    // device, which is the correct behavior for this type of driver.
    // If the requests were taking an indeterminate amount of time to complete,
    // or if the driver forwarded the requests to a lower driver/another stack,
    // the queue should have an EvtIoStop/EvtIoResume.
    //
    __analysis_assume(queueConfig.EvtIoStop != 0);
    status = WdfIoQueueCreate(device,
                              &queueConfig,
                              WDF_NO_OBJECT_ATTRIBUTES,
                              &queue);
    __analysis_assume(queueConfig.EvtIoStop == 0);

    if (FALSE == NT_SUCCESS (status)) {
        Trace(TRACE_LEVEL_ERROR,
              "%!FUNC! - WdfIoQueueCreate for IoDeviceControl failed with %!status!.", 
              status);
        goto exit;
    }

    status = WdfDeviceConfigureRequestDispatching(device,
                                                  queue,
                                                  WdfRequestTypeDeviceControl);
    if (FALSE == NT_SUCCESS (status)) {
        Trace(TRACE_LEVEL_ERROR,
              "%!FUNC! - WdfDeviceConfigureRequestDispatching for "
              "WdfRequestTypeDeviceControl failed with %!status!.", 
              status);
        goto exit;
    }

    status = AssignS0IdleSettings(device);
    if (!NT_SUCCESS(status)) {
        goto exit;
    }

    //
    // Create a device interface so that applications can open a handle to this
    // device.
    //
    status = WdfDeviceCreateDeviceInterface(device, 
                                            &GUID_DEVINTERFACE_POWERFX,
                                            NULL /* ReferenceString */);
    if (FALSE == NT_SUCCESS(status)) {
        Trace(TRACE_LEVEL_ERROR, 
              "%!FUNC! - WdfDeviceCreateDeviceInterface failed with %!status!.", 
              status);
        goto exit;
    }

    //
    // Initialize the hardware simulator
    //
    status = HwSimInitialize(device);
    if (FALSE == NT_SUCCESS(status)) {
        goto exit;
    }    
exit:
    return status;
}
Пример #5
0
VOID
SingleCompWdmIdleStateCallback(
    _In_ PVOID Context,
    _In_ ULONG Component,
    _In_ ULONG State
    )
/*++
Routine Description:

    This callback is invoked by Power Framework to notify driver about any
    F-state transition.

Arguments:

    Context - Context supplied to Power Framework. KMDF supplies WDFDEVICE as
              the context while registering with Power Framework. Hence Context
              contains the KMDF device object.
              
    Component - Component for which F state transition is requested. Since we
                have only one component this value is always 0.
                
Return Value:

    BOOLEAN indicating whether Fx transition has completed.
    
--*/
{
    WDFDEVICE device = NULL;
    FDO_DATA *fdoContext = NULL;
    BOOLEAN transitionComplete = TRUE;

    //
    // We have only component 0
    //
    if (0 != Component) {
        Trace(TRACE_LEVEL_ERROR,"%!FUNC! - Unexpected component %d",Component);
        ASSERT(FALSE);
    }

    //
    // Get the device
    //
    device = (WDFDEVICE) Context;
    
    //
    // Get the device context
    //
    fdoContext = FdoGetContext(device);

    //
    // Note the new F-state
    //
    switch (State) {
        case 0: {
            transitionComplete = F0Entry(device);
        }
        break;

        //
        // PEP may make us go to any of the F-states directly, hence we execute
        // F0Exit code for all of the Fx states.
        //
        // Transition to any Fx state happens from F0 (and not another
        // Fx state)
        //
        default: {
            ASSERT(State < FSTATE_COUNT);

            transitionComplete = F0Exit(device, State);
        }
        break;        
    }

    if (transitionComplete) {
        PoFxCompleteIdleState(fdoContext->PoHandle, 0 /* Component */);
    }
}
Пример #6
0
NTSTATUS
SingleCompEvtDeviceAdd(
    _In_    WDFDRIVER       Driver,
    _Inout_ PWDFDEVICE_INIT DeviceInit
    )
/*++
Routine Description:

    EvtDeviceAdd is called by the KMDF in response to AddDevice call from 
    the PnP manager. 

Arguments:

    Driver - Handle to the KMDF driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    An NTSTATUS value representing success or failure of the function.

--*/
{
    NTSTATUS status;
    WDFDEVICE device;
    WDF_IO_QUEUE_CONFIG     queueConfig;
    FDO_DATA               *fdoContext = NULL;
    ULONG                   queueIndex = 0;
    WDF_OBJECT_ATTRIBUTES   objectAttributes;
    WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks;
    
    PAGED_CODE();

    UNREFERENCED_PARAMETER(Driver);

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&objectAttributes, FDO_DATA);

    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks);
    pnpCallbacks.EvtDeviceD0Entry = SingleCompEvtDeviceD0Entry;
    pnpCallbacks.EvtDeviceD0Exit = SingleCompEvtDeviceD0Exit;

    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks);
    
    status = WdfDeviceCreate(&DeviceInit, &objectAttributes, &device);
    if (!NT_SUCCESS(status)) {
        Trace(TRACE_LEVEL_ERROR,
              "%!FUNC! - WdfDeviceCreate failed with %!status!.", 
              status);
        goto exit;
    }

    fdoContext = FdoGetContext(device);

    //
    // Our initial state is active
    //
    fdoContext->IsActive = TRUE;

    //
    // Create three power-managed queues, one each for read, write and IOCTL 
    // requests. The handles to these power-managed queues are stored in an 
    // array in the device object context space. When the component becomes idle
    // we need to stop our power-managed queues. When the component becomes 
    // active we need to start them. In those situations, we go through this 
    // array of power-managed queues and stop or start each queue as 
    // appropriate. Handles to non-power-managed queues should not be stored in
    // this array.
    //
    WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, 
                                           WdfIoQueueDispatchParallel);
    queueConfig.EvtIoDeviceControl = SingleCompEvtIoDeviceControl;

    //
    // By default, Static Driver Verifier (SDV) displays a warning if it 
    // doesn't find the EvtIoStop callback on a power-managed queue. 
    // The 'assume' below causes SDV to suppress this warning. If the driver 
    // has not explicitly set PowerManaged to WdfFalse, the framework creates
    // power-managed queues when the device is not a filter driver.  Normally 
    // the EvtIoStop is required for power-managed queues, but for this driver
    // it is not needed b/c the driver doesn't hold on to the requests or 
    // forward them to other drivers. This driver completes the requests 
    // directly in the queue's handlers. If the EvtIoStop callback is not 
    // implemented, the framework waits for all driver-owned requests to be
    // done before moving in the Dx/sleep states or before removing the 
    // device, which is the correct behavior for this type of driver.
    // If the requests were taking an indeterminate amount of time to complete,
    // or if the driver forwarded the requests to a lower driver/another stack,
    // the queue should have an EvtIoStop/EvtIoResume.
    //
    __analysis_assume(queueConfig.EvtIoStop != 0);
    status = WdfIoQueueCreate(device,
                              &queueConfig,
                              WDF_NO_OBJECT_ATTRIBUTES,
                              &(fdoContext->Queues[queueIndex]));
    __analysis_assume(queueConfig.EvtIoStop == 0);

    if (FALSE == NT_SUCCESS (status)) {
        Trace(TRACE_LEVEL_ERROR,
              "%!FUNC! - WdfIoQueueCreate for IoDeviceControl failed with %!status!.", 
              status);
        goto exit;
    }

    status = WdfDeviceConfigureRequestDispatching(device,
                                                  fdoContext->Queues[queueIndex],
                                                  WdfRequestTypeDeviceControl);
    if (FALSE == NT_SUCCESS (status)) {
        Trace(TRACE_LEVEL_ERROR,
              "%!FUNC! - WdfDeviceConfigureRequestDispatching for "
              "WdfRequestTypeDeviceControl failed with %!status!.", 
              status);
        goto exit;
    }

    ++queueIndex;
    
    WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, 
                                           WdfIoQueueDispatchParallel);
    queueConfig.EvtIoRead = SingleCompEvtIoRead;

    //
    // By default, Static Driver Verifier (SDV) displays a warning if it 
    // doesn't find the EvtIoStop callback on a power-managed queue. 
    // The 'assume' below causes SDV to suppress this warning. If the driver 
    // has not explicitly set PowerManaged to WdfFalse, the framework creates
    // power-managed queues when the device is not a filter driver.  Normally 
    // the EvtIoStop is required for power-managed queues, but for this driver
    // it is not needed b/c the driver doesn't hold on to the requests or 
    // forward them to other drivers. This driver completes the requests 
    // directly in the queue's handlers. If the EvtIoStop callback is not 
    // implemented, the framework waits for all driver-owned requests to be
    // done before moving in the Dx/sleep states or before removing the 
    // device, which is the correct behavior for this type of driver.
    // If the requests were taking an indeterminate amount of time to complete,
    // or if the driver forwarded the requests to a lower driver/another stack,
    // the queue should have an EvtIoStop/EvtIoResume.
    //
    __analysis_assume(queueConfig.EvtIoStop != 0);
    status = WdfIoQueueCreate(device,
                              &queueConfig,
                              WDF_NO_OBJECT_ATTRIBUTES,
                              &(fdoContext->Queues[queueIndex]));
    __analysis_assume(queueConfig.EvtIoStop == 0);
    
    if (FALSE == NT_SUCCESS (status)) {
        Trace(TRACE_LEVEL_ERROR,
              "%!FUNC! - WdfIoQueueCreate for IoRead failed with %!status!.", 
              status);
        goto exit;
    }

    status = WdfDeviceConfigureRequestDispatching(device,
                                                  fdoContext->Queues[queueIndex],
                                                  WdfRequestTypeRead);
    if (FALSE == NT_SUCCESS (status)) {
        Trace(TRACE_LEVEL_ERROR,
              "%!FUNC! - WdfDeviceConfigureRequestDispatching for "
              "WdfRequestTypeRead failed with %!status!.", 
              status);
        goto exit;
    }

    ++queueIndex;

    WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, 
                                           WdfIoQueueDispatchParallel);
    queueConfig.EvtIoWrite = SingleCompEvtIoWrite;

    //
    // By default, Static Driver Verifier (SDV) displays a warning if it 
    // doesn't find the EvtIoStop callback on a power-managed queue. 
    // The 'assume' below causes SDV to suppress this warning. If the driver 
    // has not explicitly set PowerManaged to WdfFalse, the framework creates
    // power-managed queues when the device is not a filter driver.  Normally 
    // the EvtIoStop is required for power-managed queues, but for this driver
    // it is not needed b/c the driver doesn't hold on to the requests or 
    // forward them to other drivers. This driver completes the requests 
    // directly in the queue's handlers. If the EvtIoStop callback is not 
    // implemented, the framework waits for all driver-owned requests to be
    // done before moving in the Dx/sleep states or before removing the 
    // device, which is the correct behavior for this type of driver.
    // If the requests were taking an indeterminate amount of time to complete,
    // or if the driver forwarded the requests to a lower driver/another stack,
    // the queue should have an EvtIoStop/EvtIoResume.
    //
    __analysis_assume(queueConfig.EvtIoStop != 0);
    status = WdfIoQueueCreate(device,
                              &queueConfig,
                              WDF_NO_OBJECT_ATTRIBUTES,
                              &(fdoContext->Queues[queueIndex]));
    __analysis_assume(queueConfig.EvtIoStop == 0);
    
    if (FALSE == NT_SUCCESS (status)) {
        Trace(TRACE_LEVEL_ERROR,
              "%!FUNC! - WdfIoQueueCreate for IoWrite failed with %!status!.", 
              status);
        goto exit;
    }

    status = WdfDeviceConfigureRequestDispatching(device,
                                                  fdoContext->Queues[queueIndex],
                                                  WdfRequestTypeWrite);
    if (FALSE == NT_SUCCESS (status)) {
        Trace(TRACE_LEVEL_ERROR,
              "%!FUNC! - WdfDeviceConfigureRequestDispatching for "
              "WdfRequestTypeWrite failed with %!status!.", 
              status);
        goto exit;
    }

    ++queueIndex;

    ASSERT(queueIndex == QUEUE_COUNT);

    status = AssignS0IdleSettings(device);
    if (!NT_SUCCESS(status)) {
        goto exit;
    }

    //
    // If you need to talk to hardware to figure out what F-states are 
    // applicable this can be done in EvtSelfManagedIoInit 
    // (but no later than that). EvtSelfManagedIoInit gets invoked after
    // EvtPrepareHardware so you'd have chance to initialize your hardware.
    //
    status = AssignPowerFrameworkSettings(device);
    if (!NT_SUCCESS(status)) {
        goto exit;
    }

    //
    // Create a device interface so that applications can open a handle to this
    // device.
    //
    status = WdfDeviceCreateDeviceInterface(device, 
                                            &GUID_DEVINTERFACE_POWERFX,
                                            NULL /* ReferenceString */);
    if (FALSE == NT_SUCCESS(status)) {
        Trace(TRACE_LEVEL_ERROR, 
              "%!FUNC! - WdfDeviceCreateDeviceInterface failed with %!status!.", 
              status);
        goto exit;
    }

    //
    // Initialize the hardware simulator
    //
    status = HwSimInitialize(device);
    if (FALSE == NT_SUCCESS(status)) {
        goto exit;
    }    
exit:
    return status;
}
Пример #7
0
VOID
SingleCompWdmIdleConditionCallback(
   _In_ PVOID Context,
   _In_ ULONG Component
   )
/*++
Routine Description:
    This callback is invoked by Power Framework to notify driver that one of its
    components has become idle.

Arguments:

    Context - Context that we supplied when calling 
              WdfDeviceWdmAssignPowerFrameworkSettings.
              
    Component - Component that have become idle. Since we have only one 
                component this value is always 0.
    
Return Value:

    None
    
--*/
{
    WDFDEVICE  device;
    FDO_DATA *fdoContext = NULL;
    UCHAR i = 0;

    //
    // We have only component 0
    //
    if (0 != Component) {
        Trace(TRACE_LEVEL_ERROR,"%!FUNC! - Unexpected component %d",Component);
        ASSERT(FALSE);
    }

    //
    // Get the device
    //
    device = (WDFDEVICE) Context;
    
    //
    // Get the device context
    //
    fdoContext = FdoGetContext(device);

    //
    // Initialize the count of queues to be stopped.
    //
    // Until we complete this idle transition there cannot be other idle
    // transitions, which is only where we use this count. Thus nothing races
    // with it.
    //
    // If you have other code that stops/starts queues, it may be simpler
    // to queue a work-item from this callback which stops all the queues
    // synchronously. Synchronous queue stop cannot be done from here since
    // this callback may be called at DISPATCH_LEVEL.
    //
    fdoContext->QueueStopCount = QUEUE_COUNT;
    
    //
    // Stop power-managed queues
    //
    for (i = 0; i < QUEUE_COUNT; i++) {
#pragma warning(suppress: 6387) // passing NULL Context parameter is safe in this instance
        WdfIoQueueStop(fdoContext->Queues[i],
                       SingleCompEvtQueueStopComplete, 
                       NULL /* Context */);
    }
    
    //
    // The idle transition will complete asynchronously. We'll call 
    // PoFxCompleteIdleCondition to complete it when all the queues have been
    // stopped.
    //
    // IMPORTANT NOTE
    // ==============
    // Given that the idle transition does not complete until all the power-
    // managed queues have been stopped, it is extremely important for the 
    // driver to ensure that stopping of power-managed queues is reasonably 
    // quick. If the driver fails to ensure this, the power framework can remain
    // stuck in the idle transition for a long time, which could hamper its 
    // ability to put the component in a low-power F-state. This could 
    // negatively impact any power savings that can be gained via component 
    // power management.
    //
    // In order to ensure that idle transitions can complete quickly, the driver
    // should quickly process any requests that are dispatched to it via a 
    // power-managed queue. If the driver forwards a request (that was received 
    // via a power-managed queue) to an I/O target that might keep the request 
    // pending for a long time, then the driver should cancel the request when
    // the component idle condition callback is invoked. This is because the 
    // power-managed queue cannot be stopped while the request is pending in the
    // I/O target.
    //
    return;
}
Пример #8
0
VOID
SingleCompWdmActiveConditionCallback(
    _In_ PVOID Context,
    _In_ ULONG Component
    )
/*++
Routine Description:

    This callback is invoked by Power Framework to notify driver that one of its
    components has become active.

Arguments:

    Context - Context that we supplied when calling 
              WdfDeviceWdmAssignPowerFrameworkSettings.
              
    Component - Component that have become active. Since we have only one 
                component this value is always 0.
    
Return Value:

    None
    
--*/
{
    WDFDEVICE  device;
    FDO_DATA *fdoContext = NULL;
    UCHAR i = 0;

    //
    // We have only component 0
    //
    if (0 != Component) {
        Trace(TRACE_LEVEL_ERROR,"%!FUNC! - Unexpected component %d",Component);
        ASSERT(FALSE);
    }

    //
    // Get the device
    //
    device = (WDFDEVICE) Context;
    
    //
    // Get the device context
    //
    fdoContext = FdoGetContext(device);

    //
    // Mark ourselves as active
    //
    fdoContext->IsActive = TRUE;

    //
    // Start power-managed queues
    //
    for (i = 0; i < QUEUE_COUNT; i++) {
        WdfIoQueueStart(fdoContext->Queues[i]);
    }

    return;
}