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

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

Merge "diag: Close the read when buffer is already marked free"

parents 16096e68 1c0a616a
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -257,7 +257,8 @@ struct diag_glink_info glink_dci_cmd[NUM_PERIPHERALS] = {
static void diag_state_open_glink(void *ctxt);
static void diag_state_close_glink(void *ctxt);
static int diag_glink_write(void *ctxt, unsigned char *buf, int len);
static int diag_glink_read(void *ctxt, unsigned char *buf, int buf_len);
static int diag_glink_read(void *ctxt, unsigned char *buf, int buf_len,
			struct diagfwd_buf_t *fwd_buf);
static void diag_glink_queue_read(void *ctxt);

static struct diag_peripheral_ops glink_ops = {
@@ -320,7 +321,8 @@ int diag_glink_check_state(void *ctxt)
	return (int)(atomic_read(&info->diag_state));
}

static int diag_glink_read(void *ctxt, unsigned char *buf, int buf_len)
static int diag_glink_read(void *ctxt, unsigned char *buf, int buf_len,
			struct diagfwd_buf_t *fwd_buf)
{
	struct diag_glink_info *glink_info =  NULL;
	int ret_val = 0;
+4 −4
Original line number Diff line number Diff line
@@ -1286,11 +1286,10 @@ static void __diag_fwd_open(struct diagfwd_info *fwd_info)
	 * Logging mode here is reflecting previous mode
	 * status and will be updated to new mode later.
	 *
	 * Keeping the buffers busy for Memory Device Mode.
	 * Keeping the buffers busy for Memory Device and Multi Mode.
	 */

	if ((driver->logging_mode != DIAG_USB_MODE) ||
		driver->usb_connected) {
	if (driver->logging_mode != DIAG_USB_MODE) {
		if (fwd_info->buf_1) {
			atomic_set(&fwd_info->buf_1->in_busy, 0);
			DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
@@ -1701,7 +1700,8 @@ void diagfwd_channel_read(struct diagfwd_info *fwd_info)

	DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "issued a read p: %d t: %d buf: %pK\n",
		 fwd_info->peripheral, fwd_info->type, read_buf);
	err = fwd_info->p_ops->read(fwd_info->ctxt, read_buf, read_len);
	err = fwd_info->p_ops->read(fwd_info->ctxt, read_buf, read_len,
			temp_buf);
	if (err)
		goto fail_return;

+3 −2
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -65,7 +65,8 @@ 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);
	int (*read)(void *ctxt, unsigned char *buf, int len,
			struct diagfwd_buf_t *fwd_buf);
	void (*queue_read)(void *ctxt);
};

+15 −5
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -198,7 +198,8 @@ static void diag_state_open_smd(void *ctxt);
static void diag_state_close_smd(void *ctxt);
static void smd_notify(void *ctxt, unsigned int 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 int diag_smd_read(void *ctxt, unsigned char *buf, int buf_len,
			struct diagfwd_buf_t *fwd_buf);
static void diag_smd_queue_read(void *ctxt);

static struct diag_peripheral_ops smd_ops = {
@@ -780,7 +781,8 @@ static int diag_smd_write(void *ctxt, unsigned char *buf, int len)
	return 0;
}

static int diag_smd_read(void *ctxt, unsigned char *buf, int buf_len)
static int diag_smd_read(void *ctxt, unsigned char *buf, int buf_len,
			struct diagfwd_buf_t *fwd_buf)
{
	int pkt_len = 0;
	int err = 0;
@@ -791,7 +793,7 @@ static int diag_smd_read(void *ctxt, unsigned char *buf, int buf_len)
	uint32_t read_len = 0;
	struct diag_smd_info *smd_info = NULL;

	if (!ctxt || !buf || buf_len <= 0)
	if (!ctxt || !buf || buf_len <= 0 || !fwd_buf)
		return -EIO;

	smd_info = (struct diag_smd_info *)ctxt;
@@ -810,7 +812,15 @@ static int diag_smd_read(void *ctxt, unsigned char *buf, int buf_len)
		diagfwd_channel_read_done(smd_info->fwd_ctxt, buf, 0);
		return -ERESTARTSYS;
	}

	if (atomic_read(&fwd_buf->in_busy) == 0) {
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"%s closing read thread. Buffer is already marked freed p: %d t: %d buf_num: %d\n",
			 smd_info->name, GET_BUF_PERIPHERAL(fwd_buf->ctxt),
			 GET_BUF_TYPE(fwd_buf->ctxt),
			 GET_BUF_NUM(fwd_buf->ctxt));
		diag_ws_release();
		return 0;
	}
	/*
	 * Reset the buffers. Also release the wake source hold earlier.
	 */
+18 −15
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -224,7 +224,8 @@ struct diag_socket_info socket_dci_cmd[NUM_PERIPHERALS] = {
static void diag_state_open_socket(void *ctxt);
static void diag_state_close_socket(void *ctxt);
static int diag_socket_write(void *ctxt, unsigned char *buf, int len);
static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len);
static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len,
			struct diagfwd_buf_t *fwd_buf);
static void diag_socket_queue_read(void *ctxt);
static void socket_init_work_fn(struct work_struct *work);
static int socket_ready_notify(struct notifier_block *nb,
@@ -1062,7 +1063,8 @@ void diag_socket_exit(void)
	}
}

static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len,
			struct diagfwd_buf_t *fwd_buf)
{
	int err = 0;
	int pkt_len = 0;
@@ -1082,7 +1084,7 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
	if (!info)
		return -ENODEV;

	if (!buf || !ctxt || buf_len <= 0)
	if (!buf || !ctxt || buf_len <= 0 || !fwd_buf)
		return -EINVAL;

	temp = buf;
@@ -1091,13 +1093,17 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
	err = wait_event_interruptible(info->read_wait_q,
				      (info->data_ready > 0) || (!info->hdl) ||
				      (atomic_read(&info->diag_state) == 0));
	if (err) {
		mutex_lock(&driver->diagfwd_channel_mutex[info->peripheral]);
		diagfwd_channel_read_done(info->fwd_ctxt, buf, 0);
		mutex_unlock(&driver->diagfwd_channel_mutex[info->peripheral]);
		return -ERESTARTSYS;
	if (err)
		goto fail;
	if (atomic_read(&fwd_buf->in_busy) == 0) {
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"%s closing read thread. Buffer is already marked freed p: %d t: %d buf_num: %d\n",
			 info->name, GET_BUF_PERIPHERAL(fwd_buf->ctxt),
			 GET_BUF_TYPE(fwd_buf->ctxt),
			 GET_BUF_NUM(fwd_buf->ctxt));
		diag_ws_release();
		return 0;
	}

	/*
	 * There is no need to continue reading over peripheral in this case.
	 * Release the wake source hold earlier.
@@ -1106,10 +1112,7 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			 "%s closing read thread. diag state is closed\n",
			 info->name);
		mutex_lock(&driver->diagfwd_channel_mutex[info->peripheral]);
		diagfwd_channel_read_done(info->fwd_ctxt, buf, 0);
		mutex_unlock(&driver->diagfwd_channel_mutex[info->peripheral]);
		return 0;
		goto fail;
	}

	if (!info->hdl) {
@@ -1211,7 +1214,7 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
	mutex_lock(&driver->diagfwd_channel_mutex[info->peripheral]);
	diagfwd_channel_read_done(info->fwd_ctxt, buf, 0);
	mutex_unlock(&driver->diagfwd_channel_mutex[info->peripheral]);
	return -EIO;
	return 0;
}

static int diag_socket_write(void *ctxt, unsigned char *buf, int len)