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@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb