Fabian Förg wrote:
> Hello,
>
> I realized that only one read access is possible to devices that use the
> cx88 driver.
> In my case it is a Hauppauge WinTV Nova-S-Plus DVB-S card.
> You can reproduce it with the following test:
> Launch femon concurrently two or more times. Only one femon is able to
> read from the card.
> Oliver Endriss confirmed that bug after looking in cx88-dvb.c.
> Usually, only one write access but an arbitrary amount of read accesses
> should be allowed.
Basically it's a bug in dvb_frontend.
ts_bus_ctrl() should only be called by
- the first open
- the last release
call.
Please try the attached patch.
@all:
Ok?
CU
Oliver
--
----------------------------------------------------------------
VDR Remote Plugin 0.3.9: http://www.escape-edv.de/endriss/vdr/
----------------------------------------------------------------
diff -r abb4c177bf6c linux/drivers/media/dvb/dvb-core/dvb_frontend.c
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c Wed Aug 22 00:46:48 2007 +0200
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c Thu Aug 23 01:13:49 2007 +0200
@@ -1061,18 +1061,15 @@ static int dvb_frontend_open(struct inod
dprintk ("%s\n", __FUNCTION__);
+ if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
+ if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
+ return ret;
+ }
+
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);
- return ret;
- }
- }
+ 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;
@@ -1080,13 +1077,20 @@ static int dvb_frontend_open(struct inod
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)
@@ -1101,16 +1105,18 @@ static int dvb_frontend_release(struct i
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;
}
_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb