Syntek USB Video Camera
stk11xx-buf.c
Go to the documentation of this file.
1
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/kernel.h>
37#include <linux/version.h>
38#include <linux/errno.h>
39#include <linux/slab.h>
40#include <linux/kref.h>
41#include <linux/vmalloc.h>
42#include <linux/mm.h>
43
44#include <linux/usb.h>
45#include <media/v4l2-common.h>
46#include <media/v4l2-ioctl.h>
47
48#include "stk11xx.h"
49
50
55static int default_nbrframebuf = 3;
56
57
67void * stk11xx_rvmalloc(unsigned long size)
68{
69 void *mem;
70 unsigned long addr;
71
72 size = PAGE_ALIGN(size);
73 mem = vmalloc_32(size);
74
75 if (!mem)
76 return NULL;
77
78 memset(mem, 0, size);
79
80 addr = (unsigned long) mem;
81
82 while (size > 0) {
83 SetPageReserved(vmalloc_to_page((void *) addr));
84 addr += PAGE_SIZE;
85 size -= PAGE_SIZE;
86 }
87
88 return mem;
89}
90
91
100void stk11xx_rvfree(void *mem, unsigned long size)
101{
102 unsigned long addr;
103
104 if (!mem)
105 return;
106
107 addr = (unsigned long) mem;
108
109 while ((long) size > 0) {
110 ClearPageReserved(vmalloc_to_page((void *) addr));
111 addr += PAGE_SIZE;
112 size -= PAGE_SIZE;
113 }
114
115 vfree(mem);
116}
117
118
129{
130 int i;
131 void *kbuf;
132
133 STK_DEBUG("Allocate video buffers\n");
134
135 if (dev == NULL)
136 return -ENXIO;
137
138 // Allocate isochronous pipe buffers
139 for (i=0; i<MAX_ISO_BUFS; i++) {
140 if (dev->isobuf[i].data == NULL) {
141 kbuf = kzalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
142
143 if (kbuf == NULL) {
144 STK_ERROR("Failed to allocate iso buffer %d\n", i);
145 return -ENOMEM;
146 }
147
148 STK_DEBUG("Allocated iso buffer at %p\n", kbuf);
149
150 dev->isobuf[i].data = kbuf;
151 }
152 }
153
154 // Allocate frame buffer structure
155 if (dev->framebuf == NULL) {
156 kbuf = kzalloc(default_nbrframebuf * sizeof(struct stk11xx_frame_buf), GFP_KERNEL);
157
158 if (kbuf == NULL) {
159 STK_ERROR("Failed to allocate frame buffer structure\n");
160 return -ENOMEM;
161 }
162
163 STK_DEBUG("Allocated frame buffer structure at %p\n", kbuf);
164
165 dev->framebuf = kbuf;
166 }
167
168 // Create frame buffers and make circular ring
169 for (i=0; i<default_nbrframebuf; i++) {
170 if (dev->framebuf[i].data == NULL) {
171 kbuf = vmalloc(STK11XX_FRAME_SIZE);
172
173 if (kbuf == NULL) {
174 STK_ERROR("Failed to allocate frame buffer %d\n", i);
175 return -ENOMEM;
176 }
177
178 STK_DEBUG("Allocated frame buffer %d at %p.\n", i, kbuf);
179
180 dev->framebuf[i].data = kbuf;
181 memset(kbuf, 0, STK11XX_FRAME_SIZE);
182 }
183 }
184
185 // Allocate image buffer; double buffer for mmap()
186 kbuf = stk11xx_rvmalloc(dev->nbuffers * dev->len_per_image);
187
188 if (kbuf == NULL) {
189 STK_ERROR("Failed to allocate image buffer(s). needed (%d)\n",
190 dev->nbuffers * dev->len_per_image);
191 return -ENOMEM;
192 }
193
194 STK_DEBUG("Allocated image buffer at %p\n", kbuf);
195
196 dev->image_data = kbuf;
197
198 for (i = 0; i < dev->nbuffers; i++) {
199 dev->images[i].offset = i * dev->len_per_image;
200 dev->images[i].vma_use_count = 0;
201 }
202
203 for (; i < STK11XX_MAX_IMAGES; i++)
204 dev->images[i].offset = 0;
205
206 kbuf = NULL;
207
208 return 0;
209}
210
211
222{
223 int i;
224 unsigned long flags;
225
226 STK_DEBUG("Reset all buffers\n");
227
228 spin_lock_irqsave(&dev->spinlock, flags);
229
230 dev->full_frames = NULL;
231 dev->full_frames_tail = NULL;
232
233 for (i=0; i<dev->nbuffers; i++) {
234 dev->framebuf[i].filled = 0;
235 dev->framebuf[i].errors = 0;
236
237 if (i > 0)
238 dev->framebuf[i].next = &dev->framebuf[i - 1];
239 else
240 dev->framebuf->next = NULL;
241 }
242
243 dev->empty_frames = &dev->framebuf[dev->nbuffers - 1];
244 dev->empty_frames_tail = dev->framebuf;
245 dev->read_frame = NULL;
246 dev->fill_frame = dev->empty_frames;
247 dev->empty_frames = dev->empty_frames->next;
248
249 dev->image_read_pos = 0;
250 dev->fill_image = 0;
251
252 spin_unlock_irqrestore(&dev->spinlock, flags);
253
254 for (i=0; i<dev->nbuffers; i++)
255 dev->image_used[i] = 0;
256
257 return 0;
258}
259
260
271{
272 memset(dev->image_data, 0x00, dev->nbuffers * dev->len_per_image);
273
274 return 0;
275}
276
277
288{
289 int i;
290
291 STK_DEBUG("Free buffers\n");
292
293 if (dev == NULL)
294 return -1;
295
296 // Release iso pipe buffers
297 for (i=0; i<MAX_ISO_BUFS; i++) {
298 if (dev->isobuf[i].data != NULL) {
299 kfree(dev->isobuf[i].data);
300 dev->isobuf[i].data = NULL;
301 }
302 }
303
304 // Release frame buffers
305 if (dev->framebuf != NULL) {
306 for (i=0; i<default_nbrframebuf; i++) {
307 if (dev->framebuf[i].data != NULL) {
308 vfree(dev->framebuf[i].data);
309 dev->framebuf[i].data = NULL;
310 }
311 }
312
313 kfree(dev->framebuf);
314 dev->framebuf = NULL;
315 }
316
317 // Release image buffers
318 if (dev->image_data != NULL)
319 stk11xx_rvfree(dev->image_data, dev->nbuffers * dev->len_per_image);
320
321 dev->image_data = NULL;
322
323 return 0;
324}
325
326
335{
336 STK_STREAM("Select next image\n");
337
338 dev->image_used[dev->fill_image] = 0;
339 dev->fill_image = (dev->fill_image + 1) % dev->nbuffers;
340}
341
342
353{
354 int ret = 0;
355 unsigned long flags;
356
357 STK_STREAM("Select next frame\n");
358
359 spin_lock_irqsave(&dev->spinlock, flags);
360
361 if (dev->fill_frame != NULL) {
362 if (dev->full_frames == NULL) {
363 dev->full_frames = dev->fill_frame;
364 dev->full_frames_tail = dev->full_frames;
365 }
366 else {
367 dev->full_frames_tail->next = dev->fill_frame;
368 dev->full_frames_tail = dev->fill_frame;
369 }
370 }
371
372 if (dev->empty_frames != NULL) {
373 dev->fill_frame = dev->empty_frames;
374 dev->empty_frames = dev->empty_frames->next;
375 }
376 else {
377 if (dev->full_frames == NULL) {
378 STK_ERROR("Neither empty or full frames available!\n");
379 spin_unlock_irqrestore(&dev->spinlock, flags);
380 return -EINVAL;
381 }
382
383 dev->fill_frame = dev->full_frames;
384 dev->full_frames = dev->full_frames->next;
385
386 ret = 1;
387 }
388
389 dev->fill_frame->next = NULL;
390
391 spin_unlock_irqrestore(&dev->spinlock, flags);
392
393 return ret;
394}
395
396
408{
409 int ret = 0;
410 unsigned long flags;
411
412 STK_STREAM("Sync Handle Frame\n");
413
414 spin_lock_irqsave(&dev->spinlock, flags);
415
416 if (dev->read_frame != NULL) {
417 spin_unlock_irqrestore(&dev->spinlock, flags);
418 return ret;
419 }
420
421 if (dev->full_frames == NULL) {
422 }
423 else {
424 dev->read_frame = dev->full_frames;
425 dev->full_frames = dev->full_frames->next;
426 dev->read_frame->next = NULL;
427 }
428
429 if (dev->read_frame != NULL) {
430 spin_unlock_irqrestore(&dev->spinlock, flags);
431 ret = dev_stk11xx_decompress(dev);
432 spin_lock_irqsave(&dev->spinlock, flags);
433
434 if (dev->empty_frames == NULL) {
435 dev->empty_frames = dev->read_frame;
436 dev->empty_frames_tail = dev->empty_frames;
437 }
438 else {
439 dev->empty_frames_tail->next = dev->read_frame;
440 dev->empty_frames_tail = dev->read_frame;
441 }
442
443 dev->read_frame = NULL;
444 }
445
446 spin_unlock_irqrestore(&dev->spinlock, flags);
447
449
450 return ret;
451}
452
int stk11xx_reset_buffers(struct usb_stk11xx *dev)
Reset all ISOC buffers.
int stk11xx_handle_frame(struct usb_stk11xx *dev)
Handler frame.
static int default_nbrframebuf
Definition stk11xx-buf.c:55
int stk11xx_free_buffers(struct usb_stk11xx *dev)
Release all buffers.
int stk11xx_next_frame(struct usb_stk11xx *dev)
Prepare the next frame.
void stk11xx_next_image(struct usb_stk11xx *dev)
Prepare the next image.
void stk11xx_rvfree(void *mem, unsigned long size)
Free a buffer.
int stk11xx_allocate_buffers(struct usb_stk11xx *dev)
Allocate all ISOC buffers.
void * stk11xx_rvmalloc(unsigned long size)
Allocate a buffer.
Definition stk11xx-buf.c:67
int stk11xx_clear_buffers(struct usb_stk11xx *dev)
Clear current buffers.
int dev_stk11xx_watchdog_camera(struct usb_stk11xx *dev)
A espece of software watchdog.
int dev_stk11xx_decompress(struct usb_stk11xx *dev)
Decompress/convert a frame from the video stream.
Driver for Syntek USB video camera.
#define STK_ERROR(str, args...)
Definition stk11xx.h:156
#define STK_STREAM(str, args...)
Definition stk11xx.h:181
#define STK_DEBUG(str, args...)
Definition stk11xx.h:158
#define ISO_BUFFER_SIZE
Definition stk11xx.h:91
#define MAX_ISO_BUFS
Definition stk11xx.h:88
#define STK11XX_MAX_IMAGES
Definition stk11xx.h:105
#define STK11XX_FRAME_SIZE
Definition stk11xx.h:106
unsigned long offset
Definition stk11xx.h:274
spinlock_t spinlock
Definition stk11xx.h:348