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)
> >
> > < Details >
> > - I investigated this issue and I found the issue is related the workqueue 
> > of drivers/usb/core/hub.c.
> >   If I modified the flags from WQ_FREEZABLE to "0", the issue disappeared.
> >
> >     /*
> >      * The workqueue needs to be freezable to avoid interfering with
> >      * USB-PERSIST port handover. Otherwise it might see that a full-speed
> >      * device was gone before the EHCI controller had handed its port
> >      * over to the companion full-speed controller.
> >      */
> >     hub_wq = alloc_workqueue("usb_hub_wq", WQ_FREEZABLE, 0);
> 
> That workqueue _must_ be freezable, as explained in the comment.

I got it.

> > - IIUC, an EHCI connects a full speed device first. After bus reset, an 
> > OHCI can connect the device.
> >   However, if WQ_FREEZABLE is set, the hub driver cannot issue bus reset 
> > while system resuming,
> 
> That's not true at all.  The port _does_ get reset, by
> ehci_handover_companion_ports() in drivers/usb/host/ehci-hub.c.  This
> code runs as part of the hub driver's resume routine, not in the hub_wq
> workqueue.

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

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

> >   and then the issue happened.
> >
> > - I also found another option about "persist" feature on sysfs. If a USB1.1 
> > device (exclude a hub) is connected,
> >   we can disable the feature via sysfs and then the issue also disappeared.
> >
> > < Question >
> > How to resolve the issue?
> >  - Can we modified the flags of the hub's workqueue?
> 
> Definitely not.

I got it.

> >  - Should we disable the persist feature if we need to avoid the wait in 
> > system resume?
> 
> You can disable it if you want, but you probably won't like the
> results.  (See what happens if you suspend the system while a flash
> drive is plugged into your USB-1.1 hub and is mounted.)

I understood it.

> >  - Or, other ideas?
> 
> Do some additional debugging and figure out why
> ehci_handover_companion_ports() isn't working properly on your system.

As I wrote above, I will debug an issue more why OHCI cannot detect
the connection on my system.

Best regards,
Yoshihiro Shimoda

> Alan Stern

Reply via email to