diff options
-rw-r--r-- | drivers/media/video/pwc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-ctrl.c | 19 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-if.c | 847 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-misc.c | 4 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-uncompress.c | 11 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-v4l.c | 125 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc.h | 76 |
7 files changed, 275 insertions, 808 deletions
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig index 8da42e4f1ba0..d63d0a850035 100644 --- a/drivers/media/video/pwc/Kconfig +++ b/drivers/media/video/pwc/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config USB_PWC | 1 | config USB_PWC |
2 | tristate "USB Philips Cameras" | 2 | tristate "USB Philips Cameras" |
3 | depends on VIDEO_V4L2 | 3 | depends on VIDEO_V4L2 |
4 | select VIDEOBUF2_VMALLOC | ||
4 | ---help--- | 5 | ---help--- |
5 | Say Y or M here if you want to use one of these Philips & OEM | 6 | Say Y or M here if you want to use one of these Philips & OEM |
6 | webcams: | 7 | webcams: |
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 760b4de13adf..19221cbca8c3 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
@@ -511,13 +511,9 @@ unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned i | |||
511 | return ret; | 511 | return ret; |
512 | } | 512 | } |
513 | 513 | ||
514 | #define BLACK_Y 0 | ||
515 | #define BLACK_U 128 | ||
516 | #define BLACK_V 128 | ||
517 | |||
518 | static void pwc_set_image_buffer_size(struct pwc_device *pdev) | 514 | static void pwc_set_image_buffer_size(struct pwc_device *pdev) |
519 | { | 515 | { |
520 | int i, factor = 0; | 516 | int factor = 0; |
521 | 517 | ||
522 | /* for V4L2_PIX_FMT_YUV420 */ | 518 | /* for V4L2_PIX_FMT_YUV420 */ |
523 | switch (pdev->pixfmt) { | 519 | switch (pdev->pixfmt) { |
@@ -541,22 +537,9 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev) | |||
541 | */ | 537 | */ |
542 | pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC; | 538 | pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC; |
543 | pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE; | 539 | pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE; |
544 | |||
545 | /* Fill buffers with black colors */ | ||
546 | for (i = 0; i < pwc_mbufs; i++) { | ||
547 | unsigned char *p = pdev->image_data + pdev->images[i].offset; | ||
548 | memset(p, BLACK_Y, pdev->view.x * pdev->view.y); | ||
549 | p += pdev->view.x * pdev->view.y; | ||
550 | memset(p, BLACK_U, pdev->view.x * pdev->view.y/4); | ||
551 | p += pdev->view.x * pdev->view.y/4; | ||
552 | memset(p, BLACK_V, pdev->view.x * pdev->view.y/4); | ||
553 | } | ||
554 | } | 540 | } |
555 | 541 | ||
556 | |||
557 | |||
558 | /* BRIGHTNESS */ | 542 | /* BRIGHTNESS */ |
559 | |||
560 | int pwc_get_brightness(struct pwc_device *pdev) | 543 | int pwc_get_brightness(struct pwc_device *pdev) |
561 | { | 544 | { |
562 | char buf; | 545 | char buf; |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 3d3ff6030987..907db23fdb5d 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -116,6 +116,7 @@ MODULE_DEVICE_TABLE(usb, pwc_device_table); | |||
116 | 116 | ||
117 | static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id); | 117 | static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id); |
118 | static void usb_pwc_disconnect(struct usb_interface *intf); | 118 | static void usb_pwc_disconnect(struct usb_interface *intf); |
119 | static void pwc_isoc_cleanup(struct pwc_device *pdev); | ||
119 | 120 | ||
120 | static struct usb_driver pwc_driver = { | 121 | static struct usb_driver pwc_driver = { |
121 | .name = "Philips webcam", /* name */ | 122 | .name = "Philips webcam", /* name */ |
@@ -129,8 +130,6 @@ static struct usb_driver pwc_driver = { | |||
129 | 130 | ||
130 | static int default_size = PSZ_QCIF; | 131 | static int default_size = PSZ_QCIF; |
131 | static int default_fps = 10; | 132 | static int default_fps = 10; |
132 | static int default_fbufs = 3; /* Default number of frame buffers */ | ||
133 | int pwc_mbufs = 2; /* Default number of mmap() buffers */ | ||
134 | #ifdef CONFIG_USB_PWC_DEBUG | 133 | #ifdef CONFIG_USB_PWC_DEBUG |
135 | int pwc_trace = PWC_DEBUG_LEVEL; | 134 | int pwc_trace = PWC_DEBUG_LEVEL; |
136 | #endif | 135 | #endif |
@@ -173,52 +172,6 @@ static struct video_device pwc_template = { | |||
173 | /***************************************************************************/ | 172 | /***************************************************************************/ |
174 | /* Private functions */ | 173 | /* Private functions */ |
175 | 174 | ||
176 | /* Here we want the physical address of the memory. | ||
177 | * This is used when initializing the contents of the area. | ||
178 | */ | ||
179 | |||
180 | |||
181 | |||
182 | static void *pwc_rvmalloc(unsigned long size) | ||
183 | { | ||
184 | void * mem; | ||
185 | unsigned long adr; | ||
186 | |||
187 | mem=vmalloc_32(size); | ||
188 | if (!mem) | ||
189 | return NULL; | ||
190 | |||
191 | memset(mem, 0, size); /* Clear the ram out, no junk to the user */ | ||
192 | adr=(unsigned long) mem; | ||
193 | while (size > 0) | ||
194 | { | ||
195 | SetPageReserved(vmalloc_to_page((void *)adr)); | ||
196 | adr += PAGE_SIZE; | ||
197 | size -= PAGE_SIZE; | ||
198 | } | ||
199 | return mem; | ||
200 | } | ||
201 | |||
202 | static void pwc_rvfree(void * mem, unsigned long size) | ||
203 | { | ||
204 | unsigned long adr; | ||
205 | |||
206 | if (!mem) | ||
207 | return; | ||
208 | |||
209 | adr=(unsigned long) mem; | ||
210 | while ((long) size > 0) | ||
211 | { | ||
212 | ClearPageReserved(vmalloc_to_page((void *)adr)); | ||
213 | adr += PAGE_SIZE; | ||
214 | size -= PAGE_SIZE; | ||
215 | } | ||
216 | vfree(mem); | ||
217 | } | ||
218 | |||
219 | |||
220 | |||
221 | |||
222 | static int pwc_allocate_buffers(struct pwc_device *pdev) | 175 | static int pwc_allocate_buffers(struct pwc_device *pdev) |
223 | { | 176 | { |
224 | int i, err; | 177 | int i, err; |
@@ -239,30 +192,6 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) | |||
239 | } | 192 | } |
240 | } | 193 | } |
241 | 194 | ||
242 | /* Allocate frame buffer structure */ | ||
243 | if (pdev->fbuf == NULL) { | ||
244 | kbuf = kzalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL); | ||
245 | if (kbuf == NULL) { | ||
246 | PWC_ERROR("Failed to allocate frame buffer structure.\n"); | ||
247 | return -ENOMEM; | ||
248 | } | ||
249 | PWC_DEBUG_MEMORY("Allocated frame buffer structure at %p.\n", kbuf); | ||
250 | pdev->fbuf = kbuf; | ||
251 | } | ||
252 | |||
253 | /* create frame buffers, and make circular ring */ | ||
254 | for (i = 0; i < default_fbufs; i++) { | ||
255 | if (pdev->fbuf[i].data == NULL) { | ||
256 | kbuf = vzalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ | ||
257 | if (kbuf == NULL) { | ||
258 | PWC_ERROR("Failed to allocate frame buffer %d.\n", i); | ||
259 | return -ENOMEM; | ||
260 | } | ||
261 | PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf); | ||
262 | pdev->fbuf[i].data = kbuf; | ||
263 | } | ||
264 | } | ||
265 | |||
266 | /* Allocate decompressor table space */ | 195 | /* Allocate decompressor table space */ |
267 | if (DEVICE_USE_CODEC1(pdev->type)) | 196 | if (DEVICE_USE_CODEC1(pdev->type)) |
268 | err = pwc_dec1_alloc(pdev); | 197 | err = pwc_dec1_alloc(pdev); |
@@ -274,25 +203,6 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) | |||
274 | return err; | 203 | return err; |
275 | } | 204 | } |
276 | 205 | ||
277 | /* Allocate image buffer; double buffer for mmap() */ | ||
278 | kbuf = pwc_rvmalloc(pwc_mbufs * pdev->len_per_image); | ||
279 | if (kbuf == NULL) { | ||
280 | PWC_ERROR("Failed to allocate image buffer(s). needed (%d)\n", | ||
281 | pwc_mbufs * pdev->len_per_image); | ||
282 | return -ENOMEM; | ||
283 | } | ||
284 | PWC_DEBUG_MEMORY("Allocated image buffer at %p.\n", kbuf); | ||
285 | pdev->image_data = kbuf; | ||
286 | for (i = 0; i < pwc_mbufs; i++) { | ||
287 | pdev->images[i].offset = i * pdev->len_per_image; | ||
288 | pdev->images[i].vma_use_count = 0; | ||
289 | } | ||
290 | for (; i < MAX_IMAGES; i++) { | ||
291 | pdev->images[i].offset = 0; | ||
292 | } | ||
293 | |||
294 | kbuf = NULL; | ||
295 | |||
296 | PWC_DEBUG_MEMORY("<< pwc_allocate_buffers()\n"); | 206 | PWC_DEBUG_MEMORY("<< pwc_allocate_buffers()\n"); |
297 | return 0; | 207 | return 0; |
298 | } | 208 | } |
@@ -311,19 +221,6 @@ static void pwc_free_buffers(struct pwc_device *pdev) | |||
311 | pdev->sbuf[i].data = NULL; | 221 | pdev->sbuf[i].data = NULL; |
312 | } | 222 | } |
313 | 223 | ||
314 | /* The same for frame buffers */ | ||
315 | if (pdev->fbuf != NULL) { | ||
316 | for (i = 0; i < default_fbufs; i++) { | ||
317 | if (pdev->fbuf[i].data != NULL) { | ||
318 | PWC_DEBUG_MEMORY("Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data); | ||
319 | vfree(pdev->fbuf[i].data); | ||
320 | pdev->fbuf[i].data = NULL; | ||
321 | } | ||
322 | } | ||
323 | kfree(pdev->fbuf); | ||
324 | pdev->fbuf = NULL; | ||
325 | } | ||
326 | |||
327 | /* Intermediate decompression buffer & tables */ | 224 | /* Intermediate decompression buffer & tables */ |
328 | if (pdev->decompress_data != NULL) { | 225 | if (pdev->decompress_data != NULL) { |
329 | PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n", pdev->decompress_data); | 226 | PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n", pdev->decompress_data); |
@@ -331,226 +228,23 @@ static void pwc_free_buffers(struct pwc_device *pdev) | |||
331 | pdev->decompress_data = NULL; | 228 | pdev->decompress_data = NULL; |
332 | } | 229 | } |
333 | 230 | ||
334 | /* Release image buffers */ | ||
335 | if (pdev->image_data != NULL) { | ||
336 | PWC_DEBUG_MEMORY("Freeing image buffer at %p.\n", pdev->image_data); | ||
337 | pwc_rvfree(pdev->image_data, pwc_mbufs * pdev->len_per_image); | ||
338 | } | ||
339 | pdev->image_data = NULL; | ||
340 | |||
341 | PWC_DEBUG_MEMORY("Leaving free_buffers().\n"); | 231 | PWC_DEBUG_MEMORY("Leaving free_buffers().\n"); |
342 | } | 232 | } |
343 | 233 | ||
344 | /* The frame & image buffer mess. | 234 | struct pwc_frame_buf *pwc_get_next_fill_buf(struct pwc_device *pdev) |
345 | |||
346 | Yes, this is a mess. Well, it used to be simple, but alas... In this | ||
347 | module, 3 buffers schemes are used to get the data from the USB bus to | ||
348 | the user program. The first scheme involves the ISO buffers (called thus | ||
349 | since they transport ISO data from the USB controller), and not really | ||
350 | interesting. Suffices to say the data from this buffer is quickly | ||
351 | gathered in an interrupt handler (pwc_isoc_handler) and placed into the | ||
352 | frame buffer. | ||
353 | |||
354 | The frame buffer is the second scheme, and is the central element here. | ||
355 | It collects the data from a single frame from the camera (hence, the | ||
356 | name). Frames are delimited by the USB camera with a short USB packet, | ||
357 | so that's easy to detect. The frame buffers form a list that is filled | ||
358 | by the camera+USB controller and drained by the user process through | ||
359 | either read() or mmap(). | ||
360 | |||
361 | The image buffer is the third scheme, in which frames are decompressed | ||
362 | and converted into planar format. For mmap() there is more than | ||
363 | one image buffer available. | ||
364 | |||
365 | The frame buffers provide the image buffering. In case the user process | ||
366 | is a bit slow, this introduces lag and some undesired side-effects. | ||
367 | The problem arises when the frame buffer is full. I used to drop the last | ||
368 | frame, which makes the data in the queue stale very quickly. But dropping | ||
369 | the frame at the head of the queue proved to be a litte bit more difficult. | ||
370 | I tried a circular linked scheme, but this introduced more problems than | ||
371 | it solved. | ||
372 | |||
373 | Because filling and draining are completely asynchronous processes, this | ||
374 | requires some fiddling with pointers and mutexes. | ||
375 | |||
376 | Eventually, I came up with a system with 2 lists: an 'empty' frame list | ||
377 | and a 'full' frame list: | ||
378 | * Initially, all frame buffers but one are on the 'empty' list; the one | ||
379 | remaining buffer is our initial fill frame. | ||
380 | * If a frame is needed for filling, we try to take it from the 'empty' | ||
381 | list, unless that list is empty, in which case we take the buffer at | ||
382 | the head of the 'full' list. | ||
383 | * When our fill buffer has been filled, it is appended to the 'full' | ||
384 | list. | ||
385 | * If a frame is needed by read() or mmap(), it is taken from the head of | ||
386 | the 'full' list, handled, and then appended to the 'empty' list. If no | ||
387 | buffer is present on the 'full' list, we wait. | ||
388 | The advantage is that the buffer that is currently being decompressed/ | ||
389 | converted, is on neither list, and thus not in our way (any other scheme | ||
390 | I tried had the problem of old data lingering in the queue). | ||
391 | |||
392 | Whatever strategy you choose, it always remains a tradeoff: with more | ||
393 | frame buffers the chances of a missed frame are reduced. On the other | ||
394 | hand, on slower machines it introduces lag because the queue will | ||
395 | always be full. | ||
396 | */ | ||
397 | |||
398 | /** | ||
399 | \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first. | ||
400 | */ | ||
401 | static int pwc_next_fill_frame(struct pwc_device *pdev) | ||
402 | { | 235 | { |
403 | int ret; | 236 | unsigned long flags = 0; |
404 | unsigned long flags; | 237 | struct pwc_frame_buf *buf = NULL; |
405 | 238 | ||
406 | ret = 0; | 239 | spin_lock_irqsave(&pdev->queued_bufs_lock, flags); |
407 | spin_lock_irqsave(&pdev->ptrlock, flags); | 240 | if (list_empty(&pdev->queued_bufs)) |
408 | if (pdev->fill_frame != NULL) { | 241 | goto leave; |
409 | /* append to 'full' list */ | 242 | |
410 | if (pdev->full_frames == NULL) { | 243 | buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf, list); |
411 | pdev->full_frames = pdev->fill_frame; | 244 | list_del(&buf->list); |
412 | pdev->full_frames_tail = pdev->full_frames; | 245 | leave: |
413 | } | 246 | spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags); |
414 | else { | 247 | return buf; |
415 | pdev->full_frames_tail->next = pdev->fill_frame; | ||
416 | pdev->full_frames_tail = pdev->fill_frame; | ||
417 | } | ||
418 | } | ||
419 | if (pdev->empty_frames != NULL) { | ||
420 | /* We have empty frames available. That's easy */ | ||
421 | pdev->fill_frame = pdev->empty_frames; | ||
422 | pdev->empty_frames = pdev->empty_frames->next; | ||
423 | } | ||
424 | else { | ||
425 | /* Hmm. Take it from the full list */ | ||
426 | /* sanity check */ | ||
427 | if (pdev->full_frames == NULL) { | ||
428 | PWC_ERROR("Neither empty or full frames available!\n"); | ||
429 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | ||
430 | return -EINVAL; | ||
431 | } | ||
432 | pdev->fill_frame = pdev->full_frames; | ||
433 | pdev->full_frames = pdev->full_frames->next; | ||
434 | ret = 1; | ||
435 | } | ||
436 | pdev->fill_frame->next = NULL; | ||
437 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | ||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | |||
442 | /** | ||
443 | \brief Reset all buffers, pointers and lists, except for the image_used[] buffer. | ||
444 | |||
445 | If the image_used[] buffer is cleared too, mmap()/VIDIOCSYNC will run into trouble. | ||
446 | */ | ||
447 | static void pwc_reset_buffers(struct pwc_device *pdev) | ||
448 | { | ||
449 | int i; | ||
450 | unsigned long flags; | ||
451 | |||
452 | PWC_DEBUG_MEMORY(">> %s __enter__\n", __func__); | ||
453 | |||
454 | spin_lock_irqsave(&pdev->ptrlock, flags); | ||
455 | pdev->full_frames = NULL; | ||
456 | pdev->full_frames_tail = NULL; | ||
457 | for (i = 0; i < default_fbufs; i++) { | ||
458 | pdev->fbuf[i].filled = 0; | ||
459 | if (i > 0) | ||
460 | pdev->fbuf[i].next = &pdev->fbuf[i - 1]; | ||
461 | else | ||
462 | pdev->fbuf->next = NULL; | ||
463 | } | ||
464 | pdev->empty_frames = &pdev->fbuf[default_fbufs - 1]; | ||
465 | pdev->empty_frames_tail = pdev->fbuf; | ||
466 | pdev->read_frame = NULL; | ||
467 | pdev->fill_frame = pdev->empty_frames; | ||
468 | pdev->empty_frames = pdev->empty_frames->next; | ||
469 | |||
470 | pdev->image_read_pos = 0; | ||
471 | pdev->fill_image = 0; | ||
472 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | ||
473 | |||
474 | PWC_DEBUG_MEMORY("<< %s __leaving__\n", __func__); | ||
475 | } | ||
476 | |||
477 | |||
478 | /** | ||
479 | \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers. | ||
480 | */ | ||
481 | int pwc_handle_frame(struct pwc_device *pdev) | ||
482 | { | ||
483 | int ret = 0; | ||
484 | unsigned long flags; | ||
485 | |||
486 | spin_lock_irqsave(&pdev->ptrlock, flags); | ||
487 | /* First grab our read_frame; this is removed from all lists, so | ||
488 | we can release the lock after this without problems */ | ||
489 | if (pdev->read_frame != NULL) { | ||
490 | /* This can't theoretically happen */ | ||
491 | PWC_ERROR("Huh? Read frame still in use?\n"); | ||
492 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | ||
493 | return ret; | ||
494 | } | ||
495 | |||
496 | |||
497 | if (pdev->full_frames == NULL) { | ||
498 | PWC_ERROR("Woops. No frames ready.\n"); | ||
499 | } | ||
500 | else { | ||
501 | pdev->read_frame = pdev->full_frames; | ||
502 | pdev->full_frames = pdev->full_frames->next; | ||
503 | pdev->read_frame->next = NULL; | ||
504 | } | ||
505 | |||
506 | if (pdev->read_frame != NULL) { | ||
507 | /* Decompression is a lengthy process, so it's outside of the lock. | ||
508 | This gives the isoc_handler the opportunity to fill more frames | ||
509 | in the mean time. | ||
510 | */ | ||
511 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | ||
512 | ret = pwc_decompress(pdev); | ||
513 | spin_lock_irqsave(&pdev->ptrlock, flags); | ||
514 | |||
515 | /* We're done with read_buffer, tack it to the end of the empty buffer list */ | ||
516 | if (pdev->empty_frames == NULL) { | ||
517 | pdev->empty_frames = pdev->read_frame; | ||
518 | pdev->empty_frames_tail = pdev->empty_frames; | ||
519 | } | ||
520 | else { | ||
521 | pdev->empty_frames_tail->next = pdev->read_frame; | ||
522 | pdev->empty_frames_tail = pdev->read_frame; | ||
523 | } | ||
524 | pdev->read_frame = NULL; | ||
525 | } | ||
526 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | ||
527 | return ret; | ||
528 | } | ||
529 | |||
530 | /** | ||
531 | \brief Advance pointers of image buffer (after each user request) | ||
532 | */ | ||
533 | void pwc_next_image(struct pwc_device *pdev) | ||
534 | { | ||
535 | pdev->image_used[pdev->fill_image] = 0; | ||
536 | pdev->fill_image = (pdev->fill_image + 1) % pwc_mbufs; | ||
537 | } | ||
538 | |||
539 | /** | ||
540 | * Print debug information when a frame is discarded because all of our buffer | ||
541 | * is full | ||
542 | */ | ||
543 | static void pwc_frame_dumped(struct pwc_device *pdev) | ||
544 | { | ||
545 | pdev->vframes_dumped++; | ||
546 | if (pdev->vframe_count < FRAME_LOWMARK) | ||
547 | return; | ||
548 | |||
549 | if (pdev->vframes_dumped < 20) | ||
550 | PWC_DEBUG_FLOW("Dumping frame %d\n", pdev->vframe_count); | ||
551 | else if (pdev->vframes_dumped == 20) | ||
552 | PWC_DEBUG_FLOW("Dumping frame %d (last message)\n", | ||
553 | pdev->vframe_count); | ||
554 | } | 248 | } |
555 | 249 | ||
556 | static void pwc_snapshot_button(struct pwc_device *pdev, int down) | 250 | static void pwc_snapshot_button(struct pwc_device *pdev, int down) |
@@ -570,9 +264,9 @@ static void pwc_snapshot_button(struct pwc_device *pdev, int down) | |||
570 | #endif | 264 | #endif |
571 | } | 265 | } |
572 | 266 | ||
573 | static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf) | 267 | static void pwc_frame_complete(struct pwc_device *pdev) |
574 | { | 268 | { |
575 | int awake = 0; | 269 | struct pwc_frame_buf *fbuf = pdev->fill_buf; |
576 | 270 | ||
577 | /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus | 271 | /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus |
578 | frames on the USB wire after an exposure change. This conditition is | 272 | frames on the USB wire after an exposure change. This conditition is |
@@ -584,7 +278,6 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_ | |||
584 | if (ptr[1] == 1 && ptr[0] & 0x10) { | 278 | if (ptr[1] == 1 && ptr[0] & 0x10) { |
585 | PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n"); | 279 | PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n"); |
586 | pdev->drop_frames += 2; | 280 | pdev->drop_frames += 2; |
587 | pdev->vframes_error++; | ||
588 | } | 281 | } |
589 | if ((ptr[0] ^ pdev->vmirror) & 0x01) { | 282 | if ((ptr[0] ^ pdev->vmirror) & 0x01) { |
590 | pwc_snapshot_button(pdev, ptr[0] & 0x01); | 283 | pwc_snapshot_button(pdev, ptr[0] & 0x01); |
@@ -607,8 +300,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_ | |||
607 | */ | 300 | */ |
608 | if (fbuf->filled == 4) | 301 | if (fbuf->filled == 4) |
609 | pdev->drop_frames++; | 302 | pdev->drop_frames++; |
610 | } | 303 | } else if (pdev->type == 740 || pdev->type == 720) { |
611 | else if (pdev->type == 740 || pdev->type == 720) { | ||
612 | unsigned char *ptr = (unsigned char *)fbuf->data; | 304 | unsigned char *ptr = (unsigned char *)fbuf->data; |
613 | if ((ptr[0] ^ pdev->vmirror) & 0x01) { | 305 | if ((ptr[0] ^ pdev->vmirror) & 0x01) { |
614 | pwc_snapshot_button(pdev, ptr[0] & 0x01); | 306 | pwc_snapshot_button(pdev, ptr[0] & 0x01); |
@@ -616,33 +308,23 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_ | |||
616 | pdev->vmirror = ptr[0] & 0x03; | 308 | pdev->vmirror = ptr[0] & 0x03; |
617 | } | 309 | } |
618 | 310 | ||
619 | /* In case we were instructed to drop the frame, do so silently. | 311 | /* In case we were instructed to drop the frame, do so silently. */ |
620 | The buffer pointers are not updated either (but the counters are reset below). | 312 | if (pdev->drop_frames > 0) { |
621 | */ | ||
622 | if (pdev->drop_frames > 0) | ||
623 | pdev->drop_frames--; | 313 | pdev->drop_frames--; |
624 | else { | 314 | } else { |
625 | /* Check for underflow first */ | 315 | /* Check for underflow first */ |
626 | if (fbuf->filled < pdev->frame_total_size) { | 316 | if (fbuf->filled < pdev->frame_total_size) { |
627 | PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);" | 317 | PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);" |
628 | " discarded.\n", fbuf->filled); | 318 | " discarded.\n", fbuf->filled); |
629 | pdev->vframes_error++; | 319 | } else { |
630 | } | 320 | fbuf->vb.v4l2_buf.field = V4L2_FIELD_NONE; |
631 | else { | 321 | fbuf->vb.v4l2_buf.sequence = pdev->vframe_count; |
632 | /* Send only once per EOF */ | 322 | vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE); |
633 | awake = 1; /* delay wake_ups */ | 323 | pdev->fill_buf = NULL; |
634 | 324 | pdev->vsync = 0; | |
635 | /* Find our next frame to fill. This will always succeed, since we | ||
636 | * nick a frame from either empty or full list, but if we had to | ||
637 | * take it from the full list, it means a frame got dropped. | ||
638 | */ | ||
639 | if (pwc_next_fill_frame(pdev)) | ||
640 | pwc_frame_dumped(pdev); | ||
641 | |||
642 | } | 325 | } |
643 | } /* !drop_frames */ | 326 | } /* !drop_frames */ |
644 | pdev->vframe_count++; | 327 | pdev->vframe_count++; |
645 | return awake; | ||
646 | } | 328 | } |
647 | 329 | ||
648 | /* This gets called for the Isochronous pipe (video). This is done in | 330 | /* This gets called for the Isochronous pipe (video). This is done in |
@@ -650,24 +332,20 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_ | |||
650 | */ | 332 | */ |
651 | static void pwc_isoc_handler(struct urb *urb) | 333 | static void pwc_isoc_handler(struct urb *urb) |
652 | { | 334 | { |
653 | struct pwc_device *pdev; | 335 | struct pwc_device *pdev = (struct pwc_device *)urb->context; |
654 | int i, fst, flen; | 336 | int i, fst, flen; |
655 | int awake; | 337 | unsigned char *iso_buf = NULL; |
656 | struct pwc_frame_buf *fbuf; | ||
657 | unsigned char *fillptr = NULL, *iso_buf = NULL; | ||
658 | |||
659 | awake = 0; | ||
660 | pdev = (struct pwc_device *)urb->context; | ||
661 | if (pdev == NULL) { | ||
662 | PWC_ERROR("isoc_handler() called with NULL device?!\n"); | ||
663 | return; | ||
664 | } | ||
665 | 338 | ||
666 | if (urb->status == -ENOENT || urb->status == -ECONNRESET) { | 339 | if (urb->status == -ENOENT || urb->status == -ECONNRESET || |
340 | urb->status == -ESHUTDOWN) { | ||
667 | PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); | 341 | PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); |
668 | return; | 342 | return; |
669 | } | 343 | } |
670 | if (urb->status != -EINPROGRESS && urb->status != 0) { | 344 | |
345 | if (pdev->fill_buf == NULL) | ||
346 | pdev->fill_buf = pwc_get_next_fill_buf(pdev); | ||
347 | |||
348 | if (urb->status != 0) { | ||
671 | const char *errmsg; | 349 | const char *errmsg; |
672 | 350 | ||
673 | errmsg = "Unknown"; | 351 | errmsg = "Unknown"; |
@@ -679,29 +357,21 @@ static void pwc_isoc_handler(struct urb *urb) | |||
679 | case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break; | 357 | case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break; |
680 | case -ETIME: errmsg = "Device does not respond"; break; | 358 | case -ETIME: errmsg = "Device does not respond"; break; |
681 | } | 359 | } |
682 | PWC_DEBUG_FLOW("pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg); | 360 | PWC_ERROR("pwc_isoc_handler() called with status %d [%s].\n", |
683 | /* Give up after a number of contiguous errors on the USB bus. | 361 | urb->status, errmsg); |
684 | Appearantly something is wrong so we simulate an unplug event. | 362 | /* Give up after a number of contiguous errors */ |
685 | */ | ||
686 | if (++pdev->visoc_errors > MAX_ISOC_ERRORS) | 363 | if (++pdev->visoc_errors > MAX_ISOC_ERRORS) |
687 | { | 364 | { |
688 | PWC_INFO("Too many ISOC errors, bailing out.\n"); | 365 | PWC_ERROR("Too many ISOC errors, bailing out.\n"); |
689 | pdev->error_status = EIO; | 366 | if (pdev->fill_buf) { |
690 | awake = 1; | 367 | vb2_buffer_done(&pdev->fill_buf->vb, |
691 | wake_up_interruptible(&pdev->frameq); | 368 | VB2_BUF_STATE_ERROR); |
369 | pdev->fill_buf = NULL; | ||
370 | } | ||
692 | } | 371 | } |
693 | goto handler_end; // ugly, but practical | 372 | pdev->vsync = 0; /* Drop the current frame */ |
694 | } | ||
695 | |||
696 | fbuf = pdev->fill_frame; | ||
697 | if (fbuf == NULL) { | ||
698 | PWC_ERROR("pwc_isoc_handler without valid fill frame.\n"); | ||
699 | awake = 1; | ||
700 | goto handler_end; | 373 | goto handler_end; |
701 | } | 374 | } |
702 | else { | ||
703 | fillptr = fbuf->data + fbuf->filled; | ||
704 | } | ||
705 | 375 | ||
706 | /* Reset ISOC error counter. We did get here, after all. */ | 376 | /* Reset ISOC error counter. We did get here, after all. */ |
707 | pdev->visoc_errors = 0; | 377 | pdev->visoc_errors = 0; |
@@ -715,65 +385,50 @@ static void pwc_isoc_handler(struct urb *urb) | |||
715 | fst = urb->iso_frame_desc[i].status; | 385 | fst = urb->iso_frame_desc[i].status; |
716 | flen = urb->iso_frame_desc[i].actual_length; | 386 | flen = urb->iso_frame_desc[i].actual_length; |
717 | iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | 387 | iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset; |
718 | if (fst == 0) { | 388 | if (fst != 0) { |
719 | if (flen > 0) { /* if valid data... */ | 389 | PWC_ERROR("Iso frame %d has error %d\n", i, fst); |
720 | if (pdev->vsync > 0) { /* ...and we are not sync-hunting... */ | 390 | continue; |
721 | pdev->vsync = 2; | 391 | } |
722 | 392 | if (flen > 0 && pdev->vsync) { | |
723 | /* ...copy data to frame buffer, if possible */ | 393 | struct pwc_frame_buf *fbuf = pdev->fill_buf; |
724 | if (flen + fbuf->filled > pdev->frame_total_size) { | 394 | |
725 | PWC_DEBUG_FLOW("Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size); | 395 | if (pdev->vsync == 1) { |
726 | pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */ | 396 | do_gettimeofday(&fbuf->vb.v4l2_buf.timestamp); |
727 | pdev->vframes_error++; | 397 | pdev->vsync = 2; |
728 | } | 398 | } |
729 | else { | 399 | |
730 | memmove(fillptr, iso_buf, flen); | 400 | if (flen + fbuf->filled > pdev->frame_total_size) { |
731 | fillptr += flen; | 401 | PWC_ERROR("Frame overflow (%d > %d)\n", |
732 | } | 402 | flen + fbuf->filled, |
733 | } | 403 | pdev->frame_total_size); |
404 | pdev->vsync = 0; /* Let's wait for an EOF */ | ||
405 | } else { | ||
406 | memcpy(fbuf->data + fbuf->filled, iso_buf, | ||
407 | flen); | ||
734 | fbuf->filled += flen; | 408 | fbuf->filled += flen; |
735 | } /* ..flen > 0 */ | 409 | } |
736 | 410 | } | |
737 | if (flen < pdev->vlast_packet_size) { | 411 | if (flen < pdev->vlast_packet_size) { |
738 | /* Shorter packet... We probably have the end of an image-frame; | 412 | /* Shorter packet... end of frame */ |
739 | wake up read() process and let select()/poll() do something. | 413 | if (pdev->vsync == 2) |
740 | Decompression is done in user time over there. | 414 | pwc_frame_complete(pdev); |
741 | */ | 415 | if (pdev->fill_buf == NULL) |
742 | if (pdev->vsync == 2) { | 416 | pdev->fill_buf = pwc_get_next_fill_buf(pdev); |
743 | if (pwc_rcv_short_packet(pdev, fbuf)) { | 417 | if (pdev->fill_buf) { |
744 | awake = 1; | 418 | pdev->fill_buf->filled = 0; |
745 | fbuf = pdev->fill_frame; | ||
746 | } | ||
747 | } | ||
748 | fbuf->filled = 0; | ||
749 | fillptr = fbuf->data; | ||
750 | pdev->vsync = 1; | 419 | pdev->vsync = 1; |
751 | } | 420 | } |
752 | |||
753 | pdev->vlast_packet_size = flen; | ||
754 | } /* ..status == 0 */ | ||
755 | else { | ||
756 | /* This is normally not interesting to the user, unless | ||
757 | * you are really debugging something, default = 0 */ | ||
758 | static int iso_error; | ||
759 | iso_error++; | ||
760 | if (iso_error < 20) | ||
761 | PWC_DEBUG_FLOW("Iso frame %d of USB has error %d\n", i, fst); | ||
762 | } | 421 | } |
422 | pdev->vlast_packet_size = flen; | ||
763 | } | 423 | } |
764 | 424 | ||
765 | handler_end: | 425 | handler_end: |
766 | if (awake) | ||
767 | wake_up_interruptible(&pdev->frameq); | ||
768 | |||
769 | urb->dev = pdev->udev; | ||
770 | i = usb_submit_urb(urb, GFP_ATOMIC); | 426 | i = usb_submit_urb(urb, GFP_ATOMIC); |
771 | if (i != 0) | 427 | if (i != 0) |
772 | PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); | 428 | PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); |
773 | } | 429 | } |
774 | 430 | ||
775 | 431 | static int pwc_isoc_init(struct pwc_device *pdev) | |
776 | int pwc_isoc_init(struct pwc_device *pdev) | ||
777 | { | 432 | { |
778 | struct usb_device *udev; | 433 | struct usb_device *udev; |
779 | struct urb *urb; | 434 | struct urb *urb; |
@@ -784,6 +439,8 @@ int pwc_isoc_init(struct pwc_device *pdev) | |||
784 | if (pdev->iso_init) | 439 | if (pdev->iso_init) |
785 | return 0; | 440 | return 0; |
786 | pdev->vsync = 0; | 441 | pdev->vsync = 0; |
442 | pdev->fill_buf = NULL; | ||
443 | pdev->vframe_count = 0; | ||
787 | udev = pdev->udev; | 444 | udev = pdev->udev; |
788 | 445 | ||
789 | /* Get the current alternate interface, adjust packet size */ | 446 | /* Get the current alternate interface, adjust packet size */ |
@@ -904,7 +561,7 @@ static void pwc_iso_free(struct pwc_device *pdev) | |||
904 | } | 561 | } |
905 | } | 562 | } |
906 | 563 | ||
907 | void pwc_isoc_cleanup(struct pwc_device *pdev) | 564 | static void pwc_isoc_cleanup(struct pwc_device *pdev) |
908 | { | 565 | { |
909 | PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n"); | 566 | PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n"); |
910 | 567 | ||
@@ -926,6 +583,22 @@ void pwc_isoc_cleanup(struct pwc_device *pdev) | |||
926 | PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); | 583 | PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); |
927 | } | 584 | } |
928 | 585 | ||
586 | /* | ||
587 | * Release all queued buffers, no need to take queued_bufs_lock, since all | ||
588 | * iso urbs have been killed when we're called so pwc_isoc_handler won't run. | ||
589 | */ | ||
590 | static void pwc_cleanup_queued_bufs(struct pwc_device *pdev) | ||
591 | { | ||
592 | while (!list_empty(&pdev->queued_bufs)) { | ||
593 | struct pwc_frame_buf *buf; | ||
594 | |||
595 | buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf, | ||
596 | list); | ||
597 | list_del(&buf->list); | ||
598 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); | ||
599 | } | ||
600 | } | ||
601 | |||
929 | /********* | 602 | /********* |
930 | * sysfs | 603 | * sysfs |
931 | *********/ | 604 | *********/ |
@@ -1086,12 +759,6 @@ static int pwc_video_open(struct file *file) | |||
1086 | } | 759 | } |
1087 | 760 | ||
1088 | /* Reset buffers & parameters */ | 761 | /* Reset buffers & parameters */ |
1089 | pwc_reset_buffers(pdev); | ||
1090 | for (i = 0; i < pwc_mbufs; i++) | ||
1091 | pdev->image_used[i] = 0; | ||
1092 | pdev->vframe_count = 0; | ||
1093 | pdev->vframes_dumped = 0; | ||
1094 | pdev->vframes_error = 0; | ||
1095 | pdev->visoc_errors = 0; | 762 | pdev->visoc_errors = 0; |
1096 | pdev->error_status = 0; | 763 | pdev->error_status = 0; |
1097 | pwc_construct(pdev); /* set min/max sizes correct */ | 764 | pwc_construct(pdev); /* set min/max sizes correct */ |
@@ -1161,19 +828,12 @@ static int pwc_video_close(struct file *file) | |||
1161 | if (pdev->vopen == 0) | 828 | if (pdev->vopen == 0) |
1162 | PWC_DEBUG_MODULE("video_close() called on closed device?\n"); | 829 | PWC_DEBUG_MODULE("video_close() called on closed device?\n"); |
1163 | 830 | ||
1164 | /* Dump statistics, but only if a reasonable amount of frames were | ||
1165 | processed (to prevent endless log-entries in case of snap-shot | ||
1166 | programs) | ||
1167 | */ | ||
1168 | if (pdev->vframe_count > 20) | ||
1169 | PWC_DEBUG_MODULE("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error); | ||
1170 | |||
1171 | if (DEVICE_USE_CODEC1(pdev->type)) | 831 | if (DEVICE_USE_CODEC1(pdev->type)) |
1172 | pwc_dec1_exit(); | 832 | pwc_dec1_exit(); |
1173 | else | 833 | else |
1174 | pwc_dec23_exit(); | 834 | pwc_dec23_exit(); |
1175 | 835 | ||
1176 | pwc_isoc_cleanup(pdev); | 836 | vb2_queue_release(&pdev->vb_queue); |
1177 | pwc_free_buffers(pdev); | 837 | pwc_free_buffers(pdev); |
1178 | 838 | ||
1179 | /* Turn off LEDS and power down camera, but only when not unplugged */ | 839 | /* Turn off LEDS and power down camera, but only when not unplugged */ |
@@ -1193,182 +853,155 @@ static int pwc_video_close(struct file *file) | |||
1193 | return 0; | 853 | return 0; |
1194 | } | 854 | } |
1195 | 855 | ||
1196 | /* | ||
1197 | * FIXME: what about two parallel reads ???? | ||
1198 | * ANSWER: Not supported. You can't open the device more than once, | ||
1199 | despite what the V4L1 interface says. First, I don't see | ||
1200 | the need, second there's no mechanism of alerting the | ||
1201 | 2nd/3rd/... process of events like changing image size. | ||
1202 | And I don't see the point of blocking that for the | ||
1203 | 2nd/3rd/... process. | ||
1204 | In multi-threaded environments reading parallel from any | ||
1205 | device is tricky anyhow. | ||
1206 | */ | ||
1207 | |||
1208 | static ssize_t pwc_video_read(struct file *file, char __user *buf, | 856 | static ssize_t pwc_video_read(struct file *file, char __user *buf, |
1209 | size_t count, loff_t *ppos) | 857 | size_t count, loff_t *ppos) |
1210 | { | 858 | { |
1211 | struct video_device *vdev = file->private_data; | 859 | struct video_device *vdev = file->private_data; |
1212 | struct pwc_device *pdev; | 860 | struct pwc_device *pdev = video_get_drvdata(vdev); |
1213 | int noblock = file->f_flags & O_NONBLOCK; | ||
1214 | DECLARE_WAITQUEUE(wait, current); | ||
1215 | int bytes_to_read, rv = 0; | ||
1216 | void *image_buffer_addr; | ||
1217 | 861 | ||
1218 | PWC_DEBUG_READ("pwc_video_read(vdev=0x%p, buf=%p, count=%zd) called.\n", | 862 | if (pdev->error_status) |
1219 | vdev, buf, count); | 863 | return -pdev->error_status; |
1220 | pdev = video_get_drvdata(vdev); | ||
1221 | 864 | ||
1222 | if (pdev->error_status) { | 865 | return vb2_read(&pdev->vb_queue, buf, count, ppos, |
1223 | rv = -pdev->error_status; /* Something happened, report what. */ | 866 | file->f_flags & O_NONBLOCK); |
1224 | goto err_out; | 867 | } |
1225 | } | ||
1226 | 868 | ||
1227 | /* Start the stream (if not already started) */ | 869 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait) |
1228 | rv = pwc_isoc_init(pdev); | 870 | { |
1229 | if (rv) | 871 | struct video_device *vdev = file->private_data; |
1230 | goto err_out; | 872 | struct pwc_device *pdev = video_get_drvdata(vdev); |
1231 | |||
1232 | /* In case we're doing partial reads, we don't have to wait for a frame */ | ||
1233 | if (pdev->image_read_pos == 0) { | ||
1234 | /* Do wait queueing according to the (doc)book */ | ||
1235 | add_wait_queue(&pdev->frameq, &wait); | ||
1236 | while (pdev->full_frames == NULL) { | ||
1237 | /* Check for unplugged/etc. here */ | ||
1238 | if (pdev->error_status) { | ||
1239 | remove_wait_queue(&pdev->frameq, &wait); | ||
1240 | set_current_state(TASK_RUNNING); | ||
1241 | rv = -pdev->error_status ; | ||
1242 | goto err_out; | ||
1243 | } | ||
1244 | if (noblock) { | ||
1245 | remove_wait_queue(&pdev->frameq, &wait); | ||
1246 | set_current_state(TASK_RUNNING); | ||
1247 | rv = -EWOULDBLOCK; | ||
1248 | goto err_out; | ||
1249 | } | ||
1250 | if (signal_pending(current)) { | ||
1251 | remove_wait_queue(&pdev->frameq, &wait); | ||
1252 | set_current_state(TASK_RUNNING); | ||
1253 | rv = -ERESTARTSYS; | ||
1254 | goto err_out; | ||
1255 | } | ||
1256 | mutex_unlock(&pdev->modlock); | ||
1257 | schedule(); | ||
1258 | set_current_state(TASK_INTERRUPTIBLE); | ||
1259 | mutex_lock(&pdev->modlock); | ||
1260 | } | ||
1261 | remove_wait_queue(&pdev->frameq, &wait); | ||
1262 | set_current_state(TASK_RUNNING); | ||
1263 | 873 | ||
1264 | /* Decompress and release frame */ | 874 | if (pdev->error_status) |
1265 | rv = pwc_handle_frame(pdev); | 875 | return POLL_ERR; |
1266 | if (rv) | ||
1267 | goto err_out; | ||
1268 | } | ||
1269 | 876 | ||
1270 | PWC_DEBUG_READ("Copying data to user space.\n"); | 877 | return vb2_poll(&pdev->vb_queue, file, wait); |
1271 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) | ||
1272 | bytes_to_read = pdev->frame_size + sizeof(struct pwc_raw_frame); | ||
1273 | else | ||
1274 | bytes_to_read = pdev->view.size; | ||
1275 | |||
1276 | /* copy bytes to user space; we allow for partial reads */ | ||
1277 | if (count + pdev->image_read_pos > bytes_to_read) | ||
1278 | count = bytes_to_read - pdev->image_read_pos; | ||
1279 | image_buffer_addr = pdev->image_data; | ||
1280 | image_buffer_addr += pdev->images[pdev->fill_image].offset; | ||
1281 | image_buffer_addr += pdev->image_read_pos; | ||
1282 | if (copy_to_user(buf, image_buffer_addr, count)) { | ||
1283 | rv = -EFAULT; | ||
1284 | goto err_out; | ||
1285 | } | ||
1286 | pdev->image_read_pos += count; | ||
1287 | if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */ | ||
1288 | pdev->image_read_pos = 0; | ||
1289 | pwc_next_image(pdev); | ||
1290 | } | ||
1291 | return count; | ||
1292 | err_out: | ||
1293 | return rv; | ||
1294 | } | 878 | } |
1295 | 879 | ||
1296 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait) | 880 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) |
1297 | { | 881 | { |
1298 | struct video_device *vdev = file->private_data; | 882 | struct video_device *vdev = file->private_data; |
1299 | struct pwc_device *pdev; | 883 | struct pwc_device *pdev = video_get_drvdata(vdev); |
1300 | int ret; | ||
1301 | 884 | ||
1302 | pdev = video_get_drvdata(vdev); | 885 | return vb2_mmap(&pdev->vb_queue, vma); |
886 | } | ||
1303 | 887 | ||
1304 | /* Start the stream (if not already started) */ | 888 | /***************************************************************************/ |
1305 | ret = pwc_isoc_init(pdev); | 889 | /* Videobuf2 operations */ |
1306 | if (ret) | 890 | |
1307 | return ret; | 891 | static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, |
892 | unsigned int *nplanes, unsigned long sizes[], | ||
893 | void *alloc_ctxs[]) | ||
894 | { | ||
895 | struct pwc_device *pdev = vb2_get_drv_priv(vq); | ||
1308 | 896 | ||
1309 | poll_wait(file, &pdev->frameq, wait); | 897 | if (*nbuffers < MIN_FRAMES) |
898 | *nbuffers = MIN_FRAMES; | ||
899 | else if (*nbuffers > MAX_FRAMES) | ||
900 | *nbuffers = MAX_FRAMES; | ||
901 | |||
902 | *nplanes = 1; | ||
903 | |||
904 | sizes[0] = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2); | ||
905 | |||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | static int buffer_init(struct vb2_buffer *vb) | ||
910 | { | ||
911 | struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); | ||
912 | |||
913 | /* need vmalloc since frame buffer > 128K */ | ||
914 | buf->data = vzalloc(PWC_FRAME_SIZE); | ||
915 | if (buf->data == NULL) | ||
916 | return -ENOMEM; | ||
917 | |||
918 | return 0; | ||
919 | } | ||
920 | |||
921 | static int buffer_prepare(struct vb2_buffer *vb) | ||
922 | { | ||
923 | struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue); | ||
924 | |||
925 | /* Don't allow queing new buffers after device disconnection */ | ||
1310 | if (pdev->error_status) | 926 | if (pdev->error_status) |
1311 | return POLLERR; | 927 | return -pdev->error_status; |
1312 | if (pdev->full_frames != NULL) /* we have frames waiting */ | ||
1313 | return (POLLIN | POLLRDNORM); | ||
1314 | 928 | ||
1315 | return 0; | 929 | return 0; |
1316 | } | 930 | } |
1317 | 931 | ||
1318 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) | 932 | static int buffer_finish(struct vb2_buffer *vb) |
1319 | { | 933 | { |
1320 | struct video_device *vdev = file->private_data; | 934 | struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue); |
1321 | struct pwc_device *pdev; | 935 | struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); |
1322 | unsigned long start; | ||
1323 | unsigned long size; | ||
1324 | unsigned long page, pos = 0; | ||
1325 | int index; | ||
1326 | 936 | ||
1327 | PWC_DEBUG_MEMORY(">> %s\n", __func__); | 937 | /* |
1328 | pdev = video_get_drvdata(vdev); | 938 | * Application has called dqbuf and is getting back a buffer we've |
1329 | size = vma->vm_end - vma->vm_start; | 939 | * filled, take the pwc data we've stored in buf->data and decompress |
1330 | start = vma->vm_start; | 940 | * it into a usable format, storing the result in the vb2_buffer |
941 | */ | ||
942 | return pwc_decompress(pdev, buf); | ||
943 | } | ||
944 | |||
945 | static void buffer_cleanup(struct vb2_buffer *vb) | ||
946 | { | ||
947 | struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); | ||
948 | |||
949 | vfree(buf->data); | ||
950 | } | ||
951 | |||
952 | static void buffer_queue(struct vb2_buffer *vb) | ||
953 | { | ||
954 | struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue); | ||
955 | struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); | ||
956 | unsigned long flags = 0; | ||
957 | |||
958 | spin_lock_irqsave(&pdev->queued_bufs_lock, flags); | ||
959 | list_add_tail(&buf->list, &pdev->queued_bufs); | ||
960 | spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags); | ||
961 | } | ||
962 | |||
963 | static int start_streaming(struct vb2_queue *vq) | ||
964 | { | ||
965 | struct pwc_device *pdev = vb2_get_drv_priv(vq); | ||
966 | |||
967 | return pwc_isoc_init(pdev); | ||
968 | } | ||
969 | |||
970 | static int stop_streaming(struct vb2_queue *vq) | ||
971 | { | ||
972 | struct pwc_device *pdev = vb2_get_drv_priv(vq); | ||
973 | |||
974 | pwc_isoc_cleanup(pdev); | ||
975 | pwc_cleanup_queued_bufs(pdev); | ||
1331 | 976 | ||
1332 | /* Find the idx buffer for this mapping */ | ||
1333 | for (index = 0; index < pwc_mbufs; index++) { | ||
1334 | pos = pdev->images[index].offset; | ||
1335 | if ((pos>>PAGE_SHIFT) == vma->vm_pgoff) | ||
1336 | break; | ||
1337 | } | ||
1338 | if (index == MAX_IMAGES) | ||
1339 | return -EINVAL; | ||
1340 | if (index == 0) { | ||
1341 | /* | ||
1342 | * Special case for v4l1. In v4l1, we map only one big buffer, | ||
1343 | * but in v4l2 each buffer is mapped | ||
1344 | */ | ||
1345 | unsigned long total_size; | ||
1346 | total_size = pwc_mbufs * pdev->len_per_image; | ||
1347 | if (size != pdev->len_per_image && size != total_size) { | ||
1348 | PWC_ERROR("Wrong size (%lu) needed to be len_per_image=%d or total_size=%lu\n", | ||
1349 | size, pdev->len_per_image, total_size); | ||
1350 | return -EINVAL; | ||
1351 | } | ||
1352 | } else if (size > pdev->len_per_image) | ||
1353 | return -EINVAL; | ||
1354 | |||
1355 | vma->vm_flags |= VM_IO; /* from 2.6.9-acX */ | ||
1356 | |||
1357 | pos += (unsigned long)pdev->image_data; | ||
1358 | while (size > 0) { | ||
1359 | page = vmalloc_to_pfn((void *)pos); | ||
1360 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) | ||
1361 | return -EAGAIN; | ||
1362 | start += PAGE_SIZE; | ||
1363 | pos += PAGE_SIZE; | ||
1364 | if (size > PAGE_SIZE) | ||
1365 | size -= PAGE_SIZE; | ||
1366 | else | ||
1367 | size = 0; | ||
1368 | } | ||
1369 | return 0; | 977 | return 0; |
1370 | } | 978 | } |
1371 | 979 | ||
980 | static void pwc_lock(struct vb2_queue *vq) | ||
981 | { | ||
982 | struct pwc_device *pdev = vb2_get_drv_priv(vq); | ||
983 | mutex_lock(&pdev->modlock); | ||
984 | } | ||
985 | |||
986 | static void pwc_unlock(struct vb2_queue *vq) | ||
987 | { | ||
988 | struct pwc_device *pdev = vb2_get_drv_priv(vq); | ||
989 | mutex_unlock(&pdev->modlock); | ||
990 | } | ||
991 | |||
992 | static struct vb2_ops pwc_vb_queue_ops = { | ||
993 | .queue_setup = queue_setup, | ||
994 | .buf_init = buffer_init, | ||
995 | .buf_prepare = buffer_prepare, | ||
996 | .buf_finish = buffer_finish, | ||
997 | .buf_cleanup = buffer_cleanup, | ||
998 | .buf_queue = buffer_queue, | ||
999 | .start_streaming = start_streaming, | ||
1000 | .stop_streaming = stop_streaming, | ||
1001 | .wait_prepare = pwc_unlock, | ||
1002 | .wait_finish = pwc_lock, | ||
1003 | }; | ||
1004 | |||
1372 | /***************************************************************************/ | 1005 | /***************************************************************************/ |
1373 | /* USB functions */ | 1006 | /* USB functions */ |
1374 | 1007 | ||
@@ -1648,12 +1281,22 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1648 | } | 1281 | } |
1649 | 1282 | ||
1650 | mutex_init(&pdev->modlock); | 1283 | mutex_init(&pdev->modlock); |
1651 | spin_lock_init(&pdev->ptrlock); | 1284 | spin_lock_init(&pdev->queued_bufs_lock); |
1285 | INIT_LIST_HEAD(&pdev->queued_bufs); | ||
1652 | 1286 | ||
1653 | pdev->udev = udev; | 1287 | pdev->udev = udev; |
1654 | init_waitqueue_head(&pdev->frameq); | ||
1655 | pdev->vcompression = pwc_preferred_compression; | 1288 | pdev->vcompression = pwc_preferred_compression; |
1656 | 1289 | ||
1290 | /* Init videobuf2 queue structure */ | ||
1291 | memset(&pdev->vb_queue, 0, sizeof(pdev->vb_queue)); | ||
1292 | pdev->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1293 | pdev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; | ||
1294 | pdev->vb_queue.drv_priv = pdev; | ||
1295 | pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf); | ||
1296 | pdev->vb_queue.ops = &pwc_vb_queue_ops; | ||
1297 | pdev->vb_queue.mem_ops = &vb2_vmalloc_memops; | ||
1298 | vb2_queue_init(&pdev->vb_queue); | ||
1299 | |||
1657 | /* Init video_device structure */ | 1300 | /* Init video_device structure */ |
1658 | memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template)); | 1301 | memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template)); |
1659 | pdev->vdev.parent = &intf->dev; | 1302 | pdev->vdev.parent = &intf->dev; |
@@ -1752,11 +1395,9 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
1752 | pdev->error_status = EPIPE; | 1395 | pdev->error_status = EPIPE; |
1753 | pdev->unplugged = 1; | 1396 | pdev->unplugged = 1; |
1754 | 1397 | ||
1755 | /* Alert waiting processes */ | ||
1756 | wake_up_interruptible(&pdev->frameq); | ||
1757 | |||
1758 | /* No need to keep the urbs around after disconnection */ | 1398 | /* No need to keep the urbs around after disconnection */ |
1759 | pwc_isoc_cleanup(pdev); | 1399 | pwc_isoc_cleanup(pdev); |
1400 | pwc_cleanup_queued_bufs(pdev); | ||
1760 | 1401 | ||
1761 | mutex_unlock(&pdev->modlock); | 1402 | mutex_unlock(&pdev->modlock); |
1762 | 1403 | ||
@@ -1776,8 +1417,6 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
1776 | 1417 | ||
1777 | static char *size; | 1418 | static char *size; |
1778 | static int fps; | 1419 | static int fps; |
1779 | static int fbufs; | ||
1780 | static int mbufs; | ||
1781 | static int compression = -1; | 1420 | static int compression = -1; |
1782 | static int leds[2] = { -1, -1 }; | 1421 | static int leds[2] = { -1, -1 }; |
1783 | static unsigned int leds_nargs; | 1422 | static unsigned int leds_nargs; |
@@ -1786,8 +1425,6 @@ static unsigned int dev_hint_nargs; | |||
1786 | 1425 | ||
1787 | module_param(size, charp, 0444); | 1426 | module_param(size, charp, 0444); |
1788 | module_param(fps, int, 0444); | 1427 | module_param(fps, int, 0444); |
1789 | module_param(fbufs, int, 0444); | ||
1790 | module_param(mbufs, int, 0444); | ||
1791 | #ifdef CONFIG_USB_PWC_DEBUG | 1428 | #ifdef CONFIG_USB_PWC_DEBUG |
1792 | module_param_named(trace, pwc_trace, int, 0644); | 1429 | module_param_named(trace, pwc_trace, int, 0644); |
1793 | #endif | 1430 | #endif |
@@ -1798,8 +1435,6 @@ module_param_array(dev_hint, charp, &dev_hint_nargs, 0444); | |||
1798 | 1435 | ||
1799 | MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga"); | 1436 | MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga"); |
1800 | MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); | 1437 | MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); |
1801 | MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve"); | ||
1802 | MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers"); | ||
1803 | #ifdef CONFIG_USB_PWC_DEBUG | 1438 | #ifdef CONFIG_USB_PWC_DEBUG |
1804 | MODULE_PARM_DESC(trace, "For debugging purposes"); | 1439 | MODULE_PARM_DESC(trace, "For debugging purposes"); |
1805 | #endif | 1440 | #endif |
@@ -1847,22 +1482,6 @@ static int __init usb_pwc_init(void) | |||
1847 | } | 1482 | } |
1848 | PWC_DEBUG_MODULE("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y); | 1483 | PWC_DEBUG_MODULE("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y); |
1849 | } | 1484 | } |
1850 | if (mbufs) { | ||
1851 | if (mbufs < 1 || mbufs > MAX_IMAGES) { | ||
1852 | PWC_ERROR("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES); | ||
1853 | return -EINVAL; | ||
1854 | } | ||
1855 | pwc_mbufs = mbufs; | ||
1856 | PWC_DEBUG_MODULE("Number of image buffers set to %d.\n", pwc_mbufs); | ||
1857 | } | ||
1858 | if (fbufs) { | ||
1859 | if (fbufs < 2 || fbufs > MAX_FRAMES) { | ||
1860 | PWC_ERROR("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES); | ||
1861 | return -EINVAL; | ||
1862 | } | ||
1863 | default_fbufs = fbufs; | ||
1864 | PWC_DEBUG_MODULE("Number of frame buffers set to %d.\n", default_fbufs); | ||
1865 | } | ||
1866 | #ifdef CONFIG_USB_PWC_DEBUG | 1485 | #ifdef CONFIG_USB_PWC_DEBUG |
1867 | if (pwc_trace >= 0) { | 1486 | if (pwc_trace >= 0) { |
1868 | PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace); | 1487 | PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace); |
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c index 6af5bb538358..0b031336eab8 100644 --- a/drivers/media/video/pwc/pwc-misc.c +++ b/drivers/media/video/pwc/pwc-misc.c | |||
@@ -126,8 +126,4 @@ void pwc_construct(struct pwc_device *pdev) | |||
126 | pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */ | 126 | pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */ |
127 | pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; | 127 | pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; |
128 | pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; | 128 | pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; |
129 | /* length of image, in YUV format; always allocate enough memory. */ | ||
130 | pdev->len_per_image = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2); | ||
131 | } | 129 | } |
132 | |||
133 | |||
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c index 4118184951ee..d110e38c4de0 100644 --- a/drivers/media/video/pwc/pwc-uncompress.c +++ b/drivers/media/video/pwc/pwc-uncompress.c | |||
@@ -34,17 +34,14 @@ | |||
34 | #include "pwc-dec1.h" | 34 | #include "pwc-dec1.h" |
35 | #include "pwc-dec23.h" | 35 | #include "pwc-dec23.h" |
36 | 36 | ||
37 | int pwc_decompress(struct pwc_device *pdev) | 37 | int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf) |
38 | { | 38 | { |
39 | struct pwc_frame_buf *fbuf; | ||
40 | int n, line, col, stride; | 39 | int n, line, col, stride; |
41 | void *yuv, *image; | 40 | void *yuv, *image; |
42 | u16 *src; | 41 | u16 *src; |
43 | u16 *dsty, *dstu, *dstv; | 42 | u16 *dsty, *dstu, *dstv; |
44 | 43 | ||
45 | fbuf = pdev->read_frame; | 44 | image = vb2_plane_vaddr(&fbuf->vb, 0); |
46 | image = pdev->image_data; | ||
47 | image += pdev->images[pdev->fill_image].offset; | ||
48 | 45 | ||
49 | yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ | 46 | yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ |
50 | 47 | ||
@@ -59,9 +56,13 @@ int pwc_decompress(struct pwc_device *pdev) | |||
59 | * determine this using the type of the webcam */ | 56 | * determine this using the type of the webcam */ |
60 | memcpy(raw_frame->cmd, pdev->cmd_buf, 4); | 57 | memcpy(raw_frame->cmd, pdev->cmd_buf, 4); |
61 | memcpy(raw_frame+1, yuv, pdev->frame_size); | 58 | memcpy(raw_frame+1, yuv, pdev->frame_size); |
59 | vb2_set_plane_payload(&fbuf->vb, 0, | ||
60 | pdev->frame_size + sizeof(struct pwc_raw_frame)); | ||
62 | return 0; | 61 | return 0; |
63 | } | 62 | } |
64 | 63 | ||
64 | vb2_set_plane_payload(&fbuf->vb, 0, pdev->view.size); | ||
65 | |||
65 | if (pdev->vbandlength == 0) { | 66 | if (pdev->vbandlength == 0) { |
66 | /* Uncompressed mode. | 67 | /* Uncompressed mode. |
67 | * We copy the data into the output buffer, using the viewport | 68 | * We copy the data into the output buffer, using the viewport |
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 8e72e0f56550..cda38837adcd 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
@@ -309,7 +309,7 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) | |||
309 | pixelformat != V4L2_PIX_FMT_PWC2) | 309 | pixelformat != V4L2_PIX_FMT_PWC2) |
310 | return -EINVAL; | 310 | return -EINVAL; |
311 | 311 | ||
312 | if (pdev->iso_init) | 312 | if (vb2_is_streaming(&pdev->vb_queue)) |
313 | return -EBUSY; | 313 | return -EBUSY; |
314 | 314 | ||
315 | PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d " | 315 | PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d " |
@@ -673,150 +673,47 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) | |||
673 | return pwc_vidioc_set_fmt(pdev, f); | 673 | return pwc_vidioc_set_fmt(pdev, f); |
674 | } | 674 | } |
675 | 675 | ||
676 | static int pwc_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb) | 676 | static int pwc_reqbufs(struct file *file, void *fh, |
677 | struct v4l2_requestbuffers *rb) | ||
677 | { | 678 | { |
678 | int nbuffers; | 679 | struct pwc_device *pdev = video_drvdata(file); |
679 | |||
680 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n", rb->count); | ||
681 | if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
682 | return -EINVAL; | ||
683 | if (rb->memory != V4L2_MEMORY_MMAP) | ||
684 | return -EINVAL; | ||
685 | 680 | ||
686 | nbuffers = rb->count; | 681 | return vb2_reqbufs(&pdev->vb_queue, rb); |
687 | if (nbuffers < 2) | ||
688 | nbuffers = 2; | ||
689 | else if (nbuffers > pwc_mbufs) | ||
690 | nbuffers = pwc_mbufs; | ||
691 | /* Force to use our # of buffers */ | ||
692 | rb->count = pwc_mbufs; | ||
693 | return 0; | ||
694 | } | 682 | } |
695 | 683 | ||
696 | static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) | 684 | static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) |
697 | { | 685 | { |
698 | struct pwc_device *pdev = video_drvdata(file); | 686 | struct pwc_device *pdev = video_drvdata(file); |
699 | int index; | ||
700 | 687 | ||
701 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n", buf->index); | 688 | return vb2_querybuf(&pdev->vb_queue, buf); |
702 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
703 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n"); | ||
704 | return -EINVAL; | ||
705 | } | ||
706 | index = buf->index; | ||
707 | if (index < 0 || index >= pwc_mbufs) { | ||
708 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index); | ||
709 | return -EINVAL; | ||
710 | } | ||
711 | |||
712 | buf->m.offset = index * pdev->len_per_image; | ||
713 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) | ||
714 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); | ||
715 | else | ||
716 | buf->bytesused = pdev->view.size; | ||
717 | buf->field = V4L2_FIELD_NONE; | ||
718 | buf->memory = V4L2_MEMORY_MMAP; | ||
719 | /*buf->flags = V4L2_BUF_FLAG_MAPPED;*/ | ||
720 | buf->length = pdev->len_per_image; | ||
721 | |||
722 | PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n", buf->index); | ||
723 | PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n", buf->m.offset); | ||
724 | PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n", buf->bytesused); | ||
725 | |||
726 | return 0; | ||
727 | } | 689 | } |
728 | 690 | ||
729 | static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | 691 | static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) |
730 | { | 692 | { |
731 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n", buf->index); | 693 | struct pwc_device *pdev = video_drvdata(file); |
732 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
733 | return -EINVAL; | ||
734 | if (buf->memory != V4L2_MEMORY_MMAP) | ||
735 | return -EINVAL; | ||
736 | if (buf->index >= pwc_mbufs) | ||
737 | return -EINVAL; | ||
738 | |||
739 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
740 | buf->flags &= ~V4L2_BUF_FLAG_DONE; | ||
741 | 694 | ||
742 | return 0; | 695 | return vb2_qbuf(&pdev->vb_queue, buf); |
743 | } | 696 | } |
744 | 697 | ||
745 | static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | 698 | static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) |
746 | { | 699 | { |
747 | DECLARE_WAITQUEUE(wait, current); | ||
748 | struct pwc_device *pdev = video_drvdata(file); | 700 | struct pwc_device *pdev = video_drvdata(file); |
749 | int ret; | ||
750 | |||
751 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n"); | ||
752 | |||
753 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
754 | return -EINVAL; | ||
755 | |||
756 | add_wait_queue(&pdev->frameq, &wait); | ||
757 | while (pdev->full_frames == NULL) { | ||
758 | if (pdev->error_status) { | ||
759 | remove_wait_queue(&pdev->frameq, &wait); | ||
760 | set_current_state(TASK_RUNNING); | ||
761 | return -pdev->error_status; | ||
762 | } | ||
763 | |||
764 | if (signal_pending(current)) { | ||
765 | remove_wait_queue(&pdev->frameq, &wait); | ||
766 | set_current_state(TASK_RUNNING); | ||
767 | return -ERESTARTSYS; | ||
768 | } | ||
769 | mutex_unlock(&pdev->modlock); | ||
770 | schedule(); | ||
771 | set_current_state(TASK_INTERRUPTIBLE); | ||
772 | mutex_lock(&pdev->modlock); | ||
773 | } | ||
774 | remove_wait_queue(&pdev->frameq, &wait); | ||
775 | set_current_state(TASK_RUNNING); | ||
776 | |||
777 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n"); | ||
778 | /* Decompress data in pdev->images[pdev->fill_image] */ | ||
779 | ret = pwc_handle_frame(pdev); | ||
780 | if (ret) | ||
781 | return ret; | ||
782 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n"); | ||
783 | |||
784 | buf->index = pdev->fill_image; | ||
785 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) | ||
786 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); | ||
787 | else | ||
788 | buf->bytesused = pdev->view.size; | ||
789 | buf->flags = V4L2_BUF_FLAG_MAPPED; | ||
790 | buf->field = V4L2_FIELD_NONE; | ||
791 | do_gettimeofday(&buf->timestamp); | ||
792 | buf->sequence = 0; | ||
793 | buf->memory = V4L2_MEMORY_MMAP; | ||
794 | buf->m.offset = pdev->fill_image * pdev->len_per_image; | ||
795 | buf->length = pdev->len_per_image; | ||
796 | pwc_next_image(pdev); | ||
797 | |||
798 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n", buf->index); | ||
799 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n", buf->length); | ||
800 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n", buf->m.offset); | ||
801 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n", buf->bytesused); | ||
802 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n"); | ||
803 | return 0; | ||
804 | 701 | ||
702 | return vb2_dqbuf(&pdev->vb_queue, buf, file->f_flags & O_NONBLOCK); | ||
805 | } | 703 | } |
806 | 704 | ||
807 | static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) | 705 | static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) |
808 | { | 706 | { |
809 | struct pwc_device *pdev = video_drvdata(file); | 707 | struct pwc_device *pdev = video_drvdata(file); |
810 | 708 | ||
811 | return pwc_isoc_init(pdev); | 709 | return vb2_streamon(&pdev->vb_queue, i); |
812 | } | 710 | } |
813 | 711 | ||
814 | static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) | 712 | static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) |
815 | { | 713 | { |
816 | struct pwc_device *pdev = video_drvdata(file); | 714 | struct pwc_device *pdev = video_drvdata(file); |
817 | 715 | ||
818 | pwc_isoc_cleanup(pdev); | 716 | return vb2_streamoff(&pdev->vb_queue, i); |
819 | return 0; | ||
820 | } | 717 | } |
821 | 718 | ||
822 | static int pwc_enum_framesizes(struct file *file, void *fh, | 719 | static int pwc_enum_framesizes(struct file *file, void *fh, |
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 421e75b69f29..ae92fe211f6d 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/videodev2.h> | 36 | #include <linux/videodev2.h> |
37 | #include <media/v4l2-common.h> | 37 | #include <media/v4l2-common.h> |
38 | #include <media/v4l2-ioctl.h> | 38 | #include <media/v4l2-ioctl.h> |
39 | #include <media/videobuf2-vmalloc.h> | ||
39 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 40 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
40 | #include <linux/input.h> | 41 | #include <linux/input.h> |
41 | #endif | 42 | #endif |
@@ -112,18 +113,17 @@ | |||
112 | #define FRAME_LOWMARK 5 | 113 | #define FRAME_LOWMARK 5 |
113 | 114 | ||
114 | /* Size and number of buffers for the ISO pipe. */ | 115 | /* Size and number of buffers for the ISO pipe. */ |
115 | #define MAX_ISO_BUFS 2 | 116 | #define MAX_ISO_BUFS 3 |
116 | #define ISO_FRAMES_PER_DESC 10 | 117 | #define ISO_FRAMES_PER_DESC 10 |
117 | #define ISO_MAX_FRAME_SIZE 960 | 118 | #define ISO_MAX_FRAME_SIZE 960 |
118 | #define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE) | 119 | #define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE) |
119 | 120 | ||
120 | /* Frame buffers: contains compressed or uncompressed video data. */ | ||
121 | #define MAX_FRAMES 5 | ||
122 | /* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */ | 121 | /* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */ |
123 | #define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE) | 122 | #define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE) |
124 | 123 | ||
125 | /* Absolute maximum number of buffers available for mmap() */ | 124 | /* Absolute minimum and maximum number of buffers available for mmap() */ |
126 | #define MAX_IMAGES 10 | 125 | #define MIN_FRAMES 2 |
126 | #define MAX_FRAMES 16 | ||
127 | 127 | ||
128 | /* Some macros to quickly find the type of a webcam */ | 128 | /* Some macros to quickly find the type of a webcam */ |
129 | #define DEVICE_USE_CODEC1(x) ((x)<675) | 129 | #define DEVICE_USE_CODEC1(x) ((x)<675) |
@@ -143,16 +143,10 @@ struct pwc_iso_buf | |||
143 | /* intermediate buffers with raw data from the USB cam */ | 143 | /* intermediate buffers with raw data from the USB cam */ |
144 | struct pwc_frame_buf | 144 | struct pwc_frame_buf |
145 | { | 145 | { |
146 | void *data; | 146 | struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */ |
147 | volatile int filled; /* number of bytes filled */ | 147 | struct list_head list; |
148 | struct pwc_frame_buf *next; /* list */ | 148 | void *data; |
149 | }; | 149 | int filled; /* number of bytes filled */ |
150 | |||
151 | /* additionnal informations used when dealing image between kernel and userland */ | ||
152 | struct pwc_imgbuf | ||
153 | { | ||
154 | unsigned long offset; /* offset of this buffer in the big array of image_data */ | ||
155 | int vma_use_count; /* count the number of time this memory is mapped */ | ||
156 | }; | 150 | }; |
157 | 151 | ||
158 | struct pwc_device | 152 | struct pwc_device |
@@ -177,8 +171,6 @@ struct pwc_device | |||
177 | int vframes, vsize; /* frames-per-second & size (see PSZ_*) */ | 171 | int vframes, vsize; /* frames-per-second & size (see PSZ_*) */ |
178 | int pixfmt; /* pixelformat: V4L2_PIX_FMT_YUV420 or raw: _PWC1, _PWC2 */ | 172 | int pixfmt; /* pixelformat: V4L2_PIX_FMT_YUV420 or raw: _PWC1, _PWC2 */ |
179 | int vframe_count; /* received frames */ | 173 | int vframe_count; /* received frames */ |
180 | int vframes_dumped; /* counter for dumped frames */ | ||
181 | int vframes_error; /* frames received in error */ | ||
182 | int vmax_packet_size; /* USB maxpacket size */ | 174 | int vmax_packet_size; /* USB maxpacket size */ |
183 | int vlast_packet_size; /* for frame synchronisation */ | 175 | int vlast_packet_size; /* for frame synchronisation */ |
184 | int visoc_errors; /* number of contiguous ISOC errors */ | 176 | int visoc_errors; /* number of contiguous ISOC errors */ |
@@ -192,35 +184,29 @@ struct pwc_device | |||
192 | int cmd_len; | 184 | int cmd_len; |
193 | unsigned char cmd_buf[13]; | 185 | unsigned char cmd_buf[13]; |
194 | 186 | ||
195 | /* The image acquisition requires 3 to 4 steps: | ||
196 | 1. data is gathered in short packets from the USB controller | ||
197 | 2. data is synchronized and packed into a frame buffer | ||
198 | 3a. in case data is compressed, decompress it directly into image buffer | ||
199 | 3b. in case data is uncompressed, copy into image buffer with viewport | ||
200 | 4. data is transferred to the user process | ||
201 | |||
202 | Note that MAX_ISO_BUFS != MAX_FRAMES != MAX_IMAGES.... | ||
203 | We have in effect a back-to-back-double-buffer system. | ||
204 | */ | ||
205 | /* 1: isoc */ | ||
206 | struct pwc_iso_buf sbuf[MAX_ISO_BUFS]; | 187 | struct pwc_iso_buf sbuf[MAX_ISO_BUFS]; |
207 | char iso_init; | 188 | char iso_init; |
208 | 189 | ||
209 | /* 2: frame */ | 190 | /* videobuf2 queue and queued buffers list */ |
210 | struct pwc_frame_buf *fbuf; /* all frames */ | 191 | struct vb2_queue vb_queue; |
211 | struct pwc_frame_buf *empty_frames, *empty_frames_tail; /* all empty frames */ | 192 | struct list_head queued_bufs; |
212 | struct pwc_frame_buf *full_frames, *full_frames_tail; /* all filled frames */ | 193 | spinlock_t queued_bufs_lock; |
213 | struct pwc_frame_buf *fill_frame; /* frame currently being filled */ | 194 | |
214 | struct pwc_frame_buf *read_frame; /* frame currently read by user process */ | 195 | /* |
196 | * Frame currently being filled, this only gets touched by the | ||
197 | * isoc urb complete handler, and by stream start / stop since | ||
198 | * start / stop touch it before / after starting / killing the urbs | ||
199 | * no locking is needed around this | ||
200 | */ | ||
201 | struct pwc_frame_buf *fill_buf; | ||
202 | |||
215 | int frame_header_size, frame_trailer_size; | 203 | int frame_header_size, frame_trailer_size; |
216 | int frame_size; | 204 | int frame_size; |
217 | int frame_total_size; /* including header & trailer */ | 205 | int frame_total_size; /* including header & trailer */ |
218 | int drop_frames; | 206 | int drop_frames; |
219 | 207 | ||
220 | /* 3: decompression */ | ||
221 | void *decompress_data; /* private data for decompression engine */ | 208 | void *decompress_data; /* private data for decompression engine */ |
222 | 209 | ||
223 | /* 4: image */ | ||
224 | /* We have an 'image' and a 'view', where 'image' is the fixed-size image | 210 | /* We have an 'image' and a 'view', where 'image' is the fixed-size image |
225 | as delivered by the camera, and 'view' is the size requested by the | 211 | as delivered by the camera, and 'view' is the size requested by the |
226 | program. The camera image is centered in this viewport, laced with | 212 | program. The camera image is centered in this viewport, laced with |
@@ -232,15 +218,7 @@ struct pwc_device | |||
232 | struct pwc_coord image, view; /* image and viewport size */ | 218 | struct pwc_coord image, view; /* image and viewport size */ |
233 | struct pwc_coord offset; /* offset within the viewport */ | 219 | struct pwc_coord offset; /* offset within the viewport */ |
234 | 220 | ||
235 | void *image_data; /* total buffer, which is subdivided into ... */ | ||
236 | struct pwc_imgbuf images[MAX_IMAGES];/* ...several images... */ | ||
237 | int fill_image; /* ...which are rotated. */ | ||
238 | int len_per_image; /* length per image */ | ||
239 | int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */ | ||
240 | int image_used[MAX_IMAGES]; /* For MCAPTURE and SYNC */ | ||
241 | |||
242 | struct mutex modlock; /* to prevent races in video_open(), etc */ | 221 | struct mutex modlock; /* to prevent races in video_open(), etc */ |
243 | spinlock_t ptrlock; /* for manipulating the buffer pointers */ | ||
244 | 222 | ||
245 | /*** motorized pan/tilt feature */ | 223 | /*** motorized pan/tilt feature */ |
246 | struct pwc_mpt_range angle_range; | 224 | struct pwc_mpt_range angle_range; |
@@ -253,7 +231,6 @@ struct pwc_device | |||
253 | #endif | 231 | #endif |
254 | 232 | ||
255 | /*** Misc. data ***/ | 233 | /*** Misc. data ***/ |
256 | wait_queue_head_t frameq; /* When waiting for a frame to finish... */ | ||
257 | #if PWC_INT_PIPE | 234 | #if PWC_INT_PIPE |
258 | void *usb_int_handler; /* for the interrupt endpoint */ | 235 | void *usb_int_handler; /* for the interrupt endpoint */ |
259 | #endif | 236 | #endif |
@@ -263,13 +240,6 @@ struct pwc_device | |||
263 | #ifdef CONFIG_USB_PWC_DEBUG | 240 | #ifdef CONFIG_USB_PWC_DEBUG |
264 | extern int pwc_trace; | 241 | extern int pwc_trace; |
265 | #endif | 242 | #endif |
266 | extern int pwc_mbufs; | ||
267 | |||
268 | /** functions in pwc-if.c */ | ||
269 | int pwc_handle_frame(struct pwc_device *pdev); | ||
270 | void pwc_next_image(struct pwc_device *pdev); | ||
271 | int pwc_isoc_init(struct pwc_device *pdev); | ||
272 | void pwc_isoc_cleanup(struct pwc_device *pdev); | ||
273 | 243 | ||
274 | /** Functions in pwc-misc.c */ | 244 | /** Functions in pwc-misc.c */ |
275 | /* sizes in pixels */ | 245 | /* sizes in pixels */ |
@@ -334,6 +304,6 @@ extern const struct v4l2_ioctl_ops pwc_ioctl_ops; | |||
334 | 304 | ||
335 | /** pwc-uncompress.c */ | 305 | /** pwc-uncompress.c */ |
336 | /* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ | 306 | /* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ |
337 | extern int pwc_decompress(struct pwc_device *pdev); | 307 | int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf); |
338 | 308 | ||
339 | #endif | 309 | #endif |