Em 15-01-2012 19:47, Antti Palosaari escreveu:
> On 01/15/2012 11:08 PM, Mauro Carvalho Chehab wrote:
>> There was a bug at the error code handling on dvb-fe-tool: basically, if it 
>> can't open
>> a device, it were using a NULL pointer. It was likely fixed by this commit:
>>
>> http://git.linuxtv.org/v4l-utils.git/commit/1f669eed5433d17df4d8fb1fa43d2886f99d3991
> 
> That bug was fixed as I tested.
> 
> But could you tell why dvb-fe-tool --set-delsys=DVBC/ANNEX_A calls 
> get_frontent() ?

That's what happens here, at the application level:

$ strace dvb-fe-tool -d DVBC/ANNEX_A

open("/dev/dvb/adapter0/frontend0", O_RDWR) = 3
ioctl(3, FE_GET_INFO, 0xb070c4)         = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0x7f37922be000
write(1, "Device DRXK DVB-C DVB-T (/dev/dv"..., 68Device DRXK DVB-C DVB-T 
(/dev/dvb/adapter0/frontend0) capabilities:
) = 68
write(1, "\tCAN_FEC_1_2 CAN_FEC_2_3 CAN_FEC"..., 245    CAN_FEC_1_2 CAN_FEC_2_3 
CAN_FEC_3_4 CAN_FEC_5_6 CAN_FEC_7_8 CAN_FEC_AUTO CAN_GUARD_INTERVAL_AUTO 
CAN_HIERARCHY_AUTO CAN_INVERSION_AUTO CAN_MUTE_TS CAN_QAM_16 CAN_QAM_32 
CAN_QAM_64 CAN_QAM_128 CAN_QAM_256 CAN_RECOVER CAN_TRANSMISSION_MODE_AUTO 
) = 245
ioctl(3, FE_GET_PROPERTY, 0x7fff326ce310) = 0
write(1, "DVB API Version 5.5, Current v5 "..., 54DVB API Version 5.5, Current 
v5 delivery system: DVBT
) = 54
ioctl(3, FE_GET_PROPERTY, 0x7fff326ce310) = 0
write(1, "Supported delivery systems: DVBC"..., 62Supported delivery systems: 
DVBC/ANNEX_A DVBC/ANNEX_C [DVBT] 
) = 62
write(1, "Changing delivery system to: DVB"..., 42Changing delivery system to: 
DVBC/ANNEX_A
) = 42
ioctl(3, FE_SET_PROPERTY, 0x7fff326ce340) = 0
close(3)                                = 0
exit_group(0)                           = ?


The first FE_GET_PROPERTY reads the DVB API version and the current delivery
system:

        parms->dvb_prop[0].cmd = DTV_API_VERSION;
        parms->dvb_prop[1].cmd = DTV_DELIVERY_SYSTEM;

        dtv_prop.num = 2;
        dtv_prop.props = parms->dvb_prop;

        /* Detect a DVBv3 device */
        if (ioctl(fd, FE_GET_PROPERTY, &dtv_prop) == -1) {
                parms->dvb_prop[0].u.data = 0x300;
                parms->dvb_prop[1].u.data = SYS_UNDEFINED;
        }
        parms->version = parms->dvb_prop[0].u.data;
        parms->current_sys = parms->dvb_prop[1].u.data;

The second FE_GET_PROPERTY is used only if DVB API v5.5 or upper is detected,
and does:

                parms->dvb_prop[0].cmd = DTV_ENUM_DELSYS;
                parms->n_props = 1;
                dtv_prop.num = 1;
                dtv_prop.props = parms->dvb_prop;
                if (ioctl(fd, FE_GET_PROPERTY, &dtv_prop) == -1) {
                        perror("FE_GET_PROPERTY");
                        dvb_v5_free(parms);
                        close(fd);
                        return NULL;
                }

Both were called inside dvb_fe_open().

The FE_SET_PROPERTY changes the property inside the DVBv5 cache,
at dvb_set_sys():

                dvb_prop[0].cmd = DTV_DELIVERY_SYSTEM;
                dvb_prop[0].u.data = sys;
                prop.num = 1;
                prop.props = dvb_prop;

                if (ioctl(parms->fd, FE_SET_PROPERTY, &prop) == -1) {
                        perror("Set delivery system");
                        return errno;
                }

The FE_SET_PROPERTY doesn't call a DTV_TUNE, so it shouldn't be calling the
set frontend methods inside the driver.

So, from the userspace applications standpoint, I'm not seeing anything wrong.

> That will cause this kind of calls in demod driver:
> init()
> get_frontend()
> get_frontend()
> sleep()
> 
> My guess is that it resolves current delivery system. But as demod is usually 
> sleeping (not tuned) at that phase it does not know frontend settings asked, 
> like modulation etc. In case of cxd2820r those are available after 
> set_frontend() call. I think I will add check and return -EINVAL in that case.


What seems to be happening at dvb-core/dvb_frontend.h is due to this code:

if(cmd == FE_GET_PROPERTY) {
...
                /*
                 * Fills the cache out struct with the cache contents, plus
                 * the data retrieved from get_frontend.
                 */
                dtv_get_frontend(fe, NULL);
                for (i = 0; i < tvps->num; i++) {
                        err = dtv_property_process_get(fe, c, tvp + i, file);
                        if (err < 0)
                                goto out;
                        (tvp + i)->result = err;
                }

E. g. even if the FE_GET_PROPERTY is only reading the DVB version and calling
DTV_ENUM_DELSYS, it is calling the dtv_get_frontend() to retrieve more data.

What it can be done is to do something like:

static bool need_get_frontend()
{
...
        for (i = 0; i < tvps->num; i++)
...
}

                if (need_get_frontend(tvps))
                        dtv_get_frontend(fe, NULL);
                for (i = 0; i < tvps->num; i++) {
                        err = dtv_property_process_get(fe, c, tvp + i, file);
                        if (err < 0)
                                goto out;
                        (tvp + i)->result = err;
                }

And add some logic inside need_get_frontend() to return false if the
FE_GET_PROPERTY only wants static info, like DTV_ENUM_DELSYS, DTV_VERSION
and DTV_DELIVERY_SYSTEM.

Regards,
Mauro.
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to