Fix SXGA support to enforce bayer format
[microdia.git] / sn9c20x-queue.c
blob4e3dd65cbb151ff353c3de5967ab4aa300fd3aaf
1 /**
2 * @file sn9c20x-queue.c
3 * @author Brian Johnson
5 * @brief Buffer management
7 * @note Original code from UVC webcam driver
8 * @note Copyright (C) 2005-2008 Laurent Pinchart (laurent.pinchart@skynet.be)
9 * @note Copyright (C) 2008 Brian Johnson (brijohn@gmail.com)
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * ------------------------------------------------------------------------
18 * Video buffers queue management.
20 * Video queues is initialized by sn9c20x_queue_init(). The function performs
21 * basic initialization of the sn9c20x_video_queue struct and never fails.
23 * Video buffer allocation and freeing are performed by sn9c20x_alloc_buffers()
24 * and sn9c20x_free_buffers() respectively. The former acquires the video queue
25 * lock, while the later must be called with the lock held (so that allocation
26 * can free previously allocated buffers). Trying to free buffers that are
27 * mapped to user space will return -EBUSY.
29 * Video buffers are managed using two queues. However, unlike most USB video
30 * drivers which use an in queue and an out queue, we use a main queue which
31 * holds all queued buffers (both 'empty' and 'done' buffers), and an irq
32 * queue which holds empty buffers. This design (copied from video-buf)
33 * minimizes locking in interrupt, as only one queue is shared between
34 * interrupt and user contexts.
36 * Use cases
37 * ---------
39 * Unless stated otherwise, all operations which modify the irq buffers queue
40 * are protected by the irq spinlock.
42 * 1. The user queues the buffers, starts streaming and dequeues a buffer.
44 * The buffers are added to the main and irq queues. Both operations are
45 * protected by the queue lock, and the latert is protected by the irq
46 * spinlock as well.
48 * The completion handler fetches a buffer from the irq queue and fills it
49 * with video data. If no buffer is available (irq queue empty), the handler
50 * returns immediately.
52 * When the buffer is full, the completion handler removes it from the irq
53 * queue, marks it as ready (SN9C20X_BUF_STATE_DONE) and wake its wait
54 * queue. At that point, any process waiting on the buffer will be woken up.
55 * If a process tries to dequeue a buffer after it has been marked ready,
56 * the dequeing will succeed immediately.
58 * 2. Buffers are queued, user is waiting on a buffer and the device gets
59 * disconnected.
61 * When the device is disconnected, the kernel calls the completion handler
62 * with an appropriate status code. The handler marks all buffers in the
63 * irq queue as being erroneous (SN9C20X_BUF_STATE_ERROR) and wakes them up
64 * so that any process waiting on a buffer gets woken up.
66 * Waking up up the first buffer on the irq list is not enough, as the
67 * process waiting on the buffer might restart the dequeue operation
68 * immediately.
72 #include <linux/kernel.h>
73 #include <linux/version.h>
74 #include <linux/list.h>
75 #include <linux/module.h>
76 #include <linux/usb.h>
77 #include <linux/videodev.h>
78 #include <linux/vmalloc.h>
79 #include <linux/wait.h>
80 #include <linux/mm.h>
81 #include <asm/atomic.h>
83 #include "sn9c20x.h"
85 /**
86 * @param queue
89 void sn9c20x_queue_init(struct sn9c20x_video_queue *queue)
91 mutex_init(&queue->mutex);
92 spin_lock_init(&queue->irqlock);
93 INIT_LIST_HEAD(&queue->mainqueue);
94 INIT_LIST_HEAD(&queue->irqqueue);
97 /**
98 * @brief Allocate the video buffers.
100 * @param queue
101 * @param nbuffers
102 * @param buflength
104 * Pages are reserved to make sure they will not be swaped, as they will be
105 * filled in URB completion handler.
107 * Buffers will be individually mapped, so they must all be page aligned.
109 int sn9c20x_alloc_buffers(struct sn9c20x_video_queue *queue,
110 unsigned int nbuffers, unsigned int buflength)
112 unsigned int bufsize = PAGE_ALIGN(buflength);
113 unsigned int i;
114 void *mem = NULL;
115 void *buffer = NULL;
116 int ret;
118 mutex_lock(&queue->mutex);
120 ret = sn9c20x_free_buffers(queue);
121 if (ret < 0)
122 goto done;
124 /* Bail out if no buffers should be allocated. */
125 if (nbuffers == 0)
126 goto done;
128 if (nbuffers < queue->min_buffers)
129 nbuffers = queue->min_buffers;
130 else if (nbuffers > queue->max_buffers)
131 nbuffers = queue->max_buffers;
133 /* Decrement the number of buffers until allocation succeeds. */
134 for (; nbuffers >= queue->min_buffers; --nbuffers) {
135 mem = vmalloc_32(nbuffers * bufsize);
136 buffer = kzalloc(nbuffers * sizeof(struct sn9c20x_buffer),
137 GFP_KERNEL);
138 if (mem != NULL && buffer != NULL)
139 break;
140 if (mem != NULL)
141 vfree(mem);
142 if (buffer != NULL)
143 kfree(buffer);
146 if (mem == NULL || buffer == NULL) {
147 ret = -ENOMEM;
148 goto done;
150 queue->buffer = buffer;
152 for (i = 0; i < nbuffers; ++i) {
153 memset(&queue->buffer[i], 0, sizeof queue->buffer[i]);
154 queue->buffer[i].buf.index = i;
155 queue->buffer[i].buf.m.offset = i * bufsize;
156 queue->buffer[i].buf.length = buflength;
157 queue->buffer[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
158 queue->buffer[i].buf.sequence = 0;
159 queue->buffer[i].buf.field = V4L2_FIELD_NONE;
160 queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP;
161 queue->buffer[i].buf.flags = 0;
162 init_waitqueue_head(&queue->buffer[i].wait);
165 queue->mem = mem;
166 queue->count = nbuffers;
167 queue->buf_size = bufsize;
168 ret = nbuffers;
170 done:
171 mutex_unlock(&queue->mutex);
172 return ret;
176 * @brief Free the video buffers.
178 * @param queue
180 * This function must be called with the queue lock held.
182 int sn9c20x_free_buffers(struct sn9c20x_video_queue *queue)
184 unsigned int i;
185 UDIA_DEBUG("Freeing %d v4l2 buffers\n", queue->count);
187 for (i = 0; i < queue->count; ++i) {
188 if (queue->buffer[i].vma_use_count != 0)
189 return -EBUSY;
192 if (queue->count) {
193 vfree(queue->mem);
194 kfree(queue->buffer);
195 INIT_LIST_HEAD(&queue->mainqueue);
196 INIT_LIST_HEAD(&queue->irqqueue);
197 queue->count = 0;
200 return 0;
204 * @param buf
205 * @param v4l2_buf
208 static void __sn9c20x_query_buffer(struct sn9c20x_buffer *buf,
209 struct v4l2_buffer *v4l2_buf)
211 memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf);
213 if (buf->vma_use_count)
214 v4l2_buf->flags |= V4L2_BUF_FLAG_MAPPED;
216 switch (buf->state) {
217 case SN9C20X_BUF_STATE_ERROR:
218 case SN9C20X_BUF_STATE_DONE:
219 v4l2_buf->flags |= V4L2_BUF_FLAG_DONE;
220 break;
221 case SN9C20X_BUF_STATE_QUEUED:
222 case SN9C20X_BUF_STATE_ACTIVE:
223 v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
224 break;
225 case SN9C20X_BUF_STATE_IDLE:
226 default:
227 break;
232 * @param queue
233 * @param v4l2_buf
235 * @return 0 or negative error code
238 int sn9c20x_query_buffer(struct sn9c20x_video_queue *queue,
239 struct v4l2_buffer *v4l2_buf)
241 int ret = 0;
243 mutex_lock(&queue->mutex);
244 if (v4l2_buf->index >= queue->count) {
245 ret = -EINVAL;
246 goto done;
249 __sn9c20x_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf);
251 done:
252 mutex_unlock(&queue->mutex);
253 return ret;
257 * @brief Queue a video buffer.
259 * @param queue
260 * @param v4l2_buf
262 * @return 0 or negative error code
264 * Attempting to queue a buffer that has already been
265 * queued will return -EINVAL.
267 int sn9c20x_queue_buffer(struct sn9c20x_video_queue *queue,
268 struct v4l2_buffer *v4l2_buf)
270 struct sn9c20x_buffer *buf;
271 unsigned long flags;
272 int ret = 0;
274 UDIA_DEBUG("Queuing buffer %u.\n", v4l2_buf->index);
276 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
277 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
278 UDIA_ERROR("[E] Invalid buffer type (%u) "
279 "and/or memory (%u).\n", v4l2_buf->type,
280 v4l2_buf->memory);
281 return -EINVAL;
284 mutex_lock(&queue->mutex);
285 if (v4l2_buf->index >= queue->count) {
286 UDIA_ERROR("[E] Out of range index.\n");
287 ret = -EINVAL;
288 goto done;
291 buf = &queue->buffer[v4l2_buf->index];
292 if (buf->state != SN9C20X_BUF_STATE_IDLE) {
293 UDIA_ERROR("[E] Invalid buffer state "
294 "(%u).\n", buf->state);
295 ret = -EINVAL;
296 goto done;
299 spin_lock_irqsave(&queue->irqlock, flags);
300 if (queue->flags & SN9C20X_QUEUE_DISCONNECTED) {
301 spin_unlock_irqrestore(&queue->irqlock, flags);
302 ret = -ENODEV;
303 goto done;
306 buf->state = SN9C20X_BUF_STATE_QUEUED;
307 buf->buf.bytesused = 0;
308 list_add_tail(&buf->stream, &queue->mainqueue);
309 list_add_tail(&buf->queue, &queue->irqqueue);
310 spin_unlock_irqrestore(&queue->irqlock, flags);
312 done:
313 mutex_unlock(&queue->mutex);
314 return ret;
318 * @param buf
319 * @param nonblocking
322 static int sn9c20x_queue_waiton(struct sn9c20x_buffer *buf, int nonblocking)
324 if (nonblocking) {
325 return (buf->state != SN9C20X_BUF_STATE_QUEUED &&
326 buf->state != SN9C20X_BUF_STATE_ACTIVE)
327 ? 0 : -EAGAIN;
330 return wait_event_interruptible(buf->wait,
331 buf->state != SN9C20X_BUF_STATE_QUEUED &&
332 buf->state != SN9C20X_BUF_STATE_ACTIVE);
336 * @brief Dequeue a video buffer.
338 * @param queue
339 * @param v4l2_buf
340 * @param nonblocking
342 * @return 0 or negative error code
344 * If nonblocking is false, block until a buffer is
345 * available.
347 int sn9c20x_dequeue_buffer(struct sn9c20x_video_queue *queue,
348 struct v4l2_buffer *v4l2_buf, int nonblocking)
350 struct sn9c20x_buffer *buf;
351 int ret = 0;
353 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
354 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
355 UDIA_ERROR("[E] Invalid buffer type (%u) "
356 "and/or memory (%u).\n", v4l2_buf->type,
357 v4l2_buf->memory);
358 return -EINVAL;
361 mutex_lock(&queue->mutex);
362 if (list_empty(&queue->mainqueue)) {
363 UDIA_ERROR("[E] Empty buffer queue.\n");
364 ret = -EINVAL;
365 goto done;
368 buf = list_first_entry(&queue->mainqueue, struct sn9c20x_buffer,
369 stream);
371 ret = sn9c20x_queue_waiton(buf, nonblocking);
372 if (ret < 0)
373 goto done;
375 UDIA_DEBUG("Dequeuing buffer %u (%u, %u bytes).\n",
376 buf->buf.index, buf->state, buf->buf.bytesused);
378 switch (buf->state) {
379 case SN9C20X_BUF_STATE_ERROR:
380 UDIA_WARNING("[W] Corrupted data (transmission error).\n");
381 ret = -EIO;
382 case SN9C20X_BUF_STATE_DONE:
383 buf->state = SN9C20X_BUF_STATE_IDLE;
384 break;
386 case SN9C20X_BUF_STATE_IDLE:
387 case SN9C20X_BUF_STATE_QUEUED:
388 case SN9C20X_BUF_STATE_ACTIVE:
389 default:
390 UDIA_ERROR("[E] Invalid buffer state %u "
391 "(driver bug?).\n", buf->state);
392 ret = -EINVAL;
393 goto done;
396 list_del(&buf->stream);
397 __sn9c20x_query_buffer(buf, v4l2_buf);
399 done:
400 mutex_unlock(&queue->mutex);
401 return ret;
405 * @brief Poll the video queue.
407 * @param queue
408 * @param file
409 * @param wait
411 * This function implements video queue polling and is intended to be used by
412 * the device poll handler.
414 unsigned int sn9c20x_queue_poll(struct sn9c20x_video_queue *queue,
415 struct file *file, poll_table *wait)
417 struct sn9c20x_buffer *buf;
418 unsigned int mask = 0;
420 mutex_lock(&queue->mutex);
421 if (list_empty(&queue->mainqueue)) {
422 mask |= POLLERR;
423 goto done;
425 buf = list_first_entry(&queue->mainqueue, struct sn9c20x_buffer,
426 stream);
428 poll_wait(file, &buf->wait, wait);
429 if (buf->state == SN9C20X_BUF_STATE_DONE ||
430 buf->state == SN9C20X_BUF_STATE_ERROR)
431 mask |= POLLIN | POLLRDNORM;
433 done:
434 mutex_unlock(&queue->mutex);
435 return mask;
439 * @brief Enable or disable the video buffers queue.
441 * @param queue
442 * @param enable
444 * @return 0 or negative error code
446 * The queue must be enabled before starting video acquisition and must be
447 * disabled after stopping it. This ensures that the video buffers queue
448 * state can be properly initialized before buffers are accessed from the
449 * interrupt handler.
451 * Enabling the video queue initializes parameters (such as sequence number,
452 * sync pattern, ...). If the queue is already enabled, return -EBUSY.
454 * Disabling the video queue cancels the queue and removes all buffers from
455 * the main queue.
457 * This function can't be called from interrupt context. Use
458 * sn9c20x_queue_cancel() instead.
460 int sn9c20x_queue_enable(struct sn9c20x_video_queue *queue, int enable)
462 unsigned int i;
463 int ret = 0;
465 mutex_lock(&queue->mutex);
466 if (enable) {
467 if (sn9c20x_queue_streaming(queue)) {
468 ret = -EBUSY;
469 goto done;
471 queue->sequence = 0;
472 queue->flags |= SN9C20X_QUEUE_STREAMING;
473 } else {
474 sn9c20x_queue_cancel(queue, 0);
475 INIT_LIST_HEAD(&queue->mainqueue);
477 for (i = 0; i < queue->count; ++i)
478 queue->buffer[i].state = SN9C20X_BUF_STATE_IDLE;
480 queue->flags &= ~SN9C20X_QUEUE_STREAMING;
483 done:
484 mutex_unlock(&queue->mutex);
485 return ret;
489 * @brief Cancel the video buffers queue.
491 * @param queue
493 * @param disconnect
495 * Cancelling the queue marks all buffers on the irq queue as erroneous,
496 * wakes them up and remove them from the queue.
498 * If the disconnect parameter is set, further calls to uvc_queue_buffer will
499 * fail with -ENODEV.
501 * This function acquires the irq spinlock and can be called from interrupt
502 * context.
504 void sn9c20x_queue_cancel(struct sn9c20x_video_queue *queue, int disconnect)
506 struct sn9c20x_buffer *buf;
507 unsigned long flags;
509 spin_lock_irqsave(&queue->irqlock, flags);
510 while (!list_empty(&queue->irqqueue)) {
511 buf = list_first_entry(&queue->irqqueue, struct sn9c20x_buffer,
512 queue);
513 list_del(&buf->queue);
514 buf->state = SN9C20X_BUF_STATE_ERROR;
515 wake_up(&buf->wait);
517 /* This must be protected by the irqlock spinlock to avoid race
518 * conditions between sn9c20x_queue_buffer and the disconnection
519 * event that could result in an interruptible wait in
520 * sn9c20x_dequeue_buffer. Do not blindly replace this logic by
521 * checking for the SN9C20X_DEV_DISCONNECTED state outside the
522 * queue code.
524 if (disconnect)
525 queue->flags |= SN9C20X_QUEUE_DISCONNECTED;
526 spin_unlock_irqrestore(&queue->irqlock, flags);
530 * @param queue
531 * @param buf
534 struct sn9c20x_buffer *sn9c20x_queue_next_buffer(
535 struct sn9c20x_video_queue *queue,
536 struct sn9c20x_buffer *buf)
538 struct sn9c20x_buffer *nextbuf;
539 unsigned long flags;
541 if ((queue->flags & SN9C20X_QUEUE_DROP_INCOMPLETE) &&
542 buf->buf.length != buf->buf.bytesused) {
543 buf->state = SN9C20X_BUF_STATE_QUEUED;
544 buf->buf.bytesused = 0;
545 return buf;
548 spin_lock_irqsave(&queue->irqlock, flags);
549 list_del(&buf->queue);
550 if (!list_empty(&queue->irqqueue))
551 nextbuf = list_first_entry(&queue->irqqueue,
552 struct sn9c20x_buffer, queue);
553 else
554 nextbuf = NULL;
555 spin_unlock_irqrestore(&queue->irqlock, flags);
557 buf->buf.sequence = queue->sequence++;
558 do_gettimeofday(&buf->buf.timestamp);
560 wake_up(&buf->wait);
561 return nextbuf;