Linux USB
 help / color / mirror / Atom feed
* [PATCH 0/3] xhci fixes for usb-linus
@ 2019-10-25 14:30 Mathias Nyman
  0 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2019-10-25 14:30 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

A few xhci fixes for usb-linus, solving a couple endianness issues, and a
use-after-free regression reported by Johan Hovold

-Mathias

Ben Dooks (Codethink) (1):
  usb: xhci: fix __le32/__le64 accessors in debugfs code

Mathias Nyman (1):
  xhci: Fix use-after-free regression in xhci clear hub TT
    implementation

Samuel Holland (1):
  usb: xhci: fix Immediate Data Transfer endianness

 drivers/usb/host/xhci-debugfs.c | 24 +++++++++---------
 drivers/usb/host/xhci-ring.c    |  2 ++
 drivers/usb/host/xhci.c         | 54 ++++++++++++++++++++++++++++++++++-------
 3 files changed, 59 insertions(+), 21 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] xhci fixes for usb-linus
@ 2020-04-21 14:08 Mathias Nyman
  0 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2020-04-21 14:08 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

These xhci fixes for usb-linus sort out halted empty endpoint handling,
protocol stall handling, and overcurrent handling.

Theses issues have caused usb devices to appear as if they stop working
suddenly, failed to enumerate LS/FS devices behind HS hubs (seen on some
audio devices), and host from freezing in case of suspend on over-current.

-Mathias 

Mathias Nyman (3):
  xhci: Fix handling halted endpoint even if endpoint ring appears empty
  xhci: prevent bus suspend if a roothub port detected a over-current
    condition
  xhci: Don't clear hub TT buffer on ep0 protocol stall

 drivers/usb/host/xhci-hub.c  |  9 +++++++
 drivers/usb/host/xhci-ring.c | 46 +++++++++++++++++++++++++++++++-----
 drivers/usb/host/xhci.c      | 14 +++++------
 drivers/usb/host/xhci.h      |  5 ++--
 4 files changed, 59 insertions(+), 15 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] xhci fixes for usb-linus
@ 2020-08-21  9:15 Mathias Nyman
  0 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2020-08-21  9:15 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

A few xhci fixes for usb-linus.
This series makes sure we don't ignore devices attached during suspend that
are stuck in a resume "cold attach status" state, and makes sure xhci driver
doesn't prevent queuing urbs to a endpoint only because driver previously
refused to manually clear the data toggle of a non-empty endpoint.

-Mathias

Ding Hui (1):
  xhci: Always restore EP_SOFT_CLEAR_TOGGLE even if ep reset failed

Kai-Heng Feng (1):
  xhci: Do warm-reset when both CAS and XDEV_RESUME are set

Li Jun (1):
  usb: host: xhci: fix ep context print mismatch in debugfs

 drivers/usb/host/xhci-debugfs.c |  8 ++++----
 drivers/usb/host/xhci-hub.c     | 19 ++++++++++---------
 drivers/usb/host/xhci.c         |  3 ++-
 3 files changed, 16 insertions(+), 14 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] xhci fixes for usb-linus
@ 2020-10-28 20:31 Mathias Nyman
  0 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2020-10-28 20:31 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

A few xhci patches for usb-linus, including a fix for the xhci lockdep
oops in 5.10-rc1

-Mathias

Colin Ian King (1):
  xhci: Fix sizeof() mismatch

Mathias Nyman (1):
  xhci: Don't create stream debugfs files with spinlock held.

Sandeep Singh (1):
  usb: xhci: Workaround for S3 issue on AMD SNPS 3.0 xHC

 drivers/usb/host/xhci-mem.c |  4 ++--
 drivers/usb/host/xhci-pci.c | 17 +++++++++++++++++
 drivers/usb/host/xhci.c     |  5 ++++-
 drivers/usb/host/xhci.h     |  1 +
 4 files changed, 24 insertions(+), 3 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] xhci fixes for usb-linus
@ 2022-04-08 13:48 Mathias Nyman
  0 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2022-04-08 13:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

