Loading drivers/soc/qcom/qmi_interface.c +113 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -29,6 +29,7 @@ #include <linux/mutex.h> #include <linux/hashtable.h> #include <linux/ipc_router.h> #include <linux/ipc_logging.h> #include <soc/qcom/msm_qmi_interface.h> Loading @@ -37,6 +38,21 @@ #define BUILD_INSTANCE_ID(vers, ins) (((vers) & 0xFF) | (((ins) & 0xFF) << 8)) #define LOOKUP_MASK 0xFFFFFFFF #define MAX_WQ_NAME_LEN 20 #define QMI_REQ_RESP_LOG_PAGES 3 #define QMI_IND_LOG_PAGES 2 #define QMI_REQ_RESP_LOG(buf...) \ do { \ if (qmi_req_resp_log_ctx) { \ ipc_log_string(qmi_req_resp_log_ctx, buf); \ } \ } while (0) \ #define QMI_IND_LOG(buf...) \ do { \ if (qmi_ind_log_ctx) { \ ipc_log_string(qmi_ind_log_ctx, buf); \ } \ } while (0) \ static LIST_HEAD(svc_event_nb_list); static DEFINE_MUTEX(svc_event_nb_list_lock); Loading Loading @@ -115,7 +131,69 @@ struct msg_desc err_resp_desc = { static void svc_resume_tx_worker(struct work_struct *work); static void clean_txn_info(struct qmi_handle *handle); static void *qmi_req_resp_log_ctx; static void *qmi_ind_log_ctx; /** * qmi_log() - Pass log data to IPC logging framework * @handle: The pointer to the qmi_handle * @cntl_flg: Indicates the type(request/response/indications) of the message * @txn_id: Transaction ID of the message. * @msg_id: Message ID of the incoming/outgoing message. * @msg_len: Total size of the message. * * This function builds the data the would be passed on to the IPC logging * framework. The data that would be passed corresponds to the information * that is exchanged between the IPC Router and kernel modules during * request/response/indication transactions. */ static void qmi_log(struct qmi_handle *handle, unsigned char cntl_flag, uint16_t txn_id, uint16_t msg_id, uint16_t msg_len) { uint32_t service_id = 0; const char *ops_type = NULL; if (handle->handle_type == QMI_CLIENT_HANDLE) { service_id = handle->dest_service_id; if (cntl_flag == QMI_REQUEST_CONTROL_FLAG) ops_type = "TX"; else if (cntl_flag == QMI_INDICATION_CONTROL_FLAG || cntl_flag == QMI_RESPONSE_CONTROL_FLAG) ops_type = "RX"; } else if (handle->handle_type == QMI_SERVICE_HANDLE) { service_id = handle->svc_ops_options->service_id; if (cntl_flag == QMI_REQUEST_CONTROL_FLAG) ops_type = "RX"; else if (cntl_flag == QMI_INDICATION_CONTROL_FLAG || cntl_flag == QMI_RESPONSE_CONTROL_FLAG) ops_type = "TX"; } /* * IPC Logging format is as below:- * <Type of module>(CLNT or SERV) : * <Opertaion Type> (Transmit/ RECV) : * <Control Flag> (Req/Resp/Ind) : * <Transaction ID> : * <Message ID> : * <Message Length> : * <Service ID> : */ if (qmi_req_resp_log_ctx && ((cntl_flag == QMI_REQUEST_CONTROL_FLAG) || (cntl_flag == QMI_RESPONSE_CONTROL_FLAG))) { QMI_REQ_RESP_LOG("%s %s CF:%x TI:%x MI:%x ML:%x SvcId: %x", (handle->handle_type == QMI_CLIENT_HANDLE ? "QCCI" : "QCSI"), ops_type, cntl_flag, txn_id, msg_id, msg_len, service_id); } else if (qmi_ind_log_ctx && (cntl_flag == QMI_INDICATION_CONTROL_FLAG)) { QMI_IND_LOG("%s %s CF:%x TI:%x MI:%x ML:%x SvcId: %x", (handle->handle_type == QMI_CLIENT_HANDLE ? "QCCI" : "QCSI"), ops_type, cntl_flag, txn_id, msg_id, msg_len, service_id); } } /** * add_req_handle() - Create and Add a request handle to the connection Loading Loading @@ -875,6 +953,8 @@ static int qmi_encode_and_send_req(struct qmi_txn **ret_txn_handle, } list_add_tail(&txn_handle->list, &handle->txn_list); qmi_log(handle, QMI_REQUEST_CONTROL_FLAG, txn_handle->txn_id, req_desc->msg_id, encoded_req_len); /* Send the request */ rc = msm_ipc_router_send_msg((struct msm_ipc_port *)(handle->src_port), (struct msm_ipc_addr *)handle->dest_info, Loading Loading @@ -1071,6 +1151,8 @@ static int qmi_encode_and_send_resp(struct qmi_handle *handle, encoded_resp_len); encoded_resp_len += QMI_HEADER_SIZE; qmi_log(handle, cntl_flag, txn_handle->txn_id, resp_desc->msg_id, encoded_resp_len); /* * Check if this svc_clnt has transactions queued to its pending list * and if there are any pending transactions then add the current Loading Loading @@ -1339,6 +1421,8 @@ static int send_err_resp(struct qmi_handle *handle, encoded_resp_len); encoded_resp_len += QMI_HEADER_SIZE; qmi_log(handle, QMI_RESPONSE_CONTROL_FLAG, txn_id, msg_id, encoded_resp_len); /* * Check if this svc_clnt has transactions queued to its pending list * and if there are any pending transactions then add the current Loading Loading @@ -1588,6 +1672,7 @@ int qmi_recv_msg(struct qmi_handle *handle) /* Decode the header & Handle the req, resp, indication message */ decode_qmi_header(recv_msg, &cntl_flag, &txn_id, &msg_id, &msg_len); qmi_log(handle, cntl_flag, txn_id, msg_id, msg_len); switch (cntl_flag) { case QMI_REQUEST_CONTROL_FLAG: rc = handle_qmi_request(handle, recv_msg, txn_id, msg_id, Loading Loading @@ -1656,6 +1741,7 @@ int qmi_connect_to_service(struct qmi_handle *handle, return -ENETRESET; } handle->dest_info = svc_dest_addr; handle->dest_service_id = service_id; mutex_unlock(&handle->handle_lock); return 0; Loading Loading @@ -1836,6 +1922,25 @@ int qmi_svc_event_notifier_unregister(uint32_t service_id, } EXPORT_SYMBOL(qmi_svc_event_notifier_unregister); /** * qmi_log_init() - Init function for IPC Logging * * Initialize log contexts for QMI request/response/indications. */ void qmi_log_init(void) { qmi_req_resp_log_ctx = ipc_log_context_create(QMI_REQ_RESP_LOG_PAGES, "kqmi_req_resp", 0); if (!qmi_req_resp_log_ctx) pr_err("%s: Unable to create QMI IPC logging for Req/Resp", __func__); qmi_ind_log_ctx = ipc_log_context_create(QMI_IND_LOG_PAGES, "kqmi_ind", 0); if (!qmi_ind_log_ctx) pr_err("%s: Unable to create QMI IPC %s", "logging for Indications", __func__); } /** * qmi_svc_register() - Register a QMI service with a QMI handle Loading Loading @@ -1931,5 +2036,12 @@ int qmi_svc_unregister(struct qmi_handle *handle) } EXPORT_SYMBOL(qmi_svc_unregister); static int __init qmi_interface_init(void) { qmi_log_init(); return 0; } module_init(qmi_interface_init); MODULE_DESCRIPTION("MSM QMI Interface"); MODULE_LICENSE("GPL v2"); include/soc/qcom/msm_qmi_interface.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -46,6 +46,7 @@ enum qmi_event_type { * @reset_waitq: Wait queue to wait for any reset events. * @ctl_work: Work to handle the out-of-band events for this handle. * @dest_info: Destination to which this handle is connected to. * @dest_service_id: service id of the service that client connected to. * @txn_list: List of transactions waiting for the response. * @ind_cb: Function to notify the handle owner of an indication message. * @ind_cb_priv: Private info to be passed during an indication notification. Loading @@ -72,6 +73,7 @@ struct qmi_handle { /* Client specific elements */ void *dest_info; uint32_t dest_service_id; struct list_head txn_list; void (*ind_cb)(struct qmi_handle *handle, unsigned int msg_id, void *msg, Loading Loading
drivers/soc/qcom/qmi_interface.c +113 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -29,6 +29,7 @@ #include <linux/mutex.h> #include <linux/hashtable.h> #include <linux/ipc_router.h> #include <linux/ipc_logging.h> #include <soc/qcom/msm_qmi_interface.h> Loading @@ -37,6 +38,21 @@ #define BUILD_INSTANCE_ID(vers, ins) (((vers) & 0xFF) | (((ins) & 0xFF) << 8)) #define LOOKUP_MASK 0xFFFFFFFF #define MAX_WQ_NAME_LEN 20 #define QMI_REQ_RESP_LOG_PAGES 3 #define QMI_IND_LOG_PAGES 2 #define QMI_REQ_RESP_LOG(buf...) \ do { \ if (qmi_req_resp_log_ctx) { \ ipc_log_string(qmi_req_resp_log_ctx, buf); \ } \ } while (0) \ #define QMI_IND_LOG(buf...) \ do { \ if (qmi_ind_log_ctx) { \ ipc_log_string(qmi_ind_log_ctx, buf); \ } \ } while (0) \ static LIST_HEAD(svc_event_nb_list); static DEFINE_MUTEX(svc_event_nb_list_lock); Loading Loading @@ -115,7 +131,69 @@ struct msg_desc err_resp_desc = { static void svc_resume_tx_worker(struct work_struct *work); static void clean_txn_info(struct qmi_handle *handle); static void *qmi_req_resp_log_ctx; static void *qmi_ind_log_ctx; /** * qmi_log() - Pass log data to IPC logging framework * @handle: The pointer to the qmi_handle * @cntl_flg: Indicates the type(request/response/indications) of the message * @txn_id: Transaction ID of the message. * @msg_id: Message ID of the incoming/outgoing message. * @msg_len: Total size of the message. * * This function builds the data the would be passed on to the IPC logging * framework. The data that would be passed corresponds to the information * that is exchanged between the IPC Router and kernel modules during * request/response/indication transactions. */ static void qmi_log(struct qmi_handle *handle, unsigned char cntl_flag, uint16_t txn_id, uint16_t msg_id, uint16_t msg_len) { uint32_t service_id = 0; const char *ops_type = NULL; if (handle->handle_type == QMI_CLIENT_HANDLE) { service_id = handle->dest_service_id; if (cntl_flag == QMI_REQUEST_CONTROL_FLAG) ops_type = "TX"; else if (cntl_flag == QMI_INDICATION_CONTROL_FLAG || cntl_flag == QMI_RESPONSE_CONTROL_FLAG) ops_type = "RX"; } else if (handle->handle_type == QMI_SERVICE_HANDLE) { service_id = handle->svc_ops_options->service_id; if (cntl_flag == QMI_REQUEST_CONTROL_FLAG) ops_type = "RX"; else if (cntl_flag == QMI_INDICATION_CONTROL_FLAG || cntl_flag == QMI_RESPONSE_CONTROL_FLAG) ops_type = "TX"; } /* * IPC Logging format is as below:- * <Type of module>(CLNT or SERV) : * <Opertaion Type> (Transmit/ RECV) : * <Control Flag> (Req/Resp/Ind) : * <Transaction ID> : * <Message ID> : * <Message Length> : * <Service ID> : */ if (qmi_req_resp_log_ctx && ((cntl_flag == QMI_REQUEST_CONTROL_FLAG) || (cntl_flag == QMI_RESPONSE_CONTROL_FLAG))) { QMI_REQ_RESP_LOG("%s %s CF:%x TI:%x MI:%x ML:%x SvcId: %x", (handle->handle_type == QMI_CLIENT_HANDLE ? "QCCI" : "QCSI"), ops_type, cntl_flag, txn_id, msg_id, msg_len, service_id); } else if (qmi_ind_log_ctx && (cntl_flag == QMI_INDICATION_CONTROL_FLAG)) { QMI_IND_LOG("%s %s CF:%x TI:%x MI:%x ML:%x SvcId: %x", (handle->handle_type == QMI_CLIENT_HANDLE ? "QCCI" : "QCSI"), ops_type, cntl_flag, txn_id, msg_id, msg_len, service_id); } } /** * add_req_handle() - Create and Add a request handle to the connection Loading Loading @@ -875,6 +953,8 @@ static int qmi_encode_and_send_req(struct qmi_txn **ret_txn_handle, } list_add_tail(&txn_handle->list, &handle->txn_list); qmi_log(handle, QMI_REQUEST_CONTROL_FLAG, txn_handle->txn_id, req_desc->msg_id, encoded_req_len); /* Send the request */ rc = msm_ipc_router_send_msg((struct msm_ipc_port *)(handle->src_port), (struct msm_ipc_addr *)handle->dest_info, Loading Loading @@ -1071,6 +1151,8 @@ static int qmi_encode_and_send_resp(struct qmi_handle *handle, encoded_resp_len); encoded_resp_len += QMI_HEADER_SIZE; qmi_log(handle, cntl_flag, txn_handle->txn_id, resp_desc->msg_id, encoded_resp_len); /* * Check if this svc_clnt has transactions queued to its pending list * and if there are any pending transactions then add the current Loading Loading @@ -1339,6 +1421,8 @@ static int send_err_resp(struct qmi_handle *handle, encoded_resp_len); encoded_resp_len += QMI_HEADER_SIZE; qmi_log(handle, QMI_RESPONSE_CONTROL_FLAG, txn_id, msg_id, encoded_resp_len); /* * Check if this svc_clnt has transactions queued to its pending list * and if there are any pending transactions then add the current Loading Loading @@ -1588,6 +1672,7 @@ int qmi_recv_msg(struct qmi_handle *handle) /* Decode the header & Handle the req, resp, indication message */ decode_qmi_header(recv_msg, &cntl_flag, &txn_id, &msg_id, &msg_len); qmi_log(handle, cntl_flag, txn_id, msg_id, msg_len); switch (cntl_flag) { case QMI_REQUEST_CONTROL_FLAG: rc = handle_qmi_request(handle, recv_msg, txn_id, msg_id, Loading Loading @@ -1656,6 +1741,7 @@ int qmi_connect_to_service(struct qmi_handle *handle, return -ENETRESET; } handle->dest_info = svc_dest_addr; handle->dest_service_id = service_id; mutex_unlock(&handle->handle_lock); return 0; Loading Loading @@ -1836,6 +1922,25 @@ int qmi_svc_event_notifier_unregister(uint32_t service_id, } EXPORT_SYMBOL(qmi_svc_event_notifier_unregister); /** * qmi_log_init() - Init function for IPC Logging * * Initialize log contexts for QMI request/response/indications. */ void qmi_log_init(void) { qmi_req_resp_log_ctx = ipc_log_context_create(QMI_REQ_RESP_LOG_PAGES, "kqmi_req_resp", 0); if (!qmi_req_resp_log_ctx) pr_err("%s: Unable to create QMI IPC logging for Req/Resp", __func__); qmi_ind_log_ctx = ipc_log_context_create(QMI_IND_LOG_PAGES, "kqmi_ind", 0); if (!qmi_ind_log_ctx) pr_err("%s: Unable to create QMI IPC %s", "logging for Indications", __func__); } /** * qmi_svc_register() - Register a QMI service with a QMI handle Loading Loading @@ -1931,5 +2036,12 @@ int qmi_svc_unregister(struct qmi_handle *handle) } EXPORT_SYMBOL(qmi_svc_unregister); static int __init qmi_interface_init(void) { qmi_log_init(); return 0; } module_init(qmi_interface_init); MODULE_DESCRIPTION("MSM QMI Interface"); MODULE_LICENSE("GPL v2");
include/soc/qcom/msm_qmi_interface.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -46,6 +46,7 @@ enum qmi_event_type { * @reset_waitq: Wait queue to wait for any reset events. * @ctl_work: Work to handle the out-of-band events for this handle. * @dest_info: Destination to which this handle is connected to. * @dest_service_id: service id of the service that client connected to. * @txn_list: List of transactions waiting for the response. * @ind_cb: Function to notify the handle owner of an indication message. * @ind_cb_priv: Private info to be passed during an indication notification. Loading @@ -72,6 +73,7 @@ struct qmi_handle { /* Client specific elements */ void *dest_info; uint32_t dest_service_id; struct list_head txn_list; void (*ind_cb)(struct qmi_handle *handle, unsigned int msg_id, void *msg, Loading