Commit e46980a10a76ec3282dd6832c1974b880acd23d3

Authored by Samuel Ortiz
Committed by Greg Kroah-Hartman
1 parent d6c36a475f

mei: bus: Add device enabling and disabling API

It should be left to the drivers to enable and disable the device on the
MEI bus when e.g getting probed.
For drivers to be able to safely call the enable and disable hooks, the
mei_cl_ops must be set before it's probed and thus this should happen
before registering the device on the MEI bus. Hence the mei_cl_add_device()
prototype change.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 4 changed files with 123 additions and 14 deletions Inline Diff

Documentation/misc-devices/mei/mei-client-bus.txt
1 Intel(R) Management Engine (ME) Client bus API 1 Intel(R) Management Engine (ME) Client bus API
2 =============================================== 2 ===============================================
3 3
4 4
5 Rationale 5 Rationale
6 ========= 6 =========
7 MEI misc character device is useful for dedicated applications to send and receive 7 MEI misc character device is useful for dedicated applications to send and receive
8 data to the many FW appliance found in Intel's ME from the user space. 8 data to the many FW appliance found in Intel's ME from the user space.
9 However for some of the ME functionalities it make sense to leverage existing software 9 However for some of the ME functionalities it make sense to leverage existing software
10 stack and expose them through existing kernel subsystems. 10 stack and expose them through existing kernel subsystems.
11 11
12 In order to plug seamlessly into the kernel device driver model we add kernel virtual 12 In order to plug seamlessly into the kernel device driver model we add kernel virtual
13 bus abstraction on top of the MEI driver. This allows implementing linux kernel drivers 13 bus abstraction on top of the MEI driver. This allows implementing linux kernel drivers
14 for the various MEI features as a stand alone entities found in their respective subsystem. 14 for the various MEI features as a stand alone entities found in their respective subsystem.
15 Existing device drivers can even potentially be re-used by adding an MEI CL bus layer to 15 Existing device drivers can even potentially be re-used by adding an MEI CL bus layer to
16 the existing code. 16 the existing code.
17 17
18 18
19 MEI CL bus API 19 MEI CL bus API
20 =========== 20 ===========
21 A driver implementation for an MEI Client is very similar to existing bus 21 A driver implementation for an MEI Client is very similar to existing bus
22 based device drivers. The driver registers itself as an MEI CL bus driver through 22 based device drivers. The driver registers itself as an MEI CL bus driver through
23 the mei_cl_driver structure: 23 the mei_cl_driver structure:
24 24
25 struct mei_cl_driver { 25 struct mei_cl_driver {
26 struct device_driver driver; 26 struct device_driver driver;
27 const char *name; 27 const char *name;
28 28
29 const struct mei_cl_device_id *id_table; 29 const struct mei_cl_device_id *id_table;
30 30
31 int (*probe)(struct mei_cl_device *dev, const struct mei_cl_id *id); 31 int (*probe)(struct mei_cl_device *dev, const struct mei_cl_id *id);
32 int (*remove)(struct mei_cl_device *dev); 32 int (*remove)(struct mei_cl_device *dev);
33 }; 33 };
34 34
35 struct mei_cl_id { 35 struct mei_cl_id {
36 char name[MEI_NAME_SIZE]; 36 char name[MEI_NAME_SIZE];
37 kernel_ulong_t driver_info; 37 kernel_ulong_t driver_info;
38 }; 38 };
39 39
40 The mei_cl_id structure allows the driver to bind itself against a device name. 40 The mei_cl_id structure allows the driver to bind itself against a device name.
41 41
42 To actually register a driver on the ME Client bus one must call the mei_cl_add_driver() 42 To actually register a driver on the ME Client bus one must call the mei_cl_add_driver()
43 API. This is typically called at module init time. 43 API. This is typically called at module init time.
44 44
45 Once registered on the ME Client bus, a driver will typically try to do some I/O on 45 Once registered on the ME Client bus, a driver will typically try to do some I/O on
46 this bus and this should be done through the mei_cl_send() and mei_cl_recv() 46 this bus and this should be done through the mei_cl_send() and mei_cl_recv()
47 routines. The latter is synchronous (blocks and sleeps until data shows up). 47 routines. The latter is synchronous (blocks and sleeps until data shows up).
48 In order for drivers to be notified of pending events waiting for them (e.g. 48 In order for drivers to be notified of pending events waiting for them (e.g.
49 an Rx event) they can register an event handler through the 49 an Rx event) they can register an event handler through the
50 mei_cl_register_event_cb() routine. Currently only the MEI_EVENT_RX event 50 mei_cl_register_event_cb() routine. Currently only the MEI_EVENT_RX event
51 will trigger an event handler call and the driver implementation is supposed 51 will trigger an event handler call and the driver implementation is supposed
52 to call mei_recv() from the event handler in order to fetch the pending 52 to call mei_recv() from the event handler in order to fetch the pending
53 received buffers. 53 received buffers.
54 54
55 55
56 Example 56 Example
57 ======= 57 =======
58 As a theoretical example let's pretend the ME comes with a "contact" NFC IP. 58 As a theoretical example let's pretend the ME comes with a "contact" NFC IP.
59 The driver init and exit routines for this device would look like: 59 The driver init and exit routines for this device would look like:
60 60
61 #define CONTACT_DRIVER_NAME "contact" 61 #define CONTACT_DRIVER_NAME "contact"
62 62
63 static struct mei_cl_device_id contact_mei_cl_tbl[] = { 63 static struct mei_cl_device_id contact_mei_cl_tbl[] = {
64 { CONTACT_DRIVER_NAME, }, 64 { CONTACT_DRIVER_NAME, },
65 65
66 /* required last entry */ 66 /* required last entry */
67 { } 67 { }
68 }; 68 };
69 MODULE_DEVICE_TABLE(mei_cl, contact_mei_cl_tbl); 69 MODULE_DEVICE_TABLE(mei_cl, contact_mei_cl_tbl);
70 70
71 static struct mei_cl_driver contact_driver = { 71 static struct mei_cl_driver contact_driver = {
72 .id_table = contact_mei_tbl, 72 .id_table = contact_mei_tbl,
73 .name = CONTACT_DRIVER_NAME, 73 .name = CONTACT_DRIVER_NAME,
74 74
75 .probe = contact_probe, 75 .probe = contact_probe,
76 .remove = contact_remove, 76 .remove = contact_remove,
77 }; 77 };
78 78
79 static int contact_init(void) 79 static int contact_init(void)
80 { 80 {
81 int r; 81 int r;
82 82
83 r = mei_cl_driver_register(&contact_driver); 83 r = mei_cl_driver_register(&contact_driver);
84 if (r) { 84 if (r) {
85 pr_err(CONTACT_DRIVER_NAME ": driver registration failed\n"); 85 pr_err(CONTACT_DRIVER_NAME ": driver registration failed\n");
86 return r; 86 return r;
87 } 87 }
88 88
89 return 0; 89 return 0;
90 } 90 }
91 91
92 static void __exit contact_exit(void) 92 static void __exit contact_exit(void)
93 { 93 {
94 mei_cl_driver_unregister(&contact_driver); 94 mei_cl_driver_unregister(&contact_driver);
95 } 95 }
96 96
97 module_init(contact_init); 97 module_init(contact_init);
98 module_exit(contact_exit); 98 module_exit(contact_exit);
99 99
100 And the driver's simplified probe routine would look like that: 100 And the driver's simplified probe routine would look like that:
101 101
102 int contact_probe(struct mei_cl_device *dev, struct mei_cl_device_id *id) 102 int contact_probe(struct mei_cl_device *dev, struct mei_cl_device_id *id)
103 { 103 {
104 struct contact_driver *contact; 104 struct contact_driver *contact;
105 105
106 [...] 106 [...]
107 mei_cl_enable_device(dev);
108
107 mei_cl_register_event_cb(dev, contact_event_cb, contact); 109 mei_cl_register_event_cb(dev, contact_event_cb, contact);
108 110
109 return 0; 111 return 0;
110 } 112 }
111 113
112 In the probe routine the driver basically registers an ME bus event handler 114 In the probe routine the driver first enable the MEI device and then registers
113 which is as close as it can get to registering a threaded IRQ handler. 115 an ME bus event handler which is as close as it can get to registering a
116 threaded IRQ handler.
114 The handler implementation will typically call some I/O routine depending on 117 The handler implementation will typically call some I/O routine depending on
115 the pending events: 118 the pending events:
116 119
117 #define MAX_NFC_PAYLOAD 128 120 #define MAX_NFC_PAYLOAD 128
118 121
119 static void contact_event_cb(struct mei_cl_device *dev, u32 events, 122 static void contact_event_cb(struct mei_cl_device *dev, u32 events,
120 void *context) 123 void *context)
121 { 124 {
122 struct contact_driver *contact = context; 125 struct contact_driver *contact = context;
123 126
124 if (events & BIT(MEI_EVENT_RX)) { 127 if (events & BIT(MEI_EVENT_RX)) {
125 u8 payload[MAX_NFC_PAYLOAD]; 128 u8 payload[MAX_NFC_PAYLOAD];
126 int payload_size; 129 int payload_size;
127 130
128 payload_size = mei_recv(dev, payload, MAX_NFC_PAYLOAD); 131 payload_size = mei_recv(dev, payload, MAX_NFC_PAYLOAD);
129 if (payload_size <= 0) 132 if (payload_size <= 0)
130 return; 133 return;
131 134
132 /* Hook to the NFC subsystem */ 135 /* Hook to the NFC subsystem */
133 nfc_hci_recv_frame(contact->hdev, payload, payload_size); 136 nfc_hci_recv_frame(contact->hdev, payload, payload_size);
134 } 137 }
135 } 138 }
136 139
drivers/misc/mei/bus.c
1 /* 1 /*
2 * Intel Management Engine Interface (Intel MEI) Linux driver 2 * Intel Management Engine Interface (Intel MEI) Linux driver
3 * Copyright (c) 2012-2013, Intel Corporation. 3 * Copyright (c) 2012-2013, Intel Corporation.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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, 6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation. 7 * version 2, as published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT 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 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details. 12 * more details.
13 * 13 *
14 */ 14 */
15 15
16 #include <linux/module.h> 16 #include <linux/module.h>
17 #include <linux/device.h> 17 #include <linux/device.h>
18 #include <linux/kernel.h> 18 #include <linux/kernel.h>
19 #include <linux/sched.h> 19 #include <linux/sched.h>
20 #include <linux/init.h> 20 #include <linux/init.h>
21 #include <linux/errno.h> 21 #include <linux/errno.h>
22 #include <linux/slab.h> 22 #include <linux/slab.h>
23 #include <linux/mutex.h> 23 #include <linux/mutex.h>
24 #include <linux/interrupt.h> 24 #include <linux/interrupt.h>
25 #include <linux/pci.h> 25 #include <linux/pci.h>
26 #include <linux/mei_cl_bus.h> 26 #include <linux/mei_cl_bus.h>
27 27
28 #include "mei_dev.h" 28 #include "mei_dev.h"
29 #include "hw-me.h" 29 #include "hw-me.h"
30 #include "client.h" 30 #include "client.h"
31 31
32 #define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver) 32 #define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver)
33 #define to_mei_cl_device(d) container_of(d, struct mei_cl_device, dev) 33 #define to_mei_cl_device(d) container_of(d, struct mei_cl_device, dev)
34 34
35 static int mei_cl_device_match(struct device *dev, struct device_driver *drv) 35 static int mei_cl_device_match(struct device *dev, struct device_driver *drv)
36 { 36 {
37 struct mei_cl_device *device = to_mei_cl_device(dev); 37 struct mei_cl_device *device = to_mei_cl_device(dev);
38 struct mei_cl_driver *driver = to_mei_cl_driver(drv); 38 struct mei_cl_driver *driver = to_mei_cl_driver(drv);
39 const struct mei_cl_device_id *id; 39 const struct mei_cl_device_id *id;
40 40
41 if (!device) 41 if (!device)
42 return 0; 42 return 0;
43 43
44 if (!driver || !driver->id_table) 44 if (!driver || !driver->id_table)
45 return 0; 45 return 0;
46 46
47 id = driver->id_table; 47 id = driver->id_table;
48 48
49 while (id->name[0]) { 49 while (id->name[0]) {
50 if (!strcmp(dev_name(dev), id->name)) 50 if (!strcmp(dev_name(dev), id->name))
51 return 1; 51 return 1;
52 52
53 id++; 53 id++;
54 } 54 }
55 55
56 return 0; 56 return 0;
57 } 57 }
58 58
59 static int mei_cl_device_probe(struct device *dev) 59 static int mei_cl_device_probe(struct device *dev)
60 { 60 {
61 struct mei_cl_device *device = to_mei_cl_device(dev); 61 struct mei_cl_device *device = to_mei_cl_device(dev);
62 struct mei_cl_driver *driver; 62 struct mei_cl_driver *driver;
63 struct mei_cl_device_id id; 63 struct mei_cl_device_id id;
64 64
65 if (!device) 65 if (!device)
66 return 0; 66 return 0;
67 67
68 driver = to_mei_cl_driver(dev->driver); 68 driver = to_mei_cl_driver(dev->driver);
69 if (!driver || !driver->probe) 69 if (!driver || !driver->probe)
70 return -ENODEV; 70 return -ENODEV;
71 71
72 dev_dbg(dev, "Device probe\n"); 72 dev_dbg(dev, "Device probe\n");
73 73
74 strncpy(id.name, dev_name(dev), MEI_CL_NAME_SIZE); 74 strncpy(id.name, dev_name(dev), MEI_CL_NAME_SIZE);
75 75
76 return driver->probe(device, &id); 76 return driver->probe(device, &id);
77 } 77 }
78 78
79 static int mei_cl_device_remove(struct device *dev) 79 static int mei_cl_device_remove(struct device *dev)
80 { 80 {
81 struct mei_cl_device *device = to_mei_cl_device(dev); 81 struct mei_cl_device *device = to_mei_cl_device(dev);
82 struct mei_cl_driver *driver; 82 struct mei_cl_driver *driver;
83 83
84 if (!device || !dev->driver) 84 if (!device || !dev->driver)
85 return 0; 85 return 0;
86 86
87 if (device->event_cb) { 87 if (device->event_cb) {
88 device->event_cb = NULL; 88 device->event_cb = NULL;
89 cancel_work_sync(&device->event_work); 89 cancel_work_sync(&device->event_work);
90 } 90 }
91 91
92 driver = to_mei_cl_driver(dev->driver); 92 driver = to_mei_cl_driver(dev->driver);
93 if (!driver->remove) { 93 if (!driver->remove) {
94 dev->driver = NULL; 94 dev->driver = NULL;
95 95
96 return 0; 96 return 0;
97 } 97 }
98 98
99 return driver->remove(device); 99 return driver->remove(device);
100 } 100 }
101 101
102 static ssize_t modalias_show(struct device *dev, struct device_attribute *a, 102 static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
103 char *buf) 103 char *buf)
104 { 104 {
105 int len; 105 int len;
106 106
107 len = snprintf(buf, PAGE_SIZE, "mei:%s\n", dev_name(dev)); 107 len = snprintf(buf, PAGE_SIZE, "mei:%s\n", dev_name(dev));
108 108
109 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; 109 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
110 } 110 }
111 111
112 static struct device_attribute mei_cl_dev_attrs[] = { 112 static struct device_attribute mei_cl_dev_attrs[] = {
113 __ATTR_RO(modalias), 113 __ATTR_RO(modalias),
114 __ATTR_NULL, 114 __ATTR_NULL,
115 }; 115 };
116 116
117 static int mei_cl_uevent(struct device *dev, struct kobj_uevent_env *env) 117 static int mei_cl_uevent(struct device *dev, struct kobj_uevent_env *env)
118 { 118 {
119 if (add_uevent_var(env, "MODALIAS=mei:%s", dev_name(dev))) 119 if (add_uevent_var(env, "MODALIAS=mei:%s", dev_name(dev)))
120 return -ENOMEM; 120 return -ENOMEM;
121 121
122 return 0; 122 return 0;
123 } 123 }
124 124
125 static struct bus_type mei_cl_bus_type = { 125 static struct bus_type mei_cl_bus_type = {
126 .name = "mei", 126 .name = "mei",
127 .dev_attrs = mei_cl_dev_attrs, 127 .dev_attrs = mei_cl_dev_attrs,
128 .match = mei_cl_device_match, 128 .match = mei_cl_device_match,
129 .probe = mei_cl_device_probe, 129 .probe = mei_cl_device_probe,
130 .remove = mei_cl_device_remove, 130 .remove = mei_cl_device_remove,
131 .uevent = mei_cl_uevent, 131 .uevent = mei_cl_uevent,
132 }; 132 };
133 133
134 static void mei_cl_dev_release(struct device *dev) 134 static void mei_cl_dev_release(struct device *dev)
135 { 135 {
136 kfree(to_mei_cl_device(dev)); 136 kfree(to_mei_cl_device(dev));
137 } 137 }
138 138
139 static struct device_type mei_cl_device_type = { 139 static struct device_type mei_cl_device_type = {
140 .release = mei_cl_dev_release, 140 .release = mei_cl_dev_release,
141 }; 141 };
142 142
143 static struct mei_cl *mei_bus_find_mei_cl_by_uuid(struct mei_device *dev, 143 static struct mei_cl *mei_bus_find_mei_cl_by_uuid(struct mei_device *dev,
144 uuid_le uuid) 144 uuid_le uuid)
145 { 145 {
146 struct mei_cl *cl, *next; 146 struct mei_cl *cl, *next;
147 147
148 list_for_each_entry_safe(cl, next, &dev->device_list, device_link) { 148 list_for_each_entry_safe(cl, next, &dev->device_list, device_link) {
149 if (!uuid_le_cmp(uuid, cl->device_uuid)) 149 if (!uuid_le_cmp(uuid, cl->device_uuid))
150 return cl; 150 return cl;
151 } 151 }
152 152
153 return NULL; 153 return NULL;
154 } 154 }
155 struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, 155 struct mei_cl_device *mei_cl_add_device(struct mei_device *dev,
156 uuid_le uuid, char *name) 156 uuid_le uuid, char *name,
157 struct mei_cl_ops *ops)
157 { 158 {
158 struct mei_cl_device *device; 159 struct mei_cl_device *device;
159 struct mei_cl *cl; 160 struct mei_cl *cl;
160 int status; 161 int status;
161 162
162 cl = mei_bus_find_mei_cl_by_uuid(dev, uuid); 163 cl = mei_bus_find_mei_cl_by_uuid(dev, uuid);
163 if (cl == NULL) 164 if (cl == NULL)
164 return NULL; 165 return NULL;
165 166
166 device = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL); 167 device = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL);
167 if (!device) 168 if (!device)
168 return NULL; 169 return NULL;
169 170
170 device->cl = cl; 171 device->cl = cl;
172 device->ops = ops;
171 173
172 device->dev.parent = &dev->pdev->dev; 174 device->dev.parent = &dev->pdev->dev;
173 device->dev.bus = &mei_cl_bus_type; 175 device->dev.bus = &mei_cl_bus_type;
174 device->dev.type = &mei_cl_device_type; 176 device->dev.type = &mei_cl_device_type;
175 177
176 dev_set_name(&device->dev, "%s", name); 178 dev_set_name(&device->dev, "%s", name);
177 179
178 status = device_register(&device->dev); 180 status = device_register(&device->dev);
179 if (status) { 181 if (status) {
180 dev_err(&dev->pdev->dev, "Failed to register MEI device\n"); 182 dev_err(&dev->pdev->dev, "Failed to register MEI device\n");
181 kfree(device); 183 kfree(device);
182 return NULL; 184 return NULL;
183 } 185 }
184 186
185 cl->device = device; 187 cl->device = device;
186 188
187 dev_dbg(&device->dev, "client %s registered\n", name); 189 dev_dbg(&device->dev, "client %s registered\n", name);
188 190
189 return device; 191 return device;
190 } 192 }
191 EXPORT_SYMBOL_GPL(mei_cl_add_device); 193 EXPORT_SYMBOL_GPL(mei_cl_add_device);
192 194
193 void mei_cl_remove_device(struct mei_cl_device *device) 195 void mei_cl_remove_device(struct mei_cl_device *device)
194 { 196 {
195 device_unregister(&device->dev); 197 device_unregister(&device->dev);
196 } 198 }
197 EXPORT_SYMBOL_GPL(mei_cl_remove_device); 199 EXPORT_SYMBOL_GPL(mei_cl_remove_device);
198 200
199 int __mei_cl_driver_register(struct mei_cl_driver *driver, struct module *owner) 201 int __mei_cl_driver_register(struct mei_cl_driver *driver, struct module *owner)
200 { 202 {
201 int err; 203 int err;
202 204
203 driver->driver.name = driver->name; 205 driver->driver.name = driver->name;
204 driver->driver.owner = owner; 206 driver->driver.owner = owner;
205 driver->driver.bus = &mei_cl_bus_type; 207 driver->driver.bus = &mei_cl_bus_type;
206 208
207 err = driver_register(&driver->driver); 209 err = driver_register(&driver->driver);
208 if (err) 210 if (err)
209 return err; 211 return err;
210 212
211 pr_debug("mei: driver [%s] registered\n", driver->driver.name); 213 pr_debug("mei: driver [%s] registered\n", driver->driver.name);
212 214
213 return 0; 215 return 0;
214 } 216 }
215 EXPORT_SYMBOL_GPL(__mei_cl_driver_register); 217 EXPORT_SYMBOL_GPL(__mei_cl_driver_register);
216 218
217 void mei_cl_driver_unregister(struct mei_cl_driver *driver) 219 void mei_cl_driver_unregister(struct mei_cl_driver *driver)
218 { 220 {
219 driver_unregister(&driver->driver); 221 driver_unregister(&driver->driver);
220 222
221 pr_debug("mei: driver [%s] unregistered\n", driver->driver.name); 223 pr_debug("mei: driver [%s] unregistered\n", driver->driver.name);
222 } 224 }
223 EXPORT_SYMBOL_GPL(mei_cl_driver_unregister); 225 EXPORT_SYMBOL_GPL(mei_cl_driver_unregister);
224 226
225 static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, 227 static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
226 bool blocking) 228 bool blocking)
227 { 229 {
228 struct mei_device *dev; 230 struct mei_device *dev;
229 struct mei_cl_cb *cb; 231 struct mei_cl_cb *cb;
230 int id; 232 int id;
231 int rets; 233 int rets;
232 234
233 if (WARN_ON(!cl || !cl->dev)) 235 if (WARN_ON(!cl || !cl->dev))
234 return -ENODEV; 236 return -ENODEV;
235 237
236 dev = cl->dev; 238 dev = cl->dev;
237 239
238 if (cl->state != MEI_FILE_CONNECTED) 240 if (cl->state != MEI_FILE_CONNECTED)
239 return -ENODEV; 241 return -ENODEV;
240 242
241 /* Check if we have an ME client device */ 243 /* Check if we have an ME client device */
242 id = mei_me_cl_by_id(dev, cl->me_client_id); 244 id = mei_me_cl_by_id(dev, cl->me_client_id);
243 if (id < 0) 245 if (id < 0)
244 return -ENODEV; 246 return -ENODEV;
245 247
246 if (length > dev->me_clients[id].props.max_msg_length) 248 if (length > dev->me_clients[id].props.max_msg_length)
247 return -EINVAL; 249 return -EINVAL;
248 250
249 cb = mei_io_cb_init(cl, NULL); 251 cb = mei_io_cb_init(cl, NULL);
250 if (!cb) 252 if (!cb)
251 return -ENOMEM; 253 return -ENOMEM;
252 254
253 rets = mei_io_cb_alloc_req_buf(cb, length); 255 rets = mei_io_cb_alloc_req_buf(cb, length);
254 if (rets < 0) { 256 if (rets < 0) {
255 mei_io_cb_free(cb); 257 mei_io_cb_free(cb);
256 return rets; 258 return rets;
257 } 259 }
258 260
259 memcpy(cb->request_buffer.data, buf, length); 261 memcpy(cb->request_buffer.data, buf, length);
260 262
261 mutex_lock(&dev->device_lock); 263 mutex_lock(&dev->device_lock);
262 264
263 rets = mei_cl_write(cl, cb, blocking); 265 rets = mei_cl_write(cl, cb, blocking);
264 266
265 mutex_unlock(&dev->device_lock); 267 mutex_unlock(&dev->device_lock);
266 if (rets < 0) 268 if (rets < 0)
267 mei_io_cb_free(cb); 269 mei_io_cb_free(cb);
268 270
269 return rets; 271 return rets;
270 } 272 }
271 273
272 int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) 274 int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
273 { 275 {
274 struct mei_device *dev; 276 struct mei_device *dev;
275 struct mei_cl_cb *cb; 277 struct mei_cl_cb *cb;
276 size_t r_length; 278 size_t r_length;
277 int err; 279 int err;
278 280
279 if (WARN_ON(!cl || !cl->dev)) 281 if (WARN_ON(!cl || !cl->dev))
280 return -ENODEV; 282 return -ENODEV;
281 283
282 dev = cl->dev; 284 dev = cl->dev;
283 285
284 mutex_lock(&dev->device_lock); 286 mutex_lock(&dev->device_lock);
285 287
286 if (!cl->read_cb) { 288 if (!cl->read_cb) {
287 err = mei_cl_read_start(cl); 289 err = mei_cl_read_start(cl);
288 if (err < 0) { 290 if (err < 0) {
289 mutex_unlock(&dev->device_lock); 291 mutex_unlock(&dev->device_lock);
290 return err; 292 return err;
291 } 293 }
292 } 294 }
293 295
294 if (cl->reading_state != MEI_READ_COMPLETE && 296 if (cl->reading_state != MEI_READ_COMPLETE &&
295 !waitqueue_active(&cl->rx_wait)) { 297 !waitqueue_active(&cl->rx_wait)) {
296 mutex_unlock(&dev->device_lock); 298 mutex_unlock(&dev->device_lock);
297 299
298 if (wait_event_interruptible(cl->rx_wait, 300 if (wait_event_interruptible(cl->rx_wait,
299 (MEI_READ_COMPLETE == cl->reading_state))) { 301 (MEI_READ_COMPLETE == cl->reading_state))) {
300 if (signal_pending(current)) 302 if (signal_pending(current))
301 return -EINTR; 303 return -EINTR;
302 return -ERESTARTSYS; 304 return -ERESTARTSYS;
303 } 305 }
304 306
305 mutex_lock(&dev->device_lock); 307 mutex_lock(&dev->device_lock);
306 } 308 }
307 309
308 cb = cl->read_cb; 310 cb = cl->read_cb;
309 311
310 if (cl->reading_state != MEI_READ_COMPLETE) { 312 if (cl->reading_state != MEI_READ_COMPLETE) {
311 r_length = 0; 313 r_length = 0;
312 goto out; 314 goto out;
313 } 315 }
314 316
315 r_length = min_t(size_t, length, cb->buf_idx); 317 r_length = min_t(size_t, length, cb->buf_idx);
316 318
317 memcpy(buf, cb->response_buffer.data, r_length); 319 memcpy(buf, cb->response_buffer.data, r_length);
318 320
319 mei_io_cb_free(cb); 321 mei_io_cb_free(cb);
320 cl->reading_state = MEI_IDLE; 322 cl->reading_state = MEI_IDLE;
321 cl->read_cb = NULL; 323 cl->read_cb = NULL;
322 324
323 out: 325 out:
324 mutex_unlock(&dev->device_lock); 326 mutex_unlock(&dev->device_lock);
325 327
326 return r_length; 328 return r_length;
327 } 329 }
328 330
329 inline int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length) 331 inline int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length)
330 { 332 {
331 return ___mei_cl_send(cl, buf, length, 0); 333 return ___mei_cl_send(cl, buf, length, 0);
332 } 334 }
333 335
334 inline int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length) 336 inline int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length)
335 { 337 {
336 return ___mei_cl_send(cl, buf, length, 1); 338 return ___mei_cl_send(cl, buf, length, 1);
337 } 339 }
338 340
339 int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length) 341 int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length)
340 { 342 {
341 struct mei_cl *cl = device->cl; 343 struct mei_cl *cl = device->cl;
342 344
343 if (cl == NULL) 345 if (cl == NULL)
344 return -ENODEV; 346 return -ENODEV;
345 347
346 if (device->ops && device->ops->send) 348 if (device->ops && device->ops->send)
347 return device->ops->send(device, buf, length); 349 return device->ops->send(device, buf, length);
348 350
349 return __mei_cl_send(cl, buf, length); 351 return __mei_cl_send(cl, buf, length);
350 } 352 }
351 EXPORT_SYMBOL_GPL(mei_cl_send); 353 EXPORT_SYMBOL_GPL(mei_cl_send);
352 354
353 int mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length) 355 int mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length)
354 { 356 {
355 struct mei_cl *cl = device->cl; 357 struct mei_cl *cl = device->cl;
356 358
357 if (cl == NULL) 359 if (cl == NULL)
358 return -ENODEV; 360 return -ENODEV;
359 361
360 if (device->ops && device->ops->recv) 362 if (device->ops && device->ops->recv)
361 return device->ops->recv(device, buf, length); 363 return device->ops->recv(device, buf, length);
362 364
363 return __mei_cl_recv(cl, buf, length); 365 return __mei_cl_recv(cl, buf, length);
364 } 366 }
365 EXPORT_SYMBOL_GPL(mei_cl_recv); 367 EXPORT_SYMBOL_GPL(mei_cl_recv);
366 368
367 static void mei_bus_event_work(struct work_struct *work) 369 static void mei_bus_event_work(struct work_struct *work)
368 { 370 {
369 struct mei_cl_device *device; 371 struct mei_cl_device *device;
370 372
371 device = container_of(work, struct mei_cl_device, event_work); 373 device = container_of(work, struct mei_cl_device, event_work);
372 374
373 if (device->event_cb) 375 if (device->event_cb)
374 device->event_cb(device, device->events, device->event_context); 376 device->event_cb(device, device->events, device->event_context);
375 377
376 device->events = 0; 378 device->events = 0;
377 379
378 /* Prepare for the next read */ 380 /* Prepare for the next read */
379 mei_cl_read_start(device->cl); 381 mei_cl_read_start(device->cl);
380 } 382 }
381 383
382 int mei_cl_register_event_cb(struct mei_cl_device *device, 384 int mei_cl_register_event_cb(struct mei_cl_device *device,
383 mei_cl_event_cb_t event_cb, void *context) 385 mei_cl_event_cb_t event_cb, void *context)
384 { 386 {
385 if (device->event_cb) 387 if (device->event_cb)
386 return -EALREADY; 388 return -EALREADY;
387 389
388 device->events = 0; 390 device->events = 0;
389 device->event_cb = event_cb; 391 device->event_cb = event_cb;
390 device->event_context = context; 392 device->event_context = context;
391 INIT_WORK(&device->event_work, mei_bus_event_work); 393 INIT_WORK(&device->event_work, mei_bus_event_work);
392 394
393 mei_cl_read_start(device->cl); 395 mei_cl_read_start(device->cl);
394 396
395 return 0; 397 return 0;
396 } 398 }
397 EXPORT_SYMBOL_GPL(mei_cl_register_event_cb); 399 EXPORT_SYMBOL_GPL(mei_cl_register_event_cb);
398 400
399 void *mei_cl_get_drvdata(const struct mei_cl_device *device) 401 void *mei_cl_get_drvdata(const struct mei_cl_device *device)
400 { 402 {
401 return dev_get_drvdata(&device->dev); 403 return dev_get_drvdata(&device->dev);
402 } 404 }
403 EXPORT_SYMBOL_GPL(mei_cl_get_drvdata); 405 EXPORT_SYMBOL_GPL(mei_cl_get_drvdata);
404 406
405 void mei_cl_set_drvdata(struct mei_cl_device *device, void *data) 407 void mei_cl_set_drvdata(struct mei_cl_device *device, void *data)
406 { 408 {
407 dev_set_drvdata(&device->dev, data); 409 dev_set_drvdata(&device->dev, data);
408 } 410 }
409 EXPORT_SYMBOL_GPL(mei_cl_set_drvdata); 411 EXPORT_SYMBOL_GPL(mei_cl_set_drvdata);
412
413 int mei_cl_enable_device(struct mei_cl_device *device)
414 {
415 int err;
416 struct mei_device *dev;
417 struct mei_cl *cl = device->cl;
418
419 if (cl == NULL)
420 return -ENODEV;
421
422 dev = cl->dev;
423
424 mutex_lock(&dev->device_lock);
425
426 cl->state = MEI_FILE_CONNECTING;
427
428 err = mei_cl_connect(cl, NULL);
429 if (err < 0) {
430 mutex_unlock(&dev->device_lock);
431 dev_err(&dev->pdev->dev, "Could not connect to the ME client");
432
433 return err;
434 }
435
436 mutex_unlock(&dev->device_lock);
437
438 if (device->event_cb && !cl->read_cb)
439 mei_cl_read_start(device->cl);
440
441 if (!device->ops || !device->ops->enable)
442 return 0;
443
444 return device->ops->enable(device);
445 }
446 EXPORT_SYMBOL_GPL(mei_cl_enable_device);
447
448 int mei_cl_disable_device(struct mei_cl_device *device)
449 {
450 int err;
451 struct mei_device *dev;
452 struct mei_cl *cl = device->cl;
453
454 if (cl == NULL)
455 return -ENODEV;
456
457 dev = cl->dev;
458
459 mutex_lock(&dev->device_lock);
460
461 if (cl->state != MEI_FILE_CONNECTED) {
462 mutex_unlock(&dev->device_lock);
463 dev_err(&dev->pdev->dev, "Already disconnected");
464
465 return 0;
466 }
467
468 cl->state = MEI_FILE_DISCONNECTING;
469
470 err = mei_cl_disconnect(cl);
471 if (err < 0) {
472 mutex_unlock(&dev->device_lock);
473 dev_err(&dev->pdev->dev,
474 "Could not disconnect from the ME client");
475
476 return err;
477 }
478
479 /* Flush queues and remove any pending read */
480 mei_cl_flush_queues(cl);
481
482 if (cl->read_cb) {
483 struct mei_cl_cb *cb = NULL;
484
485 cb = mei_cl_find_read_cb(cl);
486 /* Remove entry from read list */
487 if (cb)
488 list_del(&cb->list);
489
490 cb = cl->read_cb;
491 cl->read_cb = NULL;
492
493 if (cb) {
494 mei_io_cb_free(cb);
495 cb = NULL;
496 }
497 }
498
499 mutex_unlock(&dev->device_lock);
500
501 if (!device->ops || !device->ops->disable)
502 return 0;
503
504 return device->ops->disable(device);
505 }
506 EXPORT_SYMBOL_GPL(mei_cl_disable_device);
410 507
411 void mei_cl_bus_rx_event(struct mei_cl *cl) 508 void mei_cl_bus_rx_event(struct mei_cl *cl)
412 { 509 {
413 struct mei_cl_device *device = cl->device; 510 struct mei_cl_device *device = cl->device;
414 511
415 if (!device || !device->event_cb) 512 if (!device || !device->event_cb)
416 return; 513 return;
417 514
418 set_bit(MEI_CL_EVENT_RX, &device->events); 515 set_bit(MEI_CL_EVENT_RX, &device->events);
419 516
420 schedule_work(&device->event_work); 517 schedule_work(&device->event_work);
421 } 518 }
422 519
423 int __init mei_cl_bus_init(void) 520 int __init mei_cl_bus_init(void)
424 { 521 {
425 return bus_register(&mei_cl_bus_type); 522 return bus_register(&mei_cl_bus_type);
426 } 523 }
427 524
428 void __exit mei_cl_bus_exit(void) 525 void __exit mei_cl_bus_exit(void)
429 { 526 {
430 bus_unregister(&mei_cl_bus_type); 527 bus_unregister(&mei_cl_bus_type);
431 } 528 }
432 529
drivers/misc/mei/mei_dev.h
1 /* 1 /*
2 * 2 *
3 * Intel Management Engine Interface (Intel MEI) Linux driver 3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation. 4 * Copyright (c) 2003-2012, Intel Corporation.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 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, 7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation. 8 * version 2, as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT 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 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details. 13 * more details.
14 * 14 *
15 */ 15 */
16 16
17 #ifndef _MEI_DEV_H_ 17 #ifndef _MEI_DEV_H_
18 #define _MEI_DEV_H_ 18 #define _MEI_DEV_H_
19 19
20 #include <linux/types.h> 20 #include <linux/types.h>
21 #include <linux/watchdog.h> 21 #include <linux/watchdog.h>
22 #include <linux/poll.h> 22 #include <linux/poll.h>
23 #include <linux/mei.h> 23 #include <linux/mei.h>
24 #include <linux/mei_cl_bus.h> 24 #include <linux/mei_cl_bus.h>
25 25
26 #include "hw.h" 26 #include "hw.h"
27 #include "hw-me-regs.h" 27 #include "hw-me-regs.h"
28 28
29 /* 29 /*
30 * watch dog definition 30 * watch dog definition
31 */ 31 */
32 #define MEI_WD_HDR_SIZE 4 32 #define MEI_WD_HDR_SIZE 4
33 #define MEI_WD_STOP_MSG_SIZE MEI_WD_HDR_SIZE 33 #define MEI_WD_STOP_MSG_SIZE MEI_WD_HDR_SIZE
34 #define MEI_WD_START_MSG_SIZE (MEI_WD_HDR_SIZE + 16) 34 #define MEI_WD_START_MSG_SIZE (MEI_WD_HDR_SIZE + 16)
35 35
36 #define MEI_WD_DEFAULT_TIMEOUT 120 /* seconds */ 36 #define MEI_WD_DEFAULT_TIMEOUT 120 /* seconds */
37 #define MEI_WD_MIN_TIMEOUT 120 /* seconds */ 37 #define MEI_WD_MIN_TIMEOUT 120 /* seconds */
38 #define MEI_WD_MAX_TIMEOUT 65535 /* seconds */ 38 #define MEI_WD_MAX_TIMEOUT 65535 /* seconds */
39 39
40 #define MEI_WD_STOP_TIMEOUT 10 /* msecs */ 40 #define MEI_WD_STOP_TIMEOUT 10 /* msecs */
41 41
42 #define MEI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0) 42 #define MEI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0)
43 43
44 #define MEI_RD_MSG_BUF_SIZE (128 * sizeof(u32)) 44 #define MEI_RD_MSG_BUF_SIZE (128 * sizeof(u32))
45 45
46 46
47 /* 47 /*
48 * AMTHI Client UUID 48 * AMTHI Client UUID
49 */ 49 */
50 extern const uuid_le mei_amthif_guid; 50 extern const uuid_le mei_amthif_guid;
51 51
52 /* 52 /*
53 * Watchdog Client UUID 53 * Watchdog Client UUID
54 */ 54 */
55 extern const uuid_le mei_wd_guid; 55 extern const uuid_le mei_wd_guid;
56 56
57 /* 57 /*
58 * Watchdog independence state message 58 * Watchdog independence state message
59 */ 59 */
60 extern const u8 mei_wd_state_independence_msg[3][4]; 60 extern const u8 mei_wd_state_independence_msg[3][4];
61 61
62 /* 62 /*
63 * Number of Maximum MEI Clients 63 * Number of Maximum MEI Clients
64 */ 64 */
65 #define MEI_CLIENTS_MAX 256 65 #define MEI_CLIENTS_MAX 256
66 66
67 /* 67 /*
68 * Number of File descriptors/handles 68 * Number of File descriptors/handles
69 * that can be opened to the driver. 69 * that can be opened to the driver.
70 * 70 *
71 * Limit to 255: 256 Total Clients 71 * Limit to 255: 256 Total Clients
72 * minus internal client for MEI Bus Messags 72 * minus internal client for MEI Bus Messags
73 */ 73 */
74 #define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1) 74 #define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1)
75 75
76 /* 76 /*
77 * Internal Clients Number 77 * Internal Clients Number
78 */ 78 */
79 #define MEI_HOST_CLIENT_ID_ANY (-1) 79 #define MEI_HOST_CLIENT_ID_ANY (-1)
80 #define MEI_HBM_HOST_CLIENT_ID 0 /* not used, just for documentation */ 80 #define MEI_HBM_HOST_CLIENT_ID 0 /* not used, just for documentation */
81 #define MEI_WD_HOST_CLIENT_ID 1 81 #define MEI_WD_HOST_CLIENT_ID 1
82 #define MEI_IAMTHIF_HOST_CLIENT_ID 2 82 #define MEI_IAMTHIF_HOST_CLIENT_ID 2
83 83
84 84
85 /* File state */ 85 /* File state */
86 enum file_state { 86 enum file_state {
87 MEI_FILE_INITIALIZING = 0, 87 MEI_FILE_INITIALIZING = 0,
88 MEI_FILE_CONNECTING, 88 MEI_FILE_CONNECTING,
89 MEI_FILE_CONNECTED, 89 MEI_FILE_CONNECTED,
90 MEI_FILE_DISCONNECTING, 90 MEI_FILE_DISCONNECTING,
91 MEI_FILE_DISCONNECTED 91 MEI_FILE_DISCONNECTED
92 }; 92 };
93 93
94 /* MEI device states */ 94 /* MEI device states */
95 enum mei_dev_state { 95 enum mei_dev_state {
96 MEI_DEV_INITIALIZING = 0, 96 MEI_DEV_INITIALIZING = 0,
97 MEI_DEV_INIT_CLIENTS, 97 MEI_DEV_INIT_CLIENTS,
98 MEI_DEV_ENABLED, 98 MEI_DEV_ENABLED,
99 MEI_DEV_RESETING, 99 MEI_DEV_RESETING,
100 MEI_DEV_DISABLED, 100 MEI_DEV_DISABLED,
101 MEI_DEV_POWER_DOWN, 101 MEI_DEV_POWER_DOWN,
102 MEI_DEV_POWER_UP 102 MEI_DEV_POWER_UP
103 }; 103 };
104 104
105 const char *mei_dev_state_str(int state); 105 const char *mei_dev_state_str(int state);
106 106
107 /* init clients states*/ 107 /* init clients states*/
108 enum mei_init_clients_states { 108 enum mei_init_clients_states {
109 MEI_START_MESSAGE = 0, 109 MEI_START_MESSAGE = 0,
110 MEI_ENUM_CLIENTS_MESSAGE, 110 MEI_ENUM_CLIENTS_MESSAGE,
111 MEI_CLIENT_PROPERTIES_MESSAGE 111 MEI_CLIENT_PROPERTIES_MESSAGE
112 }; 112 };
113 113
114 enum iamthif_states { 114 enum iamthif_states {
115 MEI_IAMTHIF_IDLE, 115 MEI_IAMTHIF_IDLE,
116 MEI_IAMTHIF_WRITING, 116 MEI_IAMTHIF_WRITING,
117 MEI_IAMTHIF_FLOW_CONTROL, 117 MEI_IAMTHIF_FLOW_CONTROL,
118 MEI_IAMTHIF_READING, 118 MEI_IAMTHIF_READING,
119 MEI_IAMTHIF_READ_COMPLETE 119 MEI_IAMTHIF_READ_COMPLETE
120 }; 120 };
121 121
122 enum mei_file_transaction_states { 122 enum mei_file_transaction_states {
123 MEI_IDLE, 123 MEI_IDLE,
124 MEI_WRITING, 124 MEI_WRITING,
125 MEI_WRITE_COMPLETE, 125 MEI_WRITE_COMPLETE,
126 MEI_FLOW_CONTROL, 126 MEI_FLOW_CONTROL,
127 MEI_READING, 127 MEI_READING,
128 MEI_READ_COMPLETE 128 MEI_READ_COMPLETE
129 }; 129 };
130 130
131 enum mei_wd_states { 131 enum mei_wd_states {
132 MEI_WD_IDLE, 132 MEI_WD_IDLE,
133 MEI_WD_RUNNING, 133 MEI_WD_RUNNING,
134 MEI_WD_STOPPING, 134 MEI_WD_STOPPING,
135 }; 135 };
136 136
137 /** 137 /**
138 * enum mei_cb_file_ops - file operation associated with the callback 138 * enum mei_cb_file_ops - file operation associated with the callback
139 * @MEI_FOP_READ - read 139 * @MEI_FOP_READ - read
140 * @MEI_FOP_WRITE - write 140 * @MEI_FOP_WRITE - write
141 * @MEI_FOP_IOCTL - ioctl 141 * @MEI_FOP_IOCTL - ioctl
142 * @MEI_FOP_OPEN - open 142 * @MEI_FOP_OPEN - open
143 * @MEI_FOP_CLOSE - close 143 * @MEI_FOP_CLOSE - close
144 */ 144 */
145 enum mei_cb_file_ops { 145 enum mei_cb_file_ops {
146 MEI_FOP_READ = 0, 146 MEI_FOP_READ = 0,
147 MEI_FOP_WRITE, 147 MEI_FOP_WRITE,
148 MEI_FOP_IOCTL, 148 MEI_FOP_IOCTL,
149 MEI_FOP_OPEN, 149 MEI_FOP_OPEN,
150 MEI_FOP_CLOSE 150 MEI_FOP_CLOSE
151 }; 151 };
152 152
153 /* 153 /*
154 * Intel MEI message data struct 154 * Intel MEI message data struct
155 */ 155 */
156 struct mei_msg_data { 156 struct mei_msg_data {
157 u32 size; 157 u32 size;
158 unsigned char *data; 158 unsigned char *data;
159 }; 159 };
160 160
161 /** 161 /**
162 * struct mei_me_client - representation of me (fw) client 162 * struct mei_me_client - representation of me (fw) client
163 * 163 *
164 * @props - client properties 164 * @props - client properties
165 * @client_id - me client id 165 * @client_id - me client id
166 * @mei_flow_ctrl_creds - flow control credits 166 * @mei_flow_ctrl_creds - flow control credits
167 */ 167 */
168 struct mei_me_client { 168 struct mei_me_client {
169 struct mei_client_properties props; 169 struct mei_client_properties props;
170 u8 client_id; 170 u8 client_id;
171 u8 mei_flow_ctrl_creds; 171 u8 mei_flow_ctrl_creds;
172 }; 172 };
173 173
174 174
175 struct mei_cl; 175 struct mei_cl;
176 176
177 /** 177 /**
178 * struct mei_cl_cb - file operation callback structure 178 * struct mei_cl_cb - file operation callback structure
179 * 179 *
180 * @cl - file client who is running this operation 180 * @cl - file client who is running this operation
181 * @fop_type - file operation type 181 * @fop_type - file operation type
182 */ 182 */
183 struct mei_cl_cb { 183 struct mei_cl_cb {
184 struct list_head list; 184 struct list_head list;
185 struct mei_cl *cl; 185 struct mei_cl *cl;
186 enum mei_cb_file_ops fop_type; 186 enum mei_cb_file_ops fop_type;
187 struct mei_msg_data request_buffer; 187 struct mei_msg_data request_buffer;
188 struct mei_msg_data response_buffer; 188 struct mei_msg_data response_buffer;
189 unsigned long buf_idx; 189 unsigned long buf_idx;
190 unsigned long read_time; 190 unsigned long read_time;
191 struct file *file_object; 191 struct file *file_object;
192 }; 192 };
193 193
194 /* MEI client instance carried as file->pirvate_data*/ 194 /* MEI client instance carried as file->pirvate_data*/
195 struct mei_cl { 195 struct mei_cl {
196 struct list_head link; 196 struct list_head link;
197 struct mei_device *dev; 197 struct mei_device *dev;
198 enum file_state state; 198 enum file_state state;
199 wait_queue_head_t tx_wait; 199 wait_queue_head_t tx_wait;
200 wait_queue_head_t rx_wait; 200 wait_queue_head_t rx_wait;
201 wait_queue_head_t wait; 201 wait_queue_head_t wait;
202 int status; 202 int status;
203 /* ID of client connected */ 203 /* ID of client connected */
204 u8 host_client_id; 204 u8 host_client_id;
205 u8 me_client_id; 205 u8 me_client_id;
206 u8 mei_flow_ctrl_creds; 206 u8 mei_flow_ctrl_creds;
207 u8 timer_count; 207 u8 timer_count;
208 enum mei_file_transaction_states reading_state; 208 enum mei_file_transaction_states reading_state;
209 enum mei_file_transaction_states writing_state; 209 enum mei_file_transaction_states writing_state;
210 int sm_state; 210 int sm_state;
211 struct mei_cl_cb *read_cb; 211 struct mei_cl_cb *read_cb;
212 212
213 /* MEI CL bus data */ 213 /* MEI CL bus data */
214 struct mei_cl_device *device; 214 struct mei_cl_device *device;
215 struct list_head device_link; 215 struct list_head device_link;
216 uuid_le device_uuid; 216 uuid_le device_uuid;
217 }; 217 };
218 218
219 /** struct mei_hw_ops 219 /** struct mei_hw_ops
220 * 220 *
221 * @host_is_ready - query for host readiness 221 * @host_is_ready - query for host readiness
222 222
223 * @hw_is_ready - query if hw is ready 223 * @hw_is_ready - query if hw is ready
224 * @hw_reset - reset hw 224 * @hw_reset - reset hw
225 * @hw_start - start hw after reset 225 * @hw_start - start hw after reset
226 * @hw_config - configure hw 226 * @hw_config - configure hw
227 227
228 * @intr_clear - clear pending interrupts 228 * @intr_clear - clear pending interrupts
229 * @intr_enable - enable interrupts 229 * @intr_enable - enable interrupts
230 * @intr_disable - disable interrupts 230 * @intr_disable - disable interrupts
231 231
232 * @hbuf_free_slots - query for write buffer empty slots 232 * @hbuf_free_slots - query for write buffer empty slots
233 * @hbuf_is_ready - query if write buffer is empty 233 * @hbuf_is_ready - query if write buffer is empty
234 * @hbuf_max_len - query for write buffer max len 234 * @hbuf_max_len - query for write buffer max len
235 235
236 * @write - write a message to FW 236 * @write - write a message to FW
237 237
238 * @rdbuf_full_slots - query how many slots are filled 238 * @rdbuf_full_slots - query how many slots are filled
239 239
240 * @read_hdr - get first 4 bytes (header) 240 * @read_hdr - get first 4 bytes (header)
241 * @read - read a buffer from the FW 241 * @read - read a buffer from the FW
242 */ 242 */
243 struct mei_hw_ops { 243 struct mei_hw_ops {
244 244
245 bool (*host_is_ready) (struct mei_device *dev); 245 bool (*host_is_ready) (struct mei_device *dev);
246 246
247 bool (*hw_is_ready) (struct mei_device *dev); 247 bool (*hw_is_ready) (struct mei_device *dev);
248 void (*hw_reset) (struct mei_device *dev, bool enable); 248 void (*hw_reset) (struct mei_device *dev, bool enable);
249 int (*hw_start) (struct mei_device *dev); 249 int (*hw_start) (struct mei_device *dev);
250 void (*hw_config) (struct mei_device *dev); 250 void (*hw_config) (struct mei_device *dev);
251 251
252 void (*intr_clear) (struct mei_device *dev); 252 void (*intr_clear) (struct mei_device *dev);
253 void (*intr_enable) (struct mei_device *dev); 253 void (*intr_enable) (struct mei_device *dev);
254 void (*intr_disable) (struct mei_device *dev); 254 void (*intr_disable) (struct mei_device *dev);
255 255
256 int (*hbuf_free_slots) (struct mei_device *dev); 256 int (*hbuf_free_slots) (struct mei_device *dev);
257 bool (*hbuf_is_ready) (struct mei_device *dev); 257 bool (*hbuf_is_ready) (struct mei_device *dev);
258 size_t (*hbuf_max_len) (const struct mei_device *dev); 258 size_t (*hbuf_max_len) (const struct mei_device *dev);
259 259
260 int (*write)(struct mei_device *dev, 260 int (*write)(struct mei_device *dev,
261 struct mei_msg_hdr *hdr, 261 struct mei_msg_hdr *hdr,
262 unsigned char *buf); 262 unsigned char *buf);
263 263
264 int (*rdbuf_full_slots)(struct mei_device *dev); 264 int (*rdbuf_full_slots)(struct mei_device *dev);
265 265
266 u32 (*read_hdr)(const struct mei_device *dev); 266 u32 (*read_hdr)(const struct mei_device *dev);
267 int (*read) (struct mei_device *dev, 267 int (*read) (struct mei_device *dev,
268 unsigned char *buf, unsigned long len); 268 unsigned char *buf, unsigned long len);
269 }; 269 };
270 270
271 /* MEI bus API*/ 271 /* MEI bus API*/
272 struct mei_cl_device *mei_cl_add_device(struct mei_device *dev,
273 uuid_le uuid, char *name);
274 void mei_cl_remove_device(struct mei_cl_device *device);
275 272
276 int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length);
277 int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length);
278 int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length);
279
280 /** 273 /**
281 * struct mei_cl_transport_ops - MEI CL device transport ops 274 * struct mei_cl_ops - MEI CL device ops
282 * This structure allows ME host clients to implement technology 275 * This structure allows ME host clients to implement technology
283 * specific transport layers. 276 * specific operations.
284 * 277 *
278 * @enable: Enable an MEI CL device. Some devices require specific
279 * HECI commands to initialize completely.
280 * @disable: Disable an MEI CL device.
285 * @send: Tx hook for the device. This allows ME host clients to trap 281 * @send: Tx hook for the device. This allows ME host clients to trap
286 * the device driver buffers before actually physically 282 * the device driver buffers before actually physically
287 * pushing it to the ME. 283 * pushing it to the ME.
288 * @recv: Rx hook for the device. This allows ME host clients to trap the 284 * @recv: Rx hook for the device. This allows ME host clients to trap the
289 * ME buffers before forwarding them to the device driver. 285 * ME buffers before forwarding them to the device driver.
290 */ 286 */
291 struct mei_cl_transport_ops { 287 struct mei_cl_ops {
288 int (*enable)(struct mei_cl_device *device);
289 int (*disable)(struct mei_cl_device *device);
292 int (*send)(struct mei_cl_device *device, u8 *buf, size_t length); 290 int (*send)(struct mei_cl_device *device, u8 *buf, size_t length);
293 int (*recv)(struct mei_cl_device *device, u8 *buf, size_t length); 291 int (*recv)(struct mei_cl_device *device, u8 *buf, size_t length);
294 }; 292 };
295 293
294 struct mei_cl_device *mei_cl_add_device(struct mei_device *dev,
295 uuid_le uuid, char *name,
296 struct mei_cl_ops *ops);
297 void mei_cl_remove_device(struct mei_cl_device *device);
298
299 int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length);
300 int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length);
301 int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length);
296 void mei_cl_bus_rx_event(struct mei_cl *cl); 302 void mei_cl_bus_rx_event(struct mei_cl *cl);
297 int mei_cl_bus_init(void); 303 int mei_cl_bus_init(void);
298 void mei_cl_bus_exit(void); 304 void mei_cl_bus_exit(void);
299 305
300 306
301 /** 307 /**
302 * struct mei_cl_device - MEI device handle 308 * struct mei_cl_device - MEI device handle
303 * An mei_cl_device pointer is returned from mei_add_device() 309 * An mei_cl_device pointer is returned from mei_add_device()
304 * and links MEI bus clients to their actual ME host client pointer. 310 * and links MEI bus clients to their actual ME host client pointer.
305 * Drivers for MEI devices will get an mei_cl_device pointer 311 * Drivers for MEI devices will get an mei_cl_device pointer
306 * when being probed and shall use it for doing ME bus I/O. 312 * when being probed and shall use it for doing ME bus I/O.
307 * 313 *
308 * @dev: linux driver model device pointer 314 * @dev: linux driver model device pointer
309 * @uuid: me client uuid 315 * @uuid: me client uuid
310 * @cl: mei client 316 * @cl: mei client
311 * @ops: ME transport ops 317 * @ops: ME transport ops
312 * @event_cb: Drivers register this callback to get asynchronous ME 318 * @event_cb: Drivers register this callback to get asynchronous ME
313 * events (e.g. Rx buffer pending) notifications. 319 * events (e.g. Rx buffer pending) notifications.
314 * @events: Events bitmask sent to the driver. 320 * @events: Events bitmask sent to the driver.
315 * @priv_data: client private data 321 * @priv_data: client private data
316 */ 322 */
317 struct mei_cl_device { 323 struct mei_cl_device {
318 struct device dev; 324 struct device dev;
319 325
320 struct mei_cl *cl; 326 struct mei_cl *cl;
321 327
322 const struct mei_cl_transport_ops *ops; 328 const struct mei_cl_ops *ops;
323 329
324 struct work_struct event_work; 330 struct work_struct event_work;
325 mei_cl_event_cb_t event_cb; 331 mei_cl_event_cb_t event_cb;
326 void *event_context; 332 void *event_context;
327 unsigned long events; 333 unsigned long events;
328 334
329 void *priv_data; 335 void *priv_data;
330 }; 336 };
331 337
332 /** 338 /**
333 * struct mei_device - MEI private device struct 339 * struct mei_device - MEI private device struct
334 340
335 * @mem_addr - mem mapped base register address 341 * @mem_addr - mem mapped base register address
336 342
337 * @hbuf_depth - depth of hardware host/write buffer is slots 343 * @hbuf_depth - depth of hardware host/write buffer is slots
338 * @hbuf_is_ready - query if the host host/write buffer is ready 344 * @hbuf_is_ready - query if the host host/write buffer is ready
339 * @wr_msg - the buffer for hbm control messages 345 * @wr_msg - the buffer for hbm control messages
340 * @wr_ext_msg - the buffer for hbm control responses (set in read cycle) 346 * @wr_ext_msg - the buffer for hbm control responses (set in read cycle)
341 */ 347 */
342 struct mei_device { 348 struct mei_device {
343 struct pci_dev *pdev; /* pointer to pci device struct */ 349 struct pci_dev *pdev; /* pointer to pci device struct */
344 /* 350 /*
345 * lists of queues 351 * lists of queues
346 */ 352 */
347 /* array of pointers to aio lists */ 353 /* array of pointers to aio lists */
348 struct mei_cl_cb read_list; /* driver read queue */ 354 struct mei_cl_cb read_list; /* driver read queue */
349 struct mei_cl_cb write_list; /* driver write queue */ 355 struct mei_cl_cb write_list; /* driver write queue */
350 struct mei_cl_cb write_waiting_list; /* write waiting queue */ 356 struct mei_cl_cb write_waiting_list; /* write waiting queue */
351 struct mei_cl_cb ctrl_wr_list; /* managed write IOCTL list */ 357 struct mei_cl_cb ctrl_wr_list; /* managed write IOCTL list */
352 struct mei_cl_cb ctrl_rd_list; /* managed read IOCTL list */ 358 struct mei_cl_cb ctrl_rd_list; /* managed read IOCTL list */
353 359
354 /* 360 /*
355 * list of files 361 * list of files
356 */ 362 */
357 struct list_head file_list; 363 struct list_head file_list;
358 long open_handle_count; 364 long open_handle_count;
359 365
360 /* 366 /*
361 * lock for the device 367 * lock for the device
362 */ 368 */
363 struct mutex device_lock; /* device lock */ 369 struct mutex device_lock; /* device lock */
364 struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */ 370 struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */
365 371
366 bool recvd_hw_ready; 372 bool recvd_hw_ready;
367 bool recvd_msg; 373 bool recvd_msg;
368 374
369 /* 375 /*
370 * waiting queue for receive message from FW 376 * waiting queue for receive message from FW
371 */ 377 */
372 wait_queue_head_t wait_hw_ready; 378 wait_queue_head_t wait_hw_ready;
373 wait_queue_head_t wait_recvd_msg; 379 wait_queue_head_t wait_recvd_msg;
374 wait_queue_head_t wait_stop_wd; 380 wait_queue_head_t wait_stop_wd;
375 381
376 /* 382 /*
377 * mei device states 383 * mei device states
378 */ 384 */
379 enum mei_dev_state dev_state; 385 enum mei_dev_state dev_state;
380 enum mei_init_clients_states init_clients_state; 386 enum mei_init_clients_states init_clients_state;
381 u16 init_clients_timer; 387 u16 init_clients_timer;
382 388
383 unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ 389 unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */
384 u32 rd_msg_hdr; 390 u32 rd_msg_hdr;
385 391
386 /* write buffer */ 392 /* write buffer */
387 u8 hbuf_depth; 393 u8 hbuf_depth;
388 bool hbuf_is_ready; 394 bool hbuf_is_ready;
389 395
390 /* used for control messages */ 396 /* used for control messages */
391 struct { 397 struct {
392 struct mei_msg_hdr hdr; 398 struct mei_msg_hdr hdr;
393 unsigned char data[128]; 399 unsigned char data[128];
394 } wr_msg; 400 } wr_msg;
395 401
396 struct { 402 struct {
397 struct mei_msg_hdr hdr; 403 struct mei_msg_hdr hdr;
398 unsigned char data[4]; /* All HBM messages are 4 bytes */ 404 unsigned char data[4]; /* All HBM messages are 4 bytes */
399 } wr_ext_msg; /* for control responses */ 405 } wr_ext_msg; /* for control responses */
400 406
401 struct hbm_version version; 407 struct hbm_version version;
402 408
403 struct mei_me_client *me_clients; /* Note: memory has to be allocated */ 409 struct mei_me_client *me_clients; /* Note: memory has to be allocated */
404 DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); 410 DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX);
405 DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); 411 DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX);
406 u8 me_clients_num; 412 u8 me_clients_num;
407 u8 me_client_presentation_num; 413 u8 me_client_presentation_num;
408 u8 me_client_index; 414 u8 me_client_index;
409 415
410 struct mei_cl wd_cl; 416 struct mei_cl wd_cl;
411 enum mei_wd_states wd_state; 417 enum mei_wd_states wd_state;
412 bool wd_pending; 418 bool wd_pending;
413 u16 wd_timeout; 419 u16 wd_timeout;
414 unsigned char wd_data[MEI_WD_START_MSG_SIZE]; 420 unsigned char wd_data[MEI_WD_START_MSG_SIZE];
415 421
416 422
417 /* amthif list for cmd waiting */ 423 /* amthif list for cmd waiting */
418 struct mei_cl_cb amthif_cmd_list; 424 struct mei_cl_cb amthif_cmd_list;
419 /* driver managed amthif list for reading completed amthif cmd data */ 425 /* driver managed amthif list for reading completed amthif cmd data */
420 struct mei_cl_cb amthif_rd_complete_list; 426 struct mei_cl_cb amthif_rd_complete_list;
421 struct file *iamthif_file_object; 427 struct file *iamthif_file_object;
422 struct mei_cl iamthif_cl; 428 struct mei_cl iamthif_cl;
423 struct mei_cl_cb *iamthif_current_cb; 429 struct mei_cl_cb *iamthif_current_cb;
424 int iamthif_mtu; 430 int iamthif_mtu;
425 unsigned long iamthif_timer; 431 unsigned long iamthif_timer;
426 u32 iamthif_stall_timer; 432 u32 iamthif_stall_timer;
427 unsigned char *iamthif_msg_buf; /* Note: memory has to be allocated */ 433 unsigned char *iamthif_msg_buf; /* Note: memory has to be allocated */
428 u32 iamthif_msg_buf_size; 434 u32 iamthif_msg_buf_size;
429 u32 iamthif_msg_buf_index; 435 u32 iamthif_msg_buf_index;
430 enum iamthif_states iamthif_state; 436 enum iamthif_states iamthif_state;
431 bool iamthif_flow_control_pending; 437 bool iamthif_flow_control_pending;
432 bool iamthif_ioctl; 438 bool iamthif_ioctl;
433 bool iamthif_canceled; 439 bool iamthif_canceled;
434 440
435 struct work_struct init_work; 441 struct work_struct init_work;
436 442
437 /* List of bus devices */ 443 /* List of bus devices */
438 struct list_head device_list; 444 struct list_head device_list;
439 445
440 #if IS_ENABLED(CONFIG_DEBUG_FS) 446 #if IS_ENABLED(CONFIG_DEBUG_FS)
441 struct dentry *dbgfs_dir; 447 struct dentry *dbgfs_dir;
442 #endif /* CONFIG_DEBUG_FS */ 448 #endif /* CONFIG_DEBUG_FS */
443 449
444 450
445 const struct mei_hw_ops *ops; 451 const struct mei_hw_ops *ops;
446 char hw[0] __aligned(sizeof(void *)); 452 char hw[0] __aligned(sizeof(void *));
447 }; 453 };
448 454
449 static inline unsigned long mei_secs_to_jiffies(unsigned long sec) 455 static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
450 { 456 {
451 return msecs_to_jiffies(sec * MSEC_PER_SEC); 457 return msecs_to_jiffies(sec * MSEC_PER_SEC);
452 } 458 }
453 459
454 /** 460 /**
455 * mei_data2slots - get slots - number of (dwords) from a message length 461 * mei_data2slots - get slots - number of (dwords) from a message length
456 * + size of the mei header 462 * + size of the mei header
457 * @length - size of the messages in bytes 463 * @length - size of the messages in bytes
458 * returns - number of slots 464 * returns - number of slots
459 */ 465 */
460 static inline u32 mei_data2slots(size_t length) 466 static inline u32 mei_data2slots(size_t length)
461 { 467 {
462 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4); 468 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
463 } 469 }
464 470
465 /* 471 /*
466 * mei init function prototypes 472 * mei init function prototypes
467 */ 473 */
468 void mei_device_init(struct mei_device *dev); 474 void mei_device_init(struct mei_device *dev);
469 void mei_reset(struct mei_device *dev, int interrupts); 475 void mei_reset(struct mei_device *dev, int interrupts);
470 int mei_start(struct mei_device *dev); 476 int mei_start(struct mei_device *dev);
471 void mei_stop(struct mei_device *dev); 477 void mei_stop(struct mei_device *dev);
472 478
473 /* 479 /*
474 * MEI interrupt functions prototype 480 * MEI interrupt functions prototype
475 */ 481 */
476 482
477 void mei_timer(struct work_struct *work); 483 void mei_timer(struct work_struct *work);
478 int mei_irq_read_handler(struct mei_device *dev, 484 int mei_irq_read_handler(struct mei_device *dev,
479 struct mei_cl_cb *cmpl_list, s32 *slots); 485 struct mei_cl_cb *cmpl_list, s32 *slots);
480 486
481 int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list); 487 int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list);
482 void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list); 488 void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list);
483 489
484 /* 490 /*
485 * AMTHIF - AMT Host Interface Functions 491 * AMTHIF - AMT Host Interface Functions
486 */ 492 */
487 void mei_amthif_reset_params(struct mei_device *dev); 493 void mei_amthif_reset_params(struct mei_device *dev);
488 494
489 int mei_amthif_host_init(struct mei_device *dev); 495 int mei_amthif_host_init(struct mei_device *dev);
490 496
491 int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb); 497 int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb);
492 498
493 int mei_amthif_read(struct mei_device *dev, struct file *file, 499 int mei_amthif_read(struct mei_device *dev, struct file *file,
494 char __user *ubuf, size_t length, loff_t *offset); 500 char __user *ubuf, size_t length, loff_t *offset);
495 501
496 unsigned int mei_amthif_poll(struct mei_device *dev, 502 unsigned int mei_amthif_poll(struct mei_device *dev,
497 struct file *file, poll_table *wait); 503 struct file *file, poll_table *wait);
498 504
499 int mei_amthif_release(struct mei_device *dev, struct file *file); 505 int mei_amthif_release(struct mei_device *dev, struct file *file);
500 506
501 struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, 507 struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
502 struct file *file); 508 struct file *file);
503 509
504 void mei_amthif_run_next_cmd(struct mei_device *dev); 510 void mei_amthif_run_next_cmd(struct mei_device *dev);
505 511
506 512
507 int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, 513 int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
508 struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list); 514 struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list);
509 515
510 void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb); 516 void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb);
511 int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list, 517 int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
512 struct mei_device *dev, struct mei_msg_hdr *mei_hdr); 518 struct mei_device *dev, struct mei_msg_hdr *mei_hdr);
513 int mei_amthif_irq_read(struct mei_device *dev, s32 *slots); 519 int mei_amthif_irq_read(struct mei_device *dev, s32 *slots);
514 520
515 521
516 int mei_wd_send(struct mei_device *dev); 522 int mei_wd_send(struct mei_device *dev);
517 int mei_wd_stop(struct mei_device *dev); 523 int mei_wd_stop(struct mei_device *dev);
518 int mei_wd_host_init(struct mei_device *dev); 524 int mei_wd_host_init(struct mei_device *dev);
519 /* 525 /*
520 * mei_watchdog_register - Registering watchdog interface 526 * mei_watchdog_register - Registering watchdog interface
521 * once we got connection to the WD Client 527 * once we got connection to the WD Client
522 * @dev - mei device 528 * @dev - mei device
523 */ 529 */
524 void mei_watchdog_register(struct mei_device *dev); 530 void mei_watchdog_register(struct mei_device *dev);
525 /* 531 /*
526 * mei_watchdog_unregister - Unregistering watchdog interface 532 * mei_watchdog_unregister - Unregistering watchdog interface
527 * @dev - mei device 533 * @dev - mei device
528 */ 534 */
529 void mei_watchdog_unregister(struct mei_device *dev); 535 void mei_watchdog_unregister(struct mei_device *dev);
530 536
531 /* 537 /*
532 * Register Access Function 538 * Register Access Function
533 */ 539 */
534 540
535 static inline void mei_hw_config(struct mei_device *dev) 541 static inline void mei_hw_config(struct mei_device *dev)
536 { 542 {
537 dev->ops->hw_config(dev); 543 dev->ops->hw_config(dev);
538 } 544 }
539 static inline void mei_hw_reset(struct mei_device *dev, bool enable) 545 static inline void mei_hw_reset(struct mei_device *dev, bool enable)
540 { 546 {
541 dev->ops->hw_reset(dev, enable); 547 dev->ops->hw_reset(dev, enable);
542 } 548 }
543 549
544 static inline void mei_hw_start(struct mei_device *dev) 550 static inline void mei_hw_start(struct mei_device *dev)
545 { 551 {
546 dev->ops->hw_start(dev); 552 dev->ops->hw_start(dev);
547 } 553 }
548 554
549 static inline void mei_clear_interrupts(struct mei_device *dev) 555 static inline void mei_clear_interrupts(struct mei_device *dev)
550 { 556 {
551 dev->ops->intr_clear(dev); 557 dev->ops->intr_clear(dev);
552 } 558 }
553 559
554 static inline void mei_enable_interrupts(struct mei_device *dev) 560 static inline void mei_enable_interrupts(struct mei_device *dev)
555 { 561 {
556 dev->ops->intr_enable(dev); 562 dev->ops->intr_enable(dev);
557 } 563 }
558 564
559 static inline void mei_disable_interrupts(struct mei_device *dev) 565 static inline void mei_disable_interrupts(struct mei_device *dev)
560 { 566 {
561 dev->ops->intr_disable(dev); 567 dev->ops->intr_disable(dev);
562 } 568 }
563 569
564 static inline bool mei_host_is_ready(struct mei_device *dev) 570 static inline bool mei_host_is_ready(struct mei_device *dev)
565 { 571 {
566 return dev->ops->host_is_ready(dev); 572 return dev->ops->host_is_ready(dev);
567 } 573 }
568 static inline bool mei_hw_is_ready(struct mei_device *dev) 574 static inline bool mei_hw_is_ready(struct mei_device *dev)
569 { 575 {
570 return dev->ops->hw_is_ready(dev); 576 return dev->ops->hw_is_ready(dev);
571 } 577 }
572 578
573 static inline bool mei_hbuf_is_ready(struct mei_device *dev) 579 static inline bool mei_hbuf_is_ready(struct mei_device *dev)
574 { 580 {
575 return dev->ops->hbuf_is_ready(dev); 581 return dev->ops->hbuf_is_ready(dev);
576 } 582 }
577 583
578 static inline int mei_hbuf_empty_slots(struct mei_device *dev) 584 static inline int mei_hbuf_empty_slots(struct mei_device *dev)
579 { 585 {
580 return dev->ops->hbuf_free_slots(dev); 586 return dev->ops->hbuf_free_slots(dev);
581 } 587 }
582 588
583 static inline size_t mei_hbuf_max_len(const struct mei_device *dev) 589 static inline size_t mei_hbuf_max_len(const struct mei_device *dev)
584 { 590 {
585 return dev->ops->hbuf_max_len(dev); 591 return dev->ops->hbuf_max_len(dev);
586 } 592 }
587 593
588 static inline int mei_write_message(struct mei_device *dev, 594 static inline int mei_write_message(struct mei_device *dev,
589 struct mei_msg_hdr *hdr, 595 struct mei_msg_hdr *hdr,
590 unsigned char *buf) 596 unsigned char *buf)
591 { 597 {
592 return dev->ops->write(dev, hdr, buf); 598 return dev->ops->write(dev, hdr, buf);
593 } 599 }
594 600
595 static inline u32 mei_read_hdr(const struct mei_device *dev) 601 static inline u32 mei_read_hdr(const struct mei_device *dev)
596 { 602 {
597 return dev->ops->read_hdr(dev); 603 return dev->ops->read_hdr(dev);
598 } 604 }
599 605
600 static inline void mei_read_slots(struct mei_device *dev, 606 static inline void mei_read_slots(struct mei_device *dev,
601 unsigned char *buf, unsigned long len) 607 unsigned char *buf, unsigned long len)
602 { 608 {
603 dev->ops->read(dev, buf, len); 609 dev->ops->read(dev, buf, len);
604 } 610 }
605 611
606 static inline int mei_count_full_read_slots(struct mei_device *dev) 612 static inline int mei_count_full_read_slots(struct mei_device *dev)
607 { 613 {
608 return dev->ops->rdbuf_full_slots(dev); 614 return dev->ops->rdbuf_full_slots(dev);
609 } 615 }
610 616
611 #if IS_ENABLED(CONFIG_DEBUG_FS) 617 #if IS_ENABLED(CONFIG_DEBUG_FS)
612 int mei_dbgfs_register(struct mei_device *dev, const char *name); 618 int mei_dbgfs_register(struct mei_device *dev, const char *name);
613 void mei_dbgfs_deregister(struct mei_device *dev); 619 void mei_dbgfs_deregister(struct mei_device *dev);
614 #else 620 #else
615 static inline int mei_dbgfs_register(struct mei_device *dev, const char *name) 621 static inline int mei_dbgfs_register(struct mei_device *dev, const char *name)
616 { 622 {
617 return 0; 623 return 0;
618 } 624 }
619 static inline void mei_dbgfs_deregister(struct mei_device *dev) {} 625 static inline void mei_dbgfs_deregister(struct mei_device *dev) {}
620 #endif /* CONFIG_DEBUG_FS */ 626 #endif /* CONFIG_DEBUG_FS */
621 627
622 int mei_register(struct mei_device *dev); 628 int mei_register(struct mei_device *dev);
623 void mei_deregister(struct mei_device *dev); 629 void mei_deregister(struct mei_device *dev);
624 630
include/linux/mei_cl_bus.h
1 #ifndef _LINUX_MEI_CL_BUS_H 1 #ifndef _LINUX_MEI_CL_BUS_H
2 #define _LINUX_MEI_CL_BUS_H 2 #define _LINUX_MEI_CL_BUS_H
3 3
4 #include <linux/device.h> 4 #include <linux/device.h>
5 #include <linux/uuid.h> 5 #include <linux/uuid.h>
6 6
7 struct mei_cl_device; 7 struct mei_cl_device;
8 8
9 struct mei_cl_driver { 9 struct mei_cl_driver {
10 struct device_driver driver; 10 struct device_driver driver;
11 const char *name; 11 const char *name;
12 12
13 const struct mei_cl_device_id *id_table; 13 const struct mei_cl_device_id *id_table;
14 14
15 int (*probe)(struct mei_cl_device *dev, 15 int (*probe)(struct mei_cl_device *dev,
16 const struct mei_cl_device_id *id); 16 const struct mei_cl_device_id *id);
17 int (*remove)(struct mei_cl_device *dev); 17 int (*remove)(struct mei_cl_device *dev);
18 }; 18 };
19 19
20 int __mei_cl_driver_register(struct mei_cl_driver *driver, 20 int __mei_cl_driver_register(struct mei_cl_driver *driver,
21 struct module *owner); 21 struct module *owner);
22 #define mei_cl_driver_register(driver) \ 22 #define mei_cl_driver_register(driver) \
23 __mei_cl_driver_register(driver, THIS_MODULE) 23 __mei_cl_driver_register(driver, THIS_MODULE)
24 24
25 void mei_cl_driver_unregister(struct mei_cl_driver *driver); 25 void mei_cl_driver_unregister(struct mei_cl_driver *driver);
26 26
27 int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length); 27 int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length);
28 int mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length); 28 int mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length);
29 29
30 typedef void (*mei_cl_event_cb_t)(struct mei_cl_device *device, 30 typedef void (*mei_cl_event_cb_t)(struct mei_cl_device *device,
31 u32 events, void *context); 31 u32 events, void *context);
32 int mei_cl_register_event_cb(struct mei_cl_device *device, 32 int mei_cl_register_event_cb(struct mei_cl_device *device,
33 mei_cl_event_cb_t read_cb, void *context); 33 mei_cl_event_cb_t read_cb, void *context);
34 34
35 #define MEI_CL_EVENT_RX 0 35 #define MEI_CL_EVENT_RX 0
36 #define MEI_CL_EVENT_TX 1 36 #define MEI_CL_EVENT_TX 1
37 37
38 void *mei_cl_get_drvdata(const struct mei_cl_device *device); 38 void *mei_cl_get_drvdata(const struct mei_cl_device *device);
39 void mei_cl_set_drvdata(struct mei_cl_device *device, void *data); 39 void mei_cl_set_drvdata(struct mei_cl_device *device, void *data);
40 40
41 int mei_cl_enable_device(struct mei_cl_device *device);
42 int mei_cl_disable_device(struct mei_cl_device *device);
43
41 #endif /* _LINUX_MEI_CL_BUS_H */ 44 #endif /* _LINUX_MEI_CL_BUS_H */
42 45