A few small xhci fixes for usb-linus

Fixes USB 3 link resume for tunneled USB 3 devices, timers left running
after shutdown, and a bug in how we handle a full event ring.

Thanks
-Mathias


Henry Lin (1):
  xhci: stop polling roothubs after shutdown

Mathias Nyman (1):
  xhci: increase usb U3 -> U0 link resume timeout from 100ms to 500ms

Weitao Wang (1):
  USB: Fix xhci event ring dequeue pointer ERDP update issue

 drivers/usb/host/xhci-hub.c  |  2 +-
 drivers/usb/host/xhci-ring.c |  1 +
 drivers/usb/host/xhci.c      | 11 +++++++++++
 3 files changed, 13 insertions(+), 1 deletion(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] xhci fixes for usb-linus
@ 2022-08-25 15:08 Mathias Nyman
  0 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2022-08-25 15:08 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

A few xhci fixes for usb-linus.

USB3 devices aren't visible immediately after xHC reset, so don't
stop polling the roothub and suspend too early after xHC reset.

Also Revert the port poweroff patch due to regression,
and fix a null pointer issue for xHC hosts with just one roothub.

-Mathias

Mathias Nyman (3):
  xhci: Fix null pointer dereference in remove if xHC has only one
    roothub
  xhci: Add grace period after xHC start to prevent premature runtime
    suspend.
  Revert "xhci: turn off port power in shutdown"

 drivers/usb/host/xhci-hub.c  | 13 ++++++++++++-
 drivers/usb/host/xhci-plat.c | 11 ++++++++---
 drivers/usb/host/xhci.c      | 19 +++++--------------
 drivers/usb/host/xhci.h      |  4 +---
 4 files changed, 26 insertions(+), 21 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] xhci fixes for usb-linus
@ 2023-03-30 14:30 Mathias Nyman
  0 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2023-03-30 14:30 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

A few small patches for usb-linus.
Reverting xhci-pci asynchronous probe due to Renesas host regression, and
fixing a memory leak.

Thanks
Mathias

D Scott Phillips (1):
  xhci: also avoid the XHCI_ZERO_64B_REGS quirk with a passthrough iommu

Mathias Nyman (2):
  Revert "usb: xhci-pci: Set PROBE_PREFER_ASYNCHRONOUS"
  xhci: Free the command allocated for setting LPM if we return early

 drivers/usb/host/xhci-pci.c | 7 +++----
 drivers/usb/host/xhci.c     | 7 ++++++-
 2 files changed, 9 insertions(+), 5 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] xhci fixes for usb-linus
@ 2025-09-02 10:53 Mathias Nyman
  0 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2025-09-02 10:53 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

A couple xhci fixes for usb-linus

Fixing a xhci memory leak regression in 6.17-rc3, and a DbC issue
triggered when re-connecting DbC cable ~10 times without data transfers
in between

Thanks
Mathias

Mathias Nyman (3):
  xhci: dbc: decouple endpoint allocation from initialization
  xhci: dbc: Fix full DbC transfer ring after several reconnects
  xhci: fix memory leak regression when freeing xhci vdev devices depth
    first

 drivers/usb/host/xhci-dbgcap.c | 94 ++++++++++++++++++++++++----------
 drivers/usb/host/xhci-mem.c    |  2 +-
 2 files changed, 68 insertions(+), 28 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] xhci fixes for usb-linus
@ 2025-10-13 22:55 Mathias Nyman
  0 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2025-10-13 22:55 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

A few fixes for usb-linus 6.18-rc
Solve an issue in the USB2 only PCI xHCI controller support added to 6.18
Solve two DbC cases that have been around since beginning of DbC support.

Thanks
Mathias

Mathias Nyman (2):
  xhci: dbc: fix bogus 1024 byte prefix if ttyDBC read races with stall
    event
  xhci: dbc: enable back DbC in resume if it was enabled before suspend

