aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2010-01-14 08:29:02 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2010-01-14 08:29:02 -0800
commitbe3a4f9c213ed54aa7760b2a4dbc8886f8cf9bf3 (patch)
tree4aaf4a591cd2e253d2d648e871a61570b3a99176
parent9147191c813c705459d56b68523fe0d127594be5 (diff)
downloadpatches-be3a4f9c213ed54aa7760b2a4dbc8886f8cf9bf3.tar.gz
usb bugfixes
-rw-r--r--series6
-rw-r--r--usb.current/usb-add-missing-delay-during-remote-wakeup.patch75
-rw-r--r--usb.current/usb-don-t-use-gfp_kernel-while-we-cannot-reset-a-storage-device.patch70
-rw-r--r--usb.current/usb-ehci-fix-handling-of-unusual-interrupt-intervals.patch62
-rw-r--r--usb.current/usb-ehci-uhci-fix-race-between-root-hub-suspend-and-port-resume.patch86
-rw-r--r--usb.current/usb-fix-bitmask-merge-error.patch31
-rw-r--r--usb.current/usb-serial-fix-memory-leak-in-generic-driver.patch38
7 files changed, 368 insertions, 0 deletions
diff --git a/series b/series
index 8d22e8af08fe1b..25afe3321bd60d 100644
--- a/series
+++ b/series
@@ -21,6 +21,12 @@ tty.current/tty-fix-race-in-tty_fasync.patch
# USB patches for 2.6.33
#################################
usb.current/usb-serial-fix-usb-serial-fix-kfifo_len-locking.patch
+usb.current/usb-serial-fix-memory-leak-in-generic-driver.patch
+usb.current/usb-fix-bitmask-merge-error.patch
+usb.current/usb-don-t-use-gfp_kernel-while-we-cannot-reset-a-storage-device.patch
+usb.current/usb-ehci-fix-handling-of-unusual-interrupt-intervals.patch
+usb.current/usb-ehci-uhci-fix-race-between-root-hub-suspend-and-port-resume.patch
+usb.current/usb-add-missing-delay-during-remote-wakeup.patch
#################################
# Staging patches for 2.6.33
diff --git a/usb.current/usb-add-missing-delay-during-remote-wakeup.patch b/usb.current/usb-add-missing-delay-during-remote-wakeup.patch
new file mode 100644
index 00000000000000..573b5a6ea6dd93
--- /dev/null
+++ b/usb.current/usb-add-missing-delay-during-remote-wakeup.patch
@@ -0,0 +1,75 @@
+From stern@rowland.harvard.edu Thu Jan 14 08:18:33 2010
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 8 Jan 2010 11:18:38 -0500 (EST)
+Subject: USB: add missing delay during remote wakeup
+To: Greg KH <greg@kroah.com>
+Message-ID: <Pine.LNX.4.44L0.1001081109550.4862-100000@iolanthe.rowland.org>
+
+
+This patch (as1330) fixes a bug in khbud's handling of remote
+wakeups. When a device sends a remote-wakeup request, the parent hub
+(or the host controller driver, for directly attached devices) begins
+the resume sequence and notifies khubd when the sequence finishes. At
+this point the port's SUSPEND feature is automatically turned off.
+
+However the device needs an additional 10-ms resume-recovery time
+(TRSMRCY in the USB spec). Khubd does not wait for this delay if the
+SUSPEND feature is off, and as a result some devices fail to behave
+properly following a remote wakeup. This patch adds the missing
+delay to the remote-wakeup path.
+
+It also extends the resume-signalling delay used by ehci-hcd and
+uhci-hcd from 20 ms (the value in the spec) to 25 ms (the value we use
+for non-remote-wakeup resumes). The extra time appears to help some
+devices.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@kernel.org>
+Cc: Rickard Bellini <rickard.bellini@ericsson.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/core/hub.c | 3 +++
+ drivers/usb/host/ehci-hcd.c | 5 +++--
+ drivers/usb/host/uhci-hub.c | 2 +-
+ 3 files changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -3347,6 +3347,9 @@ static void hub_events(void)
+ USB_PORT_FEAT_C_SUSPEND);
+ udev = hdev->children[i-1];
+ if (udev) {
++ /* TRSMRCY = 10 msec */
++ msleep(10);
++
+ usb_lock_device(udev);
+ ret = remote_wakeup(hdev->
+ children[i-1]);
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -787,9 +787,10 @@ static irqreturn_t ehci_irq (struct usb_
+
+ /* start 20 msec resume signaling from this port,
+ * and make khubd collect PORT_STAT_C_SUSPEND to
+- * stop that signaling.
++ * stop that signaling. Use 5 ms extra for safety,
++ * like usb_port_resume() does.
+ */
+- ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
++ ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
+ ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
+ mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
+ }
+--- a/drivers/usb/host/uhci-hub.c
++++ b/drivers/usb/host/uhci-hub.c
+@@ -167,7 +167,7 @@ static void uhci_check_ports(struct uhci
+ /* Port received a wakeup request */
+ set_bit(port, &uhci->resuming_ports);
+ uhci->ports_timeout = jiffies +
+- msecs_to_jiffies(20);
++ msecs_to_jiffies(25);
+
+ /* Make sure we see the port again
+ * after the resuming period is over. */
diff --git a/usb.current/usb-don-t-use-gfp_kernel-while-we-cannot-reset-a-storage-device.patch b/usb.current/usb-don-t-use-gfp_kernel-while-we-cannot-reset-a-storage-device.patch
new file mode 100644
index 00000000000000..38552c62238cd3
--- /dev/null
+++ b/usb.current/usb-don-t-use-gfp_kernel-while-we-cannot-reset-a-storage-device.patch
@@ -0,0 +1,70 @@
+From oliver@neukum.org Thu Jan 14 08:16:43 2010
+From: Oliver Neukum <oliver@neukum.org>
+Date: Tue, 12 Jan 2010 12:32:50 +0100
+Subject: USB: Don't use GFP_KERNEL while we cannot reset a storage device
+To: Greg KH <greg@kroah.com>, Alan Stern <stern@rowland.harvard.edu>, stable@kernel.org
+Message-ID: <201001121232.50649.oliver@neukum.org>
+
+
+From: Oliver Neukum <oliver@neukum.org>
+
+Memory allocations with GFP_KERNEL can cause IO to a storage
+device which can fail resulting in a need to reset the device.
+Therefore GFP_KERNEL cannot be safely used between usb_lock_device()
+and usb_unlock_device(). Replace by GFP_NOIO.
+
+Signed-off-by: Oliver Neukum <oliver@neukum.org>
+Cc: stable <stable@kernel.org>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/devices.c | 2 +-
+ drivers/usb/core/message.c | 8 ++++----
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/core/devices.c
++++ b/drivers/usb/core/devices.c
+@@ -494,7 +494,7 @@ static ssize_t usb_device_dump(char __us
+ return 0;
+ /* allocate 2^1 pages = 8K (on i386);
+ * should be more than enough for one device */
+- pages_start = (char *)__get_free_pages(GFP_KERNEL, 1);
++ pages_start = (char *)__get_free_pages(GFP_NOIO, 1);
+ if (!pages_start)
+ return -ENOMEM;
+
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -906,11 +906,11 @@ char *usb_cache_string(struct usb_device
+ if (index <= 0)
+ return NULL;
+
+- buf = kmalloc(MAX_USB_STRING_SIZE, GFP_KERNEL);
++ buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
+ if (buf) {
+ len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
+ if (len > 0) {
+- smallbuf = kmalloc(++len, GFP_KERNEL);
++ smallbuf = kmalloc(++len, GFP_NOIO);
+ if (!smallbuf)
+ return buf;
+ memcpy(smallbuf, buf, len);
+@@ -1731,7 +1731,7 @@ int usb_set_configuration(struct usb_dev
+ if (cp) {
+ nintf = cp->desc.bNumInterfaces;
+ new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
+- GFP_KERNEL);
++ GFP_NOIO);
+ if (!new_interfaces) {
+ dev_err(&dev->dev, "Out of memory\n");
+ return -ENOMEM;
+@@ -1740,7 +1740,7 @@ int usb_set_configuration(struct usb_dev
+ for (; n < nintf; ++n) {
+ new_interfaces[n] = kzalloc(
+ sizeof(struct usb_interface),
+- GFP_KERNEL);
++ GFP_NOIO);
+ if (!new_interfaces[n]) {
+ dev_err(&dev->dev, "Out of memory\n");
+ ret = -ENOMEM;
diff --git a/usb.current/usb-ehci-fix-handling-of-unusual-interrupt-intervals.patch b/usb.current/usb-ehci-fix-handling-of-unusual-interrupt-intervals.patch
new file mode 100644
index 00000000000000..1344d3c0a671ff
--- /dev/null
+++ b/usb.current/usb-ehci-fix-handling-of-unusual-interrupt-intervals.patch
@@ -0,0 +1,62 @@
+From stern@rowland.harvard.edu Thu Jan 14 08:17:40 2010
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 8 Jan 2010 11:17:55 -0500 (EST)
+Subject: USB: EHCI: fix handling of unusual interrupt intervals
+To: Greg KH <greg@kroah.com>
+Cc: Glynn Farrow <farrowg@sg.ibm.com>, Ramya Desai <ramya.desai@gmail.com>, <stable@kernel.org>
+Message-ID: <Pine.LNX.4.44L0.1001051703580.3002-100000@iolanthe.rowland.org>
+
+
+This patch (as1320) fixes two problems related to interrupt-URB
+scheduling in ehci-hcd.
+
+ URBs with an interval of 2 or 4 microframes aren't handled.
+ For the time being, the patch reduces to interval to 1 uframe.
+
+ URBs are constrained to have an interval no larger than 1024
+ frames by usb_submit_urb(). But some EHCI controllers allow
+ use of a schedule as short as 256 frames; for these
+ controllers we may have to decrease the interval to the
+ actual schedule length.
+
+The second problem isn't very significant since few devices expose
+interrupt endpoints with an interval larger than 256 frames. But the
+first problem is critical; it will prevent the kernel from working
+with devices having interrupt intervals of 2 or 4 uframes.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@kernel.org>
+Tested-by: Glynn Farrow <farrowg@sg.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-q.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/ehci-q.c
++++ b/drivers/usb/host/ehci-q.c
+@@ -849,9 +849,10 @@ qh_make (
+ * But interval 1 scheduling is simpler, and
+ * includes high bandwidth.
+ */
+- dbg ("intr period %d uframes, NYET!",
+- urb->interval);
+- goto done;
++ urb->interval = 1;
++ } else if (qh->period > ehci->periodic_size) {
++ qh->period = ehci->periodic_size;
++ urb->interval = qh->period << 3;
+ }
+ } else {
+ int think_time;
+@@ -874,6 +875,10 @@ qh_make (
+ usb_calc_bus_time (urb->dev->speed,
+ is_input, 0, max_packet (maxp)));
+ qh->period = urb->interval;
++ if (qh->period > ehci->periodic_size) {
++ qh->period = ehci->periodic_size;
++ urb->interval = qh->period;
++ }
+ }
+ }
+
diff --git a/usb.current/usb-ehci-uhci-fix-race-between-root-hub-suspend-and-port-resume.patch b/usb.current/usb-ehci-uhci-fix-race-between-root-hub-suspend-and-port-resume.patch
new file mode 100644
index 00000000000000..5e5a9efc6f24f1
--- /dev/null
+++ b/usb.current/usb-ehci-uhci-fix-race-between-root-hub-suspend-and-port-resume.patch
@@ -0,0 +1,86 @@
+From stern@rowland.harvard.edu Thu Jan 14 08:18:08 2010
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 8 Jan 2010 11:18:20 -0500 (EST)
+Subject: USB: EHCI & UHCI: fix race between root-hub suspend and port resume
+To: Greg KH <greg@kroah.com>
+Message-ID: <Pine.LNX.4.44L0.1001051706080.3002-100000@iolanthe.rowland.org>
+
+This patch (as1321) fixes a problem with EHCI and UHCI root-hub
+suspends: If the suspend occurs while a port is trying to resume, the
+resume doesn't finish and simply gets lost. When remote wakeup is
+enabled, this is undesirable behavior.
+
+The patch checks first to see if any port resumes are in progress, and
+if they are then it fails the root-hub suspend with -EBUSY.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-hub.c | 20 +++++++++++++++++++-
+ drivers/usb/host/uhci-hcd.c | 15 ++++++++++++++-
+ 2 files changed, 33 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -120,9 +120,26 @@ static int ehci_bus_suspend (struct usb_
+ del_timer_sync(&ehci->watchdog);
+ del_timer_sync(&ehci->iaa_watchdog);
+
+- port = HCS_N_PORTS (ehci->hcs_params);
+ spin_lock_irq (&ehci->lock);
+
++ /* Once the controller is stopped, port resumes that are already
++ * in progress won't complete. Hence if remote wakeup is enabled
++ * for the root hub and any ports are in the middle of a resume or
++ * remote wakeup, we must fail the suspend.
++ */
++ if (hcd->self.root_hub->do_remote_wakeup) {
++ port = HCS_N_PORTS(ehci->hcs_params);
++ while (port--) {
++ if (ehci->reset_done[port] != 0) {
++ spin_unlock_irq(&ehci->lock);
++ ehci_dbg(ehci, "suspend failed because "
++ "port %d is resuming\n",
++ port + 1);
++ return -EBUSY;
++ }
++ }
++ }
++
+ /* stop schedules, clean any completed work */
+ if (HC_IS_RUNNING(hcd->state)) {
+ ehci_quiesce (ehci);
+@@ -138,6 +155,7 @@ static int ehci_bus_suspend (struct usb_
+ */
+ ehci->bus_suspended = 0;
+ ehci->owned_ports = 0;
++ port = HCS_N_PORTS(ehci->hcs_params);
+ while (port--) {
+ u32 __iomem *reg = &ehci->regs->port_status [port];
+ u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
+--- a/drivers/usb/host/uhci-hcd.c
++++ b/drivers/usb/host/uhci-hcd.c
+@@ -749,7 +749,20 @@ static int uhci_rh_suspend(struct usb_hc
+ spin_lock_irq(&uhci->lock);
+ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
+ rc = -ESHUTDOWN;
+- else if (!uhci->dead)
++ else if (uhci->dead)
++ ; /* Dead controllers tell no tales */
++
++ /* Once the controller is stopped, port resumes that are already
++ * in progress won't complete. Hence if remote wakeup is enabled
++ * for the root hub and any ports are in the middle of a resume or
++ * remote wakeup, we must fail the suspend.
++ */
++ else if (hcd->self.root_hub->do_remote_wakeup &&
++ uhci->resuming_ports) {
++ dev_dbg(uhci_dev(uhci), "suspend failed because a port "
++ "is resuming\n");
++ rc = -EBUSY;
++ } else
+ suspend_rh(uhci, UHCI_RH_SUSPENDED);
+ spin_unlock_irq(&uhci->lock);
+ return rc;
diff --git a/usb.current/usb-fix-bitmask-merge-error.patch b/usb.current/usb-fix-bitmask-merge-error.patch
new file mode 100644
index 00000000000000..cbe59e66fcecfd
--- /dev/null
+++ b/usb.current/usb-fix-bitmask-merge-error.patch
@@ -0,0 +1,31 @@
+From stern@rowland.harvard.edu Thu Jan 14 08:14:27 2010
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 22 Dec 2009 23:16:32 -0500 (EST)
+Subject: USB: fix bitmask merge error
+To: Greg KH <greg@kroah.com>
+Cc: Matthew Dharm <mdharm-usb@one-eyed-alien.net>, USB Storage list <usb-storage@lists.one-eyed-alien.net>, Ben Efros <ben@pc-doctor.com>, <stable@kernel.org>, Daniel Kukula <daniel.kuku@gmail.com>
+Message-ID: <Pine.LNX.4.44L0.0912222315001.15267-100000@netrider.rowland.org>
+
+This patch adds a mask bit which was mistakenly omitted from the
+as1311 patch (usb-storage: add BAD_SENSE flag).
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/storage/usb.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/storage/usb.c
++++ b/drivers/usb/storage/usb.c
+@@ -434,7 +434,8 @@ static void adjust_quirks(struct us_data
+ u16 vid = le16_to_cpu(us->pusb_dev->descriptor.idVendor);
+ u16 pid = le16_to_cpu(us->pusb_dev->descriptor.idProduct);
+ unsigned f = 0;
+- unsigned int mask = (US_FL_SANE_SENSE | US_FL_FIX_CAPACITY |
++ unsigned int mask = (US_FL_SANE_SENSE | US_FL_BAD_SENSE |
++ US_FL_FIX_CAPACITY |
+ US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE |
+ US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 |
+ US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE |
diff --git a/usb.current/usb-serial-fix-memory-leak-in-generic-driver.patch b/usb.current/usb-serial-fix-memory-leak-in-generic-driver.patch
new file mode 100644
index 00000000000000..7cfe0ee8e58ac2
--- /dev/null
+++ b/usb.current/usb-serial-fix-memory-leak-in-generic-driver.patch
@@ -0,0 +1,38 @@
+From akpm@linux-foundation.org Thu Jan 14 08:13:16 2010
+From: Johan Hovold <jhovold@gmail.com>
+Date: Wed, 06 Jan 2010 15:48:42 -0800
+Subject: usb: serial: fix memory leak in generic driver
+Cc: jhovold@gmail.com, greg@kroah.com, jason.wessel@windriver.com, stable@kernel.org
+Message-ID: <201001062348.o06Nmgxs025739@imap1.linux-foundation.org>
+
+From: Johan Hovold <jhovold@gmail.com>
+
+Fix a regression introduced by commit
+715b1dc01fe44537e8fce9566e4bb48d6821d84b ("USB: usb_debug,
+usb_generic_serial: implement multi urb write").
+
+URB transfer buffer was never freed when using multi-urb writes.
+Currently the only driver enabling multi-urb writes is usb_debug.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Cc: Greg KH <greg@kroah.com>
+Acked-by: Jason Wessel <jason.wessel@windriver.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/generic.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/generic.c
++++ b/drivers/usb/serial/generic.c
+@@ -489,6 +489,8 @@ void usb_serial_generic_write_bulk_callb
+ dbg("%s - port %d", __func__, port->number);
+
+ if (port->serial->type->max_in_flight_urbs) {
++ kfree(urb->transfer_buffer);
++
+ spin_lock_irqsave(&port->lock, flags);
+ --port->urbs_in_flight;
+ port->tx_bytes_flight -= urb->transfer_buffer_length;