Re: [PATCHv2] USB: EHCI: Fix test mode sequence

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

 



On Fri, 8 Jul 2011, Boris Todorov wrote:

> The sequence to put port in test mode is not complete.
> According EHCI specification all enabled ports must be
> put in suspend.
> 
> Signed-off-by: Boris Todorov <boris.st.todorov@xxxxxxxxx>
> ---
>  drivers/usb/host/ehci-hub.c |   13 +++++++++++++
>  1 files changed, 13 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
> index ea6184b..4b513e4 100644
> --- a/drivers/usb/host/ehci-hub.c
> +++ b/drivers/usb/host/ehci-hub.c
> @@ -52,6 +52,7 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
>  	int		port;
>  	__le32		buf;
>  	struct usb_hcd	*hcd = ehci_to_hcd(ehci);
> +	u32 __iomem     *port_sreg;
>  
>  	if (!ehci->owned_ports)
>  		return;
> @@ -1120,6 +1121,18 @@ static int ehci_hub_control (
>  			if (!selector || selector > 5)
>  				goto error;
>  			ehci_quiesce(ehci);
> +			/* put all enabled ports in suspend */
> +			while(ports--) {
> +				port_sreg = &ehci->regs->port_status[ports];
> +
> +				/* first check if port is enabled
> +				 * else results are undefined (according spec)
> +				 */
> +				if(ehci_readl(ehci, port_sreg) & PORT_PE)
> +					ehci_writel(ehci,
> +						ehci_readl(ehci, port_sreg)|PORT_SUSPEND,
> +						port_sreg);
> +			}
>  			ehci_halt(ehci);
>  			temp |= selector << 16;
>  			ehci_writel(ehci, temp, status_reg);

You didn't try to compile this, did you?

You didn't mask out the RWC bits before rewriting the status register
(although in this situation it probably doesn't matter).  Also, the
repeated ehci_readl() calls look odd.  And the final ehci_writel() 
turns off suspend mode for the port you're interested in!

Try out this version instead:

 drivers/usb/host/ehci-hub.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

Index: usb-3.0/drivers/usb/host/ehci-hub.c
===================================================================
--- usb-3.0.orig/drivers/usb/host/ehci-hub.c
+++ usb-3.0/drivers/usb/host/ehci-hub.c
@@ -1120,7 +1120,20 @@ static int ehci_hub_control (
 			if (!selector || selector > 5)
 				goto error;
 			ehci_quiesce(ehci);
+
+			/* Put all enabled ports into suspend */
+			while (ports--) {
+				u32 __iomem *sreg =
+						&ehci->regs->port_status[ports];
+
+				temp = ehci_readl(ehci, sreg) & ~PORT_RWC_BITS;
+				if (temp & PORT_PE)
+					ehci_writel(ehci, temp | PORT_SUSPEND,
+							sreg);
+			}
+
 			ehci_halt(ehci);
+			temp = ehci_readl(ehci, status_reg);
 			temp |= selector << 16;
 			ehci_writel(ehci, temp, status_reg);
 			break;

If this works on your system, submit it to Greg and I'll sign off on 
it.

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