xref: /linux/drivers/misc/mei/interrupt.c (revision 69050f8d6d075dc01af7a5f2f550a8067510366f)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2003-2018, Intel Corporation. All rights reserved.
4  * Intel Management Engine Interface (Intel MEI) Linux driver
5  */
6 
7 #include <linux/export.h>
8 #include <linux/kthread.h>
9 #include <linux/interrupt.h>
10 #include <linux/fs.h>
11 #include <linux/jiffies.h>
12 #include <linux/slab.h>
13 #include <linux/pm_runtime.h>
14 
15 #include <linux/mei.h>
16 
17 #include "mei_dev.h"
18 #include "hbm.h"
19 #include "client.h"
20 
21 
22 /**
23  * mei_irq_compl_handler - dispatch complete handlers
24  *	for the completed callbacks
25  *
26  * @dev: mei device
27  * @cmpl_list: list of completed cbs
28  */
29 void mei_irq_compl_handler(struct mei_device *dev, struct list_head *cmpl_list)
30 {
31 	struct mei_cl_cb *cb, *next;
32 	struct mei_cl *cl;
33 
34 	list_for_each_entry_safe(cb, next, cmpl_list, list) {
35 		cl = cb->cl;
36 		list_del_init(&cb->list);
37 
38 		cl_dbg(dev, cl, "completing call back.\n");
39 		mei_cl_complete(cl, cb);
40 	}
41 }
42 EXPORT_SYMBOL_GPL(mei_irq_compl_handler);
43 
44 /**
45  * mei_cl_hbm_equal - check if hbm is addressed to the client
46  *
47  * @cl: host client
48  * @mei_hdr: header of mei client message
49  *
50  * Return: true if matches, false otherwise
51  */
52 static inline int mei_cl_hbm_equal(struct mei_cl *cl,
53 			struct mei_msg_hdr *mei_hdr)
54 {
55 	return  mei_cl_host_addr(cl) == mei_hdr->host_addr &&
56 		mei_cl_me_id(cl) == mei_hdr->me_addr;
57 }
58 
59 /**
60  * mei_irq_discard_msg  - discard received message
61  *
62  * @dev: mei device
63  * @hdr: message header
64  * @discard_len: the length of the message to discard (excluding header)
65  */
66 static void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr,
67 				size_t discard_len)
68 {
69 	if (hdr->dma_ring) {
70 		mei_dma_ring_read(dev, NULL,
71 				  hdr->extension[dev->rd_msg_hdr_count - 2]);
72 		discard_len = 0;
73 	}
74 	/*
75 	 * no need to check for size as it is guaranteed
76 	 * that length fits into rd_msg_buf
77 	 */
78 	mei_read_slots(dev, dev->rd_msg_buf, discard_len);
79 	dev_dbg(&dev->dev, "discarding message " MEI_HDR_FMT "\n",
80 		MEI_HDR_PRM(hdr));
81 }
82 
83 /**
84  * mei_cl_irq_read_msg - process client message
85  *
86  * @cl: reading client
87  * @mei_hdr: header of mei client message
88  * @meta: extend meta header
89  * @cmpl_list: completion list
90  *
91  * Return: always 0
92  */
93 static int mei_cl_irq_read_msg(struct mei_cl *cl,
94 			       struct mei_msg_hdr *mei_hdr,
95 			       struct mei_ext_meta_hdr *meta,
96 			       struct list_head *cmpl_list)
97 {
98 	struct mei_device *dev = cl->dev;
99 	struct mei_cl_cb *cb;
100 
101 	struct mei_ext_hdr_vtag *vtag_hdr = NULL;
102 	struct mei_ext_hdr_gsc_f2h *gsc_f2h = NULL;
103 
104 	size_t buf_sz;
105 	u32 length;
106 	u32 ext_len;
107 
108 	length = mei_hdr->length;
109 	ext_len = 0;
110 	if (mei_hdr->extended) {
111 		ext_len = sizeof(*meta) + mei_slots2data(meta->size);
112 		length -= ext_len;
113 	}
114 
115 	cb = list_first_entry_or_null(&cl->rd_pending, struct mei_cl_cb, list);
116 	if (!cb) {
117 		if (!mei_cl_is_fixed_address(cl)) {
118 			cl_err(dev, cl, "pending read cb not found\n");
119 			goto discard;
120 		}
121 		cb = mei_cl_alloc_cb(cl, mei_cl_mtu(cl), MEI_FOP_READ, cl->fp);
122 		if (!cb)
123 			goto discard;
124 		list_add_tail(&cb->list, &cl->rd_pending);
125 	}
126 
127 	if (mei_hdr->extended) {
128 		struct mei_ext_hdr *ext = mei_ext_begin(meta);
129 		do {
130 			switch (ext->type) {
131 			case MEI_EXT_HDR_VTAG:
132 				vtag_hdr = (struct mei_ext_hdr_vtag *)ext;
133 				break;
134 			case MEI_EXT_HDR_GSC:
135 				gsc_f2h = (struct mei_ext_hdr_gsc_f2h *)ext;
136 				cb->ext_hdr = (struct mei_ext_hdr *) kzalloc_obj(*gsc_f2h,
137 										 GFP_KERNEL);
138 				if (!cb->ext_hdr) {
139 					cb->status = -ENOMEM;
140 					goto discard;
141 				}
142 				break;
143 			case MEI_EXT_HDR_NONE:
144 				fallthrough;
145 			default:
146 				cl_err(dev, cl, "unknown extended header\n");
147 				cb->status = -EPROTO;
148 				break;
149 			}
150 
151 			ext = mei_ext_next(ext);
152 		} while (!mei_ext_last(meta, ext));
153 
154 		if (!vtag_hdr && !gsc_f2h) {
155 			cl_dbg(dev, cl, "no vtag or gsc found in extended header.\n");
156 			cb->status = -EPROTO;
157 			goto discard;
158 		}
159 	}
160 
161 	if (vtag_hdr) {
162 		cl_dbg(dev, cl, "vtag: %d\n", vtag_hdr->vtag);
163 		if (cb->vtag && cb->vtag != vtag_hdr->vtag) {
164 			cl_err(dev, cl, "mismatched tag: %d != %d\n",
165 			       cb->vtag, vtag_hdr->vtag);
166 			cb->status = -EPROTO;
167 			goto discard;
168 		}
169 		cb->vtag = vtag_hdr->vtag;
170 	}
171 
172 	if (gsc_f2h) {
173 		u32 ext_hdr_len = mei_ext_hdr_len(&gsc_f2h->hdr);
174 
175 		if (!dev->hbm_f_gsc_supported) {
176 			cl_err(dev, cl, "gsc extended header is not supported\n");
177 			cb->status = -EPROTO;
178 			goto discard;
179 		}
180 
181 		if (length) {
182 			cl_err(dev, cl, "no data allowed in cb with gsc\n");
183 			cb->status = -EPROTO;
184 			goto discard;
185 		}
186 		if (ext_hdr_len > sizeof(*gsc_f2h)) {
187 			cl_err(dev, cl, "gsc extended header is too big %u\n", ext_hdr_len);
188 			cb->status = -EPROTO;
189 			goto discard;
190 		}
191 		memcpy(cb->ext_hdr, gsc_f2h, ext_hdr_len);
192 	}
193 
194 	if (!mei_cl_is_connected(cl)) {
195 		cl_dbg(dev, cl, "not connected\n");
196 		cb->status = -ENODEV;
197 		goto discard;
198 	}
199 
200 	if (mei_hdr->dma_ring)
201 		length = mei_hdr->extension[mei_data2slots(ext_len)];
202 
203 	buf_sz = length + cb->buf_idx;
204 	/* catch for integer overflow */
205 	if (buf_sz < cb->buf_idx) {
206 		cl_err(dev, cl, "message is too big len %d idx %zu\n",
207 		       length, cb->buf_idx);
208 		cb->status = -EMSGSIZE;
209 		goto discard;
210 	}
211 
212 	if (cb->buf.size < buf_sz) {
213 		cl_dbg(dev, cl, "message overflow. size %zu len %d idx %zu\n",
214 			cb->buf.size, length, cb->buf_idx);
215 		cb->status = -EMSGSIZE;
216 		goto discard;
217 	}
218 
219 	if (mei_hdr->dma_ring) {
220 		mei_dma_ring_read(dev, cb->buf.data + cb->buf_idx, length);
221 		/*  for DMA read 0 length to generate interrupt to the device */
222 		mei_read_slots(dev, cb->buf.data + cb->buf_idx, 0);
223 	} else {
224 		mei_read_slots(dev, cb->buf.data + cb->buf_idx, length);
225 	}
226 
227 	cb->buf_idx += length;
228 
229 	if (mei_hdr->msg_complete) {
230 		cl_dbg(dev, cl, "completed read length = %zu\n", cb->buf_idx);
231 		list_move_tail(&cb->list, cmpl_list);
232 	} else {
233 		pm_request_autosuspend(dev->parent);
234 	}
235 
236 	return 0;
237 
238 discard:
239 	if (cb)
240 		list_move_tail(&cb->list, cmpl_list);
241 	mei_irq_discard_msg(dev, mei_hdr, length);
242 	return 0;
243 }
244 
245 /**
246  * mei_cl_irq_disconnect_rsp - send disconnection response message
247  *
248  * @cl: client
249  * @cb: callback block.
250  * @cmpl_list: complete list.
251  *
252  * Return: 0, OK; otherwise, error.
253  */
254 static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb,
255 				     struct list_head *cmpl_list)
256 {
257 	struct mei_device *dev = cl->dev;
258 	u32 msg_slots;
259 	int slots;
260 	int ret;
261 
262 	msg_slots = mei_hbm2slots(sizeof(struct hbm_client_connect_response));
263 	slots = mei_hbuf_empty_slots(dev);
264 	if (slots < 0)
265 		return -EOVERFLOW;
266 
267 	if ((u32)slots < msg_slots)
268 		return -EMSGSIZE;
269 
270 	ret = mei_hbm_cl_disconnect_rsp(dev, cl);
271 	list_move_tail(&cb->list, cmpl_list);
272 
273 	return ret;
274 }
275 
276 /**
277  * mei_cl_irq_read - processes client read related operation from the
278  *	interrupt thread context - request for flow control credits
279  *
280  * @cl: client
281  * @cb: callback block.
282  * @cmpl_list: complete list.
283  *
284  * Return: 0, OK; otherwise, error.
285  */
286 static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
287 			   struct list_head *cmpl_list)
288 {
289 	struct mei_device *dev = cl->dev;
290 	u32 msg_slots;
291 	int slots;
292 	int ret;
293 
294 	if (!list_empty(&cl->rd_pending))
295 		return 0;
296 
297 	msg_slots = mei_hbm2slots(sizeof(struct hbm_flow_control));
298 	slots = mei_hbuf_empty_slots(dev);
299 	if (slots < 0)
300 		return -EOVERFLOW;
301 
302 	if ((u32)slots < msg_slots)
303 		return -EMSGSIZE;
304 
305 	ret = mei_hbm_cl_flow_control_req(dev, cl);
306 	if (ret) {
307 		cl->status = ret;
308 		cb->buf_idx = 0;
309 		list_move_tail(&cb->list, cmpl_list);
310 		return ret;
311 	}
312 
313 	pm_request_autosuspend(dev->parent);
314 
315 	list_move_tail(&cb->list, &cl->rd_pending);
316 
317 	return 0;
318 }
319 
320 static inline bool hdr_is_hbm(struct mei_msg_hdr *mei_hdr)
321 {
322 	return mei_hdr->host_addr == 0 && mei_hdr->me_addr == 0;
323 }
324 
325 static inline bool hdr_is_fixed(struct mei_msg_hdr *mei_hdr)
326 {
327 	return mei_hdr->host_addr == 0 && mei_hdr->me_addr != 0;
328 }
329 
330 static inline int hdr_is_valid(u32 msg_hdr)
331 {
332 	struct mei_msg_hdr *mei_hdr;
333 	u32 expected_len = 0;
334 
335 	mei_hdr = (struct mei_msg_hdr *)&msg_hdr;
336 	if (!msg_hdr || mei_hdr->reserved)
337 		return -EBADMSG;
338 
339 	if (mei_hdr->dma_ring)
340 		expected_len += MEI_SLOT_SIZE;
341 	if (mei_hdr->extended)
342 		expected_len += MEI_SLOT_SIZE;
343 	if (mei_hdr->length < expected_len)
344 		return -EBADMSG;
345 
346 	return 0;
347 }
348 
349 /**
350  * mei_irq_read_handler - bottom half read routine after ISR to
351  * handle the read processing.
352  *
353  * @dev: the device structure
354  * @cmpl_list: An instance of our list structure
355  * @slots: slots to read.
356  *
357  * Return: 0 on success, <0 on failure.
358  */
359 int mei_irq_read_handler(struct mei_device *dev,
360 			 struct list_head *cmpl_list, s32 *slots)
361 {
362 	struct mei_msg_hdr *mei_hdr;
363 	struct mei_ext_meta_hdr *meta_hdr = NULL;
364 	struct mei_cl *cl;
365 	int ret;
366 	u32 hdr_size_left;
367 	u32 hdr_size_ext;
368 	int i;
369 	int ext_hdr_end;
370 
371 	if (!dev->rd_msg_hdr[0]) {
372 		dev->rd_msg_hdr[0] = mei_read_hdr(dev);
373 		dev->rd_msg_hdr_count = 1;
374 		(*slots)--;
375 		dev_dbg(&dev->dev, "slots =%08x.\n", *slots);
376 
377 		ret = hdr_is_valid(dev->rd_msg_hdr[0]);
378 		if (ret) {
379 			dev_err(&dev->dev, "corrupted message header 0x%08X\n",
380 				dev->rd_msg_hdr[0]);
381 			goto end;
382 		}
383 	}
384 
385 	mei_hdr = (struct mei_msg_hdr *)dev->rd_msg_hdr;
386 	dev_dbg(&dev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr));
387 
388 	if (mei_slots2data(*slots) < mei_hdr->length) {
389 		dev_err(&dev->dev, "less data available than length=%08x.\n",
390 				*slots);
391 		/* we can't read the message */
392 		ret = -ENODATA;
393 		goto end;
394 	}
395 
396 	ext_hdr_end = 1;
397 	hdr_size_left = mei_hdr->length;
398 
399 	if (mei_hdr->extended) {
400 		if (!dev->rd_msg_hdr[1]) {
401 			dev->rd_msg_hdr[1] = mei_read_hdr(dev);
402 			dev->rd_msg_hdr_count++;
403 			(*slots)--;
404 			dev_dbg(&dev->dev, "extended header is %08x\n", dev->rd_msg_hdr[1]);
405 		}
406 		meta_hdr = ((struct mei_ext_meta_hdr *)&dev->rd_msg_hdr[1]);
407 		if (check_add_overflow((u32)sizeof(*meta_hdr),
408 				       mei_slots2data(meta_hdr->size),
409 				       &hdr_size_ext)) {
410 			dev_err(&dev->dev, "extended message size too big %d\n",
411 				meta_hdr->size);
412 			return -EBADMSG;
413 		}
414 		if (hdr_size_left < hdr_size_ext) {
415 			dev_err(&dev->dev, "corrupted message header len %d\n",
416 				mei_hdr->length);
417 			return -EBADMSG;
418 		}
419 		hdr_size_left -= hdr_size_ext;
420 
421 		ext_hdr_end = meta_hdr->size + 2;
422 		for (i = dev->rd_msg_hdr_count; i < ext_hdr_end; i++) {
423 			dev->rd_msg_hdr[i] = mei_read_hdr(dev);
424 			dev_dbg(&dev->dev, "extended header %d is %08x\n", i,
425 				dev->rd_msg_hdr[i]);
426 			dev->rd_msg_hdr_count++;
427 			(*slots)--;
428 		}
429 	}
430 
431 	if (mei_hdr->dma_ring) {
432 		if (hdr_size_left != sizeof(dev->rd_msg_hdr[ext_hdr_end])) {
433 			dev_err(&dev->dev, "corrupted message header len %d\n",
434 				mei_hdr->length);
435 			return -EBADMSG;
436 		}
437 
438 		dev->rd_msg_hdr[ext_hdr_end] = mei_read_hdr(dev);
439 		dev->rd_msg_hdr_count++;
440 		(*slots)--;
441 		mei_hdr->length -= sizeof(dev->rd_msg_hdr[ext_hdr_end]);
442 	}
443 
444 	/*  HBM message */
445 	if (hdr_is_hbm(mei_hdr)) {
446 		ret = mei_hbm_dispatch(dev, mei_hdr);
447 		if (ret) {
448 			dev_dbg(&dev->dev, "mei_hbm_dispatch failed ret = %d\n", ret);
449 			goto end;
450 		}
451 		goto reset_slots;
452 	}
453 
454 	/* find recipient cl */
455 	list_for_each_entry(cl, &dev->file_list, link) {
456 		if (mei_cl_hbm_equal(cl, mei_hdr)) {
457 			cl_dbg(dev, cl, "got a message\n");
458 			ret = mei_cl_irq_read_msg(cl, mei_hdr, meta_hdr, cmpl_list);
459 			goto reset_slots;
460 		}
461 	}
462 
463 	/* if no recipient cl was found we assume corrupted header */
464 	/* A message for not connected fixed address clients
465 	 * should be silently discarded
466 	 * On power down client may be force cleaned,
467 	 * silently discard such messages
468 	 */
469 	if (hdr_is_fixed(mei_hdr) ||
470 	    dev->dev_state == MEI_DEV_POWER_DOWN) {
471 		mei_irq_discard_msg(dev, mei_hdr, mei_hdr->length);
472 		ret = 0;
473 		goto reset_slots;
474 	}
475 	dev_err(&dev->dev, "no destination client found 0x%08X\n", dev->rd_msg_hdr[0]);
476 	ret = -EBADMSG;
477 	goto end;
478 
479 reset_slots:
480 	/* reset the number of slots and header */
481 	memset(dev->rd_msg_hdr, 0, sizeof(dev->rd_msg_hdr));
482 	dev->rd_msg_hdr_count = 0;
483 	*slots = mei_count_full_read_slots(dev);
484 	if (*slots == -EOVERFLOW) {
485 		/* overflow - reset */
486 		dev_err(&dev->dev, "resetting due to slots overflow.\n");
487 		/* set the event since message has been read */
488 		ret = -ERANGE;
489 		goto end;
490 	}
491 end:
492 	return ret;
493 }
494 EXPORT_SYMBOL_GPL(mei_irq_read_handler);
495 
496 
497 /**
498  * mei_irq_write_handler -  dispatch write requests
499  *  after irq received
500  *
501  * @dev: the device structure
502  * @cmpl_list: An instance of our list structure
503  *
504  * Return: 0 on success, <0 on failure.
505  */
506 int mei_irq_write_handler(struct mei_device *dev, struct list_head *cmpl_list)
507 {
508 
509 	struct mei_cl *cl;
510 	struct mei_cl_cb *cb, *next;
511 	s32 slots;
512 	int ret;
513 
514 
515 	if (!mei_hbuf_acquire(dev))
516 		return 0;
517 
518 	slots = mei_hbuf_empty_slots(dev);
519 	if (slots < 0)
520 		return -EOVERFLOW;
521 
522 	if (slots == 0)
523 		return -EMSGSIZE;
524 
525 	/* complete all waiting for write CB */
526 	dev_dbg(&dev->dev, "complete all waiting for write cb.\n");
527 
528 	list_for_each_entry_safe(cb, next, &dev->write_waiting_list, list) {
529 		cl = cb->cl;
530 
531 		cl->status = 0;
532 		cl_dbg(dev, cl, "MEI WRITE COMPLETE\n");
533 		cl->writing_state = MEI_WRITE_COMPLETE;
534 		list_move_tail(&cb->list, cmpl_list);
535 	}
536 
537 	/* complete control write list CB */
538 	dev_dbg(&dev->dev, "complete control write list cb.\n");
539 	list_for_each_entry_safe(cb, next, &dev->ctrl_wr_list, list) {
540 		cl = cb->cl;
541 		switch (cb->fop_type) {
542 		case MEI_FOP_DISCONNECT:
543 			/* send disconnect message */
544 			ret = mei_cl_irq_disconnect(cl, cb, cmpl_list);
545 			if (ret)
546 				return ret;
547 
548 			break;
549 		case MEI_FOP_READ:
550 			/* send flow control message */
551 			ret = mei_cl_irq_read(cl, cb, cmpl_list);
552 			if (ret)
553 				return ret;
554 
555 			break;
556 		case MEI_FOP_CONNECT:
557 			/* connect message */
558 			ret = mei_cl_irq_connect(cl, cb, cmpl_list);
559 			if (ret)
560 				return ret;
561 
562 			break;
563 		case MEI_FOP_DISCONNECT_RSP:
564 			/* send disconnect resp */
565 			ret = mei_cl_irq_disconnect_rsp(cl, cb, cmpl_list);
566 			if (ret)
567 				return ret;
568 			break;
569 
570 		case MEI_FOP_NOTIFY_START:
571 		case MEI_FOP_NOTIFY_STOP:
572 			ret = mei_cl_irq_notify(cl, cb, cmpl_list);
573 			if (ret)
574 				return ret;
575 			break;
576 		case MEI_FOP_DMA_MAP:
577 			ret = mei_cl_irq_dma_map(cl, cb, cmpl_list);
578 			if (ret)
579 				return ret;
580 			break;
581 		case MEI_FOP_DMA_UNMAP:
582 			ret = mei_cl_irq_dma_unmap(cl, cb, cmpl_list);
583 			if (ret)
584 				return ret;
585 			break;
586 		default:
587 			BUG();
588 		}
589 
590 	}
591 	/* complete  write list CB */
592 	dev_dbg(&dev->dev, "complete write list cb.\n");
593 	list_for_each_entry_safe(cb, next, &dev->write_list, list) {
594 		cl = cb->cl;
595 		ret = mei_cl_irq_write(cl, cb, cmpl_list);
596 		if (ret)
597 			return ret;
598 	}
599 	return 0;
600 }
601 EXPORT_SYMBOL_GPL(mei_irq_write_handler);
602 
603 
604 /**
605  * mei_connect_timeout  - connect/disconnect timeouts
606  *
607  * @cl: host client
608  */
609 static void mei_connect_timeout(struct mei_cl *cl)
610 {
611 	struct mei_device *dev = cl->dev;
612 
613 	if (cl->state == MEI_FILE_CONNECTING) {
614 		if (dev->hbm_f_dot_supported) {
615 			cl->state = MEI_FILE_DISCONNECT_REQUIRED;
616 			wake_up(&cl->wait);
617 			return;
618 		}
619 	}
620 	mei_reset(dev);
621 }
622 
623 #define MEI_STALL_TIMER_FREQ (2 * HZ)
624 /**
625  * mei_schedule_stall_timer - re-arm stall_timer work
626  *
627  * @dev: the device structure
628  *
629  * Schedule stall timer
630  */
631 void mei_schedule_stall_timer(struct mei_device *dev)
632 {
633 	schedule_delayed_work(&dev->timer_work, MEI_STALL_TIMER_FREQ);
634 }
635 
636 /**
637  * mei_timer - timer function.
638  *
639  * @work: pointer to the work_struct structure
640  *
641  */
642 void mei_timer(struct work_struct *work)
643 {
644 	struct mei_cl *cl;
645 	struct mei_device *dev = container_of(work,
646 					struct mei_device, timer_work.work);
647 	bool reschedule_timer = false;
648 
649 	mutex_lock(&dev->device_lock);
650 
651 	/* Catch interrupt stalls during HBM init handshake */
652 	if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
653 	    dev->hbm_state != MEI_HBM_IDLE) {
654 
655 		if (dev->init_clients_timer) {
656 			if (--dev->init_clients_timer == 0) {
657 				dev_err(&dev->dev, "timer: init clients timeout hbm_state = %d.\n",
658 					dev->hbm_state);
659 				mei_reset(dev);
660 				goto out;
661 			}
662 			reschedule_timer = true;
663 		}
664 	}
665 
666 	if (dev->dev_state != MEI_DEV_ENABLED)
667 		goto out;
668 
669 	/*** connect/disconnect timeouts ***/
670 	list_for_each_entry(cl, &dev->file_list, link) {
671 		if (cl->timer_count) {
672 			if (--cl->timer_count == 0) {
673 				dev_err(&dev->dev, "timer: connect/disconnect timeout.\n");
674 				mei_connect_timeout(cl);
675 				goto out;
676 			}
677 			reschedule_timer = true;
678 		}
679 	}
680 
681 out:
682 	if (dev->dev_state != MEI_DEV_DISABLED && reschedule_timer)
683 		mei_schedule_stall_timer(dev);
684 
685 	mutex_unlock(&dev->device_lock);
686 }
687