Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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#include <linux/sched.h>
18#include <linux/wait.h>
19#include <linux/delay.h>
20#include <linux/slab.h>
21#include <linux/pm_runtime.h>
22
23#include <linux/mei.h>
24
25#include "mei_dev.h"
26#include "hbm.h"
27#include "client.h"
28
29/**
30 * mei_me_cl_init - initialize me client
31 *
32 * @me_cl: me client
33 */
34void mei_me_cl_init(struct mei_me_client *me_cl)
35{
36 INIT_LIST_HEAD(&me_cl->list);
37 kref_init(&me_cl->refcnt);
38}
39
40/**
41 * mei_me_cl_get - increases me client refcount
42 *
43 * @me_cl: me client
44 *
45 * Locking: called under "dev->device_lock" lock
46 *
47 * Return: me client or NULL
48 */
49struct mei_me_client *mei_me_cl_get(struct mei_me_client *me_cl)
50{
51 if (me_cl)
52 kref_get(&me_cl->refcnt);
53
54 return me_cl;
55}
56
57/**
58 * mei_me_cl_release - unlink and free me client
59 *
60 * Locking: called under "dev->device_lock" lock
61 *
62 * @ref: me_client refcount
63 */
64static void mei_me_cl_release(struct kref *ref)
65{
66 struct mei_me_client *me_cl =
67 container_of(ref, struct mei_me_client, refcnt);
68 list_del(&me_cl->list);
69 kfree(me_cl);
70}
71/**
72 * mei_me_cl_put - decrease me client refcount and free client if necessary
73 *
74 * Locking: called under "dev->device_lock" lock
75 *
76 * @me_cl: me client
77 */
78void mei_me_cl_put(struct mei_me_client *me_cl)
79{
80 if (me_cl)
81 kref_put(&me_cl->refcnt, mei_me_cl_release);
82}
83
84/**
85 * mei_me_cl_by_uuid - locate me client by uuid
86 * increases ref count
87 *
88 * @dev: mei device
89 * @uuid: me client uuid
90 *
91 * Locking: called under "dev->device_lock" lock
92 *
93 * Return: me client or NULL if not found
94 */
95struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev,
96 const uuid_le *uuid)
97{
98 struct mei_me_client *me_cl;
99
100 list_for_each_entry(me_cl, &dev->me_clients, list)
101 if (uuid_le_cmp(*uuid, me_cl->props.protocol_name) == 0)
102 return mei_me_cl_get(me_cl);
103
104 return NULL;
105}
106
107/**
108 * mei_me_cl_by_id - locate me client by client id
109 * increases ref count
110 *
111 * @dev: the device structure
112 * @client_id: me client id
113 *
114 * Locking: called under "dev->device_lock" lock
115 *
116 * Return: me client or NULL if not found
117 */
118struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
119{
120
121 struct mei_me_client *me_cl;
122
123 list_for_each_entry(me_cl, &dev->me_clients, list)
124 if (me_cl->client_id == client_id)
125 return mei_me_cl_get(me_cl);
126
127 return NULL;
128}
129
130/**
131 * mei_me_cl_by_uuid_id - locate me client by client id and uuid
132 * increases ref count
133 *
134 * @dev: the device structure
135 * @uuid: me client uuid
136 * @client_id: me client id
137 *
138 * Locking: called under "dev->device_lock" lock
139 *
140 * Return: me client or NULL if not found
141 */
142struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev,
143 const uuid_le *uuid, u8 client_id)
144{
145 struct mei_me_client *me_cl;
146
147 list_for_each_entry(me_cl, &dev->me_clients, list)
148 if (uuid_le_cmp(*uuid, me_cl->props.protocol_name) == 0 &&
149 me_cl->client_id == client_id)
150 return mei_me_cl_get(me_cl);
151
152 return NULL;
153}
154
155/**
156 * mei_me_cl_rm_by_uuid - remove all me clients matching uuid
157 *
158 * @dev: the device structure
159 * @uuid: me client uuid
160 *
161 * Locking: called under "dev->device_lock" lock
162 */
163void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid)
164{
165 struct mei_me_client *me_cl, *next;
166
167 dev_dbg(dev->dev, "remove %pUl\n", uuid);
168 list_for_each_entry_safe(me_cl, next, &dev->me_clients, list)
169 if (uuid_le_cmp(*uuid, me_cl->props.protocol_name) == 0)
170 mei_me_cl_put(me_cl);
171}
172
173/**
174 * mei_me_cl_rm_by_uuid_id - remove all me clients matching client id
175 *
176 * @dev: the device structure
177 * @uuid: me client uuid
178 * @id: me client id
179 *
180 * Locking: called under "dev->device_lock" lock
181 */
182void mei_me_cl_rm_by_uuid_id(struct mei_device *dev, const uuid_le *uuid, u8 id)
183{
184 struct mei_me_client *me_cl, *next;
185 const uuid_le *pn;
186
187 dev_dbg(dev->dev, "remove %pUl %d\n", uuid, id);
188 list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) {
189 pn = &me_cl->props.protocol_name;
190 if (me_cl->client_id == id && uuid_le_cmp(*uuid, *pn) == 0)
191 mei_me_cl_put(me_cl);
192 }
193}
194
195/**
196 * mei_me_cl_rm_all - remove all me clients
197 *
198 * @dev: the device structure
199 *
200 * Locking: called under "dev->device_lock" lock
201 */
202void mei_me_cl_rm_all(struct mei_device *dev)
203{
204 struct mei_me_client *me_cl, *next;
205
206 list_for_each_entry_safe(me_cl, next, &dev->me_clients, list)
207 mei_me_cl_put(me_cl);
208}
209
210
211
212/**
213 * mei_cl_cmp_id - tells if the clients are the same
214 *
215 * @cl1: host client 1
216 * @cl2: host client 2
217 *
218 * Return: true - if the clients has same host and me ids
219 * false - otherwise
220 */
221static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
222 const struct mei_cl *cl2)
223{
224 return cl1 && cl2 &&
225 (cl1->host_client_id == cl2->host_client_id) &&
226 (cl1->me_client_id == cl2->me_client_id);
227}
228
229/**
230 * mei_io_list_flush - removes cbs belonging to cl.
231 *
232 * @list: an instance of our list structure
233 * @cl: host client, can be NULL for flushing the whole list
234 * @free: whether to free the cbs
235 */
236static void __mei_io_list_flush(struct mei_cl_cb *list,
237 struct mei_cl *cl, bool free)
238{
239 struct mei_cl_cb *cb;
240 struct mei_cl_cb *next;
241
242 /* enable removing everything if no cl is specified */
243 list_for_each_entry_safe(cb, next, &list->list, list) {
244 if (!cl || mei_cl_cmp_id(cl, cb->cl)) {
245 list_del(&cb->list);
246 if (free)
247 mei_io_cb_free(cb);
248 }
249 }
250}
251
252/**
253 * mei_io_list_flush - removes list entry belonging to cl.
254 *
255 * @list: An instance of our list structure
256 * @cl: host client
257 */
258void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
259{
260 __mei_io_list_flush(list, cl, false);
261}
262
263
264/**
265 * mei_io_list_free - removes cb belonging to cl and free them
266 *
267 * @list: An instance of our list structure
268 * @cl: host client
269 */
270static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl)
271{
272 __mei_io_list_flush(list, cl, true);
273}
274
275/**
276 * mei_io_cb_free - free mei_cb_private related memory
277 *
278 * @cb: mei callback struct
279 */
280void mei_io_cb_free(struct mei_cl_cb *cb)
281{
282 if (cb == NULL)
283 return;
284
285 kfree(cb->request_buffer.data);
286 kfree(cb->response_buffer.data);
287 kfree(cb);
288}
289
290/**
291 * mei_io_cb_init - allocate and initialize io callback
292 *
293 * @cl: mei client
294 * @fp: pointer to file structure
295 *
296 * Return: mei_cl_cb pointer or NULL;
297 */
298struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp)
299{
300 struct mei_cl_cb *cb;
301
302 cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
303 if (!cb)
304 return NULL;
305
306 mei_io_list_init(cb);
307
308 cb->file_object = fp;
309 cb->cl = cl;
310 cb->buf_idx = 0;
311 return cb;
312}
313
314/**
315 * mei_io_cb_alloc_req_buf - allocate request buffer
316 *
317 * @cb: io callback structure
318 * @length: size of the buffer
319 *
320 * Return: 0 on success
321 * -EINVAL if cb is NULL
322 * -ENOMEM if allocation failed
323 */
324int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length)
325{
326 if (!cb)
327 return -EINVAL;
328
329 if (length == 0)
330 return 0;
331
332 cb->request_buffer.data = kmalloc(length, GFP_KERNEL);
333 if (!cb->request_buffer.data)
334 return -ENOMEM;
335 cb->request_buffer.size = length;
336 return 0;
337}
338/**
339 * mei_io_cb_alloc_resp_buf - allocate response buffer
340 *
341 * @cb: io callback structure
342 * @length: size of the buffer
343 *
344 * Return: 0 on success
345 * -EINVAL if cb is NULL
346 * -ENOMEM if allocation failed
347 */
348int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length)
349{
350 if (!cb)
351 return -EINVAL;
352
353 if (length == 0)
354 return 0;
355
356 cb->response_buffer.data = kmalloc(length, GFP_KERNEL);
357 if (!cb->response_buffer.data)
358 return -ENOMEM;
359 cb->response_buffer.size = length;
360 return 0;
361}
362
363
364
365/**
366 * mei_cl_flush_queues - flushes queue lists belonging to cl.
367 *
368 * @cl: host client
369 *
370 * Return: 0 on success, -EINVAL if cl or cl->dev is NULL.
371 */
372int mei_cl_flush_queues(struct mei_cl *cl)
373{
374 struct mei_device *dev;
375
376 if (WARN_ON(!cl || !cl->dev))
377 return -EINVAL;
378
379 dev = cl->dev;
380
381 cl_dbg(dev, cl, "remove list entry belonging to cl\n");
382 mei_io_list_flush(&cl->dev->read_list, cl);
383 mei_io_list_free(&cl->dev->write_list, cl);
384 mei_io_list_free(&cl->dev->write_waiting_list, cl);
385 mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
386 mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
387 mei_io_list_flush(&cl->dev->amthif_cmd_list, cl);
388 mei_io_list_flush(&cl->dev->amthif_rd_complete_list, cl);
389 return 0;
390}
391
392
393/**
394 * mei_cl_init - initializes cl.
395 *
396 * @cl: host client to be initialized
397 * @dev: mei device
398 */
399void mei_cl_init(struct mei_cl *cl, struct mei_device *dev)
400{
401 memset(cl, 0, sizeof(struct mei_cl));
402 init_waitqueue_head(&cl->wait);
403 init_waitqueue_head(&cl->rx_wait);
404 init_waitqueue_head(&cl->tx_wait);
405 INIT_LIST_HEAD(&cl->link);
406 INIT_LIST_HEAD(&cl->device_link);
407 cl->reading_state = MEI_IDLE;
408 cl->writing_state = MEI_IDLE;
409 cl->dev = dev;
410}
411
412/**
413 * mei_cl_allocate - allocates cl structure and sets it up.
414 *
415 * @dev: mei device
416 * Return: The allocated file or NULL on failure
417 */
418struct mei_cl *mei_cl_allocate(struct mei_device *dev)
419{
420 struct mei_cl *cl;
421
422 cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL);
423 if (!cl)
424 return NULL;
425
426 mei_cl_init(cl, dev);
427
428 return cl;
429}
430
431/**
432 * mei_cl_find_read_cb - find this cl's callback in the read list
433 *
434 * @cl: host client
435 *
436 * Return: cb on success, NULL on error
437 */
438struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl)
439{
440 struct mei_device *dev = cl->dev;
441 struct mei_cl_cb *cb;
442
443 list_for_each_entry(cb, &dev->read_list.list, list)
444 if (mei_cl_cmp_id(cl, cb->cl))
445 return cb;
446 return NULL;
447}
448
449/** mei_cl_link: allocate host id in the host map
450 *
451 * @cl - host client
452 * @id - fixed host id or -1 for generic one
453 *
454 * Return: 0 on success
455 * -EINVAL on incorrect values
456 * -ENONET if client not found
457 */
458int mei_cl_link(struct mei_cl *cl, int id)
459{
460 struct mei_device *dev;
461 long open_handle_count;
462
463 if (WARN_ON(!cl || !cl->dev))
464 return -EINVAL;
465
466 dev = cl->dev;
467
468 /* If Id is not assigned get one*/
469 if (id == MEI_HOST_CLIENT_ID_ANY)
470 id = find_first_zero_bit(dev->host_clients_map,
471 MEI_CLIENTS_MAX);
472
473 if (id >= MEI_CLIENTS_MAX) {
474 dev_err(dev->dev, "id exceeded %d", MEI_CLIENTS_MAX);
475 return -EMFILE;
476 }
477
478 open_handle_count = dev->open_handle_count + dev->iamthif_open_count;
479 if (open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
480 dev_err(dev->dev, "open_handle_count exceeded %d",
481 MEI_MAX_OPEN_HANDLE_COUNT);
482 return -EMFILE;
483 }
484
485 dev->open_handle_count++;
486
487 cl->host_client_id = id;
488 list_add_tail(&cl->link, &dev->file_list);
489
490 set_bit(id, dev->host_clients_map);
491
492 cl->state = MEI_FILE_INITIALIZING;
493
494 cl_dbg(dev, cl, "link cl\n");
495 return 0;
496}
497
498/**
499 * mei_cl_unlink - remove me_cl from the list
500 *
501 * @cl: host client
502 *
503 * Return: always 0
504 */
505int mei_cl_unlink(struct mei_cl *cl)
506{
507 struct mei_device *dev;
508
509 /* don't shout on error exit path */
510 if (!cl)
511 return 0;
512
513 /* wd and amthif might not be initialized */
514 if (!cl->dev)
515 return 0;
516
517 dev = cl->dev;
518
519 cl_dbg(dev, cl, "unlink client");
520
521 if (dev->open_handle_count > 0)
522 dev->open_handle_count--;
523
524 /* never clear the 0 bit */
525 if (cl->host_client_id)
526 clear_bit(cl->host_client_id, dev->host_clients_map);
527
528 list_del_init(&cl->link);
529
530 cl->state = MEI_FILE_INITIALIZING;
531
532 return 0;
533}
534
535
536void mei_host_client_init(struct work_struct *work)
537{
538 struct mei_device *dev = container_of(work,
539 struct mei_device, init_work);
540 struct mei_me_client *me_cl;
541 struct mei_client_properties *props;
542
543 mutex_lock(&dev->device_lock);
544
545 list_for_each_entry(me_cl, &dev->me_clients, list) {
546 props = &me_cl->props;
547
548 if (!uuid_le_cmp(props->protocol_name, mei_amthif_guid))
549 mei_amthif_host_init(dev);
550 else if (!uuid_le_cmp(props->protocol_name, mei_wd_guid))
551 mei_wd_host_init(dev);
552 else if (!uuid_le_cmp(props->protocol_name, mei_nfc_guid))
553 mei_nfc_host_init(dev);
554
555 }
556
557 dev->dev_state = MEI_DEV_ENABLED;
558 dev->reset_count = 0;
559
560 mutex_unlock(&dev->device_lock);
561
562 pm_runtime_mark_last_busy(dev->dev);
563 dev_dbg(dev->dev, "rpm: autosuspend\n");
564 pm_runtime_autosuspend(dev->dev);
565}
566
567/**
568 * mei_hbuf_acquire - try to acquire host buffer
569 *
570 * @dev: the device structure
571 * Return: true if host buffer was acquired
572 */
573bool mei_hbuf_acquire(struct mei_device *dev)
574{
575 if (mei_pg_state(dev) == MEI_PG_ON ||
576 dev->pg_event == MEI_PG_EVENT_WAIT) {
577 dev_dbg(dev->dev, "device is in pg\n");
578 return false;
579 }
580
581 if (!dev->hbuf_is_ready) {
582 dev_dbg(dev->dev, "hbuf is not ready\n");
583 return false;
584 }
585
586 dev->hbuf_is_ready = false;
587
588 return true;
589}
590
591/**
592 * mei_cl_disconnect - disconnect host client from the me one
593 *
594 * @cl: host client
595 *
596 * Locking: called under "dev->device_lock" lock
597 *
598 * Return: 0 on success, <0 on failure.
599 */
600int mei_cl_disconnect(struct mei_cl *cl)
601{
602 struct mei_device *dev;
603 struct mei_cl_cb *cb;
604 int rets;
605
606 if (WARN_ON(!cl || !cl->dev))
607 return -ENODEV;
608
609 dev = cl->dev;
610
611 cl_dbg(dev, cl, "disconnecting");
612
613 if (cl->state != MEI_FILE_DISCONNECTING)
614 return 0;
615
616 rets = pm_runtime_get(dev->dev);
617 if (rets < 0 && rets != -EINPROGRESS) {
618 pm_runtime_put_noidle(dev->dev);
619 cl_err(dev, cl, "rpm: get failed %d\n", rets);
620 return rets;
621 }
622
623 cb = mei_io_cb_init(cl, NULL);
624 if (!cb) {
625 rets = -ENOMEM;
626 goto free;
627 }
628
629 cb->fop_type = MEI_FOP_DISCONNECT;
630
631 if (mei_hbuf_acquire(dev)) {
632 if (mei_hbm_cl_disconnect_req(dev, cl)) {
633 rets = -ENODEV;
634 cl_err(dev, cl, "failed to disconnect.\n");
635 goto free;
636 }
637 cl->timer_count = MEI_CONNECT_TIMEOUT;
638 mdelay(10); /* Wait for hardware disconnection ready */
639 list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
640 } else {
641 cl_dbg(dev, cl, "add disconnect cb to control write list\n");
642 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
643
644 }
645 mutex_unlock(&dev->device_lock);
646
647 wait_event_timeout(cl->wait,
648 MEI_FILE_DISCONNECTED == cl->state,
649 mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
650
651 mutex_lock(&dev->device_lock);
652
653 if (MEI_FILE_DISCONNECTED == cl->state) {
654 rets = 0;
655 cl_dbg(dev, cl, "successfully disconnected from FW client.\n");
656 } else {
657 cl_dbg(dev, cl, "timeout on disconnect from FW client.\n");
658 rets = -ETIME;
659 }
660
661 mei_io_list_flush(&dev->ctrl_rd_list, cl);
662 mei_io_list_flush(&dev->ctrl_wr_list, cl);
663free:
664 cl_dbg(dev, cl, "rpm: autosuspend\n");
665 pm_runtime_mark_last_busy(dev->dev);
666 pm_runtime_put_autosuspend(dev->dev);
667
668 mei_io_cb_free(cb);
669 return rets;
670}
671
672
673/**
674 * mei_cl_is_other_connecting - checks if other
675 * client with the same me client id is connecting
676 *
677 * @cl: private data of the file object
678 *
679 * Return: true if other client is connected, false - otherwise.
680 */
681bool mei_cl_is_other_connecting(struct mei_cl *cl)
682{
683 struct mei_device *dev;
684 struct mei_cl *ocl; /* the other client */
685
686 if (WARN_ON(!cl || !cl->dev))
687 return false;
688
689 dev = cl->dev;
690
691 list_for_each_entry(ocl, &dev->file_list, link) {
692 if (ocl->state == MEI_FILE_CONNECTING &&
693 ocl != cl &&
694 cl->me_client_id == ocl->me_client_id)
695 return true;
696
697 }
698
699 return false;
700}
701
702/**
703 * mei_cl_connect - connect host client to the me one
704 *
705 * @cl: host client
706 * @file: pointer to file structure
707 *
708 * Locking: called under "dev->device_lock" lock
709 *
710 * Return: 0 on success, <0 on failure.
711 */
712int mei_cl_connect(struct mei_cl *cl, struct file *file)
713{
714 struct mei_device *dev;
715 struct mei_cl_cb *cb;
716 int rets;
717
718 if (WARN_ON(!cl || !cl->dev))
719 return -ENODEV;
720
721 dev = cl->dev;
722
723 rets = pm_runtime_get(dev->dev);
724 if (rets < 0 && rets != -EINPROGRESS) {
725 pm_runtime_put_noidle(dev->dev);
726 cl_err(dev, cl, "rpm: get failed %d\n", rets);
727 return rets;
728 }
729
730 cb = mei_io_cb_init(cl, file);
731 if (!cb) {
732 rets = -ENOMEM;
733 goto out;
734 }
735
736 cb->fop_type = MEI_FOP_CONNECT;
737
738 /* run hbuf acquire last so we don't have to undo */
739 if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) {
740 cl->state = MEI_FILE_CONNECTING;
741 if (mei_hbm_cl_connect_req(dev, cl)) {
742 rets = -ENODEV;
743 goto out;
744 }
745 cl->timer_count = MEI_CONNECT_TIMEOUT;
746 list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
747 } else {
748 cl->state = MEI_FILE_INITIALIZING;
749 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
750 }
751
752 mutex_unlock(&dev->device_lock);
753 wait_event_timeout(cl->wait,
754 (cl->state == MEI_FILE_CONNECTED ||
755 cl->state == MEI_FILE_DISCONNECTED),
756 mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
757 mutex_lock(&dev->device_lock);
758
759 if (cl->state != MEI_FILE_CONNECTED) {
760 cl->state = MEI_FILE_DISCONNECTED;
761 /* something went really wrong */
762 if (!cl->status)
763 cl->status = -EFAULT;
764
765 mei_io_list_flush(&dev->ctrl_rd_list, cl);
766 mei_io_list_flush(&dev->ctrl_wr_list, cl);
767 }
768
769 rets = cl->status;
770
771out:
772 cl_dbg(dev, cl, "rpm: autosuspend\n");
773 pm_runtime_mark_last_busy(dev->dev);
774 pm_runtime_put_autosuspend(dev->dev);
775
776 mei_io_cb_free(cb);
777 return rets;
778}
779
780/**
781 * mei_cl_flow_ctrl_creds - checks flow_control credits for cl.
782 *
783 * @cl: private data of the file object
784 *
785 * Return: 1 if mei_flow_ctrl_creds >0, 0 - otherwise.
786 * -ENOENT if mei_cl is not present
787 * -EINVAL if single_recv_buf == 0
788 */
789int mei_cl_flow_ctrl_creds(struct mei_cl *cl)
790{
791 struct mei_device *dev;
792 struct mei_me_client *me_cl;
793 int rets = 0;
794
795 if (WARN_ON(!cl || !cl->dev))
796 return -EINVAL;
797
798 dev = cl->dev;
799
800 if (cl->mei_flow_ctrl_creds > 0)
801 return 1;
802
803 me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id);
804 if (!me_cl) {
805 cl_err(dev, cl, "no such me client %d\n", cl->me_client_id);
806 return -ENOENT;
807 }
808
809 if (me_cl->mei_flow_ctrl_creds > 0) {
810 rets = 1;
811 if (WARN_ON(me_cl->props.single_recv_buf == 0))
812 rets = -EINVAL;
813 }
814 mei_me_cl_put(me_cl);
815 return rets;
816}
817
818/**
819 * mei_cl_flow_ctrl_reduce - reduces flow_control.
820 *
821 * @cl: private data of the file object
822 *
823 * Return:
824 * 0 on success
825 * -ENOENT when me client is not found
826 * -EINVAL when ctrl credits are <= 0
827 */
828int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
829{
830 struct mei_device *dev;
831 struct mei_me_client *me_cl;
832 int rets;
833
834 if (WARN_ON(!cl || !cl->dev))
835 return -EINVAL;
836
837 dev = cl->dev;
838
839 me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id);
840 if (!me_cl) {
841 cl_err(dev, cl, "no such me client %d\n", cl->me_client_id);
842 return -ENOENT;
843 }
844
845 if (me_cl->props.single_recv_buf) {
846 if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0)) {
847 rets = -EINVAL;
848 goto out;
849 }
850 me_cl->mei_flow_ctrl_creds--;
851 } else {
852 if (WARN_ON(cl->mei_flow_ctrl_creds <= 0)) {
853 rets = -EINVAL;
854 goto out;
855 }
856 cl->mei_flow_ctrl_creds--;
857 }
858 rets = 0;
859out:
860 mei_me_cl_put(me_cl);
861 return rets;
862}
863
864/**
865 * mei_cl_read_start - the start read client message function.
866 *
867 * @cl: host client
868 * @length: number of bytes to read
869 *
870 * Return: 0 on success, <0 on failure.
871 */
872int mei_cl_read_start(struct mei_cl *cl, size_t length)
873{
874 struct mei_device *dev;
875 struct mei_cl_cb *cb;
876 struct mei_me_client *me_cl;
877 int rets;
878
879 if (WARN_ON(!cl || !cl->dev))
880 return -ENODEV;
881
882 dev = cl->dev;
883
884 if (!mei_cl_is_connected(cl))
885 return -ENODEV;
886
887 if (cl->read_cb) {
888 cl_dbg(dev, cl, "read is pending.\n");
889 return -EBUSY;
890 }
891 me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id);
892 if (!me_cl) {
893 cl_err(dev, cl, "no such me client %d\n", cl->me_client_id);
894 return -ENOTTY;
895 }
896 /* always allocate at least client max message */
897 length = max_t(size_t, length, me_cl->props.max_msg_length);
898 mei_me_cl_put(me_cl);
899
900 rets = pm_runtime_get(dev->dev);
901 if (rets < 0 && rets != -EINPROGRESS) {
902 pm_runtime_put_noidle(dev->dev);
903 cl_err(dev, cl, "rpm: get failed %d\n", rets);
904 return rets;
905 }
906
907 cb = mei_io_cb_init(cl, NULL);
908 if (!cb) {
909 rets = -ENOMEM;
910 goto out;
911 }
912
913 rets = mei_io_cb_alloc_resp_buf(cb, length);
914 if (rets)
915 goto out;
916
917 cb->fop_type = MEI_FOP_READ;
918 if (mei_hbuf_acquire(dev)) {
919 rets = mei_hbm_cl_flow_control_req(dev, cl);
920 if (rets < 0)
921 goto out;
922
923 list_add_tail(&cb->list, &dev->read_list.list);
924 } else {
925 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
926 }
927
928 cl->read_cb = cb;
929
930out:
931 cl_dbg(dev, cl, "rpm: autosuspend\n");
932 pm_runtime_mark_last_busy(dev->dev);
933 pm_runtime_put_autosuspend(dev->dev);
934
935 if (rets)
936 mei_io_cb_free(cb);
937
938 return rets;
939}
940
941/**
942 * mei_cl_irq_write - write a message to device
943 * from the interrupt thread context
944 *
945 * @cl: client
946 * @cb: callback block.
947 * @cmpl_list: complete list.
948 *
949 * Return: 0, OK; otherwise error.
950 */
951int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
952 struct mei_cl_cb *cmpl_list)
953{
954 struct mei_device *dev;
955 struct mei_msg_data *buf;
956 struct mei_msg_hdr mei_hdr;
957 size_t len;
958 u32 msg_slots;
959 int slots;
960 int rets;
961
962 if (WARN_ON(!cl || !cl->dev))
963 return -ENODEV;
964
965 dev = cl->dev;
966
967 buf = &cb->request_buffer;
968
969 rets = mei_cl_flow_ctrl_creds(cl);
970 if (rets < 0)
971 return rets;
972
973 if (rets == 0) {
974 cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
975 return 0;
976 }
977
978 slots = mei_hbuf_empty_slots(dev);
979 len = buf->size - cb->buf_idx;
980 msg_slots = mei_data2slots(len);
981
982 mei_hdr.host_addr = cl->host_client_id;
983 mei_hdr.me_addr = cl->me_client_id;
984 mei_hdr.reserved = 0;
985 mei_hdr.internal = cb->internal;
986
987 if (slots >= msg_slots) {
988 mei_hdr.length = len;
989 mei_hdr.msg_complete = 1;
990 /* Split the message only if we can write the whole host buffer */
991 } else if (slots == dev->hbuf_depth) {
992 msg_slots = slots;
993 len = (slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
994 mei_hdr.length = len;
995 mei_hdr.msg_complete = 0;
996 } else {
997 /* wait for next time the host buffer is empty */
998 return 0;
999 }
1000
1001 cl_dbg(dev, cl, "buf: size = %d idx = %lu\n",
1002 cb->request_buffer.size, cb->buf_idx);
1003
1004 rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx);
1005 if (rets) {
1006 cl->status = rets;
1007 list_move_tail(&cb->list, &cmpl_list->list);
1008 return rets;
1009 }
1010
1011 cl->status = 0;
1012 cl->writing_state = MEI_WRITING;
1013 cb->buf_idx += mei_hdr.length;
1014
1015 if (mei_hdr.msg_complete) {
1016 if (mei_cl_flow_ctrl_reduce(cl))
1017 return -EIO;
1018 list_move_tail(&cb->list, &dev->write_waiting_list.list);
1019 }
1020
1021 return 0;
1022}
1023
1024/**
1025 * mei_cl_write - submit a write cb to mei device
1026 * assumes device_lock is locked
1027 *
1028 * @cl: host client
1029 * @cb: write callback with filled data
1030 * @blocking: block until completed
1031 *
1032 * Return: number of bytes sent on success, <0 on failure.
1033 */
1034int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
1035{
1036 struct mei_device *dev;
1037 struct mei_msg_data *buf;
1038 struct mei_msg_hdr mei_hdr;
1039 int rets;
1040
1041
1042 if (WARN_ON(!cl || !cl->dev))
1043 return -ENODEV;
1044
1045 if (WARN_ON(!cb))
1046 return -EINVAL;
1047
1048 dev = cl->dev;
1049
1050
1051 buf = &cb->request_buffer;
1052
1053 cl_dbg(dev, cl, "size=%d\n", buf->size);
1054
1055 rets = pm_runtime_get(dev->dev);
1056 if (rets < 0 && rets != -EINPROGRESS) {
1057 pm_runtime_put_noidle(dev->dev);
1058 cl_err(dev, cl, "rpm: get failed %d\n", rets);
1059 return rets;
1060 }
1061
1062 cb->fop_type = MEI_FOP_WRITE;
1063 cb->buf_idx = 0;
1064 cl->writing_state = MEI_IDLE;
1065
1066 mei_hdr.host_addr = cl->host_client_id;
1067 mei_hdr.me_addr = cl->me_client_id;
1068 mei_hdr.reserved = 0;
1069 mei_hdr.msg_complete = 0;
1070 mei_hdr.internal = cb->internal;
1071
1072 rets = mei_cl_flow_ctrl_creds(cl);
1073 if (rets < 0)
1074 goto err;
1075
1076 if (rets == 0) {
1077 cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
1078 rets = buf->size;
1079 goto out;
1080 }
1081 if (!mei_hbuf_acquire(dev)) {
1082 cl_dbg(dev, cl, "Cannot acquire the host buffer: not sending.\n");
1083 rets = buf->size;
1084 goto out;
1085 }
1086
1087 /* Check for a maximum length */
1088 if (buf->size > mei_hbuf_max_len(dev)) {
1089 mei_hdr.length = mei_hbuf_max_len(dev);
1090 mei_hdr.msg_complete = 0;
1091 } else {
1092 mei_hdr.length = buf->size;
1093 mei_hdr.msg_complete = 1;
1094 }
1095
1096 rets = mei_write_message(dev, &mei_hdr, buf->data);
1097 if (rets)
1098 goto err;
1099
1100 cl->writing_state = MEI_WRITING;
1101 cb->buf_idx = mei_hdr.length;
1102
1103out:
1104 if (mei_hdr.msg_complete) {
1105 rets = mei_cl_flow_ctrl_reduce(cl);
1106 if (rets < 0)
1107 goto err;
1108
1109 list_add_tail(&cb->list, &dev->write_waiting_list.list);
1110 } else {
1111 list_add_tail(&cb->list, &dev->write_list.list);
1112 }
1113
1114
1115 if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) {
1116
1117 mutex_unlock(&dev->device_lock);
1118 rets = wait_event_interruptible(cl->tx_wait,
1119 cl->writing_state == MEI_WRITE_COMPLETE);
1120 mutex_lock(&dev->device_lock);
1121 /* wait_event_interruptible returns -ERESTARTSYS */
1122 if (rets) {
1123 if (signal_pending(current))
1124 rets = -EINTR;
1125 goto err;
1126 }
1127 }
1128
1129 rets = buf->size;
1130err:
1131 cl_dbg(dev, cl, "rpm: autosuspend\n");
1132 pm_runtime_mark_last_busy(dev->dev);
1133 pm_runtime_put_autosuspend(dev->dev);
1134
1135 return rets;
1136}
1137
1138
1139/**
1140 * mei_cl_complete - processes completed operation for a client
1141 *
1142 * @cl: private data of the file object.
1143 * @cb: callback block.
1144 */
1145void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
1146{
1147 if (cb->fop_type == MEI_FOP_WRITE) {
1148 mei_io_cb_free(cb);
1149 cb = NULL;
1150 cl->writing_state = MEI_WRITE_COMPLETE;
1151 if (waitqueue_active(&cl->tx_wait))
1152 wake_up_interruptible(&cl->tx_wait);
1153
1154 } else if (cb->fop_type == MEI_FOP_READ &&
1155 MEI_READING == cl->reading_state) {
1156 cl->reading_state = MEI_READ_COMPLETE;
1157 if (waitqueue_active(&cl->rx_wait))
1158 wake_up_interruptible(&cl->rx_wait);
1159 else
1160 mei_cl_bus_rx_event(cl);
1161
1162 }
1163}
1164
1165
1166/**
1167 * mei_cl_all_disconnect - disconnect forcefully all connected clients
1168 *
1169 * @dev: mei device
1170 */
1171
1172void mei_cl_all_disconnect(struct mei_device *dev)
1173{
1174 struct mei_cl *cl;
1175
1176 list_for_each_entry(cl, &dev->file_list, link) {
1177 cl->state = MEI_FILE_DISCONNECTED;
1178 cl->mei_flow_ctrl_creds = 0;
1179 cl->timer_count = 0;
1180 }
1181}
1182
1183
1184/**
1185 * mei_cl_all_wakeup - wake up all readers and writers they can be interrupted
1186 *
1187 * @dev: mei device
1188 */
1189void mei_cl_all_wakeup(struct mei_device *dev)
1190{
1191 struct mei_cl *cl;
1192
1193 list_for_each_entry(cl, &dev->file_list, link) {
1194 if (waitqueue_active(&cl->rx_wait)) {
1195 cl_dbg(dev, cl, "Waking up reading client!\n");
1196 wake_up_interruptible(&cl->rx_wait);
1197 }
1198 if (waitqueue_active(&cl->tx_wait)) {
1199 cl_dbg(dev, cl, "Waking up writing client!\n");
1200 wake_up_interruptible(&cl->tx_wait);
1201 }
1202 }
1203}
1204
1205/**
1206 * mei_cl_all_write_clear - clear all pending writes
1207 *
1208 * @dev: mei device
1209 */
1210void mei_cl_all_write_clear(struct mei_device *dev)
1211{
1212 mei_io_list_free(&dev->write_list, NULL);
1213 mei_io_list_free(&dev->write_waiting_list, NULL);
1214}
1215
1216