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