diff options
Diffstat (limited to 'drivers/media/dvb/dvb-core')
-rw-r--r-- | drivers/media/dvb/dvb-core/dmxdev.c | 68 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dmxdev.h | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_demux.c | 21 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_frontend.c | 91 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_net.c | 48 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_net.h | 1 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvbdev.c | 27 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvbdev.h | 1 |
8 files changed, 171 insertions, 88 deletions
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index fc77de45ca4d..275df65fde99 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/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; } @@ -180,8 +186,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; - if (mutex_lock_interruptible(&dmxdev->mutex)) - return -ERESTARTSYS; + mutex_lock(&dmxdev->mutex); if ((file->f_flags & O_ACCMODE) == O_WRONLY) { dmxdev->demux->disconnect_frontend(dmxdev->demux); @@ -199,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; } @@ -216,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; @@ -228,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, @@ -666,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; } @@ -673,13 +699,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file) static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter) { - if (mutex_lock_interruptible(&dmxdev->mutex)) - return -ERESTARTSYS; - - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); - return -ERESTARTSYS; - } + mutex_lock(&dmxdev->mutex); + mutex_lock(&dmxdevfilter->mutex); dvb_dmxdev_filter_stop(dmxdevfilter); dvb_dmxdev_filter_reset(dmxdevfilter); @@ -949,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 = { @@ -1033,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 }; @@ -1070,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/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h index d2bee9ffe43c..29746e70d325 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.h +++ b/drivers/media/dvb/dvb-core/dmxdev.h @@ -91,6 +91,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/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index fcff5eab21a3..6d8d1c3df863 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c @@ -673,8 +673,7 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed) struct dvb_demux *demux = feed->demux; int ret; - if (mutex_lock_interruptible(&demux->mutex)) - return -ERESTARTSYS; + mutex_lock(&demux->mutex); if (feed->state < DMX_STATE_GO) { mutex_unlock(&demux->mutex); @@ -748,8 +747,7 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dvb_demux *demux = (struct dvb_demux *)dmx; struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; - if (mutex_lock_interruptible(&demux->mutex)) - return -ERESTARTSYS; + mutex_lock(&demux->mutex); if (feed->state == DMX_STATE_FREE) { mutex_unlock(&demux->mutex); @@ -916,8 +914,7 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed) struct dvb_demux *dvbdmx = dvbdmxfeed->demux; int ret; - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdmx->mutex); if (!dvbdmx->stop_feed) { mutex_unlock(&dvbdmx->mutex); @@ -942,8 +939,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdmx->mutex); if (dvbdmxfilter->feed != dvbdmxfeed) { mutex_unlock(&dvbdmx->mutex); @@ -1016,8 +1012,7 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux, struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdmx->mutex); if (dvbdmxfeed->state == DMX_STATE_FREE) { mutex_unlock(&dvbdmx->mutex); @@ -1126,8 +1121,7 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux, if (demux->frontend) return -EINVAL; - if (mutex_lock_interruptible(&dvbdemux->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdemux->mutex); demux->frontend = frontend; mutex_unlock(&dvbdemux->mutex); @@ -1138,8 +1132,7 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux) { struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - if (mutex_lock_interruptible(&dvbdemux->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdemux->mutex); demux->frontend = NULL; mutex_unlock(&dvbdemux->mutex); diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index e85972222ab4..f4e4ca2dcade 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -36,6 +36,7 @@ #include <linux/list.h> #include <linux/freezer.h> #include <linux/jiffies.h> +#include <linux/kthread.h> #include <asm/processor.h> #include "dvb_frontend.h" @@ -100,7 +101,7 @@ struct dvb_frontend_private { struct semaphore sem; struct list_head list_head; wait_queue_head_t wait_queue; - pid_t thread_pid; + struct task_struct *thread; unsigned long release_jiffies; unsigned int exit; unsigned int wakeup; @@ -508,19 +509,11 @@ static int dvb_frontend_thread(void *data) struct dvb_frontend *fe = data; struct dvb_frontend_private *fepriv = fe->frontend_priv; unsigned long timeout; - char name [15]; fe_status_t s; struct dvb_frontend_parameters *params; dprintk("%s\n", __FUNCTION__); - snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num); - - lock_kernel(); - daemonize(name); - sigfillset(¤t->blocked); - unlock_kernel(); - fepriv->check_wrapped = 0; fepriv->quality = 0; fepriv->delay = 3*HZ; @@ -532,16 +525,18 @@ static int dvb_frontend_thread(void *data) while (1) { up(&fepriv->sem); /* is locked when we enter the thread... */ - +restart: timeout = wait_event_interruptible_timeout(fepriv->wait_queue, - dvb_frontend_should_wakeup(fe), - fepriv->delay); - if (0 != dvb_frontend_is_exiting(fe)) { + dvb_frontend_should_wakeup(fe) || kthread_should_stop(), + fepriv->delay); + + if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { /* got signal or quitting */ break; } - try_to_freeze(); + if (try_to_freeze()) + goto restart; if (down_interruptible(&fepriv->sem)) break; @@ -591,7 +586,7 @@ static int dvb_frontend_thread(void *data) fe->ops.sleep(fe); } - fepriv->thread_pid = 0; + fepriv->thread = NULL; mb(); dvb_frontend_wakeup(fe); @@ -600,7 +595,6 @@ static int dvb_frontend_thread(void *data) static void dvb_frontend_stop(struct dvb_frontend *fe) { - unsigned long ret; struct dvb_frontend_private *fepriv = fe->frontend_priv; dprintk ("%s\n", __FUNCTION__); @@ -608,33 +602,18 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) fepriv->exit = 1; mb(); - if (!fepriv->thread_pid) - return; - - /* check if the thread is really alive */ - if (kill_proc(fepriv->thread_pid, 0, 1) == -ESRCH) { - printk("dvb_frontend_stop: thread PID %d already died\n", - fepriv->thread_pid); - /* make sure the mutex was not held by the thread */ - init_MUTEX (&fepriv->sem); + if (!fepriv->thread) return; - } - /* wake up the frontend thread, so it notices that fe->exit == 1 */ - dvb_frontend_wakeup(fe); + kthread_stop(fepriv->thread); - /* wait until the frontend thread has exited */ - ret = wait_event_interruptible(fepriv->wait_queue,0 == fepriv->thread_pid); - if (-ERESTARTSYS != ret) { - fepriv->state = FESTATE_IDLE; - return; - } + init_MUTEX (&fepriv->sem); fepriv->state = FESTATE_IDLE; /* paranoia check in case a signal arrived */ - if (fepriv->thread_pid) - printk("dvb_frontend_stop: warning: thread PID %d won't exit\n", - fepriv->thread_pid); + if (fepriv->thread) + printk("dvb_frontend_stop: warning: thread %p won't exit\n", + fepriv->thread); } s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime) @@ -684,10 +663,11 @@ static int dvb_frontend_start(struct dvb_frontend *fe) { int ret; struct dvb_frontend_private *fepriv = fe->frontend_priv; + struct task_struct *fe_thread; dprintk ("%s\n", __FUNCTION__); - if (fepriv->thread_pid) { + if (fepriv->thread) { if (!fepriv->exit) return 0; else @@ -701,18 +681,18 @@ static int dvb_frontend_start(struct dvb_frontend *fe) fepriv->state = FESTATE_IDLE; fepriv->exit = 0; - fepriv->thread_pid = 0; + fepriv->thread = NULL; mb(); - ret = kernel_thread (dvb_frontend_thread, fe, 0); - - if (ret < 0) { - printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret); + fe_thread = kthread_run(dvb_frontend_thread, fe, + "kdvb-fe-%i", fe->dvb->num); + if (IS_ERR(fe_thread)) { + ret = PTR_ERR(fe_thread); + printk("dvb_frontend_start: failed to start kthread (%d)\n", ret); up(&fepriv->sem); return ret; } - fepriv->thread_pid = ret; - + fepriv->thread = fe_thread; return 0; } @@ -915,7 +895,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, fetunesettings.parameters.inversion = INVERSION_AUTO; } if (fe->ops.info.type == FE_OFDM) { - /* without hierachical coding code_rate_LP is irrelevant, + /* without hierarchical coding code_rate_LP is irrelevant, * so we tolerate the otherwise invalid FEC_NONE setting */ if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE) @@ -1044,6 +1024,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__); @@ -1053,7 +1034,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(&dvbdev->wait_queue); + } + return ret; } static struct file_operations dvb_frontend_fops = { @@ -1113,8 +1101,15 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) dprintk ("%s\n", __FUNCTION__); mutex_lock(&frontend_mutex); - dvb_unregister_device (fepriv->dvbdev); 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); /* fe is invalid now */ kfree(fepriv); diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 76e9c36597eb..4ebf33a5ffa2 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -174,7 +174,7 @@ static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb, struct ethhdr *eth; unsigned char *rawp; - skb->mac.raw=skb->data; + skb_reset_mac_header(skb); skb_pull(skb,dev->hard_header_len); eth = eth_hdr(skb); @@ -600,6 +600,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) /* Check CRC32, we've got it in our skb already. */ unsigned short ulen = htons(priv->ule_sndu_len); unsigned short utype = htons(priv->ule_sndu_type); + const u8 *tail; struct kvec iov[3] = { { &ulen, sizeof ulen }, { &utype, sizeof utype }, @@ -613,10 +614,11 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) } ule_crc = iov_crc32(ule_crc, iov, 3); - expected_crc = *((u8 *)priv->ule_skb->tail - 4) << 24 | - *((u8 *)priv->ule_skb->tail - 3) << 16 | - *((u8 *)priv->ule_skb->tail - 2) << 8 | - *((u8 *)priv->ule_skb->tail - 1); + tail = skb_tail_pointer(priv->ule_skb); + expected_crc = *(tail - 4) << 24 | + *(tail - 3) << 16 | + *(tail - 2) << 8 | + *(tail - 1); if (ule_crc != expected_crc) { printk(KERN_WARNING "%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n", priv->ts_count, ule_crc, expected_crc, priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned short *)from_where : 0); @@ -695,7 +697,9 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) } else { - memcpy(dest_addr, priv->ule_skb->data, ETH_ALEN); + skb_copy_from_linear_data(priv->ule_skb, + dest_addr, + ETH_ALEN); skb_pull(priv->ule_skb, ETH_ALEN); } } @@ -1435,11 +1439,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 = { @@ -1454,6 +1483,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<DVB_NET_DEVICES_MAX; i++) { diff --git a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb/dvb-core/dvb_net.h index f14e4ca38570..3a3126cae03b 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.h +++ b/drivers/media/dvb/dvb-core/dvb_net.h @@ -36,6 +36,7 @@ struct dvb_net { struct dvb_device *dvbdev; struct net_device *device[DVB_NET_DEVICES_MAX]; int state[DVB_NET_DEVICES_MAX]; + unsigned int exit:1; struct dmx_demux *demux; }; diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 826b47f155a0..e23d8a0ea1d3 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -199,12 +199,13 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, const struct dvb_device *template, void *priv, int type) { struct dvb_device *dvbdev; + struct file_operations *dvbdevfops; + int id; - if (mutex_lock_interruptible(&dvbdev_register_lock)) - return -ERESTARTSYS; + mutex_lock(&dvbdev_register_lock); - if ((id = dvbdev_get_free_id (adap, type)) < 0) { + if ((id = dvbdev_get_free_id (adap, type)) < 0){ mutex_unlock(&dvbdev_register_lock); *pdvbdev = NULL; printk ("%s: could get find free device id...\n", __FUNCTION__); @@ -213,7 +214,15 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL); - if (!dvbdev) { + if (!dvbdev){ + mutex_unlock(&dvbdev_register_lock); + return -ENOMEM; + } + + dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL); + + if (!dvbdevfops){ + kfree (dvbdev); mutex_unlock(&dvbdev_register_lock); return -ENOMEM; } @@ -223,7 +232,10 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dvbdev->id = id; 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; list_add_tail (&dvbdev->list_head, &adap->device_list); @@ -251,6 +263,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev) dvbdev->type, dvbdev->id))); list_del (&dvbdev->list_head); + kfree (dvbdev->fops); kfree (dvbdev); } EXPORT_SYMBOL(dvb_unregister_device); @@ -281,8 +294,7 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu { int num; - if (mutex_lock_interruptible(&dvbdev_register_lock)) - return -ERESTARTSYS; + mutex_lock(&dvbdev_register_lock); if ((num = dvbdev_get_free_adapter_num ()) < 0) { mutex_unlock(&dvbdev_register_lock); @@ -310,8 +322,7 @@ EXPORT_SYMBOL(dvb_register_adapter); int dvb_unregister_adapter(struct dvb_adapter *adap) { - if (mutex_lock_interruptible(&dvbdev_register_lock)) - return -ERESTARTSYS; + mutex_lock(&dvbdev_register_lock); list_del (&adap->list_head); mutex_unlock(&dvbdev_register_lock); return 0; diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 620e7887b3d3..6dff10ebf470 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); |