static int param_set_trace_state(const char *val, struct kernel_param *kp) { int result = 0; if (!strncmp(val, "enable", sizeof("enable") - 1)) { result = acpi_debug_trace(trace_method_name, trace_debug_level, trace_debug_layer, 0); if (result) result = -EBUSY; goto exit; } if (!strncmp(val, "disable", sizeof("disable") - 1)) { int name = 0; result = acpi_debug_trace((char *)&name, trace_debug_level, trace_debug_layer, 0); if (result) result = -EBUSY; goto exit; } if (!strncmp(val, "1", 1)) { result = acpi_debug_trace(trace_method_name, trace_debug_level, trace_debug_layer, 1); if (result) result = -EBUSY; goto exit; } result = -EINVAL; exit: return result; }
void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg) { u32 debug_level = 0; u32 debug_layer = 0; u32 flags = 0; if (enable_arg) { acpi_ut_strupr(enable_arg); } if (once_arg) { acpi_ut_strupr(once_arg); } if (method_arg) { if (acpi_db_trace_method_name) { ACPI_FREE(acpi_db_trace_method_name); acpi_db_trace_method_name = NULL; } acpi_db_trace_method_name = ACPI_ALLOCATE(strlen(method_arg) + 1); if (!acpi_db_trace_method_name) { acpi_os_printf("Failed to allocate method name (%s)\n", method_arg); return; } strcpy(acpi_db_trace_method_name, method_arg); } if (!strcmp(enable_arg, "ENABLE") || !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) { if (!strcmp(enable_arg, "ENABLE")) { /* Inherit current console settings */ debug_level = acpi_gbl_db_console_debug_level; debug_layer = acpi_dbg_layer; } else { /* Restrict console output to trace points only */ debug_level = ACPI_LV_TRACE_POINT; debug_layer = ACPI_EXECUTER; } flags = ACPI_TRACE_ENABLED; if (!strcmp(enable_arg, "OPCODE")) { flags |= ACPI_TRACE_OPCODE; } if (once_arg && !strcmp(once_arg, "ONCE")) { flags |= ACPI_TRACE_ONESHOT; } } (void)acpi_debug_trace(acpi_db_trace_method_name, debug_level, debug_layer, flags); }
static int param_set_trace_state(const char *val, struct kernel_param *kp) { acpi_status status; const char *method = trace_method_name; u32 flags = 0; /* So "xxx-once" comparison should go prior than "xxx" comparison */ #define acpi_compare_param(val, key) \ strncmp((val), (key), sizeof(key) - 1) if (!acpi_compare_param(val, "enable")) { method = NULL; flags = ACPI_TRACE_ENABLED; } else if (!acpi_compare_param(val, "disable")) method = NULL; else if (!acpi_compare_param(val, "method-once")) flags = ACPI_TRACE_ENABLED | ACPI_TRACE_ONESHOT; else if (!acpi_compare_param(val, "method")) flags = ACPI_TRACE_ENABLED; else if (!acpi_compare_param(val, "opcode-once")) flags = ACPI_TRACE_ENABLED | ACPI_TRACE_ONESHOT | ACPI_TRACE_OPCODE; else if (!acpi_compare_param(val, "opcode")) flags = ACPI_TRACE_ENABLED | ACPI_TRACE_OPCODE; else return -EINVAL; status = acpi_debug_trace(method, acpi_gbl_trace_dbg_level, acpi_gbl_trace_dbg_layer, flags); if (ACPI_FAILURE(status)) return -EBUSY; return 0; }
static int param_set_trace_method_name(const char *val, const struct kernel_param *kp) { u32 saved_flags = 0; bool is_abs_path = true; if (*val != '\\') is_abs_path = false; if ((is_abs_path && strlen(val) > 1023) || (!is_abs_path && strlen(val) > 1022)) { pr_err("%s: string parameter too long\n", kp->name); return -ENOSPC; } /* * It's not safe to update acpi_gbl_trace_method_name without * having the tracer stopped, so we save the original tracer * state and disable it. */ saved_flags = acpi_gbl_trace_flags; (void)acpi_debug_trace(NULL, acpi_gbl_trace_dbg_level, acpi_gbl_trace_dbg_layer, 0); /* This is a hack. We can't kmalloc in early boot. */ if (is_abs_path) strcpy(trace_method_name, val); else { trace_method_name[0] = '\\'; strcpy(trace_method_name+1, val); } /* Restore the original tracer state */ (void)acpi_debug_trace(trace_method_name, acpi_gbl_trace_dbg_level, acpi_gbl_trace_dbg_layer, saved_flags); return 0; }