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