aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/mei/amthif.c71
-rw-r--r--drivers/misc/mei/client.h2
-rw-r--r--drivers/misc/mei/interrupt.c37
-rw-r--r--drivers/misc/mei/mei_dev.h6
4 files changed, 35 insertions, 81 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 916625a8f037..4060e2f40286 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)
49{ 49{
50 /* reset iamthif parameters. */ 50 /* reset iamthif parameters. */
51 dev->iamthif_current_cb = NULL; 51 dev->iamthif_current_cb = NULL;
52 dev->iamthif_msg_buf_size = 0;
53 dev->iamthif_msg_buf_index = 0;
54 dev->iamthif_canceled = false; 52 dev->iamthif_canceled = false;
55 dev->iamthif_state = MEI_IAMTHIF_IDLE; 53 dev->iamthif_state = MEI_IAMTHIF_IDLE;
56 dev->iamthif_timer = 0; 54 dev->iamthif_timer = 0;
@@ -69,7 +67,6 @@ int mei_amthif_host_init(struct mei_device *dev)
69{ 67{
70 struct mei_cl *cl = &dev->iamthif_cl; 68 struct mei_cl *cl = &dev->iamthif_cl;
71 struct mei_me_client *me_cl; 69 struct mei_me_client *me_cl;
72 unsigned char *msg_buf;
73 int ret; 70 int ret;
74 71
75 dev->iamthif_state = MEI_IAMTHIF_IDLE; 72 dev->iamthif_state = MEI_IAMTHIF_IDLE;
@@ -90,18 +87,6 @@ int mei_amthif_host_init(struct mei_device *dev)
90 dev->iamthif_mtu = me_cl->props.max_msg_length; 87 dev->iamthif_mtu = me_cl->props.max_msg_length;
91 dev_dbg(dev->dev, "IAMTHIF_MTU = %d\n", dev->iamthif_mtu); 88 dev_dbg(dev->dev, "IAMTHIF_MTU = %d\n", dev->iamthif_mtu);
92 89
93 kfree(dev->iamthif_msg_buf);
94 dev->iamthif_msg_buf = NULL;
95
96 /* allocate storage for ME message buffer */
97 msg_buf = kcalloc(dev->iamthif_mtu,
98 sizeof(unsigned char), GFP_KERNEL);
99 if (!msg_buf) {
100 ret = -ENOMEM;
101 goto out;
102 }
103
104 dev->iamthif_msg_buf = msg_buf;
105 90
106 ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID); 91 ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID);
107 if (ret < 0) { 92 if (ret < 0) {
@@ -282,9 +267,6 @@ static int mei_amthif_read_start(struct mei_cl *cl, struct file *file)
282 cb->fop_type = MEI_FOP_READ; 267 cb->fop_type = MEI_FOP_READ;
283 list_add_tail(&cb->list, &dev->ctrl_wr_list.list); 268 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
284 269
285 dev->iamthif_msg_buf_index = 0;
286 dev->iamthif_msg_buf_size = 0;
287
288 dev->iamthif_state = MEI_IAMTHIF_READING; 270 dev->iamthif_state = MEI_IAMTHIF_READING;
289 dev->iamthif_file_object = cb->file_object; 271 dev->iamthif_file_object = cb->file_object;
290 dev->iamthif_current_cb = cb; 272 dev->iamthif_current_cb = cb;
@@ -340,8 +322,6 @@ int mei_amthif_run_next_cmd(struct mei_device *dev)
340 struct mei_cl *cl = &dev->iamthif_cl; 322 struct mei_cl *cl = &dev->iamthif_cl;
341 struct mei_cl_cb *cb; 323 struct mei_cl_cb *cb;
342 324
343 dev->iamthif_msg_buf_size = 0;
344 dev->iamthif_msg_buf_index = 0;
345 dev->iamthif_canceled = false; 325 dev->iamthif_canceled = false;
346 dev->iamthif_state = MEI_IAMTHIF_IDLE; 326 dev->iamthif_state = MEI_IAMTHIF_IDLE;
347 dev->iamthif_timer = 0; 327 dev->iamthif_timer = 0;
@@ -440,67 +420,34 @@ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
440 * 420 *
441 * @cl: mei client 421 * @cl: mei client
442 * @mei_hdr: header of amthif message 422 * @mei_hdr: header of amthif message
443 * @complete_list: completed callbacks list 423 * @cmpl_list: completed callbacks list
444 * 424 *
445 * Return: Always 0; error message is in cb->status 425 * Return: -ENODEV if cb is NULL 0 otherwise; error message is in cb->status
446 */ 426 */
447int mei_amthif_irq_read_msg(struct mei_cl *cl, 427int mei_amthif_irq_read_msg(struct mei_cl *cl,
448 struct mei_msg_hdr *mei_hdr, 428 struct mei_msg_hdr *mei_hdr,
449 struct mei_cl_cb *complete_list) 429 struct mei_cl_cb *cmpl_list)
450{ 430{
451 struct mei_device *dev; 431 struct mei_device *dev;
452 struct mei_cl_cb *cb; 432 int ret;
453 unsigned char *buffer;
454 433
455 dev = cl->dev; 434 dev = cl->dev;
456 435
457 if (cl->state != MEI_FILE_CONNECTED)
458 goto err;
459
460 if (dev->iamthif_state != MEI_IAMTHIF_READING) 436 if (dev->iamthif_state != MEI_IAMTHIF_READING)
461 goto err; 437 return 0;
462
463 list_for_each_entry(cb, &dev->read_list.list, list) {
464 if (cl == cb->cl)
465 break;
466 }
467
468 if (&cb->list == &dev->read_list.list) {
469 dev_err(dev->dev, "no reader found\n");
470 goto err;
471 }
472
473 if (dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length) {
474 cb->status = -ERANGE;
475 goto err;
476 }
477
478 buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index;
479 mei_read_slots(dev, buffer, mei_hdr->length);
480 438
481 dev->iamthif_msg_buf_index += mei_hdr->length; 439 ret = mei_cl_irq_read_msg(cl, mei_hdr, cmpl_list);
440 if (ret)
441 return ret;
482 442
483 if (!mei_hdr->msg_complete) 443 if (!mei_hdr->msg_complete)
484 return 0; 444 return 0;
485 445
486 dev_dbg(dev->dev, "completed amthif read.\n "); 446 dev_dbg(dev->dev, "completed amthif read.\n ");
487
488 dev->iamthif_current_cb = NULL; 447 dev->iamthif_current_cb = NULL;
489
490 dev->iamthif_stall_timer = 0; 448 dev->iamthif_stall_timer = 0;
491 cb->buf_idx = dev->iamthif_msg_buf_index;
492 cb->read_time = jiffies;
493
494 dev_dbg(dev->dev, "complete the amthif read cb.\n ");
495 list_move_tail(&cb->list, &complete_list->list);
496 449
497 return 0; 450 return 0;
498
499err:
500 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
501 dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n",
502 MEI_HDR_PRM(mei_hdr));
503 return 0;
504} 451}
505 452
506/** 453/**
@@ -530,8 +477,6 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
530 if (dev->iamthif_canceled != 1) { 477 if (dev->iamthif_canceled != 1) {
531 dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE; 478 dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE;
532 dev->iamthif_stall_timer = 0; 479 dev->iamthif_stall_timer = 0;
533 memcpy(cb->response_buffer.data,
534 dev->iamthif_msg_buf, dev->iamthif_msg_buf_index);
535 list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list); 480 list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list);
536 dev_dbg(dev->dev, "amthif read completed\n"); 481 dev_dbg(dev->dev, "amthif read completed\n");
537 dev->iamthif_timer = jiffies; 482 dev->iamthif_timer = jiffies;
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index 80386f9c27e9..21cf626e8908 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);
102int mei_cl_disconnect(struct mei_cl *cl); 102int mei_cl_disconnect(struct mei_cl *cl);
103int mei_cl_connect(struct mei_cl *cl, struct file *file); 103int mei_cl_connect(struct mei_cl *cl, struct file *file);
104int mei_cl_read_start(struct mei_cl *cl, size_t length); 104int mei_cl_read_start(struct mei_cl *cl, size_t length);
105int mei_cl_irq_read_msg(struct mei_cl *cl, struct mei_msg_hdr *hdr,
106 struct mei_cl_cb *cmpl_list);
105int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking); 107int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
106int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, 108int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
107 struct mei_cl_cb *cmpl_list); 109 struct mei_cl_cb *cmpl_list);
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 89f2fbce160f..466c1d22fb16 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)
82} 82}
83 83
84/** 84/**
85 * mei_irq_discard_msg - discard received message
86 *
87 * @dev: mei device
88 * @hdr: message header
89 */
90static inline
91void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr)
92{
93 /*
94 * no need to check for size as it is guarantied
95 * that length fits into rd_msg_buf
96 */
97 mei_read_slots(dev, dev->rd_msg_buf, hdr->length);
98 dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n",
99 MEI_HDR_PRM(hdr));
100}
101
102/**
85 * mei_cl_irq_read_msg - process client message 103 * mei_cl_irq_read_msg - process client message
86 * 104 *
87 * @cl: reading client 105 * @cl: reading client
@@ -90,9 +108,9 @@ static bool mei_cl_is_reading(struct mei_cl *cl)
90 * 108 *
91 * Return: always 0 109 * Return: always 0
92 */ 110 */
93static int mei_cl_irq_read_msg(struct mei_cl *cl, 111int mei_cl_irq_read_msg(struct mei_cl *cl,
94 struct mei_msg_hdr *mei_hdr, 112 struct mei_msg_hdr *mei_hdr,
95 struct mei_cl_cb *complete_list) 113 struct mei_cl_cb *complete_list)
96{ 114{
97 struct mei_device *dev = cl->dev; 115 struct mei_device *dev = cl->dev;
98 struct mei_cl_cb *cb; 116 struct mei_cl_cb *cb;
@@ -144,20 +162,17 @@ static int mei_cl_irq_read_msg(struct mei_cl *cl,
144 mei_read_slots(dev, buffer, mei_hdr->length); 162 mei_read_slots(dev, buffer, mei_hdr->length);
145 163
146 cb->buf_idx += mei_hdr->length; 164 cb->buf_idx += mei_hdr->length;
165
147 if (mei_hdr->msg_complete) { 166 if (mei_hdr->msg_complete) {
167 cb->read_time = jiffies;
148 cl_dbg(dev, cl, "completed read length = %lu\n", 168 cl_dbg(dev, cl, "completed read length = %lu\n",
149 cb->buf_idx); 169 cb->buf_idx);
150 list_move_tail(&cb->list, &complete_list->list); 170 list_move_tail(&cb->list, &complete_list->list);
151 } 171 }
152 172
153out: 173out:
154 if (!buffer) { 174 if (!buffer)
155 /* assume that mei_hdr->length <= MEI_RD_MSG_BUF_SIZE */ 175 mei_irq_discard_msg(dev, mei_hdr);
156 BUG_ON(mei_hdr->length > MEI_RD_MSG_BUF_SIZE);
157 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
158 dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n",
159 MEI_HDR_PRM(mei_hdr));
160 }
161 176
162 return 0; 177 return 0;
163} 178}
@@ -569,8 +584,6 @@ void mei_timer(struct work_struct *work)
569 if (--dev->iamthif_stall_timer == 0) { 584 if (--dev->iamthif_stall_timer == 0) {
570 dev_err(dev->dev, "timer: amthif hanged.\n"); 585 dev_err(dev->dev, "timer: amthif hanged.\n");
571 mei_reset(dev); 586 mei_reset(dev);
572 dev->iamthif_msg_buf_size = 0;
573 dev->iamthif_msg_buf_index = 0;
574 dev->iamthif_canceled = false; 587 dev->iamthif_canceled = false;
575 dev->iamthif_state = MEI_IAMTHIF_IDLE; 588 dev->iamthif_state = MEI_IAMTHIF_IDLE;
576 dev->iamthif_timer = 0; 589 dev->iamthif_timer = 0;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 2f2242f1bed1..57a47d6b63ee 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);
485 * @iamthif_mtu : amthif client max message length 485 * @iamthif_mtu : amthif client max message length
486 * @iamthif_timer : time stamp of current amthif command completion 486 * @iamthif_timer : time stamp of current amthif command completion
487 * @iamthif_stall_timer : timer to detect amthif hang 487 * @iamthif_stall_timer : timer to detect amthif hang
488 * @iamthif_msg_buf : amthif current message buffer
489 * @iamthif_msg_buf_size : size of current amthif message request buffer
490 * @iamthif_msg_buf_index : current index in amthif message request buffer
491 * @iamthif_state : amthif processor state 488 * @iamthif_state : amthif processor state
492 * @iamthif_canceled : current amthif command is canceled 489 * @iamthif_canceled : current amthif command is canceled
493 * 490 *
@@ -583,9 +580,6 @@ struct mei_device {
583 int iamthif_mtu; 580 int iamthif_mtu;
584 unsigned long iamthif_timer; 581 unsigned long iamthif_timer;
585 u32 iamthif_stall_timer; 582 u32 iamthif_stall_timer;
586 unsigned char *iamthif_msg_buf; /* Note: memory has to be allocated */
587 u32 iamthif_msg_buf_size;
588 u32 iamthif_msg_buf_index;
589 enum iamthif_states iamthif_state; 583 enum iamthif_states iamthif_state;
590 bool iamthif_canceled; 584 bool iamthif_canceled;
591 585