Commit 8e71a322 authored by Mathias Nyman's avatar Mathias Nyman Committed by Greg Kroah-Hartman

USB: xhci: Reset a halted endpoint immediately when we encounter a stall.

If a device is halted and reuturns a STALL, then the halted endpoint
needs to be cleared both on the host and device side. The host
side halt is cleared by issueing a xhci reset endpoint command. The device side
is cleared with a ClearFeature(ENDPOINT_HALT) request, which should
be issued by the device driver if a URB reruen -EPIPE.

Previously we cleared the host side halt after the device side was cleared.
To make sure the host side halt is cleared in time we want to issue the
reset endpoint command immedialtely when a STALL status is encountered.

Otherwise we end up not following the specs and not returning -EPIPE
several times in a row when trying to transfer data to a halted endpoint.

Fixes: bcef3fd5 (USB: xhci: Handle errors that cause endpoint halts.)
Cc: <stable@vger.kernel.org> # v2.6.33+
Tested-by: default avatarFelipe Balbi <balbi@ti.com>
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9b41ebd3
...@@ -1822,22 +1822,13 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td, ...@@ -1822,22 +1822,13 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,
ep->stopped_td = td; ep->stopped_td = td;
return 0; return 0;
} else { } else {
if (trb_comp_code == COMP_STALL) { if (trb_comp_code == COMP_STALL ||
/* The transfer is completed from the driver's xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
* perspective, but we need to issue a set dequeue trb_comp_code)) {
* command for this stalled endpoint to move the dequeue /* Issue a reset endpoint command to clear the host side
* pointer past the TD. We can't do that here because * halt, followed by a set dequeue command to move the
* the halt condition must be cleared first. Let the * dequeue pointer past the TD.
* USB class driver clear the stall later. * The class driver clears the device side halt later.
*/
ep->stopped_td = td;
ep->stopped_stream = ep_ring->stream_id;
} else if (xhci_requires_manual_halt_cleanup(xhci,
ep_ctx, trb_comp_code)) {
/* Other types of errors halt the endpoint, but the
* class driver doesn't call usb_reset_endpoint() unless
* the error is -EPIPE. Clear the halted status in the
* xHCI hardware manually.
*/ */
xhci_cleanup_halted_endpoint(xhci, xhci_cleanup_halted_endpoint(xhci,
slot_id, ep_index, ep_ring->stream_id, slot_id, ep_index, ep_ring->stream_id,
...@@ -1957,9 +1948,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, ...@@ -1957,9 +1948,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
else else
td->urb->actual_length = 0; td->urb->actual_length = 0;
xhci_cleanup_halted_endpoint(xhci, return finish_td(xhci, td, event_trb, event, ep, status, false);
slot_id, ep_index, 0, td, event_trb);
return finish_td(xhci, td, event_trb, event, ep, status, true);
} }
/* /*
* Did we transfer any data, despite the errors that might have * Did we transfer any data, despite the errors that might have
...@@ -2518,17 +2507,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, ...@@ -2518,17 +2507,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
if (ret) { if (ret) {
urb = td->urb; urb = td->urb;
urb_priv = urb->hcpriv; urb_priv = urb->hcpriv;
/* Leave the TD around for the reset endpoint function
* to use(but only if it's not a control endpoint,
* since we already queued the Set TR dequeue pointer
* command for stalled control endpoints).
*/
if (usb_endpoint_xfer_control(&urb->ep->desc) ||
(trb_comp_code != COMP_STALL &&
trb_comp_code != COMP_BABBLE))
xhci_urb_free_priv(xhci, urb_priv); xhci_urb_free_priv(xhci, urb_priv);
else
kfree(urb_priv);
usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
if ((urb->actual_length != urb->transfer_buffer_length && if ((urb->actual_length != urb->transfer_buffer_length &&
......
...@@ -2912,68 +2912,33 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, ...@@ -2912,68 +2912,33 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
} }
} }
/* Deal with stalled endpoints. The core should have sent the control message /* Called when clearing halted device. The core should have sent the control
* to clear the halt condition. However, we need to make the xHCI hardware * message to clear the device halt condition. The host side of the halt should
* reset its sequence number, since a device will expect a sequence number of * already be cleared with a reset endpoint command issued when the STALL tx
* zero after the halt condition is cleared. * event was received.
*
* Context: in_interrupt * Context: in_interrupt
*/ */
void xhci_endpoint_reset(struct usb_hcd *hcd, void xhci_endpoint_reset(struct usb_hcd *hcd,
struct usb_host_endpoint *ep) struct usb_host_endpoint *ep)
{ {
struct xhci_hcd *xhci; struct xhci_hcd *xhci;
struct usb_device *udev;
unsigned int ep_index;
unsigned long flags;
int ret;
struct xhci_virt_ep *virt_ep;
struct xhci_command *command;
xhci = hcd_to_xhci(hcd); xhci = hcd_to_xhci(hcd);
udev = (struct usb_device *) ep->hcpriv;
/* Called with a root hub endpoint (or an endpoint that wasn't added
* with xhci_add_endpoint()
*/
if (!ep->hcpriv)
return;
ep_index = xhci_get_endpoint_index(&ep->desc);
virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index];
if (!virt_ep->stopped_td) {
xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
"Endpoint 0x%x not halted, refusing to reset.",
ep->desc.bEndpointAddress);
return;
}
if (usb_endpoint_xfer_control(&ep->desc)) {
xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
"Control endpoint stall already handled.");
return;
}
command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC);
if (!command)
return;
xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
"Queueing reset endpoint command");
spin_lock_irqsave(&xhci->lock, flags);
ret = xhci_queue_reset_ep(xhci, command, udev->slot_id, ep_index);
/* /*
* Can't change the ring dequeue pointer until it's transitioned to the * We might need to implement the config ep cmd in xhci 4.8.1 note:
* stopped state, which is only upon a successful reset endpoint * The Reset Endpoint Command may only be issued to endpoints in the
* command. Better hope that last command worked! * Halted state. If software wishes reset the Data Toggle or Sequence
* Number of an endpoint that isn't in the Halted state, then software
* may issue a Configure Endpoint Command with the Drop and Add bits set
* for the target endpoint. that is in the Stopped state.
*/ */
if (!ret) {
xhci_cleanup_stalled_ring(xhci, udev, ep_index);
kfree(virt_ep->stopped_td);
xhci_ring_cmd_db(xhci);
}
virt_ep->stopped_td = NULL;
virt_ep->stopped_stream = 0;
spin_unlock_irqrestore(&xhci->lock, flags);
if (ret) /* For now just print debug to follow the situation */
xhci_warn(xhci, "FIXME allocate a new ring segment\n"); xhci_dbg(xhci, "Endpoint 0x%x ep reset callback called\n",
ep->desc.bEndpointAddress);
} }
static int xhci_check_streams_endpoint(struct xhci_hcd *xhci, static int xhci_check_streams_endpoint(struct xhci_hcd *xhci,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment