xref: /openbmc/linux/drivers/misc/mei/interrupt.c (revision 9d749629)
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->fop_type == MEI_FOP_WRITE) {
61 		mei_io_cb_free(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->fop_type == MEI_FOP_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_irq_thread_state_ok - checks if mei header matches file private data
78  *
79  * @cl: private data of the file object
80  * @mei_hdr: header of mei client message
81  *
82  * returns !=0 if matches, 0 if no match.
83  */
84 static int _mei_irq_thread_state_ok(struct mei_cl *cl,
85 				struct mei_msg_hdr *mei_hdr)
86 {
87 	return (cl->host_client_id == mei_hdr->host_addr &&
88 		cl->me_client_id == mei_hdr->me_addr &&
89 		cl->state == MEI_FILE_CONNECTED &&
90 		MEI_READ_COMPLETE != cl->reading_state);
91 }
92 
93 /**
94  * mei_irq_thread_read_client_message - bottom half read routine after ISR to
95  * handle the read mei client message data processing.
96  *
97  * @complete_list: An instance of our list structure
98  * @dev: the device structure
99  * @mei_hdr: header of mei client message
100  *
101  * returns 0 on success, <0 on failure.
102  */
103 static int mei_irq_thread_read_client_message(struct mei_cl_cb *complete_list,
104 		struct mei_device *dev,
105 		struct mei_msg_hdr *mei_hdr)
106 {
107 	struct mei_cl *cl;
108 	struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
109 	unsigned char *buffer = NULL;
110 
111 	dev_dbg(&dev->pdev->dev, "start client msg\n");
112 	if (list_empty(&dev->read_list.list))
113 		goto quit;
114 
115 	list_for_each_entry_safe(cb_pos, cb_next, &dev->read_list.list, list) {
116 		cl = cb_pos->cl;
117 		if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) {
118 			cl->reading_state = MEI_READING;
119 			buffer = cb_pos->response_buffer.data + cb_pos->buf_idx;
120 
121 			if (cb_pos->response_buffer.size <
122 					mei_hdr->length + cb_pos->buf_idx) {
123 				dev_dbg(&dev->pdev->dev, "message overflow.\n");
124 				list_del(&cb_pos->list);
125 				return -ENOMEM;
126 			}
127 			if (buffer)
128 				mei_read_slots(dev, buffer, mei_hdr->length);
129 
130 			cb_pos->buf_idx += mei_hdr->length;
131 			if (mei_hdr->msg_complete) {
132 				cl->status = 0;
133 				list_del(&cb_pos->list);
134 				dev_dbg(&dev->pdev->dev,
135 					"completed read H cl = %d, ME cl = %d, length = %lu\n",
136 					cl->host_client_id,
137 					cl->me_client_id,
138 					cb_pos->buf_idx);
139 
140 				list_add_tail(&cb_pos->list,
141 						&complete_list->list);
142 			}
143 
144 			break;
145 		}
146 
147 	}
148 
149 quit:
150 	dev_dbg(&dev->pdev->dev, "message read\n");
151 	if (!buffer) {
152 		mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
153 		dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n",
154 				*(u32 *) dev->rd_msg_buf);
155 	}
156 
157 	return 0;
158 }
159 
160 /**
161  * _mei_irq_thread_close - processes close related operation.
162  *
163  * @dev: the device structure.
164  * @slots: free slots.
165  * @cb_pos: callback block.
166  * @cl: private data of the file object.
167  * @cmpl_list: complete list.
168  *
169  * returns 0, OK; otherwise, error.
170  */
171 static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
172 				struct mei_cl_cb *cb_pos,
173 				struct mei_cl *cl,
174 				struct mei_cl_cb *cmpl_list)
175 {
176 	if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
177 			sizeof(struct hbm_client_connect_request)))
178 		return -EBADMSG;
179 
180 	*slots -= mei_data2slots(sizeof(struct hbm_client_connect_request));
181 
182 	if (mei_disconnect(dev, cl)) {
183 		cl->status = 0;
184 		cb_pos->buf_idx = 0;
185 		list_move_tail(&cb_pos->list, &cmpl_list->list);
186 		return -EMSGSIZE;
187 	} else {
188 		cl->state = MEI_FILE_DISCONNECTING;
189 		cl->status = 0;
190 		cb_pos->buf_idx = 0;
191 		list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
192 		cl->timer_count = MEI_CONNECT_TIMEOUT;
193 	}
194 
195 	return 0;
196 }
197 
198 /**
199  * is_treat_specially_client - checks if the message belongs
200  * to the file private data.
201  *
202  * @cl: private data of the file object
203  * @rs: connect response bus message
204  *
205  */
206 static bool is_treat_specially_client(struct mei_cl *cl,
207 		struct hbm_client_connect_response *rs)
208 {
209 
210 	if (cl->host_client_id == rs->host_addr &&
211 	    cl->me_client_id == rs->me_addr) {
212 		if (!rs->status) {
213 			cl->state = MEI_FILE_CONNECTED;
214 			cl->status = 0;
215 
216 		} else {
217 			cl->state = MEI_FILE_DISCONNECTED;
218 			cl->status = -ENODEV;
219 		}
220 		cl->timer_count = 0;
221 
222 		return true;
223 	}
224 	return false;
225 }
226 
227 /**
228  * mei_client_connect_response - connects to response irq routine
229  *
230  * @dev: the device structure
231  * @rs: connect response bus message
232  */
233 static void mei_client_connect_response(struct mei_device *dev,
234 		struct hbm_client_connect_response *rs)
235 {
236 
237 	struct mei_cl *cl;
238 	struct mei_cl_cb *pos = NULL, *next = NULL;
239 
240 	dev_dbg(&dev->pdev->dev,
241 			"connect_response:\n"
242 			"ME Client = %d\n"
243 			"Host Client = %d\n"
244 			"Status = %d\n",
245 			rs->me_addr,
246 			rs->host_addr,
247 			rs->status);
248 
249 	/* if WD or iamthif client treat specially */
250 
251 	if (is_treat_specially_client(&(dev->wd_cl), rs)) {
252 		dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
253 		mei_watchdog_register(dev);
254 
255 		return;
256 	}
257 
258 	if (is_treat_specially_client(&(dev->iamthif_cl), rs)) {
259 		dev->iamthif_state = MEI_IAMTHIF_IDLE;
260 		return;
261 	}
262 	list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
263 
264 		cl = pos->cl;
265 		if (!cl) {
266 			list_del(&pos->list);
267 			return;
268 		}
269 		if (pos->fop_type == MEI_FOP_IOCTL) {
270 			if (is_treat_specially_client(cl, rs)) {
271 				list_del(&pos->list);
272 				cl->status = 0;
273 				cl->timer_count = 0;
274 				break;
275 			}
276 		}
277 	}
278 }
279 
280 /**
281  * mei_client_disconnect_response - disconnects from response irq routine
282  *
283  * @dev: the device structure
284  * @rs: disconnect response bus message
285  */
286 static void mei_client_disconnect_response(struct mei_device *dev,
287 					struct hbm_client_connect_response *rs)
288 {
289 	struct mei_cl *cl;
290 	struct mei_cl_cb *pos = NULL, *next = NULL;
291 
292 	dev_dbg(&dev->pdev->dev,
293 			"disconnect_response:\n"
294 			"ME Client = %d\n"
295 			"Host Client = %d\n"
296 			"Status = %d\n",
297 			rs->me_addr,
298 			rs->host_addr,
299 			rs->status);
300 
301 	list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
302 		cl = pos->cl;
303 
304 		if (!cl) {
305 			list_del(&pos->list);
306 			return;
307 		}
308 
309 		dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
310 		if (cl->host_client_id == rs->host_addr &&
311 		    cl->me_client_id == rs->me_addr) {
312 
313 			list_del(&pos->list);
314 			if (!rs->status)
315 				cl->state = MEI_FILE_DISCONNECTED;
316 
317 			cl->status = 0;
318 			cl->timer_count = 0;
319 			break;
320 		}
321 	}
322 }
323 
324 /**
325  * same_flow_addr - tells if they have the same address.
326  *
327  * @file: private data of the file object.
328  * @flow: flow control.
329  *
330  * returns  !=0, same; 0,not.
331  */
332 static int same_flow_addr(struct mei_cl *cl, struct hbm_flow_control *flow)
333 {
334 	return (cl->host_client_id == flow->host_addr &&
335 		cl->me_client_id == flow->me_addr);
336 }
337 
338 /**
339  * add_single_flow_creds - adds single buffer credentials.
340  *
341  * @file: private data ot the file object.
342  * @flow: flow control.
343  */
344 static void add_single_flow_creds(struct mei_device *dev,
345 				  struct hbm_flow_control *flow)
346 {
347 	struct mei_me_client *client;
348 	int i;
349 
350 	for (i = 0; i < dev->me_clients_num; i++) {
351 		client = &dev->me_clients[i];
352 		if (client && flow->me_addr == client->client_id) {
353 			if (client->props.single_recv_buf) {
354 				client->mei_flow_ctrl_creds++;
355 				dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n",
356 				    flow->me_addr);
357 				dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n",
358 				    client->mei_flow_ctrl_creds);
359 			} else {
360 				BUG();	/* error in flow control */
361 			}
362 		}
363 	}
364 }
365 
366 /**
367  * mei_client_flow_control_response - flow control response irq routine
368  *
369  * @dev: the device structure
370  * @flow_control: flow control response bus message
371  */
372 static void mei_client_flow_control_response(struct mei_device *dev,
373 		struct hbm_flow_control *flow_control)
374 {
375 	struct mei_cl *cl_pos = NULL;
376 	struct mei_cl *cl_next = NULL;
377 
378 	if (!flow_control->host_addr) {
379 		/* single receive buffer */
380 		add_single_flow_creds(dev, flow_control);
381 	} else {
382 		/* normal connection */
383 		list_for_each_entry_safe(cl_pos, cl_next,
384 				&dev->file_list, link) {
385 			dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in file_list\n");
386 
387 			dev_dbg(&dev->pdev->dev, "cl of host client %d ME client %d.\n",
388 			    cl_pos->host_client_id,
389 			    cl_pos->me_client_id);
390 			dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n",
391 			    flow_control->host_addr,
392 			    flow_control->me_addr);
393 			if (same_flow_addr(cl_pos, flow_control)) {
394 				dev_dbg(&dev->pdev->dev, "recv ctrl msg for host  %d ME %d.\n",
395 				    flow_control->host_addr,
396 				    flow_control->me_addr);
397 				cl_pos->mei_flow_ctrl_creds++;
398 				dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n",
399 				    cl_pos->mei_flow_ctrl_creds);
400 				break;
401 			}
402 		}
403 	}
404 }
405 
406 /**
407  * same_disconn_addr - tells if they have the same address
408  *
409  * @file: private data of the file object.
410  * @disconn: disconnection request.
411  *
412  * returns !=0, same; 0,not.
413  */
414 static int same_disconn_addr(struct mei_cl *cl,
415 			     struct hbm_client_connect_request *req)
416 {
417 	return (cl->host_client_id == req->host_addr &&
418 		cl->me_client_id == req->me_addr);
419 }
420 
421 /**
422  * mei_client_disconnect_request - disconnects from request irq routine
423  *
424  * @dev: the device structure.
425  * @disconnect_req: disconnect request bus message.
426  */
427 static void mei_client_disconnect_request(struct mei_device *dev,
428 		struct hbm_client_connect_request *disconnect_req)
429 {
430 	struct hbm_client_connect_response *disconnect_res;
431 	struct mei_cl *pos, *next;
432 	const size_t len = sizeof(struct hbm_client_connect_response);
433 
434 	list_for_each_entry_safe(pos, next, &dev->file_list, link) {
435 		if (same_disconn_addr(pos, disconnect_req)) {
436 			dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n",
437 					disconnect_req->host_addr,
438 					disconnect_req->me_addr);
439 			pos->state = MEI_FILE_DISCONNECTED;
440 			pos->timer_count = 0;
441 			if (pos == &dev->wd_cl)
442 				dev->wd_pending = false;
443 			else if (pos == &dev->iamthif_cl)
444 				dev->iamthif_timer = 0;
445 
446 			/* prepare disconnect response */
447 			(void)mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len);
448 			disconnect_res =
449 				(struct hbm_client_connect_response *)
450 				&dev->wr_ext_msg.data;
451 			disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD;
452 			disconnect_res->host_addr = pos->host_client_id;
453 			disconnect_res->me_addr = pos->me_client_id;
454 			disconnect_res->status = 0;
455 			break;
456 		}
457 	}
458 }
459 
460 /**
461  * mei_irq_thread_read_bus_message - bottom half read routine after ISR to
462  * handle the read bus message cmd processing.
463  *
464  * @dev: the device structure
465  * @mei_hdr: header of bus message
466  */
467 static void mei_irq_thread_read_bus_message(struct mei_device *dev,
468 		struct mei_msg_hdr *mei_hdr)
469 {
470 	struct mei_bus_message *mei_msg;
471 	struct mei_me_client *me_client;
472 	struct hbm_host_version_response *version_res;
473 	struct hbm_client_connect_response *connect_res;
474 	struct hbm_client_connect_response *disconnect_res;
475 	struct hbm_client_connect_request *disconnect_req;
476 	struct hbm_flow_control *flow_control;
477 	struct hbm_props_response *props_res;
478 	struct hbm_host_enum_response *enum_res;
479 	struct hbm_host_stop_request *stop_req;
480 
481 	/* read the message to our buffer */
482 	BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf));
483 	mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
484 	mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;
485 
486 	switch (mei_msg->hbm_cmd) {
487 	case HOST_START_RES_CMD:
488 		version_res = (struct hbm_host_version_response *) mei_msg;
489 		if (version_res->host_version_supported) {
490 			dev->version.major_version = HBM_MAJOR_VERSION;
491 			dev->version.minor_version = HBM_MINOR_VERSION;
492 			if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
493 			    dev->init_clients_state == MEI_START_MESSAGE) {
494 				dev->init_clients_timer = 0;
495 				mei_host_enum_clients_message(dev);
496 			} else {
497 				dev->recvd_msg = false;
498 				dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n");
499 				mei_reset(dev, 1);
500 				return;
501 			}
502 		} else {
503 			u32 *buf = dev->wr_msg_buf;
504 			const size_t len = sizeof(struct hbm_host_stop_request);
505 
506 			dev->version = version_res->me_max_version;
507 
508 			/* send stop message */
509 			mei_hdr = mei_hbm_hdr(&buf[0], len);
510 			stop_req = (struct hbm_host_stop_request *)&buf[1];
511 			memset(stop_req, 0, len);
512 			stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
513 			stop_req->reason = DRIVER_STOP_REQUEST;
514 
515 			mei_write_message(dev, mei_hdr,
516 					(unsigned char *)stop_req, len);
517 			dev_dbg(&dev->pdev->dev, "version mismatch.\n");
518 			return;
519 		}
520 
521 		dev->recvd_msg = true;
522 		dev_dbg(&dev->pdev->dev, "host start response message received.\n");
523 		break;
524 
525 	case CLIENT_CONNECT_RES_CMD:
526 		connect_res = (struct hbm_client_connect_response *) mei_msg;
527 		mei_client_connect_response(dev, connect_res);
528 		dev_dbg(&dev->pdev->dev, "client connect response message received.\n");
529 		wake_up(&dev->wait_recvd_msg);
530 		break;
531 
532 	case CLIENT_DISCONNECT_RES_CMD:
533 		disconnect_res = (struct hbm_client_connect_response *) mei_msg;
534 		mei_client_disconnect_response(dev, disconnect_res);
535 		dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
536 		wake_up(&dev->wait_recvd_msg);
537 		break;
538 
539 	case MEI_FLOW_CONTROL_CMD:
540 		flow_control = (struct hbm_flow_control *) mei_msg;
541 		mei_client_flow_control_response(dev, flow_control);
542 		dev_dbg(&dev->pdev->dev, "client flow control response message received.\n");
543 		break;
544 
545 	case HOST_CLIENT_PROPERTIES_RES_CMD:
546 		props_res = (struct hbm_props_response *)mei_msg;
547 		me_client = &dev->me_clients[dev->me_client_presentation_num];
548 
549 		if (props_res->status || !dev->me_clients) {
550 			dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
551 			mei_reset(dev, 1);
552 			return;
553 		}
554 
555 		if (me_client->client_id != props_res->address) {
556 			dev_err(&dev->pdev->dev,
557 				"Host client properties reply mismatch\n");
558 			mei_reset(dev, 1);
559 
560 			return;
561 		}
562 
563 		if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
564 		    dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) {
565 			dev_err(&dev->pdev->dev,
566 				"Unexpected client properties reply\n");
567 			mei_reset(dev, 1);
568 
569 			return;
570 		}
571 
572 		me_client->props = props_res->client_properties;
573 		dev->me_client_index++;
574 		dev->me_client_presentation_num++;
575 
576 		mei_host_client_enumerate(dev);
577 
578 		break;
579 
580 	case HOST_ENUM_RES_CMD:
581 		enum_res = (struct hbm_host_enum_response *) mei_msg;
582 		memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
583 		if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
584 		    dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) {
585 				dev->init_clients_timer = 0;
586 				dev->me_client_presentation_num = 0;
587 				dev->me_client_index = 0;
588 				mei_allocate_me_clients_storage(dev);
589 				dev->init_clients_state =
590 					MEI_CLIENT_PROPERTIES_MESSAGE;
591 
592 				mei_host_client_enumerate(dev);
593 		} else {
594 			dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
595 			mei_reset(dev, 1);
596 			return;
597 		}
598 		break;
599 
600 	case HOST_STOP_RES_CMD:
601 		dev->dev_state = MEI_DEV_DISABLED;
602 		dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n");
603 		mei_reset(dev, 1);
604 		break;
605 
606 	case CLIENT_DISCONNECT_REQ_CMD:
607 		/* search for client */
608 		disconnect_req = (struct hbm_client_connect_request *)mei_msg;
609 		mei_client_disconnect_request(dev, disconnect_req);
610 		break;
611 
612 	case ME_STOP_REQ_CMD:
613 	{
614 		/* prepare stop request: sent in next interrupt event */
615 
616 		const size_t len = sizeof(struct hbm_host_stop_request);
617 
618 		mei_hdr = mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len);
619 		stop_req = (struct hbm_host_stop_request *)&dev->wr_ext_msg.data;
620 		memset(stop_req, 0, len);
621 		stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
622 		stop_req->reason = DRIVER_STOP_REQUEST;
623 		break;
624 	}
625 	default:
626 		BUG();
627 		break;
628 
629 	}
630 }
631 
632 
633 /**
634  * _mei_hb_read - processes read related operation.
635  *
636  * @dev: the device structure.
637  * @slots: free slots.
638  * @cb_pos: callback block.
639  * @cl: private data of the file object.
640  * @cmpl_list: complete list.
641  *
642  * returns 0, OK; otherwise, error.
643  */
644 static int _mei_irq_thread_read(struct mei_device *dev,	s32 *slots,
645 			struct mei_cl_cb *cb_pos,
646 			struct mei_cl *cl,
647 			struct mei_cl_cb *cmpl_list)
648 {
649 	if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
650 			sizeof(struct hbm_flow_control))) {
651 		/* return the cancel routine */
652 		list_del(&cb_pos->list);
653 		return -EBADMSG;
654 	}
655 
656 	*slots -= mei_data2slots(sizeof(struct hbm_flow_control));
657 
658 	if (mei_send_flow_control(dev, cl)) {
659 		cl->status = -ENODEV;
660 		cb_pos->buf_idx = 0;
661 		list_move_tail(&cb_pos->list, &cmpl_list->list);
662 		return -ENODEV;
663 	}
664 	list_move_tail(&cb_pos->list, &dev->read_list.list);
665 
666 	return 0;
667 }
668 
669 
670 /**
671  * _mei_irq_thread_ioctl - processes ioctl related operation.
672  *
673  * @dev: the device structure.
674  * @slots: free slots.
675  * @cb_pos: callback block.
676  * @cl: private data of the file object.
677  * @cmpl_list: complete list.
678  *
679  * returns 0, OK; otherwise, error.
680  */
681 static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
682 			struct mei_cl_cb *cb_pos,
683 			struct mei_cl *cl,
684 			struct mei_cl_cb *cmpl_list)
685 {
686 	if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
687 			sizeof(struct hbm_client_connect_request))) {
688 		/* return the cancel routine */
689 		list_del(&cb_pos->list);
690 		return -EBADMSG;
691 	}
692 
693 	cl->state = MEI_FILE_CONNECTING;
694 	 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request));
695 	if (mei_connect(dev, cl)) {
696 		cl->status = -ENODEV;
697 		cb_pos->buf_idx = 0;
698 		list_del(&cb_pos->list);
699 		return -ENODEV;
700 	} else {
701 		list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
702 		cl->timer_count = MEI_CONNECT_TIMEOUT;
703 	}
704 	return 0;
705 }
706 
707 /**
708  * mei_irq_thread_write_complete - write messages to device.
709  *
710  * @dev: the device structure.
711  * @slots: free slots.
712  * @cb: callback block.
713  * @cmpl_list: complete list.
714  *
715  * returns 0, OK; otherwise, error.
716  */
717 static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
718 			struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
719 {
720 	struct mei_msg_hdr *mei_hdr;
721 	struct mei_cl *cl = cb->cl;
722 	size_t len = cb->request_buffer.size - cb->buf_idx;
723 	size_t msg_slots = mei_data2slots(len);
724 
725 	mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
726 	mei_hdr->host_addr = cl->host_client_id;
727 	mei_hdr->me_addr = cl->me_client_id;
728 	mei_hdr->reserved = 0;
729 
730 	if (*slots >= msg_slots) {
731 		mei_hdr->length = len;
732 		mei_hdr->msg_complete = 1;
733 	/* Split the message only if we can write the whole host buffer */
734 	} else if (*slots == dev->hbuf_depth) {
735 		msg_slots = *slots;
736 		len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
737 		mei_hdr->length = len;
738 		mei_hdr->msg_complete = 0;
739 	} else {
740 		/* wait for next time the host buffer is empty */
741 		return 0;
742 	}
743 
744 	dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n",
745 			cb->request_buffer.size, cb->buf_idx);
746 	dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n",
747 			mei_hdr->length, mei_hdr->msg_complete);
748 
749 	*slots -=  msg_slots;
750 	if (mei_write_message(dev, mei_hdr,
751 		cb->request_buffer.data + cb->buf_idx, len)) {
752 		cl->status = -ENODEV;
753 		list_move_tail(&cb->list, &cmpl_list->list);
754 		return -ENODEV;
755 	}
756 
757 	if (mei_flow_ctrl_reduce(dev, cl))
758 		return -ENODEV;
759 
760 	cl->status = 0;
761 	cb->buf_idx += mei_hdr->length;
762 	if (mei_hdr->msg_complete)
763 		list_move_tail(&cb->list, &dev->write_waiting_list.list);
764 
765 	return 0;
766 }
767 
768 /**
769  * mei_irq_thread_read_handler - bottom half read routine after ISR to
770  * handle the read processing.
771  *
772  * @cmpl_list: An instance of our list structure
773  * @dev: the device structure
774  * @slots: slots to read.
775  *
776  * returns 0 on success, <0 on failure.
777  */
778 static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list,
779 		struct mei_device *dev,
780 		s32 *slots)
781 {
782 	struct mei_msg_hdr *mei_hdr;
783 	struct mei_cl *cl_pos = NULL;
784 	struct mei_cl *cl_next = NULL;
785 	int ret = 0;
786 
787 	if (!dev->rd_msg_hdr) {
788 		dev->rd_msg_hdr = mei_mecbrw_read(dev);
789 		dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
790 		(*slots)--;
791 		dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
792 	}
793 	mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr;
794 	dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length);
795 
796 	if (mei_hdr->reserved || !dev->rd_msg_hdr) {
797 		dev_dbg(&dev->pdev->dev, "corrupted message header.\n");
798 		ret = -EBADMSG;
799 		goto end;
800 	}
801 
802 	if (mei_hdr->host_addr || mei_hdr->me_addr) {
803 		list_for_each_entry_safe(cl_pos, cl_next,
804 					&dev->file_list, link) {
805 			dev_dbg(&dev->pdev->dev,
806 					"list_for_each_entry_safe read host"
807 					" client = %d, ME client = %d\n",
808 					cl_pos->host_client_id,
809 					cl_pos->me_client_id);
810 			if (cl_pos->host_client_id == mei_hdr->host_addr &&
811 			    cl_pos->me_client_id == mei_hdr->me_addr)
812 				break;
813 		}
814 
815 		if (&cl_pos->link == &dev->file_list) {
816 			dev_dbg(&dev->pdev->dev, "corrupted message header\n");
817 			ret = -EBADMSG;
818 			goto end;
819 		}
820 	}
821 	if (((*slots) * sizeof(u32)) < mei_hdr->length) {
822 		dev_dbg(&dev->pdev->dev,
823 				"we can't read the message slots =%08x.\n",
824 				*slots);
825 		/* we can't read the message */
826 		ret = -ERANGE;
827 		goto end;
828 	}
829 
830 	/* decide where to read the message too */
831 	if (!mei_hdr->host_addr) {
832 		dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n");
833 		mei_irq_thread_read_bus_message(dev, mei_hdr);
834 		dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n");
835 	} else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
836 		   (MEI_FILE_CONNECTED == dev->iamthif_cl.state) &&
837 		   (dev->iamthif_state == MEI_IAMTHIF_READING)) {
838 		dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n");
839 		dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
840 				mei_hdr->length);
841 
842 		ret = mei_amthif_irq_read_message(cmpl_list, dev, mei_hdr);
843 		if (ret)
844 			goto end;
845 
846 	} else {
847 		dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n");
848 		ret = mei_irq_thread_read_client_message(cmpl_list,
849 							 dev, mei_hdr);
850 		if (ret)
851 			goto end;
852 
853 	}
854 
855 	/* reset the number of slots and header */
856 	*slots = mei_count_full_read_slots(dev);
857 	dev->rd_msg_hdr = 0;
858 
859 	if (*slots == -EOVERFLOW) {
860 		/* overflow - reset */
861 		dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n");
862 		/* set the event since message has been read */
863 		ret = -ERANGE;
864 		goto end;
865 	}
866 end:
867 	return ret;
868 }
869 
870 
871 /**
872  * mei_irq_thread_write_handler - bottom half write routine after
873  * ISR to handle the write processing.
874  *
875  * @dev: the device structure
876  * @cmpl_list: An instance of our list structure
877  *
878  * returns 0 on success, <0 on failure.
879  */
880 static int mei_irq_thread_write_handler(struct mei_device *dev,
881 				struct mei_cl_cb *cmpl_list)
882 {
883 
884 	struct mei_cl *cl;
885 	struct mei_cl_cb *pos = NULL, *next = NULL;
886 	struct mei_cl_cb *list;
887 	s32 slots;
888 	int ret;
889 
890 	if (!mei_hbuf_is_empty(dev)) {
891 		dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
892 		return 0;
893 	}
894 	slots = mei_hbuf_empty_slots(dev);
895 	if (slots <= 0)
896 		return -EMSGSIZE;
897 
898 	/* complete all waiting for write CB */
899 	dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
900 
901 	list = &dev->write_waiting_list;
902 	list_for_each_entry_safe(pos, next, &list->list, list) {
903 		cl = pos->cl;
904 		if (cl == NULL)
905 			continue;
906 
907 		cl->status = 0;
908 		list_del(&pos->list);
909 		if (MEI_WRITING == cl->writing_state &&
910 		    pos->fop_type == MEI_FOP_WRITE &&
911 		    cl != &dev->iamthif_cl) {
912 			dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n");
913 			cl->writing_state = MEI_WRITE_COMPLETE;
914 			list_add_tail(&pos->list, &cmpl_list->list);
915 		}
916 		if (cl == &dev->iamthif_cl) {
917 			dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
918 			if (dev->iamthif_flow_control_pending) {
919 				ret = mei_amthif_irq_read(dev, &slots);
920 				if (ret)
921 					return ret;
922 			}
923 		}
924 	}
925 
926 	if (dev->wd_state == MEI_WD_STOPPING) {
927 		dev->wd_state = MEI_WD_IDLE;
928 		wake_up_interruptible(&dev->wait_stop_wd);
929 	}
930 
931 	if (dev->wr_ext_msg.hdr.length) {
932 		mei_write_message(dev, &dev->wr_ext_msg.hdr,
933 			dev->wr_ext_msg.data, dev->wr_ext_msg.hdr.length);
934 		slots -= mei_data2slots(dev->wr_ext_msg.hdr.length);
935 		dev->wr_ext_msg.hdr.length = 0;
936 	}
937 	if (dev->dev_state == MEI_DEV_ENABLED) {
938 		if (dev->wd_pending &&
939 		    mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
940 			if (mei_wd_send(dev))
941 				dev_dbg(&dev->pdev->dev, "wd send failed.\n");
942 			else if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
943 				return -ENODEV;
944 
945 			dev->wd_pending = false;
946 
947 			if (dev->wd_state == MEI_WD_RUNNING)
948 				slots -= mei_data2slots(MEI_WD_START_MSG_SIZE);
949 			else
950 				slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE);
951 		}
952 	}
953 
954 	/* complete control write list CB */
955 	dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
956 	list_for_each_entry_safe(pos, next, &dev->ctrl_wr_list.list, list) {
957 		cl = pos->cl;
958 		if (!cl) {
959 			list_del(&pos->list);
960 			return -ENODEV;
961 		}
962 		switch (pos->fop_type) {
963 		case MEI_FOP_CLOSE:
964 			/* send disconnect message */
965 			ret = _mei_irq_thread_close(dev, &slots, pos,
966 						cl, cmpl_list);
967 			if (ret)
968 				return ret;
969 
970 			break;
971 		case MEI_FOP_READ:
972 			/* send flow control message */
973 			ret = _mei_irq_thread_read(dev, &slots, pos,
974 						cl, cmpl_list);
975 			if (ret)
976 				return ret;
977 
978 			break;
979 		case MEI_FOP_IOCTL:
980 			/* connect message */
981 			if (mei_other_client_is_connecting(dev, cl))
982 				continue;
983 			ret = _mei_irq_thread_ioctl(dev, &slots, pos,
984 						cl, cmpl_list);
985 			if (ret)
986 				return ret;
987 
988 			break;
989 
990 		default:
991 			BUG();
992 		}
993 
994 	}
995 	/* complete  write list CB */
996 	dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
997 	list_for_each_entry_safe(pos, next, &dev->write_list.list, list) {
998 		cl = pos->cl;
999 		if (cl == NULL)
1000 			continue;
1001 		if (mei_flow_ctrl_creds(dev, cl) <= 0) {
1002 			dev_dbg(&dev->pdev->dev,
1003 				"No flow control credentials for client %d, not sending.\n",
1004 				cl->host_client_id);
1005 			continue;
1006 		}
1007 
1008 		if (cl == &dev->iamthif_cl)
1009 			ret = mei_amthif_irq_write_complete(dev, &slots,
1010 							pos, cmpl_list);
1011 		else
1012 			ret = mei_irq_thread_write_complete(dev, &slots, pos,
1013 						cmpl_list);
1014 		if (ret)
1015 			return ret;
1016 
1017 	}
1018 	return 0;
1019 }
1020 
1021 
1022 
1023 /**
1024  * mei_timer - timer function.
1025  *
1026  * @work: pointer to the work_struct structure
1027  *
1028  * NOTE: This function is called by timer interrupt work
1029  */
1030 void mei_timer(struct work_struct *work)
1031 {
1032 	unsigned long timeout;
1033 	struct mei_cl *cl_pos = NULL;
1034 	struct mei_cl *cl_next = NULL;
1035 	struct mei_cl_cb  *cb_pos = NULL;
1036 	struct mei_cl_cb  *cb_next = NULL;
1037 
1038 	struct mei_device *dev = container_of(work,
1039 					struct mei_device, timer_work.work);
1040 
1041 
1042 	mutex_lock(&dev->device_lock);
1043 	if (dev->dev_state != MEI_DEV_ENABLED) {
1044 		if (dev->dev_state == MEI_DEV_INIT_CLIENTS) {
1045 			if (dev->init_clients_timer) {
1046 				if (--dev->init_clients_timer == 0) {
1047 					dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n",
1048 						dev->init_clients_state);
1049 					mei_reset(dev, 1);
1050 				}
1051 			}
1052 		}
1053 		goto out;
1054 	}
1055 	/*** connect/disconnect timeouts ***/
1056 	list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
1057 		if (cl_pos->timer_count) {
1058 			if (--cl_pos->timer_count == 0) {
1059 				dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n");
1060 				mei_reset(dev, 1);
1061 				goto out;
1062 			}
1063 		}
1064 	}
1065 
1066 	if (dev->iamthif_stall_timer) {
1067 		if (--dev->iamthif_stall_timer == 0) {
1068 			dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n");
1069 			mei_reset(dev, 1);
1070 			dev->iamthif_msg_buf_size = 0;
1071 			dev->iamthif_msg_buf_index = 0;
1072 			dev->iamthif_canceled = false;
1073 			dev->iamthif_ioctl = true;
1074 			dev->iamthif_state = MEI_IAMTHIF_IDLE;
1075 			dev->iamthif_timer = 0;
1076 
1077 			mei_io_cb_free(dev->iamthif_current_cb);
1078 			dev->iamthif_current_cb = NULL;
1079 
1080 			dev->iamthif_file_object = NULL;
1081 			mei_amthif_run_next_cmd(dev);
1082 		}
1083 	}
1084 
1085 	if (dev->iamthif_timer) {
1086 
1087 		timeout = dev->iamthif_timer +
1088 			mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
1089 
1090 		dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
1091 				dev->iamthif_timer);
1092 		dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout);
1093 		dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies);
1094 		if (time_after(jiffies, timeout)) {
1095 			/*
1096 			 * User didn't read the AMTHI data on time (15sec)
1097 			 * freeing AMTHI for other requests
1098 			 */
1099 
1100 			dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n");
1101 
1102 			list_for_each_entry_safe(cb_pos, cb_next,
1103 				&dev->amthif_rd_complete_list.list, list) {
1104 
1105 				cl_pos = cb_pos->file_object->private_data;
1106 
1107 				/* Finding the AMTHI entry. */
1108 				if (cl_pos == &dev->iamthif_cl)
1109 					list_del(&cb_pos->list);
1110 			}
1111 			mei_io_cb_free(dev->iamthif_current_cb);
1112 			dev->iamthif_current_cb = NULL;
1113 
1114 			dev->iamthif_file_object->private_data = NULL;
1115 			dev->iamthif_file_object = NULL;
1116 			dev->iamthif_timer = 0;
1117 			mei_amthif_run_next_cmd(dev);
1118 
1119 		}
1120 	}
1121 out:
1122 	schedule_delayed_work(&dev->timer_work, 2 * HZ);
1123 	mutex_unlock(&dev->device_lock);
1124 }
1125 
1126 /**
1127  *  mei_interrupt_thread_handler - function called after ISR to handle the interrupt
1128  * processing.
1129  *
1130  * @irq: The irq number
1131  * @dev_id: pointer to the device structure
1132  *
1133  * returns irqreturn_t
1134  *
1135  */
1136 irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
1137 {
1138 	struct mei_device *dev = (struct mei_device *) dev_id;
1139 	struct mei_cl_cb complete_list;
1140 	struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
1141 	struct mei_cl *cl;
1142 	s32 slots;
1143 	int rets;
1144 	bool  bus_message_received;
1145 
1146 
1147 	dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n");
1148 	/* initialize our complete list */
1149 	mutex_lock(&dev->device_lock);
1150 	mei_io_list_init(&complete_list);
1151 	dev->host_hw_state = mei_hcsr_read(dev);
1152 
1153 	/* Ack the interrupt here
1154 	 * In case of MSI we don't go through the quick handler */
1155 	if (pci_dev_msi_enabled(dev->pdev))
1156 		mei_reg_write(dev, H_CSR, dev->host_hw_state);
1157 
1158 	dev->me_hw_state = mei_mecsr_read(dev);
1159 
1160 	/* check if ME wants a reset */
1161 	if ((dev->me_hw_state & ME_RDY_HRA) == 0 &&
1162 	    dev->dev_state != MEI_DEV_RESETING &&
1163 	    dev->dev_state != MEI_DEV_INITIALIZING) {
1164 		dev_dbg(&dev->pdev->dev, "FW not ready.\n");
1165 		mei_reset(dev, 1);
1166 		mutex_unlock(&dev->device_lock);
1167 		return IRQ_HANDLED;
1168 	}
1169 
1170 	/*  check if we need to start the dev */
1171 	if ((dev->host_hw_state & H_RDY) == 0) {
1172 		if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) {
1173 			dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
1174 			dev->host_hw_state |= (H_IE | H_IG | H_RDY);
1175 			mei_hcsr_set(dev);
1176 			dev->dev_state = MEI_DEV_INIT_CLIENTS;
1177 			dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
1178 			/* link is established
1179 			 * start sending messages.
1180 			 */
1181 			mei_host_start_message(dev);
1182 			mutex_unlock(&dev->device_lock);
1183 			return IRQ_HANDLED;
1184 		} else {
1185 			dev_dbg(&dev->pdev->dev, "FW not ready.\n");
1186 			mutex_unlock(&dev->device_lock);
1187 			return IRQ_HANDLED;
1188 		}
1189 	}
1190 	/* check slots available for reading */
1191 	slots = mei_count_full_read_slots(dev);
1192 	while (slots > 0) {
1193 		/* we have urgent data to send so break the read */
1194 		if (dev->wr_ext_msg.hdr.length)
1195 			break;
1196 		dev_dbg(&dev->pdev->dev, "slots =%08x\n", slots);
1197 		dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n");
1198 		rets = mei_irq_thread_read_handler(&complete_list, dev, &slots);
1199 		if (rets)
1200 			goto end;
1201 	}
1202 	rets = mei_irq_thread_write_handler(dev, &complete_list);
1203 end:
1204 	dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
1205 	dev->host_hw_state = mei_hcsr_read(dev);
1206 	dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
1207 
1208 	bus_message_received = false;
1209 	if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
1210 		dev_dbg(&dev->pdev->dev, "received waiting bus message\n");
1211 		bus_message_received = true;
1212 	}
1213 	mutex_unlock(&dev->device_lock);
1214 	if (bus_message_received) {
1215 		dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n");
1216 		wake_up_interruptible(&dev->wait_recvd_msg);
1217 		bus_message_received = false;
1218 	}
1219 	if (list_empty(&complete_list.list))
1220 		return IRQ_HANDLED;
1221 
1222 
1223 	list_for_each_entry_safe(cb_pos, cb_next, &complete_list.list, list) {
1224 		cl = cb_pos->cl;
1225 		list_del(&cb_pos->list);
1226 		if (cl) {
1227 			if (cl != &dev->iamthif_cl) {
1228 				dev_dbg(&dev->pdev->dev, "completing call back.\n");
1229 				_mei_cmpl(cl, cb_pos);
1230 				cb_pos = NULL;
1231 			} else if (cl == &dev->iamthif_cl) {
1232 				mei_amthif_complete(dev, cb_pos);
1233 			}
1234 		}
1235 	}
1236 	return IRQ_HANDLED;
1237 }
1238