diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2010-05-02 14:57:41 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-20 16:21:41 -0400 |
commit | cdda479f15cd13fa50a913ca85129c0437cc7b91 (patch) | |
tree | 5189c428d5f23f738dbf3e8e555c6f48da540b3a /drivers/usb/gadget/uvc_queue.c | |
parent | 910f8d0cede74beff1eee93cf9cf2a28d7600e66 (diff) |
USB gadget: video class function driver
This USB video class function driver implements a video capture device from the
host's point of view. It creates a V4L2 output device on the gadget's side to
transfer data from a userspace application over USB.
The UVC-specific descriptors are passed by the gadget driver to the UVC
function driver, making them completely configurable without any modification
to the function's driver code.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/uvc_queue.c')
-rw-r--r-- | drivers/usb/gadget/uvc_queue.c | 583 |
1 files changed, 583 insertions, 0 deletions
diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c new file mode 100644 index 000000000000..43891991bf21 --- /dev/null +++ b/drivers/usb/gadget/uvc_queue.c | |||
@@ -0,0 +1,583 @@ | |||
1 | /* | ||
2 | * uvc_queue.c -- USB Video Class driver - Buffers management | ||
3 | * | ||
4 | * Copyright (C) 2005-2010 | ||
5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
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 "uvc.h" | ||
25 | |||
26 | /* ------------------------------------------------------------------------ | ||
27 | * Video buffers queue management. | ||
28 | * | ||
29 | * Video queues is initialized by uvc_queue_init(). The function performs | ||
30 | * basic initialization of the uvc_video_queue struct and never fails. | ||
31 | * | ||
32 | * Video buffer allocation and freeing are performed by uvc_alloc_buffers and | ||
33 | * uvc_free_buffers respectively. The former acquires the video queue lock, | ||
34 | * while the later must be called with the lock held (so that allocation can | ||
35 | * free previously allocated buffers). Trying to free buffers that are mapped | ||
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 ready (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 ready, 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 | */ | ||
80 | |||
81 | void 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 | * Allocate the video buffers. | ||
92 | * | ||
93 | * Pages are reserved to make sure they will not be swapped, as they will be | ||
94 | * filled in the URB completion handler. | ||
95 | * | ||
96 | * Buffers will be individually mapped, so they must all be page aligned. | ||
97 | */ | ||
98 | int 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 | /* Bail out if no buffers should be allocated. */ | ||
115 | if (nbuffers == 0) | ||
116 | goto done; | ||
117 | |||
118 | /* Decrement the number of buffers until allocation succeeds. */ | ||
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 | |||
148 | done: | ||
149 | mutex_unlock(&queue->mutex); | ||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * Free the video buffers. | ||
155 | * | ||
156 | * This function must be called with the queue lock held. | ||
157 | */ | ||
158 | int 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 | static void __uvc_query_buffer(struct uvc_buffer *buf, | ||
176 | struct v4l2_buffer *v4l2_buf) | ||
177 | { | ||
178 | memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf); | ||
179 | |||
180 | if (buf->vma_use_count) | ||
181 | v4l2_buf->flags |= V4L2_BUF_FLAG_MAPPED; | ||
182 | |||
183 | switch (buf->state) { | ||
184 | case UVC_BUF_STATE_ERROR: | ||
185 | case UVC_BUF_STATE_DONE: | ||
186 | v4l2_buf->flags |= V4L2_BUF_FLAG_DONE; | ||
187 | break; | ||
188 | case UVC_BUF_STATE_QUEUED: | ||
189 | case UVC_BUF_STATE_ACTIVE: | ||
190 | v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
191 | break; | ||
192 | case UVC_BUF_STATE_IDLE: | ||
193 | default: | ||
194 | break; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | int uvc_query_buffer(struct uvc_video_queue *queue, | ||
199 | struct v4l2_buffer *v4l2_buf) | ||
200 | { | ||
201 | int ret = 0; | ||
202 | |||
203 | mutex_lock(&queue->mutex); | ||
204 | if (v4l2_buf->index >= queue->count) { | ||
205 | ret = -EINVAL; | ||
206 | goto done; | ||
207 | } | ||
208 | |||
209 | __uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf); | ||
210 | |||
211 | done: | ||
212 | mutex_unlock(&queue->mutex); | ||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * Queue a video buffer. Attempting to queue a buffer that has already been | ||
218 | * queued will return -EINVAL. | ||
219 | */ | ||
220 | int uvc_queue_buffer(struct uvc_video_queue *queue, | ||
221 | struct v4l2_buffer *v4l2_buf) | ||
222 | { | ||
223 | struct uvc_buffer *buf; | ||
224 | unsigned long flags; | ||
225 | int ret = 0; | ||
226 | |||
227 | uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index); | ||
228 | |||
229 | if (v4l2_buf->type != queue->type || | ||
230 | v4l2_buf->memory != V4L2_MEMORY_MMAP) { | ||
231 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " | ||
232 | "and/or memory (%u).\n", v4l2_buf->type, | ||
233 | v4l2_buf->memory); | ||
234 | return -EINVAL; | ||
235 | } | ||
236 | |||
237 | mutex_lock(&queue->mutex); | ||
238 | if (v4l2_buf->index >= queue->count) { | ||
239 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n"); | ||
240 | ret = -EINVAL; | ||
241 | goto done; | ||
242 | } | ||
243 | |||
244 | buf = &queue->buffer[v4l2_buf->index]; | ||
245 | if (buf->state != UVC_BUF_STATE_IDLE) { | ||
246 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state " | ||
247 | "(%u).\n", buf->state); | ||
248 | ret = -EINVAL; | ||
249 | goto done; | ||
250 | } | ||
251 | |||
252 | if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | ||
253 | v4l2_buf->bytesused > buf->buf.length) { | ||
254 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n"); | ||
255 | ret = -EINVAL; | ||
256 | goto done; | ||
257 | } | ||
258 | |||
259 | if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
260 | buf->buf.bytesused = 0; | ||
261 | else | ||
262 | buf->buf.bytesused = v4l2_buf->bytesused; | ||
263 | |||
264 | spin_lock_irqsave(&queue->irqlock, flags); | ||
265 | if (queue->flags & UVC_QUEUE_DISCONNECTED) { | ||
266 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
267 | ret = -ENODEV; | ||
268 | goto done; | ||
269 | } | ||
270 | buf->state = UVC_BUF_STATE_QUEUED; | ||
271 | |||
272 | ret = (queue->flags & UVC_QUEUE_PAUSED) != 0; | ||
273 | queue->flags &= ~UVC_QUEUE_PAUSED; | ||
274 | |||
275 | list_add_tail(&buf->stream, &queue->mainqueue); | ||
276 | list_add_tail(&buf->queue, &queue->irqqueue); | ||
277 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
278 | |||
279 | done: | ||
280 | mutex_unlock(&queue->mutex); | ||
281 | return ret; | ||
282 | } | ||
283 | |||
284 | static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking) | ||
285 | { | ||
286 | if (nonblocking) { | ||
287 | return (buf->state != UVC_BUF_STATE_QUEUED && | ||
288 | buf->state != UVC_BUF_STATE_ACTIVE) | ||
289 | ? 0 : -EAGAIN; | ||
290 | } | ||
291 | |||
292 | return wait_event_interruptible(buf->wait, | ||
293 | buf->state != UVC_BUF_STATE_QUEUED && | ||
294 | buf->state != UVC_BUF_STATE_ACTIVE); | ||
295 | } | ||
296 | |||
297 | /* | ||
298 | * Dequeue a video buffer. If nonblocking is false, block until a buffer is | ||
299 | * available. | ||
300 | */ | ||
301 | int uvc_dequeue_buffer(struct uvc_video_queue *queue, | ||
302 | struct v4l2_buffer *v4l2_buf, int nonblocking) | ||
303 | { | ||
304 | struct uvc_buffer *buf; | ||
305 | int ret = 0; | ||
306 | |||
307 | if (v4l2_buf->type != queue->type || | ||
308 | v4l2_buf->memory != V4L2_MEMORY_MMAP) { | ||
309 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " | ||
310 | "and/or memory (%u).\n", v4l2_buf->type, | ||
311 | v4l2_buf->memory); | ||
312 | return -EINVAL; | ||
313 | } | ||
314 | |||
315 | mutex_lock(&queue->mutex); | ||
316 | if (list_empty(&queue->mainqueue)) { | ||
317 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Empty buffer queue.\n"); | ||
318 | ret = -EINVAL; | ||
319 | goto done; | ||
320 | } | ||
321 | |||
322 | buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream); | ||
323 | if ((ret = uvc_queue_waiton(buf, nonblocking)) < 0) | ||
324 | goto done; | ||
325 | |||
326 | uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u bytes).\n", | ||
327 | buf->buf.index, buf->state, buf->buf.bytesused); | ||
328 | |||
329 | switch (buf->state) { | ||
330 | case UVC_BUF_STATE_ERROR: | ||
331 | uvc_trace(UVC_TRACE_CAPTURE, "[W] Corrupted data " | ||
332 | "(transmission error).\n"); | ||
333 | ret = -EIO; | ||
334 | case UVC_BUF_STATE_DONE: | ||
335 | buf->state = UVC_BUF_STATE_IDLE; | ||
336 | break; | ||
337 | |||
338 | case UVC_BUF_STATE_IDLE: | ||
339 | case UVC_BUF_STATE_QUEUED: | ||
340 | case UVC_BUF_STATE_ACTIVE: | ||
341 | default: | ||
342 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u " | ||
343 | "(driver bug?).\n", buf->state); | ||
344 | ret = -EINVAL; | ||
345 | goto done; | ||
346 | } | ||
347 | |||
348 | list_del(&buf->stream); | ||
349 | __uvc_query_buffer(buf, v4l2_buf); | ||
350 | |||
351 | done: | ||
352 | mutex_unlock(&queue->mutex); | ||
353 | return ret; | ||
354 | } | ||
355 | |||
356 | /* | ||
357 | * Poll the video queue. | ||
358 | * | ||
359 | * This function implements video queue polling and is intended to be used by | ||
360 | * the device poll handler. | ||
361 | */ | ||
362 | unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, | ||
363 | poll_table *wait) | ||
364 | { | ||
365 | struct uvc_buffer *buf; | ||
366 | unsigned int mask = 0; | ||
367 | |||
368 | mutex_lock(&queue->mutex); | ||
369 | if (list_empty(&queue->mainqueue)) | ||
370 | goto done; | ||
371 | |||
372 | buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream); | ||
373 | |||
374 | poll_wait(file, &buf->wait, wait); | ||
375 | if (buf->state == UVC_BUF_STATE_DONE || | ||
376 | buf->state == UVC_BUF_STATE_ERROR) | ||
377 | mask |= POLLOUT | POLLWRNORM; | ||
378 | |||
379 | done: | ||
380 | mutex_unlock(&queue->mutex); | ||
381 | return mask; | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * VMA operations. | ||
386 | */ | ||
387 | static void uvc_vm_open(struct vm_area_struct *vma) | ||
388 | { | ||
389 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
390 | buffer->vma_use_count++; | ||
391 | } | ||
392 | |||
393 | static void uvc_vm_close(struct vm_area_struct *vma) | ||
394 | { | ||
395 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
396 | buffer->vma_use_count--; | ||
397 | } | ||
398 | |||
399 | static struct vm_operations_struct uvc_vm_ops = { | ||
400 | .open = uvc_vm_open, | ||
401 | .close = uvc_vm_close, | ||
402 | }; | ||
403 | |||
404 | /* | ||
405 | * Memory-map a buffer. | ||
406 | * | ||
407 | * This function implements video buffer memory mapping and is intended to be | ||
408 | * used by the device mmap handler. | ||
409 | */ | ||
410 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) | ||
411 | { | ||
412 | struct uvc_buffer *uninitialized_var(buffer); | ||
413 | struct page *page; | ||
414 | unsigned long addr, start, size; | ||
415 | unsigned int i; | ||
416 | int ret = 0; | ||
417 | |||
418 | start = vma->vm_start; | ||
419 | size = vma->vm_end - vma->vm_start; | ||
420 | |||
421 | mutex_lock(&queue->mutex); | ||
422 | |||
423 | for (i = 0; i < queue->count; ++i) { | ||
424 | buffer = &queue->buffer[i]; | ||
425 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
426 | break; | ||
427 | } | ||
428 | |||
429 | if (i == queue->count || size != queue->buf_size) { | ||
430 | ret = -EINVAL; | ||
431 | goto done; | ||
432 | } | ||
433 | |||
434 | /* | ||
435 | * VM_IO marks the area as being an mmaped region for I/O to a | ||
436 | * device. It also prevents the region from being core dumped. | ||
437 | */ | ||
438 | vma->vm_flags |= VM_IO; | ||
439 | |||
440 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; | ||
441 | while (size > 0) { | ||
442 | page = vmalloc_to_page((void *)addr); | ||
443 | if ((ret = vm_insert_page(vma, start, page)) < 0) | ||
444 | goto done; | ||
445 | |||
446 | start += PAGE_SIZE; | ||
447 | addr += PAGE_SIZE; | ||
448 | size -= PAGE_SIZE; | ||
449 | } | ||
450 | |||
451 | vma->vm_ops = &uvc_vm_ops; | ||
452 | vma->vm_private_data = buffer; | ||
453 | uvc_vm_open(vma); | ||
454 | |||
455 | done: | ||
456 | mutex_unlock(&queue->mutex); | ||
457 | return ret; | ||
458 | } | ||
459 | |||
460 | /* | ||
461 | * Enable or disable the video buffers queue. | ||
462 | * | ||
463 | * The queue must be enabled before starting video acquisition and must be | ||
464 | * disabled after stopping it. This ensures that the video buffers queue | ||
465 | * state can be properly initialized before buffers are accessed from the | ||
466 | * interrupt handler. | ||
467 | * | ||
468 | * Enabling the video queue initializes parameters (such as sequence number, | ||
469 | * sync pattern, ...). If the queue is already enabled, return -EBUSY. | ||
470 | * | ||
471 | * Disabling the video queue cancels the queue and removes all buffers from | ||
472 | * the main queue. | ||
473 | * | ||
474 | * This function can't be called from interrupt context. Use | ||
475 | * uvc_queue_cancel() instead. | ||
476 | */ | ||
477 | int uvc_queue_enable(struct uvc_video_queue *queue, int enable) | ||
478 | { | ||
479 | unsigned int i; | ||
480 | int ret = 0; | ||
481 | |||
482 | mutex_lock(&queue->mutex); | ||
483 | if (enable) { | ||
484 | if (uvc_queue_streaming(queue)) { | ||
485 | ret = -EBUSY; | ||
486 | goto done; | ||
487 | } | ||
488 | queue->sequence = 0; | ||
489 | queue->flags |= UVC_QUEUE_STREAMING; | ||
490 | queue->buf_used = 0; | ||
491 | } else { | ||
492 | uvc_queue_cancel(queue, 0); | ||
493 | INIT_LIST_HEAD(&queue->mainqueue); | ||
494 | |||
495 | for (i = 0; i < queue->count; ++i) | ||
496 | queue->buffer[i].state = UVC_BUF_STATE_IDLE; | ||
497 | |||
498 | queue->flags &= ~UVC_QUEUE_STREAMING; | ||
499 | } | ||
500 | |||
501 | done: | ||
502 | mutex_unlock(&queue->mutex); | ||
503 | return ret; | ||
504 | } | ||
505 | |||
506 | /* | ||
507 | * Cancel the video buffers queue. | ||
508 | * | ||
509 | * Cancelling the queue marks all buffers on the irq queue as erroneous, | ||
510 | * wakes them up and removes them from the queue. | ||
511 | * | ||
512 | * If the disconnect parameter is set, further calls to uvc_queue_buffer will | ||
513 | * fail with -ENODEV. | ||
514 | * | ||
515 | * This function acquires the irq spinlock and can be called from interrupt | ||
516 | * context. | ||
517 | */ | ||
518 | void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect) | ||
519 | { | ||
520 | struct uvc_buffer *buf; | ||
521 | unsigned long flags; | ||
522 | |||
523 | spin_lock_irqsave(&queue->irqlock, flags); | ||
524 | while (!list_empty(&queue->irqqueue)) { | ||
525 | buf = list_first_entry(&queue->irqqueue, struct uvc_buffer, | ||
526 | queue); | ||
527 | list_del(&buf->queue); | ||
528 | buf->state = UVC_BUF_STATE_ERROR; | ||
529 | wake_up(&buf->wait); | ||
530 | } | ||
531 | /* This must be protected by the irqlock spinlock to avoid race | ||
532 | * conditions between uvc_queue_buffer and the disconnection event that | ||
533 | * could result in an interruptible wait in uvc_dequeue_buffer. Do not | ||
534 | * blindly replace this logic by checking for the UVC_DEV_DISCONNECTED | ||
535 | * state outside the queue code. | ||
536 | */ | ||
537 | if (disconnect) | ||
538 | queue->flags |= UVC_QUEUE_DISCONNECTED; | ||
539 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
540 | } | ||
541 | |||
542 | struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | ||
543 | struct uvc_buffer *buf) | ||
544 | { | ||
545 | struct uvc_buffer *nextbuf; | ||
546 | unsigned long flags; | ||
547 | |||
548 | if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && | ||
549 | buf->buf.length != buf->buf.bytesused) { | ||
550 | buf->state = UVC_BUF_STATE_QUEUED; | ||
551 | buf->buf.bytesused = 0; | ||
552 | return buf; | ||
553 | } | ||
554 | |||
555 | spin_lock_irqsave(&queue->irqlock, flags); | ||
556 | list_del(&buf->queue); | ||
557 | if (!list_empty(&queue->irqqueue)) | ||
558 | nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, | ||
559 | queue); | ||
560 | else | ||
561 | nextbuf = NULL; | ||
562 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
563 | |||
564 | buf->buf.sequence = queue->sequence++; | ||
565 | do_gettimeofday(&buf->buf.timestamp); | ||
566 | |||
567 | wake_up(&buf->wait); | ||
568 | return nextbuf; | ||
569 | } | ||
570 | |||
571 | struct uvc_buffer *uvc_queue_head(struct uvc_video_queue *queue) | ||
572 | { | ||
573 | struct uvc_buffer *buf = NULL; | ||
574 | |||
575 | if (!list_empty(&queue->irqqueue)) | ||
576 | buf = list_first_entry(&queue->irqqueue, struct uvc_buffer, | ||
577 | queue); | ||
578 | else | ||
579 | queue->flags |= UVC_QUEUE_PAUSED; | ||
580 | |||
581 | return buf; | ||
582 | } | ||
583 | |||