Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
426 | giacomo | 1 | /* |
2 | * generic helper functions for video4linux capture buffers, to handle |
||
3 | * memory management and PCI DMA. Right now bttv + saa7134 use it. |
||
4 | * |
||
5 | * The functions expect the hardware being able to scatter gatter |
||
6 | * (i.e. the buffers are not linear in physical memory, but fragmented |
||
7 | * into PAGE_SIZE chunks). They also assume the driver does not need |
||
8 | * to touch the video data (thus it is probably not useful for USB as |
||
9 | * data often must be uncompressed by the drivers). |
||
10 | * |
||
11 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> |
||
12 | * |
||
13 | * This program is free software; you can redistribute it and/or modify |
||
14 | * it under the terms of the GNU General Public License as published by |
||
15 | * the Free Software Foundation; either version 2 of the License, or |
||
16 | * (at your option) any later version. |
||
17 | */ |
||
18 | |||
19 | #include <linux/videodev.h> |
||
20 | |||
21 | /* --------------------------------------------------------------------- */ |
||
22 | |||
23 | /* |
||
24 | * Return a scatterlist for some page-aligned vmalloc()'ed memory |
||
25 | * block (NULL on errors). Memory for the scatterlist is allocated |
||
26 | * using kmalloc. The caller must free the memory. |
||
27 | */ |
||
28 | struct scatterlist* videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages); |
||
29 | |||
30 | /* |
||
31 | * Return a scatterlist for a an array of userpages (NULL on errors). |
||
32 | * Memory for the scatterlist is allocated using kmalloc. The caller |
||
33 | * must free the memory. |
||
34 | */ |
||
35 | struct scatterlist* videobuf_pages_to_sg(struct page **pages, int nr_pages, |
||
36 | int offset); |
||
37 | int videobuf_lock(struct page **pages, int nr_pages); |
||
38 | int videobuf_unlock(struct page **pages, int nr_pages); |
||
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_pci_*() |
||
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 | |||
61 | struct videobuf_dmabuf { |
||
62 | /* for userland buffer */ |
||
63 | int offset; |
||
64 | struct page **pages; |
||
65 | |||
66 | /* for kernel buffers */ |
||
67 | void *vmalloc; |
||
68 | |||
69 | /* for overlay buffers (pci-pci dma) */ |
||
70 | dma_addr_t bus_addr; |
||
71 | |||
72 | /* common */ |
||
73 | struct scatterlist *sglist; |
||
74 | int sglen; |
||
75 | int nr_pages; |
||
76 | int direction; |
||
77 | }; |
||
78 | |||
79 | int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction, |
||
80 | unsigned long data, unsigned long size); |
||
81 | int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, |
||
82 | int nr_pages); |
||
83 | int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction, |
||
84 | dma_addr_t addr, int nr_pages); |
||
85 | int videobuf_dma_pci_map(struct pci_dev *dev, struct videobuf_dmabuf *dma); |
||
86 | int videobuf_dma_pci_sync(struct pci_dev *dev, |
||
87 | struct videobuf_dmabuf *dma); |
||
88 | int videobuf_dma_pci_unmap(struct pci_dev *dev, struct videobuf_dmabuf *dma); |
||
89 | int videobuf_dma_free(struct videobuf_dmabuf *dma); |
||
90 | |||
91 | /* --------------------------------------------------------------------- */ |
||
92 | |||
93 | /* |
||
94 | * A small set of helper functions to manage video4linux buffers. |
||
95 | * |
||
96 | * struct videobuf_buffer holds the data structures used by the helper |
||
97 | * functions, additionally some commonly used fields for v4l buffers |
||
98 | * (width, height, lists, waitqueue) are in there. That struct should |
||
99 | * be used as first element in the drivers buffer struct. |
||
100 | * |
||
101 | * about the mmap helpers (videobuf_mmap_*): |
||
102 | * |
||
103 | * The mmaper function allows to map any subset of contingous buffers. |
||
104 | * This includes one mmap() call for all buffers (which the original |
||
105 | * video4linux API uses) as well as one mmap() for every single buffer |
||
106 | * (which v4l2 uses). |
||
107 | * |
||
108 | * If there is a valid mapping for a buffer, buffer->baddr/bsize holds |
||
109 | * userspace address + size which can be feeded into the |
||
110 | * videobuf_dma_init_user function listed above. |
||
111 | * |
||
112 | */ |
||
113 | |||
114 | struct videobuf_buffer; |
||
115 | struct videobuf_queue; |
||
116 | |||
117 | struct videobuf_mapping { |
||
118 | unsigned int count; |
||
119 | int highmem_ok; |
||
120 | unsigned long start; |
||
121 | unsigned long end; |
||
122 | struct videobuf_queue *q; |
||
123 | }; |
||
124 | |||
125 | enum videobuf_state { |
||
126 | STATE_NEEDS_INIT = 0, |
||
127 | STATE_PREPARED = 1, |
||
128 | STATE_QUEUED = 2, |
||
129 | STATE_ACTIVE = 3, |
||
130 | STATE_DONE = 4, |
||
131 | STATE_ERROR = 5, |
||
132 | STATE_IDLE = 6, |
||
133 | }; |
||
134 | |||
135 | struct videobuf_buffer { |
||
136 | unsigned int i; |
||
137 | |||
138 | /* info about the buffer */ |
||
139 | unsigned int width; |
||
140 | unsigned int height; |
||
141 | unsigned int bytesperline; /* use only if != 0 */ |
||
142 | unsigned long size; |
||
143 | enum v4l2_field field; |
||
144 | enum videobuf_state state; |
||
145 | struct videobuf_dmabuf dma; |
||
146 | struct list_head stream; /* QBUF/DQBUF list */ |
||
147 | |||
148 | /* for mmap'ed buffers */ |
||
149 | enum v4l2_memory memory; |
||
150 | size_t boff; /* buffer offset (mmap + overlay) */ |
||
151 | size_t bsize; /* buffer size */ |
||
152 | unsigned long baddr; /* buffer addr (userland ptr!) */ |
||
153 | struct videobuf_mapping *map; |
||
154 | |||
155 | /* touched by irq handler */ |
||
156 | struct list_head queue; |
||
157 | wait_queue_head_t done; |
||
158 | unsigned int field_count; |
||
159 | struct timeval ts; |
||
160 | }; |
||
161 | |||
162 | struct videobuf_queue_ops { |
||
163 | int (*buf_setup)(struct file *file, |
||
164 | unsigned int *count, unsigned int *size); |
||
165 | int (*buf_prepare)(struct file *file,struct videobuf_buffer *vb, |
||
166 | enum v4l2_field field); |
||
167 | void (*buf_queue)(struct file *file,struct videobuf_buffer *vb); |
||
168 | void (*buf_release)(struct file *file,struct videobuf_buffer *vb); |
||
169 | }; |
||
170 | |||
171 | struct videobuf_queue { |
||
172 | struct semaphore lock; |
||
173 | spinlock_t *irqlock; |
||
174 | struct pci_dev *pci; |
||
175 | |||
176 | enum v4l2_buf_type type; |
||
177 | unsigned int msize; |
||
178 | enum v4l2_field field; |
||
179 | enum v4l2_field last; /* for field=V4L2_FIELD_ALTERNATE */ |
||
180 | struct videobuf_buffer *bufs[VIDEO_MAX_FRAME]; |
||
181 | struct videobuf_queue_ops *ops; |
||
182 | |||
183 | /* capture via mmap() + ioctl(QBUF/DQBUF) */ |
||
184 | unsigned int streaming; |
||
185 | struct list_head stream; |
||
186 | |||
187 | /* capture via read() */ |
||
188 | unsigned int reading; |
||
189 | unsigned int read_off; |
||
190 | struct videobuf_buffer *read_buf; |
||
191 | }; |
||
192 | |||
193 | void* videobuf_alloc(unsigned int size); |
||
194 | int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr); |
||
195 | int videobuf_iolock(struct pci_dev *pci, struct videobuf_buffer *vb, |
||
196 | struct v4l2_framebuffer *fbuf); |
||
197 | |||
198 | void videobuf_queue_init(struct videobuf_queue *q, |
||
199 | struct videobuf_queue_ops *ops, |
||
200 | struct pci_dev *pci, spinlock_t *irqlock, |
||
201 | enum v4l2_buf_type type, |
||
202 | enum v4l2_field field, |
||
203 | unsigned int msize); |
||
204 | int videobuf_queue_is_busy(struct videobuf_queue *q); |
||
205 | void videobuf_queue_cancel(struct file *file, struct videobuf_queue *q); |
||
206 | |||
207 | enum v4l2_field videobuf_next_field(struct videobuf_queue *q); |
||
208 | void videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb, |
||
209 | enum v4l2_buf_type type); |
||
210 | int videobuf_reqbufs(struct file *file, struct videobuf_queue *q, |
||
211 | struct v4l2_requestbuffers *req); |
||
212 | int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b); |
||
213 | int videobuf_qbuf(struct file *file, struct videobuf_queue *q, |
||
214 | struct v4l2_buffer *b); |
||
215 | int videobuf_dqbuf(struct file *file, struct videobuf_queue *q, |
||
216 | struct v4l2_buffer *b); |
||
217 | int videobuf_streamon(struct file *file, struct videobuf_queue *q); |
||
218 | int videobuf_streamoff(struct file *file, struct videobuf_queue *q); |
||
219 | |||
220 | int videobuf_read_start(struct file *file, struct videobuf_queue *q); |
||
221 | void videobuf_read_stop(struct file *file, struct videobuf_queue *q); |
||
222 | ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q, |
||
223 | char *data, size_t count, loff_t *ppos, |
||
224 | int vbihack); |
||
225 | ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q, |
||
226 | char *data, size_t count, loff_t *ppos); |
||
227 | unsigned int videobuf_poll_stream(struct file *file, |
||
228 | struct videobuf_queue *q, |
||
229 | poll_table *wait); |
||
230 | |||
231 | int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q, |
||
232 | unsigned int bcount, unsigned int bsize, |
||
233 | enum v4l2_memory memory); |
||
234 | int videobuf_mmap_free(struct file *file, struct videobuf_queue *q); |
||
235 | int videobuf_mmap_mapper(struct vm_area_struct *vma, |
||
236 | struct videobuf_queue *q); |
||
237 | |||
238 | /* --------------------------------------------------------------------- */ |
||
239 | |||
240 | /* |
||
241 | * Local variables: |
||
242 | * c-basic-offset: 8 |
||
243 | * End: |
||
244 | */ |