aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/videobuf-core.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2007-08-23 15:26:14 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:14:55 -0400
commit7a7d9a89d0307b1743d782197e2c5fc5ddf183f3 (patch)
treef5b1b220672128d089b5a6c469608e90482a6f60 /drivers/media/video/videobuf-core.c
parent7c596fa964806acb3b5ababb7ec4e1da35b140b3 (diff)
V4L/DVB (6251): Replace video-buf to a more generic approach
video-buf currently does two different tasks: - Manages video buffers with a common code that allows implementing all the V4L2 different modes of buffering; - Controls memory allocations While the first task is generic, the second were written to support PCI DMA Scatter/Gather needs. The original approach can't even work for those video capture hardware that don't support scatter/gather. I did one approach to make it more generic. While the approach worked fine for vivi driver, it were not generic enough to handle USB needs. This patch creates two different modules, one containing the generic video buffer handling (videobuf-core) and another with PCI DMA S/G. After this patch, it would be simpler to write an USB video-buf and a non-SG DMA module. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org> http://thread.gmane.org/gmane.comp.video.video4linux/34978/focus=34981 Reviewed-by: Ricardo Cerqueira <v4l@cerqueira.org>
Diffstat (limited to 'drivers/media/video/videobuf-core.c')
-rw-r--r--drivers/media/video/videobuf-core.c976
1 files changed, 976 insertions, 0 deletions
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
new file mode 100644
index 000000000000..256501384af7
--- /dev/null
+++ b/drivers/media/video/videobuf-core.c
@@ -0,0 +1,976 @@
1/*
2 * generic helper functions for handling video4linux capture buffers
3 *
4 * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
5 *
6 * Highly based on video-buf written originally by:
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
8 * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org>
9 * (c) 2006 Ted Walther and John Sokol
10 *
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
14 */
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/moduleparam.h>
19#include <linux/slab.h>
20#include <linux/interrupt.h>
21
22#include <media/videobuf-core.h>
23
24#define MAGIC_BUFFER 0x20070728
25#define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \
26 { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); }
27
28static int debug = 0;
29module_param(debug, int, 0644);
30
31MODULE_DESCRIPTION("helper module to manage video4linux buffers");
32MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
33MODULE_LICENSE("GPL");
34
35#define dprintk(level, fmt, arg...) if (debug >= level) \
36 printk(KERN_DEBUG "vbuf: " fmt , ## arg)
37
38/* --------------------------------------------------------------------- */
39
40#define CALL(q, f, arg...) \
41 ( (q->int_ops->f)? q->int_ops->f(arg) : 0)
42
43void* videobuf_alloc(struct videobuf_queue* q)
44{
45 struct videobuf_buffer *vb;
46
47 BUG_ON (q->msize<sizeof(*vb));
48
49 if (!q->int_ops || !q->int_ops->alloc) {
50 printk(KERN_ERR "No specific ops defined!\n");
51 BUG();
52 }
53
54 vb = q->int_ops->alloc(q->msize);
55
56 if (NULL != vb) {
57 init_waitqueue_head(&vb->done);
58 vb->magic = MAGIC_BUFFER;
59 }
60
61 return vb;
62}
63
64int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr)
65{
66 int retval = 0;
67 DECLARE_WAITQUEUE(wait, current);
68
69 MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
70 add_wait_queue(&vb->done, &wait);
71 while (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) {
72 if (non_blocking) {
73 retval = -EAGAIN;
74 break;
75 }
76 set_current_state(intr ? TASK_INTERRUPTIBLE
77 : TASK_UNINTERRUPTIBLE);
78 if (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED)
79 schedule();
80 set_current_state(TASK_RUNNING);
81 if (intr && signal_pending(current)) {
82 dprintk(1,"buffer waiton: -EINTR\n");
83 retval = -EINTR;
84 break;
85 }
86 }
87 remove_wait_queue(&vb->done, &wait);
88 return retval;
89}
90
91int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
92 struct v4l2_framebuffer *fbuf)
93{
94 MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
95 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
96
97 return CALL(q,iolock,q,vb,fbuf);
98}
99
100/* --------------------------------------------------------------------- */
101
102
103void videobuf_queue_init(struct videobuf_queue* q,
104 struct videobuf_queue_ops *ops,
105 void *dev,
106 spinlock_t *irqlock,
107 enum v4l2_buf_type type,
108 enum v4l2_field field,
109 unsigned int msize,
110 void *priv)
111{
112 memset(q,0,sizeof(*q));
113 q->irqlock = irqlock;
114 q->dev = dev;
115 q->type = type;
116 q->field = field;
117 q->msize = msize;
118 q->ops = ops;
119 q->priv_data = priv;
120
121 /* All buffer operations are mandatory */
122 BUG_ON (!q->ops->buf_setup);
123 BUG_ON (!q->ops->buf_prepare);
124 BUG_ON (!q->ops->buf_queue);
125 BUG_ON (!q->ops->buf_release);
126
127 mutex_init(&q->lock);
128 INIT_LIST_HEAD(&q->stream);
129}
130
131int videobuf_queue_is_busy(struct videobuf_queue *q)
132{
133 int i;
134
135 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
136
137 if (q->streaming) {
138 dprintk(1,"busy: streaming active\n");
139 return 1;
140 }
141 if (q->reading) {
142 dprintk(1,"busy: pending read #1\n");
143 return 1;
144 }
145 if (q->read_buf) {
146 dprintk(1,"busy: pending read #2\n");
147 return 1;
148 }
149 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
150 if (NULL == q->bufs[i])
151 continue;
152 if (CALL(q,is_mmapped,q->bufs[i])) {
153 dprintk(1,"busy: buffer #%d mapped\n",i);
154 return 1;
155 }
156 if (q->bufs[i]->state == STATE_QUEUED) {
157 dprintk(1,"busy: buffer #%d queued\n",i);
158 return 1;
159 }
160 if (q->bufs[i]->state == STATE_ACTIVE) {
161 dprintk(1,"busy: buffer #%d avtive\n",i);
162 return 1;
163 }
164 }
165 return 0;
166}
167
168void videobuf_queue_cancel(struct videobuf_queue *q)
169{
170 unsigned long flags=0;
171 int i;
172
173 /* remove queued buffers from list */
174 if (q->irqlock)
175 spin_lock_irqsave(q->irqlock,flags);
176 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
177 if (NULL == q->bufs[i])
178 continue;
179 if (q->bufs[i]->state == STATE_QUEUED) {
180 list_del(&q->bufs[i]->queue);
181 q->bufs[i]->state = STATE_ERROR;
182 }
183 }
184 if (q->irqlock)
185 spin_unlock_irqrestore(q->irqlock,flags);
186
187 /* free all buffers + clear queue */
188 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
189 if (NULL == q->bufs[i])
190 continue;
191 q->ops->buf_release(q,q->bufs[i]);
192 }
193 INIT_LIST_HEAD(&q->stream);
194}
195
196/* --------------------------------------------------------------------- */
197
198enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
199{
200 enum v4l2_field field = q->field;
201
202 BUG_ON(V4L2_FIELD_ANY == field);
203
204 if (V4L2_FIELD_ALTERNATE == field) {
205 if (V4L2_FIELD_TOP == q->last) {
206 field = V4L2_FIELD_BOTTOM;
207 q->last = V4L2_FIELD_BOTTOM;
208 } else {
209 field = V4L2_FIELD_TOP;
210 q->last = V4L2_FIELD_TOP;
211 }
212 }
213 return field;
214}
215
216static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
217 struct videobuf_buffer *vb, enum v4l2_buf_type type)
218{
219 MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
220 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
221
222 b->index = vb->i;
223 b->type = type;
224
225 b->memory = vb->memory;
226 switch (b->memory) {
227 case V4L2_MEMORY_MMAP:
228 b->m.offset = vb->boff;
229 b->length = vb->bsize;
230 break;
231 case V4L2_MEMORY_USERPTR:
232 b->m.userptr = vb->baddr;
233 b->length = vb->bsize;
234 break;
235 case V4L2_MEMORY_OVERLAY:
236 b->m.offset = vb->boff;
237 break;
238 }
239
240 b->flags = 0;
241 if (CALL(q,is_mmapped,vb))
242 b->flags |= V4L2_BUF_FLAG_MAPPED;
243
244 switch (vb->state) {
245 case STATE_PREPARED:
246 case STATE_QUEUED:
247 case STATE_ACTIVE:
248 b->flags |= V4L2_BUF_FLAG_QUEUED;
249 break;
250 case STATE_DONE:
251 case STATE_ERROR:
252 b->flags |= V4L2_BUF_FLAG_DONE;
253 break;
254 case STATE_NEEDS_INIT:
255 case STATE_IDLE:
256 /* nothing */
257 break;
258 }
259
260 if (vb->input != UNSET) {
261 b->flags |= V4L2_BUF_FLAG_INPUT;
262 b->input = vb->input;
263 }
264
265 b->field = vb->field;
266 b->timestamp = vb->ts;
267 b->bytesused = vb->size;
268 b->sequence = vb->field_count >> 1;
269}
270
271int videobuf_reqbufs(struct videobuf_queue *q,
272 struct v4l2_requestbuffers *req)
273{
274 unsigned int size,count;
275 int retval;
276
277 if (req->type != q->type) {
278 dprintk(1,"reqbufs: queue type invalid\n");
279 return -EINVAL;
280 }
281 if (req->count < 1) {
282 dprintk(1,"reqbufs: count invalid (%d)\n",req->count);
283 return -EINVAL;
284 }
285 if (req->memory != V4L2_MEMORY_MMAP &&
286 req->memory != V4L2_MEMORY_USERPTR &&
287 req->memory != V4L2_MEMORY_OVERLAY) {
288 dprintk(1,"reqbufs: memory type invalid\n");
289 return -EINVAL;
290 }
291
292 if (q->streaming) {
293 dprintk(1,"reqbufs: streaming already exists\n");
294 return -EBUSY;
295 }
296 if (!list_empty(&q->stream)) {
297 dprintk(1,"reqbufs: stream running\n");
298 return -EBUSY;
299 }
300
301 mutex_lock(&q->lock);
302 count = req->count;
303 if (count > VIDEO_MAX_FRAME)
304 count = VIDEO_MAX_FRAME;
305 size = 0;
306 q->ops->buf_setup(q,&count,&size);
307 size = PAGE_ALIGN(size);
308 dprintk(1,"reqbufs: bufs=%d, size=0x%x [%d pages total]\n",
309 count, size, (count*size)>>PAGE_SHIFT);
310
311 retval = videobuf_mmap_setup(q,count,size,req->memory);
312 if (retval < 0) {
313 dprintk(1,"reqbufs: mmap setup returned %d\n",retval);
314 goto done;
315 }
316
317 req->count = count;
318
319 done:
320 mutex_unlock(&q->lock);
321 return retval;
322}
323
324int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
325{
326 if (unlikely(b->type != q->type)) {
327 dprintk(1,"querybuf: Wrong type.\n");
328 return -EINVAL;
329 }
330 if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) {
331 dprintk(1,"querybuf: index out of range.\n");
332 return -EINVAL;
333 }
334 if (unlikely(NULL == q->bufs[b->index])) {
335 dprintk(1,"querybuf: buffer is null.\n");
336 return -EINVAL;
337 }
338 videobuf_status(q,b,q->bufs[b->index],q->type);
339 return 0;
340}
341
342int videobuf_qbuf(struct videobuf_queue *q,
343 struct v4l2_buffer *b)
344{
345 struct videobuf_buffer *buf;
346 enum v4l2_field field;
347 unsigned long flags=0;
348 int retval;
349
350 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
351
352 mutex_lock(&q->lock);
353 retval = -EBUSY;
354 if (q->reading) {
355 dprintk(1,"qbuf: Reading running...\n");
356 goto done;
357 }
358 retval = -EINVAL;
359 if (b->type != q->type) {
360 dprintk(1,"qbuf: Wrong type.\n");
361 goto done;
362 }
363 if (b->index < 0 || b->index >= VIDEO_MAX_FRAME) {
364 dprintk(1,"qbuf: index out of range.\n");
365 goto done;
366 }
367 buf = q->bufs[b->index];
368 if (NULL == buf) {
369 dprintk(1,"qbuf: buffer is null.\n");
370 goto done;
371 }
372 MAGIC_CHECK(buf->magic,MAGIC_BUFFER);
373 if (buf->memory != b->memory) {
374 dprintk(1,"qbuf: memory type is wrong.\n");
375 goto done;
376 }
377 if (buf->state != STATE_NEEDS_INIT && buf->state != STATE_IDLE) {
378 dprintk(1,"qbuf: buffer is already queued or active.\n");
379 goto done;
380 }
381
382 if (b->flags & V4L2_BUF_FLAG_INPUT) {
383 if (b->input >= q->inputs) {
384 dprintk(1,"qbuf: wrong input.\n");
385 goto done;
386 }
387 buf->input = b->input;
388 } else {
389 buf->input = UNSET;
390 }
391
392 switch (b->memory) {
393 case V4L2_MEMORY_MMAP:
394 if (0 == buf->baddr) {
395 dprintk(1,"qbuf: mmap requested but buffer addr is zero!\n");
396 goto done;
397 }
398 break;
399 case V4L2_MEMORY_USERPTR:
400 if (b->length < buf->bsize) {
401 dprintk(1,"qbuf: buffer length is not enough\n");
402 goto done;
403 }
404 if (STATE_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr)
405 q->ops->buf_release(q,buf);
406 buf->baddr = b->m.userptr;
407 break;
408 case V4L2_MEMORY_OVERLAY:
409 buf->boff = b->m.offset;
410 break;
411 default:
412 dprintk(1,"qbuf: wrong memory type\n");
413 goto done;
414 }
415
416 dprintk(1,"qbuf: requesting next field\n");
417 field = videobuf_next_field(q);
418 retval = q->ops->buf_prepare(q,buf,field);
419 if (0 != retval) {
420 dprintk(1,"qbuf: buffer_prepare returned %d\n",retval);
421 goto done;
422 }
423
424 list_add_tail(&buf->stream,&q->stream);
425 if (q->streaming) {
426 if (q->irqlock)
427 spin_lock_irqsave(q->irqlock,flags);
428 q->ops->buf_queue(q,buf);
429 if (q->irqlock)
430 spin_unlock_irqrestore(q->irqlock,flags);
431 }
432 dprintk(1,"qbuf: succeded\n");
433 retval = 0;
434
435 done:
436 mutex_unlock(&q->lock);
437 return retval;
438}
439
440int videobuf_dqbuf(struct videobuf_queue *q,
441 struct v4l2_buffer *b, int nonblocking)
442{
443 struct videobuf_buffer *buf;
444 int retval;
445
446 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
447
448 mutex_lock(&q->lock);
449 retval = -EBUSY;
450 if (q->reading) {
451 dprintk(1,"dqbuf: Reading running...\n");
452 goto done;
453 }
454 retval = -EINVAL;
455 if (b->type != q->type) {
456 dprintk(1,"dqbuf: Wrong type.\n");
457 goto done;
458 }
459 if (list_empty(&q->stream)) {
460 dprintk(1,"dqbuf: stream running\n");
461 goto done;
462 }
463 buf = list_entry(q->stream.next, struct videobuf_buffer, stream);
464 retval = videobuf_waiton(buf, nonblocking, 1);
465 if (retval < 0) {
466 dprintk(1,"dqbuf: waiton returned %d\n",retval);
467 goto done;
468 }
469 switch (buf->state) {
470 case STATE_ERROR:
471 dprintk(1,"dqbuf: state is error\n");
472 retval = -EIO;
473 CALL(q,sync,q, buf);
474 buf->state = STATE_IDLE;
475 break;
476 case STATE_DONE:
477 dprintk(1,"dqbuf: state is done\n");
478 CALL(q,sync,q, buf);
479 buf->state = STATE_IDLE;
480 break;
481 default:
482 dprintk(1,"dqbuf: state invalid\n");
483 retval = -EINVAL;
484 goto done;
485 }
486 list_del(&buf->stream);
487 memset(b,0,sizeof(*b));
488 videobuf_status(q,b,buf,q->type);
489
490 done:
491 mutex_unlock(&q->lock);
492 return retval;
493}
494
495int videobuf_streamon(struct videobuf_queue *q)
496{
497 struct videobuf_buffer *buf;
498 struct list_head *list;
499 unsigned long flags=0;
500 int retval;
501
502 mutex_lock(&q->lock);
503 retval = -EBUSY;
504 if (q->reading)
505 goto done;
506 retval = 0;
507 if (q->streaming)
508 goto done;
509 q->streaming = 1;
510 if (q->irqlock)
511 spin_lock_irqsave(q->irqlock,flags);
512 list_for_each(list,&q->stream) {
513 buf = list_entry(list, struct videobuf_buffer, stream);
514 if (buf->state == STATE_PREPARED)
515 q->ops->buf_queue(q,buf);
516 }
517 if (q->irqlock)
518 spin_unlock_irqrestore(q->irqlock,flags);
519
520 done:
521 mutex_unlock(&q->lock);
522 return retval;
523}
524
525int videobuf_streamoff(struct videobuf_queue *q)
526{
527 int retval = -EINVAL;
528
529 mutex_lock(&q->lock);
530 if (!q->streaming)
531 goto done;
532 videobuf_queue_cancel(q);
533 q->streaming = 0;
534 retval = 0;
535
536 done:
537 mutex_unlock(&q->lock);
538 return retval;
539}
540
541static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
542 char __user *data,
543 size_t count, loff_t *ppos)
544{
545 enum v4l2_field field;
546 unsigned long flags=0;
547 int retval;
548
549 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
550
551 /* setup stuff */
552 q->read_buf = videobuf_alloc(q);
553 if (NULL == q->read_buf)
554 return -ENOMEM;
555
556 q->read_buf->memory = V4L2_MEMORY_USERPTR;
557 q->read_buf->baddr = (unsigned long)data;
558 q->read_buf->bsize = count;
559
560 field = videobuf_next_field(q);
561 retval = q->ops->buf_prepare(q,q->read_buf,field);
562 if (0 != retval)
563 goto done;
564
565 /* start capture & wait */
566 if (q->irqlock)
567 spin_lock_irqsave(q->irqlock,flags);
568 q->ops->buf_queue(q,q->read_buf);
569 if (q->irqlock)
570 spin_unlock_irqrestore(q->irqlock,flags);
571 retval = videobuf_waiton(q->read_buf,0,0);
572 if (0 == retval) {
573 CALL(q,sync,q,q->read_buf);
574 if (STATE_ERROR == q->read_buf->state)
575 retval = -EIO;
576 else
577 retval = q->read_buf->size;
578 }
579
580 done:
581 /* cleanup */
582 q->ops->buf_release(q,q->read_buf);
583 kfree(q->read_buf);
584 q->read_buf = NULL;
585 return retval;
586}
587
588ssize_t videobuf_read_one(struct videobuf_queue *q,
589 char __user *data, size_t count, loff_t *ppos,
590 int nonblocking)
591{
592 enum v4l2_field field;
593 unsigned long flags=0;
594 unsigned size, nbufs;
595 int retval;
596
597 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
598
599 mutex_lock(&q->lock);
600
601 nbufs = 1; size = 0;
602 q->ops->buf_setup(q,&nbufs,&size);
603
604 if (NULL == q->read_buf &&
605 count >= size &&
606 !nonblocking) {
607 retval = videobuf_read_zerocopy(q,data,count,ppos);
608 if (retval >= 0 || retval == -EIO)
609 /* ok, all done */
610 goto done;
611 /* fallback to kernel bounce buffer on failures */
612 }
613
614 if (NULL == q->read_buf) {
615 /* need to capture a new frame */
616 retval = -ENOMEM;
617 q->read_buf = videobuf_alloc(q);
618
619 dprintk(1,"video alloc=0x%p\n", q->read_buf);
620 if (NULL == q->read_buf)
621 goto done;
622 q->read_buf->memory = V4L2_MEMORY_USERPTR;
623 q->read_buf->bsize = count; /* preferred size */
624 field = videobuf_next_field(q);
625 retval = q->ops->buf_prepare(q,q->read_buf,field);
626
627 if (0 != retval) {
628 kfree (q->read_buf);
629 q->read_buf = NULL;
630 goto done;
631 }
632 if (q->irqlock)
633 spin_lock_irqsave(q->irqlock,flags);
634
635 q->ops->buf_queue(q,q->read_buf);
636 if (q->irqlock)
637 spin_unlock_irqrestore(q->irqlock,flags);
638 q->read_off = 0;
639 }
640
641 /* wait until capture is done */
642 retval = videobuf_waiton(q->read_buf, nonblocking, 1);
643 if (0 != retval)
644 goto done;
645
646 CALL(q,sync,q,q->read_buf);
647
648 if (STATE_ERROR == q->read_buf->state) {
649 /* catch I/O errors */
650 q->ops->buf_release(q,q->read_buf);
651 kfree(q->read_buf);
652 q->read_buf = NULL;
653 retval = -EIO;
654 goto done;
655 }
656
657 /* Copy to userspace */
658 retval=CALL(q,copy_to_user,q,data,count,nonblocking);
659 if (retval<0)
660 goto done;
661
662 q->read_off += retval;
663 if (q->read_off == q->read_buf->size) {
664 /* all data copied, cleanup */
665 q->ops->buf_release(q,q->read_buf);
666 kfree(q->read_buf);
667 q->read_buf = NULL;
668 }
669
670 done:
671 mutex_unlock(&q->lock);
672 return retval;
673}
674
675int videobuf_read_start(struct videobuf_queue *q)
676{
677 enum v4l2_field field;
678 unsigned long flags=0;
679 int count = 0, size = 0;
680 int err, i;
681
682 q->ops->buf_setup(q,&count,&size);
683 if (count < 2)
684 count = 2;
685 if (count > VIDEO_MAX_FRAME)
686 count = VIDEO_MAX_FRAME;
687 size = PAGE_ALIGN(size);
688
689 err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR);
690 if (err)
691 return err;
692
693 for (i = 0; i < count; i++) {
694 field = videobuf_next_field(q);
695 err = q->ops->buf_prepare(q,q->bufs[i],field);
696 if (err)
697 return err;
698 list_add_tail(&q->bufs[i]->stream, &q->stream);
699 }
700 if (q->irqlock)
701 spin_lock_irqsave(q->irqlock,flags);
702 for (i = 0; i < count; i++)
703 q->ops->buf_queue(q,q->bufs[i]);
704 if (q->irqlock)
705 spin_unlock_irqrestore(q->irqlock,flags);
706 q->reading = 1;
707 return 0;
708}
709
710void videobuf_read_stop(struct videobuf_queue *q)
711{
712 int i;
713
714 videobuf_queue_cancel(q);
715 videobuf_mmap_free(q);
716 INIT_LIST_HEAD(&q->stream);
717 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
718 if (NULL == q->bufs[i])
719 continue;
720 kfree(q->bufs[i]);
721 q->bufs[i] = NULL;
722 }
723 q->read_buf = NULL;
724 q->reading = 0;
725}
726
727ssize_t videobuf_read_stream(struct videobuf_queue *q,
728 char __user *data, size_t count, loff_t *ppos,
729 int vbihack, int nonblocking)
730{
731 int rc, retval;
732 unsigned long flags=0;
733
734 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
735
736 dprintk(2,"%s\n",__FUNCTION__);
737 mutex_lock(&q->lock);
738 retval = -EBUSY;
739 if (q->streaming)
740 goto done;
741 if (!q->reading) {
742 retval = videobuf_read_start(q);
743 if (retval < 0)
744 goto done;
745 }
746
747 retval = 0;
748 while (count > 0) {
749 /* get / wait for data */
750 if (NULL == q->read_buf) {
751 q->read_buf = list_entry(q->stream.next,
752 struct videobuf_buffer,
753 stream);
754 list_del(&q->read_buf->stream);
755 q->read_off = 0;
756 }
757 rc = videobuf_waiton(q->read_buf, nonblocking, 1);
758 if (rc < 0) {
759 if (0 == retval)
760 retval = rc;
761 break;
762 }
763
764 if (q->read_buf->state == STATE_DONE) {
765 rc = CALL (q,copy_stream, q, data, count,
766 retval, vbihack, nonblocking);
767 if (rc < 0) {
768 retval = rc;
769 break;
770 }
771 retval += rc;
772 count -= rc;
773 q->read_off += rc;
774 } else {
775 /* some error */
776 q->read_off = q->read_buf->size;
777 if (0 == retval)
778 retval = -EIO;
779 }
780
781 /* requeue buffer when done with copying */
782 if (q->read_off == q->read_buf->size) {
783 list_add_tail(&q->read_buf->stream,
784 &q->stream);
785 if (q->irqlock)
786 spin_lock_irqsave(q->irqlock,flags);
787 q->ops->buf_queue(q,q->read_buf);
788 if (q->irqlock)
789 spin_unlock_irqrestore(q->irqlock,flags);
790 q->read_buf = NULL;
791 }
792 if (retval < 0)
793 break;
794 }
795
796 done:
797 mutex_unlock(&q->lock);
798 return retval;
799}
800
801unsigned int videobuf_poll_stream(struct file *file,
802 struct videobuf_queue *q,
803 poll_table *wait)
804{
805 struct videobuf_buffer *buf = NULL;
806 unsigned int rc = 0;
807
808 mutex_lock(&q->lock);
809 if (q->streaming) {
810 if (!list_empty(&q->stream))
811 buf = list_entry(q->stream.next,
812 struct videobuf_buffer, stream);
813 } else {
814 if (!q->reading)
815 videobuf_read_start(q);
816 if (!q->reading) {
817 rc = POLLERR;
818 } else if (NULL == q->read_buf) {
819 q->read_buf = list_entry(q->stream.next,
820 struct videobuf_buffer,
821 stream);
822 list_del(&q->read_buf->stream);
823 q->read_off = 0;
824 }
825 buf = q->read_buf;
826 }
827 if (!buf)
828 rc = POLLERR;
829
830 if (0 == rc) {
831 poll_wait(file, &buf->done, wait);
832 if (buf->state == STATE_DONE ||
833 buf->state == STATE_ERROR)
834 rc = POLLIN|POLLRDNORM;
835 }
836 mutex_unlock(&q->lock);
837 return rc;
838}
839
840int videobuf_mmap_setup(struct videobuf_queue *q,
841 unsigned int bcount, unsigned int bsize,
842 enum v4l2_memory memory)
843{
844 unsigned int i;
845 int err;
846
847 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
848
849 err = videobuf_mmap_free(q);
850 if (0 != err)
851 return err;
852
853 /* Allocate and initialize buffers */
854 for (i = 0; i < bcount; i++) {
855 q->bufs[i] = videobuf_alloc(q);
856
857 q->bufs[i]->i = i;
858 q->bufs[i]->input = UNSET;
859 q->bufs[i]->memory = memory;
860 q->bufs[i]->bsize = bsize;
861 switch (memory) {
862 case V4L2_MEMORY_MMAP:
863 q->bufs[i]->boff = bsize * i;
864 break;
865 case V4L2_MEMORY_USERPTR:
866 case V4L2_MEMORY_OVERLAY:
867 /* nothing */
868 break;
869 }
870 }
871
872 dprintk(1,"mmap setup: %d buffers, %d bytes each\n",
873 bcount,bsize);
874
875 return 0;
876}
877
878int videobuf_mmap_free(struct videobuf_queue *q)
879{
880 int i;
881 int rc;
882
883 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
884
885 rc = CALL(q,mmap_free,q);
886 if (rc<0)
887 return rc;
888
889 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
890 if (NULL == q->bufs[i])
891 continue;
892 q->ops->buf_release(q,q->bufs[i]);
893 kfree(q->bufs[i]);
894 q->bufs[i] = NULL;
895 }
896
897 return rc;
898}
899
900int videobuf_mmap_mapper(struct videobuf_queue *q,
901 struct vm_area_struct *vma)
902{
903 int retval;
904
905 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
906
907 mutex_lock(&q->lock);
908 retval=CALL(q,mmap_mapper,q,vma);
909 mutex_unlock(&q->lock);
910
911 return retval;
912}
913
914#ifdef CONFIG_VIDEO_V4L1_COMPAT
915int videobuf_cgmbuf(struct videobuf_queue *q,
916 struct video_mbuf *mbuf, int count)
917{
918 struct v4l2_requestbuffers req;
919 int rc,i;
920
921 MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
922
923 memset(&req,0,sizeof(req));
924 req.type = q->type;
925 req.count = count;
926 req.memory = V4L2_MEMORY_MMAP;
927 rc = videobuf_reqbufs(q,&req);
928 if (rc < 0)
929 return rc;
930
931 mbuf->frames = req.count;
932 mbuf->size = 0;
933 for (i = 0; i < mbuf->frames; i++) {
934 mbuf->offsets[i] = q->bufs[i]->boff;
935 mbuf->size += q->bufs[i]->bsize;
936 }
937
938 return 0;
939}
940#endif
941
942/* --------------------------------------------------------------------- */
943
944EXPORT_SYMBOL_GPL(videobuf_waiton);
945EXPORT_SYMBOL_GPL(videobuf_iolock);
946
947EXPORT_SYMBOL_GPL(videobuf_alloc);
948
949EXPORT_SYMBOL_GPL(videobuf_queue_init);
950EXPORT_SYMBOL_GPL(videobuf_queue_cancel);
951EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
952
953EXPORT_SYMBOL_GPL(videobuf_next_field);
954EXPORT_SYMBOL_GPL(videobuf_reqbufs);
955EXPORT_SYMBOL_GPL(videobuf_querybuf);
956EXPORT_SYMBOL_GPL(videobuf_qbuf);
957EXPORT_SYMBOL_GPL(videobuf_dqbuf);
958EXPORT_SYMBOL_GPL(videobuf_cgmbuf);
959EXPORT_SYMBOL_GPL(videobuf_streamon);
960EXPORT_SYMBOL_GPL(videobuf_streamoff);
961
962EXPORT_SYMBOL_GPL(videobuf_read_start);
963EXPORT_SYMBOL_GPL(videobuf_read_stop);
964EXPORT_SYMBOL_GPL(videobuf_read_stream);
965EXPORT_SYMBOL_GPL(videobuf_read_one);
966EXPORT_SYMBOL_GPL(videobuf_poll_stream);
967
968EXPORT_SYMBOL_GPL(videobuf_mmap_setup);
969EXPORT_SYMBOL_GPL(videobuf_mmap_free);
970EXPORT_SYMBOL_GPL(videobuf_mmap_mapper);
971
972/*
973 * Local variables:
974 * c-basic-offset: 8
975 * End:
976 */