diff options
author | Toshi Kani <toshi.kani@hp.com> | 2012-11-20 20:36:28 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2012-11-21 17:20:22 -0500 |
commit | fbfddae696572e57a441252abbd65f7220e06030 (patch) | |
tree | cdd75792b688eb816e32b55b499479de45d5d4c5 | |
parent | b59bc2fbb4bb67e486c40cdb6a306c06acbaec06 (diff) |
ACPI: Add acpi_handle_<level>() interfaces
This patch introduces acpi_handle_<level>(), where <level> is
a kernel message level such as err/warn/info, to support improved
logging messages for ACPI, esp. hot-plug operations.
acpi_handle_<level>() appends "ACPI" prefix and ACPI object path
to the messages. This improves diagnosis of hotplug operations
since an error message in a log file identifies an object that
caused an issue. This interface acquires the global namespace
mutex to obtain an object path. In interrupt context, it shows
the object path as <n/a>.
acpi_handle_<level>() takes acpi_handle as an argument, which is
passed to ACPI hotplug notify handlers from the ACPICA. Therefore,
it is always available unlike other kernel objects, such as device.
For example:
acpi_handle_err(handle, "Device don't exist, dropping EJECT\n");
logs an error message like this at KERN_ERR.
ACPI: \_SB_.SCK4.CPU4: Device don't exist, dropping EJECT
ACPI hot-plug drivers can use acpi_handle_<level>() when they need
to identify a target ACPI object path in their messages, such as
error cases. The usage model is similar to dev_<level>().
acpi_handle_<level>() can be used when a device is not created or
is invalid during hot-plug operations. ACPI object path is also
consistent on the platform, unlike device name that gets incremented
over hotplug operations.
ACPI drivers should use dev_<level>() when a device object is valid.
Device name provides more user friendly information, and avoids
acquiring the global ACPI namespace mutex. ACPI drivers also
continue to use pr_<level>() when they do not need to specify device
information, such as boot-up messages.
Note: ACPI_[WARNING|INFO|ERROR]() are intended for the ACPICA and
are not associated with the kernel message level.
Signed-off-by: Toshi Kani <toshi.kani@hp.com>
Tested-by: Vijay Mohan Pandarathil <vijaymohan.pandarathil@hp.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/acpi/utils.c | 38 | ||||
-rw-r--r-- | include/linux/acpi.h | 43 |
2 files changed, 81 insertions, 0 deletions
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 462f7e300363..744371304313 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/hardirq.h> | ||
32 | #include <linux/acpi.h> | ||
31 | #include <acpi/acpi_bus.h> | 33 | #include <acpi/acpi_bus.h> |
32 | #include <acpi/acpi_drivers.h> | 34 | #include <acpi/acpi_drivers.h> |
33 | 35 | ||
@@ -457,3 +459,39 @@ acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, | |||
457 | #endif | 459 | #endif |
458 | } | 460 | } |
459 | EXPORT_SYMBOL(acpi_evaluate_hotplug_ost); | 461 | EXPORT_SYMBOL(acpi_evaluate_hotplug_ost); |
462 | |||
463 | /** | ||
464 | * acpi_handle_printk: Print message with ACPI prefix and object path | ||
465 | * | ||
466 | * This function is called through acpi_handle_<level> macros and prints | ||
467 | * a message with ACPI prefix and object path. This function acquires | ||
468 | * the global namespace mutex to obtain an object path. In interrupt | ||
469 | * context, it shows the object path as <n/a>. | ||
470 | */ | ||
471 | void | ||
472 | acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...) | ||
473 | { | ||
474 | struct va_format vaf; | ||
475 | va_list args; | ||
476 | struct acpi_buffer buffer = { | ||
477 | .length = ACPI_ALLOCATE_BUFFER, | ||
478 | .pointer = NULL | ||
479 | }; | ||
480 | const char *path; | ||
481 | |||
482 | va_start(args, fmt); | ||
483 | vaf.fmt = fmt; | ||
484 | vaf.va = &args; | ||
485 | |||
486 | if (in_interrupt() || | ||
487 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK) | ||
488 | path = "<n/a>"; | ||
489 | else | ||
490 | path = buffer.pointer; | ||
491 | |||
492 | printk("%sACPI: %s: %pV", level, path, &vaf); | ||
493 | |||
494 | va_end(args); | ||
495 | kfree(buffer.pointer); | ||
496 | } | ||
497 | EXPORT_SYMBOL(acpi_handle_printk); | ||
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 87edfcc0ab62..9201ac1f0511 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -434,4 +434,47 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state, | |||
434 | #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0) | 434 | #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0) |
435 | #endif | 435 | #endif |
436 | 436 | ||
437 | #ifdef CONFIG_ACPI | ||
438 | __printf(3, 4) | ||
439 | void acpi_handle_printk(const char *level, acpi_handle handle, | ||
440 | const char *fmt, ...); | ||
441 | #else /* !CONFIG_ACPI */ | ||
442 | static inline __printf(3, 4) void | ||
443 | acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {} | ||
444 | #endif /* !CONFIG_ACPI */ | ||
445 | |||
446 | /* | ||
447 | * acpi_handle_<level>: Print message with ACPI prefix and object path | ||
448 | * | ||
449 | * These interfaces acquire the global namespace mutex to obtain an object | ||
450 | * path. In interrupt context, it shows the object path as <n/a>. | ||
451 | */ | ||
452 | #define acpi_handle_emerg(handle, fmt, ...) \ | ||
453 | acpi_handle_printk(KERN_EMERG, handle, fmt, ##__VA_ARGS__) | ||
454 | #define acpi_handle_alert(handle, fmt, ...) \ | ||
455 | acpi_handle_printk(KERN_ALERT, handle, fmt, ##__VA_ARGS__) | ||
456 | #define acpi_handle_crit(handle, fmt, ...) \ | ||
457 | acpi_handle_printk(KERN_CRIT, handle, fmt, ##__VA_ARGS__) | ||
458 | #define acpi_handle_err(handle, fmt, ...) \ | ||
459 | acpi_handle_printk(KERN_ERR, handle, fmt, ##__VA_ARGS__) | ||
460 | #define acpi_handle_warn(handle, fmt, ...) \ | ||
461 | acpi_handle_printk(KERN_WARNING, handle, fmt, ##__VA_ARGS__) | ||
462 | #define acpi_handle_notice(handle, fmt, ...) \ | ||
463 | acpi_handle_printk(KERN_NOTICE, handle, fmt, ##__VA_ARGS__) | ||
464 | #define acpi_handle_info(handle, fmt, ...) \ | ||
465 | acpi_handle_printk(KERN_INFO, handle, fmt, ##__VA_ARGS__) | ||
466 | |||
467 | /* REVISIT: Support CONFIG_DYNAMIC_DEBUG when necessary */ | ||
468 | #if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) | ||
469 | #define acpi_handle_debug(handle, fmt, ...) \ | ||
470 | acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__) | ||
471 | #else | ||
472 | #define acpi_handle_debug(handle, fmt, ...) \ | ||
473 | ({ \ | ||
474 | if (0) \ | ||
475 | acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__); \ | ||
476 | 0; \ | ||
477 | }) | ||
478 | #endif | ||
479 | |||
437 | #endif /*_LINUX_ACPI_H*/ | 480 | #endif /*_LINUX_ACPI_H*/ |