Michal Pecio (1):
  usb: xhci-pci: Fix USB2-only root hub registration

 drivers/usb/host/xhci-dbgcap.c | 15 ++++++++++++---
 drivers/usb/host/xhci-pci.c    |  3 ++-
 2 files changed, 14 insertions(+), 4 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] xhci fixes for usb-linus
@ 2025-11-07 16:28 Mathias Nyman
  0 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2025-11-07 16:28 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

A few more fixes for usb-linus 6.18-rc
Includes the xhci sideband locking fix and a DbC data corruption fix

Thanks
Mathias

Mathias Nyman (3):
  xhci: fix stale flag preventig URBs after link state error is cleared
  xhci: dbgtty: Fix data corruption when transmitting data form DbC to
    host
  xhci: sideband: Fix race condition in sideband unregister

 drivers/usb/host/xhci-dbgcap.h   |   1 +
 drivers/usb/host/xhci-dbgtty.c   |  17 +++++-
 drivers/usb/host/xhci-ring.c     |  15 +++--
 drivers/usb/host/xhci-sideband.c | 102 ++++++++++++++++++-------------
 drivers/usb/host/xhci.c          |   1 +
 5 files changed, 86 insertions(+), 50 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] xhci fixes for usb-linus
@ 2026-03-04 22:36 Mathias Nyman
  0 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2026-03-04 22:36 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

Three small fixes sorting out a memory leak, null pointer, and interrupt
storm triggered in rarely run error paths, or in debugfs reads

Thanks
Mathias


Dayu Jiang (1):
  usb: xhci: Prevent interrupt storm on host controller error (HCE)

Mathias Nyman (1):
  xhci: Fix NULL pointer dereference when reading portli debugfs files

Zilin Guan (1):
  usb: xhci: Fix memory leak in xhci_disable_slot()

 drivers/usb/host/xhci-debugfs.c | 10 +++++++++-
 drivers/usb/host/xhci-ring.c    |  1 +
 drivers/usb/host/xhci.c         |  4 ++--
 3 files changed, 12 insertions(+), 3 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] xhci fixes for usb-linus
@ 2026-08-31  9:04 Mathias Nyman
  2026-08-31  9:04 ` [PATCH 1/3] usb: xhci: Fix HCS_ERST_MAX conversion Mathias Nyman
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Mathias Nyman @ 2026-08-31  9:04 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

xhci fixes for usb-linus on top of v7.3-rc1

kernel v7.3-rc1 has a xhci regression reported by several users making
xhci unusable for them. So far at least QEMU and Mediatek MT8173
users are affected.

The patch by Chen-Yu Tsai addresses this.

The two other patches are also nice to have.

Thanks
Mathias

Arthur Gautier (1):
  xhci: fix lost bounce buffers on TDs spanning several ring segments

Chen-Yu Tsai (1):
  usb: xhci: Fix HCS_ERST_MAX conversion

Michal Pecio (1):
  usb: xhci: Fix isochronous scheduling regression

 drivers/usb/host/xhci-mem.c  |  2 +-
 drivers/usb/host/xhci-ring.c | 43 +++++++++++++++++++++++++++---------
 2 files changed, 33 insertions(+), 12 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/3] usb: xhci: Fix HCS_ERST_MAX conversion
  2026-08-31  9:04 [PATCH 0/3] xhci fixes for usb-linus Mathias Nyman
@ 2026-08-31  9:04 ` Mathias Nyman
  2026-08-31  9:04 ` [PATCH 2/3] usb: xhci: Fix isochronous scheduling regression Mathias Nyman
  2026-08-31  9:04 ` [PATCH 3/3] xhci: fix lost bounce buffers on TDs spanning several ring segments Mathias Nyman
  2 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2026-08-31  9:04 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Chen-Yu Tsai, Niklas Neronin, Mathias Nyman

From: Chen-Yu Tsai <wenst@chromium.org>

