linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] media: prevent driver device access in disconnect path
@ 2014-07-12 16:44 Shuah Khan
  2014-07-12 16:44 ` [PATCH 1/3] media: dvb-core move fe exit flag from fepriv to fe for driver access Shuah Khan
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Shuah Khan @ 2014-07-12 16:44 UTC (permalink / raw)
  To: m.chehab, dheitmueller, olebowle; +Cc: Shuah Khan, linux-media, linux-kernel

Some fe drivers attempt to access the device for power control from
their release routines. When release routines are called after device
is disconnected, the attempts fail. fe drivers should avoid accessing
the device, from their release interfaces when called from disconnect
path. The problem is noticed in drx39xyj driver. 

This patch series does the following to fix the problem:
- exports dvb-frontend exit flag by moving it from fepriv to fe.
- changes em28xx-dvb to update the fe exit path in its usb
  disconnect path
- changes drx39xyj driver to check and avoid accessing the device in
  its release interface.
 
 
Shuah Khan (3):
  media: dvb-core move fe exit flag from fepriv to fe for driver access
  media: em28xx-dvb update fe exit flag to indicate device disconnect
  media: drx39xyj driver change to check fe exit flag from release

 drivers/media/dvb-core/dvb_frontend.c       |   26 +++++++++++---------------
 drivers/media/dvb-core/dvb_frontend.h       |    5 +++++
 drivers/media/dvb-frontends/drx39xyj/drxj.c |    4 +++-
 drivers/media/usb/em28xx/em28x-dvb.c       |    8 ++++++--
 4 files changed, 25 insertions(+), 18 deletions(-)

-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] media: dvb-core move fe exit flag from fepriv to fe for driver access
  2014-07-12 16:44 [PATCH 0/3] media: prevent driver device access in disconnect path Shuah Khan
@ 2014-07-12 16:44 ` Shuah Khan
  2014-07-12 16:44 ` [PATCH 2/3] media: em28xx-dvb update fe exit flag to indicate device disconnect Shuah Khan
  2014-07-12 16:44 ` [PATCH 3/3] media: drx39xyj driver change to check fe exit flag from release Shuah Khan
  2 siblings, 0 replies; 4+ messages in thread
From: Shuah Khan @ 2014-07-12 16:44 UTC (permalink / raw)
  To: m.chehab, dheitmueller, olebowle; +Cc: Shuah Khan, linux-media, linux-kernel

Some fe drivers attempt to access the device for power control from
their release routines. When release routines are called after device
is disconnected, the attempts fail. fe drivers should avoid accessing
the device, from their release interfaces when called from disconnect
path. dvb-frontend maintains exit flag to keep track when fe device is
disconnected in its private data structures. Export the flag in fe to
enable drivers to check the device status from their release interfaces.

Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
---
 drivers/media/dvb-core/dvb_frontend.c |   26 +++++++++++---------------
 drivers/media/dvb-core/dvb_frontend.h |    5 +++++
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 6ce435a..c833220 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -96,10 +96,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
  * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
  */
 
