mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [char-misc-next 1/4 RESEND] mei: move mei_cl_irq_write_complete to client.c
@ 2013-06-23  6:36 Tomas Winkler
  2013-06-23  6:37 ` [char-misc-next 2/4] mei: do not override a client writing state when buffering Tomas Winkler
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Tomas Winkler @ 2013-06-23  6:36 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, linux-kernel, Tomas Winkler

mei_cl_irq_write_complete operates on a client so move it
to client.c

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/client.c    | 60 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/misc/mei/client.h    |  3 +++
 drivers/misc/mei/interrupt.c | 59 -------------------------------------------
 3 files changed, 63 insertions(+), 59 deletions(-)

diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index c2534ca..788f647 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -682,6 +682,66 @@ err:
 }
 
 /**
+ * mei_cl_irq_write_complete - write a message to device
+ *	from the interrupt thread context
+ *
+ * @cl: client
+ * @cb: callback block.
+ * @slots: free slots.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise error.
+ */
+int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
+				     s32 *slots, struct mei_cl_cb *cmpl_list)
+{
+	struct mei_device *dev = cl->dev;
+	struct mei_msg_hdr mei_hdr;
+	size_t len = cb->request_buffer.size - cb->buf_idx;
+	u32 msg_slots = mei_data2slots(len);
+
+	mei_hdr.host_addr = cl->host_client_id;
+	mei_hdr.me_addr = cl->me_client_id;
+	mei_hdr.reserved = 0;
+
+	if (*slots >= msg_slots) {
+		mei_hdr.length = len;
+		mei_hdr.msg_complete = 1;
+	/* Split the message only if we can write the whole host buffer */
+	} else if (*slots == dev->hbuf_depth) {
+		msg_slots = *slots;
+		len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
+		mei_hdr.length = len;
+		mei_hdr.msg_complete = 0;
+	} else {
+		/* wait for next time the host buffer is empty */
+		return 0;
+	}
+
+	dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n",
+			cb->request_buffer.size, cb->buf_idx);
+	dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
+
+	*slots -=  msg_slots;
+	if (mei_write_message(dev, &mei_hdr,
+			cb->request_buffer.data + cb->buf_idx)) {
+		cl->status = -ENODEV;
+		list_move_tail(&cb->list, &cmpl_list->list);
+		return -ENODEV;
+	}
+
+	cl->status = 0;
+	cb->buf_idx += mei_hdr.length;
+	if (mei_hdr.msg_complete) {
+		if (mei_cl_flow_ctrl_reduce(cl))
+			return -ENODEV;
+		list_move_tail(&cb->list, &dev->write_waiting_list.list);
+	}
+
+	return 0;
+}
+
+/**
  * mei_cl_write - submit a write cb to mei device
 	assumes device_lock is locked
  *
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index 7dc2af7..26b157d 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -89,6 +89,9 @@ int mei_cl_disconnect(struct mei_cl *cl);
 int mei_cl_connect(struct mei_cl *cl, struct file *file);
 int mei_cl_read_start(struct mei_cl *cl, size_t length);
 int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
+int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
+				s32 *slots, struct mei_cl_cb *cmpl_list);
+
 void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb);
 
 void mei_host_client_init(struct work_struct *work);
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 7d9509a..4b59cb7 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -282,65 +282,6 @@ static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb,
 	return 0;
 }
 
-/**
- * mei_cl_irq_write_complete - write messages to device.
- *
- * @cl: client
- * @cb: callback block.
- * @slots: free slots.
- * @cmpl_list: complete list.
- *
- * returns 0, OK; otherwise, error.
- */
-static int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
-				     s32 *slots, struct mei_cl_cb *cmpl_list)
-{
-	struct mei_device *dev = cl->dev;
-	struct mei_msg_hdr mei_hdr;
-	size_t len = cb->request_buffer.size - cb->buf_idx;
-	u32 msg_slots = mei_data2slots(len);
-
-	mei_hdr.host_addr = cl->host_client_id;
-	mei_hdr.me_addr = cl->me_client_id;
-	mei_hdr.reserved = 0;
-
-	if (*slots >= msg_slots) {
-		mei_hdr.length = len;
-		mei_hdr.msg_complete = 1;
-	/* Split the message only if we can write the whole host buffer */
-	} else if (*slots == dev->hbuf_depth) {
-		msg_slots = *slots;
-		len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
-		mei_hdr.length = len;
-		mei_hdr.msg_complete = 0;
-	} else {
-		/* wait for next time the host buffer is empty */
-		return 0;
-	}
-
-	dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n",
-			cb->request_buffer.size, cb->buf_idx);
-	dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
-
-	*slots -=  msg_slots;
-	if (mei_write_message(dev, &mei_hdr,
-			cb->request_buffer.data + cb->buf_idx)) {
-		cl->status = -ENODEV;
-		list_move_tail(&cb->list, &cmpl_list->list);
-		return -ENODEV;
-	}
-
-
-	cl->status = 0;
-	cb->buf_idx += mei_hdr.length;
-	if (mei_hdr.msg_complete) {
-		if (mei_cl_flow_ctrl_reduce(cl))
-			return -ENODEV;
-		list_move_tail(&cb->list, &dev->write_waiting_list.list);
-	}
-
-	return 0;
-}
 
 /**
  * mei_irq_read_handler - bottom half read routine after ISR to
-- 
1.8.1.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [char-misc-next 2/4] mei: do not override a client writing state when buffering
  2013-06-23  6:36 [char-misc-next 1/4 RESEND] mei: move mei_cl_irq_write_complete to client.c Tomas Winkler
@ 2013-06-23  6:37 ` Tomas Winkler
  2013-06-23  6:37 ` [char-misc-next 3/4] mei: mei_cl_connect: don't multiply the timeout twice Tomas Winkler
  2013-06-23  6:37 ` [char-misc-next 4/4] mei: check if the hardware start succeeded Tomas Winkler
  2 siblings, 0 replies; 4+ messages in thread
From: Tomas Winkler @ 2013-06-23  6:37 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, linux-kernel, Tomas Winkler

when we buffer write request we should not switch to
MEI_WRITING since this will override MEI_WRITE_COMPLETE
state of preceding write

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/client.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 788f647..11a465a 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -731,7 +731,9 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
 	}
 
 	cl->status = 0;
+	cl->writing_state = MEI_WRITING;
 	cb->buf_idx += mei_hdr.length;
+
 	if (mei_hdr.msg_complete) {
 		if (mei_cl_flow_ctrl_reduce(cl))
 			return -ENODEV;
@@ -783,7 +785,6 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
 		cb->buf_idx = 0;
 		/* unseting complete will enqueue the cb for write */
 		mei_hdr.msg_complete = 0;
-		cl->writing_state = MEI_WRITING;
 		rets = buf->size;
 		goto out;
 	}
-- 
1.8.1.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [char-misc-next 3/4] mei: mei_cl_connect: don't multiply the timeout twice
  2013-06-23  6:36 [char-misc-next 1/4 RESEND] mei: move mei_cl_irq_write_complete to client.c Tomas Winkler
  2013-06-23  6:37 ` [char-misc-next 2/4] mei: do not override a client writing state when buffering Tomas Winkler
@ 2013-06-23  6:37 ` Tomas Winkler
  2013-06-23  6:37 ` [char-misc-next 4/4] mei: check if the hardware start succeeded Tomas Winkler
  2 siblings, 0 replies; 4+ messages in thread
From: Tomas Winkler @ 2013-06-23  6:37 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, linux-kernel, Frode Isaksen, Frode Isaksen, Tomas Winkler

From: Frode Isaksen <fisaksex@intel.com>

MEI_CL_CONNECT_TIMEOUT is the timeout in seconds to wait
for a response in mei_cl_connect.
The value was converted to jiffies using mei_secs_to_jiffies
helper function and assigned to a local variable
which is by mistake again multiplied by HZ

Signed-off-by: Frode Isaksen <frodex.isaksen@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/client.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 11a465a..21d3f5a 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -485,7 +485,6 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
 {
 	struct mei_device *dev;
 	struct mei_cl_cb *cb;
-	long timeout = mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT);
 	int rets;
 
 	if (WARN_ON(!cl || !cl->dev))
@@ -518,7 +517,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
 	rets = wait_event_timeout(dev->wait_recvd_msg,
 				 (cl->state == MEI_FILE_CONNECTED ||
 				  cl->state == MEI_FILE_DISCONNECTED),
-				 timeout * HZ);
+				 mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
 	mutex_lock(&dev->device_lock);
 
 	if (cl->state != MEI_FILE_CONNECTED) {
-- 
1.8.1.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [char-misc-next 4/4] mei: check if the hardware start succeeded
  2013-06-23  6:36 [char-misc-next 1/4 RESEND] mei: move mei_cl_irq_write_complete to client.c Tomas Winkler
  2013-06-23  6:37 ` [char-misc-next 2/4] mei: do not override a client writing state when buffering Tomas Winkler
  2013-06-23  6:37 ` [char-misc-next 3/4] mei: mei_cl_connect: don't multiply the timeout twice Tomas Winkler
@ 2013-06-23  6:37 ` Tomas Winkler
  2 siblings, 0 replies; 4+ messages in thread
