--- zzzz-none-000/linux-3.10.107/drivers/media/usb/pwc/pwc-if.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/media/usb/pwc/pwc-if.c 2021-02-04 17:41:59.000000000 +0000 @@ -241,9 +241,9 @@ PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);" " discarded.\n", fbuf->filled); } else { - fbuf->vb.v4l2_buf.field = V4L2_FIELD_NONE; - fbuf->vb.v4l2_buf.sequence = pdev->vframe_count; - vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE); + fbuf->vb.field = V4L2_FIELD_NONE; + fbuf->vb.sequence = pdev->vframe_count; + vb2_buffer_done(&fbuf->vb.vb2_buf, VB2_BUF_STATE_DONE); pdev->fill_buf = NULL; pdev->vsync = 0; } @@ -288,7 +288,7 @@ { PWC_ERROR("Too many ISOC errors, bailing out.\n"); if (pdev->fill_buf) { - vb2_buffer_done(&pdev->fill_buf->vb, + vb2_buffer_done(&pdev->fill_buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); pdev->fill_buf = NULL; } @@ -318,7 +318,7 @@ if (pdev->vsync == 1) { v4l2_get_timestamp( - &fbuf->vb.v4l2_buf.timestamp); + &fbuf->vb.timestamp); pdev->vsync = 2; } @@ -509,7 +509,8 @@ } /* Must be called with vb_queue_lock hold */ -static void pwc_cleanup_queued_bufs(struct pwc_device *pdev) +static void pwc_cleanup_queued_bufs(struct pwc_device *pdev, + enum vb2_buffer_state state) { unsigned long flags = 0; @@ -520,7 +521,7 @@ buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf, list); list_del(&buf->list); - vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); + vb2_buffer_done(&buf->vb.vb2_buf, state); } spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags); } @@ -571,7 +572,7 @@ /***************************************************************************/ /* Videobuf2 operations */ -static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, +static int queue_setup(struct vb2_queue *vq, const void *parg, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) { @@ -594,7 +595,9 @@ static int buffer_init(struct vb2_buffer *vb) { - struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct pwc_frame_buf *buf = + container_of(vbuf, struct pwc_frame_buf, vb); /* need vmalloc since frame buffer > 128K */ buf->data = vzalloc(PWC_FRAME_SIZE); @@ -615,22 +618,29 @@ return 0; } -static int buffer_finish(struct vb2_buffer *vb) +static void buffer_finish(struct vb2_buffer *vb) { struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue); - struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); - - /* - * Application has called dqbuf and is getting back a buffer we've - * filled, take the pwc data we've stored in buf->data and decompress - * it into a usable format, storing the result in the vb2_buffer - */ - return pwc_decompress(pdev, buf); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct pwc_frame_buf *buf = + container_of(vbuf, struct pwc_frame_buf, vb); + + if (vb->state == VB2_BUF_STATE_DONE) { + /* + * Application has called dqbuf and is getting back a buffer + * we've filled, take the pwc data we've stored in buf->data + * and decompress it into a usable format, storing the result + * in the vb2_buffer. + */ + pwc_decompress(pdev, buf); + } } static void buffer_cleanup(struct vb2_buffer *vb) { - struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct pwc_frame_buf *buf = + container_of(vbuf, struct pwc_frame_buf, vb); vfree(buf->data); } @@ -638,12 +648,14 @@ static void buffer_queue(struct vb2_buffer *vb) { struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue); - struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct pwc_frame_buf *buf = + container_of(vbuf, struct pwc_frame_buf, vb); unsigned long flags = 0; /* Check the device has not disconnected between prep and queuing */ if (!pdev->udev) { - vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); return; } @@ -672,29 +684,29 @@ pwc_set_leds(pdev, 0, 0); pwc_camera_power(pdev, 0); /* And cleanup any queued bufs!! */ - pwc_cleanup_queued_bufs(pdev); + pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED); } mutex_unlock(&pdev->v4l2_lock); return r; } -static int stop_streaming(struct vb2_queue *vq) +static void stop_streaming(struct vb2_queue *vq) { struct pwc_device *pdev = vb2_get_drv_priv(vq); - if (mutex_lock_interruptible(&pdev->v4l2_lock)) - return -ERESTARTSYS; + mutex_lock(&pdev->v4l2_lock); if (pdev->udev) { pwc_set_leds(pdev, 0, 0); pwc_camera_power(pdev, 0); pwc_isoc_cleanup(pdev); } - pwc_cleanup_queued_bufs(pdev); + pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_ERROR); + if (pdev->fill_buf) + vb2_buffer_done(&pdev->fill_buf->vb.vb2_buf, + VB2_BUF_STATE_ERROR); mutex_unlock(&pdev->v4l2_lock); - - return 0; } static struct vb2_ops pwc_vb_queue_ops = { @@ -1007,7 +1019,7 @@ pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf); pdev->vb_queue.ops = &pwc_vb_queue_ops; pdev->vb_queue.mem_ops = &vb2_vmalloc_memops; - pdev->vb_queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + pdev->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; rc = vb2_queue_init(&pdev->vb_queue); if (rc < 0) { PWC_ERROR("Oops, could not initialize vb2 queue.\n"); @@ -1019,7 +1031,6 @@ strcpy(pdev->vdev.name, name); pdev->vdev.queue = &pdev->vb_queue; pdev->vdev.queue->lock = &pdev->vb_queue_lock; - set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags); video_set_drvdata(&pdev->vdev, pdev); pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); @@ -1045,7 +1056,7 @@ /* Set the leds off */ pwc_set_leds(pdev, 0, 0); - /* Setup intial videomode */ + /* Setup initial videomode */ rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, V4L2_PIX_FMT_YUV420, 30, &compression, 1); if (rc) @@ -1084,7 +1095,6 @@ /* register webcam snapshot button input device */ pdev->button_dev = input_allocate_device(); if (!pdev->button_dev) { - PWC_ERROR("Err, insufficient memory for webcam snapshot button device."); rc = -ENOMEM; goto err_video_unreg; } @@ -1133,7 +1143,6 @@ if (pdev->vb_queue.streaming) pwc_isoc_cleanup(pdev); pdev->udev = NULL; - pwc_cleanup_queued_bufs(pdev); v4l2_device_disconnect(&pdev->v4l2_dev); video_unregister_device(&pdev->vdev);