Hi,
Our product is a USB redirection software - our generic USB function driver
loads for all USB mass storage & HID devices. This acts as pass-thru
between the devices and the virtual USB stack (in the remote computer).
This solution is working fine with all the devices. But with HID LCD
signature tablets(Usage=1 UsagePage=13), when the background image is
transferred as series of BULK transfer, I see the BULK URB is kept pending
in usbohci.sys or usbuhci.sys indefinetely.
The OS (both local & remote) is Windows 7 enterprise.
The USB Analyzer logs & ETW logs clearly says the request is not posted to
the device. The WinDBG analysis also hints the same.
From the driver side, I’ve validated the pipehandle, TransferFlags &
buffer; these things looks fine.
BTW the same issue is *not* seen when I use NEC/Renasas USB 3 host
controller.
Now I wish to understand,
- When a bulk transfer is kept in pending state in USB Host Controller
driver?
- By any chance the device speed matters? When directly connected, the
device speed is reported as ‘2’, but with my USB redirection software, the
UsbSpeed is reported as ‘1’ (in ETW logs, even after handling
IOCTL_GET_CONNECTION_INFO_EX properly).
0: kd> dt -r _URB_BULK_OR_INTERRUPT_TRANSFER 0x84c1f628
Wdf01000!_URB_BULK_OR_INTERRUPT_TRANSFER
+0x000 Hdr : _URB_HEADER
+0x000 Length : 0x48
+0x002 Function : 9
+0x004 Status : 0x40000000
+0x008 UsbdDeviceHandle : 0x84b63b68 Void
+0x00c UsbdFlags : 0x22
+0x010 PipeHandle : 0x84bcca8c Void
+0x014 TransferFlags : 3
+0x018 TransferBufferLength : 0
+0x01c TransferBuffer : 0x84c1f670 Void
+0x020 TransferBufferMDL : 0x84b89ed0 _MDL
+0x000 Next : (null)
+0x004 Size : 0n32
+0x006 MdlFlags : 0n12
+0x008 Process : (null)
+0x00c MappedSystemVa : 0x84c1f670 Void
+0x010 StartVa : 0x84c1f000 Void
+0x014 ByteCount : 0x15
+0x018 ByteOffset : 0x670
+0x024 UrbLink : (null)
+0x028 hca : _URB_HCD_AREA
+0x000 Reserved8 : [8] 0x84bde400 Void
1: kd> !irp 0x84a0a3d0
Irp is active with 4 stacks 4 is current (= 0x84a0a4ac)
No Mdl: No System Buffer: Thread 00000000: Irp stack trace.
cmd flg cl Device File Completion-Context
[0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
>[f, 0] 0 e1 85c66028 00000000 9be94a80-84c1f600 Success Error Cancel
pending
\Driver\usbuhci myusbflt!CompleteUrb
Args: 84c1f628 00000000 00220003 00000000
Regards,
Gokul T V
Gokul TV wrote:
…
This solution is working fine with all the devices. But with HID LCD
signature tablets(Usage=1 UsagePage=13), when the background image is
transferred as series of BULK transfer, I see the BULK URB is kept
pending in usbohci.sys or usbuhci.sys indefinetely.
…
The USB Analyzer logs & ETW logs clearly says the request is not
posted to the device. The WinDBG analysis also hints the same.
From the driver side, I’ve validated the pipehandle, TransferFlags &
buffer; these things looks fine.
BTW the same issue is *not* seen when I use NEC/Renasas USB 3 host
controller.
Now I wish to understand,
- When a bulk transfer is kept in pending state in USB Host
Controller driver?
- By any chance the device speed matters? When directly connected,
the device speed is reported as ‘2’, but with my USB redirection
software, the UsbSpeed is reported as ‘1’ (in ETW logs, even after
handling IOCTL_GET_CONNECTION_INFO_EX properly).
The speed can make a HUGE difference. On a full-speed device, a bulk
endpoint is limited to a max packet size of no more than 64 bytes. On a
high-speed device, a bulk endpoint must have a max packet size of 512
bytes. You need to use different configuration descriptors for
full-speed and high-speed operation. If you’re passing the high-speed
configuration descriptor through when the stack is expecting the
full-speed descriptor, you might be getting a disconnect. Heck, the
interfaces and the endpoints can be completely different (although they
usually aren’t).
The TransferBufferLength is set to 0 here. That’s suspicious, too.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Hi Tim Roberts,
Thanks for your inputs and time.
> The TransferBufferLength is set to 0 here. That’s suspicious, too.
I’ve verified this in the WinDBG - USBPORT_ProcessUrb alters the
TransferBufferLength
(direction) once we post the request. Looks like this is normal.
BTW, this issue looks to be related with ‘USB selective suspend’ . I tried
disabling the ‘USB Selective Suspend’ (as per this link,
http://www.groovypost.com/howto/usb-selective-suspend-windows-explained/ )
and with UHCI controllers my device is working fine. When I try the same
with OHCI controller, the issue exists!
Is it valid to return STATUS_CANCELLED for USB Idle Irp
(IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION)? Or what is the proper way to
reject USB Idle Irp (to stop Selective-Suspend)?
Regards,
Gokul T V
Gokul TV wrote:
BTW, this issue looks to be related with ‘USB selective suspend’ . I
tried disabling the ‘USB Selective Suspend’ (as per this
link, http://www.groovypost.com/howto/usb-selective-suspend-windows-explained/ )
and with UHCI controllers my device is working fine. When I try the
same with OHCI controller, the issue exists!
Is it valid to return STATUS_CANCELLED for USB Idle Irp
(IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION)? Or what is the proper
way to reject USB Idle Irp (to stop Selective-Suspend)?
So, you’re saying your fake hub is receiving this ioctl, telling you
that the device is ready to go idle, and you don’t want to play that
game. Is that right?
If so, then just complete the IRP with STATUS_SUCCESS. That ioctl says
“I’m ready to be suspended”, but the suspend operation only begins when
a lower-level driver calls the IdleCallback in the IRP. If no one calls
the idle callback, then no suspend will happen.
In other words, your response to “I’m ready to go idle” should be “gosh,
thanks very much for telling me.”
So, does this mean none of the devices on your “other end” system, where
the real hardware exists, can ever go idle? I hope you’re not running
that on a laptop on a battery.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Hi Tim,
Thanks for your inputs. Please find my inputs inline …
> So, you’re saying your fake hub is receiving this ioctl, telling you
that the device is ready to go idle, and you don’t want to play that game.
Is that right?
Yes.
> If so, then just complete the IRP with STATUS_SUCCESS.
Sure. I’ll try this & update the results.
>So, does this mean none of the devices on your “other end” system, where
the real hardware exists, can ever go idle?
>I hope you’re not running that on a laptop on a battery.
Yes. We are planning to implement this feature later (in staged manner).
The client side is PC for now.
Regards,
Gokul T V
Hi Tim,
Reporting the USB device speed properly
in USB_BUS_INTERFACE_USBDI_V1::IsDeviceHighSpeed(), solves the problem.
Looks like reporting the device speed in
IOCTL_GET_NODE_CONNECTION_INFO(_EX) doesn’t have any effect (only USBView
queries it).
Thanks for your time & support.
Regards,
Gokul T V