From bc15e02fe336da29282cde1a36a83e5c3f3d281b Mon Sep 17 00:00:00 2001 From: Markus Rechberger Date: Sat, 14 Apr 2007 10:18:58 -0300 Subject: Fix 1/3 for bug 7819: fixed frontend hotplug issue From: Markus Rechberger fixed frontend hotplug issue Signed-off-by: Michal CIJOML Semler Signed-off-by: Markus Rechberger Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 17 +++++++++++++++-- linux/drivers/media/dvb/dvb-core/dvbdev.c | 1 + linux/drivers/media/dvb/dvb-core/dvbdev.h | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') 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); -- cgit v1.2.3 From a50993cda9ca49aa4129ed55460e9c0bbeeb0781 Mon Sep 17 00:00:00 2001 From: Markus Rechberger Date: Sat, 14 Apr 2007 10:19:18 -0300 Subject: Fix 2/3 for bug 7819: fixing hotplug issue for demux[n] and dvr[n] From: Markus Rechberger fixing hotplug issue for demux[n] and dvr[n] Signed-off-by: Michal CIJOML Semler Signed-off-by: Markus Rechberger Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dmxdev.c | 56 ++++++++++++++++++++++++- linux/drivers/media/dvb/dvb-core/dmxdev.h | 2 + linux/drivers/media/dvb/dvb-core/dvb_demux.c | 2 + linux/drivers/media/dvb/dvb-core/dvb_demux.h | 1 + linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 13 +++--- 5 files changed, 67 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index a5c0e1a3e..275df65fd 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -132,6 +132,11 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; + if (dmxdev->exit) { + mutex_unlock(&dmxdev->mutex); + return -ENODEV; + } + if ((file->f_flags & O_ACCMODE) == O_RDWR) { if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { mutex_unlock(&dmxdev->mutex); @@ -171,6 +176,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) dmxdev->demux->disconnect_frontend(dmxdev->demux); dmxdev->demux->connect_frontend(dmxdev->demux, front); } + dvbdev->users++; mutex_unlock(&dmxdev->mutex); return 0; } @@ -198,7 +204,16 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) vfree(mem); } } - mutex_unlock(&dmxdev->mutex); + /* TODO */ + dvbdev->users--; + if(dvbdev->users==-1 && dmxdev->exit==1) { + fops_put(file->f_op); + file->f_op = NULL; + mutex_unlock(&dmxdev->mutex); + wake_up(&dvbdev->wait_queue); + } else + mutex_unlock(&dmxdev->mutex); + return 0; } @@ -215,6 +230,11 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, return -EINVAL; if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; + + if (dmxdev->exit) { + mutex_unlock(&dmxdev->mutex); + return -ENODEV; + } ret = dmxdev->demux->write(dmxdev->demux, buf, count); mutex_unlock(&dmxdev->mutex); return ret; @@ -227,6 +247,11 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, struct dmxdev *dmxdev = dvbdev->priv; int ret; + if (dmxdev->exit) { + mutex_unlock(&dmxdev->mutex); + return -ENODEV; + } + //mutex_lock(&dmxdev->mutex); ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, file->f_flags & O_NONBLOCK, @@ -665,6 +690,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file) dmxdevfilter->feed.ts = NULL; init_timer(&dmxdevfilter->timer); + dvbdev->users++; + mutex_unlock(&dmxdev->mutex); return 0; } @@ -943,7 +970,21 @@ static int dvb_demux_release(struct inode *inode, struct file *file) struct dmxdev_filter *dmxdevfilter = file->private_data; struct dmxdev *dmxdev = dmxdevfilter->dev; - return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); + int ret; + + ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); + + mutex_lock(&dmxdev->mutex); + dmxdev->dvbdev->users--; + if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) { + fops_put(file->f_op); + file->f_op = NULL; + mutex_unlock(&dmxdev->mutex); + wake_up(&dmxdev->dvbdev->wait_queue); + } else + mutex_unlock(&dmxdev->mutex); + + return ret; } static struct file_operations dvb_demux_fops = { @@ -1027,6 +1068,7 @@ static struct file_operations dvb_dvr_fops = { static struct dvb_device dvbdev_dvr = { .priv = NULL, .readers = 1, + .users = 1, .fops = &dvb_dvr_fops }; @@ -1064,6 +1106,16 @@ EXPORT_SYMBOL(dvb_dmxdev_init); void dvb_dmxdev_release(struct dmxdev *dmxdev) { + dmxdev->exit=1; + if (dmxdev->dvbdev->users > 1) { + wait_event(dmxdev->dvbdev->wait_queue, + dmxdev->dvbdev->users==1); + } + if (dmxdev->dvr_dvbdev->users > 1) { + wait_event(dmxdev->dvr_dvbdev->wait_queue, + dmxdev->dvr_dvbdev->users==1); + } + dvb_unregister_device(dmxdev->dvbdev); dvb_unregister_device(dmxdev->dvr_dvbdev); diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.h b/linux/drivers/media/dvb/dvb-core/dmxdev.h index 080abd9a9..bb416e6c2 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.h +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.h @@ -98,6 +98,8 @@ struct dmxdev { int filternum; int capabilities; + + unsigned int exit:1; #define DMXDEV_CAP_DUPLEX 1 struct dmx_frontend *dvr_orig_fe; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c index 6d8d1c3df..f558ac9c0 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c @@ -1208,6 +1208,8 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) dmx->disconnect_frontend = dvbdmx_disconnect_frontend; dmx->get_pes_pids = dvbdmx_get_pes_pids; + init_waitqueue_head (&dvbdemux->wait_queue); + mutex_init(&dvbdemux->mutex); spin_lock_init(&dvbdemux->lock); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.h b/linux/drivers/media/dvb/dvb-core/dvb_demux.h index 099b149e5..dcf20c4e3 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.h @@ -122,6 +122,7 @@ struct dvb_demux { u16 pids[DMX_TS_PES_OTHER]; int playing; int recording; + wait_queue_head_t wait_queue; #define DMX_MAX_PID 0x2000 struct list_head feed_list; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 7cd04c3e4..2cad44fb2 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -612,10 +612,6 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) 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; @@ -1048,7 +1044,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) if (dvbdev->users==-1 && fepriv->exit==1) { fops_put(file->f_op); file->f_op = NULL; - wake_up_interruptible (&dvbdev->wait_queue); + wake_up(&dvbdev->wait_queue); } return ret; } @@ -1109,7 +1105,14 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) struct dvb_frontend_private *fepriv = fe->frontend_priv; dprintk ("%s\n", __FUNCTION__); + mutex_lock(&frontend_mutex); dvb_frontend_stop (fe); + mutex_unlock(&frontend_mutex); + + if (fepriv->dvbdev->users < -1) + wait_event(fepriv->dvbdev->wait_queue, + fepriv->dvbdev->users==-1); + mutex_lock(&frontend_mutex); dvb_unregister_device (fepriv->dvbdev); -- cgit v1.2.3 From d6e9e2354396258d2a011ac9331472e705b87207 Mon Sep 17 00:00:00 2001 From: Markus Rechberger Date: Sat, 14 Apr 2007 10:19:36 -0300 Subject: Fix 3/3 for bug 7819: fixed hotplugging for dvbnet From: Markus Rechberger fixed hotplugging for dvbnet Signed-off-by: Michal CIJOML Semler Signed-off-by: Markus Rechberger Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dvb_demux.c | 2 -- linux/drivers/media/dvb/dvb-core/dvb_demux.h | 1 - linux/drivers/media/dvb/dvb-core/dvb_net.c | 32 +++++++++++++++++++++++++++- linux/drivers/media/dvb/dvb-core/dvb_net.h | 1 + 4 files changed, 32 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c index f558ac9c0..6d8d1c3df 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c @@ -1208,8 +1208,6 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) dmx->disconnect_frontend = dvbdmx_disconnect_frontend; dmx->get_pes_pids = dvbdmx_get_pes_pids; - init_waitqueue_head (&dvbdemux->wait_queue); - mutex_init(&dvbdemux->mutex); spin_lock_init(&dvbdemux->lock); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.h b/linux/drivers/media/dvb/dvb-core/dvb_demux.h index dcf20c4e3..099b149e5 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.h @@ -122,7 +122,6 @@ struct dvb_demux { u16 pids[DMX_TS_PES_OTHER]; int playing; int recording; - wait_queue_head_t wait_queue; #define DMX_MAX_PID 0x2000 struct list_head feed_list; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c index 3e94e6cf9..7089412e3 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_net.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c @@ -1476,11 +1476,36 @@ static int dvb_net_ioctl(struct inode *inode, struct file *file, return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl); } +static int dvb_net_close(struct inode *inode, struct file *file) +{ + struct dvb_device *dvbdev = file->private_data; + struct dvb_net *dvbnet = dvbdev->priv; + + if (!dvbdev) + return -ENODEV; + + if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + dvbdev->readers++; + } else { + dvbdev->writers++; + } + + dvbdev->users++; + + if(dvbdev->users == 1 && dvbnet->exit==1) { + fops_put(file->f_op); + file->f_op = NULL; + wake_up(&dvbdev->wait_queue); + } + return 0; +} + + static struct file_operations dvb_net_fops = { .owner = THIS_MODULE, .ioctl = dvb_net_ioctl, .open = dvb_generic_open, - .release = dvb_generic_release, + .release = dvb_net_close, }; static struct dvb_device dvbdev_net = { @@ -1495,6 +1520,11 @@ void dvb_net_release (struct dvb_net *dvbnet) { int i; + dvbnet->exit = 1; + if (dvbnet->dvbdev->users < 1) + wait_event(dvbnet->dvbdev->wait_queue, + dvbnet->dvbdev->users==1); + dvb_unregister_device(dvbnet->dvbdev); for (i=0; i Date: Wed, 2 May 2007 10:11:47 -0300 Subject: Use menuconfig objects II - DVB From: Jan Engelhardt Change Kconfig objects from "menu, config" into "menuconfig" so that the user can disable the whole feature without having to enter the menu first. Also remove one indirection (CONFIG_DVB) that does not seem to be really used inside the kernel. Signed-off-by: Jan Engelhardt Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/Kconfig | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/Kconfig b/linux/drivers/media/dvb/dvb-core/Kconfig index 1990eda10..93e24fb0e 100644 --- a/linux/drivers/media/dvb/dvb-core/Kconfig +++ b/linux/drivers/media/dvb/dvb-core/Kconfig @@ -1,12 +1,22 @@ -config DVB_CORE - tristate "DVB Core Support" - depends on DVB +menuconfig DVB_CORE + tristate "DVB for Linux" + depends on NET && INET select CRC32 help + Support Digital Video Broadcasting hardware. Enable this if you + own a DVB adapter and want to use it or if you compile Linux for + a digital SetTopBox. + DVB core utility functions for device handling, software fallbacks etc. Say Y when you have a DVB card and want to use it. Say Y if your want to build your drivers outside the kernel, but need the DVB core. All in-kernel drivers will select this automatically if needed. + + API specs and user tools are available from . + + Please report problems regarding this driver to the LinuxDVB + mailing list. + If unsure say N. config DVB_CORE_ATTACH -- cgit v1.2.3 From c2ec786d32e9a6da752ee6dc6318639f3f8dd6be Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 3 May 2007 15:59:37 -0300 Subject: Allow compiling just DVB CORE without needing to compile the drivers From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/Kconfig b/linux/drivers/media/dvb/dvb-core/Kconfig index 93e24fb0e..e3e6839f8 100644 --- a/linux/drivers/media/dvb/dvb-core/Kconfig +++ b/linux/drivers/media/dvb/dvb-core/Kconfig @@ -1,4 +1,4 @@ -menuconfig DVB_CORE +config DVB_CORE tristate "DVB for Linux" depends on NET && INET select CRC32 -- cgit v1.2.3