usb driver DTM plug and play test failed

This usb driver is based on USB BUILK smaple in DDK.It passed HCT test and passed WHQL in 2006. But when running DTM test, it failed. The error log is described as the following.
Machine Rebooted Unexpectedly when Task “RunJob- Plug and Play Driver Test - Library Job” was running

I ran the PNPtest.exe individually. I cannot find any useful information.
And I submit the test log to winqual. WHQL failed because of the this failure, they haven’t told me more information.

Can any one tell me how to do?

thank you very much.

The following is the part of the code in PNP.
NTSTATUS
BulkUsb_DispatchPnP(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++

Routine Description:

The plug and play dispatch routines.
Most of these requests the driver will completely ignore.
In all cases it must pass on the IRP to the lower driver.

Arguments:

DeviceObject - pointer to a device object.

Irp - pointer to an I/O Request Packet.

Return Value:

NT status value

–*/
{
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
KEVENT startDeviceEvent;
NTSTATUS ntStatus;

//
// initialize variables
//

irpStack = IoGetCurrentIrpStackLocation(Irp);
deviceExtension = DeviceObject->DeviceExtension;

//
// since the device is removed, fail the Irp.
//

if(Removed == deviceExtension->DeviceState) {

ntStatus = STATUS_DELETE_PENDING;

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

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return ntStatus;
}

BulkUsb_DbgPrint(3, (“///////////////////////////////////////////\n”));
BulkUsb_DbgPrint(3, (“BulkUsb_DispatchPnP::”));
BulkUsb_IoIncrement(deviceExtension);

if(irpStack->MinorFunction == IRP_MN_START_DEVICE) {

ASSERT(deviceExtension->IdleReqPend == 0);
}
else {

if(deviceExtension->SSEnable) {

CancelSelectSuspend(deviceExtension);
}
}

BulkUsb_DbgPrint(2, (PnPMinorFunctionString(irpStack->MinorFunction)));

switch(irpStack->MinorFunction) {

case IRP_MN_START_DEVICE:

ntStatus = HandleStartDevice(DeviceObject, Irp);

break;

case IRP_MN_QUERY_STOP_DEVICE:

//
// if we cannot stop the device, we fail the query stop irp
//

ntStatus = CanStopDevice(DeviceObject, Irp);

if(NT_SUCCESS(ntStatus)) {

ntStatus = HandleQueryStopDevice(DeviceObject, Irp);

return ntStatus;
}
break;

case IRP_MN_CANCEL_STOP_DEVICE:

ntStatus = HandleCancelStopDevice(DeviceObject, Irp);

break;

case IRP_MN_STOP_DEVICE:

ntStatus = HandleStopDevice(DeviceObject, Irp);

BulkUsb_DbgPrint(3, (“BulkUsb_DispatchPnP::IRP_MN_STOP_DEVICE::”));
BulkUsb_IoDecrement(deviceExtension);

return ntStatus;

case IRP_MN_QUERY_REMOVE_DEVICE:

//
// if we cannot remove the device, we fail the query remove irp
//
ntStatus = HandleQueryRemoveDevice(DeviceObject, Irp);

return ntStatus;

case IRP_MN_CANCEL_REMOVE_DEVICE:

ntStatus = HandleCancelRemoveDevice(DeviceObject, Irp);

break;

case IRP_MN_SURPRISE_REMOVAL:

ntStatus = HandleSurpriseRemoval(DeviceObject, Irp);

BulkUsb_DbgPrint(3, (“BulkUsb_DispatchPnP::IRP_MN_SURPRISE_REMOVAL::”));
BulkUsb_IoDecrement(deviceExtension);

return ntStatus;

case IRP_MN_REMOVE_DEVICE:

ntStatus = HandleRemoveDevice(DeviceObject, Irp);

return ntStatus;

case IRP_MN_QUERY_CAPABILITIES:

ntStatus = HandleQueryCapabilities(DeviceObject, Irp);

break;

default:

IoSkipCurrentIrpStackLocation(Irp);

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

BulkUsb_DbgPrint(3, (“BulkUsb_DispatchPnP::default::”));
BulkUsb_IoDecrement(deviceExtension);

return ntStatus;

} // switch

//
// complete request
//

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

IoCompleteRequest(Irp, IO_NO_INCREMENT);

//
// decrement count
//
BulkUsb_DbgPrint(3, (“BulkUsb_DispatchPnP::”));
BulkUsb_IoDecrement(deviceExtension);

return ntStatus;
}

NTSTATUS
BulkUsb_DispatchPnP(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++

Routine Description:

The plug and play dispatch routines.
Most of these requests the driver will completely ignore.
In all cases it must pass on the IRP to the lower driver.

Arguments:

DeviceObject - pointer to a device object.

Irp - pointer to an I/O Request Packet.

Return Value:

NT status value

–*/
{
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
KEVENT startDeviceEvent;
NTSTATUS ntStatus;

//
// initialize variables
//

irpStack = IoGetCurrentIrpStackLocation(Irp);
deviceExtension = DeviceObject->DeviceExtension;

//
// since the device is removed, fail the Irp.
//

if(Removed == deviceExtension->DeviceState) {

ntStatus = STATUS_DELETE_PENDING;

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

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return ntStatus;
}

BulkUsb_DbgPrint(3, (“///////////////////////////////////////////\n”));
BulkUsb_DbgPrint(3, (“BulkUsb_DispatchPnP::”));
BulkUsb_IoIncrement(deviceExtension);

if(irpStack->MinorFunction == IRP_MN_START_DEVICE) {

ASSERT(deviceExtension->IdleReqPend == 0);
}
else {

if(deviceExtension->SSEnable) {

CancelSelectSuspend(deviceExtension);
}
}

BulkUsb_DbgPrint(2, (PnPMinorFunctionString(irpStack->MinorFunction)));

switch(irpStack->MinorFunction) {

case IRP_MN_START_DEVICE:

ntStatus = HandleStartDevice(DeviceObject, Irp);

break;

case IRP_MN_QUERY_STOP_DEVICE:

//
// if we cannot stop the device, we fail the query stop irp
//

ntStatus = CanStopDevice(DeviceObject, Irp);

if(NT_SUCCESS(ntStatus)) {

ntStatus = HandleQueryStopDevice(DeviceObject, Irp);

return ntStatus;
}
break;

case IRP_MN_CANCEL_STOP_DEVICE:

ntStatus = HandleCancelStopDevice(DeviceObject, Irp);

break;

case IRP_MN_STOP_DEVICE:

ntStatus = HandleStopDevice(DeviceObject, Irp);

BulkUsb_DbgPrint(3, (“BulkUsb_DispatchPnP::IRP_MN_STOP_DEVICE::”));
BulkUsb_IoDecrement(deviceExtension);

return ntStatus;

case IRP_MN_QUERY_REMOVE_DEVICE:

//
// if we cannot remove the device, we fail the query remove irp
//
ntStatus = HandleQueryRemoveDevice(DeviceObject, Irp);

return ntStatus;

case IRP_MN_CANCEL_REMOVE_DEVICE:

ntStatus = HandleCancelRemoveDevice(DeviceObject, Irp);

break;

case IRP_MN_SURPRISE_REMOVAL:

ntStatus = HandleSurpriseRemoval(DeviceObject, Irp);

BulkUsb_DbgPrint(3, (“BulkUsb_DispatchPnP::IRP_MN_SURPRISE_REMOVAL::”));
BulkUsb_IoDecrement(deviceExtension);

return ntStatus;

case IRP_MN_REMOVE_DEVICE:

ntStatus = HandleRemoveDevice(DeviceObject, Irp);

return ntStatus;

case IRP_MN_QUERY_CAPABILITIES:

ntStatus = HandleQueryCapabilities(DeviceObject, Irp);

break;

default:

IoSkipCurrentIrpStackLocation(Irp);

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

BulkUsb_DbgPrint(3, (“BulkUsb_DispatchPnP::default::”));
BulkUsb_IoDecrement(deviceExtension);

return ntStatus;

} // switch

//
// complete request
//

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

IoCompleteRequest(Irp, IO_NO_INCREMENT);

//
// decrement count
//
BulkUsb_DbgPrint(3, (“BulkUsb_DispatchPnP::”));
BulkUsb_IoDecrement(deviceExtension);

return ntStatus;
}

case IRP_MN_START_DEVICE:
ntStatus = HandleStartDevice(DeviceObject, Irp);
break;
case IRP_MN_QUERY_STOP_DEVICE:
ntStatus = CanStopDevice(DeviceObject, Irp);
if(NT_SUCCESS(ntStatus)) {
ntStatus = HandleQueryStopDevice(DeviceObject, Irp);
return ntStatus;
}
break;
case IRP_MN_CANCEL_STOP_DEVICE:
ntStatus = HandleCancelStopDevice(DeviceObject, Irp);
break;
case IRP_MN_STOP_DEVICE:
ntStatus = HandleStopDevice(DeviceObject, Irp);
BulkUsb_IoDecrement(deviceExtension);
return ntStatus;
case IRP_MN_QUERY_REMOVE_DEVICE:
ntStatus = HandleQueryRemoveDevice(DeviceObject, Irp);
return ntStatus;
case IRP_MN_CANCEL_REMOVE_DEVICE:
ntStatus = HandleCancelRemoveDevice(DeviceObject, Irp);
break;
case IRP_MN_SURPRISE_REMOVAL:
ntStatus = HandleSurpriseRemoval(DeviceObject, Irp);
BulkUsb_DbgPrint(3, (“BulkUsb_DispatchPnP::IRP_MN_SURPRISE_REMOVAL::”));
BulkUsb_IoDecrement(deviceExtension);
return ntStatus;
case IRP_MN_REMOVE_DEVICE:
ntStatus = HandleRemoveDevice(DeviceObject, Irp);
return ntStatus;
case IRP_MN_QUERY_CAPABILITIES:
ntStatus = HandleQueryCapabilities(DeviceObject, Irp);
break;
default:
IoSkipCurrentIrpStackLocation(Irp);
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
BulkUsb_IoDecrement(deviceExtension);
return ntStatus;

huaping jiang wrote:

This usb driver is based on USB BUILK smaple in DDK.It passed HCT
test and passed WHQL in 2006. But when running DTM test, it failed.

I believe this is Michal Vodicka’s cue to lament choosing bulkusb as the basis for his driver several years ago, and how it’s ruined his life ever since, etc.

“Unexpected reboot” probably means “blue screen”. I would invoke the test manually and then post the !analyze -v output from the crash dump.

Also, I could be totally wrong, but I think someone here mentioned that bulkusb blows up on the “rebalance” test (i.e. where you get MN_STOP followed up by MN_START). That might be your problem, too.

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Friday, February 15, 2008 4:05 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] usb driver DTM plug and play test failed

huaping jiang wrote:

> This usb driver is based on USB BUILK smaple in DDK.It
passed HCT test
> and passed WHQL in 2006. But when running DTM test, it failed.

I believe this is Michal Vodicka’s cue to lament choosing
bulkusb as the basis for his driver several years ago, and
how it’s ruined his life ever since, etc.

:smiley: Hey, I have to do some work, too. Lamenting has a bit lower priority
nowadays :slight_smile:

Well, I believe this sample is so miserable it should be removed from
the WDK. With all other USB WDM samples which are similar. It wouldn’t
be a problem if one takes it as a sample only but it becomes the problem
once somebody tries to convert it to the product.

This sample might be sufficient for w9x and maybe also for w2k running
at single CPU machine. Currently, when dual core machines became
standard and quad core will follow, it is not. There is no need to start
a new project with it anymore as there are more stable KMDF samples.

In addition, when one doesn’t need something special in kernel mode, it
is possible to use WinUsb and avoid own kernel development at all.
Recently, I tried to compare performance and was positively surprised.
Converting my user mode code took only few hours, INF was made within
minutes and the performance was quite comparable with my driver.

“Unexpected reboot” probably means “blue screen”. I would
invoke the test manually and then post the !analyze -v output
from the crash dump.

I’d agree with BSOD. There is usually no need to invoke test manually,
just to examine existing crashdump. If it was enabled, of course. This
is a pre-requisite anyway; enable kernel dump.

Also, I could be totally wrong, but I think someone here
mentioned that bulkusb blows up on the “rebalance” test (i.e.
where you get MN_STOP followed up by MN_START). That might
be your problem, too.

It does but it shouldn’t lead to BSOD. IIRC rebalance test just fails.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

I had posted this issue in earlier thread; and Chris have gave me some advice.
But I cannot resolve it, so put it again.

thank you very much.

Michal Vodicka wrote:

> Also, I could be totally wrong, but I think someone here
> mentioned that bulkusb blows up on the “rebalance” test (i.e.
> where you get MN_STOP followed up by MN_START). That might
> be your problem, too.

It does but it shouldn’t lead to BSOD. IIRC rebalance test just fails.

Well, right, but (again, if I recall correctly), if you fail the rebalance test, the PNPDTest filter driver manually bugchecks, causing the BSOD (I believe they do this so you can see the backtrace into your driver where you failed the start IRP the second time around, etc.)

huaping jiang wrote:

I had posted this issue in earlier thread; and Chris have gave me
some advice. But I cannot resolve it, so put it again.

Well, sorry. I’m not sure what to tell you, all my drivers were KMDF so I had never had to deal with this (I did fail the rebalance test also sometimes, but it was because of mistakes in my logic…)

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Friday, February 15, 2008 4:08 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] usb driver DTM plug and play test failed

> It does but it shouldn’t lead to BSOD. IIRC rebalance test
just fails.

Well, right, but (again, if I recall correctly), if you fail
the rebalance test, the PNPDTest filter driver manually
bugchecks, causing the BSOD (I believe they do this so you
can see the backtrace into your driver where you failed the
start IRP the second time around, etc.)

It is some time before I had to fix this problem. I’m almost sure there
was no BSOD but also, it was several DTM versions backs. Things might
change in between and you can be right as well.

Anyway, it should be clear from crashdump and OP should start with
crashdump analysis.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

Can KWDF driver run in XP? If it can, I can try to port the KWDF usbsamp driver to our driver.

Also, I’m testing it again in DTM to catch the “unexpected machin reboot”. I will post it, if I find something.

As far as using winusb, our company need kernel driver.
Thank you very much.

huaping jiang wrote:

Can KWDF driver run in XP? If it can, I can try to port the KWDF
usbsamp driver to our driver.

Yes, as well as 2K and Vista. I think everyone would highly recommend you just dump your bulkusb-based driver and move to K(M)DF, rather than struggle with getting the DTM test to pass.

> Also, I’m testing it again in DTM to catch the “unexpected machin reboot”.

Disable the automatic reboot on BSODs in Control Panel/System, it is on by
default.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Michal Vodicka wrote (about BulkUSB):

Well, I believe this sample is so miserable it should be removed from
the WDK.

Could you state what is so miserable about it - I’ve seen the MS changes
in this sample from DDK98 to WDM6000RTM, and a lot of unused code - what
fundamental dangers did I miss?

IMHO if it is so miserable, MS should replace it with a real safe,
production-grade multi-platform sample. This way existing WDM drivers
(based on BulkUSB) can be upgraded to something acceptable.

If you need to support legacy Windows versions, even today you might
want to go for one WDM driver instead of using 2-3 driver frameworks -
WDM for W98SE/ME, KMDF for W2K, UMDF/WinUSB for WinXP/Vista. Oh, I
forgot W2K3 Server… KMDF? (Which version?) Or WinUSB?

In addition, when one doesn’t need something special in kernel mode, it
is possible to use WinUsb and avoid own kernel development at all.

Yes! Luckily! Now Windows doesn’t need any driver at all for simple bulk
USB tranfers, too. (Only a multi-megabyte co-installer.)
(No, no sarcasm here - as I am also an end-user of USB devices, I have a
vivid interest in fewer drivers. And WinUSB definitely helps!)

Recently, I tried to compare performance and was positively surprised.
Converting my user mode code took only few hours, INF was made within
minutes and the performance was quite comparable with my driver.

Ahem… we’d lose 10-20% of performance, if switching from WDM to UMDF.
(BTW, this was confirmd by s/o from MS as an excellent value.)

So it’ll probably not be much help - in our case - if UMDF is as fast as
using WinUSB - we need these 10-20% performance.

huaping jiang wrote:

Can KWDF driver run in XP? If it can, I can try to port the KWDF
usbsamp driver to our driver.

xxxxx@gmail.com wrote:

Yes, as well as 2K and Vista. I think everyone would highly
recommend you just dump your bulkusb-based driver and move to K(M)DF,
rather than struggle with getting the DTM test to pass.

I gouess you could set up a rule set for BulkUSB driver development:

  • If you have to support Win98SE/WinME, you must use WDM. Sorry!
  • If the driver is only for WinXP and newer (Vista/Server2008), use UMDF
    or WinUSB.
  • Otherwise, go for KMDF.

(Did I miss something?)

The following come from the memory.dmp when PNP test failed.
Can anyone give some advice to me? thank you very much.

ERROR_CODE: (NTSTATUS) 0xc9 - The operating system cannot run %1.

BUGCHECK_STR: 0xc9_22e

DRIVER_VERIFIER_IO_VIOLATION_TYPE: 22e

FAULTING_IP:
ViaUsbEts!BulkUsb_DispatchPnP+0 [d:\vtc_usbd\vtc_usbd_x\usbd_ets\bulkpnp.c @ 54]
f87d0882 8bff mov edi,edi

IRP_ADDRESS: 83216e28

DEVICE_OBJECT: 8154cce8

DRIVER_OBJECT: 81582bb8

IMAGE_NAME: ViaUsbEts.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 479eee33

MODULE_NAME: ViaUsbEts

FAULTING_MODULE: 00000000

DEFAULT_BUCKET_ID: DRIVER_FAULT

PROCESS_NAME: System

LOCK_ADDRESS: 805521e0 – (!locks 805521e0)

Resource @ nt!IopDeviceTreeLock (0x805521e0) Shared 1 owning threads
Threads: 820f6da8-01<*>
1 total locks, 1 locks currently held

PNP_TRIAGE:
Lock address : 0x805521e0
Thread Count : 1
Thread address: 0x820f6da8
Thread wait : 0xc51

LAST_CONTROL_TRANSFER: from 806562ab to 804f9925

STACK_TEXT:
f88a2434 806562ab 0000004c 000000c9 f88a2454 nt!KeBugCheckEx+0x1b
f88a25bc 80656a11 f88a2897 8067f210 00040000 nt!ViBugcheckHalt+0xc3
f88a2860 80656af7 80682c30 0000022e f88a288c nt!VfBugcheckThrowException+0xa1
f88a2950 80658569 0000022e 00000009 f87d0882 nt!VfBugcheckThrowIoException+0xb5
f88a2988 80655c15 81327a18 81327978 00000001 nt!VfPnpVerifyIrpStackUpward+0xdd
f88a29ac 80659a9c 81327978 00000001 81543f00 nt!VfMajorVerifyIrpStackUpward+0x45
f88a29ec 8064c75f 83216f97 83216e28 00000000 nt!IovpCompleteRequest2+0xb4
f88a2a04 804f1362 8154cce8 83216e28 f88a2a68 nt!IovpLocalCompletionRoutine+0x63
f88a2a34 8064cc38 83216e28 813270e8 00000000 nt!IopfCompleteRequest+0xa2
f88a2aa0 f87d0927 81327030 81ece040 83216f00 nt!IovCompleteRequest+0x9a
f88a2ab4 804eedf9 81327030 83216e28 806d12e8 ViaUsbEts!BulkUsb_DispatchPnP+0xa5 [d:\vtc_usbd\vtc_usbd_x\usbd_ets\bulkpnp.c @ 202]
f88a2ac4 8064c5a8 83216fb0 83216fd4 83216f94 nt!IopfCallDriver+0x31
f88a2ae8 806570b9 8154cce8 81582bb8 83216e00 nt!IovCallDriver+0xa0
f88a2afc 804eedf9 81327030 83216e28 806d12e8 nt!ViDriverDispatchPnp+0xd7
f88a2b0c 8064c5a8 83216fd4 83216ff8 83216e28 nt!IopfCallDriver+0x31
f88a2b30 f86e8a43 81327de0 81327f10 81327e58 nt!IovCallDriver+0xa0
WARNING: Stack unwind information not available. Following frames may be wrong.
f88a2b54 f86e97dc 81327f10 83216e28 83216e28 pnpfiltr+0x1a43
f88a2b70 f86e956d 81327e58 83216e28 81327e58 pnpfiltr+0x27dc
f88a2b88 804eedf9 81327e58 83216e28 806d12e8 pnpfiltr+0x256d
f88a2b98 8064c5a8 83217000 f88a2c38 83216e28 nt!IopfCallDriver+0x31
f88a2bbc 80587d67 81ed7ae0 81ed7ae0 00000003 nt!IovCallDriver+0xa0
f88a2be8 80587e8b 81327e58 f88a2c14 00000000 nt!IopSynchronousCall+0xb7
f88a2c3c 80588b7f 81ed7ae0 00000003 00000000 nt!IopRemoveDevice+0x93
f88a2c54 805899b6 81596e70 f88a2d18 f88a2ce0 nt!IopQueryRemoveLockedDeviceNode+0x3f
f88a2c6c 80589a03 81596e70 00000000 e2ad8820 nt!IopDeleteLockedDeviceNode+0x4e
f88a2ca0 8058f49f 81ed7ae0 02ad8820 00000000 nt!IopDeleteLockedDeviceNodes+0x3f
f88a2d34 8058f936 f88a2d70 806d1778 e27eba88 nt!PiProcessQueryRemoveAndEject+0x597
f88a2d50 8058fa8f f88a2d70 812e2358 8055b1fc nt!PiProcessTargetDeviceEvent+0x2a
f88a2d74 80534dd0 812e2358 00000000 820f6da8 nt!PiWalkDeviceList+0xfd
f88a2dac 805c5a28 812e2358 00000000 00000000 nt!ExpWorkerThread+0x100
f88a2ddc 80541fa2 80534cd0 00000001 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

STACK_COMMAND: .bugcheck ; kb

FOLLOWUP_IP:
ViaUsbEts!BulkUsb_DispatchPnP+0 [d:\vtc_usbd\vtc_usbd_x\usbd_ets\bulkpnp.c @ 54]
f87d0882 8bff mov edi,edi

FAULTING_SOURCE_CODE:
50:
51: NT status value
52:
53: –*/

54: {
55: PIO_STACK_LOCATION irpStack;
56: PDEVICE_EXTENSION deviceExtension;
57: KEVENT startDeviceEvent;
58: NTSTATUS ntStatus;
59:

SYMBOL_NAME: ViaUsbEts!BulkUsb_DispatchPnP+0

FOLLOWUP_NAME: MachineOwner

FAILURE_BUCKET_ID: 0xc9_22e_VRF_ViaUsbEts!BulkUsb_DispatchPnP+0

BUCKET_ID: 0xc9_22e_VRF_ViaUsbEts!BulkUsb_DispatchPnP+0

Followup: MachineOwner

“The caller has completed a successful IRP_MJ_PNP instead of passing it
down. (*IRP specified.*)”

This seems rather obvious to me. What more needs to be explained? You are
processing either a QueryRemoveDevice operation or a RemoveDevice operation
and doing so incorrectly as you did not pass it down the stack.

On Feb 18, 2008 7:46 AM, wrote:

> The following come from the memory.dmp when PNP test failed.
> Can anyone give some advice to me? thank you very much.
>
> ERROR_CODE: (NTSTATUS) 0xc9 - The operating system cannot run %1.
>
> BUGCHECK_STR: 0xc9_22e
>
> DRIVER_VERIFIER_IO_VIOLATION_TYPE: 22e
>
> FAULTING_IP:
> ViaUsbEts!BulkUsb_DispatchPnP+0 [d:\vtc_usbd\vtc_usbd_x\usbd_ets\bulkpnp.c
> @ 54]
> f87d0882 8bff mov edi,edi
>
> IRP_ADDRESS: 83216e28
>
> DEVICE_OBJECT: 8154cce8
>
> DRIVER_OBJECT: 81582bb8
>
> IMAGE_NAME: ViaUsbEts.sys
>
> DEBUG_FLR_IMAGE_TIMESTAMP: 479eee33
>
> MODULE_NAME: ViaUsbEts
>
> FAULTING_MODULE: 00000000
>
> DEFAULT_BUCKET_ID: DRIVER_FAULT
>
> PROCESS_NAME: System
>
> LOCK_ADDRESS: 805521e0 – (!locks 805521e0)
>
> Resource @ nt!IopDeviceTreeLock (0x805521e0) Shared 1 owning threads
> Threads: 820f6da8-01<>
> 1 total locks, 1 locks currently held
>
> PNP_TRIAGE:
> Lock address : 0x805521e0
> Thread Count : 1
> Thread address: 0x820f6da8
> Thread wait : 0xc51
>
> LAST_CONTROL_TRANSFER: from 806562ab to 804f9925
>
> STACK_TEXT:
> f88a2434 806562ab 0000004c 000000c9 f88a2454 nt!KeBugCheckEx+0x1b
> f88a25bc 80656a11 f88a2897 8067f210 00040000 nt!ViBugcheckHalt+0xc3
> f88a2860 80656af7 80682c30 0000022e f88a288c
> nt!VfBugcheckThrowException+0xa1
> f88a2950 80658569 0000022e 00000009 f87d0882
> nt!VfBugcheckThrowIoException+0xb5
> f88a2988 80655c15 81327a18 81327978 00000001
> nt!VfPnpVerifyIrpStackUpward+0xdd
> f88a29ac 80659a9c 81327978 00000001 81543f00
> nt!VfMajorVerifyIrpStackUpward+0x45
> f88a29ec 8064c75f 83216f97 83216e28 00000000 nt!IovpCompleteRequest2+0xb4
> f88a2a04 804f1362 8154cce8 83216e28 f88a2a68
> nt!IovpLocalCompletionRoutine+0x63
> f88a2a34 8064cc38 83216e28 813270e8 00000000 nt!IopfCompleteRequest+0xa2
> f88a2aa0 f87d0927 81327030 81ece040 83216f00 nt!IovCompleteRequest+0x9a
> f88a2ab4 804eedf9 81327030 83216e28 806d12e8
> ViaUsbEts!BulkUsb_DispatchPnP+0xa5
> [d:\vtc_usbd\vtc_usbd_x\usbd_ets\bulkpnp.c @ 202]
> f88a2ac4 8064c5a8 83216fb0 83216fd4 83216f94 nt!IopfCallDriver+0x31
> f88a2ae8 806570b9 8154cce8 81582bb8 83216e00 nt!IovCallDriver+0xa0
> f88a2afc 804eedf9 81327030 83216e28 806d12e8 nt!ViDriverDispatchPnp+0xd7
> f88a2b0c 8064c5a8 83216fd4 83216ff8 83216e28 nt!IopfCallDriver+0x31
> f88a2b30 f86e8a43 81327de0 81327f10 81327e58 nt!IovCallDriver+0xa0
> WARNING: Stack unwind information not available. Following frames may be
> wrong.
> f88a2b54 f86e97dc 81327f10 83216e28 83216e28 pnpfiltr+0x1a43
> f88a2b70 f86e956d 81327e58 83216e28 81327e58 pnpfiltr+0x27dc
> f88a2b88 804eedf9 81327e58 83216e28 806d12e8 pnpfiltr+0x256d
> f88a2b98 8064c5a8 83217000 f88a2c38 83216e28 nt!IopfCallDriver+0x31
> f88a2bbc 80587d67 81ed7ae0 81ed7ae0 00000003 nt!IovCallDriver+0xa0
> f88a2be8 80587e8b 81327e58 f88a2c14 00000000 nt!IopSynchronousCall+0xb7
> f88a2c3c 80588b7f 81ed7ae0 00000003 00000000 nt!IopRemoveDevice+0x93
> f88a2c54 805899b6 81596e70 f88a2d18 f88a2ce0
> nt!IopQueryRemoveLockedDeviceNode+0x3f
> f88a2c6c 80589a03 81596e70 00000000 e2ad8820
> nt!IopDeleteLockedDeviceNode+0x4e
> f88a2ca0 8058f49f 81ed7ae0 02ad8820 00000000
> nt!IopDeleteLockedDeviceNodes+0x3f
> f88a2d34 8058f936 f88a2d70 806d1778 e27eba88
> nt!PiProcessQueryRemoveAndEject+0x597
> f88a2d50 8058fa8f f88a2d70 812e2358 8055b1fc
> nt!PiProcessTargetDeviceEvent+0x2a
> f88a2d74 80534dd0 812e2358 00000000 820f6da8 nt!PiWalkDeviceList+0xfd
> f88a2dac 805c5a28 812e2358 00000000 00000000 nt!ExpWorkerThread+0x100
> f88a2ddc 80541fa2 80534cd0 00000001 00000000
> nt!PspSystemThreadStartup+0x34
> 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
>
>
> STACK_COMMAND: .bugcheck ; kb
>
> FOLLOWUP_IP:
> ViaUsbEts!BulkUsb_DispatchPnP+0 [d:\vtc_usbd\vtc_usbd_x\usbd_ets\bulkpnp.c
> @ 54]
> f87d0882 8bff mov edi,edi
>
> FAULTING_SOURCE_CODE:
> 50:
> 51: NT status value
> 52:
> 53: –
/
> > 54: {
> 55: PIO_STACK_LOCATION irpStack;
> 56: PDEVICE_EXTENSION deviceExtension;
> 57: KEVENT startDeviceEvent;
> 58: NTSTATUS ntStatus;
> 59:
>
>
> SYMBOL_NAME: ViaUsbEts!BulkUsb_DispatchPnP+0
>
> FOLLOWUP_NAME: MachineOwner
>
> FAILURE_BUCKET_ID: 0xc9_22e_VRF_ViaUsbEts!BulkUsb_DispatchPnP+0
>
> BUCKET_ID: 0xc9_22e_VRF_ViaUsbEts!BulkUsb_DispatchPnP+0
>
> Followup: MachineOwner
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Mark Roddy

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Hagen Patzke
Sent: Sunday, February 17, 2008 2:15 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] usb driver DTM plug and play test failed

  • If you have to support Win98SE/WinME, you must use WDM. Sorry!

If you have to support w9x, change the job. This crappy OS parody is
dead and should be dead forever.

Alternatively, write an INF which uses UsbScan built-in driver. It is
also junk and has ridiculous interface but it isn’t less stable than the
rest of w9x. We did it when supported w9x. And still use it for w2k
which support hopefully ends soon.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Hagen Patzke
Sent: Sunday, February 17, 2008 2:05 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] usb driver DTM plug and play test failed

Could you state what is so miserable about it - I’ve seen the
MS changes
in this sample from DDK98 to WDM6000RTM, and a lot of unused
code - what
fundamental dangers did I miss?

Shortly, almost everything :wink:

I don’t remember all problems as I had to rewrite at least half of code
within past years and my memory leaks quickly. So only imcomplete list:

  • selective suspend cancellation which violates WDK rules. As a bonus,
    SS implementation includes several deadlocks and double IRP completion
    because of race conditions. SS implementation is probably the worst
    part. It was forcibly added to the original code and wasn’t tested
    thoroughly (if ever)
  • IO counting code. There are several built-in deadlocks and whole
    design is ridiculous.
  • WaitWake IRP handling. Race conditions or several kinds.
  • Sx IRP handling which doesn’t fulfil Vista boot time needs
  • wrong Query Sx rules (might be already fixed)
  • driver isn’t correctly protected against premature unload -> BSOD

and many others which I forgot. There is a lot of race conditions in
different parts of code which lead to various BSODs. There are also
deadlocks which cause lockup during power transitions at XP and BSOD at
Vista after some time (because OS now timeouts).

IMHO if it is so miserable, MS should replace it with a real safe,
production-grade multi-platform sample. This way existing WDM drivers
(based on BulkUSB) can be upgraded to something acceptable.

They already did. There is KMDF sample available and I doubt they’ll
rewrite WDM samples.

If you need to support legacy Windows versions, even today you might
want to go for one WDM driver instead of using 2-3 driver
frameworks -
WDM for W98SE/ME, KMDF for W2K, UMDF/WinUSB for WinXP/Vista. Oh, I
forgot W2K3 Server… KMDF? (Which version?) Or WinUSB?

We use UsbScan for legacy OSes (w9x and w2k) and WDM driver for
everything else. WDM driver could be replaced with both UMDF and KMDF
versions.

> minutes and the performance was quite comparable with my driver.

Ahem… we’d lose 10-20% of performance, if switching from
WDM to UMDF.
(BTW, this was confirmd by s/o from MS as an excellent value.)

Sorry, I was speaking about WinUsb used directly by user mode code. Not
about user mode code using UMDF driver based on WinUsb. This is quite
different. UMDF needs kernel mode reflector which reroutes user mode
requests from app back to user mode where UMDF driver lives and it then
send them to WinUsb running in kernel mode. No surprise performance
degrades a bit.

So it’ll probably not be much help - in our case - if UMDF is
as fast as
using WinUSB - we need these 10-20% performance.

It depends on your design. WinUsb itself is as fast as WDM driver so
UMDF driver using it can be as fast as your app using WDM driver. The
problem is (probably) app using UMDF driver the same way as WDM driver
previously. If you move your user mode app/library inside UMDF driver
and export different interface, performance can be comparable. For
example, if you have a DLL which communicates with USB driver and
exports some high-level interface, move this code to UMDF driver and
export the original interface as IOCTLs. From app point of view there
can be still a DLL which’d just send new IOCTLs instead of USB requests.

The second possibility is to use KMDF driver instead of WDM.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

I have some comments regarding UMDF perf for USB devices.

Ahem… we’d lose 10-20% of performance, if switching from WDM to
UMDF.

I am not sure where this number comes from. If you use asynchronous requests with transfer size of >= 64k for bulk transfers, the UMDF throughput should be indistinguishable from that of a WDM/KMDF driver for USB 2.0. In such case UMDF latency is hidden behind asynchronous request processing and USB bus would be the bottleneck and not UMDF.

You would pay some penalty in terms of CPU usage however. That is what would typically be 10-20% when saturating USB bus on typical machines of today.

The following can lead to lower perf with UMDF however (I can, of course, not guarantee that this is an exhaustive list):

  1. If your app (or driver) does a lot of processing while transferring or receiving data from USB device and saturates the CPU, UMDF would steal some CPU cycles from the app which could cause drop in the overall perf.

  2. UMDF overhead is a per request overhead. If you do bulk transfer using several small requests of a few kb, UMDF overhead would become predominant and what I said above regarding performance parity with kernel drivers would not hold true. In such case consider consolidating your small requests into larger requests, if possible.

  3. Latency of an individual requests with UMDF would definitely be higher than with a kernel driver. So if you do synchronous processing and/or per request latency is of importance to you, then UMDF may indeed provide you lower perf.

Best way to judge is to have a mock up of your driver in UMDF (esp. the perf sensitive paths) and measure the perf and see if you find any real problems. You could adapt UMDF OSR USB fx2 sample to your device and do this measurement. I realize this is some work but that is the best way to evaluate perf as perf guesses are often not right.

With UMDF you would gain in terms of ease of development (no kernel code) and debugging (as the failures are isolated in your driver host process) and system stability.

If only single application talks to your device and you are still concerned about UMDF perf (possibly because your scenario falls under the problematic ones listed above) you can possibly use WinUSB directly in your app as Michal suggested. If general, if you can get away without having a kernel driver, that’s a win for everyone. If that still doesn’t work please consider using a KMDF driver.

HTH,
Praveen

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Michal Vodicka
Sent: Monday, February 18, 2008 3:40 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] usb driver DTM plug and play test failed

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Hagen Patzke
Sent: Sunday, February 17, 2008 2:05 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] usb driver DTM plug and play test failed

Could you state what is so miserable about it - I’ve seen the
MS changes
in this sample from DDK98 to WDM6000RTM, and a lot of unused
code - what
fundamental dangers did I miss?

Shortly, almost everything :wink:

I don’t remember all problems as I had to rewrite at least half of code
within past years and my memory leaks quickly. So only imcomplete list:

  • selective suspend cancellation which violates WDK rules. As a bonus,
    SS implementation includes several deadlocks and double IRP completion
    because of race conditions. SS implementation is probably the worst
    part. It was forcibly added to the original code and wasn’t tested
    thoroughly (if ever)
  • IO counting code. There are several built-in deadlocks and whole
    design is ridiculous.
  • WaitWake IRP handling. Race conditions or several kinds.
  • Sx IRP handling which doesn’t fulfil Vista boot time needs
  • wrong Query Sx rules (might be already fixed)
  • driver isn’t correctly protected against premature unload -> BSOD

and many others which I forgot. There is a lot of race conditions in
different parts of code which lead to various BSODs. There are also
deadlocks which cause lockup during power transitions at XP and BSOD at
Vista after some time (because OS now timeouts).

IMHO if it is so miserable, MS should replace it with a real safe,
production-grade multi-platform sample. This way existing WDM drivers
(based on BulkUSB) can be upgraded to something acceptable.

They already did. There is KMDF sample available and I doubt they’ll
rewrite WDM samples.

If you need to support legacy Windows versions, even today you might
want to go for one WDM driver instead of using 2-3 driver
frameworks -
WDM for W98SE/ME, KMDF for W2K, UMDF/WinUSB for WinXP/Vista. Oh, I
forgot W2K3 Server… KMDF? (Which version?) Or WinUSB?

We use UsbScan for legacy OSes (w9x and w2k) and WDM driver for
everything else. WDM driver could be replaced with both UMDF and KMDF
versions.

> minutes and the performance was quite comparable with my driver.

Ahem… we’d lose 10-20% of performance, if switching from
WDM to UMDF.
(BTW, this was confirmd by s/o from MS as an excellent value.)

Sorry, I was speaking about WinUsb used directly by user mode code. Not
about user mode code using UMDF driver based on WinUsb. This is quite
different. UMDF needs kernel mode reflector which reroutes user mode
requests from app back to user mode where UMDF driver lives and it then
send them to WinUsb running in kernel mode. No surprise performance
degrades a bit.

So it’ll probably not be much help - in our case - if UMDF is
as fast as
using WinUSB - we need these 10-20% performance.

It depends on your design. WinUsb itself is as fast as WDM driver so
UMDF driver using it can be as fast as your app using WDM driver. The
problem is (probably) app using UMDF driver the same way as WDM driver
previously. If you move your user mode app/library inside UMDF driver
and export different interface, performance can be comparable. For
example, if you have a DLL which communicates with USB driver and
exports some high-level interface, move this code to UMDF driver and
export the original interface as IOCTLs. From app point of view there
can be still a DLL which’d just send new IOCTLs instead of USB requests.

The second possibility is to use KMDF driver instead of WDM.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Praveen Rao wrote:

I have some comments regarding UMDF perf for USB devices.

> Ahem… we’d lose 10-20% of performance, if switching from WDM to
> UMDF.

I am not sure where this number comes from.

From measurements. :wink:

For some years our company uses the same basic comms protocol on various
channels (Eth/Usb/Proprietary/Citrix), so I can’t change it.
This protocol uses request/response blocks with a max. size of ~16kB.

If you use asynchronous requests with transfer size of >= 64k for
bulk transfers, the UMDF throughput should be indistinguishable from
that of a WDM/KMDF driver for USB 2.0. In such case UMDF latency is
hidden behind asynchronous request processing and USB bus would be
the bottleneck and not UMDF.

…which I assumed was the reason that MS could state “UMDF can saturate
USB 2.0” in the white papers available for download.

  1. UMDF overhead is a per request overhead. If you do bulk transfer
    using several small requests of a few kb, UMDF overhead would become
    predominant and what I said above regarding performance parity with
    kernel drivers would not hold true.

Yes, I figured that out at the time. :slight_smile:

IMO it would be nice if MS had a statement somewhere telling this
important fact in the documentation about UMDF.
Or - better! - even some measurements/performance comparisons.

In such case consider
consolidating your small requests into larger requests, if possible.

I did look into it, but unfortunately in our case this is not possible.

In the nature of our devices lies that there is a lot of status
information that needs to be exchanged. So there’s lots of small
requests, and only occasionally a contiguous burst of large ones.

  1. Latency of an individual requests with UMDF would definitely be
    higher than with a kernel driver. So if you do synchronous processing
    and/or per request latency is of importance to you, then UMDF may
    indeed provide you lower perf.

That’s the second contributing factor. :slight_smile:
We dispatch the requsts asynchronously, but then have to basically wait
for the result (or acknowledgement).
One of the “nice to test” things for me would be to write a test app
that tries out how everything works using synchronous requests.
(And if it works with the same throughput, possibly simplify the
application side of the communication system.)

Best way to judge is to have a mock up of your driver in UMDF (esp.
the perf sensitive paths) and measure the perf and see if you find
any real problems. You could adapt UMDF OSR USB fx2 sample to your
device and do this measurement. I realize this is some work but that
is the best way to evaluate perf as perf guesses are often not right.

No need for a mock-up. When I got the assignment to extend our driver
collection for Vista, I did some research, and to me UMDF seemed
absolutely the way to go at the time, so I started with writing one.

Therefore I do have a working, functional UMDF (WUDF) driver.

We can use it even parallel to the WDM version (different driver class
GUID), so for testing I could use one driver on one USB port, and the
other one on another USB port. Great!
(For deployment, however, I would have replaced one with the other,
using the same class GUID, of course. Or at least de-installed the old
version.)

When I measured throughput, I was puzzled, and analyzed and measured,
but could not find any major bottlenecks in the part I wrote.
On one of the connect newsgroups someone from MS confirmed that - with
our specific setup - 10-20% perf loss is actually an excellent value.

Then I found out that with WDM I could probably drop a lot of drivers
from our driver collection, and replace them with one “unified” WDM
driver – for everything from Win98SE up to Vista32 (plus another binary
for x64, and one for IA64).

That’s when I started re-writing our WDM driver, based on the WDK6000RTM
BulkUSB source, got the signatures working, and have now one driver, so
far working seemingly very stable, and useable for all OS variants.

If only single application talks to your device and you are still
concerned about UMDF perf (possibly because your scenario falls under
the problematic ones listed above) you can possibly use WinUSB
directly in your app as Michal suggested.

Once we can drop support for Win98SE/WinME (in a couple of years, I
guess), or if WinUSB becomes available for Win98SE/ME as well (when hell
freezes over, I guess), this is a seriously tempting consideration! :slight_smile:

If general, if you can get away without having a kernel driver,
that’s a win for everyone. If that still doesn’t work please consider
using a KMDF driver.

I completely agree. (And I can even claim to have tried. :slight_smile: )

But please understand: with the current - working - WDM setup, I have
now one “unified” WDM driver that runs on all OS versions we have to
support. Cuts down a lot on support and deployment efforts.

Going to KMDF plus WinUSB would - currently - not give me or our
customers any functional benefit, but only make the driver installation
process (and support) more complex.
Give me WinUSB for Win98SE/ME/2K, and I’ll reconsider. :slight_smile:

HTH, Praveen

Yes, thanks a lot for the insights! -H