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 <hdego...@redhat.com>
> 
> To this patch.
> 
> Patch 2-4 look good to and you may add my:
> 
> Reviewed-by: Hans de Goede <hdego...@redhat.com>
> 
> 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(&timestamp);
>> -    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;
>>      }
>>

Reply via email to