]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/2.6.38.4/usb-xhci-also-free-streams-when-resetting-devices.patch
Linux 4.14.124
[thirdparty/kernel/stable-queue.git] / releases / 2.6.38.4 / usb-xhci-also-free-streams-when-resetting-devices.patch
1 From 2dea75d96ade3c7cd2bfe73f99c7b3291dc3d03a Mon Sep 17 00:00:00 2001
2 From: Dmitry Torokhov <dtor@vmware.com>
3 Date: Tue, 12 Apr 2011 23:06:28 -0700
4 Subject: USB: xhci - also free streams when resetting devices
5
6 From: Dmitry Torokhov <dtor@vmware.com>
7
8 commit 2dea75d96ade3c7cd2bfe73f99c7b3291dc3d03a upstream.
9
10 Currently, when resetting a device, xHCI driver disables all but one
11 endpoints and frees their rings, but leaves alone any streams that
12 might have been allocated. Later, when users try to free allocated
13 streams, we oops in xhci_setup_no_streams_ep_input_ctx() because
14 ep->ring is NULL.
15
16 Let's free not only rings but also stream data as well, so that
17 calling free_streams() on a device that was reset will be safe.
18
19 This should be queued for stable trees back to 2.6.35.
20
21 Reviewed-by: Micah Elizabeth Scott <micah@vmware.com>
22 Signed-off-by: Dmitry Torokhov <dtor@vmware.com>
23 Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
24 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
25
26 ---
27 drivers/usb/host/xhci.c | 16 ++++++++++++----
28 1 file changed, 12 insertions(+), 4 deletions(-)
29
30 --- a/drivers/usb/host/xhci.c
31 +++ b/drivers/usb/host/xhci.c
32 @@ -2335,10 +2335,18 @@ int xhci_discover_or_reset_device(struct
33 /* Everything but endpoint 0 is disabled, so free or cache the rings. */
34 last_freed_endpoint = 1;
35 for (i = 1; i < 31; ++i) {
36 - if (!virt_dev->eps[i].ring)
37 - continue;
38 - xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
39 - last_freed_endpoint = i;
40 + struct xhci_virt_ep *ep = &virt_dev->eps[i];
41 +
42 + if (ep->ep_state & EP_HAS_STREAMS) {
43 + xhci_free_stream_info(xhci, ep->stream_info);
44 + ep->stream_info = NULL;
45 + ep->ep_state &= ~EP_HAS_STREAMS;
46 + }
47 +
48 + if (ep->ring) {
49 + xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
50 + last_freed_endpoint = i;
51 + }
52 }
53 xhci_dbg(xhci, "Output context after successful reset device cmd:\n");
54 xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint);