]>
Commit | Line | Data |
---|---|---|
30e53bb8 TW |
1 | /* |
2 | * | |
3 | * Intel Management Engine Interface (Intel MEI) Linux driver | |
4 | * Copyright (c) 2012-2013, 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/slab.h> | |
17 | #include <linux/kernel.h> | |
18 | #include <linux/device.h> | |
19 | #include <linux/debugfs.h> | |
20 | #include <linux/pci.h> | |
21 | ||
22 | #include <linux/mei.h> | |
23 | ||
24 | #include "mei_dev.h" | |
25 | #include "hw.h" | |
26 | ||
30e53bb8 TW |
27 | static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, |
28 | size_t cnt, loff_t *ppos) | |
29 | { | |
30 | struct mei_device *dev = fp->private_data; | |
31 | struct mei_me_client *cl; | |
32 | const size_t bufsz = 1024; | |
33 | char *buf = kzalloc(bufsz, GFP_KERNEL); | |
34 | int i; | |
35 | int pos = 0; | |
36 | int ret; | |
37 | ||
38 | if (!buf) | |
39 | return -ENOMEM; | |
40 | ||
41 | pos += scnprintf(buf + pos, bufsz - pos, | |
42 | " |id|addr| UUID |con|msg len|\n"); | |
43 | ||
44 | mutex_lock(&dev->device_lock); | |
45 | ||
46 | /* if the driver is not enabled the list won't b consitent */ | |
47 | if (dev->dev_state != MEI_DEV_ENABLED) | |
48 | goto out; | |
49 | ||
50 | for (i = 0; i < dev->me_clients_num; i++) { | |
51 | cl = &dev->me_clients[i]; | |
52 | ||
53 | /* skip me clients that cannot be connected */ | |
54 | if (cl->props.max_number_of_connections == 0) | |
55 | continue; | |
56 | ||
57 | pos += scnprintf(buf + pos, bufsz - pos, | |
58 | "%2d|%2d|%4d|%pUl|%3d|%7d|\n", | |
59 | i, cl->client_id, | |
60 | cl->props.fixed_address, | |
61 | &cl->props.protocol_name, | |
62 | cl->props.max_number_of_connections, | |
63 | cl->props.max_msg_length); | |
64 | } | |
65 | out: | |
66 | mutex_unlock(&dev->device_lock); | |
67 | ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, pos); | |
68 | kfree(buf); | |
69 | return ret; | |
70 | } | |
71 | ||
72 | static const struct file_operations mei_dbgfs_fops_meclients = { | |
a42f82f5 | 73 | .open = simple_open, |
30e53bb8 TW |
74 | .read = mei_dbgfs_read_meclients, |
75 | .llseek = generic_file_llseek, | |
76 | }; | |
77 | ||
78 | static ssize_t mei_dbgfs_read_devstate(struct file *fp, char __user *ubuf, | |
79 | size_t cnt, loff_t *ppos) | |
80 | { | |
81 | struct mei_device *dev = fp->private_data; | |
82 | const size_t bufsz = 1024; | |
83 | char *buf = kzalloc(bufsz, GFP_KERNEL); | |
84 | int pos = 0; | |
85 | int ret; | |
86 | ||
87 | if (!buf) | |
88 | return -ENOMEM; | |
89 | ||
90 | pos += scnprintf(buf + pos, bufsz - pos, "%s\n", | |
91 | mei_dev_state_str(dev->dev_state)); | |
92 | ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, pos); | |
93 | kfree(buf); | |
94 | return ret; | |
95 | } | |
96 | static const struct file_operations mei_dbgfs_fops_devstate = { | |
a42f82f5 | 97 | .open = simple_open, |
30e53bb8 TW |
98 | .read = mei_dbgfs_read_devstate, |
99 | .llseek = generic_file_llseek, | |
100 | }; | |
101 | ||
102 | /** | |
103 | * mei_dbgfs_deregister - Remove the debugfs files and directories | |
104 | * @mei - pointer to mei device private dat | |
105 | */ | |
106 | void mei_dbgfs_deregister(struct mei_device *dev) | |
107 | { | |
108 | if (!dev->dbgfs_dir) | |
109 | return; | |
110 | debugfs_remove_recursive(dev->dbgfs_dir); | |
111 | dev->dbgfs_dir = NULL; | |
112 | } | |
113 | ||
114 | /** | |
115 | * Add the debugfs files | |
116 | * | |
117 | */ | |
118 | int mei_dbgfs_register(struct mei_device *dev, const char *name) | |
119 | { | |
120 | struct dentry *dir, *f; | |
121 | dir = debugfs_create_dir(name, NULL); | |
122 | if (!dir) | |
123 | return -ENOMEM; | |
124 | ||
125 | f = debugfs_create_file("meclients", S_IRUSR, dir, | |
126 | dev, &mei_dbgfs_fops_meclients); | |
127 | if (!f) { | |
128 | dev_err(&dev->pdev->dev, "meclients: registration failed\n"); | |
129 | goto err; | |
130 | } | |
131 | f = debugfs_create_file("devstate", S_IRUSR, dir, | |
132 | dev, &mei_dbgfs_fops_devstate); | |
133 | if (!f) { | |
134 | dev_err(&dev->pdev->dev, "devstate: registration failed\n"); | |
135 | goto err; | |
136 | } | |
137 | dev->dbgfs_dir = dir; | |
138 | return 0; | |
139 | err: | |
140 | mei_dbgfs_deregister(dev); | |
141 | return -ENODEV; | |
142 | } | |
143 |