aboutsummaryrefslogtreecommitdiffstats
path: root/include
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 /include
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 'include')
-rw-r--r--include/media/videobuf-core.h236
-rw-r--r--include/media/videobuf-dma-sg.h142
2 files changed, 378 insertions, 0 deletions
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h
new file mode 100644
index 000000000000..0ac21ae44f69
--- /dev/null
+++ b/include/media/videobuf-core.h
@@ -0,0 +1,236 @@
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/poll.h>
17#ifdef CONFIG_VIDEO_V4L1_COMPAT
18#include <linux/videodev.h>
19#endif
20#include <linux/videodev2.h>
21
22#define UNSET (-1U)
23
24
25struct videobuf_buffer;
26struct videobuf_queue;
27
28/* --------------------------------------------------------------------- */
29
30/*
31 * A small set of helper functions to manage video4linux buffers.
32 *
33 * struct videobuf_buffer holds the data structures used by the helper
34 * functions, additionally some commonly used fields for v4l buffers
35 * (width, height, lists, waitqueue) are in there. That struct should
36 * be used as first element in the drivers buffer struct.
37 *
38 * about the mmap helpers (videobuf_mmap_*):
39 *
40 * The mmaper function allows to map any subset of contingous buffers.
41 * This includes one mmap() call for all buffers (which the original
42 * video4linux API uses) as well as one mmap() for every single buffer
43 * (which v4l2 uses).
44 *
45 * If there is a valid mapping for a buffer, buffer->baddr/bsize holds
46 * userspace address + size which can be feeded into the
47 * videobuf_dma_init_user function listed above.
48 *
49 */
50
51struct videobuf_mapping {
52 unsigned int count;
53 unsigned long start;
54 unsigned long end;
55 struct videobuf_queue *q;
56};
57
58enum videobuf_state {
59 STATE_NEEDS_INIT = 0,
60 STATE_PREPARED = 1,
61 STATE_QUEUED = 2,
62 STATE_ACTIVE = 3,
63 STATE_DONE = 4,
64 STATE_ERROR = 5,
65 STATE_IDLE = 6,
66};
67
68struct videobuf_buffer {
69 unsigned int i;
70 u32 magic;
71
72 /* info about the buffer */
73 unsigned int width;
74 unsigned int height;
75 unsigned int bytesperline; /* use only if != 0 */
76 unsigned long size;
77 unsigned int input;
78 enum v4l2_field field;
79 enum videobuf_state state;
80 struct list_head stream; /* QBUF/DQBUF list */
81
82 /* touched by irq handler */
83 struct list_head queue;
84 wait_queue_head_t done;
85 unsigned int field_count;
86 struct timeval ts;
87
88 /* Memory type */
89 enum v4l2_memory memory;
90
91 /* buffer size */
92 size_t bsize;
93
94 /* buffer offset (mmap + overlay) */
95 size_t boff;
96
97 /* buffer addr (userland ptr!) */
98 unsigned long baddr;
99
100 /* Private pointer to allow specific methods to store their data */
101 int privsize;
102 void *priv;
103};
104
105struct videobuf_queue_ops {
106 int (*buf_setup)(struct videobuf_queue *q,
107 unsigned int *count, unsigned int *size);
108 int (*buf_prepare)(struct videobuf_queue *q,
109 struct videobuf_buffer *vb,
110 enum v4l2_field field);
111 void (*buf_queue)(struct videobuf_queue *q,
112 struct videobuf_buffer *vb);
113 void (*buf_release)(struct videobuf_queue *q,
114 struct videobuf_buffer *vb);
115};
116
117#define MAGIC_QTYPE_OPS 0x12261003
118
119/* Helper operations - device type dependent */
120struct videobuf_qtype_ops {
121 u32 magic;
122
123 void* (*alloc) (size_t size);
124 int (*iolock) (struct videobuf_queue* q,
125 struct videobuf_buffer *vb,
126 struct v4l2_framebuffer *fbuf);
127 int (*mmap) (struct videobuf_queue *q,
128 unsigned int *count,
129 unsigned int *size,
130 enum v4l2_memory memory);
131 int (*sync) (struct videobuf_queue* q,
132 struct videobuf_buffer *buf);
133 int (*copy_to_user) (struct videobuf_queue *q,
134 char __user *data,
135 size_t count,
136 int nonblocking);
137 int (*copy_stream) (struct videobuf_queue *q,
138 char __user *data,
139 size_t count,
140 size_t pos,
141 int vbihack,
142 int nonblocking);
143 int (*mmap_free) (struct videobuf_queue *q);
144 int (*mmap_mapper) (struct videobuf_queue *q,
145 struct vm_area_struct *vma);
146 int (*is_mmapped) (struct videobuf_buffer *buf);
147};
148
149struct videobuf_queue {
150 struct mutex lock;
151 spinlock_t *irqlock;
152 void *dev; /* on pci, points to struct pci_dev */
153
154 enum v4l2_buf_type type;
155 unsigned int inputs; /* for V4L2_BUF_FLAG_INPUT */
156 unsigned int msize;
157 enum v4l2_field field;
158 enum v4l2_field last; /* for field=V4L2_FIELD_ALTERNATE */
159 struct videobuf_buffer *bufs[VIDEO_MAX_FRAME];
160 struct videobuf_queue_ops *ops;
161 struct videobuf_qtype_ops *int_ops;
162
163 /* capture via mmap() + ioctl(QBUF/DQBUF) */
164 unsigned int streaming;
165 struct list_head stream;
166
167 /* capture via read() */
168 unsigned int reading;
169 unsigned int read_off;
170 struct videobuf_buffer *read_buf;
171
172 /* driver private data */
173 void *priv_data;
174
175 /*FIXME: should be removed after completing the vb conversion */
176 void *priv_ops;
177};
178
179int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
180int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
181 struct v4l2_framebuffer *fbuf);
182
183void *videobuf_alloc(struct videobuf_queue* q);
184
185void videobuf_queue_init(struct videobuf_queue *q,
186 struct videobuf_queue_ops *ops,
187 void *dev,
188 spinlock_t *irqlock,
189 enum v4l2_buf_type type,
190 enum v4l2_field field,
191 unsigned int msize,
192 void *priv);
193int videobuf_queue_is_busy(struct videobuf_queue *q);
194void videobuf_queue_cancel(struct videobuf_queue *q);
195
196enum v4l2_field videobuf_next_field(struct videobuf_queue *q);
197int videobuf_reqbufs(struct videobuf_queue *q,
198 struct v4l2_requestbuffers *req);
199int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b);
200int videobuf_qbuf(struct videobuf_queue *q,
201 struct v4l2_buffer *b);
202int videobuf_dqbuf(struct videobuf_queue *q,
203 struct v4l2_buffer *b, int nonblocking);
204#ifdef CONFIG_VIDEO_V4L1_COMPAT
205int videobuf_cgmbuf(struct videobuf_queue *q,
206 struct video_mbuf *mbuf, int count);
207#endif
208int videobuf_streamon(struct videobuf_queue *q);
209int videobuf_streamoff(struct videobuf_queue *q);
210
211int videobuf_read_start(struct videobuf_queue *q);
212void videobuf_read_stop(struct videobuf_queue *q);
213ssize_t videobuf_read_stream(struct videobuf_queue *q,
214 char __user *data, size_t count, loff_t *ppos,
215 int vbihack, int nonblocking);
216ssize_t videobuf_read_one(struct videobuf_queue *q,
217 char __user *data, size_t count, loff_t *ppos,
218 int nonblocking);
219unsigned int videobuf_poll_stream(struct file *file,
220 struct videobuf_queue *q,
221 poll_table *wait);
222
223int videobuf_mmap_setup(struct videobuf_queue *q,
224 unsigned int bcount, unsigned int bsize,
225 enum v4l2_memory memory);
226int videobuf_mmap_free(struct videobuf_queue *q);
227int videobuf_mmap_mapper(struct videobuf_queue *q,
228 struct vm_area_struct *vma);
229
230/* --------------------------------------------------------------------- */
231
232/*
233 * Local variables:
234 * c-basic-offset: 8
235 * End:
236 */
diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h
new file mode 100644
index 000000000000..62a3709905f3
--- /dev/null
+++ b/include/media/videobuf-dma-sg.h
@@ -0,0 +1,142 @@
1/*
2 * helper functions for PCI DMA video4linux capture buffers
3 *
4 * The functions expect the hardware being able to scatter gatter
5 * (i.e. the buffers are not linear in physical memory, but fragmented
6 * into PAGE_SIZE chunks). They also assume the driver does not need
7 * to touch the video data.
8 *
9 * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
10 *
11 * Highly based on video-buf written originally by:
12 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
13 * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org>
14 * (c) 2006 Ted Walther and John Sokol
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2
19 */
20
21#include <media/videobuf-core.h>
22
23/* --------------------------------------------------------------------- */
24
25/*
26 * Return a scatterlist for some page-aligned vmalloc()'ed memory
27 * block (NULL on errors). Memory for the scatterlist is allocated
28 * using kmalloc. The caller must free the memory.
29 */
30struct scatterlist* videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages);
31
32/*
33 * Return a scatterlist for a an array of userpages (NULL on errors).
34 * Memory for the scatterlist is allocated using kmalloc. The caller
35 * must free the memory.
36 */
37struct scatterlist* videobuf_pages_to_sg(struct page **pages, int nr_pages,
38 int offset);
39
40/* --------------------------------------------------------------------- */
41
42/*
43 * A small set of helper functions to manage buffers (both userland
44 * and kernel) for DMA.
45 *
46 * videobuf_dma_init_*()
47 * creates a buffer. The userland version takes a userspace
48 * pointer + length. The kernel version just wants the size and
49 * does memory allocation too using vmalloc_32().
50 *
51 * videobuf_dma_*()
52 * see Documentation/DMA-mapping.txt, these functions to
53 * basically the same. The map function does also build a
54 * scatterlist for the buffer (and unmap frees it ...)
55 *
56 * videobuf_dma_free()
57 * no comment ...
58 *
59 */
60
61struct videobuf_dmabuf {
62 u32 magic;
63
64 /* for userland buffer */
65 int offset;
66 struct page **pages;
67
68 /* for kernel buffers */
69 void *vmalloc;
70
71 /* Stores the userspace pointer to vmalloc area */
72 void *varea;
73
74 /* for overlay buffers (pci-pci dma) */
75 dma_addr_t bus_addr;
76
77 /* common */
78 struct scatterlist *sglist;
79 int sglen;
80 int nr_pages;
81 int direction;
82};
83
84struct videbuf_pci_sg_memory
85{
86 u32 magic;
87
88 /* for mmap'ed buffers */
89 struct videobuf_mapping *map;
90 struct videobuf_dmabuf dma;
91};
92
93/* FIXME: To be removed soon */
94typedef int (vb_map_sg_t)(void *dev, struct scatterlist *sglist, int nr_pages,
95 int direction);
96
97/* FIXME: To be removed soon */
98struct videobuf_dma_sg_ops
99{
100 vb_map_sg_t *vb_map_sg;
101 vb_map_sg_t *vb_dma_sync_sg;
102 vb_map_sg_t *vb_unmap_sg;
103
104};
105
106void videobuf_dma_init(struct videobuf_dmabuf *dma);
107int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
108 unsigned long data, unsigned long size);
109int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
110 int nr_pages);
111int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
112 dma_addr_t addr, int nr_pages);
113int videobuf_dma_free(struct videobuf_dmabuf *dma);
114
115int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma);
116int videobuf_dma_sync(struct videobuf_queue* q,struct videobuf_dmabuf *dma);
117int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma);
118struct videobuf_dmabuf *videobuf_to_dma (struct videobuf_buffer *buf);
119
120void *videobuf_pci_alloc (size_t size);
121
122void videobuf_queue_pci_init(struct videobuf_queue* q,
123 struct videobuf_queue_ops *ops,
124 void *dev,
125 spinlock_t *irqlock,
126 enum v4l2_buf_type type,
127 enum v4l2_field field,
128 unsigned int msize,
129 void *priv);
130
131 /*FIXME: these variants are used only on *-alsa code, where videobuf is
132 * used without queue
133 */
134int videobuf_pci_dma_map(struct pci_dev *pci,struct videobuf_dmabuf *dma);
135int videobuf_pci_dma_unmap(struct pci_dev *pci,struct videobuf_dmabuf *dma);
136
137/* FIXME: temporary routine for vivi and tm6000, while lacking implementation
138 * of videobuf-vmalloc
139 */
140void videobuf_set_pci_ops (struct videobuf_queue* q,
141 struct videobuf_dma_sg_ops *ops);
142