320ebd2f06cefbbac7e03bc5ad867d1df86b7887
[firefly-linux-kernel-4.4.55.git] / drivers / misc / mei / interrupt.c
1 /*
2  *
3  * Intel Management Engine Interface (Intel MEI) Linux driver
4  * Copyright (c) 2003-2012, Intel Corporation.
5  *
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.
9  *
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
13  * more details.
14  *
15  */
16
17
18 #include <linux/pci.h>
19 #include <linux/kthread.h>
20 #include <linux/interrupt.h>
21 #include <linux/fs.h>
22 #include <linux/jiffies.h>
23
24 #include "mei_dev.h"
25 #include <linux/mei.h>
26 #include "hw.h"
27 #include "interface.h"
28
29
30 /**
31  * mei_interrupt_quick_handler - The ISR of the MEI device
32  *
33  * @irq: The irq number
34  * @dev_id: pointer to the device structure
35  *
36  * returns irqreturn_t
37  */
38 irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id)
39 {
40         struct mei_device *dev = (struct mei_device *) dev_id;
41         u32 csr_reg = mei_hcsr_read(dev);
42
43         if ((csr_reg & H_IS) != H_IS)
44                 return IRQ_NONE;
45
46         /* clear H_IS bit in H_CSR */
47         mei_reg_write(dev, H_CSR, csr_reg);
48
49         return IRQ_WAKE_THREAD;
50 }
51
52 /**
53  * _mei_cmpl - processes completed operation.
54  *
55  * @cl: private data of the file object.
56  * @cb_pos: callback block.
57  */
58 static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos)
59 {
60         if (cb_pos->major_file_operations == MEI_WRITE) {
61                 mei_free_cb_private(cb_pos);
62                 cb_pos = NULL;
63                 cl->writing_state = MEI_WRITE_COMPLETE;
64                 if (waitqueue_active(&cl->tx_wait))
65                         wake_up_interruptible(&cl->tx_wait);
66
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);
72
73         }
74 }
75
76 /**
77  * _mei_cmpl_iamthif - processes completed iamthif operation.
78  *
79  * @dev: the device structure.
80  * @cb_pos: callback block.
81  */
82 static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos)
83 {
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,
88                                 dev->iamthif_msg_buf,
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",
95                                 dev->iamthif_timer);
96         } else {
97                 mei_run_next_iamthif_cmd(dev);
98         }
99
100         dev_dbg(&dev->pdev->dev, "completing amthi call back.\n");
101         wake_up_interruptible(&dev->iamthif_cl.wait);
102 }
103
104
105 /**
106  * mei_irq_thread_read_amthi_message - bottom half read routine after ISR to
107  * handle the read amthi message data processing.
108  *
109  * @complete_list: An instance of our list structure
110  * @dev: the device structure
111  * @mei_hdr: header of amthi message
112  *
113  * returns 0 on success, <0 on failure.
114  */
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)
118 {
119         struct mei_cl *cl;
120         struct mei_cl_cb *cb;
121         unsigned char *buffer;
122
123         BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id);
124         BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING);
125
126         buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index;
127         BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length);
128
129         mei_read_slots(dev, buffer, mei_hdr->length);
130
131         dev->iamthif_msg_buf_index += mei_hdr->length;
132
133         if (!mei_hdr->msg_complete)
134                 return 0;
135
136         dev_dbg(&dev->pdev->dev,
137                         "amthi_message_buffer_index =%d\n",
138                         mei_hdr->length);
139
140         dev_dbg(&dev->pdev->dev, "completed amthi read.\n ");
141         if (!dev->iamthif_current_cb)
142                 return -ENODEV;
143
144         cb = dev->iamthif_current_cb;
145         dev->iamthif_current_cb = NULL;
146
147         cl = (struct mei_cl *)cb->file_private;
148         if (!cl)
149                 return -ENODEV;
150
151         dev->iamthif_stall_timer = 0;
152         cb->buf_idx = dev->iamthif_msg_buf_index;
153         cb->read_time = jiffies;
154         if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) {
155                 /* found the iamthif cb */
156                 dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n ");
157                 dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n ");
158                 list_add_tail(&cb->cb_list,
159                                                 &complete_list->mei_cb.cb_list);
160         }
161         return 0;
162 }
163
164 /**
165  * _mei_irq_thread_state_ok - checks if mei header matches file private data
166  *
167  * @cl: private data of the file object
168  * @mei_hdr: header of mei client message
169  *
170  * returns !=0 if matches, 0 if no match.
171  */
172 static int _mei_irq_thread_state_ok(struct mei_cl *cl,
173                                 struct mei_msg_hdr *mei_hdr)
174 {
175         return (cl->host_client_id == mei_hdr->host_addr &&
176                 cl->me_client_id == mei_hdr->me_addr &&
177                 cl->state == MEI_FILE_CONNECTED &&
178                 MEI_READ_COMPLETE != cl->reading_state);
179 }
180
181 /**
182  * mei_irq_thread_read_client_message - bottom half read routine after ISR to
183  * handle the read mei client message data processing.
184  *
185  * @complete_list: An instance of our list structure
186  * @dev: the device structure
187  * @mei_hdr: header of mei client message
188  *
189  * returns 0 on success, <0 on failure.
190  */
191 static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list,
192                 struct mei_device *dev,
193                 struct mei_msg_hdr *mei_hdr)
194 {
195         struct mei_cl *cl;
196         struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
197         unsigned char *buffer = NULL;
198
199         dev_dbg(&dev->pdev->dev, "start client msg\n");
200         if (list_empty(&dev->read_list.mei_cb.cb_list))
201                 goto quit;
202
203         list_for_each_entry_safe(cb_pos, cb_next,
204                         &dev->read_list.mei_cb.cb_list, cb_list) {
205                 cl = (struct mei_cl *)cb_pos->file_private;
206                 if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) {
207                         cl->reading_state = MEI_READING;
208                         buffer = cb_pos->response_buffer.data + cb_pos->buf_idx;
209
210                         if (cb_pos->response_buffer.size <
211                                         mei_hdr->length + cb_pos->buf_idx) {
212                                 dev_dbg(&dev->pdev->dev, "message overflow.\n");
213                                 list_del(&cb_pos->cb_list);
214                                 return -ENOMEM;
215                         }
216                         if (buffer)
217                                 mei_read_slots(dev, buffer, mei_hdr->length);
218
219                         cb_pos->buf_idx += mei_hdr->length;
220                         if (mei_hdr->msg_complete) {
221                                 cl->status = 0;
222                                 list_del(&cb_pos->cb_list);
223                                 dev_dbg(&dev->pdev->dev,
224                                         "completed read H cl = %d, ME cl = %d, length = %lu\n",
225                                         cl->host_client_id,
226                                         cl->me_client_id,
227                                         cb_pos->buf_idx);
228
229                                 list_add_tail(&cb_pos->cb_list,
230                                         &complete_list->mei_cb.cb_list);
231                         }
232
233                         break;
234                 }
235
236         }
237
238 quit:
239         dev_dbg(&dev->pdev->dev, "message read\n");
240         if (!buffer) {
241                 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
242                 dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n",
243                                 *(u32 *) dev->rd_msg_buf);
244         }
245
246         return 0;
247 }
248
249 /**
250  * _mei_irq_thread_iamthif_read - prepares to read iamthif data.
251  *
252  * @dev: the device structure.
253  * @slots: free slots.
254  *
255  * returns 0, OK; otherwise, error.
256  */
257 static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots)
258 {
259
260         if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr)
261                         + sizeof(struct hbm_flow_control))) {
262                 return -EMSGSIZE;
263         }
264         *slots -= mei_data2slots(sizeof(struct hbm_flow_control));
265         if (mei_send_flow_control(dev, &dev->iamthif_cl)) {
266                 dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n");
267                 return -EIO;
268         }
269
270         dev_dbg(&dev->pdev->dev, "iamthif flow control success\n");
271         dev->iamthif_state = MEI_IAMTHIF_READING;
272         dev->iamthif_flow_control_pending = false;
273         dev->iamthif_msg_buf_index = 0;
274         dev->iamthif_msg_buf_size = 0;
275         dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER;
276         dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
277         return 0;
278 }
279
280 /**
281  * _mei_irq_thread_close - processes close related operation.
282  *
283  * @dev: the device structure.
284  * @slots: free slots.
285  * @cb_pos: callback block.
286  * @cl: private data of the file object.
287  * @cmpl_list: complete list.
288  *
289  * returns 0, OK; otherwise, error.
290  */
291 static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
292                                 struct mei_cl_cb *cb_pos,
293                                 struct mei_cl *cl,
294                                 struct mei_io_list *cmpl_list)
295 {
296         if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
297                         sizeof(struct hbm_client_disconnect_request)))
298                 return -EBADMSG;
299
300         *slots -= mei_data2slots(sizeof(struct hbm_client_disconnect_request));
301
302         if (mei_disconnect(dev, cl)) {
303                 cl->status = 0;
304                 cb_pos->buf_idx = 0;
305                 list_move_tail(&cb_pos->cb_list,
306                                 &cmpl_list->mei_cb.cb_list);
307                 return -EMSGSIZE;
308         } else {
309                 cl->state = MEI_FILE_DISCONNECTING;
310                 cl->status = 0;
311                 cb_pos->buf_idx = 0;
312                 list_move_tail(&cb_pos->cb_list,
313                                 &dev->ctrl_rd_list.mei_cb.cb_list);
314                 cl->timer_count = MEI_CONNECT_TIMEOUT;
315         }
316
317         return 0;
318 }
319
320 /**
321  * is_treat_specially_client - checks if the message belongs
322  * to the file private data.
323  *
324  * @cl: private data of the file object
325  * @rs: connect response bus message
326  *
327  */
328 static bool is_treat_specially_client(struct mei_cl *cl,
329                 struct hbm_client_connect_response *rs)
330 {
331
332         if (cl->host_client_id == rs->host_addr &&
333             cl->me_client_id == rs->me_addr) {
334                 if (!rs->status) {
335                         cl->state = MEI_FILE_CONNECTED;
336                         cl->status = 0;
337
338                 } else {
339                         cl->state = MEI_FILE_DISCONNECTED;
340                         cl->status = -ENODEV;
341                 }
342                 cl->timer_count = 0;
343
344                 return true;
345         }
346         return false;
347 }
348
349 /**
350  * mei_client_connect_response - connects to response irq routine
351  *
352  * @dev: the device structure
353  * @rs: connect response bus message
354  */
355 static void mei_client_connect_response(struct mei_device *dev,
356                 struct hbm_client_connect_response *rs)
357 {
358
359         struct mei_cl *cl;
360         struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
361
362         dev_dbg(&dev->pdev->dev,
363                         "connect_response:\n"
364                         "ME Client = %d\n"
365                         "Host Client = %d\n"
366                         "Status = %d\n",
367                         rs->me_addr,
368                         rs->host_addr,
369                         rs->status);
370
371         /* if WD or iamthif client treat specially */
372
373         if (is_treat_specially_client(&(dev->wd_cl), rs)) {
374                 dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
375                 mei_watchdog_register(dev);
376
377                 /* next step in the state maching */
378                 mei_host_init_iamthif(dev);
379                 return;
380         }
381
382         if (is_treat_specially_client(&(dev->iamthif_cl), rs)) {
383                 dev->iamthif_state = MEI_IAMTHIF_IDLE;
384                 return;
385         }
386         list_for_each_entry_safe(cb_pos, cb_next,
387                                 &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
388
389                 cl = (struct mei_cl *)cb_pos->file_private;
390                 if (!cl) {
391                         list_del(&cb_pos->cb_list);
392                         return;
393                 }
394                 if (MEI_IOCTL == cb_pos->major_file_operations) {
395                         if (is_treat_specially_client(cl, rs)) {
396                                 list_del(&cb_pos->cb_list);
397                                 cl->status = 0;
398                                 cl->timer_count = 0;
399                                 break;
400                         }
401                 }
402         }
403 }
404
405 /**
406  * mei_client_disconnect_response - disconnects from response irq routine
407  *
408  * @dev: the device structure
409  * @rs: disconnect response bus message
410  */
411 static void mei_client_disconnect_response(struct mei_device *dev,
412                                         struct hbm_client_connect_response *rs)
413 {
414         struct mei_cl *cl;
415         struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
416
417         dev_dbg(&dev->pdev->dev,
418                         "disconnect_response:\n"
419                         "ME Client = %d\n"
420                         "Host Client = %d\n"
421                         "Status = %d\n",
422                         rs->me_addr,
423                         rs->host_addr,
424                         rs->status);
425
426         list_for_each_entry_safe(cb_pos, cb_next,
427                         &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
428                 cl = (struct mei_cl *)cb_pos->file_private;
429
430                 if (!cl) {
431                         list_del(&cb_pos->cb_list);
432                         return;
433                 }
434
435                 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
436                 if (cl->host_client_id == rs->host_addr &&
437                     cl->me_client_id == rs->me_addr) {
438
439                         list_del(&cb_pos->cb_list);
440                         if (!rs->status)
441                                 cl->state = MEI_FILE_DISCONNECTED;
442
443                         cl->status = 0;
444                         cl->timer_count = 0;
445                         break;
446                 }
447         }
448 }
449
450 /**
451  * same_flow_addr - tells if they have the same address.
452  *
453  * @file: private data of the file object.
454  * @flow: flow control.
455  *
456  * returns  !=0, same; 0,not.
457  */
458 static int same_flow_addr(struct mei_cl *cl, struct hbm_flow_control *flow)
459 {
460         return (cl->host_client_id == flow->host_addr &&
461                 cl->me_client_id == flow->me_addr);
462 }
463
464 /**
465  * add_single_flow_creds - adds single buffer credentials.
466  *
467  * @file: private data ot the file object.
468  * @flow: flow control.
469  */
470 static void add_single_flow_creds(struct mei_device *dev,
471                                   struct hbm_flow_control *flow)
472 {
473         struct mei_me_client *client;
474         int i;
475
476         for (i = 0; i < dev->me_clients_num; i++) {
477                 client = &dev->me_clients[i];
478                 if (client && flow->me_addr == client->client_id) {
479                         if (client->props.single_recv_buf) {
480                                 client->mei_flow_ctrl_creds++;
481                                 dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n",
482                                     flow->me_addr);
483                                 dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n",
484                                     client->mei_flow_ctrl_creds);
485                         } else {
486                                 BUG();  /* error in flow control */
487                         }
488                 }
489         }
490 }
491
492 /**
493  * mei_client_flow_control_response - flow control response irq routine
494  *
495  * @dev: the device structure
496  * @flow_control: flow control response bus message
497  */
498 static void mei_client_flow_control_response(struct mei_device *dev,
499                 struct hbm_flow_control *flow_control)
500 {
501         struct mei_cl *cl_pos = NULL;
502         struct mei_cl *cl_next = NULL;
503
504         if (!flow_control->host_addr) {
505                 /* single receive buffer */
506                 add_single_flow_creds(dev, flow_control);
507         } else {
508                 /* normal connection */
509                 list_for_each_entry_safe(cl_pos, cl_next,
510                                 &dev->file_list, link) {
511                         dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in file_list\n");
512
513                         dev_dbg(&dev->pdev->dev, "cl of host client %d ME client %d.\n",
514                             cl_pos->host_client_id,
515                             cl_pos->me_client_id);
516                         dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n",
517                             flow_control->host_addr,
518                             flow_control->me_addr);
519                         if (same_flow_addr(cl_pos, flow_control)) {
520                                 dev_dbg(&dev->pdev->dev, "recv ctrl msg for host  %d ME %d.\n",
521                                     flow_control->host_addr,
522                                     flow_control->me_addr);
523                                 cl_pos->mei_flow_ctrl_creds++;
524                                 dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n",
525                                     cl_pos->mei_flow_ctrl_creds);
526                                 break;
527                         }
528                 }
529         }
530 }
531
532 /**
533  * same_disconn_addr - tells if they have the same address
534  *
535  * @file: private data of the file object.
536  * @disconn: disconnection request.
537  *
538  * returns !=0, same; 0,not.
539  */
540 static int same_disconn_addr(struct mei_cl *cl,
541                              struct hbm_client_disconnect_request *disconn)
542 {
543         return (cl->host_client_id == disconn->host_addr &&
544                 cl->me_client_id == disconn->me_addr);
545 }
546
547 /**
548  * mei_client_disconnect_request - disconnects from request irq routine
549  *
550  * @dev: the device structure.
551  * @disconnect_req: disconnect request bus message.
552  */
553 static void mei_client_disconnect_request(struct mei_device *dev,
554                 struct hbm_client_disconnect_request *disconnect_req)
555 {
556         struct mei_msg_hdr *mei_hdr;
557         struct hbm_client_connect_response *disconnect_res;
558         struct mei_cl *cl_pos = NULL;
559         struct mei_cl *cl_next = NULL;
560
561         list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
562                 if (same_disconn_addr(cl_pos, disconnect_req)) {
563                         dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n",
564                                         disconnect_req->host_addr,
565                                         disconnect_req->me_addr);
566                         cl_pos->state = MEI_FILE_DISCONNECTED;
567                         cl_pos->timer_count = 0;
568                         if (cl_pos == &dev->wd_cl)
569                                 dev->wd_pending = false;
570                         else if (cl_pos == &dev->iamthif_cl)
571                                 dev->iamthif_timer = 0;
572
573                         /* prepare disconnect response */
574                         mei_hdr =
575                                 (struct mei_msg_hdr *) &dev->ext_msg_buf[0];
576                         mei_hdr->host_addr = 0;
577                         mei_hdr->me_addr = 0;
578                         mei_hdr->length =
579                                 sizeof(struct hbm_client_connect_response);
580                         mei_hdr->msg_complete = 1;
581                         mei_hdr->reserved = 0;
582
583                         disconnect_res =
584                                 (struct hbm_client_connect_response *)
585                                 &dev->ext_msg_buf[1];
586                         disconnect_res->host_addr = cl_pos->host_client_id;
587                         disconnect_res->me_addr = cl_pos->me_client_id;
588                         disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD;
589                         disconnect_res->status = 0;
590                         dev->extra_write_index = 2;
591                         break;
592                 }
593         }
594 }
595
596
597 /**
598  * mei_irq_thread_read_bus_message - bottom half read routine after ISR to
599  * handle the read bus message cmd processing.
600  *
601  * @dev: the device structure
602  * @mei_hdr: header of bus message
603  */
604 static void mei_irq_thread_read_bus_message(struct mei_device *dev,
605                 struct mei_msg_hdr *mei_hdr)
606 {
607         struct mei_bus_message *mei_msg;
608         struct hbm_host_version_response *version_res;
609         struct hbm_client_connect_response *connect_res;
610         struct hbm_client_connect_response *disconnect_res;
611         struct hbm_flow_control *flow_control;
612         struct hbm_props_response *props_res;
613         struct hbm_host_enum_response *enum_res;
614         struct hbm_client_disconnect_request *disconnect_req;
615         struct hbm_host_stop_request *host_stop_req;
616         int res;
617
618
619         /* read the message to our buffer */
620         BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf));
621         mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
622         mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;
623
624         switch (mei_msg->hbm_cmd) {
625         case HOST_START_RES_CMD:
626                 version_res = (struct hbm_host_version_response *) mei_msg;
627                 if (version_res->host_version_supported) {
628                         dev->version.major_version = HBM_MAJOR_VERSION;
629                         dev->version.minor_version = HBM_MINOR_VERSION;
630                         if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
631                             dev->init_clients_state == MEI_START_MESSAGE) {
632                                 dev->init_clients_timer = 0;
633                                 mei_host_enum_clients_message(dev);
634                         } else {
635                                 dev->recvd_msg = false;
636                                 dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n");
637                                 mei_reset(dev, 1);
638                                 return;
639                         }
640                 } else {
641                         dev->version = version_res->me_max_version;
642                         /* send stop message */
643                         mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
644                         mei_hdr->host_addr = 0;
645                         mei_hdr->me_addr = 0;
646                         mei_hdr->length = sizeof(struct hbm_host_stop_request);
647                         mei_hdr->msg_complete = 1;
648                         mei_hdr->reserved = 0;
649
650                         host_stop_req = (struct hbm_host_stop_request *)
651                                                         &dev->wr_msg_buf[1];
652
653                         memset(host_stop_req,
654                                         0,
655                                         sizeof(struct hbm_host_stop_request));
656                         host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
657                         host_stop_req->reason = DRIVER_STOP_REQUEST;
658                         mei_write_message(dev, mei_hdr,
659                                            (unsigned char *) (host_stop_req),
660                                            mei_hdr->length);
661                         dev_dbg(&dev->pdev->dev, "version mismatch.\n");
662                         return;
663                 }
664
665                 dev->recvd_msg = true;
666                 dev_dbg(&dev->pdev->dev, "host start response message received.\n");
667                 break;
668
669         case CLIENT_CONNECT_RES_CMD:
670                 connect_res =
671                         (struct hbm_client_connect_response *) mei_msg;
672                 mei_client_connect_response(dev, connect_res);
673                 dev_dbg(&dev->pdev->dev, "client connect response message received.\n");
674                 wake_up(&dev->wait_recvd_msg);
675                 break;
676
677         case CLIENT_DISCONNECT_RES_CMD:
678                 disconnect_res =
679                         (struct hbm_client_connect_response *) mei_msg;
680                 mei_client_disconnect_response(dev, disconnect_res);
681                 dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
682                 wake_up(&dev->wait_recvd_msg);
683                 break;
684
685         case MEI_FLOW_CONTROL_CMD:
686                 flow_control = (struct hbm_flow_control *) mei_msg;
687                 mei_client_flow_control_response(dev, flow_control);
688                 dev_dbg(&dev->pdev->dev, "client flow control response message received.\n");
689                 break;
690
691         case HOST_CLIENT_PROPERTIES_RES_CMD:
692                 props_res = (struct hbm_props_response *)mei_msg;
693                 if (props_res->status || !dev->me_clients) {
694                         dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
695                         mei_reset(dev, 1);
696                         return;
697                 }
698                 if (dev->me_clients[dev->me_client_presentation_num]
699                                         .client_id == props_res->address) {
700
701                         dev->me_clients[dev->me_client_presentation_num].props
702                                                 = props_res->client_properties;
703
704                         if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
705                             dev->init_clients_state ==
706                                         MEI_CLIENT_PROPERTIES_MESSAGE) {
707                                 dev->me_client_index++;
708                                 dev->me_client_presentation_num++;
709
710                                 /** Send Client Properties request **/
711                                 res = mei_host_client_properties(dev);
712                                 if (res < 0) {
713                                         dev_dbg(&dev->pdev->dev, "mei_host_client_properties() failed");
714                                         return;
715                                 } else if (!res) {
716                                         /*
717                                          * No more clients to send to.
718                                          * Clear Map for indicating now ME clients
719                                          * with associated host client
720                                          */
721                                         bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
722                                         dev->open_handle_count = 0;
723
724                                         /*
725                                          * Reserving the first three client IDs
726                                          * Client Id 0 - Reserved for MEI Bus Message communications
727                                          * Client Id 1 - Reserved for Watchdog
728                                          * Client ID 2 - Reserved for AMTHI
729                                          */
730                                         bitmap_set(dev->host_clients_map, 0, 3);
731                                         dev->dev_state = MEI_DEV_ENABLED;
732
733                                         /* if wd initialization fails, initialization the AMTHI client,
734                                          * otherwise the AMTHI client will be initialized after the WD client connect response
735                                          * will be received
736                                          */
737                                         if (mei_wd_host_init(dev))
738                                                 mei_host_init_iamthif(dev);
739                                 }
740
741                         } else {
742                                 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message");
743                                 mei_reset(dev, 1);
744                                 return;
745                         }
746                 } else {
747                         dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n");
748                         mei_reset(dev, 1);
749                         return;
750                 }
751                 break;
752
753         case HOST_ENUM_RES_CMD:
754                 enum_res = (struct hbm_host_enum_response *) mei_msg;
755                 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
756                 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
757                     dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) {
758                                 dev->init_clients_timer = 0;
759                                 dev->me_client_presentation_num = 0;
760                                 dev->me_client_index = 0;
761                                 mei_allocate_me_clients_storage(dev);
762                                 dev->init_clients_state =
763                                         MEI_CLIENT_PROPERTIES_MESSAGE;
764                                 mei_host_client_properties(dev);
765                 } else {
766                         dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
767                         mei_reset(dev, 1);
768                         return;
769                 }
770                 break;
771
772         case HOST_STOP_RES_CMD:
773                 dev->dev_state = MEI_DEV_DISABLED;
774                 dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n");
775                 mei_reset(dev, 1);
776                 break;
777
778         case CLIENT_DISCONNECT_REQ_CMD:
779                 /* search for client */
780                 disconnect_req =
781                         (struct hbm_client_disconnect_request *) mei_msg;
782                 mei_client_disconnect_request(dev, disconnect_req);
783                 break;
784
785         case ME_STOP_REQ_CMD:
786                 /* prepare stop request */
787                 mei_hdr = (struct mei_msg_hdr *) &dev->ext_msg_buf[0];
788                 mei_hdr->host_addr = 0;
789                 mei_hdr->me_addr = 0;
790                 mei_hdr->length = sizeof(struct hbm_host_stop_request);
791                 mei_hdr->msg_complete = 1;
792                 mei_hdr->reserved = 0;
793                 host_stop_req =
794                         (struct hbm_host_stop_request *) &dev->ext_msg_buf[1];
795                 memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request));
796                 host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
797                 host_stop_req->reason = DRIVER_STOP_REQUEST;
798                 host_stop_req->reserved[0] = 0;
799                 host_stop_req->reserved[1] = 0;
800                 dev->extra_write_index = 2;
801                 break;
802
803         default:
804                 BUG();
805                 break;
806
807         }
808 }
809
810
811 /**
812  * _mei_hb_read - processes read related operation.
813  *
814  * @dev: the device structure.
815  * @slots: free slots.
816  * @cb_pos: callback block.
817  * @cl: private data of the file object.
818  * @cmpl_list: complete list.
819  *
820  * returns 0, OK; otherwise, error.
821  */
822 static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots,
823                         struct mei_cl_cb *cb_pos,
824                         struct mei_cl *cl,
825                         struct mei_io_list *cmpl_list)
826 {
827         if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
828                         sizeof(struct hbm_flow_control))) {
829                 /* return the cancel routine */
830                 list_del(&cb_pos->cb_list);
831                 return -EBADMSG;
832         }
833
834         *slots -= mei_data2slots(sizeof(struct hbm_flow_control));
835
836         if (mei_send_flow_control(dev, cl)) {
837                 cl->status = -ENODEV;
838                 cb_pos->buf_idx = 0;
839                 list_move_tail(&cb_pos->cb_list, &cmpl_list->mei_cb.cb_list);
840                 return -ENODEV;
841         }
842         list_move_tail(&cb_pos->cb_list, &dev->read_list.mei_cb.cb_list);
843
844         return 0;
845 }
846
847
848 /**
849  * _mei_irq_thread_ioctl - processes ioctl related operation.
850  *
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.
856  *
857  * returns 0, OK; otherwise, error.
858  */
859 static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
860                         struct mei_cl_cb *cb_pos,
861                         struct mei_cl *cl,
862                         struct mei_io_list *cmpl_list)
863 {
864         if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
865                         sizeof(struct hbm_client_connect_request))) {
866                 /* return the cancel routine */
867                 list_del(&cb_pos->cb_list);
868                 return -EBADMSG;
869         }
870
871         cl->state = MEI_FILE_CONNECTING;
872          *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request));
873         if (mei_connect(dev, cl)) {
874                 cl->status = -ENODEV;
875                 cb_pos->buf_idx = 0;
876                 list_del(&cb_pos->cb_list);
877                 return -ENODEV;
878         } else {
879                 list_move_tail(&cb_pos->cb_list,
880                         &dev->ctrl_rd_list.mei_cb.cb_list);
881                 cl->timer_count = MEI_CONNECT_TIMEOUT;
882         }
883         return 0;
884 }
885
886 /**
887  * _mei_irq_thread_cmpl - processes completed and no-iamthif operation.
888  *
889  * @dev: the device structure.
890  * @slots: free slots.
891  * @cb_pos: callback block.
892  * @cl: private data of the file object.
893  * @cmpl_list: complete list.
894  *
895  * returns 0, OK; otherwise, error.
896  */
897 static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots,
898                         struct mei_cl_cb *cb_pos,
899                         struct mei_cl *cl,
900                         struct mei_io_list *cmpl_list)
901 {
902         struct mei_msg_hdr *mei_hdr;
903
904         if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
905                         (cb_pos->request_buffer.size - cb_pos->buf_idx))) {
906                 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
907                 mei_hdr->host_addr = cl->host_client_id;
908                 mei_hdr->me_addr = cl->me_client_id;
909                 mei_hdr->length = cb_pos->request_buffer.size - cb_pos->buf_idx;
910                 mei_hdr->msg_complete = 1;
911                 mei_hdr->reserved = 0;
912                 dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d"
913                         "mei_hdr->msg_complete = %d\n",
914                                 cb_pos->request_buffer.size,
915                                 mei_hdr->msg_complete);
916                 dev_dbg(&dev->pdev->dev, "cb_pos->buf_idx  =%lu\n",
917                                 cb_pos->buf_idx);
918                 dev_dbg(&dev->pdev->dev, "mei_hdr->length  =%d\n",
919                                 mei_hdr->length);
920                 *slots -= mei_data2slots(mei_hdr->length);
921                 if (mei_write_message(dev, mei_hdr,
922                                 (unsigned char *)
923                                 (cb_pos->request_buffer.data +
924                                 cb_pos->buf_idx),
925                                 mei_hdr->length)) {
926                         cl->status = -ENODEV;
927                         list_move_tail(&cb_pos->cb_list,
928                                 &cmpl_list->mei_cb.cb_list);
929                         return -ENODEV;
930                 } else {
931                         if (mei_flow_ctrl_reduce(dev, cl))
932                                 return -ENODEV;
933                         cl->status = 0;
934                         cb_pos->buf_idx += mei_hdr->length;
935                         list_move_tail(&cb_pos->cb_list,
936                                 &dev->write_waiting_list.mei_cb.cb_list);
937                 }
938         } else if (*slots == dev->hbuf_depth) {
939                 /* buffer is still empty */
940                 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
941                 mei_hdr->host_addr = cl->host_client_id;
942                 mei_hdr->me_addr = cl->me_client_id;
943                 mei_hdr->length =
944                         (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
945                 mei_hdr->msg_complete = 0;
946                 mei_hdr->reserved = 0;
947                 *slots -= mei_data2slots(mei_hdr->length);
948                 if (mei_write_message(dev, mei_hdr,
949                                         (unsigned char *)
950                                         (cb_pos->request_buffer.data +
951                                         cb_pos->buf_idx),
952                                         mei_hdr->length)) {
953                         cl->status = -ENODEV;
954                         list_move_tail(&cb_pos->cb_list,
955                                 &cmpl_list->mei_cb.cb_list);
956                         return -ENODEV;
957                 } else {
958                         cb_pos->buf_idx += mei_hdr->length;
959                         dev_dbg(&dev->pdev->dev,
960                                         "cb_pos->request_buffer.size =%d"
961                                         " mei_hdr->msg_complete = %d\n",
962                                         cb_pos->request_buffer.size,
963                                         mei_hdr->msg_complete);
964                         dev_dbg(&dev->pdev->dev, "cb_pos->buf_idx  =%lu\n",
965                                         cb_pos->buf_idx);
966                         dev_dbg(&dev->pdev->dev, "mei_hdr->length  =%d\n",
967                                         mei_hdr->length);
968                 }
969                 return -EMSGSIZE;
970         } else {
971                 return -EBADMSG;
972         }
973
974         return 0;
975 }
976
977 /**
978  * _mei_irq_thread_cmpl_iamthif - processes completed iamthif operation.
979  *
980  * @dev: the device structure.
981  * @slots: free slots.
982  * @cb_pos: callback block.
983  * @cl: private data of the file object.
984  * @cmpl_list: complete list.
985  *
986  * returns 0, OK; otherwise, error.
987  */
988 static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots,
989                         struct mei_cl_cb *cb_pos,
990                         struct mei_cl *cl,
991                         struct mei_io_list *cmpl_list)
992 {
993         struct mei_msg_hdr *mei_hdr;
994
995         if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
996                         dev->iamthif_msg_buf_size -
997                         dev->iamthif_msg_buf_index)) {
998                 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
999                 mei_hdr->host_addr = cl->host_client_id;
1000                 mei_hdr->me_addr = cl->me_client_id;
1001                 mei_hdr->length = dev->iamthif_msg_buf_size -
1002                         dev->iamthif_msg_buf_index;
1003                 mei_hdr->msg_complete = 1;
1004                 mei_hdr->reserved = 0;
1005
1006                 *slots -= mei_data2slots(mei_hdr->length);
1007
1008                 if (mei_write_message(dev, mei_hdr,
1009                                         (dev->iamthif_msg_buf +
1010                                         dev->iamthif_msg_buf_index),
1011                                         mei_hdr->length)) {
1012                         dev->iamthif_state = MEI_IAMTHIF_IDLE;
1013                         cl->status = -ENODEV;
1014                         list_del(&cb_pos->cb_list);
1015                         return -ENODEV;
1016                 } else {
1017                         if (mei_flow_ctrl_reduce(dev, cl))
1018                                 return -ENODEV;
1019                         dev->iamthif_msg_buf_index += mei_hdr->length;
1020                         cb_pos->buf_idx = dev->iamthif_msg_buf_index;
1021                         cl->status = 0;
1022                         dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
1023                         dev->iamthif_flow_control_pending = true;
1024                         /* save iamthif cb sent to amthi client */
1025                         dev->iamthif_current_cb = cb_pos;
1026                         list_move_tail(&cb_pos->cb_list,
1027                                 &dev->write_waiting_list.mei_cb.cb_list);
1028
1029                 }
1030         } else if (*slots == dev->hbuf_depth) {
1031                 /* buffer is still empty */
1032                 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
1033                 mei_hdr->host_addr = cl->host_client_id;
1034                 mei_hdr->me_addr = cl->me_client_id;
1035                 mei_hdr->length =
1036                         (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
1037                 mei_hdr->msg_complete = 0;
1038                 mei_hdr->reserved = 0;
1039
1040                 *slots -= mei_data2slots(mei_hdr->length);
1041
1042                 if (mei_write_message(dev, mei_hdr,
1043                                         (dev->iamthif_msg_buf +
1044                                         dev->iamthif_msg_buf_index),
1045                                         mei_hdr->length)) {
1046                         cl->status = -ENODEV;
1047                         list_del(&cb_pos->cb_list);
1048                 } else {
1049                         dev->iamthif_msg_buf_index += mei_hdr->length;
1050                 }
1051                 return -EMSGSIZE;
1052         } else {
1053                 return -EBADMSG;
1054         }
1055
1056         return 0;
1057 }
1058
1059 /**
1060  * mei_irq_thread_read_handler - bottom half read routine after ISR to
1061  * handle the read processing.
1062  *
1063  * @cmpl_list: An instance of our list structure
1064  * @dev: the device structure
1065  * @slots: slots to read.
1066  *
1067  * returns 0 on success, <0 on failure.
1068  */
1069 static int mei_irq_thread_read_handler(struct mei_io_list *cmpl_list,
1070                 struct mei_device *dev,
1071                 s32 *slots)
1072 {
1073         struct mei_msg_hdr *mei_hdr;
1074         struct mei_cl *cl_pos = NULL;
1075         struct mei_cl *cl_next = NULL;
1076         int ret = 0;
1077
1078         if (!dev->rd_msg_hdr) {
1079                 dev->rd_msg_hdr = mei_mecbrw_read(dev);
1080                 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
1081                 (*slots)--;
1082                 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
1083         }
1084         mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr;
1085         dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length);
1086
1087         if (mei_hdr->reserved || !dev->rd_msg_hdr) {
1088                 dev_dbg(&dev->pdev->dev, "corrupted message header.\n");
1089                 ret = -EBADMSG;
1090                 goto end;
1091         }
1092
1093         if (mei_hdr->host_addr || mei_hdr->me_addr) {
1094                 list_for_each_entry_safe(cl_pos, cl_next,
1095                                         &dev->file_list, link) {
1096                         dev_dbg(&dev->pdev->dev,
1097                                         "list_for_each_entry_safe read host"
1098                                         " client = %d, ME client = %d\n",
1099                                         cl_pos->host_client_id,
1100                                         cl_pos->me_client_id);
1101                         if (cl_pos->host_client_id == mei_hdr->host_addr &&
1102                             cl_pos->me_client_id == mei_hdr->me_addr)
1103                                 break;
1104                 }
1105
1106                 if (&cl_pos->link == &dev->file_list) {
1107                         dev_dbg(&dev->pdev->dev, "corrupted message header\n");
1108                         ret = -EBADMSG;
1109                         goto end;
1110                 }
1111         }
1112         if (((*slots) * sizeof(u32)) < mei_hdr->length) {
1113                 dev_dbg(&dev->pdev->dev,
1114                                 "we can't read the message slots =%08x.\n",
1115                                 *slots);
1116                 /* we can't read the message */
1117                 ret = -ERANGE;
1118                 goto end;
1119         }
1120
1121         /* decide where to read the message too */
1122         if (!mei_hdr->host_addr) {
1123                 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n");
1124                 mei_irq_thread_read_bus_message(dev, mei_hdr);
1125                 dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n");
1126         } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
1127                    (MEI_FILE_CONNECTED == dev->iamthif_cl.state) &&
1128                    (dev->iamthif_state == MEI_IAMTHIF_READING)) {
1129                 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n");
1130                 dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
1131                                 mei_hdr->length);
1132                 ret = mei_irq_thread_read_amthi_message(cmpl_list,
1133                                                         dev, mei_hdr);
1134                 if (ret)
1135                         goto end;
1136
1137         } else {
1138                 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n");
1139                 ret = mei_irq_thread_read_client_message(cmpl_list,
1140                                                          dev, mei_hdr);
1141                 if (ret)
1142                         goto end;
1143
1144         }
1145
1146         /* reset the number of slots and header */
1147         *slots = mei_count_full_read_slots(dev);
1148         dev->rd_msg_hdr = 0;
1149
1150         if (*slots == -EOVERFLOW) {
1151                 /* overflow - reset */
1152                 dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n");
1153                 /* set the event since message has been read */
1154                 ret = -ERANGE;
1155                 goto end;
1156         }
1157 end:
1158         return ret;
1159 }
1160
1161
1162 /**
1163  * mei_irq_thread_write_handler - bottom half write routine after
1164  * ISR to handle the write processing.
1165  *
1166  * @cmpl_list: An instance of our list structure
1167  * @dev: the device structure
1168  * @slots: slots to write.
1169  *
1170  * returns 0 on success, <0 on failure.
1171  */
1172 static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
1173                 struct mei_device *dev,
1174                 s32 *slots)
1175 {
1176
1177         struct mei_cl *cl;
1178         struct mei_cl_cb *pos = NULL, *next = NULL;
1179         struct mei_io_list *list;
1180         int ret;
1181
1182         if (!mei_hbuf_is_empty(dev)) {
1183                 dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
1184                 return 0;
1185         }
1186         *slots = mei_hbuf_empty_slots(dev);
1187         if (*slots <= 0)
1188                 return -EMSGSIZE;
1189
1190         /* complete all waiting for write CB */
1191         dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
1192
1193         list = &dev->write_waiting_list;
1194         list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) {
1195                 cl = (struct mei_cl *)pos->file_private;
1196                 if (cl == NULL)
1197                         continue;
1198
1199                 cl->status = 0;
1200                 list_del(&pos->cb_list);
1201                 if (MEI_WRITING == cl->writing_state &&
1202                    (pos->major_file_operations == MEI_WRITE) &&
1203                    (cl != &dev->iamthif_cl)) {
1204                         dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n");
1205                         cl->writing_state = MEI_WRITE_COMPLETE;
1206                         list_add_tail(&pos->cb_list,
1207                                       &cmpl_list->mei_cb.cb_list);
1208                 }
1209                 if (cl == &dev->iamthif_cl) {
1210                         dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
1211                         if (dev->iamthif_flow_control_pending) {
1212                                 ret = _mei_irq_thread_iamthif_read(dev, slots);
1213                                 if (ret)
1214                                         return ret;
1215                         }
1216                 }
1217         }
1218
1219         if (dev->wd_state == MEI_WD_STOPPING) {
1220                 dev->wd_state = MEI_WD_IDLE;
1221                 wake_up_interruptible(&dev->wait_stop_wd);
1222         }
1223
1224         if (dev->extra_write_index) {
1225                 dev_dbg(&dev->pdev->dev, "extra_write_index =%d.\n",
1226                                 dev->extra_write_index);
1227                 mei_write_message(dev,
1228                                 (struct mei_msg_hdr *) &dev->ext_msg_buf[0],
1229                                 (unsigned char *) &dev->ext_msg_buf[1],
1230                                 (dev->extra_write_index - 1) * sizeof(u32));
1231                 *slots -= dev->extra_write_index;
1232                 dev->extra_write_index = 0;
1233         }
1234         if (dev->dev_state == MEI_DEV_ENABLED) {
1235                 if (dev->wd_pending &&
1236                     mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
1237                         if (mei_wd_send(dev))
1238                                 dev_dbg(&dev->pdev->dev, "wd send failed.\n");
1239                         else if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
1240                                 return -ENODEV;
1241
1242                         dev->wd_pending = false;
1243
1244                         if (dev->wd_state == MEI_WD_RUNNING)
1245                                 *slots -= mei_data2slots(MEI_WD_START_MSG_SIZE);
1246                         else
1247                                 *slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE);
1248                 }
1249         }
1250
1251         /* complete control write list CB */
1252         dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
1253         list_for_each_entry_safe(pos, next,
1254                                 &dev->ctrl_wr_list.mei_cb.cb_list, cb_list) {
1255                 cl = (struct mei_cl *) pos->file_private;
1256                 if (!cl) {
1257                         list_del(&pos->cb_list);
1258                         return -ENODEV;
1259                 }
1260                 switch (pos->major_file_operations) {
1261                 case MEI_CLOSE:
1262                         /* send disconnect message */
1263                         ret = _mei_irq_thread_close(dev, slots, pos, cl, cmpl_list);
1264                         if (ret)
1265                                 return ret;
1266
1267                         break;
1268                 case MEI_READ:
1269                         /* send flow control message */
1270                         ret = _mei_irq_thread_read(dev, slots, pos, cl, cmpl_list);
1271                         if (ret)
1272                                 return ret;
1273
1274                         break;
1275                 case MEI_IOCTL:
1276                         /* connect message */
1277                         if (mei_other_client_is_connecting(dev, cl))
1278                                 continue;
1279                         ret = _mei_irq_thread_ioctl(dev, slots, pos, cl, cmpl_list);
1280                         if (ret)
1281                                 return ret;
1282
1283                         break;
1284
1285                 default:
1286                         BUG();
1287                 }
1288
1289         }
1290         /* complete  write list CB */
1291         dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
1292         list_for_each_entry_safe(pos, next,
1293                                 &dev->write_list.mei_cb.cb_list, cb_list) {
1294                 cl = (struct mei_cl *)pos->file_private;
1295                 if (cl == NULL)
1296                         continue;
1297
1298                 if (cl != &dev->iamthif_cl) {
1299                         if (mei_flow_ctrl_creds(dev, cl) <= 0) {
1300                                 dev_dbg(&dev->pdev->dev,
1301                                         "No flow control credentials for client %d, not sending.\n",
1302                                         cl->host_client_id);
1303                                 continue;
1304                         }
1305                         ret = _mei_irq_thread_cmpl(dev, slots, pos,
1306                                                 cl, cmpl_list);
1307                         if (ret)
1308                                 return ret;
1309
1310                 } else if (cl == &dev->iamthif_cl) {
1311                         /* IAMTHIF IOCTL */
1312                         dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n");
1313                         if (mei_flow_ctrl_creds(dev, cl) <= 0) {
1314                                 dev_dbg(&dev->pdev->dev,
1315                                         "No flow control credentials for amthi client %d.\n",
1316                                         cl->host_client_id);
1317                                 continue;
1318                         }
1319                         ret = _mei_irq_thread_cmpl_iamthif(dev, slots, pos,
1320                                                 cl, cmpl_list);
1321                         if (ret)
1322                                 return ret;
1323
1324                 }
1325
1326         }
1327         return 0;
1328 }
1329
1330
1331
1332 /**
1333  * mei_timer - timer function.
1334  *
1335  * @work: pointer to the work_struct structure
1336  *
1337  * NOTE: This function is called by timer interrupt work
1338  */
1339 void mei_timer(struct work_struct *work)
1340 {
1341         unsigned long timeout;
1342         struct mei_cl *cl_pos = NULL;
1343         struct mei_cl *cl_next = NULL;
1344         struct list_head *amthi_complete_list = NULL;
1345         struct mei_cl_cb  *cb_pos = NULL;
1346         struct mei_cl_cb  *cb_next = NULL;
1347
1348         struct mei_device *dev = container_of(work,
1349                                         struct mei_device, timer_work.work);
1350
1351
1352         mutex_lock(&dev->device_lock);
1353         if (dev->dev_state != MEI_DEV_ENABLED) {
1354                 if (dev->dev_state == MEI_DEV_INIT_CLIENTS) {
1355                         if (dev->init_clients_timer) {
1356                                 if (--dev->init_clients_timer == 0) {
1357                                         dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n",
1358                                                 dev->init_clients_state);
1359                                         mei_reset(dev, 1);
1360                                 }
1361                         }
1362                 }
1363                 goto out;
1364         }
1365         /*** connect/disconnect timeouts ***/
1366         list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
1367                 if (cl_pos->timer_count) {
1368                         if (--cl_pos->timer_count == 0) {
1369                                 dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n");
1370                                 mei_reset(dev, 1);
1371                                 goto out;
1372                         }
1373                 }
1374         }
1375
1376         if (dev->iamthif_stall_timer) {
1377                 if (--dev->iamthif_stall_timer == 0) {
1378                         dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n");
1379                         mei_reset(dev, 1);
1380                         dev->iamthif_msg_buf_size = 0;
1381                         dev->iamthif_msg_buf_index = 0;
1382                         dev->iamthif_canceled = false;
1383                         dev->iamthif_ioctl = true;
1384                         dev->iamthif_state = MEI_IAMTHIF_IDLE;
1385                         dev->iamthif_timer = 0;
1386
1387                         if (dev->iamthif_current_cb)
1388                                 mei_free_cb_private(dev->iamthif_current_cb);
1389
1390                         dev->iamthif_file_object = NULL;
1391                         dev->iamthif_current_cb = NULL;
1392                         mei_run_next_iamthif_cmd(dev);
1393                 }
1394         }
1395
1396         if (dev->iamthif_timer) {
1397
1398                 timeout = dev->iamthif_timer +
1399                                 msecs_to_jiffies(IAMTHIF_READ_TIMER);
1400
1401                 dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
1402                                 dev->iamthif_timer);
1403                 dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout);
1404                 dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies);
1405                 if (time_after(jiffies, timeout)) {
1406                         /*
1407                          * User didn't read the AMTHI data on time (15sec)
1408                          * freeing AMTHI for other requests
1409                          */
1410
1411                         dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n");
1412
1413                         amthi_complete_list = &dev->amthi_read_complete_list.
1414                                         mei_cb.cb_list;
1415
1416                         list_for_each_entry_safe(cb_pos, cb_next, amthi_complete_list, cb_list) {
1417
1418                                 cl_pos = cb_pos->file_object->private_data;
1419
1420                                 /* Finding the AMTHI entry. */
1421                                 if (cl_pos == &dev->iamthif_cl)
1422                                         list_del(&cb_pos->cb_list);
1423                         }
1424                         if (dev->iamthif_current_cb)
1425                                 mei_free_cb_private(dev->iamthif_current_cb);
1426
1427                         dev->iamthif_file_object->private_data = NULL;
1428                         dev->iamthif_file_object = NULL;
1429                         dev->iamthif_current_cb = NULL;
1430                         dev->iamthif_timer = 0;
1431                         mei_run_next_iamthif_cmd(dev);
1432
1433                 }
1434         }
1435 out:
1436         schedule_delayed_work(&dev->timer_work, 2 * HZ);
1437         mutex_unlock(&dev->device_lock);
1438 }
1439
1440 /**
1441  *  mei_interrupt_thread_handler - function called after ISR to handle the interrupt
1442  * processing.
1443  *
1444  * @irq: The irq number
1445  * @dev_id: pointer to the device structure
1446  *
1447  * returns irqreturn_t
1448  *
1449  */
1450 irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
1451 {
1452         struct mei_device *dev = (struct mei_device *) dev_id;
1453         struct mei_io_list complete_list;
1454         struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
1455         struct mei_cl *cl;
1456         s32 slots;
1457         int rets;
1458         bool  bus_message_received;
1459
1460
1461         dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n");
1462         /* initialize our complete list */
1463         mutex_lock(&dev->device_lock);
1464         mei_io_list_init(&complete_list);
1465         dev->host_hw_state = mei_hcsr_read(dev);
1466
1467         /* Ack the interrupt here
1468          * In case of MSI we don't go through the quick handler */
1469         if (pci_dev_msi_enabled(dev->pdev))
1470                 mei_reg_write(dev, H_CSR, dev->host_hw_state);
1471
1472         dev->me_hw_state = mei_mecsr_read(dev);
1473
1474         /* check if ME wants a reset */
1475         if ((dev->me_hw_state & ME_RDY_HRA) == 0 &&
1476             dev->dev_state != MEI_DEV_RESETING &&
1477             dev->dev_state != MEI_DEV_INITIALIZING) {
1478                 dev_dbg(&dev->pdev->dev, "FW not ready.\n");
1479                 mei_reset(dev, 1);
1480                 mutex_unlock(&dev->device_lock);
1481                 return IRQ_HANDLED;
1482         }
1483
1484         /*  check if we need to start the dev */
1485         if ((dev->host_hw_state & H_RDY) == 0) {
1486                 if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) {
1487                         dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
1488                         dev->host_hw_state |= (H_IE | H_IG | H_RDY);
1489                         mei_hcsr_set(dev);
1490                         dev->dev_state = MEI_DEV_INIT_CLIENTS;
1491                         dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
1492                         /* link is established
1493                          * start sending messages.
1494                          */
1495                         mei_host_start_message(dev);
1496                         mutex_unlock(&dev->device_lock);
1497                         return IRQ_HANDLED;
1498                 } else {
1499                         dev_dbg(&dev->pdev->dev, "FW not ready.\n");
1500                         mutex_unlock(&dev->device_lock);
1501                         return IRQ_HANDLED;
1502                 }
1503         }
1504         /* check slots available for reading */
1505         slots = mei_count_full_read_slots(dev);
1506         dev_dbg(&dev->pdev->dev, "slots =%08x  extra_write_index =%08x.\n",
1507                 slots, dev->extra_write_index);
1508         while (slots > 0 && !dev->extra_write_index) {
1509                 dev_dbg(&dev->pdev->dev, "slots =%08x  extra_write_index =%08x.\n",
1510                                 slots, dev->extra_write_index);
1511                 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n");
1512                 rets = mei_irq_thread_read_handler(&complete_list, dev, &slots);
1513                 if (rets)
1514                         goto end;
1515         }
1516         rets = mei_irq_thread_write_handler(&complete_list, dev, &slots);
1517 end:
1518         dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
1519         dev->host_hw_state = mei_hcsr_read(dev);
1520         dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
1521
1522         bus_message_received = false;
1523         if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
1524                 dev_dbg(&dev->pdev->dev, "received waiting bus message\n");
1525                 bus_message_received = true;
1526         }
1527         mutex_unlock(&dev->device_lock);
1528         if (bus_message_received) {
1529                 dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n");
1530                 wake_up_interruptible(&dev->wait_recvd_msg);
1531                 bus_message_received = false;
1532         }
1533         if (list_empty(&complete_list.mei_cb.cb_list))
1534                 return IRQ_HANDLED;
1535
1536
1537         list_for_each_entry_safe(cb_pos, cb_next,
1538                         &complete_list.mei_cb.cb_list, cb_list) {
1539                 cl = (struct mei_cl *)cb_pos->file_private;
1540                 list_del(&cb_pos->cb_list);
1541                 if (cl) {
1542                         if (cl != &dev->iamthif_cl) {
1543                                 dev_dbg(&dev->pdev->dev, "completing call back.\n");
1544                                 _mei_cmpl(cl, cb_pos);
1545                                 cb_pos = NULL;
1546                         } else if (cl == &dev->iamthif_cl) {
1547                                 _mei_cmpl_iamthif(dev, cb_pos);
1548                         }
1549                 }
1550         }
1551         return IRQ_HANDLED;
1552 }