Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ACPI AML interfacing support
0004  *
0005  * Copyright (C) 2015, Intel Corporation
0006  * Authors: Lv Zheng <lv.zheng@intel.com>
0007  */
0008 
0009 /* #define DEBUG */
0010 #define pr_fmt(fmt) "ACPI: AML: " fmt
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/wait.h>
0015 #include <linux/poll.h>
0016 #include <linux/sched.h>
0017 #include <linux/kthread.h>
0018 #include <linux/proc_fs.h>
0019 #include <linux/debugfs.h>
0020 #include <linux/circ_buf.h>
0021 #include <linux/acpi.h>
0022 #include "internal.h"
0023 
0024 #define ACPI_AML_BUF_ALIGN  (sizeof (acpi_size))
0025 #define ACPI_AML_BUF_SIZE   PAGE_SIZE
0026 
0027 #define circ_count(circ) \
0028     (CIRC_CNT((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
0029 #define circ_count_to_end(circ) \
0030     (CIRC_CNT_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
0031 #define circ_space(circ) \
0032     (CIRC_SPACE((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
0033 #define circ_space_to_end(circ) \
0034     (CIRC_SPACE_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
0035 
0036 #define ACPI_AML_OPENED     0x0001
0037 #define ACPI_AML_CLOSED     0x0002
0038 #define ACPI_AML_IN_USER    0x0004 /* user space is writing cmd */
0039 #define ACPI_AML_IN_KERN    0x0008 /* kernel space is reading cmd */
0040 #define ACPI_AML_OUT_USER   0x0010 /* user space is reading log */
0041 #define ACPI_AML_OUT_KERN   0x0020 /* kernel space is writing log */
0042 #define ACPI_AML_USER       (ACPI_AML_IN_USER | ACPI_AML_OUT_USER)
0043 #define ACPI_AML_KERN       (ACPI_AML_IN_KERN | ACPI_AML_OUT_KERN)
0044 #define ACPI_AML_BUSY       (ACPI_AML_USER | ACPI_AML_KERN)
0045 #define ACPI_AML_OPEN       (ACPI_AML_OPENED | ACPI_AML_CLOSED)
0046 
0047 struct acpi_aml_io {
0048     wait_queue_head_t wait;
0049     unsigned long flags;
0050     unsigned long users;
0051     struct mutex lock;
0052     struct task_struct *thread;
0053     char out_buf[ACPI_AML_BUF_SIZE] __aligned(ACPI_AML_BUF_ALIGN);
0054     struct circ_buf out_crc;
0055     char in_buf[ACPI_AML_BUF_SIZE] __aligned(ACPI_AML_BUF_ALIGN);
0056     struct circ_buf in_crc;
0057     acpi_osd_exec_callback function;
0058     void *context;
0059     unsigned long usages;
0060 };
0061 
0062 static struct acpi_aml_io acpi_aml_io;
0063 static bool acpi_aml_initialized;
0064 static struct file *acpi_aml_active_reader;
0065 static struct dentry *acpi_aml_dentry;
0066 
0067 static inline bool __acpi_aml_running(void)
0068 {
0069     return acpi_aml_io.thread ? true : false;
0070 }
0071 
0072 static inline bool __acpi_aml_access_ok(unsigned long flag)
0073 {
0074     /*
0075      * The debugger interface is in opened state (OPENED && !CLOSED),
0076      * then it is allowed to access the debugger buffers from either
0077      * user space or the kernel space.
0078      * In addition, for the kernel space, only the debugger thread
0079      * (thread ID matched) is allowed to access.
0080      */
0081     if (!(acpi_aml_io.flags & ACPI_AML_OPENED) ||
0082         (acpi_aml_io.flags & ACPI_AML_CLOSED) ||
0083         !__acpi_aml_running())
0084         return false;
0085     if ((flag & ACPI_AML_KERN) &&
0086         current != acpi_aml_io.thread)
0087         return false;
0088     return true;
0089 }
0090 
0091 static inline bool __acpi_aml_readable(struct circ_buf *circ, unsigned long flag)
0092 {
0093     /*
0094      * Another read is not in progress and there is data in buffer
0095      * available for read.
0096      */
0097     if (!(acpi_aml_io.flags & flag) && circ_count(circ))
0098         return true;
0099     return false;
0100 }
0101 
0102 static inline bool __acpi_aml_writable(struct circ_buf *circ, unsigned long flag)
0103 {
0104     /*
0105      * Another write is not in progress and there is buffer space
0106      * available for write.
0107      */
0108     if (!(acpi_aml_io.flags & flag) && circ_space(circ))
0109         return true;
0110     return false;
0111 }
0112 
0113 static inline bool __acpi_aml_busy(void)
0114 {
0115     if (acpi_aml_io.flags & ACPI_AML_BUSY)
0116         return true;
0117     return false;
0118 }
0119 
0120 static inline bool __acpi_aml_used(void)
0121 {
0122     return acpi_aml_io.usages ? true : false;
0123 }
0124 
0125 static inline bool acpi_aml_running(void)
0126 {
0127     bool ret;
0128 
0129     mutex_lock(&acpi_aml_io.lock);
0130     ret = __acpi_aml_running();
0131     mutex_unlock(&acpi_aml_io.lock);
0132     return ret;
0133 }
0134 
0135 static bool acpi_aml_busy(void)
0136 {
0137     bool ret;
0138 
0139     mutex_lock(&acpi_aml_io.lock);
0140     ret = __acpi_aml_busy();
0141     mutex_unlock(&acpi_aml_io.lock);
0142     return ret;
0143 }
0144 
0145 static bool acpi_aml_used(void)
0146 {
0147     bool ret;
0148 
0149     /*
0150      * The usage count is prepared to avoid race conditions between the
0151      * starts and the stops of the debugger thread.
0152      */
0153     mutex_lock(&acpi_aml_io.lock);
0154     ret = __acpi_aml_used();
0155     mutex_unlock(&acpi_aml_io.lock);
0156     return ret;
0157 }
0158 
0159 static bool acpi_aml_kern_readable(void)
0160 {
0161     bool ret;
0162 
0163     mutex_lock(&acpi_aml_io.lock);
0164     ret = !__acpi_aml_access_ok(ACPI_AML_IN_KERN) ||
0165           __acpi_aml_readable(&acpi_aml_io.in_crc, ACPI_AML_IN_KERN);
0166     mutex_unlock(&acpi_aml_io.lock);
0167     return ret;
0168 }
0169 
0170 static bool acpi_aml_kern_writable(void)
0171 {
0172     bool ret;
0173 
0174     mutex_lock(&acpi_aml_io.lock);
0175     ret = !__acpi_aml_access_ok(ACPI_AML_OUT_KERN) ||
0176           __acpi_aml_writable(&acpi_aml_io.out_crc, ACPI_AML_OUT_KERN);
0177     mutex_unlock(&acpi_aml_io.lock);
0178     return ret;
0179 }
0180 
0181 static bool acpi_aml_user_readable(void)
0182 {
0183     bool ret;
0184 
0185     mutex_lock(&acpi_aml_io.lock);
0186     ret = !__acpi_aml_access_ok(ACPI_AML_OUT_USER) ||
0187           __acpi_aml_readable(&acpi_aml_io.out_crc, ACPI_AML_OUT_USER);
0188     mutex_unlock(&acpi_aml_io.lock);
0189     return ret;
0190 }
0191 
0192 static bool acpi_aml_user_writable(void)
0193 {
0194     bool ret;
0195 
0196     mutex_lock(&acpi_aml_io.lock);
0197     ret = !__acpi_aml_access_ok(ACPI_AML_IN_USER) ||
0198           __acpi_aml_writable(&acpi_aml_io.in_crc, ACPI_AML_IN_USER);
0199     mutex_unlock(&acpi_aml_io.lock);
0200     return ret;
0201 }
0202 
0203 static int acpi_aml_lock_write(struct circ_buf *circ, unsigned long flag)
0204 {
0205     int ret = 0;
0206 
0207     mutex_lock(&acpi_aml_io.lock);
0208     if (!__acpi_aml_access_ok(flag)) {
0209         ret = -EFAULT;
0210         goto out;
0211     }
0212     if (!__acpi_aml_writable(circ, flag)) {
0213         ret = -EAGAIN;
0214         goto out;
0215     }
0216     acpi_aml_io.flags |= flag;
0217 out:
0218     mutex_unlock(&acpi_aml_io.lock);
0219     return ret;
0220 }
0221 
0222 static int acpi_aml_lock_read(struct circ_buf *circ, unsigned long flag)
0223 {
0224     int ret = 0;
0225 
0226     mutex_lock(&acpi_aml_io.lock);
0227     if (!__acpi_aml_access_ok(flag)) {
0228         ret = -EFAULT;
0229         goto out;
0230     }
0231     if (!__acpi_aml_readable(circ, flag)) {
0232         ret = -EAGAIN;
0233         goto out;
0234     }
0235     acpi_aml_io.flags |= flag;
0236 out:
0237     mutex_unlock(&acpi_aml_io.lock);
0238     return ret;
0239 }
0240 
0241 static void acpi_aml_unlock_fifo(unsigned long flag, bool wakeup)
0242 {
0243     mutex_lock(&acpi_aml_io.lock);
0244     acpi_aml_io.flags &= ~flag;
0245     if (wakeup)
0246         wake_up_interruptible(&acpi_aml_io.wait);
0247     mutex_unlock(&acpi_aml_io.lock);
0248 }
0249 
0250 static int acpi_aml_write_kern(const char *buf, int len)
0251 {
0252     int ret;
0253     struct circ_buf *crc = &acpi_aml_io.out_crc;
0254     int n;
0255     char *p;
0256 
0257     ret = acpi_aml_lock_write(crc, ACPI_AML_OUT_KERN);
0258     if (ret < 0)
0259         return ret;
0260     /* sync tail before inserting logs */
0261     smp_mb();
0262     p = &crc->buf[crc->head];
0263     n = min(len, circ_space_to_end(crc));
0264     memcpy(p, buf, n);
0265     /* sync head after inserting logs */
0266     smp_wmb();
0267     crc->head = (crc->head + n) & (ACPI_AML_BUF_SIZE - 1);
0268     acpi_aml_unlock_fifo(ACPI_AML_OUT_KERN, true);
0269     return n;
0270 }
0271 
0272 static int acpi_aml_readb_kern(void)
0273 {
0274     int ret;
0275     struct circ_buf *crc = &acpi_aml_io.in_crc;
0276     char *p;
0277 
0278     ret = acpi_aml_lock_read(crc, ACPI_AML_IN_KERN);
0279     if (ret < 0)
0280         return ret;
0281     /* sync head before removing cmds */
0282     smp_rmb();
0283     p = &crc->buf[crc->tail];
0284     ret = (int)*p;
0285     /* sync tail before inserting cmds */
0286     smp_mb();
0287     crc->tail = (crc->tail + 1) & (ACPI_AML_BUF_SIZE - 1);
0288     acpi_aml_unlock_fifo(ACPI_AML_IN_KERN, true);
0289     return ret;
0290 }
0291 
0292 /*
0293  * acpi_aml_write_log() - Capture debugger output
0294  * @msg: the debugger output
0295  *
0296  * This function should be used to implement acpi_os_printf() to filter out
0297  * the debugger output and store the output into the debugger interface
0298  * buffer. Return the size of stored logs or errno.
0299  */
0300 static ssize_t acpi_aml_write_log(const char *msg)
0301 {
0302     int ret = 0;
0303     int count = 0, size = 0;
0304 
0305     if (!acpi_aml_initialized)
0306         return -ENODEV;
0307     if (msg)
0308         count = strlen(msg);
0309     while (count > 0) {
0310 again:
0311         ret = acpi_aml_write_kern(msg + size, count);
0312         if (ret == -EAGAIN) {
0313             ret = wait_event_interruptible(acpi_aml_io.wait,
0314                 acpi_aml_kern_writable());
0315             /*
0316              * We need to retry when the condition
0317              * becomes true.
0318              */
0319             if (ret == 0)
0320                 goto again;
0321             break;
0322         }
0323         if (ret < 0)
0324             break;
0325         size += ret;
0326         count -= ret;
0327     }
0328     return size > 0 ? size : ret;
0329 }
0330 
0331 /*
0332  * acpi_aml_read_cmd() - Capture debugger input
0333  * @msg: the debugger input
0334  * @size: the size of the debugger input
0335  *
0336  * This function should be used to implement acpi_os_get_line() to capture
0337  * the debugger input commands and store the input commands into the
0338  * debugger interface buffer. Return the size of stored commands or errno.
0339  */
0340 static ssize_t acpi_aml_read_cmd(char *msg, size_t count)
0341 {
0342     int ret = 0;
0343     int size = 0;
0344 
0345     /*
0346      * This is ensured by the running fact of the debugger thread
0347      * unless a bug is introduced.
0348      */
0349     BUG_ON(!acpi_aml_initialized);
0350     while (count > 0) {
0351 again:
0352         /*
0353          * Check each input byte to find the end of the command.
0354          */
0355         ret = acpi_aml_readb_kern();
0356         if (ret == -EAGAIN) {
0357             ret = wait_event_interruptible(acpi_aml_io.wait,
0358                 acpi_aml_kern_readable());
0359             /*
0360              * We need to retry when the condition becomes
0361              * true.
0362              */
0363             if (ret == 0)
0364                 goto again;
0365         }
0366         if (ret < 0)
0367             break;
0368         *(msg + size) = (char)ret;
0369         size++;
0370         count--;
0371         if (ret == '\n') {
0372             /*
0373              * acpi_os_get_line() requires a zero terminated command
0374              * string.
0375              */
0376             *(msg + size - 1) = '\0';
0377             break;
0378         }
0379     }
0380     return size > 0 ? size : ret;
0381 }
0382 
0383 static int acpi_aml_thread(void *unused)
0384 {
0385     acpi_osd_exec_callback function = NULL;
0386     void *context;
0387 
0388     mutex_lock(&acpi_aml_io.lock);
0389     if (acpi_aml_io.function) {
0390         acpi_aml_io.usages++;
0391         function = acpi_aml_io.function;
0392         context = acpi_aml_io.context;
0393     }
0394     mutex_unlock(&acpi_aml_io.lock);
0395 
0396     if (function)
0397         function(context);
0398 
0399     mutex_lock(&acpi_aml_io.lock);
0400     acpi_aml_io.usages--;
0401     if (!__acpi_aml_used()) {
0402         acpi_aml_io.thread = NULL;
0403         wake_up(&acpi_aml_io.wait);
0404     }
0405     mutex_unlock(&acpi_aml_io.lock);
0406 
0407     return 0;
0408 }
0409 
0410 /*
0411  * acpi_aml_create_thread() - Create AML debugger thread
0412  * @function: the debugger thread callback
0413  * @context: the context to be passed to the debugger thread
0414  *
0415  * This function should be used to implement acpi_os_execute() which is
0416  * used by the ACPICA debugger to create the debugger thread.
0417  */
0418 static int acpi_aml_create_thread(acpi_osd_exec_callback function, void *context)
0419 {
0420     struct task_struct *t;
0421 
0422     mutex_lock(&acpi_aml_io.lock);
0423     acpi_aml_io.function = function;
0424     acpi_aml_io.context = context;
0425     mutex_unlock(&acpi_aml_io.lock);
0426 
0427     t = kthread_create(acpi_aml_thread, NULL, "aml");
0428     if (IS_ERR(t)) {
0429         pr_err("Failed to create AML debugger thread.\n");
0430         return PTR_ERR(t);
0431     }
0432 
0433     mutex_lock(&acpi_aml_io.lock);
0434     acpi_aml_io.thread = t;
0435     acpi_set_debugger_thread_id((acpi_thread_id)(unsigned long)t);
0436     wake_up_process(t);
0437     mutex_unlock(&acpi_aml_io.lock);
0438     return 0;
0439 }
0440 
0441 static int acpi_aml_wait_command_ready(bool single_step,
0442                        char *buffer, size_t length)
0443 {
0444     acpi_status status;
0445 
0446     if (single_step)
0447         acpi_os_printf("\n%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
0448     else
0449         acpi_os_printf("\n%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
0450 
0451     status = acpi_os_get_line(buffer, length, NULL);
0452     if (ACPI_FAILURE(status))
0453         return -EINVAL;
0454     return 0;
0455 }
0456 
0457 static int acpi_aml_notify_command_complete(void)
0458 {
0459     return 0;
0460 }
0461 
0462 static int acpi_aml_open(struct inode *inode, struct file *file)
0463 {
0464     int ret = 0;
0465     acpi_status status;
0466 
0467     mutex_lock(&acpi_aml_io.lock);
0468     /*
0469      * The debugger interface is being closed, no new user is allowed
0470      * during this period.
0471      */
0472     if (acpi_aml_io.flags & ACPI_AML_CLOSED) {
0473         ret = -EBUSY;
0474         goto err_lock;
0475     }
0476     if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
0477         /*
0478          * Only one reader is allowed to initiate the debugger
0479          * thread.
0480          */
0481         if (acpi_aml_active_reader) {
0482             ret = -EBUSY;
0483             goto err_lock;
0484         } else {
0485             pr_debug("Opening debugger reader.\n");
0486             acpi_aml_active_reader = file;
0487         }
0488     } else {
0489         /*
0490          * No writer is allowed unless the debugger thread is
0491          * ready.
0492          */
0493         if (!(acpi_aml_io.flags & ACPI_AML_OPENED)) {
0494             ret = -ENODEV;
0495             goto err_lock;
0496         }
0497     }
0498     if (acpi_aml_active_reader == file) {
0499         pr_debug("Opening debugger interface.\n");
0500         mutex_unlock(&acpi_aml_io.lock);
0501 
0502         pr_debug("Initializing debugger thread.\n");
0503         status = acpi_initialize_debugger();
0504         if (ACPI_FAILURE(status)) {
0505             pr_err("Failed to initialize debugger.\n");
0506             ret = -EINVAL;
0507             goto err_exit;
0508         }
0509         pr_debug("Debugger thread initialized.\n");
0510 
0511         mutex_lock(&acpi_aml_io.lock);
0512         acpi_aml_io.flags |= ACPI_AML_OPENED;
0513         acpi_aml_io.out_crc.head = acpi_aml_io.out_crc.tail = 0;
0514         acpi_aml_io.in_crc.head = acpi_aml_io.in_crc.tail = 0;
0515         pr_debug("Debugger interface opened.\n");
0516     }
0517     acpi_aml_io.users++;
0518 err_lock:
0519     if (ret < 0) {
0520         if (acpi_aml_active_reader == file)
0521             acpi_aml_active_reader = NULL;
0522     }
0523     mutex_unlock(&acpi_aml_io.lock);
0524 err_exit:
0525     return ret;
0526 }
0527 
0528 static int acpi_aml_release(struct inode *inode, struct file *file)
0529 {
0530     mutex_lock(&acpi_aml_io.lock);
0531     acpi_aml_io.users--;
0532     if (file == acpi_aml_active_reader) {
0533         pr_debug("Closing debugger reader.\n");
0534         acpi_aml_active_reader = NULL;
0535 
0536         pr_debug("Closing debugger interface.\n");
0537         acpi_aml_io.flags |= ACPI_AML_CLOSED;
0538 
0539         /*
0540          * Wake up all user space/kernel space blocked
0541          * readers/writers.
0542          */
0543         wake_up_interruptible(&acpi_aml_io.wait);
0544         mutex_unlock(&acpi_aml_io.lock);
0545         /*
0546          * Wait all user space/kernel space readers/writers to
0547          * stop so that ACPICA command loop of the debugger thread
0548          * should fail all its command line reads after this point.
0549          */
0550         wait_event(acpi_aml_io.wait, !acpi_aml_busy());
0551 
0552         /*
0553          * Then we try to terminate the debugger thread if it is
0554          * not terminated.
0555          */
0556         pr_debug("Terminating debugger thread.\n");
0557         acpi_terminate_debugger();
0558         wait_event(acpi_aml_io.wait, !acpi_aml_used());
0559         pr_debug("Debugger thread terminated.\n");
0560 
0561         mutex_lock(&acpi_aml_io.lock);
0562         acpi_aml_io.flags &= ~ACPI_AML_OPENED;
0563     }
0564     if (acpi_aml_io.users == 0) {
0565         pr_debug("Debugger interface closed.\n");
0566         acpi_aml_io.flags &= ~ACPI_AML_CLOSED;
0567     }
0568     mutex_unlock(&acpi_aml_io.lock);
0569     return 0;
0570 }
0571 
0572 static int acpi_aml_read_user(char __user *buf, int len)
0573 {
0574     int ret;
0575     struct circ_buf *crc = &acpi_aml_io.out_crc;
0576     int n;
0577     char *p;
0578 
0579     ret = acpi_aml_lock_read(crc, ACPI_AML_OUT_USER);
0580     if (ret < 0)
0581         return ret;
0582     /* sync head before removing logs */
0583     smp_rmb();
0584     p = &crc->buf[crc->tail];
0585     n = min(len, circ_count_to_end(crc));
0586     if (copy_to_user(buf, p, n)) {
0587         ret = -EFAULT;
0588         goto out;
0589     }
0590     /* sync tail after removing logs */
0591     smp_mb();
0592     crc->tail = (crc->tail + n) & (ACPI_AML_BUF_SIZE - 1);
0593     ret = n;
0594 out:
0595     acpi_aml_unlock_fifo(ACPI_AML_OUT_USER, ret >= 0);
0596     return ret;
0597 }
0598 
0599 static ssize_t acpi_aml_read(struct file *file, char __user *buf,
0600                  size_t count, loff_t *ppos)
0601 {
0602     int ret = 0;
0603     int size = 0;
0604 
0605     if (!count)
0606         return 0;
0607     if (!access_ok(buf, count))
0608         return -EFAULT;
0609 
0610     while (count > 0) {
0611 again:
0612         ret = acpi_aml_read_user(buf + size, count);
0613         if (ret == -EAGAIN) {
0614             if (file->f_flags & O_NONBLOCK)
0615                 break;
0616             else {
0617                 ret = wait_event_interruptible(acpi_aml_io.wait,
0618                     acpi_aml_user_readable());
0619                 /*
0620                  * We need to retry when the condition
0621                  * becomes true.
0622                  */
0623                 if (ret == 0)
0624                     goto again;
0625             }
0626         }
0627         if (ret < 0) {
0628             if (!acpi_aml_running())
0629                 ret = 0;
0630             break;
0631         }
0632         if (ret) {
0633             size += ret;
0634             count -= ret;
0635             *ppos += ret;
0636             break;
0637         }
0638     }
0639     return size > 0 ? size : ret;
0640 }
0641 
0642 static int acpi_aml_write_user(const char __user *buf, int len)
0643 {
0644     int ret;
0645     struct circ_buf *crc = &acpi_aml_io.in_crc;
0646     int n;
0647     char *p;
0648 
0649     ret = acpi_aml_lock_write(crc, ACPI_AML_IN_USER);
0650     if (ret < 0)
0651         return ret;
0652     /* sync tail before inserting cmds */
0653     smp_mb();
0654     p = &crc->buf[crc->head];
0655     n = min(len, circ_space_to_end(crc));
0656     if (copy_from_user(p, buf, n)) {
0657         ret = -EFAULT;
0658         goto out;
0659     }
0660     /* sync head after inserting cmds */
0661     smp_wmb();
0662     crc->head = (crc->head + n) & (ACPI_AML_BUF_SIZE - 1);
0663     ret = n;
0664 out:
0665     acpi_aml_unlock_fifo(ACPI_AML_IN_USER, ret >= 0);
0666     return n;
0667 }
0668 
0669 static ssize_t acpi_aml_write(struct file *file, const char __user *buf,
0670                   size_t count, loff_t *ppos)
0671 {
0672     int ret = 0;
0673     int size = 0;
0674 
0675     if (!count)
0676         return 0;
0677     if (!access_ok(buf, count))
0678         return -EFAULT;
0679 
0680     while (count > 0) {
0681 again:
0682         ret = acpi_aml_write_user(buf + size, count);
0683         if (ret == -EAGAIN) {
0684             if (file->f_flags & O_NONBLOCK)
0685                 break;
0686             else {
0687                 ret = wait_event_interruptible(acpi_aml_io.wait,
0688                     acpi_aml_user_writable());
0689                 /*
0690                  * We need to retry when the condition
0691                  * becomes true.
0692                  */
0693                 if (ret == 0)
0694                     goto again;
0695             }
0696         }
0697         if (ret < 0) {
0698             if (!acpi_aml_running())
0699                 ret = 0;
0700             break;
0701         }
0702         if (ret) {
0703             size += ret;
0704             count -= ret;
0705             *ppos += ret;
0706         }
0707     }
0708     return size > 0 ? size : ret;
0709 }
0710 
0711 static __poll_t acpi_aml_poll(struct file *file, poll_table *wait)
0712 {
0713     __poll_t masks = 0;
0714 
0715     poll_wait(file, &acpi_aml_io.wait, wait);
0716     if (acpi_aml_user_readable())
0717         masks |= EPOLLIN | EPOLLRDNORM;
0718     if (acpi_aml_user_writable())
0719         masks |= EPOLLOUT | EPOLLWRNORM;
0720 
0721     return masks;
0722 }
0723 
0724 static const struct file_operations acpi_aml_operations = {
0725     .read       = acpi_aml_read,
0726     .write      = acpi_aml_write,
0727     .poll       = acpi_aml_poll,
0728     .open       = acpi_aml_open,
0729     .release    = acpi_aml_release,
0730     .llseek     = generic_file_llseek,
0731 };
0732 
0733 static const struct acpi_debugger_ops acpi_aml_debugger = {
0734     .create_thread       = acpi_aml_create_thread,
0735     .read_cmd        = acpi_aml_read_cmd,
0736     .write_log       = acpi_aml_write_log,
0737     .wait_command_ready  = acpi_aml_wait_command_ready,
0738     .notify_command_complete = acpi_aml_notify_command_complete,
0739 };
0740 
0741 static int __init acpi_aml_init(void)
0742 {
0743     int ret;
0744 
0745     if (acpi_disabled)
0746         return -ENODEV;
0747 
0748     /* Initialize AML IO interface */
0749     mutex_init(&acpi_aml_io.lock);
0750     init_waitqueue_head(&acpi_aml_io.wait);
0751     acpi_aml_io.out_crc.buf = acpi_aml_io.out_buf;
0752     acpi_aml_io.in_crc.buf = acpi_aml_io.in_buf;
0753 
0754     acpi_aml_dentry = debugfs_create_file("acpidbg",
0755                           S_IFREG | S_IRUGO | S_IWUSR,
0756                           acpi_debugfs_dir, NULL,
0757                           &acpi_aml_operations);
0758 
0759     ret = acpi_register_debugger(THIS_MODULE, &acpi_aml_debugger);
0760     if (ret) {
0761         debugfs_remove(acpi_aml_dentry);
0762         acpi_aml_dentry = NULL;
0763         return ret;
0764     }
0765 
0766     acpi_aml_initialized = true;
0767     return 0;
0768 }
0769 
0770 static void __exit acpi_aml_exit(void)
0771 {
0772     if (acpi_aml_initialized) {
0773         acpi_unregister_debugger(&acpi_aml_debugger);
0774         debugfs_remove(acpi_aml_dentry);
0775         acpi_aml_dentry = NULL;
0776         acpi_aml_initialized = false;
0777     }
0778 }
0779 
0780 module_init(acpi_aml_init);
0781 module_exit(acpi_aml_exit);
0782 
0783 MODULE_AUTHOR("Lv Zheng");
0784 MODULE_DESCRIPTION("ACPI debugger userspace IO driver");
0785 MODULE_LICENSE("GPL");