-#define DVB_FE_NO_EXIT	0
-#define DVB_FE_NORMAL_EXIT	1
-#define DVB_FE_DEVICE_REMOVED	2
-
 static DEFINE_MUTEX(frontend_mutex);
 
 struct dvb_frontend_private {
@@ -113,7 +109,6 @@ struct dvb_frontend_private {
 	wait_queue_head_t wait_queue;
 	struct task_struct *thread;
 	unsigned long release_jiffies;
-	unsigned int exit;
 	unsigned int wakeup;
 	fe_status_t status;
 	unsigned long tune_mode_flags;
@@ -565,7 +560,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
 {
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
-	if (fepriv->exit != DVB_FE_NO_EXIT)
+	if (fe->exit != DVB_FE_NO_EXIT)
 		return 1;
 
 	if (fepriv->dvbdev->writers == 1)
@@ -629,7 +624,7 @@ restart:
 			/* got signal or quitting */
 			if (!down_interruptible(&fepriv->sem))
 				semheld = true;
-			fepriv->exit = DVB_FE_NORMAL_EXIT;
+			fe->exit = DVB_FE_NORMAL_EXIT;
 			break;
 		}
 
@@ -739,9 +734,9 @@ restart:
 
 	fepriv->thread = NULL;
 	if (kthread_should_stop())
-		fepriv->exit = DVB_FE_DEVICE_REMOVED;
+		fe->exit = DVB_FE_DEVICE_REMOVED;
 	else
-		fepriv->exit = DVB_FE_NO_EXIT;
+		fe->exit = DVB_FE_NO_EXIT;
 	mb();
 
 	if (semheld)
@@ -756,7 +751,8 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
 
 	dev_dbg(fe->dvb->device, "%s:\n", __func__);
 
-	fepriv->exit = DVB_FE_NORMAL_EXIT;
+	if (fe->exit != DVB_FE_DEVICE_REMOVED)
+		fe->exit = DVB_FE_NORMAL_EXIT;
 	mb();
 
 	if (!fepriv->thread)
@@ -826,7 +822,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
 	dev_dbg(fe->dvb->device, "%s:\n", __func__);
 
 	if (fepriv->thread) {
-		if (fepriv->exit == DVB_FE_NO_EXIT)
+		if (fe->exit == DVB_FE_NO_EXIT)
 			return 0;
 		else
 			dvb_frontend_stop (fe);
@@ -838,7 +834,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
 		return -EINTR;
 
 	fepriv->state = FESTATE_IDLE;
-	fepriv->exit = DVB_FE_NO_EXIT;
+	fe->exit = DVB_FE_NO_EXIT;
 	fepriv->thread = NULL;
 	mb();
 
@@ -1906,7 +1902,7 @@ static int dvb_frontend_ioctl(struct file *file,
 	if (down_interruptible(&fepriv->sem))
 		return -ERESTARTSYS;
 
-	if (fepriv->exit != DVB_FE_NO_EXIT) {
+	if (fe->exit != DVB_FE_NO_EXIT) {
 		up(&fepriv->sem);
 		return -ENODEV;
 	}
@@ -2424,7 +2420,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 	int ret;
 
 	dev_dbg(fe->dvb->device, "%s:\n", __func__);
-	if (fepriv->exit == DVB_FE_DEVICE_REMOVED)
+	if (fe->exit == DVB_FE_DEVICE_REMOVED)
 		return -ENODEV;
 
 	if (adapter->mfe_shared) {
@@ -2529,7 +2525,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
 
 	if (dvbdev->users == -1) {
 		wake_up(&fepriv->wait_queue);
-		if (fepriv->exit != DVB_FE_NO_EXIT)
+		if (fe->exit != DVB_FE_NO_EXIT)
 			wake_up(&dvbdev->wait_queue);
 		if (fe->ops.ts_bus_ctrl)
 			fe->ops.ts_bus_ctrl(fe, 0);
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 371b6ca..625a340 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -405,6 +405,10 @@ struct dtv_frontend_properties {
 	struct dtv_fe_stats	block_count;
 };
 
+#define DVB_FE_NO_EXIT  0
+#define DVB_FE_NORMAL_EXIT      1
+#define DVB_FE_DEVICE_REMOVED   2
+
 struct dvb_frontend {
 	struct dvb_frontend_ops ops;
 	struct dvb_adapter *dvb;
@@ -418,6 +422,7 @@ struct dvb_frontend {
 #define DVB_FRONTEND_COMPONENT_DEMOD 1
 	int (*callback)(void *adapter_priv, int component, int cmd, int arg);
 	int id;
+	unsigned int exit;
 };
 
 extern int dvb_register_frontend(struct dvb_adapter *dvb,
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] media: em28xx-dvb update fe exit flag to indicate device disconnect
  2014-07-12 16:44 [PATCH 0/3] media: prevent driver device access in disconnect path Shuah Khan
  2014-07-12 16:44 ` [PATCH 1/3] media: dvb-core move fe exit flag from fepriv to fe for driver access Shuah Khan
@ 2014-07-12 16:44 ` Shuah Khan
  2014-07-12 16:44 ` [PATCH 3/3] media: drx39xyj driver change to check fe exit flag from release Shuah Khan
  2 siblings, 0 replies; 4+ messages in thread
From: Shuah Khan @ 2014-07-12 16:44 UTC (permalink / raw)
  To: m.chehab, dheitmueller, olebowle; +Cc: Shuah Khan, linux-media, linux-kernel

Change em28xx_dvb_fini() to set fe exit flag to DVB_FE_DEVICE_REMOVED
when device is disconnected. em28xx maintains device disconnect status
in em28xx device. fe drivers will be able to now check the fe exit
status to avoid accessing the device, from their release interfaces
when called from disconnect path. This change depends on dvb-core
change that exports fe exit flag by moving it from fepriv to fe.

Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
---
 drivers/media/usb/em28xx/em28xx-dvb.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 8d5cb62..5663d62 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -1668,10 +1668,14 @@ static int em28xx_dvb_fini(struct em28xx *dev)
 	if (dev->disconnected) {
 		/* We cannot tell the device to sleep
 		 * once it has been unplugged. */
-		if (dvb->fe[0])
+		if (dvb->fe[0]) {
 			prevent_sleep(&dvb->fe[0]->ops);
-		if (dvb->fe[1])
+			dvb->fe[0]->exit = DVB_FE_DEVICE_REMOVED;
+		}
+		if (dvb->fe[1]) {
 			prevent_sleep(&dvb->fe[1]->ops);
+			dvb->fe[1]->exit = DVB_FE_DEVICE_REMOVED;
+		}
 	}
 
 	em28xx_unregister_dvb(dvb);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] media: drx39xyj driver change to check fe exit flag from release
  2014-07-12 16:44 [PATCH 0/3] media: prevent driver device access in disconnect path Shuah Khan
  2014-07-12 16:44 ` [PATCH 1/3] media: dvb-core move fe exit flag from fepriv to fe for driver access Shuah Khan
  2014-07-12 16:44 ` [PATCH 2/3] media: em28xx-dvb update fe exit flag to indicate device disconnect Shuah Khan
@ 2014-07-12 16:44 ` Shuah Khan
  2 siblings, 0 replies; 4+ messages in thread
From: Shuah Khan @ 2014-07-12 16:44 UTC (permalink / raw)
  To: m.chehab, dheitmueller, olebowle; +Cc: Shuah Khan, linux-media, linux-kernel

Change drx39xyj_release() to check fe exit flag to detect the
device disconnect state and avoid accessing the device after
it has been removed.

Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
---
 drivers/media/dvb-frontends/drx39xyj/drxj.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index 9482954..54855a9 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -12238,7 +12238,9 @@ static void drx39xxj_release(struct dvb_frontend *fe)
 	struct drx39xxj_state *state = fe->demodulator_priv;
 	struct drx_demod_instance *demod = state->demod;
 
-	drxj_close(demod);
+	/* if device is removed don't access it */
+	if (fe->exit != DVB_FE_DEVICE_REMOVED)
+		drxj_close(demod);
 
 	kfree(demod->my_ext_attr);
 	kfree(demod->my_common_attr);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-07-12 16:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-12 16:44 [PATCH 0/3] media: prevent driver device access in disconnect path Shuah Khan
2014-07-12 16:44 ` [PATCH 1/3] media: dvb-core move fe exit flag from fepriv to fe for driver access Shuah Khan
2014-07-12 16:44 ` [PATCH 2/3] media: em28xx-dvb update fe exit flag to indicate device disconnect Shuah Khan
2014-07-12 16:44 ` [PATCH 3/3] media: drx39xyj driver change to check fe exit flag from release Shuah Khan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).