* [char-misc-next 0/2] mei cleanups
@ 2013-04-08 18:56 Tomas Winkler
2013-04-08 18:56 ` [char-misc-next 1/2] mei: add mei_cl_write function Tomas Winkler
2013-04-08 18:56 ` [char-misc-next 2/2] mei: notify about the reset in error level Tomas Winkler
0 siblings, 2 replies; 3+ messages in thread
From: Tomas Winkler @ 2013-04-08 18:56 UTC (permalink / raw)
To: gregkh; +Cc: arnd, linux-kernel, Tomas Winkler
Tomas Winkler (2):
mei: add mei_cl_write function
mei: notify about the reset in error level
drivers/misc/mei/bus.c | 103 ++++++++----------------------------------
drivers/misc/mei/client.c | 105 +++++++++++++++++++++++++++++++++++++++++++
drivers/misc/mei/client.h | 7 ++-
drivers/misc/mei/hbm.c | 21 ++++-----
drivers/misc/mei/interrupt.c | 6 +--
drivers/misc/mei/main.c | 83 +++++++---------------------------
drivers/misc/mei/mei_dev.h | 6 +--
7 files changed, 158 insertions(+), 173 deletions(-)
--
1.8.1.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* [char-misc-next 1/2] mei: add mei_cl_write function
2013-04-08 18:56 [char-misc-next 0/2] mei cleanups Tomas Winkler
@ 2013-04-08 18:56 ` Tomas Winkler
2013-04-08 18:56 ` [char-misc-next 2/2] mei: notify about the reset in error level Tomas Winkler
1 sibling, 0 replies; 3+ messages in thread
From: Tomas Winkler @ 2013-04-08 18:56 UTC (permalink / raw)
To: gregkh; +Cc: arnd, linux-kernel, Tomas Winkler
consolidate write code to a specific me client in mei_cl_write function
the function is called from mei device write handler and from
mei_cl bus send function
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/bus.c | 103 ++++++++------------------------------------
drivers/misc/mei/client.c | 105 +++++++++++++++++++++++++++++++++++++++++++++
drivers/misc/mei/client.h | 7 ++-
drivers/misc/mei/main.c | 83 +++++++----------------------------
drivers/misc/mei/mei_dev.h | 6 +--
5 files changed, 146 insertions(+), 158 deletions(-)
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 8dbcb15..6badfa1 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -226,112 +226,47 @@ static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
bool blocking)
{
struct mei_device *dev;
- struct mei_msg_hdr mei_hdr;
struct mei_cl_cb *cb;
- int me_cl_id, err;
+ int id;
+ int rets;
if (WARN_ON(!cl || !cl->dev))
return -ENODEV;
+ dev = cl->dev;
+
if (cl->state != MEI_FILE_CONNECTED)
return -ENODEV;
+ /* Check if we have an ME client device */
+ id = mei_me_cl_by_id(dev, cl->me_client_id);
+ if (id < 0)
+ return -ENODEV;
+
+ if (length > dev->me_clients[id].props.max_msg_length)
+ return -EINVAL;
+
cb = mei_io_cb_init(cl, NULL);
if (!cb)
return -ENOMEM;
- err = mei_io_cb_alloc_req_buf(cb, length);
- if (err < 0) {
+ rets = mei_io_cb_alloc_req_buf(cb, length);
+ if (rets < 0) {
mei_io_cb_free(cb);
- return err;
+ return rets;
}
memcpy(cb->request_buffer.data, buf, length);
- cb->fop_type = MEI_FOP_WRITE;
-
- dev = cl->dev;
mutex_lock(&dev->device_lock);
- /* Check if we have an ME client device */
- me_cl_id = mei_me_cl_by_id(dev, cl->me_client_id);
- if (me_cl_id == dev->me_clients_num) {
- err = -ENODEV;
- goto out_err;
- }
-
- if (length > dev->me_clients[me_cl_id].props.max_msg_length) {
- err = -EINVAL;
- goto out_err;
- }
-
- err = mei_cl_flow_ctrl_creds(cl);
- if (err < 0)
- goto out_err;
-
- /* Host buffer is not ready, we queue the request */
- if (err == 0 || !dev->hbuf_is_ready) {
- cb->buf_idx = 0;
- mei_hdr.msg_complete = 0;
- cl->writing_state = MEI_WRITING;
-
- goto out;
- }
-
- dev->hbuf_is_ready = false;
-
- /* Check for a maximum length */
- if (length > mei_hbuf_max_len(dev)) {
- mei_hdr.length = mei_hbuf_max_len(dev);
- mei_hdr.msg_complete = 0;
- } else {
- mei_hdr.length = length;
- mei_hdr.msg_complete = 1;
- }
-
- mei_hdr.host_addr = cl->host_client_id;
- mei_hdr.me_addr = cl->me_client_id;
- mei_hdr.reserved = 0;
-
- if (mei_write_message(dev, &mei_hdr, buf)) {
- err = -EIO;
- goto out_err;
- }
-
- cl->writing_state = MEI_WRITING;
- cb->buf_idx = mei_hdr.length;
-
-out:
- if (mei_hdr.msg_complete) {
- if (mei_cl_flow_ctrl_reduce(cl)) {
- err = -ENODEV;
- goto out_err;
- }
- list_add_tail(&cb->list, &dev->write_waiting_list.list);
- } else {
- list_add_tail(&cb->list, &dev->write_list.list);
- }
+ rets = mei_cl_write(cl, cb, blocking);
mutex_unlock(&dev->device_lock);
+ if (rets < 0)
+ mei_io_cb_free(cb);
- if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) {
- if (wait_event_interruptible(cl->tx_wait,
- cl->writing_state == MEI_WRITE_COMPLETE)) {
- if (signal_pending(current))
- err = -EINTR;
- err = -ERESTARTSYS;
- mutex_lock(&dev->device_lock);
- goto out_err;
- }
- }
-
- return mei_hdr.length;
-
-out_err:
- mutex_unlock(&dev->device_lock);
- mei_io_cb_free(cb);
-
- return err;
+ return rets;
}
int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index e14397b..ecadd00 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -678,6 +678,111 @@ err:
}
/**
+ * mei_cl_write - submit a write cb to mei device
+ assumes device_lock is locked
+ *
+ * @cl: host client
+ * @cl: write callback with filled data
+ *
+ * returns numbe of bytes sent on success, <0 on failure.
+ */
+int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
+{
+ struct mei_device *dev;
+ struct mei_msg_data *buf;
+ struct mei_msg_hdr mei_hdr;
+ int rets;
+
+
+ if (WARN_ON(!cl || !cl->dev))
+ return -ENODEV;
+
+ if (WARN_ON(!cb))
+ return -EINVAL;
+
+ dev = cl->dev;
+
+
+ buf = &cb->request_buffer;
+
+ dev_dbg(&dev->pdev->dev, "mei_cl_write %d\n", buf->size);
+
+
+ cb->fop_type = MEI_FOP_WRITE;
+
+ rets = mei_cl_flow_ctrl_creds(cl);
+ if (rets < 0)
+ goto err;
+
+ /* Host buffer is not ready, we queue the request */
+ if (rets == 0 || !dev->hbuf_is_ready) {
+ 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;
+ }
+
+ dev->hbuf_is_ready = false;
+
+ /* Check for a maximum length */
+ if (buf->size > mei_hbuf_max_len(dev)) {
+ mei_hdr.length = mei_hbuf_max_len(dev);
+ mei_hdr.msg_complete = 0;
+ } else {
+ mei_hdr.length = buf->size;
+ mei_hdr.msg_complete = 1;
+ }
+
+ mei_hdr.host_addr = cl->host_client_id;
+ mei_hdr.me_addr = cl->me_client_id;
+ mei_hdr.reserved = 0;
+
+ dev_dbg(&dev->pdev->dev, "write " MEI_HDR_FMT "\n",
+ MEI_HDR_PRM(&mei_hdr));
+
+
+ if (mei_write_message(dev, &mei_hdr, buf->data)) {
+ rets = -EIO;
+ goto err;
+ }
+
+ cl->writing_state = MEI_WRITING;
+ cb->buf_idx = mei_hdr.length;
+
+ rets = buf->size;
+out:
+ if (mei_hdr.msg_complete) {
+ if (mei_cl_flow_ctrl_reduce(cl)) {
+ rets = -ENODEV;
+ goto err;
+ }
+ list_add_tail(&cb->list, &dev->write_waiting_list.list);
+ } else {
+ list_add_tail(&cb->list, &dev->write_list.list);
+ }
+
+
+ if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) {
+
+ mutex_unlock(&dev->device_lock);
+ if (wait_event_interruptible(cl->tx_wait,
+ cl->writing_state == MEI_WRITE_COMPLETE)) {
+ if (signal_pending(current))
+ rets = -EINTR;
+ else
+ rets = -ERESTARTSYS;
+ }
+ mutex_lock(&dev->device_lock);
+ }
+err:
+ return rets;
+}
+
+
+
+/**
* mei_cl_all_disconnect - disconnect forcefully all connected clients
*
* @dev - mei device
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index 214b239..e890c8b 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -86,17 +86,16 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl);
*/
bool mei_cl_is_other_connecting(struct mei_cl *cl);
int mei_cl_disconnect(struct mei_cl *cl);
-
-int mei_cl_read_start(struct mei_cl *cl);
-
int mei_cl_connect(struct mei_cl *cl, struct file *file);
+int mei_cl_read_start(struct mei_cl *cl);
+int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
void mei_host_client_init(struct work_struct *work);
+
void mei_cl_all_disconnect(struct mei_device *dev);
void mei_cl_all_read_wakeup(struct mei_device *dev);
void mei_cl_all_write_clear(struct mei_device *dev);
-
#endif /* _MEI_CLIENT_H_ */
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 329fb86..cb11b36 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -342,11 +342,10 @@ 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_msg_hdr mei_hdr;
struct mei_device *dev;
unsigned long timeout = 0;
int rets;
- int i;
+ int id;
if (WARN_ON(!cl || !cl->dev))
return -ENODEV;
@@ -357,24 +356,24 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
if (dev->dev_state != MEI_DEV_ENABLED) {
rets = -ENODEV;
- goto err;
+ goto out;
}
- i = mei_me_cl_by_id(dev, cl->me_client_id);
- if (i < 0) {
+ id = mei_me_cl_by_id(dev, cl->me_client_id);
+ if (id < 0) {
rets = -ENODEV;
- goto err;
+ goto out;
}
- if (length > dev->me_clients[i].props.max_msg_length || length <= 0) {
+ if (length > dev->me_clients[id].props.max_msg_length || length <= 0) {
rets = -EMSGSIZE;
- goto err;
+ goto out;
}
if (cl->state != MEI_FILE_CONNECTED) {
- rets = -ENODEV;
dev_err(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d",
cl->host_client_id, cl->me_client_id);
- goto err;
+ rets = -ENODEV;
+ goto out;
}
if (cl == &dev->iamthif_cl) {
write_cb = mei_amthif_find_read_list_entry(dev, file);
@@ -412,17 +411,15 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
if (!write_cb) {
dev_err(&dev->pdev->dev, "write cb allocation failed\n");
rets = -ENOMEM;
- goto err;
+ goto out;
}
rets = mei_io_cb_alloc_req_buf(write_cb, length);
if (rets)
- goto err;
-
- dev_dbg(&dev->pdev->dev, "cb request size = %zd\n", length);
+ goto out;
rets = copy_from_user(write_cb->request_buffer.data, ubuf, length);
if (rets)
- goto err;
+ goto out;
cl->sm_state = 0;
if (length == 4 &&
@@ -440,65 +437,17 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
if (rets) {
dev_err(&dev->pdev->dev,
"amthif write failed with status = %d\n", rets);
- goto err;
+ goto out;
}
mutex_unlock(&dev->device_lock);
return length;
}
- write_cb->fop_type = MEI_FOP_WRITE;
-
- dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n",
- cl->host_client_id, cl->me_client_id);
- rets = mei_cl_flow_ctrl_creds(cl);
- if (rets < 0)
- goto err;
-
- if (rets == 0 || !dev->hbuf_is_ready) {
- write_cb->buf_idx = 0;
- mei_hdr.msg_complete = 0;
- cl->writing_state = MEI_WRITING;
- goto out;
- }
-
- dev->hbuf_is_ready = false;
- if (length > mei_hbuf_max_len(dev)) {
- mei_hdr.length = mei_hbuf_max_len(dev);
- mei_hdr.msg_complete = 0;
- } else {
- mei_hdr.length = length;
- mei_hdr.msg_complete = 1;
- }
- mei_hdr.host_addr = cl->host_client_id;
- mei_hdr.me_addr = cl->me_client_id;
- mei_hdr.reserved = 0;
-
- dev_dbg(&dev->pdev->dev, "write " MEI_HDR_FMT "\n",
- MEI_HDR_PRM(&mei_hdr));
- if (mei_write_message(dev, &mei_hdr, write_cb->request_buffer.data)) {
- rets = -ENODEV;
- goto err;
- }
- cl->writing_state = MEI_WRITING;
- write_cb->buf_idx = mei_hdr.length;
-
+ rets = mei_cl_write(cl, write_cb, false);
out:
- if (mei_hdr.msg_complete) {
- if (mei_cl_flow_ctrl_reduce(cl)) {
- rets = -ENODEV;
- goto err;
- }
- list_add_tail(&write_cb->list, &dev->write_waiting_list.list);
- } else {
- list_add_tail(&write_cb->list, &dev->write_list.list);
- }
-
- mutex_unlock(&dev->device_lock);
- return length;
-
-err:
mutex_unlock(&dev->device_lock);
- mei_io_cb_free(write_cb);
+ if (rets < 0)
+ mei_io_cb_free(write_cb);
return rets;
}
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 8806be4..d786da6 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -153,7 +153,7 @@ enum mei_cb_file_ops {
/*
* Intel MEI message data struct
*/
-struct mei_message_data {
+struct mei_msg_data {
u32 size;
unsigned char *data;
};
@@ -184,8 +184,8 @@ struct mei_cl_cb {
struct list_head list;
struct mei_cl *cl;
enum mei_cb_file_ops fop_type;
- struct mei_message_data request_buffer;
- struct mei_message_data response_buffer;
+ struct mei_msg_data request_buffer;
+ struct mei_msg_data response_buffer;
unsigned long buf_idx;
unsigned long read_time;
struct file *file_object;
--
1.8.1.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* [char-misc-next 2/2] mei: notify about the reset in error level
2013-04-08 18:56 [char-misc-next 0/2] mei cleanups Tomas Winkler
2013-04-08 18:56 ` [char-misc-next 1/2] mei: add mei_cl_write function Tomas Winkler
@ 2013-04-08 18:56 ` Tomas Winkler
1 sibling, 0 replies; 3+ messages in thread
From: Tomas Winkler @ 2013-04-08 18:56 UTC (permalink / raw)
To: gregkh; +Cc: arnd, linux-kernel, Tomas Winkler
Display errors causing device reset using dev_err and not dev_dbg
also change messages text to something more concise
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hbm.c | 21 +++++++++------------
drivers/misc/mei/interrupt.c | 6 +++---
2 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index fb9e63b..de7f5ba 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -145,7 +145,7 @@ void mei_hbm_start_req(struct mei_device *dev)
dev->recvd_msg = false;
if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
- dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
+ dev_err(&dev->pdev->dev, "version message writet failed\n");
dev->dev_state = MEI_DEV_RESETING;
mei_reset(dev, 1);
}
@@ -175,7 +175,7 @@ static void mei_hbm_enum_clients_req(struct mei_device *dev)
if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
dev->dev_state = MEI_DEV_RESETING;
- dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
+ dev_err(&dev->pdev->dev, "enumeration request write failed.\n");
mei_reset(dev, 1);
}
dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE;
@@ -227,7 +227,7 @@ static int mei_hbm_prop_req(struct mei_device *dev)
if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
dev->dev_state = MEI_DEV_RESETING;
- dev_err(&dev->pdev->dev, "Properties request command failed\n");
+ dev_err(&dev->pdev->dev, "properties request write failed\n");
mei_reset(dev, 1);
return -EIO;
@@ -557,7 +557,7 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
mei_hbm_enum_clients_req(dev);
} else {
dev->recvd_msg = false;
- dev_dbg(&dev->pdev->dev, "reset due to received hbm: host start\n");
+ dev_err(&dev->pdev->dev, "reset: wrong host start response\n");
mei_reset(dev, 1);
return;
}
@@ -591,23 +591,20 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
me_client = &dev->me_clients[dev->me_client_presentation_num];
if (props_res->status || !dev->me_clients) {
- dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
+ dev_err(&dev->pdev->dev, "reset: properties response hbm wrong status.\n");
mei_reset(dev, 1);
return;
}
if (me_client->client_id != props_res->address) {
- dev_err(&dev->pdev->dev,
- "Host client properties reply mismatch\n");
+ dev_err(&dev->pdev->dev, "reset: host properties response address mismatch\n");
mei_reset(dev, 1);
-
return;
}
if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) {
- dev_err(&dev->pdev->dev,
- "Unexpected client properties reply\n");
+ dev_err(&dev->pdev->dev, "reset: unexpected properties response\n");
mei_reset(dev, 1);
return;
@@ -637,7 +634,7 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
/* first property reqeust */
mei_hbm_prop_req(dev);
} else {
- dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
+ dev_err(&dev->pdev->dev, "reset: unexpected enumeration response hbm.\n");
mei_reset(dev, 1);
return;
}
@@ -645,7 +642,7 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
case HOST_STOP_RES_CMD:
dev->dev_state = MEI_DEV_DISABLED;
- dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n");
+ dev_info(&dev->pdev->dev, "reset: FW stop response.\n");
mei_reset(dev, 1);
break;
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 255e085..9ff8c61 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -623,7 +623,7 @@ void mei_timer(struct work_struct *work)
if (dev->dev_state == MEI_DEV_INIT_CLIENTS) {
if (dev->init_clients_timer) {
if (--dev->init_clients_timer == 0) {
- dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n",
+ dev_err(&dev->pdev->dev, "reset: init clients timeout ,init clients state = %d.\n",
dev->init_clients_state);
mei_reset(dev, 1);
}
@@ -635,7 +635,7 @@ void mei_timer(struct work_struct *work)
list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
if (cl_pos->timer_count) {
if (--cl_pos->timer_count == 0) {
- dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n");
+ dev_err(&dev->pdev->dev, "reset: connect/disconnect timeout.\n");
mei_reset(dev, 1);
goto out;
}
@@ -644,7 +644,7 @@ void mei_timer(struct work_struct *work)
if (dev->iamthif_stall_timer) {
if (--dev->iamthif_stall_timer == 0) {
- dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n");
+ dev_err(&dev->pdev->dev, "reset: amthif hanged.\n");
mei_reset(dev, 1);
dev->iamthif_msg_buf_size = 0;
dev->iamthif_msg_buf_index = 0;
--
1.8.1.2
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-04-08 18:57 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-08 18:56 [char-misc-next 0/2] mei cleanups Tomas Winkler
2013-04-08 18:56 ` [char-misc-next 1/2] mei: add mei_cl_write function Tomas Winkler
2013-04-08 18:56 ` [char-misc-next 2/2] mei: notify about the reset in error level 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®