{
/* 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;
{
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;
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) {
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;
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;
*
* @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;
}
/**
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;
cl->reading_state != MEI_READ_COMPLETE;
}
+/**
+ * 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
*
*
* 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;
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;
}
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;