summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ad81e9a508b1..ddc30037f9ce 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -896,7 +896,7 @@ done:
}
static int xhci_handle_halted_endpoint(struct xhci_hcd *xhci,
- struct xhci_virt_ep *ep, unsigned int stream_id,
+ struct xhci_virt_ep *ep,
struct xhci_td *td,
enum xhci_ep_reset_type reset_type)
{
@@ -1110,8 +1110,7 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
td->status = -EPROTO;
}
/* reset ep, reset handler cleans up cancelled tds */
- err = xhci_handle_halted_endpoint(xhci, ep, 0, td,
- reset_type);
+ err = xhci_handle_halted_endpoint(xhci, ep, td, reset_type);
if (err)
break;
ep->ep_state &= ~EP_STOP_CMD_PENDING;
@@ -2183,8 +2182,7 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
}
/* Almost same procedure as for STALL_ERROR below */
xhci_clear_hub_tt_buffer(xhci, td, ep);
- xhci_handle_halted_endpoint(xhci, ep, ep_ring->stream_id, td,
- EP_HARD_RESET);
+ xhci_handle_halted_endpoint(xhci, ep, td, EP_HARD_RESET);
return 0;
case COMP_STALL_ERROR:
/*
@@ -2200,8 +2198,7 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
if (ep->ep_index != 0)
xhci_clear_hub_tt_buffer(xhci, td, ep);
- xhci_handle_halted_endpoint(xhci, ep, ep_ring->stream_id, td,
- EP_HARD_RESET);
+ xhci_handle_halted_endpoint(xhci, ep, td, EP_HARD_RESET);
return 0; /* xhci_handle_halted_endpoint marked td cancelled */
default:
@@ -2458,7 +2455,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
switch (trb_comp_code) {
case COMP_SUCCESS:
- ep_ring->err_count = 0;
+ ep->err_count = 0;
/* handle success with untransferred data as short packet */
if (ep_trb != td->last_trb || remaining) {
xhci_warn(xhci, "WARN Successful completion on short TX\n");
@@ -2484,14 +2481,13 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
break;
case COMP_USB_TRANSACTION_ERROR:
if (xhci->quirks & XHCI_NO_SOFT_RETRY ||
- (ep_ring->err_count++ > MAX_SOFT_RETRY) ||
+ (ep->err_count++ > MAX_SOFT_RETRY) ||
le32_to_cpu(slot_ctx->tt_info) & TT_SLOT)
break;
td->status = 0;
- xhci_handle_halted_endpoint(xhci, ep, ep_ring->stream_id, td,
- EP_SOFT_RESET);
+ xhci_handle_halted_endpoint(xhci, ep, td, EP_SOFT_RESET);
return 0;
default:
/* do nothing */
@@ -2565,8 +2561,14 @@ static int handle_tx_event(struct xhci_hcd *xhci,
case COMP_USB_TRANSACTION_ERROR:
case COMP_INVALID_STREAM_TYPE_ERROR:
case COMP_INVALID_STREAM_ID_ERROR:
- xhci_handle_halted_endpoint(xhci, ep, 0, NULL,
- EP_SOFT_RESET);
+ xhci_dbg(xhci, "Stream transaction error ep %u no id\n",
+ ep_index);
+ if (ep->err_count++ > MAX_SOFT_RETRY)
+ xhci_handle_halted_endpoint(xhci, ep, NULL,
+ EP_HARD_RESET);
+ else
+ xhci_handle_halted_endpoint(xhci, ep, NULL,
+ EP_SOFT_RESET);
goto cleanup;
case COMP_RING_UNDERRUN:
case COMP_RING_OVERRUN:
@@ -2749,9 +2751,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
if (trb_comp_code == COMP_STALL_ERROR ||
xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
trb_comp_code)) {
- xhci_handle_halted_endpoint(xhci, ep,
- ep_ring->stream_id,
- NULL,
+ xhci_handle_halted_endpoint(xhci, ep, NULL,
EP_HARD_RESET);
}
goto cleanup;
@@ -2844,9 +2844,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
if (trb_comp_code == COMP_STALL_ERROR ||
xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
trb_comp_code))
- xhci_handle_halted_endpoint(xhci, ep,
- ep_ring->stream_id,
- td, EP_HARD_RESET);
+ xhci_handle_halted_endpoint(xhci, ep, td,
+ EP_HARD_RESET);
goto cleanup;
}
@@ -3031,6 +3030,11 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
if (!(status & STS_EINT))
goto out;
+ if (status & STS_HCE) {
+ xhci_warn(xhci, "WARNING: Host Controller Error\n");
+ goto out;
+ }
+
if (status & STS_FATAL) {
xhci_warn(xhci, "WARNING: Host System Error\n");
xhci_halt(xhci);