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