From: Tomas Winkler @ 2013-06-23  6:37 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, linux-kernel, Tomas Winkler

The hw may have multiple steps for resetting
so we need to check if it has really succeeded.

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/hw-me.c   | 3 ++-
 drivers/misc/mei/init.c    | 8 +++++++-
 drivers/misc/mei/mei_dev.h | 6 +++---
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 822170f..e4f8dec 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -171,7 +171,7 @@ static void mei_me_hw_reset_release(struct mei_device *dev)
  * @dev: the device structure
  * @intr_enable: if interrupt should be enabled after reset.
  */
-static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
+static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
 {
 	struct mei_me_hw *hw = to_me_hw(dev);
 	u32 hcsr = mei_hcsr_read(hw);
@@ -191,6 +191,7 @@ static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
 		mei_me_hw_reset_release(dev);
 
 	dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", mei_hcsr_read(hw));
+	return 0;
 }
 
 /**
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 79e9e1c..1525388 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -132,13 +132,19 @@ EXPORT_SYMBOL_GPL(mei_start);
 void mei_reset(struct mei_device *dev, int interrupts_enabled)
 {
 	bool unexpected;
+	int ret;
 
 	unexpected = (dev->dev_state != MEI_DEV_INITIALIZING &&
 			dev->dev_state != MEI_DEV_DISABLED &&
 			dev->dev_state != MEI_DEV_POWER_DOWN &&
 			dev->dev_state != MEI_DEV_POWER_UP);
 
-	mei_hw_reset(dev, interrupts_enabled);
+	ret = mei_hw_reset(dev, interrupts_enabled);
+	if (ret) {
+		dev_err(&dev->pdev->dev, "hw reset failed disabling the device\n");
+		interrupts_enabled = false;
+		dev->dev_state = MEI_DEV_DISABLED;
+	}
 
 	dev->hbm_state = MEI_HBM_IDLE;
 
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 80a9031..1aa4997 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -233,7 +233,7 @@ struct mei_hw_ops {
 	bool (*host_is_ready) (struct mei_device *dev);
 
 	bool (*hw_is_ready) (struct mei_device *dev);
-	void (*hw_reset) (struct mei_device *dev, bool enable);
+	int (*hw_reset) (struct mei_device *dev, bool enable);
 	int  (*hw_start) (struct mei_device *dev);
 	void (*hw_config) (struct mei_device *dev);
 
@@ -539,9 +539,9 @@ static inline void mei_hw_config(struct mei_device *dev)
 {
 	dev->ops->hw_config(dev);
 }
-static inline void mei_hw_reset(struct mei_device *dev, bool enable)
+static inline int mei_hw_reset(struct mei_device *dev, bool enable)
 {
-	dev->ops->hw_reset(dev, enable);
+	return dev->ops->hw_reset(dev, enable);
 }
 
 static inline void mei_hw_start(struct mei_device *dev)
-- 
1.8.1.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-06-23  6:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-23  6:36 [char-misc-next 1/4 RESEND] mei: move mei_cl_irq_write_complete to client.c Tomas Winkler
2013-06-23  6:37 ` [char-misc-next 2/4] mei: do not override a client writing state when buffering Tomas Winkler
2013-06-23  6:37 ` [char-misc-next 3/4] mei: mei_cl_connect: don't multiply the timeout twice Tomas Winkler
2013-06-23  6:37 ` [char-misc-next 4/4] mei: check if the hardware start succeeded Tomas Winkler

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®