drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++ drivers/media/usb/uvc/uvc_video.c | 10 ++++++++++ drivers/media/usb/uvc/uvcvideo.h | 1 + 3 files changed, 20 insertions(+)
From: chenchangcheng <chenchangcheng@kylinos.cn>
Some broken device return wrong dwMaxPayloadTransferSize fields,
as follows:
[ 218.211425] [pid:20391,cpu4,guvcview,3]uvcvideo: Trying format 0x47504a4d (MJPG): 640x480.
[ 218.211425] [pid:20391,cpu4,guvcview,4]uvcvideo: Using default frame interval 33333.3 us (30.0 fps).
[ 218.252532] [pid:20391,cpu4,guvcview,1]uvcvideo: Trying format 0x47504a4d (MJPG): 640x480.
[ 218.252532] [pid:20391,cpu4,guvcview,2]uvcvideo: Using default frame interval 33333.3 us (30.0 fps).
[ 218.293426] [pid:20391,cpu7,guvcview,8]videobuf2_common: __setup_offsets: buffer 0, plane 0 offset 0x00000000
[ 218.294067] [pid:20391,cpu7,guvcview,9]videobuf2_common: __setup_offsets: buffer 1, plane 0 offset 0x000e1000
[ 218.294433] [pid:20391,cpu7,guvcview,0]videobuf2_common: __setup_offsets: buffer 2, plane 0 offset 0x001c2000
[ 218.294677] [pid:20391,cpu7,guvcview,1]videobuf2_common: __setup_offsets: buffer 3, plane 0 offset 0x002a3000
[ 218.294677] [pid:20391,cpu7,guvcview,2]videobuf2_common: __vb2_queue_alloc: allocated 4 buffers, 1 plane(s) each
[ 218.294738] [pid:20391,cpu7,guvcview,3]uvcvideo: uvc_v4l2_mmap
[ 218.294799] [pid:20391,cpu7,guvcview,4]videobuf2_common: vb2_mmap: buffer 0, plane 0 successfully mapped
[ 218.294799] [pid:20391,cpu7,guvcview,5]uvcvideo: uvc_v4l2_mmap
[ 218.294830] [pid:20391,cpu7,guvcview,6]videobuf2_common: vb2_mmap: buffer 1, plane 0 successfully mapped
[ 218.294830] [pid:20391,cpu7,guvcview,7]uvcvideo: uvc_v4l2_mmap
[ 218.294830] [pid:20391,cpu7,guvcview,8]videobuf2_common: vb2_mmap: buffer 2, plane 0 successfully mapped
[ 218.294860] [pid:20391,cpu7,guvcview,9]uvcvideo: uvc_v4l2_mmap
[ 218.294860] [pid:20391,cpu7,guvcview,0]videobuf2_common: vb2_mmap: buffer 3, plane 0 successfully mapped
[ 218.294860] [pid:20391,cpu7,guvcview,1]videobuf2_common: vb2_core_qbuf: qbuf of buffer 0 succeeded
[ 218.294891] [pid:20391,cpu7,guvcview,2]videobuf2_common: vb2_core_qbuf: qbuf of buffer 1 succeeded
[ 218.294891] [pid:20391,cpu7,guvcview,3]videobuf2_common: vb2_core_qbuf: qbuf of buffer 2 succeeded
[ 218.294891] [pid:20391,cpu7,guvcview,4]videobuf2_common: vb2_core_qbuf: qbuf of buffer 3 succeeded
[ 218.294891] [pid:20391,cpu7,guvcview,5]uvcvideo: Setting frame interval to 1/25 (400000).
[ 218.632537] [pid:20427,cpu6,guvcview,8]uvcvideo: Device requested 2752512 B/frame bandwidth.
[ 218.632598] [pid:20427,cpu6,guvcview,9]uvcvideo: No fast enough alt setting for requested bandwidth.
The maximum packet size of the device is 3 * 1024,
but according to the logs above, the device needs to apply for a bandwidth of 0x2a0000.
Signed-off-by: chenchangcheng <chenchangcheng@kylinos.cn>
---
drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++
drivers/media/usb/uvc/uvc_video.c | 10 ++++++++++
drivers/media/usb/uvc/uvcvideo.h | 1 +
3 files changed, 20 insertions(+)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index deadbcea5e22..6d739c3cc88f 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -3188,6 +3188,15 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) },
+ /* Alcor Corp. Slave camera */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x1b17,
+ .idProduct = 0x6684,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_OVERFLOW_BANDWIDTH) },
/* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index e3567aeb0007..463d6bf2c7df 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -262,6 +262,16 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
ctrl->dwMaxPayloadTransferSize = bandwidth;
}
+
+ if (format->flags & UVC_FMT_FLAG_COMPRESSED &&
+ stream->dev->quirks & UVC_QUIRK_OVERFLOW_BANDWIDTH &&
+ ctrl->dwMaxPayloadTransferSize > stream->maxpsize) {
+ uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
+ exceededs the size of the ep max packet.
+ use the default value of 1024 bytes.\n",
+ ctrl->dwMaxPayloadTransferSize);
+ ctrl->dwMaxPayloadTransferSize = 1024;
+ }
}
static size_t uvc_video_ctrl_size(struct uvc_streaming *stream)
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 5e388f05f3fc..20be830d37c0 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -77,6 +77,7 @@
#define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000
#define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000
#define UVC_QUIRK_MJPEG_NO_EOF 0x00020000
+#define UVC_QUIRK_OVERFLOW_BANDWIDTH 0x00040000
/* Format flags */
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
base-commit: 4701f33a10702d5fc577c32434eb62adde0a1ae1
--
2.25.1
Hi chenchangcheng,
kernel test robot noticed the following build errors:
[auto build test ERROR on 4701f33a10702d5fc577c32434eb62adde0a1ae1]
url: https://github.com/intel-lab-lkp/linux/commits/chenchangcheng/media-uvcvideo-Fix-bandwidth-issue-for-Alcor-camera/20250318-165843
base: 4701f33a10702d5fc577c32434eb62adde0a1ae1
patch link: https://lore.kernel.org/r/20250318085724.1151547-1-ccc194101%40163.com
patch subject: [PATCH v2] media: uvcvideo: Fix bandwidth issue for Alcor camera
config: sparc-randconfig-r072-20250319 (https://download.01.org/0day-ci/archive/20250319/202503191330.AveQs7tb-lkp@intel.com/config)
compiler: sparc-linux-gcc (GCC) 13.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250319/202503191330.AveQs7tb-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202503191330.AveQs7tb-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/media/usb/uvc/uvc_video.c: In function 'uvc_fixup_video_ctrl':
>> drivers/media/usb/uvc/uvc_video.c:269:17: error: implicit declaration of function 'uvc_printk'; did you mean '_printk'? [-Werror=implicit-function-declaration]
269 | uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
| ^~~~~~~~~~
| _printk
drivers/media/usb/uvc/uvc_video.c:269:42: warning: missing terminating " character
269 | uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
| ^
>> drivers/media/usb/uvc/uvc_video.c:269:42: error: missing terminating " character
269 | uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/media/usb/uvc/uvc_video.c:270:28: error: 'exceededs' undeclared (first use in this function)
270 | exceededs the size of the ep max packet.
| ^~~~~~~~~
drivers/media/usb/uvc/uvc_video.c:270:28: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/media/usb/uvc/uvc_video.c:270:37: error: expected ')' before 'the'
270 | exceededs the size of the ep max packet.
| ^~~~
| )
drivers/media/usb/uvc/uvc_video.c:269:27: note: to match this '('
269 | uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
| ^
>> drivers/media/usb/uvc/uvc_video.c:271:64: error: stray '\' in program
271 | use the default value of 1024 bytes.\n",
| ^
drivers/media/usb/uvc/uvc_video.c:271:66: warning: missing terminating " character
271 | use the default value of 1024 bytes.\n",
| ^
drivers/media/usb/uvc/uvc_video.c:271:66: error: missing terminating " character
271 | use the default value of 1024 bytes.\n",
| ^~
cc1: some warnings being treated as errors
vim +269 drivers/media/usb/uvc/uvc_video.c
162
163 static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
164 struct uvc_streaming_control *ctrl)
165 {
166 const struct uvc_format *format = NULL;
167 const struct uvc_frame *frame = NULL;
168 unsigned int i;
169
170 /*
171 * The response of the Elgato Cam Link 4K is incorrect: The second byte
172 * contains bFormatIndex (instead of being the second byte of bmHint).
173 * The first byte is always zero. The third byte is always 1.
174 *
175 * The UVC 1.5 class specification defines the first five bits in the
176 * bmHint bitfield. The remaining bits are reserved and should be zero.
177 * Therefore a valid bmHint will be less than 32.
178 *
179 * Latest Elgato Cam Link 4K firmware as of 2021-03-23 needs this fix.
180 * MCU: 20.02.19, FPGA: 67
181 */
182 if (usb_match_one_id(stream->dev->intf, &elgato_cam_link_4k) &&
183 ctrl->bmHint > 255) {
184 u8 corrected_format_index = ctrl->bmHint >> 8;
185
186 uvc_dbg(stream->dev, VIDEO,
187 "Correct USB video probe response from {bmHint: 0x%04x, bFormatIndex: %u} to {bmHint: 0x%04x, bFormatIndex: %u}\n",
188 ctrl->bmHint, ctrl->bFormatIndex,
189 1, corrected_format_index);
190 ctrl->bmHint = 1;
191 ctrl->bFormatIndex = corrected_format_index;
192 }
193
194 for (i = 0; i < stream->nformats; ++i) {
195 if (stream->formats[i].index == ctrl->bFormatIndex) {
196 format = &stream->formats[i];
197 break;
198 }
199 }
200
201 if (format == NULL)
202 return;
203
204 for (i = 0; i < format->nframes; ++i) {
205 if (format->frames[i].bFrameIndex == ctrl->bFrameIndex) {
206 frame = &format->frames[i];
207 break;
208 }
209 }
210
211 if (frame == NULL)
212 return;
213
214 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) ||
215 (ctrl->dwMaxVideoFrameSize == 0 &&
216 stream->dev->uvc_version < 0x0110))
217 ctrl->dwMaxVideoFrameSize =
218 frame->dwMaxVideoFrameBufferSize;
219
220 /*
221 * The "TOSHIBA Web Camera - 5M" Chicony device (04f2:b50b) seems to
222 * compute the bandwidth on 16 bits and erroneously sign-extend it to
223 * 32 bits, resulting in a huge bandwidth value. Detect and fix that
224 * condition by setting the 16 MSBs to 0 when they're all equal to 1.
225 */
226 if ((ctrl->dwMaxPayloadTransferSize & 0xffff0000) == 0xffff0000)
227 ctrl->dwMaxPayloadTransferSize &= ~0xffff0000;
228
229 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) &&
230 stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
231 stream->intf->num_altsetting > 1) {
232 u32 interval;
233 u32 bandwidth;
234
235 interval = (ctrl->dwFrameInterval > 100000)
236 ? ctrl->dwFrameInterval
237 : frame->dwFrameInterval[0];
238
239 /*
240 * Compute a bandwidth estimation by multiplying the frame
241 * size by the number of video frames per second, divide the
242 * result by the number of USB frames (or micro-frames for
243 * high- and super-speed devices) per second and add the UVC
244 * header size (assumed to be 12 bytes long).
245 */
246 bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
247 bandwidth *= 10000000 / interval + 1;
248 bandwidth /= 1000;
249 if (stream->dev->udev->speed >= USB_SPEED_HIGH)
250 bandwidth /= 8;
251 bandwidth += 12;
252
253 /*
254 * The bandwidth estimate is too low for many cameras. Don't use
255 * maximum packet sizes lower than 1024 bytes to try and work
256 * around the problem. According to measurements done on two
257 * different camera models, the value is high enough to get most
258 * resolutions working while not preventing two simultaneous
259 * VGA streams at 15 fps.
260 */
261 bandwidth = max_t(u32, bandwidth, 1024);
262
263 ctrl->dwMaxPayloadTransferSize = bandwidth;
264 }
265
266 if (format->flags & UVC_FMT_FLAG_COMPRESSED &&
267 stream->dev->quirks & UVC_QUIRK_OVERFLOW_BANDWIDTH &&
268 ctrl->dwMaxPayloadTransferSize > stream->maxpsize) {
> 269 uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
> 270 exceededs the size of the ep max packet.
> 271 use the default value of 1024 bytes.\n",
272 ctrl->dwMaxPayloadTransferSize);
273 ctrl->dwMaxPayloadTransferSize = 1024;
274 }
275 }
276
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi chenchangcheng,
kernel test robot noticed the following build errors:
[auto build test ERROR on 4701f33a10702d5fc577c32434eb62adde0a1ae1]
url: https://github.com/intel-lab-lkp/linux/commits/chenchangcheng/media-uvcvideo-Fix-bandwidth-issue-for-Alcor-camera/20250318-165843
base: 4701f33a10702d5fc577c32434eb62adde0a1ae1
patch link: https://lore.kernel.org/r/20250318085724.1151547-1-ccc194101%40163.com
patch subject: [PATCH v2] media: uvcvideo: Fix bandwidth issue for Alcor camera
config: i386-buildonly-randconfig-006-20250319 (https://download.01.org/0day-ci/archive/20250319/202503191353.gaC25wLw-lkp@intel.com/config)
compiler: clang version 20.1.0 (https://github.com/llvm/llvm-project 24a30daaa559829ad079f2ff7f73eb4e18095f88)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250319/202503191353.gaC25wLw-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202503191353.gaC25wLw-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/media/usb/uvc/uvc_video.c:269:3: error: call to undeclared function 'uvc_printk'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
269 | uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
| ^
drivers/media/usb/uvc/uvc_video.c:269:28: warning: missing terminating '"' character [-Winvalid-pp-token]
269 | uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
| ^
>> drivers/media/usb/uvc/uvc_video.c:269:28: error: expected expression
drivers/media/usb/uvc/uvc_video.c:271:45: warning: missing terminating '"' character [-Winvalid-pp-token]
271 | use the default value of 1024 bytes.\n",
| ^
2 warnings and 2 errors generated.
vim +/uvc_printk +269 drivers/media/usb/uvc/uvc_video.c
162
163 static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
164 struct uvc_streaming_control *ctrl)
165 {
166 const struct uvc_format *format = NULL;
167 const struct uvc_frame *frame = NULL;
168 unsigned int i;
169
170 /*
171 * The response of the Elgato Cam Link 4K is incorrect: The second byte
172 * contains bFormatIndex (instead of being the second byte of bmHint).
173 * The first byte is always zero. The third byte is always 1.
174 *
175 * The UVC 1.5 class specification defines the first five bits in the
176 * bmHint bitfield. The remaining bits are reserved and should be zero.
177 * Therefore a valid bmHint will be less than 32.
178 *
179 * Latest Elgato Cam Link 4K firmware as of 2021-03-23 needs this fix.
180 * MCU: 20.02.19, FPGA: 67
181 */
182 if (usb_match_one_id(stream->dev->intf, &elgato_cam_link_4k) &&
183 ctrl->bmHint > 255) {
184 u8 corrected_format_index = ctrl->bmHint >> 8;
185
186 uvc_dbg(stream->dev, VIDEO,
187 "Correct USB video probe response from {bmHint: 0x%04x, bFormatIndex: %u} to {bmHint: 0x%04x, bFormatIndex: %u}\n",
188 ctrl->bmHint, ctrl->bFormatIndex,
189 1, corrected_format_index);
190 ctrl->bmHint = 1;
191 ctrl->bFormatIndex = corrected_format_index;
192 }
193
194 for (i = 0; i < stream->nformats; ++i) {
195 if (stream->formats[i].index == ctrl->bFormatIndex) {
196 format = &stream->formats[i];
197 break;
198 }
199 }
200
201 if (format == NULL)
202 return;
203
204 for (i = 0; i < format->nframes; ++i) {
205 if (format->frames[i].bFrameIndex == ctrl->bFrameIndex) {
206 frame = &format->frames[i];
207 break;
208 }
209 }
210
211 if (frame == NULL)
212 return;
213
214 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) ||
215 (ctrl->dwMaxVideoFrameSize == 0 &&
216 stream->dev->uvc_version < 0x0110))
217 ctrl->dwMaxVideoFrameSize =
218 frame->dwMaxVideoFrameBufferSize;
219
220 /*
221 * The "TOSHIBA Web Camera - 5M" Chicony device (04f2:b50b) seems to
222 * compute the bandwidth on 16 bits and erroneously sign-extend it to
223 * 32 bits, resulting in a huge bandwidth value. Detect and fix that
224 * condition by setting the 16 MSBs to 0 when they're all equal to 1.
225 */
226 if ((ctrl->dwMaxPayloadTransferSize & 0xffff0000) == 0xffff0000)
227 ctrl->dwMaxPayloadTransferSize &= ~0xffff0000;
228
229 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) &&
230 stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
231 stream->intf->num_altsetting > 1) {
232 u32 interval;
233 u32 bandwidth;
234
235 interval = (ctrl->dwFrameInterval > 100000)
236 ? ctrl->dwFrameInterval
237 : frame->dwFrameInterval[0];
238
239 /*
240 * Compute a bandwidth estimation by multiplying the frame
241 * size by the number of video frames per second, divide the
242 * result by the number of USB frames (or micro-frames for
243 * high- and super-speed devices) per second and add the UVC
244 * header size (assumed to be 12 bytes long).
245 */
246 bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
247 bandwidth *= 10000000 / interval + 1;
248 bandwidth /= 1000;
249 if (stream->dev->udev->speed >= USB_SPEED_HIGH)
250 bandwidth /= 8;
251 bandwidth += 12;
252
253 /*
254 * The bandwidth estimate is too low for many cameras. Don't use
255 * maximum packet sizes lower than 1024 bytes to try and work
256 * around the problem. According to measurements done on two
257 * different camera models, the value is high enough to get most
258 * resolutions working while not preventing two simultaneous
259 * VGA streams at 15 fps.
260 */
261 bandwidth = max_t(u32, bandwidth, 1024);
262
263 ctrl->dwMaxPayloadTransferSize = bandwidth;
264 }
265
266 if (format->flags & UVC_FMT_FLAG_COMPRESSED &&
267 stream->dev->quirks & UVC_QUIRK_OVERFLOW_BANDWIDTH &&
268 ctrl->dwMaxPayloadTransferSize > stream->maxpsize) {
> 269 uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
270 exceededs the size of the ep max packet.
271 use the default value of 1024 bytes.\n",
272 ctrl->dwMaxPayloadTransferSize);
273 ctrl->dwMaxPayloadTransferSize = 1024;
274 }
275 }
276
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi chenchangcheng,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 4701f33a10702d5fc577c32434eb62adde0a1ae1]
url: https://github.com/intel-lab-lkp/linux/commits/chenchangcheng/media-uvcvideo-Fix-bandwidth-issue-for-Alcor-camera/20250318-165843
base: 4701f33a10702d5fc577c32434eb62adde0a1ae1
patch link: https://lore.kernel.org/r/20250318085724.1151547-1-ccc194101%40163.com
patch subject: [PATCH v2] media: uvcvideo: Fix bandwidth issue for Alcor camera
config: i386-buildonly-randconfig-006-20250319 (https://download.01.org/0day-ci/archive/20250319/202503191124.azEOPRHh-lkp@intel.com/config)
compiler: clang version 20.1.0 (https://github.com/llvm/llvm-project 24a30daaa559829ad079f2ff7f73eb4e18095f88)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250319/202503191124.azEOPRHh-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202503191124.azEOPRHh-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/media/usb/uvc/uvc_video.c:269:3: error: call to undeclared function 'uvc_printk'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
269 | uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
| ^
>> drivers/media/usb/uvc/uvc_video.c:269:28: warning: missing terminating '"' character [-Winvalid-pp-token]
269 | uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
| ^
drivers/media/usb/uvc/uvc_video.c:269:28: error: expected expression
drivers/media/usb/uvc/uvc_video.c:271:45: warning: missing terminating '"' character [-Winvalid-pp-token]
271 | use the default value of 1024 bytes.\n",
| ^
2 warnings and 2 errors generated.
vim +269 drivers/media/usb/uvc/uvc_video.c
162
163 static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
164 struct uvc_streaming_control *ctrl)
165 {
166 const struct uvc_format *format = NULL;
167 const struct uvc_frame *frame = NULL;
168 unsigned int i;
169
170 /*
171 * The response of the Elgato Cam Link 4K is incorrect: The second byte
172 * contains bFormatIndex (instead of being the second byte of bmHint).
173 * The first byte is always zero. The third byte is always 1.
174 *
175 * The UVC 1.5 class specification defines the first five bits in the
176 * bmHint bitfield. The remaining bits are reserved and should be zero.
177 * Therefore a valid bmHint will be less than 32.
178 *
179 * Latest Elgato Cam Link 4K firmware as of 2021-03-23 needs this fix.
180 * MCU: 20.02.19, FPGA: 67
181 */
182 if (usb_match_one_id(stream->dev->intf, &elgato_cam_link_4k) &&
183 ctrl->bmHint > 255) {
184 u8 corrected_format_index = ctrl->bmHint >> 8;
185
186 uvc_dbg(stream->dev, VIDEO,
187 "Correct USB video probe response from {bmHint: 0x%04x, bFormatIndex: %u} to {bmHint: 0x%04x, bFormatIndex: %u}\n",
188 ctrl->bmHint, ctrl->bFormatIndex,
189 1, corrected_format_index);
190 ctrl->bmHint = 1;
191 ctrl->bFormatIndex = corrected_format_index;
192 }
193
194 for (i = 0; i < stream->nformats; ++i) {
195 if (stream->formats[i].index == ctrl->bFormatIndex) {
196 format = &stream->formats[i];
197 break;
198 }
199 }
200
201 if (format == NULL)
202 return;
203
204 for (i = 0; i < format->nframes; ++i) {
205 if (format->frames[i].bFrameIndex == ctrl->bFrameIndex) {
206 frame = &format->frames[i];
207 break;
208 }
209 }
210
211 if (frame == NULL)
212 return;
213
214 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) ||
215 (ctrl->dwMaxVideoFrameSize == 0 &&
216 stream->dev->uvc_version < 0x0110))
217 ctrl->dwMaxVideoFrameSize =
218 frame->dwMaxVideoFrameBufferSize;
219
220 /*
221 * The "TOSHIBA Web Camera - 5M" Chicony device (04f2:b50b) seems to
222 * compute the bandwidth on 16 bits and erroneously sign-extend it to
223 * 32 bits, resulting in a huge bandwidth value. Detect and fix that
224 * condition by setting the 16 MSBs to 0 when they're all equal to 1.
225 */
226 if ((ctrl->dwMaxPayloadTransferSize & 0xffff0000) == 0xffff0000)
227 ctrl->dwMaxPayloadTransferSize &= ~0xffff0000;
228
229 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) &&
230 stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
231 stream->intf->num_altsetting > 1) {
232 u32 interval;
233 u32 bandwidth;
234
235 interval = (ctrl->dwFrameInterval > 100000)
236 ? ctrl->dwFrameInterval
237 : frame->dwFrameInterval[0];
238
239 /*
240 * Compute a bandwidth estimation by multiplying the frame
241 * size by the number of video frames per second, divide the
242 * result by the number of USB frames (or micro-frames for
243 * high- and super-speed devices) per second and add the UVC
244 * header size (assumed to be 12 bytes long).
245 */
246 bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
247 bandwidth *= 10000000 / interval + 1;
248 bandwidth /= 1000;
249 if (stream->dev->udev->speed >= USB_SPEED_HIGH)
250 bandwidth /= 8;
251 bandwidth += 12;
252
253 /*
254 * The bandwidth estimate is too low for many cameras. Don't use
255 * maximum packet sizes lower than 1024 bytes to try and work
256 * around the problem. According to measurements done on two
257 * different camera models, the value is high enough to get most
258 * resolutions working while not preventing two simultaneous
259 * VGA streams at 15 fps.
260 */
261 bandwidth = max_t(u32, bandwidth, 1024);
262
263 ctrl->dwMaxPayloadTransferSize = bandwidth;
264 }
265
266 if (format->flags & UVC_FMT_FLAG_COMPRESSED &&
267 stream->dev->quirks & UVC_QUIRK_OVERFLOW_BANDWIDTH &&
268 ctrl->dwMaxPayloadTransferSize > stream->maxpsize) {
> 269 uvc_printk(KERN_WARNING, "the max payload transmission size [%d]
270 exceededs the size of the ep max packet.
271 use the default value of 1024 bytes.\n",
272 ctrl->dwMaxPayloadTransferSize);
273 ctrl->dwMaxPayloadTransferSize = 1024;
274 }
275 }
276
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2025 Red Hat, Inc.