]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
media: xc5000: better handle I2C error messages
authorMauro Carvalho Chehab <mchehab@s-opensource.com>
Wed, 1 Nov 2017 21:05:43 +0000 (17:05 -0400)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Mon, 11 Dec 2017 18:15:35 +0000 (13:15 -0500)
As warned by smatch, there are several places where the I2C
transfer may fail, leading into inconsistent behavior:

drivers/media/tuners/xc5000.c:689 xc_debug_dump() error: uninitialized symbol 'regval'.
drivers/media/tuners/xc5000.c:841 xc5000_is_firmware_loaded() error: uninitialized symbol 'id'.
drivers/media/tuners/xc5000.c:939 xc5000_set_tv_freq() error: uninitialized symbol 'pll_lock_status'.
drivers/media/tuners/xc5000.c:1195 xc_load_fw_and_init_tuner() error: uninitialized symbol 'pll_lock_status'.

Handle the return codes from the I2C transfer, in order to
address those issues.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/tuners/xc5000.c

index 0e7e4fdf9e50b72c0b3ce8bca7b5273c3040a4f4..98ba177dbc29b453326767f564f48b45d10c9dbb 100644 (file)
@@ -685,8 +685,8 @@ static void xc_debug_dump(struct xc5000_priv *priv)
                (totalgain % 256) * 100 / 256);
 
        if (priv->pll_register_no) {
-               xc5000_readreg(priv, priv->pll_register_no, &regval);
-               dprintk(1, "*** PLL lock status = 0x%04x\n", regval);
+               if (!xc5000_readreg(priv, priv->pll_register_no, &regval))
+                       dprintk(1, "*** PLL lock status = 0x%04x\n", regval);
        }
 }
 
@@ -831,15 +831,16 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
        u16 id;
 
        ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
-       if (ret == 0) {
+       if (!ret) {
                if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
                        ret = -ENOENT;
                else
                        ret = 0;
+               dprintk(1, "%s() returns id = 0x%x\n", __func__, id);
+       } else {
+               dprintk(1, "%s() returns error %d\n", __func__, ret);
        }
 
-       dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
-               ret == 0 ? "True" : "False", id);
        return ret;
 }
 
@@ -935,7 +936,10 @@ static int xc5000_set_tv_freq(struct dvb_frontend *fe)
 
        if (priv->pll_register_no != 0) {
                msleep(20);
-               xc5000_readreg(priv, priv->pll_register_no, &pll_lock_status);
+               ret = xc5000_readreg(priv, priv->pll_register_no,
+                                    &pll_lock_status);
+               if (ret)
+                       return ret;
                if (pll_lock_status > 63) {
                        /* PLL is unlocked, force reload of the firmware */
                        dprintk(1, "xc5000: PLL not locked (0x%x).  Reloading...\n",
@@ -1190,8 +1194,10 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
                }
 
                if (priv->pll_register_no) {
-                       xc5000_readreg(priv, priv->pll_register_no,
-                                      &pll_lock_status);
+                       ret = xc5000_readreg(priv, priv->pll_register_no,
+                                            &pll_lock_status);
+                       if (ret)
+                               continue;
                        if (pll_lock_status > 63) {
                                /* PLL is unlocked, force reload of the firmware */
                                printk(KERN_ERR