mei: add a vtag map for each client
[linux-2.6-block.git] / drivers / misc / mei / main.c
CommitLineData
9fff0425 1// SPDX-License-Identifier: GPL-2.0
ab841160 2/*
b4a6700c 3 * Copyright (c) 2003-2020, Intel Corporation. All rights reserved.
ab841160 4 * Intel Management Engine Interface (Intel MEI) Linux driver
ab841160 5 */
9fff0425 6
ab841160
OW
7#include <linux/module.h>
8#include <linux/moduleparam.h>
9#include <linux/kernel.h>
10#include <linux/device.h>
1f180359 11#include <linux/slab.h>
ab841160
OW
12#include <linux/fs.h>
13#include <linux/errno.h>
14#include <linux/types.h>
15#include <linux/fcntl.h>
ab841160
OW
16#include <linux/poll.h>
17#include <linux/init.h>
18#include <linux/ioctl.h>
19#include <linux/cdev.h>
174cd4b1 20#include <linux/sched/signal.h>
ab841160
OW
21#include <linux/uuid.h>
22#include <linux/compat.h>
23#include <linux/jiffies.h>
24#include <linux/interrupt.h>
25
4f3afe1d 26#include <linux/mei.h>
47a73801
TW
27
28#include "mei_dev.h"
90e0b5f1 29#include "client.h"
ab841160 30
43b8a7ed
AU
31static struct class *mei_class;
32static dev_t mei_devt;
33#define MEI_MAX_DEVS MINORMASK
34static DEFINE_MUTEX(mei_minor_lock);
35static DEFINE_IDR(mei_idr);
36
ab841160
OW
37/**
38 * mei_open - the open function
39 *
40 * @inode: pointer to inode structure
41 * @file: pointer to file structure
83ce0741 42 *
a8605ea2 43 * Return: 0 on success, <0 on error
ab841160
OW
44 */
45static int mei_open(struct inode *inode, struct file *file)
46{
ab841160 47 struct mei_device *dev;
f3d8e878 48 struct mei_cl *cl;
2703d4b2 49
6f37aca8 50 int err;
ab841160 51
f3d8e878 52 dev = container_of(inode->i_cdev, struct mei_device, cdev);
5b881e3c 53 if (!dev)
e036cc57 54 return -ENODEV;
ab841160
OW
55
56 mutex_lock(&dev->device_lock);
e036cc57 57
b210d750 58 if (dev->dev_state != MEI_DEV_ENABLED) {
2bf94cab 59 dev_dbg(dev->dev, "dev_state != MEI_ENABLED dev_state = %s\n",
b210d750 60 mei_dev_state_str(dev->dev_state));
03b8d341 61 err = -ENODEV;
e036cc57 62 goto err_unlock;
1b812947 63 }
ab841160 64
7851e008 65 cl = mei_cl_alloc_linked(dev);
03b8d341
TW
66 if (IS_ERR(cl)) {
67 err = PTR_ERR(cl);
e036cc57 68 goto err_unlock;
03b8d341 69 }
ab841160 70
97d549b4 71 cl->fp = file;
ab841160 72 file->private_data = cl;
e036cc57 73
ab841160
OW
74 mutex_unlock(&dev->device_lock);
75
5b881e3c 76 return nonseekable_open(inode, file);
ab841160 77
e036cc57 78err_unlock:
ab841160 79 mutex_unlock(&dev->device_lock);
ab841160
OW
80 return err;
81}
82
f35fe5f4
AU
83/**
84 * mei_cl_vtag_remove_by_fp - remove vtag that corresponds to fp from list
85 *
86 * @cl: host client
87 * @fp: pointer to file structure
88 *
89 */
90static void mei_cl_vtag_remove_by_fp(const struct mei_cl *cl,
91 const struct file *fp)
92{
93 struct mei_cl_vtag *vtag_l, *next;
94
95 list_for_each_entry_safe(vtag_l, next, &cl->vtag_map, list) {
96 if (vtag_l->fp == fp) {
97 list_del(&vtag_l->list);
98 kfree(vtag_l);
99 return;
100 }
101 }
102}
103
ab841160
OW
104/**
105 * mei_release - the release function
106 *
107 * @inode: pointer to inode structure
108 * @file: pointer to file structure
109 *
a8605ea2 110 * Return: 0 on success, <0 on error
ab841160
OW
111 */
112static int mei_release(struct inode *inode, struct file *file)
113{
114 struct mei_cl *cl = file->private_data;
ab841160 115 struct mei_device *dev;
3c666182 116 int rets;
ab841160
OW
117
118 if (WARN_ON(!cl || !cl->dev))
119 return -ENODEV;
120
121 dev = cl->dev;
122
123 mutex_lock(&dev->device_lock);
394a77d0 124
f35fe5f4
AU
125 mei_cl_vtag_remove_by_fp(cl, file);
126
127 if (!list_empty(&cl->vtag_map)) {
128 cl_dbg(dev, cl, "not the last vtag\n");
129 mei_cl_flush_queues(cl, file);
130 rets = 0;
131 goto out;
132 }
133
3c666182 134 rets = mei_cl_disconnect(cl);
f35fe5f4
AU
135 /*
136 * Check again: This is necessary since disconnect releases the lock
137 * and another client can connect in the meantime.
138 */
139 if (!list_empty(&cl->vtag_map)) {
140 cl_dbg(dev, cl, "not the last vtag after disconnect\n");
141 mei_cl_flush_queues(cl, file);
142 goto out;
143 }
3c666182 144
f35fe5f4 145 mei_cl_flush_queues(cl, NULL);
46922186 146 cl_dbg(dev, cl, "removing\n");
a562d5c2 147
90e0b5f1 148 mei_cl_unlink(cl);
f35fe5f4 149 kfree(cl);
a562d5c2 150
f35fe5f4 151out:
a562d5c2 152 file->private_data = NULL;
ab841160 153
ab841160
OW
154 mutex_unlock(&dev->device_lock);
155 return rets;
156}
157
158
159/**
160 * mei_read - the read function.
161 *
162 * @file: pointer to file structure
163 * @ubuf: pointer to user buffer
164 * @length: buffer length
165 * @offset: data offset in buffer
166 *
a8605ea2 167 * Return: >=0 data length on success , <0 on error
ab841160
OW
168 */
169static ssize_t mei_read(struct file *file, char __user *ubuf,
441ab50f 170 size_t length, loff_t *offset)
ab841160
OW
171{
172 struct mei_cl *cl = file->private_data;
ab841160 173 struct mei_device *dev;
a9bed610 174 struct mei_cl_cb *cb = NULL;
ff1586a7 175 bool nonblock = !!(file->f_flags & O_NONBLOCK);
5151e2b5 176 ssize_t rets;
ab841160
OW
177
178 if (WARN_ON(!cl || !cl->dev))
179 return -ENODEV;
180
181 dev = cl->dev;
182
dd5de1f1 183
ab841160 184 mutex_lock(&dev->device_lock);
b210d750 185 if (dev->dev_state != MEI_DEV_ENABLED) {
ab841160
OW
186 rets = -ENODEV;
187 goto out;
188 }
189
dd5de1f1
TW
190 if (length == 0) {
191 rets = 0;
192 goto out;
193 }
194
8b2458f4
AU
195 if (ubuf == NULL) {
196 rets = -EMSGSIZE;
197 goto out;
198 }
199
a9bed610 200 cb = mei_cl_read_cb(cl, file);
8b2458f4
AU
201 if (cb)
202 goto copy_buffer;
203
204 if (*offset > 0)
ab841160 205 *offset = 0;
ab841160 206
ff1586a7
AU
207 rets = mei_cl_read_start(cl, length, file);
208 if (rets && rets != -EBUSY) {
5151e2b5 209 cl_dbg(dev, cl, "mei start read failure status = %zd\n", rets);
ab841160
OW
210 goto out;
211 }
212
ff1586a7
AU
213 if (nonblock) {
214 rets = -EAGAIN;
215 goto out;
216 }
217
cb97fbbc
AU
218 mutex_unlock(&dev->device_lock);
219 if (wait_event_interruptible(cl->rx_wait,
d1376f3d 220 mei_cl_read_cb(cl, file) ||
cb97fbbc
AU
221 !mei_cl_is_connected(cl))) {
222 if (signal_pending(current))
223 return -EINTR;
224 return -ERESTARTSYS;
225 }
226 mutex_lock(&dev->device_lock);
e2b31644 227
cb97fbbc
AU
228 if (!mei_cl_is_connected(cl)) {
229 rets = -ENODEV;
230 goto out;
231 }
ab841160 232
cb97fbbc
AU
233 cb = mei_cl_read_cb(cl, file);
234 if (!cb) {
cb97fbbc
AU
235 rets = 0;
236 goto out;
237 }
3d33ff24 238
ab841160 239copy_buffer:
3d33ff24
TW
240 /* now copy the data to user space */
241 if (cb->status) {
242 rets = cb->status;
5151e2b5 243 cl_dbg(dev, cl, "read operation failed %zd\n", rets);
3d33ff24
TW
244 goto free;
245 }
246
35bf7692 247 cl_dbg(dev, cl, "buf.size = %zu buf.idx = %zu offset = %lld\n",
8b2458f4
AU
248 cb->buf.size, cb->buf_idx, *offset);
249 if (*offset >= cb->buf_idx) {
250 rets = 0;
ab841160
OW
251 goto free;
252 }
253
ebb108ef
TW
254 /* length is being truncated to PAGE_SIZE,
255 * however buf_idx may point beyond that */
256 length = min_t(size_t, length, cb->buf_idx - *offset);
ab841160 257
5db7514d 258 if (copy_to_user(ubuf, cb->buf.data + *offset, length)) {
2bf94cab 259 dev_dbg(dev->dev, "failed to copy data to userland\n");
ab841160
OW
260 rets = -EFAULT;
261 goto free;
262 }
263
264 rets = length;
265 *offset += length;
f862b6b2
TW
266 /* not all data was read, keep the cb */
267 if (*offset < cb->buf_idx)
ab841160
OW
268 goto out;
269
270free:
d1376f3d 271 mei_cl_del_rd_completed(cl, cb);
8b2458f4 272 *offset = 0;
928fa666 273
ab841160 274out:
5151e2b5 275 cl_dbg(dev, cl, "end mei read rets = %zd\n", rets);
ab841160
OW
276 mutex_unlock(&dev->device_lock);
277 return rets;
278}
f35fe5f4
AU
279
280/**
281 * mei_cl_vtag_by_fp - obtain the vtag by file pointer
282 *
283 * @cl: host client
284 * @fp: pointer to file structure
285 *
286 * Return: vtag value on success, otherwise 0
287 */
288static u8 mei_cl_vtag_by_fp(const struct mei_cl *cl, const struct file *fp)
289{
290 struct mei_cl_vtag *cl_vtag;
291
292 if (!fp)
293 return 0;
294
295 list_for_each_entry(cl_vtag, &cl->vtag_map, list)
296 if (cl_vtag->fp == fp)
297 return cl_vtag->vtag;
298 return 0;
299}
300
ab841160
OW
301/**
302 * mei_write - the write function.
303 *
304 * @file: pointer to file structure
305 * @ubuf: pointer to user buffer
306 * @length: buffer length
307 * @offset: data offset in buffer
308 *
a8605ea2 309 * Return: >=0 data length on success , <0 on error
ab841160
OW
310 */
311static ssize_t mei_write(struct file *file, const char __user *ubuf,
441ab50f 312 size_t length, loff_t *offset)
ab841160
OW
313{
314 struct mei_cl *cl = file->private_data;
6cbb097f 315 struct mei_cl_cb *cb;
ab841160 316 struct mei_device *dev;
5151e2b5 317 ssize_t rets;
ab841160
OW
318
319 if (WARN_ON(!cl || !cl->dev))
320 return -ENODEV;
321
322 dev = cl->dev;
323
324 mutex_lock(&dev->device_lock);
325
b210d750 326 if (dev->dev_state != MEI_DEV_ENABLED) {
75f0ee15 327 rets = -ENODEV;
4234a6de 328 goto out;
ab841160
OW
329 }
330
d49ed64a
AU
331 if (!mei_cl_is_connected(cl)) {
332 cl_err(dev, cl, "is not connected");
333 rets = -ENODEV;
4234a6de 334 goto out;
75f0ee15 335 }
dd5de1f1 336
d49ed64a
AU
337 if (!mei_me_cl_is_active(cl->me_cl)) {
338 rets = -ENOTTY;
dd5de1f1
TW
339 goto out;
340 }
341
d49ed64a 342 if (length > mei_cl_mtu(cl)) {
dd5de1f1 343 rets = -EFBIG;
4234a6de 344 goto out;
75f0ee15
TW
345 }
346
d49ed64a
AU
347 if (length == 0) {
348 rets = 0;
4234a6de 349 goto out;
75f0ee15 350 }
d49ed64a 351
af336cab
AU
352 while (cl->tx_cb_queued >= dev->tx_queue_limit) {
353 if (file->f_flags & O_NONBLOCK) {
354 rets = -EAGAIN;
355 goto out;
356 }
357 mutex_unlock(&dev->device_lock);
358 rets = wait_event_interruptible(cl->tx_wait,
359 cl->writing_state == MEI_WRITE_COMPLETE ||
360 (!mei_cl_is_connected(cl)));
361 mutex_lock(&dev->device_lock);
362 if (rets) {
363 if (signal_pending(current))
364 rets = -EINTR;
365 goto out;
366 }
367 if (!mei_cl_is_connected(cl)) {
368 rets = -ENODEV;
369 goto out;
370 }
371 }
372
6cbb097f
AU
373 cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, file);
374 if (!cb) {
33d28c92 375 rets = -ENOMEM;
4234a6de 376 goto out;
ab841160 377 }
f35fe5f4 378 cb->vtag = mei_cl_vtag_by_fp(cl, file);
ab841160 379
6cbb097f 380 rets = copy_from_user(cb->buf.data, ubuf, length);
d8b29efa 381 if (rets) {
2bf94cab 382 dev_dbg(dev->dev, "failed to copy data from userland\n");
d8b29efa 383 rets = -EFAULT;
6cbb097f 384 mei_io_cb_free(cb);
4234a6de 385 goto out;
d8b29efa 386 }
ab841160 387
e0cb6b2f 388 rets = mei_cl_write(cl, cb);
b0d0cf77 389out:
ab841160 390 mutex_unlock(&dev->device_lock);
ab841160
OW
391 return rets;
392}
393
9f81abda
TW
394/**
395 * mei_ioctl_connect_client - the connect to fw client IOCTL function
396 *
9f81abda 397 * @file: private data of the file object
a8605ea2 398 * @data: IOCTL connect data, input and output parameters
9f81abda
TW
399 *
400 * Locking: called under "dev->device_lock" lock
401 *
a8605ea2 402 * Return: 0 on success, <0 on failure.
9f81abda
TW
403 */
404static int mei_ioctl_connect_client(struct file *file,
405 struct mei_connect_client_data *data)
406{
407 struct mei_device *dev;
408 struct mei_client *client;
d320832f 409 struct mei_me_client *me_cl;
9f81abda 410 struct mei_cl *cl;
9f81abda
TW
411 int rets;
412
413 cl = file->private_data;
9f81abda
TW
414 dev = cl->dev;
415
79563db9
TW
416 if (dev->dev_state != MEI_DEV_ENABLED)
417 return -ENODEV;
9f81abda
TW
418
419 if (cl->state != MEI_FILE_INITIALIZING &&
79563db9
TW
420 cl->state != MEI_FILE_DISCONNECTED)
421 return -EBUSY;
9f81abda
TW
422
423 /* find ME client we're trying to connect to */
d320832f 424 me_cl = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
f4e06246 425 if (!me_cl) {
2bf94cab 426 dev_dbg(dev->dev, "Cannot connect to FW Client UUID = %pUl\n",
d49ed64a 427 &data->in_client_uuid);
f4e06246
AU
428 rets = -ENOTTY;
429 goto end;
430 }
431
432 if (me_cl->props.fixed_address) {
433 bool forbidden = dev->override_fixed_address ?
434 !dev->allow_fixed_address : !dev->hbm_f_fa_supported;
435 if (forbidden) {
436 dev_dbg(dev->dev, "Connection forbidden to FW Client UUID = %pUl\n",
437 &data->in_client_uuid);
438 rets = -ENOTTY;
439 goto end;
440 }
9f81abda
TW
441 }
442
2bf94cab 443 dev_dbg(dev->dev, "Connect to FW Client ID = %d\n",
d49ed64a 444 me_cl->client_id);
2bf94cab 445 dev_dbg(dev->dev, "FW Client - Protocol Version = %d\n",
d320832f 446 me_cl->props.protocol_version);
2bf94cab 447 dev_dbg(dev->dev, "FW Client - Max Msg Len = %d\n",
d320832f 448 me_cl->props.max_msg_length);
9f81abda 449
9f81abda
TW
450 /* prepare the output buffer */
451 client = &data->out_client_properties;
d320832f
TW
452 client->max_msg_length = me_cl->props.max_msg_length;
453 client->protocol_version = me_cl->props.protocol_version;
2bf94cab 454 dev_dbg(dev->dev, "Can connect?\n");
9f81abda 455
d49ed64a 456 rets = mei_cl_connect(cl, me_cl, file);
9f81abda
TW
457
458end:
79563db9 459 mei_me_cl_put(me_cl);
9f81abda
TW
460 return rets;
461}
462
3c7c8468
TW
463/**
464 * mei_ioctl_client_notify_request -
465 * propagate event notification request to client
466 *
467 * @file: pointer to file structure
468 * @request: 0 - disable, 1 - enable
469 *
470 * Return: 0 on success , <0 on error
471 */
f23e2cc4 472static int mei_ioctl_client_notify_request(const struct file *file, u32 request)
3c7c8468
TW
473{
474 struct mei_cl *cl = file->private_data;
475
7326fffb
AU
476 if (request != MEI_HBM_NOTIFICATION_START &&
477 request != MEI_HBM_NOTIFICATION_STOP)
478 return -EINVAL;
479
480 return mei_cl_notify_request(cl, file, (u8)request);
3c7c8468
TW
481}
482
483/**
484 * mei_ioctl_client_notify_get - wait for notification request
485 *
486 * @file: pointer to file structure
487 * @notify_get: 0 - disable, 1 - enable
488 *
489 * Return: 0 on success , <0 on error
490 */
f23e2cc4 491static int mei_ioctl_client_notify_get(const struct file *file, u32 *notify_get)
3c7c8468
TW
492{
493 struct mei_cl *cl = file->private_data;
494 bool notify_ev;
495 bool block = (file->f_flags & O_NONBLOCK) == 0;
496 int rets;
497
498 rets = mei_cl_notify_get(cl, block, &notify_ev);
499 if (rets)
500 return rets;
501
502 *notify_get = notify_ev ? 1 : 0;
503 return 0;
504}
505
ab841160
OW
506/**
507 * mei_ioctl - the IOCTL function
508 *
509 * @file: pointer to file structure
510 * @cmd: ioctl command
511 * @data: pointer to mei message structure
512 *
a8605ea2 513 * Return: 0 on success , <0 on error
ab841160
OW
514 */
515static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
516{
517 struct mei_device *dev;
518 struct mei_cl *cl = file->private_data;
154eb18f 519 struct mei_connect_client_data connect_data;
3c7c8468 520 u32 notify_get, notify_req;
ab841160
OW
521 int rets;
522
ab841160
OW
523
524 if (WARN_ON(!cl || !cl->dev))
525 return -ENODEV;
526
527 dev = cl->dev;
528
2bf94cab 529 dev_dbg(dev->dev, "IOCTL cmd = 0x%x", cmd);
ab841160
OW
530
531 mutex_lock(&dev->device_lock);
b210d750 532 if (dev->dev_state != MEI_DEV_ENABLED) {
ab841160
OW
533 rets = -ENODEV;
534 goto out;
535 }
536
4f046e7b
TW
537 switch (cmd) {
538 case IOCTL_MEI_CONNECT_CLIENT:
2bf94cab 539 dev_dbg(dev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n");
154eb18f 540 if (copy_from_user(&connect_data, (char __user *)data,
b4a6700c 541 sizeof(connect_data))) {
2bf94cab 542 dev_dbg(dev->dev, "failed to copy data from userland\n");
4f046e7b
TW
543 rets = -EFAULT;
544 goto out;
545 }
ab841160 546
154eb18f 547 rets = mei_ioctl_connect_client(file, &connect_data);
4f046e7b
TW
548 if (rets)
549 goto out;
ab841160 550
4f046e7b 551 /* if all is ok, copying the data back to user. */
154eb18f 552 if (copy_to_user((char __user *)data, &connect_data,
b4a6700c 553 sizeof(connect_data))) {
2bf94cab 554 dev_dbg(dev->dev, "failed to copy data to userland\n");
4f046e7b
TW
555 rets = -EFAULT;
556 goto out;
557 }
558
559 break;
154eb18f 560
3c7c8468
TW
561 case IOCTL_MEI_NOTIFY_SET:
562 dev_dbg(dev->dev, ": IOCTL_MEI_NOTIFY_SET.\n");
563 if (copy_from_user(&notify_req,
564 (char __user *)data, sizeof(notify_req))) {
565 dev_dbg(dev->dev, "failed to copy data from userland\n");
566 rets = -EFAULT;
567 goto out;
568 }
569 rets = mei_ioctl_client_notify_request(file, notify_req);
570 break;
571
572 case IOCTL_MEI_NOTIFY_GET:
573 dev_dbg(dev->dev, ": IOCTL_MEI_NOTIFY_GET.\n");
574 rets = mei_ioctl_client_notify_get(file, &notify_get);
575 if (rets)
576 goto out;
577
578 dev_dbg(dev->dev, "copy connect data to user\n");
579 if (copy_to_user((char __user *)data,
580 &notify_get, sizeof(notify_get))) {
581 dev_dbg(dev->dev, "failed to copy data to userland\n");
582 rets = -EFAULT;
583 goto out;
584
585 }
586 break;
587
4f046e7b 588 default:
4f046e7b 589 rets = -ENOIOCTLCMD;
ab841160
OW
590 }
591
592out:
ab841160
OW
593 mutex_unlock(&dev->device_lock);
594 return rets;
595}
596
ab841160
OW
597/**
598 * mei_poll - the poll function
599 *
600 * @file: pointer to file structure
601 * @wait: pointer to poll_table structure
602 *
a8605ea2 603 * Return: poll mask
ab841160 604 */
afc9a42b 605static __poll_t mei_poll(struct file *file, poll_table *wait)
ab841160 606{
01699437 607 __poll_t req_events = poll_requested_events(wait);
ab841160
OW
608 struct mei_cl *cl = file->private_data;
609 struct mei_device *dev;
afc9a42b 610 __poll_t mask = 0;
2c84c297 611 bool notify_en;
ab841160
OW
612
613 if (WARN_ON(!cl || !cl->dev))
a9a08845 614 return EPOLLERR;
ab841160
OW
615
616 dev = cl->dev;
617
618 mutex_lock(&dev->device_lock);
619
a9a08845 620 notify_en = cl->notify_en && (req_events & EPOLLPRI);
f3de9b63
TW
621
622 if (dev->dev_state != MEI_DEV_ENABLED ||
623 !mei_cl_is_connected(cl)) {
a9a08845 624 mask = EPOLLERR;
ab841160
OW
625 goto out;
626 }
627
2c84c297
TW
628 if (notify_en) {
629 poll_wait(file, &cl->ev_wait, wait);
630 if (cl->notify_ev)
a9a08845 631 mask |= EPOLLPRI;
2c84c297 632 }
9fa0be8b 633
a9a08845 634 if (req_events & (EPOLLIN | EPOLLRDNORM)) {
1d9013f0
TW
635 poll_wait(file, &cl->rx_wait, wait);
636
d1376f3d 637 if (mei_cl_read_cb(cl, file))
a9a08845 638 mask |= EPOLLIN | EPOLLRDNORM;
1d9013f0 639 else
3030dc05 640 mei_cl_read_start(cl, mei_cl_mtu(cl), file);
1d9013f0 641 }
ab841160 642
03b2cbb6 643 if (req_events & (EPOLLOUT | EPOLLWRNORM)) {
af336cab
AU
644 poll_wait(file, &cl->tx_wait, wait);
645 if (cl->tx_cb_queued < dev->tx_queue_limit)
03b2cbb6 646 mask |= EPOLLOUT | EPOLLWRNORM;
af336cab
AU
647 }
648
ab841160
OW
649out:
650 mutex_unlock(&dev->device_lock);
651 return mask;
652}
653
58cde1a6
AU
654/**
655 * mei_cl_is_write_queued - check if the client has pending writes.
656 *
657 * @cl: writing host client
658 *
659 * Return: true if client is writing, false otherwise.
660 */
661static bool mei_cl_is_write_queued(struct mei_cl *cl)
662{
663 struct mei_device *dev = cl->dev;
664 struct mei_cl_cb *cb;
665
666 list_for_each_entry(cb, &dev->write_list, list)
667 if (cb->cl == cl)
668 return true;
669 list_for_each_entry(cb, &dev->write_waiting_list, list)
670 if (cb->cl == cl)
671 return true;
672 return false;
673}
674
675/**
676 * mei_fsync - the fsync handler
677 *
678 * @fp: pointer to file structure
679 * @start: unused
680 * @end: unused
681 * @datasync: unused
682 *
683 * Return: 0 on success, -ENODEV if client is not connected
684 */
685static int mei_fsync(struct file *fp, loff_t start, loff_t end, int datasync)
686{
687 struct mei_cl *cl = fp->private_data;
688 struct mei_device *dev;
689 int rets;
690
691 if (WARN_ON(!cl || !cl->dev))
692 return -ENODEV;
693
694 dev = cl->dev;
695
696 mutex_lock(&dev->device_lock);
697
698 if (dev->dev_state != MEI_DEV_ENABLED || !mei_cl_is_connected(cl)) {
699 rets = -ENODEV;
700 goto out;
701 }
702
703 while (mei_cl_is_write_queued(cl)) {
704 mutex_unlock(&dev->device_lock);
705 rets = wait_event_interruptible(cl->tx_wait,
706 cl->writing_state == MEI_WRITE_COMPLETE ||
707 !mei_cl_is_connected(cl));
708 mutex_lock(&dev->device_lock);
709 if (rets) {
710 if (signal_pending(current))
711 rets = -EINTR;
712 goto out;
713 }
714 if (!mei_cl_is_connected(cl)) {
715 rets = -ENODEV;
716 goto out;
717 }
718 }
719 rets = 0;
720out:
721 mutex_unlock(&dev->device_lock);
722 return rets;
723}
724
237092bf
TW
725/**
726 * mei_fasync - asynchronous io support
727 *
728 * @fd: file descriptor
729 * @file: pointer to file structure
730 * @band: band bitmap
731 *
ed6dc538
TW
732 * Return: negative on error,
733 * 0 if it did no changes,
734 * and positive a process was added or deleted
237092bf
TW
735 */
736static int mei_fasync(int fd, struct file *file, int band)
737{
738
739 struct mei_cl *cl = file->private_data;
740
741 if (!mei_cl_is_connected(cl))
ed6dc538 742 return -ENODEV;
237092bf
TW
743
744 return fasync_helper(fd, file, band, &cl->ev_async);
745}
746
52f6efdf
AU
747/**
748 * trc_show - mei device trc attribute show method
749 *
750 * @device: device pointer
751 * @attr: attribute pointer
752 * @buf: char out buffer
753 *
754 * Return: number of the bytes printed into buf or error
755 */
756static ssize_t trc_show(struct device *device,
757 struct device_attribute *attr, char *buf)
758{
759 struct mei_device *dev = dev_get_drvdata(device);
760 u32 trc;
761 int ret;
762
763 ret = mei_trc_status(dev, &trc);
764 if (ret)
765 return ret;
766 return sprintf(buf, "%08X\n", trc);
767}
768static DEVICE_ATTR_RO(trc);
769
55c4e640 770/**
88d1bece 771 * fw_status_show - mei device fw_status attribute show method
55c4e640
TW
772 *
773 * @device: device pointer
774 * @attr: attribute pointer
775 * @buf: char out buffer
776 *
777 * Return: number of the bytes printed into buf or error
778 */
779static ssize_t fw_status_show(struct device *device,
780 struct device_attribute *attr, char *buf)
781{
782 struct mei_device *dev = dev_get_drvdata(device);
783 struct mei_fw_status fw_status;
784 int err, i;
785 ssize_t cnt = 0;
786
787 mutex_lock(&dev->device_lock);
788 err = mei_fw_status(dev, &fw_status);
789 mutex_unlock(&dev->device_lock);
790 if (err) {
791 dev_err(device, "read fw_status error = %d\n", err);
792 return err;
793 }
794
795 for (i = 0; i < fw_status.count; i++)
796 cnt += scnprintf(buf + cnt, PAGE_SIZE - cnt, "%08X\n",
797 fw_status.status[i]);
798 return cnt;
799}
800static DEVICE_ATTR_RO(fw_status);
801
88d1bece
AU
802/**
803 * hbm_ver_show - display HBM protocol version negotiated with FW
804 *
805 * @device: device pointer
806 * @attr: attribute pointer
807 * @buf: char out buffer
808 *
809 * Return: number of the bytes printed into buf or error
810 */
811static ssize_t hbm_ver_show(struct device *device,
812 struct device_attribute *attr, char *buf)
813{
814 struct mei_device *dev = dev_get_drvdata(device);
815 struct hbm_version ver;
816
817 mutex_lock(&dev->device_lock);
818 ver = dev->version;
819 mutex_unlock(&dev->device_lock);
820
821 return sprintf(buf, "%u.%u\n", ver.major_version, ver.minor_version);
822}
823static DEVICE_ATTR_RO(hbm_ver);
824
825/**
826 * hbm_ver_drv_show - display HBM protocol version advertised by driver
827 *
828 * @device: device pointer
829 * @attr: attribute pointer
830 * @buf: char out buffer
831 *
832 * Return: number of the bytes printed into buf or error
833 */
834static ssize_t hbm_ver_drv_show(struct device *device,
835 struct device_attribute *attr, char *buf)
836{
837 return sprintf(buf, "%u.%u\n", HBM_MAJOR_VERSION, HBM_MINOR_VERSION);
838}
839static DEVICE_ATTR_RO(hbm_ver_drv);
840
af336cab
AU
841static ssize_t tx_queue_limit_show(struct device *device,
842 struct device_attribute *attr, char *buf)
843{
844 struct mei_device *dev = dev_get_drvdata(device);
845 u8 size = 0;
846
847 mutex_lock(&dev->device_lock);
848 size = dev->tx_queue_limit;
849 mutex_unlock(&dev->device_lock);
850
851 return snprintf(buf, PAGE_SIZE, "%u\n", size);
852}
853
854static ssize_t tx_queue_limit_store(struct device *device,
855 struct device_attribute *attr,
856 const char *buf, size_t count)
857{
858 struct mei_device *dev = dev_get_drvdata(device);
859 u8 limit;
860 unsigned int inp;
861 int err;
862
863 err = kstrtouint(buf, 10, &inp);
864 if (err)
865 return err;
866 if (inp > MEI_TX_QUEUE_LIMIT_MAX || inp < MEI_TX_QUEUE_LIMIT_MIN)
867 return -EINVAL;
868 limit = inp;
869
870 mutex_lock(&dev->device_lock);
871 dev->tx_queue_limit = limit;
872 mutex_unlock(&dev->device_lock);
873
874 return count;
875}
876static DEVICE_ATTR_RW(tx_queue_limit);
877
3cfaeb33
AU
878/**
879 * fw_ver_show - display ME FW version
880 *
881 * @device: device pointer
882 * @attr: attribute pointer
883 * @buf: char out buffer
884 *
885 * Return: number of the bytes printed into buf or error
886 */
887static ssize_t fw_ver_show(struct device *device,
888 struct device_attribute *attr, char *buf)
889{
890 struct mei_device *dev = dev_get_drvdata(device);
891 struct mei_fw_version *ver;
892 ssize_t cnt = 0;
893 int i;
894
895 ver = dev->fw_ver;
896
897 for (i = 0; i < MEI_MAX_FW_VER_BLOCKS; i++)
898 cnt += scnprintf(buf + cnt, PAGE_SIZE - cnt, "%u:%u.%u.%u.%u\n",
899 ver[i].platform, ver[i].major, ver[i].minor,
900 ver[i].hotfix, ver[i].buildno);
901 return cnt;
902}
903static DEVICE_ATTR_RO(fw_ver);
904
43b8a7ed
AU
905/**
906 * dev_state_show - display device state
907 *
908 * @device: device pointer
909 * @attr: attribute pointer
910 * @buf: char out buffer
911 *
912 * Return: number of the bytes printed into buf or error
913 */
914static ssize_t dev_state_show(struct device *device,
915 struct device_attribute *attr, char *buf)
916{
917 struct mei_device *dev = dev_get_drvdata(device);
918 enum mei_dev_state dev_state;
919
920 mutex_lock(&dev->device_lock);
921 dev_state = dev->dev_state;
922 mutex_unlock(&dev->device_lock);
923
924 return sprintf(buf, "%s", mei_dev_state_str(dev_state));
925}
926static DEVICE_ATTR_RO(dev_state);
927
43b8a7ed
AU
928/**
929 * dev_set_devstate: set to new device state and notify sysfs file.
930 *
931 * @dev: mei_device
932 * @state: new device state
933 */
934void mei_set_devstate(struct mei_device *dev, enum mei_dev_state state)
935{
936 struct device *clsdev;
937
938 if (dev->dev_state == state)
939 return;
940
941 dev->dev_state = state;
942
4495dfdd 943 clsdev = class_find_device_by_devt(mei_class, dev->cdev.dev);
43b8a7ed
AU
944 if (clsdev) {
945 sysfs_notify(&clsdev->kobj, NULL, "dev_state");
946 put_device(clsdev);
947 }
948}
949
2f79d3d1
AU
950/**
951 * kind_show - display device kind
952 *
953 * @device: device pointer
954 * @attr: attribute pointer
955 * @buf: char out buffer
956 *
957 * Return: number of the bytes printed into buf or error
958 */
959static ssize_t kind_show(struct device *device,
960 struct device_attribute *attr, char *buf)
961{
962 struct mei_device *dev = dev_get_drvdata(device);
963 ssize_t ret;
964
965 if (dev->kind)
966 ret = sprintf(buf, "%s\n", dev->kind);
967 else
968 ret = sprintf(buf, "%s\n", "mei");
969
970 return ret;
971}
972static DEVICE_ATTR_RO(kind);
973
55c4e640
TW
974static struct attribute *mei_attrs[] = {
975 &dev_attr_fw_status.attr,
88d1bece
AU
976 &dev_attr_hbm_ver.attr,
977 &dev_attr_hbm_ver_drv.attr,
af336cab 978 &dev_attr_tx_queue_limit.attr,
3cfaeb33 979 &dev_attr_fw_ver.attr,
43b8a7ed 980 &dev_attr_dev_state.attr,
52f6efdf 981 &dev_attr_trc.attr,
2f79d3d1 982 &dev_attr_kind.attr,
55c4e640
TW
983 NULL
984};
985ATTRIBUTE_GROUPS(mei);
986
5b881e3c
OW
987/*
988 * file operations structure will be used for mei char device.
989 */
990static const struct file_operations mei_fops = {
991 .owner = THIS_MODULE,
992 .read = mei_read,
993 .unlocked_ioctl = mei_ioctl,
407e9ef7 994 .compat_ioctl = compat_ptr_ioctl,
5b881e3c
OW
995 .open = mei_open,
996 .release = mei_release,
997 .write = mei_write,
998 .poll = mei_poll,
58cde1a6 999 .fsync = mei_fsync,
237092bf 1000 .fasync = mei_fasync,
5b881e3c
OW
1001 .llseek = no_llseek
1002};
1003
f3d8e878
AU
1004/**
1005 * mei_minor_get - obtain next free device minor number
1006 *
1007 * @dev: device pointer
1008 *
a8605ea2 1009 * Return: allocated minor, or -ENOSPC if no free minor left
5b881e3c 1010 */
f3d8e878
AU
1011static int mei_minor_get(struct mei_device *dev)
1012{
1013 int ret;
1014
1015 mutex_lock(&mei_minor_lock);
1016 ret = idr_alloc(&mei_idr, dev, 0, MEI_MAX_DEVS, GFP_KERNEL);
1017 if (ret >= 0)
1018 dev->minor = ret;
1019 else if (ret == -ENOSPC)
2bf94cab 1020 dev_err(dev->dev, "too many mei devices\n");
5b881e3c 1021
f3d8e878
AU
1022 mutex_unlock(&mei_minor_lock);
1023 return ret;
1024}
30e53bb8 1025
f3d8e878
AU
1026/**
1027 * mei_minor_free - mark device minor number as free
1028 *
1029 * @dev: device pointer
1030 */
1031static void mei_minor_free(struct mei_device *dev)
9a123f19 1032{
f3d8e878
AU
1033 mutex_lock(&mei_minor_lock);
1034 idr_remove(&mei_idr, dev->minor);
1035 mutex_unlock(&mei_minor_lock);
1036}
1037
1038int mei_register(struct mei_device *dev, struct device *parent)
1039{
1040 struct device *clsdev; /* class device */
1041 int ret, devno;
1042
1043 ret = mei_minor_get(dev);
1044 if (ret < 0)
30e53bb8
TW
1045 return ret;
1046
f3d8e878
AU
1047 /* Fill in the data structures */
1048 devno = MKDEV(MAJOR(mei_devt), dev->minor);
1049 cdev_init(&dev->cdev, &mei_fops);
154322f4 1050 dev->cdev.owner = parent->driver->owner;
f3d8e878
AU
1051
1052 /* Add the device */
1053 ret = cdev_add(&dev->cdev, devno, 1);
1054 if (ret) {
1055 dev_err(parent, "unable to add device %d:%d\n",
1056 MAJOR(mei_devt), dev->minor);
1057 goto err_dev_add;
1058 }
1059
55c4e640
TW
1060 clsdev = device_create_with_groups(mei_class, parent, devno,
1061 dev, mei_groups,
1062 "mei%d", dev->minor);
f3d8e878
AU
1063
1064 if (IS_ERR(clsdev)) {
1065 dev_err(parent, "unable to create device %d:%d\n",
1066 MAJOR(mei_devt), dev->minor);
1067 ret = PTR_ERR(clsdev);
1068 goto err_dev_create;
1069 }
1070
5666d896 1071 mei_dbgfs_register(dev, dev_name(clsdev));
30e53bb8
TW
1072
1073 return 0;
f3d8e878 1074
f3d8e878
AU
1075err_dev_create:
1076 cdev_del(&dev->cdev);
1077err_dev_add:
1078 mei_minor_free(dev);
1079 return ret;
5b881e3c 1080}
40e0b67b 1081EXPORT_SYMBOL_GPL(mei_register);
5b881e3c 1082
30e53bb8 1083void mei_deregister(struct mei_device *dev)
5b881e3c 1084{
f3d8e878
AU
1085 int devno;
1086
1087 devno = dev->cdev.dev;
1088 cdev_del(&dev->cdev);
1089
30e53bb8 1090 mei_dbgfs_deregister(dev);
f3d8e878
AU
1091
1092 device_destroy(mei_class, devno);
1093
1094 mei_minor_free(dev);
5b881e3c 1095}
40e0b67b 1096EXPORT_SYMBOL_GPL(mei_deregister);
ab841160 1097
cf3baefb
SO
1098static int __init mei_init(void)
1099{
f3d8e878
AU
1100 int ret;
1101
1102 mei_class = class_create(THIS_MODULE, "mei");
1103 if (IS_ERR(mei_class)) {
1104 pr_err("couldn't create class\n");
1105 ret = PTR_ERR(mei_class);
1106 goto err;
1107 }
1108
1109 ret = alloc_chrdev_region(&mei_devt, 0, MEI_MAX_DEVS, "mei");
1110 if (ret < 0) {
1111 pr_err("unable to allocate char dev region\n");
1112 goto err_class;
1113 }
1114
1115 ret = mei_cl_bus_init();
1116 if (ret < 0) {
1117 pr_err("unable to initialize bus\n");
1118 goto err_chrdev;
1119 }
1120
1121 return 0;
1122
1123err_chrdev:
1124 unregister_chrdev_region(mei_devt, MEI_MAX_DEVS);
1125err_class:
1126 class_destroy(mei_class);
1127err:
1128 return ret;
cf3baefb
SO
1129}
1130
1131static void __exit mei_exit(void)
1132{
f3d8e878
AU
1133 unregister_chrdev_region(mei_devt, MEI_MAX_DEVS);
1134 class_destroy(mei_class);
cf3baefb
SO
1135 mei_cl_bus_exit();
1136}
1137
1138module_init(mei_init);
1139module_exit(mei_exit);
1140
40e0b67b
TW
1141MODULE_AUTHOR("Intel Corporation");
1142MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
827eef51 1143MODULE_LICENSE("GPL v2");
ab841160 1144