This fixes one broken line in commit 6d45e9556d4a ("usb: xhci: standardize
multi bit-field macros") included in 7.3-rc1 kernel

HCS_ERST_MAX holds power of 2 value for maximum number of segments.
In the culprit commit, this was incorrectly converted to "shift up 2".
On hardware where this field is zero, this results in xhci_alloc_erst()
calling dma_alloc_coherent() with size = 0, leading to a horrible splat
and non-usable XHCI.

Revert the shift-up-2 to the BIT() macro.

Fixes: 6d45e9556d4a ("usb: xhci: standardize multi bit-field macros")
Cc: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-mem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 7a21ac81f9c8..af8d4b74c4ba 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2301,7 +2301,7 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, gfp_t flags)
 	if (!segs)
 		segs = ERST_DEFAULT_SEGS;
 
-	max_segs = FIELD_GET(HCS_ERST_MAX, xhci->hcs_params2) << 2;
+	max_segs = BIT(FIELD_GET(HCS_ERST_MAX, xhci->hcs_params2));
 	segs = min(segs, max_segs);
 
 	ir = kzalloc_node(sizeof(*ir), flags, dev_to_node(dev));
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/3] usb: xhci: Fix isochronous scheduling regression
  2026-08-31  9:04 [PATCH 0/3] xhci fixes for usb-linus Mathias Nyman
  2026-08-31  9:04 ` [PATCH 1/3] usb: xhci: Fix HCS_ERST_MAX conversion Mathias Nyman
@ 2026-08-31  9:04 ` Mathias Nyman
  2026-08-31  9:04 ` [PATCH 3/3] xhci: fix lost bounce buffers on TDs spanning several ring segments Mathias Nyman
  2 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2026-08-31  9:04 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Michal Pecio, Mathias Nyman

From: Michal Pecio <michal.pecio@gmail.com>

An isoc URB without URB_ISO_ASAP should be scheduled immediately after
the previous one, unless it's the first submission or prior URBs have
completed without resubmitting and the endpoint became idle.

An HCD_BH driver must consider URBs pending completion in the BH queue
in addition to its own queue. Regrettably, core doesn't provide much
information, we can only know if we are being called by completion now.
This issue is as old as HCD_BH, affects ehci-hcd too and has no known
reproducible impact, as drivers generally resubmit from completion.

A recent patch tried to address it by looking at xHCI HW state instead.
Obviously, HW has no knowledge of the BH giveback queue either, and the
whole solution amounts to testing whether prior URBs have been unlinked
instead of completing normally - then a new stream is assumed.

This leads to false negatives when a driver simply allows the endpoint
to empty out and begins a new stream. New URBs are scheduled into the
past and promptly fail with -EXDEV status, causing data loss and worse,
because drivers get confused by premature completion, particularly when
multiple endpoints are started at once and required to stay in sync.

snd-usb-audio underruns the OUT endpoint when userspace fails to supply
playback data in time. If this is detected in duplex mode, IN URBs are
unlinked and both streams restarted. OUT underruns again before IN even
begins, another recovery is attempted and the cycle repeats.

Fix this by using the best criteria we can muster, taken from ehci-hcd.
This brings false negative rate back to zero and false positive rate to
less than ever before in xhci-hcd. Traditional logic was equivalent to:

	if (list_empty(&ep_ring->td_list) ||
	    GET_EP_CTX_STATE(ep_ctx) != EP_STATE_RUNNING)
		// consider this URB a new stream

While free of false negatives, it had easily avoidable false positives:
* no check for completion in progress when the list is empty
* the ep_ctx check doesn't make up for it at all, but it adds a race -
  EP state can remain "stopped" for a while after the first submission

[mn: add debug message in possible false positive case where driver might
incorrectly assume new stream starts mid stream just because td list is
empty (URB enqueue is late), and workqueue isn't processing URB
completions for this endpoint at the moment]

Link: https://lore.kernel.org/linux-usb/20260813005635.34750f8c.michal.pecio@gmail.com/
Fixes: add8469b3e00 ("xhci: fix frame id calculation and checks for isoc URBs")
Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-ring.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 97a1b53c18ef..9847c5bfc41b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -4312,11 +4312,16 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
 	check_interval(urb, ep_ctx);
 
 	/*
-	 * Check if this starts the isoc data flow. Relies on hw setting ep ctx
-	 * state after doorbell ring. Consider adding list_empty(td_list) check
+	 * Schedule the URB discontiguously if all previous URBs have completed.
+	 * XXX core can't tell if completions are pending but not running yet.
 	 */
-	if (GET_EP_CTX_STATE(ep_ctx) != EP_STATE_RUNNING)
+	if (list_empty(&ep_ring->td_list) &&
+	    !hcd_periodic_completion_in_progress(xhci_to_hcd(xhci), urb->ep)) {
+		if (GET_EP_CTX_STATE(ep_ctx) == EP_STATE_RUNNING)
+			xhci_dbg(xhci, "Unexpected running ring at isoc stream start, uframe: %d\n",
+				 xep->next_uframe);
 		xep->next_uframe = -1;
+	}
 
 	return xhci_queue_isoc_tx(xhci, mem_flags, urb, slot_id, ep_index);
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/3] xhci: fix lost bounce buffers on TDs spanning several ring segments
  2026-08-31  9:04 [PATCH 0/3] xhci fixes for usb-linus Mathias Nyman
  2026-08-31  9:04 ` [PATCH 1/3] usb: xhci: Fix HCS_ERST_MAX conversion Mathias Nyman
  2026-08-31  9:04 ` [PATCH 2/3] usb: xhci: Fix isochronous scheduling regression Mathias Nyman
@ 2026-08-31  9:04 ` Mathias Nyman
  2 siblings, 0 replies; 15+ messages in thread
