On 05/12/2018 08:00 PM, Hans de Goede wrote:
> Hi Hans,
>
> Overall looks good, 1 comment inline.
>
>> - if (ret == 0 && gspca_dev->sd_desc->dq_callback) {
>> - mutex_lock(&gspca_dev->usb_lock);
>> - gspca_dev->usb_err = 0;
>> - if (gspca_dev->present)
>> - gspca_dev->sd_desc->dq_callback(gspca_dev);
>> - mutex_unlock(&gspca_dev->usb_lock);
>> - }
>> + if (!gspca_dev->sd_desc->dq_callback)
>> + return;
>>
>> - return ret;
>> + gspca_dev->usb_err = 0;
>> + gspca_dev->sd_desc->dq_callback(gspca_dev);
>> }
>
>
> You are loosing the "if (gspca_dev->present)" check around
> the dq_callback here, this may causes issues if the
> buffer_finish method gets called after the device has
> been unplugged.
Good catch, I've added the 'if' here.
>
> If the vb2 code takes care that the buffer_finish method
> doesn't get called then you may add my:
>
> Reviewed-by: Hans de Goede <[email protected]>
>
> To this patch.
>
> Patch 2-4 look good to and you may add my:
>
> Reviewed-by: Hans de Goede <[email protected]>
>
> To those too.
Thanks!
>
> Regards,
>
> Hans
>
>
> p.s.
>
> If the v4l2-ctl + vb2 frameworks take care of not having
> any driver callbacks called after disconnect, perhaps
> the present flag can be removed?
I actually tried that (using the video_is_registered() function
instead), but it is used all over in gspca subdrivers, and I didn't
want to change them all. It's easier to just keep the field.
The same is true for the streaming field, for that matter. It could
be replaced by a vb2 function, but it would require lots of changes
in gspca subdrivers as well.
Regards,
Hans
>
>
>
>> -/*
>> - * queue a video buffer
>> - *
>> - * Attempting to queue a buffer that has already been
>> - * queued will return -EINVAL.
>> - */
>> -static int vidioc_qbuf(struct file *file, void *priv,
>> - struct v4l2_buffer *v4l2_buf)
>> +static void gspca_buffer_queue(struct vb2_buffer *vb)
>> {
>> - struct gspca_dev *gspca_dev = video_drvdata(file);
>> - struct gspca_frame *frame;
>> - int i, index, ret;
>> -
>> - gspca_dbg(gspca_dev, D_FRAM, "qbuf %d\n", v4l2_buf->index);
>> -
>> - if (mutex_lock_interruptible(&gspca_dev->queue_lock))
>> - return -ERESTARTSYS;
>> -
>> - index = v4l2_buf->index;
>> - if ((unsigned) index >= gspca_dev->nframes) {
>> - gspca_dbg(gspca_dev, D_FRAM,
>> - "qbuf idx %d >= %d\n", index, gspca_dev->nframes);
>> - ret = -EINVAL;
>> - goto out;
>> - }
>> - if (v4l2_buf->memory != gspca_dev->memory) {
>> - gspca_dbg(gspca_dev, D_FRAM, "qbuf bad memory type\n");
>> - ret = -EINVAL;
>> - goto out;
>> - }
>> -
>> - frame = &gspca_dev->frame[index];
>> - if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) {
>> - gspca_dbg(gspca_dev, D_FRAM, "qbuf bad state\n");
>> - ret = -EINVAL;
>> - goto out;
>> - }
>> -
>> - frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED;
>> -
>> - if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) {
>> - frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr;
>> - frame->v4l2_buf.length = v4l2_buf->length;
>> - }
>> -
>> - /* put the buffer in the 'queued' queue */
>> - i = atomic_read(&gspca_dev->fr_q);
>> - gspca_dev->fr_queue[i] = index;
>> - atomic_set(&gspca_dev->fr_q, (i + 1) % GSPCA_MAX_FRAMES);
>> + struct gspca_dev *gspca_dev = vb2_get_drv_priv(vb->vb2_queue);
>> + struct gspca_buffer *buf = to_gspca_buffer(vb);
>> + unsigned long flags;
>>
>> - v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
>> - v4l2_buf->flags &= ~V4L2_BUF_FLAG_DONE;
>> - ret = 0;
>> -out:
>> - mutex_unlock(&gspca_dev->queue_lock);
>> - return ret;
>> + spin_lock_irqsave(&gspca_dev->qlock, flags);
>> + list_add_tail(&buf->list, &gspca_dev->buf_list);
>> + spin_unlock_irqrestore(&gspca_dev->qlock, flags);
>> }
>>
>> -/*
>> - * allocate the resources for read()
>> - */
>> -static int read_alloc(struct gspca_dev *gspca_dev,
>> - struct file *file)
>> +static void gspca_return_all_buffers(struct gspca_dev *gspca_dev,
>> + enum vb2_buffer_state state)
>> {
>> - struct v4l2_buffer v4l2_buf;
>> - int i, ret;
>> -
>> - gspca_dbg(gspca_dev, D_STREAM, "read alloc\n");
>> + struct gspca_buffer *buf, *node;
>> + unsigned long flags;
>>
>> - if (mutex_lock_interruptible(&gspca_dev->usb_lock))
>> - return -ERESTARTSYS;
>> -
>> - if (gspca_dev->nframes == 0) {
>> - struct v4l2_requestbuffers rb;
>> -
>> - memset(&rb, 0, sizeof rb);
>> - rb.count = gspca_dev->nbufread;
>> - rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
>> - rb.memory = GSPCA_MEMORY_READ;
>> - ret = vidioc_reqbufs(file, gspca_dev, &rb);
>> - if (ret != 0) {
>> - gspca_dbg(gspca_dev, D_STREAM, "read reqbuf err %d\n",
>> - ret);
>> - goto out;
>> - }
>> - memset(&v4l2_buf, 0, sizeof v4l2_buf);
>> - v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
>> - v4l2_buf.memory = GSPCA_MEMORY_READ;
>> - for (i = 0; i < gspca_dev->nbufread; i++) {
>> - v4l2_buf.index = i;
>> - ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
>> - if (ret != 0) {
>> - gspca_dbg(gspca_dev, D_STREAM, "read qbuf err:
>> %d\n",
>> - ret);
>> - goto out;
>> - }
>> - }
>> + spin_lock_irqsave(&gspca_dev->qlock, flags);
>> + list_for_each_entry_safe(buf, node, &gspca_dev->buf_list, list) {
>> + vb2_buffer_done(&buf->vb.vb2_buf, state);
>> + list_del(&buf->list);
>> }
>> -
>> - /* start streaming */
>> - ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE);
>> - if (ret != 0)
>> - gspca_dbg(gspca_dev, D_STREAM, "read streamon err %d\n", ret);
>> -out:
>> - mutex_unlock(&gspca_dev->usb_lock);
>> - return ret;
>> + spin_unlock_irqrestore(&gspca_dev->qlock, flags);
>> }
>>
>> -static __poll_t dev_poll(struct file *file, poll_table *wait)
>> +static int gspca_start_streaming(struct vb2_queue *vq, unsigned int count)
>> {
>> - struct gspca_dev *gspca_dev = video_drvdata(file);
>> - __poll_t req_events = poll_requested_events(wait);
>> - __poll_t ret = 0;
>> -
>> - gspca_dbg(gspca_dev, D_FRAM, "poll\n");
>> -
>> - if (req_events & EPOLLPRI)
>> - ret |= v4l2_ctrl_poll(file, wait);
>> -
>> - if (req_events & (EPOLLIN | EPOLLRDNORM)) {
>> - /* if reqbufs is not done, the user would use read() */
>> - if (gspca_dev->memory == GSPCA_MEMORY_NO) {
>> - if (read_alloc(gspca_dev, file) != 0) {
>> - ret |= EPOLLERR;
>> - goto out;
>> - }
>> - }
>> -
>> - poll_wait(file, &gspca_dev->wq, wait);
>> -
>> - /* check if an image has been received */
>> - if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) {
>> - ret |= EPOLLERR;
>> - goto out;
>> - }
>> - if (gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i))
>> - ret |= EPOLLIN | EPOLLRDNORM;
>> - mutex_unlock(&gspca_dev->queue_lock);
>> - }
>> + struct gspca_dev *gspca_dev = vb2_get_drv_priv(vq);
>> + int ret;
>>
>> -out:
>> - if (!gspca_dev->present)
>> - ret |= EPOLLHUP;
>> + gspca_dev->sequence = 0;
>>
>> + ret = gspca_init_transfer(gspca_dev);
>> + if (ret)
>> + gspca_return_all_buffers(gspca_dev, VB2_BUF_STATE_QUEUED);
>> return ret;
>> }
>>
>> -static ssize_t dev_read(struct file *file, char __user *data,
>> - size_t count, loff_t *ppos)
>> +static void gspca_stop_streaming(struct vb2_queue *vq)
>> {
>> - struct gspca_dev *gspca_dev = video_drvdata(file);
>> - struct gspca_frame *frame;
>> - struct v4l2_buffer v4l2_buf;
>> - struct timeval timestamp;
>> - int n, ret, ret2;
>> -
>> - gspca_dbg(gspca_dev, D_FRAM, "read (%zd)\n", count);
>> - if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */
>> - ret = read_alloc(gspca_dev, file);
>> - if (ret != 0)
>> - return ret;
>> - }
>> + struct gspca_dev *gspca_dev = vb2_get_drv_priv(vq);
>>
>> - /* get a frame */
>> - v4l2_get_timestamp(×tamp);
>> - timestamp.tv_sec--;
>> - n = 2;
>> - for (;;) {
>> - memset(&v4l2_buf, 0, sizeof v4l2_buf);
>> - v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
>> - v4l2_buf.memory = GSPCA_MEMORY_READ;
>> - ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf);
>> - if (ret != 0) {
>> - gspca_dbg(gspca_dev, D_STREAM, "read dqbuf err %d\n",
>> - ret);
>> - return ret;
>> - }
>> -
>> - /* if the process slept for more than 1 second,
>> - * get a newer frame */
>> - frame = &gspca_dev->frame[v4l2_buf.index];
>> - if (--n < 0)
>> - break; /* avoid infinite loop */
>> - if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec)
>> - break;
>> - ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
>> - if (ret != 0) {
>> - gspca_dbg(gspca_dev, D_STREAM, "read qbuf err %d\n",
>> - ret);
>> - return ret;
>> - }
>> - }
>> + gspca_stream_off(gspca_dev);
>>
>> - /* copy the frame */
>> - if (count > frame->v4l2_buf.bytesused)
>> - count = frame->v4l2_buf.bytesused;
>> - ret = copy_to_user(data, frame->data, count);
>> - if (ret != 0) {
>> - gspca_err(gspca_dev, "read cp to user lack %d / %zd\n",
>> - ret, count);
>> - ret = -EFAULT;
>> - goto out;
>> - }
>> - ret = count;
>> -out:
>> - /* in each case, requeue the buffer */
>> - ret2 = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
>> - if (ret2 != 0)
>> - return ret2;
>> - return ret;
>> + /* Release all active buffers */
>> + gspca_return_all_buffers(gspca_dev, VB2_BUF_STATE_ERROR);
>> }
>>
>> +static const struct vb2_ops gspca_qops = {
>> + .queue_setup = gspca_queue_setup,
>> + .buf_prepare = gspca_buffer_prepare,
>> + .buf_finish = gspca_buffer_finish,
>> + .buf_queue = gspca_buffer_queue,
>> + .start_streaming = gspca_start_streaming,
>> + .stop_streaming = gspca_stop_streaming,
>> + .wait_prepare = vb2_ops_wait_prepare,
>> + .wait_finish = vb2_ops_wait_finish,
>> +};
>> +
>> static const struct v4l2_file_operations dev_fops = {
>> .owner = THIS_MODULE,
>> - .open = dev_open,
>> - .release = dev_close,
>> - .read = dev_read,
>> - .mmap = dev_mmap,
>> + .open = v4l2_fh_open,
>> + .release = vb2_fop_release,
>> .unlocked_ioctl = video_ioctl2,
>> - .poll = dev_poll,
>> + .read = vb2_fop_read,
>> + .mmap = vb2_fop_mmap,
>> + .poll = vb2_fop_poll,
>> };
>>
>> static const struct v4l2_ioctl_ops dev_ioctl_ops = {
>> .vidioc_querycap = vidioc_querycap,
>> - .vidioc_dqbuf = vidioc_dqbuf,
>> - .vidioc_qbuf = vidioc_qbuf,
>> .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
>> .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
>> .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
>> .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
>> - .vidioc_streamon = vidioc_streamon,
>> .vidioc_enum_input = vidioc_enum_input,
>> .vidioc_g_input = vidioc_g_input,
>> .vidioc_s_input = vidioc_s_input,
>> - .vidioc_reqbufs = vidioc_reqbufs,
>> - .vidioc_querybuf = vidioc_querybuf,
>> - .vidioc_streamoff = vidioc_streamoff,
>> .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
>> .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
>> .vidioc_g_parm = vidioc_g_parm,
>> .vidioc_s_parm = vidioc_s_parm,
>> .vidioc_enum_framesizes = vidioc_enum_framesizes,
>> .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
>> +
>> + .vidioc_reqbufs = vb2_ioctl_reqbufs,
>> + .vidioc_create_bufs = vb2_ioctl_create_bufs,
>> + .vidioc_querybuf = vb2_ioctl_querybuf,
>> + .vidioc_qbuf = vb2_ioctl_qbuf,
>> + .vidioc_dqbuf = vb2_ioctl_dqbuf,
>> + .vidioc_expbuf = vb2_ioctl_expbuf,
>> + .vidioc_streamon = vb2_ioctl_streamon,
>> + .vidioc_streamoff = vb2_ioctl_streamoff,
>> +
>> #ifdef CONFIG_VIDEO_ADV_DEBUG
>> .vidioc_g_chip_info = vidioc_g_chip_info,
>> .vidioc_g_register = vidioc_g_register,
>> @@ -2034,6 +1441,7 @@ int gspca_dev_probe2(struct usb_interface *intf,
>> {
>> struct gspca_dev *gspca_dev;
>> struct usb_device *dev = interface_to_usbdev(intf);
>> + struct vb2_queue *q;
>> int ret;
>>
>> pr_info("%s-" GSPCA_VERSION " probing %04x:%04x\n",
>> @@ -2078,20 +1486,37 @@ int gspca_dev_probe2(struct usb_interface *intf,
>> ret = v4l2_device_register(&intf->dev, &gspca_dev->v4l2_dev);
>> if (ret)
>> goto out;
>> + gspca_dev->present = true;
>> gspca_dev->sd_desc = sd_desc;
>> - gspca_dev->nbufread = 2;
>> gspca_dev->empty_packet = -1; /* don't check the empty packets */
>> gspca_dev->vdev = gspca_template;
>> gspca_dev->vdev.v4l2_dev = &gspca_dev->v4l2_dev;
>> video_set_drvdata(&gspca_dev->vdev, gspca_dev);
>> gspca_dev->module = module;
>> - gspca_dev->present = 1;
>>
>> mutex_init(&gspca_dev->usb_lock);
>> gspca_dev->vdev.lock = &gspca_dev->usb_lock;
>> - mutex_init(&gspca_dev->queue_lock);
>> init_waitqueue_head(&gspca_dev->wq);
>>
>> + /* Initialize the vb2 queue */
>> + q = &gspca_dev->queue;
>> + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
>> + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
>> + q->drv_priv = gspca_dev;
>> + q->buf_struct_size = sizeof(struct gspca_buffer);
>> + q->ops = &gspca_qops;
>> + q->mem_ops = &vb2_vmalloc_memops;
>> + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
>> + q->min_buffers_needed = 2;
>> + q->lock = &gspca_dev->usb_lock;
>> + ret = vb2_queue_init(q);
>> + if (ret)
>> + goto out;
>> + gspca_dev->vdev.queue = q;
>> +
>> + INIT_LIST_HEAD(&gspca_dev->buf_list);
>> + spin_lock_init(&gspca_dev->qlock);
>> +
>> /* configure the subdriver and initialize the USB device */
>> ret = sd_desc->config(gspca_dev, id);
>> if (ret < 0)
>> @@ -2109,14 +1534,6 @@ int gspca_dev_probe2(struct usb_interface *intf,
>> if (ret)
>> goto out;
>>
>> - /*
>> - * Don't take usb_lock for these ioctls. This improves latency if
>> - * usb_lock is taken for a long time, e.g. when changing a control
>> - * value, and a new frame is ready to be dequeued.
>> - */
>> - v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_DQBUF);
>> - v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QBUF);
>> - v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QUERYBUF);
>> #ifdef CONFIG_VIDEO_ADV_DEBUG
>> if (!gspca_dev->sd_desc->get_register)
>> v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_REGISTER);
>> @@ -2198,8 +1615,8 @@ void gspca_disconnect(struct usb_interface *intf)
>> video_device_node_name(&gspca_dev->vdev));
>>
>> mutex_lock(&gspca_dev->usb_lock);
>> + gspca_dev->present = false;
>>
>> - gspca_dev->present = 0;
>> destroy_urbs(gspca_dev);
>>
>> #if IS_ENABLED(CONFIG_INPUT)
>> @@ -2211,11 +1628,8 @@ void gspca_disconnect(struct usb_interface *intf)
>> }
>> #endif
>> /* Free subdriver's streaming resources / stop sd workqueue(s) */
>> - if (gspca_dev->sd_desc->stop0 && gspca_dev->streaming)
>> - gspca_dev->sd_desc->stop0(gspca_dev);
>> - gspca_dev->streaming = 0;
>> + vb2_queue_release(&gspca_dev->queue);
>> gspca_dev->dev = NULL;
>> - wake_up_interruptible(&gspca_dev->wq);
>>
>> v4l2_device_disconnect(&gspca_dev->v4l2_dev);
>> video_unregister_device(&gspca_dev->vdev);
>> @@ -2234,7 +1648,7 @@ int gspca_suspend(struct usb_interface *intf,
>> pm_message_t message)
>>
>> gspca_input_destroy_urb(gspca_dev);
>>
>> - if (!gspca_dev->streaming)
>> + if (!vb2_start_streaming_called(&gspca_dev->queue))
>> return 0;
>>
>> mutex_lock(&gspca_dev->usb_lock);
>> @@ -2266,8 +1680,7 @@ int gspca_resume(struct usb_interface *intf)
>> * only write to the device registers on s_ctrl when streaming ->
>> * Clear streaming to avoid setting all ctrls twice.
>> */
>> - streaming = gspca_dev->streaming;
>> - gspca_dev->streaming = 0;
>> + streaming = vb2_start_streaming_called(&gspca_dev->queue);
>> if (streaming)
>> ret = gspca_init_transfer(gspca_dev);
>> else
>> diff --git a/drivers/media/usb/gspca/gspca.h
>> b/drivers/media/usb/gspca/gspca.h
>> index 249cb38a542f..b0ced2e14006 100644
>> --- a/drivers/media/usb/gspca/gspca.h
>> +++ b/drivers/media/usb/gspca/gspca.h
>> @@ -9,6 +9,8 @@
>> #include <media/v4l2-common.h>
>> #include <media/v4l2-ctrls.h>
>> #include <media/v4l2-device.h>
>> +#include <media/videobuf2-v4l2.h>
>> +#include <media/videobuf2-vmalloc.h>
>> #include <linux/mutex.h>
>>
>>
>> @@ -138,19 +140,22 @@ enum gspca_packet_type {
>> LAST_PACKET
>> };
>>
>> -struct gspca_frame {
>> - __u8 *data; /* frame buffer */
>> - int vma_use_count;
>> - struct v4l2_buffer v4l2_buf;
>> +struct gspca_buffer {
>> + struct vb2_v4l2_buffer vb;
>> + struct list_head list;
>> };
>>
>> +static inline struct gspca_buffer *to_gspca_buffer(struct vb2_buffer *vb2)
>> +{
>> + return container_of(vb2, struct gspca_buffer, vb.vb2_buf);
>> +}
>> +
>> struct gspca_dev {
>> struct video_device vdev; /* !! must be the first item */
>> struct module *module; /* subdriver handling the device */
>> struct v4l2_device v4l2_dev;
>> struct usb_device *dev;
>> - struct file *capt_file; /* file doing video capture */
>> - /* protected by queue_lock */
>> +
>> #if IS_ENABLED(CONFIG_INPUT)
>> struct input_dev *input_dev;
>> char phys[64]; /* physical device path */
>> @@ -176,34 +181,29 @@ struct gspca_dev {
>> struct urb *int_urb;
>> #endif
>>
>> - __u8 *frbuf; /* buffer for nframes */
>> - struct gspca_frame frame[GSPCA_MAX_FRAMES];
>> - u8 *image; /* image beeing filled */
>> - __u32 frsz; /* frame size */
>> + u8 *image; /* image being filled */
>> u32 image_len; /* current length of image */
>> - atomic_t fr_q; /* next frame to queue */
>> - atomic_t fr_i; /* frame being filled */
>> - signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */
>> - char nframes; /* number of frames */
>> - u8 fr_o; /* next frame to dequeue */
>> __u8 last_packet_type;
>> __s8 empty_packet; /* if (-1) don't check empty packets */
>> - __u8 streaming; /* protected by both mutexes (*) */
>> + bool streaming;
>>
>> __u8 curr_mode; /* current camera mode */
>> struct v4l2_pix_format pixfmt; /* current mode parameters */
>> __u32 sequence; /* frame sequence number */
>>
>> + struct vb2_queue queue;
>> +
>> + spinlock_t qlock;
>> + struct list_head buf_list;
>> +
>> wait_queue_head_t wq; /* wait queue */
>> struct mutex usb_lock; /* usb exchange protection */
>> - struct mutex queue_lock; /* ISOC queue protection */
>> int usb_err; /* USB error - protected by usb_lock */
>> u16 pkt_size; /* ISOC packet size */
>> #ifdef CONFIG_PM
>> char frozen; /* suspend - resume */
>> #endif
>> - char present; /* device connected */
>> - char nbufread; /* number of buffers for read() */
>> + bool present;
>> char memory; /* memory type (V4L2_MEMORY_xxx) */
>> __u8 iface; /* USB interface number */
>> __u8 alt; /* USB alternate setting */
>> diff --git a/drivers/media/usb/gspca/m5602/m5602_core.c
>> b/drivers/media/usb/gspca/m5602/m5602_core.c
>> index b83ec4285a0b..30b7cf1feedd 100644
>> --- a/drivers/media/usb/gspca/m5602/m5602_core.c
>> +++ b/drivers/media/usb/gspca/m5602/m5602_core.c
>> @@ -342,7 +342,7 @@ static void m5602_urb_complete(struct gspca_dev
>> *gspca_dev,
>> data += 4;
>> len -= 4;
>>
>> - if (cur_frame_len + len <= gspca_dev->frsz) {
>> + if (cur_frame_len + len <= gspca_dev->pixfmt.sizeimage) {
>> gspca_dbg(gspca_dev, D_FRAM, "Continuing frame %d
>> copying %d bytes\n",
>> sd->frame_count, len);
>>
>> @@ -351,7 +351,7 @@ static void m5602_urb_complete(struct gspca_dev
>> *gspca_dev,
>> } else {
>> /* Add the remaining data up to frame size */
>> gspca_frame_add(gspca_dev, INTER_PACKET, data,
>> - gspca_dev->frsz - cur_frame_len);
>> + gspca_dev->pixfmt.sizeimage - cur_frame_len);
>> }
>> }
>> }
>> diff --git a/drivers/media/usb/gspca/vc032x.c
>> b/drivers/media/usb/gspca/vc032x.c
>> index 6b11597977c9..52d071659634 100644
>> --- a/drivers/media/usb/gspca/vc032x.c
>> +++ b/drivers/media/usb/gspca/vc032x.c
>> @@ -3642,7 +3642,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
>> int size, l;
>>
>> l = gspca_dev->image_len;
>> - size = gspca_dev->frsz;
>> + size = gspca_dev->pixfmt.sizeimage;
>> if (len > size - l)
>> len = size - l;
>> }
>>