aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/amthif.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei/amthif.c')
-rw-r--r--drivers/misc/mei/amthif.c98
1 files changed, 44 insertions, 54 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 095d0595a49e..18794aea6062 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -431,74 +431,64 @@ unsigned int mei_amthif_poll(struct mei_device *dev,
431 * 431 *
432 * returns 0, OK; otherwise, error. 432 * returns 0, OK; otherwise, error.
433 */ 433 */
434int mei_amthif_irq_process_completed(struct mei_device *dev, s32 *slots, 434int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
435 struct mei_cl_cb *cb_pos, 435 struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
436 struct mei_cl *cl,
437 struct mei_cl_cb *cmpl_list)
438{ 436{
439 struct mei_msg_hdr *mei_hdr; 437 struct mei_msg_hdr *mei_hdr;
438 struct mei_cl *cl = cb->cl;
439 size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
440 size_t msg_slots = mei_data2slots(len);
440 441
441 if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + 442 mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
442 dev->iamthif_msg_buf_size - 443 mei_hdr->host_addr = cl->host_client_id;
443 dev->iamthif_msg_buf_index)) { 444 mei_hdr->me_addr = cl->me_client_id;
444 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; 445 mei_hdr->reserved = 0;
445 mei_hdr->host_addr = cl->host_client_id; 446
446 mei_hdr->me_addr = cl->me_client_id; 447 if (*slots >= msg_slots) {
447 mei_hdr->length = dev->iamthif_msg_buf_size - 448 mei_hdr->length = len;
448 dev->iamthif_msg_buf_index;
449 mei_hdr->msg_complete = 1; 449 mei_hdr->msg_complete = 1;
450 mei_hdr->reserved = 0; 450 /* Split the message only if we can write the whole host buffer */
451 } else if (*slots == dev->hbuf_depth) {
452 msg_slots = *slots;
453 len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
454 mei_hdr->length = len;
455 mei_hdr->msg_complete = 0;
456 } else {
457 /* wait for next time the host buffer is empty */
458 return 0;
459 }
451 460
452 *slots -= mei_data2slots(mei_hdr->length); 461 dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n",
462 mei_hdr->length, mei_hdr->msg_complete);
453 463
454 if (mei_write_message(dev, mei_hdr, 464 *slots -= msg_slots;
455 (dev->iamthif_msg_buf + 465 if (mei_write_message(dev, mei_hdr,
456 dev->iamthif_msg_buf_index), 466 dev->iamthif_msg_buf + dev->iamthif_msg_buf_index,
457 mei_hdr->length)) { 467 mei_hdr->length)) {
458 dev->iamthif_state = MEI_IAMTHIF_IDLE; 468 dev->iamthif_state = MEI_IAMTHIF_IDLE;
459 cl->status = -ENODEV; 469 cl->status = -ENODEV;
460 list_del(&cb_pos->list); 470 list_del(&cb->list);
461 return -ENODEV; 471 return -ENODEV;
462 } else { 472 }
463 if (mei_flow_ctrl_reduce(dev, cl))
464 return -ENODEV;
465 dev->iamthif_msg_buf_index += mei_hdr->length;
466 cb_pos->buf_idx = dev->iamthif_msg_buf_index;
467 cl->status = 0;
468 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
469 dev->iamthif_flow_control_pending = true;
470 /* save iamthif cb sent to amthi client */
471 dev->iamthif_current_cb = cb_pos;
472 list_move_tail(&cb_pos->list,
473 &dev->write_waiting_list.list);
474 473
475 } 474 if (mei_flow_ctrl_reduce(dev, cl))
476 } else if (*slots == dev->hbuf_depth) { 475 return -ENODEV;
477 /* buffer is still empty */
478 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
479 mei_hdr->host_addr = cl->host_client_id;
480 mei_hdr->me_addr = cl->me_client_id;
481 mei_hdr->length =
482 (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
483 mei_hdr->msg_complete = 0;
484 mei_hdr->reserved = 0;
485 476
486 *slots -= mei_data2slots(mei_hdr->length); 477 dev->iamthif_msg_buf_index += mei_hdr->length;
478 cl->status = 0;
487 479
488 if (mei_write_message(dev, mei_hdr, 480 if (mei_hdr->msg_complete) {
489 (dev->iamthif_msg_buf + 481 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
490 dev->iamthif_msg_buf_index), 482 dev->iamthif_flow_control_pending = true;
491 mei_hdr->length)) { 483
492 cl->status = -ENODEV; 484 /* save iamthif cb sent to amthi client */
493 list_del(&cb_pos->list); 485 cb->buf_idx = dev->iamthif_msg_buf_index;
494 } else { 486 dev->iamthif_current_cb = cb;
495 dev->iamthif_msg_buf_index += mei_hdr->length; 487
496 } 488 list_move_tail(&cb->list, &dev->write_waiting_list.list);
497 return -EMSGSIZE;
498 } else {
499 return -EBADMSG;
500 } 489 }
501 490
491
502 return 0; 492 return 0;
503} 493}
504 494