diff options
Diffstat (limited to 'drivers/media/dvb/dvb-core/dvb_net.c')
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_net.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 6a5ab409c4e..4ebf33a5ffa 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -1439,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 = { @@ -1458,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++) { |