diff options
author | Sarah Sharp | 2009-08-07 14:04:55 -0700 |
---|---|---|
committer | Greg Kroah-Hartman | 2009-09-23 06:46:17 -0700 |
commit | ac9d8fe7c6a8041cca5a0738915d2c4e21381421 (patch) | |
tree | 6ac3db149d39a61900e6df41ab9424f933a51489 /drivers/usb/host/xhci.h | |
parent | 82d1009f537c2a43be0a410abd33521f76ee3a5a (diff) |
USB: xhci: Add quirk for Fresco Logic xHCI hardware.
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 <sarah.a.sharp@linux.intel.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci.h')
-rw-r--r-- | drivers/usb/host/xhci.h | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index b1abaeb62b4c..bc64b500feb8 100644 --- 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_hcd *xhci, int slot_id, struct usb_device 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 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, + 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, |