diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2015-02-10 08:39:41 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-03-02 03:37:00 (GMT) |
commit | 331e4187017e5dc12fddfcca3f8041e5610ea23b (patch) | |
tree | 285f81afe13626373cb7c73726ee01a43df12169 /drivers/misc/mei | |
parent | 8660172e1d6528be02eba78516ff8282e694bb26 (diff) | |
download | linux-331e4187017e5dc12fddfcca3f8041e5610ea23b.tar.xz |
mei: iamthif: use regular client read functions
Reduce code duplication in amthif by reusing
regular client read functions.
The change also removes the need for amthif
own buffering
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r-- | drivers/misc/mei/amthif.c | 71 | ||||
-rw-r--r-- | drivers/misc/mei/client.h | 2 | ||||
-rw-r--r-- | drivers/misc/mei/interrupt.c | 37 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 6 |
4 files changed, 35 insertions, 81 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 916625a..4060e2f 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -49,8 +49,6 @@ void mei_amthif_reset_params(struct mei_device *dev) { /* reset iamthif parameters. */ dev->iamthif_current_cb = NULL; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; dev->iamthif_canceled = false; dev->iamthif_state = MEI_IAMTHIF_IDLE; dev->iamthif_timer = 0; @@ -69,7 +67,6 @@ int mei_amthif_host_init(struct mei_device *dev) { struct mei_cl *cl = &dev->iamthif_cl; struct mei_me_client *me_cl; - unsigned char *msg_buf; int ret; dev->iamthif_state = MEI_IAMTHIF_IDLE; @@ -90,18 +87,6 @@ int mei_amthif_host_init(struct mei_device *dev) dev->iamthif_mtu = me_cl->props.max_msg_length; dev_dbg(dev->dev, "IAMTHIF_MTU = %d\n", dev->iamthif_mtu); - kfree(dev->iamthif_msg_buf); - dev->iamthif_msg_buf = NULL; - - /* allocate storage for ME message buffer */ - msg_buf = kcalloc(dev->iamthif_mtu, - sizeof(unsigned char), GFP_KERNEL); - if (!msg_buf) { - ret = -ENOMEM; - goto out; - } - - dev->iamthif_msg_buf = msg_buf; ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID); if (ret < 0) { @@ -282,9 +267,6 @@ static int mei_amthif_read_start(struct mei_cl *cl, struct file *file) cb->fop_type = MEI_FOP_READ; list_add_tail(&cb->list, &dev->ctrl_wr_list.list); - dev->iamthif_msg_buf_index = 0; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_state = MEI_IAMTHIF_READING; dev->iamthif_file_object = cb->file_object; dev->iamthif_current_cb = cb; @@ -340,8 +322,6 @@ int mei_amthif_run_next_cmd(struct mei_device *dev) struct mei_cl *cl = &dev->iamthif_cl; struct mei_cl_cb *cb; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; dev->iamthif_canceled = false; dev->iamthif_state = MEI_IAMTHIF_IDLE; dev->iamthif_timer = 0; @@ -440,67 +420,34 @@ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, * * @cl: mei client * @mei_hdr: header of amthif message - * @complete_list: completed callbacks list + * @cmpl_list: completed callbacks list * - * Return: Always 0; error message is in cb->status + * Return: -ENODEV if cb is NULL 0 otherwise; error message is in cb->status */ int mei_amthif_irq_read_msg(struct mei_cl *cl, struct mei_msg_hdr *mei_hdr, - struct mei_cl_cb *complete_list) + struct mei_cl_cb *cmpl_list) { struct mei_device *dev; - struct mei_cl_cb *cb; - unsigned char *buffer; + int ret; dev = cl->dev; - if (cl->state != MEI_FILE_CONNECTED) - goto err; - if (dev->iamthif_state != MEI_IAMTHIF_READING) - goto err; - - list_for_each_entry(cb, &dev->read_list.list, list) { - if (cl == cb->cl) - break; - } - - if (&cb->list == &dev->read_list.list) { - dev_err(dev->dev, "no reader found\n"); - goto err; - } - - if (dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length) { - cb->status = -ERANGE; - goto err; - } - - buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index; - mei_read_slots(dev, buffer, mei_hdr->length); + return 0; - dev->iamthif_msg_buf_index += mei_hdr->length; + ret = mei_cl_irq_read_msg(cl, mei_hdr, cmpl_list); + if (ret) + return ret; if (!mei_hdr->msg_complete) return 0; dev_dbg(dev->dev, "completed amthif read.\n "); - dev->iamthif_current_cb = NULL; - dev->iamthif_stall_timer = 0; - cb->buf_idx = dev->iamthif_msg_buf_index; - cb->read_time = jiffies; - - dev_dbg(dev->dev, "complete the amthif read cb.\n "); - list_move_tail(&cb->list, &complete_list->list); return 0; - -err: - mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); - dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n", - MEI_HDR_PRM(mei_hdr)); - return 0; } /** @@ -530,8 +477,6 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb) if (dev->iamthif_canceled != 1) { dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE; dev->iamthif_stall_timer = 0; - memcpy(cb->response_buffer.data, - dev->iamthif_msg_buf, dev->iamthif_msg_buf_index); list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list); dev_dbg(dev->dev, "amthif read completed\n"); dev->iamthif_timer = jiffies; diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index 80386f9..21cf626 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -102,6 +102,8 @@ bool mei_cl_is_other_connecting(struct mei_cl *cl); int mei_cl_disconnect(struct mei_cl *cl); int mei_cl_connect(struct mei_cl *cl, struct file *file); int mei_cl_read_start(struct mei_cl *cl, size_t length); +int mei_cl_irq_read_msg(struct mei_cl *cl, struct mei_msg_hdr *hdr, + struct mei_cl_cb *cmpl_list); int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking); int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 89f2fbc..466c1d2 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -82,6 +82,24 @@ static bool mei_cl_is_reading(struct mei_cl *cl) } /** + * mei_irq_discard_msg - discard received message + * + * @dev: mei device + * @hdr: message header + */ +static inline +void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr) +{ + /* + * no need to check for size as it is guarantied + * that length fits into rd_msg_buf + */ + mei_read_slots(dev, dev->rd_msg_buf, hdr->length); + dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n", + MEI_HDR_PRM(hdr)); +} + +/** * mei_cl_irq_read_msg - process client message * * @cl: reading client @@ -90,9 +108,9 @@ static bool mei_cl_is_reading(struct mei_cl *cl) * * Return: always 0 */ -static int mei_cl_irq_read_msg(struct mei_cl *cl, - struct mei_msg_hdr *mei_hdr, - struct mei_cl_cb *complete_list) +int mei_cl_irq_read_msg(struct mei_cl *cl, + struct mei_msg_hdr *mei_hdr, + struct mei_cl_cb *complete_list) { struct mei_device *dev = cl->dev; struct mei_cl_cb *cb; @@ -144,20 +162,17 @@ static int mei_cl_irq_read_msg(struct mei_cl *cl, mei_read_slots(dev, buffer, mei_hdr->length); cb->buf_idx += mei_hdr->length; + if (mei_hdr->msg_complete) { + cb->read_time = jiffies; cl_dbg(dev, cl, "completed read length = %lu\n", cb->buf_idx); list_move_tail(&cb->list, &complete_list->list); } out: - if (!buffer) { - /* assume that mei_hdr->length <= MEI_RD_MSG_BUF_SIZE */ - BUG_ON(mei_hdr->length > MEI_RD_MSG_BUF_SIZE); - mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); - dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n", - MEI_HDR_PRM(mei_hdr)); - } + if (!buffer) + mei_irq_discard_msg(dev, mei_hdr); return 0; } @@ -569,8 +584,6 @@ void mei_timer(struct work_struct *work) if (--dev->iamthif_stall_timer == 0) { dev_err(dev->dev, "timer: amthif hanged.\n"); mei_reset(dev); - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; dev->iamthif_canceled = false; dev->iamthif_state = MEI_IAMTHIF_IDLE; dev->iamthif_timer = 0; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 2f2242f..57a47d6 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -485,9 +485,6 @@ const char *mei_pg_state_str(enum mei_pg_state state); * @iamthif_mtu : amthif client max message length * @iamthif_timer : time stamp of current amthif command completion * @iamthif_stall_timer : timer to detect amthif hang - * @iamthif_msg_buf : amthif current message buffer - * @iamthif_msg_buf_size : size of current amthif message request buffer - * @iamthif_msg_buf_index : current index in amthif message request buffer * @iamthif_state : amthif processor state * @iamthif_canceled : current amthif command is canceled * @@ -583,9 +580,6 @@ struct mei_device { int iamthif_mtu; unsigned long iamthif_timer; u32 iamthif_stall_timer; - unsigned char *iamthif_msg_buf; /* Note: memory has to be allocated */ - u32 iamthif_msg_buf_size; - u32 iamthif_msg_buf_index; enum iamthif_states iamthif_state; bool iamthif_canceled; |