mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 09:02:00 +00:00
[media] dvb_frontend: Don't let drivers to trash data at cache
GET_FRONTEND and G_PROPERTY can be called anytime, even when the tuner/demod is not fully locked. However, several parameters returned by those calls are available only after the demod get VITERBI lock. While several drivers do the right thing by checking the status before returning the parameter, some drivers simply blindly update the DTV properties cache without checking if the registers at the hardware contain valid values. Due to that, programs that call G_PROPERTY (or GET_FRONTEND) before having a tuner lock may interfere at the zigzag logic, as the DVB kthread calls the set_frontend() callback several times, to fine tune the frequency and to identify if the signal is inverted or not. While the drivers should be fixed to report the right status, we should prevent that such bugs would actually interfere at the device operation. So, let's use a separate var for userspace calls to get frontend. As we copy the content of the cache, this should not cause any troubles. Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
7e3e68bcfd
commit
bb31d2381c
@ -2087,6 +2087,8 @@ static int dvb_frontend_ioctl_properties(struct file *file,
|
||||
dev_dbg(fe->dvb->device, "%s: Property cache is full, tuning\n", __func__);
|
||||
|
||||
} else if (cmd == FE_GET_PROPERTY) {
|
||||
struct dtv_frontend_properties getp = fe->dtv_property_cache;
|
||||
|
||||
dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
|
||||
dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
|
||||
|
||||
@ -2108,17 +2110,18 @@ static int dvb_frontend_ioctl_properties(struct file *file,
|
||||
}
|
||||
|
||||
/*
|
||||
* Fills the cache out struct with the cache contents, plus
|
||||
* the data retrieved from get_frontend, if the frontend
|
||||
* is not idle. Otherwise, returns the cached content
|
||||
* Let's use our own copy of property cache, in order to
|
||||
* avoid mangling with DTV zigzag logic, as drivers might
|
||||
* return crap, if they don't check if the data is available
|
||||
* before updating the properties cache.
|
||||
*/
|
||||
if (fepriv->state != FESTATE_IDLE) {
|
||||
err = dtv_get_frontend(fe, c, NULL);
|
||||
err = dtv_get_frontend(fe, &getp, NULL);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < tvps->num; i++) {
|
||||
err = dtv_property_process_get(fe, c, tvp + i, file);
|
||||
err = dtv_property_process_get(fe, &getp, tvp + i, file);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
(tvp + i)->result = err;
|
||||
@ -2523,10 +2526,18 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
|
||||
err = dvb_frontend_get_event (fe, parg, file->f_flags);
|
||||
break;
|
||||
|
||||
case FE_GET_FRONTEND:
|
||||
err = dtv_get_frontend(fe, c, parg);
|
||||
break;
|
||||
case FE_GET_FRONTEND: {
|
||||
struct dtv_frontend_properties getp = fe->dtv_property_cache;
|
||||
|
||||
/*
|
||||
* Let's use our own copy of property cache, in order to
|
||||
* avoid mangling with DTV zigzag logic, as drivers might
|
||||
* return crap, if they don't check if the data is available
|
||||
* before updating the properties cache.
|
||||
*/
|
||||
err = dtv_get_frontend(fe, &getp, parg);
|
||||
break;
|
||||
}
|
||||
case FE_SET_FRONTEND_TUNE_MODE:
|
||||
fepriv->tune_mode_flags = (unsigned long) parg;
|
||||
err = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user