Calling get_frontend() before having either the frontend locked or the network signaling carriers locked won't work. So, block it at the DVB core. Signed-off-by: Mauro Carvalho Chehab <mchehab@xxxxxxxxxx> --- drivers/media/dvb/dvb-core/dvb_frontend.c | 50 ++++++++++++++-------------- 1 files changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index fbbe545..a15c4ed 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -144,11 +144,6 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe); static int dtv_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p_out); -static bool has_get_frontend(struct dvb_frontend *fe) -{ - return fe->ops.get_frontend; -} - /* * Due to DVBv3 API calls, a delivery system should be mapped into one of * the 4 DVBv3 delivery systems (FE_QPSK, FE_QAM, FE_OFDM or FE_ATSC), @@ -207,8 +202,12 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) dprintk ("%s\n", __func__); - if ((status & FE_HAS_LOCK) && has_get_frontend(fe)) - dtv_get_frontend(fe, &fepriv->parameters_out); + /* FE_HAS_LOCK implies that the frontend has parameters */ + if (status & FE_HAS_LOCK) + status |= FE_HAS_PARAMETERS; + + fepriv->status = status; + dtv_get_frontend(fe, &fepriv->parameters_out); mutex_lock(&events->mtx); @@ -465,7 +464,6 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) fe->ops.read_status(fe, &s); if (s != fepriv->status) { dvb_frontend_add_event(fe, s); - fepriv->status = s; } } @@ -663,7 +661,6 @@ restart: if (s != fepriv->status && !(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT)) { dprintk("%s: state changed, adding current state\n", __func__); dvb_frontend_add_event(fe, s); - fepriv->status = s; } break; case DVBFE_ALGO_SW: @@ -698,7 +695,6 @@ restart: fe->ops.read_status(fe, &s); if (s != fepriv->status) { dvb_frontend_add_event(fe, s); /* update event list */ - fepriv->status = s; if (!(s & FE_HAS_LOCK)) { fepriv->delay = HZ / 10; fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; @@ -1213,18 +1209,26 @@ static int dtv_property_legacy_params_sync(struct dvb_frontend *fe, static int dtv_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p_out) { + struct dvb_frontend_private *fepriv = fe->frontend_priv; int r; - if (fe->ops.get_frontend) { - r = fe->ops.get_frontend(fe); - if (unlikely(r < 0)) - return r; - if (p_out) - dtv_property_legacy_params_sync(fe, p_out); - return 0; + /* + * If the frontend is not locked, the transmission information + * is not available. So, there's no sense on calling the frontend + * to get anything, as all it has is what is already inside the + * cache. + */ + if (fepriv->status & FE_HAS_PARAMETERS) { + if (fe->ops.get_frontend) { + r = fe->ops.get_frontend(fe); + if (unlikely(r < 0)) + return r; + } } + if (p_out) + dtv_property_legacy_params_sync(fe, p_out); - /* As everything is in cache, get_frontend fops are always supported */ + /* As everything is in cache, get_frontend is always supported */ return 0; } @@ -1725,7 +1729,6 @@ static int dvb_frontend_ioctl_properties(struct file *file, { struct dvb_device *dvbdev = file->private_data; struct dvb_frontend *fe = dvbdev->priv; - struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int err = 0; @@ -1795,11 +1798,9 @@ static int dvb_frontend_ioctl_properties(struct file *file, * the data retrieved from get_frontend, if the frontend * is not idle. Otherwise, returns the cached content */ - if (fepriv->state != FESTATE_IDLE) { - err = dtv_get_frontend(fe, NULL); - if (err < 0) - goto out; - } + err = dtv_get_frontend(fe, NULL); + if (err < 0) + goto out; for (i = 0; i < tvps->num; i++) { err = dtv_property_process_get(fe, c, tvp + i, file); if (err < 0) @@ -1922,7 +1923,6 @@ static int dtv_set_frontend(struct dvb_frontend *fe) dvb_frontend_clear_events(fe); dvb_frontend_add_event(fe, 0); dvb_frontend_wakeup(fe); - fepriv->status = 0; return 0; } -- 1.7.8 -- 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