Re: [PATCH v5 2/3] media: uvcvideo: add UVC_QUIRK_CTRL_THROTTLE for fragile firmware

Jeffrey Hein
2026-04-10T00:02:01Z

Hi Michal,

Thanks for the detailed analysis.

> crash-6.17-stock-stress-20260330.log
> Empty file, not sure why included at all.

Sorry about that -- removed.

> Not sure why usb_set_interface() is called. Is this the start
> streaming case mentioned in some email? What was happening before?

Yes, this is the start-streaming path. The app (Google Meet via
browser) opens the video device, which triggers usb_set_interface()
to select the alt setting for the isochronous endpoint. The LPM
disable failure happens during that transition.

> It's suspicious that wBytesPerInterval of the endpoint is 8,
> wMaxPacket is 64 and URBs are 16 bytes.

Interesting find. I had not looked at the interrupt endpoint
descriptors closely.

> Would it be possible to repeat this test with the patch below?

Absolutely. I will apply your patch, rebuild xhci-hcd, reproduce
the crash with dynamic debug enabled (xhci_hcd +p, usbcore +p),
only the Kiyo connected, and grab dmesg via SSH during the crash.

The CI bot flagged a dts-bindings failure on v6 but all code checks
(compile, smatch, sparse, checkpatch) passed -- unrelated to the
UVC patches.

Will follow up with traces.

Thanks,
JP

