* [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®