xhci: don't use the same variable for stopped and halted rings current TD
authorMathias Nyman <mathias.nyman@linux.intel.com>
Thu, 27 Nov 2014 16:19:16 +0000 (18:19 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Dec 2014 00:14:29 +0000 (16:14 -0800)
Endpoints halted on errors, and endpoints stopped manually both used
the same ep->stopped_td to store the halted or stopped td. this causes
confusion and possible races.

There is no longer a need to use the ep->stopped_td variable to store
the halted TD. A halted endpoint is handled immediately and we can pass
it to the handling function directly.

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h

index 5f609325ec7bbed8d560d7016c1d5a731d02612d..e692e769c50c563d540cd4966514512a800d9589 100644 (file)
@@ -716,9 +716,7 @@ remove_finished_td:
                ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
        }
 
-       /* Clear stopped_td if endpoint is not halted */
-       if (!(ep->ep_state & EP_HALTED))
-               ep->stopped_td = NULL;
+       ep->stopped_td = NULL;
 
        /*
         * Drop the lock and complete the URBs in the cancelled TD list.
@@ -1732,13 +1730,11 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
                return;
 
        ep->ep_state |= EP_HALTED;
-       ep->stopped_td = td;
        ep->stopped_stream = stream_id;
 
        xhci_queue_reset_ep(xhci, command, slot_id, ep_index);
-       xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index);
+       xhci_cleanup_stalled_ring(xhci, ep_index, td);
 
-       ep->stopped_td = NULL;
        ep->stopped_stream = 0;
 
        xhci_ring_cmd_db(xhci);
index 0ea7e12d4765d2a87d242355ff21379ee473cc57..5be1bff9b4eba0dfe8937dbae8070eb0b2a57260 100644 (file)
@@ -2912,10 +2912,11 @@ static void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
 }
 
 void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
-               struct usb_device *udev, unsigned int ep_index)
+                       unsigned int ep_index, struct xhci_td *td)
 {
        struct xhci_dequeue_state deq_state;
        struct xhci_virt_ep *ep;
+       struct usb_device *udev = td->urb->dev;
 
        xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
                        "Cleaning up stalled endpoint ring");
@@ -2924,8 +2925,7 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
         * or it will attempt to resend it on the next doorbell ring.
         */
        xhci_find_new_dequeue_state(xhci, udev->slot_id,
-                       ep_index, ep->stopped_stream, ep->stopped_td,
-                       &deq_state);
+                       ep_index, ep->stopped_stream, td, &deq_state);
 
        if (!deq_state.new_deq_ptr || !deq_state.new_deq_seg)
                return;
index d745715a1e2f53648b1e1c2b1288f9c963bb42be..053c9ead4f65b3686faf85e3ad1e9c664abf3c1e 100644 (file)
@@ -1825,7 +1825,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
                unsigned int stream_id,
                struct xhci_dequeue_state *deq_state);
 void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
-               struct usb_device *udev, unsigned int ep_index);
+               unsigned int ep_index, struct xhci_td *td);
 void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci,
                unsigned int slot_id, unsigned int ep_index,
                struct xhci_dequeue_state *deq_state);