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

Reply via email to