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

Commit d0df8dfb authored by Alexander Usyskin's avatar Alexander Usyskin Committed by Greg Kroah-Hartman
Browse files

mei: amthif: don't drop read packets on timeout



Since the driver now uses a list for storing read packets instead of
single variable a pending read is no longer blocking other connections.
A pending read will be discarded up the file closure.

Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5ba0bf47
Loading
Loading
Loading
Loading
+0 −27
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ void mei_amthif_reset_params(struct mei_device *dev)
	dev->iamthif_current_cb = NULL;
	dev->iamthif_canceled = false;
	dev->iamthif_state = MEI_IAMTHIF_IDLE;
	dev->iamthif_timer = 0;
	dev->iamthif_stall_timer = 0;
	dev->iamthif_open_count = 0;
}
@@ -124,18 +123,10 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
int mei_amthif_read(struct mei_device *dev, struct file *file,
	       char __user *ubuf, size_t length, loff_t *offset)
{
	struct mei_cl *cl = file->private_data;
	struct mei_cl_cb *cb;
	unsigned long timeout;
	int rets;
	int wait_ret;

	/* Only possible if we are in timeout */
	if (!cl) {
		dev_err(dev->dev, "bad file ext.\n");
		return -ETIME;
	}

	dev_dbg(dev->dev, "checking amthif data\n");
	cb = mei_amthif_find_read_list_entry(dev, file);

@@ -168,20 +159,6 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
	}

	dev_dbg(dev->dev, "Got amthif data\n");
	dev->iamthif_timer = 0;

	timeout = cb->read_time +
		mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
	dev_dbg(dev->dev, "amthif timeout = %lud\n",
			timeout);

	if  (time_after(jiffies, timeout)) {
		dev_dbg(dev->dev, "amthif Time out\n");
		/* 15 sec for the message has expired */
		list_del_init(&cb->list);
		rets = -ETIME;
		goto free;
	}
	/* if the whole message will fit remove it from the list */
	if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset))
		list_del_init(&cb->list);
@@ -303,7 +280,6 @@ int mei_amthif_run_next_cmd(struct mei_device *dev)

	dev->iamthif_canceled = false;
	dev->iamthif_state = MEI_IAMTHIF_IDLE;
	dev->iamthif_timer = 0;
	dev->iamthif_file_object = NULL;

	dev_dbg(dev->dev, "complete amthif cmd_list cb.\n");
@@ -462,9 +438,6 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
		dev->iamthif_stall_timer = 0;
		list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list);
		dev_dbg(dev->dev, "amthif read completed\n");
		dev->iamthif_timer = jiffies;
		dev_dbg(dev->dev, "dev->iamthif_timer = %ld\n",
			dev->iamthif_timer);
	} else {
		mei_amthif_run_next_cmd(dev);
	}
+0 −1
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@
#define MEI_CLIENTS_INIT_TIMEOUT   15  /* HPS: Clients Enumeration Timeout */

#define MEI_IAMTHIF_STALL_TIMER    12  /* HPS */
#define MEI_IAMTHIF_READ_TIMER     10  /* HPS */

