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

Commit 4d9cdfe4 authored by Ravi Aravamudhan's avatar Ravi Aravamudhan
Browse files

diag: Modularize all writes to Diag SMD channels



Diag driver calls smd_write at different places. Make all writes
consistent and reduce code size.

Change-Id: Ie3b1cef2117c7a37e3341ed1a0ffd5be0884a1fe
Signed-off-by: default avatarRavi Aravamudhan <aravamud@codeaurora.org>
parent 5bd130f8
Loading
Loading
Loading
Loading
+8 −22
Original line number Diff line number Diff line
@@ -2868,7 +2868,8 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
int diag_dci_write_proc(int peripheral, int pkt_type, char *buf, int len)
{
	struct diag_smd_info *smd_info = NULL;
	int wr_size = 0, retry = 0, err = -EAGAIN, timer = 0, i;
	int i;
	int err = 0;

	if (!buf || (peripheral < 0 || peripheral > NUM_SMD_DCI_CHANNELS)
								|| len < 0) {
@@ -2897,28 +2898,13 @@ int diag_dci_write_proc(int peripheral, int pkt_type, char *buf, int len)
	if (!smd_info || !smd_info->ch)
		return -EINVAL;

	while (retry < 3) {
		mutex_lock(&smd_info->smd_ch_mutex);
		wr_size = smd_write(smd_info->ch, buf, len);
		if (wr_size == len) {
			pr_debug("diag: successfully wrote pkt_type %d of len %d to %d in trial %d",
					pkt_type, len, peripheral, (retry+1));
			err = DIAG_DCI_NO_ERROR;
			mutex_unlock(&smd_info->smd_ch_mutex);
			break;
	err = diag_smd_write(smd_info, buf, len);
	if (err) {
		pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n",
		       __func__, smd_info->peripheral,
		       smd_info->type, len, err);
	}
		pr_debug("diag: cannot write pkt_type %d of len %d to %d in trial %d",
					pkt_type, len, peripheral, (retry+1));
		retry++;
		mutex_unlock(&smd_info->smd_ch_mutex);

		/*
		 * Sleep for sometime before retrying. The delay of 2000 was
		 * determined empirically as best value to use.
		 */
		for (timer = 0; timer < 5; timer++)
			usleep(2000);
	}
	return err;
}

+32 −84
Original line number Diff line number Diff line
@@ -345,8 +345,8 @@ void diag_send_log_mask_update(struct diag_smd_info *smd_info, int equip_id)
	struct diag_log_mask_t *log_item = NULL;
	struct diag_ctrl_log_mask ctrl_pkt;
	uint32_t log_mask_size = 0;
	int wr_size = -ENOMEM, retry_count = 0;
	int i, header_size, send_once = 0;
	int err = 0;

	if (!smd_info) {
		pr_err("diag: In %s, null smd info pointer\n",
@@ -396,26 +396,13 @@ void diag_send_log_mask_update(struct diag_smd_info *smd_info, int equip_id)
			       log_mask_size);
		}

		if (smd_info->ch) {
			while (retry_count < 3) {
				mutex_lock(&smd_info->smd_ch_mutex);
				wr_size = smd_write(smd_info->ch, buf,
		err = diag_smd_write(smd_info, buf,
				     header_size + log_mask_size);
				mutex_unlock(&smd_info->smd_ch_mutex);
				if (wr_size == -ENOMEM) {
					retry_count++;
					usleep_range(10000, 10100);
				} else
				break;
		if (err) {
			pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n",
			       __func__, smd_info->peripheral, smd_info->type,
			       header_size + log_mask_size, err);
		}
			if (wr_size != header_size + log_mask_size)
				pr_err("diag: log mask update failed %d, tried %d",
					wr_size, header_size + log_mask_size);
			else
				pr_debug("diag: updated log equip ID %d,len %d\n",
					 i, log_mask_size);
		} else
			pr_err("diag: ch not valid for log update\n");
		if (send_once)
			break;
	}
@@ -427,7 +414,7 @@ void diag_send_event_mask_update(struct diag_smd_info *smd_info, int num_bytes)
{
	void *buf = driver->buf_event_mask_update;
	int header_size = sizeof(struct diag_ctrl_event_mask);
	int wr_size = -ENOMEM, retry_count = 0;
	int err = 0;

	if (!smd_info) {
		pr_err("diag: In %s, null smd info pointer\n",
@@ -473,23 +460,13 @@ void diag_send_event_mask_update(struct diag_smd_info *smd_info, int num_bytes)
		return;
	}
	memcpy(buf, driver->event_mask, header_size);
	if (smd_info->ch) {
		while (retry_count < 3) {
			mutex_lock(&smd_info->smd_ch_mutex);
			wr_size = smd_write(smd_info->ch, buf,
						header_size + num_bytes);
			mutex_unlock(&smd_info->smd_ch_mutex);
			if (wr_size == -ENOMEM) {
				retry_count++;
				usleep_range(10000, 10100);
			} else
				break;

	err = diag_smd_write(smd_info, buf, header_size + num_bytes);
	if (err) {
		pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n",
		       __func__, smd_info->peripheral, smd_info->type,
		       header_size + num_bytes, err);
	}
		if (wr_size != header_size + num_bytes)
			pr_err("diag: error writing event mask %d, tried %d\n",
					 wr_size, header_size + num_bytes);
	} else
		pr_err("diag: ch not valid for event update\n");
	mutex_unlock(&driver->diag_cntl_mutex);
}

@@ -498,9 +475,11 @@ void diag_send_msg_mask_update(struct diag_smd_info *smd_info,
				int proc)
{
	void *buf = driver->buf_msg_mask_update;
	int first, last, actual_last, size = -ENOMEM, retry_count = 0;
	int first, last, actual_last;
	int header_size = sizeof(struct diag_ctrl_msg_mask);
	uint8_t *ptr = driver->msg_masks;
	int err = 0;
	int write_len = 0;

	if (!smd_info) {
		pr_err("diag: In %s, null smd info pointer\n",
@@ -566,29 +545,13 @@ void diag_send_msg_mask_update(struct diag_smd_info *smd_info,
		driver->msg_mask->ssid_first = first;
		driver->msg_mask->ssid_last = actual_last;
		memcpy(buf, driver->msg_mask, header_size);
		if (smd_info->ch) {
			while (retry_count < 3) {
				mutex_lock(&smd_info->smd_ch_mutex);
				size = smd_write(smd_info->ch, buf, header_size
					+ 4*(driver->msg_mask->msg_mask_size));
				mutex_unlock(&smd_info->smd_ch_mutex);
				if (size == -ENOMEM) {
					retry_count++;
					usleep_range(10000, 10100);
				} else
					break;
		write_len = header_size + 4 * driver->msg_mask->msg_mask_size;
		err = diag_smd_write(smd_info, buf, write_len);
		if (err) {
			pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n",
			       __func__, smd_info->peripheral, smd_info->type,
			       write_len, err);
		}
			if (size != header_size +
				 4*(driver->msg_mask->msg_mask_size))
				pr_err("diag: proc %d, msg mask update fail %d, tried %d\n",
					proc, size, (header_size +
				4*(driver->msg_mask->msg_mask_size)));
			else
				pr_debug("diag: sending mask update for ssid first %d, last %d on PROC %d\n",
					first, actual_last, proc);
		} else
			pr_err("diag: proc %d, ch invalid msg mask update\n",
								proc);
		ptr += MAX_SSID_PER_RANGE*4;
	}
	mutex_unlock(&driver->diag_cntl_mutex);
@@ -598,9 +561,9 @@ void diag_send_feature_mask_update(struct diag_smd_info *smd_info)
{
	void *buf = driver->buf_feature_mask_update;
	int header_size = sizeof(struct diag_ctrl_feature_mask);
	int wr_size = -ENOMEM, retry_count = 0;
	uint8_t feature_bytes[FEATURE_MASK_LEN_BYTES] = {0, 0};
	int total_len = 0;
	int err = 0;

	if (!smd_info) {
		pr_err("diag: In %s, null smd info pointer\n",
@@ -630,27 +593,12 @@ void diag_send_feature_mask_update(struct diag_smd_info *smd_info)
	memcpy(buf+header_size, &feature_bytes, FEATURE_MASK_LEN_BYTES);
	total_len = header_size + FEATURE_MASK_LEN_BYTES;

	while (retry_count < 3) {
		mutex_lock(&smd_info->smd_ch_mutex);
		wr_size = smd_write(smd_info->ch, buf, total_len);
		mutex_unlock(&smd_info->smd_ch_mutex);
		if (wr_size == -ENOMEM) {
			retry_count++;
			/*
			 * The smd channel is full. Delay while
			 * smd processes existing data and smd
			 * has memory become available. The delay
			 * of 10000 was determined empirically as
			 * best value to use.
			 */
			usleep_range(10000, 10100);
		} else
			break;
	err = diag_smd_write(smd_info, buf, total_len);
	if (err) {
		pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n",
		       __func__, smd_info->peripheral, smd_info->type,
		       total_len, err);
	}
	if (wr_size != total_len)
		pr_err("diag: In %s, peripheral %d fail feature update, size: %d, tried: %d",
			__func__, smd_info->peripheral, wr_size, total_len);

	mutex_unlock(&driver->diag_cntl_mutex);
}

+57 −22
Original line number Diff line number Diff line
@@ -1060,6 +1060,7 @@ int diag_send_data(struct diag_master_table entry, unsigned char *buf,
					 int len, int type)
{
	int success = 1;
	int err = 0;
	driver->pkt_length = len;

	/* If the process_id corresponds to an apps process */
@@ -1086,16 +1087,11 @@ int diag_send_data(struct diag_master_table entry, unsigned char *buf,
						index < NUM_SMD_CMD_CHANNELS) ?
						&driver->smd_cmd[index] :
						&driver->smd_data[index];

				if (smd_info->ch) {
					mutex_lock(&smd_info->smd_ch_mutex);
					smd_write(smd_info->ch, buf, len);
					mutex_unlock(&smd_info->smd_ch_mutex);
				} else {
					pr_err("diag: In %s, smd channel %d not open, peripheral: %d, type: %d\n",
						__func__, index,
						smd_info->peripheral,
						smd_info->type);
				err = diag_smd_write(smd_info, buf, len);
				if (err) {
					pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, err: %d\n",
						__func__, smd_info->peripheral,
						smd_info->type, err);
				}
			} else {
				pr_alert("diag: In %s, incorrect channel: %d",
@@ -1716,6 +1712,7 @@ void diag_process_hdlc(void *data, unsigned len)
{
	struct diag_hdlc_decode_type hdlc;
	int ret, type = 0, crc_chk = 0;
	int err = 0;

	mutex_lock(&driver->diag_hdlc_mutex);

@@ -1777,14 +1774,13 @@ void diag_process_hdlc(void *data, unsigned len)
		if (chk_apps_only()) {
			diag_send_error_rsp(hdlc.dest_idx);
		} else { /* APQ 8060, Let Q6 respond */
			if (driver->smd_data[LPASS_DATA].ch) {
				mutex_lock(&driver->smd_data[LPASS_DATA].
								smd_ch_mutex);
				smd_write(driver->smd_data[LPASS_DATA].ch,
			err = diag_smd_write(&driver->smd_data[LPASS_DATA],
					     driver->hdlc_buf,
					     hdlc.dest_idx - 3);
				mutex_unlock(&driver->smd_data[LPASS_DATA].
								smd_ch_mutex);
			if (err) {
				pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, err: %d\n",
				       __func__, LPASS_DATA, SMD_DATA_TYPE,
				       err);
			}
		}
		type = 0;
@@ -1800,10 +1796,12 @@ void diag_process_hdlc(void *data, unsigned len)
	if ((driver->smd_data[MODEM_DATA].ch) && (ret) && (type) &&
						(hdlc.dest_idx > 3)) {
		APPEND_DEBUG('g');
		mutex_lock(&driver->smd_data[MODEM_DATA].smd_ch_mutex);
		smd_write(driver->smd_data[MODEM_DATA].ch,
		err = diag_smd_write(&driver->smd_data[MODEM_DATA],
				     driver->hdlc_buf, hdlc.dest_idx - 3);
		mutex_unlock(&driver->smd_data[MODEM_DATA].smd_ch_mutex);
		if (err) {
			pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, err: %d\n",
			       __func__, MODEM_DATA, SMD_DATA_TYPE, err);
		}
		APPEND_DEBUG('h');
#ifdef DIAG_DEBUG
		printk(KERN_INFO "writing data to SMD, pkt length %d\n", len);
@@ -2490,6 +2488,43 @@ err:
	return -ENOMEM;
}

int diag_smd_write(struct diag_smd_info *smd_info, void *buf, int len)
{
	int write_len = 0;
	int retry_count = 0;
	int max_retries = 3;

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

	if (!smd_info->ch)
		return -ENODEV;

	do {
		mutex_lock(&smd_info->smd_ch_mutex);
		write_len = smd_write(smd_info->ch, buf, len);
		mutex_unlock(&smd_info->smd_ch_mutex);
		if (write_len == len)
			break;
		/*
		 * The channel maybe busy - the FIFO can be full. Retry after
		 * sometime. The value of 10000 was chosen emprically as the
		 * optimal value for the peripherals to read data from the SMD
		 * channel.
		 */
		usleep_range(10000, 10100);
		retry_count++;
	} while (retry_count < max_retries);

	if (write_len != len)
		return -ENOMEM;

	return 0;
}

int diagfwd_init(void)
{
	int ret;
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

int diagfwd_init(void);
void diagfwd_exit(void);
int diag_smd_write(struct diag_smd_info *smd_info, void *buf, int len);
void diag_process_hdlc(void *data, unsigned len);
void diag_smd_send_req(struct diag_smd_info *smd_info);
void diag_usb_legacy_notifier(void *, unsigned, struct diag_request *);
+15 −57
Original line number Diff line number Diff line
@@ -493,8 +493,8 @@ void diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info,
{
	char buf[sizeof(struct diag_ctrl_msg_diagmode)];
	int msg_size = sizeof(struct diag_ctrl_msg_diagmode);
	int wr_size = -ENOMEM, retry_count = 0, timer;
	struct diag_smd_info *data = NULL;
	int err = 0;

	if (!smd_info || smd_info->type != SMD_CNTL_TYPE) {
		pr_err("diag: In %s, invalid channel info, smd_info: %p type: %d\n",
@@ -517,37 +517,13 @@ void diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info,
	diag_create_diag_mode_ctrl_pkt(buf, real_time);

	mutex_lock(&driver->diag_cntl_mutex);
	if (smd_info->ch) {
		while (retry_count < 3) {
			mutex_lock(&smd_info->smd_ch_mutex);
			wr_size = smd_write(smd_info->ch, buf, msg_size);
			mutex_unlock(&smd_info->smd_ch_mutex);
			if (wr_size == -ENOMEM) {
				/*
				 * The smd channel is full. Delay while
				 * smd processes existing data and smd
				 * has memory become available. The delay
				 * of 2000 was determined empirically as
				 * best value to use.
				 */
				retry_count++;
				for (timer = 0; timer < 5; timer++)
					udelay(2000);
	err = diag_smd_write(smd_info, buf, msg_size);
	if (err) {
		pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n",
		       __func__, smd_info->peripheral, smd_info->type,
		       msg_size, err);
	} else {
				data =
				&driver->smd_data[smd_info->peripheral];
				driver->real_time_mode[DIAG_LOCAL_PROC] =
								real_time;
				break;
			}
		}
		if (wr_size != msg_size)
			pr_err("diag: proc %d fail feature update %d, tried %d",
				smd_info->peripheral,
				wr_size, msg_size);
	} else {
		pr_err("diag: ch invalid, feature update on proc %d\n",
				smd_info->peripheral);
		driver->real_time_mode[DIAG_LOCAL_PROC] = real_time;
	}

	mutex_unlock(&driver->diag_cntl_mutex);
@@ -558,9 +534,8 @@ int diag_send_stm_state(struct diag_smd_info *smd_info,
{
	struct diag_ctrl_msg_stm stm_msg;
	int msg_size = sizeof(struct diag_ctrl_msg_stm);
	int retry_count = 0;
	int wr_size = 0;
	int success = 0;
	int err = 0;

	if (!smd_info || (smd_info->type != SMD_CNTL_TYPE) ||
		(driver->peripheral_supports_stm[smd_info->peripheral] ==
@@ -573,30 +548,13 @@ int diag_send_stm_state(struct diag_smd_info *smd_info,
		stm_msg.ctrl_pkt_data_len = 5;
		stm_msg.version = 1;
		stm_msg.control_data = stm_control_data;
		while (retry_count < 3) {
			mutex_lock(&smd_info->smd_ch_mutex);
			wr_size = smd_write(smd_info->ch, &stm_msg, msg_size);
			mutex_unlock(&smd_info->smd_ch_mutex);
			if (wr_size == -ENOMEM) {
				/*
				 * The smd channel is full. Delay while
				 * smd processes existing data and smd
				 * has memory become available. The delay
				 * of 10000 was determined empirically as
				 * best value to use.
				 */
				retry_count++;
				usleep_range(10000, 10000);
		err = diag_smd_write(smd_info, &stm_msg, msg_size);
		if (err) {
			pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n",
			       __func__, smd_info->peripheral, smd_info->type,
			       msg_size, err);
		} else {
			success = 1;
				break;
			}
		}
		if (wr_size != msg_size) {
			pr_err("diag: In %s, proc %d fail STM update %d, tried %d",
				__func__, smd_info->peripheral, wr_size,
				msg_size);
			success = 0;
		}
	} else {
		pr_err("diag: In %s, ch invalid, STM update on proc %d\n",