Hi Alan,
> From: Alan Stern
> Sent: Friday, February 10, 2017 12:28 AM
>
> On Thu, 9 Feb 2017, Yoshihiro Shimoda wrote:
>
> >
> > > From: Alan Stern
> > > Sent: Thursday, February 09, 2017 12:39 AM
> > > On Wed, 8 Feb 2017, Yoshihiro Shimoda wrote:
< snip >
> > 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.
Thank you for the detail. I got it.
> > 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,
Yes, I'm using platform drivers for OHCI and EHCI.
> 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.
Thank you very much for this information!
If I added the following code, the issue disappeared:
- The ehci-platform.c calls device_enable_async_suspend(hcd->self.controller)
in ehci_platform_probe()
- [This is a dirty code, but] hcd_bus_resume() calls device_pm_wait_for_dev(
rhdev->bus->controller, ohci_dev)
I will consider how to implement such a code for [eo]hci-platform drivers.
Especially, like ehci_{pre,post}_add() for platform drivers are needed, I think.
Best regards,
Yoshihiro Shimoda
> Alan Stern