The patch number 12685 was added via Janne Grunau <j...@jannau.net>
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        Linux Media Mailing List <linux-me...@vger.kernel.org>

------

From: Janne Grunau  <j...@jannau.net>
dvb-core: check fe->ops.set_frontend return value


Various frontend driver have parameter checks in their set_frontend
functions and return an error if the parameters are not supported,
tda10021 and cx24116 to name two.

The tuning ioctls FE_SET_FRONTEND/FE_SET_PROPERTY only change values
in the property cache and return before set_frontend is called. If a
set_frontend call in software zigzag algorithm fails and the card was
previously locked it will report a lock and the new parameters but is
still tuned to the old transport. This is not detectable from
userspace.

This change checks the return values of fe->ops.set_frontend and
changes the state to the added FESTATE_ERROR for software zigzag.
No lock will be reported to userspace if the State is FESTATE_ERROR.

Priority: normal

Signed-off-by: Janne Grunau <j...@jannau.net>


---

 linux/drivers/media/dvb/dvb-core/dvb_frontend.c |   26 ++++++++++++----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff -r 496b71d9a1c0 -r 0d390214bc01 
linux/drivers/media/dvb/dvb-core/dvb_frontend.c
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c   Wed Sep 02 00:15:39 
2009 +0200
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c   Wed Sep 02 00:23:09 
2009 +0200
@@ -77,6 +77,7 @@
 #define FESTATE_ZIGZAG_FAST 32
 #define FESTATE_ZIGZAG_SLOW 64
 #define FESTATE_DISEQC 128
+#define FESTATE_ERROR 256
 #define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | 
FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC)
 #define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST)
 #define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
@@ -274,6 +275,7 @@
 {
        int autoinversion;
        int ready = 0;
+       int fe_set_err = 0;
        struct dvb_frontend_private *fepriv = fe->frontend_priv;
        int original_inversion = fepriv->parameters.inversion;
        u32 original_frequency = fepriv->parameters.frequency;
@@ -350,7 +352,11 @@
        if (autoinversion)
                fepriv->parameters.inversion = fepriv->inversion;
        if (fe->ops.set_frontend)
-               fe->ops.set_frontend(fe, &fepriv->parameters);
+               fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters);
+       if (fe_set_err < 0) {
+               fepriv->state = FESTATE_ERROR;
+               return fe_set_err;
+       }
 
        fepriv->parameters.frequency = original_frequency;
        fepriv->parameters.inversion = original_inversion;
@@ -362,6 +368,7 @@
 static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
 {
        fe_status_t s = 0;
+       int retval = 0;
        struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
        /* if we've got no parameters, just keep idling */
@@ -375,8 +382,12 @@
        if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) {
                if (fepriv->state & FESTATE_RETUNE) {
                        if (fe->ops.set_frontend)
-                               fe->ops.set_frontend(fe, &fepriv->parameters);
-                       fepriv->state = FESTATE_TUNED;
+                               retval = fe->ops.set_frontend(fe,
+                                                       &fepriv->parameters);
+                       if (retval < 0)
+                               fepriv->state = FESTATE_ERROR;
+                       else
+                               fepriv->state = FESTATE_TUNED;
                }
                fepriv->delay = 3*HZ;
                fepriv->quality = 0;
@@ -454,7 +465,11 @@
                fepriv->delay = fepriv->min_delay;
 
                /* peform a tune */
-               if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) {
+               retval = dvb_frontend_swzigzag_autotune(fe,
+                                                       fepriv->check_wrapped);
+               if (retval < 0) {
+                       return;
+               } else if (retval) {
                        /* OK, if we've run out of trials at the fast speed.
                         * Drop back to slow for the _next_ attempt */
                        fepriv->state = FESTATE_SEARCHING_SLOW;
@@ -1614,7 +1629,8 @@
 
                /* if retune was requested but hasn't occured yet, prevent
                 * that user get signal state from previous tuning */
-               if(fepriv->state == FESTATE_RETUNE) {
+               if (fepriv->state == FESTATE_RETUNE ||
+                   fepriv->state == FESTATE_ERROR) {
                        err=0;
                        *status = 0;
                        break;


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/0d390214bc015468de98d196c26ad3d45e1ecb9c

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to