Re: [PATCH] USB: mutual exclusion for EHCI init and port resets

David Brownell <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
On Wednesday 10 October 2007, Alan Stern wrote:
> This patch (as999) fixes a problem that sometimes shows up when host
> controller driver modules are loaded in the wrong order.  If ehci-hcd
> happens to initialize an EHCI controller while the companion OHCI or
> UHCI controller is in the middle of a port reset, the reset can fail
> and the companion may get very confused.  The patch adds an
> rw-semaphore and uses it to keep EHCI initialization and port resets
> mutually exclusive.
> 
> Signed-off-by: Alan Stern <[email protected]>
> CC: David Brownell <[email protected]>

ACK.


> 
> ---
> 
> Index: usb-2.6/drivers/usb/core/hcd.h
> ===================================================================
> --- usb-2.6.orig/drivers/usb/core/hcd.h
> +++ usb-2.6/drivers/usb/core/hcd.h
> @@ -19,6 +19,8 @@
>  
>  #ifdef __KERNEL__
>  
> +#include <linux/rwsem.h>
> +
>  /* This file contains declarations of usbcore internals that are mostly
>   * used or exposed by Host Controller Drivers.
>   */
> @@ -470,5 +472,9 @@ static inline void usbmon_urb_complete(s
>  		: (in_interrupt () ? "in_interrupt" : "can sleep"))
>  
>  
> -#endif /* __KERNEL__ */
> +/* This rwsem is for use only by the hub driver and ehci-hcd.
> + * Nobody else should touch it.
> + */
> +extern struct rw_semaphore ehci_cf_port_reset_rwsem;
>  
> +#endif /* __KERNEL__ */
> Index: usb-2.6/drivers/usb/core/hub.c
> ===================================================================
> --- usb-2.6.orig/drivers/usb/core/hub.c
> +++ usb-2.6/drivers/usb/core/hub.c
> @@ -125,6 +125,12 @@ MODULE_PARM_DESC(use_both_schemes,
>  		"try the other device initialization scheme if the "
>  		"first one fails");
>  
> +/* Mutual exclusion for EHCI CF initialization.  This interferes with
> + * port reset on some companion controllers.
> + */
> +DECLARE_RWSEM(ehci_cf_port_reset_rwsem);
> +EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
> +
>  
>  static inline char *portspeed(int portstatus)
>  {
> @@ -1579,6 +1585,11 @@ static int hub_port_reset(struct usb_hub
>  {
>  	int i, status;
>  
> +	/* Block EHCI CF initialization during the port reset.
> +	 * Some companion controllers don't like it when they mix.
> +	 */
> +	down_read(&ehci_cf_port_reset_rwsem);
> +
>  	/* Reset the port */
>  	for (i = 0; i < PORT_RESET_TRIES; i++) {
>  		status = set_port_feature(hub->hdev,
> @@ -1610,7 +1621,7 @@ static int hub_port_reset(struct usb_hub
>  			usb_set_device_state(udev, status
>  					? USB_STATE_NOTATTACHED
>  					: USB_STATE_DEFAULT);
> -			return status;
> +			goto done;
>  		}
>  
>  		dev_dbg (hub->intfdev,
> @@ -1623,6 +1634,8 @@ static int hub_port_reset(struct usb_hub
>  		"Cannot enable port %i.  Maybe the USB cable is bad?\n",
>  		port1);
>  
> + done:
> +	up_read(&ehci_cf_port_reset_rwsem);
>  	return status;
>  }
>  
> Index: usb-2.6/drivers/usb/host/ehci-hcd.c
> ===================================================================
> --- usb-2.6.orig/drivers/usb/host/ehci-hcd.c
> +++ usb-2.6/drivers/usb/host/ehci-hcd.c
> @@ -645,10 +645,18 @@ static int ehci_run (struct usb_hcd *hcd
>  	 * are explicitly handed to companion controller(s), so no TT is
>  	 * involved with the root hub.  (Except where one is integrated,
>  	 * and there's no companion controller unless maybe for USB OTG.)
> +	 *
> +	 * Turning on the CF flag will transfer ownership of all ports
> +	 * from the companions to the EHCI controller.  If any of the
> +	 * companions are in the middle of a port reset at the time, it
> +	 * could cause trouble.  Write-locking ehci_cf_port_reset_rwsem
> +	 * guarantees that no resets are in progress.
>  	 */
> +	down_write(&ehci_cf_port_reset_rwsem);
>  	hcd->state = HC_STATE_RUNNING;
>  	ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
>  	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
> +	up_write(&ehci_cf_port_reset_rwsem);
>  
>  	temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
>  	ehci_info (ehci,
> 



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.