acpi_dbg.c 18 KB

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