diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2011-10-24 10:53:59 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-12-11 08:13:06 -0500 |
commit | 6998b6fb4b1c8f320adeee938d399c4d8dcc90e2 (patch) | |
tree | 2a8e7687fe177c526fb518f22aff497bb4fcd98c | |
parent | 3d95e932573c316ad56b8e2f283e26de0b9c891c (diff) |
[media] uvcvideo: Use videobuf2-vmalloc
Replace the current video buffers queue implementation with
videobuf2-vmalloc.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/uvc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_queue.c | 556 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_v4l2.c | 20 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_video.c | 9 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvcvideo.h | 33 |
5 files changed, 161 insertions, 458 deletions
diff --git a/drivers/media/video/uvc/Kconfig b/drivers/media/video/uvc/Kconfig index 2956a763721..6c197da531b 100644 --- a/drivers/media/video/uvc/Kconfig +++ b/drivers/media/video/uvc/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config USB_VIDEO_CLASS | 1 | config USB_VIDEO_CLASS |
2 | tristate "USB Video Class (UVC)" | 2 | tristate "USB Video Class (UVC)" |
3 | select VIDEOBUF2_VMALLOC | ||
3 | ---help--- | 4 | ---help--- |
4 | Support for the USB Video Class (UVC). Currently only video | 5 | Support for the USB Video Class (UVC). Currently only video |
5 | input devices, such as webcams, are supported. | 6 | input devices, such as webcams, are supported. |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 0fbb04bc0b0..268be579aa7 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/atomic.h> | ||
14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
15 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
16 | #include <linux/list.h> | 17 | #include <linux/list.h> |
@@ -19,7 +20,7 @@ | |||
19 | #include <linux/videodev2.h> | 20 | #include <linux/videodev2.h> |
20 | #include <linux/vmalloc.h> | 21 | #include <linux/vmalloc.h> |
21 | #include <linux/wait.h> | 22 | #include <linux/wait.h> |
22 | #include <linux/atomic.h> | 23 | #include <media/videobuf2-vmalloc.h> |
23 | 24 | ||
24 | #include "uvcvideo.h" | 25 | #include "uvcvideo.h" |
25 | 26 | ||
@@ -29,470 +30,199 @@ | |||
29 | * Video queues is initialized by uvc_queue_init(). The function performs | 30 | * Video queues is initialized by uvc_queue_init(). The function performs |
30 | * basic initialization of the uvc_video_queue struct and never fails. | 31 | * basic initialization of the uvc_video_queue struct and never fails. |
31 | * | 32 | * |
32 | * Video buffer allocation and freeing are performed by uvc_alloc_buffers and | 33 | * Video buffers are managed by videobuf2. The driver uses a mutex to protect |
33 | * uvc_free_buffers respectively. The former acquires the video queue lock, | 34 | * the videobuf2 queue operations by serializing calls to videobuf2 and a |
34 | * while the later must be called with the lock held (so that allocation can | 35 | * spinlock to protect the IRQ queue that holds the buffers to be processed by |
35 | * free previously allocated buffers). Trying to free buffers that are mapped | 36 | * the driver. |
36 | * to user space will return -EBUSY. | ||
37 | * | ||
38 | * Video buffers are managed using two queues. However, unlike most USB video | ||
39 | * drivers that use an in queue and an out queue, we use a main queue to hold | ||
40 | * all queued buffers (both 'empty' and 'done' buffers), and an irq queue to | ||
41 | * hold empty buffers. This design (copied from video-buf) minimizes locking | ||
42 | * in interrupt, as only one queue is shared between interrupt and user | ||
43 | * contexts. | ||
44 | * | ||
45 | * Use cases | ||
46 | * --------- | ||
47 | * | ||
48 | * Unless stated otherwise, all operations that modify the irq buffers queue | ||
49 | * are protected by the irq spinlock. | ||
50 | * | ||
51 | * 1. The user queues the buffers, starts streaming and dequeues a buffer. | ||
52 | * | ||
53 | * The buffers are added to the main and irq queues. Both operations are | ||
54 | * protected by the queue lock, and the later is protected by the irq | ||
55 | * spinlock as well. | ||
56 | * | ||
57 | * The completion handler fetches a buffer from the irq queue and fills it | ||
58 | * with video data. If no buffer is available (irq queue empty), the handler | ||
59 | * returns immediately. | ||
60 | * | ||
61 | * When the buffer is full, the completion handler removes it from the irq | ||
62 | * queue, marks it as done (UVC_BUF_STATE_DONE) and wakes its wait queue. | ||
63 | * At that point, any process waiting on the buffer will be woken up. If a | ||
64 | * process tries to dequeue a buffer after it has been marked done, the | ||
65 | * dequeing will succeed immediately. | ||
66 | * | ||
67 | * 2. Buffers are queued, user is waiting on a buffer and the device gets | ||
68 | * disconnected. | ||
69 | * | ||
70 | * When the device is disconnected, the kernel calls the completion handler | ||
71 | * with an appropriate status code. The handler marks all buffers in the | ||
72 | * irq queue as being erroneous (UVC_BUF_STATE_ERROR) and wakes them up so | ||
73 | * that any process waiting on a buffer gets woken up. | ||
74 | * | ||
75 | * Waking up up the first buffer on the irq list is not enough, as the | ||
76 | * process waiting on the buffer might restart the dequeue operation | ||
77 | * immediately. | ||
78 | * | ||
79 | */ | 37 | */ |
80 | 38 | ||
81 | void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, | 39 | /* ----------------------------------------------------------------------------- |
82 | int drop_corrupted) | 40 | * videobuf2 queue operations |
83 | { | ||
84 | mutex_init(&queue->mutex); | ||
85 | spin_lock_init(&queue->irqlock); | ||
86 | INIT_LIST_HEAD(&queue->mainqueue); | ||
87 | INIT_LIST_HEAD(&queue->irqqueue); | ||
88 | queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0; | ||
89 | queue->type = type; | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Free the video buffers. | ||
94 | * | ||
95 | * This function must be called with the queue lock held. | ||
96 | */ | 41 | */ |
97 | static int __uvc_free_buffers(struct uvc_video_queue *queue) | 42 | |
43 | static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | ||
44 | unsigned int *nbuffers, unsigned int *nplanes, | ||
45 | unsigned int sizes[], void *alloc_ctxs[]) | ||
98 | { | 46 | { |
99 | unsigned int i; | 47 | struct uvc_video_queue *queue = vb2_get_drv_priv(vq); |
48 | struct uvc_streaming *stream = | ||
49 | container_of(queue, struct uvc_streaming, queue); | ||
100 | 50 | ||
101 | for (i = 0; i < queue->count; ++i) { | 51 | if (*nbuffers > UVC_MAX_VIDEO_BUFFERS) |
102 | if (queue->buffer[i].vma_use_count != 0) | 52 | *nbuffers = UVC_MAX_VIDEO_BUFFERS; |
103 | return -EBUSY; | ||
104 | } | ||
105 | 53 | ||
106 | if (queue->count) { | 54 | *nplanes = 1; |
107 | uvc_queue_cancel(queue, 0); | 55 | |
108 | INIT_LIST_HEAD(&queue->mainqueue); | 56 | sizes[0] = stream->ctrl.dwMaxVideoFrameSize; |
109 | vfree(queue->mem); | ||
110 | queue->count = 0; | ||
111 | } | ||
112 | 57 | ||
113 | return 0; | 58 | return 0; |
114 | } | 59 | } |
115 | 60 | ||
116 | int uvc_free_buffers(struct uvc_video_queue *queue) | 61 | static int uvc_buffer_prepare(struct vb2_buffer *vb) |
117 | { | 62 | { |
118 | int ret; | 63 | struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); |
119 | 64 | struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); | |
120 | mutex_lock(&queue->mutex); | ||
121 | ret = __uvc_free_buffers(queue); | ||
122 | mutex_unlock(&queue->mutex); | ||
123 | |||
124 | return ret; | ||
125 | } | ||
126 | 65 | ||
127 | /* | 66 | if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT && |
128 | * Allocate the video buffers. | 67 | vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) { |
129 | * | 68 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n"); |
130 | * Pages are reserved to make sure they will not be swapped, as they will be | 69 | return -EINVAL; |
131 | * filled in the URB completion handler. | 70 | } |
132 | * | ||
133 | * Buffers will be individually mapped, so they must all be page aligned. | ||
134 | */ | ||
135 | int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers, | ||
136 | unsigned int buflength) | ||
137 | { | ||
138 | unsigned int bufsize = PAGE_ALIGN(buflength); | ||
139 | unsigned int i; | ||
140 | void *mem = NULL; | ||
141 | int ret; | ||
142 | 71 | ||
143 | if (nbuffers > UVC_MAX_VIDEO_BUFFERS) | 72 | if (unlikely(queue->flags & UVC_QUEUE_DISCONNECTED)) |
144 | nbuffers = UVC_MAX_VIDEO_BUFFERS; | 73 | return -ENODEV; |
145 | 74 | ||
146 | mutex_lock(&queue->mutex); | 75 | buf->state = UVC_BUF_STATE_QUEUED; |
76 | buf->error = 0; | ||
77 | buf->mem = vb2_plane_vaddr(vb, 0); | ||
78 | buf->length = vb2_plane_size(vb, 0); | ||
79 | if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
80 | buf->bytesused = 0; | ||
81 | else | ||
82 | buf->bytesused = vb2_get_plane_payload(vb, 0); | ||
147 | 83 | ||
148 | if ((ret = __uvc_free_buffers(queue)) < 0) | 84 | return 0; |
149 | goto done; | 85 | } |
150 | 86 | ||
151 | /* Bail out if no buffers should be allocated. */ | 87 | static void uvc_buffer_queue(struct vb2_buffer *vb) |
152 | if (nbuffers == 0) | 88 | { |
153 | goto done; | 89 | struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); |
90 | struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); | ||
91 | unsigned long flags; | ||
154 | 92 | ||
155 | /* Decrement the number of buffers until allocation succeeds. */ | 93 | spin_lock_irqsave(&queue->irqlock, flags); |
156 | for (; nbuffers > 0; --nbuffers) { | 94 | if (likely(!(queue->flags & UVC_QUEUE_DISCONNECTED))) { |
157 | mem = vmalloc_32(nbuffers * bufsize); | 95 | list_add_tail(&buf->queue, &queue->irqqueue); |
158 | if (mem != NULL) | 96 | } else { |
159 | break; | 97 | /* If the device is disconnected return the buffer to userspace |
98 | * directly. The next QBUF call will fail with -ENODEV. | ||
99 | */ | ||
100 | buf->state = UVC_BUF_STATE_ERROR; | ||
101 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); | ||
160 | } | 102 | } |
161 | 103 | ||
162 | if (mem == NULL) { | 104 | spin_unlock_irqrestore(&queue->irqlock, flags); |
163 | ret = -ENOMEM; | 105 | } |
164 | goto done; | ||
165 | } | ||
166 | 106 | ||
167 | for (i = 0; i < nbuffers; ++i) { | 107 | static struct vb2_ops uvc_queue_qops = { |
168 | memset(&queue->buffer[i], 0, sizeof queue->buffer[i]); | 108 | .queue_setup = uvc_queue_setup, |
169 | queue->buffer[i].buf.index = i; | 109 | .buf_prepare = uvc_buffer_prepare, |
170 | queue->buffer[i].buf.m.offset = i * bufsize; | 110 | .buf_queue = uvc_buffer_queue, |
171 | queue->buffer[i].buf.length = buflength; | 111 | }; |
172 | queue->buffer[i].buf.type = queue->type; | ||
173 | queue->buffer[i].buf.field = V4L2_FIELD_NONE; | ||
174 | queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP; | ||
175 | queue->buffer[i].buf.flags = 0; | ||
176 | |||
177 | queue->buffer[i].mem = queue->mem + i * bufsize; | ||
178 | queue->buffer[i].length = buflength; | ||
179 | init_waitqueue_head(&queue->buffer[i].wait); | ||
180 | } | ||
181 | 112 | ||
182 | queue->mem = mem; | 113 | void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, |
183 | queue->count = nbuffers; | 114 | int drop_corrupted) |
184 | queue->buf_size = bufsize; | 115 | { |
185 | ret = nbuffers; | 116 | queue->queue.type = type; |
117 | queue->queue.io_modes = VB2_MMAP; | ||
118 | queue->queue.drv_priv = queue; | ||
119 | queue->queue.buf_struct_size = sizeof(struct uvc_buffer); | ||
120 | queue->queue.ops = &uvc_queue_qops; | ||
121 | queue->queue.mem_ops = &vb2_vmalloc_memops; | ||
122 | vb2_queue_init(&queue->queue); | ||
186 | 123 | ||
187 | done: | 124 | mutex_init(&queue->mutex); |
188 | mutex_unlock(&queue->mutex); | 125 | spin_lock_init(&queue->irqlock); |
189 | return ret; | 126 | INIT_LIST_HEAD(&queue->irqqueue); |
127 | queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0; | ||
190 | } | 128 | } |
191 | 129 | ||
192 | /* | 130 | /* ----------------------------------------------------------------------------- |
193 | * Check if buffers have been allocated. | 131 | * V4L2 queue operations |
194 | */ | 132 | */ |
195 | int uvc_queue_allocated(struct uvc_video_queue *queue) | 133 | |
134 | int uvc_alloc_buffers(struct uvc_video_queue *queue, | ||
135 | struct v4l2_requestbuffers *rb) | ||
196 | { | 136 | { |
197 | int allocated; | 137 | int ret; |
198 | 138 | ||
199 | mutex_lock(&queue->mutex); | 139 | mutex_lock(&queue->mutex); |
200 | allocated = queue->count != 0; | 140 | ret = vb2_reqbufs(&queue->queue, rb); |
201 | mutex_unlock(&queue->mutex); | 141 | mutex_unlock(&queue->mutex); |
202 | 142 | ||
203 | return allocated; | 143 | return ret ? ret : rb->count; |
204 | } | 144 | } |
205 | 145 | ||
206 | static void __uvc_query_buffer(struct uvc_buffer *buf, | 146 | void uvc_free_buffers(struct uvc_video_queue *queue) |
207 | struct v4l2_buffer *v4l2_buf) | ||
208 | { | 147 | { |
209 | memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf); | 148 | mutex_lock(&queue->mutex); |
210 | 149 | vb2_queue_release(&queue->queue); | |
211 | if (buf->vma_use_count) | 150 | mutex_unlock(&queue->mutex); |
212 | v4l2_buf->flags |= V4L2_BUF_FLAG_MAPPED; | ||
213 | |||
214 | switch (buf->state) { | ||
215 | case UVC_BUF_STATE_ERROR: | ||
216 | case UVC_BUF_STATE_DONE: | ||
217 | v4l2_buf->flags |= V4L2_BUF_FLAG_DONE; | ||
218 | break; | ||
219 | case UVC_BUF_STATE_QUEUED: | ||
220 | case UVC_BUF_STATE_ACTIVE: | ||
221 | case UVC_BUF_STATE_READY: | ||
222 | v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
223 | break; | ||
224 | case UVC_BUF_STATE_IDLE: | ||
225 | default: | ||
226 | break; | ||
227 | } | ||
228 | } | 151 | } |
229 | 152 | ||
230 | int uvc_query_buffer(struct uvc_video_queue *queue, | 153 | int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) |
231 | struct v4l2_buffer *v4l2_buf) | ||
232 | { | 154 | { |
233 | int ret = 0; | 155 | int ret; |
234 | 156 | ||
235 | mutex_lock(&queue->mutex); | 157 | mutex_lock(&queue->mutex); |
236 | if (v4l2_buf->index >= queue->count) { | 158 | ret = vb2_querybuf(&queue->queue, buf); |
237 | ret = -EINVAL; | ||
238 | goto done; | ||
239 | } | ||
240 | |||
241 | __uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf); | ||
242 | |||
243 | done: | ||
244 | mutex_unlock(&queue->mutex); | 159 | mutex_unlock(&queue->mutex); |
160 | |||
245 | return ret; | 161 | return ret; |
246 | } | 162 | } |
247 | 163 | ||
248 | /* | 164 | int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) |
249 | * Queue a video buffer. Attempting to queue a buffer that has already been | ||
250 | * queued will return -EINVAL. | ||
251 | */ | ||
252 | int uvc_queue_buffer(struct uvc_video_queue *queue, | ||
253 | struct v4l2_buffer *v4l2_buf) | ||
254 | { | 165 | { |
255 | struct uvc_buffer *buf; | 166 | int ret; |
256 | unsigned long flags; | ||
257 | int ret = 0; | ||
258 | |||
259 | uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index); | ||
260 | |||
261 | if (v4l2_buf->type != queue->type || | ||
262 | v4l2_buf->memory != V4L2_MEMORY_MMAP) { | ||
263 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " | ||
264 | "and/or memory (%u).\n", v4l2_buf->type, | ||
265 | v4l2_buf->memory); | ||
266 | return -EINVAL; | ||
267 | } | ||
268 | 167 | ||
269 | mutex_lock(&queue->mutex); | 168 | mutex_lock(&queue->mutex); |
270 | if (v4l2_buf->index >= queue->count) { | 169 | ret = vb2_qbuf(&queue->queue, buf); |
271 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n"); | ||
272 | ret = -EINVAL; | ||
273 | goto done; | ||
274 | } | ||
275 | |||
276 | buf = &queue->buffer[v4l2_buf->index]; | ||
277 | if (buf->state != UVC_BUF_STATE_IDLE) { | ||
278 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state " | ||
279 | "(%u).\n", buf->state); | ||
280 | ret = -EINVAL; | ||
281 | goto done; | ||
282 | } | ||
283 | |||
284 | if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | ||
285 | v4l2_buf->bytesused > buf->buf.length) { | ||
286 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n"); | ||
287 | ret = -EINVAL; | ||
288 | goto done; | ||
289 | } | ||
290 | |||
291 | spin_lock_irqsave(&queue->irqlock, flags); | ||
292 | if (queue->flags & UVC_QUEUE_DISCONNECTED) { | ||
293 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
294 | ret = -ENODEV; | ||
295 | goto done; | ||
296 | } | ||
297 | buf->state = UVC_BUF_STATE_QUEUED; | ||
298 | if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
299 | buf->bytesused = 0; | ||
300 | else | ||
301 | buf->bytesused = v4l2_buf->bytesused; | ||
302 | |||
303 | list_add_tail(&buf->stream, &queue->mainqueue); | ||
304 | list_add_tail(&buf->queue, &queue->irqqueue); | ||
305 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
306 | |||
307 | done: | ||
308 | mutex_unlock(&queue->mutex); | 170 | mutex_unlock(&queue->mutex); |
309 | return ret; | ||
310 | } | ||
311 | 171 | ||
312 | static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking) | 172 | return ret; |
313 | { | ||
314 | if (nonblocking) { | ||
315 | return (buf->state != UVC_BUF_STATE_QUEUED && | ||
316 | buf->state != UVC_BUF_STATE_ACTIVE && | ||
317 | buf->state != UVC_BUF_STATE_READY) | ||
318 | ? 0 : -EAGAIN; | ||
319 | } | ||
320 | |||
321 | return wait_event_interruptible(buf->wait, | ||
322 | buf->state != UVC_BUF_STATE_QUEUED && | ||
323 | buf->state != UVC_BUF_STATE_ACTIVE && | ||
324 | buf->state != UVC_BUF_STATE_READY); | ||
325 | } | 173 | } |
326 | 174 | ||
327 | /* | 175 | int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf, |
328 | * Dequeue a video buffer. If nonblocking is false, block until a buffer is | 176 | int nonblocking) |
329 | * available. | ||
330 | */ | ||
331 | int uvc_dequeue_buffer(struct uvc_video_queue *queue, | ||
332 | struct v4l2_buffer *v4l2_buf, int nonblocking) | ||
333 | { | 177 | { |
334 | struct uvc_buffer *buf; | 178 | int ret; |
335 | int ret = 0; | ||
336 | |||
337 | if (v4l2_buf->type != queue->type || | ||
338 | v4l2_buf->memory != V4L2_MEMORY_MMAP) { | ||
339 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " | ||
340 | "and/or memory (%u).\n", v4l2_buf->type, | ||
341 | v4l2_buf->memory); | ||
342 | return -EINVAL; | ||
343 | } | ||
344 | 179 | ||
345 | mutex_lock(&queue->mutex); | 180 | mutex_lock(&queue->mutex); |
346 | if (list_empty(&queue->mainqueue)) { | 181 | ret = vb2_dqbuf(&queue->queue, buf, nonblocking); |
347 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Empty buffer queue.\n"); | ||
348 | ret = -EINVAL; | ||
349 | goto done; | ||
350 | } | ||
351 | |||
352 | buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream); | ||
353 | if ((ret = uvc_queue_waiton(buf, nonblocking)) < 0) | ||
354 | goto done; | ||
355 | |||
356 | uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u bytes).\n", | ||
357 | buf->buf.index, buf->state, buf->buf.bytesused); | ||
358 | |||
359 | switch (buf->state) { | ||
360 | case UVC_BUF_STATE_ERROR: | ||
361 | uvc_trace(UVC_TRACE_CAPTURE, "[W] Corrupted data " | ||
362 | "(transmission error).\n"); | ||
363 | ret = -EIO; | ||
364 | case UVC_BUF_STATE_DONE: | ||
365 | buf->state = UVC_BUF_STATE_IDLE; | ||
366 | break; | ||
367 | |||
368 | case UVC_BUF_STATE_IDLE: | ||
369 | case UVC_BUF_STATE_QUEUED: | ||
370 | case UVC_BUF_STATE_ACTIVE: | ||
371 | case UVC_BUF_STATE_READY: | ||
372 | default: | ||
373 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u " | ||
374 | "(driver bug?).\n", buf->state); | ||
375 | ret = -EINVAL; | ||
376 | goto done; | ||
377 | } | ||
378 | |||
379 | list_del(&buf->stream); | ||
380 | __uvc_query_buffer(buf, v4l2_buf); | ||
381 | |||
382 | done: | ||
383 | mutex_unlock(&queue->mutex); | 182 | mutex_unlock(&queue->mutex); |
384 | return ret; | ||
385 | } | ||
386 | 183 | ||
387 | /* | 184 | return ret; |
388 | * VMA operations. | ||
389 | */ | ||
390 | static void uvc_vm_open(struct vm_area_struct *vma) | ||
391 | { | ||
392 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
393 | buffer->vma_use_count++; | ||
394 | } | ||
395 | |||
396 | static void uvc_vm_close(struct vm_area_struct *vma) | ||
397 | { | ||
398 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
399 | buffer->vma_use_count--; | ||
400 | } | 185 | } |
401 | 186 | ||
402 | static const struct vm_operations_struct uvc_vm_ops = { | ||
403 | .open = uvc_vm_open, | ||
404 | .close = uvc_vm_close, | ||
405 | }; | ||
406 | |||
407 | /* | ||
408 | * Memory-map a video buffer. | ||
409 | * | ||
410 | * This function implements video buffers memory mapping and is intended to be | ||
411 | * used by the device mmap handler. | ||
412 | */ | ||
413 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) | 187 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) |
414 | { | 188 | { |
415 | struct uvc_buffer *uninitialized_var(buffer); | 189 | int ret; |
416 | struct page *page; | ||
417 | unsigned long addr, start, size; | ||
418 | unsigned int i; | ||
419 | int ret = 0; | ||
420 | |||
421 | start = vma->vm_start; | ||
422 | size = vma->vm_end - vma->vm_start; | ||
423 | 190 | ||
424 | mutex_lock(&queue->mutex); | 191 | mutex_lock(&queue->mutex); |
192 | ret = vb2_mmap(&queue->queue, vma); | ||
193 | mutex_unlock(&queue->mutex); | ||
425 | 194 | ||
426 | for (i = 0; i < queue->count; ++i) { | 195 | return ret; |
427 | buffer = &queue->buffer[i]; | 196 | } |
428 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
429 | break; | ||
430 | } | ||
431 | |||
432 | if (i == queue->count || PAGE_ALIGN(size) != queue->buf_size) { | ||
433 | ret = -EINVAL; | ||
434 | goto done; | ||
435 | } | ||
436 | |||
437 | /* | ||
438 | * VM_IO marks the area as being an mmaped region for I/O to a | ||
439 | * device. It also prevents the region from being core dumped. | ||
440 | */ | ||
441 | vma->vm_flags |= VM_IO; | ||
442 | |||
443 | addr = (unsigned long)buffer->mem; | ||
444 | #ifdef CONFIG_MMU | ||
445 | while (size > 0) { | ||
446 | page = vmalloc_to_page((void *)addr); | ||
447 | if ((ret = vm_insert_page(vma, start, page)) < 0) | ||
448 | goto done; | ||
449 | |||
450 | start += PAGE_SIZE; | ||
451 | addr += PAGE_SIZE; | ||
452 | size -= PAGE_SIZE; | ||
453 | } | ||
454 | #endif | ||
455 | 197 | ||
456 | vma->vm_ops = &uvc_vm_ops; | 198 | unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, |
457 | vma->vm_private_data = buffer; | 199 | poll_table *wait) |
458 | uvc_vm_open(vma); | 200 | { |
201 | unsigned int ret; | ||
459 | 202 | ||
460 | done: | 203 | mutex_lock(&queue->mutex); |
204 | ret = vb2_poll(&queue->queue, file, wait); | ||
461 | mutex_unlock(&queue->mutex); | 205 | mutex_unlock(&queue->mutex); |
206 | |||
462 | return ret; | 207 | return ret; |
463 | } | 208 | } |
464 | 209 | ||
465 | /* | 210 | /* ----------------------------------------------------------------------------- |
466 | * Poll the video queue. | ||
467 | * | 211 | * |
468 | * This function implements video queue polling and is intended to be used by | ||
469 | * the device poll handler. | ||
470 | */ | 212 | */ |
471 | unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, | 213 | |
472 | poll_table *wait) | 214 | /* |
215 | * Check if buffers have been allocated. | ||
216 | */ | ||
217 | int uvc_queue_allocated(struct uvc_video_queue *queue) | ||
473 | { | 218 | { |
474 | struct uvc_buffer *buf; | 219 | int allocated; |
475 | unsigned int mask = 0; | ||
476 | 220 | ||
477 | mutex_lock(&queue->mutex); | 221 | mutex_lock(&queue->mutex); |
478 | if (list_empty(&queue->mainqueue)) { | 222 | allocated = vb2_is_busy(&queue->queue); |
479 | mask |= POLLERR; | ||
480 | goto done; | ||
481 | } | ||
482 | buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream); | ||
483 | |||
484 | poll_wait(file, &buf->wait, wait); | ||
485 | if (buf->state == UVC_BUF_STATE_DONE || | ||
486 | buf->state == UVC_BUF_STATE_ERROR) { | ||
487 | if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
488 | mask |= POLLIN | POLLRDNORM; | ||
489 | else | ||
490 | mask |= POLLOUT | POLLWRNORM; | ||
491 | } | ||
492 | |||
493 | done: | ||
494 | mutex_unlock(&queue->mutex); | 223 | mutex_unlock(&queue->mutex); |
495 | return mask; | 224 | |
225 | return allocated; | ||
496 | } | 226 | } |
497 | 227 | ||
498 | #ifndef CONFIG_MMU | 228 | #ifndef CONFIG_MMU |
@@ -543,27 +273,24 @@ done: | |||
543 | */ | 273 | */ |
544 | int uvc_queue_enable(struct uvc_video_queue *queue, int enable) | 274 | int uvc_queue_enable(struct uvc_video_queue *queue, int enable) |
545 | { | 275 | { |
546 | unsigned int i; | 276 | unsigned long flags; |
547 | int ret = 0; | 277 | int ret; |
548 | 278 | ||
549 | mutex_lock(&queue->mutex); | 279 | mutex_lock(&queue->mutex); |
550 | if (enable) { | 280 | if (enable) { |
551 | if (uvc_queue_streaming(queue)) { | 281 | ret = vb2_streamon(&queue->queue, queue->queue.type); |
552 | ret = -EBUSY; | 282 | if (ret < 0) |
553 | goto done; | 283 | goto done; |
554 | } | 284 | |
555 | queue->flags |= UVC_QUEUE_STREAMING; | ||
556 | queue->buf_used = 0; | 285 | queue->buf_used = 0; |
557 | } else { | 286 | } else { |
558 | uvc_queue_cancel(queue, 0); | 287 | ret = vb2_streamoff(&queue->queue, queue->queue.type); |
559 | INIT_LIST_HEAD(&queue->mainqueue); | 288 | if (ret < 0) |
560 | 289 | goto done; | |
561 | for (i = 0; i < queue->count; ++i) { | ||
562 | queue->buffer[i].error = 0; | ||
563 | queue->buffer[i].state = UVC_BUF_STATE_IDLE; | ||
564 | } | ||
565 | 290 | ||
566 | queue->flags &= ~UVC_QUEUE_STREAMING; | 291 | spin_lock_irqsave(&queue->irqlock, flags); |
292 | INIT_LIST_HEAD(&queue->irqqueue); | ||
293 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
567 | } | 294 | } |
568 | 295 | ||
569 | done: | 296 | done: |
@@ -594,12 +321,12 @@ void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect) | |||
594 | queue); | 321 | queue); |
595 | list_del(&buf->queue); | 322 | list_del(&buf->queue); |
596 | buf->state = UVC_BUF_STATE_ERROR; | 323 | buf->state = UVC_BUF_STATE_ERROR; |
597 | wake_up(&buf->wait); | 324 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); |
598 | } | 325 | } |
599 | /* This must be protected by the irqlock spinlock to avoid race | 326 | /* This must be protected by the irqlock spinlock to avoid race |
600 | * conditions between uvc_queue_buffer and the disconnection event that | 327 | * conditions between uvc_buffer_queue and the disconnection event that |
601 | * could result in an interruptible wait in uvc_dequeue_buffer. Do not | 328 | * could result in an interruptible wait in uvc_dequeue_buffer. Do not |
602 | * blindly replace this logic by checking for the UVC_DEV_DISCONNECTED | 329 | * blindly replace this logic by checking for the UVC_QUEUE_DISCONNECTED |
603 | * state outside the queue code. | 330 | * state outside the queue code. |
604 | */ | 331 | */ |
605 | if (disconnect) | 332 | if (disconnect) |
@@ -616,15 +343,12 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
616 | if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { | 343 | if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { |
617 | buf->error = 0; | 344 | buf->error = 0; |
618 | buf->state = UVC_BUF_STATE_QUEUED; | 345 | buf->state = UVC_BUF_STATE_QUEUED; |
619 | buf->buf.bytesused = 0; | 346 | vb2_set_plane_payload(&buf->buf, 0, 0); |
620 | return buf; | 347 | return buf; |
621 | } | 348 | } |
622 | 349 | ||
623 | spin_lock_irqsave(&queue->irqlock, flags); | 350 | spin_lock_irqsave(&queue->irqlock, flags); |
624 | list_del(&buf->queue); | 351 | list_del(&buf->queue); |
625 | buf->error = 0; | ||
626 | buf->state = UVC_BUF_STATE_DONE; | ||
627 | buf->buf.bytesused = buf->bytesused; | ||
628 | if (!list_empty(&queue->irqqueue)) | 352 | if (!list_empty(&queue->irqqueue)) |
629 | nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, | 353 | nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, |
630 | queue); | 354 | queue); |
@@ -632,7 +356,9 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
632 | nextbuf = NULL; | 356 | nextbuf = NULL; |
633 | spin_unlock_irqrestore(&queue->irqlock, flags); | 357 | spin_unlock_irqrestore(&queue->irqlock, flags); |
634 | 358 | ||
635 | wake_up(&buf->wait); | 359 | buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE; |
360 | vb2_set_plane_payload(&buf->buf, 0, buf->bytesused); | ||
361 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE); | ||
362 | |||
636 | return nextbuf; | 363 | return nextbuf; |
637 | } | 364 | } |
638 | |||
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index dadf11f704d..b1dc3e507fc 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
@@ -513,10 +513,7 @@ static int uvc_v4l2_release(struct file *file) | |||
513 | /* Only free resources if this is a privileged handle. */ | 513 | /* Only free resources if this is a privileged handle. */ |
514 | if (uvc_has_privileges(handle)) { | 514 | if (uvc_has_privileges(handle)) { |
515 | uvc_video_enable(stream, 0); | 515 | uvc_video_enable(stream, 0); |
516 | 516 | uvc_free_buffers(&stream->queue); | |
517 | if (uvc_free_buffers(&stream->queue) < 0) | ||
518 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " | ||
519 | "free buffers.\n"); | ||
520 | } | 517 | } |
521 | 518 | ||
522 | /* Release the file handle. */ | 519 | /* Release the file handle. */ |
@@ -914,19 +911,11 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
914 | 911 | ||
915 | /* Buffers & streaming */ | 912 | /* Buffers & streaming */ |
916 | case VIDIOC_REQBUFS: | 913 | case VIDIOC_REQBUFS: |
917 | { | ||
918 | struct v4l2_requestbuffers *rb = arg; | ||
919 | |||
920 | if (rb->type != stream->type || | ||
921 | rb->memory != V4L2_MEMORY_MMAP) | ||
922 | return -EINVAL; | ||
923 | |||
924 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 914 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
925 | return ret; | 915 | return ret; |
926 | 916 | ||
927 | mutex_lock(&stream->mutex); | 917 | mutex_lock(&stream->mutex); |
928 | ret = uvc_alloc_buffers(&stream->queue, rb->count, | 918 | ret = uvc_alloc_buffers(&stream->queue, arg); |
929 | stream->ctrl.dwMaxVideoFrameSize); | ||
930 | mutex_unlock(&stream->mutex); | 919 | mutex_unlock(&stream->mutex); |
931 | if (ret < 0) | 920 | if (ret < 0) |
932 | return ret; | 921 | return ret; |
@@ -934,18 +923,13 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
934 | if (ret == 0) | 923 | if (ret == 0) |
935 | uvc_dismiss_privileges(handle); | 924 | uvc_dismiss_privileges(handle); |
936 | 925 | ||
937 | rb->count = ret; | ||
938 | ret = 0; | 926 | ret = 0; |
939 | break; | 927 | break; |
940 | } | ||
941 | 928 | ||
942 | case VIDIOC_QUERYBUF: | 929 | case VIDIOC_QUERYBUF: |
943 | { | 930 | { |
944 | struct v4l2_buffer *buf = arg; | 931 | struct v4l2_buffer *buf = arg; |
945 | 932 | ||
946 | if (buf->type != stream->type) | ||
947 | return -EINVAL; | ||
948 | |||
949 | if (!uvc_has_privileges(handle)) | 933 | if (!uvc_has_privileges(handle)) |
950 | return -EBUSY; | 934 | return -EBUSY; |
951 | 935 | ||
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 00fe749c0cc..2995f26ccae 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -467,9 +467,10 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
467 | else | 467 | else |
468 | ktime_get_real_ts(&ts); | 468 | ktime_get_real_ts(&ts); |
469 | 469 | ||
470 | buf->buf.sequence = stream->sequence; | 470 | buf->buf.v4l2_buf.sequence = stream->sequence; |
471 | buf->buf.timestamp.tv_sec = ts.tv_sec; | 471 | buf->buf.v4l2_buf.timestamp.tv_sec = ts.tv_sec; |
472 | buf->buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC; | 472 | buf->buf.v4l2_buf.timestamp.tv_usec = |
473 | ts.tv_nsec / NSEC_PER_USEC; | ||
473 | 474 | ||
474 | /* TODO: Handle PTS and SCR. */ | 475 | /* TODO: Handle PTS and SCR. */ |
475 | buf->state = UVC_BUF_STATE_ACTIVE; | 476 | buf->state = UVC_BUF_STATE_ACTIVE; |
@@ -728,7 +729,7 @@ static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream, | |||
728 | if (buf->bytesused == stream->queue.buf_used) { | 729 | if (buf->bytesused == stream->queue.buf_used) { |
729 | stream->queue.buf_used = 0; | 730 | stream->queue.buf_used = 0; |
730 | buf->state = UVC_BUF_STATE_READY; | 731 | buf->state = UVC_BUF_STATE_READY; |
731 | buf->buf.sequence = ++stream->sequence; | 732 | buf->buf.v4l2_buf.sequence = ++stream->sequence; |
732 | uvc_queue_next_buffer(&stream->queue, buf); | 733 | uvc_queue_next_buffer(&stream->queue, buf); |
733 | stream->last_fid ^= UVC_STREAM_FID; | 734 | stream->last_fid ^= UVC_STREAM_FID; |
734 | } | 735 | } |
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 55f917105b5..8448edc3ecc 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/videodev2.h> | 13 | #include <linux/videodev2.h> |
14 | #include <media/media-device.h> | 14 | #include <media/media-device.h> |
15 | #include <media/v4l2-device.h> | 15 | #include <media/v4l2-device.h> |
16 | #include <media/videobuf2-core.h> | ||
16 | 17 | ||
17 | /* -------------------------------------------------------------------------- | 18 | /* -------------------------------------------------------------------------- |
18 | * UVC constants | 19 | * UVC constants |
@@ -319,13 +320,9 @@ enum uvc_buffer_state { | |||
319 | }; | 320 | }; |
320 | 321 | ||
321 | struct uvc_buffer { | 322 | struct uvc_buffer { |
322 | unsigned long vma_use_count; | 323 | struct vb2_buffer buf; |
323 | struct list_head stream; | ||
324 | |||
325 | /* Touched by interrupt handler. */ | ||
326 | struct v4l2_buffer buf; | ||
327 | struct list_head queue; | 324 | struct list_head queue; |
328 | wait_queue_head_t wait; | 325 | |
329 | enum uvc_buffer_state state; | 326 | enum uvc_buffer_state state; |
330 | unsigned int error; | 327 | unsigned int error; |
331 | 328 | ||
@@ -334,24 +331,17 @@ struct uvc_buffer { | |||
334 | unsigned int bytesused; | 331 | unsigned int bytesused; |
335 | }; | 332 | }; |
336 | 333 | ||
337 | #define UVC_QUEUE_STREAMING (1 << 0) | 334 | #define UVC_QUEUE_DISCONNECTED (1 << 0) |
338 | #define UVC_QUEUE_DISCONNECTED (1 << 1) | 335 | #define UVC_QUEUE_DROP_CORRUPTED (1 << 1) |
339 | #define UVC_QUEUE_DROP_CORRUPTED (1 << 2) | ||
340 | 336 | ||
341 | struct uvc_video_queue { | 337 | struct uvc_video_queue { |
342 | enum v4l2_buf_type type; | 338 | struct vb2_queue queue; |
339 | struct mutex mutex; /* Protects queue */ | ||
343 | 340 | ||
344 | void *mem; | ||
345 | unsigned int flags; | 341 | unsigned int flags; |
346 | |||
347 | unsigned int count; | ||
348 | unsigned int buf_size; | ||
349 | unsigned int buf_used; | 342 | unsigned int buf_used; |
350 | struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS]; | ||
351 | struct mutex mutex; /* protects buffers and mainqueue */ | ||
352 | spinlock_t irqlock; /* protects irqqueue */ | ||
353 | 343 | ||
354 | struct list_head mainqueue; | 344 | spinlock_t irqlock; /* Protects irqqueue */ |
355 | struct list_head irqqueue; | 345 | struct list_head irqqueue; |
356 | }; | 346 | }; |
357 | 347 | ||
@@ -391,6 +381,7 @@ struct uvc_streaming { | |||
391 | */ | 381 | */ |
392 | struct mutex mutex; | 382 | struct mutex mutex; |
393 | 383 | ||
384 | /* Buffers queue. */ | ||
394 | unsigned int frozen : 1; | 385 | unsigned int frozen : 1; |
395 | struct uvc_video_queue queue; | 386 | struct uvc_video_queue queue; |
396 | void (*decode) (struct urb *urb, struct uvc_streaming *video, | 387 | void (*decode) (struct urb *urb, struct uvc_streaming *video, |
@@ -520,8 +511,8 @@ extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); | |||
520 | extern void uvc_queue_init(struct uvc_video_queue *queue, | 511 | extern void uvc_queue_init(struct uvc_video_queue *queue, |
521 | enum v4l2_buf_type type, int drop_corrupted); | 512 | enum v4l2_buf_type type, int drop_corrupted); |
522 | extern int uvc_alloc_buffers(struct uvc_video_queue *queue, | 513 | extern int uvc_alloc_buffers(struct uvc_video_queue *queue, |
523 | unsigned int nbuffers, unsigned int buflength); | 514 | struct v4l2_requestbuffers *rb); |
524 | extern int uvc_free_buffers(struct uvc_video_queue *queue); | 515 | extern void uvc_free_buffers(struct uvc_video_queue *queue); |
525 | extern int uvc_query_buffer(struct uvc_video_queue *queue, | 516 | extern int uvc_query_buffer(struct uvc_video_queue *queue, |
526 | struct v4l2_buffer *v4l2_buf); | 517 | struct v4l2_buffer *v4l2_buf); |
527 | extern int uvc_queue_buffer(struct uvc_video_queue *queue, | 518 | extern int uvc_queue_buffer(struct uvc_video_queue *queue, |
@@ -543,7 +534,7 @@ extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, | |||
543 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); | 534 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); |
544 | static inline int uvc_queue_streaming(struct uvc_video_queue *queue) | 535 | static inline int uvc_queue_streaming(struct uvc_video_queue *queue) |
545 | { | 536 | { |
546 | return queue->flags & UVC_QUEUE_STREAMING; | 537 | return vb2_is_streaming(&queue->queue); |
547 | } | 538 | } |
548 | 539 | ||
549 | /* V4L2 interface */ | 540 | /* V4L2 interface */ |