mirror of
https://github.com/torvalds/linux.git
synced 2024-12-02 17:11:33 +00:00
[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: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
parent
d7590b5704
commit
53460c53b7
@ -105,6 +105,15 @@ static struct tda18271_config hauppauge_woodbury_tunerconfig = {
|
||||
|
||||
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)
|
||||
{
|
||||
@ -138,6 +147,13 @@ static void urb_completion(struct urb *purb)
|
||||
ptr[0], purb->actual_length);
|
||||
schedule_work(&dev->restart_streaming);
|
||||
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 */
|
||||
@ -160,6 +176,11 @@ static int stop_urb_transfer(struct au0828_dev *dev)
|
||||
if (!dev->urb_streaming)
|
||||
return 0;
|
||||
|
||||
if (dev->bulk_timeout_running == 1) {
|
||||
dev->bulk_timeout_running = 0;
|
||||
del_timer(&dev->bulk_timeout);
|
||||
}
|
||||
|
||||
dev->urb_streaming = false;
|
||||
for (i = 0; i < URB_COUNT; i++) {
|
||||
if (dev->urbs[i]) {
|
||||
@ -232,6 +253,11 @@ static int start_urb_transfer(struct au0828_dev *dev)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -622,6 +648,10 @@ int au0828_dvb_register(struct au0828_dev *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev->bulk_timeout.function = au0828_bulk_timeout;
|
||||
dev->bulk_timeout.data = (unsigned long) dev;
|
||||
init_timer(&dev->bulk_timeout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -195,6 +195,8 @@ struct au0828_dev {
|
||||
/* Digital */
|
||||
struct au0828_dvb dvb;
|
||||
struct work_struct restart_streaming;
|
||||
struct timer_list bulk_timeout;
|
||||
int bulk_timeout_running;
|
||||
|
||||
#ifdef CONFIG_VIDEO_AU0828_V4L2
|
||||
/* Analog */
|
||||
|
Loading…
Reference in New Issue
Block a user