V4L/DVB (6105): dvb_frontend: ts_bus_ctrl() handling fixed
authorOliver Endriss <o.endriss@gmx.de>
Sat, 25 Aug 2007 15:00:23 +0000 (12:00 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Wed, 10 Oct 2007 01:06:59 +0000 (22:06 -0300)
ts_bus_ctrl() should only be called by
- the first open
- the last release call.

Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/dvb/dvb-core/dvb_frontend.c

index 880d499cd36a59aa677093045775a91522c64259..07c0db2abfbce392ce00a3e8432396859a00df13 100644 (file)
@@ -1056,18 +1056,15 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 
        dprintk ("%s\n", __FUNCTION__);
 
-       if ((ret = dvb_generic_open (inode, file)) < 0)
-               return ret;
-
-       if (fe->ops.ts_bus_ctrl) {
-               if ((ret = fe->ops.ts_bus_ctrl (fe, 1)) < 0) {
-                       dvb_generic_release (inode, file);
+       if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
+               if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
                        return ret;
-               }
        }
 
-       if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+       if ((ret = dvb_generic_open (inode, file)) < 0)
+               goto err1;
 
+       if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
                /* normal tune mode when opened R/W */
                fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
                fepriv->tone = -1;
@@ -1075,13 +1072,20 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 
                ret = dvb_frontend_start (fe);
                if (ret)
-                       dvb_generic_release (inode, file);
+                       goto err2;
 
                /*  empty event queue */
                fepriv->events.eventr = fepriv->events.eventw = 0;
        }
 
        return ret;
+
+err2:
+       dvb_generic_release(inode, file);
+err1:
+       if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
+               fe->ops.ts_bus_ctrl(fe, 0);
+       return ret;
 }
 
 static int dvb_frontend_release(struct inode *inode, struct file *file)
@@ -1096,16 +1100,18 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
        if ((file->f_flags & O_ACCMODE) != O_RDONLY)
                fepriv->release_jiffies = jiffies;
 
-       if (fe->ops.ts_bus_ctrl)
-               fe->ops.ts_bus_ctrl (fe, 0);
-
        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);
+       if (dvbdev->users == -1) {
+               if (fepriv->exit == 1) {
+                       fops_put(file->f_op);
+                       file->f_op = NULL;
+                       wake_up(&dvbdev->wait_queue);
+               }
+               if (fe->ops.ts_bus_ctrl)
+                       fe->ops.ts_bus_ctrl(fe, 0);
        }
+
        return ret;
 }