3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 #include <linux/pci.h>
19 #include <linux/kthread.h>
20 #include <linux/interrupt.h>
22 #include <linux/jiffies.h>
25 #include <linux/mei.h>
27 #include "interface.h"
31 * mei_interrupt_quick_handler - The ISR of the MEI device
33 * @irq: The irq number
34 * @dev_id: pointer to the device structure
38 irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id)
40 struct mei_device *dev = (struct mei_device *) dev_id;
41 u32 csr_reg = mei_hcsr_read(dev);
43 if ((csr_reg & H_IS) != H_IS)
46 /* clear H_IS bit in H_CSR */
47 mei_reg_write(dev, H_CSR, csr_reg);
49 return IRQ_WAKE_THREAD;
53 * _mei_cmpl - processes completed operation.
55 * @cl: private data of the file object.
56 * @cb_pos: callback block.
58 static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos)
60 if (cb_pos->fop_type == MEI_FOP_WRITE) {
61 mei_io_cb_free(cb_pos);
63 cl->writing_state = MEI_WRITE_COMPLETE;
64 if (waitqueue_active(&cl->tx_wait))
65 wake_up_interruptible(&cl->tx_wait);
67 } else if (cb_pos->fop_type == MEI_FOP_READ &&
68 MEI_READING == cl->reading_state) {
69 cl->reading_state = MEI_READ_COMPLETE;
70 if (waitqueue_active(&cl->rx_wait))
71 wake_up_interruptible(&cl->rx_wait);
77 * _mei_irq_thread_state_ok - checks if mei header matches file private data
79 * @cl: private data of the file object
80 * @mei_hdr: header of mei client message
82 * returns !=0 if matches, 0 if no match.
84 static int _mei_irq_thread_state_ok(struct mei_cl *cl,
85 struct mei_msg_hdr *mei_hdr)
87 return (cl->host_client_id == mei_hdr->host_addr &&
88 cl->me_client_id == mei_hdr->me_addr &&
89 cl->state == MEI_FILE_CONNECTED &&
90 MEI_READ_COMPLETE != cl->reading_state);
94 * mei_irq_thread_read_client_message - bottom half read routine after ISR to
95 * handle the read mei client message data processing.
97 * @complete_list: An instance of our list structure
98 * @dev: the device structure
99 * @mei_hdr: header of mei client message
101 * returns 0 on success, <0 on failure.
103 static int mei_irq_thread_read_client_message(struct mei_cl_cb *complete_list,
104 struct mei_device *dev,
105 struct mei_msg_hdr *mei_hdr)
108 struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
109 unsigned char *buffer = NULL;
111 dev_dbg(&dev->pdev->dev, "start client msg\n");
112 if (list_empty(&dev->read_list.list))
115 list_for_each_entry_safe(cb_pos, cb_next, &dev->read_list.list, list) {
117 if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) {
118 cl->reading_state = MEI_READING;
119 buffer = cb_pos->response_buffer.data + cb_pos->buf_idx;
121 if (cb_pos->response_buffer.size <
122 mei_hdr->length + cb_pos->buf_idx) {
123 dev_dbg(&dev->pdev->dev, "message overflow.\n");
124 list_del(&cb_pos->list);
128 mei_read_slots(dev, buffer, mei_hdr->length);
130 cb_pos->buf_idx += mei_hdr->length;
131 if (mei_hdr->msg_complete) {
133 list_del(&cb_pos->list);
134 dev_dbg(&dev->pdev->dev,
135 "completed read H cl = %d, ME cl = %d, length = %lu\n",
140 list_add_tail(&cb_pos->list,
141 &complete_list->list);
150 dev_dbg(&dev->pdev->dev, "message read\n");
152 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
153 dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n",
154 *(u32 *) dev->rd_msg_buf);
161 * _mei_irq_thread_close - processes close related operation.
163 * @dev: the device structure.
164 * @slots: free slots.
165 * @cb_pos: callback block.
166 * @cl: private data of the file object.
167 * @cmpl_list: complete list.
169 * returns 0, OK; otherwise, error.
171 static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
172 struct mei_cl_cb *cb_pos,
174 struct mei_cl_cb *cmpl_list)
176 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
177 sizeof(struct hbm_client_connect_request)))
180 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request));
182 if (mei_disconnect(dev, cl)) {
185 list_move_tail(&cb_pos->list, &cmpl_list->list);
188 cl->state = MEI_FILE_DISCONNECTING;
191 list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
192 cl->timer_count = MEI_CONNECT_TIMEOUT;
199 * is_treat_specially_client - checks if the message belongs
200 * to the file private data.
202 * @cl: private data of the file object
203 * @rs: connect response bus message
206 static bool is_treat_specially_client(struct mei_cl *cl,
207 struct hbm_client_connect_response *rs)
210 if (cl->host_client_id == rs->host_addr &&
211 cl->me_client_id == rs->me_addr) {
213 cl->state = MEI_FILE_CONNECTED;
217 cl->state = MEI_FILE_DISCONNECTED;
218 cl->status = -ENODEV;
228 * mei_client_connect_response - connects to response irq routine
230 * @dev: the device structure
231 * @rs: connect response bus message
233 static void mei_client_connect_response(struct mei_device *dev,
234 struct hbm_client_connect_response *rs)
238 struct mei_cl_cb *pos = NULL, *next = NULL;
240 dev_dbg(&dev->pdev->dev,
241 "connect_response:\n"
249 /* if WD or iamthif client treat specially */
251 if (is_treat_specially_client(&(dev->wd_cl), rs)) {
252 dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
253 mei_watchdog_register(dev);
258 if (is_treat_specially_client(&(dev->iamthif_cl), rs)) {
259 dev->iamthif_state = MEI_IAMTHIF_IDLE;
262 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
266 list_del(&pos->list);
269 if (pos->fop_type == MEI_FOP_IOCTL) {
270 if (is_treat_specially_client(cl, rs)) {
271 list_del(&pos->list);
281 * mei_client_disconnect_response - disconnects from response irq routine
283 * @dev: the device structure
284 * @rs: disconnect response bus message
286 static void mei_client_disconnect_response(struct mei_device *dev,
287 struct hbm_client_connect_response *rs)
290 struct mei_cl_cb *pos = NULL, *next = NULL;
292 dev_dbg(&dev->pdev->dev,
293 "disconnect_response:\n"
301 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
305 list_del(&pos->list);
309 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
310 if (cl->host_client_id == rs->host_addr &&
311 cl->me_client_id == rs->me_addr) {
313 list_del(&pos->list);
315 cl->state = MEI_FILE_DISCONNECTED;
325 * same_flow_addr - tells if they have the same address.
327 * @file: private data of the file object.
328 * @flow: flow control.
330 * returns !=0, same; 0,not.
332 static int same_flow_addr(struct mei_cl *cl, struct hbm_flow_control *flow)
334 return (cl->host_client_id == flow->host_addr &&
335 cl->me_client_id == flow->me_addr);
339 * add_single_flow_creds - adds single buffer credentials.
341 * @file: private data ot the file object.
342 * @flow: flow control.
344 static void add_single_flow_creds(struct mei_device *dev,
345 struct hbm_flow_control *flow)
347 struct mei_me_client *client;
350 for (i = 0; i < dev->me_clients_num; i++) {
351 client = &dev->me_clients[i];
352 if (client && flow->me_addr == client->client_id) {
353 if (client->props.single_recv_buf) {
354 client->mei_flow_ctrl_creds++;
355 dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n",
357 dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n",
358 client->mei_flow_ctrl_creds);
360 BUG(); /* error in flow control */
367 * mei_client_flow_control_response - flow control response irq routine
369 * @dev: the device structure
370 * @flow_control: flow control response bus message
372 static void mei_client_flow_control_response(struct mei_device *dev,
373 struct hbm_flow_control *flow_control)
375 struct mei_cl *cl_pos = NULL;
376 struct mei_cl *cl_next = NULL;
378 if (!flow_control->host_addr) {
379 /* single receive buffer */
380 add_single_flow_creds(dev, flow_control);
382 /* normal connection */
383 list_for_each_entry_safe(cl_pos, cl_next,
384 &dev->file_list, link) {
385 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in file_list\n");
387 dev_dbg(&dev->pdev->dev, "cl of host client %d ME client %d.\n",
388 cl_pos->host_client_id,
389 cl_pos->me_client_id);
390 dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n",
391 flow_control->host_addr,
392 flow_control->me_addr);
393 if (same_flow_addr(cl_pos, flow_control)) {
394 dev_dbg(&dev->pdev->dev, "recv ctrl msg for host %d ME %d.\n",
395 flow_control->host_addr,
396 flow_control->me_addr);
397 cl_pos->mei_flow_ctrl_creds++;
398 dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n",
399 cl_pos->mei_flow_ctrl_creds);
407 * same_disconn_addr - tells if they have the same address
409 * @file: private data of the file object.
410 * @disconn: disconnection request.
412 * returns !=0, same; 0,not.
414 static int same_disconn_addr(struct mei_cl *cl,
415 struct hbm_client_connect_request *req)
417 return (cl->host_client_id == req->host_addr &&
418 cl->me_client_id == req->me_addr);
422 * mei_client_disconnect_request - disconnects from request irq routine
424 * @dev: the device structure.
425 * @disconnect_req: disconnect request bus message.
427 static void mei_client_disconnect_request(struct mei_device *dev,
428 struct hbm_client_connect_request *disconnect_req)
430 struct hbm_client_connect_response *disconnect_res;
431 struct mei_cl *pos, *next;
432 const size_t len = sizeof(struct hbm_client_connect_response);
434 list_for_each_entry_safe(pos, next, &dev->file_list, link) {
435 if (same_disconn_addr(pos, disconnect_req)) {
436 dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n",
437 disconnect_req->host_addr,
438 disconnect_req->me_addr);
439 pos->state = MEI_FILE_DISCONNECTED;
440 pos->timer_count = 0;
441 if (pos == &dev->wd_cl)
442 dev->wd_pending = false;
443 else if (pos == &dev->iamthif_cl)
444 dev->iamthif_timer = 0;
446 /* prepare disconnect response */
447 (void)mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len);
449 (struct hbm_client_connect_response *)
450 &dev->wr_ext_msg.data;
451 disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD;
452 disconnect_res->host_addr = pos->host_client_id;
453 disconnect_res->me_addr = pos->me_client_id;
454 disconnect_res->status = 0;
461 * mei_irq_thread_read_bus_message - bottom half read routine after ISR to
462 * handle the read bus message cmd processing.
464 * @dev: the device structure
465 * @mei_hdr: header of bus message
467 static void mei_irq_thread_read_bus_message(struct mei_device *dev,
468 struct mei_msg_hdr *mei_hdr)
470 struct mei_bus_message *mei_msg;
471 struct mei_me_client *me_client;
472 struct hbm_host_version_response *version_res;
473 struct hbm_client_connect_response *connect_res;
474 struct hbm_client_connect_response *disconnect_res;
475 struct hbm_client_connect_request *disconnect_req;
476 struct hbm_flow_control *flow_control;
477 struct hbm_props_response *props_res;
478 struct hbm_host_enum_response *enum_res;
479 struct hbm_host_stop_request *stop_req;
481 /* read the message to our buffer */
482 BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf));
483 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
484 mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;
486 switch (mei_msg->hbm_cmd) {
487 case HOST_START_RES_CMD:
488 version_res = (struct hbm_host_version_response *) mei_msg;
489 if (version_res->host_version_supported) {
490 dev->version.major_version = HBM_MAJOR_VERSION;
491 dev->version.minor_version = HBM_MINOR_VERSION;
492 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
493 dev->init_clients_state == MEI_START_MESSAGE) {
494 dev->init_clients_timer = 0;
495 mei_host_enum_clients_message(dev);
497 dev->recvd_msg = false;
498 dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n");
503 u32 *buf = dev->wr_msg_buf;
504 const size_t len = sizeof(struct hbm_host_stop_request);
506 dev->version = version_res->me_max_version;
508 /* send stop message */
509 mei_hdr = mei_hbm_hdr(&buf[0], len);
510 stop_req = (struct hbm_host_stop_request *)&buf[1];
511 memset(stop_req, 0, len);
512 stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
513 stop_req->reason = DRIVER_STOP_REQUEST;
515 mei_write_message(dev, mei_hdr,
516 (unsigned char *)stop_req, len);
517 dev_dbg(&dev->pdev->dev, "version mismatch.\n");
521 dev->recvd_msg = true;
522 dev_dbg(&dev->pdev->dev, "host start response message received.\n");
525 case CLIENT_CONNECT_RES_CMD:
526 connect_res = (struct hbm_client_connect_response *) mei_msg;
527 mei_client_connect_response(dev, connect_res);
528 dev_dbg(&dev->pdev->dev, "client connect response message received.\n");
529 wake_up(&dev->wait_recvd_msg);
532 case CLIENT_DISCONNECT_RES_CMD:
533 disconnect_res = (struct hbm_client_connect_response *) mei_msg;
534 mei_client_disconnect_response(dev, disconnect_res);
535 dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
536 wake_up(&dev->wait_recvd_msg);
539 case MEI_FLOW_CONTROL_CMD:
540 flow_control = (struct hbm_flow_control *) mei_msg;
541 mei_client_flow_control_response(dev, flow_control);
542 dev_dbg(&dev->pdev->dev, "client flow control response message received.\n");
545 case HOST_CLIENT_PROPERTIES_RES_CMD:
546 props_res = (struct hbm_props_response *)mei_msg;
547 me_client = &dev->me_clients[dev->me_client_presentation_num];
549 if (props_res->status || !dev->me_clients) {
550 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
555 if (me_client->client_id != props_res->address) {
556 dev_err(&dev->pdev->dev,
557 "Host client properties reply mismatch\n");
563 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
564 dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) {
565 dev_err(&dev->pdev->dev,
566 "Unexpected client properties reply\n");
572 me_client->props = props_res->client_properties;
573 dev->me_client_index++;
574 dev->me_client_presentation_num++;
576 mei_host_client_enumerate(dev);
580 case HOST_ENUM_RES_CMD:
581 enum_res = (struct hbm_host_enum_response *) mei_msg;
582 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
583 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
584 dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) {
585 dev->init_clients_timer = 0;
586 dev->me_client_presentation_num = 0;
587 dev->me_client_index = 0;
588 mei_allocate_me_clients_storage(dev);
589 dev->init_clients_state =
590 MEI_CLIENT_PROPERTIES_MESSAGE;
592 mei_host_client_enumerate(dev);
594 dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
600 case HOST_STOP_RES_CMD:
601 dev->dev_state = MEI_DEV_DISABLED;
602 dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n");
606 case CLIENT_DISCONNECT_REQ_CMD:
607 /* search for client */
608 disconnect_req = (struct hbm_client_connect_request *)mei_msg;
609 mei_client_disconnect_request(dev, disconnect_req);
612 case ME_STOP_REQ_CMD:
614 /* prepare stop request: sent in next interrupt event */
616 const size_t len = sizeof(struct hbm_host_stop_request);
618 mei_hdr = mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len);
619 stop_req = (struct hbm_host_stop_request *)&dev->wr_ext_msg.data;
620 memset(stop_req, 0, len);
621 stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
622 stop_req->reason = DRIVER_STOP_REQUEST;
634 * _mei_hb_read - processes read related operation.
636 * @dev: the device structure.
637 * @slots: free slots.
638 * @cb_pos: callback block.
639 * @cl: private data of the file object.
640 * @cmpl_list: complete list.
642 * returns 0, OK; otherwise, error.
644 static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots,
645 struct mei_cl_cb *cb_pos,
647 struct mei_cl_cb *cmpl_list)
649 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
650 sizeof(struct hbm_flow_control))) {
651 /* return the cancel routine */
652 list_del(&cb_pos->list);
656 *slots -= mei_data2slots(sizeof(struct hbm_flow_control));
658 if (mei_send_flow_control(dev, cl)) {
659 cl->status = -ENODEV;
661 list_move_tail(&cb_pos->list, &cmpl_list->list);
664 list_move_tail(&cb_pos->list, &dev->read_list.list);
671 * _mei_irq_thread_ioctl - processes ioctl related operation.
673 * @dev: the device structure.
674 * @slots: free slots.
675 * @cb_pos: callback block.
676 * @cl: private data of the file object.
677 * @cmpl_list: complete list.
679 * returns 0, OK; otherwise, error.
681 static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
682 struct mei_cl_cb *cb_pos,
684 struct mei_cl_cb *cmpl_list)
686 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
687 sizeof(struct hbm_client_connect_request))) {
688 /* return the cancel routine */
689 list_del(&cb_pos->list);
693 cl->state = MEI_FILE_CONNECTING;
694 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request));
695 if (mei_connect(dev, cl)) {
696 cl->status = -ENODEV;
698 list_del(&cb_pos->list);
701 list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
702 cl->timer_count = MEI_CONNECT_TIMEOUT;
708 * mei_irq_thread_write_complete - write messages to device.
710 * @dev: the device structure.
711 * @slots: free slots.
712 * @cb: callback block.
713 * @cmpl_list: complete list.
715 * returns 0, OK; otherwise, error.
717 static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
718 struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
720 struct mei_msg_hdr *mei_hdr;
721 struct mei_cl *cl = cb->cl;
722 size_t len = cb->request_buffer.size - cb->buf_idx;
723 size_t msg_slots = mei_data2slots(len);
725 mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
726 mei_hdr->host_addr = cl->host_client_id;
727 mei_hdr->me_addr = cl->me_client_id;
728 mei_hdr->reserved = 0;
730 if (*slots >= msg_slots) {
731 mei_hdr->length = len;
732 mei_hdr->msg_complete = 1;
733 /* Split the message only if we can write the whole host buffer */
734 } else if (*slots == dev->hbuf_depth) {
736 len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
737 mei_hdr->length = len;
738 mei_hdr->msg_complete = 0;
740 /* wait for next time the host buffer is empty */
744 dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n",
745 cb->request_buffer.size, cb->buf_idx);
746 dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n",
747 mei_hdr->length, mei_hdr->msg_complete);
750 if (mei_write_message(dev, mei_hdr,
751 cb->request_buffer.data + cb->buf_idx, len)) {
752 cl->status = -ENODEV;
753 list_move_tail(&cb->list, &cmpl_list->list);
757 if (mei_flow_ctrl_reduce(dev, cl))
761 cb->buf_idx += mei_hdr->length;
762 if (mei_hdr->msg_complete)
763 list_move_tail(&cb->list, &dev->write_waiting_list.list);
769 * mei_irq_thread_read_handler - bottom half read routine after ISR to
770 * handle the read processing.
772 * @cmpl_list: An instance of our list structure
773 * @dev: the device structure
774 * @slots: slots to read.
776 * returns 0 on success, <0 on failure.
778 static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list,
779 struct mei_device *dev,
782 struct mei_msg_hdr *mei_hdr;
783 struct mei_cl *cl_pos = NULL;
784 struct mei_cl *cl_next = NULL;
787 if (!dev->rd_msg_hdr) {
788 dev->rd_msg_hdr = mei_mecbrw_read(dev);
789 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
791 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
793 mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr;
794 dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length);
796 if (mei_hdr->reserved || !dev->rd_msg_hdr) {
797 dev_dbg(&dev->pdev->dev, "corrupted message header.\n");
802 if (mei_hdr->host_addr || mei_hdr->me_addr) {
803 list_for_each_entry_safe(cl_pos, cl_next,
804 &dev->file_list, link) {
805 dev_dbg(&dev->pdev->dev,
806 "list_for_each_entry_safe read host"
807 " client = %d, ME client = %d\n",
808 cl_pos->host_client_id,
809 cl_pos->me_client_id);
810 if (cl_pos->host_client_id == mei_hdr->host_addr &&
811 cl_pos->me_client_id == mei_hdr->me_addr)
815 if (&cl_pos->link == &dev->file_list) {
816 dev_dbg(&dev->pdev->dev, "corrupted message header\n");
821 if (((*slots) * sizeof(u32)) < mei_hdr->length) {
822 dev_dbg(&dev->pdev->dev,
823 "we can't read the message slots =%08x.\n",
825 /* we can't read the message */
830 /* decide where to read the message too */
831 if (!mei_hdr->host_addr) {
832 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n");
833 mei_irq_thread_read_bus_message(dev, mei_hdr);
834 dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n");
835 } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
836 (MEI_FILE_CONNECTED == dev->iamthif_cl.state) &&
837 (dev->iamthif_state == MEI_IAMTHIF_READING)) {
838 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n");
839 dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
842 ret = mei_amthif_irq_read_message(cmpl_list, dev, mei_hdr);
847 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n");
848 ret = mei_irq_thread_read_client_message(cmpl_list,
855 /* reset the number of slots and header */
856 *slots = mei_count_full_read_slots(dev);
859 if (*slots == -EOVERFLOW) {
860 /* overflow - reset */
861 dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n");
862 /* set the event since message has been read */
872 * mei_irq_thread_write_handler - bottom half write routine after
873 * ISR to handle the write processing.
875 * @dev: the device structure
876 * @cmpl_list: An instance of our list structure
878 * returns 0 on success, <0 on failure.
880 static int mei_irq_thread_write_handler(struct mei_device *dev,
881 struct mei_cl_cb *cmpl_list)
885 struct mei_cl_cb *pos = NULL, *next = NULL;
886 struct mei_cl_cb *list;
890 if (!mei_hbuf_is_empty(dev)) {
891 dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
894 slots = mei_hbuf_empty_slots(dev);
898 /* complete all waiting for write CB */
899 dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
901 list = &dev->write_waiting_list;
902 list_for_each_entry_safe(pos, next, &list->list, list) {
908 list_del(&pos->list);
909 if (MEI_WRITING == cl->writing_state &&
910 pos->fop_type == MEI_FOP_WRITE &&
911 cl != &dev->iamthif_cl) {
912 dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n");
913 cl->writing_state = MEI_WRITE_COMPLETE;
914 list_add_tail(&pos->list, &cmpl_list->list);
916 if (cl == &dev->iamthif_cl) {
917 dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
918 if (dev->iamthif_flow_control_pending) {
919 ret = mei_amthif_irq_read(dev, &slots);
926 if (dev->wd_state == MEI_WD_STOPPING) {
927 dev->wd_state = MEI_WD_IDLE;
928 wake_up_interruptible(&dev->wait_stop_wd);
931 if (dev->wr_ext_msg.hdr.length) {
932 mei_write_message(dev, &dev->wr_ext_msg.hdr,
933 dev->wr_ext_msg.data, dev->wr_ext_msg.hdr.length);
934 slots -= mei_data2slots(dev->wr_ext_msg.hdr.length);
935 dev->wr_ext_msg.hdr.length = 0;
937 if (dev->dev_state == MEI_DEV_ENABLED) {
938 if (dev->wd_pending &&
939 mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
940 if (mei_wd_send(dev))
941 dev_dbg(&dev->pdev->dev, "wd send failed.\n");
942 else if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
945 dev->wd_pending = false;
947 if (dev->wd_state == MEI_WD_RUNNING)
948 slots -= mei_data2slots(MEI_WD_START_MSG_SIZE);
950 slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE);
954 /* complete control write list CB */
955 dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
956 list_for_each_entry_safe(pos, next, &dev->ctrl_wr_list.list, list) {
959 list_del(&pos->list);
962 switch (pos->fop_type) {
964 /* send disconnect message */
965 ret = _mei_irq_thread_close(dev, &slots, pos,
972 /* send flow control message */
973 ret = _mei_irq_thread_read(dev, &slots, pos,
980 /* connect message */
981 if (mei_other_client_is_connecting(dev, cl))
983 ret = _mei_irq_thread_ioctl(dev, &slots, pos,
995 /* complete write list CB */
996 dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
997 list_for_each_entry_safe(pos, next, &dev->write_list.list, list) {
1001 if (mei_flow_ctrl_creds(dev, cl) <= 0) {
1002 dev_dbg(&dev->pdev->dev,
1003 "No flow control credentials for client %d, not sending.\n",
1004 cl->host_client_id);
1008 if (cl == &dev->iamthif_cl)
1009 ret = mei_amthif_irq_write_complete(dev, &slots,
1012 ret = mei_irq_thread_write_complete(dev, &slots, pos,
1024 * mei_timer - timer function.
1026 * @work: pointer to the work_struct structure
1028 * NOTE: This function is called by timer interrupt work
1030 void mei_timer(struct work_struct *work)
1032 unsigned long timeout;
1033 struct mei_cl *cl_pos = NULL;
1034 struct mei_cl *cl_next = NULL;
1035 struct mei_cl_cb *cb_pos = NULL;
1036 struct mei_cl_cb *cb_next = NULL;
1038 struct mei_device *dev = container_of(work,
1039 struct mei_device, timer_work.work);
1042 mutex_lock(&dev->device_lock);
1043 if (dev->dev_state != MEI_DEV_ENABLED) {
1044 if (dev->dev_state == MEI_DEV_INIT_CLIENTS) {
1045 if (dev->init_clients_timer) {
1046 if (--dev->init_clients_timer == 0) {
1047 dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n",
1048 dev->init_clients_state);
1055 /*** connect/disconnect timeouts ***/
1056 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
1057 if (cl_pos->timer_count) {
1058 if (--cl_pos->timer_count == 0) {
1059 dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n");
1066 if (dev->iamthif_stall_timer) {
1067 if (--dev->iamthif_stall_timer == 0) {
1068 dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n");
1070 dev->iamthif_msg_buf_size = 0;
1071 dev->iamthif_msg_buf_index = 0;
1072 dev->iamthif_canceled = false;
1073 dev->iamthif_ioctl = true;
1074 dev->iamthif_state = MEI_IAMTHIF_IDLE;
1075 dev->iamthif_timer = 0;
1077 mei_io_cb_free(dev->iamthif_current_cb);
1078 dev->iamthif_current_cb = NULL;
1080 dev->iamthif_file_object = NULL;
1081 mei_amthif_run_next_cmd(dev);
1085 if (dev->iamthif_timer) {
1087 timeout = dev->iamthif_timer +
1088 mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
1090 dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
1091 dev->iamthif_timer);
1092 dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout);
1093 dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies);
1094 if (time_after(jiffies, timeout)) {
1096 * User didn't read the AMTHI data on time (15sec)
1097 * freeing AMTHI for other requests
1100 dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n");
1102 list_for_each_entry_safe(cb_pos, cb_next,
1103 &dev->amthif_rd_complete_list.list, list) {
1105 cl_pos = cb_pos->file_object->private_data;
1107 /* Finding the AMTHI entry. */
1108 if (cl_pos == &dev->iamthif_cl)
1109 list_del(&cb_pos->list);
1111 mei_io_cb_free(dev->iamthif_current_cb);
1112 dev->iamthif_current_cb = NULL;
1114 dev->iamthif_file_object->private_data = NULL;
1115 dev->iamthif_file_object = NULL;
1116 dev->iamthif_timer = 0;
1117 mei_amthif_run_next_cmd(dev);
1122 schedule_delayed_work(&dev->timer_work, 2 * HZ);
1123 mutex_unlock(&dev->device_lock);
1127 * mei_interrupt_thread_handler - function called after ISR to handle the interrupt
1130 * @irq: The irq number
1131 * @dev_id: pointer to the device structure
1133 * returns irqreturn_t
1136 irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
1138 struct mei_device *dev = (struct mei_device *) dev_id;
1139 struct mei_cl_cb complete_list;
1140 struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
1144 bool bus_message_received;
1147 dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n");
1148 /* initialize our complete list */
1149 mutex_lock(&dev->device_lock);
1150 mei_io_list_init(&complete_list);
1151 dev->host_hw_state = mei_hcsr_read(dev);
1153 /* Ack the interrupt here
1154 * In case of MSI we don't go through the quick handler */
1155 if (pci_dev_msi_enabled(dev->pdev))
1156 mei_reg_write(dev, H_CSR, dev->host_hw_state);
1158 dev->me_hw_state = mei_mecsr_read(dev);
1160 /* check if ME wants a reset */
1161 if ((dev->me_hw_state & ME_RDY_HRA) == 0 &&
1162 dev->dev_state != MEI_DEV_RESETING &&
1163 dev->dev_state != MEI_DEV_INITIALIZING) {
1164 dev_dbg(&dev->pdev->dev, "FW not ready.\n");
1166 mutex_unlock(&dev->device_lock);
1170 /* check if we need to start the dev */
1171 if ((dev->host_hw_state & H_RDY) == 0) {
1172 if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) {
1173 dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
1174 dev->host_hw_state |= (H_IE | H_IG | H_RDY);
1176 dev->dev_state = MEI_DEV_INIT_CLIENTS;
1177 dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
1178 /* link is established
1179 * start sending messages.
1181 mei_host_start_message(dev);
1182 mutex_unlock(&dev->device_lock);
1185 dev_dbg(&dev->pdev->dev, "FW not ready.\n");
1186 mutex_unlock(&dev->device_lock);
1190 /* check slots available for reading */
1191 slots = mei_count_full_read_slots(dev);
1193 /* we have urgent data to send so break the read */
1194 if (dev->wr_ext_msg.hdr.length)
1196 dev_dbg(&dev->pdev->dev, "slots =%08x\n", slots);
1197 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n");
1198 rets = mei_irq_thread_read_handler(&complete_list, dev, &slots);
1202 rets = mei_irq_thread_write_handler(dev, &complete_list);
1204 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
1205 dev->host_hw_state = mei_hcsr_read(dev);
1206 dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
1208 bus_message_received = false;
1209 if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
1210 dev_dbg(&dev->pdev->dev, "received waiting bus message\n");
1211 bus_message_received = true;
1213 mutex_unlock(&dev->device_lock);
1214 if (bus_message_received) {
1215 dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n");
1216 wake_up_interruptible(&dev->wait_recvd_msg);
1217 bus_message_received = false;
1219 if (list_empty(&complete_list.list))
1223 list_for_each_entry_safe(cb_pos, cb_next, &complete_list.list, list) {
1225 list_del(&cb_pos->list);
1227 if (cl != &dev->iamthif_cl) {
1228 dev_dbg(&dev->pdev->dev, "completing call back.\n");
1229 _mei_cmpl(cl, cb_pos);
1231 } else if (cl == &dev->iamthif_cl) {
1232 mei_amthif_complete(dev, cb_pos);