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

Commit d92c6fed authored by Ravi Aravamudhan's avatar Ravi Aravamudhan Committed by Matt Wagantall
Browse files

diag: Stop reading from peripherals during close



While switching logging modes there is a possibility that the previous
read queued to the transport layer may still be pending. This read
should be cancelled before closing the channel. Otherwise, while
opening the channel again, we may queue the same buffer twice for
reading.

Change-Id: Ic5fb7713876e245bcc3260a9e67e35e611cd93a4
Signed-off-by: default avatarRavi Aravamudhan <aravamud@codeaurora.org>
parent d371440a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -511,6 +511,7 @@ static ssize_t diag_dbgfs_read_smdinfo(struct file *file, char __user *ubuf,
				"hdl\t\t:\t%p\n"
				"inited\t\t:\t%d\n"
				"opened\t\t:\t%d\n"
				"diag_state\t:\t%d\n"
				"fifo size\t:\t%d\n"
				"open pending\t:\t%d\n"
				"close pending\t:\t%d\n"
@@ -526,6 +527,7 @@ static ssize_t diag_dbgfs_read_smdinfo(struct file *file, char __user *ubuf,
				smd_info->hdl,
				smd_info->inited,
				atomic_read(&smd_info->opened),
				atomic_read(&smd_info->diag_state),
				smd_info->fifo_size,
				work_pending(&smd_info->open_work),
				work_pending(&smd_info->close_work),
@@ -615,6 +617,7 @@ static ssize_t diag_dbgfs_read_socketinfo(struct file *file, char __user *ubuf,
				"hdl\t\t:\t%p\n"
				"inited\t\t:\t%d\n"
				"opened\t\t:\t%d\n"
				"diag_state\t:\t%d\n"
				"buf_1 busy\t:\t%d\n"
				"buf_2 busy\t:\t%d\n"
				"flow ctrl count\t:\t%d\n"
@@ -630,6 +633,7 @@ static ssize_t diag_dbgfs_read_socketinfo(struct file *file, char __user *ubuf,
				info->hdl,
				info->inited,
				atomic_read(&info->opened),
				atomic_read(&info->diag_state),
				(fwd_ctxt && fwd_ctxt->buf_1) ?
				atomic_read(&fwd_ctxt->buf_1->in_busy) : -1,
				(fwd_ctxt && fwd_ctxt->buf_2) ?
+22 −0
Original line number Diff line number Diff line
@@ -552,6 +552,16 @@ int diagfwd_register(uint8_t transport, uint8_t peripheral, uint8_t type,
		return -EINVAL;
	}

	if (atomic_read(&fwd_info->opened) &&
	    fwd_info->p_ops && fwd_info->p_ops->open) {
		/*
		 * The registration can happen late, like in the case of
		 * sockets. fwd_info->opened reflects diag_state. Propogate the
		 * state to the peipherals.
		 */
		fwd_info->p_ops->open(fwd_info->ctxt);
	}

	return 0;
}

@@ -690,6 +700,9 @@ static void __diag_fwd_open(struct diagfwd_info *fwd_info)
		atomic_set(&fwd_info->buf_2->in_busy, 0);
	spin_unlock_irqrestore(&fwd_info->buf_lock, flags);

	if (fwd_info->p_ops && fwd_info->p_ops->open)
		fwd_info->p_ops->open(fwd_info->ctxt);

	diagfwd_queue_read(fwd_info);
}

@@ -736,6 +749,9 @@ void diagfwd_close(uint8_t peripheral, uint8_t type)
	if (!fwd_info->inited)
		return;

	if (fwd_info->p_ops && fwd_info->p_ops->close)
		fwd_info->p_ops->close(fwd_info->ctxt);

	spin_lock_irqsave(&fwd_info->buf_lock, flags);
	if (fwd_info->buf_1)
		atomic_set(&fwd_info->buf_1->in_busy, 1);
@@ -772,6 +788,12 @@ int diagfwd_channel_open(struct diagfwd_info *fwd_info)
	diagfwd_queue_read(fwd_info);
	DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "p: %d t: %d considered opened\n",
		 fwd_info->peripheral, fwd_info->type);

	if (atomic_read(&fwd_info->opened)) {
		if (fwd_info->p_ops && fwd_info->p_ops->open)
			fwd_info->p_ops->open(fwd_info->ctxt);
	}

	return 0;
}

+2 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ struct diag_channel_ops {
};

struct diag_peripheral_ops {
	void (*open)(void *ctxt);
	void (*close)(void *ctxt);
	int (*write)(void *ctxt, unsigned char *buf, int len);
	int (*read)(void *ctxt, unsigned char *buf, int len);
	void (*queue_read)(void *ctxt);
+42 −1
Original line number Diff line number Diff line
@@ -144,17 +144,49 @@ struct diag_smd_info smd_dci_cmd[NUM_PERIPHERALS] = {
	}
};

static void diag_state_open_smd(void *ctxt);
static void diag_state_close_smd(void *ctxt);
static void smd_notify(void *ctxt, unsigned event);
static int diag_smd_write(void *ctxt, unsigned char *buf, int len);
static int diag_smd_read(void *ctxt, unsigned char *buf, int buf_len);
static void diag_smd_queue_read(void *ctxt);

static struct diag_peripheral_ops smd_ops = {
	.open = diag_state_open_smd,
	.close = diag_state_close_smd,
	.write = diag_smd_write,
	.read = diag_smd_read,
	.queue_read = diag_smd_queue_read
};

static void diag_state_open_smd(void *ctxt)
{
	struct diag_smd_info *smd_info = NULL;

	if (!ctxt)
		return;

	smd_info = (struct diag_smd_info *)(ctxt);
	atomic_set(&smd_info->diag_state, 1);
	DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
		 "%s setting diag state to 1", smd_info->name);
}

static void diag_state_close_smd(void *ctxt)
{
	struct diag_smd_info *smd_info = NULL;

	if (!ctxt)
		return;

	smd_info = (struct diag_smd_info *)(ctxt);
	atomic_set(&smd_info->diag_state, 0);
	DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
		 "%s setting diag state to 0", smd_info->name);
	wake_up(&smd_info->read_wait_q);
	flush_workqueue(smd_info->wq);
}

static int smd_channel_probe(struct platform_device *pdev, uint8_t type)
{
	int r = 0;
@@ -422,6 +454,7 @@ static void __diag_smd_init(struct diag_smd_info *smd_info)
	smd_info->hdl = NULL;
	smd_info->fwd_ctxt = NULL;
	atomic_set(&smd_info->opened, 0);
	atomic_set(&smd_info->diag_state, 0);

	DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s initialized fwd_ctxt: %p\n",
		 smd_info->name, smd_info->fwd_ctxt);
@@ -685,7 +718,15 @@ static int diag_smd_read(void *ctxt, unsigned char *buf, int buf_len)

	wait_event(smd_info->read_wait_q, (smd_info->hdl == NULL) ||
				(atomic_read(&smd_info->opened) == 0) ||
				(smd_cur_packet_size(smd_info->hdl)));
				(smd_cur_packet_size(smd_info->hdl)) ||
				(atomic_read(&smd_info->diag_state) == 0));

	if (atomic_read(&smd_info->diag_state) == 0) {
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			 "%s closing read thread. diag state is closed\n",
			 smd_info->name);
		return 0;
	}

	if (!smd_info->hdl || !atomic_read(&smd_info->opened)) {
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ struct diag_smd_info {
	uint8_t type;
	uint8_t inited;
	atomic_t opened;
	atomic_t diag_state;
	uint32_t fifo_size;
	smd_channel_t *hdl;
	char name[DIAG_SMD_NAME_SZ];
Loading