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

Commit 388b6055 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: qmi: Use ipc logging in qmi_interface"

parents b6d89b7b 7da17e34
Loading
Loading
Loading
Loading
+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
@@ -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>

@@ -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);
@@ -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
@@ -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,
@@ -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
@@ -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
@@ -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,
@@ -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;
@@ -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
@@ -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");
+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
@@ -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.
@@ -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,