aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorChris Rankin <rankincj@yahoo.com>2012-04-06 17:38:18 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-04-09 08:41:34 -0400
commit556a0442e08a8bc8541587a349cbf26ed14ec6de (patch)
treebfa92fdc8e06bcf3d20d759f18dae84574b92c9e /drivers/media
parent7483d45f0aee3afc0646d185cabd4af9f6cab58c (diff)
[media] dvb_frontend: regression fix: userspace ABI broken for xine
The commit e399ce77e6e has broken the DVB ABI for xine: The problem is that xine is expecting every event after a successful FE_SET_FRONTEND ioctl to have a non-zero frequency parameter, regardless of whether the tuning process has LOCKed yet. What used to happen is that the events inherited the initial tuning parameters from the FE_SET_FRONTEND call. However, the fepriv->parameters_out struct is now not initialised until the status contains the FE_HAS_LOCK bit. You might argue that this behaviour is intentional, except that if an application other than xine uses the DVB adapter and manages to set the parameters_out.frequency field to something other than zero, then xine no longer has any problems until either the adapter is replugged or the kernel modules reloaded. This can only mean that the fepriv->parameters_out struct still contains the (stale) tuning information from the previous application. Signed-off-by: Chris Rankin <rankincj@yahoo.com> Cc: stable@kernel.org # for kernel version 3.3 Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 4555baa383b2..e721975476b0 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -143,6 +143,8 @@ struct dvb_frontend_private {
143static void dvb_frontend_wakeup(struct dvb_frontend *fe); 143static void dvb_frontend_wakeup(struct dvb_frontend *fe);
144static int dtv_get_frontend(struct dvb_frontend *fe, 144static int dtv_get_frontend(struct dvb_frontend *fe,
145 struct dvb_frontend_parameters *p_out); 145 struct dvb_frontend_parameters *p_out);
146static int dtv_property_legacy_params_sync(struct dvb_frontend *fe,
147 struct dvb_frontend_parameters *p);
146 148
147static bool has_get_frontend(struct dvb_frontend *fe) 149static bool has_get_frontend(struct dvb_frontend *fe)
148{ 150{
@@ -697,6 +699,7 @@ restart:
697 fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; 699 fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
698 fepriv->delay = HZ / 2; 700 fepriv->delay = HZ / 2;
699 } 701 }
702 dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);
700 fe->ops.read_status(fe, &s); 703 fe->ops.read_status(fe, &s);
701 if (s != fepriv->status) { 704 if (s != fepriv->status) {
702 dvb_frontend_add_event(fe, s); /* update event list */ 705 dvb_frontend_add_event(fe, s); /* update event list */
@@ -1833,6 +1836,13 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
1833 return -EINVAL; 1836 return -EINVAL;
1834 1837
1835 /* 1838 /*
1839 * Initialize output parameters to match the values given by
1840 * the user. FE_SET_FRONTEND triggers an initial frontend event
1841 * with status = 0, which copies output parameters to userspace.
1842 */
1843 dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);
1844
1845 /*
1836 * Be sure that the bandwidth will be filled for all 1846 * Be sure that the bandwidth will be filled for all
1837 * non-satellite systems, as tuners need to know what 1847 * non-satellite systems, as tuners need to know what
1838 * low pass/Nyquist half filter should be applied, in 1848 * low pass/Nyquist half filter should be applied, in