* regression from 6.12.48 to 6.12.49: usb wlan adaptor stops working: bisected
@ 2025-09-26 15:54 Wolfgang Walter
2025-09-29 13:27 ` Greg Kroah-Hartman
2025-09-29 14:08 ` Neronin, Niklas
0 siblings, 2 replies; 5+ messages in thread
From: Wolfgang Walter @ 2025-09-26 15:54 UTC (permalink / raw)
To: Niklas Neronin; +Cc: Greg Kroah-Hartman, stable
Hello,o
after upgrading to 6.12.49 my wlan adapter stops working. It is
detected:
kernel: mt76x2u 4-2:1.0: ASIC revision: 76120044
kernel: mt76x2u 4-2:1.0: ROM patch build: 20141115060606a
kernel: usb 3-4: reset high-speed USB device number 2 using xhci_hcd
kernel: mt76x2u 4-2:1.0: Firmware Version: 0.0.00
kernel: mt76x2u 4-2:1.0: Build: 1
kernel: mt76x2u 4-2:1.0: Build Time: 201507311614____
but does nor work. The following 2 messages probably are relevant:
kernel: mt76x2u 4-2:1.0: MAC RX failed to stop
kernel: mt76x2u 4-2:1.0: MAC RX failed to stop
later I see a lot of
kernel: mt76x2u 4-2:1.0: error: mt76x02u_mcu_wait_resp failed with -110
I bisected it down to commit
9b28ef1e4cc07cdb35da257aa4358d0127168b68
usb: xhci: remove option to change a default ring's TRB cycle bit
9b28ef1e4cc07cdb35da257aa4358d0127168b68 is the first bad commit
commit 9b28ef1e4cc07cdb35da257aa4358d0127168b68
Author: Niklas Neronin <niklas.neronin@linux.intel.com>
Date: Wed Sep 17 08:39:07 2025 -0400
usb: xhci: remove option to change a default ring's TRB cycle bit
[ Upstream commit e1b0fa863907a61e86acc19ce2d0633941907c8e ]
The TRB cycle bit indicates TRB ownership by the Host Controller
(HC) or
Host Controller Driver (HCD). New rings are initialized with
'cycle_state'
equal to one, and all its TRBs' cycle bits are set to zero. When
handling
ring expansion, set the source ring cycle bits to the same value as
the
destination ring.
Move the cycle bit setting from xhci_segment_alloc() to
xhci_link_rings(),
and remove the 'cycle_state' argument from
xhci_initialize_ring_info().
The xhci_segment_alloc() function uses kzalloc_node() to allocate
segments,
ensuring that all TRB cycle bits are initialized to zero.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link:
https://lore.kernel.org/r/20241106101459.775897-12-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: a5c98e8b1398 ("xhci: dbc: Fix full DbC transfer ring
after several reconnects")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Regards,
--
Wolfgang Walter
Studierendenwerk München Oberbayern
Anstalt des öffentlichen Rechts
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: regression from 6.12.48 to 6.12.49: usb wlan adaptor stops working: bisected 2025-09-26 15:54 regression from 6.12.48 to 6.12.49: usb wlan adaptor stops working: bisected Wolfgang Walter @ 2025-09-29 13:27 ` Greg Kroah-Hartman 2025-09-30 17:56 ` Wolfgang Walter 2025-09-29 14:08 ` Neronin, Niklas 1 sibling, 1 reply; 5+ messages in thread From: Greg Kroah-Hartman @ 2025-09-29 13:27 UTC (permalink / raw) To: Wolfgang Walter; +Cc: Niklas Neronin, stable On Fri, Sep 26, 2025 at 05:54:00PM +0200, Wolfgang Walter wrote: > Hello,o > after upgrading to 6.12.49 my wlan adapter stops working. It is detected: > > kernel: mt76x2u 4-2:1.0: ASIC revision: 76120044 > kernel: mt76x2u 4-2:1.0: ROM patch build: 20141115060606a > kernel: usb 3-4: reset high-speed USB device number 2 using xhci_hcd > kernel: mt76x2u 4-2:1.0: Firmware Version: 0.0.00 > kernel: mt76x2u 4-2:1.0: Build: 1 > kernel: mt76x2u 4-2:1.0: Build Time: 201507311614____ > > but does nor work. The following 2 messages probably are relevant: > > kernel: mt76x2u 4-2:1.0: MAC RX failed to stop > kernel: mt76x2u 4-2:1.0: MAC RX failed to stop > > later I see a lot of > > kernel: mt76x2u 4-2:1.0: error: mt76x02u_mcu_wait_resp failed with -110 > > > I bisected it down to commit > > 9b28ef1e4cc07cdb35da257aa4358d0127168b68 > usb: xhci: remove option to change a default ring's TRB cycle bit > > > 9b28ef1e4cc07cdb35da257aa4358d0127168b68 is the first bad commit > commit 9b28ef1e4cc07cdb35da257aa4358d0127168b68 > Author: Niklas Neronin <niklas.neronin@linux.intel.com> > Date: Wed Sep 17 08:39:07 2025 -0400 > > usb: xhci: remove option to change a default ring's TRB cycle bit > > [ Upstream commit e1b0fa863907a61e86acc19ce2d0633941907c8e ] > > The TRB cycle bit indicates TRB ownership by the Host Controller (HC) or > Host Controller Driver (HCD). New rings are initialized with > 'cycle_state' > equal to one, and all its TRBs' cycle bits are set to zero. When > handling > ring expansion, set the source ring cycle bits to the same value as the > destination ring. > > Move the cycle bit setting from xhci_segment_alloc() to > xhci_link_rings(), > and remove the 'cycle_state' argument from xhci_initialize_ring_info(). > The xhci_segment_alloc() function uses kzalloc_node() to allocate > segments, > ensuring that all TRB cycle bits are initialized to zero. > > Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com> > Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> > Link: https://lore.kernel.org/r/20241106101459.775897-12-mathias.nyman@linux.intel.com > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > Stable-dep-of: a5c98e8b1398 ("xhci: dbc: Fix full DbC transfer ring > after several reconnects") > Signed-off-by: Sasha Levin <sashal@kernel.org> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > > Does 6.17 also have this problem? thanks, greg k-h ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: regression from 6.12.48 to 6.12.49: usb wlan adaptor stops working: bisected 2025-09-29 13:27 ` Greg Kroah-Hartman @ 2025-09-30 17:56 ` Wolfgang Walter 0 siblings, 0 replies; 5+ messages in thread From: Wolfgang Walter @ 2025-09-30 17:56 UTC (permalink / raw) To: Greg Kroah-Hartman; +Cc: Niklas Neronin, stable Am 2025-09-29 15:27, schrieb Greg Kroah-Hartman: > On Fri, Sep 26, 2025 at 05:54:00PM +0200, Wolfgang Walter wrote: >> Hello,o >> after upgrading to 6.12.49 my wlan adapter stops working. It is >> detected: >> >> kernel: mt76x2u 4-2:1.0: ASIC revision: 76120044 >> kernel: mt76x2u 4-2:1.0: ROM patch build: 20141115060606a >> kernel: usb 3-4: reset high-speed USB device number 2 using xhci_hcd >> kernel: mt76x2u 4-2:1.0: Firmware Version: 0.0.00 >> kernel: mt76x2u 4-2:1.0: Build: 1 >> kernel: mt76x2u 4-2:1.0: Build Time: 201507311614____ >> >> but does nor work. The following 2 messages probably are relevant: >> >> kernel: mt76x2u 4-2:1.0: MAC RX failed to stop >> kernel: mt76x2u 4-2:1.0: MAC RX failed to stop >> >> later I see a lot of >> >> kernel: mt76x2u 4-2:1.0: error: mt76x02u_mcu_wait_resp failed with >> -110 >> >> >> I bisected it down to commit >> >> 9b28ef1e4cc07cdb35da257aa4358d0127168b68 >> usb: xhci: remove option to change a default ring's TRB cycle bit >> >> >> 9b28ef1e4cc07cdb35da257aa4358d0127168b68 is the first bad commit >> commit 9b28ef1e4cc07cdb35da257aa4358d0127168b68 >> Author: Niklas Neronin <niklas.neronin@linux.intel.com> >> Date: Wed Sep 17 08:39:07 2025 -0400 >> >> usb: xhci: remove option to change a default ring's TRB cycle bit >> >> [ Upstream commit e1b0fa863907a61e86acc19ce2d0633941907c8e ] >> >> The TRB cycle bit indicates TRB ownership by the Host Controller >> (HC) or >> Host Controller Driver (HCD). New rings are initialized with >> 'cycle_state' >> equal to one, and all its TRBs' cycle bits are set to zero. When >> handling >> ring expansion, set the source ring cycle bits to the same value >> as the >> destination ring. >> >> Move the cycle bit setting from xhci_segment_alloc() to >> xhci_link_rings(), >> and remove the 'cycle_state' argument from >> xhci_initialize_ring_info(). >> The xhci_segment_alloc() function uses kzalloc_node() to allocate >> segments, >> ensuring that all TRB cycle bits are initialized to zero. >> >> Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com> >> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> >> Link: >> https://lore.kernel.org/r/20241106101459.775897-12-mathias.nyman@linux.intel.com >> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> >> Stable-dep-of: a5c98e8b1398 ("xhci: dbc: Fix full DbC transfer >> ring >> after several reconnects") >> Signed-off-by: Sasha Levin <sashal@kernel.org> >> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> >> >> > > Does 6.17 also have this problem? > > thanks, > > greg k-h I built a 6.17 kernel and it works fine, so no, 6.17 does not have this problem. Thanks a lot to you and all kernel developers who make the stable and longterm kernels possible. We use them since many years and are very happy with them. Regards -- Wolfgang Walter Studierendenwerk München Oberbayern Anstalt des öffentlichen Rechts ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: regression from 6.12.48 to 6.12.49: usb wlan adaptor stops working: bisected 2025-09-26 15:54 regression from 6.12.48 to 6.12.49: usb wlan adaptor stops working: bisected Wolfgang Walter 2025-09-29 13:27 ` Greg Kroah-Hartman @ 2025-09-29 14:08 ` Neronin, Niklas 2025-09-29 17:53 ` Wolfgang Walter 1 sibling, 1 reply; 5+ messages in thread From: Neronin, Niklas @ 2025-09-29 14:08 UTC (permalink / raw) To: Wolfgang Walter; +Cc: Greg Kroah-Hartman, stable, Mathias Nyman On 26/09/2025 18.54, Wolfgang Walter wrote: > Hello,o > after upgrading to 6.12.49 my wlan adapter stops working. It is detected: > > kernel: mt76x2u 4-2:1.0: ASIC revision: 76120044 > kernel: mt76x2u 4-2:1.0: ROM patch build: 20141115060606a > kernel: usb 3-4: reset high-speed USB device number 2 using xhci_hcd > kernel: mt76x2u 4-2:1.0: Firmware Version: 0.0.00 > kernel: mt76x2u 4-2:1.0: Build: 1 > kernel: mt76x2u 4-2:1.0: Build Time: 201507311614____ > > but does nor work. The following 2 messages probably are relevant: > > kernel: mt76x2u 4-2:1.0: MAC RX failed to stop > kernel: mt76x2u 4-2:1.0: MAC RX failed to stop > > later I see a lot of > > kernel: mt76x2u 4-2:1.0: error: mt76x02u_mcu_wait_resp failed with -110 > > > I bisected it down to commit > > 9b28ef1e4cc07cdb35da257aa4358d0127168b68 > usb: xhci: remove option to change a default ring's TRB cycle bit > > > 9b28ef1e4cc07cdb35da257aa4358d0127168b68 is the first bad commit > commit 9b28ef1e4cc07cdb35da257aa4358d0127168b68 > Author: Niklas Neronin <niklas.neronin@linux.intel.com> > Date: Wed Sep 17 08:39:07 2025 -0400 > > usb: xhci: remove option to change a default ring's TRB cycle bit > > [ Upstream commit e1b0fa863907a61e86acc19ce2d0633941907c8e ] > > The TRB cycle bit indicates TRB ownership by the Host Controller (HC) or > Host Controller Driver (HCD). New rings are initialized with 'cycle_state' > equal to one, and all its TRBs' cycle bits are set to zero. When handling > ring expansion, set the source ring cycle bits to the same value as the > destination ring. > > Move the cycle bit setting from xhci_segment_alloc() to xhci_link_rings(), > and remove the 'cycle_state' argument from xhci_initialize_ring_info(). > The xhci_segment_alloc() function uses kzalloc_node() to allocate segments, > ensuring that all TRB cycle bits are initialized to zero. > > Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com> > Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> > Link: https://lore.kernel.org/r/20241106101459.775897-12-mathias.nyman@linux.intel.com > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > Stable-dep-of: a5c98e8b1398 ("xhci: dbc: Fix full DbC transfer ring after several reconnects") > Signed-off-by: Sasha Levin <sashal@kernel.org> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > Hi, could you test if the code below helps? This reverts commit 9b28ef1e4cc0 ("usb: xhci: remove option to change a default ring's TRB cycle bit") which is upstream [2]. The original commit was never intended for stable kernels, but was added as a dependency for commit [1]. Revert it, and solve the dependency by modifying one line in xhci_dbc_ring_init(). The function call xhci_initialize_ring_info() was moved in commit [1] into xhci_dbc_ring_init(). Thus, xhci_initialize_ring_info() is also modified. [1], commit a5c98e8b1398 ("xhci: dbc: Fix full DbC transfer ring after several reconnects") [2], commit e1b0fa863907 ("usb: xhci: remove option to change a default ring's TRB cycle bit") Best Regards, Niklas diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c index 1fcc9348dd43..123506681ef0 100644 --- a/drivers/usb/host/xhci-dbgcap.c +++ b/drivers/usb/host/xhci-dbgcap.c @@ -458,7 +458,7 @@ static void xhci_dbc_ring_init(struct xhci_ring *ring) trb->link.segment_ptr = cpu_to_le64(ring->first_seg->dma); trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK)); } - xhci_initialize_ring_info(ring); + xhci_initialize_ring_info(ring, 1); } static int xhci_dbc_reinit_ep_rings(struct xhci_dbc *dbc) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index c9694526b157..f0ed38da6a0c 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -27,12 +27,14 @@ * "All components of all Command and Transfer TRBs shall be initialized to '0'" */ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, + unsigned int cycle_state, unsigned int max_packet, unsigned int num, gfp_t flags) { struct xhci_segment *seg; dma_addr_t dma; + int i; struct device *dev = xhci_to_hcd(xhci)->self.sysdev; seg = kzalloc_node(sizeof(*seg), flags, dev_to_node(dev)); @@ -54,6 +56,11 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, return NULL; } } + /* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */ + if (cycle_state == 0) { + for (i = 0; i < TRBS_PER_SEGMENT; i++) + seg->trbs[i].link.control = cpu_to_le32(TRB_CYCLE); + } seg->num = num; seg->dma = dma; seg->next = NULL; @@ -131,14 +138,6 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring, chain_links = xhci_link_chain_quirk(xhci, ring->type); - /* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */ - if (ring->cycle_state == 0) { - xhci_for_each_ring_seg(ring->first_seg, seg) { - for (int i = 0; i < TRBS_PER_SEGMENT; i++) - seg->trbs[i].link.control |= cpu_to_le32(TRB_CYCLE); - } - } - next = ring->enq_seg->next; xhci_link_segments(ring->enq_seg, first, ring->type, chain_links); xhci_link_segments(last, next, ring->type, chain_links); @@ -288,7 +287,8 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring) kfree(ring); } -void xhci_initialize_ring_info(struct xhci_ring *ring) +void xhci_initialize_ring_info(struct xhci_ring *ring, + unsigned int cycle_state) { /* The ring is empty, so the enqueue pointer == dequeue pointer */ ring->enqueue = ring->first_seg->trbs; @@ -302,7 +302,7 @@ void xhci_initialize_ring_info(struct xhci_ring *ring) * New rings are initialized with cycle state equal to 1; if we are * handling ring expansion, set the cycle state equal to the old ring. */ - ring->cycle_state = 1; + ring->cycle_state = cycle_state; /* * Each segment has a link TRB, and leave an extra TRB for SW @@ -317,6 +317,7 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, struct xhci_segment **first, struct xhci_segment **last, unsigned int num_segs, + unsigned int cycle_state, enum xhci_ring_type type, unsigned int max_packet, gfp_t flags) @@ -327,7 +328,7 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, chain_links = xhci_link_chain_quirk(xhci, type); - prev = xhci_segment_alloc(xhci, max_packet, num, flags); + prev = xhci_segment_alloc(xhci, cycle_state, max_packet, num, flags); if (!prev) return -ENOMEM; num++; @@ -336,7 +337,8 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, while (num < num_segs) { struct xhci_segment *next; - next = xhci_segment_alloc(xhci, max_packet, num, flags); + next = xhci_segment_alloc(xhci, cycle_state, max_packet, num, + flags); if (!next) goto free_segments; @@ -361,8 +363,9 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, * Set the end flag and the cycle toggle bit on the last segment. * See section 4.9.1 and figures 15 and 16. */ -struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int num_segs, - enum xhci_ring_type type, unsigned int max_packet, gfp_t flags) +struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, + unsigned int num_segs, unsigned int cycle_state, + enum xhci_ring_type type, unsigned int max_packet, gfp_t flags) { struct xhci_ring *ring; int ret; @@ -380,7 +383,7 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int num_segs, return ring; ret = xhci_alloc_segments_for_ring(xhci, &ring->first_seg, &ring->last_seg, num_segs, - type, max_packet, flags); + cycle_state, type, max_packet, flags); if (ret) goto fail; @@ -390,7 +393,7 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int num_segs, ring->last_seg->trbs[TRBS_PER_SEGMENT - 1].link.control |= cpu_to_le32(LINK_TOGGLE); } - xhci_initialize_ring_info(ring); + xhci_initialize_ring_info(ring, cycle_state); trace_xhci_ring_alloc(ring); return ring; @@ -418,8 +421,8 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, struct xhci_segment *last; int ret; - ret = xhci_alloc_segments_for_ring(xhci, &first, &last, num_new_segs, ring->type, - ring->bounce_buf_len, flags); + ret = xhci_alloc_segments_for_ring(xhci, &first, &last, num_new_segs, ring->cycle_state, + ring->type, ring->bounce_buf_len, flags); if (ret) return -ENOMEM; @@ -629,7 +632,8 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, for (cur_stream = 1; cur_stream < num_streams; cur_stream++) { stream_info->stream_rings[cur_stream] = - xhci_ring_alloc(xhci, 2, TYPE_STREAM, max_packet, mem_flags); + xhci_ring_alloc(xhci, 2, 1, TYPE_STREAM, max_packet, + mem_flags); cur_ring = stream_info->stream_rings[cur_stream]; if (!cur_ring) goto cleanup_rings; @@ -970,7 +974,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, } /* Allocate endpoint 0 ring */ - dev->eps[0].ring = xhci_ring_alloc(xhci, 2, TYPE_CTRL, 0, flags); + dev->eps[0].ring = xhci_ring_alloc(xhci, 2, 1, TYPE_CTRL, 0, flags); if (!dev->eps[0].ring) goto fail; @@ -1453,7 +1457,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, /* Set up the endpoint ring */ virt_dev->eps[ep_index].new_ring = - xhci_ring_alloc(xhci, 2, ring_type, max_packet, mem_flags); + xhci_ring_alloc(xhci, 2, 1, ring_type, max_packet, mem_flags); if (!virt_dev->eps[ep_index].new_ring) return -ENOMEM; @@ -2262,7 +2266,7 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, gfp_t flags) if (!ir) return NULL; - ir->event_ring = xhci_ring_alloc(xhci, segs, TYPE_EVENT, 0, flags); + ir->event_ring = xhci_ring_alloc(xhci, segs, 1, TYPE_EVENT, 0, flags); if (!ir->event_ring) { xhci_warn(xhci, "Failed to allocate interrupter event ring\n"); kfree(ir); @@ -2468,7 +2472,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) goto fail; /* Set up the command ring to have one segments for now. */ - xhci->cmd_ring = xhci_ring_alloc(xhci, 1, TYPE_COMMAND, 0, flags); + xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, 0, flags); if (!xhci->cmd_ring) goto fail; xhci_dbg_trace(xhci, trace_xhci_dbg_init, diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 3970ec831b8c..abbf89e82d01 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -769,7 +769,7 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci) seg->trbs[TRBS_PER_SEGMENT - 1].link.control &= cpu_to_le32(~TRB_CYCLE); } - xhci_initialize_ring_info(ring); + xhci_initialize_ring_info(ring, 1); /* * Reset the hardware dequeue pointer. * Yes, this will need to be re-written after resume, but we're paranoid diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index b2aeb444daaf..b4fa8e7e4376 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1803,12 +1803,14 @@ void xhci_slot_copy(struct xhci_hcd *xhci, int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_device *udev, struct usb_host_endpoint *ep, gfp_t mem_flags); -struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int num_segs, +struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, + unsigned int num_segs, unsigned int cycle_state, enum xhci_ring_type type, unsigned int max_packet, gfp_t flags); void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring); int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, unsigned int num_trbs, gfp_t flags); -void xhci_initialize_ring_info(struct xhci_ring *ring); +void xhci_initialize_ring_info(struct xhci_ring *ring, + unsigned int cycle_state); void xhci_free_endpoint_ring(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, unsigned int ep_index); -- 2.50.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: regression from 6.12.48 to 6.12.49: usb wlan adaptor stops working: bisected 2025-09-29 14:08 ` Neronin, Niklas @ 2025-09-29 17:53 ` Wolfgang Walter 0 siblings, 0 replies; 5+ messages in thread From: Wolfgang Walter @ 2025-09-29 17:53 UTC (permalink / raw) To: Neronin, Niklas; +Cc: Greg Kroah-Hartman, stable, Mathias Nyman Hello Niklas! Am 2025-09-29 16:08, schrieb Neronin, Niklas: > On 26/09/2025 18.54, Wolfgang Walter wrote: >> Hello,o >> after upgrading to 6.12.49 my wlan adapter stops working. It is >> detected: >> >> kernel: mt76x2u 4-2:1.0: ASIC revision: 76120044 >> kernel: mt76x2u 4-2:1.0: ROM patch build: 20141115060606a >> kernel: usb 3-4: reset high-speed USB device number 2 using xhci_hcd >> kernel: mt76x2u 4-2:1.0: Firmware Version: 0.0.00 >> kernel: mt76x2u 4-2:1.0: Build: 1 >> kernel: mt76x2u 4-2:1.0: Build Time: 201507311614____ >> >> but does nor work. The following 2 messages probably are relevant: >> >> kernel: mt76x2u 4-2:1.0: MAC RX failed to stop >> kernel: mt76x2u 4-2:1.0: MAC RX failed to stop >> >> later I see a lot of >> >> kernel: mt76x2u 4-2:1.0: error: mt76x02u_mcu_wait_resp failed with >> -110 >> >> >> I bisected it down to commit >> >> 9b28ef1e4cc07cdb35da257aa4358d0127168b68 >> usb: xhci: remove option to change a default ring's TRB cycle bit >> >> >> 9b28ef1e4cc07cdb35da257aa4358d0127168b68 is the first bad commit >> commit 9b28ef1e4cc07cdb35da257aa4358d0127168b68 >> Author: Niklas Neronin <niklas.neronin@linux.intel.com> >> Date: Wed Sep 17 08:39:07 2025 -0400 >> >> usb: xhci: remove option to change a default ring's TRB cycle bit >> >> [ Upstream commit e1b0fa863907a61e86acc19ce2d0633941907c8e ] >> >> The TRB cycle bit indicates TRB ownership by the Host Controller >> (HC) or >> Host Controller Driver (HCD). New rings are initialized with >> 'cycle_state' >> equal to one, and all its TRBs' cycle bits are set to zero. When >> handling >> ring expansion, set the source ring cycle bits to the same value >> as the >> destination ring. >> >> Move the cycle bit setting from xhci_segment_alloc() to >> xhci_link_rings(), >> and remove the 'cycle_state' argument from >> xhci_initialize_ring_info(). >> The xhci_segment_alloc() function uses kzalloc_node() to allocate >> segments, >> ensuring that all TRB cycle bits are initialized to zero. >> >> Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com> >> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> >> Link: >> https://lore.kernel.org/r/20241106101459.775897-12-mathias.nyman@linux.intel.com >> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> >> Stable-dep-of: a5c98e8b1398 ("xhci: dbc: Fix full DbC transfer >> ring after several reconnects") >> Signed-off-by: Sasha Levin <sashal@kernel.org> >> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> >> > > Hi, could you test if the code below helps? Yes, this fixes the issue. Thanks a lot. > > This reverts commit 9b28ef1e4cc0 ("usb: xhci: remove option to change a > default ring's TRB cycle bit") which is upstream [2]. > > The original commit was never intended for stable kernels, but was > added > as a dependency for commit [1]. > > Revert it, and solve the dependency by modifying one line in > xhci_dbc_ring_init(). The function call xhci_initialize_ring_info() > was moved in commit [1] into xhci_dbc_ring_init(). Thus, > xhci_initialize_ring_info() is also modified. > > [1], commit a5c98e8b1398 ("xhci: dbc: Fix full DbC transfer > ring after several reconnects") > > [2], commit e1b0fa863907 ("usb: xhci: remove option to change a > default ring's TRB cycle bit") > > Best Regards, > Niklas > > > diff --git a/drivers/usb/host/xhci-dbgcap.c > b/drivers/usb/host/xhci-dbgcap.c > index 1fcc9348dd43..123506681ef0 100644 > --- a/drivers/usb/host/xhci-dbgcap.c > +++ b/drivers/usb/host/xhci-dbgcap.c > @@ -458,7 +458,7 @@ static void xhci_dbc_ring_init(struct xhci_ring > *ring) > trb->link.segment_ptr = cpu_to_le64(ring->first_seg->dma); > trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK)); > } > - xhci_initialize_ring_info(ring); > + xhci_initialize_ring_info(ring, 1); > } > > static int xhci_dbc_reinit_ep_rings(struct xhci_dbc *dbc) > diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c > index c9694526b157..f0ed38da6a0c 100644 > --- a/drivers/usb/host/xhci-mem.c > +++ b/drivers/usb/host/xhci-mem.c > @@ -27,12 +27,14 @@ > * "All components of all Command and Transfer TRBs shall be > initialized to '0'" > */ > static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, > + unsigned int cycle_state, > unsigned int max_packet, > unsigned int num, > gfp_t flags) > { > struct xhci_segment *seg; > dma_addr_t dma; > + int i; > struct device *dev = xhci_to_hcd(xhci)->self.sysdev; > > seg = kzalloc_node(sizeof(*seg), flags, dev_to_node(dev)); > @@ -54,6 +56,11 @@ static struct xhci_segment > *xhci_segment_alloc(struct xhci_hcd *xhci, > return NULL; > } > } > + /* If the cycle state is 0, set the cycle bit to 1 for all the TRBs > */ > + if (cycle_state == 0) { > + for (i = 0; i < TRBS_PER_SEGMENT; i++) > + seg->trbs[i].link.control = cpu_to_le32(TRB_CYCLE); > + } > seg->num = num; > seg->dma = dma; > seg->next = NULL; > @@ -131,14 +138,6 @@ static void xhci_link_rings(struct xhci_hcd *xhci, > struct xhci_ring *ring, > > chain_links = xhci_link_chain_quirk(xhci, ring->type); > > - /* If the cycle state is 0, set the cycle bit to 1 for all the TRBs > */ > - if (ring->cycle_state == 0) { > - xhci_for_each_ring_seg(ring->first_seg, seg) { > - for (int i = 0; i < TRBS_PER_SEGMENT; i++) > - seg->trbs[i].link.control |= cpu_to_le32(TRB_CYCLE); > - } > - } > - > next = ring->enq_seg->next; > xhci_link_segments(ring->enq_seg, first, ring->type, chain_links); > xhci_link_segments(last, next, ring->type, chain_links); > @@ -288,7 +287,8 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct > xhci_ring *ring) > kfree(ring); > } > > -void xhci_initialize_ring_info(struct xhci_ring *ring) > +void xhci_initialize_ring_info(struct xhci_ring *ring, > + unsigned int cycle_state) > { > /* The ring is empty, so the enqueue pointer == dequeue pointer */ > ring->enqueue = ring->first_seg->trbs; > @@ -302,7 +302,7 @@ void xhci_initialize_ring_info(struct xhci_ring > *ring) > * New rings are initialized with cycle state equal to 1; if we are > * handling ring expansion, set the cycle state equal to the old > ring. > */ > - ring->cycle_state = 1; > + ring->cycle_state = cycle_state; > > /* > * Each segment has a link TRB, and leave an extra TRB for SW > @@ -317,6 +317,7 @@ static int xhci_alloc_segments_for_ring(struct > xhci_hcd *xhci, > struct xhci_segment **first, > struct xhci_segment **last, > unsigned int num_segs, > + unsigned int cycle_state, > enum xhci_ring_type type, > unsigned int max_packet, > gfp_t flags) > @@ -327,7 +328,7 @@ static int xhci_alloc_segments_for_ring(struct > xhci_hcd *xhci, > > chain_links = xhci_link_chain_quirk(xhci, type); > > - prev = xhci_segment_alloc(xhci, max_packet, num, flags); > + prev = xhci_segment_alloc(xhci, cycle_state, max_packet, num, flags); > if (!prev) > return -ENOMEM; > num++; > @@ -336,7 +337,8 @@ static int xhci_alloc_segments_for_ring(struct > xhci_hcd *xhci, > while (num < num_segs) { > struct xhci_segment *next; > > - next = xhci_segment_alloc(xhci, max_packet, num, flags); > + next = xhci_segment_alloc(xhci, cycle_state, max_packet, num, > + flags); > if (!next) > goto free_segments; > > @@ -361,8 +363,9 @@ static int xhci_alloc_segments_for_ring(struct > xhci_hcd *xhci, > * Set the end flag and the cycle toggle bit on the last segment. > * See section 4.9.1 and figures 15 and 16. > */ > -struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int > num_segs, > - enum xhci_ring_type type, unsigned int max_packet, gfp_t flags) > +struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, > + unsigned int num_segs, unsigned int cycle_state, > + enum xhci_ring_type type, unsigned int max_packet, gfp_t flags) > { > struct xhci_ring *ring; > int ret; > @@ -380,7 +383,7 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd > *xhci, unsigned int num_segs, > return ring; > > ret = xhci_alloc_segments_for_ring(xhci, &ring->first_seg, > &ring->last_seg, num_segs, > - type, max_packet, flags); > + cycle_state, type, max_packet, flags); > if (ret) > goto fail; > > @@ -390,7 +393,7 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd > *xhci, unsigned int num_segs, > ring->last_seg->trbs[TRBS_PER_SEGMENT - 1].link.control |= > cpu_to_le32(LINK_TOGGLE); > } > - xhci_initialize_ring_info(ring); > + xhci_initialize_ring_info(ring, cycle_state); > trace_xhci_ring_alloc(ring); > return ring; > > @@ -418,8 +421,8 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, > struct xhci_ring *ring, > struct xhci_segment *last; > int ret; > > - ret = xhci_alloc_segments_for_ring(xhci, &first, &last, num_new_segs, > ring->type, > - ring->bounce_buf_len, flags); > + ret = xhci_alloc_segments_for_ring(xhci, &first, &last, num_new_segs, > ring->cycle_state, > + ring->type, ring->bounce_buf_len, flags); > if (ret) > return -ENOMEM; > > @@ -629,7 +632,8 @@ struct xhci_stream_info > *xhci_alloc_stream_info(struct xhci_hcd *xhci, > > for (cur_stream = 1; cur_stream < num_streams; cur_stream++) { > stream_info->stream_rings[cur_stream] = > - xhci_ring_alloc(xhci, 2, TYPE_STREAM, max_packet, mem_flags); > + xhci_ring_alloc(xhci, 2, 1, TYPE_STREAM, max_packet, > + mem_flags); > cur_ring = stream_info->stream_rings[cur_stream]; > if (!cur_ring) > goto cleanup_rings; > @@ -970,7 +974,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, > int slot_id, > } > > /* Allocate endpoint 0 ring */ > - dev->eps[0].ring = xhci_ring_alloc(xhci, 2, TYPE_CTRL, 0, flags); > + dev->eps[0].ring = xhci_ring_alloc(xhci, 2, 1, TYPE_CTRL, 0, flags); > if (!dev->eps[0].ring) > goto fail; > > @@ -1453,7 +1457,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, > > /* Set up the endpoint ring */ > virt_dev->eps[ep_index].new_ring = > - xhci_ring_alloc(xhci, 2, ring_type, max_packet, mem_flags); > + xhci_ring_alloc(xhci, 2, 1, ring_type, max_packet, mem_flags); > if (!virt_dev->eps[ep_index].new_ring) > return -ENOMEM; > > @@ -2262,7 +2266,7 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, > unsigned int segs, gfp_t flags) > if (!ir) > return NULL; > > - ir->event_ring = xhci_ring_alloc(xhci, segs, TYPE_EVENT, 0, flags); > + ir->event_ring = xhci_ring_alloc(xhci, segs, 1, TYPE_EVENT, 0, > flags); > if (!ir->event_ring) { > xhci_warn(xhci, "Failed to allocate interrupter event ring\n"); > kfree(ir); > @@ -2468,7 +2472,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t > flags) > goto fail; > > /* Set up the command ring to have one segments for now. */ > - xhci->cmd_ring = xhci_ring_alloc(xhci, 1, TYPE_COMMAND, 0, flags); > + xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, 0, flags); > if (!xhci->cmd_ring) > goto fail; > xhci_dbg_trace(xhci, trace_xhci_dbg_init, > diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c > index 3970ec831b8c..abbf89e82d01 100644 > --- a/drivers/usb/host/xhci.c > +++ b/drivers/usb/host/xhci.c > @@ -769,7 +769,7 @@ static void xhci_clear_command_ring(struct xhci_hcd > *xhci) > seg->trbs[TRBS_PER_SEGMENT - 1].link.control &= > cpu_to_le32(~TRB_CYCLE); > } > > - xhci_initialize_ring_info(ring); > + xhci_initialize_ring_info(ring, 1); > /* > * Reset the hardware dequeue pointer. > * Yes, this will need to be re-written after resume, but we're > paranoid > diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h > index b2aeb444daaf..b4fa8e7e4376 100644 > --- a/drivers/usb/host/xhci.h > +++ b/drivers/usb/host/xhci.h > @@ -1803,12 +1803,14 @@ void xhci_slot_copy(struct xhci_hcd *xhci, > int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device > *virt_dev, > struct usb_device *udev, struct usb_host_endpoint *ep, > gfp_t mem_flags); > -struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int > num_segs, > +struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, > + unsigned int num_segs, unsigned int cycle_state, > enum xhci_ring_type type, unsigned int max_packet, gfp_t flags); > void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring); > int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, > unsigned int num_trbs, gfp_t flags); > -void xhci_initialize_ring_info(struct xhci_ring *ring); > +void xhci_initialize_ring_info(struct xhci_ring *ring, > + unsigned int cycle_state); > void xhci_free_endpoint_ring(struct xhci_hcd *xhci, > struct xhci_virt_device *virt_dev, > unsigned int ep_index); Regards, -- Wolfgang Walter Studierendenwerk München Oberbayern Anstalt des öffentlichen Rechts ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-09-30 17:57 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-09-26 15:54 regression from 6.12.48 to 6.12.49: usb wlan adaptor stops working: bisected Wolfgang Walter 2025-09-29 13:27 ` Greg Kroah-Hartman 2025-09-30 17:56 ` Wolfgang Walter 2025-09-29 14:08 ` Neronin, Niklas 2025-09-29 17:53 ` Wolfgang Walter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox