]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/misc/mei/main.c
Merge remote-tracking branches 'regulator/topic/fixed', 'regulator/topic/id-const...
[karo-tx-linux.git] / drivers / misc / mei / main.c
1 /*
2  *
3  * Intel Management Engine Interface (Intel MEI) Linux driver
4  * Copyright (c) 2003-2012, Intel Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  */
16 #include <linux/module.h>
17 #include <linux/moduleparam.h>
18 #include <linux/kernel.h>
19 #include <linux/device.h>
20 #include <linux/fs.h>
21 #include <linux/errno.h>
22 #include <linux/types.h>
23 #include <linux/fcntl.h>
24 #include <linux/aio.h>
25 #include <linux/pci.h>
26 #include <linux/poll.h>
27 #include <linux/init.h>
28 #include <linux/ioctl.h>
29 #include <linux/cdev.h>
30 #include <linux/sched.h>
31 #include <linux/uuid.h>
32 #include <linux/compat.h>
33 #include <linux/jiffies.h>
34 #include <linux/interrupt.h>
35 #include <linux/miscdevice.h>
36
37 #include <linux/mei.h>
38
39 #include "mei_dev.h"
40 #include "client.h"
41
42 /**
43  * mei_open - the open function
44  *
45  * @inode: pointer to inode structure
46  * @file: pointer to file structure
47  *
48  * returns 0 on success, <0 on error
49  */
50 static int mei_open(struct inode *inode, struct file *file)
51 {
52         struct miscdevice *misc = file->private_data;
53         struct pci_dev *pdev;
54         struct mei_cl *cl;
55         struct mei_device *dev;
56
57         int err;
58
59         if (!misc->parent)
60                 return -ENODEV;
61
62         pdev = container_of(misc->parent, struct pci_dev, dev);
63
64         dev = pci_get_drvdata(pdev);
65         if (!dev)
66                 return -ENODEV;
67
68         mutex_lock(&dev->device_lock);
69
70         cl = NULL;
71
72         err = -ENODEV;
73         if (dev->dev_state != MEI_DEV_ENABLED) {
74                 dev_dbg(&dev->pdev->dev, "dev_state != MEI_ENABLED  dev_state = %s\n",
75                     mei_dev_state_str(dev->dev_state));
76                 goto err_unlock;
77         }
78
79         err = -ENOMEM;
80         cl = mei_cl_allocate(dev);
81         if (!cl)
82                 goto err_unlock;
83
84         /* open_handle_count check is handled in the mei_cl_link */
85         err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
86         if (err)
87                 goto err_unlock;
88
89         file->private_data = cl;
90
91         mutex_unlock(&dev->device_lock);
92
93         return nonseekable_open(inode, file);
94
95 err_unlock:
96         mutex_unlock(&dev->device_lock);
97         kfree(cl);
98         return err;
99 }
100
101 /**
102  * mei_release - the release function
103  *
104  * @inode: pointer to inode structure
105  * @file: pointer to file structure
106  *
107  * returns 0 on success, <0 on error
108  */
109 static int mei_release(struct inode *inode, struct file *file)
110 {
111         struct mei_cl *cl = file->private_data;
112         struct mei_cl_cb *cb;
113         struct mei_device *dev;
114         int rets = 0;
115
116         if (WARN_ON(!cl || !cl->dev))
117                 return -ENODEV;
118
119         dev = cl->dev;
120
121         mutex_lock(&dev->device_lock);
122         if (cl == &dev->iamthif_cl) {
123                 rets = mei_amthif_release(dev, file);
124                 goto out;
125         }
126         if (cl->state == MEI_FILE_CONNECTED) {
127                 cl->state = MEI_FILE_DISCONNECTING;
128                 cl_dbg(dev, cl, "disconnecting\n");
129                 rets = mei_cl_disconnect(cl);
130         }
131         mei_cl_flush_queues(cl);
132         cl_dbg(dev, cl, "removing\n");
133
134         mei_cl_unlink(cl);
135
136
137         /* free read cb */
138         cb = NULL;
139         if (cl->read_cb) {
140                 cb = mei_cl_find_read_cb(cl);
141                 /* Remove entry from read list */
142                 if (cb)
143                         list_del(&cb->list);
144
145                 cb = cl->read_cb;
146                 cl->read_cb = NULL;
147         }
148
149         file->private_data = NULL;
150
151         mei_io_cb_free(cb);
152
153         kfree(cl);
154 out:
155         mutex_unlock(&dev->device_lock);
156         return rets;
157 }
158
159
160 /**
161  * mei_read - the read function.
162  *
163  * @file: pointer to file structure
164  * @ubuf: pointer to user buffer
165  * @length: buffer length
166  * @offset: data offset in buffer
167  *
168  * returns >=0 data length on success , <0 on error
169  */
170 static ssize_t mei_read(struct file *file, char __user *ubuf,
171                         size_t length, loff_t *offset)
172 {
173         struct mei_cl *cl = file->private_data;
174         struct mei_cl_cb *cb_pos = NULL;
175         struct mei_cl_cb *cb = NULL;
176         struct mei_device *dev;
177         int rets;
178         int err;
179
180
181         if (WARN_ON(!cl || !cl->dev))
182                 return -ENODEV;
183
184         dev = cl->dev;
185
186
187         mutex_lock(&dev->device_lock);
188         if (dev->dev_state != MEI_DEV_ENABLED) {
189                 rets = -ENODEV;
190                 goto out;
191         }
192
193         if (length == 0) {
194                 rets = 0;
195                 goto out;
196         }
197
198         if (cl == &dev->iamthif_cl) {
199                 rets = mei_amthif_read(dev, file, ubuf, length, offset);
200                 goto out;
201         }
202
203         if (cl->read_cb) {
204                 cb = cl->read_cb;
205                 /* read what left */
206                 if (cb->buf_idx > *offset)
207                         goto copy_buffer;
208                 /* offset is beyond buf_idx we have no more data return 0 */
209                 if (cb->buf_idx > 0 && cb->buf_idx <= *offset) {
210                         rets = 0;
211                         goto free;
212                 }
213                 /* Offset needs to be cleaned for contiguous reads*/
214                 if (cb->buf_idx == 0 && *offset > 0)
215                         *offset = 0;
216         } else if (*offset > 0) {
217                 *offset = 0;
218         }
219
220         err = mei_cl_read_start(cl, length);
221         if (err && err != -EBUSY) {
222                 dev_dbg(&dev->pdev->dev,
223                         "mei start read failure with status = %d\n", err);
224                 rets = err;
225                 goto out;
226         }
227
228         if (MEI_READ_COMPLETE != cl->reading_state &&
229                         !waitqueue_active(&cl->rx_wait)) {
230                 if (file->f_flags & O_NONBLOCK) {
231                         rets = -EAGAIN;
232                         goto out;
233                 }
234
235                 mutex_unlock(&dev->device_lock);
236
237                 if (wait_event_interruptible(cl->rx_wait,
238                                 MEI_READ_COMPLETE == cl->reading_state ||
239                                 mei_cl_is_transitioning(cl))) {
240
241                         if (signal_pending(current))
242                                 return -EINTR;
243                         return -ERESTARTSYS;
244                 }
245
246                 mutex_lock(&dev->device_lock);
247                 if (mei_cl_is_transitioning(cl)) {
248                         rets = -EBUSY;
249                         goto out;
250                 }
251         }
252
253         cb = cl->read_cb;
254
255         if (!cb) {
256                 rets = -ENODEV;
257                 goto out;
258         }
259         if (cl->reading_state != MEI_READ_COMPLETE) {
260                 rets = 0;
261                 goto out;
262         }
263         /* now copy the data to user space */
264 copy_buffer:
265         dev_dbg(&dev->pdev->dev, "buf.size = %d buf.idx= %ld\n",
266             cb->response_buffer.size, cb->buf_idx);
267         if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) {
268                 rets = -EMSGSIZE;
269                 goto free;
270         }
271
272         /* length is being truncated to PAGE_SIZE,
273          * however buf_idx may point beyond that */
274         length = min_t(size_t, length, cb->buf_idx - *offset);
275
276         if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) {
277                 dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n");
278                 rets = -EFAULT;
279                 goto free;
280         }
281
282         rets = length;
283         *offset += length;
284         if ((unsigned long)*offset < cb->buf_idx)
285                 goto out;
286
287 free:
288         cb_pos = mei_cl_find_read_cb(cl);
289         /* Remove entry from read list */
290         if (cb_pos)
291                 list_del(&cb_pos->list);
292         mei_io_cb_free(cb);
293         cl->reading_state = MEI_IDLE;
294         cl->read_cb = NULL;
295 out:
296         dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets);
297         mutex_unlock(&dev->device_lock);
298         return rets;
299 }
300 /**
301  * mei_write - the write function.
302  *
303  * @file: pointer to file structure
304  * @ubuf: pointer to user buffer
305  * @length: buffer length
306  * @offset: data offset in buffer
307  *
308  * returns >=0 data length on success , <0 on error
309  */
310 static ssize_t mei_write(struct file *file, const char __user *ubuf,
311                          size_t length, loff_t *offset)
312 {
313         struct mei_cl *cl = file->private_data;
314         struct mei_cl_cb *write_cb = NULL;
315         struct mei_device *dev;
316         unsigned long timeout = 0;
317         int rets;
318         int id;
319
320         if (WARN_ON(!cl || !cl->dev))
321                 return -ENODEV;
322
323         dev = cl->dev;
324
325         mutex_lock(&dev->device_lock);
326
327         if (dev->dev_state != MEI_DEV_ENABLED) {
328                 rets = -ENODEV;
329                 goto out;
330         }
331
332         id = mei_me_cl_by_id(dev, cl->me_client_id);
333         if (id < 0) {
334                 rets = -ENOTTY;
335                 goto out;
336         }
337
338         if (length == 0) {
339                 rets = 0;
340                 goto out;
341         }
342
343         if (length > dev->me_clients[id].props.max_msg_length) {
344                 rets = -EFBIG;
345                 goto out;
346         }
347
348         if (cl->state != MEI_FILE_CONNECTED) {
349                 dev_err(&dev->pdev->dev, "host client = %d,  is not connected to ME client = %d",
350                         cl->host_client_id, cl->me_client_id);
351                 rets = -ENODEV;
352                 goto out;
353         }
354         if (cl == &dev->iamthif_cl) {
355                 write_cb = mei_amthif_find_read_list_entry(dev, file);
356
357                 if (write_cb) {
358                         timeout = write_cb->read_time +
359                                 mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
360
361                         if (time_after(jiffies, timeout) ||
362                             cl->reading_state == MEI_READ_COMPLETE) {
363                                 *offset = 0;
364                                 list_del(&write_cb->list);
365                                 mei_io_cb_free(write_cb);
366                                 write_cb = NULL;
367                         }
368                 }
369         }
370
371         /* free entry used in read */
372         if (cl->reading_state == MEI_READ_COMPLETE) {
373                 *offset = 0;
374                 write_cb = mei_cl_find_read_cb(cl);
375                 if (write_cb) {
376                         list_del(&write_cb->list);
377                         mei_io_cb_free(write_cb);
378                         write_cb = NULL;
379                         cl->reading_state = MEI_IDLE;
380                         cl->read_cb = NULL;
381                 }
382         } else if (cl->reading_state == MEI_IDLE)
383                 *offset = 0;
384
385
386         write_cb = mei_io_cb_init(cl, file);
387         if (!write_cb) {
388                 dev_err(&dev->pdev->dev, "write cb allocation failed\n");
389                 rets = -ENOMEM;
390                 goto out;
391         }
392         rets = mei_io_cb_alloc_req_buf(write_cb, length);
393         if (rets)
394                 goto out;
395
396         rets = copy_from_user(write_cb->request_buffer.data, ubuf, length);
397         if (rets) {
398                 dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n");
399                 rets = -EFAULT;
400                 goto out;
401         }
402
403         if (cl == &dev->iamthif_cl) {
404                 rets = mei_amthif_write(dev, write_cb);
405
406                 if (rets) {
407                         dev_err(&dev->pdev->dev,
408                                 "amthif write failed with status = %d\n", rets);
409                         goto out;
410                 }
411                 mutex_unlock(&dev->device_lock);
412                 return length;
413         }
414
415         rets = mei_cl_write(cl, write_cb, false);
416 out:
417         mutex_unlock(&dev->device_lock);
418         if (rets < 0)
419                 mei_io_cb_free(write_cb);
420         return rets;
421 }
422
423 /**
424  * mei_ioctl_connect_client - the connect to fw client IOCTL function
425  *
426  * @dev: the device structure
427  * @data: IOCTL connect data, input and output parameters
428  * @file: private data of the file object
429  *
430  * Locking: called under "dev->device_lock" lock
431  *
432  * returns 0 on success, <0 on failure.
433  */
434 static int mei_ioctl_connect_client(struct file *file,
435                         struct mei_connect_client_data *data)
436 {
437         struct mei_device *dev;
438         struct mei_client *client;
439         struct mei_cl *cl;
440         int i;
441         int rets;
442
443         cl = file->private_data;
444         if (WARN_ON(!cl || !cl->dev))
445                 return -ENODEV;
446
447         dev = cl->dev;
448
449         if (dev->dev_state != MEI_DEV_ENABLED) {
450                 rets = -ENODEV;
451                 goto end;
452         }
453
454         if (cl->state != MEI_FILE_INITIALIZING &&
455             cl->state != MEI_FILE_DISCONNECTED) {
456                 rets = -EBUSY;
457                 goto end;
458         }
459
460         /* find ME client we're trying to connect to */
461         i = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
462         if (i < 0 || dev->me_clients[i].props.fixed_address) {
463                 dev_dbg(&dev->pdev->dev, "Cannot connect to FW Client UUID = %pUl\n",
464                                 &data->in_client_uuid);
465                 rets = -ENOTTY;
466                 goto end;
467         }
468
469         cl->me_client_id = dev->me_clients[i].client_id;
470         cl->state = MEI_FILE_CONNECTING;
471
472         dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
473                         cl->me_client_id);
474         dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n",
475                         dev->me_clients[i].props.protocol_version);
476         dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n",
477                         dev->me_clients[i].props.max_msg_length);
478
479         /* if we're connecting to amthif client then we will use the
480          * existing connection
481          */
482         if (uuid_le_cmp(data->in_client_uuid, mei_amthif_guid) == 0) {
483                 dev_dbg(&dev->pdev->dev, "FW Client is amthi\n");
484                 if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) {
485                         rets = -ENODEV;
486                         goto end;
487                 }
488                 mei_cl_unlink(cl);
489
490                 kfree(cl);
491                 cl = NULL;
492                 dev->iamthif_open_count++;
493                 file->private_data = &dev->iamthif_cl;
494
495                 client = &data->out_client_properties;
496                 client->max_msg_length =
497                         dev->me_clients[i].props.max_msg_length;
498                 client->protocol_version =
499                         dev->me_clients[i].props.protocol_version;
500                 rets = dev->iamthif_cl.status;
501
502                 goto end;
503         }
504
505
506         /* prepare the output buffer */
507         client = &data->out_client_properties;
508         client->max_msg_length = dev->me_clients[i].props.max_msg_length;
509         client->protocol_version = dev->me_clients[i].props.protocol_version;
510         dev_dbg(&dev->pdev->dev, "Can connect?\n");
511
512
513         rets = mei_cl_connect(cl, file);
514
515 end:
516         return rets;
517 }
518
519
520 /**
521  * mei_ioctl - the IOCTL function
522  *
523  * @file: pointer to file structure
524  * @cmd: ioctl command
525  * @data: pointer to mei message structure
526  *
527  * returns 0 on success , <0 on error
528  */
529 static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
530 {
531         struct mei_device *dev;
532         struct mei_cl *cl = file->private_data;
533         struct mei_connect_client_data *connect_data = NULL;
534         int rets;
535
536         if (cmd != IOCTL_MEI_CONNECT_CLIENT)
537                 return -EINVAL;
538
539         if (WARN_ON(!cl || !cl->dev))
540                 return -ENODEV;
541
542         dev = cl->dev;
543
544         dev_dbg(&dev->pdev->dev, "IOCTL cmd = 0x%x", cmd);
545
546         mutex_lock(&dev->device_lock);
547         if (dev->dev_state != MEI_DEV_ENABLED) {
548                 rets = -ENODEV;
549                 goto out;
550         }
551
552         dev_dbg(&dev->pdev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n");
553
554         connect_data = kzalloc(sizeof(struct mei_connect_client_data),
555                                                         GFP_KERNEL);
556         if (!connect_data) {
557                 rets = -ENOMEM;
558                 goto out;
559         }
560         dev_dbg(&dev->pdev->dev, "copy connect data from user\n");
561         if (copy_from_user(connect_data, (char __user *)data,
562                                 sizeof(struct mei_connect_client_data))) {
563                 dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n");
564                 rets = -EFAULT;
565                 goto out;
566         }
567
568         rets = mei_ioctl_connect_client(file, connect_data);
569
570         /* if all is ok, copying the data back to user. */
571         if (rets)
572                 goto out;
573
574         dev_dbg(&dev->pdev->dev, "copy connect data to user\n");
575         if (copy_to_user((char __user *)data, connect_data,
576                                 sizeof(struct mei_connect_client_data))) {
577                 dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n");
578                 rets = -EFAULT;
579                 goto out;
580         }
581
582 out:
583         kfree(connect_data);
584         mutex_unlock(&dev->device_lock);
585         return rets;
586 }
587
588 /**
589  * mei_compat_ioctl - the compat IOCTL function
590  *
591  * @file: pointer to file structure
592  * @cmd: ioctl command
593  * @data: pointer to mei message structure
594  *
595  * returns 0 on success , <0 on error
596  */
597 #ifdef CONFIG_COMPAT
598 static long mei_compat_ioctl(struct file *file,
599                         unsigned int cmd, unsigned long data)
600 {
601         return mei_ioctl(file, cmd, (unsigned long)compat_ptr(data));
602 }
603 #endif
604
605
606 /**
607  * mei_poll - the poll function
608  *
609  * @file: pointer to file structure
610  * @wait: pointer to poll_table structure
611  *
612  * returns poll mask
613  */
614 static unsigned int mei_poll(struct file *file, poll_table *wait)
615 {
616         struct mei_cl *cl = file->private_data;
617         struct mei_device *dev;
618         unsigned int mask = 0;
619
620         if (WARN_ON(!cl || !cl->dev))
621                 return POLLERR;
622
623         dev = cl->dev;
624
625         mutex_lock(&dev->device_lock);
626
627         if (!mei_cl_is_connected(cl)) {
628                 mask = POLLERR;
629                 goto out;
630         }
631
632         mutex_unlock(&dev->device_lock);
633
634
635         if (cl == &dev->iamthif_cl)
636                 return mei_amthif_poll(dev, file, wait);
637
638         poll_wait(file, &cl->tx_wait, wait);
639
640         mutex_lock(&dev->device_lock);
641
642         if (!mei_cl_is_connected(cl)) {
643                 mask = POLLERR;
644                 goto out;
645         }
646
647         mask |= (POLLIN | POLLRDNORM);
648
649 out:
650         mutex_unlock(&dev->device_lock);
651         return mask;
652 }
653
654 /*
655  * file operations structure will be used for mei char device.
656  */
657 static const struct file_operations mei_fops = {
658         .owner = THIS_MODULE,
659         .read = mei_read,
660         .unlocked_ioctl = mei_ioctl,
661 #ifdef CONFIG_COMPAT
662         .compat_ioctl = mei_compat_ioctl,
663 #endif
664         .open = mei_open,
665         .release = mei_release,
666         .write = mei_write,
667         .poll = mei_poll,
668         .llseek = no_llseek
669 };
670
671 /*
672  * Misc Device Struct
673  */
674 static struct miscdevice  mei_misc_device = {
675                 .name = "mei",
676                 .fops = &mei_fops,
677                 .minor = MISC_DYNAMIC_MINOR,
678 };
679
680
681 int mei_register(struct mei_device *dev)
682 {
683         int ret;
684         mei_misc_device.parent = &dev->pdev->dev;
685         ret = misc_register(&mei_misc_device);
686         if (ret)
687                 return ret;
688
689         if (mei_dbgfs_register(dev, mei_misc_device.name))
690                 dev_err(&dev->pdev->dev, "cannot register debugfs\n");
691
692         return 0;
693 }
694 EXPORT_SYMBOL_GPL(mei_register);
695
696 void mei_deregister(struct mei_device *dev)
697 {
698         mei_dbgfs_deregister(dev);
699         misc_deregister(&mei_misc_device);
700         mei_misc_device.parent = NULL;
701 }
702 EXPORT_SYMBOL_GPL(mei_deregister);
703
704 static int __init mei_init(void)
705 {
706         return mei_cl_bus_init();
707 }
708
709 static void __exit mei_exit(void)
710 {
711         mei_cl_bus_exit();
712 }
713
714 module_init(mei_init);
715 module_exit(mei_exit);
716
717 MODULE_AUTHOR("Intel Corporation");
718 MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
719 MODULE_LICENSE("GPL v2");
720