Stop 0x44 (MULTIPLE_IRP_COMPLETE_REQUESTS) Disabling Idle USB Device with KMDF-based Driver

Article translations Article translations
Close Close
Article ID: 973056 - View products that this article applies to.
Support for Windows Vista Service Pack 1 (SP1) ends on July 12, 2011. To continue receiving security updates for Windows, make sure you're running Windows Vista with Service Pack 2 (SP2). For more information, refer to this Microsoft web page: Support is ending for some versions of Windows.
Expand all | Collapse all
Source: Microsoft Support

RAPID PUBLISHING

RAPID PUBLISHING ARTICLES PROVIDE INFORMATION DIRECTLY FROM WITHIN THE MICROSOFT SUPPORT ORGANIZATION. THE INFORMATION CONTAINED HEREIN IS CREATED IN RESPONSE TO EMERGING OR UNIQUE TOPICS, OR IS INTENDED SUPPLEMENT OTHER KNOWLEDGE BASE INFORMATION.

Symptom



When you Disable a USB device that is currently Idle, you may receive a "Stop 0x44" error message on a blue screen. This error message resembles the following:

STOP 0x00000044 ( parameter1 , parameter2 , parameter3 , parameter4 )
MULTIPLE_IRP_COMPLETE_REQUESTS

Cause



This problem may occur if the USB device uses a driver written using the Kernel Mode Driver Framework (KMDF) version 1.7 or earlier.

The problem occurs when the USB device is in an Idle (USB Selective Suspend) state, and the device is then Disabled (such as by right-clicking the device in Device Manager and clicking Disable).

Under these conditions, the KMDF framework version 1.7 (or earlier) does not wait for USB Selective Suspend Irps to be completed, thus allowing the device stack to be removed before the USB Selective Suspend Irp is completed (e.g., by the Usbhub driver).

Resolution



This problem is resolved in the Kernel Mode Driver Framework (KMDF) version 1.9 and later.  Kernel Mode Driver Framework (KMDF) version 1.9 is available in the Windows 7 version of the Windows Driver Kit (WDK).

A KMDF-based USB device driver developer can work around this problem by performing the following actions:
  1. Register an EvtDeviceReleaseHardware callback routine in the driver's EvtDriverDeviceAdd callback routine.
  2. Allocate a WDFWORKITEM object in the driver's EvtDriverDeviceAdd callback routine.
  3. Allocate and initialize a KEVENT object, queue the work item in the driver's EvtDeviceReleaseHardware callback routine, passing this event as the Context parameter, and wait for the event to be signaled.
  4. In the work item callback routine, delay the thread by approximately 2 seconds and then set the event.  The exact delay value required may differ across systems and should be tested prior to final implementation.


The described workaround has two main effects:
  • It queues a work item which helps delay tearing down the device stack until the work item queue is drained up to this work item (since the USB core stack may complete the USB Selective Suspend Irp through a work item).
  • It introduces a delay in case the USB core stack’s work item and driver’s work item get executed simultaneously on multi-processor/multi-core systems.


NOTE: This is not a comprehensive solution.  It only helps mitigate the problem.

More Information



The sample code snippets below illustrate how to implement this workaround:

EvtDriverDeviceAdd(
    IN WDFDRIVER  Driver,
    IN PWDFDEVICE_INIT  DeviceInit
    ) 
{
    PWORKER_ITEM_CONTEXT  context;
    WDF_OBJECT_ATTRIBUTES  attributes;
    WDF_WORKITEM_CONFIG  workitemConfig;
    WDFWORKITEM  workItem;
 
    ...
    //
    // Set EvtDeviceReleaseHardware callback
    //
    ...
    pnpPowerCallbacks.EvtDeviceReleaseHardware = EvtDeviceReleaseHardware;
    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
    ...
    //
    // Allocate WDFWORKITEM
    //
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes,WORKER_ITEM_CONTEXT);
    attributes.ParentObject = device;

    WDF_WORKITEM_CONFIG_INIT(&workitemConfig, EvtWorkItem);

    status = WdfWorkItemCreate(&workitemConfig, &attributes, &workItem);
    if (!NT_SUCCESS(status)) {
        return status;
    }
    devContext->WorkItem = workItem;
    ...
}

NTSTATUS
EvtDeviceReleaseHardware(
    IN WDFDEVICE  Device,
    IN WDFCMRESLIST  ResourcesTranslated
    )
{
    KEVENT event;
    PWORKER_ITEM_CONTEXT context;
    WDFWORKITEM workItem;
   
    UNREFERENCED_PARAMETER(ResourcesTranslated);

    workItem = GetDeviceContext(Device)->WorkItem;
    context = GetWorkItemContext(workItem);   

    KeInitializeEvent(&event, NotificationEvent, FALSE);
    context->Event = &event;

    //
    // Queue the workitem
    //
    WdfWorkItemEnqueue(workItem); 

    //
    // Wait for workitem to signal the event
    //
    KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

    return STATUS_SUCCESS;
}

VOID
EvtWorkItem(
    IN WDFWORKITEM  WorkItem
    )
{
    PWORKER_ITEM_CONTEXT context;
    LARGE_INTEGER  interval;

    context = GetWorkItemContext(WorkItem);

    //
    // Delay the thread for 2 seconds
    //
    interval.QuadPart = -2 * 10 * 1000 * 1000;
    KeDelayExecutionThread(KernelMode, FALSE, &interval);

    //
    // signal the waiting thread
    //
    KeSetEvent(context->Event, IO_NO_INCREMENT, FALSE);
    context->Event = NULL;
}

// in header file
typedef struct _WORKER_ITEM_CONTEXT {
    PKEVENT Event;
} WORKER_ITEM_CONTEXT, * PWORKER_ITEM_CONTEXT;

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WORKER_ITEM_CONTEXT, GetWorkItemContext)

EVT_WDF_DEVICE_RELEASE_HARDWARE  EvtDeviceReleaseHardware;
EVT_WDF_WORKITEM  EvtWorkItem;

DISCLAIMER

MICROSOFT AND/OR ITS SUPPLIERS MAKE NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY, RELIABILITY OR ACCURACY OF THE INFORMATION CONTAINED IN THE DOCUMENTS AND RELATED GRAPHICS PUBLISHED ON THIS WEBSITE (THE “MATERIALS”) FOR ANY PURPOSE. THE MATERIALS MAY INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS AND MAY BE REVISED AT ANY TIME WITHOUT NOTICE.

TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, MICROSOFT AND/OR ITS SUPPLIERS DISCLAIM AND EXCLUDE ALL REPRESENTATIONS, WARRANTIES, AND CONDITIONS WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO REPRESENTATIONS, WARRANTIES, OR CONDITIONS OF TITLE, NON INFRINGEMENT, SATISFACTORY CONDITION OR QUALITY, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, WITH RESPECT TO THE MATERIALS.
Note This is a "FAST PUBLISH" article created directly from within the Microsoft support organization. The information contained herein is provided as-is in response to emerging issues. As a result of the speed in making it available, the materials may include typographical errors and may be revised at any time without notice. See Terms of Use for other considerations.

Properties

Article ID: 973056 - Last Review: June 10, 2011 - Revision: 1.1
APPLIES TO
  • Windows Vista Ultimate
  • Windows Vista Enterprise
  • Windows Vista Business
  • Windows Vista Home Premium
  • Windows Vista Home Basic
  • Windows Vista Service Pack 1
  • Windows Vista Service Pack 2
Keywords: 
kbrapidpub kbnomt KB973056

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com