diff options
Diffstat (limited to 'drivers/cam_req_mgr/cam_req_mgr_util.c')
-rw-r--r-- | drivers/cam_req_mgr/cam_req_mgr_util.c | 126 |
1 files changed, 110 insertions, 16 deletions
diff --git a/drivers/cam_req_mgr/cam_req_mgr_util.c b/drivers/cam_req_mgr/cam_req_mgr_util.c index a1a5da3..9fded8d 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_util.c +++ b/drivers/cam_req_mgr/cam_req_mgr_util.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #define pr_fmt(fmt) "CAM-REQ-MGR_UTIL %s:%d " fmt, __func__, __LINE__ @@ -35,28 +36,29 @@ int cam_req_mgr_util_init(void) rc = -ENOMEM; goto hdl_tbl_alloc_failed; } + bitmap_size = BITS_TO_LONGS(CAM_REQ_MGR_MAX_HANDLES_V2) * sizeof(long); + hdl_tbl_local->bitmap = kzalloc(bitmap_size, GFP_KERNEL); + if (!hdl_tbl_local->bitmap) { + rc = -ENOMEM; + goto bitmap_alloc_fail; + } + hdl_tbl_local->bits = bitmap_size * BITS_PER_BYTE; + spin_lock_bh(&hdl_tbl_lock); if (hdl_tbl) { spin_unlock_bh(&hdl_tbl_lock); rc = -EEXIST; + kfree(hdl_tbl_local->bitmap); kfree(hdl_tbl_local); goto hdl_tbl_check_failed; } hdl_tbl = hdl_tbl_local; spin_unlock_bh(&hdl_tbl_lock); - bitmap_size = BITS_TO_LONGS(CAM_REQ_MGR_MAX_HANDLES_V2) * sizeof(long); - hdl_tbl->bitmap = kzalloc(bitmap_size, GFP_KERNEL); - if (!hdl_tbl->bitmap) { - rc = -ENOMEM; - goto bitmap_alloc_fail; - } - hdl_tbl->bits = bitmap_size * BITS_PER_BYTE; - return rc; bitmap_alloc_fail: - kfree(hdl_tbl); + kfree(hdl_tbl_local); hdl_tbl = NULL; hdl_tbl_alloc_failed: hdl_tbl_check_failed: @@ -121,6 +123,19 @@ static int32_t cam_get_free_handle_index(void) return idx; } +static void cam_dump_tbl_info(void) +{ + int i; + + for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES_V2; i++) + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_CRM, + CAM_RATE_LIMIT_INTERVAL_5SEC, + CAM_REQ_MGR_MAX_HANDLES_V2, + "ses_hdl=%x hdl_value=%x type=%d state=%d", + hdl_tbl->hdl[i].session_hdl, hdl_tbl->hdl[i].hdl_value, + hdl_tbl->hdl[i].type, hdl_tbl->hdl[i].state); +} + int32_t cam_create_session_hdl(void *priv) { int idx; @@ -136,7 +151,9 @@ int32_t cam_create_session_hdl(void *priv) idx = cam_get_free_handle_index(); if (idx < 0) { - CAM_ERR(CAM_CRM, "Unable to create session handle"); + CAM_ERR(CAM_CRM, "Unable to create session handle(idx = %d)", + idx); + cam_dump_tbl_info(); spin_unlock_bh(&hdl_tbl_lock); return idx; } @@ -169,7 +186,9 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) idx = cam_get_free_handle_index(); if (idx < 0) { - CAM_ERR(CAM_CRM, "Unable to create device handle"); + CAM_ERR(CAM_CRM, "Unable to create device handle(idx= %d)", + idx); + cam_dump_tbl_info(); spin_unlock_bh(&hdl_tbl_lock); return idx; } @@ -189,7 +208,43 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) } EXPORT_SYMBOL_GPL(cam_create_device_hdl); -void *cam_get_device_priv(int32_t dev_hdl) +int32_t cam_create_link_hdl(struct cam_create_dev_hdl *hdl_data) +{ + int idx; + int rand = 0; + int32_t handle; + + spin_lock_bh(&hdl_tbl_lock); + if (!hdl_tbl) { + CAM_ERR(CAM_CRM, "Hdl tbl is NULL"); + spin_unlock_bh(&hdl_tbl_lock); + return -EINVAL; + } + + idx = cam_get_free_handle_index(); + if (idx < 0) { + CAM_ERR(CAM_CRM, "Unable to create link handle(idx = %d)", idx); + cam_dump_tbl_info(); + spin_unlock_bh(&hdl_tbl_lock); + return idx; + } + + get_random_bytes(&rand, CAM_REQ_MGR_RND1_BYTES); + handle = GET_DEV_HANDLE(rand, HDL_TYPE_LINK, idx); + hdl_tbl->hdl[idx].session_hdl = hdl_data->session_hdl; + hdl_tbl->hdl[idx].hdl_value = handle; + hdl_tbl->hdl[idx].type = HDL_TYPE_LINK; + hdl_tbl->hdl[idx].state = HDL_ACTIVE; + hdl_tbl->hdl[idx].priv = hdl_data->priv; + hdl_tbl->hdl[idx].ops = NULL; + spin_unlock_bh(&hdl_tbl_lock); + + CAM_DBG(CAM_CRM, "handle = %x", handle); + return handle; +} +EXPORT_SYMBOL_GPL(cam_create_link_hdl); + +void *cam_get_priv(int32_t dev_hdl, int handle_type) { int idx; int type; @@ -203,17 +258,18 @@ void *cam_get_device_priv(int32_t dev_hdl) idx = CAM_REQ_MGR_GET_HDL_IDX(dev_hdl); if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2) { - CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid idx"); + CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid idx: %d", idx); goto device_priv_fail; } if (hdl_tbl->hdl[idx].state != HDL_ACTIVE) { - CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid state"); + CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid state: %d", + hdl_tbl->hdl[idx].state); goto device_priv_fail; } type = CAM_REQ_MGR_GET_HDL_TYPE(dev_hdl); - if (HDL_TYPE_DEV != type && HDL_TYPE_SESSION != type) { + if (HDL_TYPE_DEV != type && HDL_TYPE_SESSION != type && HDL_TYPE_LINK != type) { CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid type"); goto device_priv_fail; } @@ -232,8 +288,38 @@ device_priv_fail: spin_unlock_bh(&hdl_tbl_lock); return NULL; } + +void *cam_get_device_priv(int32_t dev_hdl) +{ + void *priv; + + priv = cam_get_priv(dev_hdl, HDL_TYPE_DEV); + return priv; +} EXPORT_SYMBOL_GPL(cam_get_device_priv); +struct cam_req_mgr_core_session *cam_get_session_priv(int32_t dev_hdl) +{ + struct cam_req_mgr_core_session *priv; + + priv = (struct cam_req_mgr_core_session *) + cam_get_priv(dev_hdl, HDL_TYPE_SESSION); + + return priv; +} +EXPORT_SYMBOL_GPL(cam_get_session_priv); + +struct cam_req_mgr_core_link *cam_get_link_priv(int32_t dev_hdl) +{ + struct cam_req_mgr_core_link *priv; + + priv = (struct cam_req_mgr_core_link *) + cam_get_priv(dev_hdl, HDL_TYPE_LINK); + + return priv; +} +EXPORT_SYMBOL_GPL(cam_get_link_priv); + void *cam_get_device_ops(int32_t dev_hdl) { int idx; @@ -258,7 +344,8 @@ void *cam_get_device_ops(int32_t dev_hdl) } type = CAM_REQ_MGR_GET_HDL_TYPE(dev_hdl); - if (HDL_TYPE_DEV != type && HDL_TYPE_SESSION != type) { + if (type != HDL_TYPE_DEV && type != HDL_TYPE_SESSION && + type != HDL_TYPE_LINK) { CAM_ERR(CAM_CRM, "Invalid type"); goto device_ops_fail; } @@ -330,6 +417,13 @@ int cam_destroy_device_hdl(int32_t dev_hdl) } EXPORT_SYMBOL_GPL(cam_destroy_device_hdl); +int cam_destroy_link_hdl(int32_t dev_hdl) +{ + CAM_DBG(CAM_CRM, "handle = %x", dev_hdl); + return cam_destroy_hdl(dev_hdl, HDL_TYPE_LINK); +} +EXPORT_SYMBOL_GPL(cam_destroy_link_hdl); + int cam_destroy_session_hdl(int32_t dev_hdl) { return cam_destroy_hdl(dev_hdl, HDL_TYPE_SESSION); |