Re: [PATCH v1 3/4] media: uvcvideo: Constify formats, frames and intervals

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Laurent

On Thu, 20 Apr 2023 at 12:10, Laurent Pinchart
<laurent.pinchart@xxxxxxxxxxxxxxxx> wrote:
>
> The formats, frames and intervals stored in the uvc_streaming structure
> are not meant to change after being parsed at probe time. Make them
> const to prevent unintended modifications, and adapt the probe code
> accordingly to use non-const pointers during parsing.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
> ---
>  drivers/media/usb/uvc/uvc_driver.c | 38 +++++++++++++++---------------
>  drivers/media/usb/uvc/uvc_v4l2.c   | 31 ++++++++++++------------
>  drivers/media/usb/uvc/uvc_video.c  |  8 +++----
>  drivers/media/usb/uvc/uvcvideo.h   | 12 +++++-----
>  4 files changed, 45 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
> index 16a6ab437c6a..efc7a36a892e 100644
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -221,7 +221,8 @@ static struct uvc_streaming *uvc_stream_new(struct uvc_device *dev,
>
>  static int uvc_parse_format(struct uvc_device *dev,
>         struct uvc_streaming *streaming, struct uvc_format *format,
> -       u32 **intervals, unsigned char *buffer, int buflen)
> +       struct uvc_frame *frames, u32 **intervals, unsigned char *buffer,
> +       int buflen)
>  {
>         struct usb_interface *intf = streaming->intf;
>         struct usb_host_interface *alts = intf->cur_altsetting;
> @@ -235,6 +236,7 @@ static int uvc_parse_format(struct uvc_device *dev,
>
>         format->type = buffer[2];
>         format->index = buffer[3];
> +       format->frames = frames;
>
>         switch (buffer[2]) {
>         case UVC_VS_FORMAT_UNCOMPRESSED:
> @@ -339,8 +341,8 @@ static int uvc_parse_format(struct uvc_device *dev,
>                 ftype = 0;
>
>                 /* Create a dummy frame descriptor. */
> -               frame = &format->frames[0];
> -               memset(&format->frames[0], 0, sizeof(format->frames[0]));
> +               frame = &frames[0];
> +               memset(frame, 0, sizeof(*frame));
>                 frame->bFrameIntervalType = 1;
>                 frame->dwDefaultFrameInterval = 1;
>                 frame->dwFrameInterval = *intervals;
> @@ -370,7 +372,7 @@ static int uvc_parse_format(struct uvc_device *dev,
>          */
>         while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
>                buffer[2] == ftype) {
> -               frame = &format->frames[format->nframes];
> +               frame = &frames[format->nframes];
>                 if (ftype != UVC_VS_FRAME_FRAME_BASED)
>                         n = buflen > 25 ? buffer[25] : 0;
>                 else
> @@ -420,17 +422,6 @@ static int uvc_parse_format(struct uvc_device *dev,
>                         frame->dwMaxVideoFrameBufferSize = format->bpp
>                                 * frame->wWidth * frame->wHeight / 8;
>
> -               /*
> -                * Some bogus devices report dwMinFrameInterval equal to
> -                * dwMaxFrameInterval and have dwFrameIntervalStep set to
> -                * zero. Setting all null intervals to 1 fixes the problem and
> -                * some other divisions by zero that could happen.
> -                */
> -               for (i = 0; i < n; ++i) {
> -                       interval = get_unaligned_le32(&buffer[26+4*i]);
> -                       *(*intervals)++ = interval ? interval : 1;
> -               }
> -
>                 /*
>                  * Make sure that the default frame interval stays between
>                  * the boundaries.
> @@ -443,8 +434,18 @@ static int uvc_parse_format(struct uvc_device *dev,
>
>                 if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) {
>                         frame->bFrameIntervalType = 1;
> -                       frame->dwFrameInterval[0] =
> -                               frame->dwDefaultFrameInterval;
> +                       (*intervals)[0] = frame->dwDefaultFrameInterval;
> +               }
> +
> +               /*
> +                * Some bogus devices report dwMinFrameInterval equal to
> +                * dwMaxFrameInterval and have dwFrameIntervalStep set to
> +                * zero. Setting all null intervals to 1 fixes the problem and
> +                * some other divisions by zero that could happen.
> +                */
> +               for (i = 0; i < n; ++i) {
> +                       interval = get_unaligned_le32(&buffer[26+4*i]);
> +                       *(*intervals)++ = interval ? interval : 1;
>                 }

Aren't we overwriting the previous quirk here?

>
>                 uvc_dbg(dev, DESCR, "- %ux%u (%u.%u fps)\n",
> @@ -687,8 +688,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
>                 case UVC_VS_FORMAT_MJPEG:
>                 case UVC_VS_FORMAT_DV:
>                 case UVC_VS_FORMAT_FRAME_BASED:
> -                       format->frames = frame;
> -                       ret = uvc_parse_format(dev, streaming, format,
> +                       ret = uvc_parse_format(dev, streaming, format, frame,
>                                 &interval, buffer, buflen);
>                         if (ret < 0)
>                                 goto error;
> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
> index e7261b2543cb..5ac2a424b13d 100644
> --- a/drivers/media/usb/uvc/uvc_v4l2.c
> +++ b/drivers/media/usb/uvc/uvc_v4l2.c
> @@ -161,7 +161,7 @@ static int uvc_ioctl_xu_ctrl_map(struct uvc_video_chain *chain,
>   * the Video Probe and Commit negotiation, but some hardware don't implement
>   * that feature.
>   */
> -static u32 uvc_try_frame_interval(struct uvc_frame *frame, u32 interval)
> +static u32 uvc_try_frame_interval(const struct uvc_frame *frame, u32 interval)
>  {
>         unsigned int i;
>
> @@ -210,10 +210,11 @@ static u32 uvc_v4l2_get_bytesperline(const struct uvc_format *format,
>
>  static int uvc_v4l2_try_format(struct uvc_streaming *stream,
>         struct v4l2_format *fmt, struct uvc_streaming_control *probe,
> -       struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
> +       const struct uvc_format **uvc_format,
> +       const struct uvc_frame **uvc_frame)
>  {
> -       struct uvc_format *format = NULL;
> -       struct uvc_frame *frame = NULL;
> +       const struct uvc_format *format = NULL;
> +       const struct uvc_frame *frame = NULL;
>         u16 rw, rh;
>         unsigned int d, maxd;
>         unsigned int i;
> @@ -363,8 +364,8 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream,
>  static int uvc_v4l2_get_format(struct uvc_streaming *stream,
>         struct v4l2_format *fmt)
>  {
> -       struct uvc_format *format;
> -       struct uvc_frame *frame;
> +       const struct uvc_format *format;
> +       const struct uvc_frame *frame;
>         int ret = 0;
>
>         if (fmt->type != stream->type)
> @@ -398,8 +399,8 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream,
>         struct v4l2_format *fmt)
>  {
>         struct uvc_streaming_control probe;
> -       struct uvc_format *format;
> -       struct uvc_frame *frame;
> +       const struct uvc_format *format;
> +       const struct uvc_frame *frame;
>         int ret;
>
>         if (fmt->type != stream->type)
> @@ -465,8 +466,8 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
>  {
>         struct uvc_streaming_control probe;
>         struct v4l2_fract timeperframe;
> -       struct uvc_format *format;
> -       struct uvc_frame *frame;
> +       const struct uvc_format *format;
> +       const struct uvc_frame *frame;
>         u32 interval, maxd;
>         unsigned int i;
>         int ret;
> @@ -697,7 +698,7 @@ static int uvc_ioctl_querycap(struct file *file, void *fh,
>  static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream,
>                               struct v4l2_fmtdesc *fmt)
>  {
> -       struct uvc_format *format;
> +       const struct uvc_format *format;
>         enum v4l2_buf_type type = fmt->type;
>         u32 index = fmt->index;
>
> @@ -1249,8 +1250,8 @@ static int uvc_ioctl_enum_framesizes(struct file *file, void *fh,
>  {
>         struct uvc_fh *handle = fh;
>         struct uvc_streaming *stream = handle->stream;
> -       struct uvc_format *format = NULL;
> -       struct uvc_frame *frame = NULL;
> +       const struct uvc_format *format = NULL;
> +       const struct uvc_frame *frame = NULL;
>         unsigned int index;
>         unsigned int i;
>
> @@ -1289,8 +1290,8 @@ static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh,
>  {
>         struct uvc_fh *handle = fh;
>         struct uvc_streaming *stream = handle->stream;
> -       struct uvc_format *format = NULL;
> -       struct uvc_frame *frame = NULL;
> +       const struct uvc_format *format = NULL;
> +       const struct uvc_frame *frame = NULL;
>         unsigned int nintervals;
>         unsigned int index;
>         unsigned int i;
> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
> index 34c781b7dee2..28dde08ec6c5 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -137,8 +137,8 @@ static const struct usb_device_id elgato_cam_link_4k = {
>  static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
>         struct uvc_streaming_control *ctrl)
>  {
> -       struct uvc_format *format = NULL;
> -       struct uvc_frame *frame = NULL;
> +       const struct uvc_format *format = NULL;
> +       const struct uvc_frame *frame = NULL;
>         unsigned int i;
>
>         /*
> @@ -2100,8 +2100,8 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset)
>  int uvc_video_init(struct uvc_streaming *stream)
>  {
>         struct uvc_streaming_control *probe = &stream->ctrl;
> -       struct uvc_format *format = NULL;
> -       struct uvc_frame *frame = NULL;
> +       const struct uvc_format *format = NULL;
> +       const struct uvc_frame *frame = NULL;
>         struct uvc_urb *uvc_urb;
>         unsigned int i;
>         int ret;
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index 7b4bf52da19d..e04e1e6f4cba 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -251,7 +251,7 @@ struct uvc_frame {
>         u32 dwMaxVideoFrameBufferSize;
>         u8  bFrameIntervalType;
>         u32 dwDefaultFrameInterval;
> -       u32 *dwFrameInterval;
> +       const u32 *dwFrameInterval;
>  };
>
>  struct uvc_format {
> @@ -265,7 +265,7 @@ struct uvc_format {
>         u32 flags;
>
>         unsigned int nframes;
> -       struct uvc_frame *frames;
> +       const struct uvc_frame *frames;
>  };
>
>  struct uvc_streaming_header {
> @@ -438,12 +438,12 @@ struct uvc_streaming {
>         enum v4l2_buf_type type;
>
>         unsigned int nformats;
> -       struct uvc_format *formats;
> +       const struct uvc_format *formats;
>
>         struct uvc_streaming_control ctrl;
> -       struct uvc_format *def_format;
> -       struct uvc_format *cur_format;
> -       struct uvc_frame *cur_frame;
> +       const struct uvc_format *def_format;
> +       const struct uvc_format *cur_format;
> +       const struct uvc_frame *cur_frame;
>
>         /*
>          * Protect access to ctrl, cur_format, cur_frame and hardware video
> --
> Regards,
>
> Laurent Pinchart
>


-- 
Ricardo Ribalda



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux