diff mbox

au0828: fix logic of tuner disconnection

Message ID 1399435082-5416-1-git-send-email-cb.xiong@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

cb.xiong@samsung.com May 7, 2014, 3:58 a.m. UTC
From: Changbing Xiong <cb.xiong@samsung.com>

The driver crashed when the tuner was disconnected while restart stream
operations are still being performed. Fixed by adding a flag in struct
au0828_dvb to indicate whether restart stream operations can be performed.

If the stream gets misaligned, the work of restart stream operations are
 usually scheduled for many times in a row. If tuner is disconnected at
this time and some of restart stream operations are still not flushed,
then the driver crashed due to accessing the resource which used in
restart stream operations has been released.

Signed-off-by: Changbing Xiong <cb.xiong@samsung.com>
---
 drivers/media/usb/au0828/au0828-dvb.c |   13 +++++++++++++
 drivers/media/usb/au0828/au0828.h     |    1 +
 2 files changed, 14 insertions(+)
 mode change 100644 => 100755 drivers/media/usb/au0828/au0828-dvb.c
 mode change 100644 => 100755 drivers/media/usb/au0828/au0828.h

--
1.7.9.5

--
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

Comments

Devin Heitmueller May 7, 2014, 3:42 p.m. UTC | #1
On Tue, May 6, 2014 at 11:58 PM,  <cb.xiong@samsung.com> wrote:
> From: Changbing Xiong <cb.xiong@samsung.com>
>
> The driver crashed when the tuner was disconnected while restart stream
> operations are still being performed. Fixed by adding a flag in struct
> au0828_dvb to indicate whether restart stream operations can be performed.
>
> If the stream gets misaligned, the work of restart stream operations are
>  usually scheduled for many times in a row. If tuner is disconnected at
> this time and some of restart stream operations are still not flushed,
> then the driver crashed due to accessing the resource which used in
> restart stream operations has been released.
>
> Signed-off-by: Changbing Xiong <cb.xiong@samsung.com>

I haven't yet reviewed the logic in detail, but at a minimum this
should really be two patches - one to address the disconnect bug and a
second to deal with failure to cancel to the worker thread.  Also, you
need to pick a name for the variable that is more explanatory than
"flag".

Please resubmit this as two separate patches with "flag" renamed, and
I will then look at the actual implementation to see if it causes any
problems.

Thanks,

Devin
cb.xiong@samsung.com May 9, 2014, 5:06 a.m. UTC | #2
Thanks for your comments, and I have resubmit this according Mr. Chehab's 
comments, please check.

Thanks.

Changbing Xiong.
--
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
diff mbox

Patch

diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
old mode 100644
new mode 100755
index 9a6f156..90cdde5
--- a/drivers/media/usb/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -280,6 +280,11 @@  static void au0828_restart_dvb_streaming(struct work_struct *work)

 	mutex_lock(&dvb->lock);

+	if (dvb->flag == true) {
+		mutex_unlock(&dvb->lock);
+		return;
+	}
+
 	/* Stop transport */
 	stop_urb_transfer(dev);
 	au0828_write(dev, 0x608, 0x00);
@@ -304,6 +309,8 @@  static int dvb_register(struct au0828_dev *dev)

 	dprintk(1, "%s()\n", __func__);

+	dvb->flag = false;
+
 	INIT_WORK(&dev->restart_streaming, au0828_restart_dvb_streaming);

 	/* register adapter */
@@ -403,6 +410,10 @@  void au0828_dvb_unregister(struct au0828_dev *dev)
 	if (dvb->frontend == NULL)
 		return;

+	mutex_lock(&dvb->lock);
+	dvb->flag = true;
+	mutex_unlock(&dvb->lock);
+
 	dvb_net_release(&dvb->net);
 	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
@@ -411,6 +422,8 @@  void au0828_dvb_unregister(struct au0828_dev *dev)
 	dvb_unregister_frontend(dvb->frontend);
 	dvb_frontend_detach(dvb->frontend);
 	dvb_unregister_adapter(&dvb->adapter);
+
+	cancel_work_sync(&dev->restart_streaming);
 }

 /* All the DVB attach calls go here, this function get's modified
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
old mode 100644
new mode 100755
index ef1f57f..00255d5
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -102,6 +102,7 @@  struct au0828_dvb {
 	struct dmx_frontend fe_mem;
 	struct dvb_net net;
 	int feeding;
+	bool flag;
 };

 enum au0828_stream_state {