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,
	Alexander Usyskin <alexander.usyskin@intel.com>,
	Tomas Winkler <tomas.winkler@intel.com>
Subject: [char-misc-next 08/11] mei: support for fixed address clients
Date: Fri, 27 Mar 2015 00:28:04 +0200	[thread overview]
Message-ID: <1427408887-27979-8-git-send-email-tomas.winkler@intel.com> (raw)
In-Reply-To: <1427408887-27979-1-git-send-email-tomas.winkler@intel.com>

From: Alexander Usyskin <alexander.usyskin@intel.com>

Fixed address is simplified FW client that doesn't require
connection and doesn't support flow control.
So it can be only one host client per fixed FW client.
Fixed client access is available only for drivers on mei bus,
connection from user-space is blocked.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/client.c    | 69 ++++++++++++++++++++++++++++++++++----------
 drivers/misc/mei/client.h    | 12 ++++++++
 drivers/misc/mei/hbm.c       |  4 +--
 drivers/misc/mei/interrupt.c |  2 +-
 4 files changed, 68 insertions(+), 19 deletions(-)

diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 98335b435b75..36706705dfdc 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -764,10 +764,18 @@ void mei_cl_set_disconnected(struct mei_cl *cl)
 
 static int mei_cl_set_connecting(struct mei_cl *cl, struct mei_me_client *me_cl)
 {
-	cl->me_cl = mei_me_cl_get(me_cl);
-	if (!cl->me_cl)
+	if (!mei_me_cl_get(me_cl))
 		return -ENOENT;
 
+	/* only one connection is allowed for fixed address clients */
+	if (me_cl->props.fixed_address) {
+		if (me_cl->connect_count) {
+			mei_me_cl_put(me_cl);
+			return -EBUSY;
+		}
+	}
+
+	cl->me_cl = me_cl;
 	cl->state = MEI_FILE_CONNECTING;
 	cl->me_cl->connect_count++;
 
@@ -860,6 +868,11 @@ int mei_cl_disconnect(struct mei_cl *cl)
 	if (!mei_cl_is_connected(cl))
 		return 0;
 
+	if (mei_cl_is_fixed_address(cl)) {
+		mei_cl_set_disconnected(cl);
+		return 0;
+	}
+
 	rets = pm_runtime_get(dev->dev);
 	if (rets < 0 && rets != -EINPROGRESS) {
 		pm_runtime_put_noidle(dev->dev);
@@ -1013,16 +1026,25 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl,
 	struct mei_cl_cb *cb;
 	int rets;
 
-	if (WARN_ON(!cl || !cl->dev))
+	if (WARN_ON(!cl || !cl->dev || !me_cl))
 		return -ENODEV;
 
 	dev = cl->dev;
 
+	rets = mei_cl_set_connecting(cl, me_cl);
+	if (rets)
+		return rets;
+
+	if (mei_cl_is_fixed_address(cl)) {
+		cl->state = MEI_FILE_CONNECTED;
+		return 0;
+	}
+
 	rets = pm_runtime_get(dev->dev);
 	if (rets < 0 && rets != -EINPROGRESS) {
 		pm_runtime_put_noidle(dev->dev);
 		cl_err(dev, cl, "rpm: get failed %d\n", rets);
-		return rets;
+		goto nortpm;
 	}
 
 	cb = mei_io_cb_init(cl, MEI_FOP_CONNECT, file);
@@ -1030,9 +1052,6 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl,
 	if (rets)
 		goto out;
 
-	rets = mei_cl_set_connecting(cl, me_cl);
-	if (rets)
-		goto out;
 	list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
 
 	/* run hbuf acquire last so we don't have to undo */
@@ -1063,6 +1082,7 @@ out:
 
 	mei_io_cb_free(cb);
 
+nortpm:
 	if (!mei_cl_is_connected(cl))
 		mei_cl_set_disconnected(cl);
 
@@ -1109,12 +1129,21 @@ err:
  */
 int mei_cl_flow_ctrl_creds(struct mei_cl *cl)
 {
+	int rets;
+
 	if (WARN_ON(!cl || !cl->me_cl))
 		return -EINVAL;
 
 	if (cl->mei_flow_ctrl_creds > 0)
 		return 1;
 
+	if (mei_cl_is_fixed_address(cl)) {
+		rets = mei_cl_read_start(cl, mei_cl_mtu(cl), NULL);
+		if (rets && rets != -EBUSY)
+			return rets;
+		return 1;
+	}
+
 	if (mei_cl_is_single_recv_buf(cl)) {
 		if (cl->me_cl->mei_flow_ctrl_creds > 0)
 			return 1;
@@ -1136,6 +1165,9 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
 	if (WARN_ON(!cl || !cl->me_cl))
 		return -EINVAL;
 
+	if (mei_cl_is_fixed_address(cl))
+		return 0;
+
 	if (mei_cl_is_single_recv_buf(cl)) {
 		if (WARN_ON(cl->me_cl->mei_flow_ctrl_creds <= 0))
 			return -EINVAL;
@@ -1179,21 +1211,25 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length, struct file *fp)
 		cl_err(dev, cl, "no such me client\n");
 		return  -ENOTTY;
 	}
+
 	/* always allocate at least client max message */
 	length = max_t(size_t, length, mei_cl_mtu(cl));
+	cb = mei_cl_alloc_cb(cl, length, MEI_FOP_READ, fp);
+	if (!cb)
+		return -ENOMEM;
+
+	if (mei_cl_is_fixed_address(cl)) {
+		list_add_tail(&cb->list, &cl->rd_pending);
+		return 0;
+	}
 
 	rets = pm_runtime_get(dev->dev);
 	if (rets < 0 && rets != -EINPROGRESS) {
 		pm_runtime_put_noidle(dev->dev);
 		cl_err(dev, cl, "rpm: get failed %d\n", rets);
-		return rets;
+		goto nortpm;
 	}
 
-	cb = mei_cl_alloc_cb(cl, length, MEI_FOP_READ, fp);
-	rets = cb ? 0 : -ENOMEM;
-	if (rets)
-		goto out;
-
 	if (mei_hbuf_acquire(dev)) {
 		rets = mei_hbm_cl_flow_control_req(dev, cl);
 		if (rets < 0)
@@ -1201,6 +1237,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length, struct file *fp)
 
 		list_add_tail(&cb->list, &cl->rd_pending);
 	} else {
+		rets = 0;
 		list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
 	}
 
@@ -1208,7 +1245,7 @@ out:
 	cl_dbg(dev, cl, "rpm: autosuspend\n");
 	pm_runtime_mark_last_busy(dev->dev);
 	pm_runtime_put_autosuspend(dev->dev);
-
+nortpm:
 	if (rets)
 		mei_io_cb_free(cb);
 
@@ -1256,7 +1293,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
 	len = buf->size - cb->buf_idx;
 	msg_slots = mei_data2slots(len);
 
-	mei_hdr.host_addr = cl->host_client_id;
+	mei_hdr.host_addr = mei_cl_host_addr(cl);
 	mei_hdr.me_addr = mei_cl_me_id(cl);
 	mei_hdr.reserved = 0;
 	mei_hdr.internal = cb->internal;
@@ -1340,7 +1377,7 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
 	cb->buf_idx = 0;
 	cl->writing_state = MEI_IDLE;
 
-	mei_hdr.host_addr = cl->host_client_id;
+	mei_hdr.host_addr = mei_cl_host_addr(cl);
 	mei_hdr.me_addr = mei_cl_me_id(cl);
 	mei_hdr.reserved = 0;
 	mei_hdr.msg_complete = 0;
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index bba560e325b7..df46f73c0033 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -176,6 +176,18 @@ static inline const uuid_le *mei_cl_uuid(const struct mei_cl *cl)
 	return &cl->me_cl->props.protocol_name;
 }
 
+/**
+ * mei_cl_host_addr - client's host address
+ *
+ * @cl: host client
+ *
+ * Return: 0 for fixed address client, host address for dynamic client
+ */
+static inline u8 mei_cl_host_addr(const struct mei_cl *cl)
+{
+	return  mei_cl_is_fixed_address(cl) ? 0 : cl->host_client_id;
+}
+
 int mei_cl_disconnect(struct mei_cl *cl);
 void mei_cl_set_disconnected(struct mei_cl *cl);
 int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb,
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index f620824f7c86..a4f283165a33 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -150,7 +150,7 @@ void mei_hbm_cl_hdr(struct mei_cl *cl, u8 hbm_cmd, void *buf, size_t len)
 	memset(cmd, 0, len);
 
 	cmd->hbm_cmd = hbm_cmd;
-	cmd->host_addr = cl->host_client_id;
+	cmd->host_addr = mei_cl_host_addr(cl);
 	cmd->me_addr = mei_cl_me_id(cl);
 }
 
@@ -188,7 +188,7 @@ int mei_hbm_cl_write(struct mei_device *dev,
 static inline
 bool mei_hbm_cl_addr_equal(struct mei_cl *cl, struct mei_hbm_cl_cmd *cmd)
 {
-	return cl->host_client_id == cmd->host_addr &&
+	return  mei_cl_host_addr(cl) == cmd->host_addr &&
 		mei_cl_me_id(cl) == cmd->me_addr;
 }
 
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 74795676bb3b..3f3405269c39 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -65,7 +65,7 @@ EXPORT_SYMBOL_GPL(mei_irq_compl_handler);
 static inline int mei_cl_hbm_equal(struct mei_cl *cl,
 			struct mei_msg_hdr *mei_hdr)
 {
-	return cl->host_client_id == mei_hdr->host_addr &&
+	return  mei_cl_host_addr(cl) == mei_hdr->host_addr &&
 		mei_cl_me_id(cl) == mei_hdr->me_addr;
 }
 
-- 
1.9.3


  parent reply	other threads:[~2015-03-26 22:29 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-26 22:27 [char-misc-next 01/11] mei: fix mei_poll operation Tomas Winkler
2015-03-26 22:27 ` [char-misc-next 02/11] mei: use mei_cl_is_connected consistently Tomas Winkler
2015-03-26 22:27 ` [char-misc-next 03/11] mei: replace check for connection instead of transitioning Tomas Winkler
2015-03-26 22:28 ` [char-misc-next 04/11] mei: revamp client disconnection flow Tomas Winkler
2015-04-03 14:19   ` Greg KH
2015-04-05 11:00     ` Winkler, Tomas
2015-04-05 13:18       ` Greg KH
2015-04-06 10:19         ` Winkler, Tomas
2015-03-26 22:28 ` [char-misc-next 05/11] mei: revamp client connection Tomas Winkler
2015-03-26 22:28 ` [char-misc-next 06/11] mei: add a reference from the host client to the me client Tomas Winkler
2015-03-26 22:28 ` [char-misc-next 07/11] mei: fix flow control for single buffer clients Tomas Winkler
2015-03-26 22:28 ` Tomas Winkler [this message]
2015-03-26 22:28 ` [char-misc-next 09/11] mei: connection to fixed address clients from user-space Tomas Winkler
2015-03-26 22:28 ` [char-misc-next 10/11] mei: drop iamthif_mtu from device structure Tomas Winkler
2015-03-26 22:28 ` [char-misc-next 11/11] mei: txe: fix incorrect indentation 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=1427408887-27979-8-git-send-email-tomas.winkler@intel.com \
    --to=tomas.winkler@intel.com \
    --cc=alexander.usyskin@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®