[PATCH] USB: EHCI: adjust ehci_iso_stream for changes in ehci_qh

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
Reported-by: Colin Fletcher <colin.m.fletcher@xxxxxxxxxxxxxx>
Cc: <stable@xxxxxxxxxx>
---
 drivers/usb/host/ehci-sched.c |    3 ++-
 drivers/usb/host/ehci.h       |   11 ++++++++---
 2 files changed, 10 insertions(+), 4 deletions(-)

--- linux/drivers/usb/host/ehci.h
+++ linux/drivers/usb/host/ehci.h
@@ -394,9 +394,8 @@ struct ehci_iso_sched {
  * acts like a qh would, if EHCI had them for ISO.
  */
 struct ehci_iso_stream {
-	/* first two fields match QH, but info1 == 0 */
-	__hc32			hw_next;
-	__hc32			hw_info1;
+	/* first field matches ehci_qh; points to fake_qh_hw */
+	struct ehci_qh_hw	*fake_hw;
 
 	u32			refcount;
 	u8			bEndpointAddress;
@@ -431,6 +430,12 @@ struct ehci_iso_stream {
 
 	/* this is used to initialize sITD's tt info */
 	__hc32			address;
+
+	struct {
+		/* first two fields match ehci_qh_hw, but info1 == 0 */
+		__hc32		hw_next;
+		__hc32		hw_info1;
+	} fake_qh_hw;
 };
 
 /*-------------------------------------------------------------------------*/
--- linux/drivers/usb/host/ehci-sched.c
+++ linux/drivers/usb/host/ehci-sched.c
@@ -932,6 +932,7 @@ iso_stream_alloc (gfp_t mem_flags)
 		INIT_LIST_HEAD(&stream->free_list);
 		stream->next_uframe = -1;
 		stream->refcount = 1;
+		stream->fake_hw = (struct ehci_qh_hw *)&stream->fake_qh_hw;
 	}
 	return stream;
 }
@@ -1122,7 +1123,7 @@ iso_stream_find (struct ehci_hcd *ehci, 
 		}
 
 	/* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */
-	} else if (unlikely (stream->hw_info1 != 0)) {
+	} else if (unlikely (stream->fake_hw->hw_info1 != 0)) {
 		ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n",
 			urb->dev->devpath, epnum,
 			usb_pipein(urb->pipe) ? "in" : "out");
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux