Merge tag 'LA.UM.9.12.1.r1-09700-SMxx50.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/camera-kernel into android13-4.19-kona
"LA.UM.9.12.1.r1-09700-SMxx50.QSSI12.0" * tag 'LA.UM.9.12.1.r1-09700-SMxx50.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/camera-kernel: msm: camera: icp: io buf config num validation msm: camera: sensor: TOCTOU error handling in eeprom msm: camera: sensor: TOCTOU error handling in eeprom msm: camera: memmgr: Remove the mutex lock for kref variable msm: camera: sensor: Handling race condition in util api msm: camera: memmgr: Add refcount to track umd in use buffers msm: camera: smmu: Use get_file to increase ref count msm: camera: sensor: Using low priority queue for init setting msm: camera: reqmgr: Increase V4L2 Queue depth Change-Id: I15be6929b7950eca0564c4cb76c407cb2d35261c
This commit is contained in:
@@ -4189,7 +4189,8 @@ static bool cam_icp_mgr_is_valid_outconfig(struct cam_packet *packet)
|
|||||||
packet->io_configs_offset/4);
|
packet->io_configs_offset/4);
|
||||||
|
|
||||||
for (i = 0 ; i < packet->num_io_configs; i++)
|
for (i = 0 ; i < packet->num_io_configs; i++)
|
||||||
if (io_cfg_ptr[i].direction == CAM_BUF_OUTPUT)
|
if ((io_cfg_ptr[i].direction == CAM_BUF_OUTPUT) ||
|
||||||
|
(io_cfg_ptr[i].direction == CAM_BUF_IN_OUT))
|
||||||
num_out_map_entries++;
|
num_out_map_entries++;
|
||||||
|
|
||||||
if (num_out_map_entries <= CAM_MAX_OUT_RES) {
|
if (num_out_map_entries <= CAM_MAX_OUT_RES) {
|
||||||
@@ -4342,10 +4343,17 @@ static int cam_icp_mgr_process_io_cfg(struct cam_icp_hw_mgr *hw_mgr,
|
|||||||
if (io_cfg_ptr[i].direction == CAM_BUF_INPUT) {
|
if (io_cfg_ptr[i].direction == CAM_BUF_INPUT) {
|
||||||
sync_in_obj[j++] = io_cfg_ptr[i].fence;
|
sync_in_obj[j++] = io_cfg_ptr[i].fence;
|
||||||
prepare_args->num_in_map_entries++;
|
prepare_args->num_in_map_entries++;
|
||||||
} else {
|
} else if ((io_cfg_ptr[i].direction == CAM_BUF_OUTPUT) ||
|
||||||
|
(io_cfg_ptr[i].direction == CAM_BUF_IN_OUT)) {
|
||||||
prepare_args->out_map_entries[k++].sync_id =
|
prepare_args->out_map_entries[k++].sync_id =
|
||||||
io_cfg_ptr[i].fence;
|
io_cfg_ptr[i].fence;
|
||||||
prepare_args->num_out_map_entries++;
|
prepare_args->num_out_map_entries++;
|
||||||
|
} else {
|
||||||
|
CAM_ERR(CAM_ICP, "dir: %d, max_out:%u, out %u",
|
||||||
|
io_cfg_ptr[i].direction,
|
||||||
|
prepare_args->max_out_map_entries,
|
||||||
|
prepare_args->num_out_map_entries);
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
CAM_DBG(CAM_REQ,
|
CAM_DBG(CAM_REQ,
|
||||||
"ctx_id: %u req_id: %llu dir[%d]: %u, fence: %u resource_type = %u memh %x",
|
"ctx_id: %u req_id: %llu dir[%d]: %u, fence: %u resource_type = %u memh %x",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@@ -201,6 +201,8 @@ static void cam_mem_put_slot(int32_t idx)
|
|||||||
mutex_lock(&tbl.m_lock);
|
mutex_lock(&tbl.m_lock);
|
||||||
mutex_lock(&tbl.bufq[idx].q_lock);
|
mutex_lock(&tbl.bufq[idx].q_lock);
|
||||||
tbl.bufq[idx].active = false;
|
tbl.bufq[idx].active = false;
|
||||||
|
kref_init(&tbl.bufq[idx].krefcount);
|
||||||
|
kref_init(&tbl.bufq[idx].urefcount);
|
||||||
mutex_unlock(&tbl.bufq[idx].q_lock);
|
mutex_unlock(&tbl.bufq[idx].q_lock);
|
||||||
mutex_destroy(&tbl.bufq[idx].q_lock);
|
mutex_destroy(&tbl.bufq[idx].q_lock);
|
||||||
clear_bit(idx, tbl.bitmap);
|
clear_bit(idx, tbl.bitmap);
|
||||||
@@ -290,8 +292,7 @@ int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr, size_t *len)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tbl.bufq[idx].kmdvaddr &&
|
if (tbl.bufq[idx].kmdvaddr && kref_get_unless_zero(&tbl.bufq[idx].krefcount)) {
|
||||||
kref_get_unless_zero(&tbl.bufq[idx].krefcount)) {
|
|
||||||
*vaddr_ptr = tbl.bufq[idx].kmdvaddr;
|
*vaddr_ptr = tbl.bufq[idx].kmdvaddr;
|
||||||
*len = tbl.bufq[idx].len;
|
*len = tbl.bufq[idx].len;
|
||||||
} else {
|
} else {
|
||||||
@@ -716,7 +717,12 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd)
|
|||||||
memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls,
|
memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls,
|
||||||
sizeof(int32_t) * cmd->num_hdl);
|
sizeof(int32_t) * cmd->num_hdl);
|
||||||
tbl.bufq[idx].is_imported = false;
|
tbl.bufq[idx].is_imported = false;
|
||||||
|
|
||||||
|
if (cmd->flags & CAM_MEM_FLAG_KMD_ACCESS)
|
||||||
kref_init(&tbl.bufq[idx].krefcount);
|
kref_init(&tbl.bufq[idx].krefcount);
|
||||||
|
|
||||||
|
kref_init(&tbl.bufq[idx].urefcount);
|
||||||
|
|
||||||
tbl.bufq[idx].smmu_mapping_client = CAM_SMMU_MAPPING_USER;
|
tbl.bufq[idx].smmu_mapping_client = CAM_SMMU_MAPPING_USER;
|
||||||
mutex_unlock(&tbl.bufq[idx].q_lock);
|
mutex_unlock(&tbl.bufq[idx].q_lock);
|
||||||
|
|
||||||
@@ -823,7 +829,9 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd)
|
|||||||
memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls,
|
memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls,
|
||||||
sizeof(int32_t) * cmd->num_hdl);
|
sizeof(int32_t) * cmd->num_hdl);
|
||||||
tbl.bufq[idx].is_imported = true;
|
tbl.bufq[idx].is_imported = true;
|
||||||
|
if (cmd->flags & CAM_MEM_FLAG_KMD_ACCESS)
|
||||||
kref_init(&tbl.bufq[idx].krefcount);
|
kref_init(&tbl.bufq[idx].krefcount);
|
||||||
|
kref_init(&tbl.bufq[idx].urefcount);
|
||||||
tbl.bufq[idx].smmu_mapping_client = CAM_SMMU_MAPPING_USER;
|
tbl.bufq[idx].smmu_mapping_client = CAM_SMMU_MAPPING_USER;
|
||||||
mutex_unlock(&tbl.bufq[idx].q_lock);
|
mutex_unlock(&tbl.bufq[idx].q_lock);
|
||||||
|
|
||||||
@@ -951,6 +959,8 @@ static int cam_mem_mgr_cleanup_table(void)
|
|||||||
tbl.bufq[i].num_hdl = 0;
|
tbl.bufq[i].num_hdl = 0;
|
||||||
tbl.bufq[i].dma_buf = NULL;
|
tbl.bufq[i].dma_buf = NULL;
|
||||||
tbl.bufq[i].active = false;
|
tbl.bufq[i].active = false;
|
||||||
|
kref_init(&tbl.bufq[i].krefcount);
|
||||||
|
kref_init(&tbl.bufq[i].urefcount);
|
||||||
mutex_unlock(&tbl.bufq[i].q_lock);
|
mutex_unlock(&tbl.bufq[i].q_lock);
|
||||||
mutex_destroy(&tbl.bufq[i].q_lock);
|
mutex_destroy(&tbl.bufq[i].q_lock);
|
||||||
}
|
}
|
||||||
@@ -975,16 +985,17 @@ void cam_mem_mgr_deinit(void)
|
|||||||
mutex_destroy(&tbl.m_lock);
|
mutex_destroy(&tbl.m_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cam_mem_util_unmap(struct kref *kref)
|
static void cam_mem_util_unmap_dummy(struct kref *kref)
|
||||||
|
{
|
||||||
|
CAM_DBG(CAM_MEM, "Cam mem util unmap dummy");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cam_mem_util_unmap(int32_t idx)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int32_t idx;
|
|
||||||
enum cam_smmu_region_id region = CAM_SMMU_REGION_SHARED;
|
enum cam_smmu_region_id region = CAM_SMMU_REGION_SHARED;
|
||||||
enum cam_smmu_mapping_client client;
|
enum cam_smmu_mapping_client client;
|
||||||
struct cam_mem_buf_queue *bufq =
|
|
||||||
container_of(kref, typeof(*bufq), krefcount);
|
|
||||||
|
|
||||||
idx = CAM_MEM_MGR_GET_HDL_IDX(bufq->buf_handle);
|
|
||||||
if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) {
|
if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) {
|
||||||
CAM_ERR(CAM_MEM, "Incorrect index");
|
CAM_ERR(CAM_MEM, "Incorrect index");
|
||||||
return;
|
return;
|
||||||
@@ -1055,6 +1066,8 @@ static void cam_mem_util_unmap(struct kref *kref)
|
|||||||
tbl.bufq[idx].len = 0;
|
tbl.bufq[idx].len = 0;
|
||||||
tbl.bufq[idx].num_hdl = 0;
|
tbl.bufq[idx].num_hdl = 0;
|
||||||
tbl.bufq[idx].active = false;
|
tbl.bufq[idx].active = false;
|
||||||
|
memset(&tbl.bufq[idx].krefcount, 0, sizeof(struct kref));
|
||||||
|
memset(&tbl.bufq[idx].urefcount, 0, sizeof(struct kref));
|
||||||
mutex_unlock(&tbl.bufq[idx].q_lock);
|
mutex_unlock(&tbl.bufq[idx].q_lock);
|
||||||
mutex_destroy(&tbl.bufq[idx].q_lock);
|
mutex_destroy(&tbl.bufq[idx].q_lock);
|
||||||
clear_bit(idx, tbl.bitmap);
|
clear_bit(idx, tbl.bitmap);
|
||||||
@@ -1062,10 +1075,27 @@ static void cam_mem_util_unmap(struct kref *kref)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cam_mem_util_unmap_wrapper(struct kref *kref)
|
||||||
|
{
|
||||||
|
int32_t idx;
|
||||||
|
struct cam_mem_buf_queue *bufq = container_of(kref, typeof(*bufq), krefcount);
|
||||||
|
|
||||||
|
idx = CAM_MEM_MGR_GET_HDL_IDX(bufq->buf_handle);
|
||||||
|
if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) {
|
||||||
|
CAM_ERR(CAM_MEM, "idx: %d not valid", idx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cam_mem_util_unmap(idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void cam_mem_put_cpu_buf(int32_t buf_handle)
|
void cam_mem_put_cpu_buf(int32_t buf_handle)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int idx;
|
int idx;
|
||||||
|
uint32_t krefcount = 0, urefcount = 0;
|
||||||
|
bool unmap = false;
|
||||||
|
|
||||||
if (!buf_handle) {
|
if (!buf_handle) {
|
||||||
CAM_ERR(CAM_MEM, "Invalid buf_handle");
|
CAM_ERR(CAM_MEM, "Invalid buf_handle");
|
||||||
@@ -1091,10 +1121,24 @@ void cam_mem_put_cpu_buf(int32_t buf_handle)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap))
|
kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap_dummy);
|
||||||
|
|
||||||
|
krefcount = kref_read(&tbl.bufq[idx].krefcount);
|
||||||
|
urefcount = kref_read(&tbl.bufq[idx].urefcount);
|
||||||
|
|
||||||
|
if ((krefcount == 1) && (urefcount == 0))
|
||||||
|
unmap = true;
|
||||||
|
|
||||||
|
if (unmap) {
|
||||||
|
cam_mem_util_unmap(idx);
|
||||||
CAM_DBG(CAM_MEM,
|
CAM_DBG(CAM_MEM,
|
||||||
"Called unmap from here, buf_handle: %u, idx: %d",
|
"Called unmap from here, buf_handle: %u, idx: %d", buf_handle, idx);
|
||||||
buf_handle, idx);
|
} else if (krefcount == 0) {
|
||||||
|
CAM_ERR(CAM_MEM,
|
||||||
|
"Unbalanced release Called buf_handle: %u, idx: %d",
|
||||||
|
tbl.bufq[idx].buf_handle, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(cam_mem_put_cpu_buf);
|
EXPORT_SYMBOL(cam_mem_put_cpu_buf);
|
||||||
@@ -1104,6 +1148,8 @@ int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd)
|
|||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
uint32_t krefcount = 0, urefcount = 0;
|
||||||
|
bool unmap = false;
|
||||||
|
|
||||||
if (!atomic_read(&cam_mem_mgr_state)) {
|
if (!atomic_read(&cam_mem_mgr_state)) {
|
||||||
CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized");
|
CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized");
|
||||||
@@ -1136,10 +1182,24 @@ int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd)
|
|||||||
|
|
||||||
CAM_DBG(CAM_MEM, "Releasing hdl = %x, idx = %d", cmd->buf_handle, idx);
|
CAM_DBG(CAM_MEM, "Releasing hdl = %x, idx = %d", cmd->buf_handle, idx);
|
||||||
|
|
||||||
if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap))
|
kref_put(&tbl.bufq[idx].urefcount, cam_mem_util_unmap_dummy);
|
||||||
|
|
||||||
|
urefcount = kref_read(&tbl.bufq[idx].urefcount);
|
||||||
|
|
||||||
|
if (tbl.bufq[idx].flags & CAM_MEM_FLAG_KMD_ACCESS) {
|
||||||
|
krefcount = kref_read(&tbl.bufq[idx].krefcount);
|
||||||
|
if ((krefcount == 1) && (urefcount == 0))
|
||||||
|
unmap = true;
|
||||||
|
} else {
|
||||||
|
if (urefcount == 0)
|
||||||
|
unmap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unmap) {
|
||||||
|
cam_mem_util_unmap(idx);
|
||||||
CAM_DBG(CAM_MEM,
|
CAM_DBG(CAM_MEM,
|
||||||
"Called unmap from here, buf_handle: %u, idx: %d",
|
"Called unmap from here, buf_handle: %u, idx: %d", cmd->buf_handle, idx);
|
||||||
cmd->buf_handle, idx);
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1321,7 +1381,7 @@ int cam_mem_mgr_release_mem(struct cam_mem_mgr_memory_desc *inp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CAM_DBG(CAM_MEM, "Releasing hdl = %X", inp->mem_handle);
|
CAM_DBG(CAM_MEM, "Releasing hdl = %X", inp->mem_handle);
|
||||||
if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap))
|
if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap_wrapper))
|
||||||
CAM_DBG(CAM_MEM,
|
CAM_DBG(CAM_MEM,
|
||||||
"Called unmap from here, buf_handle: %u, idx: %d",
|
"Called unmap from here, buf_handle: %u, idx: %d",
|
||||||
tbl.bufq[idx].buf_handle, idx);
|
tbl.bufq[idx].buf_handle, idx);
|
||||||
@@ -1501,7 +1561,7 @@ int cam_mem_mgr_free_memory_region(struct cam_mem_mgr_memory_desc *inp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CAM_DBG(CAM_MEM, "Releasing hdl = %X", inp->mem_handle);
|
CAM_DBG(CAM_MEM, "Releasing hdl = %X", inp->mem_handle);
|
||||||
if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap))
|
if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap_wrapper))
|
||||||
CAM_DBG(CAM_MEM,
|
CAM_DBG(CAM_MEM,
|
||||||
"Called unmap from here, buf_handle: %u, idx: %d",
|
"Called unmap from here, buf_handle: %u, idx: %d",
|
||||||
inp->mem_handle, idx);
|
inp->mem_handle, idx);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAM_MEM_MGR_H_
|
#ifndef _CAM_MEM_MGR_H_
|
||||||
@@ -44,8 +44,10 @@ enum cam_smmu_mapping_client {
|
|||||||
* @is_imported: Flag indicating if buffer is imported from an FD in user
|
* @is_imported: Flag indicating if buffer is imported from an FD in user
|
||||||
* space
|
* space
|
||||||
* @krefcount: Reference counter to track whether the buffer is
|
* @krefcount: Reference counter to track whether the buffer is
|
||||||
* mapped and in use
|
* mapped and in use by kmd
|
||||||
* @smmu_mapping_client: Client buffer (User or kernel)
|
* @smmu_mapping_client: Client buffer (User or kernel)
|
||||||
|
* @urefcount: Reference counter to track whether the buffer is
|
||||||
|
* mapped and in use by umd
|
||||||
*/
|
*/
|
||||||
struct cam_mem_buf_queue {
|
struct cam_mem_buf_queue {
|
||||||
struct dma_buf *dma_buf;
|
struct dma_buf *dma_buf;
|
||||||
@@ -63,6 +65,7 @@ struct cam_mem_buf_queue {
|
|||||||
bool is_imported;
|
bool is_imported;
|
||||||
struct kref krefcount;
|
struct kref krefcount;
|
||||||
enum cam_smmu_mapping_client smmu_mapping_client;
|
enum cam_smmu_mapping_client smmu_mapping_client;
|
||||||
|
struct kref urefcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@@ -418,6 +418,7 @@ static int32_t cam_eeprom_parse_memory_map(
|
|||||||
int32_t rc = 0;
|
int32_t rc = 0;
|
||||||
int32_t cnt = 0;
|
int32_t cnt = 0;
|
||||||
int32_t processed_size = 0;
|
int32_t processed_size = 0;
|
||||||
|
int32_t payload_count;
|
||||||
uint8_t generic_op_code;
|
uint8_t generic_op_code;
|
||||||
struct cam_eeprom_memory_map_t *map = data->map;
|
struct cam_eeprom_memory_map_t *map = data->map;
|
||||||
struct common_header *cmm_hdr =
|
struct common_header *cmm_hdr =
|
||||||
@@ -447,24 +448,25 @@ static int32_t cam_eeprom_parse_memory_map(
|
|||||||
switch (cmm_hdr->cmd_type) {
|
switch (cmm_hdr->cmd_type) {
|
||||||
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR:
|
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR:
|
||||||
i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf;
|
i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf;
|
||||||
|
payload_count = i2c_random_wr->header.count;
|
||||||
|
|
||||||
if (i2c_random_wr->header.count == 0 ||
|
if (payload_count == 0 ||
|
||||||
i2c_random_wr->header.count >= MSM_EEPROM_MAX_MEM_MAP_CNT ||
|
payload_count >= MSM_EEPROM_MAX_MEM_MAP_CNT ||
|
||||||
(size_t)*num_map >= ((MSM_EEPROM_MAX_MEM_MAP_CNT *
|
(size_t)*num_map >= ((MSM_EEPROM_MAX_MEM_MAP_CNT *
|
||||||
MSM_EEPROM_MEMORY_MAP_MAX_SIZE) -
|
MSM_EEPROM_MEMORY_MAP_MAX_SIZE) -
|
||||||
i2c_random_wr->header.count)) {
|
payload_count)) {
|
||||||
CAM_ERR(CAM_EEPROM, "OOB Error");
|
CAM_ERR(CAM_EEPROM, "OOB Error");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_random_wr) +
|
cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_random_wr) +
|
||||||
((i2c_random_wr->header.count - 1) *
|
((payload_count - 1) *
|
||||||
sizeof(struct i2c_random_wr_payload));
|
sizeof(struct i2c_random_wr_payload));
|
||||||
|
|
||||||
if (cmd_length_in_bytes > remain_buf_len) {
|
if (cmd_length_in_bytes > remain_buf_len) {
|
||||||
CAM_ERR(CAM_EEPROM, "Not enough buffer remaining");
|
CAM_ERR(CAM_EEPROM, "Not enough buffer remaining");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
for (cnt = 0; cnt < (i2c_random_wr->header.count);
|
for (cnt = 0; cnt < (payload_count);
|
||||||
cnt++) {
|
cnt++) {
|
||||||
map[*num_map + cnt].page.addr =
|
map[*num_map + cnt].page.addr =
|
||||||
i2c_random_wr->random_wr_payload[cnt].reg_addr;
|
i2c_random_wr->random_wr_payload[cnt].reg_addr;
|
||||||
@@ -477,16 +479,16 @@ static int32_t cam_eeprom_parse_memory_map(
|
|||||||
map[*num_map + cnt].page.valid_size = 1;
|
map[*num_map + cnt].page.valid_size = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*num_map += (i2c_random_wr->header.count - 1);
|
*num_map += (payload_count - 1);
|
||||||
cmd_buf += cmd_length_in_bytes / sizeof(int32_t);
|
|
||||||
processed_size +=
|
processed_size +=
|
||||||
cmd_length_in_bytes;
|
cmd_length_in_bytes;
|
||||||
break;
|
break;
|
||||||
case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD:
|
case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD:
|
||||||
i2c_cont_rd = (struct cam_cmd_i2c_continuous_rd *)cmd_buf;
|
i2c_cont_rd = (struct cam_cmd_i2c_continuous_rd *)cmd_buf;
|
||||||
cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd);
|
cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd);
|
||||||
|
payload_count = i2c_cont_rd->header.count;
|
||||||
|
|
||||||
if (i2c_cont_rd->header.count >= U32_MAX - data->num_data) {
|
if (payload_count >= U32_MAX - data->num_data) {
|
||||||
CAM_ERR(CAM_EEPROM,
|
CAM_ERR(CAM_EEPROM,
|
||||||
"int overflow on eeprom memory block");
|
"int overflow on eeprom memory block");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -495,8 +497,7 @@ static int32_t cam_eeprom_parse_memory_map(
|
|||||||
map[*num_map].mem.addr_type = i2c_cont_rd->header.addr_type;
|
map[*num_map].mem.addr_type = i2c_cont_rd->header.addr_type;
|
||||||
map[*num_map].mem.data_type = i2c_cont_rd->header.data_type;
|
map[*num_map].mem.data_type = i2c_cont_rd->header.data_type;
|
||||||
map[*num_map].mem.valid_size =
|
map[*num_map].mem.valid_size =
|
||||||
i2c_cont_rd->header.count;
|
payload_count;
|
||||||
cmd_buf += cmd_length_in_bytes / sizeof(int32_t);
|
|
||||||
processed_size +=
|
processed_size +=
|
||||||
cmd_length_in_bytes;
|
cmd_length_in_bytes;
|
||||||
data->num_data += map[*num_map].mem.valid_size;
|
data->num_data += map[*num_map].mem.valid_size;
|
||||||
@@ -1075,6 +1076,8 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl,
|
|||||||
{
|
{
|
||||||
struct cam_buf_io_cfg *io_cfg;
|
struct cam_buf_io_cfg *io_cfg;
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
size_t plane_offset;
|
||||||
|
int32_t mem_handle;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
uintptr_t buf_addr;
|
uintptr_t buf_addr;
|
||||||
size_t buf_size;
|
size_t buf_size;
|
||||||
@@ -1084,6 +1087,8 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl,
|
|||||||
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
|
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
|
||||||
&csl_packet->payload +
|
&csl_packet->payload +
|
||||||
csl_packet->io_configs_offset);
|
csl_packet->io_configs_offset);
|
||||||
|
plane_offset = io_cfg->offsets[0];
|
||||||
|
mem_handle = io_cfg->mem_handle[0];
|
||||||
|
|
||||||
CAM_DBG(CAM_EEPROM, "number of IO configs: %d:",
|
CAM_DBG(CAM_EEPROM, "number of IO configs: %d:",
|
||||||
csl_packet->num_io_configs);
|
csl_packet->num_io_configs);
|
||||||
@@ -1091,21 +1096,21 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl,
|
|||||||
for (i = 0; i < csl_packet->num_io_configs; i++) {
|
for (i = 0; i < csl_packet->num_io_configs; i++) {
|
||||||
CAM_DBG(CAM_EEPROM, "Direction: %d:", io_cfg->direction);
|
CAM_DBG(CAM_EEPROM, "Direction: %d:", io_cfg->direction);
|
||||||
if (io_cfg->direction == CAM_BUF_OUTPUT) {
|
if (io_cfg->direction == CAM_BUF_OUTPUT) {
|
||||||
rc = cam_mem_get_cpu_buf(io_cfg->mem_handle[0],
|
rc = cam_mem_get_cpu_buf(mem_handle,
|
||||||
&buf_addr, &buf_size);
|
&buf_addr, &buf_size);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR(CAM_EEPROM, "Fail in get buffer: %d",
|
CAM_ERR(CAM_EEPROM, "Fail in get buffer: %d",
|
||||||
rc);
|
rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if (buf_size <= io_cfg->offsets[0]) {
|
if (buf_size <= plane_offset) {
|
||||||
CAM_ERR(CAM_EEPROM, "Not enough buffer");
|
CAM_ERR(CAM_EEPROM, "Not enough buffer");
|
||||||
cam_mem_put_cpu_buf(io_cfg->mem_handle[0]);
|
cam_mem_put_cpu_buf(mem_handle);
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
remain_len = buf_size - io_cfg->offsets[0];
|
remain_len = buf_size - plane_offset;
|
||||||
CAM_DBG(CAM_EEPROM, "buf_addr : %pK, buf_size : %zu\n",
|
CAM_DBG(CAM_EEPROM, "buf_addr : %pK, buf_size : %zu\n",
|
||||||
(void *)buf_addr, buf_size);
|
(void *)buf_addr, buf_size);
|
||||||
|
|
||||||
@@ -1113,16 +1118,16 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl,
|
|||||||
if (!read_buffer) {
|
if (!read_buffer) {
|
||||||
CAM_ERR(CAM_EEPROM,
|
CAM_ERR(CAM_EEPROM,
|
||||||
"invalid buffer to copy data");
|
"invalid buffer to copy data");
|
||||||
cam_mem_put_cpu_buf(io_cfg->mem_handle[0]);
|
cam_mem_put_cpu_buf(mem_handle);
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
read_buffer += io_cfg->offsets[0];
|
read_buffer += plane_offset;
|
||||||
|
|
||||||
if (remain_len < e_ctrl->cal_data.num_data) {
|
if (remain_len < e_ctrl->cal_data.num_data) {
|
||||||
CAM_ERR(CAM_EEPROM,
|
CAM_ERR(CAM_EEPROM,
|
||||||
"failed to copy, Invalid size");
|
"failed to copy, Invalid size");
|
||||||
cam_mem_put_cpu_buf(io_cfg->mem_handle[0]);
|
cam_mem_put_cpu_buf(mem_handle);
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1131,7 +1136,7 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl,
|
|||||||
e_ctrl->cal_data.num_data);
|
e_ctrl->cal_data.num_data);
|
||||||
memcpy(read_buffer, e_ctrl->cal_data.mapdata,
|
memcpy(read_buffer, e_ctrl->cal_data.mapdata,
|
||||||
e_ctrl->cal_data.num_data);
|
e_ctrl->cal_data.num_data);
|
||||||
cam_mem_put_cpu_buf(io_cfg->mem_handle[0]);
|
cam_mem_put_cpu_buf(mem_handle);
|
||||||
} else {
|
} else {
|
||||||
CAM_ERR(CAM_EEPROM, "Invalid direction");
|
CAM_ERR(CAM_EEPROM, "Invalid direction");
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
|
|||||||
@@ -150,10 +150,11 @@ int32_t cam_sensor_handle_random_write(
|
|||||||
struct list_head **list)
|
struct list_head **list)
|
||||||
{
|
{
|
||||||
struct i2c_settings_list *i2c_list;
|
struct i2c_settings_list *i2c_list;
|
||||||
int32_t rc = 0, cnt;
|
int32_t rc = 0, cnt, payload_count;
|
||||||
|
|
||||||
|
payload_count = cam_cmd_i2c_random_wr->header.count;
|
||||||
i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings,
|
i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings,
|
||||||
cam_cmd_i2c_random_wr->header.count);
|
payload_count);
|
||||||
if (i2c_list == NULL ||
|
if (i2c_list == NULL ||
|
||||||
i2c_list->i2c_settings.reg_setting == NULL) {
|
i2c_list->i2c_settings.reg_setting == NULL) {
|
||||||
CAM_ERR(CAM_SENSOR, "Failed in allocating i2c_list");
|
CAM_ERR(CAM_SENSOR, "Failed in allocating i2c_list");
|
||||||
@@ -162,15 +163,14 @@ int32_t cam_sensor_handle_random_write(
|
|||||||
|
|
||||||
*cmd_length_in_bytes = (sizeof(struct i2c_rdwr_header) +
|
*cmd_length_in_bytes = (sizeof(struct i2c_rdwr_header) +
|
||||||
sizeof(struct i2c_random_wr_payload) *
|
sizeof(struct i2c_random_wr_payload) *
|
||||||
(cam_cmd_i2c_random_wr->header.count));
|
payload_count);
|
||||||
i2c_list->op_code = CAM_SENSOR_I2C_WRITE_RANDOM;
|
i2c_list->op_code = CAM_SENSOR_I2C_WRITE_RANDOM;
|
||||||
i2c_list->i2c_settings.addr_type =
|
i2c_list->i2c_settings.addr_type =
|
||||||
cam_cmd_i2c_random_wr->header.addr_type;
|
cam_cmd_i2c_random_wr->header.addr_type;
|
||||||
i2c_list->i2c_settings.data_type =
|
i2c_list->i2c_settings.data_type =
|
||||||
cam_cmd_i2c_random_wr->header.data_type;
|
cam_cmd_i2c_random_wr->header.data_type;
|
||||||
|
|
||||||
for (cnt = 0; cnt < (cam_cmd_i2c_random_wr->header.count);
|
for (cnt = 0; cnt < payload_count; cnt++) {
|
||||||
cnt++) {
|
|
||||||
i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
|
i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
|
||||||
cam_cmd_i2c_random_wr->random_wr_payload[cnt].reg_addr;
|
cam_cmd_i2c_random_wr->random_wr_payload[cnt].reg_addr;
|
||||||
i2c_list->i2c_settings.reg_setting[cnt].reg_data =
|
i2c_list->i2c_settings.reg_setting[cnt].reg_data =
|
||||||
@@ -190,10 +190,11 @@ static int32_t cam_sensor_handle_continuous_write(
|
|||||||
struct list_head **list)
|
struct list_head **list)
|
||||||
{
|
{
|
||||||
struct i2c_settings_list *i2c_list;
|
struct i2c_settings_list *i2c_list;
|
||||||
int32_t rc = 0, cnt;
|
int32_t rc = 0, cnt, payload_count;
|
||||||
|
|
||||||
|
payload_count = cam_cmd_i2c_continuous_wr->header.count;
|
||||||
i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings,
|
i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings,
|
||||||
cam_cmd_i2c_continuous_wr->header.count);
|
payload_count);
|
||||||
if (i2c_list == NULL ||
|
if (i2c_list == NULL ||
|
||||||
i2c_list->i2c_settings.reg_setting == NULL) {
|
i2c_list->i2c_settings.reg_setting == NULL) {
|
||||||
CAM_ERR(CAM_SENSOR, "Failed in allocating i2c_list");
|
CAM_ERR(CAM_SENSOR, "Failed in allocating i2c_list");
|
||||||
@@ -203,7 +204,7 @@ static int32_t cam_sensor_handle_continuous_write(
|
|||||||
*cmd_length_in_bytes = (sizeof(struct i2c_rdwr_header) +
|
*cmd_length_in_bytes = (sizeof(struct i2c_rdwr_header) +
|
||||||
sizeof(cam_cmd_i2c_continuous_wr->reg_addr) +
|
sizeof(cam_cmd_i2c_continuous_wr->reg_addr) +
|
||||||
sizeof(struct cam_cmd_read) *
|
sizeof(struct cam_cmd_read) *
|
||||||
(cam_cmd_i2c_continuous_wr->header.count));
|
(payload_count));
|
||||||
if (cam_cmd_i2c_continuous_wr->header.op_code ==
|
if (cam_cmd_i2c_continuous_wr->header.op_code ==
|
||||||
CAMERA_SENSOR_I2C_OP_CONT_WR_BRST)
|
CAMERA_SENSOR_I2C_OP_CONT_WR_BRST)
|
||||||
i2c_list->op_code = CAM_SENSOR_I2C_WRITE_BURST;
|
i2c_list->op_code = CAM_SENSOR_I2C_WRITE_BURST;
|
||||||
@@ -220,8 +221,7 @@ static int32_t cam_sensor_handle_continuous_write(
|
|||||||
i2c_list->i2c_settings.size =
|
i2c_list->i2c_settings.size =
|
||||||
cam_cmd_i2c_continuous_wr->header.count;
|
cam_cmd_i2c_continuous_wr->header.count;
|
||||||
|
|
||||||
for (cnt = 0; cnt < (cam_cmd_i2c_continuous_wr->header.count);
|
for (cnt = 0; cnt < payload_count; cnt++) {
|
||||||
cnt++) {
|
|
||||||
i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
|
i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
|
||||||
cam_cmd_i2c_continuous_wr->reg_addr;
|
cam_cmd_i2c_continuous_wr->reg_addr;
|
||||||
i2c_list->i2c_settings.reg_setting[cnt].reg_data =
|
i2c_list->i2c_settings.reg_setting[cnt].reg_data =
|
||||||
|
|||||||
Reference in New Issue
Block a user