Only receive TD can have a transfer length less than the transfer size,
so rename COMP_SHORT_TX to COMP_SHORT_RX, XHCI_TRUST_TX_LENGTH to
XHCI_TRUST_RX_LENGTH.
handle_tx_event() is called for both receive and transmit completions
so rename to handle_data_event().
In process_bulk_intr_td():
- Only trace unexpected short completions if XHCI_TRUST_RX_LENGTH isn't set,
ratelimit the trace (as is done elsewhere).
- Only debug trace short receives if URB_SHORT_NOT_OK isn't set.
---
I hope this isn't mangled!
---
drivers/usb/host/xhci-pci.c | 4 +--
drivers/usb/host/xhci-ring.c | 62 +++++++++++++++++++++-----------------------
drivers/usb/host/xhci.h | 4 +--
3 files changed, 34 insertions(+), 36 deletions(-)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index b8dffd5..97b3edc 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -89,7 +89,7 @@ static void xhci_pci_quirks(struct device *dev, struct
xhci_hcd *xhci)
"QUIRK: Fresco Logic revision %u "
"has broken MSI implementation",
pdev->revision);
- xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+ xhci->quirks |= XHCI_TRUST_RX_LENGTH;
}
if (pdev->vendor == PCI_VENDOR_ID_NEC)
@@ -135,7 +135,7 @@ static void xhci_pci_quirks(struct device *dev, struct
xhci_hcd *xhci)
xhci->quirks |= XHCI_RESET_ON_RESUME;
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"QUIRK: Resetting on resume");
- xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+ xhci->quirks |= XHCI_TRUST_RX_LENGTH;
}
if (pdev->vendor == PCI_VENDOR_ID_VIA)
xhci->quirks |= XHCI_RESET_ON_RESUME;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 6bfbd80..e38abc2 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2071,7 +2071,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct
xhci_td *td,
*status = 0;
}
break;
- case COMP_SHORT_TX:
+ case COMP_SHORT_RX:
if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
*status = -EREMOTEIO;
else
@@ -2166,9 +2166,9 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct
xhci_td *td,
frame->status = 0;
break;
}
- if ((xhci->quirks & XHCI_TRUST_TX_LENGTH))
- trb_comp_code = COMP_SHORT_TX;
- case COMP_SHORT_TX:
+ if ((xhci->quirks & XHCI_TRUST_RX_LENGTH))
+ trb_comp_code = COMP_SHORT_RX;
+ case COMP_SHORT_RX:
frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ?
-EREMOTEIO : 0;
break;
@@ -2264,36 +2264,34 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci,
struct xhci_td *td,
switch (trb_comp_code) {
case COMP_SUCCESS:
/* Double check that the HW transferred everything. */
- if (event_trb != td->last_trb ||
- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
- xhci_warn(xhci, "WARN Successful completion "
- "on short TX\n");
- if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
- *status = -EREMOTEIO;
- else
- *status = 0;
- if ((xhci->quirks & XHCI_TRUST_TX_LENGTH))
- trb_comp_code = COMP_SHORT_TX;
- } else {
+ if (event_trb == td->last_trb &&
+ EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) {
*status = 0;
+ break;
}
- break;
- case COMP_SHORT_TX:
- if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
- *status = -EREMOTEIO;
+ if (xhci->quirks & XHCI_TRUST_RX_LENGTH)
+ trb_comp_code = COMP_SHORT_RX;
else
+ xhci_warn_ratelimited(xhci,
+ "WARN Successful completion on short
RX: needs XHCI_TRUST_RX_LENGTH quirk?\n");
+ /* FALLTHROUGH */
+ case COMP_SHORT_RX:
+ if (td->urb->transfer_flags & URB_SHORT_NOT_OK) {
+ xhci_dbg(xhci, "ep %#x - asked for %d bytes, "
+ "%d bytes untransferred\n",
+ td->urb->ep->desc.bEndpointAddress,
+ td->urb->transfer_buffer_length,
+
EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)));
+ *status = -EREMOTEIO;
+ } else {
*status = 0;
+ }
break;
default:
/* Others already handled above */
break;
}
- if (trb_comp_code == COMP_SHORT_TX)
- xhci_dbg(xhci, "ep %#x - asked for %d bytes, "
- "%d bytes untransferred\n",
- td->urb->ep->desc.bEndpointAddress,
- td->urb->transfer_buffer_length,
-
EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)));
+
/* Fast path - was this the last TRB in the TD for this URB? */
if (event_trb == td->last_trb) {
if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
@@ -2357,7 +2355,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci,
struct xhci_td *td,
* event with a corrupted Slot ID, Endpoint ID, or TRB DMA address.
* At this point, the host controller is probably hosed and should be reset.
*/
-static int handle_tx_event(struct xhci_hcd *xhci,
+static int handle_data_event(struct xhci_hcd *xhci,
struct xhci_transfer_event *event)
__releases(&xhci->lock)
__acquires(&xhci->lock)
@@ -2436,12 +2434,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
case COMP_SUCCESS:
if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
break;
- if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
- trb_comp_code = COMP_SHORT_TX;
+ if (xhci->quirks & XHCI_TRUST_RX_LENGTH)
+ trb_comp_code = COMP_SHORT_RX;
else
xhci_warn_ratelimited(xhci,
- "WARN Successful completion on short
TX: needs XHCI_TRUST_TX_LENGTH quirk?\n");
- case COMP_SHORT_TX:
+ "WARN Successful completion on short
RX: needs XHCI_TRUST_RX_LENGTH quirk?\n");
+ case COMP_SHORT_RX:
break;
case COMP_STOP:
xhci_dbg(xhci, "Stopped on Transfer TRB\n");
@@ -2604,7 +2602,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
ret = skip_isoc_td(xhci, td, event, ep, &status);
goto cleanup;
}
- if (trb_comp_code == COMP_SHORT_TX)
+ if (trb_comp_code == COMP_SHORT_RX)
ep_ring->last_td_was_short = true;
else
ep_ring->last_td_was_short = false;
@@ -2737,7 +2735,7 @@ static int xhci_handle_event(struct xhci_hcd *xhci)
update_ptrs = 0;
break;
case TRB_TYPE(TRB_TRANSFER):
- ret = handle_tx_event(xhci, &event->trans_event);
+ ret = handle_data_event(xhci, &event->trans_event);
if (ret < 0)
xhci->error_bitmask |= 1 << 9;
else
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 941d5f5..72ad988 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1032,7 +1032,7 @@ struct xhci_transfer_event {
/* Endpoint Not Enabled Error */
#define COMP_EBADEP 12
/* Short Packet */
-#define COMP_SHORT_TX 13
+#define COMP_SHORT_RX 13
/* Ring Underrun - doorbell rung for an empty isoc OUT ep ring */
#define COMP_UNDERRUN 14
/* Ring Overrun - isoc IN ep ring is empty when ep is scheduled to RX */
@@ -1541,7 +1541,7 @@ struct xhci_hcd {
#define XHCI_RESET_ON_RESUME (1 << 7)
#define XHCI_SW_BW_CHECKING (1 << 8)
#define XHCI_AMD_0x96_HOST (1 << 9)
-#define XHCI_TRUST_TX_LENGTH (1 << 10)
+#define XHCI_TRUST_RX_LENGTH (1 << 10)
#define XHCI_LPM_SUPPORT (1 << 11)
#define XHCI_INTEL_HOST (1 << 12)
#define XHCI_SPURIOUS_REBOOT (1 << 13)
--
1.8.1.2
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html