staticinlinebool __acpi_aml_access_ok(unsignedlong flag)
{ /* * The debugger interface is in opened state (OPENED && !CLOSED), * then it is allowed to access the debugger buffers from either * user space or the kernel space. * In addition, for the kernel space, only the debugger thread * (thread ID matched) is allowed to access.
*/ if (!(acpi_aml_io.flags & ACPI_AML_OPENED) ||
(acpi_aml_io.flags & ACPI_AML_CLOSED) ||
!__acpi_aml_running()) returnfalse; if ((flag & ACPI_AML_KERN) &&
current != acpi_aml_io.thread) returnfalse; returntrue;
}
staticinlinebool __acpi_aml_readable(struct circ_buf *circ, unsignedlong flag)
{ /* * Another read is not in progress and there is data in buffer * available for read.
*/ if (!(acpi_aml_io.flags & flag) && circ_count(circ)) returntrue; returnfalse;
}
staticinlinebool __acpi_aml_writable(struct circ_buf *circ, unsignedlong flag)
{ /* * Another write is not in progress and there is buffer space * available for write.
*/ if (!(acpi_aml_io.flags & flag) && circ_space(circ)) returntrue; returnfalse;
}
staticinlinebool __acpi_aml_busy(void)
{ if (acpi_aml_io.flags & ACPI_AML_BUSY) returntrue; returnfalse;
}
mutex_lock(&acpi_aml_io.lock);
ret = __acpi_aml_running();
mutex_unlock(&acpi_aml_io.lock); return ret;
}
staticbool acpi_aml_busy(void)
{ bool ret;
mutex_lock(&acpi_aml_io.lock);
ret = __acpi_aml_busy();
mutex_unlock(&acpi_aml_io.lock); return ret;
}
staticbool acpi_aml_used(void)
{ bool ret;
/* * The usage count is prepared to avoid race conditions between the * starts and the stops of the debugger thread.
*/
mutex_lock(&acpi_aml_io.lock);
ret = __acpi_aml_used();
mutex_unlock(&acpi_aml_io.lock); return ret;
}
ret = acpi_aml_lock_read(crc, ACPI_AML_IN_KERN); if (ret < 0) return ret; /* sync head before removing cmds */
smp_rmb();
p = &crc->buf[crc->tail];
ret = (int)*p; /* sync tail before inserting cmds */
smp_mb();
crc->tail = (crc->tail + 1) & (ACPI_AML_BUF_SIZE - 1);
acpi_aml_unlock_fifo(ACPI_AML_IN_KERN, true); return ret;
}
/* * acpi_aml_write_log() - Capture debugger output * @msg: the debugger output * * This function should be used to implement acpi_os_printf() to filter out * the debugger output and store the output into the debugger interface * buffer. Return the size of stored logs or errno.
*/ static ssize_t acpi_aml_write_log(constchar *msg)
{ int ret = 0; int count = 0, size = 0;
if (!acpi_aml_initialized) return -ENODEV; if (msg)
count = strlen(msg); while (count > 0) {
again:
ret = acpi_aml_write_kern(msg + size, count); if (ret == -EAGAIN) {
ret = wait_event_interruptible(acpi_aml_io.wait,
acpi_aml_kern_writable()); /* * We need to retry when the condition * becomes true.
*/ if (ret == 0) goto again; break;
} if (ret < 0) break;
size += ret;
count -= ret;
} return size > 0 ? size : ret;
}
/* * acpi_aml_read_cmd() - Capture debugger input * @msg: the debugger input * @size: the size of the debugger input * * This function should be used to implement acpi_os_get_line() to capture * the debugger input commands and store the input commands into the * debugger interface buffer. Return the size of stored commands or errno.
*/ static ssize_t acpi_aml_read_cmd(char *msg, size_t count)
{ int ret = 0; int size = 0;
/* * This is ensured by the running fact of the debugger thread * unless a bug is introduced.
*/
BUG_ON(!acpi_aml_initialized); while (count > 0) {
again: /* * Check each input byte to find the end of the command.
*/
ret = acpi_aml_readb_kern(); if (ret == -EAGAIN) {
ret = wait_event_interruptible(acpi_aml_io.wait,
acpi_aml_kern_readable()); /* * We need to retry when the condition becomes * true.
*/ if (ret == 0) goto again;
} if (ret < 0) break;
*(msg + size) = (char)ret;
size++;
count--; if (ret == '\n') { /* * acpi_os_get_line() requires a zero terminated command * string.
*/
*(msg + size - 1) = '\0'; break;
}
} return size > 0 ? size : ret;
}
staticint acpi_aml_thread(void *unused)
{
acpi_osd_exec_callback function = NULL; void *context;
mutex_lock(&acpi_aml_io.lock); if (acpi_aml_io.function) {
acpi_aml_io.usages++;
function = acpi_aml_io.function;
context = acpi_aml_io.context;
}
mutex_unlock(&acpi_aml_io.lock);
/* * acpi_aml_create_thread() - Create AML debugger thread * @function: the debugger thread callback * @context: the context to be passed to the debugger thread * * This function should be used to implement acpi_os_execute() which is * used by the ACPICA debugger to create the debugger thread.
*/ staticint acpi_aml_create_thread(acpi_osd_exec_callback function, void *context)
{ struct task_struct *t;
staticint acpi_aml_open(struct inode *inode, struct file *file)
{ int ret = 0;
acpi_status status;
mutex_lock(&acpi_aml_io.lock); /* * The debugger interface is being closed, no new user is allowed * during this period.
*/ if (acpi_aml_io.flags & ACPI_AML_CLOSED) {
ret = -EBUSY; goto err_lock;
} if ((file->f_flags & O_ACCMODE) != O_WRONLY) { /* * Only one reader is allowed to initiate the debugger * thread.
*/ if (acpi_aml_active_reader) {
ret = -EBUSY; goto err_lock;
} else {
pr_debug("Opening debugger reader.\n");
acpi_aml_active_reader = file;
}
} else { /* * No writer is allowed unless the debugger thread is * ready.
*/ if (!(acpi_aml_io.flags & ACPI_AML_OPENED)) {
ret = -ENODEV; goto err_lock;
}
} if (acpi_aml_active_reader == file) {
pr_debug("Opening debugger interface.\n");
mutex_unlock(&acpi_aml_io.lock);
pr_debug("Initializing debugger thread.\n");
status = acpi_initialize_debugger(); if (ACPI_FAILURE(status)) {
pr_err("Failed to initialize debugger.\n");
ret = -EINVAL; goto err_exit;
}
pr_debug("Debugger thread initialized.\n");
/* * Wake up all user space/kernel space blocked * readers/writers.
*/
wake_up_interruptible(&acpi_aml_io.wait);
mutex_unlock(&acpi_aml_io.lock); /* * Wait all user space/kernel space readers/writers to * stop so that ACPICA command loop of the debugger thread * should fail all its command line reads after this point.
*/
wait_event(acpi_aml_io.wait, !acpi_aml_busy());
/* * Then we try to terminate the debugger thread if it is * not terminated.
*/
pr_debug("Terminating debugger thread.\n");
acpi_terminate_debugger();
wait_event(acpi_aml_io.wait, !acpi_aml_used());
pr_debug("Debugger thread terminated.\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.