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

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

Merge "diag: Add support for extended mobile ID version 2"

parents ba4b18fe af4a128f
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ static void diag_send_log_mask_update(uint8_t peripheral, int equip_id)
		mutex_unlock(&mask->lock);
		err = diagfwd_write(peripheral, TYPE_CNTL,
				    buf, header_len + mask_size);
		if (err) {
		if (err && err != -ENODEV) {
			pr_err("diag: Unable to send log masks to peripheral %d, equip_id: %d, err: %d\n",
			       peripheral, i, err);
		}
@@ -236,7 +236,7 @@ static void diag_send_event_mask_update(uint8_t peripheral)
	write_len += sizeof(header);

	err = diagfwd_write(peripheral, TYPE_CNTL, buf, write_len);
	if (err) {
	if (err && err != -ENODEV) {
		pr_err("diag: Unable to send event masks to peripheral %d\n",
		       peripheral);
	}
@@ -327,7 +327,7 @@ proceed:

		err = diagfwd_write(peripheral, TYPE_CNTL, buf,
				    header_len + mask_size);
		if (err) {
		if (err && err != -ENODEV) {
			pr_err("diag: Unable to send msg masks to peripheral %d\n",
			       peripheral);
		}
@@ -382,7 +382,7 @@ static void diag_send_feature_mask_update(uint8_t peripheral)
	total_len = header_size + FEATURE_MASK_LEN;

	err = diagfwd_write(peripheral, TYPE_CNTL, buf, total_len);
	if (err) {
	if (err && err != -ENODEV) {
		pr_err("diag: In %s, unable to write to peripheral: %d, type: %d, len: %d, err: %d\n",
		       __func__, peripheral, TYPE_CNTL,
		       total_len, err);
+18 −3
Original line number Diff line number Diff line
@@ -97,9 +97,15 @@
#define DIAG_CMD_QUERY_TMC	0x02
#define DIAG_SS_TDSCDMA	0x57
#define DIAG_CMD_TDSCDMA_STATUS	0x0E
#define DIAG_CMD_DIAG_SUBSYS_DELAY 0x80

#define DIAG_SS_DIAG		0x12
#define DIAG_SS_PARAMS		0x32
#define DIAG_SS_FILE_READ_MODEM 0x0816
#define DIAG_SS_FILE_READ_ADSP  0x0E10
#define DIAG_SS_FILE_READ_WCNSS 0x141F
#define DIAG_SS_FILE_READ_SLPI 0x01A18
#define DIAG_SS_FILE_READ_APPS 0x020F

#define DIAG_DIAG_MAX_PKT_SZ	0x55
#define DIAG_DIAG_STM		0x214
@@ -240,7 +246,8 @@ struct diag_cmd_ext_mobile_rsp_t {
	uint8_t version;
	uint8_t padding[3];
	uint32_t family;
};
	uint32_t chip_id;
} __packed;

struct diag_cmd_reg_entry_t {
	uint16_t cmd_code;
@@ -380,6 +387,13 @@ struct diag_feature_t {
	uint8_t sent_feature_mask;
};

struct diag_mdlog_client_info {
	struct task_struct *client_process;
	int client_id;
	uint16_t notification_list;
	int signal_type;
};

struct diagchar_dev {

	/* State for the char driver */
@@ -491,6 +505,7 @@ struct diagchar_dev {
	int logging_mode;
	int mask_check;
	struct diag_md_proc_info md_proc[DIAG_NUM_PROC];
	struct diag_mdlog_client_info md_client_info;
	/* Power related variables */
	struct diag_ws_ref_t dci_ws;
	struct diag_ws_ref_t md_ws;
@@ -509,8 +524,8 @@ struct diagchar_dev {
	uint32_t max_ssid_count[NUM_PERIPHERALS];
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
	/* For sending command requests in callback mode */
	unsigned char *cb_buf;
	int cb_buf_len;
	unsigned char *hdlc_encode_buf;
	int hdlc_encode_buf_len;
#endif
};

+83 −97
Original line number Diff line number Diff line
@@ -59,8 +59,8 @@ struct diagchar_priv {
	int pid;
};

#define CALLBACK_NON_HDLC_DATA	0
#define CALLBACK_HDLC_DATA	1
#define USER_SPACE_RAW_DATA	0
#define USER_SPACE_HDLC_DATA	1

/* Memory pool variables */
/* Used for copying any incoming packet from user space clients. */
@@ -376,6 +376,8 @@ static void diag_close_logging_process(int pid)
		if (logging_proc->callback_process)
			logging_proc->callback_process = NULL;
		logging_proc->pid = 0;
		if (driver->md_client_info.client_process)
			driver->md_client_info.client_process = NULL;
		diag_update_proc_vote(DIAG_PROC_MEMORY_DEVICE, VOTE_DOWN, i);
	}
	mutex_unlock(&driver->diagchar_mutex);
@@ -844,19 +846,19 @@ static int diag_remote_init(void)
			poolsize_mdm_dci_write);
	diagmem_setsize(POOL_TYPE_QSC_MUX, itemsize_qsc_usb,
			poolsize_qsc_usb);
	driver->cb_buf = kzalloc(DIAG_MAX_HDLC_BUF_SIZE, GFP_KERNEL);
	if (!driver->cb_buf)
	driver->hdlc_encode_buf = kzalloc(DIAG_MAX_HDLC_BUF_SIZE, GFP_KERNEL);
	if (!driver->hdlc_encode_buf)
		return -ENOMEM;
	driver->cb_buf_len = 0;
	driver->hdlc_encode_buf_len = 0;
	return 0;
}

static void diag_remote_exit(void)
{
	kfree(driver->cb_buf);
	kfree(driver->hdlc_encode_buf);
}

static int diag_cb_send_data_remote(int proc, void *buf, int len,
static int diag_send_raw_data_remote(int proc, void *buf, int len,
				    uint8_t hdlc_flag)
{
	int err = 0;
@@ -866,6 +868,7 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len,
	uint16_t payload = 0;
	struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
	struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
	int bridge_index = proc - 1;

	if (!buf)
		return -EINVAL;
@@ -875,24 +878,30 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len,
		return -EBADMSG;
	}

	if (bridge_index < 0 || bridge_index > NUM_REMOTE_DEV) {
		pr_err("diag: In %s, invalid bridge index: %d\n", __func__,
			bridge_index);
		return -EINVAL;
	 }

	do {
		if (driver->cb_buf_len == 0)
		if (driver->hdlc_encode_buf_len == 0)
			break;
		usleep_range(10000, 10100);
		retry_count++;
	} while (retry_count < max_retries);

	if (driver->cb_buf_len != 0)
	if (driver->hdlc_encode_buf_len != 0)
		return -EAGAIN;

	if (driver->hdlc_disabled) {
		payload = *(uint16_t *)(buf + 2);
		driver->cb_buf_len = payload;
		driver->hdlc_encode_buf_len = payload;
		/*
		 * Adding 4 bytes for start (1 byte), version (1 byte) and
		 * payload (2 bytes)
		 */
		memcpy(driver->cb_buf, buf + 4, payload);
		memcpy(driver->hdlc_encode_buf, buf + 4, payload);
		goto send_data;
	}

@@ -902,8 +911,8 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len,
			       len);
			return -EBADMSG;
		}
		driver->cb_buf_len = len;
		memcpy(driver->cb_buf, buf, len);
		driver->hdlc_encode_buf_len = len;
		memcpy(driver->hdlc_encode_buf, buf, len);
		goto send_data;
	}

@@ -924,18 +933,19 @@ static int diag_cb_send_data_remote(int proc, void *buf, int len,
	send.last = (void *)(buf + len - 1);
	send.terminate = 1;

	enc.dest = driver->cb_buf;
	enc.dest_last = (void *)(driver->cb_buf + max_len - 1);
	enc.dest = driver->hdlc_encode_buf;
	enc.dest_last = (void *)(driver->hdlc_encode_buf + max_len - 1);
	diag_hdlc_encode(&send, &enc);
	driver->cb_buf_len = (int)(enc.dest - (void *)driver->cb_buf);
	driver->hdlc_encode_buf_len = (int)(enc.dest -
					(void *)driver->hdlc_encode_buf);

send_data:
	err = diagfwd_bridge_write(proc, driver->cb_buf,
				   driver->cb_buf_len);
	err = diagfwd_bridge_write(proc, driver->hdlc_encode_buf,
				   driver->hdlc_encode_buf_len);
	if (err) {
		pr_err_ratelimited("diag: Error writing Callback packet to proc: %d, err: %d\n",
				   proc, err);
		driver->cb_buf_len = 0;
		driver->hdlc_encode_buf_len = 0;
	}

	return err;
@@ -986,7 +996,7 @@ uint16_t diag_get_remote_device_mask(void)
	return 0;
}

static int diag_cb_send_data_remote(int proc, void *buf, int len,
static int diag_send_raw_data_remote(int proc, void *buf, int len,
				    uint8_t hdlc_flag)
{
	return -EINVAL;
@@ -1006,7 +1016,22 @@ static int mask_request_validate(unsigned char mask_buf[])

	packet_id = mask_buf[0];

	if (packet_id == 0x4B) {
	if (packet_id == DIAG_CMD_DIAG_SUBSYS_DELAY) {
		subsys_id = mask_buf[1];
		ss_cmd = *(uint16_t *)(mask_buf + 2);
		switch (subsys_id) {
		case DIAG_SS_DIAG:
			if ((ss_cmd == DIAG_SS_FILE_READ_MODEM) ||
				(ss_cmd == DIAG_SS_FILE_READ_ADSP) ||
				(ss_cmd == DIAG_SS_FILE_READ_WCNSS) ||
				(ss_cmd == DIAG_SS_FILE_READ_SLPI) ||
				(ss_cmd == DIAG_SS_FILE_READ_APPS))
				return 1;
			break;
		default:
			return 0;
		}
	} else if (packet_id == 0x4B) {
		subsys_id = mask_buf[1];
		ss_cmd = *(uint16_t *)(mask_buf + 2);
		/* Packets with SSID which are allowed */
@@ -1113,6 +1138,10 @@ static int diag_switch_logging(int requested_mode)
		driver->md_proc[DIAG_LOCAL_PROC].socket_process = NULL;
	}

	if (new_mode == MEMORY_DEVICE_MODE)
		driver->md_client_info.client_process = current;

	mutex_lock(&driver->diagchar_mutex);
	diag_ws_reset(DIAG_WS_MUX);
	err = diag_mux_switch_logging(mux_mode);
	if (err) {
@@ -1974,7 +2003,7 @@ fail:
	return err;
}

static int diag_user_process_callback_data(const char __user *buf, int len)
static int diag_user_process_raw_data(const char __user *buf, int len)
{
	int err = 0;
	int ret = 0;
@@ -2001,82 +2030,41 @@ static int diag_user_process_callback_data(const char __user *buf, int len)

	/* Check for proc_type */
	remote_proc = diag_get_remote(*(int *)user_space_data);
	if (!remote_proc) {
		wait_event_interruptible(driver->wait_q,
					 (driver->in_busy_pktdata == 0));
		ret = diag_process_apps_pkt(user_space_data, len);
		diagmem_free(driver, user_space_data, mempool);
		user_space_data = NULL;
		return ret;
	}

	if (remote_proc) {
		token_offset = sizeof(int);
		if (len <= MIN_SIZ_ALLOW) {
			pr_err("diag: In %s, possible integer underflow, payload size: %d\n",
		       __func__, len);
			diagmem_free(driver, user_space_data, mempool);
			user_space_data = NULL;
			return -EBADMSG;
		}

		len -= sizeof(int);
	ret = diag_cb_send_data_remote(remote_proc - 1,
				(void *)(user_space_data + token_offset),
				len, CALLBACK_NON_HDLC_DATA);
fail:
	}
	if (driver->mask_check) {
		if (!mask_request_validate(user_space_data +
						token_offset)) {
			pr_alert("diag: mask request Invalid\n");
			diagmem_free(driver, user_space_data, mempool);
			user_space_data = NULL;
	return ret;
			return -EFAULT;
		}

static int diag_user_process_callback_hdlc_data(const char __user *buf, int len)
{
	int err = 0;
	int ret = 0;
	int token_offset = 0;
	int remote_proc = 0;
	const int mempool = POOL_TYPE_COPY;
	unsigned char *user_space_data = NULL;

	if (!buf || len <= 0 || len > CALLBACK_BUF_SIZE) {
		pr_err_ratelimited("diag: In %s, invalid buf %p len: %d\n",
				   __func__, buf, len);
		return -EBADMSG;
	}

	user_space_data = diagmem_alloc(driver, len, mempool);
	if (!user_space_data)
		return -ENOMEM;

	err = copy_from_user(user_space_data, buf, len);
	if (err) {
		pr_err("diag: copy failed for user space data\n");
		goto fail;
	if (remote_proc) {
		ret = diag_send_raw_data_remote(remote_proc - 1,
				(void *)(user_space_data + token_offset),
				len, USER_SPACE_RAW_DATA);
		if (ret) {
			pr_err("diag: Error sending data to remote proc %d, err: %d\n",
				remote_proc, ret);
		}

	/* Check for proc_type */
	remote_proc = diag_get_remote(*(int *)user_space_data);
	if (!remote_proc) {
	} else {
		wait_event_interruptible(driver->wait_q,
					 (driver->in_busy_pktdata == 0));
		if (driver->hdlc_disabled)
			diag_process_non_hdlc_pkt(user_space_data, len);
		else
			diag_process_hdlc_pkt((void *)user_space_data, len);
		diagmem_free(driver, user_space_data, mempool);
		user_space_data = NULL;
		return 0;
	}

	token_offset = sizeof(int);
	if (len <= MIN_SIZ_ALLOW) {
		pr_err("diag: In %s, possible integer underflow, payload size: %d\n",
		       __func__, len);
		return -EBADMSG;
		ret = diag_process_apps_pkt(user_space_data, len);
		if (ret == 1)
			diag_send_error_rsp((void *)(user_space_data), len);
	}

	len -= sizeof(int);
	ret = diag_cb_send_data_remote(remote_proc - 1,
				(void *)(user_space_data + token_offset),
				len, CALLBACK_HDLC_DATA);
fail:
	diagmem_free(driver, user_space_data, mempool);
	user_space_data = NULL;
@@ -2463,11 +2451,8 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf,
						       pkt_type);
	else if (pkt_type == DCI_DATA_TYPE)
		return diag_user_process_dci_data(payload_buf, payload_len);
	else if (pkt_type == CALLBACK_DATA_TYPE)
		return diag_user_process_callback_data(payload_buf,
						       payload_len);
	else if (pkt_type == CALLBACK_HDLC_DATA_TYPE)
		return diag_user_process_callback_hdlc_data(payload_buf,
	else if (pkt_type == USER_SPACE_RAW_DATA_TYPE)
		return diag_user_process_raw_data(payload_buf,
							    payload_len);
	else if (pkt_type == USER_SPACE_DATA_TYPE)
		return diag_user_process_userspace_data(payload_buf,
@@ -2831,6 +2816,7 @@ static int __init diagchar_init(void)
		driver->md_proc[i].callback_process = NULL;
		driver->md_proc[i].socket_process = NULL;
	}
	driver->md_client_info.client_process = NULL;
	driver->mask_check = 0;
	driver->in_busy_pktdata = 0;
	driver->in_busy_dcipktdata = 0;
+5 −4
Original line number Diff line number Diff line
@@ -606,11 +606,12 @@ int diag_cmd_get_mobile_id(unsigned char *src_buf, int src_len,
	rsp.header.cmd_code = header->cmd_code;
	rsp.header.subsys_id = header->subsys_id;
	rsp.header.subsys_cmd_code = header->subsys_cmd_code;
	rsp.version = 1;
	rsp.version = 2;
	rsp.padding[0] = 0;
	rsp.padding[1] = 0;
	rsp.padding[2] = 0;
	rsp.family = (uint32_t)socinfo_get_msm_cpu();
	rsp.family = 0;
	rsp.chip_id = (uint32_t)socinfo_get_id();

	memcpy(dest_buf, &rsp, sizeof(rsp));
	write_len += sizeof(rsp);
@@ -719,7 +720,7 @@ static int diag_cmd_disable_hdlc(unsigned char *src_buf, int src_len,
	return write_len;
}

static void diag_send_error_rsp(unsigned char *buf, int len)
void diag_send_error_rsp(unsigned char *buf, int len)
{
	/* -1 to accomodate the first byte 0x13 */
	if (len > (DIAG_MAX_RSP_SIZE - 1)) {
@@ -856,7 +857,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len)
						   driver->apps_rsp_buf,
						   DIAG_MAX_RSP_SIZE);
		if (write_len > 0) {
			diag_send_rsp(driver->apps_rsp_buf, write_len - 1);
			diag_send_rsp(driver->apps_rsp_buf, write_len);
			return 0;
		}
	}
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ int diag_check_common_cmd(struct diag_pkt_header_t *header);
void diag_update_userspace_clients(unsigned int type);
void diag_update_sleeping_process(int process_id, int data_type);
int diag_process_apps_pkt(unsigned char *buf, int len);
void diag_send_error_rsp(unsigned char *buf, int len);
void diag_update_pkt_buffer(unsigned char *buf, uint32_t len, int type);
int diag_process_stm_cmd(unsigned char *buf, unsigned char *dest_buf);
#endif
Loading