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