Commit 53460c53 authored by Devin Heitmueller's avatar Devin Heitmueller Committed by Mauro Carvalho Chehab

[media] au0828: Add timer to restart TS stream if no data arrives on bulk endpoint

For reasons unclear, we intermittently see a case where the tune
is successful but the bulk stream fails to deliver any packets.

Add a timer to automatically stop/start the data pump if we
encounter such a case.
Signed-off-by: default avatarDevin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent d7590b57
...@@ -105,6 +105,15 @@ static struct tda18271_config hauppauge_woodbury_tunerconfig = { ...@@ -105,6 +105,15 @@ static struct tda18271_config hauppauge_woodbury_tunerconfig = {
static void au0828_restart_dvb_streaming(struct work_struct *work); static void au0828_restart_dvb_streaming(struct work_struct *work);
static void au0828_bulk_timeout(unsigned long data)
{
struct au0828_dev *dev = (struct au0828_dev *) data;
dprintk(1, "%s called\n", __func__);
dev->bulk_timeout_running = 0;
schedule_work(&dev->restart_streaming);
}
/*-------------------------------------------------------------------*/ /*-------------------------------------------------------------------*/
static void urb_completion(struct urb *purb) static void urb_completion(struct urb *purb)
{ {
...@@ -138,6 +147,13 @@ static void urb_completion(struct urb *purb) ...@@ -138,6 +147,13 @@ static void urb_completion(struct urb *purb)
ptr[0], purb->actual_length); ptr[0], purb->actual_length);
schedule_work(&dev->restart_streaming); schedule_work(&dev->restart_streaming);
return; return;
} else if (dev->bulk_timeout_running == 1) {
/* The URB handler has fired, so cancel timer which would
* restart endpoint if we hadn't
*/
dprintk(1, "%s cancelling bulk timeout\n", __func__);
dev->bulk_timeout_running = 0;
del_timer(&dev->bulk_timeout);
} }
/* Feed the transport payload into the kernel demux */ /* Feed the transport payload into the kernel demux */
...@@ -160,6 +176,11 @@ static int stop_urb_transfer(struct au0828_dev *dev) ...@@ -160,6 +176,11 @@ static int stop_urb_transfer(struct au0828_dev *dev)
if (!dev->urb_streaming) if (!dev->urb_streaming)
return 0; return 0;
if (dev->bulk_timeout_running == 1) {
dev->bulk_timeout_running = 0;
del_timer(&dev->bulk_timeout);
}
dev->urb_streaming = false; dev->urb_streaming = false;
for (i = 0; i < URB_COUNT; i++) { for (i = 0; i < URB_COUNT; i++) {
if (dev->urbs[i]) { if (dev->urbs[i]) {
...@@ -232,6 +253,11 @@ static int start_urb_transfer(struct au0828_dev *dev) ...@@ -232,6 +253,11 @@ static int start_urb_transfer(struct au0828_dev *dev)
} }
dev->urb_streaming = true; dev->urb_streaming = true;
/* If we don't valid data within 1 second, restart stream */
mod_timer(&dev->bulk_timeout, jiffies + (HZ));
dev->bulk_timeout_running = 1;
return 0; return 0;
} }
...@@ -622,6 +648,10 @@ int au0828_dvb_register(struct au0828_dev *dev) ...@@ -622,6 +648,10 @@ int au0828_dvb_register(struct au0828_dev *dev)
return ret; return ret;
} }
dev->bulk_timeout.function = au0828_bulk_timeout;
dev->bulk_timeout.data = (unsigned long) dev;
init_timer(&dev->bulk_timeout);
return 0; return 0;
} }
......
...@@ -195,6 +195,8 @@ struct au0828_dev { ...@@ -195,6 +195,8 @@ struct au0828_dev {
/* Digital */ /* Digital */
struct au0828_dvb dvb; struct au0828_dvb dvb;
struct work_struct restart_streaming; struct work_struct restart_streaming;
struct timer_list bulk_timeout;
int bulk_timeout_running;
#ifdef CONFIG_VIDEO_AU0828_V4L2 #ifdef CONFIG_VIDEO_AU0828_V4L2
/* Analog */ /* Analog */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment