On Thu, 9 Feb 2017, Yoshihiro Shimoda wrote:

> Hi Alan,
> 
> Thank you for the reply!
> 
> > From: Alan Stern
> > Sent: Thursday, February 09, 2017 12:39 AM
> > 
> > On Wed, 8 Feb 2017, Yoshihiro Shimoda wrote:
> > 
> > > Hi,
> > >
> > > In my environment, it causes the following message during system resume 
> > > if debug messages are enabled:
> > >
> > >   usb 2-1: Waited 2000ms for CONNECT
> > 
> > This message indicates that the port was connected to a device when the
> > system suspended, but when the system resumed the port was not
> > connected.  (Or the device did not properly enable its terminating
> > resistors, or some other problem of the same general sort.)
> 
> Yes, I understood it.
> 
> > > < My environment >
> > >  - EHCI/OHCI controllers on R-Car H3 
> > > (arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts)
> > >  - Greg's usb.git / next branch 
> > > (c95a9f83711bf53faeb4ed9bbb63a3f065613dfb) + some dts patches for R-Car H3
> > >  - A USB 1.1 (full speed) device (A USB1.1 hub is easy to reproduce)

...

> I checked the ehci_handover_companion_ports().
> If I used a USB full speed hub, the !udev->maxchild in
> the persist_enabled_on_companion() was 0.
> Then, ehci_handover_companion_ports() didn't call ehci_hub_control().
> Is this expected behavior?
> 
> static int persist_enabled_on_companion(struct usb_device *udev, void *unused)
> {
>         return !udev->maxchild && udev->persist_enabled &&
>                 udev->bus->root_hub->speed < USB_SPEED_HIGH;
> }

Ah.  Yes, it is the desired behavior.  The idea is to skip switching 
the ports back to the companion if the only USB-1.1 devices with 
persist_enabled are hubs.  It doesn't matter if a hub gets disconnected 
temporarily and then reconnected.

> If I used a USB full/low speed device, the ehci_handover_companion_ports()
> called ehci_hub_control() and rans the following as well. However, OHCI didn't
> detect the connection. So, I need to investigate this issue more.
>                         if (status & PORT_OWNER)
>                                 ehci_writel(ehci, status | PORT_CSC, reg);

So the port _does_ get switched over to the companion controller, but
for some unknown reason the companion controller doesn't detect the
connection.  Perhaps this happens because
ehci_handover_companion_ports() runs before the OHCI controller gets
reinitialized -- I noticed this in the log you posted before.

Hmmm.  You're using platform drivers for OHCI and EHCI, not PCI, 
right?  The resume_common() routine in drivers/usb/core/hcd-pci.c is 
careful to resume things in the correct order.  It contains this code:

                /*
                 * Only EHCI controllers have to wait for their companions.
                 * No locking is needed because PCI controller drivers do not
                 * get unbound during system resume.
                 */
                if (pci_dev->class == CL_EHCI && event != PM_EVENT_AUTO_RESUME)
                        for_each_companion(pci_dev, hcd,
                                        ehci_wait_for_companions);

Probably the equivalent routine in the platform driver needs to do the 
same sort of thing.  This means it needs to know about companion 
controllers.

Alan Stern

--
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

Reply via email to