On Wed, 9 Sep 2015, Roland Weber wrote:
> Hi Alan,
>
> I've switched to kernel 4.2 for the latest debug sessions.
> In drivers/usb/host/ehci-hcd.c, ehci_stop calls
> ehci_silence_controller which calls ehci_halt:
>
> static int ehci_halt (struct ehci_hcd *ehci)
> {
> u32 temp;
>
> printk(KERN_INFO "ehci_halt: entry\n");
> spin_lock_irq(&ehci->lock);
> printk(KERN_INFO "ehci_halt: after spin_lock_irq\n");
>
> /* disable any irqs left enabled by previous code */
> ehci_writel(ehci, 0, &ehci->regs->intr_enable);
> printk(KERN_INFO "ehci_halt: after first ehci_writel\n");
>
> if (ehci_is_TDI(ehci) && !tdi_in_host_mode(ehci)) {
> // this branch is not entered
> printk(KERN_INFO "ehci_halt: before early spin_unlock_irq\n");
> spin_unlock_irq(&ehci->lock);
> printk(KERN_INFO "ehci_halt: early exit\n");
> return 0;
> }
>
> /*
> * This routine gets called during probe before ehci->command
> * has been initialized, so we can't rely on its value.
> */
> ehci->command &= ~CMD_RUN;
> printk(KERN_INFO "ehci_halt: before ehci_readl\n");
> temp = ehci_readl(ehci, &ehci->regs->command);
> // this point is never reached
> printk(KERN_INFO "ehci_halt: after ehci_readl, before ehci_writel\n");
>
>
> There's one call to ehci_writel in the first part, which succeeds.
> Then the call of ehci_readl freezes. The name sounds like a generic
> communication primitive which is used from various places, so I
> didn't drill further down. If you think it might help, I will.
It is indeed a primitive operation, and there's no need to look into it
any deeper.
> Here's a transcript of the output I see:
>
> ehci-pci 0000:00:1d.0: remove, state 4
> ehci-pci 0000:00:1d.0: roothub graceful disconnect
> usb usb3: USB disconnect, device number 1
> usb3-1: USB disconnect, device number 2
> usb3-1: ep 81: release intr @ 8+64 (1.0+256) [1/0 us] mask 0001
> usb_remove_hcd: calling stop
> ehci-pci 0000:00:1d.0: stop
> ehci_silence_controller: entry
> ehci_halt: entry
> ehci_halt: after spin_lock_irq
> ehci_halt: after first ehci_writel
> ehci_halt: before ehci_readl
That is odd indeed. Note that ehci_halt() is called from ehci_setup(),
which runs during probing. So that same statement was executed
properly at some point in the past.
The only reason I can think of why it might hang is if some clock got
turned off. But I don't know of any clock which would have that
effect, or which would get turned off before we reach this point.
I also don't understand why the ehci_readl() would freeze when the
preceding ehci_writel() succeeded. Can you try putting a copy of the
ehci_readl() line just before the ehci_writel(), to see if it will work
there?
It's understandable how this could be related to "lsusb -v". Since you
don't have any devices attached to this EHCI controller, it would
naturally go into runtime suspend shortly after probing. The lsusb
command would case it to wake up, after which it would go back into
runtime suspend. As it happens, the ehci_bus_suspend() routine calls
ehci_halt().
Alan Stern
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html