1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/module.h>
17#include <linux/device.h>
18#include <linux/kernel.h>
19#include <linux/sched/signal.h>
20#include <linux/init.h>
21#include <linux/errno.h>
22#include <linux/slab.h>
23#include <linux/mutex.h>
24#include <linux/interrupt.h>
25#include <linux/mei_cl_bus.h>
26
27#include "mei_dev.h"
28#include "client.h"
29
30#define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver)
31#define to_mei_cl_device(d) container_of(d, struct mei_cl_device, dev)
32
33
34
35
36
37
38
39
40
41
42
43ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
44 unsigned int mode)
45{
46 struct mei_device *bus;
47 struct mei_cl_cb *cb;
48 ssize_t rets;
49
50 if (WARN_ON(!cl || !cl->dev))
51 return -ENODEV;
52
53 bus = cl->dev;
54
55 mutex_lock(&bus->device_lock);
56 if (bus->dev_state != MEI_DEV_ENABLED) {
57 rets = -ENODEV;
58 goto out;
59 }
60
61 if (!mei_cl_is_connected(cl)) {
62 rets = -ENODEV;
63 goto out;
64 }
65
66
67 if (!mei_me_cl_is_active(cl->me_cl)) {
68 rets = -ENOTTY;
69 goto out;
70 }
71
72 if (length > mei_cl_mtu(cl)) {
73 rets = -EFBIG;
74 goto out;
75 }
76
77 cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, NULL);
78 if (!cb) {
79 rets = -ENOMEM;
80 goto out;
81 }
82
83 cb->internal = !!(mode & MEI_CL_IO_TX_INTERNAL);
84 cb->blocking = !!(mode & MEI_CL_IO_TX_BLOCKING);
85 memcpy(cb->buf.data, buf, length);
86
87 rets = mei_cl_write(cl, cb);
88
89out:
90 mutex_unlock(&bus->device_lock);
91
92 return rets;
93}
94
95
96
97
98
99
100
101
102
103
104
105ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
106 unsigned int mode)
107{
108 struct mei_device *bus;
109 struct mei_cl_cb *cb;
110 size_t r_length;
111 ssize_t rets;
112 bool nonblock = !!(mode & MEI_CL_IO_RX_NONBLOCK);
113
114 if (WARN_ON(!cl || !cl->dev))
115 return -ENODEV;
116
117 bus = cl->dev;
118
119 mutex_lock(&bus->device_lock);
120 if (bus->dev_state != MEI_DEV_ENABLED) {
121 rets = -ENODEV;
122 goto out;
123 }
124
125 cb = mei_cl_read_cb(cl, NULL);
126 if (cb)
127 goto copy;
128
129 rets = mei_cl_read_start(cl, length, NULL);
130 if (rets && rets != -EBUSY)
131 goto out;
132
133 if (nonblock) {
134 rets = -EAGAIN;
135 goto out;
136 }
137
138
139
140 if (!waitqueue_active(&cl->rx_wait)) {
141
142 mutex_unlock(&bus->device_lock);
143
144 if (wait_event_interruptible(cl->rx_wait,
145 (!list_empty(&cl->rd_completed)) ||
146 (!mei_cl_is_connected(cl)))) {
147
148 if (signal_pending(current))
149 return -EINTR;
150 return -ERESTARTSYS;
151 }
152
153 mutex_lock(&bus->device_lock);
154
155 if (!mei_cl_is_connected(cl)) {
156 rets = -ENODEV;
157 goto out;
158 }
159 }
160
161 cb = mei_cl_read_cb(cl, NULL);
162 if (!cb) {
163 rets = 0;
164 goto out;
165 }
166
167copy:
168 if (cb->status) {
169 rets = cb->status;
170 goto free;
171 }
172
173 r_length = min_t(size_t, length, cb->buf_idx);
174 memcpy(buf, cb->buf.data, r_length);
175 rets = r_length;
176
177free:
178 mei_io_cb_free(cb);
179out:
180 mutex_unlock(&bus->device_lock);
181
182 return rets;
183}
184
185
186
187
188
189
190
191
192
193
194ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
195{
196 struct mei_cl *cl = cldev->cl;
197
198 return __mei_cl_send(cl, buf, length, MEI_CL_IO_TX_BLOCKING);
199}
200EXPORT_SYMBOL_GPL(mei_cldev_send);
201
202
203
204
205
206
207
208
209
210
211
212ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
213 size_t length)
214{
215 struct mei_cl *cl = cldev->cl;
216
217 return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK);
218}
219EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock);
220
221
222
223
224
225
226
227
228
229
230ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
231{
232 struct mei_cl *cl = cldev->cl;
233
234 return __mei_cl_recv(cl, buf, length, 0);
235}
236EXPORT_SYMBOL_GPL(mei_cldev_recv);
237
238
239
240
241
242
243static void mei_cl_bus_rx_work(struct work_struct *work)
244{
245 struct mei_cl_device *cldev;
246 struct mei_device *bus;
247
248 cldev = container_of(work, struct mei_cl_device, rx_work);
249
250 bus = cldev->bus;
251
252 if (cldev->rx_cb)
253 cldev->rx_cb(cldev);
254
255 mutex_lock(&bus->device_lock);
256 mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL);
257 mutex_unlock(&bus->device_lock);
258}
259
260
261
262
263
264
265static void mei_cl_bus_notif_work(struct work_struct *work)
266{
267 struct mei_cl_device *cldev;
268
269 cldev = container_of(work, struct mei_cl_device, notif_work);
270
271 if (cldev->notif_cb)
272 cldev->notif_cb(cldev);
273}
274
275
276
277
278
279
280
281
282
283bool mei_cl_bus_notify_event(struct mei_cl *cl)
284{
285 struct mei_cl_device *cldev = cl->cldev;
286
287 if (!cldev || !cldev->notif_cb)
288 return false;
289
290 if (!cl->notify_ev)
291 return false;
292
293 schedule_work(&cldev->notif_work);
294
295 cl->notify_ev = false;
296
297 return true;
298}
299
300
301
302
303
304
305
306
307
308bool mei_cl_bus_rx_event(struct mei_cl *cl)
309{
310 struct mei_cl_device *cldev = cl->cldev;
311
312 if (!cldev || !cldev->rx_cb)
313 return false;
314
315 schedule_work(&cldev->rx_work);
316
317 return true;
318}
319
320
321
322
323
324
325
326
327
328
329
330int mei_cldev_register_rx_cb(struct mei_cl_device *cldev, mei_cldev_cb_t rx_cb)
331{
332 struct mei_device *bus = cldev->bus;
333 int ret;
334
335 if (!rx_cb)
336 return -EINVAL;
337 if (cldev->rx_cb)
338 return -EALREADY;
339
340 cldev->rx_cb = rx_cb;
341 INIT_WORK(&cldev->rx_work, mei_cl_bus_rx_work);
342
343 mutex_lock(&bus->device_lock);
344 ret = mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL);
345 mutex_unlock(&bus->device_lock);
346 if (ret && ret != -EBUSY)
347 return ret;
348
349 return 0;
350}
351EXPORT_SYMBOL_GPL(mei_cldev_register_rx_cb);
352
353
354
355
356
357
358
359
360
361
362
363int mei_cldev_register_notif_cb(struct mei_cl_device *cldev,
364 mei_cldev_cb_t notif_cb)
365{
366 struct mei_device *bus = cldev->bus;
367 int ret;
368
369 if (!notif_cb)
370 return -EINVAL;
371
372 if (cldev->notif_cb)
373 return -EALREADY;
374
375 cldev->notif_cb = notif_cb;
376 INIT_WORK(&cldev->notif_work, mei_cl_bus_notif_work);
377
378 mutex_lock(&bus->device_lock);
379 ret = mei_cl_notify_request(cldev->cl, NULL, 1);
380 mutex_unlock(&bus->device_lock);
381 if (ret)
382 return ret;
383
384 return 0;
385}
386EXPORT_SYMBOL_GPL(mei_cldev_register_notif_cb);
387
388
389
390
391
392
393
394
395void *mei_cldev_get_drvdata(const struct mei_cl_device *cldev)
396{
397 return dev_get_drvdata(&cldev->dev);
398}
399EXPORT_SYMBOL_GPL(mei_cldev_get_drvdata);
400
401
402
403
404
405
406
407void mei_cldev_set_drvdata(struct mei_cl_device *cldev, void *data)
408{
409 dev_set_drvdata(&cldev->dev, data);
410}
411EXPORT_SYMBOL_GPL(mei_cldev_set_drvdata);
412
413
414
415
416
417
418
419
420const uuid_le *mei_cldev_uuid(const struct mei_cl_device *cldev)
421{
422 return mei_me_cl_uuid(cldev->me_cl);
423}
424EXPORT_SYMBOL_GPL(mei_cldev_uuid);
425
426
427
428
429
430
431
432
433u8 mei_cldev_ver(const struct mei_cl_device *cldev)
434{
435 return mei_me_cl_ver(cldev->me_cl);
436}
437EXPORT_SYMBOL_GPL(mei_cldev_ver);
438
439
440
441
442
443
444
445
446bool mei_cldev_enabled(struct mei_cl_device *cldev)
447{
448 return mei_cl_is_connected(cldev->cl);
449}
450EXPORT_SYMBOL_GPL(mei_cldev_enabled);
451
452
453
454
455
456
457
458
459
460int mei_cldev_enable(struct mei_cl_device *cldev)
461{
462 struct mei_device *bus = cldev->bus;
463 struct mei_cl *cl;
464 int ret;
465
466 cl = cldev->cl;
467
468 if (cl->state == MEI_FILE_UNINITIALIZED) {
469 mutex_lock(&bus->device_lock);
470 ret = mei_cl_link(cl);
471 mutex_unlock(&bus->device_lock);
472 if (ret)
473 return ret;
474
475 cl->cldev = cldev;
476 }
477
478 mutex_lock(&bus->device_lock);
479 if (mei_cl_is_connected(cl)) {
480 ret = 0;
481 goto out;
482 }
483
484 if (!mei_me_cl_is_active(cldev->me_cl)) {
485 dev_err(&cldev->dev, "me client is not active\n");
486 ret = -ENOTTY;
487 goto out;
488 }
489
490 ret = mei_cl_connect(cl, cldev->me_cl, NULL);
491 if (ret < 0)
492 dev_err(&cldev->dev, "cannot connect\n");
493
494out:
495 mutex_unlock(&bus->device_lock);
496
497 return ret;
498}
499EXPORT_SYMBOL_GPL(mei_cldev_enable);
500
501
502
503
504
505
506
507static void mei_cldev_unregister_callbacks(struct mei_cl_device *cldev)
508{
509 if (cldev->rx_cb) {
510 cancel_work_sync(&cldev->rx_work);
511 cldev->rx_cb = NULL;
512 }
513
514 if (cldev->notif_cb) {
515 cancel_work_sync(&cldev->notif_work);
516 cldev->notif_cb = NULL;
517 }
518}
519
520
521
522
523
524
525
526
527
528int mei_cldev_disable(struct mei_cl_device *cldev)
529{
530 struct mei_device *bus;
531 struct mei_cl *cl;
532 int err;
533
534 if (!cldev)
535 return -ENODEV;
536
537 cl = cldev->cl;
538
539 bus = cldev->bus;
540
541 mei_cldev_unregister_callbacks(cldev);
542
543 mutex_lock(&bus->device_lock);
544
545 if (!mei_cl_is_connected(cl)) {
546 dev_dbg(bus->dev, "Already disconnected");
547 err = 0;
548 goto out;
549 }
550
551 err = mei_cl_disconnect(cl);
552 if (err < 0)
553 dev_err(bus->dev, "Could not disconnect from the ME client");
554
555out:
556
557 mei_cl_flush_queues(cl, NULL);
558 mei_cl_unlink(cl);
559
560 mutex_unlock(&bus->device_lock);
561 return err;
562}
563EXPORT_SYMBOL_GPL(mei_cldev_disable);
564
565
566
567
568
569
570
571
572
573bool mei_cl_bus_module_get(struct mei_cl *cl)
574{
575 struct mei_cl_device *cldev = cl->cldev;
576
577 if (!cldev)
578 return true;
579
580 return try_module_get(cldev->bus->dev->driver->owner);
581}
582
583
584
585
586
587
588void mei_cl_bus_module_put(struct mei_cl *cl)
589{
590 struct mei_cl_device *cldev = cl->cldev;
591
592 if (cldev)
593 module_put(cldev->bus->dev->driver->owner);
594}
595
596
597
598
599
600
601
602
603
604static const
605struct mei_cl_device_id *mei_cl_device_find(struct mei_cl_device *cldev,
606 struct mei_cl_driver *cldrv)
607{
608 const struct mei_cl_device_id *id;
609 const uuid_le *uuid;
610 u8 version;
611 bool match;
612
613 uuid = mei_me_cl_uuid(cldev->me_cl);
614 version = mei_me_cl_ver(cldev->me_cl);
615
616 id = cldrv->id_table;
617 while (uuid_le_cmp(NULL_UUID_LE, id->uuid)) {
618 if (!uuid_le_cmp(*uuid, id->uuid)) {
619 match = true;
620
621 if (cldev->name[0])
622 if (strncmp(cldev->name, id->name,
623 sizeof(id->name)))
624 match = false;
625
626 if (id->version != MEI_CL_VERSION_ANY)
627 if (id->version != version)
628 match = false;
629 if (match)
630 return id;
631 }
632
633 id++;
634 }
635
636 return NULL;
637}
638
639
640
641
642
643
644
645
646
647static int mei_cl_device_match(struct device *dev, struct device_driver *drv)
648{
649 struct mei_cl_device *cldev = to_mei_cl_device(dev);
650 struct mei_cl_driver *cldrv = to_mei_cl_driver(drv);
651 const struct mei_cl_device_id *found_id;
652
653 if (!cldev)
654 return 0;
655
656 if (!cldev->do_match)
657 return 0;
658
659 if (!cldrv || !cldrv->id_table)
660 return 0;
661
662 found_id = mei_cl_device_find(cldev, cldrv);
663 if (found_id)
664 return 1;
665
666 return 0;
667}
668
669
670
671
672
673
674
675
676static int mei_cl_device_probe(struct device *dev)
677{
678 struct mei_cl_device *cldev;
679 struct mei_cl_driver *cldrv;
680 const struct mei_cl_device_id *id;
681 int ret;
682
683 cldev = to_mei_cl_device(dev);
684 cldrv = to_mei_cl_driver(dev->driver);
685
686 if (!cldev)
687 return 0;
688
689 if (!cldrv || !cldrv->probe)
690 return -ENODEV;
691
692 id = mei_cl_device_find(cldev, cldrv);
693 if (!id)
694 return -ENODEV;
695
696 ret = cldrv->probe(cldev, id);
697 if (ret)
698 return ret;
699
700 __module_get(THIS_MODULE);
701 return 0;
702}
703
704
705
706
707
708
709
710
711static int mei_cl_device_remove(struct device *dev)
712{
713 struct mei_cl_device *cldev = to_mei_cl_device(dev);
714 struct mei_cl_driver *cldrv;
715 int ret = 0;
716
717 if (!cldev || !dev->driver)
718 return 0;
719
720 cldrv = to_mei_cl_driver(dev->driver);
721 if (cldrv->remove)
722 ret = cldrv->remove(cldev);
723
724 mei_cldev_unregister_callbacks(cldev);
725
726 module_put(THIS_MODULE);
727 dev->driver = NULL;
728 return ret;
729
730}
731
732static ssize_t name_show(struct device *dev, struct device_attribute *a,
733 char *buf)
734{
735 struct mei_cl_device *cldev = to_mei_cl_device(dev);
736
737 return scnprintf(buf, PAGE_SIZE, "%s", cldev->name);
738}
739static DEVICE_ATTR_RO(name);
740
741static ssize_t uuid_show(struct device *dev, struct device_attribute *a,
742 char *buf)
743{
744 struct mei_cl_device *cldev = to_mei_cl_device(dev);
745 const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
746
747 return scnprintf(buf, PAGE_SIZE, "%pUl", uuid);
748}
749static DEVICE_ATTR_RO(uuid);
750
751static ssize_t version_show(struct device *dev, struct device_attribute *a,
752 char *buf)
753{
754 struct mei_cl_device *cldev = to_mei_cl_device(dev);
755 u8 version = mei_me_cl_ver(cldev->me_cl);
756
757 return scnprintf(buf, PAGE_SIZE, "%02X", version);
758}
759static DEVICE_ATTR_RO(version);
760
761static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
762 char *buf)
763{
764 struct mei_cl_device *cldev = to_mei_cl_device(dev);
765 const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
766 u8 version = mei_me_cl_ver(cldev->me_cl);
767
768 return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:%02X:",
769 cldev->name, uuid, version);
770}
771static DEVICE_ATTR_RO(modalias);
772
773static struct attribute *mei_cldev_attrs[] = {
774 &dev_attr_name.attr,
775 &dev_attr_uuid.attr,
776 &dev_attr_version.attr,
777 &dev_attr_modalias.attr,
778 NULL,
779};
780ATTRIBUTE_GROUPS(mei_cldev);
781
782
783
784
785
786
787
788
789
790static int mei_cl_device_uevent(struct device *dev, struct kobj_uevent_env *env)
791{
792 struct mei_cl_device *cldev = to_mei_cl_device(dev);
793 const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
794 u8 version = mei_me_cl_ver(cldev->me_cl);
795
796 if (add_uevent_var(env, "MEI_CL_VERSION=%d", version))
797 return -ENOMEM;
798
799 if (add_uevent_var(env, "MEI_CL_UUID=%pUl", uuid))
800 return -ENOMEM;
801
802 if (add_uevent_var(env, "MEI_CL_NAME=%s", cldev->name))
803 return -ENOMEM;
804
805 if (add_uevent_var(env, "MODALIAS=mei:%s:%pUl:%02X:",
806 cldev->name, uuid, version))
807 return -ENOMEM;
808
809 return 0;
810}
811
812static struct bus_type mei_cl_bus_type = {
813 .name = "mei",
814 .dev_groups = mei_cldev_groups,
815 .match = mei_cl_device_match,
816 .probe = mei_cl_device_probe,
817 .remove = mei_cl_device_remove,
818 .uevent = mei_cl_device_uevent,
819};
820
821static struct mei_device *mei_dev_bus_get(struct mei_device *bus)
822{
823 if (bus)
824 get_device(bus->dev);
825
826 return bus;
827}
828
829static void mei_dev_bus_put(struct mei_device *bus)
830{
831 if (bus)
832 put_device(bus->dev);
833}
834
835static void mei_cl_bus_dev_release(struct device *dev)
836{
837 struct mei_cl_device *cldev = to_mei_cl_device(dev);
838
839 if (!cldev)
840 return;
841
842 mei_me_cl_put(cldev->me_cl);
843 mei_dev_bus_put(cldev->bus);
844 kfree(cldev->cl);
845 kfree(cldev);
846}
847
848static const struct device_type mei_cl_device_type = {
849 .release = mei_cl_bus_dev_release,
850};
851
852
853
854
855
856
857static inline void mei_cl_bus_set_name(struct mei_cl_device *cldev)
858{
859 dev_set_name(&cldev->dev, "mei:%s:%pUl:%02X",
860 cldev->name,
861 mei_me_cl_uuid(cldev->me_cl),
862 mei_me_cl_ver(cldev->me_cl));
863}
864
865
866
867
868
869
870
871
872
873static struct mei_cl_device *mei_cl_bus_dev_alloc(struct mei_device *bus,
874 struct mei_me_client *me_cl)
875{
876 struct mei_cl_device *cldev;
877 struct mei_cl *cl;
878
879 cldev = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL);
880 if (!cldev)
881 return NULL;
882
883 cl = mei_cl_allocate(bus);
884 if (!cl) {
885 kfree(cldev);
886 return NULL;
887 }
888
889 device_initialize(&cldev->dev);
890 cldev->dev.parent = bus->dev;
891 cldev->dev.bus = &mei_cl_bus_type;
892 cldev->dev.type = &mei_cl_device_type;
893 cldev->bus = mei_dev_bus_get(bus);
894 cldev->me_cl = mei_me_cl_get(me_cl);
895 cldev->cl = cl;
896 mei_cl_bus_set_name(cldev);
897 cldev->is_added = 0;
898 INIT_LIST_HEAD(&cldev->bus_list);
899
900 return cldev;
901}
902
903
904
905
906
907
908
909
910
911
912static bool mei_cl_bus_dev_setup(struct mei_device *bus,
913 struct mei_cl_device *cldev)
914{
915 cldev->do_match = 1;
916 mei_cl_bus_dev_fixup(cldev);
917
918
919 if (cldev->do_match)
920 mei_cl_bus_set_name(cldev);
921
922 return cldev->do_match == 1;
923}
924
925
926
927
928
929
930
931
932static int mei_cl_bus_dev_add(struct mei_cl_device *cldev)
933{
934 int ret;
935
936 dev_dbg(cldev->bus->dev, "adding %pUL:%02X\n",
937 mei_me_cl_uuid(cldev->me_cl),
938 mei_me_cl_ver(cldev->me_cl));
939 ret = device_add(&cldev->dev);
940 if (!ret)
941 cldev->is_added = 1;
942
943 return ret;
944}
945
946
947
948
949
950
951static void mei_cl_bus_dev_stop(struct mei_cl_device *cldev)
952{
953 if (cldev->is_added)
954 device_release_driver(&cldev->dev);
955}
956
957
958
959
960
961
962
963
964static void mei_cl_bus_dev_destroy(struct mei_cl_device *cldev)
965{
966
967 WARN_ON(!mutex_is_locked(&cldev->bus->cl_bus_lock));
968
969 if (!cldev->is_added)
970 return;
971
972 device_del(&cldev->dev);
973
974 list_del_init(&cldev->bus_list);
975
976 cldev->is_added = 0;
977 put_device(&cldev->dev);
978}
979
980
981
982
983
984
985static void mei_cl_bus_remove_device(struct mei_cl_device *cldev)
986{
987 mei_cl_bus_dev_stop(cldev);
988 mei_cl_bus_dev_destroy(cldev);
989}
990
991
992
993
994
995
996void mei_cl_bus_remove_devices(struct mei_device *bus)
997{
998 struct mei_cl_device *cldev, *next;
999
1000 mutex_lock(&bus->cl_bus_lock);
1001 list_for_each_entry_safe(cldev, next, &bus->device_list, bus_list)
1002 mei_cl_bus_remove_device(cldev);
1003 mutex_unlock(&bus->cl_bus_lock);
1004}
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016static void mei_cl_bus_dev_init(struct mei_device *bus,
1017 struct mei_me_client *me_cl)
1018{
1019 struct mei_cl_device *cldev;
1020
1021 WARN_ON(!mutex_is_locked(&bus->cl_bus_lock));
1022
1023 dev_dbg(bus->dev, "initializing %pUl", mei_me_cl_uuid(me_cl));
1024
1025 if (me_cl->bus_added)
1026 return;
1027
1028 cldev = mei_cl_bus_dev_alloc(bus, me_cl);
1029 if (!cldev)
1030 return;
1031
1032 me_cl->bus_added = true;
1033 list_add_tail(&cldev->bus_list, &bus->device_list);
1034
1035}
1036
1037
1038
1039
1040
1041
1042
1043static void mei_cl_bus_rescan(struct mei_device *bus)
1044{
1045 struct mei_cl_device *cldev, *n;
1046 struct mei_me_client *me_cl;
1047
1048 mutex_lock(&bus->cl_bus_lock);
1049
1050 down_read(&bus->me_clients_rwsem);
1051 list_for_each_entry(me_cl, &bus->me_clients, list)
1052 mei_cl_bus_dev_init(bus, me_cl);
1053 up_read(&bus->me_clients_rwsem);
1054
1055 list_for_each_entry_safe(cldev, n, &bus->device_list, bus_list) {
1056
1057 if (!mei_me_cl_is_active(cldev->me_cl)) {
1058 mei_cl_bus_remove_device(cldev);
1059 continue;
1060 }
1061
1062 if (cldev->is_added)
1063 continue;
1064
1065 if (mei_cl_bus_dev_setup(bus, cldev))
1066 mei_cl_bus_dev_add(cldev);
1067 else {
1068 list_del_init(&cldev->bus_list);
1069 put_device(&cldev->dev);
1070 }
1071 }
1072 mutex_unlock(&bus->cl_bus_lock);
1073
1074 dev_dbg(bus->dev, "rescan end");
1075}
1076
1077void mei_cl_bus_rescan_work(struct work_struct *work)
1078{
1079 struct mei_device *bus =
1080 container_of(work, struct mei_device, bus_rescan_work);
1081
1082 mei_cl_bus_rescan(bus);
1083}
1084
1085int __mei_cldev_driver_register(struct mei_cl_driver *cldrv,
1086 struct module *owner)
1087{
1088 int err;
1089
1090 cldrv->driver.name = cldrv->name;
1091 cldrv->driver.owner = owner;
1092 cldrv->driver.bus = &mei_cl_bus_type;
1093
1094 err = driver_register(&cldrv->driver);
1095 if (err)
1096 return err;
1097
1098 pr_debug("mei: driver [%s] registered\n", cldrv->driver.name);
1099
1100 return 0;
1101}
1102EXPORT_SYMBOL_GPL(__mei_cldev_driver_register);
1103
1104void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv)
1105{
1106 driver_unregister(&cldrv->driver);
1107
1108 pr_debug("mei: driver [%s] unregistered\n", cldrv->driver.name);
1109}
1110EXPORT_SYMBOL_GPL(mei_cldev_driver_unregister);
1111
1112
1113int __init mei_cl_bus_init(void)
1114{
1115 return bus_register(&mei_cl_bus_type);
1116}
1117
1118void __exit mei_cl_bus_exit(void)
1119{
1120 bus_unregister(&mei_cl_bus_type);
1121}
1122