1 /*
2  * cros_ec_debugfs - debug logs for Chrome OS EC
3  *
4  * Copyright 2015 Google, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <linux/circ_buf.h>
21 #include <linux/debugfs.h>
22 #include <linux/delay.h>
23 #include <linux/fs.h>
24 #include <linux/mfd/cros_ec.h>
25 #include <linux/mfd/cros_ec_commands.h>
26 #include <linux/mutex.h>
27 #include <linux/poll.h>
28 #include <linux/sched.h>
29 #include <linux/slab.h>
30 #include <linux/wait.h>
31 
32 #include "cros_ec_dev.h"
33 #include "cros_ec_debugfs.h"
34 
35 #define LOG_SHIFT		14
36 #define LOG_SIZE		(1 << LOG_SHIFT)
37 #define LOG_POLL_SEC		10
38 
39 #define CIRC_ADD(idx, size, value)	(((idx) + (value)) & ((size) - 1))
40 
41 /* struct cros_ec_debugfs - ChromeOS EC debugging information
42  *
43  * @ec: EC device this debugfs information belongs to
44  * @dir: dentry for debugfs files
45  * @log_buffer: circular buffer for console log information
46  * @read_msg: preallocated EC command and buffer to read console log
47  * @log_mutex: mutex to protect circular buffer
48  * @log_wq: waitqueue for log readers
49  * @log_poll_work: recurring task to poll EC for new console log data
50  * @panicinfo_blob: panicinfo debugfs blob
51  */
52 struct cros_ec_debugfs {
53 	struct cros_ec_dev *ec;
54 	struct dentry *dir;
55 	/* EC log */
56 	struct circ_buf log_buffer;
57 	struct cros_ec_command *read_msg;
58 	struct mutex log_mutex;
59 	wait_queue_head_t log_wq;
60 	struct delayed_work log_poll_work;
61 	/* EC panicinfo */
62 	struct debugfs_blob_wrapper panicinfo_blob;
63 };
64 
65 /*
66  * We need to make sure that the EC log buffer on the UART is large enough,
67  * so that it is unlikely enough to overlow within LOG_POLL_SEC.
68  */
69 static void cros_ec_console_log_work(struct work_struct *__work)
70 {
71 	struct cros_ec_debugfs *debug_info =
72 		container_of(to_delayed_work(__work),
73 			     struct cros_ec_debugfs,
74 			     log_poll_work);
75 	struct cros_ec_dev *ec = debug_info->ec;
76 	struct circ_buf *cb = &debug_info->log_buffer;
77 	struct cros_ec_command snapshot_msg = {
78 		.command = EC_CMD_CONSOLE_SNAPSHOT + ec->cmd_offset,
79 	};
80 
81 	struct ec_params_console_read_v1 *read_params =
82 		(struct ec_params_console_read_v1 *)debug_info->read_msg->data;
83 	uint8_t *ec_buffer = (uint8_t *)debug_info->read_msg->data;
84 	int idx;
85 	int buf_space;
86 	int ret;
87 
88 	ret = cros_ec_cmd_xfer(ec->ec_dev, &snapshot_msg);
89 	if (ret < 0) {
90 		dev_err(ec->dev, "EC communication failed\n");
91 		goto resched;
92 	}
93 	if (snapshot_msg.result != EC_RES_SUCCESS) {
94 		dev_err(ec->dev, "EC failed to snapshot the console log\n");
95 		goto resched;
96 	}
97 
98 	/* Loop until we have read everything, or there's an error. */
99 	mutex_lock(&debug_info->log_mutex);
100 	buf_space = CIRC_SPACE(cb->head, cb->tail, LOG_SIZE);
101 
102 	while (1) {
103 		if (!buf_space) {
104 			dev_info_once(ec->dev,
105 				      "Some logs may have been dropped...\n");
106 			break;
107 		}
108 
109 		memset(read_params, '\0', sizeof(*read_params));
110 		read_params->subcmd = CONSOLE_READ_RECENT;
111 		ret = cros_ec_cmd_xfer(ec->ec_dev, debug_info->read_msg);
112 		if (ret < 0) {
113 			dev_err(ec->dev, "EC communication failed\n");
114 			break;
115 		}
116 		if (debug_info->read_msg->result != EC_RES_SUCCESS) {
117 			dev_err(ec->dev,
118 				"EC failed to read the console log\n");
119 			break;
120 		}
121 
122 		/* If the buffer is empty, we're done here. */
123 		if (ret == 0 || ec_buffer[0] == '\0')
124 			break;
125 
126 		idx = 0;
127 		while (idx < ret && ec_buffer[idx] != '\0' && buf_space > 0) {
128 			cb->buf[cb->head] = ec_buffer[idx];
129 			cb->head = CIRC_ADD(cb->head, LOG_SIZE, 1);
130 			idx++;
131 			buf_space--;
132 		}
133 
134 		wake_up(&debug_info->log_wq);
135 	}
136 
137 	mutex_unlock(&debug_info->log_mutex);
138 
139 resched:
140 	schedule_delayed_work(&debug_info->log_poll_work,
141 			      msecs_to_jiffies(LOG_POLL_SEC * 1000));
142 }
143 
144 static int cros_ec_console_log_open(struct inode *inode, struct file *file)
145 {
146 	file->private_data = inode->i_private;
147 
148 	return nonseekable_open(inode, file);
149 }
150 
151 static ssize_t cros_ec_console_log_read(struct file *file, char __user *buf,
152 					size_t count, loff_t *ppos)
153 {
154 	struct cros_ec_debugfs *debug_info = file->private_data;
155 	struct circ_buf *cb = &debug_info->log_buffer;
156 	ssize_t ret;
157 
158 	mutex_lock(&debug_info->log_mutex);
159 
160 	while (!CIRC_CNT(cb->head, cb->tail, LOG_SIZE)) {
161 		if (file->f_flags & O_NONBLOCK) {
162 			ret = -EAGAIN;
163 			goto error;
164 		}
165 
166 		mutex_unlock(&debug_info->log_mutex);
167 
168 		ret = wait_event_interruptible(debug_info->log_wq,
169 					CIRC_CNT(cb->head, cb->tail, LOG_SIZE));
170 		if (ret < 0)
171 			return ret;
172 
173 		mutex_lock(&debug_info->log_mutex);
174 	}
175 
176 	/* Only copy until the end of the circular buffer, and let userspace
177 	 * retry to get the rest of the data.
178 	 */
179 	ret = min_t(size_t, CIRC_CNT_TO_END(cb->head, cb->tail, LOG_SIZE),
180 		    count);
181 
182 	if (copy_to_user(buf, cb->buf + cb->tail, ret)) {
183 		ret = -EFAULT;
184 		goto error;
185 	}
186 
187 	cb->tail = CIRC_ADD(cb->tail, LOG_SIZE, ret);
188 
189 error:
190 	mutex_unlock(&debug_info->log_mutex);
191 	return ret;
192 }
193 
194 static unsigned int cros_ec_console_log_poll(struct file *file,
195 					     poll_table *wait)
196 {
197 	struct cros_ec_debugfs *debug_info = file->private_data;
198 	unsigned int mask = 0;
199 
200 	poll_wait(file, &debug_info->log_wq, wait);
201 
202 	mutex_lock(&debug_info->log_mutex);
203 	if (CIRC_CNT(debug_info->log_buffer.head,
204 		     debug_info->log_buffer.tail,
205 		     LOG_SIZE))
206 		mask |= POLLIN | POLLRDNORM;
207 	mutex_unlock(&debug_info->log_mutex);
208 
209 	return mask;
210 }
211 
212 static int cros_ec_console_log_release(struct inode *inode, struct file *file)
213 {
214 	return 0;
215 }
216 
217 const struct file_operations cros_ec_console_log_fops = {
218 	.owner = THIS_MODULE,
219 	.open = cros_ec_console_log_open,
220 	.read = cros_ec_console_log_read,
221 	.llseek = no_llseek,
222 	.poll = cros_ec_console_log_poll,
223 	.release = cros_ec_console_log_release,
224 };
225 
226 static int ec_read_version_supported(struct cros_ec_dev *ec)
227 {
228 	struct ec_params_get_cmd_versions_v1 *params;
229 	struct ec_response_get_cmd_versions *response;
230 	int ret;
231 
232 	struct cros_ec_command *msg;
233 
234 	msg = kzalloc(sizeof(*msg) + max(sizeof(*params), sizeof(*response)),
235 		GFP_KERNEL);
236 	if (!msg)
237 		return 0;
238 
239 	msg->command = EC_CMD_GET_CMD_VERSIONS + ec->cmd_offset;
240 	msg->outsize = sizeof(*params);
241 	msg->insize = sizeof(*response);
242 
243 	params = (struct ec_params_get_cmd_versions_v1 *)msg->data;
244 	params->cmd = EC_CMD_CONSOLE_READ;
245 	response = (struct ec_response_get_cmd_versions *)msg->data;
246 
247 	ret = cros_ec_cmd_xfer(ec->ec_dev, msg) >= 0 &&
248 		msg->result == EC_RES_SUCCESS &&
249 		(response->version_mask & EC_VER_MASK(1));
250 
251 	kfree(msg);
252 
253 	return ret;
254 }
255 
256 static int cros_ec_create_console_log(struct cros_ec_debugfs *debug_info)
257 {
258 	struct cros_ec_dev *ec = debug_info->ec;
259 	char *buf;
260 	int read_params_size;
261 	int read_response_size;
262 
263 	if (!ec_read_version_supported(ec)) {
264 		dev_warn(ec->dev,
265 			"device does not support reading the console log\n");
266 		return 0;
267 	}
268 
269 	buf = devm_kzalloc(ec->dev, LOG_SIZE, GFP_KERNEL);
270 	if (!buf)
271 		return -ENOMEM;
272 
273 	read_params_size = sizeof(struct ec_params_console_read_v1);
274 	read_response_size = ec->ec_dev->max_response;
275 	debug_info->read_msg = devm_kzalloc(ec->dev,
276 		sizeof(*debug_info->read_msg) +
277 			max(read_params_size, read_response_size), GFP_KERNEL);
278 	if (!debug_info->read_msg)
279 		return -ENOMEM;
280 
281 	debug_info->read_msg->version = 1;
282 	debug_info->read_msg->command = EC_CMD_CONSOLE_READ + ec->cmd_offset;
283 	debug_info->read_msg->outsize = read_params_size;
284 	debug_info->read_msg->insize = read_response_size;
285 
286 	debug_info->log_buffer.buf = buf;
287 	debug_info->log_buffer.head = 0;
288 	debug_info->log_buffer.tail = 0;
289 
290 	mutex_init(&debug_info->log_mutex);
291 	init_waitqueue_head(&debug_info->log_wq);
292 
293 	if (!debugfs_create_file("console_log",
294 				 S_IFREG | S_IRUGO,
295 				 debug_info->dir,
296 				 debug_info,
297 				 &cros_ec_console_log_fops))
298 		return -ENOMEM;
299 
300 	INIT_DELAYED_WORK(&debug_info->log_poll_work,
301 			  cros_ec_console_log_work);
302 	schedule_delayed_work(&debug_info->log_poll_work, 0);
303 
304 	return 0;
305 }
306 
307 static void cros_ec_cleanup_console_log(struct cros_ec_debugfs *debug_info)
308 {
309 	if (debug_info->log_buffer.buf) {
310 		cancel_delayed_work_sync(&debug_info->log_poll_work);
311 		mutex_destroy(&debug_info->log_mutex);
312 	}
313 }
314 
315 static int cros_ec_create_panicinfo(struct cros_ec_debugfs *debug_info)
316 {
317 	struct cros_ec_device *ec_dev = debug_info->ec->ec_dev;
318 	int ret;
319 	struct cros_ec_command *msg;
320 	int insize;
321 
322 	insize = ec_dev->max_response;
323 
324 	msg = devm_kzalloc(debug_info->ec->dev,
325 			sizeof(*msg) + insize, GFP_KERNEL);
326 	if (!msg)
327 		return -ENOMEM;
328 
329 	msg->command = EC_CMD_GET_PANIC_INFO;
330 	msg->insize = insize;
331 
332 	ret = cros_ec_cmd_xfer(ec_dev, msg);
333 	if (ret < 0) {
334 		dev_warn(debug_info->ec->dev, "Cannot read panicinfo.\n");
335 		ret = 0;
336 		goto free;
337 	}
338 
339 	/* No panic data */
340 	if (ret == 0)
341 		goto free;
342 
343 	debug_info->panicinfo_blob.data = msg->data;
344 	debug_info->panicinfo_blob.size = ret;
345 
346 	if (!debugfs_create_blob("panicinfo",
347 				 S_IFREG | S_IRUGO,
348 				 debug_info->dir,
349 				 &debug_info->panicinfo_blob)) {
350 		ret = -ENOMEM;
351 		goto free;
352 	}
353 
354 	return 0;
355 
356 free:
357 	devm_kfree(debug_info->ec->dev, msg);
358 	return ret;
359 }
360 
361 int cros_ec_debugfs_init(struct cros_ec_dev *ec)
362 {
363 	struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev);
364 	const char *name = ec_platform->ec_name;
365 	struct cros_ec_debugfs *debug_info;
366 	int ret;
367 
368 	debug_info = devm_kzalloc(ec->dev, sizeof(*debug_info), GFP_KERNEL);
369 	if (!debug_info)
370 		return -ENOMEM;
371 
372 	debug_info->ec = ec;
373 	debug_info->dir = debugfs_create_dir(name, NULL);
374 	if (!debug_info->dir)
375 		return -ENOMEM;
376 
377 	ret = cros_ec_create_panicinfo(debug_info);
378 	if (ret)
379 		goto remove_debugfs;
380 
381 	ret = cros_ec_create_console_log(debug_info);
382 	if (ret)
383 		goto remove_debugfs;
384 
385 	ec->debug_info = debug_info;
386 
387 	return 0;
388 
389 remove_debugfs:
390 	debugfs_remove_recursive(debug_info->dir);
391 	return ret;
392 }
393 
394 void cros_ec_debugfs_remove(struct cros_ec_dev *ec)
395 {
396 	if (!ec->debug_info)
397 		return;
398 
399 	debugfs_remove_recursive(ec->debug_info->dir);
400 	cros_ec_cleanup_console_log(ec->debug_info);
401 }
402