Re: [PATCH] USB: EHCI: don't reread PORTSC after disabling port power

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 20 Oct 2017, Uwe Kleine-König wrote:

> ehci_hub_control does the following related to overcurrent handling
> (simplified):
> 
> 	temp = ehci_readl(ehci, status_reg);
> 
> 	if (temp & PORT_OCC) {
> 		status |= USB_PORT_STAT_C_OVERCURRENT << 16;
> 
> 		if (temp & PORT_OC) {
> 			ehci_port_power(ehci, wIndex, false);
> 			temp = ehci_readl(ehci, status_reg);
> 		}
> 	}
> 
> 	if (temp & PORT_OC)
> 		status |= USB_PORT_STAT_OVERCURRENT;
> 
> At least on my i.MX25 based machine rereading the PORTSC register after
> port power was removed doesn't yield PORT_OC any more. The result is
> that repeatedly changes related to over-current
> (status |= USB_PORT_STAT_C_OVERCURRENT << 16) are reported, but
> USB_PORT_STAT_OVERCURRENT doesn't toggle as expected and is always
> unset. As a side effect the message
> 
> 	dev_err(&port_dev->dev, "over-current condition\n");
> 
> from drivers/usb/core/hub.c's port_event() never makes it to the user.
> 
> Rereading the value was introduced with the rationale:
> 
> 	I also think that the fact that we've cut off the port power
> 	should be reflected in the result of GetPortStatus request
> 	immediately, hence I'm adding a PORTSCn register readback after
> 	write...
> 
> As there are no further expected changes, just mask the PORT_POWER bit
> instead of rereading the register.
> 
> An alternative would be to check for PORT_OC before checking for
> PORT_OCC.
> 
> Fixes: 81463c1d7071 ("EHCI: only power off port if over-current is active")
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
> ---
>  drivers/usb/host/ehci-hub.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
> index df169c8e7225..08f59654654b 100644
> --- a/drivers/usb/host/ehci-hub.c
> +++ b/drivers/usb/host/ehci-hub.c
> @@ -1031,7 +1031,7 @@ int ehci_hub_control(
>  				spin_unlock_irqrestore(&ehci->lock, flags);
>  				ehci_port_power(ehci, wIndex, false);
>  				spin_lock_irqsave(&ehci->lock, flags);
> -				temp = ehci_readl(ehci, status_reg);
> +				temp |= ~PORT_POWER;
>  			}
>  		}
>  

Well, I don't know.  The USB spec says that if port power is off then a
lot of other port status bits have to be off also.  But the code tries
to have it both ways -- some of the status bits are recorded from
before the port power is turned off and some of them from afterward.

Maybe my original suggestion wasn't so good, and it would be better
simply to remove this line entirely.  Then the reported port status
would just be the values before power was removed, with no 
inconsistencies.  Can you try doing that instead and see if it works
equally well?

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux