tm6000: rewrite copy_streams

Message ID 1275319534-8616-1-git-send-email-stefan.ringel@arcor.de (mailing list archive)
State Superseded, archived
Headers

Commit Message

Stefan Ringel May 31, 2010, 3:25 p.m. UTC
  From: Stefan Ringel <stefan.ringel@arcor.de>

fusion function copy streams and copy_packets to new function copy_streams.


Signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
---
 drivers/staging/tm6000/tm6000-usb-isoc.h |    5 +-
 drivers/staging/tm6000/tm6000-video.c    |  335 +++++++++++-------------------
 2 files changed, 122 insertions(+), 218 deletions(-)
  

Comments

Mauro Carvalho Chehab May 31, 2010, 10:09 p.m. UTC | #1
Em 31-05-2010 12:25, stefan.ringel@arcor.de escreveu:
> From: Stefan Ringel <stefan.ringel@arcor.de>
> 
> fusion function copy streams and copy_packets to new function copy_streams.


There's something wrong with this patch:

$ patch -p1 -i /tmp/tm6000\:\ rewrite\ copy_streams.eml -l
(Stripping trailing CRs from patch.)
patching file drivers/staging/tm6000/tm6000-usb-isoc.h
(Stripping trailing CRs from patch.)
patching file drivers/staging/tm6000/tm6000-video.c
Hunk #1 FAILED at 186.
Hunk #2 FAILED at 439.
Hunk #3 FAILED at 451.
3 out of 6 hunks FAILED -- saving rejects to file drivers/staging/tm6000/tm6000-video.c.rej

Please rebase it against git branch "devel/for_v2.6.35" of my v4l-dvb.git tree.



