Patch "xhci: update event ring dequeue pointer position to controller correctly" has been added to the 6.8-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    xhci: update event ring dequeue pointer position to controller correctly

to the 6.8-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     xhci-update-event-ring-dequeue-pointer-position-to-c.patch
and it can be found in the queue-6.8 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit a40e190be078bfb2a661e825e325dcb8d83e9249
Author: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx>
Date:   Fri Feb 16 16:09:31 2024 -0800

    xhci: update event ring dequeue pointer position to controller correctly
    
    [ Upstream commit e30e9ad9ed66c049f32ab2ffe38f0b576bebdd2c ]
    
    The event ring dequeue pointer field (ERDP) in xHC hardware is used to
    inform controller how far the driver has processed events on the event
    ring.
    
    In the case all events are handled and event ring is empty then the
    address of the TRB after the last processed one should be written.
    This TRB is both the enqueue and dequeue pointer.
    
    But in case we are writing the ERDP in the middle of processing
    several events then ERDP field should be written with the "up to and
    including" address of the last handled event TRB.
    
    Currenly each ERDP write by driver is done as if all events are handled
    and ring is empty.
    
    Fix this by adjusting the order when software dequeue "inc_deq()"
    is called and hardware dequeue "xhci_update_erst_dequeue()" is updated.
    
    Details in xhci 1.2 specification section 4.9.4:
    
    "System software shall write the Event Ring Dequeue Pointer (ERDP)
     register to inform the xHC that it has completed the processing of Event
     TRBs up to and including the Event TRB referenced by the ERDP.
    
     The detection of a Cycle bit mismatch in an Event TRB processed by
     software indicates the location of the xHC Event Ring Enqueue Pointer
     and that the Event Ring is empty. Software shall write the ERDP with
     the address of this TRB to indicate that it has processed all Events
     in the ring"
    
    This change depends on fixes made to relocate inc_deq() calls captured
    in the below commits:
    
      commit 3321f84bfae0 ("xhci: simplify event ring dequeue tracking for
      transfer events")
    
      commit d1830364e963 ("xhci: Simplify event ring dequeue pointer update
      for port change events")
    
    Fixes: dc0ffbea5729 ("usb: host: xhci: update event ring dequeue pointer on purpose")
    Signed-off-by: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx>
    Signed-off-by: Wesley Cheng <quic_wcheng@xxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20240217001017.29969-6-quic_wcheng@xxxxxxxxxxx
    Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 129d2e83034c1..61bd29dd71a2f 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3022,9 +3022,6 @@ static int xhci_handle_event(struct xhci_hcd *xhci, struct xhci_interrupter *ir)
 		return 0;
 	}
 
-	/* Update SW event ring dequeue pointer */
-	inc_deq(xhci, ir->event_ring);
-
 	/* Are there more items on the event ring?  Caller will call us again to
 	 * check.
 	 */
@@ -3147,15 +3144,21 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
 	 * that clears the EHB.
 	 */
 	while (xhci_handle_event(xhci, ir) > 0) {
-		if (event_loop++ < TRBS_PER_SEGMENT / 2)
-			continue;
-		xhci_update_erst_dequeue(xhci, ir, false);
+		/*
+		 * If half a segment of events have been handled in one go then
+		 * update ERDP, and force isoc trbs to interrupt more often
+		 */
+		if (event_loop++ > TRBS_PER_SEGMENT / 2) {
+			xhci_update_erst_dequeue(xhci, ir, false);
+
+			if (ir->isoc_bei_interval > AVOID_BEI_INTERVAL_MIN)
+				ir->isoc_bei_interval = ir->isoc_bei_interval / 2;
 
-		/* ring is half-full, force isoc trbs to interrupt more often */
-		if (ir->isoc_bei_interval > AVOID_BEI_INTERVAL_MIN)
-			ir->isoc_bei_interval = ir->isoc_bei_interval / 2;
+			event_loop = 0;
+		}
 
-		event_loop = 0;
+		/* Update SW event ring dequeue pointer */
+		inc_deq(xhci, ir->event_ring);
 	}
 
 	xhci_update_erst_dequeue(xhci, ir, true);




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux