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

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

Merge "diag: Flush mdlog table entries while reallocation of data buffer"

parents 16a03ceb 53bf345c
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -152,15 +152,20 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx)
		return -EIO;

	ch = &diag_md[id];
	if (!ch)
		return -EINVAL;

	spin_lock_irqsave(&ch->lock, flags);
	for (i = 0; i < ch->num_tbl_entries && !found; i++) {
		if (ch->tbl[i].buf != buf)
			continue;
		found = 1;
		pr_err_ratelimited("diag: trying to write the same buffer buf: %pK, ctxt: %d len: %d at i: %d back to the table, proc: %d, mode: %d\n",
				   buf, ctx, ch->tbl[i].len,
				   i, id, driver->logging_mode);
		pr_err_ratelimited("diag: trying to write the same buffer buf: %pK, len: %d, back to the table for p: %d, t: %d, buf_num: %d, proc: %d, i: %d\n",
				   buf, ch->tbl[i].len, GET_BUF_PERIPHERAL(ctx),
				   GET_BUF_TYPE(ctx), GET_BUF_NUM(ctx), id, i);
		ch->tbl[i].buf = NULL;
		ch->tbl[i].len = 0;
		ch->tbl[i].ctx = 0;
	}
	spin_unlock_irqrestore(&ch->lock, flags);

@@ -224,7 +229,7 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
		ch = &diag_md[i];
		for (j = 0; j < ch->num_tbl_entries && !err; j++) {
			entry = &ch->tbl[j];
			if (entry->len <= 0)
			if (entry->len <= 0 || entry->buf == NULL)
				continue;

			peripheral = diag_md_get_peripheral(entry->ctx);
+6 −0
Original line number Diff line number Diff line
@@ -1657,6 +1657,9 @@ static int diagfwd_mux_write_done(unsigned char *buf, int len, int buf_ctxt,
	switch (type) {
	case TYPE_DATA:
		if (peripheral >= 0 && peripheral < NUM_PERIPHERALS) {
			DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"Marking buffer as free after write done p: %d, t: %d, buf_num: %d\n",
				peripheral, type, num);
			diagfwd_write_done(peripheral, type, num);
			diag_ws_on_copy(DIAG_WS_MUX);
		} else if (peripheral == APPS_DATA) {
@@ -1671,6 +1674,9 @@ static int diagfwd_mux_write_done(unsigned char *buf, int len, int buf_ctxt,
	case TYPE_CMD:
		if (peripheral >= 0 && peripheral < NUM_PERIPHERALS) {
			diagfwd_write_done(peripheral, type, num);
			DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"Marking buffer as free after write done p: %d, t: %d, buf_num: %d\n",
				peripheral, type, num);
		}
		if (peripheral == APPS_DATA ||
				ctxt == DIAG_MEMORY_DEVICE_MODE) {
+125 −42
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include "diag_mux.h"
#include "diag_ipc_logging.h"
#include "diagfwd_glink.h"
#include "diag_memorydevice.h"

struct data_header {
	uint8_t control_char;
@@ -187,8 +188,10 @@ static int diag_add_hdlc_encoding(unsigned char *dest_buf, int *dest_len,

static int check_bufsize_for_encoding(struct diagfwd_buf_t *buf, uint32_t len)
{
	int i, ctx = 0;
	uint32_t max_size = 0;
	unsigned char *temp_buf = NULL;
	struct diag_md_info *ch = NULL;

	if (!buf || len == 0)
		return -EINVAL;
@@ -202,11 +205,31 @@ static int check_bufsize_for_encoding(struct diagfwd_buf_t *buf, uint32_t len)
		}

		if (buf->len < max_size) {
			if (driver->logging_mode == DIAG_MEMORY_DEVICE_MODE) {
				ch = &diag_md[DIAG_LOCAL_PROC];
				for (i = 0; ch != NULL &&
						i < ch->num_tbl_entries; i++) {
					if (ch->tbl[i].buf == buf->data) {
						ctx = ch->tbl[i].ctx;
						ch->tbl[i].buf = NULL;
						ch->tbl[i].len = 0;
						ch->tbl[i].ctx = 0;
						DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
						"Flushed mdlog table entries before reallocating data buffer, p:%d, t:%d\n",
						GET_BUF_PERIPHERAL(ctx),
						GET_BUF_TYPE(ctx));
						break;
					}
				}
			}
			temp_buf = krealloc(buf->data, max_size +
						APF_DIAG_PADDING,
					    GFP_KERNEL);
			if (!temp_buf)
				return -ENOMEM;
			DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"Reallocated data buffer: %pK with size: %d\n",
			temp_buf, max_size);
			buf->data = temp_buf;
			buf->len = max_size;
		}
@@ -377,6 +400,10 @@ static void diagfwd_data_process_done(struct diagfwd_info *fwd_info,
	mutex_unlock(&fwd_info->data_mutex);
	mutex_unlock(&driver->hdlc_disable_mutex);
	if (buf) {
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
		"Marking buffer as free p: %d, t: %d, buf_num: %d\n",
			fwd_info->peripheral, fwd_info->type,
			GET_BUF_NUM(buf->ctxt));
		diagfwd_write_done(fwd_info->peripheral, fwd_info->type,
				   GET_BUF_NUM(buf->ctxt));
	}
@@ -483,17 +510,27 @@ static void diagfwd_data_read_untag_done(struct diagfwd_info *fwd_info,
			temp_buf_main += (packet_len + 4);
			processed += packet_len;
		}
		for (i = 0; i <= (fwd_info->num_pd - 2); i++) {
			if (fwd_info->type == TYPE_DATA && len_upd[i]) {

		if (flag_buf_1) {
			fwd_info->cpd_len_1 = len_cpd;
			for (i = 0; i <= (fwd_info->num_pd - 2); i++)
				if (fwd_info->type == TYPE_DATA)
					fwd_info->upd_len[i][0] = len_upd[i];
		} else if (flag_buf_2) {
			fwd_info->cpd_len_2 = len_cpd;
			for (i = 0; i <= (fwd_info->num_pd - 2); i++)
				if (fwd_info->type == TYPE_DATA)
					fwd_info->upd_len[i][1] = len_upd[i];
		}

		for (i = 0; i <= (fwd_info->num_pd - 2); i++) {
			if (fwd_info->type == TYPE_DATA && len_upd[i]) {
				if (flag_buf_1)
					temp_fwdinfo_upd =
						fwd_info->buf_upd[i][0];
				} else {
					fwd_info->upd_len[i][1] = len_upd[i];
				else
					temp_fwdinfo_upd =
						fwd_info->buf_upd[i][1];
				}
				temp_fwdinfo_upd->ctxt &= 0x00FFFFFF;
				temp_fwdinfo_upd->ctxt |=
					(SET_PD_CTXT(ctxt_upd[i]));
@@ -508,26 +545,9 @@ static void diagfwd_data_read_untag_done(struct diagfwd_info *fwd_info,
			}
		}

		if (flag_buf_1) {
			fwd_info->cpd_len_1 = len_cpd;
			for (i = 0; i <= (fwd_info->num_pd - 2); i++)
				if (fwd_info->type == TYPE_DATA)
					fwd_info->upd_len[i][0] = len_upd[i];
		} else if (flag_buf_2) {
			fwd_info->cpd_len_2 = len_cpd;
			for (i = 0; i <= (fwd_info->num_pd - 2); i++)
				if (fwd_info->type == TYPE_DATA)
					fwd_info->upd_len[i][1] = len_upd[i];
		}

		if (len_cpd) {
			if (flag_buf_1)
				fwd_info->cpd_len_1 = len_cpd;
			else
				fwd_info->cpd_len_2 = len_cpd;
			temp_fwdinfo_cpd->ctxt &= 0x00FFFFFF;
			temp_fwdinfo_cpd->ctxt |=
				(SET_PD_CTXT(ctxt_cpd));
			temp_fwdinfo_cpd->ctxt |= (SET_PD_CTXT(ctxt_cpd));
			diagfwd_data_process_done(fwd_info,
				temp_fwdinfo_cpd, len_cpd);
		} else {
@@ -543,6 +563,10 @@ static void diagfwd_data_read_untag_done(struct diagfwd_info *fwd_info,
end:
	diag_ws_release();
	if (temp_fwdinfo_cpd) {
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
		"Marking buffer as free p: %d, t: %d, buf_num: %d\n",
			fwd_info->peripheral, fwd_info->type,
			GET_BUF_NUM(temp_fwdinfo_cpd->ctxt));
		diagfwd_write_done(fwd_info->peripheral, fwd_info->type,
				   GET_BUF_NUM(temp_fwdinfo_cpd->ctxt));
	}
@@ -663,6 +687,10 @@ static void diagfwd_data_read_done(struct diagfwd_info *fwd_info,
	mutex_unlock(&fwd_info->data_mutex);
	mutex_unlock(&driver->hdlc_disable_mutex);
	if (temp_buf) {
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
		"Marking buffer as free p: %d, t: %d, buf_num: %d\n",
			fwd_info->peripheral, fwd_info->type,
			GET_BUF_NUM(temp_buf->ctxt));
		diagfwd_write_done(fwd_info->peripheral, fwd_info->type,
				   GET_BUF_NUM(temp_buf->ctxt));
	}
@@ -742,6 +770,16 @@ static void diagfwd_reset_buffers(struct diagfwd_info *fwd_info,
		else if (fwd_info->buf_2 && fwd_info->buf_2->data_raw == buf)
			atomic_set(&fwd_info->buf_2->in_busy, 0);
	}
	if (fwd_info->buf_1 && !atomic_read(&(fwd_info->buf_1->in_busy))) {
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
		"Buffer 1 for core PD is marked free, p: %d, t: %d\n",
			fwd_info->peripheral, fwd_info->type);
	}
	if (fwd_info->buf_2 && !atomic_read(&(fwd_info->buf_2->in_busy))) {
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
		"Buffer 2 for core PD is marked free, p: %d, t: %d\n",
			fwd_info->peripheral, fwd_info->type);
	}
}

int diagfwd_peripheral_init(void)
@@ -1137,10 +1175,28 @@ static void __diag_fwd_open(struct diagfwd_info *fwd_info)
	if (!fwd_info->inited)
		return;

	if (fwd_info->buf_1)
	/*
	 * Logging mode here is reflecting previous mode
	 * status and will be updated to new mode later.
	 *
	 * Keeping the buffers busy for Memory Device Mode.
	 */

	if ((driver->logging_mode != DIAG_USB_MODE) ||
		driver->usb_connected) {
		if (fwd_info->buf_1) {
			atomic_set(&fwd_info->buf_1->in_busy, 0);
	if (fwd_info->buf_2)
			DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"Buffer 1 for core PD is marked free, p: %d, t: %d\n",
				fwd_info->peripheral, fwd_info->type);
		}
		if (fwd_info->buf_2) {
			atomic_set(&fwd_info->buf_2->in_busy, 0);
			DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"Buffer 2 for core PD is marked free, p: %d, t: %d\n",
				fwd_info->peripheral, fwd_info->type);
		}
	}

	if (fwd_info->p_ops && fwd_info->p_ops->open)
		fwd_info->p_ops->open(fwd_info->ctxt);
@@ -1265,10 +1321,18 @@ int diagfwd_channel_close(struct diagfwd_info *fwd_info)
	if (fwd_info && fwd_info->c_ops && fwd_info->c_ops->close)
		fwd_info->c_ops->close(fwd_info);

	if (fwd_info->buf_1 && fwd_info->buf_1->data)
	if (fwd_info->buf_1 && fwd_info->buf_1->data) {
		atomic_set(&fwd_info->buf_1->in_busy, 0);
	if (fwd_info->buf_2 && fwd_info->buf_2->data)
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
		"Buffer 1 for core PD is marked free, p: %d, t: %d\n",
			fwd_info->peripheral, fwd_info->type);
	}
	if (fwd_info->buf_2 && fwd_info->buf_2->data) {
		atomic_set(&fwd_info->buf_2->in_busy, 0);
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
		"Buffer 2 for core PD is marked free, p: %d, t: %d\n",
				fwd_info->peripheral, fwd_info->type);
	}

	for (i = 0; i < NUM_WRITE_BUFFERS; i++) {
		if (fwd_info->buf_ptr[i])
@@ -1294,6 +1358,9 @@ int diagfwd_channel_read_done(struct diagfwd_info *fwd_info,
	 * in_busy flags. No need to queue read in this case.
	 */
	if (len == 0) {
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
		"Read Length is 0, resetting the diag buffers p: %d, t: %d\n",
			fwd_info->peripheral, fwd_info->type);
		diagfwd_reset_buffers(fwd_info, buf);
		diag_ws_release();
		return 0;
@@ -1306,7 +1373,7 @@ int diagfwd_channel_read_done(struct diagfwd_info *fwd_info,
	return 0;
}

void diagfwd_write_done(uint8_t peripheral, uint8_t type, int ctxt)
void diagfwd_write_done(uint8_t peripheral, uint8_t type, int buf_num)
{
	int i = 0, upd_valid_len = 0;
	struct diagfwd_info *fwd_info = NULL;
@@ -1318,7 +1385,7 @@ void diagfwd_write_done(uint8_t peripheral, uint8_t type, int ctxt)
	if (!fwd_info)
		return;

	if (ctxt == 1 && fwd_info->buf_1) {
	if (buf_num == 1 && fwd_info->buf_1) {
		/* Buffer 1 for core PD is freed */
		fwd_info->cpd_len_1 = 0;
		for (i = 0; i <= (fwd_info->num_pd - 2); i++) {
@@ -1327,9 +1394,13 @@ void diagfwd_write_done(uint8_t peripheral, uint8_t type, int ctxt)
				break;
			}
		}
		if (!upd_valid_len)
		if (!upd_valid_len) {
			atomic_set(&fwd_info->buf_1->in_busy, 0);
	} else if (ctxt == 2 && fwd_info->buf_2) {
			DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"Buffer 1 for core PD is marked free, p: %d, t: %d, buf_num: %d\n",
				fwd_info->peripheral, fwd_info->type, buf_num);
		}
	} else if (buf_num == 2 && fwd_info->buf_2) {
		/* Buffer 2 for core PD is freed */
		fwd_info->cpd_len_2 = 0;
		for (i = 0; i <= (fwd_info->num_pd - 2); i++) {
@@ -1338,30 +1409,42 @@ void diagfwd_write_done(uint8_t peripheral, uint8_t type, int ctxt)
				break;
			}
		}
		if (!upd_valid_len)
		if (!upd_valid_len) {
			atomic_set(&fwd_info->buf_2->in_busy, 0);
	} else if (ctxt >= 3 && (ctxt % 2)) {
			DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"Buffer 2 for core PD is marked free, p: %d, t: %d, buf_num: %d\n",
				fwd_info->peripheral, fwd_info->type, buf_num);
		}
	} else if (buf_num >= 3 && (buf_num % 2)) {
		for (i = 0; i <= (fwd_info->num_pd - 2); i++) {
			if (fwd_info->buf_upd[i][0]) {
				/* Buffer 1 for ith user PD is freed */
			atomic_set(&fwd_info->buf_upd[i][0]->in_busy, 0);
			fwd_info->upd_len[i][0] = 0;
			}
		if (!fwd_info->cpd_len_1)
			if (!fwd_info->cpd_len_1) {
				atomic_set(&fwd_info->buf_1->in_busy, 0);
				DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
				"Buffer 1 for core PD is marked free, p: %d, t: %d, buf_num: %d\n",
				fwd_info->peripheral, fwd_info->type, buf_num);
			}
		}
	} else if (ctxt >= 4 && !(ctxt % 2)) {
	} else if (buf_num >= 4 && !(buf_num % 2)) {
		for (i = 0; i <= (fwd_info->num_pd - 2); i++) {
			if (fwd_info->buf_upd[i][1]) {
				/* Buffer 2 for ith user PD is freed */
			atomic_set(&fwd_info->buf_upd[i][0]->in_busy, 0);
			atomic_set(&fwd_info->buf_upd[i][1]->in_busy, 0);
			fwd_info->upd_len[i][1] = 0;
			}
		if (!fwd_info->cpd_len_2)
			if (!fwd_info->cpd_len_2) {
				atomic_set(&fwd_info->buf_2->in_busy, 0);
				DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
				"Buffer 2 for core PD is marked free, p: %d, t: %d, buf_num: %d\n",
				fwd_info->peripheral, fwd_info->type, buf_num);
			}
		}
	} else
		pr_err("diag: In %s, invalid ctxt %d\n", __func__, ctxt);
		pr_err("diag: In %s, invalid buf_num: %d\n", __func__, buf_num);

	diagfwd_queue_read(fwd_info);
}
+1 −1
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ int diagfwd_cntl_register(uint8_t transport, uint8_t peripheral, void *ctxt,
void diagfwd_deregister(uint8_t peripheral, uint8_t type, void *ctxt);

int diagfwd_write(uint8_t peripheral, uint8_t type, void *buf, int len);
void diagfwd_write_done(uint8_t peripheral, uint8_t type, int ctxt);
void diagfwd_write_done(uint8_t peripheral, uint8_t type, int buf_num);
void diagfwd_buffers_init(struct diagfwd_info *fwd_info);

/*