> 
> 
> Signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
> ---
>  drivers/staging/tm6000/tm6000-usb-isoc.h |    5 +-
>  drivers/staging/tm6000/tm6000-video.c    |  335 +++++++++++-------------------
>  2 files changed, 122 insertions(+), 218 deletions(-)
> 
> diff --git a/drivers/staging/tm6000/tm6000-usb-isoc.h b/drivers/staging/tm6000/tm6000-usb-isoc.h
> index 5a5049a..138716a 100644
> --- a/drivers/staging/tm6000/tm6000-usb-isoc.h
> +++ b/drivers/staging/tm6000/tm6000-usb-isoc.h
> @@ -39,7 +39,7 @@ struct usb_isoc_ctl {
>  	int				pos, size, pktsize;
>  
>  		/* Last field: ODD or EVEN? */
> -	int				field;
> +	int				vfield;
>  
>  		/* Stores incomplete commands */
>  	u32				tmp_buf;
> @@ -47,7 +47,4 @@ struct usb_isoc_ctl {
>  
>  		/* Stores already requested buffers */
>  	struct tm6000_buffer    	*buf;
> -
> -		/* Stores the number of received fields */
> -	int				nfields;
>  };
> diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
> index 2a61cc3..9746fe7 100644
> --- a/drivers/staging/tm6000/tm6000-video.c
> +++ b/drivers/staging/tm6000/tm6000-video.c
> @@ -186,234 +186,145 @@ const char *tm6000_msg_type[] = {
>  /*
>   * Identify the tm5600/6000 buffer header type and properly handles
>   */
> -static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
> -			u8 *out_p, struct tm6000_buffer **buf)
> -{
> -	struct tm6000_dmaqueue  *dma_q = urb->context;
> -	struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
> -	u8 c;
> -	unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
> -	int rc = 0;
> -	/* FIXME: move to tm6000-isoc */
> -	static int last_line = -2, start_line = -2, last_field = -2;
> -
> -	/* FIXME: this is the hardcoded window size
> -	 */
> -	unsigned int linewidth = (*buf)->vb.width << 1;
> -
> -	if (!dev->isoc_ctl.cmd) {
> -		c = (header >> 24) & 0xff;
> -
> -		/* split the header fields */
> -		size  = ((header & 0x7e) << 1);
> -
> -		if (size > 0)
> -			size -= 4;
> -
> -		block = (header >> 7) & 0xf;
> -		field = (header >> 11) & 0x1;
> -		line  = (header >> 12) & 0x1ff;
> -		cmd   = (header >> 21) & 0x7;
> -
> -		/* Validates header fields */
> -		if(size > TM6000_URB_MSG_LEN)
> -			size = TM6000_URB_MSG_LEN;
> -
> -		if (cmd == TM6000_URB_MSG_VIDEO) {
> -			if ((block+1)*TM6000_URB_MSG_LEN>linewidth)
> -				cmd = TM6000_URB_MSG_ERR;
> -
> -			/* FIXME: Mounts the image as field0+field1
> -			 * It should, instead, check if the user selected
> -			 * entrelaced or non-entrelaced mode
> -			 */
> -			pos= ((line<<1)+field)*linewidth +
> -				block*TM6000_URB_MSG_LEN;
> -
> -			/* Don't allow to write out of the buffer */
> -			if (pos+TM6000_URB_MSG_LEN > (*buf)->vb.size) {
> -				dprintk(dev, V4L2_DEBUG_ISOC,
> -					"ERR: size=%d, num=%d, line=%d, "
> -					"field=%d\n",
> -					size, block, line, field);
> -
> -				cmd = TM6000_URB_MSG_ERR;
> -			}
> -		} else {
> -			pos=0;
> -		}
> -
> -		/* Prints debug info */
> -		dprintk(dev, V4L2_DEBUG_ISOC, "size=%d, num=%d, "
> -				" line=%d, field=%d\n",
> -				size, block, line, field);
> -
> -		if ((last_line!=line)&&(last_line+1!=line) &&
> -		    (cmd != TM6000_URB_MSG_ERR) )  {
> -			if (cmd != TM6000_URB_MSG_VIDEO)  {
> -				dprintk(dev, V4L2_DEBUG_ISOC,  "cmd=%d, "
> -					"size=%d, num=%d, line=%d, field=%d\n",
> -					cmd, size, block, line, field);
> -			}
> -			if (start_line<0)
> -				start_line=last_line;
> -			/* Prints debug info */
> -			dprintk(dev, V4L2_DEBUG_ISOC, "lines= %d-%d, "
> -					"field=%d\n",
> -					start_line, last_line, field);
> -
> -			if ((start_line<6 && last_line>200) &&
> -				(last_field != field) ) {
> -
> -				dev->isoc_ctl.nfields++;
> -				if (dev->isoc_ctl.nfields>=2) {
> -					dev->isoc_ctl.nfields=0;
> -
> -					/* Announces that a new buffer were filled */
> -					buffer_filled (dev, dma_q, *buf);
> -					dprintk(dev, V4L2_DEBUG_ISOC,
> -							"new buffer filled\n");
> -					get_next_buf (dma_q, buf);
> -					if (!*buf)
> -						return rc;
> -					out_p = videobuf_to_vmalloc(&((*buf)->vb));
> -					if (!out_p)
> -						return rc;
> -
> -					pos = dev->isoc_ctl.pos = 0;
> -				}
> -			}
> -
> -			start_line=line;
> -			last_field=field;
> -		}
> -		if (cmd == TM6000_URB_MSG_VIDEO)
> -			last_line = line;
> -
> -		pktsize = TM6000_URB_MSG_LEN;
> -	} else {
> -		/* Continue the last copy */
> -		cmd = dev->isoc_ctl.cmd;
> -		size= dev->isoc_ctl.size;
> -		pos = dev->isoc_ctl.pos;
> -		pktsize = dev->isoc_ctl.pktsize;
> -	}
> -
> -	cpysize = (endp-(*ptr) > size) ? size : endp - *ptr;
> -
> -	if (cpysize) {
> -		/* handles each different URB message */
> -		switch(cmd) {
> -		case TM6000_URB_MSG_VIDEO:
> -			/* Fills video buffer */
> -			memcpy(&out_p[pos], *ptr, cpysize);
> -			break;
> -		case TM6000_URB_MSG_PTS:
> -			break;
> -		case TM6000_URB_MSG_AUDIO:
> -			/* Need some code to process audio */
> -			printk ("%ld: cmd=%s, size=%d\n", jiffies,
> -				tm6000_msg_type[cmd],size);
> -			break;
> -		case TM6000_URB_MSG_VBI:
> -			break;
> -		default:
> -			dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n",
> -						tm6000_msg_type[cmd],size);
> -		}
> -	}
> -	if (cpysize<size) {
> -		/* End of URB packet, but cmd processing is not
> -		 * complete. Preserve the state for a next packet
> -		 */
> -		dev->isoc_ctl.pos = pos+cpysize;
> -		dev->isoc_ctl.size= size-cpysize;
> -		dev->isoc_ctl.cmd = cmd;
> -		dev->isoc_ctl.pktsize = pktsize-cpysize;
> -		(*ptr)+=cpysize;
> -	} else {
> -		dev->isoc_ctl.cmd = 0;
> -		(*ptr)+=pktsize;
> -	}
> -
> -	return rc;
> -}
> -
>  static int copy_streams(u8 *data, unsigned long len,
>  			struct urb *urb)
>  {
>  	struct tm6000_dmaqueue  *dma_q = urb->context;
>  	struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
> -	u8 *ptr=data, *endp=data+len;
> +	u8 *ptr=data, *endp=data+len, c;
>  	unsigned long header=0;
>  	int rc=0;
> -	struct tm6000_buffer *buf;
> -	char *outp = NULL;
> -
> -	get_next_buf(dma_q, &buf);
> -	if (buf)
> -		outp = videobuf_to_vmalloc(&buf->vb);
> +	unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
> +	struct tm6000_buffer *vbuf;
> +	char *voutp = NULL;
> +	unsigned int linewidth;
>  
> -	if (!outp)
> +	/* get video buffer */
> +	get_next_buf (dma_q, &vbuf);
> +	if (!vbuf)
> +		return rc;
> +	voutp = videobuf_to_vmalloc(&vbuf->vb);
> +	if (!voutp)
>  		return 0;
>  
> -	for (ptr=data; ptr<endp;) {
> +	for (ptr = data; ptr < endp;) {
>  		if (!dev->isoc_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 +
> +			/* Header */
> +			if (dev->isoc_ctl.tmp_buf_len > 0) {
> +				/* from last urb or packet */
> +				header = dev->isoc_ctl.tmp_buf;
> +				if (4 - dev->isoc_ctl.tmp_buf_len > 0) {
> +					memcpy ((u8 *)&header +
>  						dev->isoc_ctl.tmp_buf_len,
>  						ptr,
>  						4 - dev->isoc_ctl.tmp_buf_len);
>  					ptr += 4 - dev->isoc_ctl.tmp_buf_len;
> -					goto HEADER;
>  				}
> +				dev->isoc_ctl.tmp_buf_len = 0;
> +			} else {
> +				if (ptr + 3 >= endp) {
> +					/* have incomplete header */
> +					dev->isoc_ctl.tmp_buf_len = endp - ptr;
> +					memcpy (&dev->isoc_ctl.tmp_buf, ptr,
> +						dev->isoc_ctl.tmp_buf_len);
> +					return rc;
> +				}
> +				/* Seek for sync */
> +				for (; ptr < endp - 3; ptr++) {
> +					if (*(ptr + 3) == 0x47)
> +						break;
> +				}
> +				/* Get message header */
> +				header = *(unsigned long *)ptr;
> +				ptr += 4;
>  			}
> -			/* Seek for sync */
> -			for (;ptr<endp-3;ptr++) {
> -				if (*(ptr+3)==0x47)
> -					break;
> +			/* split the header fields */
> +			c = (header >> 24) & 0xff;
> +			size = ((header & 0x7e) << 1);
> +			if (size > 0)
> +				size -= 4;
> +			block = (header >> 7) & 0xf;
> +			field = (header >> 11) & 0x1;
> +			line  = (header >> 12) & 0x1ff;
> +			cmd   = (header >> 21) & 0x7;
> +			/* Validates haeder fields */
> +			if (size > TM6000_URB_MSG_LEN)
> +				size = TM6000_URB_MSG_LEN;
> +			pktsize = TM6000_URB_MSG_LEN;
> +			/* calculate position in buffer 
> +			 * and change the buffer
> +			 */
> +			switch (cmd) {
> +			case TM6000_URB_MSG_VIDEO:
> +				if ((dev->isoc_ctl.vfield != field) && 
> +					(field == 1)) {
> +					/* Announces that a new buffer 
> +					 * were filled 
> +					 */
> +					buffer_filled (dev, dma_q, vbuf);
> +					dprintk (dev, V4L2_DEBUG_ISOC,
> +							"new buffer filled\n");
> +					get_next_buf (dma_q, &vbuf);
> +					if (!vbuf)
> +						return rc;
> +					voutp = videobuf_to_vmalloc (&vbuf->vb);
> +					if (!voutp)
> +						return rc;
> +				}
> +				linewidth = vbuf->vb.width << 1;
> +				pos = ((line << 1) - field - 1) * linewidth +
> +					block * TM6000_URB_MSG_LEN;
> +				/* Don't allow to write out of the buffer */
> +				if (pos + size > vbuf->vb.size)
> +					cmd = TM6000_URB_MSG_ERR;
> +				dev->isoc_ctl.vfield = field;
> +				break;
> +			case TM6000_URB_MSG_AUDIO:
> +			case TM6000_URB_MSG_VBI:
> +			case TM6000_URB_MSG_PTS:
> +				break;
>  			}
> -
> -			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;
> +		} else {
> +			/* Continue the last copy */
> +			cmd = dev->isoc_ctl.cmd;
> +			size = dev->isoc_ctl.size;
> +			pos = dev->isoc_ctl.pos;
> +			pktsize = dev->isoc_ctl.pktsize;
> +		}
> +		cpysize = (endp - ptr > size) ? size : endp - ptr;
> +		if (cpysize) {
> +			/* copy data in different buffers */
> +			switch (cmd) {
> +			case TM6000_URB_MSG_VIDEO:
> +				/* Fills video buffer */
> +				if (vbuf)
> +					memcpy (&voutp[pos], ptr, cpysize);
> +				break;
> +			case TM6000_URB_MSG_AUDIO:
> +				/* Need some code to copy audio buffer */
> +				break;
> +			case TM6000_URB_MSG_VBI:
> +				/* Need some code to copy vbi buffer */
> +				break;
> +			case TM6000_URB_MSG_PTS:
> +				/* Need some code to copy pts */
> +				break;
>  			}
> -
> -			/* Get message header */
> -			header=*(unsigned long *)ptr;
> -			ptr+=4;
>  		}
> -HEADER:
> -		/* Copy or continue last copy */
> -		rc=copy_packet(urb,header,&ptr,endp,outp,&buf);
> -		if (rc<0) {
> -			buf=NULL;
> -			printk(KERN_ERR "tm6000: buffer underrun at %ld\n",
> -					jiffies);
> -			return rc;
> +		if (ptr + pktsize > endp) {
> +			/* End of URB packet, but cmd processing is not
> +			 * complete. Preserve the state for a next packet
> +			 */
> +			dev->isoc_ctl.pos = pos + cpysize;
> +			dev->isoc_ctl.size = size - cpysize;
> +			dev->isoc_ctl.cmd = cmd;
> +			dev->isoc_ctl.pktsize = pktsize - (endp - ptr);
> +			ptr += endp - ptr;
> +		} else {
> +			dev->isoc_ctl.cmd = 0;
> +			ptr += pktsize;
>  		}
> -		if (!*buf)
> -			return 0;
>  	}
> -
>  	return 0;
>  }
>  /*
> @@ -439,7 +350,7 @@ static int copy_multiplexed(u8 *ptr, unsigned long len,
>  	while (len>0) {
>  		cpysize=min(len,buf->vb.size-pos);
>  		//printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos);
> -		memcpy(&out_p[pos], ptr, cpysize);
> +		memcpy(&outp[pos], ptr, cpysize);
>  		pos+=cpysize;
>  		ptr+=cpysize;
>  		len-=cpysize;
> @@ -451,8 +362,8 @@ static int copy_multiplexed(u8 *ptr, unsigned long len,
>  			get_next_buf (dma_q, &buf);
>  			if (!buf)
>  				break;
> -			out_p = videobuf_to_vmalloc(&(buf->vb));
> -			if (!out_p)
> +			outp = videobuf_to_vmalloc(&(buf->vb));
> +			if (!outp)
>  				return rc;
>  			pos = 0;
>  		}
> @@ -510,7 +421,6 @@ static inline int tm6000_isoc_copy(struct urb *urb)
>  {
>  	struct tm6000_dmaqueue  *dma_q = urb->context;
>  	struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
> -	struct tm6000_buffer *buf;
>  	int i, len=0, rc=1, status;
>  	char *p;
>  
> @@ -585,7 +495,6 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
>  	struct urb *urb;
>  	int i;
>  
> -	dev->isoc_ctl.nfields = -1;
>  	dev->isoc_ctl.buf = NULL;
>  	for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
>  		urb=dev->isoc_ctl.urb[i];
> @@ -610,8 +519,6 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
>  	dev->isoc_ctl.urb=NULL;
>  	dev->isoc_ctl.transfer_buffer=NULL;
>  	dev->isoc_ctl.num_bufs = 0;
> -
> -	dev->isoc_ctl.num_bufs=0;
>  }
>  
>  /*

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  
Stefan Ringel June 1, 2010, 4:04 a.m. UTC | #2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
 
Am 01.06.2010 00:09, schrieb Mauro Carvalho Chehab:
> Em 31-05-2010 12:25, stefan.ringel@arcor.de escreveu:
>> From: Stefan Ringel <stefan.ringel@arcor.de>
>>
>> fusion function copy streams and copy_packets to new function
copy_streams.
>
>
> There's something wrong with this patch:
>
> $ patch -p1 -i /tmp/tm6000\:\ rewrite\ copy_streams.eml -l
> (Stripping trailing CRs from patch.)
> patching file drivers/staging/tm6000/tm6000-usb-isoc.h
> (Stripping trailing CRs from patch.)
> patching file drivers/staging/tm6000/tm6000-video.c
> Hunk #1 FAILED at 186.
> Hunk #2 FAILED at 439.
> Hunk #3 FAILED at 451.
> 3 out of 6 hunks FAILED -- saving rejects to file
drivers/staging/tm6000/tm6000-video.c.rej
>
> Please rebase it against git branch "devel/for_v2.6.35" of my
v4l-dvb.git tree.
>
Thanks, I rebase it and send it new today.
>
>
>>
>>  static int copy_streams(u8 *data, unsigned long len,
>>              struct urb *urb)
>>  {
>>      struct tm6000_dmaqueue  *dma_q = urb->context;
>>      struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
>> -    u8 *ptr=data, *endp=data+len;
>> +    u8 *ptr=data, *endp=data+len, c;
>>      unsigned long header=0;
>>      int rc=0;
>> -    struct tm6000_buffer *buf;
>> -    char *outp = NULL;
>> -
>> -    get_next_buf(dma_q, &buf);
>> -    if (buf)
>> -        outp = videobuf_to_vmalloc(&buf->vb);
>> +    unsigned int cmd, cpysize, pktsize, size, field, block, line, pos
= 0;
>> +    struct tm6000_buffer *vbuf;
>> +    char *voutp = NULL;
>> +    unsigned int linewidth;
>> 
>> -    if (!outp)
>> +    /* get video buffer */
>> +    get_next_buf (dma_q, &vbuf);
>> +    if (!vbuf)
>> +        return rc;
>> +    voutp = videobuf_to_vmalloc(&vbuf->vb);
>> +    if (!voutp)
>>          return 0;
>> 
>> -    for (ptr=data; ptr<endp;) {
>> +    for (ptr = data; ptr < endp;) {
>>          if (!dev->isoc_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 +
>> +            /* Header */
>> +            if (dev->isoc_ctl.tmp_buf_len > 0) {
>> +                /* from last urb or packet */
>> +                header = dev->isoc_ctl.tmp_buf;
>> +                if (4 - dev->isoc_ctl.tmp_buf_len > 0) {
>> +                    memcpy ((u8 *)&header +
>>                          dev->isoc_ctl.tmp_buf_len,
>>                          ptr,
>>                          4 - dev->isoc_ctl.tmp_buf_len);
>>                      ptr += 4 - dev->isoc_ctl.tmp_buf_len;
>> -                    goto HEADER;
>>                  }
>> +                dev->isoc_ctl.tmp_buf_len = 0;
>> +            } else {
>> +                if (ptr + 3 >= endp) {
>> +                    /* have incomplete header */
>> +                    dev->isoc_ctl.tmp_buf_len = endp - ptr;
>> +                    memcpy (&dev->isoc_ctl.tmp_buf, ptr,
>> +                        dev->isoc_ctl.tmp_buf_len);
>> +                    return rc;
>> +                }
>> +                /* Seek for sync */
>> +                for (; ptr < endp - 3; ptr++) {
>> +                    if (*(ptr + 3) == 0x47)
>> +                        break;
>> +                }
>> +                /* Get message header */
>> +                header = *(unsigned long *)ptr;
>> +                ptr += 4;
>>              }
>> -            /* Seek for sync */
>> -            for (;ptr<endp-3;ptr++) {
>> -                if (*(ptr+3)==0x47)
>> -                    break;
>> +            /* split the header fields */
>> +            c = (header >> 24) & 0xff;
>> +            size = ((header & 0x7e) << 1);
>> +            if (size > 0)
>> +                size -= 4;
>> +            block = (header >> 7) & 0xf;
>> +            field = (header >> 11) & 0x1;
>> +            line  = (header >> 12) & 0x1ff;
>> +            cmd   = (header >> 21) & 0x7;
>> +            /* Validates haeder fields */
>> +            if (size > TM6000_URB_MSG_LEN)
>> +                size = TM6000_URB_MSG_LEN;
>> +            pktsize = TM6000_URB_MSG_LEN;
>> +            /* calculate position in buffer
>> +             * and change the buffer
>> +             */
>> +            switch (cmd) {
>> +            case TM6000_URB_MSG_VIDEO:
>> +                if ((dev->isoc_ctl.vfield != field) &&
>> +                    (field == 1)) {
>> +                    /* Announces that a new buffer
>> +                     * were filled
>> +                     */
>> +                    buffer_filled (dev, dma_q, vbuf);
>> +                    dprintk (dev, V4L2_DEBUG_ISOC,
>> +                            "new buffer filled\n");
>> +                    get_next_buf (dma_q, &vbuf);
>> +                    if (!vbuf)
>> +                        return rc;
>> +                    voutp = videobuf_to_vmalloc (&vbuf->vb);
>> +                    if (!voutp)
>> +                        return rc;
>> +                }
>> +                linewidth = vbuf->vb.width << 1;
>> +                pos = ((line << 1) - field - 1) * linewidth +
>> +                    block * TM6000_URB_MSG_LEN;
>> +                /* Don't allow to write out of the buffer */
>> +                if (pos + size > vbuf->vb.size)
>> +                    cmd = TM6000_URB_MSG_ERR;
>> +                dev->isoc_ctl.vfield = field;
>> +                break;
>> +            case TM6000_URB_MSG_AUDIO:
>> +            case TM6000_URB_MSG_VBI:
>> +            case TM6000_URB_MSG_PTS:
>> +                break;
>>              }
>> -
>> -            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;
>> +        } else {
>> +            /* Continue the last copy */
>> +            cmd = dev->isoc_ctl.cmd;
>> +            size = dev->isoc_ctl.size;
>> +            pos = dev->isoc_ctl.pos;
>> +            pktsize = dev->isoc_ctl.pktsize;
>> +        }
>> +        cpysize = (endp - ptr > size) ? size : endp - ptr;
>> +        if (cpysize) {
>> +            /* copy data in different buffers */
>> +            switch (cmd) {
>> +            case TM6000_URB_MSG_VIDEO:
>> +                /* Fills video buffer */
>> +                if (vbuf)
>> +                    memcpy (&voutp[pos], ptr, cpysize);
>> +                break;
>> +            case TM6000_URB_MSG_AUDIO:
>> +                /* Need some code to copy audio buffer */
>> +                break;
>> +            case TM6000_URB_MSG_VBI:
>> +                /* Need some code to copy vbi buffer */
>> +                break;
>> +            case TM6000_URB_MSG_PTS:
>> +                /* Need some code to copy pts */
>> +                break;
>>              }
>> -
>> -            /* Get message header */
>> -            header=*(unsigned long *)ptr;
>> -            ptr+=4;
>>          }
>> -HEADER:
>> -        /* Copy or continue last copy */
>> -        rc=copy_packet(urb,header,&ptr,endp,outp,&buf);
>> -        if (rc<0) {
>> -            buf=NULL;
>> -            printk(KERN_ERR "tm6000: buffer underrun at %ld\n",
>> -                    jiffies);
>> -            return rc;
>> +        if (ptr + pktsize > endp) {
>> +            /* End of URB packet, but cmd processing is not
>> +             * complete. Preserve the state for a next packet
>> +             */
>> +            dev->isoc_ctl.pos = pos + cpysize;
>> +            dev->isoc_ctl.size = size - cpysize;
>> +            dev->isoc_ctl.cmd = cmd;
>> +            dev->isoc_ctl.pktsize = pktsize - (endp - ptr);
>> +            ptr += endp - ptr;
>> +        } else {
>> +            dev->isoc_ctl.cmd = 0;
>> +            ptr += pktsize;
>>          }
>> -        if (!*buf)
>> -            return 0;
>>      }
>> -
>>      return 0;
>>  }
>>  /*
>> @@ -439,7 +350,7 @@ static int copy_multiplexed(u8 *ptr, unsigned long
len,
>>      while (len>0) {
>>          cpysize=min(len,buf->vb.size-pos);
>>          //printk("Copying %d bytes (max=%lu) from %p to
%p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos);
>> -        memcpy(&out_p[pos], ptr, cpysize);
>> +        memcpy(&outp[pos], ptr, cpysize);
>>          pos+=cpysize;
>>          ptr+=cpysize;
>>          len-=cpysize;
>> @@ -451,8 +362,8 @@ static int copy_multiplexed(u8 *ptr, unsigned long
len,
>>              get_next_buf (dma_q, &buf);
>>              if (!buf)
>>                  break;
>> -            out_p = videobuf_to_vmalloc(&(buf->vb));
>> -            if (!out_p)
>> +            outp = videobuf_to_vmalloc(&(buf->vb));
>> +            if (!outp)
>>                  return rc;
>>              pos = 0;
>>          }
>> @@ -510,7 +421,6 @@ static inline int tm6000_isoc_copy(struct urb *urb)
>>  {
>>      struct tm6000_dmaqueue  *dma_q = urb->context;
>>      struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
>> -    struct tm6000_buffer *buf;
>>      int i, len=0, rc=1, status;
>>      char *p;
>> 
>> @@ -585,7 +495,6 @@ static void tm6000_uninit_isoc(struct tm6000_core
*dev)
>>      struct urb *urb;
>>      int i;
>> 
>> -    dev->isoc_ctl.nfields = -1;
>>      dev->isoc_ctl.buf = NULL;
>>      for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
>>          urb=dev->isoc_ctl.urb[i];
>> @@ -610,8 +519,6 @@ static void tm6000_uninit_isoc(struct tm6000_core
*dev)
>>      dev->isoc_ctl.urb=NULL;
>>      dev->isoc_ctl.transfer_buffer=NULL;
>>      dev->isoc_ctl.num_bufs = 0;
>> -
>> -    dev->isoc_ctl.num_bufs=0;
>>  }
>> 
>>  /*
>

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.12 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
 
iQEcBAEBAgAGBQJMBIa/AAoJEAWtPFjxMvFGCCkH/279v1htNxN02qmI3epHiPg7
SqBxo6n+GdKe6tb/UfgypRroKqiYUxXSY03zusTtOi9CmwbZ03KixNlT82VQlYul
x5pMu2uTgkGpUGPzgBR0Bw018eenWe6GDNcC0FSaLi6sWyBS+BBjUt7AUmdEYfPw
C2YwO1KGb/VEeZxfwzc4oWkLEfipoipTmfyC9jYgv8Cc/iBE4inG88jE9rASeyDF
70IbWpI53ez7zyt7zkZaQCfZ1gjxOfaUggS2ty+A16kHA4QF5rKMQl05oj/wUDl6
TUZcwuoQ9gZr8fyXIHTcvAD1Ir0Sas9F5dR+H9rHHkets+YTFpg7pvqBLGuP1GA=
=JIaH
-----END PGP SIGNATURE-----

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  

Patch

diff --git a/drivers/staging/tm6000/tm6000-usb-isoc.h b/drivers/staging/tm6000/tm6000-usb-isoc.h
index 5a5049a..138716a 100644
--- a/drivers/staging/tm6000/tm6000-usb-isoc.h
+++ b/drivers/staging/tm6000/tm6000-usb-isoc.h
@@ -39,7 +39,7 @@  struct usb_isoc_ctl {
 	int				pos, size, pktsize;
 
 		/* Last field: ODD or EVEN? */
-	int				field;
+	int				vfield;
 
 		/* Stores incomplete commands */
 	u32				tmp_buf;
@@ -47,7 +47,4 @@  struct usb_isoc_ctl {
 
 		/* Stores already requested buffers */
 	struct tm6000_buffer    	*buf;
-
-		/* Stores the number of received fields */
-	int				nfields;
 };
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 2a61cc3..9746fe7 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -186,234 +186,145 @@  const char *tm6000_msg_type[] = {
 /*
  * Identify the tm5600/6000 buffer header type and properly handles
  */
-static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
-			u8 *out_p, struct tm6000_buffer **buf)
-{
-	struct tm6000_dmaqueue  *dma_q = urb->context;
-	struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
-	u8 c;
-	unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
-	int rc = 0;
-	/* FIXME: move to tm6000-isoc */
-	static int last_line = -2, start_line = -2, last_field = -2;
-
-	/* FIXME: this is the hardcoded window size
-	 */
-	unsigned int linewidth = (*buf)->vb.width << 1;
-
-	if (!dev->isoc_ctl.cmd) {
-		c = (header >> 24) & 0xff;
-
-		/* split the header fields */
-		size  = ((header & 0x7e) << 1);
-
-		if (size > 0)
-			size -= 4;
-
-		block = (header >> 7) & 0xf;
-		field = (header >> 11) & 0x1;
-		line  = (header >> 12) & 0x1ff;
-		cmd   = (header >> 21) & 0x7;
-
-		/* Validates header fields */
-		if(size > TM6000_URB_MSG_LEN)
-			size = TM6000_URB_MSG_LEN;
-
-		if (cmd == TM6000_URB_MSG_VIDEO) {
-			if ((block+1)*TM6000_URB_MSG_LEN>linewidth)
-				cmd = TM6000_URB_MSG_ERR;
-
-			/* FIXME: Mounts the image as field0+field1
-			 * It should, instead, check if the user selected
-			 * entrelaced or non-entrelaced mode
-			 */
-			pos= ((line<<1)+field)*linewidth +
-				block*TM6000_URB_MSG_LEN;
-
-			/* Don't allow to write out of the buffer */
-			if (pos+TM6000_URB_MSG_LEN > (*buf)->vb.size) {
-				dprintk(dev, V4L2_DEBUG_ISOC,
-					"ERR: size=%d, num=%d, line=%d, "
-					"field=%d\n",
-					size, block, line, field);
-
-				cmd = TM6000_URB_MSG_ERR;
-			}
-		} else {
-			pos=0;
-		}
-
-		/* Prints debug info */
-		dprintk(dev, V4L2_DEBUG_ISOC, "size=%d, num=%d, "
-				" line=%d, field=%d\n",
-				size, block, line, field);
-
-		if ((last_line!=line)&&(last_line+1!=line) &&
-		    (cmd != TM6000_URB_MSG_ERR) )  {
-			if (cmd != TM6000_URB_MSG_VIDEO)  {
-				dprintk(dev, V4L2_DEBUG_ISOC,  "cmd=%d, "
-					"size=%d, num=%d, line=%d, field=%d\n",
-					cmd, size, block, line, field);
-			}
-			if (start_line<0)
-				start_line=last_line;
-			/* Prints debug info */
-			dprintk(dev, V4L2_DEBUG_ISOC, "lines= %d-%d, "
-					"field=%d\n",
-					start_line, last_line, field);
-
-			if ((start_line<6 && last_line>200) &&
-				(last_field != field) ) {
-
-				dev->isoc_ctl.nfields++;
-				if (dev->isoc_ctl.nfields>=2) {
-					dev->isoc_ctl.nfields=0;
-
-					/* Announces that a new buffer were filled */
-					buffer_filled (dev, dma_q, *buf);
-					dprintk(dev, V4L2_DEBUG_ISOC,
-							"new buffer filled\n");
-					get_next_buf (dma_q, buf);
-					if (!*buf)
-						return rc;
-					out_p = videobuf_to_vmalloc(&((*buf)->vb));
-					if (!out_p)
-						return rc;
-
-					pos = dev->isoc_ctl.pos = 0;
-				}
-			}
-
-			start_line=line;
-			last_field=field;
-		}
-		if (cmd == TM6000_URB_MSG_VIDEO)
-			last_line = line;
-
-		pktsize = TM6000_URB_MSG_LEN;
-	} else {
-		/* Continue the last copy */
-		cmd = dev->isoc_ctl.cmd;
-		size= dev->isoc_ctl.size;
-		pos = dev->isoc_ctl.pos;
-		pktsize = dev->isoc_ctl.pktsize;
-	}
-
-	cpysize = (endp-(*ptr) > size) ? size : endp - *ptr;
-
-	if (cpysize) {
-		/* handles each different URB message */
-		switch(cmd) {
-		case TM6000_URB_MSG_VIDEO:
-			/* Fills video buffer */
-			memcpy(&out_p[pos], *ptr, cpysize);
-			break;
-		case TM6000_URB_MSG_PTS:
-			break;
-		case TM6000_URB_MSG_AUDIO:
-			/* Need some code to process audio */
-			printk ("%ld: cmd=%s, size=%d\n", jiffies,
-				tm6000_msg_type[cmd],size);
-			break;
-		case TM6000_URB_MSG_VBI:
-			break;
-		default:
-			dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n",
-						tm6000_msg_type[cmd],size);
-		}
-	}
-	if (cpysize<size) {
-		/* End of URB packet, but cmd processing is not
-		 * complete. Preserve the state for a next packet
-		 */
-		dev->isoc_ctl.pos = pos+cpysize;
-		dev->isoc_ctl.size= size-cpysize;
-		dev->isoc_ctl.cmd = cmd;
-		dev->isoc_ctl.pktsize = pktsize-cpysize;
-		(*ptr)+=cpysize;
-	} else {
-		dev->isoc_ctl.cmd = 0;
-		(*ptr)+=pktsize;
-	}
-
-	return rc;
-}
-
 static int copy_streams(u8 *data, unsigned long len,
 			struct urb *urb)
 {
 	struct tm6000_dmaqueue  *dma_q = urb->context;
 	struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
-	u8 *ptr=data, *endp=data+len;
+	u8 *ptr=data, *endp=data+len, c;
 	unsigned long header=0;
 	int rc=0;
-	struct tm6000_buffer *buf;
-	char *outp = NULL;
-
-	get_next_buf(dma_q, &buf);
-	if (buf)
-		outp = videobuf_to_vmalloc(&buf->vb);
+	unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
+	struct tm6000_buffer *vbuf;
+	char *voutp = NULL;
+	unsigned int linewidth;
 
-	if (!outp)
+	/* get video buffer */
+	get_next_buf (dma_q, &vbuf);
+	if (!vbuf)
+		return rc;
+	voutp = videobuf_to_vmalloc(&vbuf->vb);
+	if (!voutp)
 		return 0;
 
-	for (ptr=data; ptr<endp;) {
+	for (ptr = data; ptr < endp;) {
 		if (!dev->isoc_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 +
+			/* Header */
+			if (dev->isoc_ctl.tmp_buf_len > 0) {
+				/* from last urb or packet */
+				header = dev->isoc_ctl.tmp_buf;
+				if (4 - dev->isoc_ctl.tmp_buf_len > 0) {
+					memcpy ((u8 *)&header +
 						dev->isoc_ctl.tmp_buf_len,
 						ptr,
 						4 - dev->isoc_ctl.tmp_buf_len);
 					ptr += 4 - dev->isoc_ctl.tmp_buf_len;
-					goto HEADER;
 				}
+				dev->isoc_ctl.tmp_buf_len = 0;
+			} else {
+				if (ptr + 3 >= endp) {
+					/* have incomplete header */
+					dev->isoc_ctl.tmp_buf_len = endp - ptr;
+					memcpy (&dev->isoc_ctl.tmp_buf, ptr,
+						dev->isoc_ctl.tmp_buf_len);
+					return rc;
+				}
+				/* Seek for sync */
+				for (; ptr < endp - 3; ptr++) {
+					if (*(ptr + 3) == 0x47)
+						break;
+				}
+				/* Get message header */
+				header = *(unsigned long *)ptr;
+				ptr += 4;
 			}
-			/* Seek for sync */
-			for (;ptr<endp-3;ptr++) {
-				if (*(ptr+3)==0x47)
-					break;
+			/* split the header fields */
+			c = (header >> 24) & 0xff;
+			size = ((header & 0x7e) << 1);
+			if (size > 0)
+				size -= 4;
+			block = (header >> 7) & 0xf;
+			field = (header >> 11) & 0x1;
+			line  = (header >> 12) & 0x1ff;
+			cmd   = (header >> 21) & 0x7;
+			/* Validates haeder fields */
+			if (size > TM6000_URB_MSG_LEN)
+				size = TM6000_URB_MSG_LEN;
+			pktsize = TM6000_URB_MSG_LEN;
+			/* calculate position in buffer 
+			 * and change the buffer
+			 */
+			switch (cmd) {
+			case TM6000_URB_MSG_VIDEO:
+				if ((dev->isoc_ctl.vfield != field) && 
+					(field == 1)) {
+					/* Announces that a new buffer 
+					 * were filled 
+					 */
+					buffer_filled (dev, dma_q, vbuf);
+					dprintk (dev, V4L2_DEBUG_ISOC,
+							"new buffer filled\n");
+					get_next_buf (dma_q, &vbuf);
+					if (!vbuf)
+						return rc;
+					voutp = videobuf_to_vmalloc (&vbuf->vb);
+					if (!voutp)
+						return rc;
+				}
+				linewidth = vbuf->vb.width << 1;
+				pos = ((line << 1) - field - 1) * linewidth +
+					block * TM6000_URB_MSG_LEN;
+				/* Don't allow to write out of the buffer */
+				if (pos + size > vbuf->vb.size)
+					cmd = TM6000_URB_MSG_ERR;
+				dev->isoc_ctl.vfield = field;
+				break;
+			case TM6000_URB_MSG_AUDIO:
+			case TM6000_URB_MSG_VBI:
+			case TM6000_URB_MSG_PTS:
+				break;
 			}
-
-			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;
+		} else {
+			/* Continue the last copy */
+			cmd = dev->isoc_ctl.cmd;
+			size = dev->isoc_ctl.size;
+			pos = dev->isoc_ctl.pos;
+			pktsize = dev->isoc_ctl.pktsize;
+		}
+		cpysize = (endp - ptr > size) ? size : endp - ptr;
+		if (cpysize) {
+			/* copy data in different buffers */
+			switch (cmd) {
+			case TM6000_URB_MSG_VIDEO:
+				/* Fills video buffer */
+				if (vbuf)
+					memcpy (&voutp[pos], ptr, cpysize);
+				break;
+			case TM6000_URB_MSG_AUDIO:
+				/* Need some code to copy audio buffer */
+				break;
+			case TM6000_URB_MSG_VBI:
+				/* Need some code to copy vbi buffer */
+				break;
+			case TM6000_URB_MSG_PTS:
+				/* Need some code to copy pts */
+				break;
 			}
-
-			/* Get message header */
-			header=*(unsigned long *)ptr;
-			ptr+=4;
 		}
-HEADER:
-		/* Copy or continue last copy */
-		rc=copy_packet(urb,header,&ptr,endp,outp,&buf);
-		if (rc<0) {
-			buf=NULL;
-			printk(KERN_ERR "tm6000: buffer underrun at %ld\n",
-					jiffies);
-			return rc;
+		if (ptr + pktsize > endp) {
+			/* End of URB packet, but cmd processing is not
+			 * complete. Preserve the state for a next packet
+			 */
+			dev->isoc_ctl.pos = pos + cpysize;
+			dev->isoc_ctl.size = size - cpysize;
+			dev->isoc_ctl.cmd = cmd;
+			dev->isoc_ctl.pktsize = pktsize - (endp - ptr);
+			ptr += endp - ptr;
+		} else {
+			dev->isoc_ctl.cmd = 0;
+			ptr += pktsize;
 		}
-		if (!*buf)
-			return 0;
 	}
-
 	return 0;
 }
 /*
@@ -439,7 +350,7 @@  static int copy_multiplexed(u8 *ptr, unsigned long len,
 	while (len>0) {
 		cpysize=min(len,buf->vb.size-pos);
 		//printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos);
-		memcpy(&out_p[pos], ptr, cpysize);
+		memcpy(&outp[pos], ptr, cpysize);
 		pos+=cpysize;
 		ptr+=cpysize;
 		len-=cpysize;
@@ -451,8 +362,8 @@  static int copy_multiplexed(u8 *ptr, unsigned long len,
 			get_next_buf (dma_q, &buf);
 			if (!buf)
 				break;
-			out_p = videobuf_to_vmalloc(&(buf->vb));
-			if (!out_p)
+			outp = videobuf_to_vmalloc(&(buf->vb));
+			if (!outp)
 				return rc;
 			pos = 0;
 		}
@@ -510,7 +421,6 @@  static inline int tm6000_isoc_copy(struct urb *urb)
 {
 	struct tm6000_dmaqueue  *dma_q = urb->context;
 	struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
-	struct tm6000_buffer *buf;
 	int i, len=0, rc=1, status;
 	char *p;
 
@@ -585,7 +495,6 @@  static void tm6000_uninit_isoc(struct tm6000_core *dev)
 	struct urb *urb;
 	int i;
 
-	dev->isoc_ctl.nfields = -1;
 	dev->isoc_ctl.buf = NULL;
 	for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
 		urb=dev->isoc_ctl.urb[i];
@@ -610,8 +519,6 @@  static void tm6000_uninit_isoc(struct tm6000_core *dev)
 	dev->isoc_ctl.urb=NULL;
 	dev->isoc_ctl.transfer_buffer=NULL;
 	dev->isoc_ctl.num_bufs = 0;
-
-	dev->isoc_ctl.num_bufs=0;
 }
 
 /*