diff options
author | Markus Rechberger <mrechberger@gmail.com> | 2007-04-14 10:18:58 -0300 |
---|---|---|
committer | Markus Rechberger <mrechberger@gmail.com> | 2007-04-14 10:18:58 -0300 |
commit | bc15e02fe336da29282cde1a36a83e5c3f3d281b (patch) | |
tree | 437753efcc8941238c872c5c4eb3377bcc823fa9 | |
parent | 24d2656eda71a629c958936e8a6031300214f977 (diff) | |
download | mediapointer-dvb-s2-bc15e02fe336da29282cde1a36a83e5c3f3d281b.tar.gz mediapointer-dvb-s2-bc15e02fe336da29282cde1a36a83e5c3f3d281b.tar.bz2 |
Fix 1/3 for bug 7819: fixed frontend hotplug issue
From: Markus Rechberger <markus.rechberger@amd.com>
fixed frontend hotplug issue
Signed-off-by: Michal CIJOML Semler <cijoml@volny.cz>
Signed-off-by: Markus Rechberger <markus.rechberger@amd.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 17 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvbdev.c | 1 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvbdev.h | 1 |
3 files changed, 17 insertions, 2 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 60c8b0da2..7cd04c3e4 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -611,6 +611,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; @@ -1028,6 +1033,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__); @@ -1037,7 +1043,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 = { @@ -1096,9 +1109,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/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 9c8e9c3f4..17104fb4b 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -244,6 +244,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/linux/drivers/media/dvb/dvb-core/dvbdev.h b/linux/drivers/media/dvb/dvb-core/dvbdev.h index 26e4a9135..cb76869bd 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.h +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.h @@ -70,6 +70,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); |