diff options
author | Lin Ming <ming.m.lin@intel.com> | 2010-12-09 03:51:06 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-12-11 01:31:01 -0500 |
commit | 12d3206466d2074ef0684aaf7759ae01a0a92560 (patch) | |
tree | f653b9a36f2d6ec122aa85035cd5a0ae96314ce4 /drivers/acpi/osl.c | |
parent | d90aa92c0c1625d7f02050e4d2924805840cda3d (diff) |
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.c | 66 |
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 { | |||
110 | static LIST_HEAD(acpi_ioremaps); | 110 | static LIST_HEAD(acpi_ioremaps); |
111 | static DEFINE_SPINLOCK(acpi_ioremap_lock); | 111 | static DEFINE_SPINLOCK(acpi_ioremap_lock); |
112 | 112 | ||
113 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
114 | static char osi_setup_string[OSI_STRING_LENGTH_MAX]; | ||
115 | |||
116 | static void __init acpi_osi_setup_late(void); | 113 | static void __init acpi_osi_setup_late(void); |
117 | 114 | ||
118 | /* | 115 | /* |
@@ -1054,16 +1051,47 @@ static int __init acpi_os_name_setup(char *str) | |||
1054 | 1051 | ||
1055 | __setup("acpi_os_name=", acpi_os_name_setup); | 1052 | __setup("acpi_os_name=", acpi_os_name_setup); |
1056 | 1053 | ||
1054 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
1055 | #define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */ | ||
1056 | |||
1057 | struct osi_setup_entry { | ||
1058 | char string[OSI_STRING_LENGTH_MAX]; | ||
1059 | bool enable; | ||
1060 | }; | ||
1061 | |||
1062 | static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX]; | ||
1063 | |||
1057 | void __init acpi_osi_setup(char *str) | 1064 | void __init acpi_osi_setup(char *str) |
1058 | { | 1065 | { |
1066 | struct osi_setup_entry *osi; | ||
1067 | bool enable = true; | ||
1068 | int i; | ||
1069 | |||
1059 | if (!acpi_gbl_create_osi_method) | 1070 | if (!acpi_gbl_create_osi_method) |
1060 | return; | 1071 | return; |
1061 | 1072 | ||
1062 | if (str == NULL || *str == '\0') { | 1073 | if (str == NULL || *str == '\0') { |
1063 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | 1074 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); |
1064 | acpi_gbl_create_osi_method = FALSE; | 1075 | acpi_gbl_create_osi_method = FALSE; |
1065 | } else | 1076 | return; |
1066 | strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); | 1077 | } |
1078 | |||
1079 | if (*str == '!') { | ||
1080 | str++; | ||
1081 | enable = false; | ||
1082 | } | ||
1083 | |||
1084 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
1085 | osi = &osi_setup_entries[i]; | ||
1086 | if (!strcmp(osi->string, str)) { | ||
1087 | osi->enable = enable; | ||
1088 | break; | ||
1089 | } else if (osi->string[0] == '\0') { | ||
1090 | osi->enable = enable; | ||
1091 | strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); | ||
1092 | break; | ||
1093 | } | ||
1094 | } | ||
1067 | } | 1095 | } |
1068 | 1096 | ||
1069 | static void __init set_osi_linux(unsigned int enable) | 1097 | 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) | |||
1110 | */ | 1138 | */ |
1111 | static void __init acpi_osi_setup_late(void) | 1139 | static void __init acpi_osi_setup_late(void) |
1112 | { | 1140 | { |
1113 | char *str = osi_setup_string; | 1141 | struct osi_setup_entry *osi; |
1142 | char *str; | ||
1143 | int i; | ||
1114 | acpi_status status; | 1144 | acpi_status status; |
1115 | 1145 | ||
1116 | if (*str == '\0') | 1146 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { |
1117 | return; | 1147 | osi = &osi_setup_entries[i]; |
1148 | str = osi->string; | ||
1118 | 1149 | ||
1119 | if (*str == '!') { | 1150 | if (*str == '\0') |
1120 | status = acpi_remove_interface(++str); | 1151 | break; |
1152 | if (osi->enable) { | ||
1153 | status = acpi_install_interface(str); | ||
1121 | 1154 | ||
1122 | if (ACPI_SUCCESS(status)) | 1155 | if (ACPI_SUCCESS(status)) |
1123 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | 1156 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); |
1124 | } else { | 1157 | } else { |
1125 | status = acpi_install_interface(str); | 1158 | status = acpi_remove_interface(str); |
1126 | 1159 | ||
1127 | if (ACPI_SUCCESS(status)) | 1160 | if (ACPI_SUCCESS(status)) |
1128 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); | 1161 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); |
1162 | } | ||
1129 | } | 1163 | } |
1130 | } | 1164 | } |
1131 | 1165 | ||