diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 5 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 118 | ||||
-rw-r--r-- | drivers/acpi/utilities/uteval.c | 28 | ||||
-rw-r--r-- | drivers/acpi/utilities/utxface.c | 4 | ||||
-rw-r--r-- | include/acpi/acpiosxf.h | 3 | ||||
-rw-r--r-- | include/acpi/acpixf.h | 2 |
6 files changed, 142 insertions, 18 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index ce91560229f5..5d0283cd3a81 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -170,7 +170,10 @@ and is between 256 and 4096 characters. It is defined in the file | |||
170 | acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS | 170 | acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS |
171 | Format: To spoof as Windows 98: ="Microsoft Windows" | 171 | Format: To spoof as Windows 98: ="Microsoft Windows" |
172 | 172 | ||
173 | acpi_osi= [HW,ACPI] empty param disables _OSI | 173 | acpi_osi= [HW,ACPI] Modify list of supported OS interface strings |
174 | acpi_osi="string1" # add string1 -- only one string | ||
175 | acpi_osi="!string2" # remove built-in string2 | ||
176 | acpi_osi= # disable all strings | ||
174 | 177 | ||
175 | acpi_serialize [HW,ACPI] force serialization of AML methods | 178 | acpi_serialize [HW,ACPI] force serialization of AML methods |
176 | 179 | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index b998340e23d4..58ceb18ec997 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/kmod.h> | 34 | #include <linux/kmod.h> |
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/dmi.h> | ||
36 | #include <linux/workqueue.h> | 37 | #include <linux/workqueue.h> |
37 | #include <linux/nmi.h> | 38 | #include <linux/nmi.h> |
38 | #include <linux/acpi.h> | 39 | #include <linux/acpi.h> |
@@ -73,6 +74,21 @@ static void *acpi_irq_context; | |||
73 | static struct workqueue_struct *kacpid_wq; | 74 | static struct workqueue_struct *kacpid_wq; |
74 | static struct workqueue_struct *kacpi_notify_wq; | 75 | static struct workqueue_struct *kacpi_notify_wq; |
75 | 76 | ||
77 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
78 | static char osi_additional_string[OSI_STRING_LENGTH_MAX]; | ||
79 | |||
80 | #define OSI_LINUX_ENABLED | ||
81 | #ifdef OSI_LINUX_ENABLED | ||
82 | int osi_linux = 1; /* enable _OSI(Linux) by default */ | ||
83 | #else | ||
84 | int osi_linux; /* disable _OSI(Linux) by default */ | ||
85 | #endif | ||
86 | |||
87 | |||
88 | #ifdef CONFIG_DMI | ||
89 | static struct __initdata dmi_system_id acpi_osl_dmi_table[]; | ||
90 | #endif | ||
91 | |||
76 | static void __init acpi_request_region (struct acpi_generic_address *addr, | 92 | static void __init acpi_request_region (struct acpi_generic_address *addr, |
77 | unsigned int length, char *desc) | 93 | unsigned int length, char *desc) |
78 | { | 94 | { |
@@ -121,8 +137,9 @@ static int __init acpi_reserve_resources(void) | |||
121 | } | 137 | } |
122 | device_initcall(acpi_reserve_resources); | 138 | device_initcall(acpi_reserve_resources); |
123 | 139 | ||
124 | acpi_status acpi_os_initialize(void) | 140 | acpi_status __init acpi_os_initialize(void) |
125 | { | 141 | { |
142 | dmi_check_system(acpi_osl_dmi_table); | ||
126 | return AE_OK; | 143 | return AE_OK; |
127 | } | 144 | } |
128 | 145 | ||
@@ -960,20 +977,38 @@ static int __init acpi_os_name_setup(char *str) | |||
960 | 977 | ||
961 | __setup("acpi_os_name=", acpi_os_name_setup); | 978 | __setup("acpi_os_name=", acpi_os_name_setup); |
962 | 979 | ||
980 | static void enable_osi_linux(int enable) { | ||
981 | |||
982 | if (osi_linux != enable) | ||
983 | printk(KERN_INFO PREFIX "%sabled _OSI(Linux)\n", | ||
984 | enable ? "En": "Dis"); | ||
985 | |||
986 | osi_linux = enable; | ||
987 | return; | ||
988 | } | ||
989 | |||
963 | /* | 990 | /* |
964 | * _OSI control | 991 | * Modify the list of "OS Interfaces" reported to BIOS via _OSI |
992 | * | ||
965 | * empty string disables _OSI | 993 | * empty string disables _OSI |
966 | * TBD additional string adds to _OSI | 994 | * string starting with '!' disables that string |
995 | * otherwise string is added to list, augmenting built-in strings | ||
967 | */ | 996 | */ |
968 | static int __init acpi_osi_setup(char *str) | 997 | static int __init acpi_osi_setup(char *str) |
969 | { | 998 | { |
970 | if (str == NULL || *str == '\0') { | 999 | if (str == NULL || *str == '\0') { |
971 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | 1000 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); |
972 | acpi_gbl_create_osi_method = FALSE; | 1001 | acpi_gbl_create_osi_method = FALSE; |
973 | } else { | 1002 | } else if (*str == '!') { |
974 | /* TBD */ | 1003 | if (acpi_osi_invalidate(++str) == AE_OK) |
975 | printk(KERN_ERR PREFIX "_OSI additional string ignored -- %s\n", | 1004 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); |
976 | str); | 1005 | } else if (!strcmp("!Linux", str)) { |
1006 | enable_osi_linux(0); | ||
1007 | } else if (!strcmp("Linux", str)) { | ||
1008 | enable_osi_linux(1); | ||
1009 | } else if (*osi_additional_string == '\0') { | ||
1010 | strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX); | ||
1011 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); | ||
977 | } | 1012 | } |
978 | 1013 | ||
979 | return 1; | 1014 | return 1; |
@@ -1143,11 +1178,28 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) | |||
1143 | acpi_status | 1178 | acpi_status |
1144 | acpi_os_validate_interface (char *interface) | 1179 | acpi_os_validate_interface (char *interface) |
1145 | { | 1180 | { |
1146 | 1181 | if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX)) | |
1147 | return AE_SUPPORT; | 1182 | return AE_OK; |
1183 | if (!strcmp("Linux", interface)) { | ||
1184 | printk(KERN_WARNING PREFIX | ||
1185 | "System BIOS is requesting _OSI(Linux)\n"); | ||
1186 | #ifdef OSI_LINUX_ENABLED | ||
1187 | printk(KERN_WARNING PREFIX | ||
1188 | "Please test with \"acpi_osi=!Linux\"\n" | ||
1189 | "Please send dmidecode " | ||
1190 | "to linux-acpi@vger.kernel.org\n"); | ||
1191 | #else | ||
1192 | printk(KERN_WARNING PREFIX | ||
1193 | "If \"acpi_osi=Linux\" works better,\n" | ||
1194 | "Please send dmidecode " | ||
1195 | "to linux-acpi@vger.kernel.org\n"); | ||
1196 | #endif | ||
1197 | if(osi_linux) | ||
1198 | return AE_OK; | ||
1199 | } | ||
1200 | return AE_SUPPORT; | ||
1148 | } | 1201 | } |
1149 | 1202 | ||
1150 | |||
1151 | /****************************************************************************** | 1203 | /****************************************************************************** |
1152 | * | 1204 | * |
1153 | * FUNCTION: acpi_os_validate_address | 1205 | * FUNCTION: acpi_os_validate_address |
@@ -1174,5 +1226,51 @@ acpi_os_validate_address ( | |||
1174 | return AE_OK; | 1226 | return AE_OK; |
1175 | } | 1227 | } |
1176 | 1228 | ||
1229 | #ifdef CONFIG_DMI | ||
1230 | #ifdef OSI_LINUX_ENABLED | ||
1231 | static int dmi_osi_not_linux(struct dmi_system_id *d) | ||
1232 | { | ||
1233 | printk(KERN_NOTICE "%s detected: requires not _OSI(Linux)\n", d->ident); | ||
1234 | enable_osi_linux(0); | ||
1235 | return 0; | ||
1236 | } | ||
1237 | #else | ||
1238 | static int dmi_osi_linux(struct dmi_system_id *d) | ||
1239 | { | ||
1240 | printk(KERN_NOTICE "%s detected: requires _OSI(Linux)\n", d->ident); | ||
1241 | enable_osi_linux(1); | ||
1242 | return 0; | ||
1243 | } | ||
1244 | #endif | ||
1245 | |||
1246 | static struct dmi_system_id acpi_osl_dmi_table[] __initdata = { | ||
1247 | #ifdef OSI_LINUX_ENABLED | ||
1248 | /* | ||
1249 | * Boxes that need NOT _OSI(Linux) | ||
1250 | */ | ||
1251 | { | ||
1252 | .callback = dmi_osi_not_linux, | ||
1253 | .ident = "Toshiba Satellite P100", | ||
1254 | .matches = { | ||
1255 | DMI_MATCH(DMI_BOARD_VENDOR, "TOSHIBA"), | ||
1256 | DMI_MATCH(DMI_BOARD_NAME, "Satellite P100"), | ||
1257 | }, | ||
1258 | }, | ||
1259 | #else | ||
1260 | /* | ||
1261 | * Boxes that need _OSI(Linux) | ||
1262 | */ | ||
1263 | { | ||
1264 | .callback = dmi_osi_linux, | ||
1265 | .ident = "Intel Napa CRB", | ||
1266 | .matches = { | ||
1267 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), | ||
1268 | DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"), | ||
1269 | }, | ||
1270 | }, | ||
1271 | #endif | ||
1272 | {} | ||
1273 | }; | ||
1274 | #endif /* CONFIG_DMI */ | ||
1177 | 1275 | ||
1178 | #endif | 1276 | #endif |
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index 13d5879cd98b..8ec6f8e48138 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c | |||
@@ -59,10 +59,9 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | |||
59 | /* | 59 | /* |
60 | * Strings supported by the _OSI predefined (internal) method. | 60 | * Strings supported by the _OSI predefined (internal) method. |
61 | */ | 61 | */ |
62 | static const char *acpi_interfaces_supported[] = { | 62 | static char *acpi_interfaces_supported[] = { |
63 | /* Operating System Vendor Strings */ | 63 | /* Operating System Vendor Strings */ |
64 | 64 | ||
65 | "Linux", | ||
66 | "Windows 2000", | 65 | "Windows 2000", |
67 | "Windows 2001", | 66 | "Windows 2001", |
68 | "Windows 2001 SP0", | 67 | "Windows 2001 SP0", |
@@ -158,6 +157,31 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | |||
158 | 157 | ||
159 | /******************************************************************************* | 158 | /******************************************************************************* |
160 | * | 159 | * |
160 | * FUNCTION: acpi_osi_invalidate | ||
161 | * | ||
162 | * PARAMETERS: interface_string | ||
163 | * | ||
164 | * RETURN: Status | ||
165 | * | ||
166 | * DESCRIPTION: invalidate string in pre-defiend _OSI string list | ||
167 | * | ||
168 | ******************************************************************************/ | ||
169 | |||
170 | acpi_status acpi_osi_invalidate(char *interface) | ||
171 | { | ||
172 | int i; | ||
173 | |||
174 | for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { | ||
175 | if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) { | ||
176 | *acpi_interfaces_supported[i] = '\0'; | ||
177 | return AE_OK; | ||
178 | } | ||
179 | } | ||
180 | return AE_NOT_FOUND; | ||
181 | } | ||
182 | |||
183 | /******************************************************************************* | ||
184 | * | ||
161 | * FUNCTION: acpi_ut_evaluate_object | 185 | * FUNCTION: acpi_ut_evaluate_object |
162 | * | 186 | * |
163 | * PARAMETERS: prefix_node - Starting node | 187 | * PARAMETERS: prefix_node - Starting node |
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index e9a57806cd34..2d496918b3cd 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c | |||
@@ -61,7 +61,7 @@ ACPI_MODULE_NAME("utxface") | |||
61 | * called, so any early initialization belongs here. | 61 | * called, so any early initialization belongs here. |
62 | * | 62 | * |
63 | ******************************************************************************/ | 63 | ******************************************************************************/ |
64 | acpi_status acpi_initialize_subsystem(void) | 64 | acpi_status __init acpi_initialize_subsystem(void) |
65 | { | 65 | { |
66 | acpi_status status; | 66 | acpi_status status; |
67 | 67 | ||
@@ -108,8 +108,6 @@ acpi_status acpi_initialize_subsystem(void) | |||
108 | return_ACPI_STATUS(status); | 108 | return_ACPI_STATUS(status); |
109 | } | 109 | } |
110 | 110 | ||
111 | ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem) | ||
112 | |||
113 | /******************************************************************************* | 111 | /******************************************************************************* |
114 | * | 112 | * |
115 | * FUNCTION: acpi_enable_subsystem | 113 | * FUNCTION: acpi_enable_subsystem |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 5e07db0d46e9..ca882b8e7d10 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -78,7 +78,7 @@ struct acpi_signal_fatal_info { | |||
78 | /* | 78 | /* |
79 | * OSL Initialization and shutdown primitives | 79 | * OSL Initialization and shutdown primitives |
80 | */ | 80 | */ |
81 | acpi_status acpi_os_initialize(void); | 81 | acpi_status __initdata acpi_os_initialize(void); |
82 | 82 | ||
83 | acpi_status acpi_os_terminate(void); | 83 | acpi_status acpi_os_terminate(void); |
84 | 84 | ||
@@ -236,6 +236,7 @@ acpi_os_derive_pci_id(acpi_handle rhandle, | |||
236 | * Miscellaneous | 236 | * Miscellaneous |
237 | */ | 237 | */ |
238 | acpi_status acpi_os_validate_interface(char *interface); | 238 | acpi_status acpi_os_validate_interface(char *interface); |
239 | acpi_status acpi_osi_invalidate(char* interface); | ||
239 | 240 | ||
240 | acpi_status | 241 | acpi_status |
241 | acpi_os_validate_address(u8 space_id, | 242 | acpi_os_validate_address(u8 space_id, |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index e08f7df85a4f..b5cca5daa348 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -55,7 +55,7 @@ acpi_status | |||
55 | acpi_initialize_tables(struct acpi_table_desc *initial_storage, | 55 | acpi_initialize_tables(struct acpi_table_desc *initial_storage, |
56 | u32 initial_table_count, u8 allow_resize); | 56 | u32 initial_table_count, u8 allow_resize); |
57 | 57 | ||
58 | acpi_status acpi_initialize_subsystem(void); | 58 | acpi_status __init acpi_initialize_subsystem(void); |
59 | 59 | ||
60 | acpi_status acpi_enable_subsystem(u32 flags); | 60 | acpi_status acpi_enable_subsystem(u32 flags); |
61 | 61 | ||