mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Tomas Winkler <tomas.winkler@intel.com>
To: gregkh@linuxfoundation.org
Cc: arnd@arndb.de, linux-kernel@vger.kernel.org,
	Tomas Winkler <tomas.winkler@intel.com>
Subject: [char-misc-next 10/18] mei: iamthif: send flow control as a regular client
Date: Tue, 10 Feb 2015 10:39:39 +0200	[thread overview]
Message-ID: <1423557587-21254-9-git-send-email-tomas.winkler@intel.com> (raw)
In-Reply-To: <1423557587-21254-1-git-send-email-tomas.winkler@intel.com>

Reuse common client mechanism for sending flow control
hbm message. Add new function mei_amthif_read_start
similar to mei_cl_read_start that puts control flow request
onto the control write queue and drop mei_amthif_irq_read function

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/amthif.c    | 134 +++++++++++++++++++++++--------------------
 drivers/misc/mei/interrupt.c |  25 ++------
 drivers/misc/mei/mei_dev.h   |   2 -
 3 files changed, 77 insertions(+), 84 deletions(-)

diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 788b00e23353..e6f7180fd8f2 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -255,6 +255,47 @@ out:
 }
 
 /**
+ * mei_amthif_read_start - queue message for sending read credential
+ *
+ * @cl: host client
+ * @file: file pointer of message recipient
+ *
+ * Return: 0 on success, <0 on failure.
+ */
+static int mei_amthif_read_start(struct mei_cl *cl, struct file *file)
+{
+	struct mei_device *dev = cl->dev;
+	struct mei_cl_cb *cb;
+	size_t length = dev->iamthif_mtu;
+	int rets;
+
+	cb = mei_io_cb_init(cl, file);
+	if (!cb) {
+		rets = -ENOMEM;
+		goto err;
+	}
+
+	rets = mei_io_cb_alloc_resp_buf(cb, length);
+	if (rets)
+		goto err;
+
+	cb->fop_type = MEI_FOP_READ;
+	list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
+
+	dev->iamthif_msg_buf_index = 0;
+	dev->iamthif_msg_buf_size = 0;
+
+	dev->iamthif_state = MEI_IAMTHIF_READING;
+	dev->iamthif_file_object = cb->file_object;
+	dev->iamthif_current_cb = cb;
+
+	return 0;
+err:
+	mei_io_cb_free(cb);
+	return rets;
+}
+
+/**
  * mei_amthif_send_cmd - send amthif command to the ME
  *
  * @dev: the device structure
@@ -287,6 +328,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
 	if (ret < 0)
 		return ret;
 
+	cb->fop_type = MEI_FOP_WRITE;
 	if (ret && mei_hbuf_acquire(dev)) {
 		ret = 0;
 		if (cb->request_buffer.size > mei_hbuf_max_len(dev)) {
@@ -309,19 +351,17 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
 		if (mei_hdr.msg_complete) {
 			if (mei_cl_flow_ctrl_reduce(cl))
 				return -EIO;
-			dev->iamthif_flow_control_pending = true;
-			dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
-			dev_dbg(dev->dev, "add amthif cb to write waiting list\n");
-			dev->iamthif_current_cb = cb;
-			dev->iamthif_file_object = cb->file_object;
+			cb->status = mei_amthif_read_start(cl, cb->file_object);
 			list_add_tail(&cb->list, &dev->write_waiting_list.list);
 		} else {
 			dev_dbg(dev->dev, "message does not complete, so add amthif cb to write list.\n");
 			list_add_tail(&cb->list, &dev->write_list.list);
 		}
 	} else {
+
 		list_add_tail(&cb->list, &dev->write_list.list);
 	}
+
 	return 0;
 }
 
@@ -336,17 +376,10 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
  */
 int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb)
 {
-	int ret;
-
 	if (!dev || !cb)
 		return -ENODEV;
 
-	ret = mei_io_cb_alloc_resp_buf(cb, dev->iamthif_mtu);
-	if (ret)
-		return ret;
-
 	cb->fop_type = MEI_FOP_WRITE;
-
 	if (!list_empty(&dev->amthif_cmd_list.list) ||
 	    dev->iamthif_state != MEI_IAMTHIF_IDLE) {
 		dev_dbg(dev->dev,
@@ -383,7 +416,7 @@ void mei_amthif_run_next_cmd(struct mei_device *dev)
 					typeof(*cb), list);
 	if (!cb)
 		return;
-	list_del(&cb->list);
+	list_del_init(&cb->list);
 	ret =  mei_amthif_send_cmd(dev, cb);
 	if (ret)
 		dev_warn(dev->dev, "amthif write failed status = %d\n", ret);
@@ -483,13 +516,7 @@ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
 	cl->status = 0;
 
 	if (mei_hdr.msg_complete) {
-		dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
-		dev->iamthif_flow_control_pending = true;
-
-		/* save iamthif cb sent to amthif client */
-		cb->buf_idx = dev->iamthif_msg_buf_index;
-		dev->iamthif_current_cb = cb;
-
+		cb->status = mei_amthif_read_start(cl, cb->file_object);
 		list_move_tail(&cb->list, &dev->write_waiting_list.list);
 	}
 
@@ -505,7 +532,7 @@ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
  * @mei_hdr: header of amthif message
  * @complete_list: completed callbacks list
  *
- * Return: -ENODEV if cb is NULL 0 otherwise; error message is in cb->status
+ * Return: Always 0; error message is in cb->status
  */
 int mei_amthif_irq_read_msg(struct mei_cl *cl,
 			    struct mei_msg_hdr *mei_hdr,
@@ -514,7 +541,6 @@ int mei_amthif_irq_read_msg(struct mei_cl *cl,
 	struct mei_device *dev;
 	struct mei_cl_cb *cb;
 	unsigned char *buffer;
-	int ret = 0;
 
 	dev = cl->dev;
 
@@ -524,10 +550,13 @@ int mei_amthif_irq_read_msg(struct mei_cl *cl,
 	if (dev->iamthif_state != MEI_IAMTHIF_READING)
 		goto err;
 
-	cb = dev->iamthif_current_cb;
+	list_for_each_entry(cb, &dev->read_list.list, list) {
+		if (cl == cb->cl)
+			break;
+	}
 
-	if (!cb) {
-		ret = -ENODEV;
+	if (&cb->list == &dev->read_list.list) {
+		dev_err(dev->dev, "no reader found\n");
 		goto err;
 	}
 
@@ -553,7 +582,7 @@ int mei_amthif_irq_read_msg(struct mei_cl *cl,
 	cb->read_time = jiffies;
 
 	dev_dbg(dev->dev, "complete the amthif read cb.\n ");
-	list_add_tail(&cb->list, &complete_list->list);
+	list_move_tail(&cb->list, &complete_list->list);
 
 	return 0;
 
@@ -561,38 +590,6 @@ err:
 	mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
 	dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n",
 				MEI_HDR_PRM(mei_hdr));
-	return ret;
-}
-
-/**
- * mei_amthif_irq_read - prepares to read amthif data.
- *
- * @dev: the device structure.
- * @slots: free slots.
- *
- * Return: 0, OK; otherwise, error.
- */
-int mei_amthif_irq_read(struct mei_device *dev, s32 *slots)
-{
-	u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control));
-
-	if (*slots < msg_slots)
-		return -EMSGSIZE;
-
-	*slots -= msg_slots;
-
-	if (mei_hbm_cl_flow_control_req(dev, &dev->iamthif_cl)) {
-		dev_dbg(dev->dev, "iamthif flow control failed\n");
-		return -EIO;
-	}
-
-	dev_dbg(dev->dev, "iamthif flow control success\n");
-	dev->iamthif_state = MEI_IAMTHIF_READING;
-	dev->iamthif_flow_control_pending = false;
-	dev->iamthif_msg_buf_index = 0;
-	dev->iamthif_msg_buf_size = 0;
-	dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER;
-	dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
 	return 0;
 }
 
@@ -604,17 +601,32 @@ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots)
  */
 void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
 {
+
+	if (cb->fop_type == MEI_FOP_WRITE) {
+		if (!cb->status) {
+			dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER;
+			mei_io_cb_free(cb);
+			return;
+		}
+		/*
+		 * in case of error enqueue the write cb to complete read list
+		 * so it can be propagated to the reader
+		 */
+		list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list);
+		wake_up_interruptible(&dev->iamthif_cl.wait);
+		return;
+	}
+
 	if (dev->iamthif_canceled != 1) {
 		dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE;
 		dev->iamthif_stall_timer = 0;
 		memcpy(cb->response_buffer.data,
-				dev->iamthif_msg_buf,
-				dev->iamthif_msg_buf_index);
+			dev->iamthif_msg_buf, dev->iamthif_msg_buf_index);
 		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);
+			dev->iamthif_timer);
 	} else {
 		mei_amthif_run_next_cmd(dev);
 	}
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 4cb602fba593..89f2fbce160f 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -43,7 +43,7 @@ void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list)
 
 	list_for_each_entry_safe(cb, next, &compl_list->list, list) {
 		cl = cb->cl;
-		list_del(&cb->list);
+		list_del_init(&cb->list);
 
 		dev_dbg(dev->dev, "completing call back.\n");
 		if (cl == &dev->iamthif_cl)
@@ -386,11 +386,6 @@ int mei_irq_read_handler(struct mei_device *dev,
 
 	if (cl == &dev->iamthif_cl) {
 		ret = mei_amthif_irq_read_msg(cl, mei_hdr, cmpl_list);
-		if (ret) {
-			dev_err(dev->dev, "mei_amthif_irq_read_msg failed = %d\n",
-					ret);
-			goto end;
-		}
 	} else {
 		ret = mei_cl_irq_read_msg(cl, mei_hdr, cmpl_list);
 	}
@@ -448,21 +443,9 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
 		cl = cb->cl;
 
 		cl->status = 0;
-		list_del(&cb->list);
-		if (cb->fop_type == MEI_FOP_WRITE &&
-		    cl != &dev->iamthif_cl) {
-			cl_dbg(dev, cl, "MEI WRITE COMPLETE\n");
-			cl->writing_state = MEI_WRITE_COMPLETE;
-			list_add_tail(&cb->list, &cmpl_list->list);
-		}
-		if (cl == &dev->iamthif_cl) {
-			cl_dbg(dev, cl, "check iamthif flow control.\n");
-			if (dev->iamthif_flow_control_pending) {
-				ret = mei_amthif_irq_read(dev, &slots);
-				if (ret)
-					return ret;
-			}
-		}
+		cl_dbg(dev, cl, "MEI WRITE COMPLETE\n");
+		cl->writing_state = MEI_WRITE_COMPLETE;
+		list_move_tail(&cb->list, &cmpl_list->list);
 	}
 
 	if (dev->wd_state == MEI_WD_STOPPING) {
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 6cc68de580ba..fc460af131d4 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -487,7 +487,6 @@ const char *mei_pg_state_str(enum mei_pg_state state);
  * @iamthif_msg_buf_size : size of current amthif message request buffer
  * @iamthif_msg_buf_index : current index in amthif message request buffer
  * @iamthif_state : amthif processor state
- * @iamthif_flow_control_pending: amthif waits for flow control
  * @iamthif_canceled : current amthif command is canceled
  *
  * @init_work   : work item for the device init
@@ -586,7 +585,6 @@ struct mei_device {
 	u32 iamthif_msg_buf_size;
 	u32 iamthif_msg_buf_index;
 	enum iamthif_states iamthif_state;
-	bool iamthif_flow_control_pending;
 	bool iamthif_canceled;
 
 	struct work_struct init_work;
-- 
1.9.3


  parent reply	other threads:[~2015-02-10  8:44 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-10  8:39 [char-misc-next 02/18] mei: revamp me clients list handling Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 03/18] mei: me: use io register wrappers consistently Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 04/18] mei: me: add io register tracing Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 05/18] mei: me: change power gating function name conventions Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 06/18] mei: fix function names and format in KDoc Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 07/18] mei: fix device reset on mei_cl_irq_read_msg allocation failure Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 08/18] mei: iamthif: fix device reset on mei_amthif_irq_read_msg Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 09/18] mei: iamthif: remove useless iamthif_ioctl variable Tomas Winkler
2015-02-10  8:39 ` Tomas Winkler [this message]
2015-02-10  8:39 ` [char-misc-next 11/18] mei: iamthif: use client write functions Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 12/18] mei: iamthif: use regular client read functions Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 13/18] mei: use only one buffer in callback Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 14/18] mei: always initialize the callback with the intended operation type Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 15/18] mei: add mei_cl_alloc_linked function Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 16/18] mei: simplify io callback disposal Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 17/18] mei: allow read concurrency Tomas Winkler
2015-02-10  8:39 ` [char-misc-next 18/18] mei: bus: call device disable handler prior to disconnection Tomas Winkler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1423557587-21254-9-git-send-email-tomas.winkler@intel.com \
    --to=tomas.winkler@intel.com \
    --cc=arnd@arndb.de \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®