Skip to content

Commit

Permalink
Revert "Revert "xhci: add quirk for host controllers that don't updat…
Browse files Browse the repository at this point in the history
…e endpoint DCS""

This reverts commit 96a0b80.
  • Loading branch information
pelwell committed Oct 10, 2023
1 parent 450d617 commit 35e4e7e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
1 change: 0 additions & 1 deletion drivers/usb/host/xhci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)

if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) {
xhci->quirks |= XHCI_LPM_SUPPORT;
xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS;
xhci->quirks |= XHCI_AVOID_DQ_ON_LINK;
xhci->quirks |= XHCI_VLI_TRB_CACHE_BUG;
xhci->quirks |= XHCI_VLI_SS_BULK_OUT_BUG;
Expand Down
25 changes: 24 additions & 1 deletion drivers/usb/host/xhci-ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,8 +601,11 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci,
struct xhci_ring *ep_ring;
struct xhci_command *cmd;
struct xhci_segment *new_seg;
struct xhci_segment *halted_seg = NULL;
union xhci_trb *new_deq;
int new_cycle;
union xhci_trb *halted_trb;
int index = 0;
dma_addr_t addr;
u64 hw_dequeue;
bool cycle_found = false;
Expand Down Expand Up @@ -640,7 +643,27 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci,
hw_dequeue = xhci_get_hw_deq(xhci, dev, ep_index, stream_id);
new_seg = ep_ring->deq_seg;
new_deq = ep_ring->dequeue;
new_cycle = hw_dequeue & 0x1;

/*
* Quirk: xHC write-back of the DCS field in the hardware dequeue
* pointer is wrong - use the cycle state of the TRB pointed to by
* the dequeue pointer.
*/
if (xhci->quirks & XHCI_EP_CTX_BROKEN_DCS &&
!(ep->ep_state & EP_HAS_STREAMS))
halted_seg = trb_in_td(xhci, td->start_seg,
td->first_trb, td->last_trb,
hw_dequeue & ~0xf, false);
if (halted_seg) {
index = ((dma_addr_t)(hw_dequeue & ~0xf) - halted_seg->dma) /
sizeof(*halted_trb);
halted_trb = &halted_seg->trbs[index];
new_cycle = halted_trb->generic.field[3] & 0x1;
xhci_dbg(xhci, "Endpoint DCS = %d TRB index = %d cycle = %d\n",
(u8)(hw_dequeue & 0x1), index, new_cycle);
} else {
new_cycle = hw_dequeue & 0x1;
}

/*
* We want to find the pointer, segment and cycle state of the new trb
Expand Down

0 comments on commit 35e4e7e

Please sign in to comment.