Hi, everybody.
We ported the Linux and related usb drivers to our embedded system, and using TUSB7340 as our host controller.
We also write a usb interface driver for the tested device(we say DUT A), the enumeration works fine.
But we encounter problem when we keep doing the bus reset to the same device,
the kernel will fail to complete the "set configuration" operation and argue that not enough bandwidth at 128th reset.
In addition to bus reset, if we plug and unplug the device repeatly, the host also fails to complete the set configuration.
Below are logs: (ep1 and ep2 are bulk endpoint, the kernel version is 3.0.30+)
1 Bus reset
usb 1-2: reset high speed USB device number 2 using xhci_hcd
xhci_hcd 0000:01:00.0: WARN: short transfer on control ep
xhci_hcd 0000:01:00.0: xHCI xhci_drop_endpoint called with disabled ep 81fb90e0
xhci_hcd 0000:01:00.0: xHCI xhci_drop_endpoint called with disabled ep 81fb910c
xhci_hcd 0000:01:00.0: xHCI xhci_drop_endpoint called with disabled ep 81fb9138
usb 1-2: ep 0x81 - rounding interval to 32768 microframes, ep desc says 0 micros
usb 1-2: ep 0x2 - rounding interval to 32768 microframes, ep desc says 0 microfs
[FT] skel_post_reset
[FT] usb_reset_device, result 0
...
2~127 are the same with 1
...
[FT] skel_pre_reset
128 Bus reset
usb 1-2: reset high speed USB device number 2 using xhci_hcd
xhci_hcd 0000:01:00.0: WARN: short transfer on control ep
xhci_hcd 0000:01:00.0: xHCI xhci_drop_endpoint called with disabled ep 81fb90e0
xhci_hcd 0000:01:00.0: xHCI xhci_drop_endpoint called with disabled ep 81fb910c
xhci_hcd 0000:01:00.0: xHCI xhci_drop_endpoint called with disabled ep 81fb9138
usb 1-2: ep 0x81 - rounding interval to 32768 microframes, ep desc says 0 micros
usb 1-2: ep 0x2 - rounding interval to 32768 microframes, ep desc says 0 microfs
usb 1-2: Not enough bandwidth for new device state.
usb 1-2: Busted HC? Not enough HCD resources for old configuration.
[FT] skel_post_reset
[FT] usb_reset_device, result -19
usb 1-2: USB disconnect, device number 2
[FT] skel_disconnect
skeleton 1-2:1.0: [FT] USB Skeleton #192 now disconnected
xhci_hcd 0000:01:00.0: xHCI xhci_drop_endpoint called with disabled ep 81fb90e0
xhci_hcd 0000:01:00.0: xHCI xhci_drop_endpoint called with disabled ep 81fb910c
xhci_hcd 0000:01:00.0: xHCI xhci_drop_endpoint called with disabled ep 81fb9138
[USB_CORE] generic_disconnect
usb 1-2: new high speed USB device number 3 using xhci_hcd
xhci_hcd 0000:01:00.0: WARN: short transfer on control ep
xhci_hcd 0000:01:00.0: WARN: short transfer on control ep
xhci_hcd 0000:01:00.0: WARN: short transfer on control ep
xhci_hcd 0000:01:00.0: WARN: short transfer on control ep
[USB_CORE] generic_probe, force select config #1
usb 1-2: ep 0x81 - rounding interval to 32768 microframes, ep desc says 0 micros
usb 1-2: ep 0x2 - rounding interval to 32768 microframes, ep desc says 0 microfs
usb 1-2: Not enough bandwidth for new device state.
usb 1-2: can't set config #1, error -28
Below are part of sources (modify from linux kernel usb skeleton.c)
static int skel_pre_reset(struct usb_interface *intf)
{
struct usb_skel *dev = usb_get_intfdata(intf);
printk(KERN_INFO "[FT] skel_pre_reset\n");
mutex_lock(&dev->io_mutex);
return 0;
}
static int skel_post_reset(struct usb_interface *intf)
{
struct usb_skel *dev = usb_get_intfdata(intf);
printk(KERN_INFO "[FT] skel_post_reset\n");
mutex_unlock(&dev->io_mutex);
return 0;
}
static long _usbft_bus_reset(struct file *filp)
{
struct usb_skel *dev;
long result = 0;
printk(KERN_DEBUG "[FT] Bus Reset\n");
dev = filp->private_data;
result = usb_lock_device_for_reset(dev->udev, NULL);
printk(KERN_DEBUG "[FT] usb_lock_device_for_reset, result %ld\n", result);
if(result != 0)
{
return result;
}
result = usb_reset_device(dev->udev);
printk(KERN_INFO "[FT] usb_reset_device, result %ld\n", result);
// release device lock
printk(KERN_DEBUG "[FT] device_unlock\n");
device_unlock(&(dev->udev->dev));
return result;
}
Does anybody has the same experience or some guide and would kindly share with us?
Thanks for your reading and helping.