#define MEI_PGI_TIMEOUT             1  /* PG Isolation time response 1 sec */
#define MEI_D0I3_TIMEOUT            5  /* D0i3 set/unset max response time */
+0 −32
Original line number Diff line number Diff line
@@ -156,7 +156,6 @@ int mei_cl_irq_read_msg(struct mei_cl *cl,
	cb->buf_idx += mei_hdr->length;

	if (mei_hdr->msg_complete) {
		cb->read_time = jiffies;
		cl_dbg(dev, cl, "completed read length = %lu\n", cb->buf_idx);
		list_move_tail(&cb->list, &complete_list->list);
	} else {
@@ -458,7 +457,6 @@ static void mei_connect_timeout(struct mei_cl *cl)
 */
void mei_timer(struct work_struct *work)
{
	unsigned long timeout;
	struct mei_cl *cl;

	struct mei_device *dev = container_of(work,
@@ -504,7 +502,6 @@ void mei_timer(struct work_struct *work)
			mei_reset(dev);
			dev->iamthif_canceled = false;
			dev->iamthif_state = MEI_IAMTHIF_IDLE;
			dev->iamthif_timer = 0;

			mei_io_cb_free(dev->iamthif_current_cb);
			dev->iamthif_current_cb = NULL;
@@ -514,35 +511,6 @@ void mei_timer(struct work_struct *work)
		}
	}

	if (dev->iamthif_timer) {

		timeout = dev->iamthif_timer +
			mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);

		dev_dbg(dev->dev, "dev->iamthif_timer = %ld\n",
				dev->iamthif_timer);
		dev_dbg(dev->dev, "timeout = %ld\n", timeout);
		dev_dbg(dev->dev, "jiffies = %ld\n", jiffies);
		if (time_after(jiffies, timeout)) {
			/*
			 * User didn't read the AMTHI data on time (15sec)
			 * freeing AMTHI for other requests
			 */

			dev_dbg(dev->dev, "freeing AMTHI for other requests\n");

			mei_io_list_flush(&dev->amthif_rd_complete_list,
				&dev->iamthif_cl);
			mei_io_cb_free(dev->iamthif_current_cb);
			dev->iamthif_current_cb = NULL;

			dev->iamthif_file_object->private_data = NULL;
			dev->iamthif_file_object = NULL;
			dev->iamthif_timer = 0;
			mei_amthif_run_next_cmd(dev);

		}
	}
out:
	if (dev->dev_state != MEI_DEV_DISABLED)
		schedule_delayed_work(&dev->timer_work, 2 * HZ);
+0 −16
Original line number Diff line number Diff line
@@ -274,7 +274,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
	struct mei_cl *cl = file->private_data;
	struct mei_cl_cb *write_cb = NULL;
	struct mei_device *dev;
	unsigned long timeout = 0;
	int rets;

	if (WARN_ON(!cl || !cl->dev))
@@ -310,21 +309,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
		goto out;
	}

	if (cl == &dev->iamthif_cl) {
		write_cb = mei_amthif_find_read_list_entry(dev, file);

		if (write_cb) {
			timeout = write_cb->read_time +
				mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);

			if (time_after(jiffies, timeout)) {
				*offset = 0;
				mei_io_cb_free(write_cb);
				write_cb = NULL;
			}
		}
	}

	*offset = 0;
	write_cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, file);
	if (!write_cb) {
+0 −4
Original line number Diff line number Diff line
@@ -179,7 +179,6 @@ struct mei_cl;
 * @fop_type: file operation type
 * @buf: buffer for data associated with the callback
 * @buf_idx: last read index
 * @read_time: last read operation time stamp (iamthif)
 * @file_object: pointer to file structure
 * @status: io status of the cb
 * @internal: communication between driver and FW flag
@@ -191,7 +190,6 @@ struct mei_cl_cb {
	enum mei_cb_file_ops fop_type;
	struct mei_msg_data buf;
	size_t buf_idx;
	unsigned long read_time;
	struct file *file_object;
	int status;
	u32 internal:1;
@@ -413,7 +411,6 @@ const char *mei_pg_state_str(enum mei_pg_state state);
 * @iamthif_cl  : amthif host client
 * @iamthif_current_cb : amthif current operation callback
 * @iamthif_open_count : number of opened amthif connections
 * @iamthif_timer : time stamp of current amthif command completion
 * @iamthif_stall_timer : timer to detect amthif hang
 * @iamthif_state : amthif processor state
 * @iamthif_canceled : current amthif command is canceled
@@ -504,7 +501,6 @@ struct mei_device {
	struct mei_cl iamthif_cl;
	struct mei_cl_cb *iamthif_current_cb;
	long iamthif_open_count;
	unsigned long iamthif_timer;
	u32 iamthif_stall_timer;
	enum iamthif_states iamthif_state;
	bool iamthif_canceled;