diff options
author | Aidan Thornton <makosoft@googlemail.com> | 2008-04-13 13:38:47 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 13:08:00 -0400 |
commit | d7aa80207babe694b316a48200b096cf0336ecb3 (patch) | |
tree | 5984ce3c1c9192f94db74a93459eb811c9484a91 /drivers/media/video/em28xx/em28xx-video.c | |
parent | ad0ebb96c220c461386e9a765fca3daf5590d01e (diff) |
V4L/DVB (7541): em28xx: Some fixes to videobuf
It fixes a couple of minor bugs, comments out a bogus BUG_ON, sets fh->type
correctly, uses dev->width and dev->height for now, and adds a missing spinlock
init (nasty - caused a system lockup). It also adds some debug code which
probably isn't all that useful. I haven't tested this version of the patch yet,
though, so I'm not sure what you can expect if you try it.
Signed-off-by: Aidan Thornton <makosoft@googlemail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-video.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 281 |
1 files changed, 113 insertions, 168 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 182058ac8432..4e6cc612a994 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -133,10 +133,10 @@ static void inline buffer_filled (struct em28xx *dev, | |||
133 | struct em28xx_dmaqueue *dma_q, | 133 | struct em28xx_dmaqueue *dma_q, |
134 | struct em28xx_buffer *buf) | 134 | struct em28xx_buffer *buf) |
135 | { | 135 | { |
136 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | ||
137 | |||
136 | /* Nobody is waiting something to be done, just return */ | 138 | /* Nobody is waiting something to be done, just return */ |
137 | if (!waitqueue_active(&buf->vb.done)) { | 139 | if (!waitqueue_active(&buf->vb.done)) { |
138 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | ||
139 | |||
140 | printk(KERN_ERR "em28xx: buffer underrun at %ld\n", | 140 | printk(KERN_ERR "em28xx: buffer underrun at %ld\n", |
141 | jiffies); | 141 | jiffies); |
142 | 142 | ||
@@ -174,7 +174,7 @@ static void em28xx_copy_video(struct em28xx *dev, | |||
174 | if (dma_q->pos + len > buf->vb.size) | 174 | if (dma_q->pos + len > buf->vb.size) |
175 | len = buf->vb.size - dma_q->pos; | 175 | len = buf->vb.size - dma_q->pos; |
176 | 176 | ||
177 | if (outp[0] != 0x88 && outp[0] != 0x22) { | 177 | if (p[0] != 0x88 && p[0] != 0x22) { |
178 | em28xx_isocdbg("frame is not complete\n"); | 178 | em28xx_isocdbg("frame is not complete\n"); |
179 | len += 4; | 179 | len += 4; |
180 | } else | 180 | } else |
@@ -196,8 +196,13 @@ static void em28xx_copy_video(struct em28xx *dev, | |||
196 | lencopy = dev->bytesperline - currlinedone; | 196 | lencopy = dev->bytesperline - currlinedone; |
197 | lencopy = lencopy > remain ? remain : lencopy; | 197 | lencopy = lencopy > remain ? remain : lencopy; |
198 | 198 | ||
199 | if (__copy_to_user(startwrite, startread, lencopy) != 0) | 199 | if((char*)startwrite + lencopy > (char*)outp + buf->vb.size) { |
200 | em28xx_errdev("copy_to_user failed.\n"); | 200 | em28xx_isocdbg("Overflow of %i bytes past buffer end (1)\n", |
201 | ((char*)startwrite + lencopy) - ((char*)outp + buf->vb.size)); | ||
202 | lencopy = remain = (char*)outp + buf->vb.size - (char*)startwrite; | ||
203 | } | ||
204 | BUG_ON(lencopy <= 0); | ||
205 | memcpy(startwrite, startread, lencopy); | ||
201 | 206 | ||
202 | remain -= lencopy; | 207 | remain -= lencopy; |
203 | 208 | ||
@@ -209,8 +214,16 @@ static void em28xx_copy_video(struct em28xx *dev, | |||
209 | else | 214 | else |
210 | lencopy = dev->bytesperline; | 215 | lencopy = dev->bytesperline; |
211 | 216 | ||
212 | if (__copy_to_user(startwrite, startread, lencopy) != 0) | 217 | BUG_ON(lencopy <= 0); |
213 | em28xx_errdev("copy_to_user failed.\n"); | 218 | |
219 | if((char*)startwrite + lencopy > (char*)outp + buf->vb.size) { | ||
220 | em28xx_isocdbg("Overflow of %i bytes past buffer end (2)\n", | ||
221 | ((char*)startwrite + lencopy) - ((char*)outp + buf->vb.size)); | ||
222 | lencopy = remain = (char*)outp + buf->vb.size - (char*)startwrite; | ||
223 | } | ||
224 | if(lencopy <= 0) break; | ||
225 | |||
226 | memcpy(startwrite, startread, lencopy); | ||
214 | 227 | ||
215 | remain -= lencopy; | 228 | remain -= lencopy; |
216 | } | 229 | } |
@@ -278,13 +291,14 @@ static int inline get_next_buf (struct em28xx_dmaqueue *dma_q, | |||
278 | /* | 291 | /* |
279 | * Controls the isoc copy of each urb packet | 292 | * Controls the isoc copy of each urb packet |
280 | */ | 293 | */ |
281 | static inline int em28xx_isoc_copy(struct urb *urb, struct em28xx_buffer **buf) | 294 | static inline int em28xx_isoc_copy(struct urb *urb) |
282 | { | 295 | { |
296 | struct em28xx_buffer *buf; | ||
283 | struct em28xx_dmaqueue *dma_q = urb->context; | 297 | struct em28xx_dmaqueue *dma_q = urb->context; |
284 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); | 298 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); |
285 | unsigned char *outp = videobuf_to_vmalloc (&(*buf)->vb); | 299 | unsigned char *outp; |
286 | int i, len = 0, rc = 1; | 300 | int i, len = 0, rc = 1; |
287 | char *p; | 301 | unsigned char *p; |
288 | 302 | ||
289 | if (!dev) | 303 | if (!dev) |
290 | return 0; | 304 | return 0; |
@@ -298,6 +312,17 @@ static inline int em28xx_isoc_copy(struct urb *urb, struct em28xx_buffer **buf) | |||
298 | return 0; | 312 | return 0; |
299 | } | 313 | } |
300 | 314 | ||
315 | buf=dev->isoc_ctl.buf; | ||
316 | |||
317 | if (!buf) { | ||
318 | rc=get_next_buf (dma_q, &buf); | ||
319 | if (rc<=0) | ||
320 | return rc; | ||
321 | } | ||
322 | |||
323 | outp = videobuf_to_vmalloc (&buf->vb); | ||
324 | |||
325 | |||
301 | for (i = 0; i < urb->number_of_packets; i++) { | 326 | for (i = 0; i < urb->number_of_packets; i++) { |
302 | int status = urb->iso_frame_desc[i].status; | 327 | int status = urb->iso_frame_desc[i].status; |
303 | 328 | ||
@@ -310,7 +335,7 @@ static inline int em28xx_isoc_copy(struct urb *urb, struct em28xx_buffer **buf) | |||
310 | len=urb->iso_frame_desc[i].actual_length - 4; | 335 | len=urb->iso_frame_desc[i].actual_length - 4; |
311 | 336 | ||
312 | if (urb->iso_frame_desc[i].actual_length <= 0) { | 337 | if (urb->iso_frame_desc[i].actual_length <= 0) { |
313 | em28xx_isocdbg("packet %d is empty",i); | 338 | /* em28xx_isocdbg("packet %d is empty",i); - spammy */ |
314 | continue; | 339 | continue; |
315 | } | 340 | } |
316 | if (urb->iso_frame_desc[i].actual_length > | 341 | if (urb->iso_frame_desc[i].actual_length > |
@@ -320,31 +345,37 @@ static inline int em28xx_isoc_copy(struct urb *urb, struct em28xx_buffer **buf) | |||
320 | } | 345 | } |
321 | 346 | ||
322 | p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | 347 | p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; |
323 | if (urb->iso_frame_desc[i].status != -EPROTO) | ||
324 | continue; | ||
325 | 348 | ||
326 | /* FIXME: incomplete buffer checks where removed to make | 349 | /* FIXME: incomplete buffer checks where removed to make |
327 | logic simpler. Impacts of those changes should be evaluated | 350 | logic simpler. Impacts of those changes should be evaluated |
328 | */ | 351 | */ |
329 | if (outp[0] == 0x22 && outp[1] == 0x5a) { | 352 | if (p[0] == 0x22 && p[1] == 0x5a) { |
330 | em28xx_isocdbg("Video frame, length=%i, %s", len, | 353 | /* FIXME - are the fields the right way around? */ |
331 | (outp[2] == 1)? "top" : "botton"); | 354 | em28xx_isocdbg("Video frame, length=%i, %s\n", len, |
332 | 355 | (p[2] & 1)? "top" : "bottom"); | |
333 | if (outp[2] == 1) { | 356 | em28xx_isocdbg("Current buffer is: outp = 0x%p, len = %i\n", outp, (int)buf->vb.size); |
334 | if ((*buf)->receiving) | 357 | |
335 | buffer_filled (dev, dma_q, *buf); | 358 | if (p[2] & 1) { |
359 | if (buf->receiving) { | ||
360 | buffer_filled (dev, dma_q, buf); | ||
361 | rc=get_next_buf (dma_q, &buf); | ||
362 | if (rc<=0) | ||
363 | return rc; | ||
364 | |||
365 | outp = videobuf_to_vmalloc (&buf->vb); | ||
366 | } | ||
336 | 367 | ||
337 | (*buf)->top_field = 1; | 368 | buf->top_field = 1; |
338 | } else { | 369 | } else { |
339 | (*buf)->top_field = 0; | 370 | buf->top_field = 0; |
340 | } | 371 | } |
341 | (*buf)->receiving = 1; | 372 | buf->receiving = 1; |
342 | dma_q->pos = 0; | 373 | dma_q->pos = 0; |
343 | } else if (outp[0]==0x33 && outp[1]==0x95 && outp[2]==0x00) { | 374 | } else if (p[0]==0x33 && p[1]==0x95 && p[2]==0x00) { |
344 | em28xx_isocdbg("VBI HEADER!!!"); | 375 | em28xx_isocdbg("VBI HEADER!!!\n"); |
345 | } | 376 | } |
346 | 377 | ||
347 | em28xx_copy_video(dev, dma_q, *buf, p, outp, len); | 378 | em28xx_copy_video(dev, dma_q, buf, p, outp, len); |
348 | 379 | ||
349 | /* FIXME: Should add vbi copy */ | 380 | /* FIXME: Should add vbi copy */ |
350 | } | 381 | } |
@@ -360,7 +391,6 @@ static inline int em28xx_isoc_copy(struct urb *urb, struct em28xx_buffer **buf) | |||
360 | */ | 391 | */ |
361 | static void em28xx_irq_callback(struct urb *urb) | 392 | static void em28xx_irq_callback(struct urb *urb) |
362 | { | 393 | { |
363 | struct em28xx_buffer *buf; | ||
364 | struct em28xx_dmaqueue *dma_q = urb->context; | 394 | struct em28xx_dmaqueue *dma_q = urb->context; |
365 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); | 395 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); |
366 | int rc,i; | 396 | int rc,i; |
@@ -368,19 +398,9 @@ static void em28xx_irq_callback(struct urb *urb) | |||
368 | 398 | ||
369 | spin_lock_irqsave(&dev->slock,flags); | 399 | spin_lock_irqsave(&dev->slock,flags); |
370 | 400 | ||
371 | buf=dev->isoc_ctl.buf; | ||
372 | |||
373 | if (!buf) { | ||
374 | rc=get_next_buf (dma_q, &buf); | ||
375 | if (rc<=0) | ||
376 | goto ret; | ||
377 | } | ||
378 | |||
379 | /* Copy data from URB */ | 401 | /* Copy data from URB */ |
380 | rc=em28xx_isoc_copy(urb, &buf); | 402 | rc=em28xx_isoc_copy(urb); |
381 | 403 | ||
382 | dev->isoc_ctl.buf=buf; | ||
383 | ret: | ||
384 | /* Reset urb buffers */ | 404 | /* Reset urb buffers */ |
385 | for (i = 0; i < urb->number_of_packets; i++) { | 405 | for (i = 0; i < urb->number_of_packets; i++) { |
386 | urb->iso_frame_desc[i].status = 0; | 406 | urb->iso_frame_desc[i].status = 0; |
@@ -393,8 +413,12 @@ ret: | |||
393 | urb->status); | 413 | urb->status); |
394 | } | 414 | } |
395 | 415 | ||
416 | #if 0 /* Bad idea. There are problems that cause a load of valid, but | ||
417 | empty, data packets. Don't reset the timeout unless we've actually | ||
418 | got a frame. I've had xawtv hang in free_buffer due to this! */ | ||
396 | if (rc >= 0) | 419 | if (rc >= 0) |
397 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | 420 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); |
421 | #endif | ||
398 | spin_unlock_irqrestore(&dev->slock,flags); | 422 | spin_unlock_irqrestore(&dev->slock,flags); |
399 | } | 423 | } |
400 | 424 | ||
@@ -406,6 +430,8 @@ static void em28xx_uninit_isoc(struct em28xx *dev) | |||
406 | struct urb *urb; | 430 | struct urb *urb; |
407 | int i; | 431 | int i; |
408 | 432 | ||
433 | em28xx_isocdbg("em28xx: called em28xx_uninit_isoc\n"); | ||
434 | |||
409 | dev->isoc_ctl.nfields=-1; | 435 | dev->isoc_ctl.nfields=-1; |
410 | dev->isoc_ctl.buf=NULL; | 436 | dev->isoc_ctl.buf=NULL; |
411 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | 437 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { |
@@ -432,18 +458,9 @@ static void em28xx_uninit_isoc(struct em28xx *dev) | |||
432 | 458 | ||
433 | dev->isoc_ctl.num_bufs=0; | 459 | dev->isoc_ctl.num_bufs=0; |
434 | 460 | ||
435 | em28xx_capture_start(dev, 0); | 461 | // em28xx_capture_start(dev, 0); - FIXME - how could I restart it? |
436 | } | 462 | } |
437 | 463 | ||
438 | /* | ||
439 | * Stop video thread - FIXME: Can be easily removed | ||
440 | */ | ||
441 | static void em28xx_stop_thread(struct em28xx_dmaqueue *dma_q) | ||
442 | { | ||
443 | struct em28xx *dev= container_of(dma_q, struct em28xx, vidq); | ||
444 | |||
445 | em28xx_uninit_isoc(dev); | ||
446 | } | ||
447 | 464 | ||
448 | /* | 465 | /* |
449 | * Allocate URBs and start IRQ | 466 | * Allocate URBs and start IRQ |
@@ -457,18 +474,20 @@ static int em28xx_prepare_isoc(struct em28xx *dev, int max_packets, | |||
457 | struct urb *urb; | 474 | struct urb *urb; |
458 | int j, k; | 475 | int j, k; |
459 | 476 | ||
477 | em28xx_isocdbg("em28xx: called em28xx_prepare_isoc\n"); | ||
478 | |||
460 | /* De-allocates all pending stuff */ | 479 | /* De-allocates all pending stuff */ |
461 | em28xx_uninit_isoc(dev); | 480 | em28xx_uninit_isoc(dev); |
462 | 481 | ||
463 | dev->isoc_ctl.num_bufs = num_bufs; | 482 | dev->isoc_ctl.num_bufs = num_bufs; |
464 | 483 | ||
465 | dev->isoc_ctl.urb = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL); | 484 | dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); |
466 | if (!dev->isoc_ctl.urb) { | 485 | if (!dev->isoc_ctl.urb) { |
467 | em28xx_errdev("cannot alloc memory for usb buffers\n"); | 486 | em28xx_errdev("cannot alloc memory for usb buffers\n"); |
468 | return -ENOMEM; | 487 | return -ENOMEM; |
469 | } | 488 | } |
470 | 489 | ||
471 | dev->isoc_ctl.transfer_buffer = kmalloc(sizeof(void *)*num_bufs, | 490 | dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, |
472 | GFP_KERNEL); | 491 | GFP_KERNEL); |
473 | if (!dev->isoc_ctl.urb) { | 492 | if (!dev->isoc_ctl.urb) { |
474 | em28xx_errdev("cannot allocate memory for usbtransfer\n"); | 493 | em28xx_errdev("cannot allocate memory for usbtransfer\n"); |
@@ -486,7 +505,6 @@ static int em28xx_prepare_isoc(struct em28xx *dev, int max_packets, | |||
486 | if (!urb) { | 505 | if (!urb) { |
487 | em28xx_err("cannot alloc isoc_ctl.urb %i\n", i); | 506 | em28xx_err("cannot alloc isoc_ctl.urb %i\n", i); |
488 | em28xx_uninit_isoc(dev); | 507 | em28xx_uninit_isoc(dev); |
489 | usb_free_urb(urb); | ||
490 | return -ENOMEM; | 508 | return -ENOMEM; |
491 | } | 509 | } |
492 | dev->isoc_ctl.urb[i] = urb; | 510 | dev->isoc_ctl.urb[i] = urb; |
@@ -527,15 +545,14 @@ static int em28xx_prepare_isoc(struct em28xx *dev, int max_packets, | |||
527 | return 0; | 545 | return 0; |
528 | } | 546 | } |
529 | 547 | ||
530 | static int em28xx_start_thread( struct em28xx_dmaqueue *dma_q, | 548 | static int em28xx_start_thread( struct em28xx_dmaqueue *dma_q) |
531 | struct em28xx_buffer *buf) | ||
532 | { | 549 | { |
533 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); | 550 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); |
534 | int i,rc; | 551 | int i,rc = 0; |
535 | 552 | ||
536 | init_waitqueue_head(&dma_q->wq); | 553 | em28xx_videodbg("Called em28xx_start_thread\n"); |
537 | 554 | ||
538 | em28xx_capture_start(dev, 1); | 555 | init_waitqueue_head(&dma_q->wq); |
539 | 556 | ||
540 | /* submit urbs and enables IRQ */ | 557 | /* submit urbs and enables IRQ */ |
541 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | 558 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { |
@@ -554,68 +571,6 @@ static int em28xx_start_thread( struct em28xx_dmaqueue *dma_q, | |||
554 | return 0; | 571 | return 0; |
555 | } | 572 | } |
556 | 573 | ||
557 | static int restart_video_queue(struct em28xx_dmaqueue *dma_q) | ||
558 | { | ||
559 | struct em28xx *dev= container_of(dma_q,struct em28xx,vidq); | ||
560 | |||
561 | struct em28xx_buffer *buf, *prev; | ||
562 | struct list_head *item; | ||
563 | |||
564 | em28xx_videodbg("%s dma_q=0x%08lx\n", | ||
565 | __FUNCTION__,(unsigned long)dma_q); | ||
566 | |||
567 | if (!list_empty(&dma_q->active)) { | ||
568 | buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue); | ||
569 | em28xx_videodbg("restart_queue [%p/%d]: restart dma\n", | ||
570 | buf, buf->vb.i); | ||
571 | em28xx_stop_thread(dma_q); | ||
572 | em28xx_start_thread(dma_q, buf); | ||
573 | |||
574 | /* cancel all outstanding capture / vbi requests */ | ||
575 | list_for_each(item,&dma_q->active) { | ||
576 | buf = list_entry(item, struct em28xx_buffer, vb.queue); | ||
577 | |||
578 | list_del(&buf->vb.queue); | ||
579 | buf->vb.state = VIDEOBUF_ERROR; | ||
580 | wake_up(&buf->vb.done); | ||
581 | } | ||
582 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | ||
583 | |||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | prev = NULL; | ||
588 | for (;;) { | ||
589 | if (list_empty(&dma_q->queued)) | ||
590 | return 0; | ||
591 | buf = list_entry(dma_q->queued.next, struct em28xx_buffer, vb.queue); | ||
592 | if (NULL == prev) { | ||
593 | list_del(&buf->vb.queue); | ||
594 | list_add_tail(&buf->vb.queue,&dma_q->active); | ||
595 | |||
596 | em28xx_videodbg("Restarting video dma\n"); | ||
597 | em28xx_stop_thread(dma_q); | ||
598 | em28xx_start_thread(dma_q, buf); | ||
599 | |||
600 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
601 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | ||
602 | em28xx_videodbg("[%p/%d] restart_queue -" | ||
603 | " first active\n", buf, buf->vb.i); | ||
604 | |||
605 | } else if (prev->vb.width == buf->vb.width && | ||
606 | prev->vb.height == buf->vb.height && | ||
607 | prev->fmt == buf->fmt) { | ||
608 | list_del(&buf->vb.queue); | ||
609 | list_add_tail(&buf->vb.queue,&dma_q->active); | ||
610 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
611 | em28xx_videodbg("[%p/%d] restart_queue -" | ||
612 | " move to active\n",buf,buf->vb.i); | ||
613 | } else { | ||
614 | return 0; | ||
615 | } | ||
616 | prev = buf; | ||
617 | } | ||
618 | } | ||
619 | 574 | ||
620 | static void em28xx_vid_timeout(unsigned long data) | 575 | static void em28xx_vid_timeout(unsigned long data) |
621 | { | 576 | { |
@@ -635,7 +590,7 @@ static void em28xx_vid_timeout(unsigned long data) | |||
635 | buf, buf->vb.i); | 590 | buf, buf->vb.i); |
636 | } | 591 | } |
637 | 592 | ||
638 | restart_video_queue(vidq); | 593 | /* restart_video_queue(vidq); */ |
639 | spin_unlock_irqrestore(&dev->slock,flags); | 594 | spin_unlock_irqrestore(&dev->slock,flags); |
640 | } | 595 | } |
641 | 596 | ||
@@ -648,7 +603,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | |||
648 | { | 603 | { |
649 | struct em28xx_fh *fh = vq->priv_data; | 604 | struct em28xx_fh *fh = vq->priv_data; |
650 | 605 | ||
651 | *size = 16 * fh->width * fh->height >> 3; | 606 | *size = 16 * fh->dev->width * fh->dev->height >> 3; |
652 | if (0 == *count) | 607 | if (0 == *count) |
653 | *count = EM28XX_DEF_BUF; | 608 | *count = EM28XX_DEF_BUF; |
654 | 609 | ||
@@ -676,41 +631,45 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
676 | struct em28xx_fh *fh = vq->priv_data; | 631 | struct em28xx_fh *fh = vq->priv_data; |
677 | struct em28xx_buffer *buf = container_of(vb,struct em28xx_buffer,vb); | 632 | struct em28xx_buffer *buf = container_of(vb,struct em28xx_buffer,vb); |
678 | struct em28xx *dev = fh->dev; | 633 | struct em28xx *dev = fh->dev; |
634 | struct em28xx_dmaqueue *vidq = &dev->vidq; | ||
679 | int rc = 0, urb_init = 0; | 635 | int rc = 0, urb_init = 0; |
680 | const int urbsize = EM28XX_NUM_PACKETS * dev->max_pkt_size; | ||
681 | 636 | ||
682 | BUG_ON(NULL == fh->fmt); | 637 | /* BUG_ON(NULL == fh->fmt); */ |
683 | 638 | ||
684 | /* FIXME: It assumes depth = 16 */ | 639 | /* FIXME: It assumes depth = 16 */ |
685 | /* The only currently supported format is 16 bits/pixel */ | 640 | /* The only currently supported format is 16 bits/pixel */ |
686 | buf->vb.size = 16 * fh->width * fh->height >> 3; | 641 | buf->vb.size = 16 * dev->width * dev->height >> 3; |
687 | 642 | ||
688 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 643 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
689 | return -EINVAL; | 644 | return -EINVAL; |
690 | 645 | ||
691 | if (buf->fmt != fh->fmt || | 646 | if (buf->fmt != fh->fmt || |
692 | buf->vb.width != fh->width || | 647 | buf->vb.width != dev->width || |
693 | buf->vb.height != fh->height || | 648 | buf->vb.height != dev->height || |
694 | buf->vb.field != field) { | 649 | buf->vb.field != field) { |
695 | buf->fmt = fh->fmt; | 650 | buf->fmt = fh->fmt; |
696 | buf->vb.width = fh->width; | 651 | buf->vb.width = dev->width; |
697 | buf->vb.height = fh->height; | 652 | buf->vb.height = dev->height; |
698 | buf->vb.field = field; | 653 | buf->vb.field = field; |
699 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 654 | buf->vb.state = VIDEOBUF_NEEDS_INIT; |
700 | } | 655 | } |
701 | 656 | ||
702 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 657 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
703 | if (0 != (rc = videobuf_iolock(vq,&buf->vb,NULL))) | 658 | rc = videobuf_iolock(vq, &buf->vb, NULL); |
659 | if (rc < 0) | ||
704 | goto fail; | 660 | goto fail; |
705 | urb_init=1; | ||
706 | } | 661 | } |
707 | 662 | ||
708 | |||
709 | if (!dev->isoc_ctl.num_bufs) | 663 | if (!dev->isoc_ctl.num_bufs) |
710 | urb_init=1; | 664 | urb_init=1; |
711 | 665 | ||
712 | if (urb_init) { | 666 | if (urb_init) { |
713 | rc = em28xx_prepare_isoc(dev, urbsize, EM28XX_NUM_BUFS); | 667 | rc = em28xx_prepare_isoc(dev, EM28XX_NUM_PACKETS, EM28XX_NUM_BUFS); |
668 | if (rc<0) | ||
669 | goto fail; | ||
670 | |||
671 | /* FIXME - should probably be done in response to STREAMON */ | ||
672 | rc = em28xx_start_thread(vidq); | ||
714 | if (rc<0) | 673 | if (rc<0) |
715 | goto fail; | 674 | goto fail; |
716 | } | 675 | } |
@@ -730,37 +689,10 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
730 | struct em28xx_fh *fh = vq->priv_data; | 689 | struct em28xx_fh *fh = vq->priv_data; |
731 | struct em28xx *dev = fh->dev; | 690 | struct em28xx *dev = fh->dev; |
732 | struct em28xx_dmaqueue *vidq = &dev->vidq; | 691 | struct em28xx_dmaqueue *vidq = &dev->vidq; |
733 | struct em28xx_buffer *prev; | ||
734 | 692 | ||
735 | if (!list_empty(&vidq->queued)) { | 693 | buf->vb.state = VIDEOBUF_QUEUED; |
736 | list_add_tail(&buf->vb.queue,&vidq->queued); | 694 | list_add_tail(&buf->vb.queue, &vidq->active); |
737 | buf->vb.state = VIDEOBUF_QUEUED; | 695 | |
738 | em28xx_videodbg("[%p/%d] buffer_queue - append to queued\n", | ||
739 | buf, buf->vb.i); | ||
740 | } else if (list_empty(&vidq->active)) { | ||
741 | list_add_tail(&buf->vb.queue,&vidq->active); | ||
742 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
743 | mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT); | ||
744 | em28xx_videodbg("[%p/%d] buffer_queue - first active\n", | ||
745 | buf, buf->vb.i); | ||
746 | em28xx_start_thread(vidq, buf); | ||
747 | } else { | ||
748 | prev = list_entry(vidq->active.prev, struct em28xx_buffer, | ||
749 | vb.queue); | ||
750 | if (prev->vb.width == buf->vb.width && | ||
751 | prev->vb.height == buf->vb.height && | ||
752 | prev->fmt == buf->fmt) { | ||
753 | list_add_tail(&buf->vb.queue,&vidq->active); | ||
754 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
755 | em28xx_videodbg("[%p/%d] buffer_queue -" | ||
756 | " append to active\n", buf, buf->vb.i); | ||
757 | } else { | ||
758 | list_add_tail(&buf->vb.queue,&vidq->queued); | ||
759 | buf->vb.state = VIDEOBUF_QUEUED; | ||
760 | em28xx_videodbg("[%p/%d] buffer_queue - first queued\n", | ||
761 | buf, buf->vb.i); | ||
762 | } | ||
763 | } | ||
764 | } | 696 | } |
765 | 697 | ||
766 | static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) | 698 | static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) |
@@ -768,9 +700,8 @@ static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb | |||
768 | struct em28xx_buffer *buf = container_of(vb,struct em28xx_buffer,vb); | 700 | struct em28xx_buffer *buf = container_of(vb,struct em28xx_buffer,vb); |
769 | struct em28xx_fh *fh = vq->priv_data; | 701 | struct em28xx_fh *fh = vq->priv_data; |
770 | struct em28xx *dev = (struct em28xx*)fh->dev; | 702 | struct em28xx *dev = (struct em28xx*)fh->dev; |
771 | struct em28xx_dmaqueue *vidq = &dev->vidq; | ||
772 | 703 | ||
773 | em28xx_stop_thread(vidq); | 704 | em28xx_isocdbg("em28xx: called buffer_release\n"); |
774 | 705 | ||
775 | free_buffer(vq,buf); | 706 | free_buffer(vq,buf); |
776 | } | 707 | } |
@@ -1068,6 +999,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
1068 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | 999 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); |
1069 | 1000 | ||
1070 | em28xx_set_alternate(dev); | 1001 | em28xx_set_alternate(dev); |
1002 | em28xx_capture_start(dev, 1); /* ??? */ | ||
1071 | em28xx_resolution_set(dev); | 1003 | em28xx_resolution_set(dev); |
1072 | 1004 | ||
1073 | mutex_unlock(&dev->lock); | 1005 | mutex_unlock(&dev->lock); |
@@ -1497,6 +1429,14 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1497 | if (unlikely(res_get(fh) < 0)) | 1429 | if (unlikely(res_get(fh) < 0)) |
1498 | return -EBUSY; | 1430 | return -EBUSY; |
1499 | 1431 | ||
1432 | /* We can't do this from buffer_queue or anything called from | ||
1433 | there, since it's called with IRQs disabled and the spinlock held, | ||
1434 | and this uses USB functions that may sleep | ||
1435 | |||
1436 | FIXME FIXME FIXME - putting this here means it may not always | ||
1437 | be called when it needs to be */ | ||
1438 | em28xx_capture_start(dev, 1); | ||
1439 | |||
1500 | return (videobuf_streamon(&fh->vb_vidq)); | 1440 | return (videobuf_streamon(&fh->vb_vidq)); |
1501 | } | 1441 | } |
1502 | 1442 | ||
@@ -1778,15 +1718,16 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1778 | int errCode = 0, radio = 0; | 1718 | int errCode = 0, radio = 0; |
1779 | struct em28xx *h,*dev = NULL; | 1719 | struct em28xx *h,*dev = NULL; |
1780 | struct em28xx_fh *fh; | 1720 | struct em28xx_fh *fh; |
1721 | enum v4l2_buf_type fh_type = 0; | ||
1781 | 1722 | ||
1782 | list_for_each_entry(h, &em28xx_devlist, devlist) { | 1723 | list_for_each_entry(h, &em28xx_devlist, devlist) { |
1783 | if (h->vdev->minor == minor) { | 1724 | if (h->vdev->minor == minor) { |
1784 | dev = h; | 1725 | dev = h; |
1785 | dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1726 | fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1786 | } | 1727 | } |
1787 | if (h->vbi_dev->minor == minor) { | 1728 | if (h->vbi_dev->minor == minor) { |
1788 | dev = h; | 1729 | dev = h; |
1789 | dev->type = V4L2_BUF_TYPE_VBI_CAPTURE; | 1730 | fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; |
1790 | } | 1731 | } |
1791 | if (h->radio_dev && | 1732 | if (h->radio_dev && |
1792 | h->radio_dev->minor == minor) { | 1733 | h->radio_dev->minor == minor) { |
@@ -1798,7 +1739,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1798 | return -ENODEV; | 1739 | return -ENODEV; |
1799 | 1740 | ||
1800 | em28xx_videodbg("open minor=%d type=%s users=%d\n", | 1741 | em28xx_videodbg("open minor=%d type=%s users=%d\n", |
1801 | minor,v4l2_type_names[dev->type],dev->users); | 1742 | minor, v4l2_type_names[fh_type], dev->users); |
1802 | 1743 | ||
1803 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); | 1744 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); |
1804 | 1745 | ||
@@ -1809,9 +1750,10 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1809 | mutex_lock(&dev->lock); | 1750 | mutex_lock(&dev->lock); |
1810 | fh->dev = dev; | 1751 | fh->dev = dev; |
1811 | fh->radio = radio; | 1752 | fh->radio = radio; |
1753 | fh->type = fh_type; | ||
1812 | filp->private_data = fh; | 1754 | filp->private_data = fh; |
1813 | 1755 | ||
1814 | if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { | 1756 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { |
1815 | dev->width = norm_maxw(dev); | 1757 | dev->width = norm_maxw(dev); |
1816 | dev->height = norm_maxh(dev); | 1758 | dev->height = norm_maxh(dev); |
1817 | dev->frame_size = dev->width * dev->height * 2; | 1759 | dev->frame_size = dev->width * dev->height * 2; |
@@ -1912,6 +1854,9 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
1912 | return 0; | 1854 | return 0; |
1913 | } | 1855 | } |
1914 | 1856 | ||
1857 | /* do this before setting alternate! */ | ||
1858 | em28xx_uninit_isoc(dev); | ||
1859 | |||
1915 | /* set alternate 0 */ | 1860 | /* set alternate 0 */ |
1916 | dev->alt = 0; | 1861 | dev->alt = 0; |
1917 | em28xx_videodbg("setting alternate 0\n"); | 1862 | em28xx_videodbg("setting alternate 0\n"); |
@@ -2178,7 +2123,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
2178 | 2123 | ||
2179 | dev->udev = udev; | 2124 | dev->udev = udev; |
2180 | mutex_init(&dev->lock); | 2125 | mutex_init(&dev->lock); |
2181 | spin_lock_init(&dev->queue_lock); | 2126 | spin_lock_init(&dev->slock); |
2182 | init_waitqueue_head(&dev->open); | 2127 | init_waitqueue_head(&dev->open); |
2183 | init_waitqueue_head(&dev->wait_frame); | 2128 | init_waitqueue_head(&dev->wait_frame); |
2184 | init_waitqueue_head(&dev->wait_stream); | 2129 | init_waitqueue_head(&dev->wait_stream); |