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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html