aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorStefan Ringel <stefan.ringel@arcor.de>2010-05-19 12:58:26 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-06-01 00:22:01 -0400
commit4b6ed9fd0baf34da6912bebee46c36eda0411984 (patch)
treebf0a2f1d225e5766efd3c01bdac4fd424efe9431 /drivers/staging
parent3569417e5a2c20764158961a2f6c514d26136e5f (diff)
V4L/DVB: tm6000: bugfix video image
bugfix: Avoid loosing frames, causing image delays on some of the image lines. [mchehab@redhat.com: Fix compilation breakage by merging with the patch fix] Signed-off-by: Stefan Ringel <stefan.ringel@arcor.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/tm6000/tm6000-video.c88
1 files changed, 45 insertions, 43 deletions
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 02b88b550a4..8acfebdb5cd 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -339,14 +339,23 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
339 return rc; 339 return rc;
340} 340}
341 341
342static int copy_streams(u8 *data, u8 *out_p, unsigned long len, 342static int copy_streams(u8 *data, unsigned long len,
343 struct urb *urb, struct tm6000_buffer **buf) 343 struct urb *urb)
344{ 344{
345 struct tm6000_dmaqueue *dma_q = urb->context; 345 struct tm6000_dmaqueue *dma_q = urb->context;
346 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); 346 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
347 u8 *ptr=data, *endp=data+len; 347 u8 *ptr=data, *endp=data+len;
348 unsigned long header=0; 348 unsigned long header=0;
349 int rc=0; 349 int rc=0;
350 struct tm6000_buffer *buf;
351 char *outp = NULL;
352
353 get_next_buf(dma_q, &buf);
354 if (buf)
355 outp = videobuf_to_vmalloc(&buf->vb);
356
357 if (!outp)
358 return 0;
350 359
351 for (ptr=data; ptr<endp;) { 360 for (ptr=data; ptr<endp;) {
352 if (!dev->isoc_ctl.cmd) { 361 if (!dev->isoc_ctl.cmd) {
@@ -394,14 +403,14 @@ static int copy_streams(u8 *data, u8 *out_p, unsigned long len,
394 } 403 }
395HEADER: 404HEADER:
396 /* Copy or continue last copy */ 405 /* Copy or continue last copy */
397 rc=copy_packet(urb,header,&ptr,endp,out_p,buf); 406 rc=copy_packet(urb,header,&ptr,endp,outp,&buf);
398 if (rc<0) { 407 if (rc<0) {
399 buf=NULL; 408 buf=NULL;
400 printk(KERN_ERR "tm6000: buffer underrun at %ld\n", 409 printk(KERN_ERR "tm6000: buffer underrun at %ld\n",
401 jiffies); 410 jiffies);
402 return rc; 411 return rc;
403 } 412 }
404 if (!*buf) 413 if (!buf)
405 return 0; 414 return 0;
406 } 415 }
407 416
@@ -410,31 +419,40 @@ HEADER:
410/* 419/*
411 * Identify the tm5600/6000 buffer header type and properly handles 420 * Identify the tm5600/6000 buffer header type and properly handles
412 */ 421 */
413static int copy_multiplexed(u8 *ptr, u8 *out_p, unsigned long len, 422static int copy_multiplexed(u8 *ptr, unsigned long len,
414 struct urb *urb, struct tm6000_buffer **buf) 423 struct urb *urb)
415{ 424{
416 struct tm6000_dmaqueue *dma_q = urb->context; 425 struct tm6000_dmaqueue *dma_q = urb->context;
417 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); 426 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
418 unsigned int pos=dev->isoc_ctl.pos,cpysize; 427 unsigned int pos=dev->isoc_ctl.pos,cpysize;
419 int rc=1; 428 int rc=1;
429 struct tm6000_buffer *buf;
430 char *outp = NULL;
431
432 get_next_buf(dma_q, &buf);
433 if (buf)
434 outp = videobuf_to_vmalloc(&buf->vb);
435
436 if (!outp)
437 return 0;
420 438
421 while (len>0) { 439 while (len>0) {
422 cpysize=min(len,(*buf)->vb.size-pos); 440 cpysize=min(len,buf->vb.size-pos);
423//printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos); 441 //printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos);
424 memcpy(&out_p[pos], ptr, cpysize); 442 memcpy(&outp[pos], ptr, cpysize);
425 pos+=cpysize; 443 pos+=cpysize;
426 ptr+=cpysize; 444 ptr+=cpysize;
427 len-=cpysize; 445 len-=cpysize;
428 if (pos >= (*buf)->vb.size) { 446 if (pos >= buf->vb.size) {
429 pos=0; 447 pos=0;
430 /* Announces that a new buffer were filled */ 448 /* Announces that a new buffer were filled */
431 buffer_filled (dev, dma_q, *buf); 449 buffer_filled (dev, dma_q, buf);
432 dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n"); 450 dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n");
433 get_next_buf (dma_q, buf); 451 get_next_buf (dma_q, &buf);
434 if (!*buf) 452 if (!buf)
435 break; 453 break;
436 out_p = videobuf_to_vmalloc(&((*buf)->vb)); 454 outp = videobuf_to_vmalloc(&(buf->vb));
437 if (!out_p) 455 if (!outp)
438 return rc; 456 return rc;
439 pos = 0; 457 pos = 0;
440 } 458 }
@@ -493,52 +511,36 @@ static inline int tm6000_isoc_copy(struct urb *urb)
493 struct tm6000_dmaqueue *dma_q = urb->context; 511 struct tm6000_dmaqueue *dma_q = urb->context;
494 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); 512 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
495 struct tm6000_buffer *buf; 513 struct tm6000_buffer *buf;
496 int i, len=0, rc=1; 514 int i, len=0, rc=1, status;
497 int size; 515 char *p;
498 char *outp = NULL, *p;
499 unsigned long copied;
500 516
501 get_next_buf(dma_q, &buf); 517 if (urb->status < 0) {
502 if (buf) 518 print_err_status (dev, -1, urb->status);
503 outp = videobuf_to_vmalloc(&buf->vb);
504
505 if (!outp)
506 return 0;
507
508 size = buf->vb.size;
509
510 copied=0;
511
512 if (urb->status<0) {
513 print_err_status (dev,-1,urb->status);
514 return 0; 519 return 0;
515 } 520 }
516 521
517 for (i = 0; i < urb->number_of_packets; i++) { 522 for (i = 0; i < urb->number_of_packets; i++) {
518 int status = urb->iso_frame_desc[i].status; 523 status = urb->iso_frame_desc[i].status;
519 524
520 if (status<0) { 525 if (status<0) {
521 print_err_status (dev,i,status); 526 print_err_status (dev,i,status);
522 continue; 527 continue;
523 } 528 }
524 529
525 len=urb->iso_frame_desc[i].actual_length; 530 len = urb->iso_frame_desc[i].actual_length;
526 531
527// if (len>=TM6000_URB_MSG_LEN) { 532 if (len > 0) {
528 p=urb->transfer_buffer + urb->iso_frame_desc[i].offset; 533 p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
529 if (!urb->iso_frame_desc[i].status) { 534 if (!urb->iso_frame_desc[i].status) {
530 if ((buf->fmt->fourcc)==V4L2_PIX_FMT_TM6000) { 535 if ((dev->fourcc)==V4L2_PIX_FMT_TM6000) {
531 rc=copy_multiplexed(p, outp, len, urb, &buf); 536 rc=copy_multiplexed(p, len, urb);
532 if (rc<=0) 537 if (rc<=0)
533 return rc; 538 return rc;
534 } else { 539 } else {
535 copy_streams(p, outp, len, urb, &buf); 540 copy_streams(p, len, urb);
536 } 541 }
537 } 542 }
538 copied += len; 543 }
539 if (copied >= size || !buf)
540 break;
541// }
542 } 544 }
543 return rc; 545 return rc;
544} 546}