From: Mathias Nyman @ 2026-08-31  9:04 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Arthur Gautier, stable, Michal Pecio, Mathias Nyman

From: Arthur Gautier <baloo@superbaloo.net>

When a TD reaches a link TRB with data that is not aligned to the
endpoint's wMaxPacketSize, xhci_align_td() stages the unalignable tail
through the bounce buffer of the ring segment holding that link TRB.
xhci_unmap_td_bounce_buffer() later unmaps it and, for IN transfers,
copies the data back into the URB's buffer.

The enqueue path records the segment that was bounced in td->bounce_seg,
under the assumption that a TD never spans more than two ring segments.
That assumption does not hold: a TD large enough to span three or more
segments crosses several link TRBs and can be bounced at each of them.
Only the last one survives in td->bounce_seg, so every earlier bounce
buffer is neither copied back nor DMA unmapped.

The URB still completes with actual_length equal to the requested length
and no error, so the transfer looks successful while a wMaxPacketSize
sized hole in the destination buffer silently keeps its previous
contents. It also leaks a DMA mapping per dropped bounce.

Any sufficiently large and fragmented bulk transfer can hit this. It was
found with a USB mass storage device behind xHCI backing a dm-verity
target with 512 byte hash blocks, where the stale data is detected rather
than silently consumed. The device enumerates as SuperSpeed, so
wMaxPacketSize is 1024, while dm-bufio issues one 512 byte bio per hash
block. verity_prefetch_io() makes the block layer merge hundreds of them
into a single request of up to 512 scatterlist entries of 512 bytes each.
At 256 TRBs per ring segment such a TD spans three segments, and every
segment boundary falls on an odd multiple of 512, i.e. unaligned to
wMaxPacketSize. dm-bufio then caches a hash block holding stale data and
dm-verity declares the metadata block corrupted:

  device-mapper: verity: 8:2: metadata block 10850 is corrupted

A reproducer running this under qemu is available at
https://github.com/baloo/xhci-verity

The bounce state (bounce_buf, bounce_dma, bounce_len, bounce_offs)
already lives on the ring segment, so there is nothing extra to track.
Keep recording the last bounced segment in td->bounce_seg and, on
completion, walk the segments from td->start_seg up to it, unmapping
every segment that still has a pending bounce.

