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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to