1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/kernel.h>
15#include <linux/mm.h>
16#include <linux/list.h>
17#include <linux/module.h>
18#include <linux/usb.h>
19#include <linux/videodev2.h>
20#include <linux/vmalloc.h>
21#include <linux/wait.h>
22#include <asm/atomic.h>
23
24#include "uvcvideo.h"
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
82{
83 mutex_init(&queue->mutex);
84 spin_lock_init(&queue->irqlock);
85 INIT_LIST_HEAD(&queue->mainqueue);
86 INIT_LIST_HEAD(&queue->irqqueue);
87 queue->type = type;
88}
89
90
91
92
93
94
95
96
97
98int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
99 unsigned int buflength)
100{
101 unsigned int bufsize = PAGE_ALIGN(buflength);
102 unsigned int i;
103 void *mem = NULL;
104 int ret;
105
106 if (nbuffers > UVC_MAX_VIDEO_BUFFERS)
107 nbuffers = UVC_MAX_VIDEO_BUFFERS;
108
109 mutex_lock(&queue->mutex);
110
111 if ((ret = uvc_free_buffers(queue)) < 0)
112 goto done;
113
114
115 if (nbuffers == 0)
116 goto done;
117
118
119 for (; nbuffers > 0; --nbuffers) {
120 mem = vmalloc_32(nbuffers * bufsize);
121 if (mem != NULL)
122 break;
123 }
124
125 if (mem == NULL) {
126 ret = -ENOMEM;
127 goto done;
128 }
129
130 for (i = 0; i < nbuffers; ++i) {
131 memset(&queue->buffer[i], 0, sizeof queue->buffer[i]);
132 queue->buffer[i].buf.index = i;
133 queue->buffer[i].buf.m.offset = i * bufsize;
134 queue->buffer[i].buf.length = buflength;
135 queue->buffer[i].buf.type = queue->type;
136 queue->buffer[i].buf.sequence = 0;
137 queue->buffer[i].buf.field = V4L2_FIELD_NONE;
138 queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP;
139 queue->buffer[i].buf.flags = 0;
140 init_waitqueue_head(&queue->buffer[i].wait);
141 }
142
143 queue->mem = mem;
144 queue->count = nbuffers;
145 queue->buf_size = bufsize;
146 ret = nbuffers;
147
148done:
149 mutex_unlock(&queue->mutex);
150 return ret;
151}
152
153
154
155
156
157
158int uvc_free_buffers(struct uvc_video_queue *queue)
159{
160 unsigned int i;
161
162 for (i = 0; i < queue->count; ++i) {
163 if (queue->buffer[i].vma_use_count != 0)
164 return -EBUSY;
165 }
166
167 if (queue->count) {
168 vfree(queue->mem);
169 queue->count = 0;
170 }
171
172 return 0;
173}
174
175
176
177
178int uvc_queue_allocated(struct uvc_video_queue *queue)
179{
180 int allocated;
181
182 mutex_lock(&queue->mutex);
183 allocated = queue->count != 0;
184 mutex_unlock(&queue->mutex);
185
186 return allocated;
187}
188
189static void __uvc_query_buffer(struct uvc_buffer *buf,
190 struct v4l2_buffer *v4l2_buf)
191{
192 memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf);
193
194 if (buf->vma_use_count)
195 v4l2_buf->flags |= V4L2_BUF_FLAG_MAPPED;
196
197 switch (buf->state) {
198 case UVC_BUF_STATE_ERROR:
199 case UVC_BUF_STATE_DONE:
200 v4l2_buf->flags |= V4L2_BUF_FLAG_DONE;
201 break;
202 case UVC_BUF_STATE_QUEUED:
203 case UVC_BUF_STATE_ACTIVE:
204 v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
205 break;
206 case UVC_BUF_STATE_IDLE:
207 default:
208 break;
209 }
210}
211
212int uvc_query_buffer(struct uvc_video_queue *queue,
213 struct v4l2_buffer *v4l2_buf)
214{
215 int ret = 0;
216
217 mutex_lock(&queue->mutex);
218 if (v4l2_buf->index >= queue->count) {
219 ret = -EINVAL;
220 goto done;
221 }
222
223 __uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf);
224
225done:
226 mutex_unlock(&queue->mutex);
227 return ret;
228}
229
230
231
232
233
234int uvc_queue_buffer(struct uvc_video_queue *queue,
235 struct v4l2_buffer *v4l2_buf)
236{
237 struct uvc_buffer *buf;
238 unsigned long flags;
239 int ret = 0;
240
241 uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index);
242
243 if (v4l2_buf->type != queue->type ||
244 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
245 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
246 "and/or memory (%u).\n", v4l2_buf->type,
247 v4l2_buf->memory);
248 return -EINVAL;
249 }
250
251 mutex_lock(&queue->mutex);
252 if (v4l2_buf->index >= queue->count) {
253 uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n");
254 ret = -EINVAL;
255 goto done;
256 }
257
258 buf = &queue->buffer[v4l2_buf->index];
259 if (buf->state != UVC_BUF_STATE_IDLE) {
260 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state "
261 "(%u).\n", buf->state);
262 ret = -EINVAL;
263 goto done;
264 }
265
266 if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
267 v4l2_buf->bytesused > buf->buf.length) {
268 uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n");
269 ret = -EINVAL;
270 goto done;
271 }
272
273 spin_lock_irqsave(&queue->irqlock, flags);
274 if (queue->flags & UVC_QUEUE_DISCONNECTED) {
275 spin_unlock_irqrestore(&queue->irqlock, flags);
276 ret = -ENODEV;
277 goto done;
278 }
279 buf->state = UVC_BUF_STATE_QUEUED;
280 if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
281 buf->buf.bytesused = 0;
282 else
283 buf->buf.bytesused = v4l2_buf->bytesused;
284
285 list_add_tail(&buf->stream, &queue->mainqueue);
286 list_add_tail(&buf->queue, &queue->irqqueue);
287 spin_unlock_irqrestore(&queue->irqlock, flags);
288
289done:
290 mutex_unlock(&queue->mutex);
291 return ret;
292}
293
294static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking)
295{
296 if (nonblocking) {
297 return (buf->state != UVC_BUF_STATE_QUEUED &&
298 buf->state != UVC_BUF_STATE_ACTIVE)
299 ? 0 : -EAGAIN;
300 }
301
302 return wait_event_interruptible(buf->wait,
303 buf->state != UVC_BUF_STATE_QUEUED &&
304 buf->state != UVC_BUF_STATE_ACTIVE);
305}
306
307
308
309
310
311int uvc_dequeue_buffer(struct uvc_video_queue *queue,
312 struct v4l2_buffer *v4l2_buf, int nonblocking)
313{
314 struct uvc_buffer *buf;
315 int ret = 0;
316
317 if (v4l2_buf->type != queue->type ||
318 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
319 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
320 "and/or memory (%u).\n", v4l2_buf->type,
321 v4l2_buf->memory);
322 return -EINVAL;
323 }
324
325 mutex_lock(&queue->mutex);
326 if (list_empty(&queue->mainqueue)) {
327 uvc_trace(UVC_TRACE_CAPTURE, "[E] Empty buffer queue.\n");
328 ret = -EINVAL;
329 goto done;
330 }
331
332 buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream);
333 if ((ret = uvc_queue_waiton(buf, nonblocking)) < 0)
334 goto done;
335
336 uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u bytes).\n",
337 buf->buf.index, buf->state, buf->buf.bytesused);
338
339 switch (buf->state) {
340 case UVC_BUF_STATE_ERROR:
341 uvc_trace(UVC_TRACE_CAPTURE, "[W] Corrupted data "
342 "(transmission error).\n");
343 ret = -EIO;
344 case UVC_BUF_STATE_DONE:
345 buf->state = UVC_BUF_STATE_IDLE;
346 break;
347
348 case UVC_BUF_STATE_IDLE:
349 case UVC_BUF_STATE_QUEUED:
350 case UVC_BUF_STATE_ACTIVE:
351 default:
352 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u "
353 "(driver bug?).\n", buf->state);
354 ret = -EINVAL;
355 goto done;
356 }
357
358 list_del(&buf->stream);
359 __uvc_query_buffer(buf, v4l2_buf);
360
361done:
362 mutex_unlock(&queue->mutex);
363 return ret;
364}
365
366
367
368
369
370
371
372unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
373 poll_table *wait)
374{
375 struct uvc_buffer *buf;
376 unsigned int mask = 0;
377
378 mutex_lock(&queue->mutex);
379 if (list_empty(&queue->mainqueue)) {
380 mask |= POLLERR;
381 goto done;
382 }
383 buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream);
384
385 poll_wait(file, &buf->wait, wait);
386 if (buf->state == UVC_BUF_STATE_DONE ||
387 buf->state == UVC_BUF_STATE_ERROR)
388 mask |= POLLIN | POLLRDNORM;
389
390done:
391 mutex_unlock(&queue->mutex);
392 return mask;
393}
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
413{
414 unsigned int i;
415 int ret = 0;
416
417 mutex_lock(&queue->mutex);
418 if (enable) {
419 if (uvc_queue_streaming(queue)) {
420 ret = -EBUSY;
421 goto done;
422 }
423 queue->sequence = 0;
424 queue->flags |= UVC_QUEUE_STREAMING;
425 queue->buf_used = 0;
426 } else {
427 uvc_queue_cancel(queue, 0);
428 INIT_LIST_HEAD(&queue->mainqueue);
429
430 for (i = 0; i < queue->count; ++i)
431 queue->buffer[i].state = UVC_BUF_STATE_IDLE;
432
433 queue->flags &= ~UVC_QUEUE_STREAMING;
434 }
435
436done:
437 mutex_unlock(&queue->mutex);
438 return ret;
439}
440
441
442
443
444
445
446
447
448
449
450
451
452
453void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect)
454{
455 struct uvc_buffer *buf;
456 unsigned long flags;
457
458 spin_lock_irqsave(&queue->irqlock, flags);
459 while (!list_empty(&queue->irqqueue)) {
460 buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
461 queue);
462 list_del(&buf->queue);
463 buf->state = UVC_BUF_STATE_ERROR;
464 wake_up(&buf->wait);
465 }
466
467
468
469
470
471
472 if (disconnect)
473 queue->flags |= UVC_QUEUE_DISCONNECTED;
474 spin_unlock_irqrestore(&queue->irqlock, flags);
475}
476
477struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
478 struct uvc_buffer *buf)
479{
480 struct uvc_buffer *nextbuf;
481 unsigned long flags;
482
483 if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
484 buf->buf.length != buf->buf.bytesused) {
485 buf->state = UVC_BUF_STATE_QUEUED;
486 buf->buf.bytesused = 0;
487 return buf;
488 }
489
490 spin_lock_irqsave(&queue->irqlock, flags);
491 list_del(&buf->queue);
492 if (!list_empty(&queue->irqqueue))
493 nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
494 queue);
495 else
496 nextbuf = NULL;
497 spin_unlock_irqrestore(&queue->irqlock, flags);
498
499 buf->buf.sequence = queue->sequence++;
500 do_gettimeofday(&buf->buf.timestamp);
501
502 wake_up(&buf->wait);
503 return nextbuf;
504}
505
506