From: Greg Kroah-Hartman Date: Tue, 19 Apr 2011 00:20:23 +0000 (-0700) Subject: .38 patches X-Git-Tag: v2.6.38.4~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=afb1efecbc5a1ca4eb521aed13fd22f1ce7a76ce;p=thirdparty%2Fkernel%2Fstable-queue.git .38 patches --- diff --git a/queue-2.6.38/series b/queue-2.6.38/series index 14797ef7484..a51a03e9ffc 100644 --- a/queue-2.6.38/series +++ b/queue-2.6.38/series @@ -56,3 +56,12 @@ next_pidmap-fix-overflow-condition.patch proc-do-proper-range-check-on-readdir-offset.patch powerpc-fix-oops-if-scan_dispatch_log-is-called-too-early.patch powerpc-perf_event-skip-updating-kernel-counters-if-register-value-shrinks.patch +usb-fix-qcserial-memory-leak-on-rmmod.patch +usb-qcserial-avoid-pointing-to-freed-memory.patch +usb-qcserial-add-missing-errorpath-kfrees.patch +usb-ehci-unlink-unused-qhs-when-the-controller-is-stopped.patch +usb-fix-formatting-of-superspeed-endpoints-in-proc-bus-usb-devices.patch +usb-xhci-fix-unsafe-macro-definitions.patch +usb-xhci-fix-math-in-xhci_get_endpoint_interval.patch +usb-xhci-also-free-streams-when-resetting-devices.patch +usb-fix-unplug-of-device-with-active-streams.patch diff --git a/queue-2.6.38/usb-ehci-unlink-unused-qhs-when-the-controller-is-stopped.patch b/queue-2.6.38/usb-ehci-unlink-unused-qhs-when-the-controller-is-stopped.patch new file mode 100644 index 00000000000..7333af1cd8e --- /dev/null +++ b/queue-2.6.38/usb-ehci-unlink-unused-qhs-when-the-controller-is-stopped.patch @@ -0,0 +1,76 @@ +From 94ae4976e253757e9b03a44d27d41b20f1829d80 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 5 Apr 2011 13:36:15 -0400 +Subject: USB: EHCI: unlink unused QHs when the controller is stopped + +From: Alan Stern + +commit 94ae4976e253757e9b03a44d27d41b20f1829d80 upstream. + +This patch (as1458) fixes a problem affecting ultra-reliable systems: +When hardware failover of an EHCI controller occurs, the data +structures do not get released correctly. This is because the routine +responsible for removing unused QHs from the async schedule assumes +the controller is running properly (the frame counter is used in +determining how long the QH has been idle) -- but when a failover +causes the controller to be electronically disconnected from the PCI +bus, obviously it stops running. + +The solution is simple: Allow scan_async() to remove a QH from the +async schedule if it has been idle for long enough _or_ if the +controller is stopped. + +Signed-off-by: Alan Stern +Reported-and-Tested-by: Dan Duval +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-q.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/drivers/usb/host/ehci-q.c ++++ b/drivers/usb/host/ehci-q.c +@@ -1245,24 +1245,27 @@ static void start_unlink_async (struct e + + static void scan_async (struct ehci_hcd *ehci) + { ++ bool stopped; + struct ehci_qh *qh; + enum ehci_timer_action action = TIMER_IO_WATCHDOG; + + ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index); + timer_action_done (ehci, TIMER_ASYNC_SHRINK); + rescan: ++ stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state); + qh = ehci->async->qh_next.qh; + if (likely (qh != NULL)) { + do { + /* clean any finished work for this qh */ +- if (!list_empty (&qh->qtd_list) +- && qh->stamp != ehci->stamp) { ++ if (!list_empty(&qh->qtd_list) && (stopped || ++ qh->stamp != ehci->stamp)) { + int temp; + + /* unlinks could happen here; completion + * reporting drops the lock. rescan using + * the latest schedule, but don't rescan +- * qhs we already finished (no looping). ++ * qhs we already finished (no looping) ++ * unless the controller is stopped. + */ + qh = qh_get (qh); + qh->stamp = ehci->stamp; +@@ -1283,9 +1286,9 @@ rescan: + */ + if (list_empty(&qh->qtd_list) + && qh->qh_state == QH_STATE_LINKED) { +- if (!ehci->reclaim +- && ((ehci->stamp - qh->stamp) & 0x1fff) +- >= (EHCI_SHRINK_FRAMES * 8)) ++ if (!ehci->reclaim && (stopped || ++ ((ehci->stamp - qh->stamp) & 0x1fff) ++ >= EHCI_SHRINK_FRAMES * 8)) + start_unlink_async(ehci, qh); + else + action = TIMER_ASYNC_SHRINK; diff --git a/queue-2.6.38/usb-fix-formatting-of-superspeed-endpoints-in-proc-bus-usb-devices.patch b/queue-2.6.38/usb-fix-formatting-of-superspeed-endpoints-in-proc-bus-usb-devices.patch new file mode 100644 index 00000000000..bfa64416c68 --- /dev/null +++ b/queue-2.6.38/usb-fix-formatting-of-superspeed-endpoints-in-proc-bus-usb-devices.patch @@ -0,0 +1,56 @@ +From 2868a2b1ba8f9c7f6c4170519ebb6c62934df70e Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 18 Mar 2011 21:29:01 -0700 +Subject: USB: fix formatting of SuperSpeed endpoints in /proc/bus/usb/devices + +From: Dmitry Torokhov + +commit 2868a2b1ba8f9c7f6c4170519ebb6c62934df70e upstream. + +Isochronous and interrupt SuperSpeed endpoints use the same mechanisms +for decoding bInterval values as HighSpeed ones so adjust the code +accordingly. + +Also bandwidth reservation for SuperSpeed matches highspeed, not +low/full speed. + +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/devices.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/usb/core/devices.c ++++ b/drivers/usb/core/devices.c +@@ -221,7 +221,7 @@ static char *usb_dump_endpoint_descripto + break; + case USB_ENDPOINT_XFER_INT: + type = "Int."; +- if (speed == USB_SPEED_HIGH) ++ if (speed == USB_SPEED_HIGH || speed == USB_SPEED_SUPER) + interval = 1 << (desc->bInterval - 1); + else + interval = desc->bInterval; +@@ -229,7 +229,8 @@ static char *usb_dump_endpoint_descripto + default: /* "can't happen" */ + return start; + } +- interval *= (speed == USB_SPEED_HIGH) ? 125 : 1000; ++ interval *= (speed == USB_SPEED_HIGH || ++ speed == USB_SPEED_SUPER) ? 125 : 1000; + if (interval % 1000) + unit = 'u'; + else { +@@ -542,8 +543,9 @@ static ssize_t usb_device_dump(char __us + if (level == 0) { + int max; + +- /* high speed reserves 80%, full/low reserves 90% */ +- if (usbdev->speed == USB_SPEED_HIGH) ++ /* super/high speed reserves 80%, full/low reserves 90% */ ++ if (usbdev->speed == USB_SPEED_HIGH || ++ usbdev->speed == USB_SPEED_SUPER) + max = 800; + else + max = FRAME_TIME_MAX_USECS_ALLOC; diff --git a/queue-2.6.38/usb-fix-qcserial-memory-leak-on-rmmod.patch b/queue-2.6.38/usb-fix-qcserial-memory-leak-on-rmmod.patch new file mode 100644 index 00000000000..8d245edb71f --- /dev/null +++ b/queue-2.6.38/usb-fix-qcserial-memory-leak-on-rmmod.patch @@ -0,0 +1,50 @@ +From 10c9ab15d6aee153968d150c05b3ee3df89673de Mon Sep 17 00:00:00 2001 +From: Steven Hardy +Date: Mon, 4 Apr 2011 17:57:37 +0100 +Subject: usb: Fix qcserial memory leak on rmmod + +From: Steven Hardy + +commit 10c9ab15d6aee153968d150c05b3ee3df89673de upstream. + +qcprobe function allocates serial->private but this is never freed, this +patch adds a new function qc_release() which frees serial->private, after +calling usb_wwan_release + +Signed-off-by: Steven Hardy +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/qcserial.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -205,6 +205,18 @@ static int qcprobe(struct usb_serial *se + return retval; + } + ++static void qc_release(struct usb_serial *serial) ++{ ++ struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); ++ ++ dbg("%s", __func__); ++ ++ /* Call usb_wwan release & free the private data allocated in qcprobe */ ++ usb_wwan_release(serial); ++ usb_set_serial_data(serial, NULL); ++ kfree(priv); ++} ++ + static struct usb_serial_driver qcdevice = { + .driver = { + .owner = THIS_MODULE, +@@ -222,7 +234,7 @@ static struct usb_serial_driver qcdevice + .chars_in_buffer = usb_wwan_chars_in_buffer, + .attach = usb_wwan_startup, + .disconnect = usb_wwan_disconnect, +- .release = usb_wwan_release, ++ .release = qc_release, + #ifdef CONFIG_PM + .suspend = usb_wwan_suspend, + .resume = usb_wwan_resume, diff --git a/queue-2.6.38/usb-fix-unplug-of-device-with-active-streams.patch b/queue-2.6.38/usb-fix-unplug-of-device-with-active-streams.patch new file mode 100644 index 00000000000..45eb889926a --- /dev/null +++ b/queue-2.6.38/usb-fix-unplug-of-device-with-active-streams.patch @@ -0,0 +1,50 @@ +From b214f191d95ba4b5a35aebd69cd129cf7e3b1884 Mon Sep 17 00:00:00 2001 +From: Matthew Wilcox +Date: Tue, 28 Sep 2010 00:57:32 -0400 +Subject: USB: Fix unplug of device with active streams + +From: Matthew Wilcox + +commit b214f191d95ba4b5a35aebd69cd129cf7e3b1884 upstream. + +If I unplug a device while the UAS driver is loaded, I get an oops +in usb_free_streams(). This is because usb_unbind_interface() calls +usb_disable_interface() which calls usb_disable_endpoint() which sets +ep_out and ep_in to NULL. Then the UAS driver calls usb_pipe_endpoint() +which returns a NULL pointer and passes an array of NULL pointers to +usb_free_streams(). + +I think the correct fix for this is to check for the NULL pointer +in usb_free_streams() rather than making the driver check for this +situation. My original patch for this checked for dev->state == +USB_STATE_NOTATTACHED, but the call to usb_disable_interface() is +conditional, so not all drivers would want this check. + +Note from Sarah Sharp: This patch does avoid a potential dereference, +but the real fix (which will be implemented later) is to set the +.soft_unbind flag in the usb_driver structure for the UAS driver, and +all drivers that allocate streams. The driver should free any streams +when it is unbound from the interface. This avoids leaking stream rings +in the xHCI driver when usb_disable_interface() is called. + +This should be queued for stable trees back to 2.6.35. + +Signed-off-by: Matthew Wilcox +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -1885,7 +1885,7 @@ void usb_free_streams(struct usb_interfa + + /* Streams only apply to bulk endpoints. */ + for (i = 0; i < num_eps; i++) +- if (!usb_endpoint_xfer_bulk(&eps[i]->desc)) ++ if (!eps[i] || !usb_endpoint_xfer_bulk(&eps[i]->desc)) + return; + + hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags); diff --git a/queue-2.6.38/usb-qcserial-add-missing-errorpath-kfrees.patch b/queue-2.6.38/usb-qcserial-add-missing-errorpath-kfrees.patch new file mode 100644 index 00000000000..3aab5fd7e18 --- /dev/null +++ b/queue-2.6.38/usb-qcserial-add-missing-errorpath-kfrees.patch @@ -0,0 +1,38 @@ +From cb62d65f966146a39fdde548cb474dacf1d00fa5 Mon Sep 17 00:00:00 2001 +From: Steven Hardy +Date: Mon, 4 Apr 2011 18:02:25 +0100 +Subject: usb: qcserial add missing errorpath kfrees + +From: Steven Hardy + +commit cb62d65f966146a39fdde548cb474dacf1d00fa5 upstream. + +There are two -ENODEV error paths in qcprobe where the allocated private +data is not freed, this patch adds the two missing kfrees to avoid +leaking memory on the error path + +Signed-off-by: Steven Hardy +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/qcserial.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -167,6 +167,7 @@ static int qcprobe(struct usb_serial *se + "Could not set interface, error %d\n", + retval); + retval = -ENODEV; ++ kfree(data); + } + } else if (ifnum == 2) { + dbg("Modem port found"); +@@ -191,6 +192,7 @@ static int qcprobe(struct usb_serial *se + "Could not set interface, error %d\n", + retval); + retval = -ENODEV; ++ kfree(data); + } + } + break; diff --git a/queue-2.6.38/usb-qcserial-avoid-pointing-to-freed-memory.patch b/queue-2.6.38/usb-qcserial-avoid-pointing-to-freed-memory.patch new file mode 100644 index 00000000000..b88e775f24c --- /dev/null +++ b/queue-2.6.38/usb-qcserial-avoid-pointing-to-freed-memory.patch @@ -0,0 +1,74 @@ +From 99ab3f9e4eaec35fd2d7159c31b71f17f7e613e3 Mon Sep 17 00:00:00 2001 +From: Steven Hardy +Date: Mon, 4 Apr 2011 17:59:55 +0100 +Subject: usb: qcserial avoid pointing to freed memory + +From: Steven Hardy + +commit 99ab3f9e4eaec35fd2d7159c31b71f17f7e613e3 upstream. + +Rework the qcprobe logic such that serial->private is not set when +qcprobe exits with -ENODEV, otherwise serial->private will point to freed +memory on -ENODEV + +Signed-off-by: Steven Hardy +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/qcserial.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -111,7 +111,7 @@ static int qcprobe(struct usb_serial *se + ifnum = intf->desc.bInterfaceNumber; + dbg("This Interface = %d", ifnum); + +- data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), ++ data = kzalloc(sizeof(struct usb_wwan_intf_private), + GFP_KERNEL); + if (!data) + return -ENOMEM; +@@ -134,8 +134,10 @@ static int qcprobe(struct usb_serial *se + usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { + dbg("QDL port found"); + +- if (serial->interface->num_altsetting == 1) +- return 0; ++ if (serial->interface->num_altsetting == 1) { ++ retval = 0; /* Success */ ++ break; ++ } + + retval = usb_set_interface(serial->dev, ifnum, 1); + if (retval < 0) { +@@ -145,7 +147,6 @@ static int qcprobe(struct usb_serial *se + retval = -ENODEV; + kfree(data); + } +- return retval; + } + break; + +@@ -177,7 +178,6 @@ static int qcprobe(struct usb_serial *se + retval = -ENODEV; + kfree(data); + } +- return retval; + } else if (ifnum==3) { + /* + * NMEA (serial line 9600 8N1) +@@ -199,9 +199,12 @@ static int qcprobe(struct usb_serial *se + dev_err(&serial->dev->dev, + "unknown number of interfaces: %d\n", nintf); + kfree(data); +- return -ENODEV; ++ retval = -ENODEV; + } + ++ /* Set serial->private if not returning -ENODEV */ ++ if (retval != -ENODEV) ++ usb_set_serial_data(serial, data); + return retval; + } + diff --git a/queue-2.6.38/usb-xhci-also-free-streams-when-resetting-devices.patch b/queue-2.6.38/usb-xhci-also-free-streams-when-resetting-devices.patch new file mode 100644 index 00000000000..3c455889642 --- /dev/null +++ b/queue-2.6.38/usb-xhci-also-free-streams-when-resetting-devices.patch @@ -0,0 +1,54 @@ +From 2dea75d96ade3c7cd2bfe73f99c7b3291dc3d03a Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Tue, 12 Apr 2011 23:06:28 -0700 +Subject: USB: xhci - also free streams when resetting devices + +From: Dmitry Torokhov + +commit 2dea75d96ade3c7cd2bfe73f99c7b3291dc3d03a upstream. + +Currently, when resetting a device, xHCI driver disables all but one +endpoints and frees their rings, but leaves alone any streams that +might have been allocated. Later, when users try to free allocated +streams, we oops in xhci_setup_no_streams_ep_input_ctx() because +ep->ring is NULL. + +Let's free not only rings but also stream data as well, so that +calling free_streams() on a device that was reset will be safe. + +This should be queued for stable trees back to 2.6.35. + +Reviewed-by: Micah Elizabeth Scott +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -2335,10 +2335,18 @@ int xhci_discover_or_reset_device(struct + /* Everything but endpoint 0 is disabled, so free or cache the rings. */ + last_freed_endpoint = 1; + for (i = 1; i < 31; ++i) { +- if (!virt_dev->eps[i].ring) +- continue; +- xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); +- last_freed_endpoint = i; ++ struct xhci_virt_ep *ep = &virt_dev->eps[i]; ++ ++ if (ep->ep_state & EP_HAS_STREAMS) { ++ xhci_free_stream_info(xhci, ep->stream_info); ++ ep->stream_info = NULL; ++ ep->ep_state &= ~EP_HAS_STREAMS; ++ } ++ ++ if (ep->ring) { ++ xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); ++ last_freed_endpoint = i; ++ } + } + xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); + xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); diff --git a/queue-2.6.38/usb-xhci-fix-math-in-xhci_get_endpoint_interval.patch b/queue-2.6.38/usb-xhci-fix-math-in-xhci_get_endpoint_interval.patch new file mode 100644 index 00000000000..7f499f1f9d8 --- /dev/null +++ b/queue-2.6.38/usb-xhci-fix-math-in-xhci_get_endpoint_interval.patch @@ -0,0 +1,148 @@ +From dfa49c4ad120a784ef1ff0717168aa79f55a483a Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Wed, 23 Mar 2011 22:41:23 -0700 +Subject: USB: xhci - fix math in xhci_get_endpoint_interval() + +From: Dmitry Torokhov + +commit dfa49c4ad120a784ef1ff0717168aa79f55a483a upstream. + +When parsing exponent-expressed intervals we subtract 1 from the +value and then expect it to match with original + 1, which is +highly unlikely, and we end with frequent spew: + + usb 3-4: ep 0x83 - rounding interval to 512 microframes + +Also, parsing interval for fullspeed isochronous endpoints was +incorrect - according to USB spec they use exponent-based +intervals (but xHCI spec claims frame-based intervals). I trust +USB spec more, especially since USB core agrees with it. + +This should be queued for stable kernels back to 2.6.31. + +Reviewed-by: Micah Elizabeth Scott +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-mem.c | 90 ++++++++++++++++++++++++++++++-------------- + 1 file changed, 62 insertions(+), 28 deletions(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -920,6 +920,47 @@ int xhci_setup_addressable_virt_dev(stru + return 0; + } + ++/* ++ * Convert interval expressed as 2^(bInterval - 1) == interval into ++ * straight exponent value 2^n == interval. ++ * ++ */ ++static unsigned int xhci_parse_exponent_interval(struct usb_device *udev, ++ struct usb_host_endpoint *ep) ++{ ++ unsigned int interval; ++ ++ interval = clamp_val(ep->desc.bInterval, 1, 16) - 1; ++ if (interval != ep->desc.bInterval - 1) ++ dev_warn(&udev->dev, ++ "ep %#x - rounding interval to %d microframes\n", ++ ep->desc.bEndpointAddress, ++ 1 << interval); ++ ++ return interval; ++} ++ ++/* ++ * Convert bInterval expressed in frames (in 1-255 range) to exponent of ++ * microframes, rounded down to nearest power of 2. ++ */ ++static unsigned int xhci_parse_frame_interval(struct usb_device *udev, ++ struct usb_host_endpoint *ep) ++{ ++ unsigned int interval; ++ ++ interval = fls(8 * ep->desc.bInterval) - 1; ++ interval = clamp_val(interval, 3, 10); ++ if ((1 << interval) != 8 * ep->desc.bInterval) ++ dev_warn(&udev->dev, ++ "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n", ++ ep->desc.bEndpointAddress, ++ 1 << interval, ++ 8 * ep->desc.bInterval); ++ ++ return interval; ++} ++ + /* Return the polling or NAK interval. + * + * The polling interval is expressed in "microframes". If xHCI's Interval field +@@ -937,45 +978,38 @@ static inline unsigned int xhci_get_endp + case USB_SPEED_HIGH: + /* Max NAK rate */ + if (usb_endpoint_xfer_control(&ep->desc) || +- usb_endpoint_xfer_bulk(&ep->desc)) ++ usb_endpoint_xfer_bulk(&ep->desc)) { + interval = ep->desc.bInterval; ++ break; ++ } + /* Fall through - SS and HS isoc/int have same decoding */ ++ + case USB_SPEED_SUPER: + if (usb_endpoint_xfer_int(&ep->desc) || +- usb_endpoint_xfer_isoc(&ep->desc)) { +- if (ep->desc.bInterval == 0) +- interval = 0; +- else +- interval = ep->desc.bInterval - 1; +- if (interval > 15) +- interval = 15; +- if (interval != ep->desc.bInterval + 1) +- dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n", +- ep->desc.bEndpointAddress, 1 << interval); ++ usb_endpoint_xfer_isoc(&ep->desc)) { ++ interval = xhci_parse_exponent_interval(udev, ep); + } + break; +- /* Convert bInterval (in 1-255 frames) to microframes and round down to +- * nearest power of 2. +- */ ++ + case USB_SPEED_FULL: ++ if (usb_endpoint_xfer_int(&ep->desc)) { ++ interval = xhci_parse_exponent_interval(udev, ep); ++ break; ++ } ++ /* ++ * Fall through for isochronous endpoint interval decoding ++ * since it uses the same rules as low speed interrupt ++ * endpoints. ++ */ ++ + case USB_SPEED_LOW: + if (usb_endpoint_xfer_int(&ep->desc) || +- usb_endpoint_xfer_isoc(&ep->desc)) { +- interval = fls(8*ep->desc.bInterval) - 1; +- if (interval > 10) +- interval = 10; +- if (interval < 3) +- interval = 3; +- if ((1 << interval) != 8*ep->desc.bInterval) +- dev_warn(&udev->dev, +- "ep %#x - rounding interval" +- " to %d microframes, " +- "ep desc says %d microframes\n", +- ep->desc.bEndpointAddress, +- 1 << interval, +- 8*ep->desc.bInterval); ++ usb_endpoint_xfer_isoc(&ep->desc)) { ++ ++ interval = xhci_parse_frame_interval(udev, ep); + } + break; ++ + default: + BUG(); + } diff --git a/queue-2.6.38/usb-xhci-fix-unsafe-macro-definitions.patch b/queue-2.6.38/usb-xhci-fix-unsafe-macro-definitions.patch new file mode 100644 index 00000000000..b2e3659d2bd --- /dev/null +++ b/queue-2.6.38/usb-xhci-fix-unsafe-macro-definitions.patch @@ -0,0 +1,47 @@ +From 5a6c2f3ff039154872ce597952f8b8900ea0d732 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Sun, 20 Mar 2011 02:15:17 -0700 +Subject: USB: xhci - fix unsafe macro definitions + +From: Dmitry Torokhov + +commit 5a6c2f3ff039154872ce597952f8b8900ea0d732 upstream. + +Macro arguments used in expressions need to be enclosed in parenthesis +to avoid unpleasant surprises. + +This should be queued for kernels back to 2.6.31 + +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -232,7 +232,7 @@ struct xhci_op_regs { + * notification type that matches a bit set in this bit field. + */ + #define DEV_NOTE_MASK (0xffff) +-#define ENABLE_DEV_NOTE(x) (1 << x) ++#define ENABLE_DEV_NOTE(x) (1 << (x)) + /* Most of the device notification types should only be used for debug. + * SW does need to pay attention to function wake notifications. + */ +@@ -601,11 +601,11 @@ struct xhci_ep_ctx { + #define EP_STATE_STOPPED 3 + #define EP_STATE_ERROR 4 + /* Mult - Max number of burtst within an interval, in EP companion desc. */ +-#define EP_MULT(p) ((p & 0x3) << 8) ++#define EP_MULT(p) (((p) & 0x3) << 8) + /* bits 10:14 are Max Primary Streams */ + /* bit 15 is Linear Stream Array */ + /* Interval - period between requests to an endpoint - 125u increments. */ +-#define EP_INTERVAL(p) ((p & 0xff) << 16) ++#define EP_INTERVAL(p) (((p) & 0xff) << 16) + #define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff)) + #define EP_MAXPSTREAMS_MASK (0x1f << 10) + #define EP_MAXPSTREAMS(p) (((p) << 10) & EP_MAXPSTREAMS_MASK)