2 * Intel Management Engine Interface (Intel MEI) Linux driver
3 * Copyright (c) 2012-2013, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 #include <linux/module.h>
17 #include <linux/device.h>
18 #include <linux/kernel.h>
19 #include <linux/sched.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>
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)
33 static int mei_cl_device_match(struct device
*dev
, struct device_driver
*drv
)
35 struct mei_cl_device
*device
= to_mei_cl_device(dev
);
36 struct mei_cl_driver
*driver
= to_mei_cl_driver(drv
);
37 const struct mei_cl_device_id
*id
;
44 uuid
= mei_me_cl_uuid(device
->me_cl
);
47 if (!driver
|| !driver
->id_table
)
50 id
= driver
->id_table
;
52 while (uuid_le_cmp(NULL_UUID_LE
, id
->uuid
)) {
54 if (!uuid_le_cmp(*uuid
, id
->uuid
)) {
56 if (!strncmp(name
, id
->name
, sizeof(id
->name
)))
69 static int mei_cl_device_probe(struct device
*dev
)
71 struct mei_cl_device
*device
= to_mei_cl_device(dev
);
72 struct mei_cl_driver
*driver
;
73 struct mei_cl_device_id id
;
78 driver
= to_mei_cl_driver(dev
->driver
);
79 if (!driver
|| !driver
->probe
)
82 dev_dbg(dev
, "Device probe\n");
84 strlcpy(id
.name
, device
->name
, sizeof(id
.name
));
86 return driver
->probe(device
, &id
);
89 static int mei_cl_device_remove(struct device
*dev
)
91 struct mei_cl_device
*device
= to_mei_cl_device(dev
);
92 struct mei_cl_driver
*driver
;
94 if (!device
|| !dev
->driver
)
97 if (device
->event_cb
) {
98 device
->event_cb
= NULL
;
99 cancel_work_sync(&device
->event_work
);
102 driver
= to_mei_cl_driver(dev
->driver
);
103 if (!driver
->remove
) {
109 return driver
->remove(device
);
112 static ssize_t
name_show(struct device
*dev
, struct device_attribute
*a
,
115 struct mei_cl_device
*device
= to_mei_cl_device(dev
);
118 len
= snprintf(buf
, PAGE_SIZE
, "%s", device
->name
);
120 return (len
>= PAGE_SIZE
) ? (PAGE_SIZE
- 1) : len
;
122 static DEVICE_ATTR_RO(name
);
124 static ssize_t
uuid_show(struct device
*dev
, struct device_attribute
*a
,
127 struct mei_cl_device
*device
= to_mei_cl_device(dev
);
128 const uuid_le
*uuid
= mei_me_cl_uuid(device
->me_cl
);
131 len
= snprintf(buf
, PAGE_SIZE
, "%pUl", uuid
);
133 return (len
>= PAGE_SIZE
) ? (PAGE_SIZE
- 1) : len
;
135 static DEVICE_ATTR_RO(uuid
);
137 static ssize_t
modalias_show(struct device
*dev
, struct device_attribute
*a
,
140 struct mei_cl_device
*device
= to_mei_cl_device(dev
);
141 const uuid_le
*uuid
= mei_me_cl_uuid(device
->me_cl
);
144 len
= snprintf(buf
, PAGE_SIZE
, "mei:%s:" MEI_CL_UUID_FMT
":",
145 device
->name
, MEI_CL_UUID_ARGS(uuid
->b
));
147 return (len
>= PAGE_SIZE
) ? (PAGE_SIZE
- 1) : len
;
149 static DEVICE_ATTR_RO(modalias
);
151 static struct attribute
*mei_cl_dev_attrs
[] = {
154 &dev_attr_modalias
.attr
,
157 ATTRIBUTE_GROUPS(mei_cl_dev
);
159 static int mei_cl_uevent(struct device
*dev
, struct kobj_uevent_env
*env
)
161 struct mei_cl_device
*device
= to_mei_cl_device(dev
);
162 const uuid_le
*uuid
= mei_me_cl_uuid(device
->me_cl
);
164 if (add_uevent_var(env
, "MEI_CL_UUID=%pUl", uuid
))
167 if (add_uevent_var(env
, "MEI_CL_NAME=%s", device
->name
))
170 if (add_uevent_var(env
, "MODALIAS=mei:%s:" MEI_CL_UUID_FMT
":",
171 device
->name
, MEI_CL_UUID_ARGS(uuid
->b
)))
177 static struct bus_type mei_cl_bus_type
= {
179 .dev_groups
= mei_cl_dev_groups
,
180 .match
= mei_cl_device_match
,
181 .probe
= mei_cl_device_probe
,
182 .remove
= mei_cl_device_remove
,
183 .uevent
= mei_cl_uevent
,
186 static void mei_cl_dev_release(struct device
*dev
)
188 struct mei_cl_device
*device
= to_mei_cl_device(dev
);
193 mei_me_cl_put(device
->me_cl
);
197 static struct device_type mei_cl_device_type
= {
198 .release
= mei_cl_dev_release
,
201 struct mei_cl
*mei_cl_bus_find_cl_by_uuid(struct mei_device
*dev
,
206 list_for_each_entry(cl
, &dev
->device_list
, device_link
) {
207 if (cl
->device
&& cl
->device
->me_cl
&&
208 !uuid_le_cmp(uuid
, *mei_me_cl_uuid(cl
->device
->me_cl
)))
215 struct mei_cl_device
*mei_cl_add_device(struct mei_device
*dev
,
216 struct mei_me_client
*me_cl
,
220 struct mei_cl_device
*device
;
223 device
= kzalloc(sizeof(struct mei_cl_device
), GFP_KERNEL
);
227 device
->me_cl
= mei_me_cl_get(me_cl
);
228 if (!device
->me_cl
) {
234 device
->dev
.parent
= dev
->dev
;
235 device
->dev
.bus
= &mei_cl_bus_type
;
236 device
->dev
.type
= &mei_cl_device_type
;
238 strlcpy(device
->name
, name
, sizeof(device
->name
));
240 dev_set_name(&device
->dev
, "mei:%s:%pUl", name
, mei_me_cl_uuid(me_cl
));
242 status
= device_register(&device
->dev
);
244 dev_err(dev
->dev
, "Failed to register MEI device\n");
245 mei_me_cl_put(device
->me_cl
);
252 dev_dbg(&device
->dev
, "client %s registered\n", name
);
256 EXPORT_SYMBOL_GPL(mei_cl_add_device
);
258 void mei_cl_remove_device(struct mei_cl_device
*device
)
260 device_unregister(&device
->dev
);
262 EXPORT_SYMBOL_GPL(mei_cl_remove_device
);
264 int __mei_cl_driver_register(struct mei_cl_driver
*driver
, struct module
*owner
)
268 driver
->driver
.name
= driver
->name
;
269 driver
->driver
.owner
= owner
;
270 driver
->driver
.bus
= &mei_cl_bus_type
;
272 err
= driver_register(&driver
->driver
);
276 pr_debug("mei: driver [%s] registered\n", driver
->driver
.name
);
280 EXPORT_SYMBOL_GPL(__mei_cl_driver_register
);
282 void mei_cl_driver_unregister(struct mei_cl_driver
*driver
)
284 driver_unregister(&driver
->driver
);
286 pr_debug("mei: driver [%s] unregistered\n", driver
->driver
.name
);
288 EXPORT_SYMBOL_GPL(mei_cl_driver_unregister
);
290 ssize_t
__mei_cl_send(struct mei_cl
*cl
, u8
*buf
, size_t length
,
293 struct mei_device
*dev
;
294 struct mei_cl_cb
*cb
= NULL
;
297 if (WARN_ON(!cl
|| !cl
->dev
))
302 mutex_lock(&dev
->device_lock
);
303 if (!mei_cl_is_connected(cl
)) {
308 /* Check if we have an ME client device */
309 if (!mei_me_cl_is_active(cl
->me_cl
)) {
314 if (length
> mei_cl_mtu(cl
)) {
319 cb
= mei_cl_alloc_cb(cl
, length
, MEI_FOP_WRITE
, NULL
);
325 memcpy(cb
->buf
.data
, buf
, length
);
327 rets
= mei_cl_write(cl
, cb
, blocking
);
330 mutex_unlock(&dev
->device_lock
);
337 ssize_t
__mei_cl_recv(struct mei_cl
*cl
, u8
*buf
, size_t length
)
339 struct mei_device
*dev
;
340 struct mei_cl_cb
*cb
;
344 if (WARN_ON(!cl
|| !cl
->dev
))
349 mutex_lock(&dev
->device_lock
);
351 cb
= mei_cl_read_cb(cl
, NULL
);
355 rets
= mei_cl_read_start(cl
, length
, NULL
);
356 if (rets
&& rets
!= -EBUSY
)
359 if (list_empty(&cl
->rd_completed
) && !waitqueue_active(&cl
->rx_wait
)) {
361 mutex_unlock(&dev
->device_lock
);
363 if (wait_event_interruptible(cl
->rx_wait
,
364 (!list_empty(&cl
->rd_completed
)) ||
365 (!mei_cl_is_connected(cl
)))) {
367 if (signal_pending(current
))
372 mutex_lock(&dev
->device_lock
);
374 if (!mei_cl_is_connected(cl
)) {
380 cb
= mei_cl_read_cb(cl
, NULL
);
392 r_length
= min_t(size_t, length
, cb
->buf_idx
);
393 memcpy(buf
, cb
->buf
.data
, r_length
);
399 mutex_unlock(&dev
->device_lock
);
404 ssize_t
mei_cl_send(struct mei_cl_device
*device
, u8
*buf
, size_t length
)
406 struct mei_cl
*cl
= device
->cl
;
411 return __mei_cl_send(cl
, buf
, length
, 1);
413 EXPORT_SYMBOL_GPL(mei_cl_send
);
415 ssize_t
mei_cl_recv(struct mei_cl_device
*device
, u8
*buf
, size_t length
)
417 struct mei_cl
*cl
= device
->cl
;
422 return __mei_cl_recv(cl
, buf
, length
);
424 EXPORT_SYMBOL_GPL(mei_cl_recv
);
426 static void mei_bus_event_work(struct work_struct
*work
)
428 struct mei_cl_device
*device
;
430 device
= container_of(work
, struct mei_cl_device
, event_work
);
432 if (device
->event_cb
)
433 device
->event_cb(device
, device
->events
, device
->event_context
);
437 /* Prepare for the next read */
438 mei_cl_read_start(device
->cl
, 0, NULL
);
441 int mei_cl_register_event_cb(struct mei_cl_device
*device
,
442 mei_cl_event_cb_t event_cb
, void *context
)
444 if (device
->event_cb
)
448 device
->event_cb
= event_cb
;
449 device
->event_context
= context
;
450 INIT_WORK(&device
->event_work
, mei_bus_event_work
);
452 mei_cl_read_start(device
->cl
, 0, NULL
);
456 EXPORT_SYMBOL_GPL(mei_cl_register_event_cb
);
458 void *mei_cl_get_drvdata(const struct mei_cl_device
*device
)
460 return dev_get_drvdata(&device
->dev
);
462 EXPORT_SYMBOL_GPL(mei_cl_get_drvdata
);
464 void mei_cl_set_drvdata(struct mei_cl_device
*device
, void *data
)
466 dev_set_drvdata(&device
->dev
, data
);
468 EXPORT_SYMBOL_GPL(mei_cl_set_drvdata
);
470 int mei_cl_enable_device(struct mei_cl_device
*device
)
473 struct mei_device
*dev
;
474 struct mei_cl
*cl
= device
->cl
;
481 mutex_lock(&dev
->device_lock
);
483 if (mei_cl_is_connected(cl
)) {
484 mutex_unlock(&dev
->device_lock
);
485 dev_warn(dev
->dev
, "Already connected");
489 err
= mei_cl_connect(cl
, device
->me_cl
, NULL
);
491 mutex_unlock(&dev
->device_lock
);
492 dev_err(dev
->dev
, "Could not connect to the ME client");
497 mutex_unlock(&dev
->device_lock
);
499 if (device
->event_cb
)
500 mei_cl_read_start(device
->cl
, 0, NULL
);
504 EXPORT_SYMBOL_GPL(mei_cl_enable_device
);
506 int mei_cl_disable_device(struct mei_cl_device
*device
)
509 struct mei_device
*dev
;
510 struct mei_cl
*cl
= device
->cl
;
517 device
->event_cb
= NULL
;
519 mutex_lock(&dev
->device_lock
);
521 if (!mei_cl_is_connected(cl
)) {
522 dev_err(dev
->dev
, "Already disconnected");
527 err
= mei_cl_disconnect(cl
);
529 dev_err(dev
->dev
, "Could not disconnect from the ME client");
533 /* Flush queues and remove any pending read */
534 mei_cl_flush_queues(cl
, NULL
);
537 mutex_unlock(&dev
->device_lock
);
541 EXPORT_SYMBOL_GPL(mei_cl_disable_device
);
543 void mei_cl_bus_rx_event(struct mei_cl
*cl
)
545 struct mei_cl_device
*device
= cl
->device
;
547 if (!device
|| !device
->event_cb
)
550 set_bit(MEI_CL_EVENT_RX
, &device
->events
);
552 schedule_work(&device
->event_work
);
555 int __init
mei_cl_bus_init(void)
557 return bus_register(&mei_cl_bus_type
);
560 void __exit
mei_cl_bus_exit(void)
562 bus_unregister(&mei_cl_bus_type
);