From: Greg Kroah-Hartman Date: Thu, 1 Oct 2009 22:17:55 +0000 (-0700) Subject: .31 xhci fun X-Git-Tag: v2.6.27.36~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9bb78e33cbde226b9bb2aa40ae245d474ae749e3;p=thirdparty%2Fkernel%2Fstable-queue.git .31 xhci fun --- diff --git a/queue-2.6.31/series b/queue-2.6.31/series index 5c42b8de5bf..8bb6ee149c5 100644 --- a/queue-2.6.31/series +++ b/queue-2.6.31/series @@ -99,3 +99,18 @@ usb-serial-rename-subroutines.patch usb-serial-add-missing-tests-and-debug-lines.patch usb-serial-straighten-out-serial_open.patch usb-serial-update-the-console-driver.patch +usb-xhci-work-around-for-chain-bit-in-link-trbs.patch +usb-xhci-fix-slot-and-endpoint-context-debugging.patch +usb-xhci-configure-endpoint-code-refactoring.patch +usb-xhci-set-correct-max-packet-size-for-hs-fs-control-endpoints.patch +usb-xhci-support-full-speed-devices.patch +usb-xhci-handle-stalled-control-endpoints.patch +usb-xhci-add-quirk-for-fresco-logic-xhci-hardware.patch +usb-xhci-make-trb-completion-code-comparison-readable.patch +usb-xhci-handle-babbling-endpoints-correctly.patch +usb-xhci-don-t-touch-xhci_td-after-it-s-freed.patch +usb-xhci-check-urb-s-actual-transfer-buffer-size.patch +usb-xhci-check-urb_short_not_ok-before-setting-short-packet-status.patch +usb-xhci-set-eremoteio-when-xhc-gives-bad-transfer-length.patch +usb-xhci-support-interrupt-transfers.patch +usb-fix-ss-endpoint-companion-descriptor-parsing.patch diff --git a/queue-2.6.31/usb-fix-ss-endpoint-companion-descriptor-parsing.patch b/queue-2.6.31/usb-fix-ss-endpoint-companion-descriptor-parsing.patch new file mode 100644 index 00000000000..6a17d39327d --- /dev/null +++ b/queue-2.6.31/usb-fix-ss-endpoint-companion-descriptor-parsing.patch @@ -0,0 +1,32 @@ +From 6682bb39e111b34290e25c4d275c5bcf8bbccbe1 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Tue, 8 Sep 2009 13:20:16 -0700 +Subject: USB: Fix SS endpoint companion descriptor parsing. + +From: Sarah Sharp + +commit 6682bb39e111b34290e25c4d275c5bcf8bbccbe1 upstream. + +When there's a descriptor after the SuperSpeed endpoint companion +descriptor, the previous code would have skipped over twice the length it +was supposed to. This code fixes crashes seen with UASP devices (which +have a UASP descriptor after the SS endpoint companion descriptor). + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -105,7 +105,7 @@ static int usb_parse_ss_endpoint_compani + ep->ss_ep_comp->extralen = i; + buffer += i; + size -= i; +- retval = buffer - buffer_start + i; ++ retval = buffer - buffer_start; + if (num_skipped > 0) + dev_dbg(ddev, "skipped %d descriptor%s after %s\n", + num_skipped, plural(num_skipped), diff --git a/queue-2.6.31/usb-xhci-add-quirk-for-fresco-logic-xhci-hardware.patch b/queue-2.6.31/usb-xhci-add-quirk-for-fresco-logic-xhci-hardware.patch new file mode 100644 index 00000000000..2bb9140e0af --- /dev/null +++ b/queue-2.6.31/usb-xhci-add-quirk-for-fresco-logic-xhci-hardware.patch @@ -0,0 +1,359 @@ +From ac9d8fe7c6a8041cca5a0738915d2c4e21381421 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 7 Aug 2009 14:04:55 -0700 +Subject: USB: xhci: Add quirk for Fresco Logic xHCI hardware. + +From: Sarah Sharp + +commit ac9d8fe7c6a8041cca5a0738915d2c4e21381421 upstream. + +This Fresco Logic xHCI host controller chip revision puts bad data into +the output endpoint context after a Reset Endpoint command. It needs a +Configure Endpoint command (instead of a Set TR Dequeue Pointer command) +after the reset endpoint command. + +Set up the input context before issuing the Reset Endpoint command so we +don't copy bad data from the output endpoint context. The HW also can't +handle two commands queued at once, so submit the TRB for the Configure +Endpoint command in the event handler for the Reset Endpoint command. + +Devices that stall on control endpoints before a configuration is selected +will not work under this Fresco Logic xHCI host controller revision. + +This patch is for prototype hardware that will be given to other companies +for evaluation purposes only, and should not reach consumer hands. Fresco +Logic's next chip rev should have this bug fixed. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hcd.c | 77 +++++++++++++++++++++++++++++++++++++------ + drivers/usb/host/xhci-pci.c | 13 +++++++ + drivers/usb/host/xhci-ring.c | 61 ++++++++++++++++++++++++++++++---- + drivers/usb/host/xhci.h | 20 +++++++---- + 4 files changed, 148 insertions(+), 23 deletions(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -929,6 +929,12 @@ struct xhci_td { + union xhci_trb *last_trb; + }; + ++struct xhci_dequeue_state { ++ struct xhci_segment *new_deq_seg; ++ union xhci_trb *new_deq_ptr; ++ int new_cycle_state; ++}; ++ + struct xhci_ring { + struct xhci_segment *first_seg; + union xhci_trb *enqueue; +@@ -955,12 +961,6 @@ struct xhci_ring { + u32 cycle_state; + }; + +-struct xhci_dequeue_state { +- struct xhci_segment *new_deq_seg; +- union xhci_trb *new_deq_ptr; +- int new_cycle_state; +-}; +- + struct xhci_erst_entry { + /* 64-bit event ring segment address */ + u64 seg_addr; +@@ -1063,6 +1063,7 @@ struct xhci_hcd { + int error_bitmask; + unsigned int quirks; + #define XHCI_LINK_TRB_QUIRK (1 << 0) ++#define XHCI_RESET_EP_QUIRK (1 << 1) + }; + + /* For testing purposes */ +@@ -1170,6 +1171,8 @@ int xhci_alloc_virt_device(struct xhci_h + int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev); + unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc); + unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc); ++unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index); ++unsigned int xhci_last_valid_endpoint(u32 added_ctxs); + void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep); + void xhci_endpoint_copy(struct xhci_hcd *xhci, + struct xhci_virt_device *vdev, unsigned int ep_index); +@@ -1233,8 +1236,11 @@ void xhci_queue_new_dequeue_state(struct + struct xhci_ring *ep_ring, unsigned int slot_id, + unsigned int ep_index, struct xhci_dequeue_state *deq_state); + void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, +- struct usb_device *udev, struct usb_host_endpoint *ep, ++ struct usb_device *udev, + unsigned int ep_index, struct xhci_ring *ep_ring); ++void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci, ++ unsigned int slot_id, unsigned int ep_index, ++ struct xhci_dequeue_state *deq_state); + + /* xHCI roothub code */ + int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, +--- a/drivers/usb/host/xhci-hcd.c ++++ b/drivers/usb/host/xhci-hcd.c +@@ -224,7 +224,7 @@ int xhci_init(struct usb_hcd *hcd) + xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n"); + xhci->quirks |= XHCI_LINK_TRB_QUIRK; + } else { +- xhci_dbg(xhci, "xHCI has no QUIRKS\n"); ++ xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n"); + } + retval = xhci_mem_init(xhci, GFP_KERNEL); + xhci_dbg(xhci, "Finished xhci_init\n"); +@@ -567,13 +567,22 @@ unsigned int xhci_get_endpoint_flag(stru + return 1 << (xhci_get_endpoint_index(desc) + 1); + } + ++/* Find the flag for this endpoint (for use in the control context). Use the ++ * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is ++ * bit 1, etc. ++ */ ++unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index) ++{ ++ return 1 << (ep_index + 1); ++} ++ + /* Compute the last valid endpoint context index. Basically, this is the + * endpoint index plus one. For slot contexts with more than valid endpoint, + * we find the most significant bit set in the added contexts flags. + * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000 + * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one. + */ +-static inline unsigned int xhci_last_valid_endpoint(u32 added_ctxs) ++unsigned int xhci_last_valid_endpoint(u32 added_ctxs) + { + return fls(added_ctxs) - 1; + } +@@ -1230,8 +1239,44 @@ void xhci_reset_bandwidth(struct usb_hcd + xhci_zero_in_ctx(xhci, virt_dev); + } + ++void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, ++ unsigned int slot_id, unsigned int ep_index, ++ struct xhci_dequeue_state *deq_state) ++{ ++ struct xhci_container_ctx *in_ctx; ++ struct xhci_input_control_ctx *ctrl_ctx; ++ struct xhci_ep_ctx *ep_ctx; ++ u32 added_ctxs; ++ dma_addr_t addr; ++ ++ xhci_endpoint_copy(xhci, xhci->devs[slot_id], ep_index); ++ in_ctx = xhci->devs[slot_id]->in_ctx; ++ ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); ++ addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg, ++ deq_state->new_deq_ptr); ++ if (addr == 0) { ++ xhci_warn(xhci, "WARN Cannot submit config ep after " ++ "reset ep command\n"); ++ xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n", ++ deq_state->new_deq_seg, ++ deq_state->new_deq_ptr); ++ return; ++ } ++ ep_ctx->deq = addr | deq_state->new_cycle_state; ++ ++ xhci_slot_copy(xhci, xhci->devs[slot_id]); ++ ++ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); ++ added_ctxs = xhci_get_endpoint_flag_from_index(ep_index); ++ ctrl_ctx->add_flags = added_ctxs | SLOT_FLAG; ++ ctrl_ctx->drop_flags = added_ctxs; ++ ++ xhci_dbg(xhci, "Slot ID %d Input Context:\n", slot_id); ++ xhci_dbg_ctx(xhci, in_ctx, ep_index); ++} ++ + void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, +- struct usb_device *udev, struct usb_host_endpoint *ep, ++ struct usb_device *udev, + unsigned int ep_index, struct xhci_ring *ep_ring) + { + struct xhci_dequeue_state deq_state; +@@ -1241,12 +1286,26 @@ void xhci_cleanup_stalled_ring(struct xh + * or it will attempt to resend it on the next doorbell ring. + */ + xhci_find_new_dequeue_state(xhci, udev->slot_id, +- ep_index, ep_ring->stopped_td, &deq_state); ++ ep_index, ep_ring->stopped_td, ++ &deq_state); + +- xhci_dbg(xhci, "Queueing new dequeue state\n"); +- xhci_queue_new_dequeue_state(xhci, ep_ring, +- udev->slot_id, +- ep_index, &deq_state); ++ /* HW with the reset endpoint quirk will use the saved dequeue state to ++ * issue a configure endpoint command later. ++ */ ++ if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) { ++ xhci_dbg(xhci, "Queueing new dequeue state\n"); ++ xhci_queue_new_dequeue_state(xhci, ep_ring, ++ udev->slot_id, ++ ep_index, &deq_state); ++ } else { ++ /* Better hope no one uses the input context between now and the ++ * reset endpoint completion! ++ */ ++ xhci_dbg(xhci, "Setting up input context for " ++ "configure endpoint command\n"); ++ xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id, ++ ep_index, &deq_state); ++ } + } + + /* Deal with stalled endpoints. The core should have sent the control message +@@ -1293,7 +1352,7 @@ void xhci_endpoint_reset(struct usb_hcd + * command. Better hope that last command worked! + */ + if (!ret) { +- xhci_cleanup_stalled_ring(xhci, udev, ep, ep_index, ep_ring); ++ xhci_cleanup_stalled_ring(xhci, udev, ep_index, ep_ring); + kfree(ep_ring->stopped_td); + xhci_ring_cmd_db(xhci); + } +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -24,6 +24,10 @@ + + #include "xhci.h" + ++/* Device for a quirk */ ++#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 ++#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000 ++ + static const char hcd_name[] = "xhci_hcd"; + + /* called after powerup, by probe or system-pm "wakeup" */ +@@ -62,6 +66,15 @@ static int xhci_pci_setup(struct usb_hcd + xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hcc_params); + xhci_print_registers(xhci); + ++ /* Look for vendor-specific quirks */ ++ if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && ++ pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK && ++ pdev->revision == 0x0) { ++ xhci->quirks |= XHCI_RESET_EP_QUIRK; ++ xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" ++ " endpoint cmd after reset endpoint\n"); ++ } ++ + /* Make sure the HC is halted. */ + retval = xhci_halt(xhci); + if (retval) +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -469,7 +469,6 @@ void xhci_queue_new_dequeue_state(struct + * ring running. + */ + ep_ring->state |= SET_DEQ_PENDING; +- xhci_ring_cmd_db(xhci); + } + + /* +@@ -538,6 +537,7 @@ static void handle_stopped_endpoint(stru + if (deq_state.new_deq_ptr && deq_state.new_deq_seg) { + xhci_queue_new_dequeue_state(xhci, ep_ring, + slot_id, ep_index, &deq_state); ++ xhci_ring_cmd_db(xhci); + } else { + /* Otherwise just ring the doorbell to restart the ring */ + ring_ep_doorbell(xhci, slot_id, ep_index); +@@ -651,18 +651,31 @@ static void handle_reset_ep_completion(s + { + int slot_id; + unsigned int ep_index; ++ struct xhci_ring *ep_ring; + + slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]); + ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]); ++ ep_ring = xhci->devs[slot_id]->ep_rings[ep_index]; + /* This command will only fail if the endpoint wasn't halted, + * but we don't care. + */ + xhci_dbg(xhci, "Ignoring reset ep completion code of %u\n", + (unsigned int) GET_COMP_CODE(event->status)); + +- /* Clear our internal halted state and restart the ring */ +- xhci->devs[slot_id]->ep_rings[ep_index]->state &= ~EP_HALTED; +- ring_ep_doorbell(xhci, slot_id, ep_index); ++ /* HW with the reset endpoint quirk needs to have a configure endpoint ++ * command complete before the endpoint can be used. Queue that here ++ * because the HW can't handle two commands being queued in a row. ++ */ ++ if (xhci->quirks & XHCI_RESET_EP_QUIRK) { ++ xhci_dbg(xhci, "Queueing configure endpoint command\n"); ++ xhci_queue_configure_endpoint(xhci, ++ xhci->devs[slot_id]->in_ctx->dma, slot_id); ++ xhci_ring_cmd_db(xhci); ++ } else { ++ /* Clear our internal halted state and restart the ring */ ++ ep_ring->state &= ~EP_HALTED; ++ ring_ep_doorbell(xhci, slot_id, ep_index); ++ } + } + + static void handle_cmd_completion(struct xhci_hcd *xhci, +@@ -671,6 +684,10 @@ static void handle_cmd_completion(struct + int slot_id = TRB_TO_SLOT_ID(event->flags); + u64 cmd_dma; + dma_addr_t cmd_dequeue_dma; ++ struct xhci_input_control_ctx *ctrl_ctx; ++ unsigned int ep_index; ++ struct xhci_ring *ep_ring; ++ unsigned int ep_state; + + cmd_dma = event->cmd_trb; + cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, +@@ -698,8 +715,39 @@ static void handle_cmd_completion(struct + xhci_free_virt_device(xhci, slot_id); + break; + case TRB_TYPE(TRB_CONFIG_EP): +- xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); +- complete(&xhci->devs[slot_id]->cmd_completion); ++ /* ++ * Configure endpoint commands can come from the USB core ++ * configuration or alt setting changes, or because the HW ++ * needed an extra configure endpoint command after a reset ++ * endpoint command. In the latter case, the xHCI driver is ++ * not waiting on the configure endpoint command. ++ */ ++ ctrl_ctx = xhci_get_input_control_ctx(xhci, ++ xhci->devs[slot_id]->in_ctx); ++ /* Input ctx add_flags are the endpoint index plus one */ ++ ep_index = xhci_last_valid_endpoint(ctrl_ctx->add_flags) - 1; ++ ep_ring = xhci->devs[slot_id]->ep_rings[ep_index]; ++ if (!ep_ring) { ++ /* This must have been an initial configure endpoint */ ++ xhci->devs[slot_id]->cmd_status = ++ GET_COMP_CODE(event->status); ++ complete(&xhci->devs[slot_id]->cmd_completion); ++ break; ++ } ++ ep_state = ep_ring->state; ++ xhci_dbg(xhci, "Completed config ep cmd - last ep index = %d, " ++ "state = %d\n", ep_index, ep_state); ++ if (xhci->quirks & XHCI_RESET_EP_QUIRK && ++ ep_state & EP_HALTED) { ++ /* Clear our internal halted state and restart ring */ ++ xhci->devs[slot_id]->ep_rings[ep_index]->state &= ++ ~EP_HALTED; ++ ring_ep_doorbell(xhci, slot_id, ep_index); ++ } else { ++ xhci->devs[slot_id]->cmd_status = ++ GET_COMP_CODE(event->status); ++ complete(&xhci->devs[slot_id]->cmd_completion); ++ } + break; + case TRB_TYPE(TRB_EVAL_CONTEXT): + xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); +@@ -958,7 +1006,6 @@ static int handle_tx_event(struct xhci_h + xhci_queue_reset_ep(xhci, slot_id, ep_index); + xhci_cleanup_stalled_ring(xhci, + td->urb->dev, +- td->urb->ep, + ep_index, ep_ring); + xhci_ring_cmd_db(xhci); + goto td_cleanup; diff --git a/queue-2.6.31/usb-xhci-check-urb-s-actual-transfer-buffer-size.patch b/queue-2.6.31/usb-xhci-check-urb-s-actual-transfer-buffer-size.patch new file mode 100644 index 00000000000..ce3eab85798 --- /dev/null +++ b/queue-2.6.31/usb-xhci-check-urb-s-actual-transfer-buffer-size.patch @@ -0,0 +1,57 @@ +From 99eb32db45061443ab7552b8fdceae68b90fde55 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Thu, 27 Aug 2009 14:36:24 -0700 +Subject: USB: xhci: Check URB's actual transfer buffer size. + +From: Sarah Sharp + +commit 99eb32db45061443ab7552b8fdceae68b90fde55 upstream. + +Make sure that the amount of data the xHC says was transmitted is less +than or equal to the size of the requested transfer buffer. Before, if +the host controller erroneously reported that the number of bytes +untransferred was bigger than the buffer in the URB, urb->actual_length +could be set to a very large size. + +Make sure urb->actual_length <= urb->transfer_buffer_length. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1092,7 +1092,8 @@ static int handle_tx_event(struct xhci_h + td->urb->actual_length = + td->urb->transfer_buffer_length - + TRB_LEN(event->transfer_len); +- if (td->urb->actual_length < 0) { ++ if (td->urb->transfer_buffer_length < ++ td->urb->actual_length) { + xhci_warn(xhci, "HC gave bad length " + "of %d bytes left\n", + TRB_LEN(event->transfer_len)); +@@ -1167,6 +1168,20 @@ static int handle_tx_event(struct xhci_h + td_cleanup: + /* Clean up the endpoint's TD list */ + urb = td->urb; ++ /* Do one last check of the actual transfer length. ++ * If the host controller said we transferred more data than ++ * the buffer length, urb->actual_length will be a very big ++ * number (since it's unsigned). Play it safe and say we didn't ++ * transfer anything. ++ */ ++ if (urb->actual_length > urb->transfer_buffer_length) { ++ xhci_warn(xhci, "URB transfer length is wrong, " ++ "xHC issue? req. len = %u, " ++ "act. len = %u\n", ++ urb->transfer_buffer_length, ++ urb->actual_length); ++ urb->actual_length = 0; ++ } + list_del(&td->td_list); + /* Was this TD slated to be cancelled but completed anyway? */ + if (!list_empty(&td->cancelled_td_list)) { diff --git a/queue-2.6.31/usb-xhci-check-urb_short_not_ok-before-setting-short-packet-status.patch b/queue-2.6.31/usb-xhci-check-urb_short_not_ok-before-setting-short-packet-status.patch new file mode 100644 index 00000000000..59ec41ec2d0 --- /dev/null +++ b/queue-2.6.31/usb-xhci-check-urb_short_not_ok-before-setting-short-packet-status.patch @@ -0,0 +1,45 @@ +From 204970a4bb2f584afc430ae330cd44aee329cea4 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 28 Aug 2009 14:28:15 -0700 +Subject: USB: xhci: Check URB_SHORT_NOT_OK before setting short packet status. + +From: Sarah Sharp + +commit 204970a4bb2f584afc430ae330cd44aee329cea4 upstream. + +Make sure that the driver that submitted the URB considers a short packet +an error before setting -EREMOTEIO during a short control transfer. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -991,7 +991,10 @@ static int handle_tx_event(struct xhci_h + break; + case COMP_SHORT_TX: + xhci_warn(xhci, "WARN: short transfer on control ep\n"); +- status = -EREMOTEIO; ++ if (td->urb->transfer_flags & URB_SHORT_NOT_OK) ++ status = -EREMOTEIO; ++ else ++ status = 0; + break; + case COMP_BABBLE: + /* The 0.96 spec says a babbling control endpoint +@@ -1034,7 +1037,10 @@ static int handle_tx_event(struct xhci_h + if (event_trb == td->last_trb) { + if (td->urb->actual_length != 0) { + /* Don't overwrite a previously set error code */ +- if (status == -EINPROGRESS || status == 0) ++ if ((status == -EINPROGRESS || ++ status == 0) && ++ (td->urb->transfer_flags ++ & URB_SHORT_NOT_OK)) + /* Did we already see a short data stage? */ + status = -EREMOTEIO; + } else { diff --git a/queue-2.6.31/usb-xhci-configure-endpoint-code-refactoring.patch b/queue-2.6.31/usb-xhci-configure-endpoint-code-refactoring.patch new file mode 100644 index 00000000000..3e9ba4dd559 --- /dev/null +++ b/queue-2.6.31/usb-xhci-configure-endpoint-code-refactoring.patch @@ -0,0 +1,303 @@ +From f2217e8edd95b0428d8123d426e0097a5e955f9f Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 7 Aug 2009 14:04:43 -0700 +Subject: USB: xhci: Configure endpoint code refactoring. + +From: Sarah Sharp + +commit f2217e8edd95b0428d8123d426e0097a5e955f9f upstream. + +Refactor out the code issue, wait for, and parse the event completion code +for a configure endpoint command. Modify it to support the evaluate +context command, which has a very similar submission process. Add +functions to copy parts of the output context into the input context +(which will be used in the evaluate context command). + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hcd.c | 169 +++++++++++++++++++++++++++++-------------- + drivers/usb/host/xhci-mem.c | 38 +++++++++ + drivers/usb/host/xhci-ring.c | 9 ++ + drivers/usb/host/xhci.h | 5 + + 4 files changed, 169 insertions(+), 52 deletions(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1168,6 +1168,9 @@ int xhci_setup_addressable_virt_dev(stru + unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc); + unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc); + void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep); ++void xhci_endpoint_copy(struct xhci_hcd *xhci, ++ struct xhci_virt_device *vdev, unsigned int ep_index); ++void xhci_slot_copy(struct xhci_hcd *xhci, struct xhci_virt_device *vdev); + int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, + struct usb_device *udev, struct usb_host_endpoint *ep, + gfp_t mem_flags); +@@ -1216,6 +1219,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd * + int slot_id, unsigned int ep_index); + int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, + u32 slot_id); ++int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, ++ u32 slot_id); + int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id, + unsigned int ep_index); + void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, +--- a/drivers/usb/host/xhci-hcd.c ++++ b/drivers/usb/host/xhci-hcd.c +@@ -942,6 +942,122 @@ static void xhci_zero_in_ctx(struct xhci + } + } + ++static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, ++ struct usb_device *udev, struct xhci_virt_device *virt_dev) ++{ ++ int ret; ++ ++ switch (virt_dev->cmd_status) { ++ case COMP_ENOMEM: ++ dev_warn(&udev->dev, "Not enough host controller resources " ++ "for new device state.\n"); ++ ret = -ENOMEM; ++ /* FIXME: can we allocate more resources for the HC? */ ++ break; ++ case COMP_BW_ERR: ++ dev_warn(&udev->dev, "Not enough bandwidth " ++ "for new device state.\n"); ++ ret = -ENOSPC; ++ /* FIXME: can we go back to the old state? */ ++ break; ++ case COMP_TRB_ERR: ++ /* the HCD set up something wrong */ ++ dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, " ++ "add flag = 1, " ++ "and endpoint is not disabled.\n"); ++ ret = -EINVAL; ++ break; ++ case COMP_SUCCESS: ++ dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); ++ ret = 0; ++ break; ++ default: ++ xhci_err(xhci, "ERROR: unexpected command completion " ++ "code 0x%x.\n", virt_dev->cmd_status); ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++static int xhci_evaluate_context_result(struct xhci_hcd *xhci, ++ struct usb_device *udev, struct xhci_virt_device *virt_dev) ++{ ++ int ret; ++ ++ switch (virt_dev->cmd_status) { ++ case COMP_EINVAL: ++ dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate " ++ "context command.\n"); ++ ret = -EINVAL; ++ break; ++ case COMP_EBADSLT: ++ dev_warn(&udev->dev, "WARN: slot not enabled for" ++ "evaluate context command.\n"); ++ case COMP_CTX_STATE: ++ dev_warn(&udev->dev, "WARN: invalid context state for " ++ "evaluate context command.\n"); ++ xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); ++ ret = -EINVAL; ++ break; ++ case COMP_SUCCESS: ++ dev_dbg(&udev->dev, "Successful evaluate context command\n"); ++ ret = 0; ++ break; ++ default: ++ xhci_err(xhci, "ERROR: unexpected command completion " ++ "code 0x%x.\n", virt_dev->cmd_status); ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++/* Issue a configure endpoint command or evaluate context command ++ * and wait for it to finish. ++ */ ++static int xhci_configure_endpoint(struct xhci_hcd *xhci, ++ struct usb_device *udev, struct xhci_virt_device *virt_dev, ++ bool ctx_change) ++{ ++ int ret; ++ int timeleft; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&xhci->lock, flags); ++ if (!ctx_change) ++ ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx->dma, ++ udev->slot_id); ++ else ++ ret = xhci_queue_evaluate_context(xhci, virt_dev->in_ctx->dma, ++ udev->slot_id); ++ if (ret < 0) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); ++ return -ENOMEM; ++ } ++ xhci_ring_cmd_db(xhci); ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ ++ /* Wait for the configure endpoint command to complete */ ++ timeleft = wait_for_completion_interruptible_timeout( ++ &virt_dev->cmd_completion, ++ USB_CTRL_SET_TIMEOUT); ++ if (timeleft <= 0) { ++ xhci_warn(xhci, "%s while waiting for %s command\n", ++ timeleft == 0 ? "Timeout" : "Signal", ++ ctx_change == 0 ? ++ "configure endpoint" : ++ "evaluate context"); ++ /* FIXME cancel the configure endpoint command */ ++ return -ETIME; ++ } ++ ++ if (!ctx_change) ++ return xhci_configure_endpoint_result(xhci, udev, virt_dev); ++ return xhci_evaluate_context_result(xhci, udev, virt_dev); ++} ++ + /* Called after one or more calls to xhci_add_endpoint() or + * xhci_drop_endpoint(). If this call fails, the USB core is expected + * to call xhci_reset_bandwidth(). +@@ -956,8 +1072,6 @@ int xhci_check_bandwidth(struct usb_hcd + { + int i; + int ret = 0; +- int timeleft; +- unsigned long flags; + struct xhci_hcd *xhci; + struct xhci_virt_device *virt_dev; + struct xhci_input_control_ctx *ctrl_ctx; +@@ -987,56 +1101,7 @@ int xhci_check_bandwidth(struct usb_hcd + xhci_dbg_ctx(xhci, virt_dev->in_ctx, + LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); + +- spin_lock_irqsave(&xhci->lock, flags); +- ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx->dma, +- udev->slot_id); +- if (ret < 0) { +- spin_unlock_irqrestore(&xhci->lock, flags); +- xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); +- return -ENOMEM; +- } +- xhci_ring_cmd_db(xhci); +- spin_unlock_irqrestore(&xhci->lock, flags); +- +- /* Wait for the configure endpoint command to complete */ +- timeleft = wait_for_completion_interruptible_timeout( +- &virt_dev->cmd_completion, +- USB_CTRL_SET_TIMEOUT); +- if (timeleft <= 0) { +- xhci_warn(xhci, "%s while waiting for configure endpoint command\n", +- timeleft == 0 ? "Timeout" : "Signal"); +- /* FIXME cancel the configure endpoint command */ +- return -ETIME; +- } +- +- switch (virt_dev->cmd_status) { +- case COMP_ENOMEM: +- dev_warn(&udev->dev, "Not enough host controller resources " +- "for new device state.\n"); +- ret = -ENOMEM; +- /* FIXME: can we allocate more resources for the HC? */ +- break; +- case COMP_BW_ERR: +- dev_warn(&udev->dev, "Not enough bandwidth " +- "for new device state.\n"); +- ret = -ENOSPC; +- /* FIXME: can we go back to the old state? */ +- break; +- case COMP_TRB_ERR: +- /* the HCD set up something wrong */ +- dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, add flag = 1, " +- "and endpoint is not disabled.\n"); +- ret = -EINVAL; +- break; +- case COMP_SUCCESS: +- dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); +- break; +- default: +- xhci_err(xhci, "ERROR: unexpected command completion " +- "code 0x%x.\n", virt_dev->cmd_status); +- ret = -EINVAL; +- break; +- } ++ ret = xhci_configure_endpoint(xhci, udev, virt_dev, false); + if (ret) { + /* Callee should call reset_bandwidth() */ + return ret; +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -601,6 +601,44 @@ void xhci_endpoint_zero(struct xhci_hcd + */ + } + ++/* Copy output xhci_ep_ctx to the input xhci_ep_ctx copy. ++ * Useful when you want to change one particular aspect of the endpoint and then ++ * issue a configure endpoint command. ++ */ ++void xhci_endpoint_copy(struct xhci_hcd *xhci, ++ struct xhci_virt_device *vdev, unsigned int ep_index) ++{ ++ struct xhci_ep_ctx *out_ep_ctx; ++ struct xhci_ep_ctx *in_ep_ctx; ++ ++ out_ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index); ++ in_ep_ctx = xhci_get_ep_ctx(xhci, vdev->in_ctx, ep_index); ++ ++ in_ep_ctx->ep_info = out_ep_ctx->ep_info; ++ in_ep_ctx->ep_info2 = out_ep_ctx->ep_info2; ++ in_ep_ctx->deq = out_ep_ctx->deq; ++ in_ep_ctx->tx_info = out_ep_ctx->tx_info; ++} ++ ++/* Copy output xhci_slot_ctx to the input xhci_slot_ctx. ++ * Useful when you want to change one particular aspect of the endpoint and then ++ * issue a configure endpoint command. Only the context entries field matters, ++ * but we'll copy the whole thing anyway. ++ */ ++void xhci_slot_copy(struct xhci_hcd *xhci, struct xhci_virt_device *vdev) ++{ ++ struct xhci_slot_ctx *in_slot_ctx; ++ struct xhci_slot_ctx *out_slot_ctx; ++ ++ in_slot_ctx = xhci_get_slot_ctx(xhci, vdev->in_ctx); ++ out_slot_ctx = xhci_get_slot_ctx(xhci, vdev->out_ctx); ++ ++ in_slot_ctx->dev_info = out_slot_ctx->dev_info; ++ in_slot_ctx->dev_info2 = out_slot_ctx->dev_info2; ++ in_slot_ctx->tt_info = out_slot_ctx->tt_info; ++ in_slot_ctx->dev_state = out_slot_ctx->dev_state; ++} ++ + /* Set up the scratchpad buffer array and scratchpad buffers, if needed. */ + static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags) + { +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1740,6 +1740,15 @@ int xhci_queue_configure_endpoint(struct + TRB_TYPE(TRB_CONFIG_EP) | SLOT_ID_FOR_TRB(slot_id)); + } + ++/* Queue an evaluate context command TRB */ ++int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, ++ u32 slot_id) ++{ ++ return queue_command(xhci, lower_32_bits(in_ctx_ptr), ++ upper_32_bits(in_ctx_ptr), 0, ++ TRB_TYPE(TRB_EVAL_CONTEXT) | SLOT_ID_FOR_TRB(slot_id)); ++} ++ + int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, + unsigned int ep_index) + { diff --git a/queue-2.6.31/usb-xhci-don-t-touch-xhci_td-after-it-s-freed.patch b/queue-2.6.31/usb-xhci-don-t-touch-xhci_td-after-it-s-freed.patch new file mode 100644 index 00000000000..f799550c605 --- /dev/null +++ b/queue-2.6.31/usb-xhci-don-t-touch-xhci_td-after-it-s-freed.patch @@ -0,0 +1,32 @@ +From 9191eee7b8a0e18c07c06d6da502706805cab6d2 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Thu, 27 Aug 2009 14:36:14 -0700 +Subject: USB: xhci: Don't touch xhci_td after it's freed. + +From: Sarah Sharp + +commit 9191eee7b8a0e18c07c06d6da502706805cab6d2 upstream. + +On a successful transfer, urb->td is freed before the URB is ready to be +given back to the driver. Don't touch urb->td after it's freed. This bug +would have only shown up when xHCI debugging was turned on, and the freed +memory was quickly reused for something else. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1193,7 +1193,7 @@ cleanup: + if (urb) { + usb_hcd_unlink_urb_from_ep(xhci_to_hcd(xhci), urb); + xhci_dbg(xhci, "Giveback URB %p, len = %d, status = %d\n", +- urb, td->urb->actual_length, status); ++ urb, urb->actual_length, status); + spin_unlock(&xhci->lock); + usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, status); + spin_lock(&xhci->lock); diff --git a/queue-2.6.31/usb-xhci-fix-slot-and-endpoint-context-debugging.patch b/queue-2.6.31/usb-xhci-fix-slot-and-endpoint-context-debugging.patch new file mode 100644 index 00000000000..97c873d6ab1 --- /dev/null +++ b/queue-2.6.31/usb-xhci-fix-slot-and-endpoint-context-debugging.patch @@ -0,0 +1,40 @@ +From 018218d1d9eb06116d24a02dd5e7a390f0353d0f Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 7 Aug 2009 14:04:40 -0700 +Subject: USB: xhci: Fix slot and endpoint context debugging. + +From: Sarah Sharp + +commit 018218d1d9eb06116d24a02dd5e7a390f0353d0f upstream. + +Use the virtual address of the memory hardware uses, not the address for +the container of that memory. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-dbg.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci-dbg.c ++++ b/drivers/usb/host/xhci-dbg.c +@@ -413,7 +413,8 @@ void xhci_dbg_slot_ctx(struct xhci_hcd * + int i; + + struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx); +- dma_addr_t dma = ctx->dma + ((unsigned long)slot_ctx - (unsigned long)ctx); ++ dma_addr_t dma = ctx->dma + ++ ((unsigned long)slot_ctx - (unsigned long)ctx->bytes); + int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params); + + xhci_dbg(xhci, "Slot Context:\n"); +@@ -459,7 +460,7 @@ void xhci_dbg_ep_ctx(struct xhci_hcd *xh + for (i = 0; i < last_ep_ctx; ++i) { + struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ctx, i); + dma_addr_t dma = ctx->dma + +- ((unsigned long)ep_ctx - (unsigned long)ctx); ++ ((unsigned long)ep_ctx - (unsigned long)ctx->bytes); + + xhci_dbg(xhci, "Endpoint %02d Context:\n", i); + xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n", diff --git a/queue-2.6.31/usb-xhci-handle-babbling-endpoints-correctly.patch b/queue-2.6.31/usb-xhci-handle-babbling-endpoints-correctly.patch new file mode 100644 index 00000000000..76790ed8093 --- /dev/null +++ b/queue-2.6.31/usb-xhci-handle-babbling-endpoints-correctly.patch @@ -0,0 +1,69 @@ +From 83fbcdcca03013bb5af130d6d91eba11e3d3269e Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Thu, 27 Aug 2009 14:36:03 -0700 +Subject: USB: xhci: Handle babbling endpoints correctly. + +From: Sarah Sharp + +commit 83fbcdcca03013bb5af130d6d91eba11e3d3269e upstream. + +The 0.95 xHCI spec says that non-control endpoints will be halted if a +babble is detected on a transfer. The 0.96 xHCI spec says all types of +endpoints will be halted when a babble is detected. Some hardware that +claims to be 0.95 compliant halts the control endpoint anyway. + +When a babble is detected on a control endpoint, check the hardware's +output endpoint context to see if the endpoint is marked as halted. If +the control endpoint is halted, a reset endpoint command must be issued +and the transfer ring dequeue pointer needs to be moved past the stopped +transfer. Basically, we treat it as if the control endpoint had stalled. + +Handle bulk babbling endpoints as if we got a completion event with a +stall completion code. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -993,6 +993,16 @@ static int handle_tx_event(struct xhci_h + xhci_warn(xhci, "WARN: short transfer on control ep\n"); + status = -EREMOTEIO; + break; ++ case COMP_BABBLE: ++ /* The 0.96 spec says a babbling control endpoint ++ * is not halted. The 0.96 spec says it is. Some HW ++ * claims to be 0.95 compliant, but it halts the control ++ * endpoint anyway. Check if a babble halted the ++ * endpoint. ++ */ ++ if (ep_ctx->ep_info != EP_STATE_HALTED) ++ break; ++ /* else fall through */ + case COMP_STALL: + /* Did we transfer part of the data (middle) phase? */ + if (event_trb != ep_ring->dequeue && +@@ -1137,7 +1147,8 @@ static int handle_tx_event(struct xhci_h + ep_ring->stopped_td = td; + ep_ring->stopped_trb = event_trb; + } else { +- if (GET_COMP_CODE(event->transfer_len) == COMP_STALL) { ++ if (trb_comp_code == COMP_STALL || ++ trb_comp_code == COMP_BABBLE) { + /* The transfer is completed from the driver's + * perspective, but we need to issue a set dequeue + * command for this stalled endpoint to move the dequeue +@@ -1168,7 +1179,8 @@ td_cleanup: + * control endpoints). + */ + if (usb_endpoint_xfer_control(&urb->ep->desc) || +- GET_COMP_CODE(event->transfer_len) != COMP_STALL) { ++ (trb_comp_code != COMP_STALL && ++ trb_comp_code != COMP_BABBLE)) { + kfree(td); + } + urb->hcpriv = NULL; diff --git a/queue-2.6.31/usb-xhci-handle-stalled-control-endpoints.patch b/queue-2.6.31/usb-xhci-handle-stalled-control-endpoints.patch new file mode 100644 index 00000000000..a4f787a9649 --- /dev/null +++ b/queue-2.6.31/usb-xhci-handle-stalled-control-endpoints.patch @@ -0,0 +1,190 @@ +From 82d1009f537c2a43be0a410abd33521f76ee3a5a Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 7 Aug 2009 14:04:52 -0700 +Subject: USB: xhci: Handle stalled control endpoints. + +From: Sarah Sharp + +commit 82d1009f537c2a43be0a410abd33521f76ee3a5a upstream. + +When a control endpoint stalls, the next control transfer will clear the +stall. The USB core doesn't call down to the host controller driver's +endpoint_reset() method when control endpoints stall, so the xHCI driver +has to do all its stall handling for internal state in its interrupt handler. + +When the host stalls on a control endpoint, it may stop on the data phase +or status phase of the control transfer. Like other stalled endpoints, +the xHCI driver needs to queue a Reset Endpoint command and move the +hardware's control endpoint ring dequeue pointer past the failed control +transfer (with a Set TR Dequeue Pointer or a Configure Endpoint command). + +Since the USB core doesn't call usb_hcd_reset_endpoint() for control +endpoints, we need to do this in interrupt context when we get notified of +the stalled transfer. URBs may be queued to the hardware before these two +commands complete. The endpoint queue will be restarted once both +commands complete. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hcd.c | 35 ++++++++++++++++++++++++----------- + drivers/usb/host/xhci-ring.c | 33 ++++++++++++++++++++++++++++++--- + drivers/usb/host/xhci.h | 4 ++++ + 3 files changed, 58 insertions(+), 14 deletions(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -589,6 +589,7 @@ struct xhci_ep_ctx { + */ + #define FORCE_EVENT (0x1) + #define ERROR_COUNT(p) (((p) & 0x3) << 1) ++#define CTX_TO_EP_TYPE(p) (((p) >> 3) & 0x7) + #define EP_TYPE(p) ((p) << 3) + #define ISOC_OUT_EP 1 + #define BULK_OUT_EP 2 +@@ -1231,6 +1232,9 @@ void xhci_find_new_dequeue_state(struct + void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, + struct xhci_ring *ep_ring, unsigned int slot_id, + unsigned int ep_index, struct xhci_dequeue_state *deq_state); ++void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, ++ struct usb_device *udev, struct usb_host_endpoint *ep, ++ unsigned int ep_index, struct xhci_ring *ep_ring); + + /* xHCI roothub code */ + int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, +--- a/drivers/usb/host/xhci-hcd.c ++++ b/drivers/usb/host/xhci-hcd.c +@@ -1230,6 +1230,25 @@ void xhci_reset_bandwidth(struct usb_hcd + xhci_zero_in_ctx(xhci, virt_dev); + } + ++void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, ++ struct usb_device *udev, struct usb_host_endpoint *ep, ++ unsigned int ep_index, struct xhci_ring *ep_ring) ++{ ++ struct xhci_dequeue_state deq_state; ++ ++ xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n"); ++ /* We need to move the HW's dequeue pointer past this TD, ++ * or it will attempt to resend it on the next doorbell ring. ++ */ ++ xhci_find_new_dequeue_state(xhci, udev->slot_id, ++ ep_index, ep_ring->stopped_td, &deq_state); ++ ++ xhci_dbg(xhci, "Queueing new dequeue state\n"); ++ xhci_queue_new_dequeue_state(xhci, ep_ring, ++ udev->slot_id, ++ ep_index, &deq_state); ++} ++ + /* Deal with stalled endpoints. The core should have sent the control message + * to clear the halt condition. However, we need to make the xHCI hardware + * reset its sequence number, since a device will expect a sequence number of +@@ -1244,7 +1263,6 @@ void xhci_endpoint_reset(struct usb_hcd + unsigned int ep_index; + unsigned long flags; + int ret; +- struct xhci_dequeue_state deq_state; + struct xhci_ring *ep_ring; + + xhci = hcd_to_xhci(hcd); +@@ -1261,6 +1279,10 @@ void xhci_endpoint_reset(struct usb_hcd + ep->desc.bEndpointAddress); + return; + } ++ if (usb_endpoint_xfer_control(&ep->desc)) { ++ xhci_dbg(xhci, "Control endpoint stall already handled.\n"); ++ return; ++ } + + xhci_dbg(xhci, "Queueing reset endpoint command\n"); + spin_lock_irqsave(&xhci->lock, flags); +@@ -1271,16 +1293,7 @@ void xhci_endpoint_reset(struct usb_hcd + * command. Better hope that last command worked! + */ + if (!ret) { +- xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n"); +- /* We need to move the HW's dequeue pointer past this TD, +- * or it will attempt to resend it on the next doorbell ring. +- */ +- xhci_find_new_dequeue_state(xhci, udev->slot_id, +- ep_index, ep_ring->stopped_td, &deq_state); +- xhci_dbg(xhci, "Queueing new dequeue state\n"); +- xhci_queue_new_dequeue_state(xhci, ep_ring, +- udev->slot_id, +- ep_index, &deq_state); ++ xhci_cleanup_stalled_ring(xhci, udev, ep, ep_index, ep_ring); + kfree(ep_ring->stopped_td); + xhci_ring_cmd_db(xhci); + } +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -817,6 +817,7 @@ static int handle_tx_event(struct xhci_h + { + struct xhci_virt_device *xdev; + struct xhci_ring *ep_ring; ++ unsigned int slot_id; + int ep_index; + struct xhci_td *td = 0; + dma_addr_t event_dma; +@@ -827,7 +828,8 @@ static int handle_tx_event(struct xhci_h + struct xhci_ep_ctx *ep_ctx; + + xhci_dbg(xhci, "In %s\n", __func__); +- xdev = xhci->devs[TRB_TO_SLOT_ID(event->flags)]; ++ slot_id = TRB_TO_SLOT_ID(event->flags); ++ xdev = xhci->devs[slot_id]; + if (!xdev) { + xhci_err(xhci, "ERROR Transfer event pointed to bad slot\n"); + return -ENODEV; +@@ -941,6 +943,25 @@ static int handle_tx_event(struct xhci_h + xhci_warn(xhci, "WARN: short transfer on control ep\n"); + status = -EREMOTEIO; + break; ++ case COMP_STALL: ++ /* Did we transfer part of the data (middle) phase? */ ++ if (event_trb != ep_ring->dequeue && ++ event_trb != td->last_trb) ++ td->urb->actual_length = ++ td->urb->transfer_buffer_length ++ - TRB_LEN(event->transfer_len); ++ else ++ td->urb->actual_length = 0; ++ ++ ep_ring->stopped_td = td; ++ ep_ring->stopped_trb = event_trb; ++ xhci_queue_reset_ep(xhci, slot_id, ep_index); ++ xhci_cleanup_stalled_ring(xhci, ++ td->urb->dev, ++ td->urb->ep, ++ ep_index, ep_ring); ++ xhci_ring_cmd_db(xhci); ++ goto td_cleanup; + default: + /* Others already handled above */ + break; +@@ -1083,6 +1104,7 @@ static int handle_tx_event(struct xhci_h + inc_deq(xhci, ep_ring, false); + } + ++td_cleanup: + /* Clean up the endpoint's TD list */ + urb = td->urb; + list_del(&td->td_list); +@@ -1091,8 +1113,13 @@ static int handle_tx_event(struct xhci_h + list_del(&td->cancelled_td_list); + ep_ring->cancels_pending--; + } +- /* Leave the TD around for the reset endpoint function to use */ +- if (GET_COMP_CODE(event->transfer_len) != COMP_STALL) { ++ /* 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) || ++ GET_COMP_CODE(event->transfer_len) != COMP_STALL) { + kfree(td); + } + urb->hcpriv = NULL; diff --git a/queue-2.6.31/usb-xhci-make-trb-completion-code-comparison-readable.patch b/queue-2.6.31/usb-xhci-make-trb-completion-code-comparison-readable.patch new file mode 100644 index 00000000000..80ded9fe69c --- /dev/null +++ b/queue-2.6.31/usb-xhci-make-trb-completion-code-comparison-readable.patch @@ -0,0 +1,84 @@ +From 66d1eebce5cca916e0b08d961690bb01c64751ef Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Thu, 27 Aug 2009 14:35:53 -0700 +Subject: USB: xhci: Make TRB completion code comparison readable. + +From: Sarah Sharp + +commit 66d1eebce5cca916e0b08d961690bb01c64751ef upstream. + +Use trb_comp_code instead of getting the completion code from the transfer +event every time. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -874,6 +874,7 @@ static int handle_tx_event(struct xhci_h + struct urb *urb = 0; + int status = -EINPROGRESS; + struct xhci_ep_ctx *ep_ctx; ++ u32 trb_comp_code; + + xhci_dbg(xhci, "In %s\n", __func__); + slot_id = TRB_TO_SLOT_ID(event->flags); +@@ -931,7 +932,8 @@ static int handle_tx_event(struct xhci_h + (unsigned int) event->flags); + + /* Look for common error cases */ +- switch (GET_COMP_CODE(event->transfer_len)) { ++ trb_comp_code = GET_COMP_CODE(event->transfer_len); ++ switch (trb_comp_code) { + /* Skip codes that require special handling depending on + * transfer type + */ +@@ -974,7 +976,7 @@ static int handle_tx_event(struct xhci_h + /* Was this a control transfer? */ + if (usb_endpoint_xfer_control(&td->urb->ep->desc)) { + xhci_debug_trb(xhci, xhci->event_ring->dequeue); +- switch (GET_COMP_CODE(event->transfer_len)) { ++ switch (trb_comp_code) { + case COMP_SUCCESS: + if (event_trb == ep_ring->dequeue) { + xhci_warn(xhci, "WARN: Success on ctrl setup TRB without IOC set??\n"); +@@ -1031,7 +1033,7 @@ static int handle_tx_event(struct xhci_h + } + } else { + /* Maybe the event was for the data stage? */ +- if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL) { ++ if (trb_comp_code != COMP_STOP_INVAL) { + /* We didn't stop on a link TRB in the middle */ + td->urb->actual_length = + td->urb->transfer_buffer_length - +@@ -1043,7 +1045,7 @@ static int handle_tx_event(struct xhci_h + } + } + } else { +- switch (GET_COMP_CODE(event->transfer_len)) { ++ switch (trb_comp_code) { + case COMP_SUCCESS: + /* Double check that the HW transferred everything. */ + if (event_trb != td->last_trb) { +@@ -1120,14 +1122,14 @@ static int handle_tx_event(struct xhci_h + /* If the ring didn't stop on a Link or No-op TRB, add + * in the actual bytes transferred from the Normal TRB + */ +- if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL) ++ if (trb_comp_code != COMP_STOP_INVAL) + td->urb->actual_length += + TRB_LEN(cur_trb->generic.field[2]) - + TRB_LEN(event->transfer_len); + } + } +- if (GET_COMP_CODE(event->transfer_len) == COMP_STOP_INVAL || +- GET_COMP_CODE(event->transfer_len) == COMP_STOP) { ++ if (trb_comp_code == COMP_STOP_INVAL || ++ trb_comp_code == COMP_STOP) { + /* The Endpoint Stop Command completion will take care of any + * stopped TDs. A stopped TD may be restarted, so don't update + * the ring dequeue pointer or take this TD off any lists yet. diff --git a/queue-2.6.31/usb-xhci-set-correct-max-packet-size-for-hs-fs-control-endpoints.patch b/queue-2.6.31/usb-xhci-set-correct-max-packet-size-for-hs-fs-control-endpoints.patch new file mode 100644 index 00000000000..11a1e313349 --- /dev/null +++ b/queue-2.6.31/usb-xhci-set-correct-max-packet-size-for-hs-fs-control-endpoints.patch @@ -0,0 +1,63 @@ +From 47aded8ade9fee6779b121b2b156235f261239d7 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 7 Aug 2009 14:04:46 -0700 +Subject: USB: xhci: Set correct max packet size for HS/FS control endpoints. + +From: Sarah Sharp + +commit 47aded8ade9fee6779b121b2b156235f261239d7 upstream. + +Set the max packet size for the default control endpoint on high speed +devices to be 64 bytes. High speed devices always have a max packet size +of 64 bytes. There's no use setting it to eight for the initial 8 byte +descriptor fetch and then issuing (and waiting for) an evaluate context +command to update it to 64 bytes for the subsequent control transfers. + +The USB core guesses that the max packet size on a full speed control +endpoint is 64 bytes, and then updates it after the first 8-byte +descriptor fetch. Change the initial setup for the xHCI internal +representation of the full speed device to have a 64 byte max packet size. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-mem.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -401,15 +401,28 @@ int xhci_setup_addressable_virt_dev(stru + /* Step 5 */ + ep0_ctx->ep_info2 = EP_TYPE(CTRL_EP); + /* +- * See section 4.3 bullet 6: +- * The default Max Packet size for ep0 is "8 bytes for a USB2 +- * LS/FS/HS device or 512 bytes for a USB3 SS device" + * XXX: Not sure about wireless USB devices. + */ +- if (udev->speed == USB_SPEED_SUPER) ++ switch (udev->speed) { ++ case USB_SPEED_SUPER: + ep0_ctx->ep_info2 |= MAX_PACKET(512); +- else ++ break; ++ case USB_SPEED_HIGH: ++ /* USB core guesses at a 64-byte max packet first for FS devices */ ++ case USB_SPEED_FULL: ++ ep0_ctx->ep_info2 |= MAX_PACKET(64); ++ break; ++ case USB_SPEED_LOW: + ep0_ctx->ep_info2 |= MAX_PACKET(8); ++ break; ++ case USB_SPEED_VARIABLE: ++ xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n"); ++ return -EINVAL; ++ break; ++ default: ++ /* New speed? */ ++ BUG(); ++ } + /* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */ + ep0_ctx->ep_info2 |= MAX_BURST(0); + ep0_ctx->ep_info2 |= ERROR_COUNT(3); diff --git a/queue-2.6.31/usb-xhci-set-eremoteio-when-xhc-gives-bad-transfer-length.patch b/queue-2.6.31/usb-xhci-set-eremoteio-when-xhc-gives-bad-transfer-length.patch new file mode 100644 index 00000000000..0598169679b --- /dev/null +++ b/queue-2.6.31/usb-xhci-set-eremoteio-when-xhc-gives-bad-transfer-length.patch @@ -0,0 +1,47 @@ +From 2f697f6cbff155b3ce4053a50cdf00b5be4dda11 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 28 Aug 2009 14:28:18 -0700 +Subject: USB: xhci: Set -EREMOTEIO when xHC gives bad transfer length. + +From: Sarah Sharp + +commit 2f697f6cbff155b3ce4053a50cdf00b5be4dda11 upstream. + +The xHCI hardware reports the number of bytes untransferred for a given +transfer buffer. If the hardware reports a bytes untransferred value +greater than the submitted buffer size, we want to play it safe and say no +data was transferred. If the driver considers a short packet to be an +error, remember to set -EREMOTEIO. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1104,6 +1104,11 @@ static int handle_tx_event(struct xhci_h + "of %d bytes left\n", + TRB_LEN(event->transfer_len)); + td->urb->actual_length = 0; ++ if (td->urb->transfer_flags & ++ URB_SHORT_NOT_OK) ++ status = -EREMOTEIO; ++ else ++ status = 0; + } + /* Don't overwrite a previously set error code */ + if (status == -EINPROGRESS) { +@@ -1187,6 +1192,10 @@ td_cleanup: + urb->transfer_buffer_length, + urb->actual_length); + urb->actual_length = 0; ++ if (td->urb->transfer_flags & URB_SHORT_NOT_OK) ++ status = -EREMOTEIO; ++ else ++ status = 0; + } + list_del(&td->td_list); + /* Was this TD slated to be cancelled but completed anyway? */ diff --git a/queue-2.6.31/usb-xhci-support-full-speed-devices.patch b/queue-2.6.31/usb-xhci-support-full-speed-devices.patch new file mode 100644 index 00000000000..7a6870de738 --- /dev/null +++ b/queue-2.6.31/usb-xhci-support-full-speed-devices.patch @@ -0,0 +1,180 @@ +From 2d3f1fac7ee8bb4c6fad40f838488edbeabb0c50 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 7 Aug 2009 14:04:49 -0700 +Subject: USB: xhci: Support full speed devices. + +From: Sarah Sharp + +commit 2d3f1fac7ee8bb4c6fad40f838488edbeabb0c50 upstream. + +Full speed devices have varying max packet sizes (8, 16, 32, or 64) for +endpoint 0. The xHCI hardware needs to know the real max packet size +that the USB core discovers after it fetches the first 8 bytes of the +device descriptor. + +In order to fix this without adding a new hook to host controller drivers, +the xHCI driver looks for an updated max packet size for control +endpoints. If it finds an updated size, it issues an evaluate context +command and waits for that command to finish. This should only happen in +the initialization and device descriptor fetching steps in the khubd +thread, so blocking should be fine. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hcd.c | 88 ++++++++++++++++++++++++++++++++++++++++--- + drivers/usb/host/xhci-ring.c | 4 + + drivers/usb/host/xhci.h | 2 + 3 files changed, 89 insertions(+), 5 deletions(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -601,6 +601,8 @@ struct xhci_ep_ctx { + /* bit 7 is Host Initiate Disable - for disabling stream selection */ + #define MAX_BURST(p) (((p)&0xff) << 8) + #define MAX_PACKET(p) (((p)&0xffff) << 16) ++#define MAX_PACKET_MASK (0xffff << 16) ++#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff) + + + /** +--- a/drivers/usb/host/xhci-hcd.c ++++ b/drivers/usb/host/xhci-hcd.c +@@ -601,6 +601,70 @@ int xhci_check_args(struct usb_hcd *hcd, + return 1; + } + ++static int xhci_configure_endpoint(struct xhci_hcd *xhci, ++ struct usb_device *udev, struct xhci_virt_device *virt_dev, ++ bool ctx_change); ++ ++/* ++ * Full speed devices may have a max packet size greater than 8 bytes, but the ++ * USB core doesn't know that until it reads the first 8 bytes of the ++ * descriptor. If the usb_device's max packet size changes after that point, ++ * we need to issue an evaluate context command and wait on it. ++ */ ++static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, ++ unsigned int ep_index, struct urb *urb) ++{ ++ struct xhci_container_ctx *in_ctx; ++ struct xhci_container_ctx *out_ctx; ++ struct xhci_input_control_ctx *ctrl_ctx; ++ struct xhci_ep_ctx *ep_ctx; ++ int max_packet_size; ++ int hw_max_packet_size; ++ int ret = 0; ++ ++ out_ctx = xhci->devs[slot_id]->out_ctx; ++ ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); ++ hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2); ++ max_packet_size = urb->dev->ep0.desc.wMaxPacketSize; ++ if (hw_max_packet_size != max_packet_size) { ++ xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n"); ++ xhci_dbg(xhci, "Max packet size in usb_device = %d\n", ++ max_packet_size); ++ xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n", ++ hw_max_packet_size); ++ xhci_dbg(xhci, "Issuing evaluate context command.\n"); ++ ++ /* Set up the modified control endpoint 0 */ ++ xhci_endpoint_copy(xhci, xhci->devs[slot_id], ep_index); ++ in_ctx = xhci->devs[slot_id]->in_ctx; ++ ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); ++ ep_ctx->ep_info2 &= ~MAX_PACKET_MASK; ++ ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size); ++ ++ /* Set up the input context flags for the command */ ++ /* FIXME: This won't work if a non-default control endpoint ++ * changes max packet sizes. ++ */ ++ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); ++ ctrl_ctx->add_flags = EP0_FLAG; ++ ctrl_ctx->drop_flags = 0; ++ ++ xhci_dbg(xhci, "Slot %d input context\n", slot_id); ++ xhci_dbg_ctx(xhci, in_ctx, ep_index); ++ xhci_dbg(xhci, "Slot %d output context\n", slot_id); ++ xhci_dbg_ctx(xhci, out_ctx, ep_index); ++ ++ ret = xhci_configure_endpoint(xhci, urb->dev, ++ xhci->devs[slot_id], true); ++ ++ /* Clean up the input context for later use by bandwidth ++ * functions. ++ */ ++ ctrl_ctx->add_flags = SLOT_FLAG; ++ } ++ return ret; ++} ++ + /* + * non-error returns are a promise to giveback() the urb later + * we drop ownership so next owner (or urb unlink) can get it +@@ -612,13 +676,13 @@ int xhci_urb_enqueue(struct usb_hcd *hcd + int ret = 0; + unsigned int slot_id, ep_index; + ++ + if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) + return -EINVAL; + + slot_id = urb->dev->slot_id; + ep_index = xhci_get_endpoint_index(&urb->ep->desc); + +- spin_lock_irqsave(&xhci->lock, flags); + if (!xhci->devs || !xhci->devs[slot_id]) { + if (!in_interrupt()) + dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n"); +@@ -631,19 +695,33 @@ int xhci_urb_enqueue(struct usb_hcd *hcd + ret = -ESHUTDOWN; + goto exit; + } +- if (usb_endpoint_xfer_control(&urb->ep->desc)) ++ if (usb_endpoint_xfer_control(&urb->ep->desc)) { ++ /* Check to see if the max packet size for the default control ++ * endpoint changed during FS device enumeration ++ */ ++ if (urb->dev->speed == USB_SPEED_FULL) { ++ ret = xhci_check_maxpacket(xhci, slot_id, ++ ep_index, urb); ++ if (ret < 0) ++ return ret; ++ } ++ + /* We have a spinlock and interrupts disabled, so we must pass + * atomic context to this function, which may allocate memory. + */ ++ spin_lock_irqsave(&xhci->lock, flags); + ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, + slot_id, ep_index); +- else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { ++ spin_lock_irqsave(&xhci->lock, flags); + ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, + slot_id, ep_index); +- else ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ } else { + ret = -EINVAL; ++ } + exit: +- spin_unlock_irqrestore(&xhci->lock, flags); + return ret; + } + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -701,6 +701,10 @@ static void handle_cmd_completion(struct + xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); + complete(&xhci->devs[slot_id]->cmd_completion); + break; ++ case TRB_TYPE(TRB_EVAL_CONTEXT): ++ xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); ++ complete(&xhci->devs[slot_id]->cmd_completion); ++ break; + case TRB_TYPE(TRB_ADDR_DEV): + xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); + complete(&xhci->addr_dev); diff --git a/queue-2.6.31/usb-xhci-support-interrupt-transfers.patch b/queue-2.6.31/usb-xhci-support-interrupt-transfers.patch new file mode 100644 index 00000000000..63b8e9ccb36 --- /dev/null +++ b/queue-2.6.31/usb-xhci-support-interrupt-transfers.patch @@ -0,0 +1,132 @@ +From 624defa12f304b4d11eda309bc207fa5a1900d0f Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Wed, 2 Sep 2009 12:14:28 -0700 +Subject: USB: xhci: Support interrupt transfers. + +From: Sarah Sharp + +commit 624defa12f304b4d11eda309bc207fa5a1900d0f upstream. + +Interrupt transfers are submitted to the xHCI hardware using the same TRB +type as bulk transfers. Re-use the bulk transfer enqueueing code to +enqueue interrupt transfers. + +Interrupt transfers are a bit different than bulk transfers. When the +interrupt endpoint is to be serviced, the xHC will consume (at most) one +TD. A TD (comprised of sg list entries) can take several service +intervals to transmit. The important thing for device drivers to note is +that if they use the scatter gather interface to submit interrupt +requests, they will not get data sent from two different scatter gather +lists in the same service interval. + +For now, the xHCI driver will use the service interval from the endpoint's +descriptor (bInterval). Drivers will need a hook to poll at a more +frequent interval. Set urb->interval to the interval that the xHCI +hardware will use. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hcd.c | 5 ++++ + drivers/usb/host/xhci-ring.c | 48 ++++++++++++++++++++++++++++++++++++++++++- + drivers/usb/host/xhci.h | 3 ++ + 3 files changed, 55 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -581,6 +581,7 @@ struct xhci_ep_ctx { + /* bit 15 is Linear Stream Array */ + /* Interval - period between requests to an endpoint - 125u increments. */ + #define EP_INTERVAL(p) ((p & 0xff) << 16) ++#define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff)) + + /* ep_info2 bitmasks */ + /* +@@ -1223,6 +1224,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd * + int slot_id, unsigned int ep_index); + int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, + int slot_id, unsigned int ep_index); ++int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, ++ int slot_id, unsigned int ep_index); + int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, + u32 slot_id); + int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, +--- a/drivers/usb/host/xhci-hcd.c ++++ b/drivers/usb/host/xhci-hcd.c +@@ -727,6 +727,11 @@ int xhci_urb_enqueue(struct usb_hcd *hcd + ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, + slot_id, ep_index); + spin_unlock_irqrestore(&xhci->lock, flags); ++ } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { ++ spin_lock_irqsave(&xhci->lock, flags); ++ ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, ++ slot_id, ep_index); ++ spin_unlock_irqrestore(&xhci->lock, flags); + } else { + ret = -EINVAL; + } +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1072,7 +1072,12 @@ static int handle_tx_event(struct xhci_h + else + status = 0; + } else { +- xhci_dbg(xhci, "Successful bulk transfer!\n"); ++ if (usb_endpoint_xfer_bulk(&td->urb->ep->desc)) ++ xhci_dbg(xhci, "Successful bulk " ++ "transfer!\n"); ++ else ++ xhci_dbg(xhci, "Successful interrupt " ++ "transfer!\n"); + status = 0; + } + break; +@@ -1464,6 +1469,47 @@ static void giveback_first_trb(struct xh + ring_ep_doorbell(xhci, slot_id, ep_index); + } + ++/* ++ * xHCI uses normal TRBs for both bulk and interrupt. When the interrupt ++ * endpoint is to be serviced, the xHC will consume (at most) one TD. A TD ++ * (comprised of sg list entries) can take several service intervals to ++ * transmit. ++ */ ++int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ++ struct urb *urb, int slot_id, unsigned int ep_index) ++{ ++ struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ++ xhci->devs[slot_id]->out_ctx, ep_index); ++ int xhci_interval; ++ int ep_interval; ++ ++ xhci_interval = EP_INTERVAL_TO_UFRAMES(ep_ctx->ep_info); ++ ep_interval = urb->interval; ++ /* Convert to microframes */ ++ if (urb->dev->speed == USB_SPEED_LOW || ++ urb->dev->speed == USB_SPEED_FULL) ++ ep_interval *= 8; ++ /* FIXME change this to a warning and a suggestion to use the new API ++ * to set the polling interval (once the API is added). ++ */ ++ if (xhci_interval != ep_interval) { ++ if (!printk_ratelimit()) ++ dev_dbg(&urb->dev->dev, "Driver uses different interval" ++ " (%d microframe%s) than xHCI " ++ "(%d microframe%s)\n", ++ ep_interval, ++ ep_interval == 1 ? "" : "s", ++ xhci_interval, ++ xhci_interval == 1 ? "" : "s"); ++ urb->interval = xhci_interval; ++ /* Convert back to frames for LS/FS devices */ ++ if (urb->dev->speed == USB_SPEED_LOW || ++ urb->dev->speed == USB_SPEED_FULL) ++ urb->interval /= 8; ++ } ++ return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); ++} ++ + static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, + struct urb *urb, int slot_id, unsigned int ep_index) + { diff --git a/queue-2.6.31/usb-xhci-work-around-for-chain-bit-in-link-trbs.patch b/queue-2.6.31/usb-xhci-work-around-for-chain-bit-in-link-trbs.patch new file mode 100644 index 00000000000..ffeeb8a10c3 --- /dev/null +++ b/queue-2.6.31/usb-xhci-work-around-for-chain-bit-in-link-trbs.patch @@ -0,0 +1,145 @@ +From b0567b3f635db72c881a0d561cebb544ec085073 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 7 Aug 2009 14:04:36 -0700 +Subject: USB: xhci: Work around for chain bit in link TRBs. + +From: Sarah Sharp + +commit b0567b3f635db72c881a0d561cebb544ec085073 upstream. + +Different sections of the xHCI 0.95 specification had opposing +requirements for the chain bit in a link transaction request buffer (TRB). +The chain bit is used to designate that adjacent TRBs are all part of the +same scatter gather list that should be sent to the device. Link TRBs can +be in the middle, or at the beginning or end of these chained TRBs. + +Sections 4.11.5.1 and 6.4.4.1 both stated the link TRB "shall have the +chain bit set to 1", meaning it is always chained to the next TRB. +However, section 4.6.9 on the stop endpoint command has specific cases for +what the hardware must do for a link TRB with the chain bit set to 0. The +0.96 specification errata later cleared up this issue by fixing the +4.11.5.1 and 6.4.4.1 sections to state that a link TRB can have the chain +bit set to 1 or 0. + +The problem is that the xHCI cancellation code depends on the chain bit of +the link TRB being cleared when it's at the end of a TD, and some 0.95 +xHCI hardware simply stops processing the ring when it encounters a link +TRB with the chain bit cleared. + +Allow users who are testing 0.95 xHCI prototypes to set a module parameter +(link_quirk) to turn on this link TRB work around. Cancellation may not +work if the ring is stopped exactly on a link TRB with chain bit set, but +cancellation should be a relatively uncommon case. + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hcd.c | 12 ++++++++++++ + drivers/usb/host/xhci-mem.c | 3 +++ + drivers/usb/host/xhci-ring.c | 15 +++++++++++---- + drivers/usb/host/xhci.h | 9 +++++++++ + 4 files changed, 35 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1058,6 +1058,8 @@ struct xhci_hcd { + int noops_submitted; + int noops_handled; + int error_bitmask; ++ unsigned int quirks; ++#define XHCI_LINK_TRB_QUIRK (1 << 0) + }; + + /* For testing purposes */ +@@ -1136,6 +1138,13 @@ static inline void xhci_write_64(struct + writel(val_hi, ptr + 1); + } + ++static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci) ++{ ++ u32 temp = xhci_readl(xhci, &xhci->cap_regs->hc_capbase); ++ return ((HC_VERSION(temp) == 0x95) && ++ (xhci->quirks & XHCI_LINK_TRB_QUIRK)); ++} ++ + /* xHCI debugging */ + void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num); + void xhci_print_registers(struct xhci_hcd *xhci); +--- a/drivers/usb/host/xhci-hcd.c ++++ b/drivers/usb/host/xhci-hcd.c +@@ -22,12 +22,18 @@ + + #include + #include ++#include + + #include "xhci.h" + + #define DRIVER_AUTHOR "Sarah Sharp" + #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" + ++/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */ ++static int link_quirk; ++module_param(link_quirk, int, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); ++ + /* TODO: copied from ehci-hcd.c - can this be refactored? */ + /* + * handshake - spin reading hc until handshake completes or fails +@@ -214,6 +220,12 @@ int xhci_init(struct usb_hcd *hcd) + + xhci_dbg(xhci, "xhci_init\n"); + spin_lock_init(&xhci->lock); ++ if (link_quirk) { ++ xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n"); ++ xhci->quirks |= XHCI_LINK_TRB_QUIRK; ++ } else { ++ xhci_dbg(xhci, "xHCI has no QUIRKS\n"); ++ } + retval = xhci_mem_init(xhci, GFP_KERNEL); + xhci_dbg(xhci, "Finished xhci_init\n"); + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -94,6 +94,9 @@ static void xhci_link_segments(struct xh + val = prev->trbs[TRBS_PER_SEGMENT-1].link.control; + val &= ~TRB_TYPE_BITMASK; + val |= TRB_TYPE(TRB_LINK); ++ /* Always set the chain bit with 0.95 hardware */ ++ if (xhci_link_trb_quirk(xhci)) ++ val |= TRB_CHAIN; + prev->trbs[TRBS_PER_SEGMENT-1].link.control = val; + } + xhci_dbg(xhci, "Linking segment 0x%llx to segment 0x%llx (DMA)\n", +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -172,8 +172,9 @@ static void inc_deq(struct xhci_hcd *xhc + * have their chain bit cleared (so that each Link TRB is a separate TD). + * + * Section 6.4.4.1 of the 0.95 spec says link TRBs cannot have the chain bit +- * set, but other sections talk about dealing with the chain bit set. +- * Assume section 6.4.4.1 is wrong, and the chain bit can be set in a Link TRB. ++ * set, but other sections talk about dealing with the chain bit set. This was ++ * fixed in the 0.96 specification errata, but we have to assume that all 0.95 ++ * xHCI hardware can't handle the chain bit being cleared on a link TRB. + */ + static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer) + { +@@ -191,8 +192,14 @@ static void inc_enq(struct xhci_hcd *xhc + while (last_trb(xhci, ring, ring->enq_seg, next)) { + if (!consumer) { + if (ring != xhci->event_ring) { +- next->link.control &= ~TRB_CHAIN; +- next->link.control |= chain; ++ /* If we're not dealing with 0.95 hardware, ++ * carry over the chain bit of the previous TRB ++ * (which may mean the chain bit is cleared). ++ */ ++ if (!xhci_link_trb_quirk(xhci)) { ++ next->link.control &= ~TRB_CHAIN; ++ next->link.control |= chain; ++ } + /* Give this link TRB to the hardware */ + wmb(); + if (next->link.control & TRB_CYCLE)