acpi_dbg.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. /*
  2. * ACPI AML interfacing support
  3. *
  4. * Copyright (C) 2015, Intel Corporation
  5. * Authors: Lv Zheng <lv.zheng@intel.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. /* #define DEBUG */
  12. #define pr_fmt(fmt) "ACPI : AML: " fmt
  13. #include <linux/kernel.h>
  14. #include <linux/module.h>
  15. #include <linux/wait.h>
  16. #include <linux/poll.h>
  17. #include <linux/sched.h>
  18. #include <linux/kthread.h>
  19. #include <linux/proc_fs.h>
  20. #include <linux/debugfs.h>
  21. #include <linux/circ_buf.h>
  22. #include <linux/acpi.h>
  23. #include "internal.h"
  24. #define ACPI_AML_BUF_ALIGN (sizeof (acpi_size))
  25. #define ACPI_AML_BUF_SIZE PAGE_SIZE
  26. #define circ_count(circ) \
  27. (CIRC_CNT((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
  28. #define circ_count_to_end(circ) \
  29. (CIRC_CNT_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
  30. #define circ_space(circ) \
  31. (CIRC_SPACE((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
  32. #define circ_space_to_end(circ) \
  33. (CIRC_SPACE_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
  34. #define ACPI_AML_OPENED 0x0001
  35. #define ACPI_AML_CLOSED 0x0002
  36. #define ACPI_AML_IN_USER 0x0004 /* user space is writing cmd */
  37. #define ACPI_AML_IN_KERN 0x0008 /* kernel space is reading cmd */
  38. #define ACPI_AML_OUT_USER 0x0010 /* user space is reading log */
  39. #define ACPI_AML_OUT_KERN 0x0020 /* kernel space is writing log */
  40. #define ACPI_AML_USER (ACPI_AML_IN_USER | ACPI_AML_OUT_USER)
  41. #define ACPI_AML_KERN (ACPI_AML_IN_KERN | ACPI_AML_OUT_KERN)
  42. #define ACPI_AML_BUSY (ACPI_AML_USER | ACPI_AML_KERN)
  43. #define ACPI_AML_OPEN (ACPI_AML_OPENED | ACPI_AML_CLOSED)
  44. struct acpi_aml_io {
  45. wait_queue_head_t wait;
  46. unsigned long flags;
  47. unsigned long users;
  48. struct mutex lock;
  49. struct task_struct *thread;
  50. char out_buf[ACPI_AML_BUF_SIZE] __aligned(ACPI_AML_BUF_ALIGN);
  51. struct circ_buf out_crc;
  52. char in_buf[ACPI_AML_BUF_SIZE] __aligned(ACPI_AML_BUF_ALIGN);
  53. struct circ_buf in_crc;
  54. acpi_osd_exec_callback function;
  55. void *context;
  56. unsigned long usages;
  57. };
  58. static struct acpi_aml_io acpi_aml_io;
  59. static bool acpi_aml_initialized;
  60. static struct file *acpi_aml_active_reader;
  61. static struct dentry *acpi_aml_dentry;
  62. static inline bool __acpi_aml_running(void)
  63. {
  64. return acpi_aml_io.thread ? true : false;
  65. }
  66. static inline bool __acpi_aml_access_ok(unsigned long flag)
  67. {
  68. /*
  69. * The debugger interface is in opened state (OPENED && !CLOSED),
  70. * then it is allowed to access the debugger buffers from either
  71. * user space or the kernel space.
  72. * In addition, for the kernel space, only the debugger thread
  73. * (thread ID matched) is allowed to access.
  74. */
  75. if (!(acpi_aml_io.flags & ACPI_AML_OPENED) ||
  76. (acpi_aml_io.flags & ACPI_AML_CLOSED) ||
  77. !__acpi_aml_running())
  78. return false;
  79. if ((flag & ACPI_AML_KERN) &&
  80. current != acpi_aml_io.thread)
  81. return false;
  82. return true;
  83. }
  84. static inline bool __acpi_aml_readable(struct circ_buf *circ, unsigned long flag)
  85. {
  86. /*
  87. * Another read is not in progress and there is data in buffer
  88. * available for read.
  89. */
  90. if (!(acpi_aml_io.flags & flag) && circ_count(circ))
  91. return true;
  92. return false;
  93. }
  94. static inline bool __acpi_aml_writable(struct circ_buf *circ, unsigned long flag)
  95. {
  96. /*
  97. * Another write is not in progress and there is buffer space
  98. * available for write.
  99. */
  100. if (!(acpi_aml_io.flags & flag) && circ_space(circ))
  101. return true;
  102. return false;
  103. }
  104. static inline bool __acpi_aml_busy(void)
  105. {
  106. if (acpi_aml_io.flags & ACPI_AML_BUSY)
  107. return true;
  108. return false;
  109. }
  110. static inline bool __acpi_aml_opened(void)
  111. {
  112. if (acpi_aml_io.flags & ACPI_AML_OPEN)
  113. return true;
  114. return false;
  115. }
  116. static inline bool __acpi_aml_used(void)
  117. {
  118. return acpi_aml_io.usages ? true : false;
  119. }
  120. static inline bool acpi_aml_running(void)
  121. {
  122. bool ret;
  123. mutex_lock(&acpi_aml_io.lock);
  124. ret = __acpi_aml_running();
  125. mutex_unlock(&acpi_aml_io.lock);
  126. return ret;
  127. }
  128. static bool acpi_aml_busy(void)
  129. {
  130. bool ret;
  131. mutex_lock(&acpi_aml_io.lock);
  132. ret = __acpi_aml_busy();
  133. mutex_unlock(&acpi_aml_io.lock);
  134. return ret;
  135. }
  136. static bool acpi_aml_used(void)
  137. {
  138. bool ret;
  139. /*
  140. * The usage count is prepared to avoid race conditions between the
  141. * starts and the stops of the debugger thread.
  142. */
  143. mutex_lock(&acpi_aml_io.lock);
  144. ret = __acpi_aml_used();
  145. mutex_unlock(&acpi_aml_io.lock);
  146. return ret;
  147. }
  148. static bool acpi_aml_kern_readable(void)
  149. {
  150. bool ret;
  151. mutex_lock(&acpi_aml_io.lock);
  152. ret = !__acpi_aml_access_ok(ACPI_AML_IN_KERN) ||
  153. __acpi_aml_readable(&acpi_aml_io.in_crc, ACPI_AML_IN_KERN);
  154. mutex_unlock(&acpi_aml_io.lock);
  155. return ret;
  156. }
  157. static bool acpi_aml_kern_writable(void)
  158. {
  159. bool ret;
  160. mutex_lock(&acpi_aml_io.lock);
  161. ret = !__acpi_aml_access_ok(ACPI_AML_OUT_KERN) ||
  162. __acpi_aml_writable(&acpi_aml_io.out_crc, ACPI_AML_OUT_KERN);
  163. mutex_unlock(&acpi_aml_io.lock);
  164. return ret;
  165. }
  166. static bool acpi_aml_user_readable(void)
  167. {
  168. bool ret;
  169. mutex_lock(&acpi_aml_io.lock);
  170. ret = !__acpi_aml_access_ok(ACPI_AML_OUT_USER) ||
  171. __acpi_aml_readable(&acpi_aml_io.out_crc, ACPI_AML_OUT_USER);
  172. mutex_unlock(&acpi_aml_io.lock);
  173. return ret;
  174. }
  175. static bool acpi_aml_user_writable(void)
  176. {
  177. bool ret;
  178. mutex_lock(&acpi_aml_io.lock);
  179. ret = !__acpi_aml_access_ok(ACPI_AML_IN_USER) ||
  180. __acpi_aml_writable(&acpi_aml_io.in_crc, ACPI_AML_IN_USER);
  181. mutex_unlock(&acpi_aml_io.lock);
  182. return ret;
  183. }
  184. static int acpi_aml_lock_write(struct circ_buf *circ, unsigned long flag)
  185. {
  186. int ret = 0;
  187. mutex_lock(&acpi_aml_io.lock);
  188. if (!__acpi_aml_access_ok(flag)) {
  189. ret = -EFAULT;
  190. goto out;
  191. }
  192. if (!__acpi_aml_writable(circ, flag)) {
  193. ret = -EAGAIN;
  194. goto out;
  195. }
  196. acpi_aml_io.flags |= flag;
  197. out:
  198. mutex_unlock(&acpi_aml_io.lock);
  199. return ret;
  200. }
  201. static int acpi_aml_lock_read(struct circ_buf *circ, unsigned long flag)
  202. {
  203. int ret = 0;
  204. mutex_lock(&acpi_aml_io.lock);
  205. if (!__acpi_aml_access_ok(flag)) {
  206. ret = -EFAULT;
  207. goto out;
  208. }
  209. if (!__acpi_aml_readable(circ, flag)) {
  210. ret = -EAGAIN;
  211. goto out;
  212. }
  213. acpi_aml_io.flags |= flag;
  214. out:
  215. mutex_unlock(&acpi_aml_io.lock);
  216. return ret;
  217. }
  218. static void acpi_aml_unlock_fifo(unsigned long flag, bool wakeup)
  219. {
  220. mutex_lock(&acpi_aml_io.lock);
  221. acpi_aml_io.flags &= ~flag;
  222. if (wakeup)
  223. wake_up_interruptible(&acpi_aml_io.wait);
  224. mutex_unlock(&acpi_aml_io.lock);
  225. }
  226. static int acpi_aml_write_kern(const char *buf, int len)
  227. {
  228. int ret;
  229. struct circ_buf *crc = &acpi_aml_io.out_crc;
  230. int n;
  231. char *p;
  232. ret = acpi_aml_lock_write(crc, ACPI_AML_OUT_KERN);
  233. if (ret < 0)
  234. return ret;
  235. /* sync tail before inserting logs */
  236. smp_mb();
  237. p = &crc->buf[crc->head];
  238. n = min(len, circ_space_to_end(crc));
  239. memcpy(p, buf, n);
  240. /* sync head after inserting logs */
  241. smp_wmb();
  242. crc->head = (crc->head + n) & (ACPI_AML_BUF_SIZE - 1);
  243. acpi_aml_unlock_fifo(ACPI_AML_OUT_KERN, true);
  244. return n;
  245. }
  246. static int acpi_aml_readb_kern(void)
  247. {
  248. int ret;
  249. struct circ_buf *crc = &acpi_aml_io.in_crc;
  250. char *p;
  251. ret = acpi_aml_lock_read(crc, ACPI_AML_IN_KERN);
  252. if (ret < 0)
  253. return ret;
  254. /* sync head before removing cmds */
  255. smp_rmb();
  256. p = &crc->buf[crc->tail];
  257. ret = (int)*p;
  258. /* sync tail before inserting cmds */
  259. smp_mb();
  260. crc->tail = (crc->tail + 1) & (ACPI_AML_BUF_SIZE - 1);
  261. acpi_aml_unlock_fifo(ACPI_AML_IN_KERN, true);
  262. return ret;
  263. }
  264. /*
  265. * acpi_aml_write_log() - Capture debugger output
  266. * @msg: the debugger output
  267. *
  268. * This function should be used to implement acpi_os_printf() to filter out
  269. * the debugger output and store the output into the debugger interface
  270. * buffer. Return the size of stored logs or errno.
  271. */
  272. static ssize_t acpi_aml_write_log(const char *msg)
  273. {
  274. int ret = 0;
  275. int count = 0, size = 0;
  276. if (!acpi_aml_initialized)
  277. return -ENODEV;
  278. if (msg)
  279. count = strlen(msg);
  280. while (count > 0) {
  281. again:
  282. ret = acpi_aml_write_kern(msg + size, count);
  283. if (ret == -EAGAIN) {
  284. ret = wait_event_interruptible(acpi_aml_io.wait,
  285. acpi_aml_kern_writable());
  286. /*
  287. * We need to retry when the condition
  288. * becomes true.
  289. */
  290. if (ret == 0)
  291. goto again;
  292. break;
  293. }
  294. if (ret < 0)
  295. break;
  296. size += ret;
  297. count -= ret;
  298. }
  299. return size > 0 ? size : ret;
  300. }
  301. /*
  302. * acpi_aml_read_cmd() - Capture debugger input
  303. * @msg: the debugger input
  304. * @size: the size of the debugger input
  305. *
  306. * This function should be used to implement acpi_os_get_line() to capture
  307. * the debugger input commands and store the input commands into the
  308. * debugger interface buffer. Return the size of stored commands or errno.
  309. */
  310. static ssize_t acpi_aml_read_cmd(char *msg, size_t count)
  311. {
  312. int ret = 0;
  313. int size = 0;
  314. /*
  315. * This is ensured by the running fact of the debugger thread
  316. * unless a bug is introduced.
  317. */
  318. BUG_ON(!acpi_aml_initialized);
  319. while (count > 0) {
  320. again:
  321. /*
  322. * Check each input byte to find the end of the command.
  323. */
  324. ret = acpi_aml_readb_kern();
  325. if (ret == -EAGAIN) {
  326. ret = wait_event_interruptible(acpi_aml_io.wait,
  327. acpi_aml_kern_readable());
  328. /*
  329. * We need to retry when the condition becomes
  330. * true.
  331. */
  332. if (ret == 0)
  333. goto again;
  334. }
  335. if (ret < 0)
  336. break;
  337. *(msg + size) = (char)ret;
  338. size++;
  339. count--;
  340. if (ret == '\n') {
  341. /*
  342. * acpi_os_get_line() requires a zero terminated command
  343. * string.
  344. */
  345. *(msg + size - 1) = '\0';
  346. break;
  347. }
  348. }
  349. return size > 0 ? size : ret;
  350. }
  351. static int acpi_aml_thread(void *unsed)
  352. {
  353. acpi_osd_exec_callback function = NULL;
  354. void *context;
  355. mutex_lock(&acpi_aml_io.lock);
  356. if (acpi_aml_io.function) {
  357. acpi_aml_io.usages++;
  358. function = acpi_aml_io.function;
  359. context = acpi_aml_io.context;
  360. }
  361. mutex_unlock(&acpi_aml_io.lock);
  362. if (function)
  363. function(context);
  364. mutex_lock(&acpi_aml_io.lock);
  365. acpi_aml_io.usages--;
  366. if (!__acpi_aml_used()) {
  367. acpi_aml_io.thread = NULL;
  368. wake_up(&acpi_aml_io.wait);
  369. }
  370. mutex_unlock(&acpi_aml_io.lock);
  371. return 0;
  372. }
  373. /*
  374. * acpi_aml_create_thread() - Create AML debugger thread
  375. * @function: the debugger thread callback
  376. * @context: the context to be passed to the debugger thread
  377. *
  378. * This function should be used to implement acpi_os_execute() which is
  379. * used by the ACPICA debugger to create the debugger thread.
  380. */
  381. static int acpi_aml_create_thread(acpi_osd_exec_callback function, void *context)
  382. {
  383. struct task_struct *t;
  384. mutex_lock(&acpi_aml_io.lock);
  385. acpi_aml_io.function = function;
  386. acpi_aml_io.context = context;
  387. mutex_unlock(&acpi_aml_io.lock);
  388. t = kthread_create(acpi_aml_thread, NULL, "aml");
  389. if (IS_ERR(t)) {
  390. pr_err("Failed to create AML debugger thread.\n");
  391. return PTR_ERR(t);
  392. }
  393. mutex_lock(&acpi_aml_io.lock);
  394. acpi_aml_io.thread = t;
  395. acpi_set_debugger_thread_id((acpi_thread_id)(unsigned long)t);
  396. wake_up_process(t);
  397. mutex_unlock(&acpi_aml_io.lock);
  398. return 0;
  399. }
  400. static int acpi_aml_wait_command_ready(bool single_step,
  401. char *buffer, size_t length)
  402. {
  403. acpi_status status;
  404. if (single_step)
  405. acpi_os_printf("\n%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
  406. else
  407. acpi_os_printf("\n%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
  408. status = acpi_os_get_line(buffer, length, NULL);
  409. if (ACPI_FAILURE(status))
  410. return -EINVAL;
  411. return 0;
  412. }
  413. static int acpi_aml_notify_command_complete(void)
  414. {
  415. return 0;
  416. }
  417. static int acpi_aml_open(struct inode *inode, struct file *file)
  418. {
  419. int ret = 0;
  420. acpi_status status;
  421. mutex_lock(&acpi_aml_io.lock);
  422. /*
  423. * The debugger interface is being closed, no new user is allowed
  424. * during this period.
  425. */
  426. if (acpi_aml_io.flags & ACPI_AML_CLOSED) {
  427. ret = -EBUSY;
  428. goto err_lock;
  429. }
  430. if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
  431. /*
  432. * Only one reader is allowed to initiate the debugger
  433. * thread.
  434. */
  435. if (acpi_aml_active_reader) {
  436. ret = -EBUSY;
  437. goto err_lock;
  438. } else {
  439. pr_debug("Opening debugger reader.\n");
  440. acpi_aml_active_reader = file;
  441. }
  442. } else {
  443. /*
  444. * No writer is allowed unless the debugger thread is
  445. * ready.
  446. */
  447. if (!(acpi_aml_io.flags & ACPI_AML_OPENED)) {
  448. ret = -ENODEV;
  449. goto err_lock;
  450. }
  451. }
  452. if (acpi_aml_active_reader == file) {
  453. pr_debug("Opening debugger interface.\n");
  454. mutex_unlock(&acpi_aml_io.lock);
  455. pr_debug("Initializing debugger thread.\n");
  456. status = acpi_initialize_debugger();
  457. if (ACPI_FAILURE(status)) {
  458. pr_err("Failed to initialize debugger.\n");
  459. ret = -EINVAL;
  460. goto err_exit;
  461. }
  462. pr_debug("Debugger thread initialized.\n");
  463. mutex_lock(&acpi_aml_io.lock);
  464. acpi_aml_io.flags |= ACPI_AML_OPENED;
  465. acpi_aml_io.out_crc.head = acpi_aml_io.out_crc.tail = 0;
  466. acpi_aml_io.in_crc.head = acpi_aml_io.in_crc.tail = 0;
  467. pr_debug("Debugger interface opened.\n");
  468. }
  469. acpi_aml_io.users++;
  470. err_lock:
  471. if (ret < 0) {
  472. if (acpi_aml_active_reader == file)
  473. acpi_aml_active_reader = NULL;
  474. }
  475. mutex_unlock(&acpi_aml_io.lock);
  476. err_exit:
  477. return ret;
  478. }
  479. static int acpi_aml_release(struct inode *inode, struct file *file)
  480. {
  481. mutex_lock(&acpi_aml_io.lock);
  482. acpi_aml_io.users--;
  483. if (file == acpi_aml_active_reader) {
  484. pr_debug("Closing debugger reader.\n");
  485. acpi_aml_active_reader = NULL;
  486. pr_debug("Closing debugger interface.\n");
  487. acpi_aml_io.flags |= ACPI_AML_CLOSED;
  488. /*
  489. * Wake up all user space/kernel space blocked
  490. * readers/writers.
  491. */
  492. wake_up_interruptible(&acpi_aml_io.wait);
  493. mutex_unlock(&acpi_aml_io.lock);
  494. /*
  495. * Wait all user space/kernel space readers/writers to
  496. * stop so that ACPICA command loop of the debugger thread
  497. * should fail all its command line reads after this point.
  498. */
  499. wait_event(acpi_aml_io.wait, !acpi_aml_busy());
  500. /*
  501. * Then we try to terminate the debugger thread if it is
  502. * not terminated.
  503. */
  504. pr_debug("Terminating debugger thread.\n");
  505. acpi_terminate_debugger();
  506. wait_event(acpi_aml_io.wait, !acpi_aml_used());
  507. pr_debug("Debugger thread terminated.\n");
  508. mutex_lock(&acpi_aml_io.lock);
  509. acpi_aml_io.flags &= ~ACPI_AML_OPENED;
  510. }
  511. if (acpi_aml_io.users == 0) {
  512. pr_debug("Debugger interface closed.\n");
  513. acpi_aml_io.flags &= ~ACPI_AML_CLOSED;
  514. }
  515. mutex_unlock(&acpi_aml_io.lock);
  516. return 0;
  517. }
  518. static int acpi_aml_read_user(char __user *buf, int len)
  519. {
  520. int ret;
  521. struct circ_buf *crc = &acpi_aml_io.out_crc;
  522. int n;
  523. char *p;
  524. ret = acpi_aml_lock_read(crc, ACPI_AML_OUT_USER);
  525. if (ret < 0)
  526. return ret;
  527. /* sync head before removing logs */
  528. smp_rmb();
  529. p = &crc->buf[crc->tail];
  530. n = min(len, circ_count_to_end(crc));
  531. if (copy_to_user(buf, p, n)) {
  532. ret = -EFAULT;
  533. goto out;
  534. }
  535. /* sync tail after removing logs */
  536. smp_mb();
  537. crc->tail = (crc->tail + n) & (ACPI_AML_BUF_SIZE - 1);
  538. ret = n;
  539. out:
  540. acpi_aml_unlock_fifo(ACPI_AML_OUT_USER, ret >= 0);
  541. return ret;
  542. }
  543. static ssize_t acpi_aml_read(struct file *file, char __user *buf,
  544. size_t count, loff_t *ppos)
  545. {
  546. int ret = 0;
  547. int size = 0;
  548. if (!count)
  549. return 0;
  550. if (!access_ok(VERIFY_WRITE, buf, count))
  551. return -EFAULT;
  552. while (count > 0) {
  553. again:
  554. ret = acpi_aml_read_user(buf + size, count);
  555. if (ret == -EAGAIN) {
  556. if (file->f_flags & O_NONBLOCK)
  557. break;
  558. else {
  559. ret = wait_event_interruptible(acpi_aml_io.wait,
  560. acpi_aml_user_readable());
  561. /*
  562. * We need to retry when the condition
  563. * becomes true.
  564. */
  565. if (ret == 0)
  566. goto again;
  567. }
  568. }
  569. if (ret < 0) {
  570. if (!acpi_aml_running())
  571. ret = 0;
  572. break;
  573. }
  574. if (ret) {
  575. size += ret;
  576. count -= ret;
  577. *ppos += ret;
  578. break;
  579. }
  580. }
  581. return size > 0 ? size : ret;
  582. }
  583. static int acpi_aml_write_user(const char __user *buf, int len)
  584. {
  585. int ret;
  586. struct circ_buf *crc = &acpi_aml_io.in_crc;
  587. int n;
  588. char *p;
  589. ret = acpi_aml_lock_write(crc, ACPI_AML_IN_USER);
  590. if (ret < 0)
  591. return ret;
  592. /* sync tail before inserting cmds */
  593. smp_mb();
  594. p = &crc->buf[crc->head];
  595. n = min(len, circ_space_to_end(crc));
  596. if (copy_from_user(p, buf, n)) {
  597. ret = -EFAULT;
  598. goto out;
  599. }
  600. /* sync head after inserting cmds */
  601. smp_wmb();
  602. crc->head = (crc->head + n) & (ACPI_AML_BUF_SIZE - 1);
  603. ret = n;
  604. out:
  605. acpi_aml_unlock_fifo(ACPI_AML_IN_USER, ret >= 0);
  606. return n;
  607. }
  608. static ssize_t acpi_aml_write(struct file *file, const char __user *buf,
  609. size_t count, loff_t *ppos)
  610. {
  611. int ret = 0;
  612. int size = 0;
  613. if (!count)
  614. return 0;
  615. if (!access_ok(VERIFY_READ, buf, count))
  616. return -EFAULT;
  617. while (count > 0) {
  618. again:
  619. ret = acpi_aml_write_user(buf + size, count);
  620. if (ret == -EAGAIN) {
  621. if (file->f_flags & O_NONBLOCK)
  622. break;
  623. else {
  624. ret = wait_event_interruptible(acpi_aml_io.wait,
  625. acpi_aml_user_writable());
  626. /*
  627. * We need to retry when the condition
  628. * becomes true.
  629. */
  630. if (ret == 0)
  631. goto again;
  632. }
  633. }
  634. if (ret < 0) {
  635. if (!acpi_aml_running())
  636. ret = 0;
  637. break;
  638. }
  639. if (ret) {
  640. size += ret;
  641. count -= ret;
  642. *ppos += ret;
  643. }
  644. }
  645. return size > 0 ? size : ret;
  646. }
  647. static unsigned int acpi_aml_poll(struct file *file, poll_table *wait)
  648. {
  649. int masks = 0;
  650. poll_wait(file, &acpi_aml_io.wait, wait);
  651. if (acpi_aml_user_readable())
  652. masks |= POLLIN | POLLRDNORM;
  653. if (acpi_aml_user_writable())
  654. masks |= POLLOUT | POLLWRNORM;
  655. return masks;
  656. }
  657. static const struct file_operations acpi_aml_operations = {
  658. .read = acpi_aml_read,
  659. .write = acpi_aml_write,
  660. .poll = acpi_aml_poll,
  661. .open = acpi_aml_open,
  662. .release = acpi_aml_release,
  663. .llseek = generic_file_llseek,
  664. };
  665. static const struct acpi_debugger_ops acpi_aml_debugger = {
  666. .create_thread = acpi_aml_create_thread,
  667. .read_cmd = acpi_aml_read_cmd,
  668. .write_log = acpi_aml_write_log,
  669. .wait_command_ready = acpi_aml_wait_command_ready,
  670. .notify_command_complete = acpi_aml_notify_command_complete,
  671. };
  672. int __init acpi_aml_init(void)
  673. {
  674. int ret = 0;
  675. if (!acpi_debugfs_dir) {
  676. ret = -ENOENT;
  677. goto err_exit;
  678. }
  679. /* Initialize AML IO interface */
  680. mutex_init(&acpi_aml_io.lock);
  681. init_waitqueue_head(&acpi_aml_io.wait);
  682. acpi_aml_io.out_crc.buf = acpi_aml_io.out_buf;
  683. acpi_aml_io.in_crc.buf = acpi_aml_io.in_buf;
  684. acpi_aml_dentry = debugfs_create_file("acpidbg",
  685. S_IFREG | S_IRUGO | S_IWUSR,
  686. acpi_debugfs_dir, NULL,
  687. &acpi_aml_operations);
  688. if (acpi_aml_dentry == NULL) {
  689. ret = -ENODEV;
  690. goto err_exit;
  691. }
  692. ret = acpi_register_debugger(THIS_MODULE, &acpi_aml_debugger);
  693. if (ret)
  694. goto err_fs;
  695. acpi_aml_initialized = true;
  696. err_fs:
  697. if (ret) {
  698. debugfs_remove(acpi_aml_dentry);
  699. acpi_aml_dentry = NULL;
  700. }
  701. err_exit:
  702. return ret;
  703. }
  704. void __exit acpi_aml_exit(void)
  705. {
  706. if (acpi_aml_initialized) {
  707. acpi_unregister_debugger(&acpi_aml_debugger);
  708. if (acpi_aml_dentry) {
  709. debugfs_remove(acpi_aml_dentry);
  710. acpi_aml_dentry = NULL;
  711. }
  712. acpi_aml_initialized = false;
  713. }
  714. }
  715. module_init(acpi_aml_init);
  716. module_exit(acpi_aml_exit);
  717. MODULE_AUTHOR("Lv Zheng");
  718. MODULE_DESCRIPTION("ACPI debugger userspace IO driver");
  719. MODULE_LICENSE("GPL");