* [PATCH] media: uvcvideo: Add quirk to retry SET_INTERFACE for SVBONY SV105C
@ 2026-10-19 11:07 Ostashow Constantine via B4 Relay
2026-10-19 11:17 ` Laurent Pinchart
0 siblings, 1 reply; 8+ messages in thread
From: Ostashow Constantine via B4 Relay @ 2026-10-19 11:07 UTC (permalink / raw)
To: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, stable, Ostashow Constantine
From: Ostashow Constantine <ostashow@gmail.com>
The SVBONY SV105C (0c45:636b, Sonix based) fails most SET_INTERFACE
requests that select a streaming alternate setting right after a
VS_COMMIT control. The request completes with -EPROTO, so
VIDIOC_STREAMON fails and capture applications see the camera
randomly failing to start.
A usbmon capture of a failing VIDIOC_STREAMON:
S Co:1:003:0 s 21 01 0200 0001 001a 26 = 01000104 15160500 ...
C Co:1:003:0 0 26 >
S Co:1:003:0 s 01 0b 0004 0001 0000 0
C Co:1:003:0 -71 0
S Co:1:003:0 s 01 0b 0000 0001 0000 0
C Co:1:003:0 0 0
The failure rate is around 80% and does not depend on the alternate
setting (alt 1, the smallest one with 128 bytes per microframe, fails
as often as alt 6), on a delay between VS_COMMIT and SET_INTERFACE
(0 to 100 ms tested), or on USB autosuspend. SET_INTERFACE without a
preceding VS_COMMIT succeeded 15 out of 15 times, and an immediate
retry after the -EPROTO failure succeeded 15 out of 15 times. Once
streaming has started, the camera works reliably. It also works with
the Windows UVC driver.
Add a UVC_QUIRK_RETRY_SET_INTERFACE quirk that retries SET_INTERFACE
up to three times when it fails with -EPROTO, and enable it for the
SV105C. With the quirk, 35 out of 35 stream starts succeeded, 29 of
them needed a retry, and no start needed more than one.
lsusb -v:
Bus 001 Device 003: ID 0c45:636b Microdia SVBONY SV105C
Negotiated speed: High Speed (480Mbps)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.01
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 [unknown]
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x0c45 Microdia
idProduct 0x636b SVBONY SV105C
bcdDevice 1.00
iManufacturer 2 Sonix Technology Co., Ltd.
iProduct 1 SVBONY SV105C
iSerial 3 SN0001
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x032e
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 14 Video
bFunctionSubClass 3 Video Interface Collection
bFunctionProtocol 0
iFunction 5
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 1 Video Control
bInterfaceProtocol 0
iInterface 5
VideoControl Interface Descriptor:
bLength 13
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdUVC 1.00
wTotalLength 0x0050
dwClockFrequency 15.000000MHz
bInCollection 1
baInterfaceNr( 0) 1
VideoControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 4
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 3
iTerminal 0
VideoControl Interface Descriptor:
bLength 29
bDescriptorType 36
bDescriptorSubtype 6 (EXTENSION_UNIT)
bUnitID 3
guidExtensionCode {28f03370-6311-4a2e-ba2c-6890eb334016}
bNumControls 32
bNrInPins 1
baSourceID( 0) 2
bControlSize 4
bmControls( 0) 0x9f
bmControls( 1) 0x07
bmControls( 2) 0x07
bmControls( 3) 0x07
iExtension 0
VideoControl Interface Descriptor:
bLength 18
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Camera Sensor
bAssocTerminal 0
iTerminal 0
wObjectiveFocalLengthMin 0
wObjectiveFocalLengthMax 0
wOcularFocalLength 0
bControlSize 3
bmControls 0x0000000e
Auto-Exposure Mode
Auto-Exposure Priority
Exposure Time (Absolute)
VideoControl Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 5 (PROCESSING_UNIT)
Warning: Descriptor too short
bUnitID 2
bSourceID 1
wMaxMultiplier 0
bControlSize 2
bmControls 0x0000177f
Brightness
Contrast
Hue
Saturation
Sharpness
Gamma
White Balance Temperature
Backlight Compensation
Gain
Power Line Frequency
White Balance Temperature, Auto
iProcessing 0
bmVideoStandards 0x31
None
NTSC - 625/50
PAL - 525/60
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0010 1x 16 bytes
bInterval 6
VideoControl Endpoint Descriptor:
bLength 5
bDescriptorType 37
bDescriptorSubtype 3 (EP_INTERRUPT)
wMaxTransferSize 128
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
VideoStreaming Interface Descriptor:
bLength 15
bDescriptorType 36
bDescriptorSubtype 1 (INPUT_HEADER)
bNumFormats 2
wTotalLength 0x024f
bEndpointAddress 0x81 EP 1 IN
bmInfo 0
bTerminalLink 4
bStillCaptureMethod 2
bTriggerSupport 1
bTriggerUsage 1
bControlSize 1
bmaControls( 0) 0
bmaControls( 1) 0
VideoStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 6 (FORMAT_MJPEG)
bFormatIndex 1
bNumFrameDescriptors 8
bFlags 0
Fixed-size samples: No
bDefaultFrameIndex 1
bAspectRatioX 0
bAspectRatioY 0
bmInterlaceFlags 0x00
Interlaced stream or variable: No
Fields per frame: 1 fields
Field 1 first: No
Field pattern: Field 1 only
bCopyProtect 0
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 1
bmCapabilities 0x00
Still image unsupported
wWidth 1920
wHeight 1080
dwMinBitRate 995328000
dwMaxBitRate 995328000
dwMaxVideoFrameBufferSize 4147789
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 2
bmCapabilities 0x00
Still image unsupported
wWidth 1280
wHeight 1024
dwMinBitRate 629145600
dwMaxBitRate 629145600
dwMaxVideoFrameBufferSize 2622029
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 3
bmCapabilities 0x00
Still image unsupported
wWidth 1280
wHeight 960
dwMinBitRate 589824000
dwMaxBitRate 589824000
dwMaxVideoFrameBufferSize 2458189
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 4
bmCapabilities 0x00
Still image unsupported
wWidth 1280
wHeight 720
dwMinBitRate 442368000
dwMaxBitRate 442368000
dwMaxVideoFrameBufferSize 1843789
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 5
bmCapabilities 0x00
Still image unsupported
wWidth 800
wHeight 600
dwMinBitRate 230400000
dwMaxBitRate 230400000
dwMaxVideoFrameBufferSize 960589
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 6
bmCapabilities 0x00
Still image unsupported
wWidth 640
wHeight 480
dwMinBitRate 147456000
dwMaxBitRate 147456000
dwMaxVideoFrameBufferSize 614989
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 7
bmCapabilities 0x00
Still image unsupported
wWidth 480
wHeight 640
dwMinBitRate 147456000
dwMaxBitRate 147456000
dwMaxVideoFrameBufferSize 614989
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 8
bmCapabilities 0x00
Still image unsupported
wWidth 1920
wHeight 1080
dwMinBitRate 995328000
dwMaxBitRate 995328000
dwMaxVideoFrameBufferSize 4147789
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 34
bDescriptorType 36
bDescriptorSubtype 3 (STILL_IMAGE_FRAME)
bEndpointAddress 0x00 EP 0 OUT
bNumImageSizePatterns 7
wWidth( 0) 1920
wHeight( 0) 1080
wWidth( 1) 1280
wHeight( 1) 720
wWidth( 2) 800
wHeight( 2) 600
wWidth( 3) 640
wHeight( 3) 480
wWidth( 4) 640
wHeight( 4) 360
wWidth( 5) 320
wHeight( 5) 240
wWidth( 6) 320
wHeight( 6) 180
bNumCompressionPatterns 0
VideoStreaming Interface Descriptor:
bLength 27
bDescriptorType 36
bDescriptorSubtype 4 (FORMAT_UNCOMPRESSED)
bFormatIndex 2
bNumFrameDescriptors 8
guidFormat {32595559-0000-0010-8000-00aa00389b71}
bBitsPerPixel 16
bDefaultFrameIndex 1
bAspectRatioX 0
bAspectRatioY 0
bmInterlaceFlags 0x00
Interlaced stream or variable: No
Fields per frame: 2 fields
Field 1 first: No
Field pattern: Field 1 only
bCopyProtect 0
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 1
bmCapabilities 0x00
Still image unsupported
wWidth 1920
wHeight 1080
dwMinBitRate 165888000
dwMaxBitRate 165888000
dwMaxVideoFrameBufferSize 4147200
dwDefaultFrameInterval 2000000
bFrameIntervalType 1
dwFrameInterval( 0) 2000000
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 2
bmCapabilities 0x00
Still image unsupported
wWidth 1280
wHeight 1024
dwMinBitRate 104857600
dwMaxBitRate 104857600
dwMaxVideoFrameBufferSize 2621440
dwDefaultFrameInterval 2000000
bFrameIntervalType 1
dwFrameInterval( 0) 2000000
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 3
bmCapabilities 0x00
Still image unsupported
wWidth 1280
wHeight 960
dwMinBitRate 98304000
dwMaxBitRate 98304000
dwMaxVideoFrameBufferSize 2457600
dwDefaultFrameInterval 2000000
bFrameIntervalType 1
dwFrameInterval( 0) 2000000
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 4
bmCapabilities 0x00
Still image unsupported
wWidth 1280
wHeight 720
dwMinBitRate 147456000
dwMaxBitRate 147456000
dwMaxVideoFrameBufferSize 1843200
dwDefaultFrameInterval 1000000
bFrameIntervalType 1
dwFrameInterval( 0) 1000000
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 5
bmCapabilities 0x00
Still image unsupported
wWidth 800
wHeight 600
dwMinBitRate 153600000
dwMaxBitRate 153600000
dwMaxVideoFrameBufferSize 960000
dwDefaultFrameInterval 500000
bFrameIntervalType 1
dwFrameInterval( 0) 500000
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 6
bmCapabilities 0x00
Still image unsupported
wWidth 640
wHeight 480
dwMinBitRate 147456000
dwMaxBitRate 147456000
dwMaxVideoFrameBufferSize 614400
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 7
bmCapabilities 0x00
Still image unsupported
wWidth 480
wHeight 640
dwMinBitRate 147456000
dwMaxBitRate 147456000
dwMaxVideoFrameBufferSize 614400
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 8
bmCapabilities 0x00
Still image unsupported
wWidth 1920
wHeight 1080
dwMinBitRate 165888000
dwMaxBitRate 165888000
dwMaxVideoFrameBufferSize 4147200
dwDefaultFrameInterval 2000000
bFrameIntervalType 1
dwFrameInterval( 0) 2000000
VideoStreaming Interface Descriptor:
bLength 18
bDescriptorType 36
bDescriptorSubtype 3 (STILL_IMAGE_FRAME)
bEndpointAddress 0x00 EP 0 OUT
bNumImageSizePatterns 3
wWidth( 0) 1920
wHeight( 0) 1080
wWidth( 1) 1280
wHeight( 1) 720
wWidth( 2) 640
wHeight( 2) 480
bNumCompressionPatterns 0
VideoStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 13 (COLORFORMAT)
bColorPrimaries 1 (BT.709,sRGB)
bTransferCharacteristics 1 (BT.709)
bMatrixCoefficients 4 (SMPTE 170M (BT.601))
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0080 1x 128 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 2
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0100 1x 256 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 3
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0320 1x 800 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 4
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0b20 2x 800 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 5
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x1320 3x 800 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 6
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x1400 3x 1024 bytes
bInterval 1
Cc: stable@vger.kernel.org
Assisted-by: claude-opus-5-5
Signed-off-by: Ostashow Constantine <ostashow@gmail.com>
---
Notes for reviewers (not part of the commit message):
Testing:
- Runtime-tested on a Raspberry Pi 4 (VL805 xHCI) running 6.18.57, with
this patch applied to the 6.18.57 uvcvideo sources (it applies with
line offsets only). Results are in the commit message. Before the
patch, 3/20 and 5/20 stream starts succeeded.
- Built with W=1 without new warnings: as part of the 6.18.57 module,
and the patched media/next sources against 6.18 headers plus the
media/next include/linux/usb/uvc.h.
- Not runtime-tested on media/next itself, and not tested on other host
controllers (e.g. x86 xHCI). I can't tell whether the failure depends
on the host controller.
Tool disclosure (Documentation/process/generated-content.rst):
The root-cause analysis (usbmon capture, libusb experiments varying the
alternate setting, the delay after VS_COMMIT and retries), the patch and
this changelog were produced by an AI coding assistant (Claude Code,
claude-opus-5-5) in an interactive session, at my request, on my
hardware. I have reviewed the patch and take responsibility for it.
---
drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++
drivers/media/usb/uvc/uvc_video.c | 14 ++++++++++++++
drivers/media/usb/uvc/uvcvideo.h | 1 +
3 files changed, 24 insertions(+)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index cbc145697..9e1f855cd 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2928,6 +2928,15 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_INFO_QUIRK(UVC_QUIRK_MJPEG_NO_EOF) },
+ /* SVBONY SV105C */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0c45,
+ .idProduct = 0x636b,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RETRY_SET_INTERFACE) },
/* MT6227 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index a92a986ab..3a3b1d1d7 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -2100,6 +2100,20 @@ static int uvc_video_start_transfer(struct uvc_streaming *stream,
}
ret = usb_set_interface(stream->dev->udev, intfnum, altsetting);
+
+ /*
+ * Some devices, namely the SVBONY SV105C, fail most of the
+ * SET_INTERFACE requests that follow a VS_COMMIT control with
+ * a protocol error. Retrying the request immediately succeeds.
+ */
+ for (i = 0; ret == -EPROTO && i < 3 &&
+ (stream->dev->quirks & UVC_QUIRK_RETRY_SET_INTERFACE); ++i) {
+ uvc_dbg(stream->dev, VIDEO,
+ "SET_INTERFACE failed (%d), retrying\n", ret);
+ ret = usb_set_interface(stream->dev->udev, intfnum,
+ altsetting);
+ }
+
if (ret < 0)
return ret;
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index af8cef94f..19851c3d2 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -81,6 +81,7 @@
#define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000
#define UVC_QUIRK_MJPEG_NO_EOF 0x00020000
#define UVC_QUIRK_MSXU_META 0x00040000
+#define UVC_QUIRK_RETRY_SET_INTERFACE 0x00080000
/* Format flags */
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
---
base-commit: d7e7bca7169873b46e857c025c10f3336c1258d8
change-id: 20261019-sv105c-retry-set-interface-759a92a1e7b5
Best regards,
--
Ostashow Constantine <ostashow@gmail.com>
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] media: uvcvideo: Add quirk to retry SET_INTERFACE for SVBONY SV105C
2026-10-19 11:07 [PATCH] media: uvcvideo: Add quirk to retry SET_INTERFACE for SVBONY SV105C Ostashow Constantine via B4 Relay
@ 2026-10-19 11:17 ` Laurent Pinchart
2026-10-19 11:21 ` Hans de Goede
0 siblings, 1 reply; 8+ messages in thread
From: Laurent Pinchart @ 2026-10-19 11:17 UTC (permalink / raw)
To: ostashow
Cc: Hans de Goede, Mauro Carvalho Chehab, linux-media, linux-kernel, stable
On Mon, Oct 19, 2026 at 02:07:28PM +0300, Ostashow Constantine via B4 Relay wrote:
> From: Ostashow Constantine <ostashow@gmail.com>
>
> The SVBONY SV105C (0c45:636b, Sonix based) fails most SET_INTERFACE
> requests that select a streaming alternate setting right after a
> VS_COMMIT control. The request completes with -EPROTO, so
> VIDIOC_STREAMON fails and capture applications see the camera
> randomly failing to start.
>
> A usbmon capture of a failing VIDIOC_STREAMON:
>
> S Co:1:003:0 s 21 01 0200 0001 001a 26 = 01000104 15160500 ...
> C Co:1:003:0 0 26 >
> S Co:1:003:0 s 01 0b 0004 0001 0000 0
> C Co:1:003:0 -71 0
> S Co:1:003:0 s 01 0b 0000 0001 0000 0
> C Co:1:003:0 0 0
>
> The failure rate is around 80% and does not depend on the alternate
> setting (alt 1, the smallest one with 128 bytes per microframe, fails
> as often as alt 6), on a delay between VS_COMMIT and SET_INTERFACE
> (0 to 100 ms tested), or on USB autosuspend. SET_INTERFACE without a
> preceding VS_COMMIT succeeded 15 out of 15 times, and an immediate
> retry after the -EPROTO failure succeeded 15 out of 15 times. Once
> streaming has started, the camera works reliably. It also works with
> the Windows UVC driver.
What does Windows do differently then ?
> Add a UVC_QUIRK_RETRY_SET_INTERFACE quirk that retries SET_INTERFACE
> up to three times when it fails with -EPROTO, and enable it for the
> SV105C. With the quirk, 35 out of 35 stream starts succeeded, 29 of
> them needed a retry, and no start needed more than one.
>
> lsusb -v:
>
> Bus 001 Device 003: ID 0c45:636b Microdia SVBONY SV105C
> Negotiated speed: High Speed (480Mbps)
> Device Descriptor:
> bLength 18
> bDescriptorType 1
> bcdUSB 2.01
> bDeviceClass 239 Miscellaneous Device
> bDeviceSubClass 2 [unknown]
> bDeviceProtocol 1 Interface Association
> bMaxPacketSize0 64
> idVendor 0x0c45 Microdia
> idProduct 0x636b SVBONY SV105C
> bcdDevice 1.00
> iManufacturer 2 Sonix Technology Co., Ltd.
> iProduct 1 SVBONY SV105C
> iSerial 3 SN0001
> bNumConfigurations 1
> Configuration Descriptor:
> bLength 9
> bDescriptorType 2
> wTotalLength 0x032e
> bNumInterfaces 2
> bConfigurationValue 1
> iConfiguration 0
> bmAttributes 0x80
> (Bus Powered)
> MaxPower 500mA
> Interface Association:
> bLength 8
> bDescriptorType 11
> bFirstInterface 0
> bInterfaceCount 2
> bFunctionClass 14 Video
> bFunctionSubClass 3 Video Interface Collection
> bFunctionProtocol 0
> iFunction 5
> Interface Descriptor:
> bLength 9
> bDescriptorType 4
> bInterfaceNumber 0
> bAlternateSetting 0
> bNumEndpoints 1
> bInterfaceClass 14 Video
> bInterfaceSubClass 1 Video Control
> bInterfaceProtocol 0
> iInterface 5
> VideoControl Interface Descriptor:
> bLength 13
> bDescriptorType 36
> bDescriptorSubtype 1 (HEADER)
> bcdUVC 1.00
> wTotalLength 0x0050
> dwClockFrequency 15.000000MHz
> bInCollection 1
> baInterfaceNr( 0) 1
> VideoControl Interface Descriptor:
> bLength 9
> bDescriptorType 36
> bDescriptorSubtype 3 (OUTPUT_TERMINAL)
> bTerminalID 4
> wTerminalType 0x0101 USB Streaming
> bAssocTerminal 0
> bSourceID 3
> iTerminal 0
> VideoControl Interface Descriptor:
> bLength 29
> bDescriptorType 36
> bDescriptorSubtype 6 (EXTENSION_UNIT)
> bUnitID 3
> guidExtensionCode {28f03370-6311-4a2e-ba2c-6890eb334016}
> bNumControls 32
> bNrInPins 1
> baSourceID( 0) 2
> bControlSize 4
> bmControls( 0) 0x9f
> bmControls( 1) 0x07
> bmControls( 2) 0x07
> bmControls( 3) 0x07
> iExtension 0
> VideoControl Interface Descriptor:
> bLength 18
> bDescriptorType 36
> bDescriptorSubtype 2 (INPUT_TERMINAL)
> bTerminalID 1
> wTerminalType 0x0201 Camera Sensor
> bAssocTerminal 0
> iTerminal 0
> wObjectiveFocalLengthMin 0
> wObjectiveFocalLengthMax 0
> wOcularFocalLength 0
> bControlSize 3
> bmControls 0x0000000e
> Auto-Exposure Mode
> Auto-Exposure Priority
> Exposure Time (Absolute)
> VideoControl Interface Descriptor:
> bLength 11
> bDescriptorType 36
> bDescriptorSubtype 5 (PROCESSING_UNIT)
> Warning: Descriptor too short
> bUnitID 2
> bSourceID 1
> wMaxMultiplier 0
> bControlSize 2
> bmControls 0x0000177f
> Brightness
> Contrast
> Hue
> Saturation
> Sharpness
> Gamma
> White Balance Temperature
> Backlight Compensation
> Gain
> Power Line Frequency
> White Balance Temperature, Auto
> iProcessing 0
> bmVideoStandards 0x31
> None
> NTSC - 625/50
> PAL - 525/60
> Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x83 EP 3 IN
> bmAttributes 3
> Transfer Type Interrupt
> Synch Type None
> Usage Type Data
> wMaxPacketSize 0x0010 1x 16 bytes
> bInterval 6
> VideoControl Endpoint Descriptor:
> bLength 5
> bDescriptorType 37
> bDescriptorSubtype 3 (EP_INTERRUPT)
> wMaxTransferSize 128
> Interface Descriptor:
> bLength 9
> bDescriptorType 4
> bInterfaceNumber 1
> bAlternateSetting 0
> bNumEndpoints 0
> bInterfaceClass 14 Video
> bInterfaceSubClass 2 Video Streaming
> bInterfaceProtocol 0
> iInterface 0
> VideoStreaming Interface Descriptor:
> bLength 15
> bDescriptorType 36
> bDescriptorSubtype 1 (INPUT_HEADER)
> bNumFormats 2
> wTotalLength 0x024f
> bEndpointAddress 0x81 EP 1 IN
> bmInfo 0
> bTerminalLink 4
> bStillCaptureMethod 2
> bTriggerSupport 1
> bTriggerUsage 1
> bControlSize 1
> bmaControls( 0) 0
> bmaControls( 1) 0
> VideoStreaming Interface Descriptor:
> bLength 11
> bDescriptorType 36
> bDescriptorSubtype 6 (FORMAT_MJPEG)
> bFormatIndex 1
> bNumFrameDescriptors 8
> bFlags 0
> Fixed-size samples: No
> bDefaultFrameIndex 1
> bAspectRatioX 0
> bAspectRatioY 0
> bmInterlaceFlags 0x00
> Interlaced stream or variable: No
> Fields per frame: 1 fields
> Field 1 first: No
> Field pattern: Field 1 only
> bCopyProtect 0
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 7 (FRAME_MJPEG)
> bFrameIndex 1
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1920
> wHeight 1080
> dwMinBitRate 995328000
> dwMaxBitRate 995328000
> dwMaxVideoFrameBufferSize 4147789
> dwDefaultFrameInterval 333333
> bFrameIntervalType 1
> dwFrameInterval( 0) 333333
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 7 (FRAME_MJPEG)
> bFrameIndex 2
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1280
> wHeight 1024
> dwMinBitRate 629145600
> dwMaxBitRate 629145600
> dwMaxVideoFrameBufferSize 2622029
> dwDefaultFrameInterval 333333
> bFrameIntervalType 1
> dwFrameInterval( 0) 333333
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 7 (FRAME_MJPEG)
> bFrameIndex 3
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1280
> wHeight 960
> dwMinBitRate 589824000
> dwMaxBitRate 589824000
> dwMaxVideoFrameBufferSize 2458189
> dwDefaultFrameInterval 333333
> bFrameIntervalType 1
> dwFrameInterval( 0) 333333
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 7 (FRAME_MJPEG)
> bFrameIndex 4
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1280
> wHeight 720
> dwMinBitRate 442368000
> dwMaxBitRate 442368000
> dwMaxVideoFrameBufferSize 1843789
> dwDefaultFrameInterval 333333
> bFrameIntervalType 1
> dwFrameInterval( 0) 333333
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 7 (FRAME_MJPEG)
> bFrameIndex 5
> bmCapabilities 0x00
> Still image unsupported
> wWidth 800
> wHeight 600
> dwMinBitRate 230400000
> dwMaxBitRate 230400000
> dwMaxVideoFrameBufferSize 960589
> dwDefaultFrameInterval 333333
> bFrameIntervalType 1
> dwFrameInterval( 0) 333333
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 7 (FRAME_MJPEG)
> bFrameIndex 6
> bmCapabilities 0x00
> Still image unsupported
> wWidth 640
> wHeight 480
> dwMinBitRate 147456000
> dwMaxBitRate 147456000
> dwMaxVideoFrameBufferSize 614989
> dwDefaultFrameInterval 333333
> bFrameIntervalType 1
> dwFrameInterval( 0) 333333
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 7 (FRAME_MJPEG)
> bFrameIndex 7
> bmCapabilities 0x00
> Still image unsupported
> wWidth 480
> wHeight 640
> dwMinBitRate 147456000
> dwMaxBitRate 147456000
> dwMaxVideoFrameBufferSize 614989
> dwDefaultFrameInterval 333333
> bFrameIntervalType 1
> dwFrameInterval( 0) 333333
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 7 (FRAME_MJPEG)
> bFrameIndex 8
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1920
> wHeight 1080
> dwMinBitRate 995328000
> dwMaxBitRate 995328000
> dwMaxVideoFrameBufferSize 4147789
> dwDefaultFrameInterval 333333
> bFrameIntervalType 1
> dwFrameInterval( 0) 333333
> VideoStreaming Interface Descriptor:
> bLength 34
> bDescriptorType 36
> bDescriptorSubtype 3 (STILL_IMAGE_FRAME)
> bEndpointAddress 0x00 EP 0 OUT
> bNumImageSizePatterns 7
> wWidth( 0) 1920
> wHeight( 0) 1080
> wWidth( 1) 1280
> wHeight( 1) 720
> wWidth( 2) 800
> wHeight( 2) 600
> wWidth( 3) 640
> wHeight( 3) 480
> wWidth( 4) 640
> wHeight( 4) 360
> wWidth( 5) 320
> wHeight( 5) 240
> wWidth( 6) 320
> wHeight( 6) 180
> bNumCompressionPatterns 0
> VideoStreaming Interface Descriptor:
> bLength 27
> bDescriptorType 36
> bDescriptorSubtype 4 (FORMAT_UNCOMPRESSED)
> bFormatIndex 2
> bNumFrameDescriptors 8
> guidFormat {32595559-0000-0010-8000-00aa00389b71}
> bBitsPerPixel 16
> bDefaultFrameIndex 1
> bAspectRatioX 0
> bAspectRatioY 0
> bmInterlaceFlags 0x00
> Interlaced stream or variable: No
> Fields per frame: 2 fields
> Field 1 first: No
> Field pattern: Field 1 only
> bCopyProtect 0
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> bFrameIndex 1
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1920
> wHeight 1080
> dwMinBitRate 165888000
> dwMaxBitRate 165888000
> dwMaxVideoFrameBufferSize 4147200
> dwDefaultFrameInterval 2000000
> bFrameIntervalType 1
> dwFrameInterval( 0) 2000000
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> bFrameIndex 2
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1280
> wHeight 1024
> dwMinBitRate 104857600
> dwMaxBitRate 104857600
> dwMaxVideoFrameBufferSize 2621440
> dwDefaultFrameInterval 2000000
> bFrameIntervalType 1
> dwFrameInterval( 0) 2000000
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> bFrameIndex 3
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1280
> wHeight 960
> dwMinBitRate 98304000
> dwMaxBitRate 98304000
> dwMaxVideoFrameBufferSize 2457600
> dwDefaultFrameInterval 2000000
> bFrameIntervalType 1
> dwFrameInterval( 0) 2000000
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> bFrameIndex 4
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1280
> wHeight 720
> dwMinBitRate 147456000
> dwMaxBitRate 147456000
> dwMaxVideoFrameBufferSize 1843200
> dwDefaultFrameInterval 1000000
> bFrameIntervalType 1
> dwFrameInterval( 0) 1000000
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> bFrameIndex 5
> bmCapabilities 0x00
> Still image unsupported
> wWidth 800
> wHeight 600
> dwMinBitRate 153600000
> dwMaxBitRate 153600000
> dwMaxVideoFrameBufferSize 960000
> dwDefaultFrameInterval 500000
> bFrameIntervalType 1
> dwFrameInterval( 0) 500000
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> bFrameIndex 6
> bmCapabilities 0x00
> Still image unsupported
> wWidth 640
> wHeight 480
> dwMinBitRate 147456000
> dwMaxBitRate 147456000
> dwMaxVideoFrameBufferSize 614400
> dwDefaultFrameInterval 333333
> bFrameIntervalType 1
> dwFrameInterval( 0) 333333
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> bFrameIndex 7
> bmCapabilities 0x00
> Still image unsupported
> wWidth 480
> wHeight 640
> dwMinBitRate 147456000
> dwMaxBitRate 147456000
> dwMaxVideoFrameBufferSize 614400
> dwDefaultFrameInterval 333333
> bFrameIntervalType 1
> dwFrameInterval( 0) 333333
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> bFrameIndex 8
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1920
> wHeight 1080
> dwMinBitRate 165888000
> dwMaxBitRate 165888000
> dwMaxVideoFrameBufferSize 4147200
> dwDefaultFrameInterval 2000000
> bFrameIntervalType 1
> dwFrameInterval( 0) 2000000
> VideoStreaming Interface Descriptor:
> bLength 18
> bDescriptorType 36
> bDescriptorSubtype 3 (STILL_IMAGE_FRAME)
> bEndpointAddress 0x00 EP 0 OUT
> bNumImageSizePatterns 3
> wWidth( 0) 1920
> wHeight( 0) 1080
> wWidth( 1) 1280
> wHeight( 1) 720
> wWidth( 2) 640
> wHeight( 2) 480
> bNumCompressionPatterns 0
> VideoStreaming Interface Descriptor:
> bLength 6
> bDescriptorType 36
> bDescriptorSubtype 13 (COLORFORMAT)
> bColorPrimaries 1 (BT.709,sRGB)
> bTransferCharacteristics 1 (BT.709)
> bMatrixCoefficients 4 (SMPTE 170M (BT.601))
> Interface Descriptor:
> bLength 9
> bDescriptorType 4
> bInterfaceNumber 1
> bAlternateSetting 1
> bNumEndpoints 1
> bInterfaceClass 14 Video
> bInterfaceSubClass 2 Video Streaming
> bInterfaceProtocol 0
> iInterface 0
> Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x81 EP 1 IN
> bmAttributes 5
> Transfer Type Isochronous
> Synch Type Asynchronous
> Usage Type Data
> wMaxPacketSize 0x0080 1x 128 bytes
> bInterval 1
> Interface Descriptor:
> bLength 9
> bDescriptorType 4
> bInterfaceNumber 1
> bAlternateSetting 2
> bNumEndpoints 1
> bInterfaceClass 14 Video
> bInterfaceSubClass 2 Video Streaming
> bInterfaceProtocol 0
> iInterface 0
> Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x81 EP 1 IN
> bmAttributes 5
> Transfer Type Isochronous
> Synch Type Asynchronous
> Usage Type Data
> wMaxPacketSize 0x0100 1x 256 bytes
> bInterval 1
> Interface Descriptor:
> bLength 9
> bDescriptorType 4
> bInterfaceNumber 1
> bAlternateSetting 3
> bNumEndpoints 1
> bInterfaceClass 14 Video
> bInterfaceSubClass 2 Video Streaming
> bInterfaceProtocol 0
> iInterface 0
> Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x81 EP 1 IN
> bmAttributes 5
> Transfer Type Isochronous
> Synch Type Asynchronous
> Usage Type Data
> wMaxPacketSize 0x0320 1x 800 bytes
> bInterval 1
> Interface Descriptor:
> bLength 9
> bDescriptorType 4
> bInterfaceNumber 1
> bAlternateSetting 4
> bNumEndpoints 1
> bInterfaceClass 14 Video
> bInterfaceSubClass 2 Video Streaming
> bInterfaceProtocol 0
> iInterface 0
> Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x81 EP 1 IN
> bmAttributes 5
> Transfer Type Isochronous
> Synch Type Asynchronous
> Usage Type Data
> wMaxPacketSize 0x0b20 2x 800 bytes
> bInterval 1
> Interface Descriptor:
> bLength 9
> bDescriptorType 4
> bInterfaceNumber 1
> bAlternateSetting 5
> bNumEndpoints 1
> bInterfaceClass 14 Video
> bInterfaceSubClass 2 Video Streaming
> bInterfaceProtocol 0
> iInterface 0
> Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x81 EP 1 IN
> bmAttributes 5
> Transfer Type Isochronous
> Synch Type Asynchronous
> Usage Type Data
> wMaxPacketSize 0x1320 3x 800 bytes
> bInterval 1
> Interface Descriptor:
> bLength 9
> bDescriptorType 4
> bInterfaceNumber 1
> bAlternateSetting 6
> bNumEndpoints 1
> bInterfaceClass 14 Video
> bInterfaceSubClass 2 Video Streaming
> bInterfaceProtocol 0
> iInterface 0
> Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x81 EP 1 IN
> bmAttributes 5
> Transfer Type Isochronous
> Synch Type Asynchronous
> Usage Type Data
> wMaxPacketSize 0x1400 3x 1024 bytes
> bInterval 1
>
> Cc: stable@vger.kernel.org
> Assisted-by: claude-opus-5-5
> Signed-off-by: Ostashow Constantine <ostashow@gmail.com>
> ---
> Notes for reviewers (not part of the commit message):
>
> Testing:
> - Runtime-tested on a Raspberry Pi 4 (VL805 xHCI) running 6.18.57, with
> this patch applied to the 6.18.57 uvcvideo sources (it applies with
> line offsets only). Results are in the commit message. Before the
> patch, 3/20 and 5/20 stream starts succeeded.
> - Built with W=1 without new warnings: as part of the 6.18.57 module,
> and the patched media/next sources against 6.18 headers plus the
> media/next include/linux/usb/uvc.h.
> - Not runtime-tested on media/next itself, and not tested on other host
> controllers (e.g. x86 xHCI). I can't tell whether the failure depends
> on the host controller.
>
> Tool disclosure (Documentation/process/generated-content.rst):
> The root-cause analysis (usbmon capture, libusb experiments varying the
> alternate setting, the delay after VS_COMMIT and retries), the patch and
> this changelog were produced by an AI coding assistant (Claude Code,
> claude-opus-5-5) in an interactive session, at my request, on my
> hardware. I have reviewed the patch and take responsibility for it.
> ---
> drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++
> drivers/media/usb/uvc/uvc_video.c | 14 ++++++++++++++
> drivers/media/usb/uvc/uvcvideo.h | 1 +
> 3 files changed, 24 insertions(+)
>
> diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
> index cbc145697..9e1f855cd 100644
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -2928,6 +2928,15 @@ static const struct usb_device_id uvc_ids[] = {
> .bInterfaceSubClass = 1,
> .bInterfaceProtocol = 0,
> .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_MJPEG_NO_EOF) },
> + /* SVBONY SV105C */
> + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
> + | USB_DEVICE_ID_MATCH_INT_INFO,
> + .idVendor = 0x0c45,
> + .idProduct = 0x636b,
> + .bInterfaceClass = USB_CLASS_VIDEO,
> + .bInterfaceSubClass = 1,
> + .bInterfaceProtocol = 0,
> + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RETRY_SET_INTERFACE) },
> /* MT6227 */
> { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
> | USB_DEVICE_ID_MATCH_INT_INFO,
> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
> index a92a986ab..3a3b1d1d7 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -2100,6 +2100,20 @@ static int uvc_video_start_transfer(struct uvc_streaming *stream,
> }
>
> ret = usb_set_interface(stream->dev->udev, intfnum, altsetting);
> +
> + /*
> + * Some devices, namely the SVBONY SV105C, fail most of the
> + * SET_INTERFACE requests that follow a VS_COMMIT control with
> + * a protocol error. Retrying the request immediately succeeds.
> + */
> + for (i = 0; ret == -EPROTO && i < 3 &&
> + (stream->dev->quirks & UVC_QUIRK_RETRY_SET_INTERFACE); ++i) {
> + uvc_dbg(stream->dev, VIDEO,
> + "SET_INTERFACE failed (%d), retrying\n", ret);
> + ret = usb_set_interface(stream->dev->udev, intfnum,
> + altsetting);
> + }
> +
> if (ret < 0)
> return ret;
>
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index af8cef94f..19851c3d2 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -81,6 +81,7 @@
> #define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000
> #define UVC_QUIRK_MJPEG_NO_EOF 0x00020000
> #define UVC_QUIRK_MSXU_META 0x00040000
> +#define UVC_QUIRK_RETRY_SET_INTERFACE 0x00080000
>
> /* Format flags */
> #define UVC_FMT_FLAG_COMPRESSED 0x00000001
>
> ---
> base-commit: d7e7bca7169873b46e857c025c10f3336c1258d8
> change-id: 20261019-sv105c-retry-set-interface-759a92a1e7b5
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] media: uvcvideo: Add quirk to retry SET_INTERFACE for SVBONY SV105C
2026-10-19 11:17 ` Laurent Pinchart
@ 2026-10-19 11:21 ` Hans de Goede
2026-10-19 11:27 ` Laurent Pinchart
0 siblings, 1 reply; 8+ messages in thread
From: Hans de Goede @ 2026-10-19 11:21 UTC (permalink / raw)
To: Laurent Pinchart, ostashow
Cc: Mauro Carvalho Chehab, linux-media, linux-kernel, stable
Hi,
On 19-Oct-26 1:17 PM, Laurent Pinchart wrote:
> On Mon, Oct 19, 2026 at 02:07:28PM +0300, Ostashow Constantine via B4 Relay wrote:
>> From: Ostashow Constantine <ostashow@gmail.com>
>>
>> The SVBONY SV105C (0c45:636b, Sonix based) fails most SET_INTERFACE
>> requests that select a streaming alternate setting right after a
>> VS_COMMIT control. The request completes with -EPROTO, so
>> VIDIOC_STREAMON fails and capture applications see the camera
>> randomly failing to start.
>>
>> A usbmon capture of a failing VIDIOC_STREAMON:
>>
>> S Co:1:003:0 s 21 01 0200 0001 001a 26 = 01000104 15160500 ...
>> C Co:1:003:0 0 26 >
>> S Co:1:003:0 s 01 0b 0004 0001 0000 0
>> C Co:1:003:0 -71 0
>> S Co:1:003:0 s 01 0b 0000 0001 0000 0
>> C Co:1:003:0 0 0
>>
>> The failure rate is around 80% and does not depend on the alternate
>> setting (alt 1, the smallest one with 128 bytes per microframe, fails
>> as often as alt 6), on a delay between VS_COMMIT and SET_INTERFACE
>> (0 to 100 ms tested), or on USB autosuspend. SET_INTERFACE without a
>> preceding VS_COMMIT succeeded 15 out of 15 times, and an immediate
>> retry after the -EPROTO failure succeeded 15 out of 15 times. Once
>> streaming has started, the camera works reliably. It also works with
>> the Windows UVC driver.
>
> What does Windows do differently then ?
I guess Windows always has a short-delay of at least one USB frame-time
between the VS_COMMIT and SET_INTERFACE. I think we should simply add
a flseep(1000) before the set_interface instead of adding a quirk for
this.
Regards,
Hans
>
>> Add a UVC_QUIRK_RETRY_SET_INTERFACE quirk that retries SET_INTERFACE
>> up to three times when it fails with -EPROTO, and enable it for the
>> SV105C. With the quirk, 35 out of 35 stream starts succeeded, 29 of
>> them needed a retry, and no start needed more than one.
>>
>> lsusb -v:
>>
>> Bus 001 Device 003: ID 0c45:636b Microdia SVBONY SV105C
>> Negotiated speed: High Speed (480Mbps)
>> Device Descriptor:
>> bLength 18
>> bDescriptorType 1
>> bcdUSB 2.01
>> bDeviceClass 239 Miscellaneous Device
>> bDeviceSubClass 2 [unknown]
>> bDeviceProtocol 1 Interface Association
>> bMaxPacketSize0 64
>> idVendor 0x0c45 Microdia
>> idProduct 0x636b SVBONY SV105C
>> bcdDevice 1.00
>> iManufacturer 2 Sonix Technology Co., Ltd.
>> iProduct 1 SVBONY SV105C
>> iSerial 3 SN0001
>> bNumConfigurations 1
>> Configuration Descriptor:
>> bLength 9
>> bDescriptorType 2
>> wTotalLength 0x032e
>> bNumInterfaces 2
>> bConfigurationValue 1
>> iConfiguration 0
>> bmAttributes 0x80
>> (Bus Powered)
>> MaxPower 500mA
>> Interface Association:
>> bLength 8
>> bDescriptorType 11
>> bFirstInterface 0
>> bInterfaceCount 2
>> bFunctionClass 14 Video
>> bFunctionSubClass 3 Video Interface Collection
>> bFunctionProtocol 0
>> iFunction 5
>> Interface Descriptor:
>> bLength 9
>> bDescriptorType 4
>> bInterfaceNumber 0
>> bAlternateSetting 0
>> bNumEndpoints 1
>> bInterfaceClass 14 Video
>> bInterfaceSubClass 1 Video Control
>> bInterfaceProtocol 0
>> iInterface 5
>> VideoControl Interface Descriptor:
>> bLength 13
>> bDescriptorType 36
>> bDescriptorSubtype 1 (HEADER)
>> bcdUVC 1.00
>> wTotalLength 0x0050
>> dwClockFrequency 15.000000MHz
>> bInCollection 1
>> baInterfaceNr( 0) 1
>> VideoControl Interface Descriptor:
>> bLength 9
>> bDescriptorType 36
>> bDescriptorSubtype 3 (OUTPUT_TERMINAL)
>> bTerminalID 4
>> wTerminalType 0x0101 USB Streaming
>> bAssocTerminal 0
>> bSourceID 3
>> iTerminal 0
>> VideoControl Interface Descriptor:
>> bLength 29
>> bDescriptorType 36
>> bDescriptorSubtype 6 (EXTENSION_UNIT)
>> bUnitID 3
>> guidExtensionCode {28f03370-6311-4a2e-ba2c-6890eb334016}
>> bNumControls 32
>> bNrInPins 1
>> baSourceID( 0) 2
>> bControlSize 4
>> bmControls( 0) 0x9f
>> bmControls( 1) 0x07
>> bmControls( 2) 0x07
>> bmControls( 3) 0x07
>> iExtension 0
>> VideoControl Interface Descriptor:
>> bLength 18
>> bDescriptorType 36
>> bDescriptorSubtype 2 (INPUT_TERMINAL)
>> bTerminalID 1
>> wTerminalType 0x0201 Camera Sensor
>> bAssocTerminal 0
>> iTerminal 0
>> wObjectiveFocalLengthMin 0
>> wObjectiveFocalLengthMax 0
>> wOcularFocalLength 0
>> bControlSize 3
>> bmControls 0x0000000e
>> Auto-Exposure Mode
>> Auto-Exposure Priority
>> Exposure Time (Absolute)
>> VideoControl Interface Descriptor:
>> bLength 11
>> bDescriptorType 36
>> bDescriptorSubtype 5 (PROCESSING_UNIT)
>> Warning: Descriptor too short
>> bUnitID 2
>> bSourceID 1
>> wMaxMultiplier 0
>> bControlSize 2
>> bmControls 0x0000177f
>> Brightness
>> Contrast
>> Hue
>> Saturation
>> Sharpness
>> Gamma
>> White Balance Temperature
>> Backlight Compensation
>> Gain
>> Power Line Frequency
>> White Balance Temperature, Auto
>> iProcessing 0
>> bmVideoStandards 0x31
>> None
>> NTSC - 625/50
>> PAL - 525/60
>> Endpoint Descriptor:
>> bLength 7
>> bDescriptorType 5
>> bEndpointAddress 0x83 EP 3 IN
>> bmAttributes 3
>> Transfer Type Interrupt
>> Synch Type None
>> Usage Type Data
>> wMaxPacketSize 0x0010 1x 16 bytes
>> bInterval 6
>> VideoControl Endpoint Descriptor:
>> bLength 5
>> bDescriptorType 37
>> bDescriptorSubtype 3 (EP_INTERRUPT)
>> wMaxTransferSize 128
>> Interface Descriptor:
>> bLength 9
>> bDescriptorType 4
>> bInterfaceNumber 1
>> bAlternateSetting 0
>> bNumEndpoints 0
>> bInterfaceClass 14 Video
>> bInterfaceSubClass 2 Video Streaming
>> bInterfaceProtocol 0
>> iInterface 0
>> VideoStreaming Interface Descriptor:
>> bLength 15
>> bDescriptorType 36
>> bDescriptorSubtype 1 (INPUT_HEADER)
>> bNumFormats 2
>> wTotalLength 0x024f
>> bEndpointAddress 0x81 EP 1 IN
>> bmInfo 0
>> bTerminalLink 4
>> bStillCaptureMethod 2
>> bTriggerSupport 1
>> bTriggerUsage 1
>> bControlSize 1
>> bmaControls( 0) 0
>> bmaControls( 1) 0
>> VideoStreaming Interface Descriptor:
>> bLength 11
>> bDescriptorType 36
>> bDescriptorSubtype 6 (FORMAT_MJPEG)
>> bFormatIndex 1
>> bNumFrameDescriptors 8
>> bFlags 0
>> Fixed-size samples: No
>> bDefaultFrameIndex 1
>> bAspectRatioX 0
>> bAspectRatioY 0
>> bmInterlaceFlags 0x00
>> Interlaced stream or variable: No
>> Fields per frame: 1 fields
>> Field 1 first: No
>> Field pattern: Field 1 only
>> bCopyProtect 0
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 7 (FRAME_MJPEG)
>> bFrameIndex 1
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 1920
>> wHeight 1080
>> dwMinBitRate 995328000
>> dwMaxBitRate 995328000
>> dwMaxVideoFrameBufferSize 4147789
>> dwDefaultFrameInterval 333333
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 333333
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 7 (FRAME_MJPEG)
>> bFrameIndex 2
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 1280
>> wHeight 1024
>> dwMinBitRate 629145600
>> dwMaxBitRate 629145600
>> dwMaxVideoFrameBufferSize 2622029
>> dwDefaultFrameInterval 333333
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 333333
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 7 (FRAME_MJPEG)
>> bFrameIndex 3
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 1280
>> wHeight 960
>> dwMinBitRate 589824000
>> dwMaxBitRate 589824000
>> dwMaxVideoFrameBufferSize 2458189
>> dwDefaultFrameInterval 333333
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 333333
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 7 (FRAME_MJPEG)
>> bFrameIndex 4
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 1280
>> wHeight 720
>> dwMinBitRate 442368000
>> dwMaxBitRate 442368000
>> dwMaxVideoFrameBufferSize 1843789
>> dwDefaultFrameInterval 333333
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 333333
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 7 (FRAME_MJPEG)
>> bFrameIndex 5
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 800
>> wHeight 600
>> dwMinBitRate 230400000
>> dwMaxBitRate 230400000
>> dwMaxVideoFrameBufferSize 960589
>> dwDefaultFrameInterval 333333
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 333333
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 7 (FRAME_MJPEG)
>> bFrameIndex 6
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 640
>> wHeight 480
>> dwMinBitRate 147456000
>> dwMaxBitRate 147456000
>> dwMaxVideoFrameBufferSize 614989
>> dwDefaultFrameInterval 333333
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 333333
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 7 (FRAME_MJPEG)
>> bFrameIndex 7
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 480
>> wHeight 640
>> dwMinBitRate 147456000
>> dwMaxBitRate 147456000
>> dwMaxVideoFrameBufferSize 614989
>> dwDefaultFrameInterval 333333
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 333333
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 7 (FRAME_MJPEG)
>> bFrameIndex 8
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 1920
>> wHeight 1080
>> dwMinBitRate 995328000
>> dwMaxBitRate 995328000
>> dwMaxVideoFrameBufferSize 4147789
>> dwDefaultFrameInterval 333333
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 333333
>> VideoStreaming Interface Descriptor:
>> bLength 34
>> bDescriptorType 36
>> bDescriptorSubtype 3 (STILL_IMAGE_FRAME)
>> bEndpointAddress 0x00 EP 0 OUT
>> bNumImageSizePatterns 7
>> wWidth( 0) 1920
>> wHeight( 0) 1080
>> wWidth( 1) 1280
>> wHeight( 1) 720
>> wWidth( 2) 800
>> wHeight( 2) 600
>> wWidth( 3) 640
>> wHeight( 3) 480
>> wWidth( 4) 640
>> wHeight( 4) 360
>> wWidth( 5) 320
>> wHeight( 5) 240
>> wWidth( 6) 320
>> wHeight( 6) 180
>> bNumCompressionPatterns 0
>> VideoStreaming Interface Descriptor:
>> bLength 27
>> bDescriptorType 36
>> bDescriptorSubtype 4 (FORMAT_UNCOMPRESSED)
>> bFormatIndex 2
>> bNumFrameDescriptors 8
>> guidFormat {32595559-0000-0010-8000-00aa00389b71}
>> bBitsPerPixel 16
>> bDefaultFrameIndex 1
>> bAspectRatioX 0
>> bAspectRatioY 0
>> bmInterlaceFlags 0x00
>> Interlaced stream or variable: No
>> Fields per frame: 2 fields
>> Field 1 first: No
>> Field pattern: Field 1 only
>> bCopyProtect 0
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
>> bFrameIndex 1
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 1920
>> wHeight 1080
>> dwMinBitRate 165888000
>> dwMaxBitRate 165888000
>> dwMaxVideoFrameBufferSize 4147200
>> dwDefaultFrameInterval 2000000
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 2000000
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
>> bFrameIndex 2
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 1280
>> wHeight 1024
>> dwMinBitRate 104857600
>> dwMaxBitRate 104857600
>> dwMaxVideoFrameBufferSize 2621440
>> dwDefaultFrameInterval 2000000
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 2000000
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
>> bFrameIndex 3
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 1280
>> wHeight 960
>> dwMinBitRate 98304000
>> dwMaxBitRate 98304000
>> dwMaxVideoFrameBufferSize 2457600
>> dwDefaultFrameInterval 2000000
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 2000000
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
>> bFrameIndex 4
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 1280
>> wHeight 720
>> dwMinBitRate 147456000
>> dwMaxBitRate 147456000
>> dwMaxVideoFrameBufferSize 1843200
>> dwDefaultFrameInterval 1000000
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 1000000
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
>> bFrameIndex 5
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 800
>> wHeight 600
>> dwMinBitRate 153600000
>> dwMaxBitRate 153600000
>> dwMaxVideoFrameBufferSize 960000
>> dwDefaultFrameInterval 500000
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 500000
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
>> bFrameIndex 6
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 640
>> wHeight 480
>> dwMinBitRate 147456000
>> dwMaxBitRate 147456000
>> dwMaxVideoFrameBufferSize 614400
>> dwDefaultFrameInterval 333333
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 333333
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
>> bFrameIndex 7
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 480
>> wHeight 640
>> dwMinBitRate 147456000
>> dwMaxBitRate 147456000
>> dwMaxVideoFrameBufferSize 614400
>> dwDefaultFrameInterval 333333
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 333333
>> VideoStreaming Interface Descriptor:
>> bLength 30
>> bDescriptorType 36
>> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
>> bFrameIndex 8
>> bmCapabilities 0x00
>> Still image unsupported
>> wWidth 1920
>> wHeight 1080
>> dwMinBitRate 165888000
>> dwMaxBitRate 165888000
>> dwMaxVideoFrameBufferSize 4147200
>> dwDefaultFrameInterval 2000000
>> bFrameIntervalType 1
>> dwFrameInterval( 0) 2000000
>> VideoStreaming Interface Descriptor:
>> bLength 18
>> bDescriptorType 36
>> bDescriptorSubtype 3 (STILL_IMAGE_FRAME)
>> bEndpointAddress 0x00 EP 0 OUT
>> bNumImageSizePatterns 3
>> wWidth( 0) 1920
>> wHeight( 0) 1080
>> wWidth( 1) 1280
>> wHeight( 1) 720
>> wWidth( 2) 640
>> wHeight( 2) 480
>> bNumCompressionPatterns 0
>> VideoStreaming Interface Descriptor:
>> bLength 6
>> bDescriptorType 36
>> bDescriptorSubtype 13 (COLORFORMAT)
>> bColorPrimaries 1 (BT.709,sRGB)
>> bTransferCharacteristics 1 (BT.709)
>> bMatrixCoefficients 4 (SMPTE 170M (BT.601))
>> Interface Descriptor:
>> bLength 9
>> bDescriptorType 4
>> bInterfaceNumber 1
>> bAlternateSetting 1
>> bNumEndpoints 1
>> bInterfaceClass 14 Video
>> bInterfaceSubClass 2 Video Streaming
>> bInterfaceProtocol 0
>> iInterface 0
>> Endpoint Descriptor:
>> bLength 7
>> bDescriptorType 5
>> bEndpointAddress 0x81 EP 1 IN
>> bmAttributes 5
>> Transfer Type Isochronous
>> Synch Type Asynchronous
>> Usage Type Data
>> wMaxPacketSize 0x0080 1x 128 bytes
>> bInterval 1
>> Interface Descriptor:
>> bLength 9
>> bDescriptorType 4
>> bInterfaceNumber 1
>> bAlternateSetting 2
>> bNumEndpoints 1
>> bInterfaceClass 14 Video
>> bInterfaceSubClass 2 Video Streaming
>> bInterfaceProtocol 0
>> iInterface 0
>> Endpoint Descriptor:
>> bLength 7
>> bDescriptorType 5
>> bEndpointAddress 0x81 EP 1 IN
>> bmAttributes 5
>> Transfer Type Isochronous
>> Synch Type Asynchronous
>> Usage Type Data
>> wMaxPacketSize 0x0100 1x 256 bytes
>> bInterval 1
>> Interface Descriptor:
>> bLength 9
>> bDescriptorType 4
>> bInterfaceNumber 1
>> bAlternateSetting 3
>> bNumEndpoints 1
>> bInterfaceClass 14 Video
>> bInterfaceSubClass 2 Video Streaming
>> bInterfaceProtocol 0
>> iInterface 0
>> Endpoint Descriptor:
>> bLength 7
>> bDescriptorType 5
>> bEndpointAddress 0x81 EP 1 IN
>> bmAttributes 5
>> Transfer Type Isochronous
>> Synch Type Asynchronous
>> Usage Type Data
>> wMaxPacketSize 0x0320 1x 800 bytes
>> bInterval 1
>> Interface Descriptor:
>> bLength 9
>> bDescriptorType 4
>> bInterfaceNumber 1
>> bAlternateSetting 4
>> bNumEndpoints 1
>> bInterfaceClass 14 Video
>> bInterfaceSubClass 2 Video Streaming
>> bInterfaceProtocol 0
>> iInterface 0
>> Endpoint Descriptor:
>> bLength 7
>> bDescriptorType 5
>> bEndpointAddress 0x81 EP 1 IN
>> bmAttributes 5
>> Transfer Type Isochronous
>> Synch Type Asynchronous
>> Usage Type Data
>> wMaxPacketSize 0x0b20 2x 800 bytes
>> bInterval 1
>> Interface Descriptor:
>> bLength 9
>> bDescriptorType 4
>> bInterfaceNumber 1
>> bAlternateSetting 5
>> bNumEndpoints 1
>> bInterfaceClass 14 Video
>> bInterfaceSubClass 2 Video Streaming
>> bInterfaceProtocol 0
>> iInterface 0
>> Endpoint Descriptor:
>> bLength 7
>> bDescriptorType 5
>> bEndpointAddress 0x81 EP 1 IN
>> bmAttributes 5
>> Transfer Type Isochronous
>> Synch Type Asynchronous
>> Usage Type Data
>> wMaxPacketSize 0x1320 3x 800 bytes
>> bInterval 1
>> Interface Descriptor:
>> bLength 9
>> bDescriptorType 4
>> bInterfaceNumber 1
>> bAlternateSetting 6
>> bNumEndpoints 1
>> bInterfaceClass 14 Video
>> bInterfaceSubClass 2 Video Streaming
>> bInterfaceProtocol 0
>> iInterface 0
>> Endpoint Descriptor:
>> bLength 7
>> bDescriptorType 5
>> bEndpointAddress 0x81 EP 1 IN
>> bmAttributes 5
>> Transfer Type Isochronous
>> Synch Type Asynchronous
>> Usage Type Data
>> wMaxPacketSize 0x1400 3x 1024 bytes
>> bInterval 1
>>
>> Cc: stable@vger.kernel.org
>> Assisted-by: claude-opus-5-5
>> Signed-off-by: Ostashow Constantine <ostashow@gmail.com>
>> ---
>> Notes for reviewers (not part of the commit message):
>>
>> Testing:
>> - Runtime-tested on a Raspberry Pi 4 (VL805 xHCI) running 6.18.57, with
>> this patch applied to the 6.18.57 uvcvideo sources (it applies with
>> line offsets only). Results are in the commit message. Before the
>> patch, 3/20 and 5/20 stream starts succeeded.
>> - Built with W=1 without new warnings: as part of the 6.18.57 module,
>> and the patched media/next sources against 6.18 headers plus the
>> media/next include/linux/usb/uvc.h.
>> - Not runtime-tested on media/next itself, and not tested on other host
>> controllers (e.g. x86 xHCI). I can't tell whether the failure depends
>> on the host controller.
>>
>> Tool disclosure (Documentation/process/generated-content.rst):
>> The root-cause analysis (usbmon capture, libusb experiments varying the
>> alternate setting, the delay after VS_COMMIT and retries), the patch and
>> this changelog were produced by an AI coding assistant (Claude Code,
>> claude-opus-5-5) in an interactive session, at my request, on my
>> hardware. I have reviewed the patch and take responsibility for it.
>> ---
>> drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++
>> drivers/media/usb/uvc/uvc_video.c | 14 ++++++++++++++
>> drivers/media/usb/uvc/uvcvideo.h | 1 +
>> 3 files changed, 24 insertions(+)
>>
>> diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
>> index cbc145697..9e1f855cd 100644
>> --- a/drivers/media/usb/uvc/uvc_driver.c
>> +++ b/drivers/media/usb/uvc/uvc_driver.c
>> @@ -2928,6 +2928,15 @@ static const struct usb_device_id uvc_ids[] = {
>> .bInterfaceSubClass = 1,
>> .bInterfaceProtocol = 0,
>> .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_MJPEG_NO_EOF) },
>> + /* SVBONY SV105C */
>> + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
>> + | USB_DEVICE_ID_MATCH_INT_INFO,
>> + .idVendor = 0x0c45,
>> + .idProduct = 0x636b,
>> + .bInterfaceClass = USB_CLASS_VIDEO,
>> + .bInterfaceSubClass = 1,
>> + .bInterfaceProtocol = 0,
>> + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RETRY_SET_INTERFACE) },
>> /* MT6227 */
>> { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
>> | USB_DEVICE_ID_MATCH_INT_INFO,
>> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
>> index a92a986ab..3a3b1d1d7 100644
>> --- a/drivers/media/usb/uvc/uvc_video.c
>> +++ b/drivers/media/usb/uvc/uvc_video.c
>> @@ -2100,6 +2100,20 @@ static int uvc_video_start_transfer(struct uvc_streaming *stream,
>> }
>>
>> ret = usb_set_interface(stream->dev->udev, intfnum, altsetting);
>> +
>> + /*
>> + * Some devices, namely the SVBONY SV105C, fail most of the
>> + * SET_INTERFACE requests that follow a VS_COMMIT control with
>> + * a protocol error. Retrying the request immediately succeeds.
>> + */
>> + for (i = 0; ret == -EPROTO && i < 3 &&
>> + (stream->dev->quirks & UVC_QUIRK_RETRY_SET_INTERFACE); ++i) {
>> + uvc_dbg(stream->dev, VIDEO,
>> + "SET_INTERFACE failed (%d), retrying\n", ret);
>> + ret = usb_set_interface(stream->dev->udev, intfnum,
>> + altsetting);
>> + }
>> +
>> if (ret < 0)
>> return ret;
>>
>> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
>> index af8cef94f..19851c3d2 100644
>> --- a/drivers/media/usb/uvc/uvcvideo.h
>> +++ b/drivers/media/usb/uvc/uvcvideo.h
>> @@ -81,6 +81,7 @@
>> #define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000
>> #define UVC_QUIRK_MJPEG_NO_EOF 0x00020000
>> #define UVC_QUIRK_MSXU_META 0x00040000
>> +#define UVC_QUIRK_RETRY_SET_INTERFACE 0x00080000
>>
>> /* Format flags */
>> #define UVC_FMT_FLAG_COMPRESSED 0x00000001
>>
>> ---
>> base-commit: d7e7bca7169873b46e857c025c10f3336c1258d8
>> change-id: 20261019-sv105c-retry-set-interface-759a92a1e7b5
>
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] media: uvcvideo: Add quirk to retry SET_INTERFACE for SVBONY SV105C
2026-10-19 11:21 ` Hans de Goede
@ 2026-10-19 11:27 ` Laurent Pinchart
2026-10-19 11:58 ` Константин Осташов
0 siblings, 1 reply; 8+ messages in thread
From: Laurent Pinchart @ 2026-10-19 11:27 UTC (permalink / raw)
To: Hans de Goede
Cc: ostashow, Mauro Carvalho Chehab, linux-media, linux-kernel, stable
On Mon, Oct 19, 2026 at 01:21:49PM +0200, Hans de Goede wrote:
> On 19-Oct-26 1:17 PM, Laurent Pinchart wrote:
> > On Mon, Oct 19, 2026 at 02:07:28PM +0300, Ostashow Constantine via B4 Relay wrote:
> >> From: Ostashow Constantine <ostashow@gmail.com>
> >>
> >> The SVBONY SV105C (0c45:636b, Sonix based) fails most SET_INTERFACE
> >> requests that select a streaming alternate setting right after a
> >> VS_COMMIT control. The request completes with -EPROTO, so
> >> VIDIOC_STREAMON fails and capture applications see the camera
> >> randomly failing to start.
> >>
> >> A usbmon capture of a failing VIDIOC_STREAMON:
> >>
> >> S Co:1:003:0 s 21 01 0200 0001 001a 26 = 01000104 15160500 ...
> >> C Co:1:003:0 0 26 >
> >> S Co:1:003:0 s 01 0b 0004 0001 0000 0
> >> C Co:1:003:0 -71 0
> >> S Co:1:003:0 s 01 0b 0000 0001 0000 0
> >> C Co:1:003:0 0 0
> >>
> >> The failure rate is around 80% and does not depend on the alternate
> >> setting (alt 1, the smallest one with 128 bytes per microframe, fails
> >> as often as alt 6), on a delay between VS_COMMIT and SET_INTERFACE
> >> (0 to 100 ms tested), or on USB autosuspend. SET_INTERFACE without a
> >> preceding VS_COMMIT succeeded 15 out of 15 times, and an immediate
> >> retry after the -EPROTO failure succeeded 15 out of 15 times. Once
> >> streaming has started, the camera works reliably. It also works with
> >> the Windows UVC driver.
> >
> > What does Windows do differently then ?
>
> I guess Windows always has a short-delay of at least one USB frame-time
> between the VS_COMMIT and SET_INTERFACE. I think we should simply add
> a flseep(1000) before the set_interface instead of adding a quirk for
> this.
The commit message says it doesn't help, but I can't tell if that can be
trusted.
> >> Add a UVC_QUIRK_RETRY_SET_INTERFACE quirk that retries SET_INTERFACE
> >> up to three times when it fails with -EPROTO, and enable it for the
> >> SV105C. With the quirk, 35 out of 35 stream starts succeeded, 29 of
> >> them needed a retry, and no start needed more than one.
> >>
> >> lsusb -v:
> >>
> >> Bus 001 Device 003: ID 0c45:636b Microdia SVBONY SV105C
> >> Negotiated speed: High Speed (480Mbps)
> >> Device Descriptor:
> >> bLength 18
> >> bDescriptorType 1
> >> bcdUSB 2.01
> >> bDeviceClass 239 Miscellaneous Device
> >> bDeviceSubClass 2 [unknown]
> >> bDeviceProtocol 1 Interface Association
> >> bMaxPacketSize0 64
> >> idVendor 0x0c45 Microdia
> >> idProduct 0x636b SVBONY SV105C
> >> bcdDevice 1.00
> >> iManufacturer 2 Sonix Technology Co., Ltd.
> >> iProduct 1 SVBONY SV105C
> >> iSerial 3 SN0001
> >> bNumConfigurations 1
> >> Configuration Descriptor:
> >> bLength 9
> >> bDescriptorType 2
> >> wTotalLength 0x032e
> >> bNumInterfaces 2
> >> bConfigurationValue 1
> >> iConfiguration 0
> >> bmAttributes 0x80
> >> (Bus Powered)
> >> MaxPower 500mA
> >> Interface Association:
> >> bLength 8
> >> bDescriptorType 11
> >> bFirstInterface 0
> >> bInterfaceCount 2
> >> bFunctionClass 14 Video
> >> bFunctionSubClass 3 Video Interface Collection
> >> bFunctionProtocol 0
> >> iFunction 5
> >> Interface Descriptor:
> >> bLength 9
> >> bDescriptorType 4
> >> bInterfaceNumber 0
> >> bAlternateSetting 0
> >> bNumEndpoints 1
> >> bInterfaceClass 14 Video
> >> bInterfaceSubClass 1 Video Control
> >> bInterfaceProtocol 0
> >> iInterface 5
> >> VideoControl Interface Descriptor:
> >> bLength 13
> >> bDescriptorType 36
> >> bDescriptorSubtype 1 (HEADER)
> >> bcdUVC 1.00
> >> wTotalLength 0x0050
> >> dwClockFrequency 15.000000MHz
> >> bInCollection 1
> >> baInterfaceNr( 0) 1
> >> VideoControl Interface Descriptor:
> >> bLength 9
> >> bDescriptorType 36
> >> bDescriptorSubtype 3 (OUTPUT_TERMINAL)
> >> bTerminalID 4
> >> wTerminalType 0x0101 USB Streaming
> >> bAssocTerminal 0
> >> bSourceID 3
> >> iTerminal 0
> >> VideoControl Interface Descriptor:
> >> bLength 29
> >> bDescriptorType 36
> >> bDescriptorSubtype 6 (EXTENSION_UNIT)
> >> bUnitID 3
> >> guidExtensionCode {28f03370-6311-4a2e-ba2c-6890eb334016}
> >> bNumControls 32
> >> bNrInPins 1
> >> baSourceID( 0) 2
> >> bControlSize 4
> >> bmControls( 0) 0x9f
> >> bmControls( 1) 0x07
> >> bmControls( 2) 0x07
> >> bmControls( 3) 0x07
> >> iExtension 0
> >> VideoControl Interface Descriptor:
> >> bLength 18
> >> bDescriptorType 36
> >> bDescriptorSubtype 2 (INPUT_TERMINAL)
> >> bTerminalID 1
> >> wTerminalType 0x0201 Camera Sensor
> >> bAssocTerminal 0
> >> iTerminal 0
> >> wObjectiveFocalLengthMin 0
> >> wObjectiveFocalLengthMax 0
> >> wOcularFocalLength 0
> >> bControlSize 3
> >> bmControls 0x0000000e
> >> Auto-Exposure Mode
> >> Auto-Exposure Priority
> >> Exposure Time (Absolute)
> >> VideoControl Interface Descriptor:
> >> bLength 11
> >> bDescriptorType 36
> >> bDescriptorSubtype 5 (PROCESSING_UNIT)
> >> Warning: Descriptor too short
> >> bUnitID 2
> >> bSourceID 1
> >> wMaxMultiplier 0
> >> bControlSize 2
> >> bmControls 0x0000177f
> >> Brightness
> >> Contrast
> >> Hue
> >> Saturation
> >> Sharpness
> >> Gamma
> >> White Balance Temperature
> >> Backlight Compensation
> >> Gain
> >> Power Line Frequency
> >> White Balance Temperature, Auto
> >> iProcessing 0
> >> bmVideoStandards 0x31
> >> None
> >> NTSC - 625/50
> >> PAL - 525/60
> >> Endpoint Descriptor:
> >> bLength 7
> >> bDescriptorType 5
> >> bEndpointAddress 0x83 EP 3 IN
> >> bmAttributes 3
> >> Transfer Type Interrupt
> >> Synch Type None
> >> Usage Type Data
> >> wMaxPacketSize 0x0010 1x 16 bytes
> >> bInterval 6
> >> VideoControl Endpoint Descriptor:
> >> bLength 5
> >> bDescriptorType 37
> >> bDescriptorSubtype 3 (EP_INTERRUPT)
> >> wMaxTransferSize 128
> >> Interface Descriptor:
> >> bLength 9
> >> bDescriptorType 4
> >> bInterfaceNumber 1
> >> bAlternateSetting 0
> >> bNumEndpoints 0
> >> bInterfaceClass 14 Video
> >> bInterfaceSubClass 2 Video Streaming
> >> bInterfaceProtocol 0
> >> iInterface 0
> >> VideoStreaming Interface Descriptor:
> >> bLength 15
> >> bDescriptorType 36
> >> bDescriptorSubtype 1 (INPUT_HEADER)
> >> bNumFormats 2
> >> wTotalLength 0x024f
> >> bEndpointAddress 0x81 EP 1 IN
> >> bmInfo 0
> >> bTerminalLink 4
> >> bStillCaptureMethod 2
> >> bTriggerSupport 1
> >> bTriggerUsage 1
> >> bControlSize 1
> >> bmaControls( 0) 0
> >> bmaControls( 1) 0
> >> VideoStreaming Interface Descriptor:
> >> bLength 11
> >> bDescriptorType 36
> >> bDescriptorSubtype 6 (FORMAT_MJPEG)
> >> bFormatIndex 1
> >> bNumFrameDescriptors 8
> >> bFlags 0
> >> Fixed-size samples: No
> >> bDefaultFrameIndex 1
> >> bAspectRatioX 0
> >> bAspectRatioY 0
> >> bmInterlaceFlags 0x00
> >> Interlaced stream or variable: No
> >> Fields per frame: 1 fields
> >> Field 1 first: No
> >> Field pattern: Field 1 only
> >> bCopyProtect 0
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 7 (FRAME_MJPEG)
> >> bFrameIndex 1
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 1920
> >> wHeight 1080
> >> dwMinBitRate 995328000
> >> dwMaxBitRate 995328000
> >> dwMaxVideoFrameBufferSize 4147789
> >> dwDefaultFrameInterval 333333
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 333333
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 7 (FRAME_MJPEG)
> >> bFrameIndex 2
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 1280
> >> wHeight 1024
> >> dwMinBitRate 629145600
> >> dwMaxBitRate 629145600
> >> dwMaxVideoFrameBufferSize 2622029
> >> dwDefaultFrameInterval 333333
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 333333
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 7 (FRAME_MJPEG)
> >> bFrameIndex 3
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 1280
> >> wHeight 960
> >> dwMinBitRate 589824000
> >> dwMaxBitRate 589824000
> >> dwMaxVideoFrameBufferSize 2458189
> >> dwDefaultFrameInterval 333333
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 333333
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 7 (FRAME_MJPEG)
> >> bFrameIndex 4
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 1280
> >> wHeight 720
> >> dwMinBitRate 442368000
> >> dwMaxBitRate 442368000
> >> dwMaxVideoFrameBufferSize 1843789
> >> dwDefaultFrameInterval 333333
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 333333
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 7 (FRAME_MJPEG)
> >> bFrameIndex 5
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 800
> >> wHeight 600
> >> dwMinBitRate 230400000
> >> dwMaxBitRate 230400000
> >> dwMaxVideoFrameBufferSize 960589
> >> dwDefaultFrameInterval 333333
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 333333
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 7 (FRAME_MJPEG)
> >> bFrameIndex 6
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 640
> >> wHeight 480
> >> dwMinBitRate 147456000
> >> dwMaxBitRate 147456000
> >> dwMaxVideoFrameBufferSize 614989
> >> dwDefaultFrameInterval 333333
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 333333
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 7 (FRAME_MJPEG)
> >> bFrameIndex 7
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 480
> >> wHeight 640
> >> dwMinBitRate 147456000
> >> dwMaxBitRate 147456000
> >> dwMaxVideoFrameBufferSize 614989
> >> dwDefaultFrameInterval 333333
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 333333
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 7 (FRAME_MJPEG)
> >> bFrameIndex 8
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 1920
> >> wHeight 1080
> >> dwMinBitRate 995328000
> >> dwMaxBitRate 995328000
> >> dwMaxVideoFrameBufferSize 4147789
> >> dwDefaultFrameInterval 333333
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 333333
> >> VideoStreaming Interface Descriptor:
> >> bLength 34
> >> bDescriptorType 36
> >> bDescriptorSubtype 3 (STILL_IMAGE_FRAME)
> >> bEndpointAddress 0x00 EP 0 OUT
> >> bNumImageSizePatterns 7
> >> wWidth( 0) 1920
> >> wHeight( 0) 1080
> >> wWidth( 1) 1280
> >> wHeight( 1) 720
> >> wWidth( 2) 800
> >> wHeight( 2) 600
> >> wWidth( 3) 640
> >> wHeight( 3) 480
> >> wWidth( 4) 640
> >> wHeight( 4) 360
> >> wWidth( 5) 320
> >> wHeight( 5) 240
> >> wWidth( 6) 320
> >> wHeight( 6) 180
> >> bNumCompressionPatterns 0
> >> VideoStreaming Interface Descriptor:
> >> bLength 27
> >> bDescriptorType 36
> >> bDescriptorSubtype 4 (FORMAT_UNCOMPRESSED)
> >> bFormatIndex 2
> >> bNumFrameDescriptors 8
> >> guidFormat {32595559-0000-0010-8000-00aa00389b71}
> >> bBitsPerPixel 16
> >> bDefaultFrameIndex 1
> >> bAspectRatioX 0
> >> bAspectRatioY 0
> >> bmInterlaceFlags 0x00
> >> Interlaced stream or variable: No
> >> Fields per frame: 2 fields
> >> Field 1 first: No
> >> Field pattern: Field 1 only
> >> bCopyProtect 0
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> >> bFrameIndex 1
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 1920
> >> wHeight 1080
> >> dwMinBitRate 165888000
> >> dwMaxBitRate 165888000
> >> dwMaxVideoFrameBufferSize 4147200
> >> dwDefaultFrameInterval 2000000
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 2000000
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> >> bFrameIndex 2
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 1280
> >> wHeight 1024
> >> dwMinBitRate 104857600
> >> dwMaxBitRate 104857600
> >> dwMaxVideoFrameBufferSize 2621440
> >> dwDefaultFrameInterval 2000000
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 2000000
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> >> bFrameIndex 3
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 1280
> >> wHeight 960
> >> dwMinBitRate 98304000
> >> dwMaxBitRate 98304000
> >> dwMaxVideoFrameBufferSize 2457600
> >> dwDefaultFrameInterval 2000000
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 2000000
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> >> bFrameIndex 4
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 1280
> >> wHeight 720
> >> dwMinBitRate 147456000
> >> dwMaxBitRate 147456000
> >> dwMaxVideoFrameBufferSize 1843200
> >> dwDefaultFrameInterval 1000000
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 1000000
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> >> bFrameIndex 5
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 800
> >> wHeight 600
> >> dwMinBitRate 153600000
> >> dwMaxBitRate 153600000
> >> dwMaxVideoFrameBufferSize 960000
> >> dwDefaultFrameInterval 500000
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 500000
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> >> bFrameIndex 6
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 640
> >> wHeight 480
> >> dwMinBitRate 147456000
> >> dwMaxBitRate 147456000
> >> dwMaxVideoFrameBufferSize 614400
> >> dwDefaultFrameInterval 333333
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 333333
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> >> bFrameIndex 7
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 480
> >> wHeight 640
> >> dwMinBitRate 147456000
> >> dwMaxBitRate 147456000
> >> dwMaxVideoFrameBufferSize 614400
> >> dwDefaultFrameInterval 333333
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 333333
> >> VideoStreaming Interface Descriptor:
> >> bLength 30
> >> bDescriptorType 36
> >> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> >> bFrameIndex 8
> >> bmCapabilities 0x00
> >> Still image unsupported
> >> wWidth 1920
> >> wHeight 1080
> >> dwMinBitRate 165888000
> >> dwMaxBitRate 165888000
> >> dwMaxVideoFrameBufferSize 4147200
> >> dwDefaultFrameInterval 2000000
> >> bFrameIntervalType 1
> >> dwFrameInterval( 0) 2000000
> >> VideoStreaming Interface Descriptor:
> >> bLength 18
> >> bDescriptorType 36
> >> bDescriptorSubtype 3 (STILL_IMAGE_FRAME)
> >> bEndpointAddress 0x00 EP 0 OUT
> >> bNumImageSizePatterns 3
> >> wWidth( 0) 1920
> >> wHeight( 0) 1080
> >> wWidth( 1) 1280
> >> wHeight( 1) 720
> >> wWidth( 2) 640
> >> wHeight( 2) 480
> >> bNumCompressionPatterns 0
> >> VideoStreaming Interface Descriptor:
> >> bLength 6
> >> bDescriptorType 36
> >> bDescriptorSubtype 13 (COLORFORMAT)
> >> bColorPrimaries 1 (BT.709,sRGB)
> >> bTransferCharacteristics 1 (BT.709)
> >> bMatrixCoefficients 4 (SMPTE 170M (BT.601))
> >> Interface Descriptor:
> >> bLength 9
> >> bDescriptorType 4
> >> bInterfaceNumber 1
> >> bAlternateSetting 1
> >> bNumEndpoints 1
> >> bInterfaceClass 14 Video
> >> bInterfaceSubClass 2 Video Streaming
> >> bInterfaceProtocol 0
> >> iInterface 0
> >> Endpoint Descriptor:
> >> bLength 7
> >> bDescriptorType 5
> >> bEndpointAddress 0x81 EP 1 IN
> >> bmAttributes 5
> >> Transfer Type Isochronous
> >> Synch Type Asynchronous
> >> Usage Type Data
> >> wMaxPacketSize 0x0080 1x 128 bytes
> >> bInterval 1
> >> Interface Descriptor:
> >> bLength 9
> >> bDescriptorType 4
> >> bInterfaceNumber 1
> >> bAlternateSetting 2
> >> bNumEndpoints 1
> >> bInterfaceClass 14 Video
> >> bInterfaceSubClass 2 Video Streaming
> >> bInterfaceProtocol 0
> >> iInterface 0
> >> Endpoint Descriptor:
> >> bLength 7
> >> bDescriptorType 5
> >> bEndpointAddress 0x81 EP 1 IN
> >> bmAttributes 5
> >> Transfer Type Isochronous
> >> Synch Type Asynchronous
> >> Usage Type Data
> >> wMaxPacketSize 0x0100 1x 256 bytes
> >> bInterval 1
> >> Interface Descriptor:
> >> bLength 9
> >> bDescriptorType 4
> >> bInterfaceNumber 1
> >> bAlternateSetting 3
> >> bNumEndpoints 1
> >> bInterfaceClass 14 Video
> >> bInterfaceSubClass 2 Video Streaming
> >> bInterfaceProtocol 0
> >> iInterface 0
> >> Endpoint Descriptor:
> >> bLength 7
> >> bDescriptorType 5
> >> bEndpointAddress 0x81 EP 1 IN
> >> bmAttributes 5
> >> Transfer Type Isochronous
> >> Synch Type Asynchronous
> >> Usage Type Data
> >> wMaxPacketSize 0x0320 1x 800 bytes
> >> bInterval 1
> >> Interface Descriptor:
> >> bLength 9
> >> bDescriptorType 4
> >> bInterfaceNumber 1
> >> bAlternateSetting 4
> >> bNumEndpoints 1
> >> bInterfaceClass 14 Video
> >> bInterfaceSubClass 2 Video Streaming
> >> bInterfaceProtocol 0
> >> iInterface 0
> >> Endpoint Descriptor:
> >> bLength 7
> >> bDescriptorType 5
> >> bEndpointAddress 0x81 EP 1 IN
> >> bmAttributes 5
> >> Transfer Type Isochronous
> >> Synch Type Asynchronous
> >> Usage Type Data
> >> wMaxPacketSize 0x0b20 2x 800 bytes
> >> bInterval 1
> >> Interface Descriptor:
> >> bLength 9
> >> bDescriptorType 4
> >> bInterfaceNumber 1
> >> bAlternateSetting 5
> >> bNumEndpoints 1
> >> bInterfaceClass 14 Video
> >> bInterfaceSubClass 2 Video Streaming
> >> bInterfaceProtocol 0
> >> iInterface 0
> >> Endpoint Descriptor:
> >> bLength 7
> >> bDescriptorType 5
> >> bEndpointAddress 0x81 EP 1 IN
> >> bmAttributes 5
> >> Transfer Type Isochronous
> >> Synch Type Asynchronous
> >> Usage Type Data
> >> wMaxPacketSize 0x1320 3x 800 bytes
> >> bInterval 1
> >> Interface Descriptor:
> >> bLength 9
> >> bDescriptorType 4
> >> bInterfaceNumber 1
> >> bAlternateSetting 6
> >> bNumEndpoints 1
> >> bInterfaceClass 14 Video
> >> bInterfaceSubClass 2 Video Streaming
> >> bInterfaceProtocol 0
> >> iInterface 0
> >> Endpoint Descriptor:
> >> bLength 7
> >> bDescriptorType 5
> >> bEndpointAddress 0x81 EP 1 IN
> >> bmAttributes 5
> >> Transfer Type Isochronous
> >> Synch Type Asynchronous
> >> Usage Type Data
> >> wMaxPacketSize 0x1400 3x 1024 bytes
> >> bInterval 1
> >>
> >> Cc: stable@vger.kernel.org
> >> Assisted-by: claude-opus-5-5
> >> Signed-off-by: Ostashow Constantine <ostashow@gmail.com>
> >> ---
> >> Notes for reviewers (not part of the commit message):
> >>
> >> Testing:
> >> - Runtime-tested on a Raspberry Pi 4 (VL805 xHCI) running 6.18.57, with
> >> this patch applied to the 6.18.57 uvcvideo sources (it applies with
> >> line offsets only). Results are in the commit message. Before the
> >> patch, 3/20 and 5/20 stream starts succeeded.
> >> - Built with W=1 without new warnings: as part of the 6.18.57 module,
> >> and the patched media/next sources against 6.18 headers plus the
> >> media/next include/linux/usb/uvc.h.
> >> - Not runtime-tested on media/next itself, and not tested on other host
> >> controllers (e.g. x86 xHCI). I can't tell whether the failure depends
> >> on the host controller.
> >>
> >> Tool disclosure (Documentation/process/generated-content.rst):
> >> The root-cause analysis (usbmon capture, libusb experiments varying the
> >> alternate setting, the delay after VS_COMMIT and retries), the patch and
> >> this changelog were produced by an AI coding assistant (Claude Code,
> >> claude-opus-5-5) in an interactive session, at my request, on my
> >> hardware. I have reviewed the patch and take responsibility for it.
> >> ---
> >> drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++
> >> drivers/media/usb/uvc/uvc_video.c | 14 ++++++++++++++
> >> drivers/media/usb/uvc/uvcvideo.h | 1 +
> >> 3 files changed, 24 insertions(+)
> >>
> >> diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
> >> index cbc145697..9e1f855cd 100644
> >> --- a/drivers/media/usb/uvc/uvc_driver.c
> >> +++ b/drivers/media/usb/uvc/uvc_driver.c
> >> @@ -2928,6 +2928,15 @@ static const struct usb_device_id uvc_ids[] = {
> >> .bInterfaceSubClass = 1,
> >> .bInterfaceProtocol = 0,
> >> .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_MJPEG_NO_EOF) },
> >> + /* SVBONY SV105C */
> >> + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
> >> + | USB_DEVICE_ID_MATCH_INT_INFO,
> >> + .idVendor = 0x0c45,
> >> + .idProduct = 0x636b,
> >> + .bInterfaceClass = USB_CLASS_VIDEO,
> >> + .bInterfaceSubClass = 1,
> >> + .bInterfaceProtocol = 0,
> >> + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RETRY_SET_INTERFACE) },
> >> /* MT6227 */
> >> { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
> >> | USB_DEVICE_ID_MATCH_INT_INFO,
> >> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
> >> index a92a986ab..3a3b1d1d7 100644
> >> --- a/drivers/media/usb/uvc/uvc_video.c
> >> +++ b/drivers/media/usb/uvc/uvc_video.c
> >> @@ -2100,6 +2100,20 @@ static int uvc_video_start_transfer(struct uvc_streaming *stream,
> >> }
> >>
> >> ret = usb_set_interface(stream->dev->udev, intfnum, altsetting);
> >> +
> >> + /*
> >> + * Some devices, namely the SVBONY SV105C, fail most of the
> >> + * SET_INTERFACE requests that follow a VS_COMMIT control with
> >> + * a protocol error. Retrying the request immediately succeeds.
> >> + */
> >> + for (i = 0; ret == -EPROTO && i < 3 &&
> >> + (stream->dev->quirks & UVC_QUIRK_RETRY_SET_INTERFACE); ++i) {
> >> + uvc_dbg(stream->dev, VIDEO,
> >> + "SET_INTERFACE failed (%d), retrying\n", ret);
> >> + ret = usb_set_interface(stream->dev->udev, intfnum,
> >> + altsetting);
> >> + }
> >> +
> >> if (ret < 0)
> >> return ret;
> >>
> >> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> >> index af8cef94f..19851c3d2 100644
> >> --- a/drivers/media/usb/uvc/uvcvideo.h
> >> +++ b/drivers/media/usb/uvc/uvcvideo.h
> >> @@ -81,6 +81,7 @@
> >> #define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000
> >> #define UVC_QUIRK_MJPEG_NO_EOF 0x00020000
> >> #define UVC_QUIRK_MSXU_META 0x00040000
> >> +#define UVC_QUIRK_RETRY_SET_INTERFACE 0x00080000
> >>
> >> /* Format flags */
> >> #define UVC_FMT_FLAG_COMPRESSED 0x00000001
> >>
> >> ---
> >> base-commit: d7e7bca7169873b46e857c025c10f3336c1258d8
> >> change-id: 20261019-sv105c-retry-set-interface-759a92a1e7b5
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] media: uvcvideo: Add quirk to retry SET_INTERFACE for SVBONY SV105C
2026-10-19 11:27 ` Laurent Pinchart
@ 2026-10-19 11:58 ` Константин Осташов
2026-10-19 12:33 ` Hans de Goede
0 siblings, 1 reply; 8+ messages in thread
From: Константин Осташов @ 2026-10-19 11:58 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Hans de Goede, Mauro Carvalho Chehab, linux-media, linux-kernel, stable
Hi Laurent, Hans,
On Mon, Oct 19, 2026 at 02:27:26PM +0300, Laurent Pinchart wrote:
> On Mon, Oct 19, 2026 at 01:21:49PM +0200, Hans de Goede wrote:
> > On 19-Oct-26 1:17 PM, Laurent Pinchart wrote:
> > > What does Windows do differently then ?
> >
> > I guess Windows always has a short-delay of at least one USB frame-time
> > between the VS_COMMIT and SET_INTERFACE. I think we should simply add
> > a flseep(1000) before the set_interface instead of adding a quirk for
> > this.
>
> The commit message says it doesn't help, but I can't tell if that can be
> trusted.
Fair point. I have measured both sides again.
Windows 11, AMD xHCI, camera on a root port, 120 stream starts with
ffmpeg/DirectShow (MJPEG 1920x1080, and YUYV 1920x1080 for 5 of them),
captured with USBPcap and an ETW trace of USBXHCI/UCX/USBHUB3:
- The requests are the same as on Linux: PROBE GET_CUR, SET_CUR,
GET_CUR, GET_MAX, GET_MIN, SET_CUR, GET_CUR, then a 26 byte COMMIT,
then SET_INTERFACE alt 6. There is nothing else in between.
- The SET_INTERFACE URB is submitted 22 us after the COMMIT completes.
The xHCI driver first runs a Configure Endpoint command (3 ms), then
queues the control transfer. That puts about 3 ms between the two
requests.
- The control transfer completes successfully after 263 ms, every time
(402 ms for YUYV 1920x1080). In a 100 start run, the ETW trace shows
exactly 10 control transfers on the camera's EP0 per start (8 for
probe/commit and 2 for SET_INTERFACE alt 6/alt 0). There was no
Reset Endpoint command, and every xHCI command completed with Success.
Windows does not see an error and does not retry. 0 failures out of
120.
Linux 6.18, Raspberry Pi 4 (VL805 xHCI, camera behind the VL805's
internal USB 2.0 hub). I added an fsleep() right before
usb_set_interface() in uvc_video_start_transfer() and checked the
resulting gap in usbmon. 20 starts per value, MJPEG 1920x1080, auto
exposure:
fsleep() COMMIT -> SET_INTERFACE (usbmon) first SET_INTERFACE -EPROTO
none 0.35 - 0.90 ms 1/20
1 ms 1.53 - 1.84 ms 2/20
5 ms 5.42 - 7.26 ms 6/20
20 ms 20.4 - 26.4 ms 3/20
100 ms 100.7 - 108.1 ms 5/20
300 ms 319.5 - 325.2 ms 1/20
So a delay does not help, even one longer than the time the device
takes to complete the request.
The timing differs between failure and success. A failing
SET_INTERFACE completes with -EPROTO about 1 ms after it is submitted.
A successful one, whether the first attempt or the retry, takes about
260 ms, the same as on Windows. My guess is that the device starts
reconfiguring right after the SETUP stage and sometimes fails to
answer the status stage for a few microframes before it starts
NAKing. The VL805 then reports a transaction error. I have no bus
analyzer to confirm this.
I also need to correct the commit message: the failure rate is not a
stable 80%. Today it was between 0% and 50% per series of 10 to 20
starts, with auto exposure failing more often than manual exposure.
The retry always succeeded on the first attempt.
With 0 out of 120 on Windows against roughly 15% per start on the Pi,
the difference is real. I can't tell yet whether it comes from the OS
or from the host controller. I haven't tested the camera with Linux
on a non-VL805 controller. I can do that before a v2 if it would help.
--
Regards,
Constantine
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] media: uvcvideo: Add quirk to retry SET_INTERFACE for SVBONY SV105C
2026-10-19 11:58 ` Константин Осташов
@ 2026-10-19 12:33 ` Hans de Goede
2026-10-19 12:38 ` Laurent Pinchart
0 siblings, 1 reply; 8+ messages in thread
From: Hans de Goede @ 2026-10-19 12:33 UTC (permalink / raw)
To: Константин
Осташов,
Laurent Pinchart
Cc: Mauro Carvalho Chehab, linux-media, linux-kernel, stable
Hi,
On 19-Oct-26 1:58 PM, Константин Осташов wrote:
> Hi Laurent, Hans,
>
> On Mon, Oct 19, 2026 at 02:27:26PM +0300, Laurent Pinchart wrote:
>> On Mon, Oct 19, 2026 at 01:21:49PM +0200, Hans de Goede wrote:
>>> On 19-Oct-26 1:17 PM, Laurent Pinchart wrote:
>>>> What does Windows do differently then ?
>>>
>>> I guess Windows always has a short-delay of at least one USB frame-time
>>> between the VS_COMMIT and SET_INTERFACE. I think we should simply add
>>> a flseep(1000) before the set_interface instead of adding a quirk for
>>> this.
>>
>> The commit message says it doesn't help, but I can't tell if that can be
>> trusted.
>
> Fair point. I have measured both sides again.
>
> Windows 11, AMD xHCI, camera on a root port, 120 stream starts with
> ffmpeg/DirectShow (MJPEG 1920x1080, and YUYV 1920x1080 for 5 of them),
> captured with USBPcap and an ETW trace of USBXHCI/UCX/USBHUB3:
>
> - The requests are the same as on Linux: PROBE GET_CUR, SET_CUR,
> GET_CUR, GET_MAX, GET_MIN, SET_CUR, GET_CUR, then a 26 byte COMMIT,
> then SET_INTERFACE alt 6. There is nothing else in between.
> - The SET_INTERFACE URB is submitted 22 us after the COMMIT completes.
> The xHCI driver first runs a Configure Endpoint command (3 ms), then
> queues the control transfer. That puts about 3 ms between the two
> requests.
When you say "then queurs the control transfer", you mean the control
transfer for the SET_INTERFACE, right ?
I wonder if the problem is that Linux is missing this Configure Endpoint
command ?
> - The control transfer completes successfully after 263 ms, every time
> (402 ms for YUYV 1920x1080). In a 100 start run, the ETW trace shows
> exactly 10 control transfers on the camera's EP0 per start (8 for
> probe/commit and 2 for SET_INTERFACE alt 6/alt 0). There was no
> Reset Endpoint command, and every xHCI command completed with Success.
> Windows does not see an error and does not retry. 0 failures out of
> 120.
>
> Linux 6.18, Raspberry Pi 4 (VL805 xHCI, camera behind the VL805's
> internal USB 2.0 hub). I added an fsleep() right before
> usb_set_interface() in uvc_video_start_transfer() and checked the
> resulting gap in usbmon. 20 starts per value, MJPEG 1920x1080, auto
> exposure:
> > fsleep() COMMIT -> SET_INTERFACE (usbmon) first SET_INTERFACE -EPROTO
> none 0.35 - 0.90 ms 1/20
> 1 ms 1.53 - 1.84 ms 2/20
> 5 ms 5.42 - 7.26 ms 6/20
> 20 ms 20.4 - 26.4 ms 3/20
> 100 ms 100.7 - 108.1 ms 5/20
> 300 ms 319.5 - 325.2 ms 1/20
>
> So a delay does not help, even one longer than the time the device
> takes to complete the request.
>
> The timing differs between failure and success. A failing
> SET_INTERFACE completes with -EPROTO about 1 ms after it is submitted.
> A successful one, whether the first attempt or the retry, takes about
> 260 ms, the same as on Windows. My guess is that the device starts
> reconfiguring right after the SETUP stage and sometimes fails to
> answer the status stage for a few microframes before it starts
> NAKing. The VL805 then reports a transaction error. I have no bus
> analyzer to confirm this.
>
> I also need to correct the commit message: the failure rate is not a
> stable 80%. Today it was between 0% and 50% per series of 10 to 20
> starts, with auto exposure failing more often than manual exposure.
> The retry always succeeded on the first attempt.
>
> With 0 out of 120 on Windows against roughly 15% per start on the Pi,
> the difference is real. I can't tell yet whether it comes from the OS
> or from the host controller. I haven't tested the camera with Linux
> on a non-VL805 controller. I can do that before a v2 if it would help.
Have you tried reproducing this on a different XHCI controller then
the one found in the Raspberry Pi 4 ? I wonder if this problem
is specific to the VL805 xHCI controller.
Likewise have you tried reproducing this under Windows with an USB2.0
hub in between ?
Regards,
Hans
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] media: uvcvideo: Add quirk to retry SET_INTERFACE for SVBONY SV105C
2026-10-19 12:33 ` Hans de Goede
@ 2026-10-19 12:38 ` Laurent Pinchart
2026-10-19 12:20 ` Ostashow Constantine
0 siblings, 1 reply; 8+ messages in thread
From: Laurent Pinchart @ 2026-10-19 12:38 UTC (permalink / raw)
To: Hans de Goede
Cc: Константин
Осташов,
Mauro Carvalho Chehab, linux-media, linux-kernel, stable
On Mon, Oct 19, 2026 at 02:33:11PM +0200, Hans de Goede wrote:
> On 19-Oct-26 1:58 PM, Константин Осташов wrote:
> > On Mon, Oct 19, 2026 at 02:27:26PM +0300, Laurent Pinchart wrote:
> >> On Mon, Oct 19, 2026 at 01:21:49PM +0200, Hans de Goede wrote:
> >>> On 19-Oct-26 1:17 PM, Laurent Pinchart wrote:
> >>>> What does Windows do differently then ?
> >>>
> >>> I guess Windows always has a short-delay of at least one USB frame-time
> >>> between the VS_COMMIT and SET_INTERFACE. I think we should simply add
> >>> a flseep(1000) before the set_interface instead of adding a quirk for
> >>> this.
> >>
> >> The commit message says it doesn't help, but I can't tell if that can be
> >> trusted.
> >
> > Fair point. I have measured both sides again.
> >
> > Windows 11, AMD xHCI, camera on a root port, 120 stream starts with
> > ffmpeg/DirectShow (MJPEG 1920x1080, and YUYV 1920x1080 for 5 of them),
> > captured with USBPcap and an ETW trace of USBXHCI/UCX/USBHUB3:
> >
> > - The requests are the same as on Linux: PROBE GET_CUR, SET_CUR,
> > GET_CUR, GET_MAX, GET_MIN, SET_CUR, GET_CUR, then a 26 byte COMMIT,
> > then SET_INTERFACE alt 6. There is nothing else in between.
> > - The SET_INTERFACE URB is submitted 22 us after the COMMIT completes.
> > The xHCI driver first runs a Configure Endpoint command (3 ms), then
> > queues the control transfer. That puts about 3 ms between the two
> > requests.
>
> When you say "then queurs the control transfer", you mean the control
> transfer for the SET_INTERFACE, right ?
>
> I wonder if the problem is that Linux is missing this Configure Endpoint
> command ?
>
> > - The control transfer completes successfully after 263 ms, every time
> > (402 ms for YUYV 1920x1080). In a 100 start run, the ETW trace shows
> > exactly 10 control transfers on the camera's EP0 per start (8 for
> > probe/commit and 2 for SET_INTERFACE alt 6/alt 0). There was no
> > Reset Endpoint command, and every xHCI command completed with Success.
> > Windows does not see an error and does not retry. 0 failures out of
> > 120.
> >
> > Linux 6.18, Raspberry Pi 4 (VL805 xHCI, camera behind the VL805's
> > internal USB 2.0 hub). I added an fsleep() right before
> > usb_set_interface() in uvc_video_start_transfer() and checked the
> > resulting gap in usbmon. 20 starts per value, MJPEG 1920x1080, auto
> > exposure:
> > > fsleep() COMMIT -> SET_INTERFACE (usbmon) first SET_INTERFACE -EPROTO
> > none 0.35 - 0.90 ms 1/20
> > 1 ms 1.53 - 1.84 ms 2/20
> > 5 ms 5.42 - 7.26 ms 6/20
> > 20 ms 20.4 - 26.4 ms 3/20
> > 100 ms 100.7 - 108.1 ms 5/20
> > 300 ms 319.5 - 325.2 ms 1/20
> >
> > So a delay does not help, even one longer than the time the device
> > takes to complete the request.
> >
> > The timing differs between failure and success. A failing
> > SET_INTERFACE completes with -EPROTO about 1 ms after it is submitted.
> > A successful one, whether the first attempt or the retry, takes about
> > 260 ms, the same as on Windows. My guess is that the device starts
> > reconfiguring right after the SETUP stage and sometimes fails to
> > answer the status stage for a few microframes before it starts
> > NAKing. The VL805 then reports a transaction error. I have no bus
> > analyzer to confirm this.
> >
> > I also need to correct the commit message: the failure rate is not a
> > stable 80%. Today it was between 0% and 50% per series of 10 to 20
> > starts, with auto exposure failing more often than manual exposure.
> > The retry always succeeded on the first attempt.
> >
> > With 0 out of 120 on Windows against roughly 15% per start on the Pi,
> > the difference is real. I can't tell yet whether it comes from the OS
> > or from the host controller. I haven't tested the camera with Linux
> > on a non-VL805 controller. I can do that before a v2 if it would help.
>
> Have you tried reproducing this on a different XHCI controller then
> the one found in the Raspberry Pi 4 ?
In particular the same one as the system running windows.
> I wonder if this problem
> is specific to the VL805 xHCI controller.
>
> Likewise have you tried reproducing this under Windows with an USB2.0
> hub in between ?
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] media: uvcvideo: Add quirk to retry SET_INTERFACE for SVBONY SV105C
2026-10-19 12:38 ` Laurent Pinchart
@ 2026-10-19 12:20 ` Ostashow Constantine
0 siblings, 0 replies; 8+ messages in thread
From: Ostashow Constantine @ 2026-10-19 12:20 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Hans de Goede, Mauro Carvalho Chehab, linux-media, linux-kernel, stable
To: Hans de Goede <hansg@kernel.org>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>, Mauro
Carvalho Chehab <mchehab@kernel.org>, linux-media@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH] media: uvcvideo: Add quirk to retry SET_INTERFACE
for SVBONY SV105C
In-Reply-To: <20261019123803.GA855235@killaraus.ideasonboard.com>
Hi Hans, Laurent,
On Mon, Oct 19, 2026 at 02:33:11PM +0200, Hans de Goede wrote:
> When you say "then queurs the control transfer", you mean the control
> transfer for the SET_INTERFACE, right ?
Yes. On Windows the order is: COMMIT completes, Configure Endpoint
command (about 3 ms), then the SET_INTERFACE control transfer.
> I wonder if the problem is that Linux is missing this Configure Endpoint
> command ?
It isn't. I traced the xhci-hcd events on the Pi for 20 stream starts
(MJPEG 1920x1080, auto exposure). Linux does the same thing in the same
order, because usb_set_interface() calls usb_hcd_alloc_bandwidth()
before it sends the request:
COMMIT status stage Success
+0.07-0.46 ms Configure Endpoint (Add: slot 1in, Isoc IN, maxp 1024,
burst 2, ESIT 3072) 0.23-0.26 ms, Success
+0.06-0.11 ms SET_INTERFACE alt 6 queued, doorbell
+0.9 ms Transfer Event 'USB Transaction Error' on the Status
Stage TRB
Reset Endpoint, Set TR Dequeue, Configure Endpoint
(Drop 1in), Configure Endpoint (Add 1in)
retry SET_INTERFACE alt 6, Success after 259-295 ms
The first SET_INTERFACE failed in 17 of the 20 starts, more often than
the roughly 15% I see without tracing, and the retry succeeded every
time. When the first attempt succeeds, it takes
260-262 ms. The error event always points at the Status Stage TRB, so
the Setup stage was accepted and the transaction error happens in the
status stage. That fits the guess in my previous mail.
Configure Endpoint itself is faster on the VL805: about 0.25 ms, against
2.7-3 ms on the AMD controller (see below, the same under Linux and
Windows). I don't think the timing explains the failure, though. The
fsleep() test in my previous mail put 1 to 300 ms between COMMIT and
SET_INTERFACE and did not help. On the AMD controller under Linux, the
gap between Configure Endpoint completion and the SETUP is even
shorter than on the Pi (0.02 ms), and nothing fails there.
On Mon, Oct 19, 2026 at 03:38:03PM +0300, Laurent Pinchart wrote:
> > Have you tried reproducing this on a different XHCI controller then
> > the one found in the Raspberry Pi 4 ?
>
> In particular the same one as the system running windows.
Yes, now. I booted Ubuntu 26.04 (kernel 7.0.0-30-generic, stock
uvcvideo, no patch) from a live USB stick on the Windows PC. The camera
was on the same AMD chipset xHCI (1022:43ee), behind the onboard GL850G
USB 2.0 hub (see below). The test was MJPEG 1920x1080 with auto exposure
and v4l2-ctl --stream-mmap:
- 50 stream starts without tracing: 0 failures.
- 30 stream starts with xhci-hcd trace events: 0 failures. Every
SET_INTERFACE alt 6 completed with Success on the first attempt, in
261-262 ms. There was no Transaction Error and no Reset Endpoint on
the camera's EP0 during stream start.
- The order is the same as on the Pi: COMMIT, Configure Endpoint,
SET_INTERFACE. Configure Endpoint takes 2.73-2.94 ms here, much like
the ~3 ms under Windows. The SETUP is queued 0.02 ms after it
completes.
(The only EP0 errors in the trace were two STALLs of
CLEAR_FEATURE(DEVICE_REMOTE_WAKEUP) when the camera resumed from
autosuspend. They are not related to stream start.)
So the same Linux code works on the AMD controller, with or without a
USB 2.0 hub in between. The failure looks specific to the Raspberry Pi
4's VL805 xHCI (or its internal hub): the status stage of this
particular request ends in a transaction error there, while the AMD
controller simply waits about 260 ms for the device to complete it.
> > Likewise have you tried reproducing this under Windows with an USB2.0
> > hub in between ?
Yes, now. Same PC, same AMD xHCI (chipset controller 1022:43ee). The
camera sat behind the board's onboard Genesys GL850G USB 2.0 hub
(05e3:0608), the same kind of topology as on the Pi, where the camera
is behind the VL805's internal hub. 120 starts with ffmpeg/DirectShow,
MJPEG 1920x1080, with an ETW trace of USBXHCI/UCX:
- 0 failures out of 120.
- Exactly 10 control transfers on the camera's EP0 per start, as on
the root port. No retries.
- No Reset Endpoint command at all. Every xHCI command completed with
Success: 240 Configure Endpoint (alt 6 and alt 0 per start); the
only other commands were Stop Endpoint and Set TR Dequeue.
- SET_INTERFACE alt 6 takes 262-263 ms, measured to the first isoch
transfer, the same as on the root port.
So on Windows a USB 2.0 hub in between doesn't make the camera fail.
Given that, how would you like v2? I can keep the retry as a UVC quirk
for this camera, or try to describe the VL805 behaviour to the xHCI
maintainers if you think it belongs there. The Pi 4 is a common host
for these astronomy cameras, so the quirk would help users either way.
Regards,
Constantine
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-10-19 15:20 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-19 11:07 [PATCH] media: uvcvideo: Add quirk to retry SET_INTERFACE for SVBONY SV105C Ostashow Constantine via B4 Relay
2026-10-19 11:17 ` Laurent Pinchart
2026-10-19 11:21 ` Hans de Goede
2026-10-19 11:27 ` Laurent Pinchart
2026-10-19 11:58 ` Константин Осташов
2026-10-19 12:33 ` Hans de Goede
2026-10-19 12:38 ` Laurent Pinchart
2026-10-19 12:20 ` Ostashow Constantine
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®