summaryrefslogtreecommitdiff
path: root/linux/drivers/staging
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-01-09 19:12:39 -0200
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-01-09 19:12:39 -0200
commit9c6ab876f808fd366f2946fe99e4d41019e41884 (patch)
tree05740bb6eeb7df57f7a31f612852853732fd3dc6 /linux/drivers/staging
parent6e36bcd7dca87490799165821dd3f00233fcf86a (diff)
downloadmediapointer-dvb-s2-9c6ab876f808fd366f2946fe99e4d41019e41884.tar.gz
mediapointer-dvb-s2-9c6ab876f808fd366f2946fe99e4d41019e41884.tar.bz2
tm6000: fix image hangs
From: Mauro Carvalho Chehab <mchehab@redhat.com> A previous committed patch hanged image output. This patch corrects this issue. It also warrants that buffer is updated for each frame0+frame1 frame set. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux/drivers/staging')
-rw-r--r--linux/drivers/staging/tm6000/tm6000-cards.c2
-rw-r--r--linux/drivers/staging/tm6000/tm6000-usb-isoc.h4
-rw-r--r--linux/drivers/staging/tm6000/tm6000-video.c84
3 files changed, 42 insertions, 48 deletions
diff --git a/linux/drivers/staging/tm6000/tm6000-cards.c b/linux/drivers/staging/tm6000/tm6000-cards.c
index d2ebcd6d7..d1fbaaa3d 100644
--- a/linux/drivers/staging/tm6000/tm6000-cards.c
+++ b/linux/drivers/staging/tm6000/tm6000-cards.c
@@ -435,6 +435,7 @@ static int tm6000_usb_probe(struct usb_interface *interface,
}
}
+#if 0
if (interface->altsetting->desc.bAlternateSetting) {
printk("selecting alt setting %d\n",
interface->altsetting->desc.bAlternateSetting);
@@ -444,6 +445,7 @@ static int tm6000_usb_probe(struct usb_interface *interface,
if (rc<0)
goto err;
}
+#endif
printk("tm6000: New video device @ %s Mbps (%04x:%04x, ifnum %d)\n",
speed,
diff --git a/linux/drivers/staging/tm6000/tm6000-usb-isoc.h b/linux/drivers/staging/tm6000/tm6000-usb-isoc.h
index 5dc8d4250..79a92168a 100644
--- a/linux/drivers/staging/tm6000/tm6000-usb-isoc.h
+++ b/linux/drivers/staging/tm6000/tm6000-usb-isoc.h
@@ -51,4 +51,8 @@ struct usb_isoc_ctl {
/* Stores the number of received fields */
int nfields;
+
+ /* Checks if a complete field were received */
+ int last_line;
+ unsigned int fields:2;
};
diff --git a/linux/drivers/staging/tm6000/tm6000-video.c b/linux/drivers/staging/tm6000/tm6000-video.c
index 780cf9ee0..9d6618005 100644
--- a/linux/drivers/staging/tm6000/tm6000-video.c
+++ b/linux/drivers/staging/tm6000/tm6000-video.c
@@ -262,6 +262,22 @@ static int copy_packet (struct urb *urb, u32 header, u8 **ptr, u8 *endp,
" line=%d, field=%d\n",
size, block, line, field);
+ /* Checks if a complete set of frame0 + frame 1 were received */
+ if (dev->isoc_ctl.last_line > line) {
+ if (dev->isoc_ctl.fields == 3) {
+ /* Announces that a new buffer were filled */
+ buffer_filled(dev, dma_q, *buf);
+ dprintk(dev, V4L2_DEBUG_ISOC,
+ "new buffer filled\n");
+ rc = get_next_buf(dma_q, buf);
+
+ dev->isoc_ctl.fields = 0;
+ } else {
+ dev->isoc_ctl.fields |= 1 << field;
+ }
+ }
+ dev->isoc_ctl.last_line = line;
+
if ((last_line!=line)&&(last_line+1!=line) &&
(cmd != TM6000_URB_MSG_ERR) ) {
if (cmd != TM6000_URB_MSG_VIDEO) {
@@ -282,12 +298,6 @@ static int copy_packet (struct urb *urb, u32 header, u8 **ptr, u8 *endp,
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");
- rc=get_next_buf (dma_q, buf);
}
}
@@ -650,11 +660,17 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev,
int max_packets, int num_bufs)
{
struct tm6000_dmaqueue *dma_q = &dev->vidq;
- int i;
+ int i, rc;
int sb_size, pipe;
struct urb *urb;
int j, k;
+ dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %dx%d packets"
+ " of %d bytes each to handle %u size\n",
+ max_packets, num_bufs,
+ dev->max_isoc_in, dev->isoc_ctl.max_pkt_size);
+
+
/* De-allocates all pending stuff */
tm6000_uninit_isoc(dev);
@@ -708,6 +724,17 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev,
}
memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
+#if 0
+ /* Selects the selected interface/alternate setting */
+ dprintk(dev, V4L2_DEBUG_ISOC,
+ "Selecting if 0, alt 1, interval %d\n",
+ dev->isoc_in->desc.bInterval);
+
+ rc = usb_set_interface(dev->udev, 0, 1);
+ if (rc < 0)
+ return rc;
+#endif
+
pipe=usb_rcvisocpipe(dev->udev,
dev->isoc_in->desc.bEndpointAddress &
USB_ENDPOINT_NUMBER_MASK);
@@ -886,7 +913,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
struct tm6000_fh *fh = vq->priv_data;
struct tm6000_buffer *buf = container_of(vb,struct tm6000_buffer,vb);
struct tm6000_core *dev = fh->dev;
- int rc=0, urbsize, urb_init=0, npackets=1;
+ int rc = 0, urb_init = 0;
BUG_ON(NULL == fh->fmt);
@@ -925,50 +952,11 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
urb_init=1;
}
-
if (!dev->isoc_ctl.num_bufs)
urb_init=1;
if (urb_init) {
- /* memory for video
- Should be at least
- Vres x Vres x 2 bytes/pixel by frame */
- urbsize=buf->vb.size;
-
- /* Need also one PTS */
- urbsize+=180;
-
- /* memory for audio
- Should be at least
- bitrate * 2 channels * 2 bytes / frame rate */
- if (dev->norm & V4L2_STD_525_60) {
- urbsize+=(dev->audio_bitrate*4+29)/30;
- } else {
- urbsize+=(dev->audio_bitrate*4+24)/25;
- }
-
- /* each audio frame seeems to have a frame number
- with 2 bytes */
- urbsize+=2;
-
- /* Add 4 bytes by each 180 bytes frame */
- urbsize+=((urbsize+179)/180)*4;
-
- /* Round to an enough number of URBs */
- urbsize=(urbsize+dev->max_isoc_in-1)/dev->max_isoc_in;
-
- /* Avoids allocating big memory areas for URB */
- while ((urbsize*dev->max_isoc_in)/npackets>65535) {
- npackets++;
- }
- urbsize/=(urbsize+npackets-1)/npackets;
-
- dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %dx%d packets"
- " of %d bytes each to handle %lu size\n",
- npackets,urbsize,dev->max_isoc_in,buf->vb.size);
-
- rc = tm6000_prepare_isoc(dev, urbsize, npackets);
-
+ rc = tm6000_prepare_isoc(dev, 128, 1);
if (rc<0)
goto fail;
}