On Wed Jan 14 10:32:14 2026 +0000, Ricardo Ribalda wrote:
> The uvc_alloc_urb_buffer() function implicitly depended on the
> stream->urb_size field, which was set by its caller,
> uvc_alloc_urb_buffers(). This implicit data flow makes the code harder
> to follow.
> 
> More importantly, stream->urb_size was updated within the allocation
> loop before the allocation was confirmed to be successful. If the
> allocation failed, the stream object would be left with a urb_size that
> doesn't correspond to valid, allocated URB buffers.
> 
> Refactor uvc_alloc_urb_buffer() to accept the buffer size as an explicit
> argument. This makes the function's dependencies clear and improves the
> robustness of the error handling path. The stream->urb_size is now set only
> after a complete and successful allocation.
> 
> This is a pure refactoring and introduces no functional changes.
> 
> Signed-off-by: Ricardo Ribalda <[email protected]>
> Reviewed-by: Laurent Pinchart <[email protected]>
> Tested-by: Itay Chamiel <[email protected]>
> Link: 
> https://patch.msgid.link/[email protected]
> Signed-off-by: Laurent Pinchart <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/usb/uvc/uvc_video.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

---

diff --git a/drivers/media/usb/uvc/uvc_video.c 
b/drivers/media/usb/uvc/uvc_video.c
index ec76595f3c4b..59eb95a4b70c 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -1771,12 +1771,13 @@ static void uvc_free_urb_buffers(struct uvc_streaming 
*stream)
 }
 
 static bool uvc_alloc_urb_buffer(struct uvc_streaming *stream,
-                                struct uvc_urb *uvc_urb, gfp_t gfp_flags)
+                                struct uvc_urb *uvc_urb, unsigned int size,
+                                gfp_t gfp_flags)
 {
        struct usb_device *udev = stream->dev->udev;
 
-       uvc_urb->buffer = usb_alloc_noncoherent(udev, stream->urb_size,
-                                               gfp_flags, &uvc_urb->dma,
+       uvc_urb->buffer = usb_alloc_noncoherent(udev, size, gfp_flags,
+                                               &uvc_urb->dma,
                                                uvc_stream_dir(stream),
                                                &uvc_urb->sgt);
        return !!uvc_urb->buffer;
@@ -1813,12 +1814,13 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming 
*stream,
 
        /* Retry allocations until one succeed. */
        for (; npackets > 0; npackets /= 2) {
-               stream->urb_size = psize * npackets;
+               unsigned int urb_size = psize * npackets;
 
                for (i = 0; i < UVC_URBS; ++i) {
                        struct uvc_urb *uvc_urb = &stream->uvc_urb[i];
 
-                       if (!uvc_alloc_urb_buffer(stream, uvc_urb, gfp_flags)) {
+                       if (!uvc_alloc_urb_buffer(stream, uvc_urb, urb_size,
+                                                 gfp_flags)) {
                                uvc_free_urb_buffers(stream);
                                break;
                        }
@@ -1830,6 +1832,7 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming 
*stream,
                        uvc_dbg(stream->dev, VIDEO,
                                "Allocated %u URB buffers of %ux%u bytes 
each\n",
                                UVC_URBS, npackets, psize);
+                       stream->urb_size = urb_size;
                        return npackets;
                }
        }
@@ -1837,7 +1840,6 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming 
*stream,
        uvc_dbg(stream->dev, VIDEO,
                "Failed to allocate URB buffers (%u bytes per packet)\n",
                psize);
-       stream->urb_size = 0;
        return 0;
 }
 
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to