cros_ec_debugfs.c 13 KB

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