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

Commit 997b7493 authored by Ravi Aravamudhan's avatar Ravi Aravamudhan Committed by Gerrit - the friendly Code Review server
Browse files

diag: Expand msg mask buffer dynamically



Diag driver should support any number of msg mask set by the tools.
It truncates the msg mask to the maximum size of the buffer that is
used to store the msg mask. This patch implements this change.

Change-Id: Ieff2180475c5c1bcf9f8a90dffc78d689b2e5c5e
Signed-off-by: default avatarRavi Aravamudhan <aravamud@codeaurora.org>
parent 5ef36a5b
Loading
Loading
Loading
Loading
+42 −22
Original line number Diff line number Diff line
@@ -327,14 +327,15 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last)
	}

	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
		if (((first < mask->ssid_first) || (last > mask->ssid_last)) &&
							first != ALL_SSID) {
		if (((first < mask->ssid_first) ||
		     (last > mask->ssid_last_tools)) && first != ALL_SSID) {
			continue;
		}

		mutex_lock(&mask->lock);
		if (mask_info->status == DIAG_CTRL_MASK_VALID) {
			mask_size = mask->ssid_last - mask->ssid_first + 1;
			mask_size =
				mask->ssid_last_tools - mask->ssid_first + 1;
			temp_len = mask_size * sizeof(uint32_t);
			if (temp_len + header_len <= mask_info->update_buf_len)
				goto proceed;
@@ -360,7 +361,7 @@ proceed:
		header.stream_id = 1;
		header.msg_mode = 0;
		header.ssid_first = mask->ssid_first;
		header.ssid_last = mask->ssid_last;
		header.ssid_last = mask->ssid_last_tools;
		header.msg_mask_size = mask_size;
		mask_size *= sizeof(uint32_t);
		header.data_len = MSG_MASK_CTRL_HEADER_LEN + mask_size;
@@ -508,7 +509,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
			break;
		}
		ssid_range.ssid_first = mask_ptr->ssid_first;
		ssid_range.ssid_last = mask_ptr->ssid_last;
		ssid_range.ssid_last = mask_ptr->ssid_last_tools;
		memcpy(dest_buf + write_len, &ssid_range, sizeof(ssid_range));
		write_len += sizeof(ssid_range);
	}
@@ -606,7 +607,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
	mask = (struct diag_msg_mask_t *)mask_info->ptr;
	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
		if ((req->ssid_first < mask->ssid_first) ||
		    (req->ssid_first > mask->ssid_last)) {
		    (req->ssid_first > mask->ssid_last_tools)) {
			continue;
		}
		mask_size = mask->range * sizeof(uint32_t);
@@ -638,6 +639,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
	struct diag_msg_build_mask_t *req = NULL;
	struct diag_msg_build_mask_t rsp;
	struct diag_mask_info *mask_info = NULL;
	uint32_t *temp = NULL;

	mask_info = (!info) ? &msg_mask : info->msg_mask;
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
@@ -654,28 +656,43 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
	mask = (struct diag_msg_mask_t *)mask_info->ptr;
	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
		if ((req->ssid_first < mask->ssid_first) ||
		    (req->ssid_first > mask->ssid_last)) {
		    (req->ssid_first > mask->ssid_last_tools)) {
			continue;
		}
		found = 1;
		mutex_lock(&mask->lock);
		if (req->ssid_last > mask->ssid_last) {
			pr_debug("diag: Msg SSID range mismatch\n");
			mask->ssid_last = req->ssid_last;
		}
		mask_size = req->ssid_last - req->ssid_first + 1;
		if (mask_size > mask->range) {
		if (mask_size > MAX_SSID_PER_RANGE) {
			pr_warn("diag: In %s, truncating ssid range, %d-%d to max allowed: %d\n",
				__func__, mask->ssid_first, mask->ssid_last,
				mask->range);
			mask_size = mask->range;
			mask->ssid_last = mask->ssid_first + mask->range;
				MAX_SSID_PER_RANGE);
			mask_size = MAX_SSID_PER_RANGE;
			mask->range_tools = MAX_SSID_PER_RANGE;
			mask->ssid_last_tools =
				mask->ssid_first + mask->range_tools;
		}
		offset = req->ssid_first - mask->ssid_first;
		if (offset + mask_size > mask->range) {
			pr_err("diag: In %s, Not enough space for msg mask, mask_size: %d\n",
		if (req->ssid_last > mask->ssid_last_tools) {
			pr_debug("diag: Msg SSID range mismatch\n");
			if (mask_size != MAX_SSID_PER_RANGE)
				mask->ssid_last_tools = req->ssid_last;
			temp = krealloc(mask->ptr,
					mask_size * sizeof(uint32_t),
					GFP_KERNEL);
			if (!temp) {
				pr_err_ratelimited("diag: In %s, unable to allocate memory for msg mask ptr, mask_size: %d\n",
						   __func__, mask_size);
				mutex_unlock(&mask->lock);
				return -ENOMEM;
			}
			mask->ptr = temp;
			mask->range_tools = mask_size;
		}

		offset = req->ssid_first - mask->ssid_first;
		if (offset + mask_size > mask->range_tools) {
			pr_err("diag: In %s, Not in msg mask range, mask_size: %d, offset: %d\n",
			       __func__, mask_size, offset);
			mutex_unlock(&mask->lock);
			break;
		}
		mask_size = mask_size * sizeof(uint32_t);
@@ -1230,9 +1247,11 @@ int diag_create_msg_mask_table_entry(struct diag_msg_mask_t *msg_mask,
		return -EINVAL;
	msg_mask->ssid_first = range->ssid_first;
	msg_mask->ssid_last = range->ssid_last;
	msg_mask->ssid_last_tools = range->ssid_last;
	msg_mask->range = msg_mask->ssid_last - msg_mask->ssid_first + 1;
	if (msg_mask->range < MAX_SSID_PER_RANGE)
		msg_mask->range = MAX_SSID_PER_RANGE;
	msg_mask->range_tools = msg_mask->range;
	mutex_init(&msg_mask->lock);
	if (msg_mask->range > 0) {
		msg_mask->ptr = kzalloc(msg_mask->range * sizeof(uint32_t),
@@ -1757,14 +1776,15 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
		len = 0;
		mutex_lock(&mask->lock);
		header.ssid_first = mask->ssid_first;
		header.ssid_last = mask->ssid_last;
		header.range = mask->range;
		header.ssid_last = mask->ssid_last_tools;
		header.range = mask->range_tools;
		memcpy(ptr, &header, sizeof(header));
		len += sizeof(header);
		copy_len = (sizeof(uint32_t) * mask->range);
		copy_len = (sizeof(uint32_t) * mask->range_tools);
		if ((len + copy_len) > mask_info->update_buf_len) {
			pr_err("diag: In %s, no space to update msg mask, first: %d, last: %d\n",
			       __func__, mask->ssid_first, mask->ssid_last);
			       __func__, mask->ssid_first,
			       mask->ssid_last_tools);
			mutex_unlock(&mask->lock);
			continue;
		}
+2 −0
Original line number Diff line number Diff line
@@ -33,7 +33,9 @@ struct diag_ssid_range_t {
struct diag_msg_mask_t {
	uint32_t ssid_first;
	uint32_t ssid_last;
	uint32_t ssid_last_tools;
	uint32_t range;
	uint32_t range_tools;
	struct mutex lock;
	uint32_t *ptr;
};
+0 −6
Original line number Diff line number Diff line
@@ -454,7 +454,6 @@ static int update_msg_mask_tbl_entry(struct diag_msg_mask_t *mask,
				     struct diag_ssid_range_t *range)
{
	uint32_t temp_range;
	uint32_t *temp = NULL;

	if (!mask || !range)
		return -EIO;
@@ -465,11 +464,6 @@ static int update_msg_mask_tbl_entry(struct diag_msg_mask_t *mask,
	}
	if (range->ssid_last >= mask->ssid_last) {
		temp_range = range->ssid_last - mask->ssid_first + 1;
		temp = krealloc(mask->ptr, temp_range * sizeof(uint32_t),
				GFP_KERNEL);
		if (!temp)
			return -ENOMEM;
		mask->ptr = temp;
		mask->ssid_last = range->ssid_last;
		mask->range = temp_range;
	}