On Thu, 21 Feb 2008, Herton Ronaldo Krzesinski wrote:
> I inserted some dev_printk/printk's, I paste here for reference. I went
> further
> trying to debug, so that's why there is more things, I'll explain:
Your debugging helped. Here are the key lines:
> [ 58.071856] hub 5-0:1.0: trying to enable port power on non-switchable hub
> [ 58.172665] ehci_hcd 0000:00:1d.7: GetStatus port 1 status 001803 POWER
> sig=j CSC CONNECT
> [ 58.183620] usb 1-1: finish reset-resume
> [ 58.183627] usb 1-1: finish_port_resume: udev->reset_resume enabled
> [ 58.234776] ehci_hcd 0000:00:1d.7: port 1 high speed
> [ 58.234785] ehci_hcd 0000:00:1d.7: GetStatus port 1 status 001007 POWER
> sig=se0 PE CSC CONNECT
> [ 58.234803] usb 1-1: usb_reset_device ret == -107
> [ 58.234807] hub 1-0:1.0: logical disconnect on port 1
> [ 58.234815] usb 1-1: gone after usb resume? status -19
> [ 58.234819] usb 1-1: can't resume, status -19
> So the child branch is taken and USB_PERSIST && child->persist_enabled
> evaluates as true. Also udev->reset_resume is enabled. The problem here
> is inside usb_reset_device. The devices are redetected because a
> reenumeration is forced, see that usb_reset_device return -ENOTCONN because:
>
> - usb_reset_device call chain is hub_port_init -> hub_port_reset ->
> hub_port_wait_reset. In hub_port_wait_reset, the call to hub_port_status
> doesn't fail, but portstatus or portchange are respectively
> USB_PORT_STAT_CONNECTION or USB_PORT_STAT_C_CONNECTION
> (Look that no one of the printks in hub_port_wait_reset are printed),
> and -ENOTCONN then from one of the two returns go back until
> usb_reset_device that then takes the re_enumeration label that causes the
> logical disconnect, so the redetection happens.
>
> I don't know why ehci is returning this portchange/portstatus, but this is
> triggering the redetection.
Yes, the problem is the USB_PORT_STAT_C_CONNECTION. (Although I'm not
sure why udev->reset_resume was enabled...)
Anyway, try this patch; it ought to help.
Alan Stern
Index: usb-2.6/drivers/usb/core/hub.c
===================================================================
--- usb-2.6.orig/drivers/usb/core/hub.c
+++ usb-2.6/drivers/usb/core/hub.c
@@ -1903,6 +1903,24 @@ int usb_port_resume(struct usb_device *u
status = hub_port_status(hub, port1, &portstatus, &portchange);
SuspendCleared:
+ /* Even if the root hub didn't lose power, an unplug-replug
+ * cycle should cause USB_PERSIST to kick in.
+ */
+ dev_dbg(&udev->dev, "persist_enabled %d status %d "
+ "portstatus %x change %x\n",
+ udev->persist_enabled, status,
+ portstatus, portchange);
+ if (USB_PERSIST && udev->persist_enabled && status >= 0 &&
+ !(portstatus & USB_PORT_STAT_ENABLE)) {
+ if (portchange & USB_PORT_STAT_C_ENABLE)
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_ENABLE);
+ if (portchange & USB_PORT_STAT_C_CONNECTION)
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_CONNECTION);
+ udev->reset_resume = 1;
+ }
+
if (USB_PERSIST && udev->reset_resume)
want_flags = USB_PORT_STAT_POWER
| USB_PORT_STAT_CONNECTION;
-
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html