On Thu, Apr 9, 2026 at 1:17 PM Michal Pecio <michal.pecio@gmail.com> wrote:
>
> On Thu, 9 Apr 2026 10:02:47 +0200, Michal Pecio wrote:
> > On Thu, 9 Apr 2026 08:45:17 +0200, Ricardo Ribalda wrote:
> > > A usb device shall not be able crash the whole USB host. I believe
> > > that you already captured some logs and the USB guys are looking
> > > into it. I'd really like to hear what they have to say after
> > > reviewing them.
> >
> > Sorry, I forgot about this bug. I will take a closer look at logs
> > later today.
>
> lsusb -v of identical(?) device is found here:
> http://linux-hardware.org/?probe=a1cd74d9ac&log=lsusb
>
> And I'm looking at the logs here:
> https://github.com/jphein/kiyo-xhci-fix/tree/main/kernel-patches/crash-evidence
>
> crash-6.17-stock-stress-20260330.log
> Empty file, not sure why included at all.
>
> crash-6.17-video-call-20260330.log
> No debug messages. At some point:
> Mar 30 10:00:52 katana kernel: usb 2-3.4: disable of device-initiated U1 failed.
> Mar 30 10:00:53 katana kernel: usb 2-3.4: Failed to set U2 timeout to 0x0,error code -110
> Mar 30 10:00:53 katana kernel: uvcvideo 2-3.4:1.1: usb_set_interface Failed to disable LPM
> Mar 30 10:00:54 katana kernel: usb 2-3.4: Failed to query (SET_CUR) UVC control 11 on unit 3: -71 (exp. 1).
> Mar 30 10:00:54 katana kernel: usb 2-3.4: Failed to query (SET_CUR) UVC control 11 on unit 3: -71 (exp. 1).
> Mar 30 10:00:54 katana kernel: usb 2-3.4: Failed to query (SET_CUR) UVC control 11 on unit 3: -71 (exp. 1).
>
> Not sure if the LPM thing is the cause or a symptom of general EP 0
> disfunction, as seen in subsequent EPROTO errors.
>
> Not sure why usb_set_interface() is called. Is this the start streaming
> case mentioned in some email? What was happening before?
>
> stall-6.17-stock-no-workarounds-20260330.log
> All sorts of repeating errors, including stall on EP1IN ("ep 2") which
> is supposedly isochronous and shouldn't. Clearly some broken state, not
> sure how things got there.
>
> stall-6.17-stress-during-call-20260330.log
> This is the most interesting one.
>
> The first slightly unusual thing is repeated unlinks on EP5IN (int),
> not sure why uvcvideo would do that, possibly result of the stess test.
> I know that such pattern alone can break ASMedia host controllers for
> no reason I understand, though this one is Intel.
>
> It's suspicious that wBytesPerInterval of the endpoint is 8, wMaxPacket
> is 64 and URBs are 16 bytes. Just in case, I attach a test patch which
> rises wBytesPerInterval to match wMaxPacketSize.
>
> The first definite anomaly is Transaction Error on EP5IN:
> Mar 30 16:59:16 katana kernel: xhci_hcd 0000:00:14.0: Transfer error for slot 18 ep 10 on endpoint
> Mar 30 16:59:16 katana kernel: xhci_hcd 0000:00:14.0: Hard-reset ep 10, slot 18
>
> Not sure why endpoint reset follows immediately without retries.
> The test patch also removes one potential reason. We might see whether
> the retries will fail, or if retrying until the transfer succeeds
> magically prevents the subsequent disaster. Perhaps the device gets
> unusually upset about sequence mismatch on this endpoint, which results
> from not clearing this halt condition properly (known problem).
>
> Five seconds later two control URBs are unlinked:
> Mar 30 16:59:21 katana kernel: xhci_hcd 0000:00:14.0: Cancel URB 00000000122aa5e2, dev 3.1, ep 0x0, starting at offset 0x11e227b40
> Mar 30 16:59:21 katana kernel: xhci_hcd 0000:00:14.0: // Ding dong!
> Mar 30 16:59:21 katana kernel: xhci_hcd 0000:00:14.0: Cancel URB 000000008a55bcd3, dev 3.1, ep 0x0, starting at offset 0x11e227b20
> Mar 30 16:59:21 katana kernel: xhci_hcd 0000:00:14.0: Not queuing Stop Endpoint on slot 18 ep 0 in state 0x44
>
> Probably timeout, i.e. things got stuck. Oddly, state 0x44 indicates
> that this control endpoint has previously halted - error or stall.
>
> Higher layers notice that things are timing out:
>
> Mar 30 16:59:21 katana kernel: usb 2-3.1: pipewire timed out on ep0out len=0/0
> Mar 30 16:59:21 katana kernel: usb 2-3.1: disable of device-initiated U1 failed.
> Mar 30 16:59:21 katana kernel: usb 2-3.1: ThreadPoolSingl timed out on ep0out len=0/1
>
> Nothing works from now. At some point the parent hub reports
> disconnection and reconnection. Still nothing works.
>
> ---
>
> Would it be possible to repeat this test with the patch below?
> It overrides the suspicious wBytesPerInterval and hopefully enables
> retries of this failed interrupt URB. We will see what happens.
>
> xhci-mem.c b/drivers/usb/host/xhci-mem.c
> index 1d50c91afd7f..17d78b4e07bf 100644
> --- a/drivers/usb/host/xhci-mem.c
> +++ b/drivers/usb/host/xhci-mem.c
> @@ -1464,6 +1464,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
> mult = xhci_get_endpoint_mult(xhci, udev, ep);
> max_packet = xhci_usb_endpoint_maxp(udev, ep);
> max_burst = xhci_get_endpoint_max_burst(udev, ep);
> + if (interval && max_esit_payload < max_packet) {
> + xhci_err(xhci, "max_esit_payload %d -> %d\n", max_esit_payload, max_packet);
> + max_esit_payload = max_packet;
> + }
> avg_trb_len = max_esit_payload;
>
> /* FIXME dig Mult and streams info out of ep companion desc */
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 98ef014c8dee..e5823650850a 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -2544,6 +2544,7 @@ static void process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
> td->status = 0;
> break;
> case COMP_SHORT_PACKET:
> + ep->err_count = 0;
> td->status = 0;
> break;
> case COMP_STOPPED_SHORT_PACKET:
>
>
>
>