From 2b1050b49a9a5f7bb57006648d145e001a3eaa8b Mon Sep 17 00:00:00 2001 From: Hariram Purushothaman Date: Wed, 31 Jul 2013 14:30:36 -0700 Subject: msm: camera: Fix various small issues in cci driver Remove some unused ioctl exposed, Also add some bound checks for ioctl user params. Change-Id: Ifdd441fdb25fd20b005c4e4e1ebe4e203f1216ac CRs-Fixed: 511382 Signed-off-by: Hariram Purushothaman --- .../platform/msm/camera_v2/sensor/cci/msm_cci.c | 101 +++++++++++++-------- include/media/msm_cam_sensor.h | 2 + 2 files changed, 63 insertions(+), 40 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c index 7f4f231..6beb92e 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c @@ -41,6 +41,9 @@ /* Max bytes that can be read per CCI read transaction */ #define CCI_READ_MAX 12 +#define CCI_I2C_READ_MAX_RETRIES 3 +#define CCI_I2C_MAX_READ 8192 +#define CCI_I2C_MAX_WRITE 8192 static struct v4l2_subdev *g_cci_subdev; @@ -87,36 +90,6 @@ static void msm_cci_set_clk_param(struct cci_device *cci_dev) return; } -static int32_t msm_cci_i2c_config_sync_timer(struct v4l2_subdev *sd, - struct msm_camera_cci_ctrl *c_ctrl) -{ - struct cci_device *cci_dev; - cci_dev = v4l2_get_subdevdata(sd); - msm_camera_io_w(c_ctrl->cci_info->cid, cci_dev->base + - CCI_SET_CID_SYNC_TIMER_0_ADDR + (c_ctrl->cci_info->cid * 0x4)); - return 0; -} - -static int32_t msm_cci_i2c_set_freq(struct v4l2_subdev *sd, - struct msm_camera_cci_ctrl *c_ctrl) -{ - struct cci_device *cci_dev; - uint32_t val; - cci_dev = v4l2_get_subdevdata(sd); - val = c_ctrl->cci_info->freq; - msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SCL_CTL_ADDR + - c_ctrl->cci_info->cci_i2c_master*0x100); - msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_0_ADDR + - c_ctrl->cci_info->cci_i2c_master*0x100); - msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_1_ADDR + - c_ctrl->cci_info->cci_i2c_master*0x100); - msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_2_ADDR + - c_ctrl->cci_info->cci_i2c_master*0x100); - msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR + - c_ctrl->cci_info->cci_i2c_master*0x100); - return 0; -} - static void msm_cci_flush_queue(struct cci_device *cci_dev, enum cci_i2c_master_t master) { @@ -213,8 +186,29 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, uint16_t cmd_size = i2c_msg->size; struct msm_camera_i2c_reg_conf *i2c_cmd = i2c_msg->reg_conf_tbl; enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master; + + if (i2c_cmd == NULL) { + pr_err("%s:%d Failed line\n", __func__, + __LINE__); + return -EINVAL; + } + + if ((!cmd_size) || (cmd_size > CCI_I2C_MAX_WRITE)) { + pr_err("%s:%d Failed line\n", __func__, __LINE__); + return -EINVAL; + } + CDBG("%s addr type %d data type %d\n", __func__, i2c_msg->addr_type, i2c_msg->data_type); + + if (i2c_msg->addr_type >= MSM_CAMERA_I2C_ADDR_TYPE_MAX) { + pr_err("%s failed line %d\n", __func__, __LINE__); + return -EINVAL; + } + if (i2c_msg->data_type >= MSM_CAMERA_I2C_DATA_TYPE_MAX) { + pr_err("%s failed line %d\n", __func__, __LINE__); + return -EINVAL; + } /* assume total size within the max queue */ while (cmd_size) { CDBG("%s cmd_size %d addr 0x%x data 0x%x", __func__, @@ -321,6 +315,18 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd, goto ERROR; } + if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) { + pr_err("%s:%d More than max retries\n", __func__, + __LINE__); + goto ERROR; + } + + if (read_cfg->data == NULL) { + pr_err("%s:%d Data ptr is NULL\n", __func__, + __LINE__); + goto ERROR; + } + CDBG("%s master %d, queue %d\n", __func__, master, queue); CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__, c_ctrl->cci_info->sid, c_ctrl->cci_info->retries, @@ -341,6 +347,11 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd, goto ERROR; } + if (read_cfg->addr_type >= MSM_CAMERA_I2C_ADDR_TYPE_MAX) { + CDBG("%s failed line %d\n", __func__, __LINE__); + goto ERROR; + } + if (read_cfg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4) | ((read_cfg->addr & 0xFF) << 8); @@ -454,9 +465,14 @@ static int32_t msm_cci_i2c_read_bytes(struct v4l2_subdev *sd, return -EINVAL; } + if (c_ctrl->cci_info->cci_i2c_master > MASTER_MAX) { + pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__); + return -EINVAL; + } + master = c_ctrl->cci_info->cci_i2c_master; read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg; - if (!read_cfg->num_byte) { + if ((!read_cfg->num_byte) || (read_cfg->num_byte > CCI_I2C_MAX_READ)) { pr_err("%s:%d read num bytes 0\n", __func__, __LINE__); rc = -EINVAL; goto ERROR; @@ -494,6 +510,10 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd, enum cci_i2c_master_t master; enum cci_i2c_queue_t queue = QUEUE_0; cci_dev = v4l2_get_subdevdata(sd); + if (c_ctrl->cci_info->cci_i2c_master > MASTER_MAX) { + pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__); + return -EINVAL; + } master = c_ctrl->cci_info->cci_i2c_master; CDBG("%s master %d, queue %d\n", __func__, master, queue); CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__, @@ -514,6 +534,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd, __LINE__, rc); goto ERROR; } + if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) { + pr_err("%s:%d More than max retries\n", __func__, + __LINE__); + goto ERROR; + } val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 | c_ctrl->cci_info->retries << 16 | @@ -533,7 +558,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd, goto ERROR; } - msm_cci_data_queue(cci_dev, c_ctrl, queue); + rc = msm_cci_data_queue(cci_dev, c_ctrl, queue); + if (rc < 0) { + CDBG("%s failed line %d\n", __func__, __LINE__); + goto ERROR; + } val = CCI_I2C_UNLOCK_CMD; CDBG("%s:%d CCI_I2C_UNLOCK_CMD\n", __func__, __LINE__); rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue); @@ -703,14 +732,6 @@ static int32_t msm_cci_config(struct v4l2_subdev *sd, case MSM_CCI_RELEASE: rc = msm_cci_release(sd); break; - case MSM_CCI_SET_SID: - break; - case MSM_CCI_SET_FREQ: - rc = msm_cci_i2c_set_freq(sd, cci_ctrl); - break; - case MSM_CCI_SET_SYNC_CID: - rc = msm_cci_i2c_config_sync_timer(sd, cci_ctrl); - break; case MSM_CCI_I2C_READ: rc = msm_cci_i2c_read_bytes(sd, cci_ctrl); break; diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h index 2805401..da16bb8 100644 --- a/include/media/msm_cam_sensor.h +++ b/include/media/msm_cam_sensor.h @@ -52,6 +52,7 @@ enum msm_camera_i2c_reg_addr_type { MSM_CAMERA_I2C_BYTE_ADDR = 1, MSM_CAMERA_I2C_WORD_ADDR, MSM_CAMERA_I2C_3B_ADDR, + MSM_CAMERA_I2C_ADDR_TYPE_MAX, }; enum msm_camera_i2c_data_type { @@ -62,6 +63,7 @@ enum msm_camera_i2c_data_type { MSM_CAMERA_I2C_SET_WORD_MASK, MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA, + MSM_CAMERA_I2C_DATA_TYPE_MAX, }; enum msm_sensor_power_seq_type_t { -- cgit v1.1