From 438763f37eb9664b6372bdfee990f8c33acdc63c Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 25 Dec 2012 19:05:59 +0200 Subject: mei: drop redundant length parameter from mei_write_message function The length is already part of the message header and it is validated before the function call Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 18794aea6062..8a9313a1ee7b 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -300,8 +300,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) mei_hdr.reserved = 0; dev->iamthif_msg_buf_index += mei_hdr.length; if (mei_write_message(dev, &mei_hdr, - (unsigned char *)(dev->iamthif_msg_buf), - mei_hdr.length)) + (unsigned char *)dev->iamthif_msg_buf)) return -ENODEV; if (mei_hdr.msg_complete) { @@ -463,8 +462,7 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, *slots -= msg_slots; if (mei_write_message(dev, mei_hdr, - dev->iamthif_msg_buf + dev->iamthif_msg_buf_index, - mei_hdr->length)) { + dev->iamthif_msg_buf + dev->iamthif_msg_buf_index)) { dev->iamthif_state = MEI_IAMTHIF_IDLE; cl->status = -ENODEV; list_del(&cb->list); -- cgit v1.2.3 From 15d4acc57f23b6e02e587b773458a7c0e23e501d Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 25 Dec 2012 19:06:00 +0200 Subject: mei: use unified format for printing mei message header Introduce MEI_HDR_FMT and MEI_HDR_PRM macros. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 3 +-- drivers/misc/mei/interface.c | 4 +--- drivers/misc/mei/interrupt.c | 14 ++++++-------- drivers/misc/mei/main.c | 5 +++-- drivers/misc/mei/mei_dev.h | 5 +++++ 5 files changed, 16 insertions(+), 15 deletions(-) (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 8a9313a1ee7b..77acd2349b1b 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -457,8 +457,7 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, return 0; } - dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n", - mei_hdr->length, mei_hdr->msg_complete); + dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); *slots -= msg_slots; if (mei_write_message(dev, mei_hdr, diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 21ccbe6f7162..17d93f71d6bf 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -127,9 +127,7 @@ int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, int i; int empty_slots; - dev_dbg(&dev->pdev->dev, - "mei_write_message header=%08x.\n", - *((u32 *) header)); + dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header)); empty_slots = mei_hbuf_empty_slots(dev); dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index b72fa8196ddb..fe93d1c9c242 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -150,8 +150,8 @@ quit: dev_dbg(&dev->pdev->dev, "message read\n"); if (!buffer) { mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); - dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n", - *(u32 *) dev->rd_msg_buf); + dev_dbg(&dev->pdev->dev, "discarding message " MEI_HDR_FMT "\n", + MEI_HDR_PRM(mei_hdr)); } return 0; @@ -742,8 +742,7 @@ static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n", cb->request_buffer.size, cb->buf_idx); - dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n", - mei_hdr->length, mei_hdr->msg_complete); + dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); *slots -= msg_slots; if (mei_write_message(dev, mei_hdr, @@ -790,7 +789,7 @@ static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list, dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); } mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr; - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length); + dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); if (mei_hdr->reserved || !dev->rd_msg_hdr) { dev_dbg(&dev->pdev->dev, "corrupted message header.\n"); @@ -835,13 +834,12 @@ static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list, (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && (dev->iamthif_state == MEI_IAMTHIF_READING)) { dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", - mei_hdr->length); + + dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); ret = mei_amthif_irq_read_message(cmpl_list, dev, mei_hdr); if (ret) goto end; - } else { dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n"); ret = mei_irq_thread_read_client_message(cmpl_list, diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index b281c235d898..7751b58540ac 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -552,8 +552,9 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, 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, "call mei_write_message header=%08x.\n", - *((u32 *) &mei_hdr)); + + 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; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 25da04549d04..da0980531c62 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -506,4 +506,9 @@ static inline struct mei_msg_hdr *mei_hbm_hdr(u32 *buf, size_t length) return hdr; } +#define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d comp=%1d" +#define MEI_HDR_PRM(hdr) \ + (hdr)->host_addr, (hdr)->me_addr, \ + (hdr)->length, (hdr)->msg_complete + #endif -- cgit v1.2.3 From 47a73801f498883ea3acccb8f6ff1b5c7a3553de Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 25 Dec 2012 19:06:03 +0200 Subject: mei: include local headers after the system ones first include linux/mei.h then only local headers to avoid possible false dependencies Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 3 +-- drivers/misc/mei/init.c | 4 ++-- drivers/misc/mei/interface.c | 3 ++- drivers/misc/mei/interrupt.c | 4 ++-- drivers/misc/mei/iorw.c | 4 ++-- drivers/misc/mei/main.c | 3 ++- drivers/misc/mei/wd.c | 4 ++-- 7 files changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 77acd2349b1b..bb613f733309 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -31,10 +31,9 @@ #include #include +#include #include "mei_dev.h" -#include "hw.h" -#include #include "interface.h" const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index c0c0b3e22579..08884ef13f31 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -19,10 +19,10 @@ #include #include +#include + #include "mei_dev.h" -#include "hw.h" #include "interface.h" -#include const char *mei_dev_state_str(int state) { diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 17d93f71d6bf..810431e30cd2 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -15,8 +15,9 @@ */ #include -#include "mei_dev.h" #include + +#include "mei_dev.h" #include "interface.h" diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index fe93d1c9c242..0a020ad92f00 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -21,9 +21,9 @@ #include #include -#include "mei_dev.h" #include -#include "hw.h" + +#include "mei_dev.h" #include "interface.h" diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index eb93a1b53b9b..7ccc3d8a079e 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -33,9 +33,9 @@ #include -#include "mei_dev.h" -#include "hw.h" #include + +#include "mei_dev.h" #include "interface.h" /** diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 7751b58540ac..da9426054815 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -37,8 +37,9 @@ #include #include -#include "mei_dev.h" #include + +#include "mei_dev.h" #include "interface.h" /* AMT device is a singleton on the platform */ diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 9d4d4aa0f0e8..9c3738a4eb08 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -21,10 +21,10 @@ #include #include +#include + #include "mei_dev.h" -#include "hw.h" #include "interface.h" -#include static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; -- cgit v1.2.3 From e46f187487a8c28e64417e51ba628746a5397838 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 25 Dec 2012 19:06:10 +0200 Subject: mei: use structured buffer for the write buffer We can drop useless castings and use proper types. We remove the casting in mei_hbm_hdr function and add new function mei_hbm_stop_request_prepare that utilize the new structure Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 25 ++++---- drivers/misc/mei/hbm.c | 134 ++++++++++++++++++++++--------------------- drivers/misc/mei/interrupt.c | 25 ++++---- drivers/misc/mei/mei_dev.h | 12 ++-- drivers/misc/mei/wd.c | 17 +++--- 5 files changed, 108 insertions(+), 105 deletions(-) (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index bb613f733309..f9d458cced21 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -432,34 +432,33 @@ unsigned int mei_amthif_poll(struct mei_device *dev, int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) { - struct mei_msg_hdr *mei_hdr; + struct mei_msg_hdr mei_hdr; struct mei_cl *cl = cb->cl; size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index; size_t msg_slots = mei_data2slots(len); - mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->reserved = 0; + 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; + 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; + 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, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); + dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr)); *slots -= msg_slots; - if (mei_write_message(dev, mei_hdr, + if (mei_write_message(dev, &mei_hdr, dev->iamthif_msg_buf + dev->iamthif_msg_buf_index)) { dev->iamthif_state = MEI_IAMTHIF_IDLE; cl->status = -ENODEV; @@ -470,10 +469,10 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, if (mei_flow_ctrl_reduce(dev, cl)) return -ENODEV; - dev->iamthif_msg_buf_index += mei_hdr->length; + dev->iamthif_msg_buf_index += mei_hdr.length; cl->status = 0; - if (mei_hdr->msg_complete) { + if (mei_hdr.msg_complete) { dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; dev->iamthif_flow_control_pending = true; diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index bc36c23cd2db..e9ba51d5a46c 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -67,21 +67,21 @@ bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf) */ void mei_host_start_message(struct mei_device *dev) { - struct mei_msg_hdr *mei_hdr; + struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; struct hbm_host_version_request *start_req; const size_t len = sizeof(struct hbm_host_version_request); - mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); + mei_hbm_hdr(mei_hdr, len); /* host start message */ - start_req = (struct hbm_host_version_request *)&dev->wr_msg_buf[1]; + start_req = (struct hbm_host_version_request *)dev->wr_msg.data; memset(start_req, 0, len); start_req->hbm_cmd = HOST_START_REQ_CMD; start_req->host_version.major_version = HBM_MAJOR_VERSION; start_req->host_version.minor_version = HBM_MINOR_VERSION; dev->recvd_msg = false; - if (mei_write_message(dev, mei_hdr, (unsigned char *)start_req)) { + 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->dev_state = MEI_DEV_RESETING; mei_reset(dev, 1); @@ -100,17 +100,17 @@ void mei_host_start_message(struct mei_device *dev) */ void mei_host_enum_clients_message(struct mei_device *dev) { - struct mei_msg_hdr *mei_hdr; + struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; struct hbm_host_enum_request *enum_req; const size_t len = sizeof(struct hbm_host_enum_request); /* enumerate clients */ - mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); + mei_hbm_hdr(mei_hdr, len); - enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1]; - memset(enum_req, 0, sizeof(struct hbm_host_enum_request)); + enum_req = (struct hbm_host_enum_request *)dev->wr_msg.data; + memset(enum_req, 0, len); enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; - if (mei_write_message(dev, mei_hdr, (unsigned char *)enum_req)) { + 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"); mei_reset(dev, 1); @@ -124,7 +124,7 @@ void mei_host_enum_clients_message(struct mei_device *dev) int mei_host_client_enumerate(struct mei_device *dev) { - struct mei_msg_hdr *mei_hdr; + struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; struct hbm_props_request *prop_req; const size_t len = sizeof(struct hbm_props_request); unsigned long next_client_index; @@ -146,8 +146,8 @@ int mei_host_client_enumerate(struct mei_device *dev) dev->me_clients[client_num].client_id = next_client_index; dev->me_clients[client_num].mei_flow_ctrl_creds = 0; - mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); - prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1]; + mei_hbm_hdr(mei_hdr, len); + prop_req = (struct hbm_props_request *)dev->wr_msg.data; memset(prop_req, 0, sizeof(struct hbm_props_request)); @@ -155,7 +155,7 @@ int mei_host_client_enumerate(struct mei_device *dev) prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; prop_req->address = next_client_index; - if (mei_write_message(dev, mei_hdr, (unsigned char *) prop_req)) { + 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"); mei_reset(dev, 1); @@ -169,6 +169,27 @@ int mei_host_client_enumerate(struct mei_device *dev) return 0; } +/** + * mei_hbm_stop_req_prepare - perpare stop request message + * + * @dev - mei device + * @mei_hdr - mei message header + * @data - hbm message body buffer + */ +static void mei_hbm_stop_req_prepare(struct mei_device *dev, + struct mei_msg_hdr *mei_hdr, unsigned char *data) +{ + struct hbm_host_stop_request *req = + (struct hbm_host_stop_request *)data; + const size_t len = sizeof(struct hbm_host_stop_request); + + mei_hbm_hdr(mei_hdr, len); + + memset(req, 0, len); + req->hbm_cmd = HOST_STOP_REQ_CMD; + req->reason = DRIVER_STOP_REQUEST; +} + /** * mei_send_flow_control - sends flow control to fw. * @@ -179,17 +200,16 @@ int mei_host_client_enumerate(struct mei_device *dev) */ int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl) { - struct mei_msg_hdr *mei_hdr; - unsigned char *buf = (unsigned char *)&dev->wr_msg_buf[1]; + struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; const size_t len = sizeof(struct hbm_flow_control); - mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); - mei_hbm_cl_hdr(cl, MEI_FLOW_CONTROL_CMD, buf, len); + mei_hbm_hdr(mei_hdr, len); + mei_hbm_cl_hdr(cl, MEI_FLOW_CONTROL_CMD, dev->wr_msg.data, len); dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n", cl->host_client_id, cl->me_client_id); - return mei_write_message(dev, mei_hdr, buf); + return mei_write_message(dev, mei_hdr, dev->wr_msg.data); } /** @@ -202,14 +222,13 @@ int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl) */ int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) { - struct mei_msg_hdr *hdr; - unsigned char *buf = (unsigned char *)&dev->wr_msg_buf[1]; + struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; const size_t len = sizeof(struct hbm_client_connect_request); - hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); - mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_REQ_CMD, buf, len); + mei_hbm_hdr(mei_hdr, len); + mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_REQ_CMD, dev->wr_msg.data, len); - return mei_write_message(dev, hdr, buf); + return mei_write_message(dev, mei_hdr, dev->wr_msg.data); } /** @@ -222,14 +241,13 @@ int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) */ int mei_connect(struct mei_device *dev, struct mei_cl *cl) { - struct mei_msg_hdr *hdr; - unsigned char *buf = (unsigned char *)&dev->wr_msg_buf[1]; + struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; const size_t len = sizeof(struct hbm_client_connect_request); - hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); - mei_hbm_cl_hdr(cl, CLIENT_CONNECT_REQ_CMD, buf, len); + mei_hbm_hdr(mei_hdr, len); + mei_hbm_cl_hdr(cl, CLIENT_CONNECT_REQ_CMD, dev->wr_msg.data, len); - return mei_write_message(dev, hdr, buf); + return mei_write_message(dev, mei_hdr, dev->wr_msg.data); } /** @@ -257,9 +275,9 @@ static void mei_client_disconnect_request(struct mei_device *dev, dev->iamthif_timer = 0; /* prepare disconnect response */ - (void)mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len); + mei_hbm_hdr(&dev->wr_ext_msg.hdr, len); mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_RES_CMD, - &dev->wr_ext_msg.data, len); + dev->wr_ext_msg.data, len); break; } } @@ -284,7 +302,6 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) struct hbm_flow_control *flow_control; struct hbm_props_response *props_res; struct hbm_host_enum_response *enum_res; - struct hbm_host_stop_request *stop_req; /* read the message to our buffer */ BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf)); @@ -294,34 +311,27 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) switch (mei_msg->hbm_cmd) { case HOST_START_RES_CMD: version_res = (struct hbm_host_version_response *)mei_msg; - if (version_res->host_version_supported) { - dev->version.major_version = HBM_MAJOR_VERSION; - dev->version.minor_version = HBM_MINOR_VERSION; - if (dev->dev_state == MEI_DEV_INIT_CLIENTS && - dev->init_clients_state == MEI_START_MESSAGE) { - dev->init_clients_timer = 0; - mei_host_enum_clients_message(dev); - } else { - dev->recvd_msg = false; - dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n"); - mei_reset(dev, 1); - return; - } - } else { - u32 *buf = dev->wr_msg_buf; - const size_t len = sizeof(struct hbm_host_stop_request); - + if (!version_res->host_version_supported) { dev->version = version_res->me_max_version; + dev_dbg(&dev->pdev->dev, "version mismatch.\n"); - /* send stop message */ - hdr = mei_hbm_hdr(&buf[0], len); - stop_req = (struct hbm_host_stop_request *)&buf[1]; - memset(stop_req, 0, len); - stop_req->hbm_cmd = HOST_STOP_REQ_CMD; - stop_req->reason = DRIVER_STOP_REQUEST; + mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr, + dev->wr_msg.data); + mei_write_message(dev, &dev->wr_msg.hdr, + dev->wr_msg.data); + return; + } - mei_write_message(dev, hdr, (unsigned char *)stop_req); - dev_dbg(&dev->pdev->dev, "version mismatch.\n"); + dev->version.major_version = HBM_MAJOR_VERSION; + dev->version.minor_version = HBM_MINOR_VERSION; + if (dev->dev_state == MEI_DEV_INIT_CLIENTS && + dev->init_clients_state == MEI_START_MESSAGE) { + dev->init_clients_timer = 0; + mei_host_enum_clients_message(dev); + } else { + dev->recvd_msg = false; + dev_dbg(&dev->pdev->dev, "reset due to received hbm: host start\n"); + mei_reset(dev, 1); return; } @@ -417,18 +427,10 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) break; case ME_STOP_REQ_CMD: - { - /* prepare stop request: sent in next interrupt event */ - const size_t len = sizeof(struct hbm_host_stop_request); - - hdr = mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len); - stop_req = (struct hbm_host_stop_request *)&dev->wr_ext_msg.data; - memset(stop_req, 0, len); - stop_req->hbm_cmd = HOST_STOP_REQ_CMD; - stop_req->reason = DRIVER_STOP_REQUEST; + mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr, + dev->wr_ext_msg.data); break; - } default: BUG(); break; diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index d4312a8e139a..9cbf148e02e0 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -469,25 +469,24 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) { - struct mei_msg_hdr *mei_hdr; + struct mei_msg_hdr mei_hdr; struct mei_cl *cl = cb->cl; size_t len = cb->request_buffer.size - cb->buf_idx; size_t msg_slots = mei_data2slots(len); - mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->reserved = 0; + 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; + 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; + mei_hdr.length = len; + mei_hdr.msg_complete = 0; } else { /* wait for next time the host buffer is empty */ return 0; @@ -495,10 +494,10 @@ static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, 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)); + dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr)); *slots -= msg_slots; - if (mei_write_message(dev, mei_hdr, + 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); @@ -509,8 +508,8 @@ static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, return -ENODEV; cl->status = 0; - cb->buf_idx += mei_hdr->length; - if (mei_hdr->msg_complete) + cb->buf_idx += mei_hdr.length; + if (mei_hdr.msg_complete) list_move_tail(&cb->list, &dev->write_waiting_list.list); return 0; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 107a820a6ba4..1ea331ac2463 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -265,7 +265,13 @@ struct mei_device { unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ u32 rd_msg_hdr; - u32 wr_msg_buf[128]; /* used for control messages */ + + /* used for control messages */ + struct { + struct mei_msg_hdr hdr; + unsigned char data[128]; + } wr_msg; + struct { struct mei_msg_hdr hdr; unsigned char data[4]; /* All HBM messages are 4 bytes */ @@ -459,15 +465,13 @@ void mei_disable_interrupts(struct mei_device *dev); void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr); -static inline struct mei_msg_hdr *mei_hbm_hdr(u32 *buf, size_t length) +static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length) { - struct mei_msg_hdr *hdr = (struct mei_msg_hdr *)buf; hdr->host_addr = 0; hdr->me_addr = 0; hdr->length = length; hdr->msg_complete = 1; hdr->reserved = 0; - return hdr; } #define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d comp=%1d" diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 9c3738a4eb08..3997a630847f 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -101,22 +101,21 @@ int mei_wd_host_init(struct mei_device *dev) */ int mei_wd_send(struct mei_device *dev) { - struct mei_msg_hdr *hdr; + struct mei_msg_hdr hdr; - hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - hdr->host_addr = dev->wd_cl.host_client_id; - hdr->me_addr = dev->wd_cl.me_client_id; - hdr->msg_complete = 1; - hdr->reserved = 0; + hdr.host_addr = dev->wd_cl.host_client_id; + hdr.me_addr = dev->wd_cl.me_client_id; + hdr.msg_complete = 1; + hdr.reserved = 0; if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE)) - hdr->length = MEI_WD_START_MSG_SIZE; + hdr.length = MEI_WD_START_MSG_SIZE; else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_HDR_SIZE)) - hdr->length = MEI_WD_STOP_MSG_SIZE; + hdr.length = MEI_WD_STOP_MSG_SIZE; else return -EINVAL; - return mei_write_message(dev, hdr, dev->wd_data); + return mei_write_message(dev, &hdr, dev->wd_data); } /** -- cgit v1.2.3 From 8120e7201cf9795bc98ffb2e3064b657c0f34c05 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 25 Dec 2012 19:06:11 +0200 Subject: mei: add common prefix to hbm function 1. use mei_hbm_ for basic host bus message function 2. use mei_hbm_cl prefix for host bus messages that operation on behalf of a client Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 7 +++--- drivers/misc/mei/hbm.c | 56 +++++++++++++++++++++++++------------------- drivers/misc/mei/init.c | 4 ++-- drivers/misc/mei/interface.h | 11 +++++---- drivers/misc/mei/interrupt.c | 10 ++++---- drivers/misc/mei/iorw.c | 4 ++-- drivers/misc/mei/mei_dev.h | 9 ------- drivers/misc/mei/wd.c | 2 +- 8 files changed, 53 insertions(+), 50 deletions(-) (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index f9d458cced21..6e3cd31eae3b 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -98,7 +98,7 @@ void mei_amthif_host_init(struct mei_device *dev) dev->iamthif_msg_buf = msg_buf; - if (mei_connect(dev, &dev->iamthif_cl)) { + if (mei_hbm_cl_connect_req(dev, &dev->iamthif_cl)) { dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n"); dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; dev->iamthif_cl.host_client_id = 0; @@ -558,7 +558,7 @@ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots) return -EMSGSIZE; } *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); - if (mei_send_flow_control(dev, &dev->iamthif_cl)) { + if (mei_hbm_cl_flow_control_req(dev, &dev->iamthif_cl)) { dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); return -EIO; } @@ -630,7 +630,8 @@ static bool mei_clear_list(struct mei_device *dev, if (dev->iamthif_current_cb == cb_pos) { dev->iamthif_current_cb = NULL; /* send flow control to iamthif client */ - mei_send_flow_control(dev, &dev->iamthif_cl); + mei_hbm_cl_flow_control_req(dev, + &dev->iamthif_cl); } /* free all allocated buffers */ mei_io_cb_free(cb_pos); diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index e9ba51d5a46c..3c9914038490 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -59,13 +59,11 @@ bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf) /** - * host_start_message - mei host sends start message. + * mei_hbm_start_req - sends start request message. * * @dev: the device structure - * - * returns none. */ -void mei_host_start_message(struct mei_device *dev) +void mei_hbm_start_req(struct mei_device *dev) { struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; struct hbm_host_version_request *start_req; @@ -92,13 +90,13 @@ void mei_host_start_message(struct mei_device *dev) } /** - * host_enum_clients_message - host sends enumeration client request message. + * mei_hbm_enum_clients_req - sends enumeration client request message. * * @dev: the device structure * * returns none. */ -void mei_host_enum_clients_message(struct mei_device *dev) +static void mei_hbm_enum_clients_req(struct mei_device *dev) { struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; struct hbm_host_enum_request *enum_req; @@ -120,8 +118,15 @@ void mei_host_enum_clients_message(struct mei_device *dev) return; } +/** + * mei_hbm_prop_requsest - request property for a single client + * + * @dev: the device structure + * + * returns none. + */ -int mei_host_client_enumerate(struct mei_device *dev) +static int mei_hbm_prop_req(struct mei_device *dev) { struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; @@ -191,14 +196,14 @@ static void mei_hbm_stop_req_prepare(struct mei_device *dev, } /** - * mei_send_flow_control - sends flow control to fw. + * mei_hbm_cl_flow_control_req - sends flow control requst. * * @dev: the device structure - * @cl: private data of the file object + * @cl: client info * * This function returns -EIO on write failure */ -int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl) +int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl) { struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; const size_t len = sizeof(struct hbm_flow_control); @@ -213,14 +218,14 @@ int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl) } /** - * mei_disconnect - sends disconnect message to fw. + * mei_hbm_cl_disconnect_req - sends disconnect message to fw. * * @dev: the device structure - * @cl: private data of the file object + * @cl: a client to disconnect from * * This function returns -EIO on write failure */ -int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) +int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl) { struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; const size_t len = sizeof(struct hbm_client_connect_request); @@ -232,14 +237,14 @@ int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) } /** - * mei_connect - sends connect message to fw. + * mei_hbm_cl_connect_req - send connection request to specific me client * * @dev: the device structure - * @cl: private data of the file object + * @cl: a client to connect to * - * This function returns -EIO on write failure + * returns -EIO on write failure */ -int mei_connect(struct mei_device *dev, struct mei_cl *cl) +int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl) { struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; const size_t len = sizeof(struct hbm_client_connect_request); @@ -251,12 +256,13 @@ int mei_connect(struct mei_device *dev, struct mei_cl *cl) } /** - * mei_client_disconnect_request - disconnects from request irq routine + * mei_client_disconnect_request - disconnect request initiated by me + * host sends disoconnect response * * @dev: the device structure. - * @disconnect_req: disconnect request bus message. + * @disconnect_req: disconnect request bus message from the me */ -static void mei_client_disconnect_request(struct mei_device *dev, +static void mei_hbm_fw_disconnect_req(struct mei_device *dev, struct hbm_client_connect_request *disconnect_req) { struct mei_cl *cl, *next; @@ -327,7 +333,7 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) if (dev->dev_state == MEI_DEV_INIT_CLIENTS && dev->init_clients_state == MEI_START_MESSAGE) { dev->init_clients_timer = 0; - mei_host_enum_clients_message(dev); + mei_hbm_enum_clients_req(dev); } else { dev->recvd_msg = false; dev_dbg(&dev->pdev->dev, "reset due to received hbm: host start\n"); @@ -390,7 +396,8 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) dev->me_client_index++; dev->me_client_presentation_num++; - mei_host_client_enumerate(dev); + /* request property for the next client */ + mei_hbm_prop_req(dev); break; @@ -406,7 +413,8 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) dev->init_clients_state = MEI_CLIENT_PROPERTIES_MESSAGE; - mei_host_client_enumerate(dev); + /* 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"); mei_reset(dev, 1); @@ -423,7 +431,7 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) case CLIENT_DISCONNECT_REQ_CMD: /* search for client */ disconnect_req = (struct hbm_client_connect_request *)mei_msg; - mei_client_disconnect_request(dev, disconnect_req); + mei_hbm_fw_disconnect_req(dev, disconnect_req); break; case ME_STOP_REQ_CMD: diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 0536170ff856..418a85f315f1 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -529,9 +529,9 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) cb->fop_type = MEI_FOP_CLOSE; if (dev->mei_host_buffer_is_empty) { dev->mei_host_buffer_is_empty = false; - if (mei_disconnect(dev, cl)) { + if (mei_hbm_cl_disconnect_req(dev, cl)) { rets = -ENODEV; - dev_dbg(&dev->pdev->dev, "failed to call mei_disconnect.\n"); + dev_err(&dev->pdev->dev, "failed to disconnect.\n"); goto free; } mdelay(10); /* Wait for hardware disconnection ready */ diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h index ca732990a7eb..90a3dfda9db5 100644 --- a/drivers/misc/mei/interface.h +++ b/drivers/misc/mei/interface.h @@ -69,12 +69,15 @@ void mei_watchdog_register(struct mei_device *dev); */ void mei_watchdog_unregister(struct mei_device *dev); +int mei_other_client_is_connecting(struct mei_device *dev, struct mei_cl *cl); int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl); -int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl); +void mei_hbm_start_req(struct mei_device *dev); -int mei_disconnect(struct mei_device *dev, struct mei_cl *cl); -int mei_other_client_is_connecting(struct mei_device *dev, struct mei_cl *cl); -int mei_connect(struct mei_device *dev, struct mei_cl *cl); +int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl); +int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl); +int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl); + +void mei_host_client_init(struct work_struct *work); #endif /* _MEI_INTERFACE_H_ */ diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 9cbf148e02e0..eb744cc4f72a 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -157,7 +157,7 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); - if (mei_disconnect(dev, cl)) { + if (mei_hbm_cl_disconnect_req(dev, cl)) { cl->status = 0; cb_pos->buf_idx = 0; list_move_tail(&cb_pos->list, &cmpl_list->list); @@ -407,7 +407,7 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); - if (mei_send_flow_control(dev, cl)) { + if (mei_hbm_cl_flow_control_req(dev, cl)) { cl->status = -ENODEV; cb_pos->buf_idx = 0; list_move_tail(&cb_pos->list, &cmpl_list->list); @@ -443,8 +443,8 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, } cl->state = MEI_FILE_CONNECTING; - *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); - if (mei_connect(dev, cl)) { + *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); + if (mei_hbm_cl_connect_req(dev, cl)) { cl->status = -ENODEV; cb_pos->buf_idx = 0; list_del(&cb_pos->list); @@ -927,7 +927,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) /* link is established * start sending messages. */ - mei_host_start_message(dev); + mei_hbm_start_req(dev); mutex_unlock(&dev->device_lock); return IRQ_HANDLED; } else { diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index 7ccc3d8a079e..d8e08bcf3263 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -258,7 +258,7 @@ int mei_ioctl_connect_client(struct file *file, && !mei_other_client_is_connecting(dev, cl)) { dev_dbg(&dev->pdev->dev, "Sending Connect Message\n"); dev->mei_host_buffer_is_empty = false; - if (mei_connect(dev, cl)) { + if (mei_hbm_cl_connect_req(dev, cl)) { dev_dbg(&dev->pdev->dev, "Sending connect message - failed\n"); rets = -ENODEV; goto end; @@ -350,7 +350,7 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl) cl->read_cb = cb; if (dev->mei_host_buffer_is_empty) { dev->mei_host_buffer_is_empty = false; - if (mei_send_flow_control(dev, cl)) { + if (mei_hbm_cl_flow_control_req(dev, cl)) { rets = -ENODEV; goto err; } diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 1ea331ac2463..0ad32cc49c06 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -383,15 +383,6 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, } - -/* - * MEI Host Client Functions - */ -void mei_host_start_message(struct mei_device *dev); -void mei_host_enum_clients_message(struct mei_device *dev); -int mei_host_client_enumerate(struct mei_device *dev); -void mei_host_client_init(struct work_struct *work); - /* * MEI interrupt functions prototype */ diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 3997a630847f..4f2e9db86478 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -79,7 +79,7 @@ int mei_wd_host_init(struct mei_device *dev) return -ENOENT; } - if (mei_connect(dev, &dev->wd_cl)) { + if (mei_hbm_cl_connect_req(dev, &dev->wd_cl)) { dev_err(&dev->pdev->dev, "wd: failed to connect to the client\n"); dev->wd_cl.state = MEI_FILE_DISCONNECTED; dev->wd_cl.host_client_id = 0; -- cgit v1.2.3 From 0edb23fc3451c84350edcc999c023d225a49530d Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 8 Jan 2013 23:07:12 +0200 Subject: mei: add new hbm.h header to export hbm protocol hbm.h provides access host bus messaging functionality for other MEI layers Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 1 + drivers/misc/mei/hbm.c | 1 + drivers/misc/mei/hbm.h | 39 +++++++++++++++++++++++++++++++++++++++ drivers/misc/mei/init.c | 1 + drivers/misc/mei/interface.h | 7 ++----- drivers/misc/mei/interrupt.c | 1 + drivers/misc/mei/iorw.c | 1 + drivers/misc/mei/mei_dev.h | 10 ---------- drivers/misc/mei/wd.c | 1 + 9 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 drivers/misc/mei/hbm.h (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 6e3cd31eae3b..add4254eb850 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -34,6 +34,7 @@ #include #include "mei_dev.h" +#include "hbm.h" #include "interface.h" const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 6b58b0a10378..9956aaf58aa4 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -20,6 +20,7 @@ #include #include "mei_dev.h" +#include "hbm.h" #include "interface.h" /** diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h new file mode 100644 index 000000000000..b552afbaf85c --- /dev/null +++ b/drivers/misc/mei/hbm.h @@ -0,0 +1,39 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef _MEI_HBM_H_ +#define _MEI_HBM_H_ + +void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr); + +static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length) +{ + hdr->host_addr = 0; + hdr->me_addr = 0; + hdr->length = length; + hdr->msg_complete = 1; + hdr->reserved = 0; +} + +void mei_hbm_start_req(struct mei_device *dev); + +int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl); +int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl); +int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl); + + +#endif /* _MEI_HBM_H_ */ + diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 418a85f315f1..55895fc21ff1 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -22,6 +22,7 @@ #include #include "mei_dev.h" +#include "hbm.h" #include "interface.h" const char *mei_dev_state_str(int state) diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h index 90a3dfda9db5..3d06c087ddd2 100644 --- a/drivers/misc/mei/interface.h +++ b/drivers/misc/mei/interface.h @@ -72,12 +72,9 @@ void mei_watchdog_unregister(struct mei_device *dev); int mei_other_client_is_connecting(struct mei_device *dev, struct mei_cl *cl); int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl); -void mei_hbm_start_req(struct mei_device *dev); +void mei_host_client_init(struct work_struct *work); + -int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl); -int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl); -int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl); -void mei_host_client_init(struct work_struct *work); #endif /* _MEI_INTERFACE_H_ */ diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index a735c8b7ca82..2495e35ccb27 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -24,6 +24,7 @@ #include #include "mei_dev.h" +#include "hbm.h" #include "interface.h" diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index d8e08bcf3263..4328c2d2ca54 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -36,6 +36,7 @@ #include #include "mei_dev.h" +#include "hbm.h" #include "interface.h" /** diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 54ddac324578..1b54e675d3f1 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -445,16 +445,6 @@ void mei_enable_interrupts(struct mei_device *dev); void mei_disable_interrupts(struct mei_device *dev); -void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr); - -static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length) -{ - hdr->host_addr = 0; - hdr->me_addr = 0; - hdr->length = length; - hdr->msg_complete = 1; - hdr->reserved = 0; -} #define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d comp=%1d" #define MEI_HDR_PRM(hdr) \ diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 4f2e9db86478..9814bc1dba01 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -24,6 +24,7 @@ #include #include "mei_dev.h" +#include "hbm.h" #include "interface.h" static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; -- cgit v1.2.3 From 90e0b5f18569bdd03c5ddd1d8c99946f42af77b8 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 8 Jan 2013 23:07:14 +0200 Subject: mei: fix client functions names Use common prefix for function names: mei_cl_ - for host clients mei_me_ - for me clients mei_io_ - for io callback functions Because mei_cl holds mei_device back pointer we can also drop the dev argument from the client functions add client.h header to export the clients API Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 9 +- drivers/misc/mei/client.c | 221 ++++++++++++++++++++++++++----------------- drivers/misc/mei/client.h | 97 +++++++++++++++++++ drivers/misc/mei/init.c | 6 +- drivers/misc/mei/interface.h | 8 -- drivers/misc/mei/interrupt.c | 11 ++- drivers/misc/mei/main.c | 47 +++------ drivers/misc/mei/mei_dev.h | 53 ----------- drivers/misc/mei/wd.c | 13 +-- 9 files changed, 267 insertions(+), 198 deletions(-) create mode 100644 drivers/misc/mei/client.h (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index add4254eb850..cbc9c4e4e321 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -36,6 +36,7 @@ #include "mei_dev.h" #include "hbm.h" #include "interface.h" +#include "client.h" const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, @@ -73,7 +74,7 @@ void mei_amthif_host_init(struct mei_device *dev) dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; /* find ME amthi client */ - i = mei_me_cl_link(dev, &dev->iamthif_cl, + i = mei_cl_link_me(&dev->iamthif_cl, &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID); if (i < 0) { dev_info(&dev->pdev->dev, "failed to find iamthif client.\n"); @@ -280,7 +281,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) memcpy(dev->iamthif_msg_buf, cb->request_buffer.data, cb->request_buffer.size); - ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl); + ret = mei_cl_flow_ctrl_creds(&dev->iamthif_cl); if (ret < 0) return ret; @@ -304,7 +305,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) return -ENODEV; if (mei_hdr.msg_complete) { - if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl)) + if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl)) return -ENODEV; dev->iamthif_flow_control_pending = true; dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; @@ -467,7 +468,7 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, return -ENODEV; } - if (mei_flow_ctrl_reduce(dev, cl)) + if (mei_cl_flow_ctrl_reduce(cl)) return -ENODEV; dev->iamthif_msg_buf_index += mei_hdr.length; diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 19f62073fa67..e300637c89ed 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -24,6 +24,54 @@ #include "mei_dev.h" #include "hbm.h" #include "interface.h" +#include "client.h" + +/** + * mei_me_cl_by_uuid - locate index of me client + * + * @dev: mei device + * returns me client index or -ENOENT if not found + */ +int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *uuid) +{ + int i, res = -ENOENT; + + for (i = 0; i < dev->me_clients_num; ++i) + if (uuid_le_cmp(*uuid, + dev->me_clients[i].props.protocol_name) == 0) { + res = i; + break; + } + + return res; +} + + +/** + * mei_me_cl_by_id return index to me_clients for client_id + * + * @dev: the device structure + * @client_id: me client id + * + * Locking: called under "dev->device_lock" lock + * + * returns index on success, -ENOENT on failure. + */ + +int mei_me_cl_by_id(struct mei_device *dev, u8 client_id) +{ + int i; + for (i = 0; i < dev->me_clients_num; i++) + if (dev->me_clients[i].client_id == client_id) + break; + if (WARN_ON(dev->me_clients[i].client_id != client_id)) + return -ENOENT; + + if (i == dev->me_clients_num) + return -ENOENT; + + return i; +} /** @@ -141,7 +189,7 @@ int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length) */ int mei_cl_flush_queues(struct mei_cl *cl) { - if (!cl || !cl->dev) + if (WARN_ON(!cl || !cl->dev)) return -EINVAL; dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n"); @@ -155,52 +203,6 @@ int mei_cl_flush_queues(struct mei_cl *cl) return 0; } -/** - * mei_me_cl_by_uuid - locate index of me client - * - * @dev: mei device - * returns me client index or -ENOENT if not found - */ -int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *uuid) -{ - int i, res = -ENOENT; - - for (i = 0; i < dev->me_clients_num; ++i) - if (uuid_le_cmp(*uuid, - dev->me_clients[i].props.protocol_name) == 0) { - res = i; - break; - } - - return res; -} - - -/** - * mei_me_cl_by_id return index to me_clients for client_id - * - * @dev: the device structure - * @client_id: me client id - * - * Locking: called under "dev->device_lock" lock - * - * returns index on success, -ENOENT on failure. - */ - -int mei_me_cl_by_id(struct mei_device *dev, u8 client_id) -{ - int i; - for (i = 0; i < dev->me_clients_num; i++) - if (dev->me_clients[i].client_id == client_id) - break; - if (WARN_ON(dev->me_clients[i].client_id != client_id)) - return -ENOENT; - - if (i == dev->me_clients_num) - return -ENOENT; - - return i; -} /** * mei_cl_init - initializes intialize cl. @@ -239,12 +241,29 @@ struct mei_cl *mei_cl_allocate(struct mei_device *dev) return cl; } +/** + * mei_cl_find_read_cb - find this cl's callback in the read list + * + * @dev: device structure + * returns cb on success, NULL on error + */ +struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl) +{ + struct mei_device *dev = cl->dev; + struct mei_cl_cb *cb = NULL; + struct mei_cl_cb *next = NULL; + + list_for_each_entry_safe(cb, next, &dev->read_list.list, list) + if (mei_cl_cmp_id(cl, cb->cl)) + return cb; + return NULL; +} + /** * mei_me_cl_link - create link between host and me clinet and add * me_cl to the list * - * @dev: the device structure * @cl: link between me and host client assocated with opened file descriptor * @uuid: uuid of ME client * @client_id: id of the host client @@ -253,14 +272,16 @@ struct mei_cl *mei_cl_allocate(struct mei_device *dev) * -EINVAL on incorrect values * -ENONET if client not found */ -int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl, - const uuid_le *uuid, u8 host_cl_id) +int mei_cl_link_me(struct mei_cl *cl, const uuid_le *uuid, u8 host_cl_id) { + struct mei_device *dev; int i; - if (!dev || !cl || !uuid) + if (WARN_ON(!cl || !cl->dev || !uuid)) return -EINVAL; + dev = cl->dev; + /* check for valid client id */ i = mei_me_cl_by_uuid(dev, uuid); if (i >= 0) { @@ -275,22 +296,30 @@ int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl, return -ENOENT; } /** - * mei_me_cl_unlink - remove me_cl from the list + * mei_cl_unlink - remove me_cl from the list * * @dev: the device structure * @host_client_id: host client id to be removed */ -void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl) +int mei_cl_unlink(struct mei_cl *cl) { + struct mei_device *dev; struct mei_cl *pos, *next; + + if (WARN_ON(!cl || !cl->dev)) + return -EINVAL; + + dev = cl->dev; + list_for_each_entry_safe(pos, next, &dev->file_list, link) { if (cl->host_client_id == pos->host_client_id) { dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n", - pos->host_client_id, pos->me_client_id); + pos->host_client_id, pos->me_client_id); list_del_init(&pos->link); break; } } + return 0; } @@ -330,23 +359,25 @@ void mei_host_client_init(struct work_struct *work) /** - * mei_disconnect_host_client - sends disconnect message to fw from host client. + * mei_cl_disconnect - disconnect host clinet form the me one * - * @dev: the device structure - * @cl: private data of the file object + * @cl: host client * * Locking: called under "dev->device_lock" lock * * returns 0 on success, <0 on failure. */ -int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) +int mei_cl_disconnect(struct mei_cl *cl) { + struct mei_device *dev; struct mei_cl_cb *cb; int rets, err; - if (!dev || !cl) + if (WARN_ON(!cl || !cl->dev)) return -ENODEV; + dev = cl->dev; + if (cl->state != MEI_FILE_DISCONNECTING) return 0; @@ -401,32 +432,36 @@ free: /** - * mei_other_client_is_connecting - checks if other - * client with the same client id is connected. + * mei_cl_is_other_connecting - checks if other + * client with the same me client id is connecting * - * @dev: the device structure * @cl: private data of the file object * - * returns 1 if other client is connected, 0 - otherwise. + * returns ture if other client is connected, 0 - otherwise. */ -int mei_other_client_is_connecting(struct mei_device *dev, - struct mei_cl *cl) +bool mei_cl_is_other_connecting(struct mei_cl *cl) { - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; + struct mei_device *dev; + struct mei_cl *pos; + struct mei_cl *next; - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if ((cl_pos->state == MEI_FILE_CONNECTING) && - (cl_pos != cl) && - cl->me_client_id == cl_pos->me_client_id) - return 1; + if (WARN_ON(!cl || !cl->dev)) + return false; + + dev = cl->dev; + + list_for_each_entry_safe(pos, next, &dev->file_list, link) { + if ((pos->state == MEI_FILE_CONNECTING) && + (pos != cl) && cl->me_client_id == pos->me_client_id) + return true; } - return 0; + + return false; } /** - * mei_flow_ctrl_creds - checks flow_control credentials. + * mei_cl_flow_ctrl_creds - checks flow_control credits for cl. * * @dev: the device structure * @cl: private data of the file object @@ -435,10 +470,16 @@ int mei_other_client_is_connecting(struct mei_device *dev, * -ENOENT if mei_cl is not present * -EINVAL if single_recv_buf == 0 */ -int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl) +int mei_cl_flow_ctrl_creds(struct mei_cl *cl) { + struct mei_device *dev; int i; + if (WARN_ON(!cl || !cl->dev)) + return -EINVAL; + + dev = cl->dev; + if (!dev->me_clients_num) return 0; @@ -461,7 +502,7 @@ int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl) } /** - * mei_flow_ctrl_reduce - reduces flow_control. + * mei_cl_flow_ctrl_reduce - reduces flow_control. * * @dev: the device structure * @cl: private data of the file object @@ -470,10 +511,16 @@ int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl) * -ENOENT when me client is not found * -EINVAL when ctrl credits are <= 0 */ -int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl) +int mei_cl_flow_ctrl_reduce(struct mei_cl *cl) { + struct mei_device *dev; int i; + if (WARN_ON(!cl || !cl->dev)) + return -EINVAL; + + dev = cl->dev; + if (!dev->me_clients_num) return -ENOENT; @@ -571,7 +618,7 @@ int mei_ioctl_connect_client(struct file *file, goto end; } clear_bit(cl->host_client_id, dev->host_clients_map); - mei_me_cl_unlink(dev, cl); + mei_cl_unlink(cl); kfree(cl); cl = NULL; @@ -598,8 +645,8 @@ int mei_ioctl_connect_client(struct file *file, client->max_msg_length = dev->me_clients[i].props.max_msg_length; client->protocol_version = dev->me_clients[i].props.protocol_version; dev_dbg(&dev->pdev->dev, "Can connect?\n"); - if (dev->mei_host_buffer_is_empty - && !mei_other_client_is_connecting(dev, cl)) { + if (dev->mei_host_buffer_is_empty && + !mei_cl_is_other_connecting(cl)) { dev_dbg(&dev->pdev->dev, "Sending Connect Message\n"); dev->mei_host_buffer_is_empty = false; if (mei_hbm_cl_connect_req(dev, cl)) { @@ -650,20 +697,24 @@ end: } /** - * mei_start_read - the start read client message function. + * mei_cl_start_read - the start read client message function. * - * @dev: the device structure - * @if_num: minor number - * @cl: private data of the file object + * @cl: host client * * returns 0 on success, <0 on failure. */ -int mei_start_read(struct mei_device *dev, struct mei_cl *cl) +int mei_cl_read_start(struct mei_cl *cl) { + struct mei_device *dev; struct mei_cl_cb *cb; int rets; int i; + if (WARN_ON(!cl || !cl->dev)) + return -ENODEV; + + dev = cl->dev; + if (cl->state != MEI_FILE_CONNECTED) return -ENODEV; diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h new file mode 100644 index 000000000000..8dfd052dd0e6 --- /dev/null +++ b/drivers/misc/mei/client.h @@ -0,0 +1,97 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef _MEI_CLIENT_H_ +#define _MEI_CLIENT_H_ + +#include +#include +#include +#include + +#include "mei_dev.h" + +int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid); +int mei_me_cl_by_id(struct mei_device *dev, u8 client_id); + +/* + * MEI IO Functions + */ +struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp); +void mei_io_cb_free(struct mei_cl_cb *priv_cb); +int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length); +int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length); + + +/** + * mei_io_list_init - Sets up a queue list. + * + * @list: An instance cl callback structure + */ +static inline void mei_io_list_init(struct mei_cl_cb *list) +{ + INIT_LIST_HEAD(&list->list); +} +void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl); + +/* + * MEI Host Client Functions + */ + +struct mei_cl *mei_cl_allocate(struct mei_device *dev); +void mei_cl_init(struct mei_cl *cl, struct mei_device *dev); + + +int mei_cl_link_me(struct mei_cl *cl, const uuid_le *uuid, u8 host_cl_id); +int mei_cl_unlink(struct mei_cl *cl); + +int mei_cl_flush_queues(struct mei_cl *cl); +struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl); + +/** + * mei_cl_cmp_id - tells if file private data have same id + * + * @fe1: private data of 1. file object + * @fe2: private data of 2. file object + * + * returns true - if ids are the same and not NULL + */ +static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, + const struct mei_cl *cl2) +{ + return cl1 && cl2 && + (cl1->host_client_id == cl2->host_client_id) && + (cl1->me_client_id == cl2->me_client_id); +} + + +int mei_cl_flow_ctrl_creds(struct mei_cl *cl); + +int mei_cl_flow_ctrl_reduce(struct mei_cl *cl); +/* + * MEI input output function prototype + */ +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); + +void mei_host_client_init(struct work_struct *work); + + +#endif /* _MEI_CLIENT_H_ */ diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 6c1f1f838d2b..7028dbd99cf7 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -23,6 +23,7 @@ #include "mei_dev.h" #include "interface.h" +#include "client.h" const char *mei_dev_state_str(int state) { @@ -241,9 +242,8 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) } /* remove entry if already in list */ dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n"); - mei_me_cl_unlink(dev, &dev->wd_cl); - - mei_me_cl_unlink(dev, &dev->iamthif_cl); + mei_cl_unlink(&dev->wd_cl); + mei_cl_unlink(&dev->iamthif_cl); mei_amthif_reset_params(dev); memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg)); diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h index 3d06c087ddd2..01d1ef518595 100644 --- a/drivers/misc/mei/interface.h +++ b/drivers/misc/mei/interface.h @@ -50,7 +50,6 @@ static inline unsigned char mei_data2slots(size_t length) int mei_count_full_read_slots(struct mei_device *dev); -int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl); @@ -69,12 +68,5 @@ void mei_watchdog_register(struct mei_device *dev); */ void mei_watchdog_unregister(struct mei_device *dev); -int mei_other_client_is_connecting(struct mei_device *dev, struct mei_cl *cl); -int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl); - -void mei_host_client_init(struct work_struct *work); - - - #endif /* _MEI_INTERFACE_H_ */ diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 2495e35ccb27..0a141afcea89 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -26,6 +26,7 @@ #include "mei_dev.h" #include "hbm.h" #include "interface.h" +#include "client.h" /** @@ -297,7 +298,7 @@ static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, return -ENODEV; } - if (mei_flow_ctrl_reduce(dev, cl)) + if (mei_cl_flow_ctrl_reduce(cl)) return -ENODEV; cl->status = 0; @@ -478,10 +479,10 @@ static int mei_irq_thread_write_handler(struct mei_device *dev, } if (dev->dev_state == MEI_DEV_ENABLED) { if (dev->wd_pending && - mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { + mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) { if (mei_wd_send(dev)) dev_dbg(&dev->pdev->dev, "wd send failed.\n"); - else if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) + else if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) return -ENODEV; dev->wd_pending = false; @@ -520,7 +521,7 @@ static int mei_irq_thread_write_handler(struct mei_device *dev, break; case MEI_FOP_IOCTL: /* connect message */ - if (mei_other_client_is_connecting(dev, cl)) + if (mei_cl_is_other_connecting(cl)) continue; ret = _mei_irq_thread_ioctl(dev, &slots, pos, cl, cmpl_list); @@ -540,7 +541,7 @@ static int mei_irq_thread_write_handler(struct mei_device *dev, cl = pos->cl; if (cl == NULL) continue; - if (mei_flow_ctrl_creds(dev, cl) <= 0) { + if (mei_cl_flow_ctrl_creds(cl) <= 0) { dev_dbg(&dev->pdev->dev, "No flow control credentials for client %d, not sending.\n", cl->host_client_id); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index da9426054815..95f05d97a115 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -41,6 +41,7 @@ #include "mei_dev.h" #include "interface.h" +#include "client.h" /* AMT device is a singleton on the platform */ static struct pci_dev *mei_pdev; @@ -90,28 +91,6 @@ MODULE_DEVICE_TABLE(pci, mei_pci_tbl); static DEFINE_MUTEX(mei_mutex); -/** - * find_read_list_entry - find read list entry - * - * @dev: device structure - * @file: pointer to file structure - * - * returns cb on success, NULL on error - */ -static struct mei_cl_cb *find_read_list_entry( - struct mei_device *dev, - struct mei_cl *cl) -{ - struct mei_cl_cb *pos = NULL; - struct mei_cl_cb *next = NULL; - - dev_dbg(&dev->pdev->dev, "remove read_list CB\n"); - list_for_each_entry_safe(pos, next, &dev->read_list.list, list) - if (mei_cl_cmp_id(cl, pos->cl)) - return pos; - return NULL; -} - /** * mei_open - the open function * @@ -217,7 +196,7 @@ static int mei_release(struct inode *inode, struct file *file) "ME client = %d\n", cl->host_client_id, cl->me_client_id); - rets = mei_disconnect_host_client(dev, cl); + rets = mei_cl_disconnect(cl); } mei_cl_flush_queues(cl); dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n", @@ -228,12 +207,12 @@ static int mei_release(struct inode *inode, struct file *file) clear_bit(cl->host_client_id, dev->host_clients_map); dev->open_handle_count--; } - mei_me_cl_unlink(dev, cl); + mei_cl_unlink(cl); /* free read cb */ cb = NULL; if (cl->read_cb) { - cb = find_read_list_entry(dev, cl); + cb = mei_cl_find_read_cb(cl); /* Remove entry from read list */ if (cb) list_del(&cb->list); @@ -323,7 +302,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, goto out; } - err = mei_start_read(dev, cl); + err = mei_cl_read_start(cl); if (err && err != -EBUSY) { dev_dbg(&dev->pdev->dev, "mei start read failure with status = %d\n", err); @@ -394,7 +373,7 @@ copy_buffer: goto out; free: - cb_pos = find_read_list_entry(dev, cl); + cb_pos = mei_cl_find_read_cb(cl); /* Remove entry from read list */ if (cb_pos) list_del(&cb_pos->list); @@ -476,7 +455,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, /* free entry used in read */ if (cl->reading_state == MEI_READ_COMPLETE) { *offset = 0; - write_cb = find_read_list_entry(dev, cl); + write_cb = mei_cl_find_read_cb(cl); if (write_cb) { list_del(&write_cb->list); mei_io_cb_free(write_cb); @@ -531,7 +510,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", cl->host_client_id, cl->me_client_id); - rets = mei_flow_ctrl_creds(dev, cl); + rets = mei_cl_flow_ctrl_creds(cl); if (rets < 0) goto err; @@ -565,7 +544,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, out: if (mei_hdr.msg_complete) { - if (mei_flow_ctrl_reduce(dev, cl)) { + if (mei_cl_flow_ctrl_reduce(cl)) { rets = -ENODEV; goto err; } @@ -904,11 +883,11 @@ static void mei_remove(struct pci_dev *pdev) if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) { dev->iamthif_cl.state = MEI_FILE_DISCONNECTING; - mei_disconnect_host_client(dev, &dev->iamthif_cl); + mei_cl_disconnect(&dev->iamthif_cl); } if (dev->wd_cl.state == MEI_FILE_CONNECTED) { dev->wd_cl.state = MEI_FILE_DISCONNECTING; - mei_disconnect_host_client(dev, &dev->wd_cl); + mei_cl_disconnect(&dev->wd_cl); } /* Unregistering watchdog device */ @@ -916,8 +895,8 @@ static void mei_remove(struct pci_dev *pdev) /* remove entry if already in list */ dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n"); - mei_me_cl_unlink(dev, &dev->wd_cl); - mei_me_cl_unlink(dev, &dev->iamthif_cl); + mei_cl_unlink(&dev->wd_cl); + mei_cl_unlink(&dev->iamthif_cl); dev->iamthif_current_cb = NULL; dev->me_clients_num = 0; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 1b54e675d3f1..5a1ac9a37e10 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -329,59 +329,9 @@ void mei_reset(struct mei_device *dev, int interrupts); int mei_hw_init(struct mei_device *dev); int mei_task_initialize_clients(void *data); int mei_initialize_clients(struct mei_device *dev); -int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl); void mei_allocate_me_clients_storage(struct mei_device *dev); -int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl, - const uuid_le *cguid, u8 host_client_id); -void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl); -int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid); -int mei_me_cl_by_id(struct mei_device *dev, u8 client_id); - -/* - * MEI IO Functions - */ -struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp); -void mei_io_cb_free(struct mei_cl_cb *priv_cb); -int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length); -int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length); - - -/** - * mei_io_list_init - Sets up a queue list. - * - * @list: An instance cl callback structure - */ -static inline void mei_io_list_init(struct mei_cl_cb *list) -{ - INIT_LIST_HEAD(&list->list); -} -void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl); - -/* - * MEI ME Client Functions - */ - -struct mei_cl *mei_cl_allocate(struct mei_device *dev); -void mei_cl_init(struct mei_cl *cl, struct mei_device *dev); -int mei_cl_flush_queues(struct mei_cl *cl); -/** - * mei_cl_cmp_id - tells if file private data have same id - * - * @fe1: private data of 1. file object - * @fe2: private data of 2. file object - * - * returns true - if ids are the same and not NULL - */ -static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, - const struct mei_cl *cl2) -{ - return cl1 && cl2 && - (cl1->host_client_id == cl2->host_client_id) && - (cl1->me_client_id == cl2->me_client_id); -} - /* * MEI interrupt functions prototype @@ -395,9 +345,6 @@ void mei_timer(struct work_struct *work); */ int mei_ioctl_connect_client(struct file *file, struct mei_connect_client_data *data); - -int mei_start_read(struct mei_device *dev, struct mei_cl *cl); - /* * AMTHIF - AMT Host Interface Functions */ diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 9814bc1dba01..5ad5225ea2b9 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -26,6 +26,7 @@ #include "mei_dev.h" #include "hbm.h" #include "interface.h" +#include "client.h" static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; @@ -72,7 +73,7 @@ int mei_wd_host_init(struct mei_device *dev) dev->wd_state = MEI_WD_IDLE; /* Connect WD ME client to the host client */ - id = mei_me_cl_link(dev, &dev->wd_cl, + id = mei_cl_link_me(&dev->wd_cl, &mei_wd_guid, MEI_WD_HOST_CLIENT_ID); if (id < 0) { @@ -141,7 +142,7 @@ int mei_wd_stop(struct mei_device *dev) dev->wd_state = MEI_WD_STOPPING; - ret = mei_flow_ctrl_creds(dev, &dev->wd_cl); + ret = mei_cl_flow_ctrl_creds(&dev->wd_cl); if (ret < 0) goto out; @@ -150,7 +151,7 @@ int mei_wd_stop(struct mei_device *dev) dev->mei_host_buffer_is_empty = false; if (!mei_wd_send(dev)) { - ret = mei_flow_ctrl_reduce(dev, &dev->wd_cl); + ret = mei_cl_flow_ctrl_reduce(&dev->wd_cl); if (ret) goto out; } else { @@ -271,7 +272,7 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) /* Check if we can send the ping to HW*/ if (dev->mei_host_buffer_is_empty && - mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { + mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) { dev->mei_host_buffer_is_empty = false; dev_dbg(&dev->pdev->dev, "wd: sending ping\n"); @@ -282,9 +283,9 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) goto end; } - if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) { + if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) { dev_err(&dev->pdev->dev, - "wd: mei_flow_ctrl_reduce() failed.\n"); + "wd: mei_cl_flow_ctrl_reduce() failed.\n"); ret = -EIO; goto end; } -- cgit v1.2.3 From 9dc64d6a26b016df52d222abe9279a92d9f7cc4c Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 8 Jan 2013 23:07:17 +0200 Subject: mei: rename interface to hw-me Rename hw-me.h to hw-me-regs.h as this file contains only register definitions. Files hw-me.[ch] now contains ME hw dependant functionality Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/Makefile | 2 +- drivers/misc/mei/amthif.c | 2 +- drivers/misc/mei/client.c | 1 - drivers/misc/mei/hbm.c | 2 +- drivers/misc/mei/hw-me-regs.h | 167 +++++++++++++++++++++++ drivers/misc/mei/hw-me.c | 299 ++++++++++++++++++++++++++++++++++++++++++ drivers/misc/mei/hw-me.h | 181 +++++-------------------- drivers/misc/mei/init.c | 1 - drivers/misc/mei/interface.c | 299 ------------------------------------------ drivers/misc/mei/interface.h | 52 -------- drivers/misc/mei/interrupt.c | 2 +- drivers/misc/mei/main.c | 2 +- drivers/misc/mei/mei_dev.h | 2 +- drivers/misc/mei/wd.c | 2 +- 14 files changed, 506 insertions(+), 508 deletions(-) create mode 100644 drivers/misc/mei/hw-me-regs.h create mode 100644 drivers/misc/mei/hw-me.c delete mode 100644 drivers/misc/mei/interface.c delete mode 100644 drivers/misc/mei/interface.h (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile index 67f543ab234f..9f719339e594 100644 --- a/drivers/misc/mei/Makefile +++ b/drivers/misc/mei/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_INTEL_MEI) += mei.o mei-objs := init.o mei-objs += hbm.o mei-objs += interrupt.o -mei-objs += interface.o +mei-objs += hw-me.o mei-objs += main.o mei-objs += amthif.o mei-objs += wd.o diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index cbc9c4e4e321..adc4120c91d3 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -35,7 +35,7 @@ #include "mei_dev.h" #include "hbm.h" -#include "interface.h" +#include "hw-me.h" #include "client.h" const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index cc3e76c60417..e2e9cb7df067 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -23,7 +23,6 @@ #include "mei_dev.h" #include "hbm.h" -#include "interface.h" #include "client.h" /** diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 9956aaf58aa4..f0c3fc4590d5 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -21,7 +21,7 @@ #include "mei_dev.h" #include "hbm.h" -#include "interface.h" +#include "hw-me.h" /** * mei_hbm_cl_hdr - construct client hbm header diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h new file mode 100644 index 000000000000..6a203b6e8346 --- /dev/null +++ b/drivers/misc/mei/hw-me-regs.h @@ -0,0 +1,167 @@ +/****************************************************************************** + * Intel Management Engine Interface (Intel MEI) Linux driver + * Intel MEI Interface Header + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation. + * linux-mei@linux.intel.com + * http://www.intel.com + * + * BSD LICENSE + * + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef _MEI_HW_MEI_REGS_H_ +#define _MEI_HW_MEI_REGS_H_ + +/* + * MEI device IDs + */ +#define MEI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */ +#define MEI_DEV_ID_82G35 0x2984 /* 82G35 Express */ +#define MEI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */ +#define MEI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */ + +#define MEI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */ +#define MEI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */ + +#define MEI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */ +#define MEI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */ +#define MEI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */ +#define MEI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */ +#define MEI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */ + +#define MEI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */ +#define MEI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */ +#define MEI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */ +#define MEI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */ +#define MEI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */ + +#define MEI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */ +#define MEI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */ +#define MEI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */ +#define MEI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */ + +#define MEI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */ +#define MEI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */ +#define MEI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */ +#define MEI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */ + +#define MEI_DEV_ID_IBXPK_1 0x3B64 /* Calpella */ +#define MEI_DEV_ID_IBXPK_2 0x3B65 /* Calpella */ + +#define MEI_DEV_ID_CPT_1 0x1C3A /* Couger Point */ +#define MEI_DEV_ID_PBG_1 0x1D3A /* C600/X79 Patsburg */ + +#define MEI_DEV_ID_PPT_1 0x1E3A /* Panther Point */ +#define MEI_DEV_ID_PPT_2 0x1CBA /* Panther Point */ +#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */ + +#define MEI_DEV_ID_LPT 0x8C3A /* Lynx Point */ +#define MEI_DEV_ID_LPT_LP 0x9C3A /* Lynx Point LP */ +/* + * MEI HW Section + */ + +/* MEI registers */ +/* H_CB_WW - Host Circular Buffer (CB) Write Window register */ +#define H_CB_WW 0 +/* H_CSR - Host Control Status register */ +#define H_CSR 4 +/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */ +#define ME_CB_RW 8 +/* ME_CSR_HA - ME Control Status Host Access register (read only) */ +#define ME_CSR_HA 0xC + + +/* register bits of H_CSR (Host Control Status register) */ +/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */ +#define H_CBD 0xFF000000 +/* Host Circular Buffer Write Pointer */ +#define H_CBWP 0x00FF0000 +/* Host Circular Buffer Read Pointer */ +#define H_CBRP 0x0000FF00 +/* Host Reset */ +#define H_RST 0x00000010 +/* Host Ready */ +#define H_RDY 0x00000008 +/* Host Interrupt Generate */ +#define H_IG 0x00000004 +/* Host Interrupt Status */ +#define H_IS 0x00000002 +/* Host Interrupt Enable */ +#define H_IE 0x00000001 + + +/* register bits of ME_CSR_HA (ME Control Status Host Access register) */ +/* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only +access to ME_CBD */ +#define ME_CBD_HRA 0xFF000000 +/* ME CB Write Pointer HRA - host read only access to ME_CBWP */ +#define ME_CBWP_HRA 0x00FF0000 +/* ME CB Read Pointer HRA - host read only access to ME_CBRP */ +#define ME_CBRP_HRA 0x0000FF00 +/* ME Reset HRA - host read only access to ME_RST */ +#define ME_RST_HRA 0x00000010 +/* ME Ready HRA - host read only access to ME_RDY */ +#define ME_RDY_HRA 0x00000008 +/* ME Interrupt Generate HRA - host read only access to ME_IG */ +#define ME_IG_HRA 0x00000004 +/* ME Interrupt Status HRA - host read only access to ME_IS */ +#define ME_IS_HRA 0x00000002 +/* ME Interrupt Enable HRA - host read only access to ME_IE */ +#define ME_IE_HRA 0x00000001 + +#endif /* _MEI_HW_MEI_REGS_H_ */ diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c new file mode 100644 index 000000000000..4e6b657cd806 --- /dev/null +++ b/drivers/misc/mei/hw-me.c @@ -0,0 +1,299 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include + +#include "mei_dev.h" +#include "hw-me.h" + +/** + * mei_reg_read - Reads 32bit data from the mei device + * + * @dev: the device structure + * @offset: offset from which to read the data + * + * returns register value (u32) + */ +static inline u32 mei_reg_read(const struct mei_device *dev, + unsigned long offset) +{ + return ioread32(dev->mem_addr + offset); +} + + +/** + * mei_reg_write - Writes 32bit data to the mei device + * + * @dev: the device structure + * @offset: offset from which to write the data + * @value: register value to write (u32) + */ +static inline void mei_reg_write(const struct mei_device *dev, + unsigned long offset, u32 value) +{ + iowrite32(value, dev->mem_addr + offset); +} + +/** + * mei_hcsr_read - Reads 32bit data from the host CSR + * + * @dev: the device structure + * + * returns the byte read. + */ +u32 mei_hcsr_read(const struct mei_device *dev) +{ + return mei_reg_read(dev, H_CSR); +} + +u32 mei_mecbrw_read(const struct mei_device *dev) +{ + return mei_reg_read(dev, ME_CB_RW); +} +/** + * mei_mecsr_read - Reads 32bit data from the ME CSR + * + * @dev: the device structure + * + * returns ME_CSR_HA register value (u32) + */ +u32 mei_mecsr_read(const struct mei_device *dev) +{ + return mei_reg_read(dev, ME_CSR_HA); +} + +/** + * mei_set_csr_register - writes H_CSR register to the mei device, + * and ignores the H_IS bit for it is write-one-to-zero. + * + * @dev: the device structure + */ +void mei_hcsr_set(struct mei_device *dev) +{ + if ((dev->host_hw_state & H_IS) == H_IS) + dev->host_hw_state &= ~H_IS; + mei_reg_write(dev, H_CSR, dev->host_hw_state); + dev->host_hw_state = mei_hcsr_read(dev); +} + +/** + * mei_enable_interrupts - clear and stop interrupts + * + * @dev: the device structure + */ +void mei_clear_interrupts(struct mei_device *dev) +{ + if ((dev->host_hw_state & H_IS) == H_IS) + mei_reg_write(dev, H_CSR, dev->host_hw_state); +} + +/** + * mei_enable_interrupts - enables mei device interrupts + * + * @dev: the device structure + */ +void mei_enable_interrupts(struct mei_device *dev) +{ + dev->host_hw_state |= H_IE; + mei_hcsr_set(dev); +} + +/** + * mei_disable_interrupts - disables mei device interrupts + * + * @dev: the device structure + */ +void mei_disable_interrupts(struct mei_device *dev) +{ + dev->host_hw_state &= ~H_IE; + mei_hcsr_set(dev); +} + + +/** + * mei_interrupt_quick_handler - The ISR of the MEI device + * + * @irq: The irq number + * @dev_id: pointer to the device structure + * + * returns irqreturn_t + */ +irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id) +{ + struct mei_device *dev = (struct mei_device *) dev_id; + u32 csr_reg = mei_hcsr_read(dev); + + if ((csr_reg & H_IS) != H_IS) + return IRQ_NONE; + + /* clear H_IS bit in H_CSR */ + mei_reg_write(dev, H_CSR, csr_reg); + + return IRQ_WAKE_THREAD; +} + +/** + * mei_hbuf_filled_slots - gets number of device filled buffer slots + * + * @device: the device structure + * + * returns number of filled slots + */ +static unsigned char mei_hbuf_filled_slots(struct mei_device *dev) +{ + char read_ptr, write_ptr; + + dev->host_hw_state = mei_hcsr_read(dev); + + read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8); + write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16); + + return (unsigned char) (write_ptr - read_ptr); +} + +/** + * mei_hbuf_is_empty - checks if host buffer is empty. + * + * @dev: the device structure + * + * returns true if empty, false - otherwise. + */ +bool mei_hbuf_is_empty(struct mei_device *dev) +{ + return mei_hbuf_filled_slots(dev) == 0; +} + +/** + * mei_hbuf_empty_slots - counts write empty slots. + * + * @dev: the device structure + * + * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count + */ +int mei_hbuf_empty_slots(struct mei_device *dev) +{ + unsigned char filled_slots, empty_slots; + + filled_slots = mei_hbuf_filled_slots(dev); + empty_slots = dev->hbuf_depth - filled_slots; + + /* check for overflow */ + if (filled_slots > dev->hbuf_depth) + return -EOVERFLOW; + + return empty_slots; +} + +/** + * mei_write_message - writes a message to mei device. + * + * @dev: the device structure + * @hader: mei HECI header of message + * @buf: message payload will be written + * + * This function returns -EIO if write has failed + */ +int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, + unsigned char *buf) +{ + unsigned long rem, dw_cnt; + unsigned long length = header->length; + u32 *reg_buf = (u32 *)buf; + int i; + int empty_slots; + + dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header)); + + empty_slots = mei_hbuf_empty_slots(dev); + dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); + + dw_cnt = mei_data2slots(length); + if (empty_slots < 0 || dw_cnt > empty_slots) + return -EIO; + + mei_reg_write(dev, H_CB_WW, *((u32 *) header)); + + for (i = 0; i < length / 4; i++) + mei_reg_write(dev, H_CB_WW, reg_buf[i]); + + rem = length & 0x3; + if (rem > 0) { + u32 reg = 0; + memcpy(®, &buf[length - rem], rem); + mei_reg_write(dev, H_CB_WW, reg); + } + + dev->host_hw_state = mei_hcsr_read(dev); + dev->host_hw_state |= H_IG; + mei_hcsr_set(dev); + dev->me_hw_state = mei_mecsr_read(dev); + if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) + return -EIO; + + return 0; +} + +/** + * mei_count_full_read_slots - counts read full slots. + * + * @dev: the device structure + * + * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count + */ +int mei_count_full_read_slots(struct mei_device *dev) +{ + char read_ptr, write_ptr; + unsigned char buffer_depth, filled_slots; + + dev->me_hw_state = mei_mecsr_read(dev); + buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24); + read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8); + write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16); + filled_slots = (unsigned char) (write_ptr - read_ptr); + + /* check for overflow */ + if (filled_slots > buffer_depth) + return -EOVERFLOW; + + dev_dbg(&dev->pdev->dev, "filled_slots =%08x\n", filled_slots); + return (int)filled_slots; +} + +/** + * mei_read_slots - reads a message from mei device. + * + * @dev: the device structure + * @buffer: message buffer will be written + * @buffer_length: message size will be read + */ +void mei_read_slots(struct mei_device *dev, unsigned char *buffer, + unsigned long buffer_length) +{ + u32 *reg_buf = (u32 *)buffer; + + for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32)) + *reg_buf++ = mei_mecbrw_read(dev); + + if (buffer_length > 0) { + u32 reg = mei_mecbrw_read(dev); + memcpy(reg_buf, ®, buffer_length); + } + + dev->host_hw_state |= H_IG; + mei_hcsr_set(dev); +} + diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h index a42b2a2bafa5..73bef545e4d5 100644 --- a/drivers/misc/mei/hw-me.h +++ b/drivers/misc/mei/hw-me.h @@ -1,167 +1,52 @@ -/****************************************************************************** - * Intel Management Engine Interface (Intel MEI) Linux driver - * Intel MEI Interface Header - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation. - * linux-mei@linux.intel.com - * http://www.intel.com - * - * BSD LICENSE - * - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. +/* * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - *****************************************************************************/ -#ifndef _MEI_HW_MEI_H_ -#define _MEI_HW_MEI_H_ - -/* - * MEI device IDs */ -#define MEI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */ -#define MEI_DEV_ID_82G35 0x2984 /* 82G35 Express */ -#define MEI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */ -#define MEI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */ - -#define MEI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */ -#define MEI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */ -#define MEI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */ -#define MEI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */ -#define MEI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */ -#define MEI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */ -#define MEI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */ -#define MEI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */ -#define MEI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */ -#define MEI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */ -#define MEI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */ -#define MEI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */ +#ifndef _MEI_INTERFACE_H_ +#define _MEI_INTERFACE_H_ -#define MEI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */ -#define MEI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */ -#define MEI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */ -#define MEI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */ +#include +#include "mei_dev.h" -#define MEI_DEV_ID_IBXPK_1 0x3B64 /* Calpella */ -#define MEI_DEV_ID_IBXPK_2 0x3B65 /* Calpella */ -#define MEI_DEV_ID_CPT_1 0x1C3A /* Couger Point */ -#define MEI_DEV_ID_PBG_1 0x1D3A /* C600/X79 Patsburg */ -#define MEI_DEV_ID_PPT_1 0x1E3A /* Panther Point */ -#define MEI_DEV_ID_PPT_2 0x1CBA /* Panther Point */ -#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */ +void mei_read_slots(struct mei_device *dev, + unsigned char *buffer, + unsigned long buffer_length); -#define MEI_DEV_ID_LPT 0x8C3A /* Lynx Point */ -#define MEI_DEV_ID_LPT_LP 0x9C3A /* Lynx Point LP */ -/* - * MEI HW Section - */ +int mei_write_message(struct mei_device *dev, + struct mei_msg_hdr *header, + unsigned char *buf); -/* MEI registers */ -/* H_CB_WW - Host Circular Buffer (CB) Write Window register */ -#define H_CB_WW 0 -/* H_CSR - Host Control Status register */ -#define H_CSR 4 -/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */ -#define ME_CB_RW 8 -/* ME_CSR_HA - ME Control Status Host Access register (read only) */ -#define ME_CSR_HA 0xC +bool mei_hbuf_is_empty(struct mei_device *dev); +int mei_hbuf_empty_slots(struct mei_device *dev); -/* register bits of H_CSR (Host Control Status register) */ -/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */ -#define H_CBD 0xFF000000 -/* Host Circular Buffer Write Pointer */ -#define H_CBWP 0x00FF0000 -/* Host Circular Buffer Read Pointer */ -#define H_CBRP 0x0000FF00 -/* Host Reset */ -#define H_RST 0x00000010 -/* Host Ready */ -#define H_RDY 0x00000008 -/* Host Interrupt Generate */ -#define H_IG 0x00000004 -/* Host Interrupt Status */ -#define H_IS 0x00000002 -/* Host Interrupt Enable */ -#define H_IE 0x00000001 +static inline size_t mei_hbuf_max_data(const struct mei_device *dev) +{ + return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr); +} +/* get slots (dwords) from a message length + header (bytes) */ +static inline unsigned char mei_data2slots(size_t length) +{ + return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4); +} -/* register bits of ME_CSR_HA (ME Control Status Host Access register) */ -/* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only -access to ME_CBD */ -#define ME_CBD_HRA 0xFF000000 -/* ME CB Write Pointer HRA - host read only access to ME_CBWP */ -#define ME_CBWP_HRA 0x00FF0000 -/* ME CB Read Pointer HRA - host read only access to ME_CBRP */ -#define ME_CBRP_HRA 0x0000FF00 -/* ME Reset HRA - host read only access to ME_RST */ -#define ME_RST_HRA 0x00000010 -/* ME Ready HRA - host read only access to ME_RDY */ -#define ME_RDY_HRA 0x00000008 -/* ME Interrupt Generate HRA - host read only access to ME_IG */ -#define ME_IG_HRA 0x00000004 -/* ME Interrupt Status HRA - host read only access to ME_IS */ -#define ME_IS_HRA 0x00000002 -/* ME Interrupt Enable HRA - host read only access to ME_IE */ -#define ME_IE_HRA 0x00000001 +int mei_count_full_read_slots(struct mei_device *dev); -#endif /* _MEI_HW_MEI_H_ */ +#endif /* _MEI_INTERFACE_H_ */ diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 7028dbd99cf7..88407dfd8557 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -22,7 +22,6 @@ #include #include "mei_dev.h" -#include "interface.h" #include "client.h" const char *mei_dev_state_str(int state) diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c deleted file mode 100644 index 3cb0cff01285..000000000000 --- a/drivers/misc/mei/interface.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#include -#include - -#include "mei_dev.h" -#include "interface.h" - -/** - * mei_reg_read - Reads 32bit data from the mei device - * - * @dev: the device structure - * @offset: offset from which to read the data - * - * returns register value (u32) - */ -static inline u32 mei_reg_read(const struct mei_device *dev, - unsigned long offset) -{ - return ioread32(dev->mem_addr + offset); -} - - -/** - * mei_reg_write - Writes 32bit data to the mei device - * - * @dev: the device structure - * @offset: offset from which to write the data - * @value: register value to write (u32) - */ -static inline void mei_reg_write(const struct mei_device *dev, - unsigned long offset, u32 value) -{ - iowrite32(value, dev->mem_addr + offset); -} - -/** - * mei_hcsr_read - Reads 32bit data from the host CSR - * - * @dev: the device structure - * - * returns the byte read. - */ -u32 mei_hcsr_read(const struct mei_device *dev) -{ - return mei_reg_read(dev, H_CSR); -} - -u32 mei_mecbrw_read(const struct mei_device *dev) -{ - return mei_reg_read(dev, ME_CB_RW); -} -/** - * mei_mecsr_read - Reads 32bit data from the ME CSR - * - * @dev: the device structure - * - * returns ME_CSR_HA register value (u32) - */ -u32 mei_mecsr_read(const struct mei_device *dev) -{ - return mei_reg_read(dev, ME_CSR_HA); -} - -/** - * mei_set_csr_register - writes H_CSR register to the mei device, - * and ignores the H_IS bit for it is write-one-to-zero. - * - * @dev: the device structure - */ -void mei_hcsr_set(struct mei_device *dev) -{ - if ((dev->host_hw_state & H_IS) == H_IS) - dev->host_hw_state &= ~H_IS; - mei_reg_write(dev, H_CSR, dev->host_hw_state); - dev->host_hw_state = mei_hcsr_read(dev); -} - -/** - * mei_enable_interrupts - clear and stop interrupts - * - * @dev: the device structure - */ -void mei_clear_interrupts(struct mei_device *dev) -{ - if ((dev->host_hw_state & H_IS) == H_IS) - mei_reg_write(dev, H_CSR, dev->host_hw_state); -} - -/** - * mei_enable_interrupts - enables mei device interrupts - * - * @dev: the device structure - */ -void mei_enable_interrupts(struct mei_device *dev) -{ - dev->host_hw_state |= H_IE; - mei_hcsr_set(dev); -} - -/** - * mei_disable_interrupts - disables mei device interrupts - * - * @dev: the device structure - */ -void mei_disable_interrupts(struct mei_device *dev) -{ - dev->host_hw_state &= ~H_IE; - mei_hcsr_set(dev); -} - - -/** - * mei_interrupt_quick_handler - The ISR of the MEI device - * - * @irq: The irq number - * @dev_id: pointer to the device structure - * - * returns irqreturn_t - */ -irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id) -{ - struct mei_device *dev = (struct mei_device *) dev_id; - u32 csr_reg = mei_hcsr_read(dev); - - if ((csr_reg & H_IS) != H_IS) - return IRQ_NONE; - - /* clear H_IS bit in H_CSR */ - mei_reg_write(dev, H_CSR, csr_reg); - - return IRQ_WAKE_THREAD; -} - -/** - * mei_hbuf_filled_slots - gets number of device filled buffer slots - * - * @device: the device structure - * - * returns number of filled slots - */ -static unsigned char mei_hbuf_filled_slots(struct mei_device *dev) -{ - char read_ptr, write_ptr; - - dev->host_hw_state = mei_hcsr_read(dev); - - read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8); - write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16); - - return (unsigned char) (write_ptr - read_ptr); -} - -/** - * mei_hbuf_is_empty - checks if host buffer is empty. - * - * @dev: the device structure - * - * returns true if empty, false - otherwise. - */ -bool mei_hbuf_is_empty(struct mei_device *dev) -{ - return mei_hbuf_filled_slots(dev) == 0; -} - -/** - * mei_hbuf_empty_slots - counts write empty slots. - * - * @dev: the device structure - * - * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count - */ -int mei_hbuf_empty_slots(struct mei_device *dev) -{ - unsigned char filled_slots, empty_slots; - - filled_slots = mei_hbuf_filled_slots(dev); - empty_slots = dev->hbuf_depth - filled_slots; - - /* check for overflow */ - if (filled_slots > dev->hbuf_depth) - return -EOVERFLOW; - - return empty_slots; -} - -/** - * mei_write_message - writes a message to mei device. - * - * @dev: the device structure - * @hader: mei HECI header of message - * @buf: message payload will be written - * - * This function returns -EIO if write has failed - */ -int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, - unsigned char *buf) -{ - unsigned long rem, dw_cnt; - unsigned long length = header->length; - u32 *reg_buf = (u32 *)buf; - int i; - int empty_slots; - - dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header)); - - empty_slots = mei_hbuf_empty_slots(dev); - dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); - - dw_cnt = mei_data2slots(length); - if (empty_slots < 0 || dw_cnt > empty_slots) - return -EIO; - - mei_reg_write(dev, H_CB_WW, *((u32 *) header)); - - for (i = 0; i < length / 4; i++) - mei_reg_write(dev, H_CB_WW, reg_buf[i]); - - rem = length & 0x3; - if (rem > 0) { - u32 reg = 0; - memcpy(®, &buf[length - rem], rem); - mei_reg_write(dev, H_CB_WW, reg); - } - - dev->host_hw_state = mei_hcsr_read(dev); - dev->host_hw_state |= H_IG; - mei_hcsr_set(dev); - dev->me_hw_state = mei_mecsr_read(dev); - if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) - return -EIO; - - return 0; -} - -/** - * mei_count_full_read_slots - counts read full slots. - * - * @dev: the device structure - * - * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count - */ -int mei_count_full_read_slots(struct mei_device *dev) -{ - char read_ptr, write_ptr; - unsigned char buffer_depth, filled_slots; - - dev->me_hw_state = mei_mecsr_read(dev); - buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24); - read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8); - write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16); - filled_slots = (unsigned char) (write_ptr - read_ptr); - - /* check for overflow */ - if (filled_slots > buffer_depth) - return -EOVERFLOW; - - dev_dbg(&dev->pdev->dev, "filled_slots =%08x\n", filled_slots); - return (int)filled_slots; -} - -/** - * mei_read_slots - reads a message from mei device. - * - * @dev: the device structure - * @buffer: message buffer will be written - * @buffer_length: message size will be read - */ -void mei_read_slots(struct mei_device *dev, unsigned char *buffer, - unsigned long buffer_length) -{ - u32 *reg_buf = (u32 *)buffer; - - for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32)) - *reg_buf++ = mei_mecbrw_read(dev); - - if (buffer_length > 0) { - u32 reg = mei_mecbrw_read(dev); - memcpy(reg_buf, ®, buffer_length); - } - - dev->host_hw_state |= H_IG; - mei_hcsr_set(dev); -} - diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h deleted file mode 100644 index 73bef545e4d5..000000000000 --- a/drivers/misc/mei/interface.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - - - -#ifndef _MEI_INTERFACE_H_ -#define _MEI_INTERFACE_H_ - -#include -#include "mei_dev.h" - - - -void mei_read_slots(struct mei_device *dev, - unsigned char *buffer, - unsigned long buffer_length); - -int mei_write_message(struct mei_device *dev, - struct mei_msg_hdr *header, - unsigned char *buf); - -bool mei_hbuf_is_empty(struct mei_device *dev); - -int mei_hbuf_empty_slots(struct mei_device *dev); - -static inline size_t mei_hbuf_max_data(const struct mei_device *dev) -{ - return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr); -} - -/* get slots (dwords) from a message length + header (bytes) */ -static inline unsigned char mei_data2slots(size_t length) -{ - return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4); -} - -int mei_count_full_read_slots(struct mei_device *dev); - -#endif /* _MEI_INTERFACE_H_ */ diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 0a141afcea89..d1ef92617c19 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -25,7 +25,7 @@ #include "mei_dev.h" #include "hbm.h" -#include "interface.h" +#include "hw-me.h" #include "client.h" diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 8d3c134314c6..e31ade30086d 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -40,7 +40,7 @@ #include #include "mei_dev.h" -#include "interface.h" +#include "hw-me.h" #include "client.h" /* AMT device is a singleton on the platform */ diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index d41177b3fc69..87b1f6a1a1dd 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -23,7 +23,7 @@ #include #include "hw.h" -#include "hw-me.h" +#include "hw-me-regs.h" /* * watch dog definition diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 5ad5225ea2b9..bfcbcc8c028b 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -25,7 +25,7 @@ #include "mei_dev.h" #include "hbm.h" -#include "interface.h" +#include "hw-me.h" #include "client.h" static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; -- cgit v1.2.3 From 1a1aca42c989051dce34d49b4e04a25dafe01d74 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 8 Jan 2013 23:07:21 +0200 Subject: mei: rename remaining amthi strings to amthif the only real thing that left was mei_amthi_guid the rest was in the strings and comments Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 62 +++++++++++++++++++++++----------------------- drivers/misc/mei/client.c | 2 +- drivers/misc/mei/main.c | 6 ++--- drivers/misc/mei/mei_dev.h | 2 +- 4 files changed, 36 insertions(+), 36 deletions(-) (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index adc4120c91d3..64a9bfa5ad20 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -38,9 +38,9 @@ #include "hw-me.h" #include "client.h" -const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, - 0xa8, 0x46, 0xe0, 0xff, 0x65, - 0x81, 0x4c); +const uuid_le mei_amthif_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, + 0xac, 0xa8, 0x46, 0xe0, + 0xff, 0x65, 0x81, 0x4c); /** * mei_amthif_reset_params - initializes mei device iamthif @@ -73,9 +73,9 @@ void mei_amthif_host_init(struct mei_device *dev) mei_cl_init(&dev->iamthif_cl, dev); dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; - /* find ME amthi client */ + /* find ME amthif client */ i = mei_cl_link_me(&dev->iamthif_cl, - &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID); + &mei_amthif_guid, MEI_IAMTHIF_HOST_CLIENT_ID); if (i < 0) { dev_info(&dev->pdev->dev, "failed to find iamthif client.\n"); return; @@ -169,10 +169,10 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id); if (i < 0) { - dev_dbg(&dev->pdev->dev, "amthi client not found.\n"); + dev_dbg(&dev->pdev->dev, "amthif client not found.\n"); return -ENODEV; } - dev_dbg(&dev->pdev->dev, "checking amthi data\n"); + dev_dbg(&dev->pdev->dev, "checking amthif data\n"); cb = mei_amthif_find_read_list_entry(dev, file); /* Check for if we can block or not*/ @@ -180,7 +180,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, return -EAGAIN; - dev_dbg(&dev->pdev->dev, "waiting for amthi data\n"); + dev_dbg(&dev->pdev->dev, "waiting for amthif data\n"); while (cb == NULL) { /* unlock the Mutex */ mutex_unlock(&dev->device_lock); @@ -198,17 +198,17 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, } - dev_dbg(&dev->pdev->dev, "Got amthi data\n"); + dev_dbg(&dev->pdev->dev, "Got amthif data\n"); dev->iamthif_timer = 0; if (cb) { timeout = cb->read_time + mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); - dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n", + dev_dbg(&dev->pdev->dev, "amthif timeout = %lud\n", timeout); if (time_after(jiffies, timeout)) { - dev_dbg(&dev->pdev->dev, "amthi Time out\n"); + dev_dbg(&dev->pdev->dev, "amthif Time out\n"); /* 15 sec for the message has expired */ list_del(&cb->list); rets = -ETIMEDOUT; @@ -228,9 +228,9 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, * remove message from deletion list */ - dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n", + dev_dbg(&dev->pdev->dev, "amthif cb->response_buffer size - %d\n", cb->response_buffer.size); - dev_dbg(&dev->pdev->dev, "amthi cb->buf_idx - %lu\n", cb->buf_idx); + dev_dbg(&dev->pdev->dev, "amthif cb->buf_idx - %lu\n", cb->buf_idx); /* length is being turncated to PAGE_SIZE, however, * the buf_idx may point beyond */ @@ -246,7 +246,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, } } free: - dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n"); + dev_dbg(&dev->pdev->dev, "free amthif cb memory.\n"); *offset = 0; mei_io_cb_free(cb); out: @@ -270,7 +270,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) if (!dev || !cb) return -ENODEV; - dev_dbg(&dev->pdev->dev, "write data to amthi client.\n"); + dev_dbg(&dev->pdev->dev, "write data to amthif client.\n"); dev->iamthif_state = MEI_IAMTHIF_WRITING; dev->iamthif_current_cb = cb; @@ -309,12 +309,12 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) return -ENODEV; dev->iamthif_flow_control_pending = true; dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; - dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n"); + dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n"); dev->iamthif_current_cb = cb; dev->iamthif_file_object = cb->file_object; list_add_tail(&cb->list, &dev->write_waiting_list.list); } else { - dev_dbg(&dev->pdev->dev, "message does not complete, so add amthi cb to write list.\n"); + dev_dbg(&dev->pdev->dev, "message does not complete, so add amthif cb to write list.\n"); list_add_tail(&cb->list, &dev->write_list.list); } } else { @@ -383,7 +383,7 @@ void mei_amthif_run_next_cmd(struct mei_device *dev) dev->iamthif_timer = 0; dev->iamthif_file_object = NULL; - dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n"); + dev_dbg(&dev->pdev->dev, "complete amthif cmd_list cb.\n"); list_for_each_entry_safe(pos, next, &dev->amthif_cmd_list.list, list) { list_del(&pos->list); @@ -392,7 +392,7 @@ void mei_amthif_run_next_cmd(struct mei_device *dev) status = mei_amthif_send_cmd(dev, pos); if (status) { dev_dbg(&dev->pdev->dev, - "amthi write failed status = %d\n", + "amthif write failed status = %d\n", status); return; } @@ -412,7 +412,7 @@ unsigned int mei_amthif_poll(struct mei_device *dev, if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && dev->iamthif_file_object == file) { mask |= (POLLIN | POLLRDNORM); - dev_dbg(&dev->pdev->dev, "run next amthi cb\n"); + dev_dbg(&dev->pdev->dev, "run next amthif cb\n"); mei_amthif_run_next_cmd(dev); } return mask; @@ -478,7 +478,7 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; dev->iamthif_flow_control_pending = true; - /* save iamthif cb sent to amthi client */ + /* save iamthif cb sent to amthif client */ cb->buf_idx = dev->iamthif_msg_buf_index; dev->iamthif_current_cb = cb; @@ -491,11 +491,11 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, /** * mei_amthif_irq_read_message - read routine after ISR to - * handle the read amthi message + * handle the read amthif message * * @complete_list: An instance of our list structure * @dev: the device structure - * @mei_hdr: header of amthi message + * @mei_hdr: header of amthif message * * returns 0 on success, <0 on failure. */ @@ -519,10 +519,10 @@ int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list, return 0; dev_dbg(&dev->pdev->dev, - "amthi_message_buffer_index =%d\n", + "amthif_message_buffer_index =%d\n", mei_hdr->length); - dev_dbg(&dev->pdev->dev, "completed amthi read.\n "); + dev_dbg(&dev->pdev->dev, "completed amthif read.\n "); if (!dev->iamthif_current_cb) return -ENODEV; @@ -537,8 +537,8 @@ int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list, cb->read_time = jiffies; if (dev->iamthif_ioctl && cb->cl == &dev->iamthif_cl) { /* found the iamthif cb */ - dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n "); - dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n "); + dev_dbg(&dev->pdev->dev, "complete the amthif read cb.\n "); + dev_dbg(&dev->pdev->dev, "add the amthif read cb to complete.\n "); list_add_tail(&cb->list, &complete_list->list); } return 0; @@ -590,7 +590,7 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb) dev->iamthif_msg_buf, dev->iamthif_msg_buf_index); list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list); - dev_dbg(&dev->pdev->dev, "amthi read completed\n"); + dev_dbg(&dev->pdev->dev, "amthif read completed\n"); dev->iamthif_timer = jiffies; dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", dev->iamthif_timer); @@ -598,7 +598,7 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb) mei_amthif_run_next_cmd(dev); } - dev_dbg(&dev->pdev->dev, "completing amthi call back.\n"); + dev_dbg(&dev->pdev->dev, "completing amthif call back.\n"); wake_up_interruptible(&dev->iamthif_cl.wait); } @@ -704,11 +704,11 @@ int mei_amthif_release(struct mei_device *dev, struct file *file) if (dev->iamthif_file_object == file && dev->iamthif_state != MEI_IAMTHIF_IDLE) { - dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n", + dev_dbg(&dev->pdev->dev, "amthif canceled iamthif state %d\n", dev->iamthif_state); dev->iamthif_canceled = true; if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) { - dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n"); + dev_dbg(&dev->pdev->dev, "run next amthif iamthif cb\n"); mei_amthif_run_next_cmd(dev); } } diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 231eda2b09e1..8103d94facb8 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -345,7 +345,7 @@ void mei_host_client_init(struct work_struct *work) for (i = 0; i < dev->me_clients_num; i++) { client_props = &dev->me_clients[i].props; - if (!uuid_le_cmp(client_props->protocol_name, mei_amthi_guid)) + if (!uuid_le_cmp(client_props->protocol_name, mei_amthif_guid)) mei_amthif_host_init(dev); else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid)) mei_wd_host_init(dev); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 5c7c85505c91..d5d1a5957d5f 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -497,7 +497,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (rets) { dev_err(&dev->pdev->dev, - "amthi write failed with status = %d\n", rets); + "amthif write failed with status = %d\n", rets); goto err; } mutex_unlock(&dev->device_lock); @@ -611,10 +611,10 @@ static int mei_ioctl_connect_client(struct file *file, dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n", dev->me_clients[i].props.max_msg_length); - /* if we're connecting to amthi client then we will use the + /* if we're connecting to amthif client then we will use the * existing connection */ - if (uuid_le_cmp(data->in_client_uuid, mei_amthi_guid) == 0) { + if (uuid_le_cmp(data->in_client_uuid, mei_amthif_guid) == 0) { dev_dbg(&dev->pdev->dev, "FW Client is amthi\n"); if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { rets = -ENODEV; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 681c0ee7a5de..285e8e01d429 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -46,7 +46,7 @@ /* * AMTHI Client UUID */ -extern const uuid_le mei_amthi_guid; +extern const uuid_le mei_amthif_guid; /* * Watchdog Client UUID -- cgit v1.2.3 From 781d0d89224bbbc438c2c0360cfd4822bb35d280 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 8 Jan 2013 23:07:22 +0200 Subject: mei: normalize me host client linking routines In order we can use the same code pattern for in-kernel and user space host clients we replace mei_cl_link_to_me with mei_cl_link function. We then have to keep me client lookupout of the new link function. The unlinking cannot be yet symetric due to amthif connection handling Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 42 ++++++++++++++++++++++-------------- drivers/misc/mei/client.c | 53 ++++++++++++++++++++++++++-------------------- drivers/misc/mei/client.h | 2 +- drivers/misc/mei/init.c | 4 ++++ drivers/misc/mei/main.c | 27 ++++++++--------------- drivers/misc/mei/mei_dev.h | 10 ++++----- drivers/misc/mei/wd.c | 35 +++++++++++++++++++----------- 7 files changed, 98 insertions(+), 75 deletions(-) (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 64a9bfa5ad20..88e6aa0f6b4e 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -65,22 +65,22 @@ void mei_amthif_reset_params(struct mei_device *dev) * @dev: the device structure * */ -void mei_amthif_host_init(struct mei_device *dev) +int mei_amthif_host_init(struct mei_device *dev) { - int i; + struct mei_cl *cl = &dev->iamthif_cl; unsigned char *msg_buf; + int ret, i; - mei_cl_init(&dev->iamthif_cl, dev); - dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; + mei_cl_init(cl, dev); - /* find ME amthif client */ - i = mei_cl_link_me(&dev->iamthif_cl, - &mei_amthif_guid, MEI_IAMTHIF_HOST_CLIENT_ID); + i = mei_me_cl_by_uuid(dev, &mei_amthif_guid); if (i < 0) { - dev_info(&dev->pdev->dev, "failed to find iamthif client.\n"); - return; + dev_info(&dev->pdev->dev, "amthif: failed to find the client\n"); + return -ENOENT; } + cl->me_client_id = dev->me_clients[i].client_id; + /* Assign iamthif_mtu to the value received from ME */ dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length; @@ -94,19 +94,29 @@ void mei_amthif_host_init(struct mei_device *dev) msg_buf = kcalloc(dev->iamthif_mtu, sizeof(unsigned char), GFP_KERNEL); if (!msg_buf) { - dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n"); - return; + dev_err(&dev->pdev->dev, "amthif: memory allocation for ME message buffer failed.\n"); + return -ENOMEM; } dev->iamthif_msg_buf = msg_buf; - if (mei_hbm_cl_connect_req(dev, &dev->iamthif_cl)) { - dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n"); - dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; - dev->iamthif_cl.host_client_id = 0; + ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID); + + if (ret < 0) { + dev_err(&dev->pdev->dev, "amthif: failed link client\n"); + return -ENOENT; + } + + cl->state = MEI_FILE_CONNECTING; + + if (mei_hbm_cl_connect_req(dev, cl)) { + dev_dbg(&dev->pdev->dev, "amthif: Failed to connect to ME client\n"); + cl->state = MEI_FILE_DISCONNECTED; + cl->host_client_id = 0; } else { - dev->iamthif_cl.timer_count = MEI_CONNECT_TIMEOUT; + cl->timer_count = MEI_CONNECT_TIMEOUT; } + return 0; } /** diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 8103d94facb8..d566dd880eb0 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -258,54 +258,61 @@ struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl) return NULL; } - -/** - * mei_me_cl_link - create link between host and me clinet and add - * me_cl to the list - * - * @cl: link between me and host client assocated with opened file descriptor - * @uuid: uuid of ME client - * @client_id: id of the host client +/** mei_cl_link: allocte host id in the host map * - * returns ME client index if ME client + * @cl - host client + * @id - fixed host id or -1 for genereting one + * returns 0 on success * -EINVAL on incorrect values * -ENONET if client not found */ -int mei_cl_link_me(struct mei_cl *cl, const uuid_le *uuid, u8 host_cl_id) +int mei_cl_link(struct mei_cl *cl, int id) { struct mei_device *dev; - int i; - if (WARN_ON(!cl || !cl->dev || !uuid)) + if (WARN_ON(!cl || !cl->dev)) return -EINVAL; dev = cl->dev; - /* check for valid client id */ - i = mei_me_cl_by_uuid(dev, uuid); - if (i >= 0) { - cl->me_client_id = dev->me_clients[i].client_id; - cl->state = MEI_FILE_CONNECTING; - cl->host_client_id = host_cl_id; + /* If Id is not asigned get one*/ + if (id == MEI_HOST_CLIENT_ID_ANY) + id = find_first_zero_bit(dev->host_clients_map, + MEI_CLIENTS_MAX); - list_add_tail(&cl->link, &dev->file_list); - return (u8)i; + if (id >= MEI_CLIENTS_MAX) { + dev_err(&dev->pdev->dev, "id exceded %d", MEI_CLIENTS_MAX) ; + return -ENOENT; } - return -ENOENT; + dev->open_handle_count++; + + cl->host_client_id = id; + list_add_tail(&cl->link, &dev->file_list); + + set_bit(id, dev->host_clients_map); + + cl->state = MEI_FILE_INITIALIZING; + + dev_dbg(&dev->pdev->dev, "link cl host id = %d\n", cl->host_client_id); + return 0; } + /** * mei_cl_unlink - remove me_cl from the list * * @dev: the device structure - * @host_client_id: host client id to be removed */ int mei_cl_unlink(struct mei_cl *cl) { struct mei_device *dev; struct mei_cl *pos, *next; - if (WARN_ON(!cl || !cl->dev)) + /* don't shout on error exit path */ + if (!cl) + return 0; + + if (WARN_ON(!cl->dev)) return -EINVAL; dev = cl->dev; diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index 8dfd052dd0e6..240a1f321342 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -55,7 +55,7 @@ struct mei_cl *mei_cl_allocate(struct mei_device *dev); void mei_cl_init(struct mei_cl *cl, struct mei_device *dev); -int mei_cl_link_me(struct mei_cl *cl, const uuid_le *uuid, u8 host_cl_id); +int mei_cl_link(struct mei_cl *cl, int id); int mei_cl_unlink(struct mei_cl *cl); int mei_cl_flush_queues(struct mei_cl *cl); diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 636639fbfc0a..9e4011ef8508 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -242,7 +242,11 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) /* remove entry if already in list */ dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n"); mei_cl_unlink(&dev->wd_cl); + if (dev->open_handle_count > 0) + dev->open_handle_count--; mei_cl_unlink(&dev->iamthif_cl); + if (dev->open_handle_count > 0) + dev->open_handle_count--; mei_amthif_reset_params(dev); memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg)); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index d5d1a5957d5f..ec5fd7a0e289 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -103,7 +103,6 @@ static int mei_open(struct inode *inode, struct file *file) { struct mei_cl *cl; struct mei_device *dev; - unsigned long cl_id; int err; err = -ENODEV; @@ -133,24 +132,9 @@ static int mei_open(struct inode *inode, struct file *file) goto out_unlock; } - cl_id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX); - if (cl_id >= MEI_CLIENTS_MAX) { - dev_err(&dev->pdev->dev, "client_id exceded %d", - MEI_CLIENTS_MAX) ; + err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); + if (err) goto out_unlock; - } - - cl->host_client_id = cl_id; - - dev_dbg(&dev->pdev->dev, "client_id = %d\n", cl->host_client_id); - - dev->open_handle_count++; - - list_add_tail(&cl->link, &dev->file_list); - - set_bit(cl->host_client_id, dev->host_clients_map); - cl->state = MEI_FILE_INITIALIZING; - cl->sm_state = 0; file->private_data = cl; mutex_unlock(&dev->device_lock); @@ -209,6 +193,7 @@ static int mei_release(struct inode *inode, struct file *file) } mei_cl_unlink(cl); + /* free read cb */ cb = NULL; if (cl->read_cb) { @@ -991,7 +976,13 @@ static void mei_remove(struct pci_dev *pdev) /* remove entry if already in list */ dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n"); + + if (dev->open_handle_count > 0) + dev->open_handle_count--; mei_cl_unlink(&dev->wd_cl); + + if (dev->open_handle_count > 0) + dev->open_handle_count--; mei_cl_unlink(&dev->iamthif_cl); dev->iamthif_current_cb = NULL; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 285e8e01d429..dcd7a44a806e 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -67,16 +67,16 @@ extern const u8 mei_wd_state_independence_msg[3][4]; * Number of File descriptors/handles * that can be opened to the driver. * - * Limit to 253: 256 Total Clients + * Limit to 255: 256 Total Clients * minus internal client for MEI Bus Messags - * minus internal client for AMTHI - * minus internal client for Watchdog */ -#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 3) +#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1) /* * Internal Clients Number */ +#define MEI_HOST_CLIENT_ID_ANY (-1) +#define MEI_HBM_HOST_CLIENT_ID 0 /* not used, just for documentation */ #define MEI_WD_HOST_CLIENT_ID 1 #define MEI_IAMTHIF_HOST_CLIENT_ID 2 @@ -339,7 +339,7 @@ void mei_timer(struct work_struct *work); */ void mei_amthif_reset_params(struct mei_device *dev); -void mei_amthif_host_init(struct mei_device *dev); +int mei_amthif_host_init(struct mei_device *dev); int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb); diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index bfcbcc8c028b..77b3820380b0 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -64,30 +64,41 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) */ int mei_wd_host_init(struct mei_device *dev) { - int id; - mei_cl_init(&dev->wd_cl, dev); + struct mei_cl *cl = &dev->wd_cl; + int i; + int ret; + + mei_cl_init(cl, dev); - /* look for WD client and connect to it */ - dev->wd_cl.state = MEI_FILE_DISCONNECTED; dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT; dev->wd_state = MEI_WD_IDLE; - /* Connect WD ME client to the host client */ - id = mei_cl_link_me(&dev->wd_cl, - &mei_wd_guid, MEI_WD_HOST_CLIENT_ID); - if (id < 0) { + /* check for valid client id */ + i = mei_me_cl_by_uuid(dev, &mei_wd_guid); + if (i < 0) { dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); return -ENOENT; } - if (mei_hbm_cl_connect_req(dev, &dev->wd_cl)) { + cl->me_client_id = dev->me_clients[i].client_id; + + ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID); + + if (ret < 0) { + dev_info(&dev->pdev->dev, "wd: failed link client\n"); + return -ENOENT; + } + + cl->state = MEI_FILE_CONNECTING; + + if (mei_hbm_cl_connect_req(dev, cl)) { dev_err(&dev->pdev->dev, "wd: failed to connect to the client\n"); - dev->wd_cl.state = MEI_FILE_DISCONNECTED; - dev->wd_cl.host_client_id = 0; + cl->state = MEI_FILE_DISCONNECTED; + cl->host_client_id = 0; return -EIO; } - dev->wd_cl.timer_count = MEI_CONNECT_TIMEOUT; + cl->timer_count = MEI_CONNECT_TIMEOUT; return 0; } -- cgit v1.2.3 From 6222f7bf8d7e2b16ffcc14bcb2c32ea069aac9fa Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 8 Jan 2013 23:07:23 +0200 Subject: mei: move MEI_IAMTHIF_IDLE to amthif host init function Since the amthif state is not examined until amthif is connected we can safely move it to the amthif host init function Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 2 ++ drivers/misc/mei/init.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 88e6aa0f6b4e..7199e8369f1e 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -71,6 +71,8 @@ int mei_amthif_host_init(struct mei_device *dev) unsigned char *msg_buf; int ret, i; + dev->iamthif_state = MEI_IAMTHIF_IDLE; + mei_cl_init(cl, dev); i = mei_me_cl_by_uuid(dev, &mei_amthif_guid); diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 9e4011ef8508..70fad4ea474c 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -68,7 +68,6 @@ struct mei_device *mei_device_init(struct pci_dev *pdev) init_waitqueue_head(&dev->wait_recvd_msg); init_waitqueue_head(&dev->wait_stop_wd); dev->dev_state = MEI_DEV_INITIALIZING; - dev->iamthif_state = MEI_IAMTHIF_IDLE; mei_io_list_init(&dev->read_list); mei_io_list_init(&dev->write_list); -- cgit v1.2.3 From 827eef51f8dd9a4ab62b4ad270c15472f46938f2 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 6 Feb 2013 14:06:41 +0200 Subject: mei: separate compilation of the ME hardware specifics We add struct mei_hw_ops to virtualize access to hw specific configurations. This allows us to separate the compilation of the ME interface from the ME hardware specifics Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/Kconfig | 17 ++++-- drivers/misc/mei/Makefile | 6 +- drivers/misc/mei/amthif.c | 6 +- drivers/misc/mei/hw-me.c | 87 +++++++++++++++++++--------- drivers/misc/mei/hw-me.h | 19 ------- drivers/misc/mei/init.c | 2 +- drivers/misc/mei/interrupt.c | 10 ++-- drivers/misc/mei/main.c | 5 +- drivers/misc/mei/mei_dev.h | 132 +++++++++++++++++++++++++++++++++++++++---- 9 files changed, 210 insertions(+), 74 deletions(-) (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig index 5a79ccde2fdf..fa5c24982c88 100644 --- a/drivers/misc/mei/Kconfig +++ b/drivers/misc/mei/Kconfig @@ -1,11 +1,22 @@ config INTEL_MEI - tristate "Intel Management Engine Interface (Intel MEI)" - depends on X86 && PCI && WATCHDOG_CORE + tristate "Intel Management Engine Interface" + depends on X86 && PCI help The Intel Management Engine (Intel ME) provides Manageability, Security and Media services for system containing Intel chipsets. if selected /dev/mei misc device will be created. + For more information see + + +config INTEL_MEI_ME + bool "ME Enabled Intel Chipsets" + depends on INTEL_MEI + depends on X86 && PCI && WATCHDOG_CORE + default y + help + MEI support for ME Enabled Intel chipsets. + Supported Chipsets are: 7 Series Chipset Family 6 Series Chipset Family @@ -24,5 +35,3 @@ config INTEL_MEI 82Q33 Express 82X38/X48 Express - For more information see - diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile index 068f55354811..040af6c7b147 100644 --- a/drivers/misc/mei/Makefile +++ b/drivers/misc/mei/Makefile @@ -6,9 +6,9 @@ obj-$(CONFIG_INTEL_MEI) += mei.o mei-objs := init.o mei-objs += hbm.o mei-objs += interrupt.o -mei-objs += hw-me.o +mei-objs += client.o mei-objs += main.o mei-objs += amthif.o mei-objs += wd.o -mei-objs += client.o -mei-objs += pci-me.o +mei-$(CONFIG_INTEL_MEI_ME) += pci-me.o +mei-$(CONFIG_INTEL_MEI_ME) += hw-me.o diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 263ed4ccd6f2..a7c483850083 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -300,8 +300,8 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) if (ret && dev->mei_host_buffer_is_empty) { ret = 0; dev->mei_host_buffer_is_empty = false; - if (cb->request_buffer.size > mei_hbuf_max_data(dev)) { - mei_hdr.length = mei_hbuf_max_data(dev); + if (cb->request_buffer.size > mei_hbuf_max_len(dev)) { + mei_hdr.length = mei_hbuf_max_len(dev); mei_hdr.msg_complete = 0; } else { mei_hdr.length = cb->request_buffer.size; @@ -583,7 +583,7 @@ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots) dev->iamthif_msg_buf_index = 0; dev->iamthif_msg_buf_size = 0; dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER; - dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); + dev->mei_host_buffer_is_empty = mei_hbuf_is_ready(dev); return 0; } diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 3bdf22848a91..6300943497ae 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -56,7 +56,7 @@ static inline void mei_reg_write(const struct mei_me_hw *hw, * * returns ME_CB_RW register value (u32) */ -u32 mei_mecbrw_read(const struct mei_device *dev) +static u32 mei_me_mecbrw_read(const struct mei_device *dev) { return mei_reg_read(to_me_hw(dev), ME_CB_RW); } @@ -102,7 +102,7 @@ static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr) * * @dev: mei device */ -void mei_hw_config(struct mei_device *dev) +static void mei_me_hw_config(struct mei_device *dev) { u32 hcsr = mei_hcsr_read(to_me_hw(dev)); /* Doesn't change in runtime */ @@ -113,20 +113,19 @@ void mei_hw_config(struct mei_device *dev) * * @dev: the device structure */ -void mei_clear_interrupts(struct mei_device *dev) +static void mei_me_intr_clear(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); u32 hcsr = mei_hcsr_read(hw); if ((hcsr & H_IS) == H_IS) mei_reg_write(hw, H_CSR, hcsr); } - /** - * mei_enable_interrupts - enables mei device interrupts + * mei_me_intr_enable - enables mei device interrupts * * @dev: the device structure */ -void mei_enable_interrupts(struct mei_device *dev) +static void mei_me_intr_enable(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); u32 hcsr = mei_hcsr_read(hw); @@ -139,7 +138,7 @@ void mei_enable_interrupts(struct mei_device *dev) * * @dev: the device structure */ -void mei_disable_interrupts(struct mei_device *dev) +static void mei_me_intr_disable(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); u32 hcsr = mei_hcsr_read(hw); @@ -148,12 +147,12 @@ void mei_disable_interrupts(struct mei_device *dev) } /** - * mei_hw_reset - resets fw via mei csr register. + * mei_me_hw_reset - resets fw via mei csr register. * * @dev: the device structure * @interrupts_enabled: if interrupt should be enabled after reset. */ -void mei_hw_reset(struct mei_device *dev, bool intr_enable) +static void 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); @@ -180,25 +179,25 @@ void mei_hw_reset(struct mei_device *dev, bool intr_enable) } /** - * mei_host_set_ready - enable device + * mei_me_host_set_ready - enable device * * @dev - mei device * returns bool */ -void mei_host_set_ready(struct mei_device *dev) +static void mei_me_host_set_ready(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); hw->host_hw_state |= H_IE | H_IG | H_RDY; mei_hcsr_set(hw, hw->host_hw_state); } /** - * mei_host_is_ready - check whether the host has turned ready + * mei_me_host_is_ready - check whether the host has turned ready * * @dev - mei device * returns bool */ -bool mei_host_is_ready(struct mei_device *dev) +static bool mei_me_host_is_ready(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); hw->host_hw_state = mei_hcsr_read(hw); @@ -206,12 +205,12 @@ bool mei_host_is_ready(struct mei_device *dev) } /** - * mei_me_is_ready - check whether the me has turned ready + * mei_me_hw_is_ready - check whether the me(hw) has turned ready * * @dev - mei device * returns bool */ -bool mei_me_is_ready(struct mei_device *dev) +static bool mei_me_hw_is_ready(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); hw->me_hw_state = mei_mecsr_read(hw); @@ -268,19 +267,19 @@ static unsigned char mei_hbuf_filled_slots(struct mei_device *dev) * * returns true if empty, false - otherwise. */ -bool mei_hbuf_is_empty(struct mei_device *dev) +static bool mei_me_hbuf_is_empty(struct mei_device *dev) { return mei_hbuf_filled_slots(dev) == 0; } /** - * mei_hbuf_empty_slots - counts write empty slots. + * mei_me_hbuf_empty_slots - counts write empty slots. * * @dev: the device structure * * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count */ -int mei_hbuf_empty_slots(struct mei_device *dev) +static int mei_me_hbuf_empty_slots(struct mei_device *dev) { unsigned char filled_slots, empty_slots; @@ -294,6 +293,12 @@ int mei_hbuf_empty_slots(struct mei_device *dev) return empty_slots; } +static size_t mei_me_hbuf_max_len(const struct mei_device *dev) +{ + return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr); +} + + /** * mei_write_message - writes a message to mei device. * @@ -303,8 +308,9 @@ int mei_hbuf_empty_slots(struct mei_device *dev) * * This function returns -EIO if write has failed */ -int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, - unsigned char *buf) +static int mei_me_write_message(struct mei_device *dev, + struct mei_msg_hdr *header, + unsigned char *buf) { struct mei_me_hw *hw = to_me_hw(dev); unsigned long rem, dw_cnt; @@ -337,20 +343,20 @@ int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, hcsr = mei_hcsr_read(hw) | H_IG; mei_hcsr_set(hw, hcsr); - if (!mei_me_is_ready(dev)) + if (!mei_me_hw_is_ready(dev)) return -EIO; return 0; } /** - * mei_count_full_read_slots - counts read full slots. + * mei_me_count_full_read_slots - counts read full slots. * * @dev: the device structure * * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count */ -int mei_count_full_read_slots(struct mei_device *dev) +static int mei_me_count_full_read_slots(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); char read_ptr, write_ptr; @@ -371,13 +377,13 @@ int mei_count_full_read_slots(struct mei_device *dev) } /** - * mei_read_slots - reads a message from mei device. + * mei_me_read_slots - reads a message from mei device. * * @dev: the device structure * @buffer: message buffer will be written * @buffer_length: message size will be read */ -void mei_read_slots(struct mei_device *dev, unsigned char *buffer, +static int mei_me_read_slots(struct mei_device *dev, unsigned char *buffer, unsigned long buffer_length) { struct mei_me_hw *hw = to_me_hw(dev); @@ -385,17 +391,42 @@ void mei_read_slots(struct mei_device *dev, unsigned char *buffer, u32 hcsr; for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32)) - *reg_buf++ = mei_mecbrw_read(dev); + *reg_buf++ = mei_me_mecbrw_read(dev); if (buffer_length > 0) { - u32 reg = mei_mecbrw_read(dev); + u32 reg = mei_me_mecbrw_read(dev); memcpy(reg_buf, ®, buffer_length); } hcsr = mei_hcsr_read(hw) | H_IG; mei_hcsr_set(hw, hcsr); + return 0; } +static const struct mei_hw_ops mei_me_hw_ops = { + + .host_set_ready = mei_me_host_set_ready, + .host_is_ready = mei_me_host_is_ready, + + .hw_is_ready = mei_me_hw_is_ready, + .hw_reset = mei_me_hw_reset, + .hw_config = mei_me_hw_config, + + .intr_clear = mei_me_intr_clear, + .intr_enable = mei_me_intr_enable, + .intr_disable = mei_me_intr_disable, + + .hbuf_free_slots = mei_me_hbuf_empty_slots, + .hbuf_is_ready = mei_me_hbuf_is_empty, + .hbuf_max_len = mei_me_hbuf_max_len, + + .write = mei_me_write_message, + + .rdbuf_full_slots = mei_me_count_full_read_slots, + .read_hdr = mei_me_mecbrw_read, + .read = mei_me_read_slots +}; + /** * init_mei_device - allocates and initializes the mei device structure * @@ -422,6 +453,8 @@ struct mei_device *mei_me_dev_init(struct pci_dev *pdev) INIT_DELAYED_WORK(&dev->timer_work, mei_timer); INIT_WORK(&dev->init_work, mei_host_client_init); + dev->ops = &mei_me_hw_ops; + dev->pdev = pdev; return dev; } diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h index 53bcc0087e26..9a3aaab9bcf0 100644 --- a/drivers/misc/mei/hw-me.h +++ b/drivers/misc/mei/hw-me.h @@ -36,29 +36,10 @@ struct mei_me_hw { struct mei_device *mei_me_dev_init(struct pci_dev *pdev); -void mei_read_slots(struct mei_device *dev, - unsigned char *buffer, - unsigned long buffer_length); - -int mei_write_message(struct mei_device *dev, - struct mei_msg_hdr *header, - unsigned char *buf); - -bool mei_hbuf_is_empty(struct mei_device *dev); - -int mei_hbuf_empty_slots(struct mei_device *dev); - -static inline size_t mei_hbuf_max_data(const struct mei_device *dev) -{ - return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr); -} - /* get slots (dwords) from a message length + header (bytes) */ static inline unsigned char mei_data2slots(size_t length) { return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4); } -int mei_count_full_read_slots(struct mei_device *dev); - #endif /* _MEI_INTERFACE_H_ */ diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 1e1876ff25b1..51a005e80952 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -104,7 +104,7 @@ int mei_hw_init(struct mei_device *dev) goto err; } - if (!mei_me_is_ready(dev)) { + if (!mei_hw_is_ready(dev)) { dev_err(&dev->pdev->dev, "ME is not ready.\n"); goto err; } diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index b04ed9bdf758..431aa91fd002 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -329,7 +329,7 @@ static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list, int ret = 0; if (!dev->rd_msg_hdr) { - dev->rd_msg_hdr = mei_mecbrw_read(dev); + dev->rd_msg_hdr = mei_read_hdr(dev); dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); (*slots)--; dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); @@ -430,7 +430,7 @@ static int mei_irq_thread_write_handler(struct mei_device *dev, s32 slots; int ret; - if (!mei_hbuf_is_empty(dev)) { + if (!mei_hbuf_is_ready(dev)) { dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); return 0; } @@ -698,7 +698,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) mei_clear_interrupts(dev); /* check if ME wants a reset */ - if (!mei_me_is_ready(dev) && + if (!mei_hw_is_ready(dev) && dev->dev_state != MEI_DEV_RESETING && dev->dev_state != MEI_DEV_INITIALIZING) { dev_dbg(&dev->pdev->dev, "FW not ready.\n"); @@ -709,7 +709,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) /* check if we need to start the dev */ if (!mei_host_is_ready(dev)) { - if (mei_me_is_ready(dev)) { + if (mei_hw_is_ready(dev)) { dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); mei_host_set_ready(dev); @@ -743,7 +743,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) rets = mei_irq_thread_write_handler(dev, &complete_list); end: dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); - dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); + dev->mei_host_buffer_is_empty = mei_hbuf_is_ready(dev); bus_message_received = false; if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 018623c9a8e1..843ae2febc70 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -462,8 +462,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, } dev->mei_host_buffer_is_empty = false; - if (length > mei_hbuf_max_data(dev)) { - mei_hdr.length = mei_hbuf_max_data(dev); + 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; @@ -765,4 +765,5 @@ void mei_deregister(void) mei_misc_device.parent = NULL; } +MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index bb759fd9ee4a..c974292f16d6 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -211,6 +211,58 @@ struct mei_cl { struct mei_cl_cb *read_cb; }; +/** struct mei_hw_ops + * + * @host_set_ready - notify FW that host side is ready + * @host_is_ready - query for host readiness + + * @hw_is_ready - query if hw is ready + * @hw_reset - reset hw + * @hw_config - configure hw + + * @intr_clear - clear pending interrupts + * @intr_enable - enable interrupts + * @intr_disable - disable interrupts + + * @hbuf_free_slots - query for write buffer empty slots + * @hbuf_is_ready - query if write buffer is empty + * @hbuf_max_len - query for write buffer max len + + * @write - write a message to FW + + * @rdbuf_full_slots - query how many slots are filled + + * @read_hdr - get first 4 bytes (header) + * @read - read a buffer from the FW + */ +struct mei_hw_ops { + + void (*host_set_ready) (struct mei_device *dev); + 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); + void (*hw_config) (struct mei_device *dev); + + void (*intr_clear) (struct mei_device *dev); + void (*intr_enable) (struct mei_device *dev); + void (*intr_disable) (struct mei_device *dev); + + int (*hbuf_free_slots) (struct mei_device *dev); + bool (*hbuf_is_ready) (struct mei_device *dev); + size_t (*hbuf_max_len) (const struct mei_device *dev); + + int (*write)(struct mei_device *dev, + struct mei_msg_hdr *hdr, + unsigned char *buf); + + int (*rdbuf_full_slots)(struct mei_device *dev); + + u32 (*read_hdr)(const struct mei_device *dev); + int (*read) (struct mei_device *dev, + unsigned char *buf, unsigned long len); +}; + /** * struct mei_device - MEI private device struct * @mem_addr - mem mapped base register address @@ -306,6 +358,8 @@ struct mei_device { bool iamthif_canceled; struct work_struct init_work; + + const struct mei_hw_ops *ops; char hw[0] __aligned(sizeof(void *)); }; @@ -376,26 +430,84 @@ void mei_watchdog_register(struct mei_device *dev); */ void mei_watchdog_unregister(struct mei_device *dev); - /* * Register Access Function */ -void mei_hw_config(struct mei_device *dev); -void mei_hw_reset(struct mei_device *dev, bool intr_enable); -u32 mei_mecbrw_read(const struct mei_device *dev); +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) +{ + dev->ops->hw_reset(dev, enable); +} + +static inline void mei_clear_interrupts(struct mei_device *dev) +{ + dev->ops->intr_clear(dev); +} + +static inline void mei_enable_interrupts(struct mei_device *dev) +{ + dev->ops->intr_enable(dev); +} +static inline void mei_disable_interrupts(struct mei_device *dev) +{ + dev->ops->intr_disable(dev); +} +static inline void mei_host_set_ready(struct mei_device *dev) +{ + dev->ops->host_set_ready(dev); +} +static inline bool mei_host_is_ready(struct mei_device *dev) +{ + return dev->ops->host_is_ready(dev); +} +static inline bool mei_hw_is_ready(struct mei_device *dev) +{ + return dev->ops->hw_is_ready(dev); +} -void mei_clear_interrupts(struct mei_device *dev); -void mei_enable_interrupts(struct mei_device *dev); -void mei_disable_interrupts(struct mei_device *dev); +static inline bool mei_hbuf_is_ready(struct mei_device *dev) +{ + return dev->ops->hbuf_is_ready(dev); +} -void mei_host_set_ready(struct mei_device *dev); -bool mei_host_is_ready(struct mei_device *dev); -bool mei_me_is_ready(struct mei_device *dev); +static inline int mei_hbuf_empty_slots(struct mei_device *dev) +{ + return dev->ops->hbuf_free_slots(dev); +} +static inline size_t mei_hbuf_max_len(const struct mei_device *dev) +{ + return dev->ops->hbuf_max_len(dev); +} +static inline int mei_write_message(struct mei_device *dev, + struct mei_msg_hdr *hdr, + unsigned char *buf) +{ + return dev->ops->write(dev, hdr, buf); +} + +static inline u32 mei_read_hdr(const struct mei_device *dev) +{ + return dev->ops->read_hdr(dev); +} + +static inline void mei_read_slots(struct mei_device *dev, + unsigned char *buf, unsigned long len) +{ + dev->ops->read(dev, buf, len); +} + +static inline int mei_count_full_read_slots(struct mei_device *dev) +{ + return dev->ops->rdbuf_full_slots(dev); +} int mei_register(struct device *dev); void mei_deregister(void); -- cgit v1.2.3 From 330dd7da5ec80e2c49c66bf353d8b4fa4fb8f5a9 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 6 Feb 2013 14:06:43 +0200 Subject: mei: rename to mei_host_buffer_is_empty to hbuf_is_ready we rename the mei_host_buffer_is_empty to keep naming convention of hbuf and also make the query more generic to be correct also for other under laying hardware Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 8 ++++---- drivers/misc/mei/client.c | 13 ++++++------- drivers/misc/mei/hw-me.c | 2 +- drivers/misc/mei/main.c | 4 ++-- drivers/misc/mei/mei_dev.h | 14 ++++++++++---- drivers/misc/mei/wd.c | 9 ++++----- 6 files changed, 27 insertions(+), 23 deletions(-) (limited to 'drivers/misc/mei/amthif.c') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index a7c483850083..c86d7e3839a4 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -297,9 +297,9 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) if (ret < 0) return ret; - if (ret && dev->mei_host_buffer_is_empty) { + if (ret && dev->hbuf_is_ready) { ret = 0; - dev->mei_host_buffer_is_empty = false; + dev->hbuf_is_ready = false; if (cb->request_buffer.size > mei_hbuf_max_len(dev)) { mei_hdr.length = mei_hbuf_max_len(dev); mei_hdr.msg_complete = 0; @@ -330,7 +330,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) list_add_tail(&cb->list, &dev->write_list.list); } } else { - if (!(dev->mei_host_buffer_is_empty)) + if (!dev->hbuf_is_ready) dev_dbg(&dev->pdev->dev, "host buffer is not empty"); dev_dbg(&dev->pdev->dev, "No flow control credentials, so add iamthif cb to write list.\n"); @@ -583,7 +583,7 @@ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots) dev->iamthif_msg_buf_index = 0; dev->iamthif_msg_buf_size = 0; dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER; - dev->mei_host_buffer_is_empty = mei_hbuf_is_ready(dev); + dev->hbuf_is_ready = mei_hbuf_is_ready(dev); return 0; } diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index a921001053ba..e46663ee76de 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -393,8 +393,8 @@ int mei_cl_disconnect(struct mei_cl *cl) return -ENOMEM; cb->fop_type = MEI_FOP_CLOSE; - if (dev->mei_host_buffer_is_empty) { - dev->mei_host_buffer_is_empty = false; + if (dev->hbuf_is_ready) { + dev->hbuf_is_ready = false; if (mei_hbm_cl_disconnect_req(dev, cl)) { rets = -ENODEV; dev_err(&dev->pdev->dev, "failed to disconnect.\n"); @@ -496,9 +496,8 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) cb->fop_type = MEI_FOP_IOCTL; - if (dev->mei_host_buffer_is_empty && - !mei_cl_is_other_connecting(cl)) { - dev->mei_host_buffer_is_empty = false; + if (dev->hbuf_is_ready && !mei_cl_is_other_connecting(cl)) { + dev->hbuf_is_ready = false; if (mei_hbm_cl_connect_req(dev, cl)) { rets = -ENODEV; @@ -661,8 +660,8 @@ int mei_cl_read_start(struct mei_cl *cl) cb->fop_type = MEI_FOP_READ; cl->read_cb = cb; - if (dev->mei_host_buffer_is_empty) { - dev->mei_host_buffer_is_empty = false; + if (dev->hbuf_is_ready) { + dev->hbuf_is_ready = false; if (mei_hbm_cl_flow_control_req(dev, cl)) { rets = -ENODEV; goto err; diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 3bebf8d85ff9..45ea7185c003 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -486,7 +486,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) rets = mei_irq_write_handler(dev, &complete_list); end: dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); - dev->mei_host_buffer_is_empty = mei_hbuf_is_ready(dev); + dev->hbuf_is_ready = mei_hbuf_is_ready(dev); bus_message_received = false; if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 843ae2febc70..903f809b21f7 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -454,14 +454,14 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (rets < 0) goto err; - if (rets == 0 || dev->mei_host_buffer_is_empty == false) { + 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->mei_host_buffer_is_empty = false; + 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; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 7d07cef75664..cb80166161f0 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -265,9 +265,13 @@ struct mei_hw_ops { /** * struct mei_device - MEI private device struct + * @mem_addr - mem mapped base register address - * @hbuf_depth - depth of host(write) buffer - * @wr_ext_msg - buffer for hbm control responses (set in read cycle) + + * @hbuf_depth - depth of hardware host/write buffer is slots + * @hbuf_is_ready - query if the host host/write buffer is ready + * @wr_msg - the buffer for hbm control messages + * @wr_ext_msg - the buffer for hbm control responses (set in read cycle) */ struct mei_device { struct pci_dev *pdev; /* pointer to pci device struct */ @@ -294,7 +298,6 @@ struct mei_device { struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */ bool recvd_msg; - u8 hbuf_depth; /* * waiting queue for receive message from FW */ @@ -311,6 +314,10 @@ struct mei_device { unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ u32 rd_msg_hdr; + /* write buffer */ + u8 hbuf_depth; + bool hbuf_is_ready; + /* used for control messages */ struct { struct mei_msg_hdr hdr; @@ -330,7 +337,6 @@ struct mei_device { u8 me_clients_num; u8 me_client_presentation_num; u8 me_client_index; - bool mei_host_buffer_is_empty; struct mei_cl wd_cl; enum mei_wd_states wd_state; diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 77b3820380b0..2413247fc392 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -157,9 +157,9 @@ int mei_wd_stop(struct mei_device *dev) if (ret < 0) goto out; - if (ret && dev->mei_host_buffer_is_empty) { + if (ret && dev->hbuf_is_ready) { ret = 0; - dev->mei_host_buffer_is_empty = false; + dev->hbuf_is_ready = false; if (!mei_wd_send(dev)) { ret = mei_cl_flow_ctrl_reduce(&dev->wd_cl); @@ -282,10 +282,9 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) dev->wd_state = MEI_WD_RUNNING; /* Check if we can send the ping to HW*/ - if (dev->mei_host_buffer_is_empty && - mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) { + if (dev->hbuf_is_ready && mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) { - dev->mei_host_buffer_is_empty = false; + dev->hbuf_is_ready = false; dev_dbg(&dev->pdev->dev, "wd: sending ping\n"); if (mei_wd_send(dev)) { -- cgit v1.2.3