aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2010-03-01 11:18:56 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-19 10:24:06 -0400
commit1082f57abfa26590b60c43f503afb24102a37016 (patch)
tree05f1d88c99c0e9a2cd65c830f16ac92a3bc18ecb
parent92bc3648e6027384479852b770a542722fadee7c (diff)
USB: EHCI: adjust ehci_iso_stream for changes in ehci_qh
The EHCI driver stores in usb_host_endpoint.hcpriv a pointer to either an ehci_qh or an ehci_iso_stream structure, and uses the contents of the hw_info1 field to distinguish the two cases. After ehci_qh was split into hw and sw parts, ehci_iso_stream must also be adjusted so that it again looks like an ehci_qh structure. This fixes a NULL pointer access in ehci_endpoint_disable() when it tries to access qh->hw->hw_info1. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Reported-by: Colin Fletcher <colin.m.fletcher@googlemail.com> Cc: stable <stable@kernel.org> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/host/ehci-hcd.c2
-rw-r--r--drivers/usb/host/ehci-sched.c4
-rw-r--r--drivers/usb/host/ehci.h5
3 files changed, 5 insertions, 6 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d8d6d3461d32..dc55a62859c6 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -995,7 +995,7 @@ rescan:
995 /* endpoints can be iso streams. for now, we don't 995 /* endpoints can be iso streams. for now, we don't
996 * accelerate iso completions ... so spin a while. 996 * accelerate iso completions ... so spin a while.
997 */ 997 */
998 if (qh->hw->hw_info1 == 0) { 998 if (qh->hw == NULL) {
999 ehci_vdbg (ehci, "iso delay\n"); 999 ehci_vdbg (ehci, "iso delay\n");
1000 goto idle_timeout; 1000 goto idle_timeout;
1001 } 1001 }
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index cd1e8bf5327e..a0aaaaff2560 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1123,8 +1123,8 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
1123 urb->interval); 1123 urb->interval);
1124 } 1124 }
1125 1125
1126 /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */ 1126 /* if dev->ep [epnum] is a QH, hw is set */
1127 } else if (unlikely (stream->hw_info1 != 0)) { 1127 } else if (unlikely (stream->hw != NULL)) {
1128 ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", 1128 ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n",
1129 urb->dev->devpath, epnum, 1129 urb->dev->devpath, epnum,
1130 usb_pipein(urb->pipe) ? "in" : "out"); 1130 usb_pipein(urb->pipe) ? "in" : "out");
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 2d85e21ff282..b1dce96dd621 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -394,9 +394,8 @@ struct ehci_iso_sched {
394 * acts like a qh would, if EHCI had them for ISO. 394 * acts like a qh would, if EHCI had them for ISO.
395 */ 395 */
396struct ehci_iso_stream { 396struct ehci_iso_stream {
397 /* first two fields match QH, but info1 == 0 */ 397 /* first field matches ehci_hq, but is NULL */
398 __hc32 hw_next; 398 struct ehci_qh_hw *hw;
399 __hc32 hw_info1;
400 399
401 u32 refcount; 400 u32 refcount;
402 u8 bEndpointAddress; 401 u8 bEndpointAddress;