Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: cinergyT2: which kernel/usb module to use?



Hi Stefan,

Stefan Lucke wrote:

On Donnerstag, 2. Dezember 2004 22:38, Stefan Lucke wrote:


But there is to my opinion a race condition with FE_SET_FRONTEND and the query
function, as the latter is only called in 333ms intervals. So in between two
calls of cinergyt2_query() there may be a tuning call. If the status is the
same after 2nd query call, even a poll() may fail. So I set "stat->lock_bits=0;" after
calling cinergyt2_command() for tuning. But even with this change
I get vdr looping :-( .

Another point: in .._query() functions, calls to cinergy are protected by down_..() up() .
Issueing tuning commands is unprotected ;-) .

Finally I got the impression that this is a hardware problem and cinergyT2 in this
situation does not get a lock. So I have to return my cinergyT2s.

:) don't be too fast -- see below:

Code in cinergyt2_query now looks like:
printk("%s: entry: %d %s\n",__FUNCTION__, call_cnt++, (s->lock_bits & FE_HAS_LOCK)? "locked":"unlocked");
s->lock_bits|=FE_HAS_LOCK;
if (lock_bits != s->lock_bits) {
if (s->lock_bits & FE_HAS_LOCK)
printk ("NOW LOCKED ! \n");
cinergyt2->pending_fe_events++;
wake_up_interruptible(&cinergyt2->poll_wq);
}

and FE_SET_FRONTEND handling like:
down_interruptible(&cinergyt2->sem);

param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
param->tps = cpu_to_le16(compute_tps(&p));
param->freq = cpu_to_le32(p.frequency / 1000);
param->bandwidth = 8 - p.u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
stat->lock_bits=0;

Clearing the lock bits here makes no sense, this is only the local copy on the host side of the demod's status bits. The tuner locks just too fast for you (not really a bad thing IMHO - we're rather proud of this;)). The proper fix is much easier: simply increment the event counter and wake up the poll wait queue when setting parameters (like as if there were an event) and you're done...

err = cinergyt2_command(cinergyt2,
(char *) param, sizeof(*param),
NULL, 0);
up(&cinergyt2->sem);
printk ("FE_SET_FRONTEND\n");

As I set HAS_LOCK allways, vdr does not enter a loop, but still gets no data.
(forgot to say this is vdr-1.3.17).

like I said before, the FE_GET_EVENT approach has several non-trivial to resolve drawbacks, better fix the application not to use events, the GET_EVENT ioctl will vanish in the next API versions anyways (but for your problem the solution is much simpler, see above - ;).

Dec 3 06:53:00 jarada vdr[2000]: switching to channel 7
Dec 3 06:53:00 jarada vdr[2031]: transfer thread ended (pid=2031, tid=491526)
Dec 3 06:53:00 jarada vdr[2000]: buffer stats: 122476 (11%) used
Dec 3 06:53:00 jarada vdr[2034]: TS buffer on device 1 thread ended (pid=2034, tid=540681)
Dec 3 06:53:00 jarada vdr[2032]: buffer stats: 43616 (2%) used
Dec 3 06:53:00 jarada vdr[2032]: receiver on device 1 thread ended (pid=2032, tid=507911)
Dec 3 06:53:00 jarada vdr[2000]: buffer stats: 43992 (2%) used
Dec 3 06:53:00 jarada kernel: FE_SET_FRONTEND
Dec 3 06:53:01 jarada kernel: cinergyt2_query: entry: 148 unlocked
Dec 3 06:53:01 jarada kernel: NOW LOCKED !
Dec 3 06:53:01 jarada kernel: cinergyt2_query: entry: 149 unlocked
Dec 3 06:53:01 jarada kernel: cinergyt2_query: entry: 150 unlocked

As the workaround would be: switch to channel 24 and then to ch 7 which in
turn will not be realized in vdr, so I think it is a hardware problem.

Is there something in firmware which could be changed ?

Yes, the hardware is programmable and can get upgraded in the field (which we will do for USB1.1 support one day - ), but your problem is definitely not a hardware problem but the result of incredible performance; you really don't want us to degrade this, right?
;) enjoy,
please let me know if the approach outlined above works for you,
I can also prepare a patch for you if you like,

Holger





Home | Main Index | Thread Index