From cc6c60d912ceeb390a0969a7c76dc05fa3fffaa9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 19 Sep 2007 16:24:05 -0300 Subject: [PATCH] V4L/DVB (12799): tm6000: avoid troubles if a header is broken on separate URBs Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-usb-isoc.h | 3 ++ drivers/staging/tm6000/tm6000-video.c | 56 ++++++++++++++++++------ 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/drivers/staging/tm6000/tm6000-usb-isoc.h b/drivers/staging/tm6000/tm6000-usb-isoc.h index 27b103f939d9..83a4ed0d1bca 100644 --- a/drivers/staging/tm6000/tm6000-usb-isoc.h +++ b/drivers/staging/tm6000/tm6000-usb-isoc.h @@ -38,4 +38,7 @@ struct usb_isoc_ctl { /* Last field: ODD or EVEN? */ int field; + + u32 tmp_buf; + int tmp_buf_len; }; diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c index 44d455f2d315..372850c3e70b 100644 --- a/drivers/staging/tm6000/tm6000-video.c +++ b/drivers/staging/tm6000/tm6000-video.c @@ -212,7 +212,7 @@ static u8 *copy_packet (struct urb *urb, u32 header, u8 *data, u8 *endp, /* Validates header fields */ if(size>TM6000_URB_MSG_LEN) - size=TM6000_URB_MSG_LEN; + size = TM6000_URB_MSG_LEN; if(block>=8) cmd = TM6000_URB_MSG_ERR; @@ -220,8 +220,7 @@ static u8 *copy_packet (struct urb *urb, u32 header, u8 *data, u8 *endp, * It should, instead, check if the user selected * entrelaced or non-entrelaced mode */ - pos=((line<<1)+field)*linesize+ - block*TM6000_URB_MSG_LEN; + pos=((line<<1)+field)*linesize+block*TM6000_URB_MSG_LEN; /* Don't allow to write out of the buffer */ if (pos+TM6000_URB_MSG_LEN > (*buf)->vb.size) @@ -232,6 +231,7 @@ static u8 *copy_packet (struct urb *urb, u32 header, u8 *data, u8 *endp, " line=%d, field=%d\n", size, block, line, field); + pktsize = TM6000_URB_MSG_LEN; ///////////////////////////// /// nao seria size??? @@ -251,8 +251,9 @@ static u8 *copy_packet (struct urb *urb, u32 header, u8 *data, u8 *endp, switch(cmd) { case TM6000_URB_MSG_VIDEO: /* Fills video buffer */ - bufcpy(*buf,&out_p[pos],ptr,cpysize); - break; + if (__copy_to_user(&out_p[pos],ptr,cpysize)!=0) + tm6000_err("copy_to_user failed.\n"); + break; } } if (cpysizecontext; struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); u8 *ptr=data, *endp=data+len; - u32 header=0; + unsigned long header=0; int rc=0; for (ptr=data; ptrisoc_ctl.cmd) { + u8 *p=(u8 *)&dev->isoc_ctl.tmp_buf; + /* FIXME: This seems very complex + * It just recovers up to 3 bytes of the header that + * might be at the previous packet + */ + if (dev->isoc_ctl.tmp_buf_len) { + while (dev->isoc_ctl.tmp_buf_len) { + if ( *(ptr+3-dev->isoc_ctl.tmp_buf_len) == 0x47) { + break; + } + p++; + dev->isoc_ctl.tmp_buf_len--; + } + if (dev->isoc_ctl.tmp_buf_len) { + memcpy (&header,p, + dev->isoc_ctl.tmp_buf_len); + memcpy (((u8 *)header)+ + dev->isoc_ctl.tmp_buf, + ptr, + 4-dev->isoc_ctl.tmp_buf_len); + ptr+=4-dev->isoc_ctl.tmp_buf_len; + goto HEADER; + } + } /* Seek for sync */ - for (ptr+=3;ptr=endp) + + if (ptr+3>=endp) { + dev->isoc_ctl.tmp_buf_len=endp-ptr; + memcpy (&dev->isoc_ctl.tmp_buf,ptr, + dev->isoc_ctl.tmp_buf_len); + dev->isoc_ctl.cmd=0; return rc; + } /* Get message header */ header=*(unsigned long *)ptr; ptr+=4; } - +HEADER: /* Copy or continue last copy */ ptr=copy_packet(urb,header,ptr,endp,out_p,buf); } @@ -581,7 +610,8 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->isoc_ctl.transfer_buffer[i]) { tm6000_err ("unable to allocate %i bytes for transfer" - " buffer %i\n", sb_size, i); + " buffer %i, in int=%i\n", + sb_size, i, in_interrupt()); tm6000_uninit_isoc(dev); return -ENOMEM; } -- 2.39.5