V4L/DVB (5512): Fix 3/3 for bug 7819: fixed hotplugging for dvbnet
authorMarkus Rechberger <markus.rechberger@amd.com>
Sat, 14 Apr 2007 13:19:36 +0000 (10:19 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Fri, 27 Apr 2007 18:45:32 +0000 (15:45 -0300)
fixed hotplugging for dvbnet

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>
drivers/media/dvb/dvb-core/dvb_demux.c
drivers/media/dvb/dvb-core/dvb_demux.h
drivers/media/dvb/dvb-core/dvb_net.c
drivers/media/dvb/dvb-core/dvb_net.h

index f558ac9c09547bd27b2cd8c75ded25a6566314b1..6d8d1c3df8631a4832b34954e44e5633cd3a34c6 100644 (file)
@@ -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);
 
index e1e91399afd91fc43c0444e8a89687e4ae4a916c..2c5f915329ca9c5658e68628208f57c58c856364 100644 (file)
@@ -119,7 +119,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;
index 6a5ab409c4e71919b5331339adc51ed9b3b4fa0c..4ebf33a5ffa2b1c5bab38c1fafca0e0e83c06c9a 100644 (file)
@@ -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++) {
index f14e4ca385708cab14c498167ff5265e1d51f543..3a3126cae03b0c26d81b1f639017a1c87b0554c4 100644 (file)
@@ -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;
 };