V4L/DVB (12827): tm6000: fix image hangs
authorMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 9 Jan 2008 21:12:39 +0000 (18:12 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 18 May 2010 03:40:08 +0000 (00:40 -0300)
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>
drivers/staging/tm6000/tm6000-cards.c
drivers/staging/tm6000/tm6000-usb-isoc.h
drivers/staging/tm6000/tm6000-video.c

index d081f1423152d2aa419aa1c129317ffb0695aa6d..650ed8e88f38db69feaf08c4e118d333b2e0eaa1 100644 (file)
@@ -410,15 +410,6 @@ static int tm6000_usb_probe(struct usb_interface *interface,
                }
        }
 
-       if (interface->altsetting->desc.bAlternateSetting) {
-               printk("selecting alt setting %d\n",
-                      interface->altsetting->desc.bAlternateSetting);
-               rc = usb_set_interface (usbdev,
-                               interface->altsetting->desc.bInterfaceNumber,
-                               interface->altsetting->desc.bAlternateSetting);
-               if (rc<0)
-                       goto err;
-       }
 
        printk("tm6000: New video device @ %s Mbps (%04x:%04x, ifnum %d)\n",
                speed,
index 10e72c04f74f79de55c22ba856684a83cb020323..24b0fd07900ed105f5952c506983c2004629b7c8 100644 (file)
@@ -50,4 +50,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;
 };
index b72cfd0d7559d9e3b615d0b8f12ca83b3397fb05..528ac6e8b0854654008b430884bd58117dfdf945 100644 (file)
@@ -257,6 +257,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)  {
@@ -277,12 +293,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);
                        }
                }
 
@@ -631,11 +641,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);
 
@@ -684,6 +700,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev,
                }
                memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
 
+
                pipe=usb_rcvisocpipe(dev->udev,
                                        dev->isoc_in->desc.bEndpointAddress &
                                        USB_ENDPOINT_NUMBER_MASK);
@@ -862,7 +879,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);
 
@@ -890,50 +907,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;
        }