Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9759cccb authored by Karthik Dillibabu's avatar Karthik Dillibabu Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: core: validation of session/device/link handle



This change is to validate session, device and link handle.
Also, checks whether the device handle belongs to
correct session handle or not.

CRs-Fixed: 3496553
Change-Id: I6b86bf7d0908a280e90e085a3b3e1727facdf8c6
Signed-off-by: default avatarKarthik Dillibabu <quic_kard@quicinc.com>
parent e687fa9a
Loading
Loading
Loading
Loading
+44 −71
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include <linux/module.h>
@@ -2681,9 +2681,7 @@ static int cam_req_mgr_cb_add_req(struct cam_req_mgr_add_request *add_req)
		return -EINVAL;
	}

	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(add_req->link_hdl);

	link = cam_get_link_priv(add_req->link_hdl);
	if (!link) {
		CAM_DBG(CAM_CRM, "link ptr NULL %x", add_req->link_hdl);
		return -EINVAL;
@@ -2760,8 +2758,7 @@ static int cam_req_mgr_cb_notify_err(
		goto end;
	}

	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(err_info->link_hdl);
	link = cam_get_link_priv(err_info->link_hdl);
	if (!link) {
		CAM_DBG(CAM_CRM, "link ptr NULL %x", err_info->link_hdl);
		rc = -EINVAL;
@@ -2820,8 +2817,7 @@ static int cam_req_mgr_cb_notify_timer(
		goto end;
	}

	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(timer_data->link_hdl);
	link = cam_get_link_priv(timer_data->link_hdl);
	if (!link) {
		CAM_DBG(CAM_CRM, "link ptr NULL %x", timer_data->link_hdl);
		rc = -EINVAL;
@@ -2867,8 +2863,7 @@ static int cam_req_mgr_cb_notify_stop(
		goto end;
	}

	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(stop_info->link_hdl);
	link = cam_get_link_priv(stop_info->link_hdl);
	if (!link) {
		CAM_DBG(CAM_CRM, "link ptr NULL %x", stop_info->link_hdl);
		rc = -EINVAL;
@@ -2929,8 +2924,7 @@ static int cam_req_mgr_cb_notify_trigger(
		goto end;
	}

	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(trigger_data->link_hdl);
	link = cam_get_link_priv(trigger_data->link_hdl);
	if (!link) {
		CAM_DBG(CAM_CRM, "link ptr NULL %x", trigger_data->link_hdl);
		rc = -EINVAL;
@@ -3245,7 +3239,7 @@ static int __cam_req_mgr_unlink(struct cam_req_mgr_core_link *link)
	__cam_req_mgr_destroy_subdev(&link->l_dev);

	/* Destroy the link handle */
	rc = cam_destroy_device_hdl(link->link_hdl);
	rc = cam_destroy_link_hdl(link->link_hdl);
	if (rc < 0) {
		CAM_ERR(CAM_CRM, "error destroying link hdl %x rc %d",
			link->link_hdl, rc);
@@ -3271,11 +3265,9 @@ int cam_req_mgr_destroy_session(
	}

	mutex_lock(&g_crm_core_dev->crm_lock);
	cam_session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(ses_info->session_hdl);
	if (!cam_session ||
		(cam_session->session_hdl != ses_info->session_hdl)) {
		CAM_ERR(CAM_CRM, "ses:%s ses_info->ses_hdl:%x ses->ses_hdl:%x",
	cam_session = cam_get_session_priv(ses_info->session_hdl);
	if (!cam_session || (cam_session->session_hdl != ses_info->session_hdl)) {
		CAM_ERR(CAM_CRM, "session: %s, ses_info->ses_hdl:%x, session->ses_hdl:%x",
			CAM_IS_NULL_TO_STR(cam_session), ses_info->session_hdl,
			(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL :
					 cam_session->session_hdl);
@@ -3336,15 +3328,11 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
	mutex_lock(&g_crm_core_dev->crm_lock);

	/* session hdl's priv data is cam session struct */
	cam_session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(link_info->u.link_info_v1.session_hdl);
	if (!cam_session || (cam_session->session_hdl !=
				link_info->u.link_info_v1.session_hdl)) {
		CAM_ERR(CAM_CRM, "ses:%s lnk_info->ses_hdl:%x ses->ses_hdl:%x",
			CAM_IS_NULL_TO_STR(cam_session),
			link_info->u.link_info_v1.session_hdl,
			(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL :
					 cam_session->session_hdl);
	cam_session = cam_get_session_priv(link_info->u.link_info_v1.session_hdl);
	if (!cam_session || (cam_session->session_hdl != link_info->u.link_info_v1.session_hdl)) {
		CAM_ERR(CAM_CRM, "session: %s, link_info->ses_hdl:%x, session->ses_hdl:%x",
			CAM_IS_NULL_TO_STR(cam_session), link_info->u.link_info_v1.session_hdl,
			(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
		mutex_unlock(&g_crm_core_dev->crm_lock);
		return -EINVAL;
	}
@@ -3363,8 +3351,8 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
	root_dev.priv = (void *)link;
	root_dev.dev_id = CAM_CRM;
	mutex_lock(&link->lock);
	/* Create unique dev handle for link */
	link->link_hdl = cam_create_device_hdl(&root_dev);
	/* Create unique handle for link */
	link->link_hdl = cam_create_link_hdl(&root_dev);
	if (link->link_hdl < 0) {
		CAM_ERR(CAM_CRM,
			"Insufficient memory to create new device handle");
@@ -3418,7 +3406,7 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
setup_failed:
	__cam_req_mgr_destroy_subdev(&link->l_dev);
create_subdev_failed:
	cam_destroy_device_hdl(link->link_hdl);
	cam_destroy_link_hdl(link->link_hdl);
	link_info->u.link_info_v1.link_hdl = -1;
link_hdl_fail:
	mutex_unlock(&link->lock);
@@ -3450,15 +3438,11 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
	mutex_lock(&g_crm_core_dev->crm_lock);

	/* session hdl's priv data is cam session struct */
	cam_session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(link_info->u.link_info_v2.session_hdl);
	if (!cam_session || (cam_session->session_hdl !=
				link_info->u.link_info_v2.session_hdl)) {
		CAM_ERR(CAM_CRM, "ses:%s lnk_info->ses_hdl:%x ses->ses_hdl:%x",
			CAM_IS_NULL_TO_STR(cam_session),
			link_info->u.link_info_v2.session_hdl,
			(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL :
					 cam_session->session_hdl);
	cam_session = cam_get_session_priv(link_info->u.link_info_v2.session_hdl);
	if (!cam_session || (cam_session->session_hdl != link_info->u.link_info_v2.session_hdl)) {
		CAM_ERR(CAM_CRM, "session: %s, link_info->ses_hdl:%x, session->ses_hdl:%x",
			CAM_IS_NULL_TO_STR(cam_session), link_info->u.link_info_v2.session_hdl,
			(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
		mutex_unlock(&g_crm_core_dev->crm_lock);
		return -EINVAL;
	}
@@ -3478,8 +3462,8 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
	root_dev.dev_id = CAM_CRM;

	mutex_lock(&link->lock);
	/* Create unique dev handle for link */
	link->link_hdl = cam_create_device_hdl(&root_dev);
	/* Create unique handle for link */
	link->link_hdl = cam_create_link_hdl(&root_dev);
	if (link->link_hdl < 0) {
		CAM_ERR(CAM_CRM,
			"Insufficient memory to create new device handle");
@@ -3533,7 +3517,7 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
setup_failed:
	__cam_req_mgr_destroy_subdev(&link->l_dev);
create_subdev_failed:
	cam_destroy_device_hdl(link->link_hdl);
	cam_destroy_link_hdl(link->link_hdl);
	link_info->u.link_info_v2.link_hdl = -1;
link_hdl_fail:
	mutex_unlock(&link->lock);
@@ -3558,21 +3542,17 @@ int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info)
	CAM_DBG(CAM_CRM, "link_hdl %x", unlink_info->link_hdl);

	/* session hdl's priv data is cam session struct */
	cam_session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(unlink_info->session_hdl);
	if (!cam_session || (cam_session->session_hdl !=
				unlink_info->session_hdl)) {
		CAM_ERR(CAM_CRM, "ses:%s unlink->ses_hdl:%x ses->ses_hdl:%x",
			CAM_IS_NULL_TO_STR(cam_session),
			unlink_info->session_hdl,
			(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL :
					 cam_session->session_hdl);
	cam_session = cam_get_session_priv(unlink_info->session_hdl);
	if (!cam_session || (cam_session->session_hdl != unlink_info->session_hdl)) {
		CAM_ERR(CAM_CRM, "session: %s, unlink_info->ses_hdl:%x, cam_session->ses_hdl:%x",
			CAM_IS_NULL_TO_STR(cam_session), unlink_info->session_hdl,
			(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
		mutex_unlock(&g_crm_core_dev->crm_lock);
		return -EINVAL;
	}

	/* link hdl's priv data is core_link struct */
	link = cam_get_device_priv(unlink_info->link_hdl);
	link = cam_get_link_priv(unlink_info->link_hdl);
	if (!link || (link->link_hdl != unlink_info->link_hdl)) {
		CAM_ERR(CAM_CRM, "link:%s unlink->lnk_hdl:%x link->lnk_hdl:%x",
			CAM_IS_NULL_TO_STR(link), unlink_info->link_hdl,
@@ -3606,8 +3586,7 @@ int cam_req_mgr_schedule_request(
	}

	mutex_lock(&g_crm_core_dev->crm_lock);
	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(sched_req->link_hdl);
	link = cam_get_link_priv(sched_req->link_hdl);
	if (!link || (link->link_hdl != sched_req->link_hdl)) {
		CAM_ERR(CAM_CRM, "link:%s sched->lnk_hdl:%x link->lnk_hdl:%x",
			CAM_IS_NULL_TO_STR(link), sched_req->link_hdl,
@@ -3720,11 +3699,9 @@ int cam_req_mgr_sync_config(

	mutex_lock(&g_crm_core_dev->crm_lock);
	/* session hdl's priv data is cam session struct */
	cam_session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(sync_info->session_hdl);
	if (!cam_session ||
		(cam_session->session_hdl != sync_info->session_hdl)) {
		CAM_ERR(CAM_CRM, "ses:%s sync_info->ses_hdl:%x ses->ses_hdl:%x",
	cam_session = cam_get_session_priv(sync_info->session_hdl);
	if (!cam_session || (cam_session->session_hdl != sync_info->session_hdl)) {
		CAM_ERR(CAM_CRM, "session: %s, sync_info->session_hdl:%x, session->ses_hdl:%x",
			CAM_IS_NULL_TO_STR(cam_session), sync_info->session_hdl,
			(!cam_session) ?
			CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
@@ -3738,7 +3715,7 @@ int cam_req_mgr_sync_config(
		sync_info->link_hdls[0], sync_info->link_hdls[1]);

	/* only two links existing per session in dual cam use case*/
	link1 = cam_get_device_priv(sync_info->link_hdls[0]);
	link1 = cam_get_link_priv(sync_info->link_hdls[0]);
	if (!link1 || (link1->link_hdl != sync_info->link_hdls[0])) {
		CAM_ERR(CAM_CRM, "lnk:%s sync_info->lnk_hdl[0]:%x lnk1_hdl:%x",
			CAM_IS_NULL_TO_STR(link1), sync_info->link_hdls[0],
@@ -3748,7 +3725,7 @@ int cam_req_mgr_sync_config(
		goto done;
	}

	link2 = cam_get_device_priv(sync_info->link_hdls[1]);
	link2 = cam_get_link_priv(sync_info->link_hdls[1]);
	if (!link2 || (link2->link_hdl != sync_info->link_hdls[1])) {
		CAM_ERR(CAM_CRM, "lnk:%s sync_info->lnk_hdl[1]:%x lnk2_hdl:%x",
			CAM_IS_NULL_TO_STR(link2), sync_info->link_hdls[1],
@@ -3820,9 +3797,9 @@ int cam_req_mgr_flush_requests(
	}

	mutex_lock(&g_crm_core_dev->crm_lock);

	/* session hdl's priv data is cam session struct */
	session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(flush_info->session_hdl);
	session = cam_get_session_priv(flush_info->session_hdl);
	if (!session || (session->session_hdl != flush_info->session_hdl)) {
		CAM_ERR(CAM_CRM, "ses:%s flush->ses_hdl:%x ses->ses_hdl:%x",
			CAM_IS_NULL_TO_STR(session), flush_info->session_hdl,
@@ -3837,8 +3814,7 @@ int cam_req_mgr_flush_requests(
		goto end;
	}

	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(flush_info->link_hdl);
	link = cam_get_link_priv(flush_info->link_hdl);
	if (!link || (link->link_hdl != flush_info->link_hdl)) {
		CAM_ERR(CAM_CRM, "link:%s flush->link_hdl:%x link->link_hdl:%x",
			CAM_IS_NULL_TO_STR(link), flush_info->link_hdl,
@@ -3897,8 +3873,7 @@ int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control)

	mutex_lock(&g_crm_core_dev->crm_lock);
	for (i = 0; i < control->num_links; i++) {
		link = (struct cam_req_mgr_core_link *)
			cam_get_device_priv(control->link_hdls[i]);
		link = cam_get_link_priv(control->link_hdls[i]);
		if (!link || (link->link_hdl != control->link_hdls[i])) {
			CAM_ERR(CAM_CRM,
				"link:%s control->lnk_hdl:%x link->lnk_hdl:%x",
@@ -3977,8 +3952,7 @@ int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req)

	mutex_lock(&g_crm_core_dev->crm_lock);
	/* session hdl's priv data is cam session struct */
	session = (struct cam_req_mgr_core_session *)
	    cam_get_device_priv(dump_req->session_handle);
	session = cam_get_session_priv(dump_req->session_handle);
	if (!session || (session->session_hdl != dump_req->session_handle)) {
		CAM_ERR(CAM_CRM, "ses:%s dump_req->ses_hdl:%x ses->ses_hdl:%x",
			CAM_IS_NULL_TO_STR(session), dump_req->session_handle,
@@ -3993,8 +3967,7 @@ int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req)
		goto end;
	}

	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(dump_req->link_hdl);
	link = cam_get_link_priv(dump_req->link_hdl);
	if (!link || (link->link_hdl != dump_req->link_hdl)) {
		CAM_ERR(CAM_CRM, "link:%s dump_rq->lnk_hdl:%x link->lnk_hdl:%x",
			CAM_IS_NULL_TO_STR(link), dump_req->link_hdl,
+103 −18
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2021, 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__
@@ -36,28 +37,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:
@@ -124,6 +126,18 @@ 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,
			"session_hdl=%x hdl_value=%x type=%d state=%d dev_id=%lld",
			hdl_tbl->hdl[i].session_hdl, hdl_tbl->hdl[i].hdl_value,
			hdl_tbl->hdl[i].type, hdl_tbl->hdl[i].state, hdl_tbl->hdl[i].dev_id);
}

int32_t cam_create_session_hdl(void *priv)
{
	int idx;
@@ -139,7 +153,8 @@ 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;
	}
@@ -181,8 +196,8 @@ 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(idx= %d)", idx);
		CAM_ERR(CAM_CRM, "Unable to create device handle(idx= %d)", idx);
		cam_dump_tbl_info();
		spin_unlock_bh(&hdl_tbl_lock);
		return idx;
	}
@@ -202,7 +217,43 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
	return handle;
}

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;
	hdl_tbl->hdl[idx].dev_id = hdl_data->dev_id;
	spin_unlock_bh(&hdl_tbl_lock);

	CAM_DBG(CAM_CRM, "handle = %x", handle);
	return handle;
}

void *cam_get_priv(int32_t dev_hdl, int handle_type)
{
	int idx;
	int type;
@@ -216,18 +267,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) {
		CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid type");
	if (type != handle_type) {
		CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid type:%d", type);
		goto device_priv_fail;
	}

@@ -246,6 +297,34 @@ void *cam_get_device_priv(int32_t dev_hdl)
	return NULL;
}

void *cam_get_device_priv(int32_t dev_hdl)
{
	void *priv;

	priv = cam_get_priv(dev_hdl, HDL_TYPE_DEV);
	return 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;
}

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;
}

void *cam_get_device_ops(int32_t dev_hdl)
{
	int idx;
@@ -270,7 +349,7 @@ 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 (HDL_TYPE_DEV != type && HDL_TYPE_SESSION != type && HDL_TYPE_LINK != type) {
		CAM_ERR(CAM_CRM, "Invalid type");
		goto device_ops_fail;
	}
@@ -341,6 +420,12 @@ int cam_destroy_device_hdl(int32_t dev_hdl)
	return cam_destroy_hdl(dev_hdl, HDL_TYPE_DEV);
}

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);
}

int cam_destroy_session_hdl(int32_t dev_hdl)
{
	return cam_destroy_hdl(dev_hdl, HDL_TYPE_SESSION);
+50 −5
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#ifndef _CAM_REQ_MGR_UTIL_API_H_
@@ -9,6 +10,9 @@
#include <media/cam_req_mgr.h>
#include "cam_req_mgr_util_priv.h"

/* Interval for cam_info_rate_limit_custom() */
#define CAM_RATE_LIMIT_INTERVAL_5SEC 5

/**
 * state of a handle(session/device)
 * @HDL_FREE: free handle
@@ -21,12 +25,14 @@ enum hdl_state {

/**
 * handle type
 * @HDL_TYPE_DEV: for device and link
 * @HDL_TYPE_DEV: for device
 * @HDL_TYPE_SESSION: for session
 * @HDL_TYPE_LINK: for link
 */
enum hdl_type {
	HDL_TYPE_DEV = 1,
	HDL_TYPE_SESSION
	HDL_TYPE_SESSION,
	HDL_TYPE_LINK
};

/**
@@ -103,8 +109,19 @@ int32_t cam_create_session_hdl(void *priv);
int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data);

/**
 * cam_get_device_priv() - get private data of a handle
 * @dev_hdl: handle for a session/link/device
 * cam_create_link_hdl() - create a link handle
 * @hdl_data: session hdl, flags, ops and priv dara as input
 *
 * cam_req_mgr_core calls this function to get
 * session and link handles
 * KMD drivers calls this function to create
 * a link handle. Returns a unique link handle
 */
int32_t cam_create_link_hdl(struct cam_create_dev_hdl *hdl_data);

/**
 * cam_get_device_priv() - get private data of a device handle
 * @dev_hdl: handle for a device
 *
 * cam_req_mgr_core and KMD drivers use this function to
 * get private data of a handle. Returns a private data
@@ -112,6 +129,26 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data);
 */
void *cam_get_device_priv(int32_t dev_hdl);

/**
 * cam_get_session_priv() - get private data of a session handle
 * @dev_hdl: handle for a session
 *
 * cam_req_mgr_core and KMD drivers use this function to
 * get private data of a handle. Returns a private data
 * structure pointer.
 */
struct cam_req_mgr_core_session *cam_get_session_priv(int32_t dev_hdl);

/**
 * cam_get_link_priv() - get private data of a link handle
 * @dev_hdl: handle for a link
 *
 * cam_req_mgr_core and KMD drivers use this function to
 * get private data of a handle. Returns a private data
 * structure pointer.
 */
struct cam_req_mgr_core_link *cam_get_link_priv(int32_t dev_hdl);

/**
 * cam_get_device_ops() - get ops of a handle
 * @dev_hdl: handle for a session/link/device
@@ -123,12 +160,20 @@ void *cam_get_device_ops(int32_t dev_hdl);

/**
 * cam_destroy_device_hdl() - destroy device handle
 * @dev_hdl: handle for a link/device.
 * @dev_hdl: handle for a device.
 *
 * Returns success/failure
 */
int32_t cam_destroy_device_hdl(int32_t dev_hdl);

/**
 * cam_destroy_link_hdl() - destroy link handle
 * @dev_hdl: handle for a link.
 *
 * Returns success/failure
 */
int32_t cam_destroy_link_hdl(int32_t dev_hdl);

/**
 * cam_destroy_session_hdl() - destroy device handle
 * @dev_hdl: handle for a session