Stopping at td->bounce_seg rather than td->end_seg matters: a bounce
implies the TD continues past that segment's link TRB, so bounce_seg is
always strictly before end_seg, and a later TD may already have started
in end_seg and been bounced there. Walking that far would copy a foreign
bounce buffer into this URB and unmap it twice. It also keeps the walk
correct if a TD ever wraps the whole ring so that end_seg == start_seg.

[mn: Add ring->num_segs check to prevent unlikely infinite for loop.]

Fixes: f9c589e142d0 ("xhci: TD-fragment, align the unsplittable case with a bounce buffer")
Cc: stable@vger.kernel.org
Suggested-by: Michal Pecio <michal.pecio@gmail.com>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-ring.c | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 9847c5bfc41b..ec278a9f9540 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -824,21 +824,18 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
 	usb_hcd_giveback_urb(hcd, urb, status);
 }
 
-static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci,
-		struct xhci_ring *ring, struct xhci_td *td)
+static void xhci_unmap_one_bounce_buffer(struct xhci_hcd *xhci,
+		struct xhci_ring *ring, struct xhci_td *td,
+		struct xhci_segment *seg)
 {
 	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
-	struct xhci_segment *seg = td->bounce_seg;
 	struct urb *urb = td->urb;
 	size_t len;
 
-	if (!ring || !seg || !urb)
-		return;
-
 	if (usb_urb_dir_out(urb)) {
 		dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len,
 				 DMA_TO_DEVICE);
-		return;
+		goto done;
 	}
 
 	dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len,
@@ -854,10 +851,29 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci,
 		memcpy(urb->transfer_buffer + seg->bounce_offs, seg->bounce_buf,
 		       seg->bounce_len);
 	}
+done:
 	seg->bounce_len = 0;
 	seg->bounce_offs = 0;
 }
 
+static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci,
+		struct xhci_ring *ring, struct xhci_td *td)
+{
+	struct xhci_segment *seg;
+	int i = 0;
+
+	if (!td->bounce_seg || !ring || !td->urb)
+		return;
+
+	/* td->bounce_seg is the last one bounced, unmap them all */
+	for (seg = td->start_seg; i++ < ring->num_segs; seg = seg->next) {
+		if (seg->bounce_len)
+			xhci_unmap_one_bounce_buffer(xhci, ring, td, seg);
+		if (seg == td->bounce_seg)
+			break;
+	}
+}
+
 static void xhci_td_cleanup(struct xhci_hcd *xhci, struct xhci_td *td,
 			    struct xhci_ring *ep_ring, int status)
 {
@@ -3685,7 +3701,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 						  &trb_buff_len,
 						  ring->enq_seg)) {
 					send_addr = ring->enq_seg->bounce_dma;
-					/* assuming TD won't span 2 segs */
+					/* TD bounced at least, and last on this seg */
 					td->bounce_seg = ring->enq_seg;
 				}
 			}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-08-31  9:05 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-31  9:04 [PATCH 0/3] xhci fixes for usb-linus Mathias Nyman
2026-08-31  9:04 ` [PATCH 1/3] usb: xhci: Fix HCS_ERST_MAX conversion Mathias Nyman
2026-08-31  9:04 ` [PATCH 2/3] usb: xhci: Fix isochronous scheduling regression Mathias Nyman
2026-08-31  9:04 ` [PATCH 3/3] xhci: fix lost bounce buffers on TDs spanning several ring segments Mathias Nyman
  -- strict thread matches above, loose matches on Subject: below --
2026-03-04 22:36 [PATCH 0/3] xhci fixes for usb-linus Mathias Nyman
2025-11-07 16:28 Mathias Nyman
2025-10-13 22:55 Mathias Nyman
2025-09-02 10:53 Mathias Nyman
2023-03-30 14:30 Mathias Nyman
2022-08-25 15:08 Mathias Nyman
2022-04-08 13:48 Mathias Nyman
2020-10-28 20:31 Mathias Nyman
2020-08-21  9:15 Mathias Nyman
2020-04-21 14:08 Mathias Nyman
2019-10-25 14:30 Mathias Nyman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox