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