9ff8c61fe457a1ddf533c9c969894665b48e6362
[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/export.h>
19 #include <linux/pci.h>
20 #include <linux/kthread.h>
21 #include <linux/interrupt.h>
22 #include <linux/fs.h>
23 #include <linux/jiffies.h>
24
25 #include <linux/mei.h>
26
27 #include "mei_dev.h"
28 #include "hbm.h"
29 #include "hw-me.h"
30 #include "client.h"
31
32
33 /**
34  * mei_cl_complete_handler - processes completed operation for a client
35  *
36  * @cl: private data of the file object.
37  * @cb: callback block.
38  */
39 static void mei_cl_complete_handler(struct mei_cl *cl, struct mei_cl_cb *cb)
40 {
41         if (cb->fop_type == MEI_FOP_WRITE) {
42                 mei_io_cb_free(cb);
43                 cb = NULL;
44                 cl->writing_state = MEI_WRITE_COMPLETE;
45                 if (waitqueue_active(&cl->tx_wait))
46                         wake_up_interruptible(&cl->tx_wait);
47
48         } else if (cb->fop_type == MEI_FOP_READ &&
49                         MEI_READING == cl->reading_state) {
50                 cl->reading_state = MEI_READ_COMPLETE;
51                 if (waitqueue_active(&cl->rx_wait))
52                         wake_up_interruptible(&cl->rx_wait);
53                 else
54                         mei_cl_bus_rx_event(cl);
55
56         }
57 }
58
59 /**
60  * mei_irq_compl_handler - dispatch complete handelers
61  *      for the completed callbacks
62  *
63  * @dev - mei device
64  * @compl_list - list of completed cbs
65  */
66 void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list)
67 {
68         struct mei_cl_cb *cb, *next;
69         struct mei_cl *cl;
70
71         list_for_each_entry_safe(cb, next, &compl_list->list, list) {
72                 cl = cb->cl;
73                 list_del(&cb->list);
74                 if (!cl)
75                         continue;
76
77                 dev_dbg(&dev->pdev->dev, "completing call back.\n");
78                 if (cl == &dev->iamthif_cl)
79                         mei_amthif_complete(dev, cb);
80                 else
81                         mei_cl_complete_handler(cl, cb);
82         }
83 }
84 EXPORT_SYMBOL_GPL(mei_irq_compl_handler);
85 /**
86  * _mei_irq_thread_state_ok - checks if mei header matches file private data
87  *
88  * @cl: private data of the file object
89  * @mei_hdr: header of mei client message
90  *
91  * returns !=0 if matches, 0 if no match.
92  */
93 static int _mei_irq_thread_state_ok(struct mei_cl *cl,
94                                 struct mei_msg_hdr *mei_hdr)
95 {
96         return (cl->host_client_id == mei_hdr->host_addr &&
97                 cl->me_client_id == mei_hdr->me_addr &&
98                 cl->state == MEI_FILE_CONNECTED &&
99                 MEI_READ_COMPLETE != cl->reading_state);
100 }
101
102 /**
103  * mei_irq_thread_read_client_message - bottom half read routine after ISR to
104  * handle the read mei client message data processing.
105  *
106  * @complete_list: An instance of our list structure
107  * @dev: the device structure
108  * @mei_hdr: header of mei client message
109  *
110  * returns 0 on success, <0 on failure.
111  */
112 static int mei_irq_thread_read_client_message(struct mei_cl_cb *complete_list,
113                 struct mei_device *dev,
114                 struct mei_msg_hdr *mei_hdr)
115 {
116         struct mei_cl *cl;
117         struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
118         unsigned char *buffer = NULL;
119
120         dev_dbg(&dev->pdev->dev, "start client msg\n");
121         if (list_empty(&dev->read_list.list))
122                 goto quit;
123
124         list_for_each_entry_safe(cb_pos, cb_next, &dev->read_list.list, list) {
125                 cl = cb_pos->cl;
126                 if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) {
127                         cl->reading_state = MEI_READING;
128                         buffer = cb_pos->response_buffer.data + cb_pos->buf_idx;
129
130                         if (cb_pos->response_buffer.size <
131                                         mei_hdr->length + cb_pos->buf_idx) {
132                                 dev_dbg(&dev->pdev->dev, "message overflow.\n");
133                                 list_del(&cb_pos->list);
134                                 return -ENOMEM;
135                         }
136                         if (buffer)
137                                 mei_read_slots(dev, buffer, mei_hdr->length);
138
139                         cb_pos->buf_idx += mei_hdr->length;
140                         if (mei_hdr->msg_complete) {
141                                 cl->status = 0;
142                                 list_del(&cb_pos->list);
143                                 dev_dbg(&dev->pdev->dev,
144                                         "completed read H cl = %d, ME cl = %d, length = %lu\n",
145                                         cl->host_client_id,
146                                         cl->me_client_id,
147                                         cb_pos->buf_idx);
148
149                                 list_add_tail(&cb_pos->list,
150                                                 &complete_list->list);
151                         }
152
153                         break;
154                 }
155
156         }
157
158 quit:
159         dev_dbg(&dev->pdev->dev, "message read\n");
160         if (!buffer) {
161                 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
162                 dev_dbg(&dev->pdev->dev, "discarding message " MEI_HDR_FMT "\n",
163                                 MEI_HDR_PRM(mei_hdr));
164         }
165
166         return 0;
167 }
168
169 /**
170  * _mei_irq_thread_close - processes close related operation.
171  *
172  * @dev: the device structure.
173  * @slots: free slots.
174  * @cb_pos: callback block.
175  * @cl: private data of the file object.
176  * @cmpl_list: complete list.
177  *
178  * returns 0, OK; otherwise, error.
179  */
180 static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
181                                 struct mei_cl_cb *cb_pos,
182                                 struct mei_cl *cl,
183                                 struct mei_cl_cb *cmpl_list)
184 {
185         u32 msg_slots =
186                 mei_data2slots(sizeof(struct hbm_client_connect_request));
187
188         if (*slots < msg_slots)
189                 return -EMSGSIZE;
190
191         *slots -= msg_slots;
192
193         if (mei_hbm_cl_disconnect_req(dev, cl)) {
194                 cl->status = 0;
195                 cb_pos->buf_idx = 0;
196                 list_move_tail(&cb_pos->list, &cmpl_list->list);
197                 return -EIO;
198         }
199
200         cl->state = MEI_FILE_DISCONNECTING;
201         cl->status = 0;
202         cb_pos->buf_idx = 0;
203         list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
204         cl->timer_count = MEI_CONNECT_TIMEOUT;
205
206         return 0;
207 }
208
209
210 /**
211  * _mei_hb_read - processes read related operation.
212  *
213  * @dev: the device structure.
214  * @slots: free slots.
215  * @cb_pos: callback block.
216  * @cl: private data of the file object.
217  * @cmpl_list: complete list.
218  *
219  * returns 0, OK; otherwise, error.
220  */
221 static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots,
222                         struct mei_cl_cb *cb_pos,
223                         struct mei_cl *cl,
224                         struct mei_cl_cb *cmpl_list)
225 {
226         u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control));
227
228         if (*slots < msg_slots) {
229                 /* return the cancel routine */
230                 list_del(&cb_pos->list);
231                 return -EMSGSIZE;
232         }
233
234         *slots -= msg_slots;
235
236         if (mei_hbm_cl_flow_control_req(dev, cl)) {
237                 cl->status = -ENODEV;
238                 cb_pos->buf_idx = 0;
239                 list_move_tail(&cb_pos->list, &cmpl_list->list);
240                 return -ENODEV;
241         }
242         list_move_tail(&cb_pos->list, &dev->read_list.list);
243
244         return 0;
245 }
246
247
248 /**
249  * _mei_irq_thread_ioctl - processes ioctl related operation.
250  *
251  * @dev: the device structure.
252  * @slots: free slots.
253  * @cb_pos: callback block.
254  * @cl: private data of the file object.
255  * @cmpl_list: complete list.
256  *
257  * returns 0, OK; otherwise, error.
258  */
259 static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
260                         struct mei_cl_cb *cb_pos,
261                         struct mei_cl *cl,
262                         struct mei_cl_cb *cmpl_list)
263 {
264         u32 msg_slots =
265                 mei_data2slots(sizeof(struct hbm_client_connect_request));
266
267         if (*slots < msg_slots) {
268                 /* return the cancel routine */
269                 list_del(&cb_pos->list);
270                 return -EMSGSIZE;
271         }
272
273         *slots -=  msg_slots;
274
275         cl->state = MEI_FILE_CONNECTING;
276
277         if (mei_hbm_cl_connect_req(dev, cl)) {
278                 cl->status = -ENODEV;
279                 cb_pos->buf_idx = 0;
280                 list_del(&cb_pos->list);
281                 return -ENODEV;
282         } else {
283                 list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
284                 cl->timer_count = MEI_CONNECT_TIMEOUT;
285         }
286         return 0;
287 }
288
289 /**
290  * mei_irq_thread_write_complete - write messages to device.
291  *
292  * @dev: the device structure.
293  * @slots: free slots.
294  * @cb: callback block.
295  * @cmpl_list: complete list.
296  *
297  * returns 0, OK; otherwise, error.
298  */
299 static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
300                         struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
301 {
302         struct mei_msg_hdr mei_hdr;
303         struct mei_cl *cl = cb->cl;
304         size_t len = cb->request_buffer.size - cb->buf_idx;
305         u32 msg_slots = mei_data2slots(len);
306
307         mei_hdr.host_addr = cl->host_client_id;
308         mei_hdr.me_addr = cl->me_client_id;
309         mei_hdr.reserved = 0;
310
311         if (*slots >= msg_slots) {
312                 mei_hdr.length = len;
313                 mei_hdr.msg_complete = 1;
314         /* Split the message only if we can write the whole host buffer */
315         } else if (*slots == dev->hbuf_depth) {
316                 msg_slots = *slots;
317                 len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
318                 mei_hdr.length = len;
319                 mei_hdr.msg_complete = 0;
320         } else {
321                 /* wait for next time the host buffer is empty */
322                 return 0;
323         }
324
325         dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n",
326                         cb->request_buffer.size, cb->buf_idx);
327         dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
328
329         *slots -=  msg_slots;
330         if (mei_write_message(dev, &mei_hdr,
331                         cb->request_buffer.data + cb->buf_idx)) {
332                 cl->status = -ENODEV;
333                 list_move_tail(&cb->list, &cmpl_list->list);
334                 return -ENODEV;
335         }
336
337         if (mei_cl_flow_ctrl_reduce(cl))
338                 return -ENODEV;
339
340         cl->status = 0;
341         cb->buf_idx += mei_hdr.length;
342         if (mei_hdr.msg_complete)
343                 list_move_tail(&cb->list, &dev->write_waiting_list.list);
344
345         return 0;
346 }
347
348 /**
349  * mei_irq_thread_read_handler - bottom half read routine after ISR to
350  * handle the read processing.
351  *
352  * @dev: the device structure
353  * @cmpl_list: An instance of our list structure
354  * @slots: slots to read.
355  *
356  * returns 0 on success, <0 on failure.
357  */
358 int mei_irq_read_handler(struct mei_device *dev,
359                 struct mei_cl_cb *cmpl_list, s32 *slots)
360 {
361         struct mei_msg_hdr *mei_hdr;
362         struct mei_cl *cl_pos = NULL;
363         struct mei_cl *cl_next = NULL;
364         int ret = 0;
365
366         if (!dev->rd_msg_hdr) {
367                 dev->rd_msg_hdr = mei_read_hdr(dev);
368                 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
369                 (*slots)--;
370                 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
371         }
372         mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr;
373         dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr));
374
375         if (mei_hdr->reserved || !dev->rd_msg_hdr) {
376                 dev_dbg(&dev->pdev->dev, "corrupted message header.\n");
377                 ret = -EBADMSG;
378                 goto end;
379         }
380
381         if (mei_hdr->host_addr || mei_hdr->me_addr) {
382                 list_for_each_entry_safe(cl_pos, cl_next,
383                                         &dev->file_list, link) {
384                         dev_dbg(&dev->pdev->dev,
385                                         "list_for_each_entry_safe read host"
386                                         " client = %d, ME client = %d\n",
387                                         cl_pos->host_client_id,
388                                         cl_pos->me_client_id);
389                         if (cl_pos->host_client_id == mei_hdr->host_addr &&
390                             cl_pos->me_client_id == mei_hdr->me_addr)
391                                 break;
392                 }
393
394                 if (&cl_pos->link == &dev->file_list) {
395                         dev_dbg(&dev->pdev->dev, "corrupted message header\n");
396                         ret = -EBADMSG;
397                         goto end;
398                 }
399         }
400         if (((*slots) * sizeof(u32)) < mei_hdr->length) {
401                 dev_dbg(&dev->pdev->dev,
402                                 "we can't read the message slots =%08x.\n",
403                                 *slots);
404                 /* we can't read the message */
405                 ret = -ERANGE;
406                 goto end;
407         }
408
409         /* decide where to read the message too */
410         if (!mei_hdr->host_addr) {
411                 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n");
412                 mei_hbm_dispatch(dev, mei_hdr);
413                 dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n");
414         } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
415                    (MEI_FILE_CONNECTED == dev->iamthif_cl.state) &&
416                    (dev->iamthif_state == MEI_IAMTHIF_READING)) {
417                 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n");
418
419                 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr));
420
421                 ret = mei_amthif_irq_read_message(cmpl_list, dev, mei_hdr);
422                 if (ret)
423                         goto end;
424         } else {
425                 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n");
426                 ret = mei_irq_thread_read_client_message(cmpl_list,
427                                                          dev, mei_hdr);
428                 if (ret)
429                         goto end;
430
431         }
432
433         /* reset the number of slots and header */
434         *slots = mei_count_full_read_slots(dev);
435         dev->rd_msg_hdr = 0;
436
437         if (*slots == -EOVERFLOW) {
438                 /* overflow - reset */
439                 dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n");
440                 /* set the event since message has been read */
441                 ret = -ERANGE;
442                 goto end;
443         }
444 end:
445         return ret;
446 }
447 EXPORT_SYMBOL_GPL(mei_irq_read_handler);
448
449
450 /**
451  * mei_irq_write_handler -  dispatch write requests
452  *  after irq received
453  *
454  * @dev: the device structure
455  * @cmpl_list: An instance of our list structure
456  *
457  * returns 0 on success, <0 on failure.
458  */
459 int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
460 {
461
462         struct mei_cl *cl;
463         struct mei_cl_cb *pos = NULL, *next = NULL;
464         struct mei_cl_cb *list;
465         s32 slots;
466         int ret;
467
468         if (!mei_hbuf_is_ready(dev)) {
469                 dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
470                 return 0;
471         }
472         slots = mei_hbuf_empty_slots(dev);
473         if (slots <= 0)
474                 return -EMSGSIZE;
475
476         /* complete all waiting for write CB */
477         dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
478
479         list = &dev->write_waiting_list;
480         list_for_each_entry_safe(pos, next, &list->list, list) {
481                 cl = pos->cl;
482                 if (cl == NULL)
483                         continue;
484
485                 cl->status = 0;
486                 list_del(&pos->list);
487                 if (MEI_WRITING == cl->writing_state &&
488                     pos->fop_type == MEI_FOP_WRITE &&
489                     cl != &dev->iamthif_cl) {
490                         dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n");
491                         cl->writing_state = MEI_WRITE_COMPLETE;
492                         list_add_tail(&pos->list, &cmpl_list->list);
493                 }
494                 if (cl == &dev->iamthif_cl) {
495                         dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
496                         if (dev->iamthif_flow_control_pending) {
497                                 ret = mei_amthif_irq_read(dev, &slots);
498                                 if (ret)
499                                         return ret;
500                         }
501                 }
502         }
503
504         if (dev->wd_state == MEI_WD_STOPPING) {
505                 dev->wd_state = MEI_WD_IDLE;
506                 wake_up_interruptible(&dev->wait_stop_wd);
507         }
508
509         if (dev->wr_ext_msg.hdr.length) {
510                 mei_write_message(dev, &dev->wr_ext_msg.hdr,
511                                 dev->wr_ext_msg.data);
512                 slots -= mei_data2slots(dev->wr_ext_msg.hdr.length);
513                 dev->wr_ext_msg.hdr.length = 0;
514         }
515         if (dev->dev_state == MEI_DEV_ENABLED) {
516                 if (dev->wd_pending &&
517                     mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) {
518                         if (mei_wd_send(dev))
519                                 dev_dbg(&dev->pdev->dev, "wd send failed.\n");
520                         else if (mei_cl_flow_ctrl_reduce(&dev->wd_cl))
521                                 return -ENODEV;
522
523                         dev->wd_pending = false;
524
525                         if (dev->wd_state == MEI_WD_RUNNING)
526                                 slots -= mei_data2slots(MEI_WD_START_MSG_SIZE);
527                         else
528                                 slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE);
529                 }
530         }
531
532         /* complete control write list CB */
533         dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
534         list_for_each_entry_safe(pos, next, &dev->ctrl_wr_list.list, list) {
535                 cl = pos->cl;
536                 if (!cl) {
537                         list_del(&pos->list);
538                         return -ENODEV;
539                 }
540                 switch (pos->fop_type) {
541                 case MEI_FOP_CLOSE:
542                         /* send disconnect message */
543                         ret = _mei_irq_thread_close(dev, &slots, pos,
544                                                 cl, cmpl_list);
545                         if (ret)
546                                 return ret;
547
548                         break;
549                 case MEI_FOP_READ:
550                         /* send flow control message */
551                         ret = _mei_irq_thread_read(dev, &slots, pos,
552                                                 cl, cmpl_list);
553                         if (ret)
554                                 return ret;
555
556                         break;
557                 case MEI_FOP_IOCTL:
558                         /* connect message */
559                         if (mei_cl_is_other_connecting(cl))
560                                 continue;
561                         ret = _mei_irq_thread_ioctl(dev, &slots, pos,
562                                                 cl, cmpl_list);
563                         if (ret)
564                                 return ret;
565
566                         break;
567
568                 default:
569                         BUG();
570                 }
571
572         }
573         /* complete  write list CB */
574         dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
575         list_for_each_entry_safe(pos, next, &dev->write_list.list, list) {
576                 cl = pos->cl;
577                 if (cl == NULL)
578                         continue;
579                 if (mei_cl_flow_ctrl_creds(cl) <= 0) {
580                         dev_dbg(&dev->pdev->dev,
581                                 "No flow control credentials for client %d, not sending.\n",
582                                 cl->host_client_id);
583                         continue;
584                 }
585
586                 if (cl == &dev->iamthif_cl)
587                         ret = mei_amthif_irq_write_complete(dev, &slots,
588                                                         pos, cmpl_list);
589                 else
590                         ret = mei_irq_thread_write_complete(dev, &slots, pos,
591                                                 cmpl_list);
592                 if (ret)
593                         return ret;
594
595         }
596         return 0;
597 }
598 EXPORT_SYMBOL_GPL(mei_irq_write_handler);
599
600
601
602 /**
603  * mei_timer - timer function.
604  *
605  * @work: pointer to the work_struct structure
606  *
607  * NOTE: This function is called by timer interrupt work
608  */
609 void mei_timer(struct work_struct *work)
610 {
611         unsigned long timeout;
612         struct mei_cl *cl_pos = NULL;
613         struct mei_cl *cl_next = NULL;
614         struct mei_cl_cb  *cb_pos = NULL;
615         struct mei_cl_cb  *cb_next = NULL;
616
617         struct mei_device *dev = container_of(work,
618                                         struct mei_device, timer_work.work);
619
620
621         mutex_lock(&dev->device_lock);
622         if (dev->dev_state != MEI_DEV_ENABLED) {
623                 if (dev->dev_state == MEI_DEV_INIT_CLIENTS) {
624                         if (dev->init_clients_timer) {
625                                 if (--dev->init_clients_timer == 0) {
626                                         dev_err(&dev->pdev->dev, "reset: init clients timeout ,init clients state = %d.\n",
627                                                 dev->init_clients_state);
628                                         mei_reset(dev, 1);
629                                 }
630                         }
631                 }
632                 goto out;
633         }
634         /*** connect/disconnect timeouts ***/
635         list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
636                 if (cl_pos->timer_count) {
637                         if (--cl_pos->timer_count == 0) {
638                                 dev_err(&dev->pdev->dev, "reset: connect/disconnect timeout.\n");
639                                 mei_reset(dev, 1);
640                                 goto out;
641                         }
642                 }
643         }
644
645         if (dev->iamthif_stall_timer) {
646                 if (--dev->iamthif_stall_timer == 0) {
647                         dev_err(&dev->pdev->dev, "reset: amthif  hanged.\n");
648                         mei_reset(dev, 1);
649                         dev->iamthif_msg_buf_size = 0;
650                         dev->iamthif_msg_buf_index = 0;
651                         dev->iamthif_canceled = false;
652                         dev->iamthif_ioctl = true;
653                         dev->iamthif_state = MEI_IAMTHIF_IDLE;
654                         dev->iamthif_timer = 0;
655
656                         mei_io_cb_free(dev->iamthif_current_cb);
657                         dev->iamthif_current_cb = NULL;
658
659                         dev->iamthif_file_object = NULL;
660                         mei_amthif_run_next_cmd(dev);
661                 }
662         }
663
664         if (dev->iamthif_timer) {
665
666                 timeout = dev->iamthif_timer +
667                         mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
668
669                 dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
670                                 dev->iamthif_timer);
671                 dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout);
672                 dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies);
673                 if (time_after(jiffies, timeout)) {
674                         /*
675                          * User didn't read the AMTHI data on time (15sec)
676                          * freeing AMTHI for other requests
677                          */
678
679                         dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n");
680
681                         list_for_each_entry_safe(cb_pos, cb_next,
682                                 &dev->amthif_rd_complete_list.list, list) {
683
684                                 cl_pos = cb_pos->file_object->private_data;
685
686                                 /* Finding the AMTHI entry. */
687                                 if (cl_pos == &dev->iamthif_cl)
688                                         list_del(&cb_pos->list);
689                         }
690                         mei_io_cb_free(dev->iamthif_current_cb);
691                         dev->iamthif_current_cb = NULL;
692
693                         dev->iamthif_file_object->private_data = NULL;
694                         dev->iamthif_file_object = NULL;
695                         dev->iamthif_timer = 0;
696                         mei_amthif_run_next_cmd(dev);
697
698                 }
699         }
700 out:
701         schedule_delayed_work(&dev->timer_work, 2 * HZ);
702         mutex_unlock(&dev->device_lock);
703 }
704