Loading drivers/soc/qcom/memshare/heap_mem_ext_v01.c +11 −134 Original line number Diff line number Diff line Loading @@ -11,133 +11,10 @@ * */ #include <linux/qmi_encdec.h> #include <soc/qcom/msm_qmi_interface.h> #include <linux/soc/qcom/qmi.h> #include "heap_mem_ext_v01.h" struct elem_info mem_alloc_req_msg_data_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(uint32_t), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct mem_alloc_req_msg_v01, num_bytes), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(uint8_t), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct mem_alloc_req_msg_v01, block_alignment_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(uint32_t), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct mem_alloc_req_msg_v01, block_alignment), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct elem_info mem_alloc_resp_msg_data_v01_ei[] = { { .data_type = QMI_SIGNED_2_BYTE_ENUM, .elem_len = 1, .elem_size = sizeof(uint16_t), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct mem_alloc_resp_msg_v01, resp), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(uint8_t), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct mem_alloc_resp_msg_v01, handle_valid), }, { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, .elem_size = sizeof(uint64_t), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct mem_alloc_resp_msg_v01, handle), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(uint8_t), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct mem_alloc_resp_msg_v01, num_bytes_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(uint32_t), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct mem_alloc_resp_msg_v01, num_bytes), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct elem_info mem_free_req_msg_data_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, .elem_size = sizeof(uint64_t), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct mem_free_req_msg_v01, handle), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct elem_info mem_free_resp_msg_data_v01_ei[] = { { .data_type = QMI_SIGNED_2_BYTE_ENUM, .elem_len = 1, .elem_size = sizeof(uint16_t), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct mem_free_resp_msg_v01, resp), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct elem_info dhms_mem_alloc_addr_info_type_v01_ei[] = { struct qmi_elem_info dhms_mem_alloc_addr_info_type_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, Loading Loading @@ -165,7 +42,7 @@ struct elem_info dhms_mem_alloc_addr_info_type_v01_ei[] = { }, }; struct elem_info mem_alloc_generic_req_msg_data_v01_ei[] = { struct qmi_elem_info mem_alloc_generic_req_msg_data_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, Loading Loading @@ -245,7 +122,7 @@ struct elem_info mem_alloc_generic_req_msg_data_v01_ei[] = { }, }; struct elem_info mem_alloc_generic_resp_msg_data_v01_ei[] = { struct qmi_elem_info mem_alloc_generic_resp_msg_data_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, Loading @@ -255,7 +132,7 @@ struct elem_info mem_alloc_generic_resp_msg_data_v01_ei[] = { .offset = offsetof(struct mem_alloc_generic_resp_msg_v01, resp), .ei_array = get_qmi_response_type_v01_ei(), .ei_array = qmi_response_type_v01_ei, }, { .data_type = QMI_OPT_FLAG, Loading Loading @@ -316,7 +193,7 @@ struct elem_info mem_alloc_generic_resp_msg_data_v01_ei[] = { }, }; struct elem_info mem_free_generic_req_msg_data_v01_ei[] = { struct qmi_elem_info mem_free_generic_req_msg_data_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, Loading Loading @@ -380,7 +257,7 @@ struct elem_info mem_free_generic_req_msg_data_v01_ei[] = { }, }; struct elem_info mem_free_generic_resp_msg_data_v01_ei[] = { struct qmi_elem_info mem_free_generic_resp_msg_data_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, Loading @@ -390,7 +267,7 @@ struct elem_info mem_free_generic_resp_msg_data_v01_ei[] = { .offset = offsetof(struct mem_free_generic_resp_msg_v01, resp), .ei_array = get_qmi_response_type_v01_ei(), .ei_array = qmi_response_type_v01_ei, }, { .data_type = QMI_EOTI, Loading @@ -399,7 +276,7 @@ struct elem_info mem_free_generic_resp_msg_data_v01_ei[] = { }, }; struct elem_info mem_query_size_req_msg_data_v01_ei[] = { struct qmi_elem_info mem_query_size_req_msg_data_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, Loading Loading @@ -434,7 +311,7 @@ struct elem_info mem_query_size_req_msg_data_v01_ei[] = { }, }; struct elem_info mem_query_size_resp_msg_data_v01_ei[] = { struct qmi_elem_info mem_query_size_resp_msg_data_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, Loading @@ -444,7 +321,7 @@ struct elem_info mem_query_size_resp_msg_data_v01_ei[] = { .offset = offsetof(struct mem_query_size_rsp_msg_v01, resp), .ei_array = get_qmi_response_type_v01_ei(), .ei_array = qmi_response_type_v01_ei, }, { .data_type = QMI_OPT_FLAG, Loading drivers/soc/qcom/memshare/heap_mem_ext_v01.h +8 −92 Original line number Diff line number Diff line Loading @@ -14,10 +14,11 @@ #ifndef HEAP_MEM_EXT_SERVICE_01_H #define HEAP_MEM_EXT_SERVICE_01_H #include <soc/qcom/msm_qmi_interface.h> #include <linux/soc/qcom/qmi.h> #define MEM_ALLOC_REQ_MAX_MSG_LEN_V01 255 #define MEM_FREE_REQ_MAX_MSG_LEN_V01 255 #define MEM_QUERY_MAX_MSG_LEN_V01 255 #define MAX_ARR_CNT_V01 64 struct dhms_mem_alloc_addr_info_type_v01 { Loading Loading @@ -82,83 +83,6 @@ enum dhms_mem_block_align_enum_v01 { */ }; /* Request Message; This command is used for getting * the multiple physically contiguous * memory blocks from the server memory subsystem */ struct mem_alloc_req_msg_v01 { /* Mandatory */ /*requested size*/ uint32_t num_bytes; /* Optional */ /* Must be set to true if block_alignment * is being passed */ uint8_t block_alignment_valid; /* The block alignment for the memory block to be allocated */ enum dhms_mem_block_align_enum_v01 block_alignment; }; /* Message */ /* Response Message; This command is used for getting * the multiple physically contiguous memory blocks * from the server memory subsystem */ struct mem_alloc_resp_msg_v01 { /* Mandatory */ /* Result Code */ /* The result of the requested memory operation */ enum qmi_result_type_v01 resp; /* Optional */ /* Memory Block Handle */ /* Must be set to true if handle is being passed */ uint8_t handle_valid; /* The physical address of the memory allocated on the HLOS */ uint64_t handle; /* Optional */ /* Memory block size */ /* Must be set to true if num_bytes is being passed */ uint8_t num_bytes_valid; /* The number of bytes actually allocated for the request. * This value can be smaller than the size requested in * QMI_DHMS_MEM_ALLOC_REQ_MSG. */ uint32_t num_bytes; }; /* Message */ /* Request Message; This command is used for releasing * the multiple physically contiguous * memory blocks to the server memory subsystem */ struct mem_free_req_msg_v01 { /* Mandatory */ /* Physical address of memory to be freed */ uint32_t handle; }; /* Message */ /* Response Message; This command is used for releasing * the multiple physically contiguous * memory blocks to the server memory subsystem */ struct mem_free_resp_msg_v01 { /* Mandatory */ /* Result of the requested memory operation, todo, * need to check the async operation for free */ enum qmi_result_type_v01 resp; }; /* Message */ /* Request Message; This command is used for getting * the multiple physically contiguous * memory blocks from the server memory subsystem Loading Loading @@ -330,22 +254,14 @@ struct mem_query_size_rsp_msg_v01 { }; /* Message */ extern struct elem_info mem_alloc_req_msg_data_v01_ei[]; extern struct elem_info mem_alloc_resp_msg_data_v01_ei[]; extern struct elem_info mem_free_req_msg_data_v01_ei[]; extern struct elem_info mem_free_resp_msg_data_v01_ei[]; extern struct elem_info mem_alloc_generic_req_msg_data_v01_ei[]; extern struct elem_info mem_alloc_generic_resp_msg_data_v01_ei[]; extern struct elem_info mem_free_generic_req_msg_data_v01_ei[]; extern struct elem_info mem_free_generic_resp_msg_data_v01_ei[]; extern struct elem_info mem_query_size_req_msg_data_v01_ei[]; extern struct elem_info mem_query_size_resp_msg_data_v01_ei[]; extern struct qmi_elem_info mem_alloc_generic_req_msg_data_v01_ei[]; extern struct qmi_elem_info mem_alloc_generic_resp_msg_data_v01_ei[]; extern struct qmi_elem_info mem_free_generic_req_msg_data_v01_ei[]; extern struct qmi_elem_info mem_free_generic_resp_msg_data_v01_ei[]; extern struct qmi_elem_info mem_query_size_req_msg_data_v01_ei[]; extern struct qmi_elem_info mem_query_size_resp_msg_data_v01_ei[]; /*Service Message Definition*/ #define MEM_ALLOC_REQ_MSG_V01 0x0020 #define MEM_ALLOC_RESP_MSG_V01 0x0020 #define MEM_FREE_REQ_MSG_V01 0x0021 #define MEM_FREE_RESP_MSG_V01 0x0021 #define MEM_ALLOC_GENERIC_REQ_MSG_V01 0x0022 #define MEM_ALLOC_GENERIC_RESP_MSG_V01 0x0022 #define MEM_FREE_GENERIC_REQ_MSG_V01 0x0023 Loading drivers/soc/qcom/memshare/msm_memshare.c +77 −289 Original line number Diff line number Diff line Loading @@ -18,9 +18,9 @@ #include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/notifier.h> #include <linux/soc/qcom/qmi.h> #include <soc/qcom/subsystem_restart.h> #include <soc/qcom/subsystem_notif.h> #include <soc/qcom/msm_qmi_interface.h> #include <soc/qcom/scm.h> #include "msm_memshare.h" #include "heap_mem_ext_v01.h" Loading @@ -34,8 +34,6 @@ static unsigned long(attrs); static struct qmi_handle *mem_share_svc_handle; static void mem_share_svc_recv_msg(struct work_struct *work); static DECLARE_DELAYED_WORK(work_recv_msg, mem_share_svc_recv_msg); static struct workqueue_struct *mem_share_svc_workqueue; static uint64_t bootup_request; static bool ramdump_event; Loading @@ -58,65 +56,6 @@ static struct memshare_driver *memsh_drv; static struct memshare_child *memsh_child; static struct mem_blocks memblock[MAX_CLIENTS]; static uint32_t num_clients; static struct msg_desc mem_share_svc_alloc_req_desc = { .max_msg_len = MEM_ALLOC_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_ALLOC_REQ_MSG_V01, .ei_array = mem_alloc_req_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_alloc_resp_desc = { .max_msg_len = MEM_ALLOC_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_ALLOC_RESP_MSG_V01, .ei_array = mem_alloc_resp_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_free_req_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_FREE_REQ_MSG_V01, .ei_array = mem_free_req_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_free_resp_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_FREE_RESP_MSG_V01, .ei_array = mem_free_resp_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_alloc_generic_req_desc = { .max_msg_len = MEM_ALLOC_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_ALLOC_GENERIC_REQ_MSG_V01, .ei_array = mem_alloc_generic_req_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_alloc_generic_resp_desc = { .max_msg_len = MEM_ALLOC_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_ALLOC_GENERIC_RESP_MSG_V01, .ei_array = mem_alloc_generic_resp_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_free_generic_req_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_FREE_GENERIC_REQ_MSG_V01, .ei_array = mem_free_generic_req_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_free_generic_resp_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_FREE_GENERIC_RESP_MSG_V01, .ei_array = mem_free_generic_resp_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_size_query_req_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_QUERY_SIZE_REQ_MSG_V01, .ei_array = mem_query_size_req_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_size_query_resp_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_QUERY_SIZE_RESP_MSG_V01, .ei_array = mem_query_size_resp_msg_data_v01_ei, }; /* * This API creates ramdump dev handlers Loading Loading @@ -488,49 +427,8 @@ static void shared_hyp_mapping(int client_id) memblock[client_id].hyp_mapping = 1; } static int handle_alloc_req(void *req_h, void *req, void *conn_h) { struct mem_alloc_req_msg_v01 *alloc_req; struct mem_alloc_resp_msg_v01 alloc_resp; int rc = 0; mutex_lock(&memsh_drv->mem_share); alloc_req = (struct mem_alloc_req_msg_v01 *)req; pr_debug("memshare: %s: Received Alloc Request: alloc_req->num_bytes = %d\n", __func__, alloc_req->num_bytes); if (!memblock[GPS].size) { memset(&alloc_resp, 0, sizeof(alloc_resp)); alloc_resp.resp = QMI_RESULT_FAILURE_V01; rc = memshare_alloc(memsh_drv->dev, alloc_req->num_bytes, &memblock[GPS]); } alloc_resp.num_bytes_valid = 1; alloc_resp.num_bytes = alloc_req->num_bytes; alloc_resp.handle_valid = 1; alloc_resp.handle = memblock[GPS].phy_addr; if (rc) { alloc_resp.resp = QMI_RESULT_FAILURE_V01; memblock[GPS].size = 0; } else { alloc_resp.resp = QMI_RESULT_SUCCESS_V01; } mutex_unlock(&memsh_drv->mem_share); pr_debug("memshare: %s, alloc_resp.num_bytes :%d, alloc_resp.resp :%lx\n", __func__, alloc_resp.num_bytes, (unsigned long int)alloc_resp.resp); rc = qmi_send_resp_from_cb(mem_share_svc_handle, conn_h, req_h, &mem_share_svc_alloc_resp_desc, &alloc_resp, sizeof(alloc_resp)); if (rc < 0) pr_err("memshare: %s, Error sending the alloc request: %d\n", __func__, rc); return rc; } static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h) static void handle_alloc_generic_req(struct qmi_handle *handle, struct sockaddr_qrtr *sq, struct qmi_txn *txn, const void *decoded_msg) { struct mem_alloc_generic_req_msg_v01 *alloc_req; struct mem_alloc_generic_resp_msg_v01 *alloc_resp; Loading @@ -539,14 +437,14 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h) uint32_t size = 0; mutex_lock(&memsh_drv->mem_share); alloc_req = (struct mem_alloc_generic_req_msg_v01 *)req; alloc_req = (struct mem_alloc_generic_req_msg_v01 *)decoded_msg; pr_debug("memshare: alloc request client id: %d proc _id: %d\n", alloc_req->client_id, alloc_req->proc_id); alloc_resp = kzalloc(sizeof(*alloc_resp), GFP_KERNEL); if (!alloc_resp) { mutex_unlock(&memsh_drv->mem_share); return -ENOMEM; return; } alloc_resp->resp.result = QMI_RESULT_FAILURE_V01; alloc_resp->resp.error = QMI_ERR_NO_MEMORY_V01; Loading @@ -560,7 +458,7 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h) kfree(alloc_resp); alloc_resp = NULL; mutex_unlock(&memsh_drv->mem_share); return -EINVAL; return; } if (!memblock[client_id].allotted) { Loading Loading @@ -601,47 +499,22 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h) pr_debug("memshare: alloc_resp.num_bytes :%d, alloc_resp.resp.result :%lx\n", alloc_resp->dhms_mem_alloc_addr_info[0].num_bytes, (unsigned long int)alloc_resp->resp.result); rc = qmi_send_resp_from_cb(mem_share_svc_handle, conn_h, req_h, &mem_share_svc_alloc_generic_resp_desc, alloc_resp, sizeof(alloc_resp)); rc = qmi_send_response(mem_share_svc_handle, sq, txn, MEM_ALLOC_GENERIC_RESP_MSG_V01, sizeof(struct mem_alloc_generic_resp_msg_v01), mem_alloc_generic_resp_msg_data_v01_ei, alloc_resp); if (rc < 0) pr_err("memshare: %s, Error sending the alloc request: %d\n", pr_err("memshare: %s, Error sending the alloc response: %d\n", __func__, rc); kfree(alloc_resp); alloc_resp = NULL; return rc; } static int handle_free_req(void *req_h, void *req, void *conn_h) { struct mem_free_req_msg_v01 *free_req; struct mem_free_resp_msg_v01 free_resp; int rc; mutex_lock(&memsh_drv->mem_free); if (!memblock[GPS].guarantee) { free_req = (struct mem_free_req_msg_v01 *)req; pr_debug("memshare: %s: Received Free Request\n", __func__); memset(&free_resp, 0, sizeof(free_resp)); dma_free_coherent(memsh_drv->dev, memblock[GPS].size, memblock[GPS].virtual_addr, free_req->handle); } free_resp.resp = QMI_RESULT_SUCCESS_V01; mutex_unlock(&memsh_drv->mem_free); rc = qmi_send_resp_from_cb(mem_share_svc_handle, conn_h, req_h, &mem_share_svc_free_resp_desc, &free_resp, sizeof(free_resp)); if (rc < 0) pr_err("memshare: %s, Error sending the free request: %d\n", __func__, rc); return rc; return; } static int handle_free_generic_req(void *req_h, void *req, void *conn_h) static void handle_free_generic_req(struct qmi_handle *handle, struct sockaddr_qrtr *sq, struct qmi_txn *txn, const void *decoded_msg) { struct mem_free_generic_req_msg_v01 *free_req; struct mem_free_generic_resp_msg_v01 free_resp; Loading @@ -652,7 +525,7 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h) int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC}; mutex_lock(&memsh_drv->mem_free); free_req = (struct mem_free_generic_req_msg_v01 *)req; free_req = (struct mem_free_generic_req_msg_v01 *)decoded_msg; pr_debug("memshare: %s: Received Free Request\n", __func__); memset(&free_resp, 0, sizeof(free_resp)); free_resp.resp.error = QMI_ERR_INTERNAL_V01; Loading Loading @@ -709,30 +582,31 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h) } mutex_unlock(&memsh_drv->mem_free); rc = qmi_send_resp_from_cb(mem_share_svc_handle, conn_h, req_h, &mem_share_svc_free_generic_resp_desc, &free_resp, sizeof(free_resp)); rc = qmi_send_response(mem_share_svc_handle, sq, txn, MEM_FREE_GENERIC_RESP_MSG_V01, sizeof(struct mem_free_generic_resp_msg_v01), mem_free_generic_resp_msg_data_v01_ei, &free_resp); if (rc < 0) pr_err("memshare: %s, Error sending the free request: %d\n", pr_err("memshare: %s, Error sending the free response: %d\n", __func__, rc); return rc; return; } static int handle_query_size_req(void *req_h, void *req, void *conn_h) static void handle_query_size_req(struct qmi_handle *handle, struct sockaddr_qrtr *sq, struct qmi_txn *txn, const void *decoded_msg) { int rc, client_id; struct mem_query_size_req_msg_v01 *query_req; struct mem_query_size_rsp_msg_v01 *query_resp; mutex_lock(&memsh_drv->mem_share); query_req = (struct mem_query_size_req_msg_v01 *)req; query_req = (struct mem_query_size_req_msg_v01 *)decoded_msg; query_resp = kzalloc(sizeof(*query_resp), GFP_KERNEL); if (!query_resp) { mutex_unlock(&memsh_drv->mem_share); return -ENOMEM; return; } pr_debug("memshare: query request client id: %d proc _id: %d\n", query_req->client_id, query_req->proc_id); Loading @@ -746,7 +620,7 @@ static int handle_query_size_req(void *req_h, void *req, void *conn_h) kfree(query_resp); query_resp = NULL; mutex_unlock(&memsh_drv->mem_share); return -EINVAL; return; } if (memblock[client_id].size) { Loading @@ -763,148 +637,51 @@ static int handle_query_size_req(void *req_h, void *req, void *conn_h) pr_debug("memshare: query_resp.size :%d, query_resp.resp.result :%lx\n", query_resp->size, (unsigned long int)query_resp->resp.result); rc = qmi_send_resp_from_cb(mem_share_svc_handle, conn_h, req_h, &mem_share_svc_size_query_resp_desc, query_resp, sizeof(query_resp)); rc = qmi_send_response(mem_share_svc_handle, sq, txn, MEM_QUERY_SIZE_RESP_MSG_V01, MEM_QUERY_MAX_MSG_LEN_V01, mem_query_size_resp_msg_data_v01_ei, query_resp); if (rc < 0) pr_err("memshare: %s, Error sending the query request: %d\n", pr_err("memshare: %s, Error sending the query response: %d\n", __func__, rc); kfree(query_resp); query_resp = NULL; return rc; } static int mem_share_svc_connect_cb(struct qmi_handle *handle, void *conn_h) { if (mem_share_svc_handle != handle || !conn_h) return -EINVAL; return 0; return; } static int mem_share_svc_disconnect_cb(struct qmi_handle *handle, void *conn_h) static void mem_share_svc_disconnect_cb(struct qmi_handle *qmi, unsigned int node, unsigned int port) { if (mem_share_svc_handle != handle || !conn_h) return -EINVAL; return 0; pr_debug("memshare: Received QMI client disconnect event\n"); } static int mem_share_svc_req_desc_cb(unsigned int msg_id, struct msg_desc **req_desc) { int rc; pr_debug("memshare: %s\n", __func__); switch (msg_id) { case MEM_ALLOC_REQ_MSG_V01: *req_desc = &mem_share_svc_alloc_req_desc; rc = sizeof(struct mem_alloc_req_msg_v01); break; case MEM_FREE_REQ_MSG_V01: *req_desc = &mem_share_svc_free_req_desc; rc = sizeof(struct mem_free_req_msg_v01); break; case MEM_ALLOC_GENERIC_REQ_MSG_V01: *req_desc = &mem_share_svc_alloc_generic_req_desc; rc = sizeof(struct mem_alloc_generic_req_msg_v01); break; case MEM_FREE_GENERIC_REQ_MSG_V01: *req_desc = &mem_share_svc_free_generic_req_desc; rc = sizeof(struct mem_free_generic_req_msg_v01); break; case MEM_QUERY_SIZE_REQ_MSG_V01: *req_desc = &mem_share_svc_size_query_req_desc; rc = sizeof(struct mem_query_size_req_msg_v01); break; default: rc = -ENOTSUPP; break; } return rc; } static struct qmi_ops server_ops = { .del_client = mem_share_svc_disconnect_cb, }; static int mem_share_svc_req_cb(struct qmi_handle *handle, void *conn_h, void *req_h, unsigned int msg_id, void *req) static struct qmi_msg_handler qmi_memshare_handlers[] = { { int rc; pr_debug("memshare: %s\n", __func__); if (mem_share_svc_handle != handle || !conn_h) return -EINVAL; switch (msg_id) { case MEM_ALLOC_REQ_MSG_V01: rc = handle_alloc_req(req_h, req, conn_h); break; case MEM_FREE_REQ_MSG_V01: rc = handle_free_req(req_h, req, conn_h); break; case MEM_ALLOC_GENERIC_REQ_MSG_V01: rc = handle_alloc_generic_req(req_h, req, conn_h); break; case MEM_FREE_GENERIC_REQ_MSG_V01: rc = handle_free_generic_req(req_h, req, conn_h); break; case MEM_QUERY_SIZE_REQ_MSG_V01: rc = handle_query_size_req(req_h, req, conn_h); break; default: rc = -ENOTSUPP; break; } return rc; } static void mem_share_svc_recv_msg(struct work_struct *work) .type = QMI_REQUEST, .msg_id = MEM_ALLOC_GENERIC_REQ_MSG_V01, .ei = mem_alloc_generic_req_msg_data_v01_ei, .decoded_size = MEM_ALLOC_REQ_MAX_MSG_LEN_V01, .fn = handle_alloc_generic_req, }, { int rc; pr_debug("memshare: %s\n", __func__); do { rc = qmi_recv_msg(mem_share_svc_handle); pr_debug("memshare: %s: Notified about a Receive Event", __func__); } while (!rc); if (rc != -ENOMSG) pr_err("memshare: %s: Error = %d while receiving message\n", __func__, rc); } static void qmi_mem_share_svc_ntfy(struct qmi_handle *handle, enum qmi_event_type event, void *priv) .type = QMI_REQUEST, .msg_id = MEM_FREE_GENERIC_REQ_MSG_V01, .ei = mem_free_generic_req_msg_data_v01_ei, .decoded_size = MEM_FREE_REQ_MAX_MSG_LEN_V01, .fn = handle_free_generic_req, }, { pr_debug("memshare: %s\n", __func__); if (event == QMI_RECV_MSG) queue_delayed_work(mem_share_svc_workqueue, &work_recv_msg, 0); } static struct qmi_svc_ops_options mem_share_svc_ops_options = { .version = 1, .service_id = MEM_SHARE_SERVICE_SVC_ID, .service_vers = MEM_SHARE_SERVICE_VERS, .service_ins = MEM_SHARE_SERVICE_INS_ID, .connect_cb = mem_share_svc_connect_cb, .disconnect_cb = mem_share_svc_disconnect_cb, .req_desc_cb = mem_share_svc_req_desc_cb, .req_cb = mem_share_svc_req_cb, .type = QMI_REQUEST, .msg_id = MEM_QUERY_SIZE_REQ_MSG_V01, .ei = mem_query_size_req_msg_data_v01_ei, .decoded_size = MEM_QUERY_MAX_MSG_LEN_V01, .fn = handle_query_size_req, }, }; int memshare_alloc(struct device *dev, Loading Loading @@ -937,18 +714,30 @@ static void memshare_init_worker(struct work_struct *work) if (!mem_share_svc_workqueue) return; mem_share_svc_handle = qmi_handle_create(qmi_mem_share_svc_ntfy, NULL); mem_share_svc_handle = kzalloc(sizeof(struct qmi_handle), GFP_KERNEL); if (!mem_share_svc_handle) { destroy_workqueue(mem_share_svc_workqueue); return; } rc = qmi_handle_init(mem_share_svc_handle, sizeof(struct qmi_elem_info), &server_ops, qmi_memshare_handlers); if (rc < 0) { pr_err("memshare: %s: Creating mem_share_svc qmi handle failed\n", __func__); kfree(mem_share_svc_handle); destroy_workqueue(mem_share_svc_workqueue); return; } rc = qmi_svc_register(mem_share_svc_handle, &mem_share_svc_ops_options); rc = qmi_add_server(mem_share_svc_handle, MEM_SHARE_SERVICE_SVC_ID, MEM_SHARE_SERVICE_VERS, MEM_SHARE_SERVICE_INS_ID); if (rc < 0) { pr_err("memshare: %s: Registering mem share svc failed %d\n", __func__, rc); qmi_handle_destroy(mem_share_svc_handle); qmi_handle_release(mem_share_svc_handle); kfree(mem_share_svc_handle); destroy_workqueue(mem_share_svc_workqueue); return; } Loading Loading @@ -1094,11 +883,10 @@ static int memshare_remove(struct platform_device *pdev) if (!memsh_drv) return 0; qmi_svc_unregister(mem_share_svc_handle); flush_workqueue(mem_share_svc_workqueue); qmi_handle_destroy(mem_share_svc_handle); qmi_handle_release(mem_share_svc_handle); kfree(mem_share_svc_handle); destroy_workqueue(mem_share_svc_workqueue); return 0; } Loading Loading
drivers/soc/qcom/memshare/heap_mem_ext_v01.c +11 −134 Original line number Diff line number Diff line Loading @@ -11,133 +11,10 @@ * */ #include <linux/qmi_encdec.h> #include <soc/qcom/msm_qmi_interface.h> #include <linux/soc/qcom/qmi.h> #include "heap_mem_ext_v01.h" struct elem_info mem_alloc_req_msg_data_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(uint32_t), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct mem_alloc_req_msg_v01, num_bytes), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(uint8_t), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct mem_alloc_req_msg_v01, block_alignment_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(uint32_t), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct mem_alloc_req_msg_v01, block_alignment), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct elem_info mem_alloc_resp_msg_data_v01_ei[] = { { .data_type = QMI_SIGNED_2_BYTE_ENUM, .elem_len = 1, .elem_size = sizeof(uint16_t), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct mem_alloc_resp_msg_v01, resp), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(uint8_t), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct mem_alloc_resp_msg_v01, handle_valid), }, { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, .elem_size = sizeof(uint64_t), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct mem_alloc_resp_msg_v01, handle), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(uint8_t), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct mem_alloc_resp_msg_v01, num_bytes_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(uint32_t), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct mem_alloc_resp_msg_v01, num_bytes), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct elem_info mem_free_req_msg_data_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, .elem_size = sizeof(uint64_t), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct mem_free_req_msg_v01, handle), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct elem_info mem_free_resp_msg_data_v01_ei[] = { { .data_type = QMI_SIGNED_2_BYTE_ENUM, .elem_len = 1, .elem_size = sizeof(uint16_t), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct mem_free_resp_msg_v01, resp), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct elem_info dhms_mem_alloc_addr_info_type_v01_ei[] = { struct qmi_elem_info dhms_mem_alloc_addr_info_type_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, Loading Loading @@ -165,7 +42,7 @@ struct elem_info dhms_mem_alloc_addr_info_type_v01_ei[] = { }, }; struct elem_info mem_alloc_generic_req_msg_data_v01_ei[] = { struct qmi_elem_info mem_alloc_generic_req_msg_data_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, Loading Loading @@ -245,7 +122,7 @@ struct elem_info mem_alloc_generic_req_msg_data_v01_ei[] = { }, }; struct elem_info mem_alloc_generic_resp_msg_data_v01_ei[] = { struct qmi_elem_info mem_alloc_generic_resp_msg_data_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, Loading @@ -255,7 +132,7 @@ struct elem_info mem_alloc_generic_resp_msg_data_v01_ei[] = { .offset = offsetof(struct mem_alloc_generic_resp_msg_v01, resp), .ei_array = get_qmi_response_type_v01_ei(), .ei_array = qmi_response_type_v01_ei, }, { .data_type = QMI_OPT_FLAG, Loading Loading @@ -316,7 +193,7 @@ struct elem_info mem_alloc_generic_resp_msg_data_v01_ei[] = { }, }; struct elem_info mem_free_generic_req_msg_data_v01_ei[] = { struct qmi_elem_info mem_free_generic_req_msg_data_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, Loading Loading @@ -380,7 +257,7 @@ struct elem_info mem_free_generic_req_msg_data_v01_ei[] = { }, }; struct elem_info mem_free_generic_resp_msg_data_v01_ei[] = { struct qmi_elem_info mem_free_generic_resp_msg_data_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, Loading @@ -390,7 +267,7 @@ struct elem_info mem_free_generic_resp_msg_data_v01_ei[] = { .offset = offsetof(struct mem_free_generic_resp_msg_v01, resp), .ei_array = get_qmi_response_type_v01_ei(), .ei_array = qmi_response_type_v01_ei, }, { .data_type = QMI_EOTI, Loading @@ -399,7 +276,7 @@ struct elem_info mem_free_generic_resp_msg_data_v01_ei[] = { }, }; struct elem_info mem_query_size_req_msg_data_v01_ei[] = { struct qmi_elem_info mem_query_size_req_msg_data_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, Loading Loading @@ -434,7 +311,7 @@ struct elem_info mem_query_size_req_msg_data_v01_ei[] = { }, }; struct elem_info mem_query_size_resp_msg_data_v01_ei[] = { struct qmi_elem_info mem_query_size_resp_msg_data_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, Loading @@ -444,7 +321,7 @@ struct elem_info mem_query_size_resp_msg_data_v01_ei[] = { .offset = offsetof(struct mem_query_size_rsp_msg_v01, resp), .ei_array = get_qmi_response_type_v01_ei(), .ei_array = qmi_response_type_v01_ei, }, { .data_type = QMI_OPT_FLAG, Loading
drivers/soc/qcom/memshare/heap_mem_ext_v01.h +8 −92 Original line number Diff line number Diff line Loading @@ -14,10 +14,11 @@ #ifndef HEAP_MEM_EXT_SERVICE_01_H #define HEAP_MEM_EXT_SERVICE_01_H #include <soc/qcom/msm_qmi_interface.h> #include <linux/soc/qcom/qmi.h> #define MEM_ALLOC_REQ_MAX_MSG_LEN_V01 255 #define MEM_FREE_REQ_MAX_MSG_LEN_V01 255 #define MEM_QUERY_MAX_MSG_LEN_V01 255 #define MAX_ARR_CNT_V01 64 struct dhms_mem_alloc_addr_info_type_v01 { Loading Loading @@ -82,83 +83,6 @@ enum dhms_mem_block_align_enum_v01 { */ }; /* Request Message; This command is used for getting * the multiple physically contiguous * memory blocks from the server memory subsystem */ struct mem_alloc_req_msg_v01 { /* Mandatory */ /*requested size*/ uint32_t num_bytes; /* Optional */ /* Must be set to true if block_alignment * is being passed */ uint8_t block_alignment_valid; /* The block alignment for the memory block to be allocated */ enum dhms_mem_block_align_enum_v01 block_alignment; }; /* Message */ /* Response Message; This command is used for getting * the multiple physically contiguous memory blocks * from the server memory subsystem */ struct mem_alloc_resp_msg_v01 { /* Mandatory */ /* Result Code */ /* The result of the requested memory operation */ enum qmi_result_type_v01 resp; /* Optional */ /* Memory Block Handle */ /* Must be set to true if handle is being passed */ uint8_t handle_valid; /* The physical address of the memory allocated on the HLOS */ uint64_t handle; /* Optional */ /* Memory block size */ /* Must be set to true if num_bytes is being passed */ uint8_t num_bytes_valid; /* The number of bytes actually allocated for the request. * This value can be smaller than the size requested in * QMI_DHMS_MEM_ALLOC_REQ_MSG. */ uint32_t num_bytes; }; /* Message */ /* Request Message; This command is used for releasing * the multiple physically contiguous * memory blocks to the server memory subsystem */ struct mem_free_req_msg_v01 { /* Mandatory */ /* Physical address of memory to be freed */ uint32_t handle; }; /* Message */ /* Response Message; This command is used for releasing * the multiple physically contiguous * memory blocks to the server memory subsystem */ struct mem_free_resp_msg_v01 { /* Mandatory */ /* Result of the requested memory operation, todo, * need to check the async operation for free */ enum qmi_result_type_v01 resp; }; /* Message */ /* Request Message; This command is used for getting * the multiple physically contiguous * memory blocks from the server memory subsystem Loading Loading @@ -330,22 +254,14 @@ struct mem_query_size_rsp_msg_v01 { }; /* Message */ extern struct elem_info mem_alloc_req_msg_data_v01_ei[]; extern struct elem_info mem_alloc_resp_msg_data_v01_ei[]; extern struct elem_info mem_free_req_msg_data_v01_ei[]; extern struct elem_info mem_free_resp_msg_data_v01_ei[]; extern struct elem_info mem_alloc_generic_req_msg_data_v01_ei[]; extern struct elem_info mem_alloc_generic_resp_msg_data_v01_ei[]; extern struct elem_info mem_free_generic_req_msg_data_v01_ei[]; extern struct elem_info mem_free_generic_resp_msg_data_v01_ei[]; extern struct elem_info mem_query_size_req_msg_data_v01_ei[]; extern struct elem_info mem_query_size_resp_msg_data_v01_ei[]; extern struct qmi_elem_info mem_alloc_generic_req_msg_data_v01_ei[]; extern struct qmi_elem_info mem_alloc_generic_resp_msg_data_v01_ei[]; extern struct qmi_elem_info mem_free_generic_req_msg_data_v01_ei[]; extern struct qmi_elem_info mem_free_generic_resp_msg_data_v01_ei[]; extern struct qmi_elem_info mem_query_size_req_msg_data_v01_ei[]; extern struct qmi_elem_info mem_query_size_resp_msg_data_v01_ei[]; /*Service Message Definition*/ #define MEM_ALLOC_REQ_MSG_V01 0x0020 #define MEM_ALLOC_RESP_MSG_V01 0x0020 #define MEM_FREE_REQ_MSG_V01 0x0021 #define MEM_FREE_RESP_MSG_V01 0x0021 #define MEM_ALLOC_GENERIC_REQ_MSG_V01 0x0022 #define MEM_ALLOC_GENERIC_RESP_MSG_V01 0x0022 #define MEM_FREE_GENERIC_REQ_MSG_V01 0x0023 Loading
drivers/soc/qcom/memshare/msm_memshare.c +77 −289 Original line number Diff line number Diff line Loading @@ -18,9 +18,9 @@ #include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/notifier.h> #include <linux/soc/qcom/qmi.h> #include <soc/qcom/subsystem_restart.h> #include <soc/qcom/subsystem_notif.h> #include <soc/qcom/msm_qmi_interface.h> #include <soc/qcom/scm.h> #include "msm_memshare.h" #include "heap_mem_ext_v01.h" Loading @@ -34,8 +34,6 @@ static unsigned long(attrs); static struct qmi_handle *mem_share_svc_handle; static void mem_share_svc_recv_msg(struct work_struct *work); static DECLARE_DELAYED_WORK(work_recv_msg, mem_share_svc_recv_msg); static struct workqueue_struct *mem_share_svc_workqueue; static uint64_t bootup_request; static bool ramdump_event; Loading @@ -58,65 +56,6 @@ static struct memshare_driver *memsh_drv; static struct memshare_child *memsh_child; static struct mem_blocks memblock[MAX_CLIENTS]; static uint32_t num_clients; static struct msg_desc mem_share_svc_alloc_req_desc = { .max_msg_len = MEM_ALLOC_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_ALLOC_REQ_MSG_V01, .ei_array = mem_alloc_req_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_alloc_resp_desc = { .max_msg_len = MEM_ALLOC_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_ALLOC_RESP_MSG_V01, .ei_array = mem_alloc_resp_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_free_req_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_FREE_REQ_MSG_V01, .ei_array = mem_free_req_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_free_resp_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_FREE_RESP_MSG_V01, .ei_array = mem_free_resp_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_alloc_generic_req_desc = { .max_msg_len = MEM_ALLOC_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_ALLOC_GENERIC_REQ_MSG_V01, .ei_array = mem_alloc_generic_req_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_alloc_generic_resp_desc = { .max_msg_len = MEM_ALLOC_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_ALLOC_GENERIC_RESP_MSG_V01, .ei_array = mem_alloc_generic_resp_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_free_generic_req_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_FREE_GENERIC_REQ_MSG_V01, .ei_array = mem_free_generic_req_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_free_generic_resp_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_FREE_GENERIC_RESP_MSG_V01, .ei_array = mem_free_generic_resp_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_size_query_req_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_QUERY_SIZE_REQ_MSG_V01, .ei_array = mem_query_size_req_msg_data_v01_ei, }; static struct msg_desc mem_share_svc_size_query_resp_desc = { .max_msg_len = MEM_FREE_REQ_MAX_MSG_LEN_V01, .msg_id = MEM_QUERY_SIZE_RESP_MSG_V01, .ei_array = mem_query_size_resp_msg_data_v01_ei, }; /* * This API creates ramdump dev handlers Loading Loading @@ -488,49 +427,8 @@ static void shared_hyp_mapping(int client_id) memblock[client_id].hyp_mapping = 1; } static int handle_alloc_req(void *req_h, void *req, void *conn_h) { struct mem_alloc_req_msg_v01 *alloc_req; struct mem_alloc_resp_msg_v01 alloc_resp; int rc = 0; mutex_lock(&memsh_drv->mem_share); alloc_req = (struct mem_alloc_req_msg_v01 *)req; pr_debug("memshare: %s: Received Alloc Request: alloc_req->num_bytes = %d\n", __func__, alloc_req->num_bytes); if (!memblock[GPS].size) { memset(&alloc_resp, 0, sizeof(alloc_resp)); alloc_resp.resp = QMI_RESULT_FAILURE_V01; rc = memshare_alloc(memsh_drv->dev, alloc_req->num_bytes, &memblock[GPS]); } alloc_resp.num_bytes_valid = 1; alloc_resp.num_bytes = alloc_req->num_bytes; alloc_resp.handle_valid = 1; alloc_resp.handle = memblock[GPS].phy_addr; if (rc) { alloc_resp.resp = QMI_RESULT_FAILURE_V01; memblock[GPS].size = 0; } else { alloc_resp.resp = QMI_RESULT_SUCCESS_V01; } mutex_unlock(&memsh_drv->mem_share); pr_debug("memshare: %s, alloc_resp.num_bytes :%d, alloc_resp.resp :%lx\n", __func__, alloc_resp.num_bytes, (unsigned long int)alloc_resp.resp); rc = qmi_send_resp_from_cb(mem_share_svc_handle, conn_h, req_h, &mem_share_svc_alloc_resp_desc, &alloc_resp, sizeof(alloc_resp)); if (rc < 0) pr_err("memshare: %s, Error sending the alloc request: %d\n", __func__, rc); return rc; } static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h) static void handle_alloc_generic_req(struct qmi_handle *handle, struct sockaddr_qrtr *sq, struct qmi_txn *txn, const void *decoded_msg) { struct mem_alloc_generic_req_msg_v01 *alloc_req; struct mem_alloc_generic_resp_msg_v01 *alloc_resp; Loading @@ -539,14 +437,14 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h) uint32_t size = 0; mutex_lock(&memsh_drv->mem_share); alloc_req = (struct mem_alloc_generic_req_msg_v01 *)req; alloc_req = (struct mem_alloc_generic_req_msg_v01 *)decoded_msg; pr_debug("memshare: alloc request client id: %d proc _id: %d\n", alloc_req->client_id, alloc_req->proc_id); alloc_resp = kzalloc(sizeof(*alloc_resp), GFP_KERNEL); if (!alloc_resp) { mutex_unlock(&memsh_drv->mem_share); return -ENOMEM; return; } alloc_resp->resp.result = QMI_RESULT_FAILURE_V01; alloc_resp->resp.error = QMI_ERR_NO_MEMORY_V01; Loading @@ -560,7 +458,7 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h) kfree(alloc_resp); alloc_resp = NULL; mutex_unlock(&memsh_drv->mem_share); return -EINVAL; return; } if (!memblock[client_id].allotted) { Loading Loading @@ -601,47 +499,22 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h) pr_debug("memshare: alloc_resp.num_bytes :%d, alloc_resp.resp.result :%lx\n", alloc_resp->dhms_mem_alloc_addr_info[0].num_bytes, (unsigned long int)alloc_resp->resp.result); rc = qmi_send_resp_from_cb(mem_share_svc_handle, conn_h, req_h, &mem_share_svc_alloc_generic_resp_desc, alloc_resp, sizeof(alloc_resp)); rc = qmi_send_response(mem_share_svc_handle, sq, txn, MEM_ALLOC_GENERIC_RESP_MSG_V01, sizeof(struct mem_alloc_generic_resp_msg_v01), mem_alloc_generic_resp_msg_data_v01_ei, alloc_resp); if (rc < 0) pr_err("memshare: %s, Error sending the alloc request: %d\n", pr_err("memshare: %s, Error sending the alloc response: %d\n", __func__, rc); kfree(alloc_resp); alloc_resp = NULL; return rc; } static int handle_free_req(void *req_h, void *req, void *conn_h) { struct mem_free_req_msg_v01 *free_req; struct mem_free_resp_msg_v01 free_resp; int rc; mutex_lock(&memsh_drv->mem_free); if (!memblock[GPS].guarantee) { free_req = (struct mem_free_req_msg_v01 *)req; pr_debug("memshare: %s: Received Free Request\n", __func__); memset(&free_resp, 0, sizeof(free_resp)); dma_free_coherent(memsh_drv->dev, memblock[GPS].size, memblock[GPS].virtual_addr, free_req->handle); } free_resp.resp = QMI_RESULT_SUCCESS_V01; mutex_unlock(&memsh_drv->mem_free); rc = qmi_send_resp_from_cb(mem_share_svc_handle, conn_h, req_h, &mem_share_svc_free_resp_desc, &free_resp, sizeof(free_resp)); if (rc < 0) pr_err("memshare: %s, Error sending the free request: %d\n", __func__, rc); return rc; return; } static int handle_free_generic_req(void *req_h, void *req, void *conn_h) static void handle_free_generic_req(struct qmi_handle *handle, struct sockaddr_qrtr *sq, struct qmi_txn *txn, const void *decoded_msg) { struct mem_free_generic_req_msg_v01 *free_req; struct mem_free_generic_resp_msg_v01 free_resp; Loading @@ -652,7 +525,7 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h) int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC}; mutex_lock(&memsh_drv->mem_free); free_req = (struct mem_free_generic_req_msg_v01 *)req; free_req = (struct mem_free_generic_req_msg_v01 *)decoded_msg; pr_debug("memshare: %s: Received Free Request\n", __func__); memset(&free_resp, 0, sizeof(free_resp)); free_resp.resp.error = QMI_ERR_INTERNAL_V01; Loading Loading @@ -709,30 +582,31 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h) } mutex_unlock(&memsh_drv->mem_free); rc = qmi_send_resp_from_cb(mem_share_svc_handle, conn_h, req_h, &mem_share_svc_free_generic_resp_desc, &free_resp, sizeof(free_resp)); rc = qmi_send_response(mem_share_svc_handle, sq, txn, MEM_FREE_GENERIC_RESP_MSG_V01, sizeof(struct mem_free_generic_resp_msg_v01), mem_free_generic_resp_msg_data_v01_ei, &free_resp); if (rc < 0) pr_err("memshare: %s, Error sending the free request: %d\n", pr_err("memshare: %s, Error sending the free response: %d\n", __func__, rc); return rc; return; } static int handle_query_size_req(void *req_h, void *req, void *conn_h) static void handle_query_size_req(struct qmi_handle *handle, struct sockaddr_qrtr *sq, struct qmi_txn *txn, const void *decoded_msg) { int rc, client_id; struct mem_query_size_req_msg_v01 *query_req; struct mem_query_size_rsp_msg_v01 *query_resp; mutex_lock(&memsh_drv->mem_share); query_req = (struct mem_query_size_req_msg_v01 *)req; query_req = (struct mem_query_size_req_msg_v01 *)decoded_msg; query_resp = kzalloc(sizeof(*query_resp), GFP_KERNEL); if (!query_resp) { mutex_unlock(&memsh_drv->mem_share); return -ENOMEM; return; } pr_debug("memshare: query request client id: %d proc _id: %d\n", query_req->client_id, query_req->proc_id); Loading @@ -746,7 +620,7 @@ static int handle_query_size_req(void *req_h, void *req, void *conn_h) kfree(query_resp); query_resp = NULL; mutex_unlock(&memsh_drv->mem_share); return -EINVAL; return; } if (memblock[client_id].size) { Loading @@ -763,148 +637,51 @@ static int handle_query_size_req(void *req_h, void *req, void *conn_h) pr_debug("memshare: query_resp.size :%d, query_resp.resp.result :%lx\n", query_resp->size, (unsigned long int)query_resp->resp.result); rc = qmi_send_resp_from_cb(mem_share_svc_handle, conn_h, req_h, &mem_share_svc_size_query_resp_desc, query_resp, sizeof(query_resp)); rc = qmi_send_response(mem_share_svc_handle, sq, txn, MEM_QUERY_SIZE_RESP_MSG_V01, MEM_QUERY_MAX_MSG_LEN_V01, mem_query_size_resp_msg_data_v01_ei, query_resp); if (rc < 0) pr_err("memshare: %s, Error sending the query request: %d\n", pr_err("memshare: %s, Error sending the query response: %d\n", __func__, rc); kfree(query_resp); query_resp = NULL; return rc; } static int mem_share_svc_connect_cb(struct qmi_handle *handle, void *conn_h) { if (mem_share_svc_handle != handle || !conn_h) return -EINVAL; return 0; return; } static int mem_share_svc_disconnect_cb(struct qmi_handle *handle, void *conn_h) static void mem_share_svc_disconnect_cb(struct qmi_handle *qmi, unsigned int node, unsigned int port) { if (mem_share_svc_handle != handle || !conn_h) return -EINVAL; return 0; pr_debug("memshare: Received QMI client disconnect event\n"); } static int mem_share_svc_req_desc_cb(unsigned int msg_id, struct msg_desc **req_desc) { int rc; pr_debug("memshare: %s\n", __func__); switch (msg_id) { case MEM_ALLOC_REQ_MSG_V01: *req_desc = &mem_share_svc_alloc_req_desc; rc = sizeof(struct mem_alloc_req_msg_v01); break; case MEM_FREE_REQ_MSG_V01: *req_desc = &mem_share_svc_free_req_desc; rc = sizeof(struct mem_free_req_msg_v01); break; case MEM_ALLOC_GENERIC_REQ_MSG_V01: *req_desc = &mem_share_svc_alloc_generic_req_desc; rc = sizeof(struct mem_alloc_generic_req_msg_v01); break; case MEM_FREE_GENERIC_REQ_MSG_V01: *req_desc = &mem_share_svc_free_generic_req_desc; rc = sizeof(struct mem_free_generic_req_msg_v01); break; case MEM_QUERY_SIZE_REQ_MSG_V01: *req_desc = &mem_share_svc_size_query_req_desc; rc = sizeof(struct mem_query_size_req_msg_v01); break; default: rc = -ENOTSUPP; break; } return rc; } static struct qmi_ops server_ops = { .del_client = mem_share_svc_disconnect_cb, }; static int mem_share_svc_req_cb(struct qmi_handle *handle, void *conn_h, void *req_h, unsigned int msg_id, void *req) static struct qmi_msg_handler qmi_memshare_handlers[] = { { int rc; pr_debug("memshare: %s\n", __func__); if (mem_share_svc_handle != handle || !conn_h) return -EINVAL; switch (msg_id) { case MEM_ALLOC_REQ_MSG_V01: rc = handle_alloc_req(req_h, req, conn_h); break; case MEM_FREE_REQ_MSG_V01: rc = handle_free_req(req_h, req, conn_h); break; case MEM_ALLOC_GENERIC_REQ_MSG_V01: rc = handle_alloc_generic_req(req_h, req, conn_h); break; case MEM_FREE_GENERIC_REQ_MSG_V01: rc = handle_free_generic_req(req_h, req, conn_h); break; case MEM_QUERY_SIZE_REQ_MSG_V01: rc = handle_query_size_req(req_h, req, conn_h); break; default: rc = -ENOTSUPP; break; } return rc; } static void mem_share_svc_recv_msg(struct work_struct *work) .type = QMI_REQUEST, .msg_id = MEM_ALLOC_GENERIC_REQ_MSG_V01, .ei = mem_alloc_generic_req_msg_data_v01_ei, .decoded_size = MEM_ALLOC_REQ_MAX_MSG_LEN_V01, .fn = handle_alloc_generic_req, }, { int rc; pr_debug("memshare: %s\n", __func__); do { rc = qmi_recv_msg(mem_share_svc_handle); pr_debug("memshare: %s: Notified about a Receive Event", __func__); } while (!rc); if (rc != -ENOMSG) pr_err("memshare: %s: Error = %d while receiving message\n", __func__, rc); } static void qmi_mem_share_svc_ntfy(struct qmi_handle *handle, enum qmi_event_type event, void *priv) .type = QMI_REQUEST, .msg_id = MEM_FREE_GENERIC_REQ_MSG_V01, .ei = mem_free_generic_req_msg_data_v01_ei, .decoded_size = MEM_FREE_REQ_MAX_MSG_LEN_V01, .fn = handle_free_generic_req, }, { pr_debug("memshare: %s\n", __func__); if (event == QMI_RECV_MSG) queue_delayed_work(mem_share_svc_workqueue, &work_recv_msg, 0); } static struct qmi_svc_ops_options mem_share_svc_ops_options = { .version = 1, .service_id = MEM_SHARE_SERVICE_SVC_ID, .service_vers = MEM_SHARE_SERVICE_VERS, .service_ins = MEM_SHARE_SERVICE_INS_ID, .connect_cb = mem_share_svc_connect_cb, .disconnect_cb = mem_share_svc_disconnect_cb, .req_desc_cb = mem_share_svc_req_desc_cb, .req_cb = mem_share_svc_req_cb, .type = QMI_REQUEST, .msg_id = MEM_QUERY_SIZE_REQ_MSG_V01, .ei = mem_query_size_req_msg_data_v01_ei, .decoded_size = MEM_QUERY_MAX_MSG_LEN_V01, .fn = handle_query_size_req, }, }; int memshare_alloc(struct device *dev, Loading Loading @@ -937,18 +714,30 @@ static void memshare_init_worker(struct work_struct *work) if (!mem_share_svc_workqueue) return; mem_share_svc_handle = qmi_handle_create(qmi_mem_share_svc_ntfy, NULL); mem_share_svc_handle = kzalloc(sizeof(struct qmi_handle), GFP_KERNEL); if (!mem_share_svc_handle) { destroy_workqueue(mem_share_svc_workqueue); return; } rc = qmi_handle_init(mem_share_svc_handle, sizeof(struct qmi_elem_info), &server_ops, qmi_memshare_handlers); if (rc < 0) { pr_err("memshare: %s: Creating mem_share_svc qmi handle failed\n", __func__); kfree(mem_share_svc_handle); destroy_workqueue(mem_share_svc_workqueue); return; } rc = qmi_svc_register(mem_share_svc_handle, &mem_share_svc_ops_options); rc = qmi_add_server(mem_share_svc_handle, MEM_SHARE_SERVICE_SVC_ID, MEM_SHARE_SERVICE_VERS, MEM_SHARE_SERVICE_INS_ID); if (rc < 0) { pr_err("memshare: %s: Registering mem share svc failed %d\n", __func__, rc); qmi_handle_destroy(mem_share_svc_handle); qmi_handle_release(mem_share_svc_handle); kfree(mem_share_svc_handle); destroy_workqueue(mem_share_svc_workqueue); return; } Loading Loading @@ -1094,11 +883,10 @@ static int memshare_remove(struct platform_device *pdev) if (!memsh_drv) return 0; qmi_svc_unregister(mem_share_svc_handle); flush_workqueue(mem_share_svc_workqueue); qmi_handle_destroy(mem_share_svc_handle); qmi_handle_release(mem_share_svc_handle); kfree(mem_share_svc_handle); destroy_workqueue(mem_share_svc_workqueue); return 0; } Loading