3
* Intel Management Engine Interface (Intel MEI) Linux driver
4
* Copyright (c) 2003-2011, 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>
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->major_file_operations == MEI_WRITE) {
61
mei_free_cb_private(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->major_file_operations == MEI_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_cmpl_iamthif - processes completed iamthif operation.
79
* @dev: the device structure.
80
* @cb_pos: callback block.
82
static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos)
84
if (dev->iamthif_canceled != 1) {
85
dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE;
86
dev->iamthif_stall_timer = 0;
87
memcpy(cb_pos->response_buffer.data,
89
dev->iamthif_msg_buf_index);
90
list_add_tail(&cb_pos->cb_list,
91
&dev->amthi_read_complete_list.mei_cb.cb_list);
92
dev_dbg(&dev->pdev->dev, "amthi read completed.\n");
93
dev->iamthif_timer = jiffies;
94
dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
97
run_next_iamthif_cmd(dev);
100
dev_dbg(&dev->pdev->dev, "completing amthi call back.\n");
101
wake_up_interruptible(&dev->iamthif_cl.wait);
106
* mei_irq_thread_read_amthi_message - bottom half read routine after ISR to
107
* handle the read amthi message data processing.
109
* @complete_list: An instance of our list structure
110
* @dev: the device structure
111
* @mei_hdr: header of amthi message
113
* returns 0 on success, <0 on failure.
115
static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list,
116
struct mei_device *dev,
117
struct mei_msg_hdr *mei_hdr)
120
struct mei_cl_cb *cb;
121
unsigned char *buffer;
123
BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id);
124
BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING);
126
buffer = (unsigned char *) (dev->iamthif_msg_buf +
127
dev->iamthif_msg_buf_index);
128
BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length);
130
mei_read_slots(dev, buffer, mei_hdr->length);
132
dev->iamthif_msg_buf_index += mei_hdr->length;
134
if (!mei_hdr->msg_complete)
137
dev_dbg(&dev->pdev->dev,
138
"amthi_message_buffer_index =%d\n",
141
dev_dbg(&dev->pdev->dev, "completed amthi read.\n ");
142
if (!dev->iamthif_current_cb)
145
cb = dev->iamthif_current_cb;
146
dev->iamthif_current_cb = NULL;
148
cl = (struct mei_cl *)cb->file_private;
152
dev->iamthif_stall_timer = 0;
153
cb->information = dev->iamthif_msg_buf_index;
154
cb->read_time = jiffies;
155
if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) {
156
/* found the iamthif cb */
157
dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n ");
158
dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n ");
159
list_add_tail(&cb->cb_list,
160
&complete_list->mei_cb.cb_list);
166
* _mei_irq_thread_state_ok - checks if mei header matches file private data
168
* @cl: private data of the file object
169
* @mei_hdr: header of mei client message
171
* returns !=0 if matches, 0 if no match.
173
static int _mei_irq_thread_state_ok(struct mei_cl *cl,
174
struct mei_msg_hdr *mei_hdr)
176
return (cl->host_client_id == mei_hdr->host_addr &&
177
cl->me_client_id == mei_hdr->me_addr &&
178
cl->state == MEI_FILE_CONNECTED &&
179
MEI_READ_COMPLETE != cl->reading_state);
183
* mei_irq_thread_read_client_message - bottom half read routine after ISR to
184
* handle the read mei client message data processing.
186
* @complete_list: An instance of our list structure
187
* @dev: the device structure
188
* @mei_hdr: header of mei client message
190
* returns 0 on success, <0 on failure.
192
static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list,
193
struct mei_device *dev,
194
struct mei_msg_hdr *mei_hdr)
197
struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
198
unsigned char *buffer;
200
dev_dbg(&dev->pdev->dev, "start client msg\n");
201
if (!(dev->read_list.status == 0 &&
202
!list_empty(&dev->read_list.mei_cb.cb_list)))
205
list_for_each_entry_safe(cb_pos, cb_next,
206
&dev->read_list.mei_cb.cb_list, cb_list) {
207
cl = (struct mei_cl *)cb_pos->file_private;
208
if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) {
209
cl->reading_state = MEI_READING;
210
buffer = (unsigned char *)
211
(cb_pos->response_buffer.data +
212
cb_pos->information);
213
BUG_ON(cb_pos->response_buffer.size <
215
cb_pos->information);
217
if (cb_pos->response_buffer.size <
218
mei_hdr->length + cb_pos->information) {
219
dev_dbg(&dev->pdev->dev, "message overflow.\n");
220
list_del(&cb_pos->cb_list);
224
mei_read_slots(dev, buffer, mei_hdr->length);
226
cb_pos->information += mei_hdr->length;
227
if (mei_hdr->msg_complete) {
229
list_del(&cb_pos->cb_list);
230
dev_dbg(&dev->pdev->dev,
231
"completed read host client = %d,"
233
"data length = %lu\n",
236
cb_pos->information);
238
*(cb_pos->response_buffer.data +
239
cb_pos->information) = '\0';
240
dev_dbg(&dev->pdev->dev, "cb_pos->res_buffer - %s\n",
241
cb_pos->response_buffer.data);
242
list_add_tail(&cb_pos->cb_list,
243
&complete_list->mei_cb.cb_list);
252
dev_dbg(&dev->pdev->dev, "message read\n");
254
mei_read_slots(dev, (unsigned char *) dev->rd_msg_buf,
256
dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n",
257
*(u32 *) dev->rd_msg_buf);
264
* _mei_irq_thread_iamthif_read - prepares to read iamthif data.
266
* @dev: the device structure.
267
* @slots: free slots.
269
* returns 0, OK; otherwise, error.
271
static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots)
274
if (((*slots) * sizeof(u32)) >= (sizeof(struct mei_msg_hdr)
275
+ sizeof(struct hbm_flow_control))) {
276
*slots -= (sizeof(struct mei_msg_hdr) +
277
sizeof(struct hbm_flow_control) + 3) / 4;
278
if (!mei_send_flow_control(dev, &dev->iamthif_cl)) {
279
dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n");
281
dev_dbg(&dev->pdev->dev, "iamthif flow control success\n");
282
dev->iamthif_state = MEI_IAMTHIF_READING;
283
dev->iamthif_flow_control_pending = 0;
284
dev->iamthif_msg_buf_index = 0;
285
dev->iamthif_msg_buf_size = 0;
286
dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER;
287
dev->mei_host_buffer_is_empty =
288
mei_host_buffer_is_empty(dev);
297
* _mei_irq_thread_close - processes close related operation.
299
* @dev: the device structure.
300
* @slots: free slots.
301
* @cb_pos: callback block.
302
* @cl: private data of the file object.
303
* @cmpl_list: complete list.
305
* returns 0, OK; otherwise, error.
307
static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
308
struct mei_cl_cb *cb_pos,
310
struct mei_io_list *cmpl_list)
312
if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
313
sizeof(struct hbm_client_disconnect_request))) {
314
*slots -= (sizeof(struct mei_msg_hdr) +
315
sizeof(struct hbm_client_disconnect_request) + 3) / 4;
317
if (!mei_disconnect(dev, cl)) {
319
cb_pos->information = 0;
320
list_move_tail(&cb_pos->cb_list,
321
&cmpl_list->mei_cb.cb_list);
324
cl->state = MEI_FILE_DISCONNECTING;
326
cb_pos->information = 0;
327
list_move_tail(&cb_pos->cb_list,
328
&dev->ctrl_rd_list.mei_cb.cb_list);
329
cl->timer_count = MEI_CONNECT_TIMEOUT;
332
/* return the cancel routine */
340
* is_treat_specially_client - checks if the message belongs
341
* to the file private data.
343
* @cl: private data of the file object
344
* @rs: connect response bus message
347
static bool is_treat_specially_client(struct mei_cl *cl,
348
struct hbm_client_connect_response *rs)
351
if (cl->host_client_id == rs->host_addr &&
352
cl->me_client_id == rs->me_addr) {
354
cl->state = MEI_FILE_CONNECTED;
358
cl->state = MEI_FILE_DISCONNECTED;
359
cl->status = -ENODEV;
369
* mei_client_connect_response - connects to response irq routine
371
* @dev: the device structure
372
* @rs: connect response bus message
374
static void mei_client_connect_response(struct mei_device *dev,
375
struct hbm_client_connect_response *rs)
379
struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
381
dev_dbg(&dev->pdev->dev,
382
"connect_response:\n"
390
/* if WD or iamthif client treat specially */
392
if (is_treat_specially_client(&(dev->wd_cl), rs)) {
393
dev_dbg(&dev->pdev->dev, "dev->wd_timeout =%d.\n",
396
dev->wd_due_counter = (dev->wd_timeout) ? 1 : 0;
398
dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
399
host_init_iamthif(dev);
403
if (is_treat_specially_client(&(dev->iamthif_cl), rs)) {
404
dev->iamthif_state = MEI_IAMTHIF_IDLE;
407
if (!dev->ctrl_rd_list.status &&
408
!list_empty(&dev->ctrl_rd_list.mei_cb.cb_list)) {
409
list_for_each_entry_safe(cb_pos, cb_next,
410
&dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
411
cl = (struct mei_cl *)cb_pos->file_private;
413
list_del(&cb_pos->cb_list);
416
if (MEI_IOCTL == cb_pos->major_file_operations) {
417
if (is_treat_specially_client(cl, rs)) {
418
list_del(&cb_pos->cb_list);
429
* mei_client_disconnect_response - disconnects from response irq routine
431
* @dev: the device structure
432
* @rs: disconnect response bus message
434
static void mei_client_disconnect_response(struct mei_device *dev,
435
struct hbm_client_connect_response *rs)
438
struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
440
dev_dbg(&dev->pdev->dev,
441
"disconnect_response:\n"
449
if (!dev->ctrl_rd_list.status &&
450
!list_empty(&dev->ctrl_rd_list.mei_cb.cb_list)) {
451
list_for_each_entry_safe(cb_pos, cb_next,
452
&dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
453
cl = (struct mei_cl *)cb_pos->file_private;
456
list_del(&cb_pos->cb_list);
460
dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
461
if (cl->host_client_id == rs->host_addr &&
462
cl->me_client_id == rs->me_addr) {
464
list_del(&cb_pos->cb_list);
466
cl->state = MEI_FILE_DISCONNECTED;
477
* same_flow_addr - tells if they have the same address.
479
* @file: private data of the file object.
480
* @flow: flow control.
482
* returns !=0, same; 0,not.
484
static int same_flow_addr(struct mei_cl *cl, struct hbm_flow_control *flow)
486
return (cl->host_client_id == flow->host_addr &&
487
cl->me_client_id == flow->me_addr);
491
* add_single_flow_creds - adds single buffer credentials.
493
* @file: private data ot the file object.
494
* @flow: flow control.
496
static void add_single_flow_creds(struct mei_device *dev,
497
struct hbm_flow_control *flow)
499
struct mei_me_client *client;
502
for (i = 0; i < dev->num_mei_me_clients; i++) {
503
client = &dev->me_clients[i];
504
if (client && flow->me_addr == client->client_id) {
505
if (client->props.single_recv_buf) {
506
client->mei_flow_ctrl_creds++;
507
dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n",
509
dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n",
510
client->mei_flow_ctrl_creds);
512
BUG(); /* error in flow control */
519
* mei_client_flow_control_response - flow control response irq routine
521
* @dev: the device structure
522
* @flow_control: flow control response bus message
524
static void mei_client_flow_control_response(struct mei_device *dev,
525
struct hbm_flow_control *flow_control)
527
struct mei_cl *cl_pos = NULL;
528
struct mei_cl *cl_next = NULL;
530
if (!flow_control->host_addr) {
531
/* single receive buffer */
532
add_single_flow_creds(dev, flow_control);
534
/* normal connection */
535
list_for_each_entry_safe(cl_pos, cl_next,
536
&dev->file_list, link) {
537
dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in file_list\n");
539
dev_dbg(&dev->pdev->dev, "cl of host client %d ME client %d.\n",
540
cl_pos->host_client_id,
541
cl_pos->me_client_id);
542
dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n",
543
flow_control->host_addr,
544
flow_control->me_addr);
545
if (same_flow_addr(cl_pos, flow_control)) {
546
dev_dbg(&dev->pdev->dev, "recv ctrl msg for host %d ME %d.\n",
547
flow_control->host_addr,
548
flow_control->me_addr);
549
cl_pos->mei_flow_ctrl_creds++;
550
dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n",
551
cl_pos->mei_flow_ctrl_creds);
559
* same_disconn_addr - tells if they have the same address
561
* @file: private data of the file object.
562
* @disconn: disconnection request.
564
* returns !=0, same; 0,not.
566
static int same_disconn_addr(struct mei_cl *cl,
567
struct hbm_client_disconnect_request *disconn)
569
return (cl->host_client_id == disconn->host_addr &&
570
cl->me_client_id == disconn->me_addr);
574
* mei_client_disconnect_request - disconnects from request irq routine
576
* @dev: the device structure.
577
* @disconnect_req: disconnect request bus message.
579
static void mei_client_disconnect_request(struct mei_device *dev,
580
struct hbm_client_disconnect_request *disconnect_req)
582
struct mei_msg_hdr *mei_hdr;
583
struct hbm_client_connect_response *disconnect_res;
584
struct mei_cl *cl_pos = NULL;
585
struct mei_cl *cl_next = NULL;
587
list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
588
if (same_disconn_addr(cl_pos, disconnect_req)) {
589
dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n",
590
disconnect_req->host_addr,
591
disconnect_req->me_addr);
592
cl_pos->state = MEI_FILE_DISCONNECTED;
593
cl_pos->timer_count = 0;
594
if (cl_pos == &dev->wd_cl) {
595
dev->wd_due_counter = 0;
597
} else if (cl_pos == &dev->iamthif_cl)
598
dev->iamthif_timer = 0;
600
/* prepare disconnect response */
602
(struct mei_msg_hdr *) &dev->ext_msg_buf[0];
603
mei_hdr->host_addr = 0;
604
mei_hdr->me_addr = 0;
606
sizeof(struct hbm_client_connect_response);
607
mei_hdr->msg_complete = 1;
608
mei_hdr->reserved = 0;
611
(struct hbm_client_connect_response *)
612
&dev->ext_msg_buf[1];
613
disconnect_res->host_addr = cl_pos->host_client_id;
614
disconnect_res->me_addr = cl_pos->me_client_id;
615
*(u8 *) (&disconnect_res->cmd) =
616
CLIENT_DISCONNECT_RES_CMD;
617
disconnect_res->status = 0;
618
dev->extra_write_index = 2;
626
* mei_irq_thread_read_bus_message - bottom half read routine after ISR to
627
* handle the read bus message cmd processing.
629
* @dev: the device structure
630
* @mei_hdr: header of bus message
632
static void mei_irq_thread_read_bus_message(struct mei_device *dev,
633
struct mei_msg_hdr *mei_hdr)
635
struct mei_bus_message *mei_msg;
636
struct hbm_host_version_response *version_res;
637
struct hbm_client_connect_response *connect_res;
638
struct hbm_client_connect_response *disconnect_res;
639
struct hbm_flow_control *flow_control;
640
struct hbm_props_response *props_res;
641
struct hbm_host_enum_response *enum_res;
642
struct hbm_client_disconnect_request *disconnect_req;
643
struct hbm_host_stop_request *host_stop_req;
645
unsigned char *buffer;
647
/* read the message to our buffer */
648
buffer = (unsigned char *) dev->rd_msg_buf;
649
BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf));
650
mei_read_slots(dev, buffer, mei_hdr->length);
651
mei_msg = (struct mei_bus_message *) buffer;
653
switch (*(u8 *) mei_msg) {
654
case HOST_START_RES_CMD:
655
version_res = (struct hbm_host_version_response *) mei_msg;
656
if (version_res->host_version_supported) {
657
dev->version.major_version = HBM_MAJOR_VERSION;
658
dev->version.minor_version = HBM_MINOR_VERSION;
659
if (dev->mei_state == MEI_INIT_CLIENTS &&
660
dev->init_clients_state == MEI_START_MESSAGE) {
661
dev->init_clients_timer = 0;
662
host_enum_clients_message(dev);
665
dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n");
670
dev->version = version_res->me_max_version;
671
/* send stop message */
672
mei_hdr->host_addr = 0;
673
mei_hdr->me_addr = 0;
674
mei_hdr->length = sizeof(struct hbm_host_stop_request);
675
mei_hdr->msg_complete = 1;
676
mei_hdr->reserved = 0;
678
host_stop_req = (struct hbm_host_stop_request *)
681
memset(host_stop_req,
683
sizeof(struct hbm_host_stop_request));
684
host_stop_req->cmd.cmd = HOST_STOP_REQ_CMD;
685
host_stop_req->reason = DRIVER_STOP_REQUEST;
686
mei_write_message(dev, mei_hdr,
687
(unsigned char *) (host_stop_req),
689
dev_dbg(&dev->pdev->dev, "version mismatch.\n");
694
dev_dbg(&dev->pdev->dev, "host start response message received.\n");
697
case CLIENT_CONNECT_RES_CMD:
699
(struct hbm_client_connect_response *) mei_msg;
700
mei_client_connect_response(dev, connect_res);
701
dev_dbg(&dev->pdev->dev, "client connect response message received.\n");
702
wake_up(&dev->wait_recvd_msg);
705
case CLIENT_DISCONNECT_RES_CMD:
707
(struct hbm_client_connect_response *) mei_msg;
708
mei_client_disconnect_response(dev, disconnect_res);
709
dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
710
wake_up(&dev->wait_recvd_msg);
713
case MEI_FLOW_CONTROL_CMD:
714
flow_control = (struct hbm_flow_control *) mei_msg;
715
mei_client_flow_control_response(dev, flow_control);
716
dev_dbg(&dev->pdev->dev, "client flow control response message received.\n");
719
case HOST_CLIENT_PROPERTIES_RES_CMD:
720
props_res = (struct hbm_props_response *)mei_msg;
721
if (props_res->status || !dev->me_clients) {
722
dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
726
if (dev->me_clients[dev->me_client_presentation_num]
727
.client_id == props_res->address) {
729
dev->me_clients[dev->me_client_presentation_num].props
730
= props_res->client_properties;
732
if (dev->mei_state == MEI_INIT_CLIENTS &&
733
dev->init_clients_state ==
734
MEI_CLIENT_PROPERTIES_MESSAGE) {
735
dev->me_client_index++;
736
dev->me_client_presentation_num++;
737
host_client_properties(dev);
739
dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message");
744
dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n");
750
case HOST_ENUM_RES_CMD:
751
enum_res = (struct hbm_host_enum_response *) mei_msg;
752
memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
753
if (dev->mei_state == MEI_INIT_CLIENTS &&
754
dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) {
755
dev->init_clients_timer = 0;
756
dev->me_client_presentation_num = 0;
757
dev->me_client_index = 0;
758
allocate_me_clients_storage(dev);
759
dev->init_clients_state =
760
MEI_CLIENT_PROPERTIES_MESSAGE;
761
host_client_properties(dev);
763
dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
769
case HOST_STOP_RES_CMD:
770
dev->mei_state = MEI_DISABLED;
771
dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n");
775
case CLIENT_DISCONNECT_REQ_CMD:
776
/* search for client */
778
(struct hbm_client_disconnect_request *) mei_msg;
779
mei_client_disconnect_request(dev, disconnect_req);
782
case ME_STOP_REQ_CMD:
783
/* prepare stop request */
784
mei_hdr = (struct mei_msg_hdr *) &dev->ext_msg_buf[0];
785
mei_hdr->host_addr = 0;
786
mei_hdr->me_addr = 0;
787
mei_hdr->length = sizeof(struct hbm_host_stop_request);
788
mei_hdr->msg_complete = 1;
789
mei_hdr->reserved = 0;
791
(struct hbm_host_stop_request *) &dev->ext_msg_buf[1];
792
memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request));
793
host_stop_req->cmd.cmd = HOST_STOP_REQ_CMD;
794
host_stop_req->reason = DRIVER_STOP_REQUEST;
795
host_stop_req->reserved[0] = 0;
796
host_stop_req->reserved[1] = 0;
797
dev->extra_write_index = 2;
809
* _mei_hb_read - processes read related operation.
811
* @dev: the device structure.
812
* @slots: free slots.
813
* @cb_pos: callback block.
814
* @cl: private data of the file object.
815
* @cmpl_list: complete list.
817
* returns 0, OK; otherwise, error.
819
static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots,
820
struct mei_cl_cb *cb_pos,
822
struct mei_io_list *cmpl_list)
824
if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
825
sizeof(struct hbm_flow_control))) {
826
*slots -= (sizeof(struct mei_msg_hdr) +
827
sizeof(struct hbm_flow_control) + 3) / 4;
828
if (!mei_send_flow_control(dev, cl)) {
829
cl->status = -ENODEV;
830
cb_pos->information = 0;
831
list_move_tail(&cb_pos->cb_list,
832
&cmpl_list->mei_cb.cb_list);
835
list_move_tail(&cb_pos->cb_list,
836
&dev->read_list.mei_cb.cb_list);
839
/* return the cancel routine */
840
list_del(&cb_pos->cb_list);
849
* _mei_irq_thread_ioctl - processes ioctl related operation.
851
* @dev: the device structure.
852
* @slots: free slots.
853
* @cb_pos: callback block.
854
* @cl: private data of the file object.
855
* @cmpl_list: complete list.
857
* returns 0, OK; otherwise, error.
859
static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
860
struct mei_cl_cb *cb_pos,
862
struct mei_io_list *cmpl_list)
864
if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
865
sizeof(struct hbm_client_connect_request))) {
866
cl->state = MEI_FILE_CONNECTING;
867
*slots -= (sizeof(struct mei_msg_hdr) +
868
sizeof(struct hbm_client_connect_request) + 3) / 4;
869
if (!mei_connect(dev, cl)) {
870
cl->status = -ENODEV;
871
cb_pos->information = 0;
872
list_del(&cb_pos->cb_list);
875
list_move_tail(&cb_pos->cb_list,
876
&dev->ctrl_rd_list.mei_cb.cb_list);
877
cl->timer_count = MEI_CONNECT_TIMEOUT;
880
/* return the cancel routine */
881
list_del(&cb_pos->cb_list);
889
* _mei_irq_thread_cmpl - processes completed and no-iamthif operation.
891
* @dev: the device structure.
892
* @slots: free slots.
893
* @cb_pos: callback block.
894
* @cl: private data of the file object.
895
* @cmpl_list: complete list.
897
* returns 0, OK; otherwise, error.
899
static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots,
900
struct mei_cl_cb *cb_pos,
902
struct mei_io_list *cmpl_list)
904
struct mei_msg_hdr *mei_hdr;
906
if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
907
(cb_pos->request_buffer.size -
908
cb_pos->information))) {
909
mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
910
mei_hdr->host_addr = cl->host_client_id;
911
mei_hdr->me_addr = cl->me_client_id;
912
mei_hdr->length = cb_pos->request_buffer.size -
914
mei_hdr->msg_complete = 1;
915
mei_hdr->reserved = 0;
916
dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d"
917
"mei_hdr->msg_complete = %d\n",
918
cb_pos->request_buffer.size,
919
mei_hdr->msg_complete);
920
dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n",
921
cb_pos->information);
922
dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
924
*slots -= (sizeof(struct mei_msg_hdr) +
925
mei_hdr->length + 3) / 4;
926
if (!mei_write_message(dev, mei_hdr,
928
(cb_pos->request_buffer.data +
929
cb_pos->information),
931
cl->status = -ENODEV;
932
list_move_tail(&cb_pos->cb_list,
933
&cmpl_list->mei_cb.cb_list);
936
if (mei_flow_ctrl_reduce(dev, cl))
939
cb_pos->information += mei_hdr->length;
940
list_move_tail(&cb_pos->cb_list,
941
&dev->write_waiting_list.mei_cb.cb_list);
943
} else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
944
/* buffer is still empty */
945
mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
946
mei_hdr->host_addr = cl->host_client_id;
947
mei_hdr->me_addr = cl->me_client_id;
949
(*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
950
mei_hdr->msg_complete = 0;
951
mei_hdr->reserved = 0;
953
(*slots) -= (sizeof(struct mei_msg_hdr) +
954
mei_hdr->length + 3) / 4;
955
if (!mei_write_message(dev, mei_hdr,
957
(cb_pos->request_buffer.data +
958
cb_pos->information),
960
cl->status = -ENODEV;
961
list_move_tail(&cb_pos->cb_list,
962
&cmpl_list->mei_cb.cb_list);
965
cb_pos->information += mei_hdr->length;
966
dev_dbg(&dev->pdev->dev,
967
"cb_pos->request_buffer.size =%d"
968
" mei_hdr->msg_complete = %d\n",
969
cb_pos->request_buffer.size,
970
mei_hdr->msg_complete);
971
dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n",
972
cb_pos->information);
973
dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
985
* _mei_irq_thread_cmpl_iamthif - processes completed iamthif operation.
987
* @dev: the device structure.
988
* @slots: free slots.
989
* @cb_pos: callback block.
990
* @cl: private data of the file object.
991
* @cmpl_list: complete list.
993
* returns 0, OK; otherwise, error.
995
static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots,
996
struct mei_cl_cb *cb_pos,
998
struct mei_io_list *cmpl_list)
1000
struct mei_msg_hdr *mei_hdr;
1002
if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
1003
dev->iamthif_msg_buf_size -
1004
dev->iamthif_msg_buf_index)) {
1005
mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
1006
mei_hdr->host_addr = cl->host_client_id;
1007
mei_hdr->me_addr = cl->me_client_id;
1008
mei_hdr->length = dev->iamthif_msg_buf_size -
1009
dev->iamthif_msg_buf_index;
1010
mei_hdr->msg_complete = 1;
1011
mei_hdr->reserved = 0;
1013
*slots -= (sizeof(struct mei_msg_hdr) +
1014
mei_hdr->length + 3) / 4;
1016
if (!mei_write_message(dev, mei_hdr,
1017
(dev->iamthif_msg_buf +
1018
dev->iamthif_msg_buf_index),
1020
dev->iamthif_state = MEI_IAMTHIF_IDLE;
1021
cl->status = -ENODEV;
1022
list_del(&cb_pos->cb_list);
1025
if (mei_flow_ctrl_reduce(dev, cl))
1027
dev->iamthif_msg_buf_index += mei_hdr->length;
1028
cb_pos->information = dev->iamthif_msg_buf_index;
1030
dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
1031
dev->iamthif_flow_control_pending = 1;
1032
/* save iamthif cb sent to amthi client */
1033
dev->iamthif_current_cb = cb_pos;
1034
list_move_tail(&cb_pos->cb_list,
1035
&dev->write_waiting_list.mei_cb.cb_list);
1038
} else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
1039
/* buffer is still empty */
1040
mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
1041
mei_hdr->host_addr = cl->host_client_id;
1042
mei_hdr->me_addr = cl->me_client_id;
1044
(*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
1045
mei_hdr->msg_complete = 0;
1046
mei_hdr->reserved = 0;
1048
*slots -= (sizeof(struct mei_msg_hdr) +
1049
mei_hdr->length + 3) / 4;
1051
if (!mei_write_message(dev, mei_hdr,
1052
(dev->iamthif_msg_buf +
1053
dev->iamthif_msg_buf_index),
1055
cl->status = -ENODEV;
1056
list_del(&cb_pos->cb_list);
1058
dev->iamthif_msg_buf_index += mei_hdr->length;
1069
* mei_irq_thread_read_handler - bottom half read routine after ISR to
1070
* handle the read processing.
1072
* @cmpl_list: An instance of our list structure
1073
* @dev: the device structure
1074
* @slots: slots to read.
1076
* returns 0 on success, <0 on failure.
1078
static int mei_irq_thread_read_handler(struct mei_io_list *cmpl_list,
1079
struct mei_device *dev,
1082
struct mei_msg_hdr *mei_hdr;
1083
struct mei_cl *cl_pos = NULL;
1084
struct mei_cl *cl_next = NULL;
1087
if (!dev->rd_msg_hdr) {
1088
dev->rd_msg_hdr = mei_mecbrw_read(dev);
1089
dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
1091
dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
1093
mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr;
1094
dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length);
1096
if (mei_hdr->reserved || !dev->rd_msg_hdr) {
1097
dev_dbg(&dev->pdev->dev, "corrupted message header.\n");
1102
if (mei_hdr->host_addr || mei_hdr->me_addr) {
1103
list_for_each_entry_safe(cl_pos, cl_next,
1104
&dev->file_list, link) {
1105
dev_dbg(&dev->pdev->dev,
1106
"list_for_each_entry_safe read host"
1107
" client = %d, ME client = %d\n",
1108
cl_pos->host_client_id,
1109
cl_pos->me_client_id);
1110
if (cl_pos->host_client_id == mei_hdr->host_addr &&
1111
cl_pos->me_client_id == mei_hdr->me_addr)
1115
if (&cl_pos->link == &dev->file_list) {
1116
dev_dbg(&dev->pdev->dev, "corrupted message header\n");
1121
if (((*slots) * sizeof(u32)) < mei_hdr->length) {
1122
dev_dbg(&dev->pdev->dev,
1123
"we can't read the message slots =%08x.\n",
1125
/* we can't read the message */
1130
/* decide where to read the message too */
1131
if (!mei_hdr->host_addr) {
1132
dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n");
1133
mei_irq_thread_read_bus_message(dev, mei_hdr);
1134
dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n");
1135
} else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
1136
(MEI_FILE_CONNECTED == dev->iamthif_cl.state) &&
1137
(dev->iamthif_state == MEI_IAMTHIF_READING)) {
1138
dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n");
1139
dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
1141
ret = mei_irq_thread_read_amthi_message(cmpl_list,
1147
dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n");
1148
ret = mei_irq_thread_read_client_message(cmpl_list,
1155
/* reset the number of slots and header */
1156
*slots = mei_count_full_read_slots(dev);
1157
dev->rd_msg_hdr = 0;
1159
if (*slots == -EOVERFLOW) {
1160
/* overflow - reset */
1161
dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n");
1162
/* set the event since message has been read */
1172
* mei_irq_thread_write_handler - bottom half write routine after
1173
* ISR to handle the write processing.
1175
* @cmpl_list: An instance of our list structure
1176
* @dev: the device structure
1177
* @slots: slots to write.
1179
* returns 0 on success, <0 on failure.
1181
static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
1182
struct mei_device *dev,
1187
struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
1188
struct mei_io_list *list;
1191
if (!mei_host_buffer_is_empty(dev)) {
1192
dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
1195
dev->write_hang = -1;
1196
*slots = mei_count_empty_write_slots(dev);
1197
/* complete all waiting for write CB */
1198
dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
1200
list = &dev->write_waiting_list;
1201
if (!list->status && !list_empty(&list->mei_cb.cb_list)) {
1202
list_for_each_entry_safe(cb_pos, cb_next,
1203
&list->mei_cb.cb_list, cb_list) {
1204
cl = (struct mei_cl *)cb_pos->file_private;
1207
list_del(&cb_pos->cb_list);
1208
if (MEI_WRITING == cl->writing_state &&
1209
(cb_pos->major_file_operations ==
1211
(cl != &dev->iamthif_cl)) {
1212
dev_dbg(&dev->pdev->dev,
1213
"MEI WRITE COMPLETE\n");
1216
list_add_tail(&cb_pos->cb_list,
1217
&cmpl_list->mei_cb.cb_list);
1219
if (cl == &dev->iamthif_cl) {
1220
dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
1221
if (dev->iamthif_flow_control_pending) {
1223
_mei_irq_thread_iamthif_read(
1234
if (dev->stop && !dev->wd_pending) {
1235
dev->wd_stopped = 1;
1236
wake_up_interruptible(&dev->wait_stop_wd);
1240
if (dev->extra_write_index) {
1241
dev_dbg(&dev->pdev->dev, "extra_write_index =%d.\n",
1242
dev->extra_write_index);
1243
mei_write_message(dev,
1244
(struct mei_msg_hdr *) &dev->ext_msg_buf[0],
1245
(unsigned char *) &dev->ext_msg_buf[1],
1246
(dev->extra_write_index - 1) * sizeof(u32));
1247
*slots -= dev->extra_write_index;
1248
dev->extra_write_index = 0;
1250
if (dev->mei_state == MEI_ENABLED) {
1251
if (dev->wd_pending &&
1252
mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
1253
if (mei_wd_send(dev))
1254
dev_dbg(&dev->pdev->dev, "wd send failed.\n");
1256
if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
1259
dev->wd_pending = 0;
1261
if (dev->wd_timeout) {
1262
*slots -= (sizeof(struct mei_msg_hdr) +
1263
MEI_START_WD_DATA_SIZE + 3) / 4;
1264
dev->wd_due_counter = 2;
1266
*slots -= (sizeof(struct mei_msg_hdr) +
1267
MEI_WD_PARAMS_SIZE + 3) / 4;
1268
dev->wd_due_counter = 0;
1276
/* complete control write list CB */
1277
if (!dev->ctrl_wr_list.status) {
1278
/* complete control write list CB */
1279
dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
1280
list_for_each_entry_safe(cb_pos, cb_next,
1281
&dev->ctrl_wr_list.mei_cb.cb_list, cb_list) {
1282
cl = (struct mei_cl *)
1283
cb_pos->file_private;
1285
list_del(&cb_pos->cb_list);
1288
switch (cb_pos->major_file_operations) {
1290
/* send disconnect message */
1291
ret = _mei_irq_thread_close(dev, slots,
1292
cb_pos, cl, cmpl_list);
1298
/* send flow control message */
1299
ret = _mei_irq_thread_read(dev, slots,
1300
cb_pos, cl, cmpl_list);
1306
/* connect message */
1307
if (!mei_other_client_is_connecting(dev,
1310
ret = _mei_irq_thread_ioctl(dev, slots,
1311
cb_pos, cl, cmpl_list);
1323
/* complete write list CB */
1324
if (!dev->write_list.status &&
1325
!list_empty(&dev->write_list.mei_cb.cb_list)) {
1326
dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
1327
list_for_each_entry_safe(cb_pos, cb_next,
1328
&dev->write_list.mei_cb.cb_list, cb_list) {
1329
cl = (struct mei_cl *)cb_pos->file_private;
1332
if (cl != &dev->iamthif_cl) {
1333
if (!mei_flow_ctrl_creds(dev,
1335
dev_dbg(&dev->pdev->dev,
1337
" credentials for client"
1338
" %d, not sending.\n",
1339
cl->host_client_id);
1342
ret = _mei_irq_thread_cmpl(dev, slots,
1348
} else if (cl == &dev->iamthif_cl) {
1350
dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n");
1351
if (!mei_flow_ctrl_creds(dev,
1353
dev_dbg(&dev->pdev->dev,
1355
" credentials for amthi"
1357
cl->host_client_id);
1360
ret = _mei_irq_thread_cmpl_iamthif(dev,
1379
* mei_timer - timer function.
1381
* @work: pointer to the work_struct structure
1383
* NOTE: This function is called by timer interrupt work
1385
void mei_wd_timer(struct work_struct *work)
1387
unsigned long timeout;
1388
struct mei_cl *cl_pos = NULL;
1389
struct mei_cl *cl_next = NULL;
1390
struct list_head *amthi_complete_list = NULL;
1391
struct mei_cl_cb *cb_pos = NULL;
1392
struct mei_cl_cb *cb_next = NULL;
1394
struct mei_device *dev = container_of(work,
1395
struct mei_device, wd_work.work);
1398
mutex_lock(&dev->device_lock);
1399
if (dev->mei_state != MEI_ENABLED) {
1400
if (dev->mei_state == MEI_INIT_CLIENTS) {
1401
if (dev->init_clients_timer) {
1402
if (--dev->init_clients_timer == 0) {
1403
dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n",
1404
dev->init_clients_state);
1411
/*** connect/disconnect timeouts ***/
1412
list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
1413
if (cl_pos->timer_count) {
1414
if (--cl_pos->timer_count == 0) {
1415
dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n");
1422
if (dev->wd_cl.state != MEI_FILE_CONNECTED)
1426
if (dev->wd_due_counter && !dev->wd_bypass) {
1427
if (--dev->wd_due_counter == 0) {
1428
if (dev->mei_host_buffer_is_empty &&
1429
mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
1430
dev->mei_host_buffer_is_empty = 0;
1431
dev_dbg(&dev->pdev->dev, "send watchdog.\n");
1433
if (mei_wd_send(dev))
1434
dev_dbg(&dev->pdev->dev, "wd send failed.\n");
1436
if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
1439
if (dev->wd_timeout)
1440
dev->wd_due_counter = 2;
1442
dev->wd_due_counter = 0;
1445
dev->wd_pending = 1;
1449
if (dev->iamthif_stall_timer) {
1450
if (--dev->iamthif_stall_timer == 0) {
1451
dev_dbg(&dev->pdev->dev, "reseting because of hang to amthi.\n");
1453
dev->iamthif_msg_buf_size = 0;
1454
dev->iamthif_msg_buf_index = 0;
1455
dev->iamthif_canceled = 0;
1456
dev->iamthif_ioctl = 1;
1457
dev->iamthif_state = MEI_IAMTHIF_IDLE;
1458
dev->iamthif_timer = 0;
1460
if (dev->iamthif_current_cb)
1461
mei_free_cb_private(dev->iamthif_current_cb);
1463
dev->iamthif_file_object = NULL;
1464
dev->iamthif_current_cb = NULL;
1465
run_next_iamthif_cmd(dev);
1469
if (dev->iamthif_timer) {
1471
timeout = dev->iamthif_timer +
1472
msecs_to_jiffies(IAMTHIF_READ_TIMER);
1474
dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
1475
dev->iamthif_timer);
1476
dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout);
1477
dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies);
1478
if (time_after(jiffies, timeout)) {
1480
* User didn't read the AMTHI data on time (15sec)
1481
* freeing AMTHI for other requests
1484
dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n");
1486
amthi_complete_list = &dev->amthi_read_complete_list.
1489
if (!list_empty(amthi_complete_list)) {
1491
list_for_each_entry_safe(cb_pos, cb_next,
1492
amthi_complete_list,
1495
cl_pos = cb_pos->file_object->private_data;
1497
/* Finding the AMTHI entry. */
1498
if (cl_pos == &dev->iamthif_cl)
1499
list_del(&cb_pos->cb_list);
1502
if (dev->iamthif_current_cb)
1503
mei_free_cb_private(dev->iamthif_current_cb);
1505
dev->iamthif_file_object->private_data = NULL;
1506
dev->iamthif_file_object = NULL;
1507
dev->iamthif_current_cb = NULL;
1508
dev->iamthif_timer = 0;
1509
run_next_iamthif_cmd(dev);
1514
schedule_delayed_work(&dev->wd_work, 2 * HZ);
1515
mutex_unlock(&dev->device_lock);
1519
* mei_interrupt_thread_handler - function called after ISR to handle the interrupt
1522
* @irq: The irq number
1523
* @dev_id: pointer to the device structure
1525
* returns irqreturn_t
1528
irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
1530
struct mei_device *dev = (struct mei_device *) dev_id;
1531
struct mei_io_list complete_list;
1532
struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
1536
bool bus_message_received;
1539
dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n");
1540
/* initialize our complete list */
1541
mutex_lock(&dev->device_lock);
1542
mei_initialize_list(&complete_list, dev);
1543
dev->host_hw_state = mei_hcsr_read(dev);
1544
dev->me_hw_state = mei_mecsr_read(dev);
1546
/* check if ME wants a reset */
1547
if ((dev->me_hw_state & ME_RDY_HRA) == 0 &&
1548
dev->mei_state != MEI_RESETING &&
1549
dev->mei_state != MEI_INITIALIZING) {
1550
dev_dbg(&dev->pdev->dev, "FW not ready.\n");
1552
mutex_unlock(&dev->device_lock);
1556
/* check if we need to start the dev */
1557
if ((dev->host_hw_state & H_RDY) == 0) {
1558
if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) {
1559
dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
1560
dev->host_hw_state |= (H_IE | H_IG | H_RDY);
1562
dev->mei_state = MEI_INIT_CLIENTS;
1563
dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
1564
/* link is established
1565
* start sending messages.
1567
host_start_message(dev);
1568
mutex_unlock(&dev->device_lock);
1571
dev_dbg(&dev->pdev->dev, "FW not ready.\n");
1572
mutex_unlock(&dev->device_lock);
1576
/* check slots avalable for reading */
1577
slots = mei_count_full_read_slots(dev);
1578
dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n",
1579
slots, dev->extra_write_index);
1580
while (slots > 0 && !dev->extra_write_index) {
1581
dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n",
1582
slots, dev->extra_write_index);
1583
dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n");
1584
rets = mei_irq_thread_read_handler(&complete_list, dev, &slots);
1588
rets = mei_irq_thread_write_handler(&complete_list, dev, &slots);
1590
dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
1591
dev->host_hw_state = mei_hcsr_read(dev);
1592
dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev);
1594
bus_message_received = false;
1595
if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
1596
dev_dbg(&dev->pdev->dev, "received waiting bus message\n");
1597
bus_message_received = true;
1599
mutex_unlock(&dev->device_lock);
1600
if (bus_message_received) {
1601
dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n");
1602
wake_up_interruptible(&dev->wait_recvd_msg);
1603
bus_message_received = false;
1605
if (complete_list.status || list_empty(&complete_list.mei_cb.cb_list))
1609
list_for_each_entry_safe(cb_pos, cb_next,
1610
&complete_list.mei_cb.cb_list, cb_list) {
1611
cl = (struct mei_cl *)cb_pos->file_private;
1612
list_del(&cb_pos->cb_list);
1614
if (cl != &dev->iamthif_cl) {
1615
dev_dbg(&dev->pdev->dev, "completing call back.\n");
1616
_mei_cmpl(cl, cb_pos);
1618
} else if (cl == &dev->iamthif_cl) {
1619
_mei_cmpl_iamthif(dev, cb_pos);