From ca5be9cd0516629cb8ee335b7dad076e66d72a22 Mon Sep 17 00:00:00 2001 From: Markus Rechberger Date: Sat, 14 Apr 2007 10:18:58 -0300 Subject: [PATCH] V4L/DVB (5510): Fix 1/3 for bug 7819: fixed frontend hotplug issue fixed frontend hotplug issue Signed-off-by: Michal CIJOML Semler Signed-off-by: Markus Rechberger Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_frontend.c | 17 +++++++++++++++-- drivers/media/dvb/dvb-core/dvbdev.c | 1 + drivers/media/dvb/dvb-core/dvbdev.h | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index a21a894d3f..9783d392b7 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -606,6 +606,11 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) return; kthread_stop(fepriv->thread); + + if (fepriv->dvbdev->users < -1) + wait_event_interruptible(fepriv->dvbdev->wait_queue, + fepriv->dvbdev->users==-1); + init_MUTEX (&fepriv->sem); fepriv->state = FESTATE_IDLE; @@ -1023,6 +1028,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) struct dvb_device *dvbdev = file->private_data; struct dvb_frontend *fe = dvbdev->priv; struct dvb_frontend_private *fepriv = fe->frontend_priv; + int ret; dprintk ("%s\n", __FUNCTION__); @@ -1032,7 +1038,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) if (fe->ops.ts_bus_ctrl) fe->ops.ts_bus_ctrl (fe, 0); - return dvb_generic_release (inode, file); + ret = dvb_generic_release (inode, file); + + if (dvbdev->users==-1 && fepriv->exit==1) { + fops_put(file->f_op); + file->f_op = NULL; + wake_up_interruptible (&dvbdev->wait_queue); + } + return ret; } static struct file_operations dvb_frontend_fops = { @@ -1091,9 +1104,9 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) struct dvb_frontend_private *fepriv = fe->frontend_priv; dprintk ("%s\n", __FUNCTION__); + dvb_frontend_stop (fe); mutex_lock(&frontend_mutex); dvb_unregister_device (fepriv->dvbdev); - dvb_frontend_stop (fe); /* fe is invalid now */ kfree(fepriv); diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 14a372a0fe..e23d8a0ea1 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -233,6 +233,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dvbdev->adapter = adap; dvbdev->priv = priv; dvbdev->fops = dvbdevfops; + init_waitqueue_head (&dvbdev->wait_queue); memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations)); dvbdev->fops->owner = adap->module; diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 620e7887b3..6dff10ebf4 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h @@ -69,6 +69,7 @@ struct dvb_device { int writers; int users; + wait_queue_head_t wait_queue; /* don't really need those !? -- FIXME: use video_usercopy */ int (*kernel_ioctl)(struct inode *inode, struct file *file, unsigned int cmd, void *arg); -- 2.39.5