diff options
Diffstat (limited to 'drivers/media/tuners')
-rw-r--r-- | drivers/media/tuners/e4000.c | 25 | ||||
-rw-r--r-- | drivers/media/tuners/fc0012.c | 2 | ||||
-rw-r--r-- | drivers/media/tuners/fc0013.c | 2 | ||||
-rw-r--r-- | drivers/media/tuners/fc2580.c | 25 | ||||
-rw-r--r-- | drivers/media/tuners/r820t.c | 22 | ||||
-rw-r--r-- | drivers/media/tuners/tda18212.c | 25 | ||||
-rw-r--r-- | drivers/media/tuners/tda18218.c | 23 | ||||
-rw-r--r-- | drivers/media/tuners/tda9887.c | 4 | ||||
-rw-r--r-- | drivers/media/tuners/tuner-xc2028.c | 12 |
9 files changed, 109 insertions, 31 deletions
diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index 6c96e489877..72971a8d3c3 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c @@ -21,20 +21,30 @@ #include "e4000_priv.h" #include <linux/math64.h> +/* Max transfer size done by I2C transfer functions */ +#define MAX_XFER_SIZE 64 + /* write multiple registers */ static int e4000_wr_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len) { int ret; - u8 buf[1 + len]; + u8 buf[MAX_XFER_SIZE]; struct i2c_msg msg[1] = { { .addr = priv->cfg->i2c_addr, .flags = 0, - .len = sizeof(buf), + .len = 1 + len, .buf = buf, } }; + if (1 + len > sizeof(buf)) { + dev_warn(&priv->i2c->dev, + "%s: i2c wr reg=%04x: len=%d is too big!\n", + KBUILD_MODNAME, reg, len); + return -EINVAL; + } + buf[0] = reg; memcpy(&buf[1], val, len); @@ -54,7 +64,7 @@ static int e4000_wr_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len) static int e4000_rd_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len) { int ret; - u8 buf[len]; + u8 buf[MAX_XFER_SIZE]; struct i2c_msg msg[2] = { { .addr = priv->cfg->i2c_addr, @@ -64,11 +74,18 @@ static int e4000_rd_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len) }, { .addr = priv->cfg->i2c_addr, .flags = I2C_M_RD, - .len = sizeof(buf), + .len = len, .buf = buf, } }; + if (len > sizeof(buf)) { + dev_warn(&priv->i2c->dev, + "%s: i2c rd reg=%04x: len=%d is too big!\n", + KBUILD_MODNAME, reg, len); + return -EINVAL; + } + ret = i2c_transfer(priv->i2c, msg, 2); if (ret == 2) { memcpy(val, buf, len); diff --git a/drivers/media/tuners/fc0012.c b/drivers/media/tuners/fc0012.c index f4d0e797a6c..d74e9205681 100644 --- a/drivers/media/tuners/fc0012.c +++ b/drivers/media/tuners/fc0012.c @@ -139,7 +139,7 @@ static int fc0012_set_params(struct dvb_frontend *fe) unsigned char reg[7], am, pm, multi, tmp; unsigned long f_vco; unsigned short xtal_freq_khz_2, xin, xdiv; - int vco_select = false; + bool vco_select = false; if (fe->callback) { ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, diff --git a/drivers/media/tuners/fc0013.c b/drivers/media/tuners/fc0013.c index bd8f0f1e8f3..b4162315773 100644 --- a/drivers/media/tuners/fc0013.c +++ b/drivers/media/tuners/fc0013.c @@ -233,7 +233,7 @@ static int fc0013_set_params(struct dvb_frontend *fe) unsigned char reg[7], am, pm, multi, tmp; unsigned long f_vco; unsigned short xtal_freq_khz_2, xin, xdiv; - int vco_select = false; + bool vco_select = false; if (fe->callback) { ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index 81f38aae9c6..3aecaf46509 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c @@ -20,6 +20,9 @@ #include "fc2580_priv.h" +/* Max transfer size done by I2C transfer functions */ +#define MAX_XFER_SIZE 64 + /* * TODO: * I2C write and read works only for one single register. Multiple registers @@ -41,16 +44,23 @@ static int fc2580_wr_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) { int ret; - u8 buf[1 + len]; + u8 buf[MAX_XFER_SIZE]; struct i2c_msg msg[1] = { { .addr = priv->cfg->i2c_addr, .flags = 0, - .len = sizeof(buf), + .len = 1 + len, .buf = buf, } }; + if (1 + len > sizeof(buf)) { + dev_warn(&priv->i2c->dev, + "%s: i2c wr reg=%04x: len=%d is too big!\n", + KBUILD_MODNAME, reg, len); + return -EINVAL; + } + buf[0] = reg; memcpy(&buf[1], val, len); @@ -69,7 +79,7 @@ static int fc2580_wr_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) static int fc2580_rd_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) { int ret; - u8 buf[len]; + u8 buf[MAX_XFER_SIZE]; struct i2c_msg msg[2] = { { .addr = priv->cfg->i2c_addr, @@ -79,11 +89,18 @@ static int fc2580_rd_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) }, { .addr = priv->cfg->i2c_addr, .flags = I2C_M_RD, - .len = sizeof(buf), + .len = len, .buf = buf, } }; + if (len > sizeof(buf)) { + dev_warn(&priv->i2c->dev, + "%s: i2c rd reg=%04x: len=%d is too big!\n", + KBUILD_MODNAME, reg, len); + return -EINVAL; + } + ret = i2c_transfer(priv->i2c, msg, 2); if (ret == 2) { memcpy(val, buf, len); diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c index 1c23666468c..d9ee43fae62 100644 --- a/drivers/media/tuners/r820t.c +++ b/drivers/media/tuners/r820t.c @@ -612,10 +612,19 @@ static int r820t_set_pll(struct r820t_priv *priv, enum v4l2_tuner_type type, vco_fine_tune = (data[4] & 0x30) >> 4; - if (vco_fine_tune > VCO_POWER_REF) - div_num = div_num - 1; - else if (vco_fine_tune < VCO_POWER_REF) - div_num = div_num + 1; + tuner_dbg("mix_div=%d div_num=%d vco_fine_tune=%d\n", + mix_div, div_num, vco_fine_tune); + + /* + * XXX: R828D/16MHz seems to have always vco_fine_tune=1. + * Due to that, this calculation goes wrong. + */ + if (priv->cfg->rafael_chip != CHIP_R828D) { + if (vco_fine_tune > VCO_POWER_REF) + div_num = div_num - 1; + else if (vco_fine_tune < VCO_POWER_REF) + div_num = div_num + 1; + } rc = r820t_write_reg_mask(priv, 0x10, div_num << 5, 0xe0); if (rc < 0) @@ -637,11 +646,6 @@ static int r820t_set_pll(struct r820t_priv *priv, enum v4l2_tuner_type type, vco_fra = pll_ref * 129 / 128; } - if (nint > 63) { - tuner_info("No valid PLL values for %u kHz!\n", freq); - return -EINVAL; - } - ni = (nint - 13) / 4; si = nint - 4 * ni - 13; diff --git a/drivers/media/tuners/tda18212.c b/drivers/media/tuners/tda18212.c index e4a84ee231c..abe256e1f84 100644 --- a/drivers/media/tuners/tda18212.c +++ b/drivers/media/tuners/tda18212.c @@ -20,6 +20,9 @@ #include "tda18212.h" +/* Max transfer size done by I2C transfer functions */ +#define MAX_XFER_SIZE 64 + struct tda18212_priv { struct tda18212_config *cfg; struct i2c_adapter *i2c; @@ -32,16 +35,23 @@ static int tda18212_wr_regs(struct tda18212_priv *priv, u8 reg, u8 *val, int len) { int ret; - u8 buf[len+1]; + u8 buf[MAX_XFER_SIZE]; struct i2c_msg msg[1] = { { .addr = priv->cfg->i2c_address, .flags = 0, - .len = sizeof(buf), + .len = 1 + len, .buf = buf, } }; + if (1 + len > sizeof(buf)) { + dev_warn(&priv->i2c->dev, + "%s: i2c wr reg=%04x: len=%d is too big!\n", + KBUILD_MODNAME, reg, len); + return -EINVAL; + } + buf[0] = reg; memcpy(&buf[1], val, len); @@ -61,7 +71,7 @@ static int tda18212_rd_regs(struct tda18212_priv *priv, u8 reg, u8 *val, int len) { int ret; - u8 buf[len]; + u8 buf[MAX_XFER_SIZE]; struct i2c_msg msg[2] = { { .addr = priv->cfg->i2c_address, @@ -71,11 +81,18 @@ static int tda18212_rd_regs(struct tda18212_priv *priv, u8 reg, u8 *val, }, { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, - .len = sizeof(buf), + .len = len, .buf = buf, } }; + if (len > sizeof(buf)) { + dev_warn(&priv->i2c->dev, + "%s: i2c rd reg=%04x: len=%d is too big!\n", + KBUILD_MODNAME, reg, len); + return -EINVAL; + } + ret = i2c_transfer(priv->i2c, msg, 2); if (ret == 2) { memcpy(val, buf, len); diff --git a/drivers/media/tuners/tda18218.c b/drivers/media/tuners/tda18218.c index 2d31aeb6b08..9300e9361e3 100644 --- a/drivers/media/tuners/tda18218.c +++ b/drivers/media/tuners/tda18218.c @@ -20,11 +20,14 @@ #include "tda18218_priv.h" +/* Max transfer size done by I2C transfer functions */ +#define MAX_XFER_SIZE 64 + /* write multiple registers */ static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len) { int ret = 0, len2, remaining; - u8 buf[1 + len]; + u8 buf[MAX_XFER_SIZE]; struct i2c_msg msg[1] = { { .addr = priv->cfg->i2c_address, @@ -33,6 +36,13 @@ static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len) } }; + if (1 + len > sizeof(buf)) { + dev_warn(&priv->i2c->dev, + "%s: i2c wr reg=%04x: len=%d is too big!\n", + KBUILD_MODNAME, reg, len); + return -EINVAL; + } + for (remaining = len; remaining > 0; remaining -= (priv->cfg->i2c_wr_max - 1)) { len2 = remaining; @@ -63,7 +73,7 @@ static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len) static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len) { int ret; - u8 buf[reg+len]; /* we must start read always from reg 0x00 */ + u8 buf[MAX_XFER_SIZE]; /* we must start read always from reg 0x00 */ struct i2c_msg msg[2] = { { .addr = priv->cfg->i2c_address, @@ -73,11 +83,18 @@ static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len) }, { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, - .len = sizeof(buf), + .len = reg + len, .buf = buf, } }; + if (reg + len > sizeof(buf)) { + dev_warn(&priv->i2c->dev, + "%s: i2c wr reg=%04x: len=%d is too big!\n", + KBUILD_MODNAME, reg, len); + return -EINVAL; + } + ret = i2c_transfer(priv->i2c, msg, 2); if (ret == 2) { memcpy(val, &buf[reg], len); diff --git a/drivers/media/tuners/tda9887.c b/drivers/media/tuners/tda9887.c index 300005c535b..9823248d743 100644 --- a/drivers/media/tuners/tda9887.c +++ b/drivers/media/tuners/tda9887.c @@ -536,8 +536,8 @@ static int tda9887_status(struct dvb_frontend *fe) unsigned char buf[1]; int rc; - memset(buf,0,sizeof(buf)); - if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,buf,1))) + rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, 1); + if (rc != 1) tuner_info("i2c i/o error: rc == %d (should be 1)\n", rc); dump_read_message(fe, buf); return 0; diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index 878d2c4d9e8..4be5cf808a4 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c @@ -24,6 +24,9 @@ #include <linux/dvb/frontend.h> #include "dvb_frontend.h" +/* Max transfer size done by I2C transfer functions */ +#define MAX_XFER_SIZE 80 + /* Registers (Write-only) */ #define XREG_INIT 0x00 #define XREG_RF_FREQ 0x02 @@ -547,7 +550,10 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, { struct xc2028_data *priv = fe->tuner_priv; int pos, rc; - unsigned char *p, *endp, buf[priv->ctrl.max_len]; + unsigned char *p, *endp, buf[MAX_XFER_SIZE]; + + if (priv->ctrl.max_len > sizeof(buf)) + priv->ctrl.max_len = sizeof(buf); tuner_dbg("%s called\n", __func__); @@ -572,7 +578,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, return -EINVAL; } - size = le16_to_cpu(*(__u16 *) p); + size = le16_to_cpu(*(__le16 *) p); p += sizeof(size); if (size == 0xffff) @@ -683,7 +689,7 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type, /* 16 SCODE entries per file; each SCODE entry is 12 bytes and * has a 2-byte size header in the firmware format. */ if (priv->firm[pos].size != 14 * 16 || scode >= 16 || - le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12) + le16_to_cpu(*(__le16 *)(p + 14 * scode)) != 12) return -EINVAL; p += 14 * scode + 2; } |