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