提交 62889610 编写于 作者: S Sarah Sharp 提交者: Greg Kroah-Hartman

USB: xhci: Handle short control packets correctly.

When there is a short packet on a control transfer, the xHCI host controller
hardware will generate two events.  The first event will be for the data stage
TD with a completion code for a short packet.  The second event will be for the
status stage with a successful completion code.  Before this patch, the xHCI
driver would giveback the short control URB when it received the event for the
data stage TD.  Then it would become confused when it saw a status stage event
for the endpoint for an URB it had already finished processing.

Change the xHCI host controller driver to wait for the status stage event when
it receives a short transfer completion code for a data stage TD.
Signed-off-by: NSarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 8e595a5d
......@@ -892,15 +892,23 @@ static int handle_tx_event(struct xhci_hcd *xhci,
if (event_trb != ep_ring->dequeue) {
/* The event was for the status stage */
if (event_trb == td->last_trb) {
td->urb->actual_length =
td->urb->transfer_buffer_length;
/* Did we already see a short data stage? */
if (td->urb->actual_length != 0)
status = -EREMOTEIO;
else
td->urb->actual_length =
td->urb->transfer_buffer_length;
} else {
/* Maybe the event was for the data stage? */
if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL)
if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL) {
/* We didn't stop on a link TRB in the middle */
td->urb->actual_length =
td->urb->transfer_buffer_length -
TRB_LEN(event->transfer_len);
xhci_dbg(xhci, "Waiting for status stage event\n");
urb = NULL;
goto cleanup;
}
}
}
} else {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册