summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/osl.c
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2010-12-09 16:51:06 +0800
committerLen Brown <len.brown@intel.com>2010-12-11 01:31:01 -0500
commit12d3206466d2074ef0684aaf7759ae01a0a92560 (patch)
treef653b9a36f2d6ec122aa85035cd5a0ae96314ce4 /drivers/acpi/osl.c
parentd90aa92c0c1625d7f02050e4d2924805840cda3d (diff)
downloadlinux-12d3206466d2074ef0684aaf7759ae01a0a92560.tar.bz2
ACPI: fix allowing to add/remove multiple _OSI strings
commit b0ed7a91(ACPICA/ACPI: Add new host interfaces for _OSI suppor) introduced another regression that only one _OSI string can be added or removed. Now multiple _OSI strings can be added or removed, for example acpi_osi=Linux acpi_osi=FreeBSD acpi_osi="!Windows 2006" Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r--drivers/acpi/osl.c66
1 files changed, 50 insertions, 16 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 6867443c4941..d0a1bb54367b 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -110,9 +110,6 @@ struct acpi_ioremap {
static LIST_HEAD(acpi_ioremaps);
static DEFINE_SPINLOCK(acpi_ioremap_lock);
-#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
-static char osi_setup_string[OSI_STRING_LENGTH_MAX];
-
static void __init acpi_osi_setup_late(void);
/*
@@ -1054,16 +1051,47 @@ static int __init acpi_os_name_setup(char *str)
__setup("acpi_os_name=", acpi_os_name_setup);
+#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
+#define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */
+
+struct osi_setup_entry {
+ char string[OSI_STRING_LENGTH_MAX];
+ bool enable;
+};
+
+static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX];
+
void __init acpi_osi_setup(char *str)
{
+ struct osi_setup_entry *osi;
+ bool enable = true;
+ int i;
+
if (!acpi_gbl_create_osi_method)
return;
if (str == NULL || *str == '\0') {
printk(KERN_INFO PREFIX "_OSI method disabled\n");
acpi_gbl_create_osi_method = FALSE;
- } else
- strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX);
+ return;
+ }
+
+ if (*str == '!') {
+ str++;
+ enable = false;
+ }
+
+ for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+ osi = &osi_setup_entries[i];
+ if (!strcmp(osi->string, str)) {
+ osi->enable = enable;
+ break;
+ } else if (osi->string[0] == '\0') {
+ osi->enable = enable;
+ strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
+ break;
+ }
+ }
}
static void __init set_osi_linux(unsigned int enable)
@@ -1110,22 +1138,28 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
*/
static void __init acpi_osi_setup_late(void)
{
- char *str = osi_setup_string;
+ struct osi_setup_entry *osi;
+ char *str;
+ int i;
acpi_status status;
- if (*str == '\0')
- return;
+ for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+ osi = &osi_setup_entries[i];
+ str = osi->string;
- if (*str == '!') {
- status = acpi_remove_interface(++str);
+ if (*str == '\0')
+ break;
+ if (osi->enable) {
+ status = acpi_install_interface(str);
- if (ACPI_SUCCESS(status))
- printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
- } else {
- status = acpi_install_interface(str);
+ if (ACPI_SUCCESS(status))
+ printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+ } else {
+ status = acpi_remove_interface(str);
- if (ACPI_SUCCESS(status))
- printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+ if (ACPI_SUCCESS(status))
+ printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
+ }
}
}