mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			69 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 2b0d70ec4fba339947992252c949c8cbd9be04af Mon Sep 17 00:00:00 2001
 | |
| From: Phil Elwell <phil@raspberrypi.com>
 | |
| Date: Tue, 10 Oct 2023 14:49:50 +0100
 | |
| Subject: [PATCH] Revert "Revert "xhci: add quirk for host controllers that
 | |
|  don't update endpoint DCS""
 | |
| 
 | |
| This reverts commit 96a0b80eb1b02e1330d525d4c866ccdfa8c67434.
 | |
| ---
 | |
|  drivers/usb/host/xhci-pci.c  |  4 +++-
 | |
|  drivers/usb/host/xhci-ring.c | 25 ++++++++++++++++++++++++-
 | |
|  2 files changed, 27 insertions(+), 2 deletions(-)
 | |
| 
 | |
| --- a/drivers/usb/host/xhci-pci.c
 | |
| +++ b/drivers/usb/host/xhci-pci.c
 | |
| @@ -293,8 +293,10 @@ static void xhci_pci_quirks(struct devic
 | |
|  			pdev->device == 0x3432)
 | |
|  		xhci->quirks |= XHCI_BROKEN_STREAMS;
 | |
|  
 | |
| -	if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483)
 | |
| +	if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) {
 | |
|  		xhci->quirks |= XHCI_LPM_SUPPORT;
 | |
| +		xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS;
 | |
| +	}
 | |
|  
 | |
|  	if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
 | |
|  		pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) {
 | |
| --- a/drivers/usb/host/xhci-ring.c
 | |
| +++ b/drivers/usb/host/xhci-ring.c
 | |
| @@ -592,8 +592,11 @@ static int xhci_move_dequeue_past_td(str
 | |
|  	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;
 | |
| @@ -631,7 +634,27 @@ static int xhci_move_dequeue_past_td(str
 | |
|  	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
 |