On Fri, Oct 12, 2012 at 11:04:25AM -0400, Alan Stern wrote: > On Fri, 12 Oct 2012, Peter Chen wrote: > > > Taking EHCI controller as an example, it just needs to change > > ehci_bus_resume, > > if there is any enabled, unsuspended port, set > > hcd->unsuspended_device_on_port > > We don't need to do that. See below. > > > > usb_bus_resume() can poll the port statuses to see if there are any > > > enabled, unsuspended ports. If there aren't any, the delay can be > > > skipped. > > Taking EHCI controller as an example, you mean: > > > > - Change hcd_bus_resume like below: > > > > status = hcd->driver->bus_resume(hcd); > > clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); > > if (status == 0) { > > char buffer[6]; > > > > status = hcd->driver->hub_status_data(hcd, buffer); > > if (status != 0) { > > /* There are any enabled unsuspended ports */ > > /* TRSMRCY = 10 msec */ > > msleep(10); > > spin_lock_irq(&hcd_root_hub_lock); > > - Add get any enabled, unsuspended port as port change condition at > > ehci_hub_status_data. > > No, like this: > > --- usb-3.6.orig/drivers/usb/core/hcd.c > +++ usb-3.6/drivers/usb/core/hcd.c > @@ -2023,6 +2023,7 @@ int hcd_bus_resume(struct usb_device *rh > struct usb_hcd *hcd = container_of(rhdev->bus, struct usb_hcd, self); > int status; > int old_state = hcd->state; > + int port1; > > dev_dbg(&rhdev->dev, "usb %sresume\n", > (PMSG_IS_AUTO(msg) ? "auto-" : "")); > @@ -2039,8 +2040,6 @@ int hcd_bus_resume(struct usb_device *rh > status = hcd->driver->bus_resume(hcd); > clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); > if (status == 0) { > - /* TRSMRCY = 10 msec */ > - msleep(10); > spin_lock_irq(&hcd_root_hub_lock); > if (!HCD_DEAD(hcd)) { > usb_set_device_state(rhdev, rhdev->actconfig > @@ -2050,6 +2049,22 @@ int hcd_bus_resume(struct usb_device *rh > hcd->state = HC_STATE_RUNNING; > } > spin_unlock_irq(&hcd_root_hub_lock); > + > + /* Any enabled non-suspended port requires TRSMRCY delay */ > + for (port1 = 1; port1 <= rhdev->maxchild; ++port1) { > + __le16 buf[2]; > + unsigned pstatus; > + > + buf[0] = 0; > + hcd->driver->hub_control(hcd, USB_DIR_IN | USB_RT_PORT, > + 0, port1, (char *) buf, 4); > + pstatus = le16_to_cpu(buf[0]); > + if ((pstatus & USB_PORT_STAT_ENABLE) && > + !(pstatus & USB_PORT_STAT_SUSPEND)) { > + msleep(10); /* TRSMRCY */ > + break; > + } > + } > } else { > hcd->state = old_state; > dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", > > I haven't tested this, just compiled it. I have tested it at Freescale i.mx6Q sabrelite board, your patch is ok. Will you post a patch or I do it for you?
> > Alan Stern > > -- Best Regards, Peter Chen -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html