diff options
Diffstat (limited to 'drivers/acpi')
153 files changed, 6535 insertions, 6694 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index df4514436ba8..5c087a5bddf8 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -11,7 +11,7 @@ config ACPI | |||
11 | bool "ACPI Support" | 11 | bool "ACPI Support" |
12 | depends on IA64 || X86 | 12 | depends on IA64 || X86 |
13 | depends on PCI | 13 | depends on PCI |
14 | select PM | 14 | depends on PM |
15 | default y | 15 | default y |
16 | ---help--- | 16 | ---help--- |
17 | Advanced Configuration and Power Interface (ACPI) support for | 17 | Advanced Configuration and Power Interface (ACPI) support for |
@@ -111,6 +111,7 @@ config ACPI_BATTERY | |||
111 | 111 | ||
112 | config ACPI_BUTTON | 112 | config ACPI_BUTTON |
113 | tristate "Button" | 113 | tristate "Button" |
114 | depends on INPUT | ||
114 | default y | 115 | default y |
115 | help | 116 | help |
116 | This driver handles events on the power, sleep and lid buttons. | 117 | This driver handles events on the power, sleep and lid buttons. |
@@ -120,7 +121,7 @@ config ACPI_BUTTON | |||
120 | 121 | ||
121 | config ACPI_VIDEO | 122 | config ACPI_VIDEO |
122 | tristate "Video" | 123 | tristate "Video" |
123 | depends on X86 | 124 | depends on X86 && BACKLIGHT_CLASS_DEVICE |
124 | help | 125 | help |
125 | This driver implement the ACPI Extensions For Display Adapters | 126 | This driver implement the ACPI Extensions For Display Adapters |
126 | for integrated graphics devices on motherboard, as specified in | 127 | for integrated graphics devices on motherboard, as specified in |
@@ -152,6 +153,13 @@ config ACPI_DOCK | |||
152 | help | 153 | help |
153 | This driver adds support for ACPI controlled docking stations | 154 | This driver adds support for ACPI controlled docking stations |
154 | 155 | ||
156 | config ACPI_BAY | ||
157 | tristate "Removable Drive Bay (EXPERIMENTAL)" | ||
158 | depends on EXPERIMENTAL | ||
159 | help | ||
160 | This driver adds support for ACPI controlled removable drive | ||
161 | bays such as the IBM ultrabay or the Dell Module Bay. | ||
162 | |||
155 | config ACPI_PROCESSOR | 163 | config ACPI_PROCESSOR |
156 | tristate "Processor" | 164 | tristate "Processor" |
157 | default y | 165 | default y |
@@ -186,6 +194,7 @@ config ACPI_NUMA | |||
186 | config ACPI_ASUS | 194 | config ACPI_ASUS |
187 | tristate "ASUS/Medion Laptop Extras" | 195 | tristate "ASUS/Medion Laptop Extras" |
188 | depends on X86 | 196 | depends on X86 |
197 | select BACKLIGHT_CLASS_DEVICE | ||
189 | ---help--- | 198 | ---help--- |
190 | This driver provides support for extra features of ACPI-compatible | 199 | This driver provides support for extra features of ACPI-compatible |
191 | ASUS laptops. As some of Medion laptops are made by ASUS, it may also | 200 | ASUS laptops. As some of Medion laptops are made by ASUS, it may also |
@@ -214,6 +223,7 @@ config ACPI_ASUS | |||
214 | config ACPI_IBM | 223 | config ACPI_IBM |
215 | tristate "IBM ThinkPad Laptop Extras" | 224 | tristate "IBM ThinkPad Laptop Extras" |
216 | depends on X86 | 225 | depends on X86 |
226 | select BACKLIGHT_CLASS_DEVICE | ||
217 | ---help--- | 227 | ---help--- |
218 | This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds | 228 | This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds |
219 | support for Fn-Fx key combinations, Bluetooth control, video | 229 | support for Fn-Fx key combinations, Bluetooth control, video |
@@ -239,6 +249,7 @@ config ACPI_IBM_DOCK | |||
239 | config ACPI_TOSHIBA | 249 | config ACPI_TOSHIBA |
240 | tristate "Toshiba Laptop Extras" | 250 | tristate "Toshiba Laptop Extras" |
241 | depends on X86 | 251 | depends on X86 |
252 | select BACKLIGHT_CLASS_DEVICE | ||
242 | ---help--- | 253 | ---help--- |
243 | This driver adds support for access to certain system settings | 254 | This driver adds support for access to certain system settings |
244 | on "legacy free" Toshiba laptops. These laptops can be recognized by | 255 | on "legacy free" Toshiba laptops. These laptops can be recognized by |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index a7495107057c..399b0e8c41c4 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -44,7 +44,8 @@ obj-$(CONFIG_ACPI_BUTTON) += button.o | |||
44 | obj-$(CONFIG_ACPI_EC) += ec.o | 44 | obj-$(CONFIG_ACPI_EC) += ec.o |
45 | obj-$(CONFIG_ACPI_FAN) += fan.o | 45 | obj-$(CONFIG_ACPI_FAN) += fan.o |
46 | obj-$(CONFIG_ACPI_DOCK) += dock.o | 46 | obj-$(CONFIG_ACPI_DOCK) += dock.o |
47 | obj-$(CONFIG_ACPI_VIDEO) += video.o | 47 | obj-$(CONFIG_ACPI_BAY) += bay.o |
48 | obj-$(CONFIG_ACPI_VIDEO) += video.o | ||
48 | obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o | 49 | obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o |
49 | obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o | 50 | obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o |
50 | obj-$(CONFIG_ACPI_POWER) += power.o | 51 | obj-$(CONFIG_ACPI_POWER) += power.o |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 11abc7bf777e..6daeace796a8 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -109,7 +109,7 @@ static struct proc_dir_entry *acpi_ac_dir; | |||
109 | 109 | ||
110 | static int acpi_ac_seq_show(struct seq_file *seq, void *offset) | 110 | static int acpi_ac_seq_show(struct seq_file *seq, void *offset) |
111 | { | 111 | { |
112 | struct acpi_ac *ac = (struct acpi_ac *)seq->private; | 112 | struct acpi_ac *ac = seq->private; |
113 | 113 | ||
114 | 114 | ||
115 | if (!ac) | 115 | if (!ac) |
@@ -187,7 +187,7 @@ static int acpi_ac_remove_fs(struct acpi_device *device) | |||
187 | 187 | ||
188 | static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) | 188 | static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) |
189 | { | 189 | { |
190 | struct acpi_ac *ac = (struct acpi_ac *)data; | 190 | struct acpi_ac *ac = data; |
191 | struct acpi_device *device = NULL; | 191 | struct acpi_device *device = NULL; |
192 | 192 | ||
193 | 193 | ||
@@ -221,10 +221,9 @@ static int acpi_ac_add(struct acpi_device *device) | |||
221 | if (!device) | 221 | if (!device) |
222 | return -EINVAL; | 222 | return -EINVAL; |
223 | 223 | ||
224 | ac = kmalloc(sizeof(struct acpi_ac), GFP_KERNEL); | 224 | ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); |
225 | if (!ac) | 225 | if (!ac) |
226 | return -ENOMEM; | 226 | return -ENOMEM; |
227 | memset(ac, 0, sizeof(struct acpi_ac)); | ||
228 | 227 | ||
229 | ac->device = device; | 228 | ac->device = device; |
230 | strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); | 229 | strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); |
@@ -269,7 +268,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type) | |||
269 | if (!device || !acpi_driver_data(device)) | 268 | if (!device || !acpi_driver_data(device)) |
270 | return -EINVAL; | 269 | return -EINVAL; |
271 | 270 | ||
272 | ac = (struct acpi_ac *)acpi_driver_data(device); | 271 | ac = acpi_driver_data(device); |
273 | 272 | ||
274 | status = acpi_remove_notify_handler(device->handle, | 273 | status = acpi_remove_notify_handler(device->handle, |
275 | ACPI_ALL_NOTIFY, acpi_ac_notify); | 274 | ACPI_ALL_NOTIFY, acpi_ac_notify); |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 6bcd9e8e7bcb..cd946ed192d3 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -395,10 +395,9 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
395 | if (!device) | 395 | if (!device) |
396 | return -EINVAL; | 396 | return -EINVAL; |
397 | 397 | ||
398 | mem_device = kmalloc(sizeof(struct acpi_memory_device), GFP_KERNEL); | 398 | mem_device = kzalloc(sizeof(struct acpi_memory_device), GFP_KERNEL); |
399 | if (!mem_device) | 399 | if (!mem_device) |
400 | return -ENOMEM; | 400 | return -ENOMEM; |
401 | memset(mem_device, 0, sizeof(struct acpi_memory_device)); | ||
402 | 401 | ||
403 | INIT_LIST_HEAD(&mem_device->res_list); | 402 | INIT_LIST_HEAD(&mem_device->res_list); |
404 | mem_device->device = device; | 403 | mem_device->device = device; |
@@ -429,7 +428,7 @@ static int acpi_memory_device_remove(struct acpi_device *device, int type) | |||
429 | if (!device || !acpi_driver_data(device)) | 428 | if (!device || !acpi_driver_data(device)) |
430 | return -EINVAL; | 429 | return -EINVAL; |
431 | 430 | ||
432 | mem_device = (struct acpi_memory_device *)acpi_driver_data(device); | 431 | mem_device = acpi_driver_data(device); |
433 | kfree(mem_device); | 432 | kfree(mem_device); |
434 | 433 | ||
435 | return 0; | 434 | return 0; |
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index c7ac9297a204..31ad70a6e22e 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * Pontus Fuchs - Helper functions, cleanup | 26 | * Pontus Fuchs - Helper functions, cleanup |
27 | * Johann Wiesner - Small compile fixes | 27 | * Johann Wiesner - Small compile fixes |
28 | * John Belmonte - ACPI code for Toshiba laptop was a good starting point. | 28 | * John Belmonte - ACPI code for Toshiba laptop was a good starting point. |
29 | * Éric Burghard - LED display support for W1N | 29 | * �ic Burghard - LED display support for W1N |
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | 32 | ||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/types.h> | 36 | #include <linux/types.h> |
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/backlight.h> | ||
38 | #include <acpi/acpi_drivers.h> | 39 | #include <acpi/acpi_drivers.h> |
39 | #include <acpi/acpi_bus.h> | 40 | #include <acpi/acpi_bus.h> |
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
@@ -402,6 +403,8 @@ static struct model_data model_conf[END_MODEL] = { | |||
402 | /* procdir we use */ | 403 | /* procdir we use */ |
403 | static struct proc_dir_entry *asus_proc_dir; | 404 | static struct proc_dir_entry *asus_proc_dir; |
404 | 405 | ||
406 | static struct backlight_device *asus_backlight_device; | ||
407 | |||
405 | /* | 408 | /* |
406 | * This header is made available to allow proper configuration given model, | 409 | * This header is made available to allow proper configuration given model, |
407 | * revision number , ... this info cannot go in struct asus_hotk because it is | 410 | * revision number , ... this info cannot go in struct asus_hotk because it is |
@@ -779,7 +782,7 @@ proc_write_lcd(struct file *file, const char __user * buffer, | |||
779 | return rv; | 782 | return rv; |
780 | } | 783 | } |
781 | 784 | ||
782 | static int read_brightness(void) | 785 | static int read_brightness(struct backlight_device *bd) |
783 | { | 786 | { |
784 | int value; | 787 | int value; |
785 | 788 | ||
@@ -801,9 +804,10 @@ static int read_brightness(void) | |||
801 | /* | 804 | /* |
802 | * Change the brightness level | 805 | * Change the brightness level |
803 | */ | 806 | */ |
804 | static void set_brightness(int value) | 807 | static int set_brightness(int value) |
805 | { | 808 | { |
806 | acpi_status status = 0; | 809 | acpi_status status = 0; |
810 | int ret = 0; | ||
807 | 811 | ||
808 | /* SPLV laptop */ | 812 | /* SPLV laptop */ |
809 | if (hotk->methods->brightness_set) { | 813 | if (hotk->methods->brightness_set) { |
@@ -811,11 +815,12 @@ static void set_brightness(int value) | |||
811 | value, NULL)) | 815 | value, NULL)) |
812 | printk(KERN_WARNING | 816 | printk(KERN_WARNING |
813 | "Asus ACPI: Error changing brightness\n"); | 817 | "Asus ACPI: Error changing brightness\n"); |
814 | return; | 818 | ret = -EIO; |
819 | goto out; | ||
815 | } | 820 | } |
816 | 821 | ||
817 | /* No SPLV method if we are here, act as appropriate */ | 822 | /* No SPLV method if we are here, act as appropriate */ |
818 | value -= read_brightness(); | 823 | value -= read_brightness(NULL); |
819 | while (value != 0) { | 824 | while (value != 0) { |
820 | status = acpi_evaluate_object(NULL, (value > 0) ? | 825 | status = acpi_evaluate_object(NULL, (value > 0) ? |
821 | hotk->methods->brightness_up : | 826 | hotk->methods->brightness_up : |
@@ -825,15 +830,22 @@ static void set_brightness(int value) | |||
825 | if (ACPI_FAILURE(status)) | 830 | if (ACPI_FAILURE(status)) |
826 | printk(KERN_WARNING | 831 | printk(KERN_WARNING |
827 | "Asus ACPI: Error changing brightness\n"); | 832 | "Asus ACPI: Error changing brightness\n"); |
833 | ret = -EIO; | ||
828 | } | 834 | } |
829 | return; | 835 | out: |
836 | return ret; | ||
837 | } | ||
838 | |||
839 | static int set_brightness_status(struct backlight_device *bd) | ||
840 | { | ||
841 | return set_brightness(bd->props->brightness); | ||
830 | } | 842 | } |
831 | 843 | ||
832 | static int | 844 | static int |
833 | proc_read_brn(char *page, char **start, off_t off, int count, int *eof, | 845 | proc_read_brn(char *page, char **start, off_t off, int count, int *eof, |
834 | void *data) | 846 | void *data) |
835 | { | 847 | { |
836 | return sprintf(page, "%d\n", read_brightness()); | 848 | return sprintf(page, "%d\n", read_brightness(NULL)); |
837 | } | 849 | } |
838 | 850 | ||
839 | static int | 851 | static int |
@@ -1116,7 +1128,6 @@ static int asus_model_match(char *model) | |||
1116 | static int asus_hotk_get_info(void) | 1128 | static int asus_hotk_get_info(void) |
1117 | { | 1129 | { |
1118 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 1130 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
1119 | struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1120 | union acpi_object *model = NULL; | 1131 | union acpi_object *model = NULL; |
1121 | int bsts_result; | 1132 | int bsts_result; |
1122 | char *string = NULL; | 1133 | char *string = NULL; |
@@ -1130,11 +1141,9 @@ static int asus_hotk_get_info(void) | |||
1130 | * HID), this bit will be moved. A global variable asus_info contains | 1141 | * HID), this bit will be moved. A global variable asus_info contains |
1131 | * the DSDT header. | 1142 | * the DSDT header. |
1132 | */ | 1143 | */ |
1133 | status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt); | 1144 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info); |
1134 | if (ACPI_FAILURE(status)) | 1145 | if (ACPI_FAILURE(status)) |
1135 | printk(KERN_WARNING " Couldn't get the DSDT table header\n"); | 1146 | printk(KERN_WARNING " Couldn't get the DSDT table header\n"); |
1136 | else | ||
1137 | asus_info = (struct acpi_table_header *)dsdt.pointer; | ||
1138 | 1147 | ||
1139 | /* We have to write 0 on init this far for all ASUS models */ | 1148 | /* We have to write 0 on init this far for all ASUS models */ |
1140 | if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { | 1149 | if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { |
@@ -1156,7 +1165,7 @@ static int asus_hotk_get_info(void) | |||
1156 | * asus_model_match() and try something completely different. | 1165 | * asus_model_match() and try something completely different. |
1157 | */ | 1166 | */ |
1158 | if (buffer.pointer) { | 1167 | if (buffer.pointer) { |
1159 | model = (union acpi_object *)buffer.pointer; | 1168 | model = buffer.pointer; |
1160 | switch (model->type) { | 1169 | switch (model->type) { |
1161 | case ACPI_TYPE_STRING: | 1170 | case ACPI_TYPE_STRING: |
1162 | string = model->string.pointer; | 1171 | string = model->string.pointer; |
@@ -1252,11 +1261,9 @@ static int asus_hotk_add(struct acpi_device *device) | |||
1252 | printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n", | 1261 | printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n", |
1253 | ASUS_ACPI_VERSION); | 1262 | ASUS_ACPI_VERSION); |
1254 | 1263 | ||
1255 | hotk = | 1264 | hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); |
1256 | (struct asus_hotk *)kmalloc(sizeof(struct asus_hotk), GFP_KERNEL); | ||
1257 | if (!hotk) | 1265 | if (!hotk) |
1258 | return -ENOMEM; | 1266 | return -ENOMEM; |
1259 | memset(hotk, 0, sizeof(struct asus_hotk)); | ||
1260 | 1267 | ||
1261 | hotk->handle = device->handle; | 1268 | hotk->handle = device->handle; |
1262 | strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME); | 1269 | strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME); |
@@ -1333,6 +1340,24 @@ static int asus_hotk_remove(struct acpi_device *device, int type) | |||
1333 | return 0; | 1340 | return 0; |
1334 | } | 1341 | } |
1335 | 1342 | ||
1343 | static struct backlight_properties asus_backlight_data = { | ||
1344 | .owner = THIS_MODULE, | ||
1345 | .get_brightness = read_brightness, | ||
1346 | .update_status = set_brightness_status, | ||
1347 | .max_brightness = 15, | ||
1348 | }; | ||
1349 | |||
1350 | static void __exit asus_acpi_exit(void) | ||
1351 | { | ||
1352 | if (asus_backlight_device) | ||
1353 | backlight_device_unregister(asus_backlight_device); | ||
1354 | |||
1355 | acpi_bus_unregister_driver(&asus_hotk_driver); | ||
1356 | remove_proc_entry(PROC_ASUS, acpi_root_dir); | ||
1357 | |||
1358 | return; | ||
1359 | } | ||
1360 | |||
1336 | static int __init asus_acpi_init(void) | 1361 | static int __init asus_acpi_init(void) |
1337 | { | 1362 | { |
1338 | int result; | 1363 | int result; |
@@ -1370,17 +1395,15 @@ static int __init asus_acpi_init(void) | |||
1370 | return result; | 1395 | return result; |
1371 | } | 1396 | } |
1372 | 1397 | ||
1373 | return 0; | 1398 | asus_backlight_device = backlight_device_register("asus",NULL,NULL, |
1374 | } | 1399 | &asus_backlight_data); |
1375 | 1400 | if (IS_ERR(asus_backlight_device)) { | |
1376 | static void __exit asus_acpi_exit(void) | 1401 | printk(KERN_ERR "Could not register asus backlight device\n"); |
1377 | { | 1402 | asus_backlight_device = NULL; |
1378 | acpi_bus_unregister_driver(&asus_hotk_driver); | 1403 | asus_acpi_exit(); |
1379 | remove_proc_entry(PROC_ASUS, acpi_root_dir); | 1404 | } |
1380 | |||
1381 | kfree(asus_info); | ||
1382 | 1405 | ||
1383 | return; | 1406 | return 0; |
1384 | } | 1407 | } |
1385 | 1408 | ||
1386 | module_init(asus_acpi_init); | 1409 | module_init(asus_acpi_init); |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 07c3c276ad34..2f4521a48fe7 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -149,7 +149,7 @@ acpi_battery_get_info(struct acpi_battery *battery, | |||
149 | return -ENODEV; | 149 | return -ENODEV; |
150 | } | 150 | } |
151 | 151 | ||
152 | package = (union acpi_object *)buffer.pointer; | 152 | package = buffer.pointer; |
153 | 153 | ||
154 | /* Extract Package Data */ | 154 | /* Extract Package Data */ |
155 | 155 | ||
@@ -160,12 +160,11 @@ acpi_battery_get_info(struct acpi_battery *battery, | |||
160 | goto end; | 160 | goto end; |
161 | } | 161 | } |
162 | 162 | ||
163 | data.pointer = kmalloc(data.length, GFP_KERNEL); | 163 | data.pointer = kzalloc(data.length, GFP_KERNEL); |
164 | if (!data.pointer) { | 164 | if (!data.pointer) { |
165 | result = -ENOMEM; | 165 | result = -ENOMEM; |
166 | goto end; | 166 | goto end; |
167 | } | 167 | } |
168 | memset(data.pointer, 0, data.length); | ||
169 | 168 | ||
170 | status = acpi_extract_package(package, &format, &data); | 169 | status = acpi_extract_package(package, &format, &data); |
171 | if (ACPI_FAILURE(status)) { | 170 | if (ACPI_FAILURE(status)) { |
@@ -179,7 +178,7 @@ acpi_battery_get_info(struct acpi_battery *battery, | |||
179 | kfree(buffer.pointer); | 178 | kfree(buffer.pointer); |
180 | 179 | ||
181 | if (!result) | 180 | if (!result) |
182 | (*bif) = (struct acpi_battery_info *)data.pointer; | 181 | (*bif) = data.pointer; |
183 | 182 | ||
184 | return result; | 183 | return result; |
185 | } | 184 | } |
@@ -209,7 +208,7 @@ acpi_battery_get_status(struct acpi_battery *battery, | |||
209 | return -ENODEV; | 208 | return -ENODEV; |
210 | } | 209 | } |
211 | 210 | ||
212 | package = (union acpi_object *)buffer.pointer; | 211 | package = buffer.pointer; |
213 | 212 | ||
214 | /* Extract Package Data */ | 213 | /* Extract Package Data */ |
215 | 214 | ||
@@ -220,12 +219,11 @@ acpi_battery_get_status(struct acpi_battery *battery, | |||
220 | goto end; | 219 | goto end; |
221 | } | 220 | } |
222 | 221 | ||
223 | data.pointer = kmalloc(data.length, GFP_KERNEL); | 222 | data.pointer = kzalloc(data.length, GFP_KERNEL); |
224 | if (!data.pointer) { | 223 | if (!data.pointer) { |
225 | result = -ENOMEM; | 224 | result = -ENOMEM; |
226 | goto end; | 225 | goto end; |
227 | } | 226 | } |
228 | memset(data.pointer, 0, data.length); | ||
229 | 227 | ||
230 | status = acpi_extract_package(package, &format, &data); | 228 | status = acpi_extract_package(package, &format, &data); |
231 | if (ACPI_FAILURE(status)) { | 229 | if (ACPI_FAILURE(status)) { |
@@ -239,7 +237,7 @@ acpi_battery_get_status(struct acpi_battery *battery, | |||
239 | kfree(buffer.pointer); | 237 | kfree(buffer.pointer); |
240 | 238 | ||
241 | if (!result) | 239 | if (!result) |
242 | (*bst) = (struct acpi_battery_status *)data.pointer; | 240 | (*bst) = data.pointer; |
243 | 241 | ||
244 | return result; | 242 | return result; |
245 | } | 243 | } |
@@ -334,7 +332,7 @@ static struct proc_dir_entry *acpi_battery_dir; | |||
334 | static int acpi_battery_read_info(struct seq_file *seq, void *offset) | 332 | static int acpi_battery_read_info(struct seq_file *seq, void *offset) |
335 | { | 333 | { |
336 | int result = 0; | 334 | int result = 0; |
337 | struct acpi_battery *battery = (struct acpi_battery *)seq->private; | 335 | struct acpi_battery *battery = seq->private; |
338 | struct acpi_battery_info *bif = NULL; | 336 | struct acpi_battery_info *bif = NULL; |
339 | char *units = "?"; | 337 | char *units = "?"; |
340 | 338 | ||
@@ -418,7 +416,7 @@ static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) | |||
418 | static int acpi_battery_read_state(struct seq_file *seq, void *offset) | 416 | static int acpi_battery_read_state(struct seq_file *seq, void *offset) |
419 | { | 417 | { |
420 | int result = 0; | 418 | int result = 0; |
421 | struct acpi_battery *battery = (struct acpi_battery *)seq->private; | 419 | struct acpi_battery *battery = seq->private; |
422 | struct acpi_battery_status *bst = NULL; | 420 | struct acpi_battery_status *bst = NULL; |
423 | char *units = "?"; | 421 | char *units = "?"; |
424 | 422 | ||
@@ -494,7 +492,7 @@ static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) | |||
494 | 492 | ||
495 | static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) | 493 | static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) |
496 | { | 494 | { |
497 | struct acpi_battery *battery = (struct acpi_battery *)seq->private; | 495 | struct acpi_battery *battery = seq->private; |
498 | char *units = "?"; | 496 | char *units = "?"; |
499 | 497 | ||
500 | 498 | ||
@@ -531,8 +529,8 @@ acpi_battery_write_alarm(struct file *file, | |||
531 | { | 529 | { |
532 | int result = 0; | 530 | int result = 0; |
533 | char alarm_string[12] = { '\0' }; | 531 | char alarm_string[12] = { '\0' }; |
534 | struct seq_file *m = (struct seq_file *)file->private_data; | 532 | struct seq_file *m = file->private_data; |
535 | struct acpi_battery *battery = (struct acpi_battery *)m->private; | 533 | struct acpi_battery *battery = m->private; |
536 | 534 | ||
537 | 535 | ||
538 | if (!battery || (count > sizeof(alarm_string) - 1)) | 536 | if (!battery || (count > sizeof(alarm_string) - 1)) |
@@ -658,7 +656,7 @@ static int acpi_battery_remove_fs(struct acpi_device *device) | |||
658 | 656 | ||
659 | static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) | 657 | static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) |
660 | { | 658 | { |
661 | struct acpi_battery *battery = (struct acpi_battery *)data; | 659 | struct acpi_battery *battery = data; |
662 | struct acpi_device *device = NULL; | 660 | struct acpi_device *device = NULL; |
663 | 661 | ||
664 | 662 | ||
@@ -694,10 +692,9 @@ static int acpi_battery_add(struct acpi_device *device) | |||
694 | if (!device) | 692 | if (!device) |
695 | return -EINVAL; | 693 | return -EINVAL; |
696 | 694 | ||
697 | battery = kmalloc(sizeof(struct acpi_battery), GFP_KERNEL); | 695 | battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); |
698 | if (!battery) | 696 | if (!battery) |
699 | return -ENOMEM; | 697 | return -ENOMEM; |
700 | memset(battery, 0, sizeof(struct acpi_battery)); | ||
701 | 698 | ||
702 | battery->device = device; | 699 | battery->device = device; |
703 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); | 700 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); |
@@ -742,7 +739,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
742 | if (!device || !acpi_driver_data(device)) | 739 | if (!device || !acpi_driver_data(device)) |
743 | return -EINVAL; | 740 | return -EINVAL; |
744 | 741 | ||
745 | battery = (struct acpi_battery *)acpi_driver_data(device); | 742 | battery = acpi_driver_data(device); |
746 | 743 | ||
747 | status = acpi_remove_notify_handler(device->handle, | 744 | status = acpi_remove_notify_handler(device->handle, |
748 | ACPI_ALL_NOTIFY, | 745 | ACPI_ALL_NOTIFY, |
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c new file mode 100644 index 000000000000..aa1b131c0fce --- /dev/null +++ b/drivers/acpi/bay.c | |||
@@ -0,0 +1,506 @@ | |||
1 | /* | ||
2 | * bay.c - ACPI removable drive bay driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com> | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or (at | ||
11 | * your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
21 | * | ||
22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
23 | */ | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/notifier.h> | ||
29 | #include <acpi/acpi_bus.h> | ||
30 | #include <acpi/acpi_drivers.h> | ||
31 | #include <linux/seq_file.h> | ||
32 | #include <asm/uaccess.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | |||
35 | #define ACPI_BAY_DRIVER_NAME "ACPI Removable Drive Bay Driver" | ||
36 | |||
37 | ACPI_MODULE_NAME("bay") | ||
38 | MODULE_AUTHOR("Kristen Carlson Accardi"); | ||
39 | MODULE_DESCRIPTION(ACPI_BAY_DRIVER_NAME); | ||
40 | MODULE_LICENSE("GPL"); | ||
41 | #define ACPI_BAY_CLASS "bay" | ||
42 | #define ACPI_BAY_COMPONENT 0x10000000 | ||
43 | #define _COMPONENT ACPI_BAY_COMPONENT | ||
44 | #define bay_dprintk(h,s) {\ | ||
45 | char prefix[80] = {'\0'};\ | ||
46 | struct acpi_buffer buffer = {sizeof(prefix), prefix};\ | ||
47 | acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\ | ||
48 | printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); } | ||
49 | static void bay_notify(acpi_handle handle, u32 event, void *data); | ||
50 | static int acpi_bay_add(struct acpi_device *device); | ||
51 | static int acpi_bay_remove(struct acpi_device *device, int type); | ||
52 | static int acpi_bay_match(struct acpi_device *device, | ||
53 | struct acpi_driver *driver); | ||
54 | |||
55 | static struct acpi_driver acpi_bay_driver = { | ||
56 | .name = ACPI_BAY_DRIVER_NAME, | ||
57 | .class = ACPI_BAY_CLASS, | ||
58 | .ops = { | ||
59 | .add = acpi_bay_add, | ||
60 | .remove = acpi_bay_remove, | ||
61 | .match = acpi_bay_match, | ||
62 | }, | ||
63 | }; | ||
64 | |||
65 | struct bay { | ||
66 | acpi_handle handle; | ||
67 | char *name; | ||
68 | struct list_head list; | ||
69 | struct platform_device *pdev; | ||
70 | }; | ||
71 | |||
72 | static LIST_HEAD(drive_bays); | ||
73 | |||
74 | |||
75 | /***************************************************************************** | ||
76 | * Drive Bay functions * | ||
77 | *****************************************************************************/ | ||
78 | /** | ||
79 | * is_ejectable - see if a device is ejectable | ||
80 | * @handle: acpi handle of the device | ||
81 | * | ||
82 | * If an acpi object has a _EJ0 method, then it is ejectable | ||
83 | */ | ||
84 | static int is_ejectable(acpi_handle handle) | ||
85 | { | ||
86 | acpi_status status; | ||
87 | acpi_handle tmp; | ||
88 | |||
89 | status = acpi_get_handle(handle, "_EJ0", &tmp); | ||
90 | if (ACPI_FAILURE(status)) | ||
91 | return 0; | ||
92 | return 1; | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * bay_present - see if the bay device is present | ||
97 | * @bay: the drive bay | ||
98 | * | ||
99 | * execute the _STA method. | ||
100 | */ | ||
101 | static int bay_present(struct bay *bay) | ||
102 | { | ||
103 | unsigned long sta; | ||
104 | acpi_status status; | ||
105 | |||
106 | if (bay) { | ||
107 | status = acpi_evaluate_integer(bay->handle, "_STA", NULL, &sta); | ||
108 | if (ACPI_SUCCESS(status) && sta) | ||
109 | return 1; | ||
110 | } | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * eject_device - respond to an eject request | ||
116 | * @handle - the device to eject | ||
117 | * | ||
118 | * Call this devices _EJ0 method. | ||
119 | */ | ||
120 | static void eject_device(acpi_handle handle) | ||
121 | { | ||
122 | struct acpi_object_list arg_list; | ||
123 | union acpi_object arg; | ||
124 | |||
125 | bay_dprintk(handle, "Ejecting device"); | ||
126 | |||
127 | arg_list.count = 1; | ||
128 | arg_list.pointer = &arg; | ||
129 | arg.type = ACPI_TYPE_INTEGER; | ||
130 | arg.integer.value = 1; | ||
131 | |||
132 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0", | ||
133 | &arg_list, NULL))) | ||
134 | pr_debug("Failed to evaluate _EJ0!\n"); | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * show_present - read method for "present" file in sysfs | ||
139 | */ | ||
140 | static ssize_t show_present(struct device *dev, | ||
141 | struct device_attribute *attr, char *buf) | ||
142 | { | ||
143 | struct bay *bay = dev_get_drvdata(dev); | ||
144 | return snprintf(buf, PAGE_SIZE, "%d\n", bay_present(bay)); | ||
145 | |||
146 | } | ||
147 | DEVICE_ATTR(present, S_IRUGO, show_present, NULL); | ||
148 | |||
149 | /* | ||
150 | * write_eject - write method for "eject" file in sysfs | ||
151 | */ | ||
152 | static ssize_t write_eject(struct device *dev, struct device_attribute *attr, | ||
153 | const char *buf, size_t count) | ||
154 | { | ||
155 | struct bay *bay = dev_get_drvdata(dev); | ||
156 | |||
157 | if (!count) | ||
158 | return -EINVAL; | ||
159 | |||
160 | eject_device(bay->handle); | ||
161 | return count; | ||
162 | } | ||
163 | DEVICE_ATTR(eject, S_IWUSR, NULL, write_eject); | ||
164 | |||
165 | /** | ||
166 | * is_ata - see if a device is an ata device | ||
167 | * @handle: acpi handle of the device | ||
168 | * | ||
169 | * If an acpi object has one of 4 ATA ACPI methods defined, | ||
170 | * then it is an ATA device | ||
171 | */ | ||
172 | static int is_ata(acpi_handle handle) | ||
173 | { | ||
174 | acpi_handle tmp; | ||
175 | |||
176 | if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || | ||
177 | (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || | ||
178 | (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || | ||
179 | (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) | ||
180 | return 1; | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * parent_is_ata(acpi_handle handle) | ||
187 | * | ||
188 | */ | ||
189 | static int parent_is_ata(acpi_handle handle) | ||
190 | { | ||
191 | acpi_handle phandle; | ||
192 | |||
193 | if (acpi_get_parent(handle, &phandle)) | ||
194 | return 0; | ||
195 | |||
196 | return is_ata(phandle); | ||
197 | } | ||
198 | |||
199 | /** | ||
200 | * is_ejectable_bay - see if a device is an ejectable drive bay | ||
201 | * @handle: acpi handle of the device | ||
202 | * | ||
203 | * If an acpi object is ejectable and has one of the ACPI ATA | ||
204 | * methods defined, then we can safely call it an ejectable | ||
205 | * drive bay | ||
206 | */ | ||
207 | static int is_ejectable_bay(acpi_handle handle) | ||
208 | { | ||
209 | if ((is_ata(handle) || parent_is_ata(handle)) && is_ejectable(handle)) | ||
210 | return 1; | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * eject_removable_drive - try to eject this drive | ||
216 | * @dev : the device structure of the drive | ||
217 | * | ||
218 | * If a device is a removable drive that requires an _EJ0 method | ||
219 | * to be executed in order to safely remove from the system, do | ||
220 | * it. ATM - always returns success | ||
221 | */ | ||
222 | int eject_removable_drive(struct device *dev) | ||
223 | { | ||
224 | acpi_handle handle = DEVICE_ACPI_HANDLE(dev); | ||
225 | |||
226 | if (handle) { | ||
227 | bay_dprintk(handle, "Got device handle"); | ||
228 | if (is_ejectable_bay(handle)) | ||
229 | eject_device(handle); | ||
230 | } else { | ||
231 | printk("No acpi handle for device\n"); | ||
232 | } | ||
233 | |||
234 | /* should I return an error code? */ | ||
235 | return 0; | ||
236 | } | ||
237 | EXPORT_SYMBOL_GPL(eject_removable_drive); | ||
238 | |||
239 | static int acpi_bay_add(struct acpi_device *device) | ||
240 | { | ||
241 | bay_dprintk(device->handle, "adding bay device"); | ||
242 | strcpy(acpi_device_name(device), "Dockable Bay"); | ||
243 | strcpy(acpi_device_class(device), "bay"); | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static int acpi_bay_add_fs(struct bay *bay) | ||
248 | { | ||
249 | int ret; | ||
250 | struct device *dev = &bay->pdev->dev; | ||
251 | |||
252 | ret = device_create_file(dev, &dev_attr_present); | ||
253 | if (ret) | ||
254 | goto add_fs_err; | ||
255 | ret = device_create_file(dev, &dev_attr_eject); | ||
256 | if (ret) { | ||
257 | device_remove_file(dev, &dev_attr_present); | ||
258 | goto add_fs_err; | ||
259 | } | ||
260 | return 0; | ||
261 | |||
262 | add_fs_err: | ||
263 | bay_dprintk(bay->handle, "Error adding sysfs files\n"); | ||
264 | return ret; | ||
265 | } | ||
266 | |||
267 | static void acpi_bay_remove_fs(struct bay *bay) | ||
268 | { | ||
269 | struct device *dev = &bay->pdev->dev; | ||
270 | |||
271 | /* cleanup sysfs */ | ||
272 | device_remove_file(dev, &dev_attr_present); | ||
273 | device_remove_file(dev, &dev_attr_eject); | ||
274 | } | ||
275 | |||
276 | static int bay_is_dock_device(acpi_handle handle) | ||
277 | { | ||
278 | acpi_handle parent; | ||
279 | |||
280 | acpi_get_parent(handle, &parent); | ||
281 | |||
282 | /* if the device or it's parent is dependent on the | ||
283 | * dock, then we are a dock device | ||
284 | */ | ||
285 | return (is_dock_device(handle) || is_dock_device(parent)); | ||
286 | } | ||
287 | |||
288 | static int bay_add(acpi_handle handle, int id) | ||
289 | { | ||
290 | acpi_status status; | ||
291 | struct bay *new_bay; | ||
292 | struct platform_device *pdev; | ||
293 | struct acpi_buffer nbuffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
294 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &nbuffer); | ||
295 | |||
296 | bay_dprintk(handle, "Adding notify handler"); | ||
297 | |||
298 | /* | ||
299 | * Initialize bay device structure | ||
300 | */ | ||
301 | new_bay = kzalloc(GFP_ATOMIC, sizeof(*new_bay)); | ||
302 | INIT_LIST_HEAD(&new_bay->list); | ||
303 | new_bay->handle = handle; | ||
304 | new_bay->name = (char *)nbuffer.pointer; | ||
305 | |||
306 | /* initialize platform device stuff */ | ||
307 | pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0); | ||
308 | if (pdev == NULL) { | ||
309 | printk(KERN_ERR PREFIX "Error registering bay device\n"); | ||
310 | goto bay_add_err; | ||
311 | } | ||
312 | new_bay->pdev = pdev; | ||
313 | platform_set_drvdata(pdev, new_bay); | ||
314 | |||
315 | if (acpi_bay_add_fs(new_bay)) { | ||
316 | platform_device_unregister(new_bay->pdev); | ||
317 | goto bay_add_err; | ||
318 | } | ||
319 | |||
320 | /* register for events on this device */ | ||
321 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
322 | bay_notify, new_bay); | ||
323 | if (ACPI_FAILURE(status)) { | ||
324 | printk(KERN_ERR PREFIX "Error installing bay notify handler\n"); | ||
325 | } | ||
326 | |||
327 | /* if we are on a dock station, we should register for dock | ||
328 | * notifications. | ||
329 | */ | ||
330 | if (bay_is_dock_device(handle)) { | ||
331 | bay_dprintk(handle, "Is dependent on dock\n"); | ||
332 | register_hotplug_dock_device(handle, bay_notify, new_bay); | ||
333 | } | ||
334 | list_add(&new_bay->list, &drive_bays); | ||
335 | printk(KERN_INFO PREFIX "Bay [%s] Added\n", new_bay->name); | ||
336 | return 0; | ||
337 | |||
338 | bay_add_err: | ||
339 | kfree(new_bay->name); | ||
340 | kfree(new_bay); | ||
341 | return -ENODEV; | ||
342 | } | ||
343 | |||
344 | static int acpi_bay_remove(struct acpi_device *device, int type) | ||
345 | { | ||
346 | /*** FIXME: do something here */ | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int acpi_bay_match(struct acpi_device *device, | ||
351 | struct acpi_driver *driver) | ||
352 | { | ||
353 | if (!device || !driver) | ||
354 | return -EINVAL; | ||
355 | |||
356 | if (is_ejectable_bay(device->handle)) { | ||
357 | bay_dprintk(device->handle, "matching bay device"); | ||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | return -ENODEV; | ||
362 | } | ||
363 | |||
364 | /** | ||
365 | * bay_create_acpi_device - add new devices to acpi | ||
366 | * @handle - handle of the device to add | ||
367 | * | ||
368 | * This function will create a new acpi_device for the given | ||
369 | * handle if one does not exist already. This should cause | ||
370 | * acpi to scan for drivers for the given devices, and call | ||
371 | * matching driver's add routine. | ||
372 | * | ||
373 | * Returns a pointer to the acpi_device corresponding to the handle. | ||
374 | */ | ||
375 | static struct acpi_device * bay_create_acpi_device(acpi_handle handle) | ||
376 | { | ||
377 | struct acpi_device *device = NULL; | ||
378 | struct acpi_device *parent_device; | ||
379 | acpi_handle parent; | ||
380 | int ret; | ||
381 | |||
382 | bay_dprintk(handle, "Trying to get device"); | ||
383 | if (acpi_bus_get_device(handle, &device)) { | ||
384 | /* | ||
385 | * no device created for this object, | ||
386 | * so we should create one. | ||
387 | */ | ||
388 | bay_dprintk(handle, "No device for handle"); | ||
389 | acpi_get_parent(handle, &parent); | ||
390 | if (acpi_bus_get_device(parent, &parent_device)) | ||
391 | parent_device = NULL; | ||
392 | |||
393 | ret = acpi_bus_add(&device, parent_device, handle, | ||
394 | ACPI_BUS_TYPE_DEVICE); | ||
395 | if (ret) { | ||
396 | pr_debug("error adding bus, %x\n", | ||
397 | -ret); | ||
398 | return NULL; | ||
399 | } | ||
400 | } | ||
401 | return device; | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | * bay_notify - act upon an acpi bay notification | ||
406 | * @handle: the bay handle | ||
407 | * @event: the acpi event | ||
408 | * @data: our driver data struct | ||
409 | * | ||
410 | */ | ||
411 | static void bay_notify(acpi_handle handle, u32 event, void *data) | ||
412 | { | ||
413 | struct acpi_device *dev; | ||
414 | |||
415 | bay_dprintk(handle, "Bay event"); | ||
416 | |||
417 | switch(event) { | ||
418 | case ACPI_NOTIFY_BUS_CHECK: | ||
419 | printk("Bus Check\n"); | ||
420 | case ACPI_NOTIFY_DEVICE_CHECK: | ||
421 | printk("Device Check\n"); | ||
422 | dev = bay_create_acpi_device(handle); | ||
423 | if (dev) | ||
424 | acpi_bus_generate_event(dev, event, 0); | ||
425 | else | ||
426 | printk("No device for generating event\n"); | ||
427 | /* wouldn't it be a good idea to just rescan SATA | ||
428 | * right here? | ||
429 | */ | ||
430 | break; | ||
431 | case ACPI_NOTIFY_EJECT_REQUEST: | ||
432 | printk("Eject request\n"); | ||
433 | dev = bay_create_acpi_device(handle); | ||
434 | if (dev) | ||
435 | acpi_bus_generate_event(dev, event, 0); | ||
436 | else | ||
437 | printk("No device for generating eventn"); | ||
438 | |||
439 | /* wouldn't it be a good idea to just call the | ||
440 | * eject_device here if we were a SATA device? | ||
441 | */ | ||
442 | break; | ||
443 | default: | ||
444 | printk("unknown event %d\n", event); | ||
445 | } | ||
446 | } | ||
447 | |||
448 | static acpi_status | ||
449 | find_bay(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
450 | { | ||
451 | int *count = (int *)context; | ||
452 | |||
453 | /* | ||
454 | * there could be more than one ejectable bay. | ||
455 | * so, just return AE_OK always so that every object | ||
456 | * will be checked. | ||
457 | */ | ||
458 | if (is_ejectable_bay(handle)) { | ||
459 | bay_dprintk(handle, "found ejectable bay"); | ||
460 | if (!bay_add(handle, *count)) | ||
461 | (*count)++; | ||
462 | } | ||
463 | return AE_OK; | ||
464 | } | ||
465 | |||
466 | static int __init bay_init(void) | ||
467 | { | ||
468 | int bays = 0; | ||
469 | |||
470 | INIT_LIST_HEAD(&drive_bays); | ||
471 | |||
472 | /* look for dockable drive bays */ | ||
473 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
474 | ACPI_UINT32_MAX, find_bay, &bays, NULL); | ||
475 | |||
476 | if (bays) | ||
477 | if ((acpi_bus_register_driver(&acpi_bay_driver) < 0)) | ||
478 | printk(KERN_ERR "Unable to register bay driver\n"); | ||
479 | |||
480 | if (!bays) | ||
481 | return -ENODEV; | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | static void __exit bay_exit(void) | ||
487 | { | ||
488 | struct bay *bay, *tmp; | ||
489 | |||
490 | list_for_each_entry_safe(bay, tmp, &drive_bays, list) { | ||
491 | if (is_dock_device(bay->handle)) | ||
492 | unregister_hotplug_dock_device(bay->handle); | ||
493 | acpi_bay_remove_fs(bay); | ||
494 | acpi_remove_notify_handler(bay->handle, ACPI_SYSTEM_NOTIFY, | ||
495 | bay_notify); | ||
496 | platform_device_unregister(bay->pdev); | ||
497 | kfree(bay->name); | ||
498 | kfree(bay); | ||
499 | } | ||
500 | |||
501 | acpi_bus_unregister_driver(&acpi_bay_driver); | ||
502 | } | ||
503 | |||
504 | postcore_initcall(bay_init); | ||
505 | module_exit(bay_exit); | ||
506 | |||
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index f9c972b26f4f..f289fd41e77d 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -44,7 +44,7 @@ struct acpi_blacklist_item { | |||
44 | char oem_id[7]; | 44 | char oem_id[7]; |
45 | char oem_table_id[9]; | 45 | char oem_table_id[9]; |
46 | u32 oem_revision; | 46 | u32 oem_revision; |
47 | acpi_table_type table; | 47 | char *table; |
48 | enum acpi_blacklist_predicates oem_revision_predicate; | 48 | enum acpi_blacklist_predicates oem_revision_predicate; |
49 | char *reason; | 49 | char *reason; |
50 | u32 is_critical_error; | 50 | u32 is_critical_error; |
@@ -56,18 +56,18 @@ struct acpi_blacklist_item { | |||
56 | */ | 56 | */ |
57 | static struct acpi_blacklist_item acpi_blacklist[] __initdata = { | 57 | static struct acpi_blacklist_item acpi_blacklist[] __initdata = { |
58 | /* Compaq Presario 1700 */ | 58 | /* Compaq Presario 1700 */ |
59 | {"PTLTD ", " DSDT ", 0x06040000, ACPI_DSDT, less_than_or_equal, | 59 | {"PTLTD ", " DSDT ", 0x06040000, ACPI_SIG_DSDT, less_than_or_equal, |
60 | "Multiple problems", 1}, | 60 | "Multiple problems", 1}, |
61 | /* Sony FX120, FX140, FX150? */ | 61 | /* Sony FX120, FX140, FX150? */ |
62 | {"SONY ", "U0 ", 0x20010313, ACPI_DSDT, less_than_or_equal, | 62 | {"SONY ", "U0 ", 0x20010313, ACPI_SIG_DSDT, less_than_or_equal, |
63 | "ACPI driver problem", 1}, | 63 | "ACPI driver problem", 1}, |
64 | /* Compaq Presario 800, Insyde BIOS */ | 64 | /* Compaq Presario 800, Insyde BIOS */ |
65 | {"INT440", "SYSFexxx", 0x00001001, ACPI_DSDT, less_than_or_equal, | 65 | {"INT440", "SYSFexxx", 0x00001001, ACPI_SIG_DSDT, less_than_or_equal, |
66 | "Does not use _REG to protect EC OpRegions", 1}, | 66 | "Does not use _REG to protect EC OpRegions", 1}, |
67 | /* IBM 600E - _ADR should return 7, but it returns 1 */ | 67 | /* IBM 600E - _ADR should return 7, but it returns 1 */ |
68 | {"IBM ", "TP600E ", 0x00000105, ACPI_DSDT, less_than_or_equal, | 68 | {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal, |
69 | "Incorrect _ADR", 1}, | 69 | "Incorrect _ADR", 1}, |
70 | {"ASUS\0\0", "P2B-S ", 0, ACPI_DSDT, all_versions, | 70 | {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions, |
71 | "Bogus PCI routing", 1}, | 71 | "Bogus PCI routing", 1}, |
72 | 72 | ||
73 | {""} | 73 | {""} |
@@ -79,7 +79,7 @@ static int __init blacklist_by_year(void) | |||
79 | { | 79 | { |
80 | int year = dmi_get_year(DMI_BIOS_DATE); | 80 | int year = dmi_get_year(DMI_BIOS_DATE); |
81 | /* Doesn't exist? Likely an old system */ | 81 | /* Doesn't exist? Likely an old system */ |
82 | if (year == -1) | 82 | if (year == -1) |
83 | return 1; | 83 | return 1; |
84 | /* 0? Likely a buggy new BIOS */ | 84 | /* 0? Likely a buggy new BIOS */ |
85 | if (year == 0) | 85 | if (year == 0) |
@@ -103,22 +103,21 @@ int __init acpi_blacklisted(void) | |||
103 | { | 103 | { |
104 | int i = 0; | 104 | int i = 0; |
105 | int blacklisted = 0; | 105 | int blacklisted = 0; |
106 | struct acpi_table_header *table_header; | 106 | struct acpi_table_header table_header; |
107 | 107 | ||
108 | while (acpi_blacklist[i].oem_id[0] != '\0') { | 108 | while (acpi_blacklist[i].oem_id[0] != '\0') { |
109 | if (acpi_get_table_header_early | 109 | if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) { |
110 | (acpi_blacklist[i].table, &table_header)) { | ||
111 | i++; | 110 | i++; |
112 | continue; | 111 | continue; |
113 | } | 112 | } |
114 | 113 | ||
115 | if (strncmp(acpi_blacklist[i].oem_id, table_header->oem_id, 6)) { | 114 | if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) { |
116 | i++; | 115 | i++; |
117 | continue; | 116 | continue; |
118 | } | 117 | } |
119 | 118 | ||
120 | if (strncmp | 119 | if (strncmp |
121 | (acpi_blacklist[i].oem_table_id, table_header->oem_table_id, | 120 | (acpi_blacklist[i].oem_table_id, table_header.oem_table_id, |
122 | 8)) { | 121 | 8)) { |
123 | i++; | 122 | i++; |
124 | continue; | 123 | continue; |
@@ -127,14 +126,14 @@ int __init acpi_blacklisted(void) | |||
127 | if ((acpi_blacklist[i].oem_revision_predicate == all_versions) | 126 | if ((acpi_blacklist[i].oem_revision_predicate == all_versions) |
128 | || (acpi_blacklist[i].oem_revision_predicate == | 127 | || (acpi_blacklist[i].oem_revision_predicate == |
129 | less_than_or_equal | 128 | less_than_or_equal |
130 | && table_header->oem_revision <= | 129 | && table_header.oem_revision <= |
131 | acpi_blacklist[i].oem_revision) | 130 | acpi_blacklist[i].oem_revision) |
132 | || (acpi_blacklist[i].oem_revision_predicate == | 131 | || (acpi_blacklist[i].oem_revision_predicate == |
133 | greater_than_or_equal | 132 | greater_than_or_equal |
134 | && table_header->oem_revision >= | 133 | && table_header.oem_revision >= |
135 | acpi_blacklist[i].oem_revision) | 134 | acpi_blacklist[i].oem_revision) |
136 | || (acpi_blacklist[i].oem_revision_predicate == equal | 135 | || (acpi_blacklist[i].oem_revision_predicate == equal |
137 | && table_header->oem_revision == | 136 | && table_header.oem_revision == |
138 | acpi_blacklist[i].oem_revision)) { | 137 | acpi_blacklist[i].oem_revision)) { |
139 | 138 | ||
140 | printk(KERN_ERR PREFIX | 139 | printk(KERN_ERR PREFIX |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index da471f647d07..c26468da4295 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -44,9 +44,6 @@ ACPI_MODULE_NAME("acpi_bus") | |||
44 | extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger); | 44 | extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger); |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | struct fadt_descriptor acpi_fadt; | ||
48 | EXPORT_SYMBOL(acpi_fadt); | ||
49 | |||
50 | struct acpi_device *acpi_root; | 47 | struct acpi_device *acpi_root; |
51 | struct proc_dir_entry *acpi_root_dir; | 48 | struct proc_dir_entry *acpi_root_dir; |
52 | EXPORT_SYMBOL(acpi_root_dir); | 49 | EXPORT_SYMBOL(acpi_root_dir); |
@@ -561,6 +558,9 @@ static int __init acpi_bus_init_irq(void) | |||
561 | case ACPI_IRQ_MODEL_IOSAPIC: | 558 | case ACPI_IRQ_MODEL_IOSAPIC: |
562 | message = "IOSAPIC"; | 559 | message = "IOSAPIC"; |
563 | break; | 560 | break; |
561 | case ACPI_IRQ_MODEL_PLATFORM: | ||
562 | message = "platform specific model"; | ||
563 | break; | ||
564 | default: | 564 | default: |
565 | printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n"); | 565 | printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n"); |
566 | return -ENODEV; | 566 | return -ENODEV; |
@@ -579,11 +579,12 @@ static int __init acpi_bus_init_irq(void) | |||
579 | return 0; | 579 | return 0; |
580 | } | 580 | } |
581 | 581 | ||
582 | acpi_native_uint acpi_gbl_permanent_mmap; | ||
583 | |||
584 | |||
582 | void __init acpi_early_init(void) | 585 | void __init acpi_early_init(void) |
583 | { | 586 | { |
584 | acpi_status status = AE_OK; | 587 | acpi_status status = AE_OK; |
585 | struct acpi_buffer buffer = { sizeof(acpi_fadt), &acpi_fadt }; | ||
586 | |||
587 | 588 | ||
588 | if (acpi_disabled) | 589 | if (acpi_disabled) |
589 | return; | 590 | return; |
@@ -594,6 +595,15 @@ void __init acpi_early_init(void) | |||
594 | if (!acpi_strict) | 595 | if (!acpi_strict) |
595 | acpi_gbl_enable_interpreter_slack = TRUE; | 596 | acpi_gbl_enable_interpreter_slack = TRUE; |
596 | 597 | ||
598 | acpi_gbl_permanent_mmap = 1; | ||
599 | |||
600 | status = acpi_reallocate_root_table(); | ||
601 | if (ACPI_FAILURE(status)) { | ||
602 | printk(KERN_ERR PREFIX | ||
603 | "Unable to reallocate ACPI tables\n"); | ||
604 | goto error0; | ||
605 | } | ||
606 | |||
597 | status = acpi_initialize_subsystem(); | 607 | status = acpi_initialize_subsystem(); |
598 | if (ACPI_FAILURE(status)) { | 608 | if (ACPI_FAILURE(status)) { |
599 | printk(KERN_ERR PREFIX | 609 | printk(KERN_ERR PREFIX |
@@ -608,32 +618,25 @@ void __init acpi_early_init(void) | |||
608 | goto error0; | 618 | goto error0; |
609 | } | 619 | } |
610 | 620 | ||
611 | /* | ||
612 | * Get a separate copy of the FADT for use by other drivers. | ||
613 | */ | ||
614 | status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &buffer); | ||
615 | if (ACPI_FAILURE(status)) { | ||
616 | printk(KERN_ERR PREFIX "Unable to get the FADT\n"); | ||
617 | goto error0; | ||
618 | } | ||
619 | #ifdef CONFIG_X86 | 621 | #ifdef CONFIG_X86 |
620 | if (!acpi_ioapic) { | 622 | if (!acpi_ioapic) { |
621 | extern acpi_interrupt_flags acpi_sci_flags; | 623 | extern u8 acpi_sci_flags; |
622 | 624 | ||
623 | /* compatible (0) means level (3) */ | 625 | /* compatible (0) means level (3) */ |
624 | if (acpi_sci_flags.trigger == 0) | 626 | if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) { |
625 | acpi_sci_flags.trigger = 3; | 627 | acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK; |
626 | 628 | acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL; | |
629 | } | ||
627 | /* Set PIC-mode SCI trigger type */ | 630 | /* Set PIC-mode SCI trigger type */ |
628 | acpi_pic_sci_set_trigger(acpi_fadt.sci_int, | 631 | acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt, |
629 | acpi_sci_flags.trigger); | 632 | (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2); |
630 | } else { | 633 | } else { |
631 | extern int acpi_sci_override_gsi; | 634 | extern int acpi_sci_override_gsi; |
632 | /* | 635 | /* |
633 | * now that acpi_fadt is initialized, | 636 | * now that acpi_gbl_FADT is initialized, |
634 | * update it with result from INT_SRC_OVR parsing | 637 | * update it with result from INT_SRC_OVR parsing |
635 | */ | 638 | */ |
636 | acpi_fadt.sci_int = acpi_sci_override_gsi; | 639 | acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi; |
637 | } | 640 | } |
638 | #endif | 641 | #endif |
639 | 642 | ||
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 7fda02c98310..c726612fafb6 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
32 | #include <linux/input.h> | ||
32 | #include <acpi/acpi_bus.h> | 33 | #include <acpi/acpi_bus.h> |
33 | #include <acpi/acpi_drivers.h> | 34 | #include <acpi/acpi_drivers.h> |
34 | 35 | ||
@@ -62,7 +63,7 @@ | |||
62 | #define _COMPONENT ACPI_BUTTON_COMPONENT | 63 | #define _COMPONENT ACPI_BUTTON_COMPONENT |
63 | ACPI_MODULE_NAME("acpi_button") | 64 | ACPI_MODULE_NAME("acpi_button") |
64 | 65 | ||
65 | MODULE_AUTHOR("Paul Diefenbaugh"); | 66 | MODULE_AUTHOR("Paul Diefenbaugh"); |
66 | MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME); | 67 | MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME); |
67 | MODULE_LICENSE("GPL"); | 68 | MODULE_LICENSE("GPL"); |
68 | 69 | ||
@@ -78,12 +79,14 @@ static struct acpi_driver acpi_button_driver = { | |||
78 | .ops = { | 79 | .ops = { |
79 | .add = acpi_button_add, | 80 | .add = acpi_button_add, |
80 | .remove = acpi_button_remove, | 81 | .remove = acpi_button_remove, |
81 | }, | 82 | }, |
82 | }; | 83 | }; |
83 | 84 | ||
84 | struct acpi_button { | 85 | struct acpi_button { |
85 | struct acpi_device *device; /* Fixed button kludge */ | 86 | struct acpi_device *device; /* Fixed button kludge */ |
86 | u8 type; | 87 | unsigned int type; |
88 | struct input_dev *input; | ||
89 | char phys[32]; /* for input device */ | ||
87 | unsigned long pushed; | 90 | unsigned long pushed; |
88 | }; | 91 | }; |
89 | 92 | ||
@@ -109,8 +112,7 @@ static struct proc_dir_entry *acpi_button_dir; | |||
109 | 112 | ||
110 | static int acpi_button_info_seq_show(struct seq_file *seq, void *offset) | 113 | static int acpi_button_info_seq_show(struct seq_file *seq, void *offset) |
111 | { | 114 | { |
112 | struct acpi_button *button = (struct acpi_button *)seq->private; | 115 | struct acpi_button *button = seq->private; |
113 | |||
114 | 116 | ||
115 | if (!button || !button->device) | 117 | if (!button || !button->device) |
116 | return 0; | 118 | return 0; |
@@ -128,22 +130,17 @@ static int acpi_button_info_open_fs(struct inode *inode, struct file *file) | |||
128 | 130 | ||
129 | static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) | 131 | static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) |
130 | { | 132 | { |
131 | struct acpi_button *button = (struct acpi_button *)seq->private; | 133 | struct acpi_button *button = seq->private; |
132 | acpi_status status; | 134 | acpi_status status; |
133 | unsigned long state; | 135 | unsigned long state; |
134 | 136 | ||
135 | |||
136 | if (!button || !button->device) | 137 | if (!button || !button->device) |
137 | return 0; | 138 | return 0; |
138 | 139 | ||
139 | status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state); | 140 | status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state); |
140 | if (ACPI_FAILURE(status)) { | 141 | seq_printf(seq, "state: %s\n", |
141 | seq_printf(seq, "state: unsupported\n"); | 142 | ACPI_FAILURE(status) ? "unsupported" : |
142 | } else { | 143 | (state ? "open" : "closed")); |
143 | seq_printf(seq, "state: %s\n", | ||
144 | (state ? "open" : "closed")); | ||
145 | } | ||
146 | |||
147 | return 0; | 144 | return 0; |
148 | } | 145 | } |
149 | 146 | ||
@@ -159,8 +156,7 @@ static struct proc_dir_entry *acpi_lid_dir; | |||
159 | static int acpi_button_add_fs(struct acpi_device *device) | 156 | static int acpi_button_add_fs(struct acpi_device *device) |
160 | { | 157 | { |
161 | struct proc_dir_entry *entry = NULL; | 158 | struct proc_dir_entry *entry = NULL; |
162 | struct acpi_button *button = NULL; | 159 | struct acpi_button *button; |
163 | |||
164 | 160 | ||
165 | if (!device || !acpi_driver_data(device)) | 161 | if (!device || !acpi_driver_data(device)) |
166 | return -EINVAL; | 162 | return -EINVAL; |
@@ -228,10 +224,8 @@ static int acpi_button_add_fs(struct acpi_device *device) | |||
228 | 224 | ||
229 | static int acpi_button_remove_fs(struct acpi_device *device) | 225 | static int acpi_button_remove_fs(struct acpi_device *device) |
230 | { | 226 | { |
231 | struct acpi_button *button = NULL; | 227 | struct acpi_button *button = acpi_driver_data(device); |
232 | |||
233 | 228 | ||
234 | button = acpi_driver_data(device); | ||
235 | if (acpi_device_dir(device)) { | 229 | if (acpi_device_dir(device)) { |
236 | if (button->type == ACPI_BUTTON_TYPE_LID) | 230 | if (button->type == ACPI_BUTTON_TYPE_LID) |
237 | remove_proc_entry(ACPI_BUTTON_FILE_STATE, | 231 | remove_proc_entry(ACPI_BUTTON_FILE_STATE, |
@@ -253,14 +247,34 @@ static int acpi_button_remove_fs(struct acpi_device *device) | |||
253 | 247 | ||
254 | static void acpi_button_notify(acpi_handle handle, u32 event, void *data) | 248 | static void acpi_button_notify(acpi_handle handle, u32 event, void *data) |
255 | { | 249 | { |
256 | struct acpi_button *button = (struct acpi_button *)data; | 250 | struct acpi_button *button = data; |
257 | 251 | struct input_dev *input; | |
258 | 252 | ||
259 | if (!button || !button->device) | 253 | if (!button || !button->device) |
260 | return; | 254 | return; |
261 | 255 | ||
262 | switch (event) { | 256 | switch (event) { |
263 | case ACPI_BUTTON_NOTIFY_STATUS: | 257 | case ACPI_BUTTON_NOTIFY_STATUS: |
258 | input = button->input; | ||
259 | |||
260 | if (button->type == ACPI_BUTTON_TYPE_LID) { | ||
261 | struct acpi_handle *handle = button->device->handle; | ||
262 | unsigned long state; | ||
263 | |||
264 | if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID", | ||
265 | NULL, &state))) | ||
266 | input_report_switch(input, SW_LID, !state); | ||
267 | |||
268 | } else { | ||
269 | int keycode = test_bit(KEY_SLEEP, input->keybit) ? | ||
270 | KEY_SLEEP : KEY_POWER; | ||
271 | |||
272 | input_report_key(input, keycode, 1); | ||
273 | input_sync(input); | ||
274 | input_report_key(input, keycode, 0); | ||
275 | } | ||
276 | input_sync(input); | ||
277 | |||
264 | acpi_bus_generate_event(button->device, event, | 278 | acpi_bus_generate_event(button->device, event, |
265 | ++button->pushed); | 279 | ++button->pushed); |
266 | break; | 280 | break; |
@@ -275,8 +289,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) | |||
275 | 289 | ||
276 | static acpi_status acpi_button_notify_fixed(void *data) | 290 | static acpi_status acpi_button_notify_fixed(void *data) |
277 | { | 291 | { |
278 | struct acpi_button *button = (struct acpi_button *)data; | 292 | struct acpi_button *button = data; |
279 | |||
280 | 293 | ||
281 | if (!button) | 294 | if (!button) |
282 | return AE_BAD_PARAMETER; | 295 | return AE_BAD_PARAMETER; |
@@ -286,24 +299,75 @@ static acpi_status acpi_button_notify_fixed(void *data) | |||
286 | return AE_OK; | 299 | return AE_OK; |
287 | } | 300 | } |
288 | 301 | ||
289 | static int acpi_button_add(struct acpi_device *device) | 302 | static int acpi_button_install_notify_handlers(struct acpi_button *button) |
290 | { | 303 | { |
291 | int result = 0; | 304 | acpi_status status; |
292 | acpi_status status = AE_OK; | ||
293 | struct acpi_button *button = NULL; | ||
294 | 305 | ||
306 | switch (button->type) { | ||
307 | case ACPI_BUTTON_TYPE_POWERF: | ||
308 | status = | ||
309 | acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, | ||
310 | acpi_button_notify_fixed, | ||
311 | button); | ||
312 | break; | ||
313 | case ACPI_BUTTON_TYPE_SLEEPF: | ||
314 | status = | ||
315 | acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, | ||
316 | acpi_button_notify_fixed, | ||
317 | button); | ||
318 | break; | ||
319 | default: | ||
320 | status = acpi_install_notify_handler(button->device->handle, | ||
321 | ACPI_DEVICE_NOTIFY, | ||
322 | acpi_button_notify, | ||
323 | button); | ||
324 | break; | ||
325 | } | ||
326 | |||
327 | return ACPI_FAILURE(status) ? -ENODEV : 0; | ||
328 | } | ||
329 | |||
330 | static void acpi_button_remove_notify_handlers(struct acpi_button *button) | ||
331 | { | ||
332 | switch (button->type) { | ||
333 | case ACPI_BUTTON_TYPE_POWERF: | ||
334 | acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, | ||
335 | acpi_button_notify_fixed); | ||
336 | break; | ||
337 | case ACPI_BUTTON_TYPE_SLEEPF: | ||
338 | acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, | ||
339 | acpi_button_notify_fixed); | ||
340 | break; | ||
341 | default: | ||
342 | acpi_remove_notify_handler(button->device->handle, | ||
343 | ACPI_DEVICE_NOTIFY, | ||
344 | acpi_button_notify); | ||
345 | break; | ||
346 | } | ||
347 | } | ||
348 | |||
349 | static int acpi_button_add(struct acpi_device *device) | ||
350 | { | ||
351 | int error; | ||
352 | struct acpi_button *button; | ||
353 | struct input_dev *input; | ||
295 | 354 | ||
296 | if (!device) | 355 | if (!device) |
297 | return -EINVAL; | 356 | return -EINVAL; |
298 | 357 | ||
299 | button = kmalloc(sizeof(struct acpi_button), GFP_KERNEL); | 358 | button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL); |
300 | if (!button) | 359 | if (!button) |
301 | return -ENOMEM; | 360 | return -ENOMEM; |
302 | memset(button, 0, sizeof(struct acpi_button)); | ||
303 | 361 | ||
304 | button->device = device; | 362 | button->device = device; |
305 | acpi_driver_data(device) = button; | 363 | acpi_driver_data(device) = button; |
306 | 364 | ||
365 | button->input = input = input_allocate_device(); | ||
366 | if (!input) { | ||
367 | error = -ENOMEM; | ||
368 | goto err_free_button; | ||
369 | } | ||
370 | |||
307 | /* | 371 | /* |
308 | * Determine the button type (via hid), as fixed-feature buttons | 372 | * Determine the button type (via hid), as fixed-feature buttons |
309 | * need to be handled a bit differently than generic-space. | 373 | * need to be handled a bit differently than generic-space. |
@@ -338,39 +402,48 @@ static int acpi_button_add(struct acpi_device *device) | |||
338 | } else { | 402 | } else { |
339 | printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", | 403 | printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", |
340 | acpi_device_hid(device)); | 404 | acpi_device_hid(device)); |
341 | result = -ENODEV; | 405 | error = -ENODEV; |
342 | goto end; | 406 | goto err_free_input; |
343 | } | 407 | } |
344 | 408 | ||
345 | result = acpi_button_add_fs(device); | 409 | error = acpi_button_add_fs(device); |
346 | if (result) | 410 | if (error) |
347 | goto end; | 411 | goto err_free_input; |
412 | |||
413 | error = acpi_button_install_notify_handlers(button); | ||
414 | if (error) | ||
415 | goto err_remove_fs; | ||
416 | |||
417 | snprintf(button->phys, sizeof(button->phys), | ||
418 | "%s/button/input0", acpi_device_hid(device)); | ||
419 | |||
420 | input->name = acpi_device_name(device); | ||
421 | input->phys = button->phys; | ||
422 | input->id.bustype = BUS_HOST; | ||
423 | input->id.product = button->type; | ||
348 | 424 | ||
349 | switch (button->type) { | 425 | switch (button->type) { |
426 | case ACPI_BUTTON_TYPE_POWER: | ||
350 | case ACPI_BUTTON_TYPE_POWERF: | 427 | case ACPI_BUTTON_TYPE_POWERF: |
351 | status = | 428 | input->evbit[0] = BIT(EV_KEY); |
352 | acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, | 429 | set_bit(KEY_POWER, input->keybit); |
353 | acpi_button_notify_fixed, | ||
354 | button); | ||
355 | break; | 430 | break; |
431 | |||
432 | case ACPI_BUTTON_TYPE_SLEEP: | ||
356 | case ACPI_BUTTON_TYPE_SLEEPF: | 433 | case ACPI_BUTTON_TYPE_SLEEPF: |
357 | status = | 434 | input->evbit[0] = BIT(EV_KEY); |
358 | acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, | 435 | set_bit(KEY_SLEEP, input->keybit); |
359 | acpi_button_notify_fixed, | ||
360 | button); | ||
361 | break; | 436 | break; |
362 | default: | 437 | |
363 | status = acpi_install_notify_handler(device->handle, | 438 | case ACPI_BUTTON_TYPE_LID: |
364 | ACPI_DEVICE_NOTIFY, | 439 | input->evbit[0] = BIT(EV_SW); |
365 | acpi_button_notify, | 440 | set_bit(SW_LID, input->swbit); |
366 | button); | ||
367 | break; | 441 | break; |
368 | } | 442 | } |
369 | 443 | ||
370 | if (ACPI_FAILURE(status)) { | 444 | error = input_register_device(input); |
371 | result = -ENODEV; | 445 | if (error) |
372 | goto end; | 446 | goto err_remove_handlers; |
373 | } | ||
374 | 447 | ||
375 | if (device->wakeup.flags.valid) { | 448 | if (device->wakeup.flags.valid) { |
376 | /* Button's GPE is run-wake GPE */ | 449 | /* Button's GPE is run-wake GPE */ |
@@ -385,47 +458,31 @@ static int acpi_button_add(struct acpi_device *device) | |||
385 | printk(KERN_INFO PREFIX "%s [%s]\n", | 458 | printk(KERN_INFO PREFIX "%s [%s]\n", |
386 | acpi_device_name(device), acpi_device_bid(device)); | 459 | acpi_device_name(device), acpi_device_bid(device)); |
387 | 460 | ||
388 | end: | 461 | return 0; |
389 | if (result) { | ||
390 | acpi_button_remove_fs(device); | ||
391 | kfree(button); | ||
392 | } | ||
393 | 462 | ||
394 | return result; | 463 | err_remove_handlers: |
464 | acpi_button_remove_notify_handlers(button); | ||
465 | err_remove_fs: | ||
466 | acpi_button_remove_fs(device); | ||
467 | err_free_input: | ||
468 | input_free_device(input); | ||
469 | err_free_button: | ||
470 | kfree(button); | ||
471 | return error; | ||
395 | } | 472 | } |
396 | 473 | ||
397 | static int acpi_button_remove(struct acpi_device *device, int type) | 474 | static int acpi_button_remove(struct acpi_device *device, int type) |
398 | { | 475 | { |
399 | acpi_status status = 0; | 476 | struct acpi_button *button; |
400 | struct acpi_button *button = NULL; | ||
401 | |||
402 | 477 | ||
403 | if (!device || !acpi_driver_data(device)) | 478 | if (!device || !acpi_driver_data(device)) |
404 | return -EINVAL; | 479 | return -EINVAL; |
405 | 480 | ||
406 | button = acpi_driver_data(device); | 481 | button = acpi_driver_data(device); |
407 | 482 | ||
408 | /* Unregister for device notifications. */ | 483 | acpi_button_remove_notify_handlers(button); |
409 | switch (button->type) { | ||
410 | case ACPI_BUTTON_TYPE_POWERF: | ||
411 | status = | ||
412 | acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, | ||
413 | acpi_button_notify_fixed); | ||
414 | break; | ||
415 | case ACPI_BUTTON_TYPE_SLEEPF: | ||
416 | status = | ||
417 | acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, | ||
418 | acpi_button_notify_fixed); | ||
419 | break; | ||
420 | default: | ||
421 | status = acpi_remove_notify_handler(device->handle, | ||
422 | ACPI_DEVICE_NOTIFY, | ||
423 | acpi_button_notify); | ||
424 | break; | ||
425 | } | ||
426 | |||
427 | acpi_button_remove_fs(device); | 484 | acpi_button_remove_fs(device); |
428 | 485 | input_unregister_device(button->input); | |
429 | kfree(button); | 486 | kfree(button); |
430 | 487 | ||
431 | return 0; | 488 | return 0; |
@@ -433,8 +490,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) | |||
433 | 490 | ||
434 | static int __init acpi_button_init(void) | 491 | static int __init acpi_button_init(void) |
435 | { | 492 | { |
436 | int result = 0; | 493 | int result; |
437 | |||
438 | 494 | ||
439 | acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); | 495 | acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); |
440 | if (!acpi_button_dir) | 496 | if (!acpi_button_dir) |
@@ -451,7 +507,6 @@ static int __init acpi_button_init(void) | |||
451 | 507 | ||
452 | static void __exit acpi_button_exit(void) | 508 | static void __exit acpi_button_exit(void) |
453 | { | 509 | { |
454 | |||
455 | acpi_bus_unregister_driver(&acpi_button_driver); | 510 | acpi_bus_unregister_driver(&acpi_button_driver); |
456 | 511 | ||
457 | if (acpi_power_dir) | 512 | if (acpi_power_dir) |
@@ -461,8 +516,6 @@ static void __exit acpi_button_exit(void) | |||
461 | if (acpi_lid_dir) | 516 | if (acpi_lid_dir) |
462 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); | 517 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); |
463 | remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); | 518 | remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); |
464 | |||
465 | return; | ||
466 | } | 519 | } |
467 | 520 | ||
468 | module_init(acpi_button_init); | 521 | module_init(acpi_button_init); |
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 914f56ae4b44..69a68fd394cf 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -96,11 +96,10 @@ static int acpi_container_add(struct acpi_device *device) | |||
96 | return -EINVAL; | 96 | return -EINVAL; |
97 | } | 97 | } |
98 | 98 | ||
99 | container = kmalloc(sizeof(struct acpi_container), GFP_KERNEL); | 99 | container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL); |
100 | if (!container) | 100 | if (!container) |
101 | return -ENOMEM; | 101 | return -ENOMEM; |
102 | 102 | ||
103 | memset(container, 0, sizeof(struct acpi_container)); | ||
104 | container->handle = device->handle; | 103 | container->handle = device->handle; |
105 | strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME); | 104 | strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME); |
106 | strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS); | 105 | strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS); |
@@ -117,7 +116,7 @@ static int acpi_container_remove(struct acpi_device *device, int type) | |||
117 | acpi_status status = AE_OK; | 116 | acpi_status status = AE_OK; |
118 | struct acpi_container *pc = NULL; | 117 | struct acpi_container *pc = NULL; |
119 | 118 | ||
120 | pc = (struct acpi_container *)acpi_driver_data(device); | 119 | pc = acpi_driver_data(device); |
121 | kfree(pc); | 120 | kfree(pc); |
122 | return status; | 121 | return status; |
123 | } | 122 | } |
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c index a6d77efb41a0..f049639bac35 100644 --- a/drivers/acpi/dispatcher/dsfield.c +++ b/drivers/acpi/dispatcher/dsfield.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -133,7 +133,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
133 | } | 133 | } |
134 | } | 134 | } |
135 | 135 | ||
136 | /* We could put the returned object (Node) on the object stack for later, | 136 | /* |
137 | * We could put the returned object (Node) on the object stack for later, | ||
137 | * but for now, we will put it in the "op" object that the parser uses, | 138 | * but for now, we will put it in the "op" object that the parser uses, |
138 | * so we can get it again at the end of this scope | 139 | * so we can get it again at the end of this scope |
139 | */ | 140 | */ |
@@ -514,8 +515,33 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, | |||
514 | 515 | ||
515 | /* Third arg is the bank_value */ | 516 | /* Third arg is the bank_value */ |
516 | 517 | ||
518 | /* TBD: This arg is a term_arg, not a constant, and must be evaluated */ | ||
519 | |||
517 | arg = arg->common.next; | 520 | arg = arg->common.next; |
518 | info.bank_value = (u32) arg->common.value.integer; | 521 | |
522 | /* Currently, only the following constants are supported */ | ||
523 | |||
524 | switch (arg->common.aml_opcode) { | ||
525 | case AML_ZERO_OP: | ||
526 | info.bank_value = 0; | ||
527 | break; | ||
528 | |||
529 | case AML_ONE_OP: | ||
530 | info.bank_value = 1; | ||
531 | break; | ||
532 | |||
533 | case AML_BYTE_OP: | ||
534 | case AML_WORD_OP: | ||
535 | case AML_DWORD_OP: | ||
536 | case AML_QWORD_OP: | ||
537 | info.bank_value = (u32) arg->common.value.integer; | ||
538 | break; | ||
539 | |||
540 | default: | ||
541 | info.bank_value = 0; | ||
542 | ACPI_ERROR((AE_INFO, | ||
543 | "Non-constant BankValue for BankField is not implemented")); | ||
544 | } | ||
519 | 545 | ||
520 | /* Fourth arg is the field flags */ | 546 | /* Fourth arg is the field flags */ |
521 | 547 | ||
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c index 1888c055d10f..af923c388520 100644 --- a/drivers/acpi/dispatcher/dsinit.c +++ b/drivers/acpi/dispatcher/dsinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -44,6 +44,7 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acdispat.h> | 45 | #include <acpi/acdispat.h> |
46 | #include <acpi/acnamesp.h> | 46 | #include <acpi/acnamesp.h> |
47 | #include <acpi/actables.h> | ||
47 | 48 | ||
48 | #define _COMPONENT ACPI_DISPATCHER | 49 | #define _COMPONENT ACPI_DISPATCHER |
49 | ACPI_MODULE_NAME("dsinit") | 50 | ACPI_MODULE_NAME("dsinit") |
@@ -90,7 +91,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, | |||
90 | * We are only interested in NS nodes owned by the table that | 91 | * We are only interested in NS nodes owned by the table that |
91 | * was just loaded | 92 | * was just loaded |
92 | */ | 93 | */ |
93 | if (node->owner_id != info->table_desc->owner_id) { | 94 | if (node->owner_id != info->owner_id) { |
94 | return (AE_OK); | 95 | return (AE_OK); |
95 | } | 96 | } |
96 | 97 | ||
@@ -150,14 +151,21 @@ acpi_ds_init_one_object(acpi_handle obj_handle, | |||
150 | ******************************************************************************/ | 151 | ******************************************************************************/ |
151 | 152 | ||
152 | acpi_status | 153 | acpi_status |
153 | acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, | 154 | acpi_ds_initialize_objects(acpi_native_uint table_index, |
154 | struct acpi_namespace_node * start_node) | 155 | struct acpi_namespace_node * start_node) |
155 | { | 156 | { |
156 | acpi_status status; | 157 | acpi_status status; |
157 | struct acpi_init_walk_info info; | 158 | struct acpi_init_walk_info info; |
159 | struct acpi_table_header *table; | ||
160 | acpi_owner_id owner_id; | ||
158 | 161 | ||
159 | ACPI_FUNCTION_TRACE(ds_initialize_objects); | 162 | ACPI_FUNCTION_TRACE(ds_initialize_objects); |
160 | 163 | ||
164 | status = acpi_tb_get_owner_id(table_index, &owner_id); | ||
165 | if (ACPI_FAILURE(status)) { | ||
166 | return_ACPI_STATUS(status); | ||
167 | } | ||
168 | |||
161 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 169 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
162 | "**** Starting initialization of namespace objects ****\n")); | 170 | "**** Starting initialization of namespace objects ****\n")); |
163 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:")); | 171 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:")); |
@@ -166,7 +174,8 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, | |||
166 | info.op_region_count = 0; | 174 | info.op_region_count = 0; |
167 | info.object_count = 0; | 175 | info.object_count = 0; |
168 | info.device_count = 0; | 176 | info.device_count = 0; |
169 | info.table_desc = table_desc; | 177 | info.table_index = table_index; |
178 | info.owner_id = owner_id; | ||
170 | 179 | ||
171 | /* Walk entire namespace from the supplied root */ | 180 | /* Walk entire namespace from the supplied root */ |
172 | 181 | ||
@@ -176,10 +185,14 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, | |||
176 | ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); | 185 | ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); |
177 | } | 186 | } |
178 | 187 | ||
188 | status = acpi_get_table_by_index(table_index, &table); | ||
189 | if (ACPI_FAILURE(status)) { | ||
190 | return_ACPI_STATUS(status); | ||
191 | } | ||
192 | |||
179 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | 193 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
180 | "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n", | 194 | "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n", |
181 | table_desc->pointer->signature, | 195 | table->signature, owner_id, info.object_count, |
182 | table_desc->owner_id, info.object_count, | ||
183 | info.device_count, info.method_count, | 196 | info.device_count, info.method_count, |
184 | info.op_region_count)); | 197 | info.op_region_count)); |
185 | 198 | ||
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index cf888add3191..1cbe61905824 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -327,7 +327,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, | |||
327 | ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state); | 327 | ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state); |
328 | 328 | ||
329 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 329 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
330 | "Execute method %p, currentstate=%p\n", | 330 | "Calling method %p, currentstate=%p\n", |
331 | this_walk_state->prev_op, this_walk_state)); | 331 | this_walk_state->prev_op, this_walk_state)); |
332 | 332 | ||
333 | /* | 333 | /* |
@@ -351,49 +351,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, | |||
351 | return_ACPI_STATUS(status); | 351 | return_ACPI_STATUS(status); |
352 | } | 352 | } |
353 | 353 | ||
354 | /* | 354 | /* Begin method parse/execution. Create a new walk state */ |
355 | * 1) Parse the method. All "normal" methods are parsed for each execution. | ||
356 | * Internal methods (_OSI, etc.) do not require parsing. | ||
357 | */ | ||
358 | if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) { | ||
359 | |||
360 | /* Create a new walk state for the parse */ | ||
361 | |||
362 | next_walk_state = | ||
363 | acpi_ds_create_walk_state(obj_desc->method.owner_id, op, | ||
364 | obj_desc, NULL); | ||
365 | if (!next_walk_state) { | ||
366 | status = AE_NO_MEMORY; | ||
367 | goto cleanup; | ||
368 | } | ||
369 | |||
370 | /* Create and init a parse tree root */ | ||
371 | |||
372 | op = acpi_ps_create_scope_op(); | ||
373 | if (!op) { | ||
374 | status = AE_NO_MEMORY; | ||
375 | goto cleanup; | ||
376 | } | ||
377 | |||
378 | status = acpi_ds_init_aml_walk(next_walk_state, op, method_node, | ||
379 | obj_desc->method.aml_start, | ||
380 | obj_desc->method.aml_length, | ||
381 | NULL, 1); | ||
382 | if (ACPI_FAILURE(status)) { | ||
383 | acpi_ps_delete_parse_tree(op); | ||
384 | goto cleanup; | ||
385 | } | ||
386 | |||
387 | /* Begin AML parse (deletes next_walk_state) */ | ||
388 | |||
389 | status = acpi_ps_parse_aml(next_walk_state); | ||
390 | acpi_ps_delete_parse_tree(op); | ||
391 | if (ACPI_FAILURE(status)) { | ||
392 | goto cleanup; | ||
393 | } | ||
394 | } | ||
395 | |||
396 | /* 2) Begin method execution. Create a new walk state */ | ||
397 | 355 | ||
398 | next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id, | 356 | next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id, |
399 | NULL, obj_desc, thread); | 357 | NULL, obj_desc, thread); |
@@ -424,7 +382,8 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, | |||
424 | 382 | ||
425 | status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, | 383 | status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, |
426 | obj_desc->method.aml_start, | 384 | obj_desc->method.aml_start, |
427 | obj_desc->method.aml_length, info, 3); | 385 | obj_desc->method.aml_length, info, |
386 | ACPI_IMODE_EXECUTE); | ||
428 | 387 | ||
429 | ACPI_FREE(info); | 388 | ACPI_FREE(info); |
430 | if (ACPI_FAILURE(status)) { | 389 | if (ACPI_FAILURE(status)) { |
@@ -445,8 +404,8 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, | |||
445 | this_walk_state->num_operands = 0; | 404 | this_walk_state->num_operands = 0; |
446 | 405 | ||
447 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 406 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
448 | "Starting nested execution, newstate=%p\n", | 407 | "**** Begin nested execution of [%4.4s] **** WalkState=%p\n", |
449 | next_walk_state)); | 408 | method_node->name.ascii, next_walk_state)); |
450 | 409 | ||
451 | /* Invoke an internal method if necessary */ | 410 | /* Invoke an internal method if necessary */ |
452 | 411 | ||
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c index 459160ff9058..ba4626e06a5e 100644 --- a/drivers/acpi/dispatcher/dsmthdat.c +++ b/drivers/acpi/dispatcher/dsmthdat.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 72190abb1d59..a474ca2334d5 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -260,7 +260,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, | |||
260 | } | 260 | } |
261 | 261 | ||
262 | obj_desc->buffer.flags |= AOPOBJ_DATA_VALID; | 262 | obj_desc->buffer.flags |= AOPOBJ_DATA_VALID; |
263 | op->common.node = (struct acpi_namespace_node *)obj_desc; | 263 | op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc); |
264 | return_ACPI_STATUS(AE_OK); | 264 | return_ACPI_STATUS(AE_OK); |
265 | } | 265 | } |
266 | 266 | ||
@@ -270,7 +270,8 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, | |||
270 | * | 270 | * |
271 | * PARAMETERS: walk_state - Current walk state | 271 | * PARAMETERS: walk_state - Current walk state |
272 | * Op - Parser object to be translated | 272 | * Op - Parser object to be translated |
273 | * package_length - Number of elements in the package | 273 | * element_count - Number of elements in the package - this is |
274 | * the num_elements argument to Package() | ||
274 | * obj_desc_ptr - Where the ACPI internal object is returned | 275 | * obj_desc_ptr - Where the ACPI internal object is returned |
275 | * | 276 | * |
276 | * RETURN: Status | 277 | * RETURN: Status |
@@ -278,18 +279,29 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, | |||
278 | * DESCRIPTION: Translate a parser Op package object to the equivalent | 279 | * DESCRIPTION: Translate a parser Op package object to the equivalent |
279 | * namespace object | 280 | * namespace object |
280 | * | 281 | * |
282 | * NOTE: The number of elements in the package will be always be the num_elements | ||
283 | * count, regardless of the number of elements in the package list. If | ||
284 | * num_elements is smaller, only that many package list elements are used. | ||
285 | * if num_elements is larger, the Package object is padded out with | ||
286 | * objects of type Uninitialized (as per ACPI spec.) | ||
287 | * | ||
288 | * Even though the ASL compilers do not allow num_elements to be smaller | ||
289 | * than the Package list length (for the fixed length package opcode), some | ||
290 | * BIOS code modifies the AML on the fly to adjust the num_elements, and | ||
291 | * this code compensates for that. This also provides compatibility with | ||
292 | * other AML interpreters. | ||
293 | * | ||
281 | ******************************************************************************/ | 294 | ******************************************************************************/ |
282 | 295 | ||
283 | acpi_status | 296 | acpi_status |
284 | acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | 297 | acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, |
285 | union acpi_parse_object *op, | 298 | union acpi_parse_object *op, |
286 | u32 package_length, | 299 | u32 element_count, |
287 | union acpi_operand_object **obj_desc_ptr) | 300 | union acpi_operand_object **obj_desc_ptr) |
288 | { | 301 | { |
289 | union acpi_parse_object *arg; | 302 | union acpi_parse_object *arg; |
290 | union acpi_parse_object *parent; | 303 | union acpi_parse_object *parent; |
291 | union acpi_operand_object *obj_desc = NULL; | 304 | union acpi_operand_object *obj_desc = NULL; |
292 | u32 package_list_length; | ||
293 | acpi_status status = AE_OK; | 305 | acpi_status status = AE_OK; |
294 | acpi_native_uint i; | 306 | acpi_native_uint i; |
295 | 307 | ||
@@ -318,32 +330,13 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
318 | obj_desc->package.node = parent->common.node; | 330 | obj_desc->package.node = parent->common.node; |
319 | } | 331 | } |
320 | 332 | ||
321 | obj_desc->package.count = package_length; | ||
322 | |||
323 | /* Count the number of items in the package list */ | ||
324 | |||
325 | arg = op->common.value.arg; | ||
326 | arg = arg->common.next; | ||
327 | for (package_list_length = 0; arg; package_list_length++) { | ||
328 | arg = arg->common.next; | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * The package length (number of elements) will be the greater | ||
333 | * of the specified length and the length of the initializer list | ||
334 | */ | ||
335 | if (package_list_length > package_length) { | ||
336 | obj_desc->package.count = package_list_length; | ||
337 | } | ||
338 | |||
339 | /* | 333 | /* |
340 | * Allocate the pointer array (array of pointers to the | 334 | * Allocate the element array (array of pointers to the individual |
341 | * individual objects). Add an extra pointer slot so | 335 | * objects) based on the num_elements parameter. Add an extra pointer slot |
342 | * that the list is always null terminated. | 336 | * so that the list is always null terminated. |
343 | */ | 337 | */ |
344 | obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size) | 338 | obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size) |
345 | obj_desc->package. | 339 | element_count + |
346 | count + | ||
347 | 1) * sizeof(void *)); | 340 | 1) * sizeof(void *)); |
348 | 341 | ||
349 | if (!obj_desc->package.elements) { | 342 | if (!obj_desc->package.elements) { |
@@ -351,15 +344,20 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
351 | return_ACPI_STATUS(AE_NO_MEMORY); | 344 | return_ACPI_STATUS(AE_NO_MEMORY); |
352 | } | 345 | } |
353 | 346 | ||
347 | obj_desc->package.count = element_count; | ||
348 | |||
354 | /* | 349 | /* |
355 | * Initialize all elements of the package | 350 | * Initialize the elements of the package, up to the num_elements count. |
351 | * Package is automatically padded with uninitialized (NULL) elements | ||
352 | * if num_elements is greater than the package list length. Likewise, | ||
353 | * Package is truncated if num_elements is less than the list length. | ||
356 | */ | 354 | */ |
357 | arg = op->common.value.arg; | 355 | arg = op->common.value.arg; |
358 | arg = arg->common.next; | 356 | arg = arg->common.next; |
359 | for (i = 0; arg; i++) { | 357 | for (i = 0; arg && (i < element_count); i++) { |
360 | if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { | 358 | if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { |
361 | 359 | ||
362 | /* Object (package or buffer) is already built */ | 360 | /* This package element is already built, just get it */ |
363 | 361 | ||
364 | obj_desc->package.elements[i] = | 362 | obj_desc->package.elements[i] = |
365 | ACPI_CAST_PTR(union acpi_operand_object, | 363 | ACPI_CAST_PTR(union acpi_operand_object, |
@@ -373,8 +371,14 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
373 | arg = arg->common.next; | 371 | arg = arg->common.next; |
374 | } | 372 | } |
375 | 373 | ||
374 | if (!arg) { | ||
375 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
376 | "Package List length larger than NumElements count (%X), truncated\n", | ||
377 | element_count)); | ||
378 | } | ||
379 | |||
376 | obj_desc->package.flags |= AOPOBJ_DATA_VALID; | 380 | obj_desc->package.flags |= AOPOBJ_DATA_VALID; |
377 | op->common.node = (struct acpi_namespace_node *)obj_desc; | 381 | op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc); |
378 | return_ACPI_STATUS(status); | 382 | return_ACPI_STATUS(status); |
379 | } | 383 | } |
380 | 384 | ||
@@ -488,8 +492,9 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
488 | /* | 492 | /* |
489 | * Defer evaluation of Buffer term_arg operand | 493 | * Defer evaluation of Buffer term_arg operand |
490 | */ | 494 | */ |
491 | obj_desc->buffer.node = (struct acpi_namespace_node *) | 495 | obj_desc->buffer.node = |
492 | walk_state->operands[0]; | 496 | ACPI_CAST_PTR(struct acpi_namespace_node, |
497 | walk_state->operands[0]); | ||
493 | obj_desc->buffer.aml_start = op->named.data; | 498 | obj_desc->buffer.aml_start = op->named.data; |
494 | obj_desc->buffer.aml_length = op->named.length; | 499 | obj_desc->buffer.aml_length = op->named.length; |
495 | break; | 500 | break; |
@@ -499,8 +504,9 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
499 | /* | 504 | /* |
500 | * Defer evaluation of Package term_arg operand | 505 | * Defer evaluation of Package term_arg operand |
501 | */ | 506 | */ |
502 | obj_desc->package.node = (struct acpi_namespace_node *) | 507 | obj_desc->package.node = |
503 | walk_state->operands[0]; | 508 | ACPI_CAST_PTR(struct acpi_namespace_node, |
509 | walk_state->operands[0]); | ||
504 | obj_desc->package.aml_start = op->named.data; | 510 | obj_desc->package.aml_start = op->named.data; |
505 | obj_desc->package.aml_length = op->named.length; | 511 | obj_desc->package.aml_length = op->named.length; |
506 | break; | 512 | break; |
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index 5b974a8fe614..6c6104a7a247 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -114,7 +114,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node, | |||
114 | } | 114 | } |
115 | 115 | ||
116 | status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, | 116 | status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, |
117 | aml_length, NULL, 1); | 117 | aml_length, NULL, ACPI_IMODE_LOAD_PASS1); |
118 | if (ACPI_FAILURE(status)) { | 118 | if (ACPI_FAILURE(status)) { |
119 | acpi_ds_delete_walk_state(walk_state); | 119 | acpi_ds_delete_walk_state(walk_state); |
120 | goto cleanup; | 120 | goto cleanup; |
@@ -157,7 +157,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node, | |||
157 | /* Execute the opcode and arguments */ | 157 | /* Execute the opcode and arguments */ |
158 | 158 | ||
159 | status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, | 159 | status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, |
160 | aml_length, NULL, 3); | 160 | aml_length, NULL, ACPI_IMODE_EXECUTE); |
161 | if (ACPI_FAILURE(status)) { | 161 | if (ACPI_FAILURE(status)) { |
162 | acpi_ds_delete_walk_state(walk_state); | 162 | acpi_ds_delete_walk_state(walk_state); |
163 | goto cleanup; | 163 | goto cleanup; |
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 05230baf5de8..e4073e05a75c 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index d7a616c3104e..69693fa07224 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -219,7 +219,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, | |||
219 | if (!op) { | 219 | if (!op) { |
220 | status = acpi_ds_load2_begin_op(walk_state, out_op); | 220 | status = acpi_ds_load2_begin_op(walk_state, out_op); |
221 | if (ACPI_FAILURE(status)) { | 221 | if (ACPI_FAILURE(status)) { |
222 | return_ACPI_STATUS(status); | 222 | goto error_exit; |
223 | } | 223 | } |
224 | 224 | ||
225 | op = *out_op; | 225 | op = *out_op; |
@@ -238,7 +238,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, | |||
238 | 238 | ||
239 | status = acpi_ds_scope_stack_pop(walk_state); | 239 | status = acpi_ds_scope_stack_pop(walk_state); |
240 | if (ACPI_FAILURE(status)) { | 240 | if (ACPI_FAILURE(status)) { |
241 | return_ACPI_STATUS(status); | 241 | goto error_exit; |
242 | } | 242 | } |
243 | } | 243 | } |
244 | } | 244 | } |
@@ -287,7 +287,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, | |||
287 | 287 | ||
288 | status = acpi_ds_result_stack_push(walk_state); | 288 | status = acpi_ds_result_stack_push(walk_state); |
289 | if (ACPI_FAILURE(status)) { | 289 | if (ACPI_FAILURE(status)) { |
290 | return_ACPI_STATUS(status); | 290 | goto error_exit; |
291 | } | 291 | } |
292 | 292 | ||
293 | status = acpi_ds_exec_begin_control_op(walk_state, op); | 293 | status = acpi_ds_exec_begin_control_op(walk_state, op); |
@@ -328,6 +328,10 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, | |||
328 | /* Nothing to do here during method execution */ | 328 | /* Nothing to do here during method execution */ |
329 | 329 | ||
330 | return_ACPI_STATUS(status); | 330 | return_ACPI_STATUS(status); |
331 | |||
332 | error_exit: | ||
333 | status = acpi_ds_method_error(status, walk_state); | ||
334 | return_ACPI_STATUS(status); | ||
331 | } | 335 | } |
332 | 336 | ||
333 | /***************************************************************************** | 337 | /***************************************************************************** |
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index e3ca7f6539c1..8ab9d1b29a4c 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -196,6 +196,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
196 | * one of the opcodes that actually opens a scope | 196 | * one of the opcodes that actually opens a scope |
197 | */ | 197 | */ |
198 | switch (node->type) { | 198 | switch (node->type) { |
199 | case ACPI_TYPE_ANY: | ||
199 | case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ | 200 | case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ |
200 | case ACPI_TYPE_DEVICE: | 201 | case ACPI_TYPE_DEVICE: |
201 | case ACPI_TYPE_POWER: | 202 | case ACPI_TYPE_POWER: |
@@ -546,6 +547,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | |||
546 | acpi_status status; | 547 | acpi_status status; |
547 | acpi_object_type object_type; | 548 | acpi_object_type object_type; |
548 | char *buffer_ptr; | 549 | char *buffer_ptr; |
550 | u32 flags; | ||
549 | 551 | ||
550 | ACPI_FUNCTION_TRACE(ds_load2_begin_op); | 552 | ACPI_FUNCTION_TRACE(ds_load2_begin_op); |
551 | 553 | ||
@@ -669,6 +671,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | |||
669 | * one of the opcodes that actually opens a scope | 671 | * one of the opcodes that actually opens a scope |
670 | */ | 672 | */ |
671 | switch (node->type) { | 673 | switch (node->type) { |
674 | case ACPI_TYPE_ANY: | ||
672 | case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ | 675 | case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ |
673 | case ACPI_TYPE_DEVICE: | 676 | case ACPI_TYPE_DEVICE: |
674 | case ACPI_TYPE_POWER: | 677 | case ACPI_TYPE_POWER: |
@@ -750,12 +753,20 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | |||
750 | break; | 753 | break; |
751 | } | 754 | } |
752 | 755 | ||
753 | /* Add new entry into namespace */ | 756 | flags = ACPI_NS_NO_UPSEARCH; |
757 | if (walk_state->pass_number == ACPI_IMODE_EXECUTE) { | ||
758 | |||
759 | /* Execution mode, node cannot already exist, node is temporary */ | ||
760 | |||
761 | flags |= (ACPI_NS_ERROR_IF_FOUND | ACPI_NS_TEMPORARY); | ||
762 | } | ||
763 | |||
764 | /* Add new entry or lookup existing entry */ | ||
754 | 765 | ||
755 | status = | 766 | status = |
756 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, | 767 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, |
757 | object_type, ACPI_IMODE_LOAD_PASS2, | 768 | object_type, ACPI_IMODE_LOAD_PASS2, flags, |
758 | ACPI_NS_NO_UPSEARCH, walk_state, &(node)); | 769 | walk_state, &node); |
759 | break; | 770 | break; |
760 | } | 771 | } |
761 | 772 | ||
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c index c9228972f5f6..3927c495e4bf 100644 --- a/drivers/acpi/dispatcher/dswscope.c +++ b/drivers/acpi/dispatcher/dswscope.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index 7817e5522679..16c8e38b51ef 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index bf5b79ed3613..688e83a16906 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/notifier.h> | 29 | #include <linux/notifier.h> |
30 | #include <linux/platform_device.h> | ||
30 | #include <linux/jiffies.h> | 31 | #include <linux/jiffies.h> |
31 | #include <acpi/acpi_bus.h> | 32 | #include <acpi/acpi_bus.h> |
32 | #include <acpi/acpi_drivers.h> | 33 | #include <acpi/acpi_drivers.h> |
@@ -39,13 +40,15 @@ MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME); | |||
39 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
40 | 41 | ||
41 | static struct atomic_notifier_head dock_notifier_list; | 42 | static struct atomic_notifier_head dock_notifier_list; |
43 | static struct platform_device dock_device; | ||
44 | static char dock_device_name[] = "dock"; | ||
42 | 45 | ||
43 | struct dock_station { | 46 | struct dock_station { |
44 | acpi_handle handle; | 47 | acpi_handle handle; |
45 | unsigned long last_dock_time; | 48 | unsigned long last_dock_time; |
46 | u32 flags; | 49 | u32 flags; |
47 | spinlock_t dd_lock; | 50 | spinlock_t dd_lock; |
48 | spinlock_t hp_lock; | 51 | struct mutex hp_lock; |
49 | struct list_head dependent_devices; | 52 | struct list_head dependent_devices; |
50 | struct list_head hotplug_devices; | 53 | struct list_head hotplug_devices; |
51 | }; | 54 | }; |
@@ -115,9 +118,9 @@ static void | |||
115 | dock_add_hotplug_device(struct dock_station *ds, | 118 | dock_add_hotplug_device(struct dock_station *ds, |
116 | struct dock_dependent_device *dd) | 119 | struct dock_dependent_device *dd) |
117 | { | 120 | { |
118 | spin_lock(&ds->hp_lock); | 121 | mutex_lock(&ds->hp_lock); |
119 | list_add_tail(&dd->hotplug_list, &ds->hotplug_devices); | 122 | list_add_tail(&dd->hotplug_list, &ds->hotplug_devices); |
120 | spin_unlock(&ds->hp_lock); | 123 | mutex_unlock(&ds->hp_lock); |
121 | } | 124 | } |
122 | 125 | ||
123 | /** | 126 | /** |
@@ -131,9 +134,9 @@ static void | |||
131 | dock_del_hotplug_device(struct dock_station *ds, | 134 | dock_del_hotplug_device(struct dock_station *ds, |
132 | struct dock_dependent_device *dd) | 135 | struct dock_dependent_device *dd) |
133 | { | 136 | { |
134 | spin_lock(&ds->hp_lock); | 137 | mutex_lock(&ds->hp_lock); |
135 | list_del(&dd->hotplug_list); | 138 | list_del(&dd->hotplug_list); |
136 | spin_unlock(&ds->hp_lock); | 139 | mutex_unlock(&ds->hp_lock); |
137 | } | 140 | } |
138 | 141 | ||
139 | /** | 142 | /** |
@@ -296,7 +299,7 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) | |||
296 | { | 299 | { |
297 | struct dock_dependent_device *dd; | 300 | struct dock_dependent_device *dd; |
298 | 301 | ||
299 | spin_lock(&ds->hp_lock); | 302 | mutex_lock(&ds->hp_lock); |
300 | 303 | ||
301 | /* | 304 | /* |
302 | * First call driver specific hotplug functions | 305 | * First call driver specific hotplug functions |
@@ -318,15 +321,17 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) | |||
318 | else | 321 | else |
319 | dock_create_acpi_device(dd->handle); | 322 | dock_create_acpi_device(dd->handle); |
320 | } | 323 | } |
321 | spin_unlock(&ds->hp_lock); | 324 | mutex_unlock(&ds->hp_lock); |
322 | } | 325 | } |
323 | 326 | ||
324 | static void dock_event(struct dock_station *ds, u32 event, int num) | 327 | static void dock_event(struct dock_station *ds, u32 event, int num) |
325 | { | 328 | { |
329 | struct device *dev = &dock_device.dev; | ||
326 | /* | 330 | /* |
327 | * we don't do events until someone tells me that | 331 | * Indicate that the status of the dock station has |
328 | * they would like to have them. | 332 | * changed. |
329 | */ | 333 | */ |
334 | kobject_uevent(&dev->kobj, KOBJ_CHANGE); | ||
330 | } | 335 | } |
331 | 336 | ||
332 | /** | 337 | /** |
@@ -441,6 +446,9 @@ static int dock_in_progress(struct dock_station *ds) | |||
441 | */ | 446 | */ |
442 | int register_dock_notifier(struct notifier_block *nb) | 447 | int register_dock_notifier(struct notifier_block *nb) |
443 | { | 448 | { |
449 | if (!dock_station) | ||
450 | return -ENODEV; | ||
451 | |||
444 | return atomic_notifier_chain_register(&dock_notifier_list, nb); | 452 | return atomic_notifier_chain_register(&dock_notifier_list, nb); |
445 | } | 453 | } |
446 | 454 | ||
@@ -452,6 +460,9 @@ EXPORT_SYMBOL_GPL(register_dock_notifier); | |||
452 | */ | 460 | */ |
453 | void unregister_dock_notifier(struct notifier_block *nb) | 461 | void unregister_dock_notifier(struct notifier_block *nb) |
454 | { | 462 | { |
463 | if (!dock_station) | ||
464 | return; | ||
465 | |||
455 | atomic_notifier_chain_unregister(&dock_notifier_list, nb); | 466 | atomic_notifier_chain_unregister(&dock_notifier_list, nb); |
456 | } | 467 | } |
457 | 468 | ||
@@ -512,6 +523,37 @@ void unregister_hotplug_dock_device(acpi_handle handle) | |||
512 | EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); | 523 | EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); |
513 | 524 | ||
514 | /** | 525 | /** |
526 | * handle_eject_request - handle an undock request checking for error conditions | ||
527 | * | ||
528 | * Check to make sure the dock device is still present, then undock and | ||
529 | * hotremove all the devices that may need removing. | ||
530 | */ | ||
531 | static int handle_eject_request(struct dock_station *ds, u32 event) | ||
532 | { | ||
533 | if (!dock_present(ds)) | ||
534 | return -ENODEV; | ||
535 | |||
536 | if (dock_in_progress(ds)) | ||
537 | return -EBUSY; | ||
538 | |||
539 | /* | ||
540 | * here we need to generate the undock | ||
541 | * event prior to actually doing the undock | ||
542 | * so that the device struct still exists. | ||
543 | */ | ||
544 | dock_event(ds, event, UNDOCK_EVENT); | ||
545 | hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); | ||
546 | undock(ds); | ||
547 | eject_dock(ds); | ||
548 | if (dock_present(ds)) { | ||
549 | printk(KERN_ERR PREFIX "Unable to undock!\n"); | ||
550 | return -EBUSY; | ||
551 | } | ||
552 | |||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | /** | ||
515 | * dock_notify - act upon an acpi dock notification | 557 | * dock_notify - act upon an acpi dock notification |
516 | * @handle: the dock station handle | 558 | * @handle: the dock station handle |
517 | * @event: the acpi event | 559 | * @event: the acpi event |
@@ -519,13 +561,11 @@ EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); | |||
519 | * | 561 | * |
520 | * If we are notified to dock, then check to see if the dock is | 562 | * If we are notified to dock, then check to see if the dock is |
521 | * present and then dock. Notify all drivers of the dock event, | 563 | * present and then dock. Notify all drivers of the dock event, |
522 | * and then hotplug and devices that may need hotplugging. For undock | 564 | * and then hotplug and devices that may need hotplugging. |
523 | * check to make sure the dock device is still present, then undock | ||
524 | * and hotremove all the devices that may need removing. | ||
525 | */ | 565 | */ |
526 | static void dock_notify(acpi_handle handle, u32 event, void *data) | 566 | static void dock_notify(acpi_handle handle, u32 event, void *data) |
527 | { | 567 | { |
528 | struct dock_station *ds = (struct dock_station *)data; | 568 | struct dock_station *ds = data; |
529 | 569 | ||
530 | switch (event) { | 570 | switch (event) { |
531 | case ACPI_NOTIFY_BUS_CHECK: | 571 | case ACPI_NOTIFY_BUS_CHECK: |
@@ -553,19 +593,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
553 | * to the driver who wish to hotplug. | 593 | * to the driver who wish to hotplug. |
554 | */ | 594 | */ |
555 | case ACPI_NOTIFY_EJECT_REQUEST: | 595 | case ACPI_NOTIFY_EJECT_REQUEST: |
556 | if (!dock_in_progress(ds) && dock_present(ds)) { | 596 | handle_eject_request(ds, event); |
557 | /* | ||
558 | * here we need to generate the undock | ||
559 | * event prior to actually doing the undock | ||
560 | * so that the device struct still exists. | ||
561 | */ | ||
562 | dock_event(ds, event, UNDOCK_EVENT); | ||
563 | hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); | ||
564 | undock(ds); | ||
565 | eject_dock(ds); | ||
566 | if (dock_present(ds)) | ||
567 | printk(KERN_ERR PREFIX "Unable to undock!\n"); | ||
568 | } | ||
569 | break; | 597 | break; |
570 | default: | 598 | default: |
571 | printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); | 599 | printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); |
@@ -587,23 +615,58 @@ static acpi_status | |||
587 | find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) | 615 | find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) |
588 | { | 616 | { |
589 | acpi_status status; | 617 | acpi_status status; |
590 | acpi_handle tmp; | 618 | acpi_handle tmp, parent; |
591 | struct dock_station *ds = (struct dock_station *)context; | 619 | struct dock_station *ds = context; |
592 | struct dock_dependent_device *dd; | 620 | struct dock_dependent_device *dd; |
593 | 621 | ||
594 | status = acpi_bus_get_ejd(handle, &tmp); | 622 | status = acpi_bus_get_ejd(handle, &tmp); |
595 | if (ACPI_FAILURE(status)) | 623 | if (ACPI_FAILURE(status)) { |
596 | return AE_OK; | 624 | /* try the parent device as well */ |
625 | status = acpi_get_parent(handle, &parent); | ||
626 | if (ACPI_FAILURE(status)) | ||
627 | goto fdd_out; | ||
628 | /* see if parent is dependent on dock */ | ||
629 | status = acpi_bus_get_ejd(parent, &tmp); | ||
630 | if (ACPI_FAILURE(status)) | ||
631 | goto fdd_out; | ||
632 | } | ||
597 | 633 | ||
598 | if (tmp == ds->handle) { | 634 | if (tmp == ds->handle) { |
599 | dd = alloc_dock_dependent_device(handle); | 635 | dd = alloc_dock_dependent_device(handle); |
600 | if (dd) | 636 | if (dd) |
601 | add_dock_dependent_device(ds, dd); | 637 | add_dock_dependent_device(ds, dd); |
602 | } | 638 | } |
603 | 639 | fdd_out: | |
604 | return AE_OK; | 640 | return AE_OK; |
605 | } | 641 | } |
606 | 642 | ||
643 | /* | ||
644 | * show_docked - read method for "docked" file in sysfs | ||
645 | */ | ||
646 | static ssize_t show_docked(struct device *dev, | ||
647 | struct device_attribute *attr, char *buf) | ||
648 | { | ||
649 | return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station)); | ||
650 | |||
651 | } | ||
652 | DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); | ||
653 | |||
654 | /* | ||
655 | * write_undock - write method for "undock" file in sysfs | ||
656 | */ | ||
657 | static ssize_t write_undock(struct device *dev, struct device_attribute *attr, | ||
658 | const char *buf, size_t count) | ||
659 | { | ||
660 | int ret; | ||
661 | |||
662 | if (!count) | ||
663 | return -EINVAL; | ||
664 | |||
665 | ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST); | ||
666 | return ret ? ret: count; | ||
667 | } | ||
668 | DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock); | ||
669 | |||
607 | /** | 670 | /** |
608 | * dock_add - add a new dock station | 671 | * dock_add - add a new dock station |
609 | * @handle: the dock station handle | 672 | * @handle: the dock station handle |
@@ -626,9 +689,33 @@ static int dock_add(acpi_handle handle) | |||
626 | INIT_LIST_HEAD(&dock_station->dependent_devices); | 689 | INIT_LIST_HEAD(&dock_station->dependent_devices); |
627 | INIT_LIST_HEAD(&dock_station->hotplug_devices); | 690 | INIT_LIST_HEAD(&dock_station->hotplug_devices); |
628 | spin_lock_init(&dock_station->dd_lock); | 691 | spin_lock_init(&dock_station->dd_lock); |
629 | spin_lock_init(&dock_station->hp_lock); | 692 | mutex_init(&dock_station->hp_lock); |
630 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); | 693 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); |
631 | 694 | ||
695 | /* initialize platform device stuff */ | ||
696 | dock_device.name = dock_device_name; | ||
697 | ret = platform_device_register(&dock_device); | ||
698 | if (ret) { | ||
699 | printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret); | ||
700 | kfree(dock_station); | ||
701 | return ret; | ||
702 | } | ||
703 | ret = device_create_file(&dock_device.dev, &dev_attr_docked); | ||
704 | if (ret) { | ||
705 | printk("Error %d adding sysfs file\n", ret); | ||
706 | platform_device_unregister(&dock_device); | ||
707 | kfree(dock_station); | ||
708 | return ret; | ||
709 | } | ||
710 | ret = device_create_file(&dock_device.dev, &dev_attr_undock); | ||
711 | if (ret) { | ||
712 | printk("Error %d adding sysfs file\n", ret); | ||
713 | device_remove_file(&dock_device.dev, &dev_attr_docked); | ||
714 | platform_device_unregister(&dock_device); | ||
715 | kfree(dock_station); | ||
716 | return ret; | ||
717 | } | ||
718 | |||
632 | /* Find dependent devices */ | 719 | /* Find dependent devices */ |
633 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | 720 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
634 | ACPI_UINT32_MAX, find_dock_devices, dock_station, | 721 | ACPI_UINT32_MAX, find_dock_devices, dock_station, |
@@ -638,7 +725,8 @@ static int dock_add(acpi_handle handle) | |||
638 | dd = alloc_dock_dependent_device(handle); | 725 | dd = alloc_dock_dependent_device(handle); |
639 | if (!dd) { | 726 | if (!dd) { |
640 | kfree(dock_station); | 727 | kfree(dock_station); |
641 | return -ENOMEM; | 728 | ret = -ENOMEM; |
729 | goto dock_add_err_unregister; | ||
642 | } | 730 | } |
643 | add_dock_dependent_device(dock_station, dd); | 731 | add_dock_dependent_device(dock_station, dd); |
644 | 732 | ||
@@ -658,8 +746,12 @@ static int dock_add(acpi_handle handle) | |||
658 | return 0; | 746 | return 0; |
659 | 747 | ||
660 | dock_add_err: | 748 | dock_add_err: |
661 | kfree(dock_station); | ||
662 | kfree(dd); | 749 | kfree(dd); |
750 | dock_add_err_unregister: | ||
751 | device_remove_file(&dock_device.dev, &dev_attr_docked); | ||
752 | device_remove_file(&dock_device.dev, &dev_attr_undock); | ||
753 | platform_device_unregister(&dock_device); | ||
754 | kfree(dock_station); | ||
663 | return ret; | 755 | return ret; |
664 | } | 756 | } |
665 | 757 | ||
@@ -686,6 +778,11 @@ static int dock_remove(void) | |||
686 | if (ACPI_FAILURE(status)) | 778 | if (ACPI_FAILURE(status)) |
687 | printk(KERN_ERR "Error removing notify handler\n"); | 779 | printk(KERN_ERR "Error removing notify handler\n"); |
688 | 780 | ||
781 | /* cleanup sysfs */ | ||
782 | device_remove_file(&dock_device.dev, &dev_attr_docked); | ||
783 | device_remove_file(&dock_device.dev, &dev_attr_undock); | ||
784 | platform_device_unregister(&dock_device); | ||
785 | |||
689 | /* free dock station memory */ | 786 | /* free dock station memory */ |
690 | kfree(dock_station); | 787 | kfree(dock_station); |
691 | return 0; | 788 | return 0; |
@@ -703,7 +800,7 @@ static int dock_remove(void) | |||
703 | static acpi_status | 800 | static acpi_status |
704 | find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) | 801 | find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) |
705 | { | 802 | { |
706 | int *count = (int *)context; | 803 | int *count = context; |
707 | acpi_status status = AE_OK; | 804 | acpi_status status = AE_OK; |
708 | 805 | ||
709 | if (is_dock(handle)) { | 806 | if (is_dock(handle)) { |
@@ -726,7 +823,7 @@ static int __init dock_init(void) | |||
726 | ACPI_UINT32_MAX, find_dock, &num, NULL); | 823 | ACPI_UINT32_MAX, find_dock, &num, NULL); |
727 | 824 | ||
728 | if (!num) | 825 | if (!num) |
729 | return -ENODEV; | 826 | printk(KERN_INFO "No dock devices found.\n"); |
730 | 827 | ||
731 | return 0; | 828 | return 0; |
732 | } | 829 | } |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e6d4b084dca2..743ce27fa0bb 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -45,35 +45,34 @@ ACPI_MODULE_NAME("acpi_ec") | |||
45 | #define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" | 45 | #define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" |
46 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 46 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
47 | #define ACPI_EC_FILE_INFO "info" | 47 | #define ACPI_EC_FILE_INFO "info" |
48 | 48 | #undef PREFIX | |
49 | #define PREFIX "ACPI: EC: " | ||
49 | /* EC status register */ | 50 | /* EC status register */ |
50 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ | 51 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ |
51 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ | 52 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ |
52 | #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ | 53 | #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ |
53 | #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ | 54 | #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ |
54 | |||
55 | /* EC commands */ | 55 | /* EC commands */ |
56 | #define ACPI_EC_COMMAND_READ 0x80 | 56 | enum ec_command { |
57 | #define ACPI_EC_COMMAND_WRITE 0x81 | 57 | ACPI_EC_COMMAND_READ = 0x80, |
58 | #define ACPI_EC_BURST_ENABLE 0x82 | 58 | ACPI_EC_COMMAND_WRITE = 0x81, |
59 | #define ACPI_EC_BURST_DISABLE 0x83 | 59 | ACPI_EC_BURST_ENABLE = 0x82, |
60 | #define ACPI_EC_COMMAND_QUERY 0x84 | 60 | ACPI_EC_BURST_DISABLE = 0x83, |
61 | 61 | ACPI_EC_COMMAND_QUERY = 0x84, | |
62 | }; | ||
62 | /* EC events */ | 63 | /* EC events */ |
63 | enum { | 64 | enum ec_event { |
64 | ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ | 65 | ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ |
65 | ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ | 66 | ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ |
66 | }; | 67 | }; |
67 | 68 | ||
68 | #define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ | 69 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
69 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 70 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
70 | #define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ | ||
71 | #define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ | ||
72 | 71 | ||
73 | enum { | 72 | static enum ec_mode { |
74 | EC_INTR = 1, /* Output buffer full */ | 73 | EC_INTR = 1, /* Output buffer full */ |
75 | EC_POLL, /* Input buffer empty */ | 74 | EC_POLL, /* Input buffer empty */ |
76 | }; | 75 | } acpi_ec_mode = EC_INTR; |
77 | 76 | ||
78 | static int acpi_ec_remove(struct acpi_device *device, int type); | 77 | static int acpi_ec_remove(struct acpi_device *device, int type); |
79 | static int acpi_ec_start(struct acpi_device *device); | 78 | static int acpi_ec_start(struct acpi_device *device); |
@@ -93,22 +92,21 @@ static struct acpi_driver acpi_ec_driver = { | |||
93 | }; | 92 | }; |
94 | 93 | ||
95 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ | 94 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ |
96 | struct acpi_ec { | 95 | static struct acpi_ec { |
97 | acpi_handle handle; | 96 | acpi_handle handle; |
98 | unsigned long uid; | 97 | unsigned long uid; |
99 | unsigned long gpe_bit; | 98 | unsigned long gpe; |
100 | unsigned long command_addr; | 99 | unsigned long command_addr; |
101 | unsigned long data_addr; | 100 | unsigned long data_addr; |
102 | unsigned long global_lock; | 101 | unsigned long global_lock; |
103 | struct semaphore sem; | 102 | struct mutex lock; |
104 | unsigned int expect_event; | 103 | atomic_t query_pending; |
105 | atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ | 104 | atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ |
106 | wait_queue_head_t wait; | 105 | wait_queue_head_t wait; |
107 | } *ec_ecdt; | 106 | } *ec_ecdt; |
108 | 107 | ||
109 | /* External interfaces use first EC only, so remember */ | 108 | /* External interfaces use first EC only, so remember */ |
110 | static struct acpi_device *first_ec; | 109 | static struct acpi_device *first_ec; |
111 | static int acpi_ec_mode = EC_INTR; | ||
112 | 110 | ||
113 | /* -------------------------------------------------------------------------- | 111 | /* -------------------------------------------------------------------------- |
114 | Transaction Management | 112 | Transaction Management |
@@ -134,54 +132,41 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) | |||
134 | outb(data, ec->data_addr); | 132 | outb(data, ec->data_addr); |
135 | } | 133 | } |
136 | 134 | ||
137 | static int acpi_ec_check_status(u8 status, u8 event) | 135 | static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event) |
138 | { | 136 | { |
139 | switch (event) { | 137 | u8 status = acpi_ec_read_status(ec); |
140 | case ACPI_EC_EVENT_OBF_1: | 138 | |
139 | if (event == ACPI_EC_EVENT_OBF_1) { | ||
141 | if (status & ACPI_EC_FLAG_OBF) | 140 | if (status & ACPI_EC_FLAG_OBF) |
142 | return 1; | 141 | return 1; |
143 | break; | 142 | } else if (event == ACPI_EC_EVENT_IBF_0) { |
144 | case ACPI_EC_EVENT_IBF_0: | ||
145 | if (!(status & ACPI_EC_FLAG_IBF)) | 143 | if (!(status & ACPI_EC_FLAG_IBF)) |
146 | return 1; | 144 | return 1; |
147 | break; | ||
148 | default: | ||
149 | break; | ||
150 | } | 145 | } |
151 | 146 | ||
152 | return 0; | 147 | return 0; |
153 | } | 148 | } |
154 | 149 | ||
155 | static int acpi_ec_wait(struct acpi_ec *ec, u8 event) | 150 | static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event) |
156 | { | 151 | { |
157 | int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0; | 152 | if (acpi_ec_mode == EC_POLL) { |
158 | long time_left; | 153 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
159 | 154 | while (time_before(jiffies, delay)) { | |
160 | ec->expect_event = event; | 155 | if (acpi_ec_check_status(ec, event)) |
161 | if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) { | ||
162 | ec->expect_event = 0; | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | do { | ||
167 | if (acpi_ec_mode == EC_POLL) { | ||
168 | udelay(ACPI_EC_UDELAY); | ||
169 | } else { | ||
170 | time_left = wait_event_timeout(ec->wait, | ||
171 | !ec->expect_event, | ||
172 | msecs_to_jiffies(ACPI_EC_DELAY)); | ||
173 | if (time_left > 0) { | ||
174 | ec->expect_event = 0; | ||
175 | return 0; | 156 | return 0; |
176 | } | ||
177 | } | 157 | } |
178 | if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) { | 158 | } else { |
179 | ec->expect_event = 0; | 159 | if (wait_event_timeout(ec->wait, |
160 | acpi_ec_check_status(ec, event), | ||
161 | msecs_to_jiffies(ACPI_EC_DELAY)) || | ||
162 | acpi_ec_check_status(ec, event)) { | ||
180 | return 0; | 163 | return 0; |
164 | } else { | ||
165 | printk(KERN_ERR PREFIX "acpi_ec_wait timeout," | ||
166 | " status = %d, expect_event = %d\n", | ||
167 | acpi_ec_read_status(ec), event); | ||
181 | } | 168 | } |
182 | } while (--i > 0); | 169 | } |
183 | |||
184 | ec->expect_event = 0; | ||
185 | 170 | ||
186 | return -ETIME; | 171 | return -ETIME; |
187 | } | 172 | } |
@@ -196,7 +181,6 @@ int acpi_ec_enter_burst_mode(struct acpi_ec *ec) | |||
196 | u8 tmp = 0; | 181 | u8 tmp = 0; |
197 | u8 status = 0; | 182 | u8 status = 0; |
198 | 183 | ||
199 | |||
200 | status = acpi_ec_read_status(ec); | 184 | status = acpi_ec_read_status(ec); |
201 | if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { | 185 | if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { |
202 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | 186 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
@@ -212,7 +196,7 @@ int acpi_ec_enter_burst_mode(struct acpi_ec *ec) | |||
212 | 196 | ||
213 | atomic_set(&ec->leaving_burst, 0); | 197 | atomic_set(&ec->leaving_burst, 0); |
214 | return 0; | 198 | return 0; |
215 | end: | 199 | end: |
216 | ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode")); | 200 | ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode")); |
217 | return -1; | 201 | return -1; |
218 | } | 202 | } |
@@ -221,58 +205,68 @@ int acpi_ec_leave_burst_mode(struct acpi_ec *ec) | |||
221 | { | 205 | { |
222 | u8 status = 0; | 206 | u8 status = 0; |
223 | 207 | ||
224 | |||
225 | status = acpi_ec_read_status(ec); | 208 | status = acpi_ec_read_status(ec); |
226 | if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){ | 209 | if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)) { |
227 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | 210 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
228 | if(status) | 211 | if (status) |
229 | goto end; | 212 | goto end; |
230 | acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE); | 213 | acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE); |
231 | acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | 214 | acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
232 | } | 215 | } |
233 | atomic_set(&ec->leaving_burst, 1); | 216 | atomic_set(&ec->leaving_burst, 1); |
234 | return 0; | 217 | return 0; |
235 | end: | 218 | end: |
236 | ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode")); | 219 | ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode")); |
237 | return -1; | 220 | return -1; |
238 | } | 221 | } |
239 | #endif /* ACPI_FUTURE_USAGE */ | 222 | #endif /* ACPI_FUTURE_USAGE */ |
240 | 223 | ||
241 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | 224 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, |
242 | const u8 *wdata, unsigned wdata_len, | 225 | const u8 * wdata, unsigned wdata_len, |
243 | u8 *rdata, unsigned rdata_len) | 226 | u8 * rdata, unsigned rdata_len) |
244 | { | 227 | { |
245 | int result; | 228 | int result = 0; |
246 | 229 | ||
247 | acpi_ec_write_cmd(ec, command); | 230 | acpi_ec_write_cmd(ec, command); |
248 | 231 | ||
249 | for (; wdata_len > 0; wdata_len --) { | 232 | for (; wdata_len > 0; --wdata_len) { |
250 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | 233 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
251 | if (result) | 234 | if (result) { |
252 | return result; | 235 | printk(KERN_ERR PREFIX |
236 | "write_cmd timeout, command = %d\n", command); | ||
237 | goto end; | ||
238 | } | ||
253 | acpi_ec_write_data(ec, *(wdata++)); | 239 | acpi_ec_write_data(ec, *(wdata++)); |
254 | } | 240 | } |
255 | 241 | ||
256 | if (command == ACPI_EC_COMMAND_WRITE) { | 242 | if (!rdata_len) { |
257 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | 243 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
258 | if (result) | 244 | if (result) { |
259 | return result; | 245 | printk(KERN_ERR PREFIX |
246 | "finish-write timeout, command = %d\n", command); | ||
247 | goto end; | ||
248 | } | ||
249 | } else if (command == ACPI_EC_COMMAND_QUERY) { | ||
250 | atomic_set(&ec->query_pending, 0); | ||
260 | } | 251 | } |
261 | 252 | ||
262 | for (; rdata_len > 0; rdata_len --) { | 253 | for (; rdata_len > 0; --rdata_len) { |
263 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); | 254 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); |
264 | if (result) | 255 | if (result) { |
265 | return result; | 256 | printk(KERN_ERR PREFIX "read timeout, command = %d\n", |
257 | command); | ||
258 | goto end; | ||
259 | } | ||
266 | 260 | ||
267 | *(rdata++) = acpi_ec_read_data(ec); | 261 | *(rdata++) = acpi_ec_read_data(ec); |
268 | } | 262 | } |
269 | 263 | end: | |
270 | return 0; | 264 | return result; |
271 | } | 265 | } |
272 | 266 | ||
273 | static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, | 267 | static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, |
274 | const u8 *wdata, unsigned wdata_len, | 268 | const u8 * wdata, unsigned wdata_len, |
275 | u8 *rdata, unsigned rdata_len) | 269 | u8 * rdata, unsigned rdata_len) |
276 | { | 270 | { |
277 | int status; | 271 | int status; |
278 | u32 glk; | 272 | u32 glk; |
@@ -280,36 +274,40 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, | |||
280 | if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata)) | 274 | if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata)) |
281 | return -EINVAL; | 275 | return -EINVAL; |
282 | 276 | ||
283 | if (rdata) | 277 | if (rdata) |
284 | memset(rdata, 0, rdata_len); | 278 | memset(rdata, 0, rdata_len); |
285 | 279 | ||
280 | mutex_lock(&ec->lock); | ||
286 | if (ec->global_lock) { | 281 | if (ec->global_lock) { |
287 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | 282 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
288 | if (ACPI_FAILURE(status)) | 283 | if (ACPI_FAILURE(status)) |
289 | return -ENODEV; | 284 | return -ENODEV; |
290 | } | 285 | } |
291 | down(&ec->sem); | 286 | |
287 | /* Make sure GPE is enabled before doing transaction */ | ||
288 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | ||
292 | 289 | ||
293 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | 290 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
294 | if (status) { | 291 | if (status) { |
295 | printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); | 292 | printk(KERN_DEBUG PREFIX |
293 | "input buffer is not empty, aborting transaction\n"); | ||
296 | goto end; | 294 | goto end; |
297 | } | 295 | } |
298 | 296 | ||
299 | status = acpi_ec_transaction_unlocked(ec, command, | 297 | status = acpi_ec_transaction_unlocked(ec, command, |
300 | wdata, wdata_len, | 298 | wdata, wdata_len, |
301 | rdata, rdata_len); | 299 | rdata, rdata_len); |
302 | 300 | ||
303 | end: | 301 | end: |
304 | up(&ec->sem); | ||
305 | 302 | ||
306 | if (ec->global_lock) | 303 | if (ec->global_lock) |
307 | acpi_release_global_lock(glk); | 304 | acpi_release_global_lock(glk); |
305 | mutex_unlock(&ec->lock); | ||
308 | 306 | ||
309 | return status; | 307 | return status; |
310 | } | 308 | } |
311 | 309 | ||
312 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) | 310 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) |
313 | { | 311 | { |
314 | int result; | 312 | int result; |
315 | u8 d; | 313 | u8 d; |
@@ -322,15 +320,15 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) | |||
322 | 320 | ||
323 | static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | 321 | static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) |
324 | { | 322 | { |
325 | u8 wdata[2] = { address, data }; | 323 | u8 wdata[2] = { address, data }; |
326 | return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE, | 324 | return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE, |
327 | wdata, 2, NULL, 0); | 325 | wdata, 2, NULL, 0); |
328 | } | 326 | } |
329 | 327 | ||
330 | /* | 328 | /* |
331 | * Externally callable EC access functions. For now, assume 1 EC only | 329 | * Externally callable EC access functions. For now, assume 1 EC only |
332 | */ | 330 | */ |
333 | int ec_read(u8 addr, u8 *val) | 331 | int ec_read(u8 addr, u8 * val) |
334 | { | 332 | { |
335 | struct acpi_ec *ec; | 333 | struct acpi_ec *ec; |
336 | int err; | 334 | int err; |
@@ -369,9 +367,9 @@ int ec_write(u8 addr, u8 val) | |||
369 | 367 | ||
370 | EXPORT_SYMBOL(ec_write); | 368 | EXPORT_SYMBOL(ec_write); |
371 | 369 | ||
372 | extern int ec_transaction(u8 command, | 370 | int ec_transaction(u8 command, |
373 | const u8 *wdata, unsigned wdata_len, | 371 | const u8 * wdata, unsigned wdata_len, |
374 | u8 *rdata, unsigned rdata_len) | 372 | u8 * rdata, unsigned rdata_len) |
375 | { | 373 | { |
376 | struct acpi_ec *ec; | 374 | struct acpi_ec *ec; |
377 | 375 | ||
@@ -386,65 +384,49 @@ extern int ec_transaction(u8 command, | |||
386 | 384 | ||
387 | EXPORT_SYMBOL(ec_transaction); | 385 | EXPORT_SYMBOL(ec_transaction); |
388 | 386 | ||
389 | static int acpi_ec_query(struct acpi_ec *ec, u8 *data) | 387 | static int acpi_ec_query(struct acpi_ec *ec, u8 * data) |
390 | { | 388 | { |
391 | int result; | 389 | int result; |
392 | u8 d; | 390 | u8 d; |
393 | 391 | ||
394 | if (!ec || !data) | 392 | if (!ec || !data) |
395 | return -EINVAL; | 393 | return -EINVAL; |
396 | 394 | ||
397 | /* | 395 | /* |
398 | * Query the EC to find out which _Qxx method we need to evaluate. | 396 | * Query the EC to find out which _Qxx method we need to evaluate. |
399 | * Note that successful completion of the query causes the ACPI_EC_SCI | 397 | * Note that successful completion of the query causes the ACPI_EC_SCI |
400 | * bit to be cleared (and thus clearing the interrupt source). | 398 | * bit to be cleared (and thus clearing the interrupt source). |
401 | */ | 399 | */ |
402 | 400 | ||
403 | result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1); | 401 | result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1); |
404 | if (result) | 402 | if (result) |
405 | return result; | 403 | return result; |
406 | 404 | ||
407 | if (!d) | 405 | if (!d) |
408 | return -ENODATA; | 406 | return -ENODATA; |
409 | 407 | ||
410 | *data = d; | 408 | *data = d; |
411 | return 0; | 409 | return 0; |
412 | } | 410 | } |
413 | 411 | ||
414 | /* -------------------------------------------------------------------------- | 412 | /* -------------------------------------------------------------------------- |
415 | Event Management | 413 | Event Management |
416 | -------------------------------------------------------------------------- */ | 414 | -------------------------------------------------------------------------- */ |
417 | 415 | ||
418 | struct acpi_ec_query_data { | ||
419 | acpi_handle handle; | ||
420 | u8 data; | ||
421 | }; | ||
422 | |||
423 | static void acpi_ec_gpe_query(void *ec_cxt) | 416 | static void acpi_ec_gpe_query(void *ec_cxt) |
424 | { | 417 | { |
425 | struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; | 418 | struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; |
426 | u8 value = 0; | 419 | u8 value = 0; |
427 | static char object_name[8]; | 420 | char object_name[8]; |
428 | 421 | ||
429 | if (!ec) | 422 | if (!ec || acpi_ec_query(ec, &value)) |
430 | goto end; | 423 | return; |
431 | |||
432 | value = acpi_ec_read_status(ec); | ||
433 | |||
434 | if (!(value & ACPI_EC_FLAG_SCI)) | ||
435 | goto end; | ||
436 | |||
437 | if (acpi_ec_query(ec, &value)) | ||
438 | goto end; | ||
439 | 424 | ||
440 | snprintf(object_name, 8, "_Q%2.2X", value); | 425 | snprintf(object_name, 8, "_Q%2.2X", value); |
441 | 426 | ||
442 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); | 427 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); |
443 | 428 | ||
444 | acpi_evaluate_object(ec->handle, object_name, NULL, NULL); | 429 | acpi_evaluate_object(ec->handle, object_name, NULL, NULL); |
445 | |||
446 | end: | ||
447 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | ||
448 | } | 430 | } |
449 | 431 | ||
450 | static u32 acpi_ec_gpe_handler(void *data) | 432 | static u32 acpi_ec_gpe_handler(void *data) |
@@ -453,22 +435,18 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
453 | u8 value; | 435 | u8 value; |
454 | struct acpi_ec *ec = (struct acpi_ec *)data; | 436 | struct acpi_ec *ec = (struct acpi_ec *)data; |
455 | 437 | ||
456 | acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); | ||
457 | value = acpi_ec_read_status(ec); | ||
458 | |||
459 | if (acpi_ec_mode == EC_INTR) { | 438 | if (acpi_ec_mode == EC_INTR) { |
460 | if (acpi_ec_check_status(value, ec->expect_event)) { | 439 | wake_up(&ec->wait); |
461 | ec->expect_event = 0; | ||
462 | wake_up(&ec->wait); | ||
463 | } | ||
464 | } | 440 | } |
465 | 441 | ||
466 | if (value & ACPI_EC_FLAG_SCI) { | 442 | value = acpi_ec_read_status(ec); |
467 | status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); | 443 | if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { |
468 | return status == AE_OK ? | 444 | atomic_set(&ec->query_pending, 1); |
469 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; | 445 | status = |
446 | acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, | ||
447 | ec); | ||
470 | } | 448 | } |
471 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); | 449 | |
472 | return status == AE_OK ? | 450 | return status == AE_OK ? |
473 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; | 451 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; |
474 | } | 452 | } |
@@ -504,7 +482,6 @@ acpi_ec_space_handler(u32 function, | |||
504 | acpi_integer f_v = 0; | 482 | acpi_integer f_v = 0; |
505 | int i = 0; | 483 | int i = 0; |
506 | 484 | ||
507 | |||
508 | if ((address > 0xFF) || !value || !handler_context) | 485 | if ((address > 0xFF) || !value || !handler_context) |
509 | return AE_BAD_PARAMETER; | 486 | return AE_BAD_PARAMETER; |
510 | 487 | ||
@@ -518,7 +495,7 @@ acpi_ec_space_handler(u32 function, | |||
518 | switch (function) { | 495 | switch (function) { |
519 | case ACPI_READ: | 496 | case ACPI_READ: |
520 | temp = 0; | 497 | temp = 0; |
521 | result = acpi_ec_read(ec, (u8) address, (u8 *) &temp); | 498 | result = acpi_ec_read(ec, (u8) address, (u8 *) & temp); |
522 | break; | 499 | break; |
523 | case ACPI_WRITE: | 500 | case ACPI_WRITE: |
524 | result = acpi_ec_write(ec, (u8) address, (u8) temp); | 501 | result = acpi_ec_write(ec, (u8) address, (u8) temp); |
@@ -571,18 +548,15 @@ static int acpi_ec_read_info(struct seq_file *seq, void *offset) | |||
571 | { | 548 | { |
572 | struct acpi_ec *ec = (struct acpi_ec *)seq->private; | 549 | struct acpi_ec *ec = (struct acpi_ec *)seq->private; |
573 | 550 | ||
574 | |||
575 | if (!ec) | 551 | if (!ec) |
576 | goto end; | 552 | goto end; |
577 | 553 | ||
578 | seq_printf(seq, "gpe bit: 0x%02x\n", | 554 | seq_printf(seq, "gpe: 0x%02x\n", (u32) ec->gpe); |
579 | (u32) ec->gpe_bit); | ||
580 | seq_printf(seq, "ports: 0x%02x, 0x%02x\n", | 555 | seq_printf(seq, "ports: 0x%02x, 0x%02x\n", |
581 | (u32) ec->command_addr, | 556 | (u32) ec->command_addr, (u32) ec->data_addr); |
582 | (u32) ec->data_addr); | ||
583 | seq_printf(seq, "use global lock: %s\n", | 557 | seq_printf(seq, "use global lock: %s\n", |
584 | ec->global_lock ? "yes" : "no"); | 558 | ec->global_lock ? "yes" : "no"); |
585 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 559 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); |
586 | 560 | ||
587 | end: | 561 | end: |
588 | return 0; | 562 | return 0; |
@@ -605,7 +579,6 @@ static int acpi_ec_add_fs(struct acpi_device *device) | |||
605 | { | 579 | { |
606 | struct proc_dir_entry *entry = NULL; | 580 | struct proc_dir_entry *entry = NULL; |
607 | 581 | ||
608 | |||
609 | if (!acpi_device_dir(device)) { | 582 | if (!acpi_device_dir(device)) { |
610 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | 583 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), |
611 | acpi_ec_dir); | 584 | acpi_ec_dir); |
@@ -648,18 +621,17 @@ static int acpi_ec_add(struct acpi_device *device) | |||
648 | acpi_status status = AE_OK; | 621 | acpi_status status = AE_OK; |
649 | struct acpi_ec *ec = NULL; | 622 | struct acpi_ec *ec = NULL; |
650 | 623 | ||
651 | |||
652 | if (!device) | 624 | if (!device) |
653 | return -EINVAL; | 625 | return -EINVAL; |
654 | 626 | ||
655 | ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 627 | ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
656 | if (!ec) | 628 | if (!ec) |
657 | return -ENOMEM; | 629 | return -ENOMEM; |
658 | memset(ec, 0, sizeof(struct acpi_ec)); | ||
659 | 630 | ||
660 | ec->handle = device->handle; | 631 | ec->handle = device->handle; |
661 | ec->uid = -1; | 632 | ec->uid = -1; |
662 | init_MUTEX(&ec->sem); | 633 | mutex_init(&ec->lock); |
634 | atomic_set(&ec->query_pending, 0); | ||
663 | if (acpi_ec_mode == EC_INTR) { | 635 | if (acpi_ec_mode == EC_INTR) { |
664 | atomic_set(&ec->leaving_burst, 1); | 636 | atomic_set(&ec->leaving_burst, 1); |
665 | init_waitqueue_head(&ec->wait); | 637 | init_waitqueue_head(&ec->wait); |
@@ -669,8 +641,7 @@ static int acpi_ec_add(struct acpi_device *device) | |||
669 | acpi_driver_data(device) = ec; | 641 | acpi_driver_data(device) = ec; |
670 | 642 | ||
671 | /* Use the global lock for all EC transactions? */ | 643 | /* Use the global lock for all EC transactions? */ |
672 | acpi_evaluate_integer(ec->handle, "_GLK", NULL, | 644 | acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock); |
673 | &ec->global_lock); | ||
674 | 645 | ||
675 | /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: | 646 | /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: |
676 | http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ | 647 | http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ |
@@ -679,7 +650,7 @@ static int acpi_ec_add(struct acpi_device *device) | |||
679 | ACPI_ADR_SPACE_EC, | 650 | ACPI_ADR_SPACE_EC, |
680 | &acpi_ec_space_handler); | 651 | &acpi_ec_space_handler); |
681 | 652 | ||
682 | acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, | 653 | acpi_remove_gpe_handler(NULL, ec_ecdt->gpe, |
683 | &acpi_ec_gpe_handler); | 654 | &acpi_ec_gpe_handler); |
684 | 655 | ||
685 | kfree(ec_ecdt); | 656 | kfree(ec_ecdt); |
@@ -687,11 +658,10 @@ static int acpi_ec_add(struct acpi_device *device) | |||
687 | 658 | ||
688 | /* Get GPE bit assignment (EC events). */ | 659 | /* Get GPE bit assignment (EC events). */ |
689 | /* TODO: Add support for _GPE returning a package */ | 660 | /* TODO: Add support for _GPE returning a package */ |
690 | status = | 661 | status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe); |
691 | acpi_evaluate_integer(ec->handle, "_GPE", NULL, | ||
692 | &ec->gpe_bit); | ||
693 | if (ACPI_FAILURE(status)) { | 662 | if (ACPI_FAILURE(status)) { |
694 | ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment")); | 663 | ACPI_EXCEPTION((AE_INFO, status, |
664 | "Obtaining GPE bit assignment")); | ||
695 | result = -ENODEV; | 665 | result = -ENODEV; |
696 | goto end; | 666 | goto end; |
697 | } | 667 | } |
@@ -701,13 +671,13 @@ static int acpi_ec_add(struct acpi_device *device) | |||
701 | goto end; | 671 | goto end; |
702 | 672 | ||
703 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", | 673 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", |
704 | acpi_device_name(device), acpi_device_bid(device), | 674 | acpi_device_name(device), acpi_device_bid(device), |
705 | (u32) ec->gpe_bit)); | 675 | (u32) ec->gpe)); |
706 | 676 | ||
707 | if (!first_ec) | 677 | if (!first_ec) |
708 | first_ec = device; | 678 | first_ec = device; |
709 | 679 | ||
710 | end: | 680 | end: |
711 | if (result) | 681 | if (result) |
712 | kfree(ec); | 682 | kfree(ec); |
713 | 683 | ||
@@ -718,7 +688,6 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
718 | { | 688 | { |
719 | struct acpi_ec *ec = NULL; | 689 | struct acpi_ec *ec = NULL; |
720 | 690 | ||
721 | |||
722 | if (!device) | 691 | if (!device) |
723 | return -EINVAL; | 692 | return -EINVAL; |
724 | 693 | ||
@@ -761,7 +730,6 @@ static int acpi_ec_start(struct acpi_device *device) | |||
761 | acpi_status status = AE_OK; | 730 | acpi_status status = AE_OK; |
762 | struct acpi_ec *ec = NULL; | 731 | struct acpi_ec *ec = NULL; |
763 | 732 | ||
764 | |||
765 | if (!device) | 733 | if (!device) |
766 | return -EINVAL; | 734 | return -EINVAL; |
767 | 735 | ||
@@ -782,27 +750,26 @@ static int acpi_ec_start(struct acpi_device *device) | |||
782 | } | 750 | } |
783 | 751 | ||
784 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx", | 752 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx", |
785 | ec->gpe_bit, ec->command_addr, ec->data_addr)); | 753 | ec->gpe, ec->command_addr, ec->data_addr)); |
786 | 754 | ||
787 | /* | 755 | /* |
788 | * Install GPE handler | 756 | * Install GPE handler |
789 | */ | 757 | */ |
790 | status = acpi_install_gpe_handler(NULL, ec->gpe_bit, | 758 | status = acpi_install_gpe_handler(NULL, ec->gpe, |
791 | ACPI_GPE_EDGE_TRIGGERED, | 759 | ACPI_GPE_EDGE_TRIGGERED, |
792 | &acpi_ec_gpe_handler, ec); | 760 | &acpi_ec_gpe_handler, ec); |
793 | if (ACPI_FAILURE(status)) { | 761 | if (ACPI_FAILURE(status)) { |
794 | return -ENODEV; | 762 | return -ENODEV; |
795 | } | 763 | } |
796 | acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME); | 764 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); |
797 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 765 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); |
798 | 766 | ||
799 | status = acpi_install_address_space_handler(ec->handle, | 767 | status = acpi_install_address_space_handler(ec->handle, |
800 | ACPI_ADR_SPACE_EC, | 768 | ACPI_ADR_SPACE_EC, |
801 | &acpi_ec_space_handler, | 769 | &acpi_ec_space_handler, |
802 | &acpi_ec_space_setup, ec); | 770 | &acpi_ec_space_setup, ec); |
803 | if (ACPI_FAILURE(status)) { | 771 | if (ACPI_FAILURE(status)) { |
804 | acpi_remove_gpe_handler(NULL, ec->gpe_bit, | 772 | acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); |
805 | &acpi_ec_gpe_handler); | ||
806 | return -ENODEV; | 773 | return -ENODEV; |
807 | } | 774 | } |
808 | 775 | ||
@@ -814,7 +781,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type) | |||
814 | acpi_status status = AE_OK; | 781 | acpi_status status = AE_OK; |
815 | struct acpi_ec *ec = NULL; | 782 | struct acpi_ec *ec = NULL; |
816 | 783 | ||
817 | |||
818 | if (!device) | 784 | if (!device) |
819 | return -EINVAL; | 785 | return -EINVAL; |
820 | 786 | ||
@@ -826,9 +792,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type) | |||
826 | if (ACPI_FAILURE(status)) | 792 | if (ACPI_FAILURE(status)) |
827 | return -ENODEV; | 793 | return -ENODEV; |
828 | 794 | ||
829 | status = | 795 | status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); |
830 | acpi_remove_gpe_handler(NULL, ec->gpe_bit, | ||
831 | &acpi_ec_gpe_handler); | ||
832 | if (ACPI_FAILURE(status)) | 796 | if (ACPI_FAILURE(status)) |
833 | return -ENODEV; | 797 | return -ENODEV; |
834 | 798 | ||
@@ -841,7 +805,7 @@ acpi_fake_ecdt_callback(acpi_handle handle, | |||
841 | { | 805 | { |
842 | acpi_status status; | 806 | acpi_status status; |
843 | 807 | ||
844 | init_MUTEX(&ec_ecdt->sem); | 808 | mutex_init(&ec_ecdt->lock); |
845 | if (acpi_ec_mode == EC_INTR) { | 809 | if (acpi_ec_mode == EC_INTR) { |
846 | init_waitqueue_head(&ec_ecdt->wait); | 810 | init_waitqueue_head(&ec_ecdt->wait); |
847 | } | 811 | } |
@@ -853,16 +817,15 @@ acpi_fake_ecdt_callback(acpi_handle handle, | |||
853 | ec_ecdt->uid = -1; | 817 | ec_ecdt->uid = -1; |
854 | acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid); | 818 | acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid); |
855 | 819 | ||
856 | status = | 820 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe); |
857 | acpi_evaluate_integer(handle, "_GPE", NULL, | ||
858 | &ec_ecdt->gpe_bit); | ||
859 | if (ACPI_FAILURE(status)) | 821 | if (ACPI_FAILURE(status)) |
860 | return status; | 822 | return status; |
861 | ec_ecdt->global_lock = TRUE; | 823 | ec_ecdt->global_lock = TRUE; |
862 | ec_ecdt->handle = handle; | 824 | ec_ecdt->handle = handle; |
863 | 825 | ||
864 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", | 826 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", |
865 | ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr)); | 827 | ec_ecdt->gpe, ec_ecdt->command_addr, |
828 | ec_ecdt->data_addr)); | ||
866 | 829 | ||
867 | return AE_CTRL_TERMINATE; | 830 | return AE_CTRL_TERMINATE; |
868 | } | 831 | } |
@@ -884,12 +847,11 @@ static int __init acpi_ec_fake_ecdt(void) | |||
884 | 847 | ||
885 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT")); | 848 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT")); |
886 | 849 | ||
887 | ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 850 | ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
888 | if (!ec_ecdt) { | 851 | if (!ec_ecdt) { |
889 | ret = -ENOMEM; | 852 | ret = -ENOMEM; |
890 | goto error; | 853 | goto error; |
891 | } | 854 | } |
892 | memset(ec_ecdt, 0, sizeof(struct acpi_ec)); | ||
893 | 855 | ||
894 | status = acpi_get_devices(ACPI_EC_HID, | 856 | status = acpi_get_devices(ACPI_EC_HID, |
895 | acpi_fake_ecdt_callback, NULL, NULL); | 857 | acpi_fake_ecdt_callback, NULL, NULL); |
@@ -901,7 +863,7 @@ static int __init acpi_ec_fake_ecdt(void) | |||
901 | goto error; | 863 | goto error; |
902 | } | 864 | } |
903 | return 0; | 865 | return 0; |
904 | error: | 866 | error: |
905 | return ret; | 867 | return ret; |
906 | } | 868 | } |
907 | 869 | ||
@@ -910,9 +872,8 @@ static int __init acpi_ec_get_real_ecdt(void) | |||
910 | acpi_status status; | 872 | acpi_status status; |
911 | struct acpi_table_ecdt *ecdt_ptr; | 873 | struct acpi_table_ecdt *ecdt_ptr; |
912 | 874 | ||
913 | status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, | 875 | status = acpi_get_table(ACPI_SIG_ECDT, 1, |
914 | (struct acpi_table_header **) | 876 | (struct acpi_table_header **)&ecdt_ptr); |
915 | &ecdt_ptr); | ||
916 | if (ACPI_FAILURE(status)) | 877 | if (ACPI_FAILURE(status)) |
917 | return -ENODEV; | 878 | return -ENODEV; |
918 | 879 | ||
@@ -921,30 +882,28 @@ static int __init acpi_ec_get_real_ecdt(void) | |||
921 | /* | 882 | /* |
922 | * Generate a temporary ec context to use until the namespace is scanned | 883 | * Generate a temporary ec context to use until the namespace is scanned |
923 | */ | 884 | */ |
924 | ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 885 | ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
925 | if (!ec_ecdt) | 886 | if (!ec_ecdt) |
926 | return -ENOMEM; | 887 | return -ENOMEM; |
927 | memset(ec_ecdt, 0, sizeof(struct acpi_ec)); | ||
928 | 888 | ||
929 | init_MUTEX(&ec_ecdt->sem); | 889 | mutex_init(&ec_ecdt->lock); |
930 | if (acpi_ec_mode == EC_INTR) { | 890 | if (acpi_ec_mode == EC_INTR) { |
931 | init_waitqueue_head(&ec_ecdt->wait); | 891 | init_waitqueue_head(&ec_ecdt->wait); |
932 | } | 892 | } |
933 | ec_ecdt->command_addr = ecdt_ptr->ec_control.address; | 893 | ec_ecdt->command_addr = ecdt_ptr->control.address; |
934 | ec_ecdt->data_addr = ecdt_ptr->ec_data.address; | 894 | ec_ecdt->data_addr = ecdt_ptr->data.address; |
935 | ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit; | 895 | ec_ecdt->gpe = ecdt_ptr->gpe; |
936 | /* use the GL just to be safe */ | 896 | /* use the GL just to be safe */ |
937 | ec_ecdt->global_lock = TRUE; | 897 | ec_ecdt->global_lock = TRUE; |
938 | ec_ecdt->uid = ecdt_ptr->uid; | 898 | ec_ecdt->uid = ecdt_ptr->uid; |
939 | 899 | ||
940 | status = | 900 | status = acpi_get_handle(NULL, ecdt_ptr->id, &ec_ecdt->handle); |
941 | acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle); | ||
942 | if (ACPI_FAILURE(status)) { | 901 | if (ACPI_FAILURE(status)) { |
943 | goto error; | 902 | goto error; |
944 | } | 903 | } |
945 | 904 | ||
946 | return 0; | 905 | return 0; |
947 | error: | 906 | error: |
948 | ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT")); | 907 | ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT")); |
949 | kfree(ec_ecdt); | 908 | kfree(ec_ecdt); |
950 | ec_ecdt = NULL; | 909 | ec_ecdt = NULL; |
@@ -970,14 +929,14 @@ int __init acpi_ec_ecdt_probe(void) | |||
970 | /* | 929 | /* |
971 | * Install GPE handler | 930 | * Install GPE handler |
972 | */ | 931 | */ |
973 | status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit, | 932 | status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe, |
974 | ACPI_GPE_EDGE_TRIGGERED, | 933 | ACPI_GPE_EDGE_TRIGGERED, |
975 | &acpi_ec_gpe_handler, ec_ecdt); | 934 | &acpi_ec_gpe_handler, ec_ecdt); |
976 | if (ACPI_FAILURE(status)) { | 935 | if (ACPI_FAILURE(status)) { |
977 | goto error; | 936 | goto error; |
978 | } | 937 | } |
979 | acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME); | 938 | acpi_set_gpe_type(NULL, ec_ecdt->gpe, ACPI_GPE_TYPE_RUNTIME); |
980 | acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR); | 939 | acpi_enable_gpe(NULL, ec_ecdt->gpe, ACPI_NOT_ISR); |
981 | 940 | ||
982 | status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, | 941 | status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, |
983 | ACPI_ADR_SPACE_EC, | 942 | ACPI_ADR_SPACE_EC, |
@@ -985,7 +944,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
985 | &acpi_ec_space_setup, | 944 | &acpi_ec_space_setup, |
986 | ec_ecdt); | 945 | ec_ecdt); |
987 | if (ACPI_FAILURE(status)) { | 946 | if (ACPI_FAILURE(status)) { |
988 | acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, | 947 | acpi_remove_gpe_handler(NULL, ec_ecdt->gpe, |
989 | &acpi_ec_gpe_handler); | 948 | &acpi_ec_gpe_handler); |
990 | goto error; | 949 | goto error; |
991 | } | 950 | } |
@@ -1004,7 +963,6 @@ static int __init acpi_ec_init(void) | |||
1004 | { | 963 | { |
1005 | int result = 0; | 964 | int result = 0; |
1006 | 965 | ||
1007 | |||
1008 | if (acpi_disabled) | 966 | if (acpi_disabled) |
1009 | return 0; | 967 | return 0; |
1010 | 968 | ||
@@ -1057,7 +1015,8 @@ static int __init acpi_ec_set_intr_mode(char *str) | |||
1057 | acpi_ec_mode = EC_POLL; | 1015 | acpi_ec_mode = EC_POLL; |
1058 | } | 1016 | } |
1059 | acpi_ec_driver.ops.add = acpi_ec_add; | 1017 | acpi_ec_driver.ops.add = acpi_ec_add; |
1060 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling")); | 1018 | printk(KERN_NOTICE PREFIX "%s mode.\n", |
1019 | intr ? "interrupt" : "polling"); | ||
1061 | 1020 | ||
1062 | return 1; | 1021 | return 1; |
1063 | } | 1022 | } |
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c index 919037d6acff..a1f87b5def2a 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/events/evevent.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -70,13 +70,6 @@ acpi_status acpi_ev_initialize_events(void) | |||
70 | 70 | ||
71 | ACPI_FUNCTION_TRACE(ev_initialize_events); | 71 | ACPI_FUNCTION_TRACE(ev_initialize_events); |
72 | 72 | ||
73 | /* Make sure we have ACPI tables */ | ||
74 | |||
75 | if (!acpi_gbl_DSDT) { | ||
76 | ACPI_WARNING((AE_INFO, "No ACPI tables present!")); | ||
77 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
78 | } | ||
79 | |||
80 | /* | 73 | /* |
81 | * Initialize the Fixed and General Purpose Events. This is done prior to | 74 | * Initialize the Fixed and General Purpose Events. This is done prior to |
82 | * enabling SCIs to prevent interrupts from occurring before the handlers are | 75 | * enabling SCIs to prevent interrupts from occurring before the handlers are |
@@ -211,8 +204,7 @@ static acpi_status acpi_ev_fixed_event_initialize(void) | |||
211 | if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) { | 204 | if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) { |
212 | status = | 205 | status = |
213 | acpi_set_register(acpi_gbl_fixed_event_info[i]. | 206 | acpi_set_register(acpi_gbl_fixed_event_info[i]. |
214 | enable_register_id, 0, | 207 | enable_register_id, 0); |
215 | ACPI_MTX_LOCK); | ||
216 | if (ACPI_FAILURE(status)) { | 208 | if (ACPI_FAILURE(status)) { |
217 | return (status); | 209 | return (status); |
218 | } | 210 | } |
@@ -298,7 +290,7 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) | |||
298 | /* Clear the status bit */ | 290 | /* Clear the status bit */ |
299 | 291 | ||
300 | (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. | 292 | (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. |
301 | status_register_id, 1, ACPI_MTX_DO_NOT_LOCK); | 293 | status_register_id, 1); |
302 | 294 | ||
303 | /* | 295 | /* |
304 | * Make sure we've got a handler. If not, report an error. | 296 | * Make sure we've got a handler. If not, report an error. |
@@ -306,8 +298,7 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) | |||
306 | */ | 298 | */ |
307 | if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { | 299 | if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { |
308 | (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. | 300 | (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. |
309 | enable_register_id, 0, | 301 | enable_register_id, 0); |
310 | ACPI_MTX_DO_NOT_LOCK); | ||
311 | 302 | ||
312 | ACPI_ERROR((AE_INFO, | 303 | ACPI_ERROR((AE_INFO, |
313 | "No installed handler for fixed event [%08X]", | 304 | "No installed handler for fixed event [%08X]", |
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index c76c0583ca6a..dfac3ecc596e 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -121,7 +121,9 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, | |||
121 | if (!gpe_register_info) { | 121 | if (!gpe_register_info) { |
122 | return_ACPI_STATUS(AE_NOT_EXIST); | 122 | return_ACPI_STATUS(AE_NOT_EXIST); |
123 | } | 123 | } |
124 | register_bit = gpe_event_info->register_bit; | 124 | register_bit = (u8) |
125 | (1 << | ||
126 | (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); | ||
125 | 127 | ||
126 | /* 1) Disable case. Simply clear all enable bits */ | 128 | /* 1) Disable case. Simply clear all enable bits */ |
127 | 129 | ||
@@ -458,8 +460,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
458 | 460 | ||
459 | /* Examine one GPE bit */ | 461 | /* Examine one GPE bit */ |
460 | 462 | ||
461 | if (enabled_status_byte & | 463 | if (enabled_status_byte & (1 << j)) { |
462 | acpi_gbl_decode_to8bit[j]) { | ||
463 | /* | 464 | /* |
464 | * Found an active GPE. Dispatch the event to a handler | 465 | * Found an active GPE. Dispatch the event to a handler |
465 | * or method. | 466 | * or method. |
@@ -570,7 +571,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
570 | 571 | ||
571 | if (ACPI_FAILURE(status)) { | 572 | if (ACPI_FAILURE(status)) { |
572 | ACPI_EXCEPTION((AE_INFO, status, | 573 | ACPI_EXCEPTION((AE_INFO, status, |
573 | "While evaluating GPE method [%4.4s]", | 574 | "while evaluating GPE method [%4.4s]", |
574 | acpi_ut_get_node_name | 575 | acpi_ut_get_node_name |
575 | (local_gpe_event_info.dispatch. | 576 | (local_gpe_event_info.dispatch. |
576 | method_node))); | 577 | method_node))); |
@@ -618,6 +619,8 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
618 | 619 | ||
619 | ACPI_FUNCTION_TRACE(ev_gpe_dispatch); | 620 | ACPI_FUNCTION_TRACE(ev_gpe_dispatch); |
620 | 621 | ||
622 | acpi_gpe_count++; | ||
623 | |||
621 | /* | 624 | /* |
622 | * If edge-triggered, clear the GPE status bit now. Note that | 625 | * If edge-triggered, clear the GPE status bit now. Note that |
623 | * level-triggered events are cleared after the GPE is serviced. | 626 | * level-triggered events are cleared after the GPE is serviced. |
@@ -633,20 +636,23 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
633 | } | 636 | } |
634 | } | 637 | } |
635 | 638 | ||
636 | /* Save current system state */ | 639 | if (!acpi_gbl_system_awake_and_running) { |
637 | 640 | /* | |
638 | if (acpi_gbl_system_awake_and_running) { | 641 | * We just woke up because of a wake GPE. Disable any further GPEs |
639 | ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); | 642 | * until we are fully up and running (Only wake GPEs should be enabled |
640 | } else { | 643 | * at this time, but we just brute-force disable them all.) |
641 | ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); | 644 | * 1) We must disable this particular wake GPE so it won't fire again |
645 | * 2) We want to disable all wake GPEs, since we are now awake | ||
646 | */ | ||
647 | (void)acpi_hw_disable_all_gpes(); | ||
642 | } | 648 | } |
643 | 649 | ||
644 | /* | 650 | /* |
645 | * Dispatch the GPE to either an installed handler, or the control | 651 | * Dispatch the GPE to either an installed handler, or the control method |
646 | * method associated with this GPE (_Lxx or _Exx). | 652 | * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke |
647 | * If a handler exists, we invoke it and do not attempt to run the method. | 653 | * it and do not attempt to run the method. If there is neither a handler |
648 | * If there is neither a handler nor a method, we disable the level to | 654 | * nor a method, we disable this GPE to prevent further such pointless |
649 | * prevent further events from coming in here. | 655 | * events from firing. |
650 | */ | 656 | */ |
651 | switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { | 657 | switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { |
652 | case ACPI_GPE_DISPATCH_HANDLER: | 658 | case ACPI_GPE_DISPATCH_HANDLER: |
@@ -677,8 +683,8 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
677 | case ACPI_GPE_DISPATCH_METHOD: | 683 | case ACPI_GPE_DISPATCH_METHOD: |
678 | 684 | ||
679 | /* | 685 | /* |
680 | * Disable GPE, so it doesn't keep firing before the method has a | 686 | * Disable the GPE, so it doesn't keep firing before the method has a |
681 | * chance to run. | 687 | * chance to run (it runs asynchronously with interrupts enabled). |
682 | */ | 688 | */ |
683 | status = acpi_ev_disable_gpe(gpe_event_info); | 689 | status = acpi_ev_disable_gpe(gpe_event_info); |
684 | if (ACPI_FAILURE(status)) { | 690 | if (ACPI_FAILURE(status)) { |
@@ -711,7 +717,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
711 | gpe_number)); | 717 | gpe_number)); |
712 | 718 | ||
713 | /* | 719 | /* |
714 | * Disable the GPE. The GPE will remain disabled until the ACPI | 720 | * Disable the GPE. The GPE will remain disabled until the ACPI |
715 | * Core Subsystem is restarted, or a handler is installed. | 721 | * Core Subsystem is restarted, or a handler is installed. |
716 | */ | 722 | */ |
717 | status = acpi_ev_disable_gpe(gpe_event_info); | 723 | status = acpi_ev_disable_gpe(gpe_event_info); |
@@ -726,50 +732,3 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
726 | 732 | ||
727 | return_UINT32(ACPI_INTERRUPT_HANDLED); | 733 | return_UINT32(ACPI_INTERRUPT_HANDLED); |
728 | } | 734 | } |
729 | |||
730 | #ifdef ACPI_GPE_NOTIFY_CHECK | ||
731 | /******************************************************************************* | ||
732 | * TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED | ||
733 | * | ||
734 | * FUNCTION: acpi_ev_check_for_wake_only_gpe | ||
735 | * | ||
736 | * PARAMETERS: gpe_event_info - info for this GPE | ||
737 | * | ||
738 | * RETURN: Status | ||
739 | * | ||
740 | * DESCRIPTION: Determine if a a GPE is "wake-only". | ||
741 | * | ||
742 | * Called from Notify() code in interpreter when a "DeviceWake" | ||
743 | * Notify comes in. | ||
744 | * | ||
745 | ******************************************************************************/ | ||
746 | |||
747 | acpi_status | ||
748 | acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info) | ||
749 | { | ||
750 | acpi_status status; | ||
751 | |||
752 | ACPI_FUNCTION_TRACE(ev_check_for_wake_only_gpe); | ||
753 | |||
754 | if ((gpe_event_info) && /* Only >0 for _Lxx/_Exx */ | ||
755 | ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) { /* System state at GPE time */ | ||
756 | /* This must be a wake-only GPE, disable it */ | ||
757 | |||
758 | status = acpi_ev_disable_gpe(gpe_event_info); | ||
759 | |||
760 | /* Set GPE to wake-only. Do not change wake disabled/enabled status */ | ||
761 | |||
762 | acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE); | ||
763 | |||
764 | ACPI_INFO((AE_INFO, | ||
765 | "GPE %p was updated from wake/run to wake-only", | ||
766 | gpe_event_info)); | ||
767 | |||
768 | /* This was a wake-only GPE */ | ||
769 | |||
770 | return_ACPI_STATUS(AE_WAKE_ONLY_GPE); | ||
771 | } | ||
772 | |||
773 | return_ACPI_STATUS(AE_OK); | ||
774 | } | ||
775 | #endif | ||
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index 95ddeb48bc0f..ad5bc76edf46 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -529,7 +529,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 | |||
529 | 529 | ||
530 | /* Install new interrupt handler if not SCI_INT */ | 530 | /* Install new interrupt handler if not SCI_INT */ |
531 | 531 | ||
532 | if (interrupt_number != acpi_gbl_FADT->sci_int) { | 532 | if (interrupt_number != acpi_gbl_FADT.sci_interrupt) { |
533 | status = acpi_os_install_interrupt_handler(interrupt_number, | 533 | status = acpi_os_install_interrupt_handler(interrupt_number, |
534 | acpi_ev_gpe_xrupt_handler, | 534 | acpi_ev_gpe_xrupt_handler, |
535 | gpe_xrupt); | 535 | gpe_xrupt); |
@@ -567,7 +567,7 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) | |||
567 | 567 | ||
568 | /* We never want to remove the SCI interrupt handler */ | 568 | /* We never want to remove the SCI interrupt handler */ |
569 | 569 | ||
570 | if (gpe_xrupt->interrupt_number == acpi_gbl_FADT->sci_int) { | 570 | if (gpe_xrupt->interrupt_number == acpi_gbl_FADT.sci_interrupt) { |
571 | gpe_xrupt->gpe_block_list_head = NULL; | 571 | gpe_xrupt->gpe_block_list_head = NULL; |
572 | return_ACPI_STATUS(AE_OK); | 572 | return_ACPI_STATUS(AE_OK); |
573 | } | 573 | } |
@@ -796,30 +796,31 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) | |||
796 | (u8) (gpe_block->block_base_number + | 796 | (u8) (gpe_block->block_base_number + |
797 | (i * ACPI_GPE_REGISTER_WIDTH)); | 797 | (i * ACPI_GPE_REGISTER_WIDTH)); |
798 | 798 | ||
799 | ACPI_STORE_ADDRESS(this_register->status_address.address, | 799 | this_register->status_address.address = |
800 | (gpe_block->block_address.address + i)); | 800 | gpe_block->block_address.address + i; |
801 | 801 | ||
802 | ACPI_STORE_ADDRESS(this_register->enable_address.address, | 802 | this_register->enable_address.address = |
803 | (gpe_block->block_address.address | 803 | gpe_block->block_address.address + i + |
804 | + i + gpe_block->register_count)); | 804 | gpe_block->register_count; |
805 | 805 | ||
806 | this_register->status_address.address_space_id = | 806 | this_register->status_address.space_id = |
807 | gpe_block->block_address.address_space_id; | 807 | gpe_block->block_address.space_id; |
808 | this_register->enable_address.address_space_id = | 808 | this_register->enable_address.space_id = |
809 | gpe_block->block_address.address_space_id; | 809 | gpe_block->block_address.space_id; |
810 | this_register->status_address.register_bit_width = | 810 | this_register->status_address.bit_width = |
811 | ACPI_GPE_REGISTER_WIDTH; | 811 | ACPI_GPE_REGISTER_WIDTH; |
812 | this_register->enable_address.register_bit_width = | 812 | this_register->enable_address.bit_width = |
813 | ACPI_GPE_REGISTER_WIDTH; | 813 | ACPI_GPE_REGISTER_WIDTH; |
814 | this_register->status_address.register_bit_offset = | 814 | this_register->status_address.bit_offset = |
815 | ACPI_GPE_REGISTER_WIDTH; | 815 | ACPI_GPE_REGISTER_WIDTH; |
816 | this_register->enable_address.register_bit_offset = | 816 | this_register->enable_address.bit_offset = |
817 | ACPI_GPE_REGISTER_WIDTH; | 817 | ACPI_GPE_REGISTER_WIDTH; |
818 | 818 | ||
819 | /* Init the event_info for each GPE within this register */ | 819 | /* Init the event_info for each GPE within this register */ |
820 | 820 | ||
821 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { | 821 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { |
822 | this_event->register_bit = acpi_gbl_decode_to8bit[j]; | 822 | this_event->gpe_number = |
823 | (u8) (this_register->base_gpe_number + j); | ||
823 | this_event->register_info = this_register; | 824 | this_event->register_info = this_register; |
824 | this_event++; | 825 | this_event++; |
825 | } | 826 | } |
@@ -1109,11 +1110,12 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1109 | * If EITHER the register length OR the block address are zero, then that | 1110 | * If EITHER the register length OR the block address are zero, then that |
1110 | * particular block is not supported. | 1111 | * particular block is not supported. |
1111 | */ | 1112 | */ |
1112 | if (acpi_gbl_FADT->gpe0_blk_len && acpi_gbl_FADT->xgpe0_blk.address) { | 1113 | if (acpi_gbl_FADT.gpe0_block_length && |
1114 | acpi_gbl_FADT.xgpe0_block.address) { | ||
1113 | 1115 | ||
1114 | /* GPE block 0 exists (has both length and address > 0) */ | 1116 | /* GPE block 0 exists (has both length and address > 0) */ |
1115 | 1117 | ||
1116 | register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2); | 1118 | register_count0 = (u16) (acpi_gbl_FADT.gpe0_block_length / 2); |
1117 | 1119 | ||
1118 | gpe_number_max = | 1120 | gpe_number_max = |
1119 | (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1; | 1121 | (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1; |
@@ -1121,9 +1123,9 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1121 | /* Install GPE Block 0 */ | 1123 | /* Install GPE Block 0 */ |
1122 | 1124 | ||
1123 | status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, | 1125 | status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, |
1124 | &acpi_gbl_FADT->xgpe0_blk, | 1126 | &acpi_gbl_FADT.xgpe0_block, |
1125 | register_count0, 0, | 1127 | register_count0, 0, |
1126 | acpi_gbl_FADT->sci_int, | 1128 | acpi_gbl_FADT.sci_interrupt, |
1127 | &acpi_gbl_gpe_fadt_blocks[0]); | 1129 | &acpi_gbl_gpe_fadt_blocks[0]); |
1128 | 1130 | ||
1129 | if (ACPI_FAILURE(status)) { | 1131 | if (ACPI_FAILURE(status)) { |
@@ -1132,20 +1134,21 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1132 | } | 1134 | } |
1133 | } | 1135 | } |
1134 | 1136 | ||
1135 | if (acpi_gbl_FADT->gpe1_blk_len && acpi_gbl_FADT->xgpe1_blk.address) { | 1137 | if (acpi_gbl_FADT.gpe1_block_length && |
1138 | acpi_gbl_FADT.xgpe1_block.address) { | ||
1136 | 1139 | ||
1137 | /* GPE block 1 exists (has both length and address > 0) */ | 1140 | /* GPE block 1 exists (has both length and address > 0) */ |
1138 | 1141 | ||
1139 | register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2); | 1142 | register_count1 = (u16) (acpi_gbl_FADT.gpe1_block_length / 2); |
1140 | 1143 | ||
1141 | /* Check for GPE0/GPE1 overlap (if both banks exist) */ | 1144 | /* Check for GPE0/GPE1 overlap (if both banks exist) */ |
1142 | 1145 | ||
1143 | if ((register_count0) && | 1146 | if ((register_count0) && |
1144 | (gpe_number_max >= acpi_gbl_FADT->gpe1_base)) { | 1147 | (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) { |
1145 | ACPI_ERROR((AE_INFO, | 1148 | ACPI_ERROR((AE_INFO, |
1146 | "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1", | 1149 | "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1", |
1147 | gpe_number_max, acpi_gbl_FADT->gpe1_base, | 1150 | gpe_number_max, acpi_gbl_FADT.gpe1_base, |
1148 | acpi_gbl_FADT->gpe1_base + | 1151 | acpi_gbl_FADT.gpe1_base + |
1149 | ((register_count1 * | 1152 | ((register_count1 * |
1150 | ACPI_GPE_REGISTER_WIDTH) - 1))); | 1153 | ACPI_GPE_REGISTER_WIDTH) - 1))); |
1151 | 1154 | ||
@@ -1157,10 +1160,11 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1157 | 1160 | ||
1158 | status = | 1161 | status = |
1159 | acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, | 1162 | acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, |
1160 | &acpi_gbl_FADT->xgpe1_blk, | 1163 | &acpi_gbl_FADT.xgpe1_block, |
1161 | register_count1, | 1164 | register_count1, |
1162 | acpi_gbl_FADT->gpe1_base, | 1165 | acpi_gbl_FADT.gpe1_base, |
1163 | acpi_gbl_FADT->sci_int, | 1166 | acpi_gbl_FADT. |
1167 | sci_interrupt, | ||
1164 | &acpi_gbl_gpe_fadt_blocks | 1168 | &acpi_gbl_gpe_fadt_blocks |
1165 | [1]); | 1169 | [1]); |
1166 | 1170 | ||
@@ -1173,7 +1177,7 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1173 | * GPE0 and GPE1 do not have to be contiguous in the GPE number | 1177 | * GPE0 and GPE1 do not have to be contiguous in the GPE number |
1174 | * space. However, GPE0 always starts at GPE number zero. | 1178 | * space. However, GPE0 always starts at GPE number zero. |
1175 | */ | 1179 | */ |
1176 | gpe_number_max = acpi_gbl_FADT->gpe1_base + | 1180 | gpe_number_max = acpi_gbl_FADT.gpe1_base + |
1177 | ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1); | 1181 | ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1); |
1178 | } | 1182 | } |
1179 | } | 1183 | } |
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index ee2a10bf9077..1b784ffe54c3 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -63,14 +63,18 @@ static const char *acpi_notify_value_names[] = { | |||
63 | }; | 63 | }; |
64 | #endif | 64 | #endif |
65 | 65 | ||
66 | /* Pointer to FACS needed for the Global Lock */ | ||
67 | |||
68 | static struct acpi_table_facs *facs = NULL; | ||
69 | |||
66 | /* Local prototypes */ | 70 | /* Local prototypes */ |
67 | 71 | ||
68 | static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); | 72 | static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); |
69 | 73 | ||
70 | static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context); | ||
71 | |||
72 | static u32 acpi_ev_global_lock_handler(void *context); | 74 | static u32 acpi_ev_global_lock_handler(void *context); |
73 | 75 | ||
76 | static acpi_status acpi_ev_remove_global_lock_handler(void); | ||
77 | |||
74 | /******************************************************************************* | 78 | /******************************************************************************* |
75 | * | 79 | * |
76 | * FUNCTION: acpi_ev_is_notify_object | 80 | * FUNCTION: acpi_ev_is_notify_object |
@@ -282,68 +286,45 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) | |||
282 | 286 | ||
283 | /******************************************************************************* | 287 | /******************************************************************************* |
284 | * | 288 | * |
285 | * FUNCTION: acpi_ev_global_lock_thread | ||
286 | * | ||
287 | * PARAMETERS: Context - From thread interface, not used | ||
288 | * | ||
289 | * RETURN: None | ||
290 | * | ||
291 | * DESCRIPTION: Invoked by SCI interrupt handler upon acquisition of the | ||
292 | * Global Lock. Simply signal all threads that are waiting | ||
293 | * for the lock. | ||
294 | * | ||
295 | ******************************************************************************/ | ||
296 | |||
297 | static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context) | ||
298 | { | ||
299 | acpi_status status; | ||
300 | |||
301 | /* Signal threads that are waiting for the lock */ | ||
302 | |||
303 | if (acpi_gbl_global_lock_thread_count) { | ||
304 | |||
305 | /* Send sufficient units to the semaphore */ | ||
306 | |||
307 | status = | ||
308 | acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, | ||
309 | acpi_gbl_global_lock_thread_count); | ||
310 | if (ACPI_FAILURE(status)) { | ||
311 | ACPI_ERROR((AE_INFO, | ||
312 | "Could not signal Global Lock semaphore")); | ||
313 | } | ||
314 | } | ||
315 | } | ||
316 | |||
317 | /******************************************************************************* | ||
318 | * | ||
319 | * FUNCTION: acpi_ev_global_lock_handler | 289 | * FUNCTION: acpi_ev_global_lock_handler |
320 | * | 290 | * |
321 | * PARAMETERS: Context - From thread interface, not used | 291 | * PARAMETERS: Context - From thread interface, not used |
322 | * | 292 | * |
323 | * RETURN: ACPI_INTERRUPT_HANDLED or ACPI_INTERRUPT_NOT_HANDLED | 293 | * RETURN: ACPI_INTERRUPT_HANDLED |
324 | * | 294 | * |
325 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock | 295 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock |
326 | * release interrupt occurs. Grab the global lock and queue | 296 | * release interrupt occurs. Attempt to acquire the global lock, |
327 | * the global lock thread for execution | 297 | * if successful, signal the thread waiting for the lock. |
298 | * | ||
299 | * NOTE: Assumes that the semaphore can be signaled from interrupt level. If | ||
300 | * this is not possible for some reason, a separate thread will have to be | ||
301 | * scheduled to do this. | ||
328 | * | 302 | * |
329 | ******************************************************************************/ | 303 | ******************************************************************************/ |
330 | 304 | ||
331 | static u32 acpi_ev_global_lock_handler(void *context) | 305 | static u32 acpi_ev_global_lock_handler(void *context) |
332 | { | 306 | { |
333 | u8 acquired = FALSE; | 307 | u8 acquired = FALSE; |
334 | acpi_status status; | ||
335 | 308 | ||
336 | /* | 309 | /* |
337 | * Attempt to get the lock | 310 | * Attempt to get the lock. |
311 | * | ||
338 | * If we don't get it now, it will be marked pending and we will | 312 | * If we don't get it now, it will be marked pending and we will |
339 | * take another interrupt when it becomes free. | 313 | * take another interrupt when it becomes free. |
340 | */ | 314 | */ |
341 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); | 315 | ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired); |
342 | if (acquired) { | 316 | if (acquired) { |
343 | 317 | ||
344 | /* Got the lock, now wake all threads waiting for it */ | 318 | /* Got the lock, now wake all threads waiting for it */ |
319 | |||
345 | acpi_gbl_global_lock_acquired = TRUE; | 320 | acpi_gbl_global_lock_acquired = TRUE; |
346 | acpi_ev_global_lock_thread(context); | 321 | /* Send a unit to the semaphore */ |
322 | |||
323 | if (ACPI_FAILURE(acpi_os_signal_semaphore( | ||
324 | acpi_gbl_global_lock_semaphore, 1))) { | ||
325 | ACPI_ERROR((AE_INFO, | ||
326 | "Could not signal Global Lock semaphore")); | ||
327 | } | ||
347 | } | 328 | } |
348 | 329 | ||
349 | return (ACPI_INTERRUPT_HANDLED); | 330 | return (ACPI_INTERRUPT_HANDLED); |
@@ -367,6 +348,13 @@ acpi_status acpi_ev_init_global_lock_handler(void) | |||
367 | 348 | ||
368 | ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); | 349 | ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); |
369 | 350 | ||
351 | status = | ||
352 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, | ||
353 | (struct acpi_table_header **)&facs); | ||
354 | if (ACPI_FAILURE(status)) { | ||
355 | return_ACPI_STATUS(status); | ||
356 | } | ||
357 | |||
370 | acpi_gbl_global_lock_present = TRUE; | 358 | acpi_gbl_global_lock_present = TRUE; |
371 | status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, | 359 | status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, |
372 | acpi_ev_global_lock_handler, | 360 | acpi_ev_global_lock_handler, |
@@ -390,6 +378,31 @@ acpi_status acpi_ev_init_global_lock_handler(void) | |||
390 | return_ACPI_STATUS(status); | 378 | return_ACPI_STATUS(status); |
391 | } | 379 | } |
392 | 380 | ||
381 | /******************************************************************************* | ||
382 | * | ||
383 | * FUNCTION: acpi_ev_remove_global_lock_handler | ||
384 | * | ||
385 | * PARAMETERS: None | ||
386 | * | ||
387 | * RETURN: Status | ||
388 | * | ||
389 | * DESCRIPTION: Remove the handler for the Global Lock | ||
390 | * | ||
391 | ******************************************************************************/ | ||
392 | |||
393 | static acpi_status acpi_ev_remove_global_lock_handler(void) | ||
394 | { | ||
395 | acpi_status status; | ||
396 | |||
397 | ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler); | ||
398 | |||
399 | acpi_gbl_global_lock_present = FALSE; | ||
400 | status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL, | ||
401 | acpi_ev_global_lock_handler); | ||
402 | |||
403 | return_ACPI_STATUS(status); | ||
404 | } | ||
405 | |||
393 | /****************************************************************************** | 406 | /****************************************************************************** |
394 | * | 407 | * |
395 | * FUNCTION: acpi_ev_acquire_global_lock | 408 | * FUNCTION: acpi_ev_acquire_global_lock |
@@ -400,6 +413,16 @@ acpi_status acpi_ev_init_global_lock_handler(void) | |||
400 | * | 413 | * |
401 | * DESCRIPTION: Attempt to gain ownership of the Global Lock. | 414 | * DESCRIPTION: Attempt to gain ownership of the Global Lock. |
402 | * | 415 | * |
416 | * MUTEX: Interpreter must be locked | ||
417 | * | ||
418 | * Note: The original implementation allowed multiple threads to "acquire" the | ||
419 | * Global Lock, and the OS would hold the lock until the last thread had | ||
420 | * released it. However, this could potentially starve the BIOS out of the | ||
421 | * lock, especially in the case where there is a tight handshake between the | ||
422 | * Embedded Controller driver and the BIOS. Therefore, this implementation | ||
423 | * allows only one thread to acquire the HW Global Lock at a time, and makes | ||
424 | * the global lock appear as a standard mutex on the OS side. | ||
425 | * | ||
403 | *****************************************************************************/ | 426 | *****************************************************************************/ |
404 | 427 | ||
405 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) | 428 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) |
@@ -409,53 +432,51 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
409 | 432 | ||
410 | ACPI_FUNCTION_TRACE(ev_acquire_global_lock); | 433 | ACPI_FUNCTION_TRACE(ev_acquire_global_lock); |
411 | 434 | ||
412 | #ifndef ACPI_APPLICATION | 435 | /* |
413 | /* Make sure that we actually have a global lock */ | 436 | * Only one thread can acquire the GL at a time, the global_lock_mutex |
414 | 437 | * enforces this. This interface releases the interpreter if we must wait. | |
415 | if (!acpi_gbl_global_lock_present) { | 438 | */ |
416 | return_ACPI_STATUS(AE_NO_GLOBAL_LOCK); | 439 | status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout); |
440 | if (ACPI_FAILURE(status)) { | ||
441 | return_ACPI_STATUS(status); | ||
417 | } | 442 | } |
418 | #endif | ||
419 | |||
420 | /* One more thread wants the global lock */ | ||
421 | |||
422 | acpi_gbl_global_lock_thread_count++; | ||
423 | 443 | ||
424 | /* | 444 | /* |
425 | * If we (OS side vs. BIOS side) have the hardware lock already, | 445 | * Make sure that a global lock actually exists. If not, just treat |
426 | * we are done | 446 | * the lock as a standard mutex. |
427 | */ | 447 | */ |
428 | if (acpi_gbl_global_lock_acquired) { | 448 | if (!acpi_gbl_global_lock_present) { |
449 | acpi_gbl_global_lock_acquired = TRUE; | ||
429 | return_ACPI_STATUS(AE_OK); | 450 | return_ACPI_STATUS(AE_OK); |
430 | } | 451 | } |
431 | 452 | ||
432 | /* We must acquire the actual hardware lock */ | 453 | /* Attempt to acquire the actual hardware lock */ |
433 | 454 | ||
434 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); | 455 | ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired); |
435 | if (acquired) { | 456 | if (acquired) { |
436 | 457 | ||
437 | /* We got the lock */ | 458 | /* We got the lock */ |
438 | 459 | ||
439 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 460 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
440 | "Acquired the HW Global Lock\n")); | 461 | "Acquired hardware Global Lock\n")); |
441 | 462 | ||
442 | acpi_gbl_global_lock_acquired = TRUE; | 463 | acpi_gbl_global_lock_acquired = TRUE; |
443 | return_ACPI_STATUS(AE_OK); | 464 | return_ACPI_STATUS(AE_OK); |
444 | } | 465 | } |
445 | 466 | ||
446 | /* | 467 | /* |
447 | * Did not get the lock. The pending bit was set above, and we must now | 468 | * Did not get the lock. The pending bit was set above, and we must now |
448 | * wait until we get the global lock released interrupt. | 469 | * wait until we get the global lock released interrupt. |
449 | */ | 470 | */ |
450 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n")); | 471 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); |
451 | 472 | ||
452 | /* | 473 | /* |
453 | * Acquire the global lock semaphore first. | 474 | * Wait for handshake with the global lock interrupt handler. |
454 | * Since this wait will block, we must release the interpreter | 475 | * This interface releases the interpreter if we must wait. |
455 | */ | 476 | */ |
456 | status = | 477 | status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, |
457 | acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, | 478 | ACPI_WAIT_FOREVER); |
458 | timeout); | 479 | |
459 | return_ACPI_STATUS(status); | 480 | return_ACPI_STATUS(status); |
460 | } | 481 | } |
461 | 482 | ||
@@ -478,38 +499,39 @@ acpi_status acpi_ev_release_global_lock(void) | |||
478 | 499 | ||
479 | ACPI_FUNCTION_TRACE(ev_release_global_lock); | 500 | ACPI_FUNCTION_TRACE(ev_release_global_lock); |
480 | 501 | ||
481 | if (!acpi_gbl_global_lock_thread_count) { | 502 | /* Lock must be already acquired */ |
503 | |||
504 | if (!acpi_gbl_global_lock_acquired) { | ||
482 | ACPI_WARNING((AE_INFO, | 505 | ACPI_WARNING((AE_INFO, |
483 | "Cannot release HW Global Lock, it has not been acquired")); | 506 | "Cannot release the ACPI Global Lock, it has not been acquired")); |
484 | return_ACPI_STATUS(AE_NOT_ACQUIRED); | 507 | return_ACPI_STATUS(AE_NOT_ACQUIRED); |
485 | } | 508 | } |
486 | 509 | ||
487 | /* One fewer thread has the global lock */ | 510 | if (acpi_gbl_global_lock_present) { |
488 | 511 | ||
489 | acpi_gbl_global_lock_thread_count--; | 512 | /* Allow any thread to release the lock */ |
490 | if (acpi_gbl_global_lock_thread_count) { | ||
491 | 513 | ||
492 | /* There are still some threads holding the lock, cannot release */ | 514 | ACPI_RELEASE_GLOBAL_LOCK(facs, pending); |
493 | 515 | ||
494 | return_ACPI_STATUS(AE_OK); | 516 | /* |
517 | * If the pending bit was set, we must write GBL_RLS to the control | ||
518 | * register | ||
519 | */ | ||
520 | if (pending) { | ||
521 | status = | ||
522 | acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE, | ||
523 | 1); | ||
524 | } | ||
525 | |||
526 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
527 | "Released hardware Global Lock\n")); | ||
495 | } | 528 | } |
496 | 529 | ||
497 | /* | ||
498 | * No more threads holding lock, we can do the actual hardware | ||
499 | * release | ||
500 | */ | ||
501 | ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, pending); | ||
502 | acpi_gbl_global_lock_acquired = FALSE; | 530 | acpi_gbl_global_lock_acquired = FALSE; |
503 | 531 | ||
504 | /* | 532 | /* Release the local GL mutex */ |
505 | * If the pending bit was set, we must write GBL_RLS to the control | ||
506 | * register | ||
507 | */ | ||
508 | if (pending) { | ||
509 | status = acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE, | ||
510 | 1, ACPI_MTX_LOCK); | ||
511 | } | ||
512 | 533 | ||
534 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex); | ||
513 | return_ACPI_STATUS(status); | 535 | return_ACPI_STATUS(status); |
514 | } | 536 | } |
515 | 537 | ||
@@ -559,6 +581,12 @@ void acpi_ev_terminate(void) | |||
559 | if (ACPI_FAILURE(status)) { | 581 | if (ACPI_FAILURE(status)) { |
560 | ACPI_ERROR((AE_INFO, "Could not remove SCI handler")); | 582 | ACPI_ERROR((AE_INFO, "Could not remove SCI handler")); |
561 | } | 583 | } |
584 | |||
585 | status = acpi_ev_remove_global_lock_handler(); | ||
586 | if (ACPI_FAILURE(status)) { | ||
587 | ACPI_ERROR((AE_INFO, | ||
588 | "Could not remove Global Lock handler")); | ||
589 | } | ||
562 | } | 590 | } |
563 | 591 | ||
564 | /* Deallocate all handler objects installed within GPE info structs */ | 592 | /* Deallocate all handler objects installed within GPE info structs */ |
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index 21caae04fe85..e99f0c435a47 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -291,7 +291,6 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
291 | u32 bit_width, acpi_integer * value) | 291 | u32 bit_width, acpi_integer * value) |
292 | { | 292 | { |
293 | acpi_status status; | 293 | acpi_status status; |
294 | acpi_status status2; | ||
295 | acpi_adr_space_handler handler; | 294 | acpi_adr_space_handler handler; |
296 | acpi_adr_space_setup region_setup; | 295 | acpi_adr_space_setup region_setup; |
297 | union acpi_operand_object *handler_desc; | 296 | union acpi_operand_object *handler_desc; |
@@ -345,7 +344,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
345 | * setup will potentially execute control methods | 344 | * setup will potentially execute control methods |
346 | * (e.g., _REG method for this region) | 345 | * (e.g., _REG method for this region) |
347 | */ | 346 | */ |
348 | acpi_ex_exit_interpreter(); | 347 | acpi_ex_relinquish_interpreter(); |
349 | 348 | ||
350 | status = region_setup(region_obj, ACPI_REGION_ACTIVATE, | 349 | status = region_setup(region_obj, ACPI_REGION_ACTIVATE, |
351 | handler_desc->address_space.context, | 350 | handler_desc->address_space.context, |
@@ -353,10 +352,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
353 | 352 | ||
354 | /* Re-enter the interpreter */ | 353 | /* Re-enter the interpreter */ |
355 | 354 | ||
356 | status2 = acpi_ex_enter_interpreter(); | 355 | acpi_ex_reacquire_interpreter(); |
357 | if (ACPI_FAILURE(status2)) { | ||
358 | return_ACPI_STATUS(status2); | ||
359 | } | ||
360 | 356 | ||
361 | /* Check for failure of the Region Setup */ | 357 | /* Check for failure of the Region Setup */ |
362 | 358 | ||
@@ -409,7 +405,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
409 | * exit the interpreter because the handler *might* block -- we don't | 405 | * exit the interpreter because the handler *might* block -- we don't |
410 | * know what it will do, so we can't hold the lock on the intepreter. | 406 | * know what it will do, so we can't hold the lock on the intepreter. |
411 | */ | 407 | */ |
412 | acpi_ex_exit_interpreter(); | 408 | acpi_ex_relinquish_interpreter(); |
413 | } | 409 | } |
414 | 410 | ||
415 | /* Call the handler */ | 411 | /* Call the handler */ |
@@ -430,10 +426,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
430 | * We just returned from a non-default handler, we must re-enter the | 426 | * We just returned from a non-default handler, we must re-enter the |
431 | * interpreter | 427 | * interpreter |
432 | */ | 428 | */ |
433 | status2 = acpi_ex_enter_interpreter(); | 429 | acpi_ex_reacquire_interpreter(); |
434 | if (ACPI_FAILURE(status2)) { | ||
435 | return_ACPI_STATUS(status2); | ||
436 | } | ||
437 | } | 430 | } |
438 | 431 | ||
439 | return_ACPI_STATUS(status); | 432 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index 203d1359190a..a4fa7e6822a3 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -48,6 +48,11 @@ | |||
48 | #define _COMPONENT ACPI_EVENTS | 48 | #define _COMPONENT ACPI_EVENTS |
49 | ACPI_MODULE_NAME("evrgnini") | 49 | ACPI_MODULE_NAME("evrgnini") |
50 | 50 | ||
51 | /* Local prototypes */ | ||
52 | static u8 acpi_ev_match_pci_root_bridge(char *id); | ||
53 | |||
54 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); | ||
55 | |||
51 | /******************************************************************************* | 56 | /******************************************************************************* |
52 | * | 57 | * |
53 | * FUNCTION: acpi_ev_system_memory_region_setup | 58 | * FUNCTION: acpi_ev_system_memory_region_setup |
@@ -62,6 +67,7 @@ ACPI_MODULE_NAME("evrgnini") | |||
62 | * DESCRIPTION: Setup a system_memory operation region | 67 | * DESCRIPTION: Setup a system_memory operation region |
63 | * | 68 | * |
64 | ******************************************************************************/ | 69 | ******************************************************************************/ |
70 | |||
65 | acpi_status | 71 | acpi_status |
66 | acpi_ev_system_memory_region_setup(acpi_handle handle, | 72 | acpi_ev_system_memory_region_setup(acpi_handle handle, |
67 | u32 function, | 73 | u32 function, |
@@ -168,9 +174,9 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
168 | union acpi_operand_object *handler_obj; | 174 | union acpi_operand_object *handler_obj; |
169 | struct acpi_namespace_node *parent_node; | 175 | struct acpi_namespace_node *parent_node; |
170 | struct acpi_namespace_node *pci_root_node; | 176 | struct acpi_namespace_node *pci_root_node; |
177 | struct acpi_namespace_node *pci_device_node; | ||
171 | union acpi_operand_object *region_obj = | 178 | union acpi_operand_object *region_obj = |
172 | (union acpi_operand_object *)handle; | 179 | (union acpi_operand_object *)handle; |
173 | struct acpi_device_id object_hID; | ||
174 | 180 | ||
175 | ACPI_FUNCTION_TRACE(ev_pci_config_region_setup); | 181 | ACPI_FUNCTION_TRACE(ev_pci_config_region_setup); |
176 | 182 | ||
@@ -215,45 +221,30 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
215 | 221 | ||
216 | pci_root_node = parent_node; | 222 | pci_root_node = parent_node; |
217 | while (pci_root_node != acpi_gbl_root_node) { | 223 | while (pci_root_node != acpi_gbl_root_node) { |
218 | status = | ||
219 | acpi_ut_execute_HID(pci_root_node, &object_hID); | ||
220 | if (ACPI_SUCCESS(status)) { | ||
221 | /* | ||
222 | * Got a valid _HID string, check if this is a PCI root. | ||
223 | * New for ACPI 3.0: check for a PCI Express root also. | ||
224 | */ | ||
225 | if (! | ||
226 | (ACPI_STRNCMP | ||
227 | (object_hID.value, PCI_ROOT_HID_STRING, | ||
228 | sizeof(PCI_ROOT_HID_STRING))) | ||
229 | || | ||
230 | !(ACPI_STRNCMP | ||
231 | (object_hID.value, | ||
232 | PCI_EXPRESS_ROOT_HID_STRING, | ||
233 | sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { | ||
234 | |||
235 | /* Install a handler for this PCI root bridge */ | ||
236 | 224 | ||
237 | status = | 225 | /* Get the _HID/_CID in order to detect a root_bridge */ |
238 | acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); | 226 | |
239 | if (ACPI_FAILURE(status)) { | 227 | if (acpi_ev_is_pci_root_bridge(pci_root_node)) { |
240 | if (status == AE_SAME_HANDLER) { | 228 | |
241 | /* | 229 | /* Install a handler for this PCI root bridge */ |
242 | * It is OK if the handler is already installed on the root | 230 | |
243 | * bridge. Still need to return a context object for the | 231 | status = acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); |
244 | * new PCI_Config operation region, however. | 232 | if (ACPI_FAILURE(status)) { |
245 | */ | 233 | if (status == AE_SAME_HANDLER) { |
246 | status = AE_OK; | 234 | /* |
247 | } else { | 235 | * It is OK if the handler is already installed on the root |
248 | ACPI_EXCEPTION((AE_INFO, | 236 | * bridge. Still need to return a context object for the |
249 | status, | 237 | * new PCI_Config operation region, however. |
250 | "Could not install PciConfig handler for Root Bridge %4.4s", | 238 | */ |
251 | acpi_ut_get_node_name | 239 | status = AE_OK; |
252 | (pci_root_node))); | 240 | } else { |
253 | } | 241 | ACPI_EXCEPTION((AE_INFO, status, |
242 | "Could not install PciConfig handler for Root Bridge %4.4s", | ||
243 | acpi_ut_get_node_name | ||
244 | (pci_root_node))); | ||
254 | } | 245 | } |
255 | break; | ||
256 | } | 246 | } |
247 | break; | ||
257 | } | 248 | } |
258 | 249 | ||
259 | pci_root_node = acpi_ns_get_parent_node(pci_root_node); | 250 | pci_root_node = acpi_ns_get_parent_node(pci_root_node); |
@@ -282,14 +273,25 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
282 | /* | 273 | /* |
283 | * For PCI_Config space access, we need the segment, bus, | 274 | * For PCI_Config space access, we need the segment, bus, |
284 | * device and function numbers. Acquire them here. | 275 | * device and function numbers. Acquire them here. |
276 | * | ||
277 | * Find the parent device object. (This allows the operation region to be | ||
278 | * within a subscope under the device, such as a control method.) | ||
285 | */ | 279 | */ |
280 | pci_device_node = region_obj->region.node; | ||
281 | while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) { | ||
282 | pci_device_node = acpi_ns_get_parent_node(pci_device_node); | ||
283 | } | ||
284 | |||
285 | if (!pci_device_node) { | ||
286 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | ||
287 | } | ||
286 | 288 | ||
287 | /* | 289 | /* |
288 | * Get the PCI device and function numbers from the _ADR object | 290 | * Get the PCI device and function numbers from the _ADR object |
289 | * contained in the parent's scope. | 291 | * contained in the parent's scope. |
290 | */ | 292 | */ |
291 | status = | 293 | status = |
292 | acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, parent_node, | 294 | acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node, |
293 | &pci_value); | 295 | &pci_value); |
294 | 296 | ||
295 | /* | 297 | /* |
@@ -329,6 +331,91 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
329 | 331 | ||
330 | /******************************************************************************* | 332 | /******************************************************************************* |
331 | * | 333 | * |
334 | * FUNCTION: acpi_ev_match_pci_root_bridge | ||
335 | * | ||
336 | * PARAMETERS: Id - The HID/CID in string format | ||
337 | * | ||
338 | * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge | ||
339 | * | ||
340 | * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. | ||
341 | * | ||
342 | ******************************************************************************/ | ||
343 | |||
344 | static u8 acpi_ev_match_pci_root_bridge(char *id) | ||
345 | { | ||
346 | |||
347 | /* | ||
348 | * Check if this is a PCI root. | ||
349 | * ACPI 3.0+: check for a PCI Express root also. | ||
350 | */ | ||
351 | if (!(ACPI_STRNCMP(id, | ||
352 | PCI_ROOT_HID_STRING, | ||
353 | sizeof(PCI_ROOT_HID_STRING))) || | ||
354 | !(ACPI_STRNCMP(id, | ||
355 | PCI_EXPRESS_ROOT_HID_STRING, | ||
356 | sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { | ||
357 | return (TRUE); | ||
358 | } | ||
359 | |||
360 | return (FALSE); | ||
361 | } | ||
362 | |||
363 | /******************************************************************************* | ||
364 | * | ||
365 | * FUNCTION: acpi_ev_is_pci_root_bridge | ||
366 | * | ||
367 | * PARAMETERS: Node - Device node being examined | ||
368 | * | ||
369 | * RETURN: TRUE if device is a PCI/PCI-Express Root Bridge | ||
370 | * | ||
371 | * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by | ||
372 | * examining the _HID and _CID for the device. | ||
373 | * | ||
374 | ******************************************************************************/ | ||
375 | |||
376 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) | ||
377 | { | ||
378 | acpi_status status; | ||
379 | struct acpi_device_id hid; | ||
380 | struct acpi_compatible_id_list *cid; | ||
381 | acpi_native_uint i; | ||
382 | |||
383 | /* | ||
384 | * Get the _HID and check for a PCI Root Bridge | ||
385 | */ | ||
386 | status = acpi_ut_execute_HID(node, &hid); | ||
387 | if (ACPI_FAILURE(status)) { | ||
388 | return (FALSE); | ||
389 | } | ||
390 | |||
391 | if (acpi_ev_match_pci_root_bridge(hid.value)) { | ||
392 | return (TRUE); | ||
393 | } | ||
394 | |||
395 | /* | ||
396 | * The _HID did not match. | ||
397 | * Get the _CID and check for a PCI Root Bridge | ||
398 | */ | ||
399 | status = acpi_ut_execute_CID(node, &cid); | ||
400 | if (ACPI_FAILURE(status)) { | ||
401 | return (FALSE); | ||
402 | } | ||
403 | |||
404 | /* Check all _CIDs in the returned list */ | ||
405 | |||
406 | for (i = 0; i < cid->count; i++) { | ||
407 | if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) { | ||
408 | ACPI_FREE(cid); | ||
409 | return (TRUE); | ||
410 | } | ||
411 | } | ||
412 | |||
413 | ACPI_FREE(cid); | ||
414 | return (FALSE); | ||
415 | } | ||
416 | |||
417 | /******************************************************************************* | ||
418 | * | ||
332 | * FUNCTION: acpi_ev_pci_bar_region_setup | 419 | * FUNCTION: acpi_ev_pci_bar_region_setup |
333 | * | 420 | * |
334 | * PARAMETERS: Handle - Region we are interested in | 421 | * PARAMETERS: Handle - Region we are interested in |
@@ -432,6 +519,9 @@ acpi_ev_default_region_setup(acpi_handle handle, | |||
432 | * a PCI address in the scope of the definition. This address is | 519 | * a PCI address in the scope of the definition. This address is |
433 | * required to perform an access to PCI config space. | 520 | * required to perform an access to PCI config space. |
434 | * | 521 | * |
522 | * MUTEX: Interpreter should be unlocked, because we may run the _REG | ||
523 | * method for this region. | ||
524 | * | ||
435 | ******************************************************************************/ | 525 | ******************************************************************************/ |
436 | 526 | ||
437 | acpi_status | 527 | acpi_status |
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c index 8106215ad554..7e5d15ce2395 100644 --- a/drivers/acpi/events/evsci.c +++ b/drivers/acpi/events/evsci.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -142,9 +142,10 @@ u32 acpi_ev_install_sci_handler(void) | |||
142 | 142 | ||
143 | ACPI_FUNCTION_TRACE(ev_install_sci_handler); | 143 | ACPI_FUNCTION_TRACE(ev_install_sci_handler); |
144 | 144 | ||
145 | status = acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT->sci_int, | 145 | status = |
146 | acpi_ev_sci_xrupt_handler, | 146 | acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, |
147 | acpi_gbl_gpe_xrupt_list_head); | 147 | acpi_ev_sci_xrupt_handler, |
148 | acpi_gbl_gpe_xrupt_list_head); | ||
148 | return_ACPI_STATUS(status); | 149 | return_ACPI_STATUS(status); |
149 | } | 150 | } |
150 | 151 | ||
@@ -175,8 +176,9 @@ acpi_status acpi_ev_remove_sci_handler(void) | |||
175 | 176 | ||
176 | /* Just let the OS remove the handler and disable the level */ | 177 | /* Just let the OS remove the handler and disable the level */ |
177 | 178 | ||
178 | status = acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT->sci_int, | 179 | status = |
179 | acpi_ev_sci_xrupt_handler); | 180 | acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, |
181 | acpi_ev_sci_xrupt_handler); | ||
180 | 182 | ||
181 | return_ACPI_STATUS(status); | 183 | return_ACPI_STATUS(status); |
182 | } | 184 | } |
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c index 923fd2b46955..685a103a3587 100644 --- a/drivers/acpi/events/evxface.c +++ b/drivers/acpi/events/evxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -768,11 +768,9 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) | |||
768 | return (AE_BAD_PARAMETER); | 768 | return (AE_BAD_PARAMETER); |
769 | } | 769 | } |
770 | 770 | ||
771 | status = acpi_ex_enter_interpreter(); | 771 | /* Must lock interpreter to prevent race conditions */ |
772 | if (ACPI_FAILURE(status)) { | ||
773 | return (status); | ||
774 | } | ||
775 | 772 | ||
773 | acpi_ex_enter_interpreter(); | ||
776 | status = acpi_ev_acquire_global_lock(timeout); | 774 | status = acpi_ev_acquire_global_lock(timeout); |
777 | acpi_ex_exit_interpreter(); | 775 | acpi_ex_exit_interpreter(); |
778 | 776 | ||
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 7ebc2efac936..17065e98807c 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -44,6 +44,7 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acevents.h> | 45 | #include <acpi/acevents.h> |
46 | #include <acpi/acnamesp.h> | 46 | #include <acpi/acnamesp.h> |
47 | #include <acpi/actables.h> | ||
47 | 48 | ||
48 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
49 | ACPI_MODULE_NAME("evxfevnt") | 50 | ACPI_MODULE_NAME("evxfevnt") |
@@ -65,13 +66,14 @@ acpi_status acpi_enable(void) | |||
65 | 66 | ||
66 | ACPI_FUNCTION_TRACE(acpi_enable); | 67 | ACPI_FUNCTION_TRACE(acpi_enable); |
67 | 68 | ||
68 | /* Make sure we have the FADT */ | 69 | /* ACPI tables must be present */ |
69 | 70 | ||
70 | if (!acpi_gbl_FADT) { | 71 | if (!acpi_tb_tables_loaded()) { |
71 | ACPI_WARNING((AE_INFO, "No FADT information present!")); | ||
72 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | 72 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); |
73 | } | 73 | } |
74 | 74 | ||
75 | /* Check current mode */ | ||
76 | |||
75 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { | 77 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { |
76 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 78 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
77 | "System is already in ACPI mode\n")); | 79 | "System is already in ACPI mode\n")); |
@@ -111,11 +113,6 @@ acpi_status acpi_disable(void) | |||
111 | 113 | ||
112 | ACPI_FUNCTION_TRACE(acpi_disable); | 114 | ACPI_FUNCTION_TRACE(acpi_disable); |
113 | 115 | ||
114 | if (!acpi_gbl_FADT) { | ||
115 | ACPI_WARNING((AE_INFO, "No FADT information present!")); | ||
116 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
117 | } | ||
118 | |||
119 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { | 116 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { |
120 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 117 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
121 | "System is already in legacy (non-ACPI) mode\n")); | 118 | "System is already in legacy (non-ACPI) mode\n")); |
@@ -169,7 +166,7 @@ acpi_status acpi_enable_event(u32 event, u32 flags) | |||
169 | */ | 166 | */ |
170 | status = | 167 | status = |
171 | acpi_set_register(acpi_gbl_fixed_event_info[event]. | 168 | acpi_set_register(acpi_gbl_fixed_event_info[event]. |
172 | enable_register_id, 1, ACPI_MTX_LOCK); | 169 | enable_register_id, 1); |
173 | if (ACPI_FAILURE(status)) { | 170 | if (ACPI_FAILURE(status)) { |
174 | return_ACPI_STATUS(status); | 171 | return_ACPI_STATUS(status); |
175 | } | 172 | } |
@@ -178,7 +175,7 @@ acpi_status acpi_enable_event(u32 event, u32 flags) | |||
178 | 175 | ||
179 | status = | 176 | status = |
180 | acpi_get_register(acpi_gbl_fixed_event_info[event]. | 177 | acpi_get_register(acpi_gbl_fixed_event_info[event]. |
181 | enable_register_id, &value, ACPI_MTX_LOCK); | 178 | enable_register_id, &value); |
182 | if (ACPI_FAILURE(status)) { | 179 | if (ACPI_FAILURE(status)) { |
183 | return_ACPI_STATUS(status); | 180 | return_ACPI_STATUS(status); |
184 | } | 181 | } |
@@ -368,14 +365,14 @@ acpi_status acpi_disable_event(u32 event, u32 flags) | |||
368 | */ | 365 | */ |
369 | status = | 366 | status = |
370 | acpi_set_register(acpi_gbl_fixed_event_info[event]. | 367 | acpi_set_register(acpi_gbl_fixed_event_info[event]. |
371 | enable_register_id, 0, ACPI_MTX_LOCK); | 368 | enable_register_id, 0); |
372 | if (ACPI_FAILURE(status)) { | 369 | if (ACPI_FAILURE(status)) { |
373 | return_ACPI_STATUS(status); | 370 | return_ACPI_STATUS(status); |
374 | } | 371 | } |
375 | 372 | ||
376 | status = | 373 | status = |
377 | acpi_get_register(acpi_gbl_fixed_event_info[event]. | 374 | acpi_get_register(acpi_gbl_fixed_event_info[event]. |
378 | enable_register_id, &value, ACPI_MTX_LOCK); | 375 | enable_register_id, &value); |
379 | if (ACPI_FAILURE(status)) { | 376 | if (ACPI_FAILURE(status)) { |
380 | return_ACPI_STATUS(status); | 377 | return_ACPI_STATUS(status); |
381 | } | 378 | } |
@@ -421,7 +418,7 @@ acpi_status acpi_clear_event(u32 event) | |||
421 | */ | 418 | */ |
422 | status = | 419 | status = |
423 | acpi_set_register(acpi_gbl_fixed_event_info[event]. | 420 | acpi_set_register(acpi_gbl_fixed_event_info[event]. |
424 | status_register_id, 1, ACPI_MTX_LOCK); | 421 | status_register_id, 1); |
425 | 422 | ||
426 | return_ACPI_STATUS(status); | 423 | return_ACPI_STATUS(status); |
427 | } | 424 | } |
@@ -510,7 +507,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) | |||
510 | 507 | ||
511 | status = | 508 | status = |
512 | acpi_get_register(acpi_gbl_fixed_event_info[event]. | 509 | acpi_get_register(acpi_gbl_fixed_event_info[event]. |
513 | status_register_id, event_status, ACPI_MTX_LOCK); | 510 | status_register_id, event_status); |
514 | 511 | ||
515 | return_ACPI_STATUS(status); | 512 | return_ACPI_STATUS(status); |
516 | } | 513 | } |
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c index 83b12a9afa32..7bf09c5fb242 100644 --- a/drivers/acpi/events/evxfregn.c +++ b/drivers/acpi/events/evxfregn.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index c8341fa5fe01..25802f302ffe 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -54,7 +54,7 @@ ACPI_MODULE_NAME("exconfig") | |||
54 | 54 | ||
55 | /* Local prototypes */ | 55 | /* Local prototypes */ |
56 | static acpi_status | 56 | static acpi_status |
57 | acpi_ex_add_table(struct acpi_table_header *table, | 57 | acpi_ex_add_table(acpi_native_uint table_index, |
58 | struct acpi_namespace_node *parent_node, | 58 | struct acpi_namespace_node *parent_node, |
59 | union acpi_operand_object **ddb_handle); | 59 | union acpi_operand_object **ddb_handle); |
60 | 60 | ||
@@ -74,12 +74,11 @@ acpi_ex_add_table(struct acpi_table_header *table, | |||
74 | ******************************************************************************/ | 74 | ******************************************************************************/ |
75 | 75 | ||
76 | static acpi_status | 76 | static acpi_status |
77 | acpi_ex_add_table(struct acpi_table_header *table, | 77 | acpi_ex_add_table(acpi_native_uint table_index, |
78 | struct acpi_namespace_node *parent_node, | 78 | struct acpi_namespace_node *parent_node, |
79 | union acpi_operand_object **ddb_handle) | 79 | union acpi_operand_object **ddb_handle) |
80 | { | 80 | { |
81 | acpi_status status; | 81 | acpi_status status; |
82 | struct acpi_table_desc table_info; | ||
83 | union acpi_operand_object *obj_desc; | 82 | union acpi_operand_object *obj_desc; |
84 | 83 | ||
85 | ACPI_FUNCTION_TRACE(ex_add_table); | 84 | ACPI_FUNCTION_TRACE(ex_add_table); |
@@ -98,42 +97,16 @@ acpi_ex_add_table(struct acpi_table_header *table, | |||
98 | 97 | ||
99 | /* Install the new table into the local data structures */ | 98 | /* Install the new table into the local data structures */ |
100 | 99 | ||
101 | ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc)); | 100 | obj_desc->reference.object = ACPI_CAST_PTR(void, table_index); |
102 | |||
103 | table_info.type = ACPI_TABLE_ID_SSDT; | ||
104 | table_info.pointer = table; | ||
105 | table_info.length = (acpi_size) table->length; | ||
106 | table_info.allocation = ACPI_MEM_ALLOCATED; | ||
107 | |||
108 | status = acpi_tb_install_table(&table_info); | ||
109 | obj_desc->reference.object = table_info.installed_desc; | ||
110 | |||
111 | if (ACPI_FAILURE(status)) { | ||
112 | if (status == AE_ALREADY_EXISTS) { | ||
113 | |||
114 | /* Table already exists, just return the handle */ | ||
115 | |||
116 | return_ACPI_STATUS(AE_OK); | ||
117 | } | ||
118 | goto cleanup; | ||
119 | } | ||
120 | 101 | ||
121 | /* Add the table to the namespace */ | 102 | /* Add the table to the namespace */ |
122 | 103 | ||
123 | status = acpi_ns_load_table(table_info.installed_desc, parent_node); | 104 | status = acpi_ns_load_table(table_index, parent_node); |
124 | if (ACPI_FAILURE(status)) { | 105 | if (ACPI_FAILURE(status)) { |
125 | 106 | acpi_ut_remove_reference(obj_desc); | |
126 | /* Uninstall table on error */ | 107 | *ddb_handle = NULL; |
127 | |||
128 | (void)acpi_tb_uninstall_table(table_info.installed_desc); | ||
129 | goto cleanup; | ||
130 | } | 108 | } |
131 | 109 | ||
132 | return_ACPI_STATUS(AE_OK); | ||
133 | |||
134 | cleanup: | ||
135 | acpi_ut_remove_reference(obj_desc); | ||
136 | *ddb_handle = NULL; | ||
137 | return_ACPI_STATUS(status); | 110 | return_ACPI_STATUS(status); |
138 | } | 111 | } |
139 | 112 | ||
@@ -146,7 +119,7 @@ acpi_ex_add_table(struct acpi_table_header *table, | |||
146 | * | 119 | * |
147 | * RETURN: Status | 120 | * RETURN: Status |
148 | * | 121 | * |
149 | * DESCRIPTION: Load an ACPI table | 122 | * DESCRIPTION: Load an ACPI table from the RSDT/XSDT |
150 | * | 123 | * |
151 | ******************************************************************************/ | 124 | ******************************************************************************/ |
152 | 125 | ||
@@ -156,33 +129,20 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
156 | { | 129 | { |
157 | acpi_status status; | 130 | acpi_status status; |
158 | union acpi_operand_object **operand = &walk_state->operands[0]; | 131 | union acpi_operand_object **operand = &walk_state->operands[0]; |
159 | struct acpi_table_header *table; | 132 | acpi_native_uint table_index; |
160 | struct acpi_namespace_node *parent_node; | 133 | struct acpi_namespace_node *parent_node; |
161 | struct acpi_namespace_node *start_node; | 134 | struct acpi_namespace_node *start_node; |
162 | struct acpi_namespace_node *parameter_node = NULL; | 135 | struct acpi_namespace_node *parameter_node = NULL; |
163 | union acpi_operand_object *ddb_handle; | 136 | union acpi_operand_object *ddb_handle; |
137 | struct acpi_table_header *table; | ||
164 | 138 | ||
165 | ACPI_FUNCTION_TRACE(ex_load_table_op); | 139 | ACPI_FUNCTION_TRACE(ex_load_table_op); |
166 | 140 | ||
167 | #if 0 | 141 | /* Find the ACPI table in the RSDT/XSDT */ |
168 | /* | ||
169 | * Make sure that the signature does not match one of the tables that | ||
170 | * is already loaded. | ||
171 | */ | ||
172 | status = acpi_tb_match_signature(operand[0]->string.pointer, NULL); | ||
173 | if (status == AE_OK) { | ||
174 | |||
175 | /* Signature matched -- don't allow override */ | ||
176 | |||
177 | return_ACPI_STATUS(AE_ALREADY_EXISTS); | ||
178 | } | ||
179 | #endif | ||
180 | |||
181 | /* Find the ACPI table */ | ||
182 | 142 | ||
183 | status = acpi_tb_find_table(operand[0]->string.pointer, | 143 | status = acpi_tb_find_table(operand[0]->string.pointer, |
184 | operand[1]->string.pointer, | 144 | operand[1]->string.pointer, |
185 | operand[2]->string.pointer, &table); | 145 | operand[2]->string.pointer, &table_index); |
186 | if (ACPI_FAILURE(status)) { | 146 | if (ACPI_FAILURE(status)) { |
187 | if (status != AE_NOT_FOUND) { | 147 | if (status != AE_NOT_FOUND) { |
188 | return_ACPI_STATUS(status); | 148 | return_ACPI_STATUS(status); |
@@ -245,7 +205,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
245 | 205 | ||
246 | /* Load the table into the namespace */ | 206 | /* Load the table into the namespace */ |
247 | 207 | ||
248 | status = acpi_ex_add_table(table, parent_node, &ddb_handle); | 208 | status = acpi_ex_add_table(table_index, parent_node, &ddb_handle); |
249 | if (ACPI_FAILURE(status)) { | 209 | if (ACPI_FAILURE(status)) { |
250 | return_ACPI_STATUS(status); | 210 | return_ACPI_STATUS(status); |
251 | } | 211 | } |
@@ -266,9 +226,13 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
266 | } | 226 | } |
267 | } | 227 | } |
268 | 228 | ||
269 | ACPI_INFO((AE_INFO, | 229 | status = acpi_get_table_by_index(table_index, &table); |
270 | "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", | 230 | if (ACPI_SUCCESS(status)) { |
271 | table->signature, table->oem_id, table->oem_table_id)); | 231 | ACPI_INFO((AE_INFO, |
232 | "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", | ||
233 | table->signature, table->oem_id, | ||
234 | table->oem_table_id)); | ||
235 | } | ||
272 | 236 | ||
273 | *return_desc = ddb_handle; | 237 | *return_desc = ddb_handle; |
274 | return_ACPI_STATUS(status); | 238 | return_ACPI_STATUS(status); |
@@ -278,7 +242,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
278 | * | 242 | * |
279 | * FUNCTION: acpi_ex_load_op | 243 | * FUNCTION: acpi_ex_load_op |
280 | * | 244 | * |
281 | * PARAMETERS: obj_desc - Region or Field where the table will be | 245 | * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be |
282 | * obtained | 246 | * obtained |
283 | * Target - Where a handle to the table will be stored | 247 | * Target - Where a handle to the table will be stored |
284 | * walk_state - Current state | 248 | * walk_state - Current state |
@@ -287,6 +251,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
287 | * | 251 | * |
288 | * DESCRIPTION: Load an ACPI table from a field or operation region | 252 | * DESCRIPTION: Load an ACPI table from a field or operation region |
289 | * | 253 | * |
254 | * NOTE: Region Fields (Field, bank_field, index_fields) are resolved to buffer | ||
255 | * objects before this code is reached. | ||
256 | * | ||
257 | * If source is an operation region, it must refer to system_memory, as | ||
258 | * per the ACPI specification. | ||
259 | * | ||
290 | ******************************************************************************/ | 260 | ******************************************************************************/ |
291 | 261 | ||
292 | acpi_status | 262 | acpi_status |
@@ -294,22 +264,26 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
294 | union acpi_operand_object *target, | 264 | union acpi_operand_object *target, |
295 | struct acpi_walk_state *walk_state) | 265 | struct acpi_walk_state *walk_state) |
296 | { | 266 | { |
297 | acpi_status status; | ||
298 | union acpi_operand_object *ddb_handle; | 267 | union acpi_operand_object *ddb_handle; |
299 | union acpi_operand_object *buffer_desc = NULL; | 268 | struct acpi_table_desc table_desc; |
300 | struct acpi_table_header *table_ptr = NULL; | 269 | acpi_native_uint table_index; |
301 | acpi_physical_address address; | 270 | acpi_status status; |
302 | struct acpi_table_header table_header; | ||
303 | acpi_integer temp; | ||
304 | u32 i; | ||
305 | 271 | ||
306 | ACPI_FUNCTION_TRACE(ex_load_op); | 272 | ACPI_FUNCTION_TRACE(ex_load_op); |
307 | 273 | ||
308 | /* Object can be either an op_region or a Field */ | 274 | ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); |
275 | |||
276 | /* Source Object can be either an op_region or a Buffer/Field */ | ||
309 | 277 | ||
310 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 278 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { |
311 | case ACPI_TYPE_REGION: | 279 | case ACPI_TYPE_REGION: |
312 | 280 | ||
281 | /* Region must be system_memory (from ACPI spec) */ | ||
282 | |||
283 | if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { | ||
284 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | ||
285 | } | ||
286 | |||
313 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n", | 287 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n", |
314 | obj_desc, | 288 | obj_desc, |
315 | acpi_ut_get_object_type_name(obj_desc))); | 289 | acpi_ut_get_object_type_name(obj_desc))); |
@@ -325,113 +299,41 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
325 | } | 299 | } |
326 | } | 300 | } |
327 | 301 | ||
328 | /* Get the base physical address of the region */ | 302 | table_desc.address = obj_desc->region.address; |
329 | 303 | table_desc.length = obj_desc->region.length; | |
330 | address = obj_desc->region.address; | 304 | table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; |
331 | |||
332 | /* Get part of the table header to get the table length */ | ||
333 | |||
334 | table_header.length = 0; | ||
335 | for (i = 0; i < 8; i++) { | ||
336 | status = | ||
337 | acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, | ||
338 | (acpi_physical_address) | ||
339 | (i + address), 8, | ||
340 | &temp); | ||
341 | if (ACPI_FAILURE(status)) { | ||
342 | return_ACPI_STATUS(status); | ||
343 | } | ||
344 | |||
345 | /* Get the one valid byte of the returned 64-bit value */ | ||
346 | |||
347 | ACPI_CAST_PTR(u8, &table_header)[i] = (u8) temp; | ||
348 | } | ||
349 | |||
350 | /* Sanity check the table length */ | ||
351 | |||
352 | if (table_header.length < sizeof(struct acpi_table_header)) { | ||
353 | return_ACPI_STATUS(AE_BAD_HEADER); | ||
354 | } | ||
355 | |||
356 | /* Allocate a buffer for the entire table */ | ||
357 | |||
358 | table_ptr = ACPI_ALLOCATE(table_header.length); | ||
359 | if (!table_ptr) { | ||
360 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
361 | } | ||
362 | |||
363 | /* Get the entire table from the op region */ | ||
364 | |||
365 | for (i = 0; i < table_header.length; i++) { | ||
366 | status = | ||
367 | acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, | ||
368 | (acpi_physical_address) | ||
369 | (i + address), 8, | ||
370 | &temp); | ||
371 | if (ACPI_FAILURE(status)) { | ||
372 | goto cleanup; | ||
373 | } | ||
374 | |||
375 | /* Get the one valid byte of the returned 64-bit value */ | ||
376 | |||
377 | ACPI_CAST_PTR(u8, table_ptr)[i] = (u8) temp; | ||
378 | } | ||
379 | break; | 305 | break; |
380 | 306 | ||
381 | case ACPI_TYPE_LOCAL_REGION_FIELD: | 307 | case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ |
382 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
383 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | ||
384 | 308 | ||
385 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Field %p %s\n", | 309 | /* Simply extract the buffer from the buffer object */ |
386 | obj_desc, | ||
387 | acpi_ut_get_object_type_name(obj_desc))); | ||
388 | 310 | ||
389 | /* | 311 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
390 | * The length of the field must be at least as large as the table. | 312 | "Load from Buffer or Field %p %s\n", obj_desc, |
391 | * Read the entire field and thus the entire table. Buffer is | 313 | acpi_ut_get_object_type_name(obj_desc))); |
392 | * allocated during the read. | ||
393 | */ | ||
394 | status = | ||
395 | acpi_ex_read_data_from_field(walk_state, obj_desc, | ||
396 | &buffer_desc); | ||
397 | if (ACPI_FAILURE(status)) { | ||
398 | return_ACPI_STATUS(status); | ||
399 | } | ||
400 | |||
401 | table_ptr = ACPI_CAST_PTR(struct acpi_table_header, | ||
402 | buffer_desc->buffer.pointer); | ||
403 | |||
404 | /* All done with the buffer_desc, delete it */ | ||
405 | |||
406 | buffer_desc->buffer.pointer = NULL; | ||
407 | acpi_ut_remove_reference(buffer_desc); | ||
408 | 314 | ||
409 | /* Sanity check the table length */ | 315 | table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header, |
316 | obj_desc->buffer.pointer); | ||
317 | table_desc.length = table_desc.pointer->length; | ||
318 | table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; | ||
410 | 319 | ||
411 | if (table_ptr->length < sizeof(struct acpi_table_header)) { | 320 | obj_desc->buffer.pointer = NULL; |
412 | status = AE_BAD_HEADER; | ||
413 | goto cleanup; | ||
414 | } | ||
415 | break; | 321 | break; |
416 | 322 | ||
417 | default: | 323 | default: |
418 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 324 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
419 | } | 325 | } |
420 | 326 | ||
421 | /* The table must be either an SSDT or a PSDT */ | 327 | /* |
422 | 328 | * Install the new table into the local data structures | |
423 | if ((!ACPI_COMPARE_NAME(table_ptr->signature, PSDT_SIG)) && | 329 | */ |
424 | (!ACPI_COMPARE_NAME(table_ptr->signature, SSDT_SIG))) { | 330 | status = acpi_tb_add_table(&table_desc, &table_index); |
425 | ACPI_ERROR((AE_INFO, | 331 | if (ACPI_FAILURE(status)) { |
426 | "Table has invalid signature [%4.4s], must be SSDT or PSDT", | ||
427 | table_ptr->signature)); | ||
428 | status = AE_BAD_SIGNATURE; | ||
429 | goto cleanup; | 332 | goto cleanup; |
430 | } | 333 | } |
431 | 334 | ||
432 | /* Install the new table into the local data structures */ | 335 | status = |
433 | 336 | acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); | |
434 | status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle); | ||
435 | if (ACPI_FAILURE(status)) { | 337 | if (ACPI_FAILURE(status)) { |
436 | 338 | ||
437 | /* On error, table_ptr was deallocated above */ | 339 | /* On error, table_ptr was deallocated above */ |
@@ -450,13 +352,9 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
450 | return_ACPI_STATUS(status); | 352 | return_ACPI_STATUS(status); |
451 | } | 353 | } |
452 | 354 | ||
453 | ACPI_INFO((AE_INFO, | ||
454 | "Dynamic SSDT Load - OemId [%6.6s] OemTableId [%8.8s]", | ||
455 | table_ptr->oem_id, table_ptr->oem_table_id)); | ||
456 | |||
457 | cleanup: | 355 | cleanup: |
458 | if (ACPI_FAILURE(status)) { | 356 | if (ACPI_FAILURE(status)) { |
459 | ACPI_FREE(table_ptr); | 357 | acpi_tb_delete_table(&table_desc); |
460 | } | 358 | } |
461 | return_ACPI_STATUS(status); | 359 | return_ACPI_STATUS(status); |
462 | } | 360 | } |
@@ -477,7 +375,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
477 | { | 375 | { |
478 | acpi_status status = AE_OK; | 376 | acpi_status status = AE_OK; |
479 | union acpi_operand_object *table_desc = ddb_handle; | 377 | union acpi_operand_object *table_desc = ddb_handle; |
480 | struct acpi_table_desc *table_info; | 378 | acpi_native_uint table_index; |
481 | 379 | ||
482 | ACPI_FUNCTION_TRACE(ex_unload_table); | 380 | ACPI_FUNCTION_TRACE(ex_unload_table); |
483 | 381 | ||
@@ -493,19 +391,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
493 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 391 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
494 | } | 392 | } |
495 | 393 | ||
496 | /* Get the actual table descriptor from the ddb_handle */ | 394 | /* Get the table index from the ddb_handle */ |
497 | 395 | ||
498 | table_info = (struct acpi_table_desc *)table_desc->reference.object; | 396 | table_index = (acpi_native_uint) table_desc->reference.object; |
499 | 397 | ||
500 | /* | 398 | /* |
501 | * Delete the entire namespace under this table Node | 399 | * Delete the entire namespace under this table Node |
502 | * (Offset contains the table_id) | 400 | * (Offset contains the table_id) |
503 | */ | 401 | */ |
504 | acpi_ns_delete_namespace_by_owner(table_info->owner_id); | 402 | acpi_tb_delete_namespace_by_owner(table_index); |
505 | 403 | acpi_tb_release_owner_id(table_index); | |
506 | /* Delete the table itself */ | ||
507 | 404 | ||
508 | (void)acpi_tb_uninstall_table(table_info->installed_desc); | 405 | acpi_tb_set_table_loaded_flag(table_index, FALSE); |
509 | 406 | ||
510 | /* Delete the table descriptor (ddb_handle) */ | 407 | /* Delete the table descriptor (ddb_handle) */ |
511 | 408 | ||
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c index 544e81a6a438..d470e8b1f4ea 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/executer/exconvrt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c index 34eec82c1b1e..7c38528a7e83 100644 --- a/drivers/acpi/executer/excreate.c +++ b/drivers/acpi/executer/excreate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -359,8 +359,9 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) | |||
359 | union acpi_operand_object **operand = &walk_state->operands[0]; | 359 | union acpi_operand_object **operand = &walk_state->operands[0]; |
360 | union acpi_operand_object *obj_desc; | 360 | union acpi_operand_object *obj_desc; |
361 | struct acpi_namespace_node *node; | 361 | struct acpi_namespace_node *node; |
362 | struct acpi_table_header *table; | ||
363 | union acpi_operand_object *region_obj2; | 362 | union acpi_operand_object *region_obj2; |
363 | acpi_native_uint table_index; | ||
364 | struct acpi_table_header *table; | ||
364 | 365 | ||
365 | ACPI_FUNCTION_TRACE(ex_create_table_region); | 366 | ACPI_FUNCTION_TRACE(ex_create_table_region); |
366 | 367 | ||
@@ -380,7 +381,7 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) | |||
380 | 381 | ||
381 | status = acpi_tb_find_table(operand[1]->string.pointer, | 382 | status = acpi_tb_find_table(operand[1]->string.pointer, |
382 | operand[2]->string.pointer, | 383 | operand[2]->string.pointer, |
383 | operand[3]->string.pointer, &table); | 384 | operand[3]->string.pointer, &table_index); |
384 | if (ACPI_FAILURE(status)) { | 385 | if (ACPI_FAILURE(status)) { |
385 | return_ACPI_STATUS(status); | 386 | return_ACPI_STATUS(status); |
386 | } | 387 | } |
@@ -395,6 +396,11 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) | |||
395 | region_obj2 = obj_desc->common.next_object; | 396 | region_obj2 = obj_desc->common.next_object; |
396 | region_obj2->extra.region_context = NULL; | 397 | region_obj2->extra.region_context = NULL; |
397 | 398 | ||
399 | status = acpi_get_table_by_index(table_index, &table); | ||
400 | if (ACPI_FAILURE(status)) { | ||
401 | return_ACPI_STATUS(status); | ||
402 | } | ||
403 | |||
398 | /* Init the region from the operands */ | 404 | /* Init the region from the operands */ |
399 | 405 | ||
400 | obj_desc->region.space_id = REGION_DATA_TABLE; | 406 | obj_desc->region.space_id = REGION_DATA_TABLE; |
@@ -553,7 +559,8 @@ acpi_ex_create_method(u8 * aml_start, | |||
553 | 559 | ||
554 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); | 560 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); |
555 | if (!obj_desc) { | 561 | if (!obj_desc) { |
556 | return_ACPI_STATUS(AE_NO_MEMORY); | 562 | status = AE_NO_MEMORY; |
563 | goto exit; | ||
557 | } | 564 | } |
558 | 565 | ||
559 | /* Save the method's AML pointer and length */ | 566 | /* Save the method's AML pointer and length */ |
@@ -576,10 +583,7 @@ acpi_ex_create_method(u8 * aml_start, | |||
576 | * Get the sync_level. If method is serialized, a mutex will be | 583 | * Get the sync_level. If method is serialized, a mutex will be |
577 | * created for this method when it is parsed. | 584 | * created for this method when it is parsed. |
578 | */ | 585 | */ |
579 | if (acpi_gbl_all_methods_serialized) { | 586 | if (method_flags & AML_METHOD_SERIALIZED) { |
580 | obj_desc->method.sync_level = 0; | ||
581 | obj_desc->method.method_flags |= AML_METHOD_SERIALIZED; | ||
582 | } else if (method_flags & AML_METHOD_SERIALIZED) { | ||
583 | /* | 587 | /* |
584 | * ACPI 1.0: sync_level = 0 | 588 | * ACPI 1.0: sync_level = 0 |
585 | * ACPI 2.0: sync_level = sync_level in method declaration | 589 | * ACPI 2.0: sync_level = sync_level in method declaration |
@@ -597,6 +601,7 @@ acpi_ex_create_method(u8 * aml_start, | |||
597 | 601 | ||
598 | acpi_ut_remove_reference(obj_desc); | 602 | acpi_ut_remove_reference(obj_desc); |
599 | 603 | ||
604 | exit: | ||
600 | /* Remove a reference to the operand */ | 605 | /* Remove a reference to the operand */ |
601 | 606 | ||
602 | acpi_ut_remove_reference(operand[1]); | 607 | acpi_ut_remove_reference(operand[1]); |
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 2450943add33..68d283fd60e7 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -59,8 +59,6 @@ static void acpi_ex_out_string(char *title, char *value); | |||
59 | 59 | ||
60 | static void acpi_ex_out_pointer(char *title, void *value); | 60 | static void acpi_ex_out_pointer(char *title, void *value); |
61 | 61 | ||
62 | static void acpi_ex_out_address(char *title, acpi_physical_address value); | ||
63 | |||
64 | static void | 62 | static void |
65 | acpi_ex_dump_object(union acpi_operand_object *obj_desc, | 63 | acpi_ex_dump_object(union acpi_operand_object *obj_desc, |
66 | struct acpi_exdump_info *info); | 64 | struct acpi_exdump_info *info); |
@@ -92,10 +90,11 @@ static struct acpi_exdump_info acpi_ex_dump_string[4] = { | |||
92 | {ACPI_EXD_STRING, 0, NULL} | 90 | {ACPI_EXD_STRING, 0, NULL} |
93 | }; | 91 | }; |
94 | 92 | ||
95 | static struct acpi_exdump_info acpi_ex_dump_buffer[4] = { | 93 | static struct acpi_exdump_info acpi_ex_dump_buffer[5] = { |
96 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL}, | 94 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL}, |
97 | {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"}, | 95 | {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"}, |
98 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"}, | 96 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"}, |
97 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.node), "Parent Node"}, | ||
99 | {ACPI_EXD_BUFFER, 0, NULL} | 98 | {ACPI_EXD_BUFFER, 0, NULL} |
100 | }; | 99 | }; |
101 | 100 | ||
@@ -165,8 +164,8 @@ static struct acpi_exdump_info acpi_ex_dump_power[5] = { | |||
165 | 164 | ||
166 | static struct acpi_exdump_info acpi_ex_dump_processor[7] = { | 165 | static struct acpi_exdump_info acpi_ex_dump_processor[7] = { |
167 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL}, | 166 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL}, |
168 | {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"}, | 167 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"}, |
169 | {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.length), "Length"}, | 168 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.length), "Length"}, |
170 | {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"}, | 169 | {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"}, |
171 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify), | 170 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify), |
172 | "System Notify"}, | 171 | "System Notify"}, |
@@ -379,18 +378,12 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, | |||
379 | break; | 378 | break; |
380 | 379 | ||
381 | case ACPI_EXD_POINTER: | 380 | case ACPI_EXD_POINTER: |
381 | case ACPI_EXD_ADDRESS: | ||
382 | 382 | ||
383 | acpi_ex_out_pointer(name, | 383 | acpi_ex_out_pointer(name, |
384 | *ACPI_CAST_PTR(void *, target)); | 384 | *ACPI_CAST_PTR(void *, target)); |
385 | break; | 385 | break; |
386 | 386 | ||
387 | case ACPI_EXD_ADDRESS: | ||
388 | |||
389 | acpi_ex_out_address(name, | ||
390 | *ACPI_CAST_PTR | ||
391 | (acpi_physical_address, target)); | ||
392 | break; | ||
393 | |||
394 | case ACPI_EXD_STRING: | 387 | case ACPI_EXD_STRING: |
395 | 388 | ||
396 | acpi_ut_print_string(obj_desc->string.pointer, | 389 | acpi_ut_print_string(obj_desc->string.pointer, |
@@ -834,16 +827,6 @@ static void acpi_ex_out_pointer(char *title, void *value) | |||
834 | acpi_os_printf("%20s : %p\n", title, value); | 827 | acpi_os_printf("%20s : %p\n", title, value); |
835 | } | 828 | } |
836 | 829 | ||
837 | static void acpi_ex_out_address(char *title, acpi_physical_address value) | ||
838 | { | ||
839 | |||
840 | #if ACPI_MACHINE_WIDTH == 16 | ||
841 | acpi_os_printf("%20s : %p\n", title, value); | ||
842 | #else | ||
843 | acpi_os_printf("%20s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value)); | ||
844 | #endif | ||
845 | } | ||
846 | |||
847 | /******************************************************************************* | 830 | /******************************************************************************* |
848 | * | 831 | * |
849 | * FUNCTION: acpi_ex_dump_namespace_node | 832 | * FUNCTION: acpi_ex_dump_namespace_node |
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c index 9ea9c3a67ca9..2d88a3d8d1ad 100644 --- a/drivers/acpi/executer/exfield.c +++ b/drivers/acpi/executer/exfield.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index 40f0bee6faa5..65a48b6170ee 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -257,14 +257,13 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
257 | } | 257 | } |
258 | 258 | ||
259 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, | 259 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, |
260 | " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n", | 260 | " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n", |
261 | acpi_ut_get_region_name(rgn_desc->region. | 261 | acpi_ut_get_region_name(rgn_desc->region. |
262 | space_id), | 262 | space_id), |
263 | rgn_desc->region.space_id, | 263 | rgn_desc->region.space_id, |
264 | obj_desc->common_field.access_byte_width, | 264 | obj_desc->common_field.access_byte_width, |
265 | obj_desc->common_field.base_byte_offset, | 265 | obj_desc->common_field.base_byte_offset, |
266 | field_datum_byte_offset, | 266 | field_datum_byte_offset, (void *)address)); |
267 | ACPI_FORMAT_UINT64(address))); | ||
268 | 267 | ||
269 | /* Invoke the appropriate address_space/op_region handler */ | 268 | /* Invoke the appropriate address_space/op_region handler */ |
270 | 269 | ||
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index bd98aab017cf..f13d1cec2d6d 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c index 3a39c2e8e104..5101bad5baf8 100644 --- a/drivers/acpi/executer/exmutex.c +++ b/drivers/acpi/executer/exmutex.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -44,6 +44,7 @@ | |||
44 | 44 | ||
45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
46 | #include <acpi/acinterp.h> | 46 | #include <acpi/acinterp.h> |
47 | #include <acpi/acevents.h> | ||
47 | 48 | ||
48 | #define _COMPONENT ACPI_EXECUTER | 49 | #define _COMPONENT ACPI_EXECUTER |
49 | ACPI_MODULE_NAME("exmutex") | 50 | ACPI_MODULE_NAME("exmutex") |
@@ -150,7 +151,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, | |||
150 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 151 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
151 | } | 152 | } |
152 | 153 | ||
153 | /* Sanity check -- we must have a valid thread ID */ | 154 | /* Sanity check: we must have a valid thread ID */ |
154 | 155 | ||
155 | if (!walk_state->thread) { | 156 | if (!walk_state->thread) { |
156 | ACPI_ERROR((AE_INFO, | 157 | ACPI_ERROR((AE_INFO, |
@@ -174,24 +175,28 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, | |||
174 | /* Support for multiple acquires by the owning thread */ | 175 | /* Support for multiple acquires by the owning thread */ |
175 | 176 | ||
176 | if (obj_desc->mutex.owner_thread) { | 177 | if (obj_desc->mutex.owner_thread) { |
177 | 178 | if (obj_desc->mutex.owner_thread->thread_id == | |
178 | /* Special case for Global Lock, allow all threads */ | 179 | walk_state->thread->thread_id) { |
179 | |||
180 | if ((obj_desc->mutex.owner_thread->thread_id == | ||
181 | walk_state->thread->thread_id) || | ||
182 | (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK)) { | ||
183 | /* | 180 | /* |
184 | * The mutex is already owned by this thread, | 181 | * The mutex is already owned by this thread, just increment the |
185 | * just increment the acquisition depth | 182 | * acquisition depth |
186 | */ | 183 | */ |
187 | obj_desc->mutex.acquisition_depth++; | 184 | obj_desc->mutex.acquisition_depth++; |
188 | return_ACPI_STATUS(AE_OK); | 185 | return_ACPI_STATUS(AE_OK); |
189 | } | 186 | } |
190 | } | 187 | } |
191 | 188 | ||
192 | /* Acquire the mutex, wait if necessary */ | 189 | /* Acquire the mutex, wait if necessary. Special case for Global Lock */ |
190 | |||
191 | if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { | ||
192 | status = | ||
193 | acpi_ev_acquire_global_lock((u16) time_desc->integer.value); | ||
194 | } else { | ||
195 | status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex, | ||
196 | (u16) time_desc->integer. | ||
197 | value); | ||
198 | } | ||
193 | 199 | ||
194 | status = acpi_ex_system_acquire_mutex(time_desc, obj_desc); | ||
195 | if (ACPI_FAILURE(status)) { | 200 | if (ACPI_FAILURE(status)) { |
196 | 201 | ||
197 | /* Includes failure from a timeout on time_desc */ | 202 | /* Includes failure from a timeout on time_desc */ |
@@ -211,7 +216,6 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, | |||
211 | /* Link the mutex to the current thread for force-unlock at method exit */ | 216 | /* Link the mutex to the current thread for force-unlock at method exit */ |
212 | 217 | ||
213 | acpi_ex_link_mutex(obj_desc, walk_state->thread); | 218 | acpi_ex_link_mutex(obj_desc, walk_state->thread); |
214 | |||
215 | return_ACPI_STATUS(AE_OK); | 219 | return_ACPI_STATUS(AE_OK); |
216 | } | 220 | } |
217 | 221 | ||
@@ -232,7 +236,7 @@ acpi_status | |||
232 | acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | 236 | acpi_ex_release_mutex(union acpi_operand_object *obj_desc, |
233 | struct acpi_walk_state *walk_state) | 237 | struct acpi_walk_state *walk_state) |
234 | { | 238 | { |
235 | acpi_status status; | 239 | acpi_status status = AE_OK; |
236 | 240 | ||
237 | ACPI_FUNCTION_TRACE(ex_release_mutex); | 241 | ACPI_FUNCTION_TRACE(ex_release_mutex); |
238 | 242 | ||
@@ -249,7 +253,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
249 | return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); | 253 | return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); |
250 | } | 254 | } |
251 | 255 | ||
252 | /* Sanity check -- we must have a valid thread ID */ | 256 | /* Sanity check: we must have a valid thread ID */ |
253 | 257 | ||
254 | if (!walk_state->thread) { | 258 | if (!walk_state->thread) { |
255 | ACPI_ERROR((AE_INFO, | 259 | ACPI_ERROR((AE_INFO, |
@@ -264,18 +268,18 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
264 | */ | 268 | */ |
265 | if ((obj_desc->mutex.owner_thread->thread_id != | 269 | if ((obj_desc->mutex.owner_thread->thread_id != |
266 | walk_state->thread->thread_id) | 270 | walk_state->thread->thread_id) |
267 | && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) { | 271 | && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) { |
268 | ACPI_ERROR((AE_INFO, | 272 | ACPI_ERROR((AE_INFO, |
269 | "Thread %X cannot release Mutex [%4.4s] acquired by thread %X", | 273 | "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", |
270 | (u32) walk_state->thread->thread_id, | 274 | (unsigned long)walk_state->thread->thread_id, |
271 | acpi_ut_get_node_name(obj_desc->mutex.node), | 275 | acpi_ut_get_node_name(obj_desc->mutex.node), |
272 | (u32) obj_desc->mutex.owner_thread->thread_id)); | 276 | (unsigned long)obj_desc->mutex.owner_thread->thread_id)); |
273 | return_ACPI_STATUS(AE_AML_NOT_OWNER); | 277 | return_ACPI_STATUS(AE_AML_NOT_OWNER); |
274 | } | 278 | } |
275 | 279 | ||
276 | /* | 280 | /* |
277 | * The sync level of the mutex must be less than or | 281 | * The sync level of the mutex must be less than or equal to the current |
278 | * equal to the current sync level | 282 | * sync level |
279 | */ | 283 | */ |
280 | if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { | 284 | if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { |
281 | ACPI_ERROR((AE_INFO, | 285 | ACPI_ERROR((AE_INFO, |
@@ -298,11 +302,15 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
298 | 302 | ||
299 | acpi_ex_unlink_mutex(obj_desc); | 303 | acpi_ex_unlink_mutex(obj_desc); |
300 | 304 | ||
301 | /* Release the mutex */ | 305 | /* Release the mutex, special case for Global Lock */ |
302 | 306 | ||
303 | status = acpi_ex_system_release_mutex(obj_desc); | 307 | if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { |
308 | status = acpi_ev_release_global_lock(); | ||
309 | } else { | ||
310 | acpi_os_release_mutex(obj_desc->mutex.os_mutex); | ||
311 | } | ||
304 | 312 | ||
305 | /* Update the mutex and walk state, restore sync_level before acquire */ | 313 | /* Update the mutex and restore sync_level */ |
306 | 314 | ||
307 | obj_desc->mutex.owner_thread = NULL; | 315 | obj_desc->mutex.owner_thread = NULL; |
308 | walk_state->thread->current_sync_level = | 316 | walk_state->thread->current_sync_level = |
@@ -321,39 +329,49 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
321 | * | 329 | * |
322 | * DESCRIPTION: Release all mutexes held by this thread | 330 | * DESCRIPTION: Release all mutexes held by this thread |
323 | * | 331 | * |
332 | * NOTE: This function is called as the thread is exiting the interpreter. | ||
333 | * Mutexes are not released when an individual control method is exited, but | ||
334 | * only when the parent thread actually exits the interpreter. This allows one | ||
335 | * method to acquire a mutex, and a different method to release it, as long as | ||
336 | * this is performed underneath a single parent control method. | ||
337 | * | ||
324 | ******************************************************************************/ | 338 | ******************************************************************************/ |
325 | 339 | ||
326 | void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) | 340 | void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) |
327 | { | 341 | { |
328 | union acpi_operand_object *next = thread->acquired_mutex_list; | 342 | union acpi_operand_object *next = thread->acquired_mutex_list; |
329 | union acpi_operand_object *this; | 343 | union acpi_operand_object *obj_desc; |
330 | acpi_status status; | ||
331 | 344 | ||
332 | ACPI_FUNCTION_ENTRY(); | 345 | ACPI_FUNCTION_ENTRY(); |
333 | 346 | ||
334 | /* Traverse the list of owned mutexes, releasing each one */ | 347 | /* Traverse the list of owned mutexes, releasing each one */ |
335 | 348 | ||
336 | while (next) { | 349 | while (next) { |
337 | this = next; | 350 | obj_desc = next; |
338 | next = this->mutex.next; | 351 | next = obj_desc->mutex.next; |
352 | |||
353 | obj_desc->mutex.prev = NULL; | ||
354 | obj_desc->mutex.next = NULL; | ||
355 | obj_desc->mutex.acquisition_depth = 0; | ||
356 | |||
357 | /* Release the mutex, special case for Global Lock */ | ||
339 | 358 | ||
340 | this->mutex.acquisition_depth = 1; | 359 | if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { |
341 | this->mutex.prev = NULL; | ||
342 | this->mutex.next = NULL; | ||
343 | 360 | ||
344 | /* Release the mutex */ | 361 | /* Ignore errors */ |
345 | 362 | ||
346 | status = acpi_ex_system_release_mutex(this); | 363 | (void)acpi_ev_release_global_lock(); |
347 | if (ACPI_FAILURE(status)) { | 364 | } else { |
348 | continue; | 365 | acpi_os_release_mutex(obj_desc->mutex.os_mutex); |
349 | } | 366 | } |
350 | 367 | ||
351 | /* Mark mutex unowned */ | 368 | /* Mark mutex unowned */ |
352 | 369 | ||
353 | this->mutex.owner_thread = NULL; | 370 | obj_desc->mutex.owner_thread = NULL; |
354 | 371 | ||
355 | /* Update Thread sync_level (Last mutex is the important one) */ | 372 | /* Update Thread sync_level (Last mutex is the important one) */ |
356 | 373 | ||
357 | thread->current_sync_level = this->mutex.original_sync_level; | 374 | thread->current_sync_level = |
375 | obj_desc->mutex.original_sync_level; | ||
358 | } | 376 | } |
359 | } | 377 | } |
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c index d3d70364626c..1ee4fb1175c6 100644 --- a/drivers/acpi/executer/exnames.c +++ b/drivers/acpi/executer/exnames.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c index 6374d8be88e0..252f10acbbcc 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/executer/exoparg1.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -104,9 +104,7 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state) | |||
104 | status = AE_NO_MEMORY; | 104 | status = AE_NO_MEMORY; |
105 | goto cleanup; | 105 | goto cleanup; |
106 | } | 106 | } |
107 | #if ACPI_MACHINE_WIDTH != 16 | ||
108 | return_desc->integer.value = acpi_os_get_timer(); | 107 | return_desc->integer.value = acpi_os_get_timer(); |
109 | #endif | ||
110 | break; | 108 | break; |
111 | 109 | ||
112 | default: /* Unknown opcode */ | 110 | default: /* Unknown opcode */ |
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index 7d2cbc113160..17e652e65379 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c index e2d945dfd509..7fe67cf82cee 100644 --- a/drivers/acpi/executer/exoparg3.c +++ b/drivers/acpi/executer/exoparg3.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c index f0c0ba6eb408..bd80a9cb3d65 100644 --- a/drivers/acpi/executer/exoparg6.c +++ b/drivers/acpi/executer/exoparg6.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c index 44d064f427b9..a6696621ff1b 100644 --- a/drivers/acpi/executer/exprep.c +++ b/drivers/acpi/executer/exprep.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index 3cc97ba48b36..2e9ce94798c7 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -155,16 +155,15 @@ acpi_ex_system_memory_space_handler(u32 function, | |||
155 | 155 | ||
156 | /* Create a new mapping starting at the address given */ | 156 | /* Create a new mapping starting at the address given */ |
157 | 157 | ||
158 | status = acpi_os_map_memory(address, window_size, | 158 | mem_info->mapped_logical_address = |
159 | (void **)&mem_info-> | 159 | acpi_os_map_memory((acpi_native_uint) address, window_size); |
160 | mapped_logical_address); | 160 | if (!mem_info->mapped_logical_address) { |
161 | if (ACPI_FAILURE(status)) { | ||
162 | ACPI_ERROR((AE_INFO, | 161 | ACPI_ERROR((AE_INFO, |
163 | "Could not map memory at %8.8X%8.8X, size %X", | 162 | "Could not map memory at %8.8X%8.8X, size %X", |
164 | ACPI_FORMAT_UINT64(address), | 163 | ACPI_FORMAT_UINT64(address), |
165 | (u32) window_size)); | 164 | (u32) window_size)); |
166 | mem_info->mapped_length = 0; | 165 | mem_info->mapped_length = 0; |
167 | return_ACPI_STATUS(status); | 166 | return_ACPI_STATUS(AE_NO_MEMORY); |
168 | } | 167 | } |
169 | 168 | ||
170 | /* Save the physical address and mapping size */ | 169 | /* Save the physical address and mapping size */ |
@@ -210,11 +209,10 @@ acpi_ex_system_memory_space_handler(u32 function, | |||
210 | *value = (acpi_integer) ACPI_GET32(logical_addr_ptr); | 209 | *value = (acpi_integer) ACPI_GET32(logical_addr_ptr); |
211 | break; | 210 | break; |
212 | 211 | ||
213 | #if ACPI_MACHINE_WIDTH != 16 | ||
214 | case 64: | 212 | case 64: |
215 | *value = (acpi_integer) ACPI_GET64(logical_addr_ptr); | 213 | *value = (acpi_integer) ACPI_GET64(logical_addr_ptr); |
216 | break; | 214 | break; |
217 | #endif | 215 | |
218 | default: | 216 | default: |
219 | /* bit_width was already validated */ | 217 | /* bit_width was already validated */ |
220 | break; | 218 | break; |
@@ -236,11 +234,9 @@ acpi_ex_system_memory_space_handler(u32 function, | |||
236 | ACPI_SET32(logical_addr_ptr) = (u32) * value; | 234 | ACPI_SET32(logical_addr_ptr) = (u32) * value; |
237 | break; | 235 | break; |
238 | 236 | ||
239 | #if ACPI_MACHINE_WIDTH != 16 | ||
240 | case 64: | 237 | case 64: |
241 | ACPI_SET64(logical_addr_ptr) = (u64) * value; | 238 | ACPI_SET64(logical_addr_ptr) = (u64) * value; |
242 | break; | 239 | break; |
243 | #endif | ||
244 | 240 | ||
245 | default: | 241 | default: |
246 | /* bit_width was already validated */ | 242 | /* bit_width was already validated */ |
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c index 3089b05a1368..2b3a01cc4929 100644 --- a/drivers/acpi/executer/exresnte.c +++ b/drivers/acpi/executer/exresnte.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c index 6499de878017..6c64e55dab0e 100644 --- a/drivers/acpi/executer/exresolv.c +++ b/drivers/acpi/executer/exresolv.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -141,7 +141,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
141 | acpi_status status = AE_OK; | 141 | acpi_status status = AE_OK; |
142 | union acpi_operand_object *stack_desc; | 142 | union acpi_operand_object *stack_desc; |
143 | void *temp_node; | 143 | void *temp_node; |
144 | union acpi_operand_object *obj_desc; | 144 | union acpi_operand_object *obj_desc = NULL; |
145 | u16 opcode; | 145 | u16 opcode; |
146 | 146 | ||
147 | ACPI_FUNCTION_TRACE(ex_resolve_object_to_value); | 147 | ACPI_FUNCTION_TRACE(ex_resolve_object_to_value); |
@@ -299,8 +299,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
299 | status = acpi_ds_get_package_arguments(stack_desc); | 299 | status = acpi_ds_get_package_arguments(stack_desc); |
300 | break; | 300 | break; |
301 | 301 | ||
302 | /* These cases may never happen here, but just in case.. */ | ||
303 | |||
304 | case ACPI_TYPE_BUFFER_FIELD: | 302 | case ACPI_TYPE_BUFFER_FIELD: |
305 | case ACPI_TYPE_LOCAL_REGION_FIELD: | 303 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
306 | case ACPI_TYPE_LOCAL_BANK_FIELD: | 304 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
@@ -314,6 +312,10 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
314 | status = | 312 | status = |
315 | acpi_ex_read_data_from_field(walk_state, stack_desc, | 313 | acpi_ex_read_data_from_field(walk_state, stack_desc, |
316 | &obj_desc); | 314 | &obj_desc); |
315 | |||
316 | /* Remove a reference to the original operand, then override */ | ||
317 | |||
318 | acpi_ut_remove_reference(*stack_ptr); | ||
317 | *stack_ptr = (void *)obj_desc; | 319 | *stack_ptr = (void *)obj_desc; |
318 | break; | 320 | break; |
319 | 321 | ||
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c index 4c93d0972333..ba761862a599 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/executer/exresop.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -611,22 +611,20 @@ acpi_ex_resolve_operands(u16 opcode, | |||
611 | } | 611 | } |
612 | goto next_operand; | 612 | goto next_operand; |
613 | 613 | ||
614 | case ARGI_REGION_OR_FIELD: | 614 | case ARGI_REGION_OR_BUFFER: /* Used by Load() only */ |
615 | 615 | ||
616 | /* Need an operand of type REGION or a FIELD in a region */ | 616 | /* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */ |
617 | 617 | ||
618 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 618 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { |
619 | case ACPI_TYPE_BUFFER: | ||
619 | case ACPI_TYPE_REGION: | 620 | case ACPI_TYPE_REGION: |
620 | case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
621 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
622 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | ||
623 | 621 | ||
624 | /* Valid operand */ | 622 | /* Valid operand */ |
625 | break; | 623 | break; |
626 | 624 | ||
627 | default: | 625 | default: |
628 | ACPI_ERROR((AE_INFO, | 626 | ACPI_ERROR((AE_INFO, |
629 | "Needed [Region/RegionField], found [%s] %p", | 627 | "Needed [Region/Buffer], found [%s] %p", |
630 | acpi_ut_get_object_type_name | 628 | acpi_ut_get_object_type_name |
631 | (obj_desc), obj_desc)); | 629 | (obj_desc), obj_desc)); |
632 | 630 | ||
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index 0456405ba019..f4b69a637820 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c index 591aaf0e18b3..1d622c625c64 100644 --- a/drivers/acpi/executer/exstoren.c +++ b/drivers/acpi/executer/exstoren.c | |||
@@ -7,7 +7,7 @@ | |||
7 | *****************************************************************************/ | 7 | *****************************************************************************/ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Copyright (C) 2000 - 2006, R. Byron Moore | 10 | * Copyright (C) 2000 - 2007, R. Byron Moore |
11 | * All rights reserved. | 11 | * All rights reserved. |
12 | * | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c index 99ebe5adfcda..8233d40178ee 100644 --- a/drivers/acpi/executer/exstorob.c +++ b/drivers/acpi/executer/exstorob.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c index 28aef3e69ecc..9460baff3032 100644 --- a/drivers/acpi/executer/exsystem.c +++ b/drivers/acpi/executer/exsystem.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -66,7 +66,6 @@ ACPI_MODULE_NAME("exsystem") | |||
66 | acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) | 66 | acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) |
67 | { | 67 | { |
68 | acpi_status status; | 68 | acpi_status status; |
69 | acpi_status status2; | ||
70 | 69 | ||
71 | ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); | 70 | ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); |
72 | 71 | ||
@@ -79,7 +78,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) | |||
79 | 78 | ||
80 | /* We must wait, so unlock the interpreter */ | 79 | /* We must wait, so unlock the interpreter */ |
81 | 80 | ||
82 | acpi_ex_exit_interpreter(); | 81 | acpi_ex_relinquish_interpreter(); |
83 | 82 | ||
84 | status = acpi_os_wait_semaphore(semaphore, 1, timeout); | 83 | status = acpi_os_wait_semaphore(semaphore, 1, timeout); |
85 | 84 | ||
@@ -89,13 +88,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) | |||
89 | 88 | ||
90 | /* Reacquire the interpreter */ | 89 | /* Reacquire the interpreter */ |
91 | 90 | ||
92 | status2 = acpi_ex_enter_interpreter(); | 91 | acpi_ex_reacquire_interpreter(); |
93 | if (ACPI_FAILURE(status2)) { | ||
94 | |||
95 | /* Report fatal error, could not acquire interpreter */ | ||
96 | |||
97 | return_ACPI_STATUS(status2); | ||
98 | } | ||
99 | } | 92 | } |
100 | 93 | ||
101 | return_ACPI_STATUS(status); | 94 | return_ACPI_STATUS(status); |
@@ -119,7 +112,6 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) | |||
119 | acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) | 112 | acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) |
120 | { | 113 | { |
121 | acpi_status status; | 114 | acpi_status status; |
122 | acpi_status status2; | ||
123 | 115 | ||
124 | ACPI_FUNCTION_TRACE(ex_system_wait_mutex); | 116 | ACPI_FUNCTION_TRACE(ex_system_wait_mutex); |
125 | 117 | ||
@@ -132,7 +124,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) | |||
132 | 124 | ||
133 | /* We must wait, so unlock the interpreter */ | 125 | /* We must wait, so unlock the interpreter */ |
134 | 126 | ||
135 | acpi_ex_exit_interpreter(); | 127 | acpi_ex_relinquish_interpreter(); |
136 | 128 | ||
137 | status = acpi_os_acquire_mutex(mutex, timeout); | 129 | status = acpi_os_acquire_mutex(mutex, timeout); |
138 | 130 | ||
@@ -142,13 +134,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) | |||
142 | 134 | ||
143 | /* Reacquire the interpreter */ | 135 | /* Reacquire the interpreter */ |
144 | 136 | ||
145 | status2 = acpi_ex_enter_interpreter(); | 137 | acpi_ex_reacquire_interpreter(); |
146 | if (ACPI_FAILURE(status2)) { | ||
147 | |||
148 | /* Report fatal error, could not acquire interpreter */ | ||
149 | |||
150 | return_ACPI_STATUS(status2); | ||
151 | } | ||
152 | } | 138 | } |
153 | 139 | ||
154 | return_ACPI_STATUS(status); | 140 | return_ACPI_STATUS(status); |
@@ -209,96 +195,18 @@ acpi_status acpi_ex_system_do_stall(u32 how_long) | |||
209 | 195 | ||
210 | acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) | 196 | acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) |
211 | { | 197 | { |
212 | acpi_status status; | ||
213 | |||
214 | ACPI_FUNCTION_ENTRY(); | 198 | ACPI_FUNCTION_ENTRY(); |
215 | 199 | ||
216 | /* Since this thread will sleep, we must release the interpreter */ | 200 | /* Since this thread will sleep, we must release the interpreter */ |
217 | 201 | ||
218 | acpi_ex_exit_interpreter(); | 202 | acpi_ex_relinquish_interpreter(); |
219 | 203 | ||
220 | acpi_os_sleep(how_long); | 204 | acpi_os_sleep(how_long); |
221 | 205 | ||
222 | /* And now we must get the interpreter again */ | 206 | /* And now we must get the interpreter again */ |
223 | 207 | ||
224 | status = acpi_ex_enter_interpreter(); | 208 | acpi_ex_reacquire_interpreter(); |
225 | return (status); | 209 | return (AE_OK); |
226 | } | ||
227 | |||
228 | /******************************************************************************* | ||
229 | * | ||
230 | * FUNCTION: acpi_ex_system_acquire_mutex | ||
231 | * | ||
232 | * PARAMETERS: time_desc - Maximum time to wait for the mutex | ||
233 | * obj_desc - The object descriptor for this op | ||
234 | * | ||
235 | * RETURN: Status | ||
236 | * | ||
237 | * DESCRIPTION: Provides an access point to perform synchronization operations | ||
238 | * within the AML. This function will cause a lock to be generated | ||
239 | * for the Mutex pointed to by obj_desc. | ||
240 | * | ||
241 | ******************************************************************************/ | ||
242 | |||
243 | acpi_status | ||
244 | acpi_ex_system_acquire_mutex(union acpi_operand_object * time_desc, | ||
245 | union acpi_operand_object * obj_desc) | ||
246 | { | ||
247 | acpi_status status = AE_OK; | ||
248 | |||
249 | ACPI_FUNCTION_TRACE_PTR(ex_system_acquire_mutex, obj_desc); | ||
250 | |||
251 | if (!obj_desc) { | ||
252 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
253 | } | ||
254 | |||
255 | /* Support for the _GL_ Mutex object -- go get the global lock */ | ||
256 | |||
257 | if (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK) { | ||
258 | status = | ||
259 | acpi_ev_acquire_global_lock((u16) time_desc->integer.value); | ||
260 | return_ACPI_STATUS(status); | ||
261 | } | ||
262 | |||
263 | status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex, | ||
264 | (u16) time_desc->integer.value); | ||
265 | return_ACPI_STATUS(status); | ||
266 | } | ||
267 | |||
268 | /******************************************************************************* | ||
269 | * | ||
270 | * FUNCTION: acpi_ex_system_release_mutex | ||
271 | * | ||
272 | * PARAMETERS: obj_desc - The object descriptor for this op | ||
273 | * | ||
274 | * RETURN: Status | ||
275 | * | ||
276 | * DESCRIPTION: Provides an access point to perform synchronization operations | ||
277 | * within the AML. This operation is a request to release a | ||
278 | * previously acquired Mutex. If the Mutex variable is set then | ||
279 | * it will be decremented. | ||
280 | * | ||
281 | ******************************************************************************/ | ||
282 | |||
283 | acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc) | ||
284 | { | ||
285 | acpi_status status = AE_OK; | ||
286 | |||
287 | ACPI_FUNCTION_TRACE(ex_system_release_mutex); | ||
288 | |||
289 | if (!obj_desc) { | ||
290 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
291 | } | ||
292 | |||
293 | /* Support for the _GL_ Mutex object -- release the global lock */ | ||
294 | |||
295 | if (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK) { | ||
296 | status = acpi_ev_release_global_lock(); | ||
297 | return_ACPI_STATUS(status); | ||
298 | } | ||
299 | |||
300 | acpi_os_release_mutex(obj_desc->mutex.os_mutex); | ||
301 | return_ACPI_STATUS(AE_OK); | ||
302 | } | 210 | } |
303 | 211 | ||
304 | /******************************************************************************* | 212 | /******************************************************************************* |
@@ -314,7 +222,7 @@ acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc) | |||
314 | * | 222 | * |
315 | ******************************************************************************/ | 223 | ******************************************************************************/ |
316 | 224 | ||
317 | acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc) | 225 | acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc) |
318 | { | 226 | { |
319 | acpi_status status = AE_OK; | 227 | acpi_status status = AE_OK; |
320 | 228 | ||
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c index 982c8b65876f..6b0aeccbb69b 100644 --- a/drivers/acpi/executer/exutils.c +++ b/drivers/acpi/executer/exutils.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -76,14 +76,15 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base); | |||
76 | * | 76 | * |
77 | * PARAMETERS: None | 77 | * PARAMETERS: None |
78 | * | 78 | * |
79 | * RETURN: Status | 79 | * RETURN: None |
80 | * | 80 | * |
81 | * DESCRIPTION: Enter the interpreter execution region. Failure to enter | 81 | * DESCRIPTION: Enter the interpreter execution region. Failure to enter |
82 | * the interpreter region is a fatal system error | 82 | * the interpreter region is a fatal system error. Used in |
83 | * conjunction with exit_interpreter. | ||
83 | * | 84 | * |
84 | ******************************************************************************/ | 85 | ******************************************************************************/ |
85 | 86 | ||
86 | acpi_status acpi_ex_enter_interpreter(void) | 87 | void acpi_ex_enter_interpreter(void) |
87 | { | 88 | { |
88 | acpi_status status; | 89 | acpi_status status; |
89 | 90 | ||
@@ -91,31 +92,55 @@ acpi_status acpi_ex_enter_interpreter(void) | |||
91 | 92 | ||
92 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | 93 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); |
93 | if (ACPI_FAILURE(status)) { | 94 | if (ACPI_FAILURE(status)) { |
94 | ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex")); | 95 | ACPI_ERROR((AE_INFO, |
96 | "Could not acquire AML Interpreter mutex")); | ||
95 | } | 97 | } |
96 | 98 | ||
97 | return_ACPI_STATUS(status); | 99 | return_VOID; |
98 | } | 100 | } |
99 | 101 | ||
100 | /******************************************************************************* | 102 | /******************************************************************************* |
101 | * | 103 | * |
102 | * FUNCTION: acpi_ex_exit_interpreter | 104 | * FUNCTION: acpi_ex_reacquire_interpreter |
103 | * | 105 | * |
104 | * PARAMETERS: None | 106 | * PARAMETERS: None |
105 | * | 107 | * |
106 | * RETURN: None | 108 | * RETURN: None |
107 | * | 109 | * |
108 | * DESCRIPTION: Exit the interpreter execution region | 110 | * DESCRIPTION: Reacquire the interpreter execution region from within the |
111 | * interpreter code. Failure to enter the interpreter region is a | ||
112 | * fatal system error. Used in conjuction with | ||
113 | * relinquish_interpreter | ||
114 | * | ||
115 | ******************************************************************************/ | ||
116 | |||
117 | void acpi_ex_reacquire_interpreter(void) | ||
118 | { | ||
119 | ACPI_FUNCTION_TRACE(ex_reacquire_interpreter); | ||
120 | |||
121 | /* | ||
122 | * If the global serialized flag is set, do not release the interpreter, | ||
123 | * since it was not actually released by acpi_ex_relinquish_interpreter. | ||
124 | * This forces the interpreter to be single threaded. | ||
125 | */ | ||
126 | if (!acpi_gbl_all_methods_serialized) { | ||
127 | acpi_ex_enter_interpreter(); | ||
128 | } | ||
129 | |||
130 | return_VOID; | ||
131 | } | ||
132 | |||
133 | /******************************************************************************* | ||
134 | * | ||
135 | * FUNCTION: acpi_ex_exit_interpreter | ||
136 | * | ||
137 | * PARAMETERS: None | ||
138 | * | ||
139 | * RETURN: None | ||
109 | * | 140 | * |
110 | * Cases where the interpreter is unlocked: | 141 | * DESCRIPTION: Exit the interpreter execution region. This is the top level |
111 | * 1) Completion of the execution of a control method | 142 | * routine used to exit the interpreter when all processing has |
112 | * 2) Method blocked on a Sleep() AML opcode | 143 | * been completed. |
113 | * 3) Method blocked on an Acquire() AML opcode | ||
114 | * 4) Method blocked on a Wait() AML opcode | ||
115 | * 5) Method blocked to acquire the global lock | ||
116 | * 6) Method blocked to execute a serialized control method that is | ||
117 | * already executing | ||
118 | * 7) About to invoke a user-installed opregion handler | ||
119 | * | 144 | * |
120 | ******************************************************************************/ | 145 | ******************************************************************************/ |
121 | 146 | ||
@@ -127,7 +152,46 @@ void acpi_ex_exit_interpreter(void) | |||
127 | 152 | ||
128 | status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | 153 | status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); |
129 | if (ACPI_FAILURE(status)) { | 154 | if (ACPI_FAILURE(status)) { |
130 | ACPI_ERROR((AE_INFO, "Could not release interpreter mutex")); | 155 | ACPI_ERROR((AE_INFO, |
156 | "Could not release AML Interpreter mutex")); | ||
157 | } | ||
158 | |||
159 | return_VOID; | ||
160 | } | ||
161 | |||
162 | /******************************************************************************* | ||
163 | * | ||
164 | * FUNCTION: acpi_ex_relinquish_interpreter | ||
165 | * | ||
166 | * PARAMETERS: None | ||
167 | * | ||
168 | * RETURN: None | ||
169 | * | ||
170 | * DESCRIPTION: Exit the interpreter execution region, from within the | ||
171 | * interpreter - before attempting an operation that will possibly | ||
172 | * block the running thread. | ||
173 | * | ||
174 | * Cases where the interpreter is unlocked internally | ||
175 | * 1) Method to be blocked on a Sleep() AML opcode | ||
176 | * 2) Method to be blocked on an Acquire() AML opcode | ||
177 | * 3) Method to be blocked on a Wait() AML opcode | ||
178 | * 4) Method to be blocked to acquire the global lock | ||
179 | * 5) Method to be blocked waiting to execute a serialized control method | ||
180 | * that is currently executing | ||
181 | * 6) About to invoke a user-installed opregion handler | ||
182 | * | ||
183 | ******************************************************************************/ | ||
184 | |||
185 | void acpi_ex_relinquish_interpreter(void) | ||
186 | { | ||
187 | ACPI_FUNCTION_TRACE(ex_relinquish_interpreter); | ||
188 | |||
189 | /* | ||
190 | * If the global serialized flag is set, do not release the interpreter. | ||
191 | * This forces the interpreter to be single threaded. | ||
192 | */ | ||
193 | if (!acpi_gbl_all_methods_serialized) { | ||
194 | acpi_ex_exit_interpreter(); | ||
131 | } | 195 | } |
132 | 196 | ||
133 | return_VOID; | 197 | return_VOID; |
@@ -141,8 +205,8 @@ void acpi_ex_exit_interpreter(void) | |||
141 | * | 205 | * |
142 | * RETURN: none | 206 | * RETURN: none |
143 | * | 207 | * |
144 | * DESCRIPTION: Truncate a number to 32-bits if the currently executing method | 208 | * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is |
145 | * belongs to a 32-bit ACPI table. | 209 | * 32-bit, as determined by the revision of the DSDT. |
146 | * | 210 | * |
147 | ******************************************************************************/ | 211 | ******************************************************************************/ |
148 | 212 | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index b24942041b3f..af22fdf73413 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -99,8 +99,8 @@ acpi_fan_write_state(struct file *file, const char __user * buffer, | |||
99 | size_t count, loff_t * ppos) | 99 | size_t count, loff_t * ppos) |
100 | { | 100 | { |
101 | int result = 0; | 101 | int result = 0; |
102 | struct seq_file *m = (struct seq_file *)file->private_data; | 102 | struct seq_file *m = file->private_data; |
103 | struct acpi_fan *fan = (struct acpi_fan *)m->private; | 103 | struct acpi_fan *fan = m->private; |
104 | char state_string[12] = { '\0' }; | 104 | char state_string[12] = { '\0' }; |
105 | 105 | ||
106 | 106 | ||
@@ -186,10 +186,9 @@ static int acpi_fan_add(struct acpi_device *device) | |||
186 | if (!device) | 186 | if (!device) |
187 | return -EINVAL; | 187 | return -EINVAL; |
188 | 188 | ||
189 | fan = kmalloc(sizeof(struct acpi_fan), GFP_KERNEL); | 189 | fan = kzalloc(sizeof(struct acpi_fan), GFP_KERNEL); |
190 | if (!fan) | 190 | if (!fan) |
191 | return -ENOMEM; | 191 | return -ENOMEM; |
192 | memset(fan, 0, sizeof(struct acpi_fan)); | ||
193 | 192 | ||
194 | fan->device = device; | 193 | fan->device = device; |
195 | strcpy(acpi_device_name(device), "Fan"); | 194 | strcpy(acpi_device_name(device), "Fan"); |
@@ -229,7 +228,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type) | |||
229 | if (!device || !acpi_driver_data(device)) | 228 | if (!device || !acpi_driver_data(device)) |
230 | return -EINVAL; | 229 | return -EINVAL; |
231 | 230 | ||
232 | fan = (struct acpi_fan *)acpi_driver_data(device); | 231 | fan = acpi_driver_data(device); |
233 | 232 | ||
234 | acpi_fan_remove_fs(device); | 233 | acpi_fan_remove_fs(device); |
235 | 234 | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index a2f46d587d55..7b6c9ff9bebe 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -86,125 +86,6 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) | |||
86 | return ret; | 86 | return ret; |
87 | } | 87 | } |
88 | 88 | ||
89 | /* Get PCI root bridge's handle from its segment and bus number */ | ||
90 | struct acpi_find_pci_root { | ||
91 | unsigned int seg; | ||
92 | unsigned int bus; | ||
93 | acpi_handle handle; | ||
94 | }; | ||
95 | |||
96 | static acpi_status | ||
97 | do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | ||
98 | { | ||
99 | unsigned long *busnr = (unsigned long *)data; | ||
100 | struct acpi_resource_address64 address; | ||
101 | |||
102 | if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && | ||
103 | resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 && | ||
104 | resource->type != ACPI_RESOURCE_TYPE_ADDRESS64) | ||
105 | return AE_OK; | ||
106 | |||
107 | acpi_resource_to_address64(resource, &address); | ||
108 | if ((address.address_length > 0) && | ||
109 | (address.resource_type == ACPI_BUS_NUMBER_RANGE)) | ||
110 | *busnr = address.minimum; | ||
111 | |||
112 | return AE_OK; | ||
113 | } | ||
114 | |||
115 | static int get_root_bridge_busnr(acpi_handle handle) | ||
116 | { | ||
117 | acpi_status status; | ||
118 | unsigned long bus, bbn; | ||
119 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
120 | |||
121 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
122 | |||
123 | status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, | ||
124 | &bbn); | ||
125 | if (status == AE_NOT_FOUND) { | ||
126 | /* Assume bus = 0 */ | ||
127 | printk(KERN_INFO PREFIX | ||
128 | "Assume root bridge [%s] bus is 0\n", | ||
129 | (char *)buffer.pointer); | ||
130 | status = AE_OK; | ||
131 | bbn = 0; | ||
132 | } | ||
133 | if (ACPI_FAILURE(status)) { | ||
134 | bbn = -ENODEV; | ||
135 | goto exit; | ||
136 | } | ||
137 | if (bbn > 0) | ||
138 | goto exit; | ||
139 | |||
140 | /* _BBN in some systems return 0 for all root bridges */ | ||
141 | bus = -1; | ||
142 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | ||
143 | do_root_bridge_busnr_callback, &bus); | ||
144 | /* If _CRS failed, we just use _BBN */ | ||
145 | if (ACPI_FAILURE(status) || (bus == -1)) | ||
146 | goto exit; | ||
147 | /* We select _CRS */ | ||
148 | if (bbn != bus) { | ||
149 | printk(KERN_INFO PREFIX | ||
150 | "_BBN and _CRS returns different value for %s. Select _CRS\n", | ||
151 | (char *)buffer.pointer); | ||
152 | bbn = bus; | ||
153 | } | ||
154 | exit: | ||
155 | kfree(buffer.pointer); | ||
156 | return (int)bbn; | ||
157 | } | ||
158 | |||
159 | static acpi_status | ||
160 | find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
161 | { | ||
162 | struct acpi_find_pci_root *find = (struct acpi_find_pci_root *)context; | ||
163 | unsigned long seg, bus; | ||
164 | acpi_status status; | ||
165 | int tmp; | ||
166 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
167 | |||
168 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
169 | |||
170 | status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &seg); | ||
171 | if (status == AE_NOT_FOUND) { | ||
172 | /* Assume seg = 0 */ | ||
173 | status = AE_OK; | ||
174 | seg = 0; | ||
175 | } | ||
176 | if (ACPI_FAILURE(status)) { | ||
177 | status = AE_CTRL_DEPTH; | ||
178 | goto exit; | ||
179 | } | ||
180 | |||
181 | tmp = get_root_bridge_busnr(handle); | ||
182 | if (tmp < 0) { | ||
183 | printk(KERN_ERR PREFIX | ||
184 | "Find root bridge failed for %s\n", | ||
185 | (char *)buffer.pointer); | ||
186 | status = AE_CTRL_DEPTH; | ||
187 | goto exit; | ||
188 | } | ||
189 | bus = tmp; | ||
190 | |||
191 | if (seg == find->seg && bus == find->bus) | ||
192 | find->handle = handle; | ||
193 | status = AE_OK; | ||
194 | exit: | ||
195 | kfree(buffer.pointer); | ||
196 | return status; | ||
197 | } | ||
198 | |||
199 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) | ||
200 | { | ||
201 | struct acpi_find_pci_root find = { seg, bus, NULL }; | ||
202 | |||
203 | acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL); | ||
204 | return find.handle; | ||
205 | } | ||
206 | EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); | ||
207 | |||
208 | /* Get device's handler per its address under its parent */ | 89 | /* Get device's handler per its address under its parent */ |
209 | struct acpi_find_child { | 90 | struct acpi_find_child { |
210 | acpi_handle handle; | 91 | acpi_handle handle; |
@@ -217,7 +98,7 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
217 | acpi_status status; | 98 | acpi_status status; |
218 | struct acpi_device_info *info; | 99 | struct acpi_device_info *info; |
219 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 100 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
220 | struct acpi_find_child *find = (struct acpi_find_child *)context; | 101 | struct acpi_find_child *find = context; |
221 | 102 | ||
222 | status = acpi_get_object_info(handle, &buffer); | 103 | status = acpi_get_object_info(handle, &buffer); |
223 | if (ACPI_SUCCESS(status)) { | 104 | if (ACPI_SUCCESS(status)) { |
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c index de50fab2a910..6031ca13dd2f 100644 --- a/drivers/acpi/hardware/hwacpi.c +++ b/drivers/acpi/hardware/hwacpi.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -49,41 +49,6 @@ ACPI_MODULE_NAME("hwacpi") | |||
49 | 49 | ||
50 | /****************************************************************************** | 50 | /****************************************************************************** |
51 | * | 51 | * |
52 | * FUNCTION: acpi_hw_initialize | ||
53 | * | ||
54 | * PARAMETERS: None | ||
55 | * | ||
56 | * RETURN: Status | ||
57 | * | ||
58 | * DESCRIPTION: Initialize and validate the various ACPI registers defined in | ||
59 | * the FADT. | ||
60 | * | ||
61 | ******************************************************************************/ | ||
62 | acpi_status acpi_hw_initialize(void) | ||
63 | { | ||
64 | acpi_status status; | ||
65 | |||
66 | ACPI_FUNCTION_TRACE(hw_initialize); | ||
67 | |||
68 | /* We must have the ACPI tables by the time we get here */ | ||
69 | |||
70 | if (!acpi_gbl_FADT) { | ||
71 | ACPI_ERROR((AE_INFO, "No FADT is present")); | ||
72 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
73 | } | ||
74 | |||
75 | /* Sanity check the FADT for valid values */ | ||
76 | |||
77 | status = acpi_ut_validate_fadt(); | ||
78 | if (ACPI_FAILURE(status)) { | ||
79 | return_ACPI_STATUS(status); | ||
80 | } | ||
81 | |||
82 | return_ACPI_STATUS(AE_OK); | ||
83 | } | ||
84 | |||
85 | /****************************************************************************** | ||
86 | * | ||
87 | * FUNCTION: acpi_hw_set_mode | 52 | * FUNCTION: acpi_hw_set_mode |
88 | * | 53 | * |
89 | * PARAMETERS: Mode - SYS_MODE_ACPI or SYS_MODE_LEGACY | 54 | * PARAMETERS: Mode - SYS_MODE_ACPI or SYS_MODE_LEGACY |
@@ -93,7 +58,6 @@ acpi_status acpi_hw_initialize(void) | |||
93 | * DESCRIPTION: Transitions the system into the requested mode. | 58 | * DESCRIPTION: Transitions the system into the requested mode. |
94 | * | 59 | * |
95 | ******************************************************************************/ | 60 | ******************************************************************************/ |
96 | |||
97 | acpi_status acpi_hw_set_mode(u32 mode) | 61 | acpi_status acpi_hw_set_mode(u32 mode) |
98 | { | 62 | { |
99 | 63 | ||
@@ -106,7 +70,7 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
106 | * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, | 70 | * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, |
107 | * system does not support mode transition. | 71 | * system does not support mode transition. |
108 | */ | 72 | */ |
109 | if (!acpi_gbl_FADT->smi_cmd) { | 73 | if (!acpi_gbl_FADT.smi_command) { |
110 | ACPI_ERROR((AE_INFO, | 74 | ACPI_ERROR((AE_INFO, |
111 | "No SMI_CMD in FADT, mode transition failed")); | 75 | "No SMI_CMD in FADT, mode transition failed")); |
112 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); | 76 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); |
@@ -119,7 +83,7 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
119 | * we make sure both the numbers are zero to determine these | 83 | * we make sure both the numbers are zero to determine these |
120 | * transitions are not supported. | 84 | * transitions are not supported. |
121 | */ | 85 | */ |
122 | if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) { | 86 | if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) { |
123 | ACPI_ERROR((AE_INFO, | 87 | ACPI_ERROR((AE_INFO, |
124 | "No ACPI mode transition supported in this system (enable/disable both zero)")); | 88 | "No ACPI mode transition supported in this system (enable/disable both zero)")); |
125 | return_ACPI_STATUS(AE_OK); | 89 | return_ACPI_STATUS(AE_OK); |
@@ -130,9 +94,8 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
130 | 94 | ||
131 | /* BIOS should have disabled ALL fixed and GP events */ | 95 | /* BIOS should have disabled ALL fixed and GP events */ |
132 | 96 | ||
133 | status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, | 97 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, |
134 | (u32) acpi_gbl_FADT->acpi_enable, | 98 | (u32) acpi_gbl_FADT.acpi_enable, 8); |
135 | 8); | ||
136 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 99 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
137 | "Attempting to enable ACPI mode\n")); | 100 | "Attempting to enable ACPI mode\n")); |
138 | break; | 101 | break; |
@@ -143,8 +106,8 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
143 | * BIOS should clear all fixed status bits and restore fixed event | 106 | * BIOS should clear all fixed status bits and restore fixed event |
144 | * enable bits to default | 107 | * enable bits to default |
145 | */ | 108 | */ |
146 | status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, | 109 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, |
147 | (u32) acpi_gbl_FADT->acpi_disable, | 110 | (u32) acpi_gbl_FADT.acpi_disable, |
148 | 8); | 111 | 8); |
149 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 112 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
150 | "Attempting to enable Legacy (non-ACPI) mode\n")); | 113 | "Attempting to enable Legacy (non-ACPI) mode\n")); |
@@ -204,12 +167,11 @@ u32 acpi_hw_get_mode(void) | |||
204 | * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, | 167 | * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, |
205 | * system does not support mode transition. | 168 | * system does not support mode transition. |
206 | */ | 169 | */ |
207 | if (!acpi_gbl_FADT->smi_cmd) { | 170 | if (!acpi_gbl_FADT.smi_command) { |
208 | return_UINT32(ACPI_SYS_MODE_ACPI); | 171 | return_UINT32(ACPI_SYS_MODE_ACPI); |
209 | } | 172 | } |
210 | 173 | ||
211 | status = | 174 | status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value); |
212 | acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK); | ||
213 | if (ACPI_FAILURE(status)) { | 175 | if (ACPI_FAILURE(status)) { |
214 | return_UINT32(ACPI_SYS_MODE_LEGACY); | 176 | return_UINT32(ACPI_SYS_MODE_LEGACY); |
215 | } | 177 | } |
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c index 608a3a60ee11..117a05cadaaa 100644 --- a/drivers/acpi/hardware/hwgpe.c +++ b/drivers/acpi/hardware/hwgpe.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -105,14 +105,20 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info) | |||
105 | acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) | 105 | acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) |
106 | { | 106 | { |
107 | acpi_status status; | 107 | acpi_status status; |
108 | u8 register_bit; | ||
108 | 109 | ||
109 | ACPI_FUNCTION_ENTRY(); | 110 | ACPI_FUNCTION_ENTRY(); |
110 | 111 | ||
112 | register_bit = (u8) | ||
113 | (1 << | ||
114 | (gpe_event_info->gpe_number - | ||
115 | gpe_event_info->register_info->base_gpe_number)); | ||
116 | |||
111 | /* | 117 | /* |
112 | * Write a one to the appropriate bit in the status register to | 118 | * Write a one to the appropriate bit in the status register to |
113 | * clear this GPE. | 119 | * clear this GPE. |
114 | */ | 120 | */ |
115 | status = acpi_hw_low_level_write(8, gpe_event_info->register_bit, | 121 | status = acpi_hw_low_level_write(8, register_bit, |
116 | &gpe_event_info->register_info-> | 122 | &gpe_event_info->register_info-> |
117 | status_address); | 123 | status_address); |
118 | 124 | ||
@@ -155,7 +161,10 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
155 | 161 | ||
156 | /* Get the register bitmask for this GPE */ | 162 | /* Get the register bitmask for this GPE */ |
157 | 163 | ||
158 | register_bit = gpe_event_info->register_bit; | 164 | register_bit = (u8) |
165 | (1 << | ||
166 | (gpe_event_info->gpe_number - | ||
167 | gpe_event_info->register_info->base_gpe_number)); | ||
159 | 168 | ||
160 | /* GPE currently enabled? (enabled for runtime?) */ | 169 | /* GPE currently enabled? (enabled for runtime?) */ |
161 | 170 | ||
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c index fa58c1edce1e..1d371fa663f2 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/hardware/hwregs.c | |||
@@ -7,7 +7,7 @@ | |||
7 | ******************************************************************************/ | 7 | ******************************************************************************/ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Copyright (C) 2000 - 2006, R. Byron Moore | 10 | * Copyright (C) 2000 - 2007, R. Byron Moore |
11 | * All rights reserved. | 11 | * All rights reserved. |
12 | * | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without |
@@ -54,17 +54,15 @@ ACPI_MODULE_NAME("hwregs") | |||
54 | * | 54 | * |
55 | * FUNCTION: acpi_hw_clear_acpi_status | 55 | * FUNCTION: acpi_hw_clear_acpi_status |
56 | * | 56 | * |
57 | * PARAMETERS: Flags - Lock the hardware or not | 57 | * PARAMETERS: None |
58 | * | 58 | * |
59 | * RETURN: none | 59 | * RETURN: None |
60 | * | 60 | * |
61 | * DESCRIPTION: Clears all fixed and general purpose status bits | 61 | * DESCRIPTION: Clears all fixed and general purpose status bits |
62 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | 62 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED |
63 | * | 63 | * |
64 | * NOTE: TBD: Flags parameter is obsolete, to be removed | ||
65 | * | ||
66 | ******************************************************************************/ | 64 | ******************************************************************************/ |
67 | acpi_status acpi_hw_clear_acpi_status(u32 flags) | 65 | acpi_status acpi_hw_clear_acpi_status(void) |
68 | { | 66 | { |
69 | acpi_status status; | 67 | acpi_status status; |
70 | acpi_cpu_flags lock_flags = 0; | 68 | acpi_cpu_flags lock_flags = 0; |
@@ -73,7 +71,7 @@ acpi_status acpi_hw_clear_acpi_status(u32 flags) | |||
73 | 71 | ||
74 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", | 72 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", |
75 | ACPI_BITMASK_ALL_FIXED_STATUS, | 73 | ACPI_BITMASK_ALL_FIXED_STATUS, |
76 | (u16) acpi_gbl_FADT->xpm1a_evt_blk.address)); | 74 | (u16) acpi_gbl_FADT.xpm1a_event_block.address)); |
77 | 75 | ||
78 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 76 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); |
79 | 77 | ||
@@ -86,10 +84,10 @@ acpi_status acpi_hw_clear_acpi_status(u32 flags) | |||
86 | 84 | ||
87 | /* Clear the fixed events */ | 85 | /* Clear the fixed events */ |
88 | 86 | ||
89 | if (acpi_gbl_FADT->xpm1b_evt_blk.address) { | 87 | if (acpi_gbl_FADT.xpm1b_event_block.address) { |
90 | status = | 88 | status = |
91 | acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, | 89 | acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, |
92 | &acpi_gbl_FADT->xpm1b_evt_blk); | 90 | &acpi_gbl_FADT.xpm1b_event_block); |
93 | if (ACPI_FAILURE(status)) { | 91 | if (ACPI_FAILURE(status)) { |
94 | goto unlock_and_exit; | 92 | goto unlock_and_exit; |
95 | } | 93 | } |
@@ -253,18 +251,15 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) | |||
253 | * | 251 | * |
254 | * PARAMETERS: register_id - ID of ACPI bit_register to access | 252 | * PARAMETERS: register_id - ID of ACPI bit_register to access |
255 | * return_value - Value that was read from the register | 253 | * return_value - Value that was read from the register |
256 | * Flags - Lock the hardware or not | ||
257 | * | 254 | * |
258 | * RETURN: Status and the value read from specified Register. Value | 255 | * RETURN: Status and the value read from specified Register. Value |
259 | * returned is normalized to bit0 (is shifted all the way right) | 256 | * returned is normalized to bit0 (is shifted all the way right) |
260 | * | 257 | * |
261 | * DESCRIPTION: ACPI bit_register read function. | 258 | * DESCRIPTION: ACPI bit_register read function. |
262 | * | 259 | * |
263 | * NOTE: TBD: Flags parameter is obsolete, to be removed | ||
264 | * | ||
265 | ******************************************************************************/ | 260 | ******************************************************************************/ |
266 | 261 | ||
267 | acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags) | 262 | acpi_status acpi_get_register(u32 register_id, u32 * return_value) |
268 | { | 263 | { |
269 | u32 register_value = 0; | 264 | u32 register_value = 0; |
270 | struct acpi_bit_register_info *bit_reg_info; | 265 | struct acpi_bit_register_info *bit_reg_info; |
@@ -312,16 +307,13 @@ ACPI_EXPORT_SYMBOL(acpi_get_register) | |||
312 | * PARAMETERS: register_id - ID of ACPI bit_register to access | 307 | * PARAMETERS: register_id - ID of ACPI bit_register to access |
313 | * Value - (only used on write) value to write to the | 308 | * Value - (only used on write) value to write to the |
314 | * Register, NOT pre-normalized to the bit pos | 309 | * Register, NOT pre-normalized to the bit pos |
315 | * Flags - Lock the hardware or not | ||
316 | * | 310 | * |
317 | * RETURN: Status | 311 | * RETURN: Status |
318 | * | 312 | * |
319 | * DESCRIPTION: ACPI Bit Register write function. | 313 | * DESCRIPTION: ACPI Bit Register write function. |
320 | * | 314 | * |
321 | * NOTE: TBD: Flags parameter is obsolete, to be removed | ||
322 | * | ||
323 | ******************************************************************************/ | 315 | ******************************************************************************/ |
324 | acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) | 316 | acpi_status acpi_set_register(u32 register_id, u32 value) |
325 | { | 317 | { |
326 | u32 register_value = 0; | 318 | u32 register_value = 0; |
327 | struct acpi_bit_register_info *bit_reg_info; | 319 | struct acpi_bit_register_info *bit_reg_info; |
@@ -422,8 +414,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) | |||
422 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 414 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
423 | "PM2 control: Read %X from %8.8X%8.8X\n", | 415 | "PM2 control: Read %X from %8.8X%8.8X\n", |
424 | register_value, | 416 | register_value, |
425 | ACPI_FORMAT_UINT64(acpi_gbl_FADT-> | 417 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. |
426 | xpm2_cnt_blk.address))); | 418 | xpm2_control_block. |
419 | address))); | ||
427 | 420 | ||
428 | ACPI_REGISTER_INSERT_VALUE(register_value, | 421 | ACPI_REGISTER_INSERT_VALUE(register_value, |
429 | bit_reg_info->bit_position, | 422 | bit_reg_info->bit_position, |
@@ -433,8 +426,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) | |||
433 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 426 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
434 | "About to write %4.4X to %8.8X%8.8X\n", | 427 | "About to write %4.4X to %8.8X%8.8X\n", |
435 | register_value, | 428 | register_value, |
436 | ACPI_FORMAT_UINT64(acpi_gbl_FADT-> | 429 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. |
437 | xpm2_cnt_blk.address))); | 430 | xpm2_control_block. |
431 | address))); | ||
438 | 432 | ||
439 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 433 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, |
440 | ACPI_REGISTER_PM2_CONTROL, | 434 | ACPI_REGISTER_PM2_CONTROL, |
@@ -495,7 +489,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) | |||
495 | 489 | ||
496 | status = | 490 | status = |
497 | acpi_hw_low_level_read(16, &value1, | 491 | acpi_hw_low_level_read(16, &value1, |
498 | &acpi_gbl_FADT->xpm1a_evt_blk); | 492 | &acpi_gbl_FADT.xpm1a_event_block); |
499 | if (ACPI_FAILURE(status)) { | 493 | if (ACPI_FAILURE(status)) { |
500 | goto unlock_and_exit; | 494 | goto unlock_and_exit; |
501 | } | 495 | } |
@@ -504,7 +498,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) | |||
504 | 498 | ||
505 | status = | 499 | status = |
506 | acpi_hw_low_level_read(16, &value2, | 500 | acpi_hw_low_level_read(16, &value2, |
507 | &acpi_gbl_FADT->xpm1b_evt_blk); | 501 | &acpi_gbl_FADT.xpm1b_event_block); |
508 | value1 |= value2; | 502 | value1 |= value2; |
509 | break; | 503 | break; |
510 | 504 | ||
@@ -527,14 +521,14 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) | |||
527 | 521 | ||
528 | status = | 522 | status = |
529 | acpi_hw_low_level_read(16, &value1, | 523 | acpi_hw_low_level_read(16, &value1, |
530 | &acpi_gbl_FADT->xpm1a_cnt_blk); | 524 | &acpi_gbl_FADT.xpm1a_control_block); |
531 | if (ACPI_FAILURE(status)) { | 525 | if (ACPI_FAILURE(status)) { |
532 | goto unlock_and_exit; | 526 | goto unlock_and_exit; |
533 | } | 527 | } |
534 | 528 | ||
535 | status = | 529 | status = |
536 | acpi_hw_low_level_read(16, &value2, | 530 | acpi_hw_low_level_read(16, &value2, |
537 | &acpi_gbl_FADT->xpm1b_cnt_blk); | 531 | &acpi_gbl_FADT.xpm1b_control_block); |
538 | value1 |= value2; | 532 | value1 |= value2; |
539 | break; | 533 | break; |
540 | 534 | ||
@@ -542,19 +536,20 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) | |||
542 | 536 | ||
543 | status = | 537 | status = |
544 | acpi_hw_low_level_read(8, &value1, | 538 | acpi_hw_low_level_read(8, &value1, |
545 | &acpi_gbl_FADT->xpm2_cnt_blk); | 539 | &acpi_gbl_FADT.xpm2_control_block); |
546 | break; | 540 | break; |
547 | 541 | ||
548 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 542 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
549 | 543 | ||
550 | status = | 544 | status = |
551 | acpi_hw_low_level_read(32, &value1, | 545 | acpi_hw_low_level_read(32, &value1, |
552 | &acpi_gbl_FADT->xpm_tmr_blk); | 546 | &acpi_gbl_FADT.xpm_timer_block); |
553 | break; | 547 | break; |
554 | 548 | ||
555 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 549 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
556 | 550 | ||
557 | status = acpi_os_read_port(acpi_gbl_FADT->smi_cmd, &value1, 8); | 551 | status = |
552 | acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8); | ||
558 | break; | 553 | break; |
559 | 554 | ||
560 | default: | 555 | default: |
@@ -635,7 +630,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) | |||
635 | 630 | ||
636 | status = | 631 | status = |
637 | acpi_hw_low_level_write(16, value, | 632 | acpi_hw_low_level_write(16, value, |
638 | &acpi_gbl_FADT->xpm1a_evt_blk); | 633 | &acpi_gbl_FADT.xpm1a_event_block); |
639 | if (ACPI_FAILURE(status)) { | 634 | if (ACPI_FAILURE(status)) { |
640 | goto unlock_and_exit; | 635 | goto unlock_and_exit; |
641 | } | 636 | } |
@@ -644,7 +639,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) | |||
644 | 639 | ||
645 | status = | 640 | status = |
646 | acpi_hw_low_level_write(16, value, | 641 | acpi_hw_low_level_write(16, value, |
647 | &acpi_gbl_FADT->xpm1b_evt_blk); | 642 | &acpi_gbl_FADT.xpm1b_event_block); |
648 | break; | 643 | break; |
649 | 644 | ||
650 | case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ | 645 | case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ |
@@ -682,49 +677,50 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) | |||
682 | 677 | ||
683 | status = | 678 | status = |
684 | acpi_hw_low_level_write(16, value, | 679 | acpi_hw_low_level_write(16, value, |
685 | &acpi_gbl_FADT->xpm1a_cnt_blk); | 680 | &acpi_gbl_FADT.xpm1a_control_block); |
686 | if (ACPI_FAILURE(status)) { | 681 | if (ACPI_FAILURE(status)) { |
687 | goto unlock_and_exit; | 682 | goto unlock_and_exit; |
688 | } | 683 | } |
689 | 684 | ||
690 | status = | 685 | status = |
691 | acpi_hw_low_level_write(16, value, | 686 | acpi_hw_low_level_write(16, value, |
692 | &acpi_gbl_FADT->xpm1b_cnt_blk); | 687 | &acpi_gbl_FADT.xpm1b_control_block); |
693 | break; | 688 | break; |
694 | 689 | ||
695 | case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ | 690 | case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ |
696 | 691 | ||
697 | status = | 692 | status = |
698 | acpi_hw_low_level_write(16, value, | 693 | acpi_hw_low_level_write(16, value, |
699 | &acpi_gbl_FADT->xpm1a_cnt_blk); | 694 | &acpi_gbl_FADT.xpm1a_control_block); |
700 | break; | 695 | break; |
701 | 696 | ||
702 | case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ | 697 | case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ |
703 | 698 | ||
704 | status = | 699 | status = |
705 | acpi_hw_low_level_write(16, value, | 700 | acpi_hw_low_level_write(16, value, |
706 | &acpi_gbl_FADT->xpm1b_cnt_blk); | 701 | &acpi_gbl_FADT.xpm1b_control_block); |
707 | break; | 702 | break; |
708 | 703 | ||
709 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ | 704 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ |
710 | 705 | ||
711 | status = | 706 | status = |
712 | acpi_hw_low_level_write(8, value, | 707 | acpi_hw_low_level_write(8, value, |
713 | &acpi_gbl_FADT->xpm2_cnt_blk); | 708 | &acpi_gbl_FADT.xpm2_control_block); |
714 | break; | 709 | break; |
715 | 710 | ||
716 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 711 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
717 | 712 | ||
718 | status = | 713 | status = |
719 | acpi_hw_low_level_write(32, value, | 714 | acpi_hw_low_level_write(32, value, |
720 | &acpi_gbl_FADT->xpm_tmr_blk); | 715 | &acpi_gbl_FADT.xpm_timer_block); |
721 | break; | 716 | break; |
722 | 717 | ||
723 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 718 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
724 | 719 | ||
725 | /* SMI_CMD is currently always in IO space */ | 720 | /* SMI_CMD is currently always in IO space */ |
726 | 721 | ||
727 | status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, value, 8); | 722 | status = |
723 | acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8); | ||
728 | break; | 724 | break; |
729 | 725 | ||
730 | default: | 726 | default: |
@@ -783,7 +779,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) | |||
783 | * Two address spaces supported: Memory or IO. | 779 | * Two address spaces supported: Memory or IO. |
784 | * PCI_Config is not supported here because the GAS struct is insufficient | 780 | * PCI_Config is not supported here because the GAS struct is insufficient |
785 | */ | 781 | */ |
786 | switch (reg->address_space_id) { | 782 | switch (reg->space_id) { |
787 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 783 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
788 | 784 | ||
789 | status = acpi_os_read_memory((acpi_physical_address) address, | 785 | status = acpi_os_read_memory((acpi_physical_address) address, |
@@ -792,22 +788,20 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) | |||
792 | 788 | ||
793 | case ACPI_ADR_SPACE_SYSTEM_IO: | 789 | case ACPI_ADR_SPACE_SYSTEM_IO: |
794 | 790 | ||
795 | status = acpi_os_read_port((acpi_io_address) address, | 791 | status = |
796 | value, width); | 792 | acpi_os_read_port((acpi_io_address) address, value, width); |
797 | break; | 793 | break; |
798 | 794 | ||
799 | default: | 795 | default: |
800 | ACPI_ERROR((AE_INFO, | 796 | ACPI_ERROR((AE_INFO, |
801 | "Unsupported address space: %X", | 797 | "Unsupported address space: %X", reg->space_id)); |
802 | reg->address_space_id)); | ||
803 | return (AE_BAD_PARAMETER); | 798 | return (AE_BAD_PARAMETER); |
804 | } | 799 | } |
805 | 800 | ||
806 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 801 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
807 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", | 802 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", |
808 | *value, width, | 803 | *value, width, ACPI_FORMAT_UINT64(address), |
809 | ACPI_FORMAT_UINT64(address), | 804 | acpi_ut_get_region_name(reg->space_id))); |
810 | acpi_ut_get_region_name(reg->address_space_id))); | ||
811 | 805 | ||
812 | return (status); | 806 | return (status); |
813 | } | 807 | } |
@@ -854,7 +848,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) | |||
854 | * Two address spaces supported: Memory or IO. | 848 | * Two address spaces supported: Memory or IO. |
855 | * PCI_Config is not supported here because the GAS struct is insufficient | 849 | * PCI_Config is not supported here because the GAS struct is insufficient |
856 | */ | 850 | */ |
857 | switch (reg->address_space_id) { | 851 | switch (reg->space_id) { |
858 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 852 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
859 | 853 | ||
860 | status = acpi_os_write_memory((acpi_physical_address) address, | 854 | status = acpi_os_write_memory((acpi_physical_address) address, |
@@ -863,22 +857,20 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) | |||
863 | 857 | ||
864 | case ACPI_ADR_SPACE_SYSTEM_IO: | 858 | case ACPI_ADR_SPACE_SYSTEM_IO: |
865 | 859 | ||
866 | status = acpi_os_write_port((acpi_io_address) address, | 860 | status = acpi_os_write_port((acpi_io_address) address, value, |
867 | value, width); | 861 | width); |
868 | break; | 862 | break; |
869 | 863 | ||
870 | default: | 864 | default: |
871 | ACPI_ERROR((AE_INFO, | 865 | ACPI_ERROR((AE_INFO, |
872 | "Unsupported address space: %X", | 866 | "Unsupported address space: %X", reg->space_id)); |
873 | reg->address_space_id)); | ||
874 | return (AE_BAD_PARAMETER); | 867 | return (AE_BAD_PARAMETER); |
875 | } | 868 | } |
876 | 869 | ||
877 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 870 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
878 | "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", | 871 | "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", |
879 | value, width, | 872 | value, width, ACPI_FORMAT_UINT64(address), |
880 | ACPI_FORMAT_UINT64(address), | 873 | acpi_ut_get_region_name(reg->space_id))); |
881 | acpi_ut_get_region_name(reg->address_space_id))); | ||
882 | 874 | ||
883 | return (status); | 875 | return (status); |
884 | } | 876 | } |
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 8bb43cae60c2..57901ca3ade9 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -43,6 +43,7 @@ | |||
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
46 | #include <acpi/actables.h> | ||
46 | 47 | ||
47 | #define _COMPONENT ACPI_HARDWARE | 48 | #define _COMPONENT ACPI_HARDWARE |
48 | ACPI_MODULE_NAME("hwsleep") | 49 | ACPI_MODULE_NAME("hwsleep") |
@@ -62,17 +63,32 @@ ACPI_MODULE_NAME("hwsleep") | |||
62 | acpi_status | 63 | acpi_status |
63 | acpi_set_firmware_waking_vector(acpi_physical_address physical_address) | 64 | acpi_set_firmware_waking_vector(acpi_physical_address physical_address) |
64 | { | 65 | { |
66 | struct acpi_table_facs *facs; | ||
67 | acpi_status status; | ||
65 | 68 | ||
66 | ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); | 69 | ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); |
67 | 70 | ||
71 | /* Get the FACS */ | ||
72 | |||
73 | status = | ||
74 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, | ||
75 | (struct acpi_table_header **)&facs); | ||
76 | if (ACPI_FAILURE(status)) { | ||
77 | return_ACPI_STATUS(status); | ||
78 | } | ||
79 | |||
68 | /* Set the vector */ | 80 | /* Set the vector */ |
69 | 81 | ||
70 | if (acpi_gbl_common_fACS.vector_width == 32) { | 82 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { |
71 | *(ACPI_CAST_PTR | 83 | /* |
72 | (u32, acpi_gbl_common_fACS.firmware_waking_vector)) | 84 | * ACPI 1.0 FACS or short table or optional X_ field is zero |
73 | = (u32) physical_address; | 85 | */ |
86 | facs->firmware_waking_vector = (u32) physical_address; | ||
74 | } else { | 87 | } else { |
75 | *acpi_gbl_common_fACS.firmware_waking_vector = physical_address; | 88 | /* |
89 | * ACPI 2.0 FACS with valid X_ field | ||
90 | */ | ||
91 | facs->xfirmware_waking_vector = physical_address; | ||
76 | } | 92 | } |
77 | 93 | ||
78 | return_ACPI_STATUS(AE_OK); | 94 | return_ACPI_STATUS(AE_OK); |
@@ -97,6 +113,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) | |||
97 | acpi_status | 113 | acpi_status |
98 | acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) | 114 | acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) |
99 | { | 115 | { |
116 | struct acpi_table_facs *facs; | ||
117 | acpi_status status; | ||
100 | 118 | ||
101 | ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector); | 119 | ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector); |
102 | 120 | ||
@@ -104,16 +122,29 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) | |||
104 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 122 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
105 | } | 123 | } |
106 | 124 | ||
125 | /* Get the FACS */ | ||
126 | |||
127 | status = | ||
128 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, | ||
129 | (struct acpi_table_header **)&facs); | ||
130 | if (ACPI_FAILURE(status)) { | ||
131 | return_ACPI_STATUS(status); | ||
132 | } | ||
133 | |||
107 | /* Get the vector */ | 134 | /* Get the vector */ |
108 | 135 | ||
109 | if (acpi_gbl_common_fACS.vector_width == 32) { | 136 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { |
110 | *physical_address = (acpi_physical_address) | 137 | /* |
111 | * | 138 | * ACPI 1.0 FACS or short table or optional X_ field is zero |
112 | (ACPI_CAST_PTR | 139 | */ |
113 | (u32, acpi_gbl_common_fACS.firmware_waking_vector)); | 140 | *physical_address = |
141 | (acpi_physical_address) facs->firmware_waking_vector; | ||
114 | } else { | 142 | } else { |
143 | /* | ||
144 | * ACPI 2.0 FACS with valid X_ field | ||
145 | */ | ||
115 | *physical_address = | 146 | *physical_address = |
116 | *acpi_gbl_common_fACS.firmware_waking_vector; | 147 | (acpi_physical_address) facs->xfirmware_waking_vector; |
117 | } | 148 | } |
118 | 149 | ||
119 | return_ACPI_STATUS(AE_OK); | 150 | return_ACPI_STATUS(AE_OK); |
@@ -246,15 +277,14 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
246 | 277 | ||
247 | /* Clear wake status */ | 278 | /* Clear wake status */ |
248 | 279 | ||
249 | status = | 280 | status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); |
250 | acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); | ||
251 | if (ACPI_FAILURE(status)) { | 281 | if (ACPI_FAILURE(status)) { |
252 | return_ACPI_STATUS(status); | 282 | return_ACPI_STATUS(status); |
253 | } | 283 | } |
254 | 284 | ||
255 | /* Clear all fixed and general purpose status bits */ | 285 | /* Clear all fixed and general purpose status bits */ |
256 | 286 | ||
257 | status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); | 287 | status = acpi_hw_clear_acpi_status(); |
258 | if (ACPI_FAILURE(status)) { | 288 | if (ACPI_FAILURE(status)) { |
259 | return_ACPI_STATUS(status); | 289 | return_ACPI_STATUS(status); |
260 | } | 290 | } |
@@ -367,8 +397,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
367 | /* Wait until we enter sleep state */ | 397 | /* Wait until we enter sleep state */ |
368 | 398 | ||
369 | do { | 399 | do { |
370 | status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value, | 400 | status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); |
371 | ACPI_MTX_DO_NOT_LOCK); | ||
372 | if (ACPI_FAILURE(status)) { | 401 | if (ACPI_FAILURE(status)) { |
373 | return_ACPI_STATUS(status); | 402 | return_ACPI_STATUS(status); |
374 | } | 403 | } |
@@ -401,13 +430,12 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) | |||
401 | 430 | ||
402 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); | 431 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); |
403 | 432 | ||
404 | status = | 433 | status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); |
405 | acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); | ||
406 | if (ACPI_FAILURE(status)) { | 434 | if (ACPI_FAILURE(status)) { |
407 | return_ACPI_STATUS(status); | 435 | return_ACPI_STATUS(status); |
408 | } | 436 | } |
409 | 437 | ||
410 | status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); | 438 | status = acpi_hw_clear_acpi_status(); |
411 | if (ACPI_FAILURE(status)) { | 439 | if (ACPI_FAILURE(status)) { |
412 | return_ACPI_STATUS(status); | 440 | return_ACPI_STATUS(status); |
413 | } | 441 | } |
@@ -429,13 +457,12 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) | |||
429 | 457 | ||
430 | ACPI_FLUSH_CPU_CACHE(); | 458 | ACPI_FLUSH_CPU_CACHE(); |
431 | 459 | ||
432 | status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, | 460 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, |
433 | (u32) acpi_gbl_FADT->S4bios_req, 8); | 461 | (u32) acpi_gbl_FADT.S4bios_request, 8); |
434 | 462 | ||
435 | do { | 463 | do { |
436 | acpi_os_stall(1000); | 464 | acpi_os_stall(1000); |
437 | status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value, | 465 | status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); |
438 | ACPI_MTX_DO_NOT_LOCK); | ||
439 | if (ACPI_FAILURE(status)) { | 466 | if (ACPI_FAILURE(status)) { |
440 | return_ACPI_STATUS(status); | 467 | return_ACPI_STATUS(status); |
441 | } | 468 | } |
@@ -568,13 +595,11 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
568 | 595 | ||
569 | (void) | 596 | (void) |
570 | acpi_set_register(acpi_gbl_fixed_event_info | 597 | acpi_set_register(acpi_gbl_fixed_event_info |
571 | [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1, | 598 | [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1); |
572 | ACPI_MTX_DO_NOT_LOCK); | ||
573 | 599 | ||
574 | (void) | 600 | (void) |
575 | acpi_set_register(acpi_gbl_fixed_event_info | 601 | acpi_set_register(acpi_gbl_fixed_event_info |
576 | [ACPI_EVENT_POWER_BUTTON].status_register_id, 1, | 602 | [ACPI_EVENT_POWER_BUTTON].status_register_id, 1); |
577 | ACPI_MTX_DO_NOT_LOCK); | ||
578 | 603 | ||
579 | arg.integer.value = ACPI_SST_WORKING; | 604 | arg.integer.value = ACPI_SST_WORKING; |
580 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); | 605 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); |
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c index c4ec47c939fd..c32eab696acd 100644 --- a/drivers/acpi/hardware/hwtimer.c +++ b/drivers/acpi/hardware/hwtimer.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -66,7 +66,7 @@ acpi_status acpi_get_timer_resolution(u32 * resolution) | |||
66 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 66 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
67 | } | 67 | } |
68 | 68 | ||
69 | if (acpi_gbl_FADT->tmr_val_ext == 0) { | 69 | if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) { |
70 | *resolution = 24; | 70 | *resolution = 24; |
71 | } else { | 71 | } else { |
72 | *resolution = 32; | 72 | *resolution = 32; |
@@ -98,7 +98,8 @@ acpi_status acpi_get_timer(u32 * ticks) | |||
98 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 98 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
99 | } | 99 | } |
100 | 100 | ||
101 | status = acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT->xpm_tmr_blk); | 101 | status = |
102 | acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT.xpm_timer_block); | ||
102 | 103 | ||
103 | return_ACPI_STATUS(status); | 104 | return_ACPI_STATUS(status); |
104 | } | 105 | } |
@@ -153,7 +154,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) | |||
153 | if (start_ticks < end_ticks) { | 154 | if (start_ticks < end_ticks) { |
154 | delta_ticks = end_ticks - start_ticks; | 155 | delta_ticks = end_ticks - start_ticks; |
155 | } else if (start_ticks > end_ticks) { | 156 | } else if (start_ticks > end_ticks) { |
156 | if (acpi_gbl_FADT->tmr_val_ext == 0) { | 157 | if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) { |
157 | 158 | ||
158 | /* 24-bit Timer */ | 159 | /* 24-bit Timer */ |
159 | 160 | ||
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c index 1ba2db671865..8edfb92f7ede 100644 --- a/drivers/acpi/hotkey.c +++ b/drivers/acpi/hotkey.c | |||
@@ -265,8 +265,7 @@ static char *format_result(union acpi_object *object) | |||
265 | 265 | ||
266 | static int hotkey_polling_seq_show(struct seq_file *seq, void *offset) | 266 | static int hotkey_polling_seq_show(struct seq_file *seq, void *offset) |
267 | { | 267 | { |
268 | struct acpi_polling_hotkey *poll_hotkey = | 268 | struct acpi_polling_hotkey *poll_hotkey = seq->private; |
269 | (struct acpi_polling_hotkey *)seq->private; | ||
270 | char *buf; | 269 | char *buf; |
271 | 270 | ||
272 | 271 | ||
@@ -577,7 +576,7 @@ init_poll_hotkey_device(union acpi_hotkey *key, char **config_entry, | |||
577 | if (ACPI_FAILURE(status)) | 576 | if (ACPI_FAILURE(status)) |
578 | goto do_fail_zero; | 577 | goto do_fail_zero; |
579 | key->poll_hotkey.poll_result = | 578 | key->poll_hotkey.poll_result = |
580 | (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL); | 579 | kmalloc(sizeof(union acpi_object), GFP_KERNEL); |
581 | if (!key->poll_hotkey.poll_result) | 580 | if (!key->poll_hotkey.poll_result) |
582 | goto do_fail_zero; | 581 | goto do_fail_zero; |
583 | return AE_OK; | 582 | return AE_OK; |
diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c index 6342e612c203..8338be0990bc 100644 --- a/drivers/acpi/i2c_ec.c +++ b/drivers/acpi/i2c_ec.c | |||
@@ -309,18 +309,16 @@ static int acpi_ec_hc_add(struct acpi_device *device) | |||
309 | return -EINVAL; | 309 | return -EINVAL; |
310 | } | 310 | } |
311 | 311 | ||
312 | ec_hc = kmalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL); | 312 | ec_hc = kzalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL); |
313 | if (!ec_hc) { | 313 | if (!ec_hc) { |
314 | return -ENOMEM; | 314 | return -ENOMEM; |
315 | } | 315 | } |
316 | memset(ec_hc, 0, sizeof(struct acpi_ec_hc)); | ||
317 | 316 | ||
318 | smbus = kmalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL); | 317 | smbus = kzalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL); |
319 | if (!smbus) { | 318 | if (!smbus) { |
320 | kfree(ec_hc); | 319 | kfree(ec_hc); |
321 | return -ENOMEM; | 320 | return -ENOMEM; |
322 | } | 321 | } |
323 | memset(smbus, 0, sizeof(struct acpi_ec_smbus)); | ||
324 | 322 | ||
325 | ec_hc->handle = device->handle; | 323 | ec_hc->handle = device->handle; |
326 | strcpy(acpi_device_name(device), ACPI_EC_HC_DEVICE_NAME); | 324 | strcpy(acpi_device_name(device), ACPI_EC_HC_DEVICE_NAME); |
@@ -393,7 +391,7 @@ static void __exit acpi_ec_hc_exit(void) | |||
393 | 391 | ||
394 | struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device) | 392 | struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device) |
395 | { | 393 | { |
396 | return ((struct acpi_ec_hc *)acpi_driver_data(device->parent)); | 394 | return acpi_driver_data(device->parent); |
397 | } | 395 | } |
398 | 396 | ||
399 | EXPORT_SYMBOL(acpi_get_ec_hc); | 397 | EXPORT_SYMBOL(acpi_get_ec_hc); |
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 003a9876c968..c6144ca66638 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * | 4 | * |
5 | * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net> | 5 | * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net> |
6 | * Copyright (C) 2006 Henrique de Moraes Holschuh <hmh@hmh.eng.br> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -19,10 +20,14 @@ | |||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 21 | */ |
21 | 22 | ||
22 | #define IBM_VERSION "0.12a" | 23 | #define IBM_VERSION "0.13" |
23 | 24 | ||
24 | /* | 25 | /* |
25 | * Changelog: | 26 | * Changelog: |
27 | * | ||
28 | * 2006-11-22 0.13 new maintainer | ||
29 | * changelog now lives in git commit history, and will | ||
30 | * not be updated further in-file. | ||
26 | * | 31 | * |
27 | * 2005-08-17 0.12 fix compilation on 2.6.13-rc kernels | 32 | * 2005-08-17 0.12 fix compilation on 2.6.13-rc kernels |
28 | * 2005-03-17 0.11 support for 600e, 770x | 33 | * 2005-03-17 0.11 support for 600e, 770x |
@@ -77,9 +82,16 @@ | |||
77 | #include <linux/module.h> | 82 | #include <linux/module.h> |
78 | #include <linux/init.h> | 83 | #include <linux/init.h> |
79 | #include <linux/types.h> | 84 | #include <linux/types.h> |
85 | #include <linux/string.h> | ||
86 | |||
80 | #include <linux/proc_fs.h> | 87 | #include <linux/proc_fs.h> |
88 | #include <linux/backlight.h> | ||
81 | #include <asm/uaccess.h> | 89 | #include <asm/uaccess.h> |
82 | 90 | ||
91 | #include <linux/dmi.h> | ||
92 | #include <linux/jiffies.h> | ||
93 | #include <linux/workqueue.h> | ||
94 | |||
83 | #include <acpi/acpi_drivers.h> | 95 | #include <acpi/acpi_drivers.h> |
84 | #include <acpi/acnamesp.h> | 96 | #include <acpi/acnamesp.h> |
85 | 97 | ||
@@ -88,7 +100,7 @@ | |||
88 | #define IBM_FILE "ibm_acpi" | 100 | #define IBM_FILE "ibm_acpi" |
89 | #define IBM_URL "http://ibm-acpi.sf.net/" | 101 | #define IBM_URL "http://ibm-acpi.sf.net/" |
90 | 102 | ||
91 | MODULE_AUTHOR("Borislav Deianov"); | 103 | MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh"); |
92 | MODULE_DESCRIPTION(IBM_DESC); | 104 | MODULE_DESCRIPTION(IBM_DESC); |
93 | MODULE_VERSION(IBM_VERSION); | 105 | MODULE_VERSION(IBM_VERSION); |
94 | MODULE_LICENSE("GPL"); | 106 | MODULE_LICENSE("GPL"); |
@@ -116,28 +128,6 @@ static acpi_handle root_handle = NULL; | |||
116 | static char *object##_path; \ | 128 | static char *object##_path; \ |
117 | static char *object##_paths[] = { paths } | 129 | static char *object##_paths[] = { paths } |
118 | 130 | ||
119 | /* | ||
120 | * The following models are supported to various degrees: | ||
121 | * | ||
122 | * 570, 600e, 600x, 770e, 770x | ||
123 | * A20m, A21e, A21m, A21p, A22p, A30, A30p, A31, A31p | ||
124 | * G40, G41 | ||
125 | * R30, R31, R32, R40, R40e, R50, R50e, R50p, R51 | ||
126 | * T20, T21, T22, T23, T30, T40, T40p, T41, T41p, T42, T42p, T43 | ||
127 | * X20, X21, X22, X23, X24, X30, X31, X40 | ||
128 | * | ||
129 | * The following models have no supported features: | ||
130 | * | ||
131 | * 240, 240x, i1400 | ||
132 | * | ||
133 | * Still missing DSDTs for the following models: | ||
134 | * | ||
135 | * A20p, A22e, A22m | ||
136 | * R52 | ||
137 | * S31 | ||
138 | * T43p | ||
139 | */ | ||
140 | |||
141 | IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */ | 131 | IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */ |
142 | "\\_SB.PCI.ISA.EC", /* 570 */ | 132 | "\\_SB.PCI.ISA.EC", /* 570 */ |
143 | "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */ | 133 | "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */ |
@@ -169,6 +159,7 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */ | |||
169 | #endif | 159 | #endif |
170 | IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */ | 160 | IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */ |
171 | "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */ | 161 | "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */ |
162 | "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */ | ||
172 | "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */ | 163 | "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */ |
173 | ); /* A21e, R30, R31 */ | 164 | ); /* A21e, R30, R31 */ |
174 | 165 | ||
@@ -203,7 +194,7 @@ IBM_HANDLE(led, ec, "SLED", /* 570 */ | |||
203 | IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ | 194 | IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ |
204 | IBM_HANDLE(ecrd, ec, "ECRD"); /* 570 */ | 195 | IBM_HANDLE(ecrd, ec, "ECRD"); /* 570 */ |
205 | IBM_HANDLE(ecwr, ec, "ECWR"); /* 570 */ | 196 | IBM_HANDLE(ecwr, ec, "ECWR"); /* 570 */ |
206 | IBM_HANDLE(fans, ec, "FANS"); /* X31, X40 */ | 197 | IBM_HANDLE(fans, ec, "FANS"); /* X31, X40, X41 */ |
207 | 198 | ||
208 | IBM_HANDLE(gfan, ec, "GFAN", /* 570 */ | 199 | IBM_HANDLE(gfan, ec, "GFAN", /* 570 */ |
209 | "\\FSPD", /* 600e/x, 770e, 770x */ | 200 | "\\FSPD", /* 600e/x, 770e, 770x */ |
@@ -216,6 +207,152 @@ IBM_HANDLE(sfan, ec, "SFAN", /* 570 */ | |||
216 | #define IBM_HKEY_HID "IBM0068" | 207 | #define IBM_HKEY_HID "IBM0068" |
217 | #define IBM_PCI_HID "PNP0A03" | 208 | #define IBM_PCI_HID "PNP0A03" |
218 | 209 | ||
210 | enum thermal_access_mode { | ||
211 | IBMACPI_THERMAL_NONE = 0, /* No thermal support */ | ||
212 | IBMACPI_THERMAL_ACPI_TMP07, /* Use ACPI TMP0-7 */ | ||
213 | IBMACPI_THERMAL_ACPI_UPDT, /* Use ACPI TMP0-7 with UPDT */ | ||
214 | IBMACPI_THERMAL_TPEC_8, /* Use ACPI EC regs, 8 sensors */ | ||
215 | IBMACPI_THERMAL_TPEC_16, /* Use ACPI EC regs, 16 sensors */ | ||
216 | }; | ||
217 | |||
218 | #define IBMACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */ | ||
219 | struct ibm_thermal_sensors_struct { | ||
220 | s32 temp[IBMACPI_MAX_THERMAL_SENSORS]; | ||
221 | }; | ||
222 | |||
223 | /* | ||
224 | * FAN ACCESS MODES | ||
225 | * | ||
226 | * IBMACPI_FAN_RD_ACPI_GFAN: | ||
227 | * ACPI GFAN method: returns fan level | ||
228 | * | ||
229 | * see IBMACPI_FAN_WR_ACPI_SFAN | ||
230 | * EC 0x2f not available if GFAN exists | ||
231 | * | ||
232 | * IBMACPI_FAN_WR_ACPI_SFAN: | ||
233 | * ACPI SFAN method: sets fan level, 0 (stop) to 7 (max) | ||
234 | * | ||
235 | * EC 0x2f might be available *for reading*, but never for writing. | ||
236 | * | ||
237 | * IBMACPI_FAN_WR_TPEC: | ||
238 | * ThinkPad EC register 0x2f (HFSP): fan control loop mode Supported | ||
239 | * on almost all ThinkPads | ||
240 | * | ||
241 | * Fan speed changes of any sort (including those caused by the | ||
242 | * disengaged mode) are usually done slowly by the firmware as the | ||
243 | * maximum ammount of fan duty cycle change per second seems to be | ||
244 | * limited. | ||
245 | * | ||
246 | * Reading is not available if GFAN exists. | ||
247 | * Writing is not available if SFAN exists. | ||
248 | * | ||
249 | * Bits | ||
250 | * 7 automatic mode engaged; | ||
251 | * (default operation mode of the ThinkPad) | ||
252 | * fan level is ignored in this mode. | ||
253 | * 6 disengage mode (takes precedence over bit 7); | ||
254 | * not available on all thinkpads. May disable | ||
255 | * the tachometer, and speeds up fan to 100% duty-cycle, | ||
256 | * which speeds it up far above the standard RPM | ||
257 | * levels. It is not impossible that it could cause | ||
258 | * hardware damage. | ||
259 | * 5-3 unused in some models. Extra bits for fan level | ||
260 | * in others, but still useless as all values above | ||
261 | * 7 map to the same speed as level 7 in these models. | ||
262 | * 2-0 fan level (0..7 usually) | ||
263 | * 0x00 = stop | ||
264 | * 0x07 = max (set when temperatures critical) | ||
265 | * Some ThinkPads may have other levels, see | ||
266 | * IBMACPI_FAN_WR_ACPI_FANS (X31/X40/X41) | ||
267 | * | ||
268 | * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at | ||
269 | * boot. Apparently the EC does not intialize it, so unless ACPI DSDT | ||
270 | * does so, its initial value is meaningless (0x07). | ||
271 | * | ||
272 | * For firmware bugs, refer to: | ||
273 | * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues | ||
274 | * | ||
275 | * ---- | ||
276 | * | ||
277 | * ThinkPad EC register 0x84 (LSB), 0x85 (MSB): | ||
278 | * Main fan tachometer reading (in RPM) | ||
279 | * | ||
280 | * This register is present on all ThinkPads with a new-style EC, and | ||
281 | * it is known not to be present on the A21m/e, and T22, as there is | ||
282 | * something else in offset 0x84 according to the ACPI DSDT. Other | ||
283 | * ThinkPads from this same time period (and earlier) probably lack the | ||
284 | * tachometer as well. | ||
285 | * | ||
286 | * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare | ||
287 | * was never fixed by IBM to report the EC firmware version string | ||
288 | * probably support the tachometer (like the early X models), so | ||
289 | * detecting it is quite hard. We need more data to know for sure. | ||
290 | * | ||
291 | * FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings | ||
292 | * might result. | ||
293 | * | ||
294 | * FIRMWARE BUG: when EC 0x2f bit 6 is set (disengaged mode), this | ||
295 | * register is not invalidated in ThinkPads that disable tachometer | ||
296 | * readings. Thus, the tachometer readings go stale. | ||
297 | * | ||
298 | * For firmware bugs, refer to: | ||
299 | * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues | ||
300 | * | ||
301 | * IBMACPI_FAN_WR_ACPI_FANS: | ||
302 | * ThinkPad X31, X40, X41. Not available in the X60. | ||
303 | * | ||
304 | * FANS ACPI handle: takes three arguments: low speed, medium speed, | ||
305 | * high speed. ACPI DSDT seems to map these three speeds to levels | ||
306 | * as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH | ||
307 | * (this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3") | ||
308 | * | ||
309 | * The speeds are stored on handles | ||
310 | * (FANA:FAN9), (FANC:FANB), (FANE:FAND). | ||
311 | * | ||
312 | * There are three default speed sets, acessible as handles: | ||
313 | * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H | ||
314 | * | ||
315 | * ACPI DSDT switches which set is in use depending on various | ||
316 | * factors. | ||
317 | * | ||
318 | * IBMACPI_FAN_WR_TPEC is also available and should be used to | ||
319 | * command the fan. The X31/X40/X41 seems to have 8 fan levels, | ||
320 | * but the ACPI tables just mention level 7. | ||
321 | */ | ||
322 | |||
323 | enum fan_status_access_mode { | ||
324 | IBMACPI_FAN_NONE = 0, /* No fan status or control */ | ||
325 | IBMACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */ | ||
326 | IBMACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */ | ||
327 | }; | ||
328 | |||
329 | enum fan_control_access_mode { | ||
330 | IBMACPI_FAN_WR_NONE = 0, /* No fan control */ | ||
331 | IBMACPI_FAN_WR_ACPI_SFAN, /* Use ACPI SFAN */ | ||
332 | IBMACPI_FAN_WR_TPEC, /* Use ACPI EC reg 0x2f */ | ||
333 | IBMACPI_FAN_WR_ACPI_FANS, /* Use ACPI FANS and EC reg 0x2f */ | ||
334 | }; | ||
335 | |||
336 | enum fan_control_commands { | ||
337 | IBMACPI_FAN_CMD_SPEED = 0x0001, /* speed command */ | ||
338 | IBMACPI_FAN_CMD_LEVEL = 0x0002, /* level command */ | ||
339 | IBMACPI_FAN_CMD_ENABLE = 0x0004, /* enable/disable cmd, | ||
340 | * and also watchdog cmd */ | ||
341 | }; | ||
342 | |||
343 | enum { /* Fan control constants */ | ||
344 | fan_status_offset = 0x2f, /* EC register 0x2f */ | ||
345 | fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM) | ||
346 | * 0x84 must be read before 0x85 */ | ||
347 | |||
348 | IBMACPI_FAN_EC_DISENGAGED = 0x40, /* EC mode: tachometer | ||
349 | * disengaged */ | ||
350 | IBMACPI_FAN_EC_AUTO = 0x80, /* EC mode: auto fan | ||
351 | * control */ | ||
352 | }; | ||
353 | |||
354 | static char *ibm_thinkpad_ec_found = NULL; | ||
355 | |||
219 | struct ibm_struct { | 356 | struct ibm_struct { |
220 | char *name; | 357 | char *name; |
221 | char param[32]; | 358 | char param[32]; |
@@ -243,6 +380,8 @@ struct ibm_struct { | |||
243 | 380 | ||
244 | static struct proc_dir_entry *proc_dir = NULL; | 381 | static struct proc_dir_entry *proc_dir = NULL; |
245 | 382 | ||
383 | static struct backlight_device *ibm_backlight_device = NULL; | ||
384 | |||
246 | #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") | 385 | #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") |
247 | #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") | 386 | #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") |
248 | #define strlencmp(a,b) (strncmp((a), (b), strlen(b))) | 387 | #define strlencmp(a,b) (strncmp((a), (b), strlen(b))) |
@@ -352,7 +491,7 @@ static char *next_cmd(char **cmds) | |||
352 | return start; | 491 | return start; |
353 | } | 492 | } |
354 | 493 | ||
355 | static int driver_init(void) | 494 | static int ibm_acpi_driver_init(void) |
356 | { | 495 | { |
357 | printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); | 496 | printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); |
358 | printk(IBM_INFO "%s\n", IBM_URL); | 497 | printk(IBM_INFO "%s\n", IBM_URL); |
@@ -581,8 +720,7 @@ static int wan_status(void) | |||
581 | { | 720 | { |
582 | int status; | 721 | int status; |
583 | 722 | ||
584 | if (!wan_supported || | 723 | if (!wan_supported || !acpi_evalf(hkey_handle, &status, "GWAN", "d")) |
585 | !acpi_evalf(hkey_handle, &status, "GWAN", "d")) | ||
586 | status = 0; | 724 | status = 0; |
587 | 725 | ||
588 | return status; | 726 | return status; |
@@ -630,12 +768,15 @@ static int wan_write(char *buf) | |||
630 | return 0; | 768 | return 0; |
631 | } | 769 | } |
632 | 770 | ||
633 | static int video_supported; | 771 | enum video_access_mode { |
634 | static int video_orig_autosw; | 772 | IBMACPI_VIDEO_NONE = 0, |
773 | IBMACPI_VIDEO_570, /* 570 */ | ||
774 | IBMACPI_VIDEO_770, /* 600e/x, 770e, 770x */ | ||
775 | IBMACPI_VIDEO_NEW, /* all others */ | ||
776 | }; | ||
635 | 777 | ||
636 | #define VIDEO_570 1 | 778 | static enum video_access_mode video_supported; |
637 | #define VIDEO_770 2 | 779 | static int video_orig_autosw; |
638 | #define VIDEO_NEW 3 | ||
639 | 780 | ||
640 | static int video_init(void) | 781 | static int video_init(void) |
641 | { | 782 | { |
@@ -647,16 +788,16 @@ static int video_init(void) | |||
647 | 788 | ||
648 | if (!vid_handle) | 789 | if (!vid_handle) |
649 | /* video switching not supported on R30, R31 */ | 790 | /* video switching not supported on R30, R31 */ |
650 | video_supported = 0; | 791 | video_supported = IBMACPI_VIDEO_NONE; |
651 | else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd")) | 792 | else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd")) |
652 | /* 570 */ | 793 | /* 570 */ |
653 | video_supported = VIDEO_570; | 794 | video_supported = IBMACPI_VIDEO_570; |
654 | else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd")) | 795 | else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd")) |
655 | /* 600e/x, 770e, 770x */ | 796 | /* 600e/x, 770e, 770x */ |
656 | video_supported = VIDEO_770; | 797 | video_supported = IBMACPI_VIDEO_770; |
657 | else | 798 | else |
658 | /* all others */ | 799 | /* all others */ |
659 | video_supported = VIDEO_NEW; | 800 | video_supported = IBMACPI_VIDEO_NEW; |
660 | 801 | ||
661 | return 0; | 802 | return 0; |
662 | } | 803 | } |
@@ -666,15 +807,15 @@ static int video_status(void) | |||
666 | int status = 0; | 807 | int status = 0; |
667 | int i; | 808 | int i; |
668 | 809 | ||
669 | if (video_supported == VIDEO_570) { | 810 | if (video_supported == IBMACPI_VIDEO_570) { |
670 | if (acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 0x87)) | 811 | if (acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 0x87)) |
671 | status = i & 3; | 812 | status = i & 3; |
672 | } else if (video_supported == VIDEO_770) { | 813 | } else if (video_supported == IBMACPI_VIDEO_770) { |
673 | if (acpi_evalf(NULL, &i, "\\VCDL", "d")) | 814 | if (acpi_evalf(NULL, &i, "\\VCDL", "d")) |
674 | status |= 0x01 * i; | 815 | status |= 0x01 * i; |
675 | if (acpi_evalf(NULL, &i, "\\VCDC", "d")) | 816 | if (acpi_evalf(NULL, &i, "\\VCDC", "d")) |
676 | status |= 0x02 * i; | 817 | status |= 0x02 * i; |
677 | } else if (video_supported == VIDEO_NEW) { | 818 | } else if (video_supported == IBMACPI_VIDEO_NEW) { |
678 | acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1); | 819 | acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1); |
679 | if (acpi_evalf(NULL, &i, "\\VCDC", "d")) | 820 | if (acpi_evalf(NULL, &i, "\\VCDC", "d")) |
680 | status |= 0x02 * i; | 821 | status |= 0x02 * i; |
@@ -693,9 +834,10 @@ static int video_autosw(void) | |||
693 | { | 834 | { |
694 | int autosw = 0; | 835 | int autosw = 0; |
695 | 836 | ||
696 | if (video_supported == VIDEO_570) | 837 | if (video_supported == IBMACPI_VIDEO_570) |
697 | acpi_evalf(vid_handle, &autosw, "SWIT", "d"); | 838 | acpi_evalf(vid_handle, &autosw, "SWIT", "d"); |
698 | else if (video_supported == VIDEO_770 || video_supported == VIDEO_NEW) | 839 | else if (video_supported == IBMACPI_VIDEO_770 || |
840 | video_supported == IBMACPI_VIDEO_NEW) | ||
699 | acpi_evalf(vid_handle, &autosw, "^VDEE", "d"); | 841 | acpi_evalf(vid_handle, &autosw, "^VDEE", "d"); |
700 | 842 | ||
701 | return autosw & 1; | 843 | return autosw & 1; |
@@ -715,12 +857,12 @@ static int video_read(char *p) | |||
715 | len += sprintf(p + len, "status:\t\tsupported\n"); | 857 | len += sprintf(p + len, "status:\t\tsupported\n"); |
716 | len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0)); | 858 | len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0)); |
717 | len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1)); | 859 | len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1)); |
718 | if (video_supported == VIDEO_NEW) | 860 | if (video_supported == IBMACPI_VIDEO_NEW) |
719 | len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3)); | 861 | len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3)); |
720 | len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0)); | 862 | len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0)); |
721 | len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n"); | 863 | len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n"); |
722 | len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n"); | 864 | len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n"); |
723 | if (video_supported == VIDEO_NEW) | 865 | if (video_supported == IBMACPI_VIDEO_NEW) |
724 | len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n"); | 866 | len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n"); |
725 | len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n"); | 867 | len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n"); |
726 | len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n"); | 868 | len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n"); |
@@ -735,7 +877,7 @@ static int video_switch(void) | |||
735 | 877 | ||
736 | if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1)) | 878 | if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1)) |
737 | return -EIO; | 879 | return -EIO; |
738 | ret = video_supported == VIDEO_570 ? | 880 | ret = video_supported == IBMACPI_VIDEO_570 ? |
739 | acpi_evalf(ec_handle, NULL, "_Q16", "v") : | 881 | acpi_evalf(ec_handle, NULL, "_Q16", "v") : |
740 | acpi_evalf(vid_handle, NULL, "VSWT", "v"); | 882 | acpi_evalf(vid_handle, NULL, "VSWT", "v"); |
741 | acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw); | 883 | acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw); |
@@ -745,9 +887,9 @@ static int video_switch(void) | |||
745 | 887 | ||
746 | static int video_expand(void) | 888 | static int video_expand(void) |
747 | { | 889 | { |
748 | if (video_supported == VIDEO_570) | 890 | if (video_supported == IBMACPI_VIDEO_570) |
749 | return acpi_evalf(ec_handle, NULL, "_Q17", "v"); | 891 | return acpi_evalf(ec_handle, NULL, "_Q17", "v"); |
750 | else if (video_supported == VIDEO_770) | 892 | else if (video_supported == IBMACPI_VIDEO_770) |
751 | return acpi_evalf(vid_handle, NULL, "VEXP", "v"); | 893 | return acpi_evalf(vid_handle, NULL, "VEXP", "v"); |
752 | else | 894 | else |
753 | return acpi_evalf(NULL, NULL, "\\VEXP", "v"); | 895 | return acpi_evalf(NULL, NULL, "\\VEXP", "v"); |
@@ -757,10 +899,10 @@ static int video_switch2(int status) | |||
757 | { | 899 | { |
758 | int ret; | 900 | int ret; |
759 | 901 | ||
760 | if (video_supported == VIDEO_570) { | 902 | if (video_supported == IBMACPI_VIDEO_570) { |
761 | ret = acpi_evalf(NULL, NULL, | 903 | ret = acpi_evalf(NULL, NULL, |
762 | "\\_SB.PHS2", "vdd", 0x8b, status | 0x80); | 904 | "\\_SB.PHS2", "vdd", 0x8b, status | 0x80); |
763 | } else if (video_supported == VIDEO_770) { | 905 | } else if (video_supported == IBMACPI_VIDEO_770) { |
764 | int autosw = video_autosw(); | 906 | int autosw = video_autosw(); |
765 | if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1)) | 907 | if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1)) |
766 | return -EIO; | 908 | return -EIO; |
@@ -796,10 +938,10 @@ static int video_write(char *buf) | |||
796 | enable |= 0x02; | 938 | enable |= 0x02; |
797 | } else if (strlencmp(cmd, "crt_disable") == 0) { | 939 | } else if (strlencmp(cmd, "crt_disable") == 0) { |
798 | disable |= 0x02; | 940 | disable |= 0x02; |
799 | } else if (video_supported == VIDEO_NEW && | 941 | } else if (video_supported == IBMACPI_VIDEO_NEW && |
800 | strlencmp(cmd, "dvi_enable") == 0) { | 942 | strlencmp(cmd, "dvi_enable") == 0) { |
801 | enable |= 0x08; | 943 | enable |= 0x08; |
802 | } else if (video_supported == VIDEO_NEW && | 944 | } else if (video_supported == IBMACPI_VIDEO_NEW && |
803 | strlencmp(cmd, "dvi_disable") == 0) { | 945 | strlencmp(cmd, "dvi_disable") == 0) { |
804 | disable |= 0x08; | 946 | disable |= 0x08; |
805 | } else if (strlencmp(cmd, "auto_enable") == 0) { | 947 | } else if (strlencmp(cmd, "auto_enable") == 0) { |
@@ -907,6 +1049,7 @@ static int _sta(acpi_handle handle) | |||
907 | 1049 | ||
908 | return status; | 1050 | return status; |
909 | } | 1051 | } |
1052 | |||
910 | #ifdef CONFIG_ACPI_IBM_DOCK | 1053 | #ifdef CONFIG_ACPI_IBM_DOCK |
911 | #define dock_docked() (_sta(dock_handle) & 1) | 1054 | #define dock_docked() (_sta(dock_handle) & 1) |
912 | 1055 | ||
@@ -1094,26 +1237,28 @@ static int cmos_write(char *buf) | |||
1094 | return 0; | 1237 | return 0; |
1095 | } | 1238 | } |
1096 | 1239 | ||
1097 | static int led_supported; | 1240 | enum led_access_mode { |
1098 | 1241 | IBMACPI_LED_NONE = 0, | |
1099 | #define LED_570 1 | 1242 | IBMACPI_LED_570, /* 570 */ |
1100 | #define LED_OLD 2 | 1243 | IBMACPI_LED_OLD, /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ |
1101 | #define LED_NEW 3 | 1244 | IBMACPI_LED_NEW, /* all others */ |
1245 | }; | ||
1246 | static enum led_access_mode led_supported; | ||
1102 | 1247 | ||
1103 | static int led_init(void) | 1248 | static int led_init(void) |
1104 | { | 1249 | { |
1105 | if (!led_handle) | 1250 | if (!led_handle) |
1106 | /* led not supported on R30, R31 */ | 1251 | /* led not supported on R30, R31 */ |
1107 | led_supported = 0; | 1252 | led_supported = IBMACPI_LED_NONE; |
1108 | else if (strlencmp(led_path, "SLED") == 0) | 1253 | else if (strlencmp(led_path, "SLED") == 0) |
1109 | /* 570 */ | 1254 | /* 570 */ |
1110 | led_supported = LED_570; | 1255 | led_supported = IBMACPI_LED_570; |
1111 | else if (strlencmp(led_path, "SYSL") == 0) | 1256 | else if (strlencmp(led_path, "SYSL") == 0) |
1112 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ | 1257 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ |
1113 | led_supported = LED_OLD; | 1258 | led_supported = IBMACPI_LED_OLD; |
1114 | else | 1259 | else |
1115 | /* all others */ | 1260 | /* all others */ |
1116 | led_supported = LED_NEW; | 1261 | led_supported = IBMACPI_LED_NEW; |
1117 | 1262 | ||
1118 | return 0; | 1263 | return 0; |
1119 | } | 1264 | } |
@@ -1130,7 +1275,7 @@ static int led_read(char *p) | |||
1130 | } | 1275 | } |
1131 | len += sprintf(p + len, "status:\t\tsupported\n"); | 1276 | len += sprintf(p + len, "status:\t\tsupported\n"); |
1132 | 1277 | ||
1133 | if (led_supported == LED_570) { | 1278 | if (led_supported == IBMACPI_LED_570) { |
1134 | /* 570 */ | 1279 | /* 570 */ |
1135 | int i, status; | 1280 | int i, status; |
1136 | for (i = 0; i < 8; i++) { | 1281 | for (i = 0; i < 8; i++) { |
@@ -1179,13 +1324,13 @@ static int led_write(char *buf) | |||
1179 | } else | 1324 | } else |
1180 | return -EINVAL; | 1325 | return -EINVAL; |
1181 | 1326 | ||
1182 | if (led_supported == LED_570) { | 1327 | if (led_supported == IBMACPI_LED_570) { |
1183 | /* 570 */ | 1328 | /* 570 */ |
1184 | led = 1 << led; | 1329 | led = 1 << led; |
1185 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", | 1330 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", |
1186 | led, led_sled_arg1[ind])) | 1331 | led, led_sled_arg1[ind])) |
1187 | return -EIO; | 1332 | return -EIO; |
1188 | } else if (led_supported == LED_OLD) { | 1333 | } else if (led_supported == IBMACPI_LED_OLD) { |
1189 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ | 1334 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ |
1190 | led = 1 << led; | 1335 | led = 1 << led; |
1191 | ret = ec_write(EC_HLMS, led); | 1336 | ret = ec_write(EC_HLMS, led); |
@@ -1272,50 +1417,142 @@ static int acpi_ec_write(int i, u8 v) | |||
1272 | return 1; | 1417 | return 1; |
1273 | } | 1418 | } |
1274 | 1419 | ||
1275 | static int thermal_tmp_supported; | 1420 | static enum thermal_access_mode thermal_read_mode; |
1276 | static int thermal_updt_supported; | ||
1277 | 1421 | ||
1278 | static int thermal_init(void) | 1422 | static int thermal_init(void) |
1279 | { | 1423 | { |
1280 | /* temperatures not supported on 570, G4x, R30, R31, R32 */ | 1424 | u8 t, ta1, ta2; |
1281 | thermal_tmp_supported = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); | 1425 | int i; |
1426 | int acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); | ||
1427 | |||
1428 | if (ibm_thinkpad_ec_found && experimental) { | ||
1429 | /* | ||
1430 | * Direct EC access mode: sensors at registers | ||
1431 | * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for | ||
1432 | * non-implemented, thermal sensors return 0x80 when | ||
1433 | * not available | ||
1434 | */ | ||
1282 | 1435 | ||
1283 | /* 600e/x, 770e, 770x */ | 1436 | ta1 = ta2 = 0; |
1284 | thermal_updt_supported = acpi_evalf(ec_handle, NULL, "UPDT", "qv"); | 1437 | for (i = 0; i < 8; i++) { |
1438 | if (likely(acpi_ec_read(0x78 + i, &t))) { | ||
1439 | ta1 |= t; | ||
1440 | } else { | ||
1441 | ta1 = 0; | ||
1442 | break; | ||
1443 | } | ||
1444 | if (likely(acpi_ec_read(0xC0 + i, &t))) { | ||
1445 | ta2 |= t; | ||
1446 | } else { | ||
1447 | ta1 = 0; | ||
1448 | break; | ||
1449 | } | ||
1450 | } | ||
1451 | if (ta1 == 0) { | ||
1452 | /* This is sheer paranoia, but we handle it anyway */ | ||
1453 | if (acpi_tmp7) { | ||
1454 | printk(IBM_ERR | ||
1455 | "ThinkPad ACPI EC access misbehaving, " | ||
1456 | "falling back to ACPI TMPx access mode\n"); | ||
1457 | thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07; | ||
1458 | } else { | ||
1459 | printk(IBM_ERR | ||
1460 | "ThinkPad ACPI EC access misbehaving, " | ||
1461 | "disabling thermal sensors access\n"); | ||
1462 | thermal_read_mode = IBMACPI_THERMAL_NONE; | ||
1463 | } | ||
1464 | } else { | ||
1465 | thermal_read_mode = | ||
1466 | (ta2 != 0) ? | ||
1467 | IBMACPI_THERMAL_TPEC_16 : IBMACPI_THERMAL_TPEC_8; | ||
1468 | } | ||
1469 | } else if (acpi_tmp7) { | ||
1470 | if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) { | ||
1471 | /* 600e/x, 770e, 770x */ | ||
1472 | thermal_read_mode = IBMACPI_THERMAL_ACPI_UPDT; | ||
1473 | } else { | ||
1474 | /* Standard ACPI TMPx access, max 8 sensors */ | ||
1475 | thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07; | ||
1476 | } | ||
1477 | } else { | ||
1478 | /* temperatures not supported on 570, G4x, R30, R31, R32 */ | ||
1479 | thermal_read_mode = IBMACPI_THERMAL_NONE; | ||
1480 | } | ||
1285 | 1481 | ||
1286 | return 0; | 1482 | return 0; |
1287 | } | 1483 | } |
1288 | 1484 | ||
1289 | static int thermal_read(char *p) | 1485 | static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s) |
1290 | { | 1486 | { |
1291 | int len = 0; | 1487 | int i, t; |
1488 | s8 tmp; | ||
1489 | char tmpi[] = "TMPi"; | ||
1292 | 1490 | ||
1293 | if (!thermal_tmp_supported) | 1491 | if (!s) |
1294 | len += sprintf(p + len, "temperatures:\tnot supported\n"); | 1492 | return -EINVAL; |
1295 | else { | ||
1296 | int i, t; | ||
1297 | char tmpi[] = "TMPi"; | ||
1298 | s8 tmp[8]; | ||
1299 | 1493 | ||
1300 | if (thermal_updt_supported) | 1494 | switch (thermal_read_mode) { |
1301 | if (!acpi_evalf(ec_handle, NULL, "UPDT", "v")) | 1495 | #if IBMACPI_MAX_THERMAL_SENSORS >= 16 |
1496 | case IBMACPI_THERMAL_TPEC_16: | ||
1497 | for (i = 0; i < 8; i++) { | ||
1498 | if (!acpi_ec_read(0xC0 + i, &tmp)) | ||
1499 | return -EIO; | ||
1500 | s->temp[i + 8] = tmp * 1000; | ||
1501 | } | ||
1502 | /* fallthrough */ | ||
1503 | #endif | ||
1504 | case IBMACPI_THERMAL_TPEC_8: | ||
1505 | for (i = 0; i < 8; i++) { | ||
1506 | if (!acpi_ec_read(0x78 + i, &tmp)) | ||
1302 | return -EIO; | 1507 | return -EIO; |
1508 | s->temp[i] = tmp * 1000; | ||
1509 | } | ||
1510 | return (thermal_read_mode == IBMACPI_THERMAL_TPEC_16) ? 16 : 8; | ||
1303 | 1511 | ||
1512 | case IBMACPI_THERMAL_ACPI_UPDT: | ||
1513 | if (!acpi_evalf(ec_handle, NULL, "UPDT", "v")) | ||
1514 | return -EIO; | ||
1304 | for (i = 0; i < 8; i++) { | 1515 | for (i = 0; i < 8; i++) { |
1305 | tmpi[3] = '0' + i; | 1516 | tmpi[3] = '0' + i; |
1306 | if (!acpi_evalf(ec_handle, &t, tmpi, "d")) | 1517 | if (!acpi_evalf(ec_handle, &t, tmpi, "d")) |
1307 | return -EIO; | 1518 | return -EIO; |
1308 | if (thermal_updt_supported) | 1519 | s->temp[i] = (t - 2732) * 100; |
1309 | tmp[i] = (t - 2732 + 5) / 10; | ||
1310 | else | ||
1311 | tmp[i] = t; | ||
1312 | } | 1520 | } |
1521 | return 8; | ||
1313 | 1522 | ||
1314 | len += sprintf(p + len, | 1523 | case IBMACPI_THERMAL_ACPI_TMP07: |
1315 | "temperatures:\t%d %d %d %d %d %d %d %d\n", | 1524 | for (i = 0; i < 8; i++) { |
1316 | tmp[0], tmp[1], tmp[2], tmp[3], | 1525 | tmpi[3] = '0' + i; |
1317 | tmp[4], tmp[5], tmp[6], tmp[7]); | 1526 | if (!acpi_evalf(ec_handle, &t, tmpi, "d")) |
1527 | return -EIO; | ||
1528 | s->temp[i] = t * 1000; | ||
1529 | } | ||
1530 | return 8; | ||
1531 | |||
1532 | case IBMACPI_THERMAL_NONE: | ||
1533 | default: | ||
1534 | return 0; | ||
1318 | } | 1535 | } |
1536 | } | ||
1537 | |||
1538 | static int thermal_read(char *p) | ||
1539 | { | ||
1540 | int len = 0; | ||
1541 | int n, i; | ||
1542 | struct ibm_thermal_sensors_struct t; | ||
1543 | |||
1544 | n = thermal_get_sensors(&t); | ||
1545 | if (unlikely(n < 0)) | ||
1546 | return n; | ||
1547 | |||
1548 | len += sprintf(p + len, "temperatures:\t"); | ||
1549 | |||
1550 | if (n > 0) { | ||
1551 | for (i = 0; i < (n - 1); i++) | ||
1552 | len += sprintf(p + len, "%d ", t.temp[i] / 1000); | ||
1553 | len += sprintf(p + len, "%d\n", t.temp[i] / 1000); | ||
1554 | } else | ||
1555 | len += sprintf(p + len, "not supported\n"); | ||
1319 | 1556 | ||
1320 | return len; | 1557 | return len; |
1321 | } | 1558 | } |
@@ -1381,12 +1618,23 @@ static int ecdump_write(char *buf) | |||
1381 | 1618 | ||
1382 | static int brightness_offset = 0x31; | 1619 | static int brightness_offset = 0x31; |
1383 | 1620 | ||
1621 | static int brightness_get(struct backlight_device *bd) | ||
1622 | { | ||
1623 | u8 level; | ||
1624 | if (!acpi_ec_read(brightness_offset, &level)) | ||
1625 | return -EIO; | ||
1626 | |||
1627 | level &= 0x7; | ||
1628 | |||
1629 | return level; | ||
1630 | } | ||
1631 | |||
1384 | static int brightness_read(char *p) | 1632 | static int brightness_read(char *p) |
1385 | { | 1633 | { |
1386 | int len = 0; | 1634 | int len = 0; |
1387 | u8 level; | 1635 | int level; |
1388 | 1636 | ||
1389 | if (!acpi_ec_read(brightness_offset, &level)) { | 1637 | if ((level = brightness_get(NULL)) < 0) { |
1390 | len += sprintf(p + len, "level:\t\tunreadable\n"); | 1638 | len += sprintf(p + len, "level:\t\tunreadable\n"); |
1391 | } else { | 1639 | } else { |
1392 | len += sprintf(p + len, "level:\t\t%d\n", level & 0x7); | 1640 | len += sprintf(p + len, "level:\t\t%d\n", level & 0x7); |
@@ -1401,16 +1649,34 @@ static int brightness_read(char *p) | |||
1401 | #define BRIGHTNESS_UP 4 | 1649 | #define BRIGHTNESS_UP 4 |
1402 | #define BRIGHTNESS_DOWN 5 | 1650 | #define BRIGHTNESS_DOWN 5 |
1403 | 1651 | ||
1404 | static int brightness_write(char *buf) | 1652 | static int brightness_set(int value) |
1405 | { | 1653 | { |
1406 | int cmos_cmd, inc, i; | 1654 | int cmos_cmd, inc, i; |
1407 | u8 level; | 1655 | int current_value = brightness_get(NULL); |
1656 | |||
1657 | value &= 7; | ||
1658 | |||
1659 | cmos_cmd = value > current_value ? BRIGHTNESS_UP : BRIGHTNESS_DOWN; | ||
1660 | inc = value > current_value ? 1 : -1; | ||
1661 | for (i = current_value; i != value; i += inc) { | ||
1662 | if (!cmos_eval(cmos_cmd)) | ||
1663 | return -EIO; | ||
1664 | if (!acpi_ec_write(brightness_offset, i + inc)) | ||
1665 | return -EIO; | ||
1666 | } | ||
1667 | |||
1668 | return 0; | ||
1669 | } | ||
1670 | |||
1671 | static int brightness_write(char *buf) | ||
1672 | { | ||
1673 | int level; | ||
1408 | int new_level; | 1674 | int new_level; |
1409 | char *cmd; | 1675 | char *cmd; |
1410 | 1676 | ||
1411 | while ((cmd = next_cmd(&buf))) { | 1677 | while ((cmd = next_cmd(&buf))) { |
1412 | if (!acpi_ec_read(brightness_offset, &level)) | 1678 | if ((level = brightness_get(NULL)) < 0) |
1413 | return -EIO; | 1679 | return level; |
1414 | level &= 7; | 1680 | level &= 7; |
1415 | 1681 | ||
1416 | if (strlencmp(cmd, "up") == 0) { | 1682 | if (strlencmp(cmd, "up") == 0) { |
@@ -1423,19 +1689,44 @@ static int brightness_write(char *buf) | |||
1423 | } else | 1689 | } else |
1424 | return -EINVAL; | 1690 | return -EINVAL; |
1425 | 1691 | ||
1426 | cmos_cmd = new_level > level ? BRIGHTNESS_UP : BRIGHTNESS_DOWN; | 1692 | brightness_set(new_level); |
1427 | inc = new_level > level ? 1 : -1; | 1693 | } |
1428 | for (i = level; i != new_level; i += inc) { | 1694 | |
1429 | if (!cmos_eval(cmos_cmd)) | 1695 | return 0; |
1430 | return -EIO; | 1696 | } |
1431 | if (!acpi_ec_write(brightness_offset, i + inc)) | 1697 | |
1432 | return -EIO; | 1698 | static int brightness_update_status(struct backlight_device *bd) |
1433 | } | 1699 | { |
1700 | return brightness_set(bd->props->brightness); | ||
1701 | } | ||
1702 | |||
1703 | static struct backlight_properties ibm_backlight_data = { | ||
1704 | .owner = THIS_MODULE, | ||
1705 | .get_brightness = brightness_get, | ||
1706 | .update_status = brightness_update_status, | ||
1707 | .max_brightness = 7, | ||
1708 | }; | ||
1709 | |||
1710 | static int brightness_init(void) | ||
1711 | { | ||
1712 | ibm_backlight_device = backlight_device_register("ibm", NULL, NULL, | ||
1713 | &ibm_backlight_data); | ||
1714 | if (IS_ERR(ibm_backlight_device)) { | ||
1715 | printk(IBM_ERR "Could not register backlight device\n"); | ||
1716 | return PTR_ERR(ibm_backlight_device); | ||
1434 | } | 1717 | } |
1435 | 1718 | ||
1436 | return 0; | 1719 | return 0; |
1437 | } | 1720 | } |
1438 | 1721 | ||
1722 | static void brightness_exit(void) | ||
1723 | { | ||
1724 | if (ibm_backlight_device) { | ||
1725 | backlight_device_unregister(ibm_backlight_device); | ||
1726 | ibm_backlight_device = NULL; | ||
1727 | } | ||
1728 | } | ||
1729 | |||
1439 | static int volume_offset = 0x30; | 1730 | static int volume_offset = 0x30; |
1440 | 1731 | ||
1441 | static int volume_read(char *p) | 1732 | static int volume_read(char *p) |
@@ -1522,90 +1813,486 @@ static int volume_write(char *buf) | |||
1522 | return 0; | 1813 | return 0; |
1523 | } | 1814 | } |
1524 | 1815 | ||
1525 | static int fan_status_offset = 0x2f; | 1816 | static enum fan_status_access_mode fan_status_access_mode; |
1526 | static int fan_rpm_offset = 0x84; | 1817 | static enum fan_control_access_mode fan_control_access_mode; |
1818 | static enum fan_control_commands fan_control_commands; | ||
1527 | 1819 | ||
1528 | static int fan_read(char *p) | 1820 | static int fan_control_status_known; |
1821 | static u8 fan_control_initial_status; | ||
1822 | |||
1823 | static void fan_watchdog_fire(struct work_struct *ignored); | ||
1824 | static int fan_watchdog_maxinterval; | ||
1825 | static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire); | ||
1826 | |||
1827 | static int fan_init(void) | ||
1529 | { | 1828 | { |
1530 | int len = 0; | 1829 | fan_status_access_mode = IBMACPI_FAN_NONE; |
1531 | int s; | 1830 | fan_control_access_mode = IBMACPI_FAN_WR_NONE; |
1532 | u8 lo, hi, status; | 1831 | fan_control_commands = 0; |
1832 | fan_control_status_known = 1; | ||
1833 | fan_watchdog_maxinterval = 0; | ||
1533 | 1834 | ||
1534 | if (gfan_handle) { | 1835 | if (gfan_handle) { |
1535 | /* 570, 600e/x, 770e, 770x */ | 1836 | /* 570, 600e/x, 770e, 770x */ |
1536 | if (!acpi_evalf(gfan_handle, &s, NULL, "d")) | 1837 | fan_status_access_mode = IBMACPI_FAN_RD_ACPI_GFAN; |
1537 | return -EIO; | 1838 | } else { |
1839 | /* all other ThinkPads: note that even old-style | ||
1840 | * ThinkPad ECs supports the fan control register */ | ||
1841 | if (likely(acpi_ec_read(fan_status_offset, | ||
1842 | &fan_control_initial_status))) { | ||
1843 | fan_status_access_mode = IBMACPI_FAN_RD_TPEC; | ||
1844 | |||
1845 | /* In some ThinkPads, neither the EC nor the ACPI | ||
1846 | * DSDT initialize the fan status, and it ends up | ||
1847 | * being set to 0x07 when it *could* be either | ||
1848 | * 0x07 or 0x80. | ||
1849 | * | ||
1850 | * Enable for TP-1Y (T43), TP-78 (R51e), | ||
1851 | * TP-76 (R52), TP-70 (T43, R52), which are known | ||
1852 | * to be buggy. */ | ||
1853 | if (fan_control_initial_status == 0x07 && | ||
1854 | ibm_thinkpad_ec_found && | ||
1855 | ((ibm_thinkpad_ec_found[0] == '1' && | ||
1856 | ibm_thinkpad_ec_found[1] == 'Y') || | ||
1857 | (ibm_thinkpad_ec_found[0] == '7' && | ||
1858 | (ibm_thinkpad_ec_found[1] == '6' || | ||
1859 | ibm_thinkpad_ec_found[1] == '8' || | ||
1860 | ibm_thinkpad_ec_found[1] == '0')) | ||
1861 | )) { | ||
1862 | printk(IBM_NOTICE | ||
1863 | "fan_init: initial fan status is " | ||
1864 | "unknown, assuming it is in auto " | ||
1865 | "mode\n"); | ||
1866 | fan_control_status_known = 0; | ||
1867 | } | ||
1868 | } else { | ||
1869 | printk(IBM_ERR | ||
1870 | "ThinkPad ACPI EC access misbehaving, " | ||
1871 | "fan status and control unavailable\n"); | ||
1872 | return 0; | ||
1873 | } | ||
1874 | } | ||
1538 | 1875 | ||
1539 | len += sprintf(p + len, "level:\t\t%d\n", s); | 1876 | if (sfan_handle) { |
1877 | /* 570, 770x-JL */ | ||
1878 | fan_control_access_mode = IBMACPI_FAN_WR_ACPI_SFAN; | ||
1879 | fan_control_commands |= | ||
1880 | IBMACPI_FAN_CMD_LEVEL | IBMACPI_FAN_CMD_ENABLE; | ||
1540 | } else { | 1881 | } else { |
1882 | if (!gfan_handle) { | ||
1883 | /* gfan without sfan means no fan control */ | ||
1884 | /* all other models implement TP EC 0x2f control */ | ||
1885 | |||
1886 | if (fans_handle) { | ||
1887 | /* X31, X40, X41 */ | ||
1888 | fan_control_access_mode = | ||
1889 | IBMACPI_FAN_WR_ACPI_FANS; | ||
1890 | fan_control_commands |= | ||
1891 | IBMACPI_FAN_CMD_SPEED | | ||
1892 | IBMACPI_FAN_CMD_LEVEL | | ||
1893 | IBMACPI_FAN_CMD_ENABLE; | ||
1894 | } else { | ||
1895 | fan_control_access_mode = IBMACPI_FAN_WR_TPEC; | ||
1896 | fan_control_commands |= | ||
1897 | IBMACPI_FAN_CMD_LEVEL | | ||
1898 | IBMACPI_FAN_CMD_ENABLE; | ||
1899 | } | ||
1900 | } | ||
1901 | } | ||
1902 | |||
1903 | return 0; | ||
1904 | } | ||
1905 | |||
1906 | static int fan_get_status(u8 *status) | ||
1907 | { | ||
1908 | u8 s; | ||
1909 | |||
1910 | /* TODO: | ||
1911 | * Add IBMACPI_FAN_RD_ACPI_FANS ? */ | ||
1912 | |||
1913 | switch (fan_status_access_mode) { | ||
1914 | case IBMACPI_FAN_RD_ACPI_GFAN: | ||
1915 | /* 570, 600e/x, 770e, 770x */ | ||
1916 | |||
1917 | if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) | ||
1918 | return -EIO; | ||
1919 | |||
1920 | if (likely(status)) | ||
1921 | *status = s & 0x07; | ||
1922 | |||
1923 | break; | ||
1924 | |||
1925 | case IBMACPI_FAN_RD_TPEC: | ||
1541 | /* all except 570, 600e/x, 770e, 770x */ | 1926 | /* all except 570, 600e/x, 770e, 770x */ |
1542 | if (!acpi_ec_read(fan_status_offset, &status)) | 1927 | if (unlikely(!acpi_ec_read(fan_status_offset, &s))) |
1543 | len += sprintf(p + len, "status:\t\tunreadable\n"); | 1928 | return -EIO; |
1544 | else | ||
1545 | len += sprintf(p + len, "status:\t\t%s\n", | ||
1546 | enabled(status, 7)); | ||
1547 | 1929 | ||
1548 | if (!acpi_ec_read(fan_rpm_offset, &lo) || | 1930 | if (likely(status)) |
1549 | !acpi_ec_read(fan_rpm_offset + 1, &hi)) | 1931 | *status = s; |
1550 | len += sprintf(p + len, "speed:\t\tunreadable\n"); | 1932 | |
1551 | else | 1933 | break; |
1552 | len += sprintf(p + len, "speed:\t\t%d\n", | 1934 | |
1553 | (hi << 8) + lo); | 1935 | default: |
1936 | return -ENXIO; | ||
1554 | } | 1937 | } |
1555 | 1938 | ||
1556 | if (sfan_handle) | 1939 | return 0; |
1557 | /* 570, 770x-JL */ | 1940 | } |
1558 | len += sprintf(p + len, "commands:\tlevel <level>" | 1941 | |
1559 | " (<level> is 0-7)\n"); | 1942 | static int fan_get_speed(unsigned int *speed) |
1560 | if (!gfan_handle) | 1943 | { |
1944 | u8 hi, lo; | ||
1945 | |||
1946 | switch (fan_status_access_mode) { | ||
1947 | case IBMACPI_FAN_RD_TPEC: | ||
1561 | /* all except 570, 600e/x, 770e, 770x */ | 1948 | /* all except 570, 600e/x, 770e, 770x */ |
1562 | len += sprintf(p + len, "commands:\tenable, disable\n"); | 1949 | if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) || |
1563 | if (fans_handle) | 1950 | !acpi_ec_read(fan_rpm_offset + 1, &hi))) |
1564 | /* X31, X40 */ | 1951 | return -EIO; |
1952 | |||
1953 | if (likely(speed)) | ||
1954 | *speed = (hi << 8) | lo; | ||
1955 | |||
1956 | break; | ||
1957 | |||
1958 | default: | ||
1959 | return -ENXIO; | ||
1960 | } | ||
1961 | |||
1962 | return 0; | ||
1963 | } | ||
1964 | |||
1965 | static void fan_exit(void) | ||
1966 | { | ||
1967 | cancel_delayed_work(&fan_watchdog_task); | ||
1968 | flush_scheduled_work(); | ||
1969 | } | ||
1970 | |||
1971 | static void fan_watchdog_reset(void) | ||
1972 | { | ||
1973 | static int fan_watchdog_active = 0; | ||
1974 | |||
1975 | if (fan_watchdog_active) | ||
1976 | cancel_delayed_work(&fan_watchdog_task); | ||
1977 | |||
1978 | if (fan_watchdog_maxinterval > 0) { | ||
1979 | fan_watchdog_active = 1; | ||
1980 | if (!schedule_delayed_work(&fan_watchdog_task, | ||
1981 | msecs_to_jiffies(fan_watchdog_maxinterval | ||
1982 | * 1000))) { | ||
1983 | printk(IBM_ERR "failed to schedule the fan watchdog, " | ||
1984 | "watchdog will not trigger\n"); | ||
1985 | } | ||
1986 | } else | ||
1987 | fan_watchdog_active = 0; | ||
1988 | } | ||
1989 | |||
1990 | static int fan_read(char *p) | ||
1991 | { | ||
1992 | int len = 0; | ||
1993 | int rc; | ||
1994 | u8 status; | ||
1995 | unsigned int speed = 0; | ||
1996 | |||
1997 | switch (fan_status_access_mode) { | ||
1998 | case IBMACPI_FAN_RD_ACPI_GFAN: | ||
1999 | /* 570, 600e/x, 770e, 770x */ | ||
2000 | if ((rc = fan_get_status(&status)) < 0) | ||
2001 | return rc; | ||
2002 | |||
2003 | len += sprintf(p + len, "status:\t\t%s\n" | ||
2004 | "level:\t\t%d\n", | ||
2005 | (status != 0) ? "enabled" : "disabled", status); | ||
2006 | break; | ||
2007 | |||
2008 | case IBMACPI_FAN_RD_TPEC: | ||
2009 | /* all except 570, 600e/x, 770e, 770x */ | ||
2010 | if ((rc = fan_get_status(&status)) < 0) | ||
2011 | return rc; | ||
2012 | |||
2013 | if (unlikely(!fan_control_status_known)) { | ||
2014 | if (status != fan_control_initial_status) | ||
2015 | fan_control_status_known = 1; | ||
2016 | else | ||
2017 | /* Return most likely status. In fact, it | ||
2018 | * might be the only possible status */ | ||
2019 | status = IBMACPI_FAN_EC_AUTO; | ||
2020 | } | ||
2021 | |||
2022 | len += sprintf(p + len, "status:\t\t%s\n", | ||
2023 | (status != 0) ? "enabled" : "disabled"); | ||
2024 | |||
2025 | /* No ThinkPad boots on disengaged mode, we can safely | ||
2026 | * assume the tachometer is online if fan control status | ||
2027 | * was unknown */ | ||
2028 | if ((rc = fan_get_speed(&speed)) < 0) | ||
2029 | return rc; | ||
2030 | |||
2031 | len += sprintf(p + len, "speed:\t\t%d\n", speed); | ||
2032 | |||
2033 | if (status & IBMACPI_FAN_EC_DISENGAGED) | ||
2034 | /* Disengaged mode takes precedence */ | ||
2035 | len += sprintf(p + len, "level:\t\tdisengaged\n"); | ||
2036 | else if (status & IBMACPI_FAN_EC_AUTO) | ||
2037 | len += sprintf(p + len, "level:\t\tauto\n"); | ||
2038 | else | ||
2039 | len += sprintf(p + len, "level:\t\t%d\n", status); | ||
2040 | break; | ||
2041 | |||
2042 | case IBMACPI_FAN_NONE: | ||
2043 | default: | ||
2044 | len += sprintf(p + len, "status:\t\tnot supported\n"); | ||
2045 | } | ||
2046 | |||
2047 | if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) { | ||
2048 | len += sprintf(p + len, "commands:\tlevel <level>"); | ||
2049 | |||
2050 | switch (fan_control_access_mode) { | ||
2051 | case IBMACPI_FAN_WR_ACPI_SFAN: | ||
2052 | len += sprintf(p + len, " (<level> is 0-7)\n"); | ||
2053 | break; | ||
2054 | |||
2055 | default: | ||
2056 | len += sprintf(p + len, " (<level> is 0-7, " | ||
2057 | "auto, disengaged)\n"); | ||
2058 | break; | ||
2059 | } | ||
2060 | } | ||
2061 | |||
2062 | if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE) | ||
2063 | len += sprintf(p + len, "commands:\tenable, disable\n" | ||
2064 | "commands:\twatchdog <timeout> (<timeout> is 0 (off), " | ||
2065 | "1-120 (seconds))\n"); | ||
2066 | |||
2067 | if (fan_control_commands & IBMACPI_FAN_CMD_SPEED) | ||
1565 | len += sprintf(p + len, "commands:\tspeed <speed>" | 2068 | len += sprintf(p + len, "commands:\tspeed <speed>" |
1566 | " (<speed> is 0-65535)\n"); | 2069 | " (<speed> is 0-65535)\n"); |
1567 | 2070 | ||
1568 | return len; | 2071 | return len; |
1569 | } | 2072 | } |
1570 | 2073 | ||
1571 | static int fan_write(char *buf) | 2074 | static int fan_set_level(int level) |
1572 | { | 2075 | { |
1573 | char *cmd; | 2076 | switch (fan_control_access_mode) { |
1574 | int level, speed; | 2077 | case IBMACPI_FAN_WR_ACPI_SFAN: |
1575 | 2078 | if (level >= 0 && level <= 7) { | |
1576 | while ((cmd = next_cmd(&buf))) { | ||
1577 | if (sfan_handle && | ||
1578 | sscanf(cmd, "level %d", &level) == 1 && | ||
1579 | level >= 0 && level <= 7) { | ||
1580 | /* 570, 770x-JL */ | ||
1581 | if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level)) | 2079 | if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level)) |
1582 | return -EIO; | 2080 | return -EIO; |
1583 | } else if (!gfan_handle && strlencmp(cmd, "enable") == 0) { | 2081 | } else |
1584 | /* all except 570, 600e/x, 770e, 770x */ | 2082 | return -EINVAL; |
1585 | if (!acpi_ec_write(fan_status_offset, 0x80)) | 2083 | break; |
1586 | return -EIO; | 2084 | |
1587 | } else if (!gfan_handle && strlencmp(cmd, "disable") == 0) { | 2085 | case IBMACPI_FAN_WR_ACPI_FANS: |
1588 | /* all except 570, 600e/x, 770e, 770x */ | 2086 | case IBMACPI_FAN_WR_TPEC: |
1589 | if (!acpi_ec_write(fan_status_offset, 0x00)) | 2087 | if ((level != IBMACPI_FAN_EC_AUTO) && |
1590 | return -EIO; | 2088 | (level != IBMACPI_FAN_EC_DISENGAGED) && |
1591 | } else if (fans_handle && | 2089 | ((level < 0) || (level > 7))) |
1592 | sscanf(cmd, "speed %d", &speed) == 1 && | 2090 | return -EINVAL; |
1593 | speed >= 0 && speed <= 65535) { | 2091 | |
1594 | /* X31, X40 */ | 2092 | if (!acpi_ec_write(fan_status_offset, level)) |
2093 | return -EIO; | ||
2094 | else | ||
2095 | fan_control_status_known = 1; | ||
2096 | break; | ||
2097 | |||
2098 | default: | ||
2099 | return -ENXIO; | ||
2100 | } | ||
2101 | return 0; | ||
2102 | } | ||
2103 | |||
2104 | static int fan_set_enable(void) | ||
2105 | { | ||
2106 | u8 s; | ||
2107 | int rc; | ||
2108 | |||
2109 | switch (fan_control_access_mode) { | ||
2110 | case IBMACPI_FAN_WR_ACPI_FANS: | ||
2111 | case IBMACPI_FAN_WR_TPEC: | ||
2112 | if ((rc = fan_get_status(&s)) < 0) | ||
2113 | return rc; | ||
2114 | |||
2115 | /* Don't go out of emergency fan mode */ | ||
2116 | if (s != 7) | ||
2117 | s = IBMACPI_FAN_EC_AUTO; | ||
2118 | |||
2119 | if (!acpi_ec_write(fan_status_offset, s)) | ||
2120 | return -EIO; | ||
2121 | else | ||
2122 | fan_control_status_known = 1; | ||
2123 | break; | ||
2124 | |||
2125 | case IBMACPI_FAN_WR_ACPI_SFAN: | ||
2126 | if ((rc = fan_get_status(&s)) < 0) | ||
2127 | return rc; | ||
2128 | |||
2129 | s &= 0x07; | ||
2130 | |||
2131 | /* Set fan to at least level 4 */ | ||
2132 | if (s < 4) | ||
2133 | s = 4; | ||
2134 | |||
2135 | if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s)) | ||
2136 | return -EIO; | ||
2137 | break; | ||
2138 | |||
2139 | default: | ||
2140 | return -ENXIO; | ||
2141 | } | ||
2142 | return 0; | ||
2143 | } | ||
2144 | |||
2145 | static int fan_set_disable(void) | ||
2146 | { | ||
2147 | switch (fan_control_access_mode) { | ||
2148 | case IBMACPI_FAN_WR_ACPI_FANS: | ||
2149 | case IBMACPI_FAN_WR_TPEC: | ||
2150 | if (!acpi_ec_write(fan_status_offset, 0x00)) | ||
2151 | return -EIO; | ||
2152 | else | ||
2153 | fan_control_status_known = 1; | ||
2154 | break; | ||
2155 | |||
2156 | case IBMACPI_FAN_WR_ACPI_SFAN: | ||
2157 | if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00)) | ||
2158 | return -EIO; | ||
2159 | break; | ||
2160 | |||
2161 | default: | ||
2162 | return -ENXIO; | ||
2163 | } | ||
2164 | return 0; | ||
2165 | } | ||
2166 | |||
2167 | static int fan_set_speed(int speed) | ||
2168 | { | ||
2169 | switch (fan_control_access_mode) { | ||
2170 | case IBMACPI_FAN_WR_ACPI_FANS: | ||
2171 | if (speed >= 0 && speed <= 65535) { | ||
1595 | if (!acpi_evalf(fans_handle, NULL, NULL, "vddd", | 2172 | if (!acpi_evalf(fans_handle, NULL, NULL, "vddd", |
1596 | speed, speed, speed)) | 2173 | speed, speed, speed)) |
1597 | return -EIO; | 2174 | return -EIO; |
1598 | } else | 2175 | } else |
1599 | return -EINVAL; | 2176 | return -EINVAL; |
1600 | } | 2177 | break; |
1601 | 2178 | ||
2179 | default: | ||
2180 | return -ENXIO; | ||
2181 | } | ||
1602 | return 0; | 2182 | return 0; |
1603 | } | 2183 | } |
1604 | 2184 | ||
2185 | static int fan_write_cmd_level(const char *cmd, int *rc) | ||
2186 | { | ||
2187 | int level; | ||
2188 | |||
2189 | if (strlencmp(cmd, "level auto") == 0) | ||
2190 | level = IBMACPI_FAN_EC_AUTO; | ||
2191 | else if (strlencmp(cmd, "level disengaged") == 0) | ||
2192 | level = IBMACPI_FAN_EC_DISENGAGED; | ||
2193 | else if (sscanf(cmd, "level %d", &level) != 1) | ||
2194 | return 0; | ||
2195 | |||
2196 | if ((*rc = fan_set_level(level)) == -ENXIO) | ||
2197 | printk(IBM_ERR "level command accepted for unsupported " | ||
2198 | "access mode %d", fan_control_access_mode); | ||
2199 | |||
2200 | return 1; | ||
2201 | } | ||
2202 | |||
2203 | static int fan_write_cmd_enable(const char *cmd, int *rc) | ||
2204 | { | ||
2205 | if (strlencmp(cmd, "enable") != 0) | ||
2206 | return 0; | ||
2207 | |||
2208 | if ((*rc = fan_set_enable()) == -ENXIO) | ||
2209 | printk(IBM_ERR "enable command accepted for unsupported " | ||
2210 | "access mode %d", fan_control_access_mode); | ||
2211 | |||
2212 | return 1; | ||
2213 | } | ||
2214 | |||
2215 | static int fan_write_cmd_disable(const char *cmd, int *rc) | ||
2216 | { | ||
2217 | if (strlencmp(cmd, "disable") != 0) | ||
2218 | return 0; | ||
2219 | |||
2220 | if ((*rc = fan_set_disable()) == -ENXIO) | ||
2221 | printk(IBM_ERR "disable command accepted for unsupported " | ||
2222 | "access mode %d", fan_control_access_mode); | ||
2223 | |||
2224 | return 1; | ||
2225 | } | ||
2226 | |||
2227 | static int fan_write_cmd_speed(const char *cmd, int *rc) | ||
2228 | { | ||
2229 | int speed; | ||
2230 | |||
2231 | /* TODO: | ||
2232 | * Support speed <low> <medium> <high> ? */ | ||
2233 | |||
2234 | if (sscanf(cmd, "speed %d", &speed) != 1) | ||
2235 | return 0; | ||
2236 | |||
2237 | if ((*rc = fan_set_speed(speed)) == -ENXIO) | ||
2238 | printk(IBM_ERR "speed command accepted for unsupported " | ||
2239 | "access mode %d", fan_control_access_mode); | ||
2240 | |||
2241 | return 1; | ||
2242 | } | ||
2243 | |||
2244 | static int fan_write_cmd_watchdog(const char *cmd, int *rc) | ||
2245 | { | ||
2246 | int interval; | ||
2247 | |||
2248 | if (sscanf(cmd, "watchdog %d", &interval) != 1) | ||
2249 | return 0; | ||
2250 | |||
2251 | if (interval < 0 || interval > 120) | ||
2252 | *rc = -EINVAL; | ||
2253 | else | ||
2254 | fan_watchdog_maxinterval = interval; | ||
2255 | |||
2256 | return 1; | ||
2257 | } | ||
2258 | |||
2259 | static int fan_write(char *buf) | ||
2260 | { | ||
2261 | char *cmd; | ||
2262 | int rc = 0; | ||
2263 | |||
2264 | while (!rc && (cmd = next_cmd(&buf))) { | ||
2265 | if (!((fan_control_commands & IBMACPI_FAN_CMD_LEVEL) && | ||
2266 | fan_write_cmd_level(cmd, &rc)) && | ||
2267 | !((fan_control_commands & IBMACPI_FAN_CMD_ENABLE) && | ||
2268 | (fan_write_cmd_enable(cmd, &rc) || | ||
2269 | fan_write_cmd_disable(cmd, &rc) || | ||
2270 | fan_write_cmd_watchdog(cmd, &rc))) && | ||
2271 | !((fan_control_commands & IBMACPI_FAN_CMD_SPEED) && | ||
2272 | fan_write_cmd_speed(cmd, &rc)) | ||
2273 | ) | ||
2274 | rc = -EINVAL; | ||
2275 | else if (!rc) | ||
2276 | fan_watchdog_reset(); | ||
2277 | } | ||
2278 | |||
2279 | return rc; | ||
2280 | } | ||
2281 | |||
2282 | static void fan_watchdog_fire(struct work_struct *ignored) | ||
2283 | { | ||
2284 | printk(IBM_NOTICE "fan watchdog: enabling fan\n"); | ||
2285 | if (fan_set_enable()) { | ||
2286 | printk(IBM_ERR "fan watchdog: error while enabling fan\n"); | ||
2287 | /* reschedule for later */ | ||
2288 | fan_watchdog_reset(); | ||
2289 | } | ||
2290 | } | ||
2291 | |||
1605 | static struct ibm_struct ibms[] = { | 2292 | static struct ibm_struct ibms[] = { |
1606 | { | 2293 | { |
1607 | .name = "driver", | 2294 | .name = "driver", |
1608 | .init = driver_init, | 2295 | .init = ibm_acpi_driver_init, |
1609 | .read = driver_read, | 2296 | .read = driver_read, |
1610 | }, | 2297 | }, |
1611 | { | 2298 | { |
@@ -1702,6 +2389,8 @@ static struct ibm_struct ibms[] = { | |||
1702 | .name = "brightness", | 2389 | .name = "brightness", |
1703 | .read = brightness_read, | 2390 | .read = brightness_read, |
1704 | .write = brightness_write, | 2391 | .write = brightness_write, |
2392 | .init = brightness_init, | ||
2393 | .exit = brightness_exit, | ||
1705 | }, | 2394 | }, |
1706 | { | 2395 | { |
1707 | .name = "volume", | 2396 | .name = "volume", |
@@ -1712,6 +2401,8 @@ static struct ibm_struct ibms[] = { | |||
1712 | .name = "fan", | 2401 | .name = "fan", |
1713 | .read = fan_read, | 2402 | .read = fan_read, |
1714 | .write = fan_write, | 2403 | .write = fan_write, |
2404 | .init = fan_init, | ||
2405 | .exit = fan_exit, | ||
1715 | .experimental = 1, | 2406 | .experimental = 1, |
1716 | }, | 2407 | }, |
1717 | }; | 2408 | }; |
@@ -1719,7 +2410,7 @@ static struct ibm_struct ibms[] = { | |||
1719 | static int dispatch_read(char *page, char **start, off_t off, int count, | 2410 | static int dispatch_read(char *page, char **start, off_t off, int count, |
1720 | int *eof, void *data) | 2411 | int *eof, void *data) |
1721 | { | 2412 | { |
1722 | struct ibm_struct *ibm = (struct ibm_struct *)data; | 2413 | struct ibm_struct *ibm = data; |
1723 | int len; | 2414 | int len; |
1724 | 2415 | ||
1725 | if (!ibm || !ibm->read) | 2416 | if (!ibm || !ibm->read) |
@@ -1744,7 +2435,7 @@ static int dispatch_read(char *page, char **start, off_t off, int count, | |||
1744 | static int dispatch_write(struct file *file, const char __user * userbuf, | 2435 | static int dispatch_write(struct file *file, const char __user * userbuf, |
1745 | unsigned long count, void *data) | 2436 | unsigned long count, void *data) |
1746 | { | 2437 | { |
1747 | struct ibm_struct *ibm = (struct ibm_struct *)data; | 2438 | struct ibm_struct *ibm = data; |
1748 | char *kernbuf; | 2439 | char *kernbuf; |
1749 | int ret; | 2440 | int ret; |
1750 | 2441 | ||
@@ -1773,7 +2464,7 @@ static int dispatch_write(struct file *file, const char __user * userbuf, | |||
1773 | 2464 | ||
1774 | static void dispatch_notify(acpi_handle handle, u32 event, void *data) | 2465 | static void dispatch_notify(acpi_handle handle, u32 event, void *data) |
1775 | { | 2466 | { |
1776 | struct ibm_struct *ibm = (struct ibm_struct *)data; | 2467 | struct ibm_struct *ibm = data; |
1777 | 2468 | ||
1778 | if (!ibm || !ibm->notify) | 2469 | if (!ibm || !ibm->notify) |
1779 | return; | 2470 | return; |
@@ -1805,7 +2496,7 @@ static int __init setup_notify(struct ibm_struct *ibm) | |||
1805 | ibm->name, status); | 2496 | ibm->name, status); |
1806 | return -ENODEV; | 2497 | return -ENODEV; |
1807 | } | 2498 | } |
1808 | 2499 | ibm->notify_installed = 1; | |
1809 | return 0; | 2500 | return 0; |
1810 | } | 2501 | } |
1811 | 2502 | ||
@@ -1818,14 +2509,13 @@ static int __init register_driver(struct ibm_struct *ibm) | |||
1818 | { | 2509 | { |
1819 | int ret; | 2510 | int ret; |
1820 | 2511 | ||
1821 | ibm->driver = kmalloc(sizeof(struct acpi_driver), GFP_KERNEL); | 2512 | ibm->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); |
1822 | if (!ibm->driver) { | 2513 | if (!ibm->driver) { |
1823 | printk(IBM_ERR "kmalloc(ibm->driver) failed\n"); | 2514 | printk(IBM_ERR "kmalloc(ibm->driver) failed\n"); |
1824 | return -1; | 2515 | return -1; |
1825 | } | 2516 | } |
1826 | 2517 | ||
1827 | memset(ibm->driver, 0, sizeof(struct acpi_driver)); | 2518 | sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name); |
1828 | sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name); | ||
1829 | ibm->driver->ids = ibm->hid; | 2519 | ibm->driver->ids = ibm->hid; |
1830 | ibm->driver->ops.add = &ibm_device_add; | 2520 | ibm->driver->ops.add = &ibm_device_add; |
1831 | 2521 | ||
@@ -1882,7 +2572,6 @@ static int __init ibm_init(struct ibm_struct *ibm) | |||
1882 | ret = setup_notify(ibm); | 2572 | ret = setup_notify(ibm); |
1883 | if (ret < 0) | 2573 | if (ret < 0) |
1884 | return ret; | 2574 | return ret; |
1885 | ibm->notify_installed = 1; | ||
1886 | } | 2575 | } |
1887 | 2576 | ||
1888 | return 0; | 2577 | return 0; |
@@ -1971,6 +2660,33 @@ static void acpi_ibm_exit(void) | |||
1971 | ibm_exit(&ibms[i]); | 2660 | ibm_exit(&ibms[i]); |
1972 | 2661 | ||
1973 | remove_proc_entry(IBM_DIR, acpi_root_dir); | 2662 | remove_proc_entry(IBM_DIR, acpi_root_dir); |
2663 | |||
2664 | if (ibm_thinkpad_ec_found) | ||
2665 | kfree(ibm_thinkpad_ec_found); | ||
2666 | } | ||
2667 | |||
2668 | static char* __init check_dmi_for_ec(void) | ||
2669 | { | ||
2670 | struct dmi_device *dev = NULL; | ||
2671 | char ec_fw_string[18]; | ||
2672 | |||
2673 | /* | ||
2674 | * ThinkPad T23 or newer, A31 or newer, R50e or newer, | ||
2675 | * X32 or newer, all Z series; Some models must have an | ||
2676 | * up-to-date BIOS or they will not be detected. | ||
2677 | * | ||
2678 | * See http://thinkwiki.org/wiki/List_of_DMI_IDs | ||
2679 | */ | ||
2680 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { | ||
2681 | if (sscanf(dev->name, | ||
2682 | "IBM ThinkPad Embedded Controller -[%17c", | ||
2683 | ec_fw_string) == 1) { | ||
2684 | ec_fw_string[sizeof(ec_fw_string) - 1] = 0; | ||
2685 | ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; | ||
2686 | return kstrdup(ec_fw_string, GFP_KERNEL); | ||
2687 | } | ||
2688 | } | ||
2689 | return NULL; | ||
1974 | } | 2690 | } |
1975 | 2691 | ||
1976 | static int __init acpi_ibm_init(void) | 2692 | static int __init acpi_ibm_init(void) |
@@ -1992,6 +2708,12 @@ static int __init acpi_ibm_init(void) | |||
1992 | return -ENODEV; | 2708 | return -ENODEV; |
1993 | } | 2709 | } |
1994 | 2710 | ||
2711 | /* Models with newer firmware report the EC in DMI */ | ||
2712 | ibm_thinkpad_ec_found = check_dmi_for_ec(); | ||
2713 | if (ibm_thinkpad_ec_found) | ||
2714 | printk(IBM_INFO "ThinkPad EC firmware %s\n", | ||
2715 | ibm_thinkpad_ec_found); | ||
2716 | |||
1995 | /* these handles are not required */ | 2717 | /* these handles are not required */ |
1996 | IBM_HANDLE_INIT(vid); | 2718 | IBM_HANDLE_INIT(vid); |
1997 | IBM_HANDLE_INIT(vid2); | 2719 | IBM_HANDLE_INIT(vid2); |
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c index bedb5118e312..8f13b4f3e906 100644 --- a/drivers/acpi/motherboard.c +++ b/drivers/acpi/motherboard.c | |||
@@ -124,41 +124,41 @@ static void __init acpi_request_region (struct acpi_generic_address *addr, | |||
124 | if (!addr->address || !length) | 124 | if (!addr->address || !length) |
125 | return; | 125 | return; |
126 | 126 | ||
127 | if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) | 127 | if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) |
128 | request_region(addr->address, length, desc); | 128 | request_region(addr->address, length, desc); |
129 | else if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | 129 | else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) |
130 | request_mem_region(addr->address, length, desc); | 130 | request_mem_region(addr->address, length, desc); |
131 | } | 131 | } |
132 | 132 | ||
133 | static void __init acpi_reserve_resources(void) | 133 | static void __init acpi_reserve_resources(void) |
134 | { | 134 | { |
135 | acpi_request_region(&acpi_gbl_FADT->xpm1a_evt_blk, | 135 | acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, |
136 | acpi_gbl_FADT->pm1_evt_len, "ACPI PM1a_EVT_BLK"); | 136 | acpi_gbl_FADT.pm1_event_length, "ACPI PM1a_EVT_BLK"); |
137 | 137 | ||
138 | acpi_request_region(&acpi_gbl_FADT->xpm1b_evt_blk, | 138 | acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, |
139 | acpi_gbl_FADT->pm1_evt_len, "ACPI PM1b_EVT_BLK"); | 139 | acpi_gbl_FADT.pm1_event_length, "ACPI PM1b_EVT_BLK"); |
140 | 140 | ||
141 | acpi_request_region(&acpi_gbl_FADT->xpm1a_cnt_blk, | 141 | acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, |
142 | acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1a_CNT_BLK"); | 142 | acpi_gbl_FADT.pm1_control_length, "ACPI PM1a_CNT_BLK"); |
143 | 143 | ||
144 | acpi_request_region(&acpi_gbl_FADT->xpm1b_cnt_blk, | 144 | acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, |
145 | acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1b_CNT_BLK"); | 145 | acpi_gbl_FADT.pm1_control_length, "ACPI PM1b_CNT_BLK"); |
146 | 146 | ||
147 | if (acpi_gbl_FADT->pm_tm_len == 4) | 147 | if (acpi_gbl_FADT.pm_timer_length == 4) |
148 | acpi_request_region(&acpi_gbl_FADT->xpm_tmr_blk, 4, "ACPI PM_TMR"); | 148 | acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR"); |
149 | 149 | ||
150 | acpi_request_region(&acpi_gbl_FADT->xpm2_cnt_blk, | 150 | acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, |
151 | acpi_gbl_FADT->pm2_cnt_len, "ACPI PM2_CNT_BLK"); | 151 | acpi_gbl_FADT.pm2_control_length, "ACPI PM2_CNT_BLK"); |
152 | 152 | ||
153 | /* Length of GPE blocks must be a non-negative multiple of 2 */ | 153 | /* Length of GPE blocks must be a non-negative multiple of 2 */ |
154 | 154 | ||
155 | if (!(acpi_gbl_FADT->gpe0_blk_len & 0x1)) | 155 | if (!(acpi_gbl_FADT.gpe0_block_length & 0x1)) |
156 | acpi_request_region(&acpi_gbl_FADT->xgpe0_blk, | 156 | acpi_request_region(&acpi_gbl_FADT.xgpe0_block, |
157 | acpi_gbl_FADT->gpe0_blk_len, "ACPI GPE0_BLK"); | 157 | acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK"); |
158 | 158 | ||
159 | if (!(acpi_gbl_FADT->gpe1_blk_len & 0x1)) | 159 | if (!(acpi_gbl_FADT.gpe1_block_length & 0x1)) |
160 | acpi_request_region(&acpi_gbl_FADT->xgpe1_blk, | 160 | acpi_request_region(&acpi_gbl_FADT.xgpe1_block, |
161 | acpi_gbl_FADT->gpe1_blk_len, "ACPI GPE1_BLK"); | 161 | acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK"); |
162 | } | 162 | } |
163 | 163 | ||
164 | static int __init acpi_motherboard_init(void) | 164 | static int __init acpi_motherboard_init(void) |
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c index c1c6c236df9a..57faf598bad8 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/namespace/nsaccess.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -195,31 +195,27 @@ acpi_status acpi_ns_root_initialize(void) | |||
195 | obj_desc->mutex.sync_level = | 195 | obj_desc->mutex.sync_level = |
196 | (u8) (ACPI_TO_INTEGER(val) - 1); | 196 | (u8) (ACPI_TO_INTEGER(val) - 1); |
197 | 197 | ||
198 | if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { | 198 | /* Create a mutex */ |
199 | 199 | ||
200 | /* Create a counting semaphore for the global lock */ | 200 | status = |
201 | acpi_os_create_mutex(&obj_desc->mutex. | ||
202 | os_mutex); | ||
203 | if (ACPI_FAILURE(status)) { | ||
204 | acpi_ut_remove_reference(obj_desc); | ||
205 | goto unlock_and_exit; | ||
206 | } | ||
201 | 207 | ||
202 | status = | 208 | /* Special case for ACPI Global Lock */ |
203 | acpi_os_create_semaphore | ||
204 | (ACPI_NO_UNIT_LIMIT, 1, | ||
205 | &acpi_gbl_global_lock_semaphore); | ||
206 | if (ACPI_FAILURE(status)) { | ||
207 | acpi_ut_remove_reference | ||
208 | (obj_desc); | ||
209 | goto unlock_and_exit; | ||
210 | } | ||
211 | 209 | ||
212 | /* Mark this mutex as very special */ | 210 | if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { |
211 | acpi_gbl_global_lock_mutex = | ||
212 | obj_desc->mutex.os_mutex; | ||
213 | 213 | ||
214 | obj_desc->mutex.os_mutex = | 214 | /* Create additional counting semaphore for global lock */ |
215 | ACPI_GLOBAL_LOCK; | ||
216 | } else { | ||
217 | /* Create a mutex */ | ||
218 | 215 | ||
219 | status = | 216 | status = |
220 | acpi_os_create_mutex(&obj_desc-> | 217 | acpi_os_create_semaphore(1, 0, |
221 | mutex. | 218 | &acpi_gbl_global_lock_semaphore); |
222 | os_mutex); | ||
223 | if (ACPI_FAILURE(status)) { | 219 | if (ACPI_FAILURE(status)) { |
224 | acpi_ut_remove_reference | 220 | acpi_ut_remove_reference |
225 | (obj_desc); | 221 | (obj_desc); |
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c index 55b407aae266..1d693d8ad2d8 100644 --- a/drivers/acpi/namespace/nsalloc.c +++ b/drivers/acpi/namespace/nsalloc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -61,6 +61,9 @@ ACPI_MODULE_NAME("nsalloc") | |||
61 | struct acpi_namespace_node *acpi_ns_create_node(u32 name) | 61 | struct acpi_namespace_node *acpi_ns_create_node(u32 name) |
62 | { | 62 | { |
63 | struct acpi_namespace_node *node; | 63 | struct acpi_namespace_node *node; |
64 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
65 | u32 temp; | ||
66 | #endif | ||
64 | 67 | ||
65 | ACPI_FUNCTION_TRACE(ns_create_node); | 68 | ACPI_FUNCTION_TRACE(ns_create_node); |
66 | 69 | ||
@@ -71,6 +74,15 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name) | |||
71 | 74 | ||
72 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++); | 75 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++); |
73 | 76 | ||
77 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
78 | temp = | ||
79 | acpi_gbl_ns_node_list->total_allocated - | ||
80 | acpi_gbl_ns_node_list->total_freed; | ||
81 | if (temp > acpi_gbl_ns_node_list->max_occupied) { | ||
82 | acpi_gbl_ns_node_list->max_occupied = temp; | ||
83 | } | ||
84 | #endif | ||
85 | |||
74 | node->name.integer = name; | 86 | node->name.integer = name; |
75 | ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED); | 87 | ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED); |
76 | return_PTR(node); | 88 | return_PTR(node); |
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index d72df66aa965..1fc4f86676e1 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -205,7 +205,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
205 | 205 | ||
206 | if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { | 206 | if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { |
207 | this_node->name.integer = | 207 | this_node->name.integer = |
208 | acpi_ut_repair_name(this_node->name.integer); | 208 | acpi_ut_repair_name(this_node->name.ascii); |
209 | 209 | ||
210 | ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", | 210 | ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", |
211 | this_node->name.integer)); | 211 | this_node->name.integer)); |
@@ -226,6 +226,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
226 | obj_desc = acpi_ns_get_attached_object(this_node); | 226 | obj_desc = acpi_ns_get_attached_object(this_node); |
227 | acpi_dbg_level = dbg_level; | 227 | acpi_dbg_level = dbg_level; |
228 | 228 | ||
229 | /* Temp nodes are those nodes created by a control method */ | ||
230 | |||
231 | if (this_node->flags & ANOBJ_TEMPORARY) { | ||
232 | acpi_os_printf("(T) "); | ||
233 | } | ||
234 | |||
229 | switch (info->display_type & ACPI_DISPLAY_MASK) { | 235 | switch (info->display_type & ACPI_DISPLAY_MASK) { |
230 | case ACPI_DISPLAY_SUMMARY: | 236 | case ACPI_DISPLAY_SUMMARY: |
231 | 237 | ||
@@ -623,7 +629,8 @@ acpi_ns_dump_objects(acpi_object_type type, | |||
623 | info.display_type = display_type; | 629 | info.display_type = display_type; |
624 | 630 | ||
625 | (void)acpi_ns_walk_namespace(type, start_handle, max_depth, | 631 | (void)acpi_ns_walk_namespace(type, start_handle, max_depth, |
626 | ACPI_NS_WALK_NO_UNLOCK, | 632 | ACPI_NS_WALK_NO_UNLOCK | |
633 | ACPI_NS_WALK_TEMP_NODES, | ||
627 | acpi_ns_dump_one_object, (void *)&info, | 634 | acpi_ns_dump_one_object, (void *)&info, |
628 | NULL); | 635 | NULL); |
629 | } | 636 | } |
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c index c6bf5d30fca3..5097e167939e 100644 --- a/drivers/acpi/namespace/nsdumpdv.c +++ b/drivers/acpi/namespace/nsdumpdv.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 4b0a4a8c9843..aa6370c67ec1 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -154,11 +154,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) | |||
154 | * Execute the method via the interpreter. The interpreter is locked | 154 | * Execute the method via the interpreter. The interpreter is locked |
155 | * here before calling into the AML parser | 155 | * here before calling into the AML parser |
156 | */ | 156 | */ |
157 | status = acpi_ex_enter_interpreter(); | 157 | acpi_ex_enter_interpreter(); |
158 | if (ACPI_FAILURE(status)) { | ||
159 | return_ACPI_STATUS(status); | ||
160 | } | ||
161 | |||
162 | status = acpi_ps_execute_method(info); | 158 | status = acpi_ps_execute_method(info); |
163 | acpi_ex_exit_interpreter(); | 159 | acpi_ex_exit_interpreter(); |
164 | } else { | 160 | } else { |
@@ -182,10 +178,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) | |||
182 | * resolution, we must lock it because we could access an opregion. | 178 | * resolution, we must lock it because we could access an opregion. |
183 | * The opregion access code assumes that the interpreter is locked. | 179 | * The opregion access code assumes that the interpreter is locked. |
184 | */ | 180 | */ |
185 | status = acpi_ex_enter_interpreter(); | 181 | acpi_ex_enter_interpreter(); |
186 | if (ACPI_FAILURE(status)) { | ||
187 | return_ACPI_STATUS(status); | ||
188 | } | ||
189 | 182 | ||
190 | /* Function has a strange interface */ | 183 | /* Function has a strange interface */ |
191 | 184 | ||
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c index aec8488c0019..326af8fc0ce7 100644 --- a/drivers/acpi/namespace/nsinit.c +++ b/drivers/acpi/namespace/nsinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -213,7 +213,7 @@ acpi_ns_init_one_object(acpi_handle obj_handle, | |||
213 | u32 level, void *context, void **return_value) | 213 | u32 level, void *context, void **return_value) |
214 | { | 214 | { |
215 | acpi_object_type type; | 215 | acpi_object_type type; |
216 | acpi_status status; | 216 | acpi_status status = AE_OK; |
217 | struct acpi_init_walk_info *info = | 217 | struct acpi_init_walk_info *info = |
218 | (struct acpi_init_walk_info *)context; | 218 | (struct acpi_init_walk_info *)context; |
219 | struct acpi_namespace_node *node = | 219 | struct acpi_namespace_node *node = |
@@ -267,10 +267,7 @@ acpi_ns_init_one_object(acpi_handle obj_handle, | |||
267 | /* | 267 | /* |
268 | * Must lock the interpreter before executing AML code | 268 | * Must lock the interpreter before executing AML code |
269 | */ | 269 | */ |
270 | status = acpi_ex_enter_interpreter(); | 270 | acpi_ex_enter_interpreter(); |
271 | if (ACPI_FAILURE(status)) { | ||
272 | return (status); | ||
273 | } | ||
274 | 271 | ||
275 | /* | 272 | /* |
276 | * Each of these types can contain executable AML code within the | 273 | * Each of these types can contain executable AML code within the |
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index fe75d888e183..d4f9654fd20f 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -44,13 +44,12 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
46 | #include <acpi/acdispat.h> | 46 | #include <acpi/acdispat.h> |
47 | #include <acpi/actables.h> | ||
47 | 48 | ||
48 | #define _COMPONENT ACPI_NAMESPACE | 49 | #define _COMPONENT ACPI_NAMESPACE |
49 | ACPI_MODULE_NAME("nsload") | 50 | ACPI_MODULE_NAME("nsload") |
50 | 51 | ||
51 | /* Local prototypes */ | 52 | /* Local prototypes */ |
52 | static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type); | ||
53 | |||
54 | #ifdef ACPI_FUTURE_IMPLEMENTATION | 53 | #ifdef ACPI_FUTURE_IMPLEMENTATION |
55 | acpi_status acpi_ns_unload_namespace(acpi_handle handle); | 54 | acpi_status acpi_ns_unload_namespace(acpi_handle handle); |
56 | 55 | ||
@@ -62,7 +61,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); | |||
62 | * | 61 | * |
63 | * FUNCTION: acpi_ns_load_table | 62 | * FUNCTION: acpi_ns_load_table |
64 | * | 63 | * |
65 | * PARAMETERS: table_desc - Descriptor for table to be loaded | 64 | * PARAMETERS: table_index - Index for table to be loaded |
66 | * Node - Owning NS node | 65 | * Node - Owning NS node |
67 | * | 66 | * |
68 | * RETURN: Status | 67 | * RETURN: Status |
@@ -72,42 +71,13 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); | |||
72 | ******************************************************************************/ | 71 | ******************************************************************************/ |
73 | 72 | ||
74 | acpi_status | 73 | acpi_status |
75 | acpi_ns_load_table(struct acpi_table_desc *table_desc, | 74 | acpi_ns_load_table(acpi_native_uint table_index, |
76 | struct acpi_namespace_node *node) | 75 | struct acpi_namespace_node *node) |
77 | { | 76 | { |
78 | acpi_status status; | 77 | acpi_status status; |
79 | 78 | ||
80 | ACPI_FUNCTION_TRACE(ns_load_table); | 79 | ACPI_FUNCTION_TRACE(ns_load_table); |
81 | 80 | ||
82 | /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */ | ||
83 | |||
84 | if (! | ||
85 | (acpi_gbl_table_data[table_desc->type]. | ||
86 | flags & ACPI_TABLE_EXECUTABLE)) { | ||
87 | |||
88 | /* Just ignore this table */ | ||
89 | |||
90 | return_ACPI_STATUS(AE_OK); | ||
91 | } | ||
92 | |||
93 | /* Check validity of the AML start and length */ | ||
94 | |||
95 | if (!table_desc->aml_start) { | ||
96 | ACPI_ERROR((AE_INFO, "Null AML pointer")); | ||
97 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
98 | } | ||
99 | |||
100 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AML block at %p\n", | ||
101 | table_desc->aml_start)); | ||
102 | |||
103 | /* Ignore table if there is no AML contained within */ | ||
104 | |||
105 | if (!table_desc->aml_length) { | ||
106 | ACPI_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]", | ||
107 | table_desc->pointer->signature)); | ||
108 | return_ACPI_STATUS(AE_OK); | ||
109 | } | ||
110 | |||
111 | /* | 81 | /* |
112 | * Parse the table and load the namespace with all named | 82 | * Parse the table and load the namespace with all named |
113 | * objects found within. Control methods are NOT parsed | 83 | * objects found within. Control methods are NOT parsed |
@@ -117,15 +87,34 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, | |||
117 | * to another control method, we can't continue parsing | 87 | * to another control method, we can't continue parsing |
118 | * because we don't know how many arguments to parse next! | 88 | * because we don't know how many arguments to parse next! |
119 | */ | 89 | */ |
90 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
91 | if (ACPI_FAILURE(status)) { | ||
92 | return_ACPI_STATUS(status); | ||
93 | } | ||
94 | |||
95 | /* If table already loaded into namespace, just return */ | ||
96 | |||
97 | if (acpi_tb_is_table_loaded(table_index)) { | ||
98 | status = AE_ALREADY_EXISTS; | ||
99 | goto unlock; | ||
100 | } | ||
101 | |||
120 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 102 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
121 | "**** Loading table into namespace ****\n")); | 103 | "**** Loading table into namespace ****\n")); |
122 | 104 | ||
123 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 105 | status = acpi_tb_allocate_owner_id(table_index); |
124 | if (ACPI_FAILURE(status)) { | 106 | if (ACPI_FAILURE(status)) { |
125 | return_ACPI_STATUS(status); | 107 | goto unlock; |
108 | } | ||
109 | |||
110 | status = acpi_ns_parse_table(table_index, node->child); | ||
111 | if (ACPI_SUCCESS(status)) { | ||
112 | acpi_tb_set_table_loaded_flag(table_index, TRUE); | ||
113 | } else { | ||
114 | acpi_tb_release_owner_id(table_index); | ||
126 | } | 115 | } |
127 | 116 | ||
128 | status = acpi_ns_parse_table(table_desc, node->child); | 117 | unlock: |
129 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 118 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
130 | 119 | ||
131 | if (ACPI_FAILURE(status)) { | 120 | if (ACPI_FAILURE(status)) { |
@@ -141,7 +130,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, | |||
141 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 130 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
142 | "**** Begin Table Method Parsing and Object Initialization ****\n")); | 131 | "**** Begin Table Method Parsing and Object Initialization ****\n")); |
143 | 132 | ||
144 | status = acpi_ds_initialize_objects(table_desc, node); | 133 | status = acpi_ds_initialize_objects(table_index, node); |
145 | 134 | ||
146 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 135 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
147 | "**** Completed Table Method Parsing and Object Initialization ****\n")); | 136 | "**** Completed Table Method Parsing and Object Initialization ****\n")); |
@@ -149,99 +138,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, | |||
149 | return_ACPI_STATUS(status); | 138 | return_ACPI_STATUS(status); |
150 | } | 139 | } |
151 | 140 | ||
152 | /******************************************************************************* | 141 | #ifdef ACPI_OBSOLETE_FUNCTIONS |
153 | * | ||
154 | * FUNCTION: acpi_ns_load_table_by_type | ||
155 | * | ||
156 | * PARAMETERS: table_type - Id of the table type to load | ||
157 | * | ||
158 | * RETURN: Status | ||
159 | * | ||
160 | * DESCRIPTION: Load an ACPI table or tables into the namespace. All tables | ||
161 | * of the given type are loaded. The mechanism allows this | ||
162 | * routine to be called repeatedly. | ||
163 | * | ||
164 | ******************************************************************************/ | ||
165 | |||
166 | static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type) | ||
167 | { | ||
168 | u32 i; | ||
169 | acpi_status status; | ||
170 | struct acpi_table_desc *table_desc; | ||
171 | |||
172 | ACPI_FUNCTION_TRACE(ns_load_table_by_type); | ||
173 | |||
174 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
175 | if (ACPI_FAILURE(status)) { | ||
176 | return_ACPI_STATUS(status); | ||
177 | } | ||
178 | |||
179 | /* | ||
180 | * Table types supported are: | ||
181 | * DSDT (one), SSDT/PSDT (multiple) | ||
182 | */ | ||
183 | switch (table_type) { | ||
184 | case ACPI_TABLE_ID_DSDT: | ||
185 | |||
186 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n")); | ||
187 | |||
188 | table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_DSDT].next; | ||
189 | |||
190 | /* If table already loaded into namespace, just return */ | ||
191 | |||
192 | if (table_desc->loaded_into_namespace) { | ||
193 | goto unlock_and_exit; | ||
194 | } | ||
195 | |||
196 | /* Now load the single DSDT */ | ||
197 | |||
198 | status = acpi_ns_load_table(table_desc, acpi_gbl_root_node); | ||
199 | if (ACPI_SUCCESS(status)) { | ||
200 | table_desc->loaded_into_namespace = TRUE; | ||
201 | } | ||
202 | break; | ||
203 | |||
204 | case ACPI_TABLE_ID_SSDT: | ||
205 | case ACPI_TABLE_ID_PSDT: | ||
206 | |||
207 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
208 | "Namespace load: %d SSDT or PSDTs\n", | ||
209 | acpi_gbl_table_lists[table_type].count)); | ||
210 | |||
211 | /* | ||
212 | * Traverse list of SSDT or PSDT tables | ||
213 | */ | ||
214 | table_desc = acpi_gbl_table_lists[table_type].next; | ||
215 | for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) { | ||
216 | /* | ||
217 | * Only attempt to load table into namespace if it is not | ||
218 | * already loaded! | ||
219 | */ | ||
220 | if (!table_desc->loaded_into_namespace) { | ||
221 | status = | ||
222 | acpi_ns_load_table(table_desc, | ||
223 | acpi_gbl_root_node); | ||
224 | if (ACPI_FAILURE(status)) { | ||
225 | break; | ||
226 | } | ||
227 | |||
228 | table_desc->loaded_into_namespace = TRUE; | ||
229 | } | ||
230 | |||
231 | table_desc = table_desc->next; | ||
232 | } | ||
233 | break; | ||
234 | |||
235 | default: | ||
236 | status = AE_SUPPORT; | ||
237 | break; | ||
238 | } | ||
239 | |||
240 | unlock_and_exit: | ||
241 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
242 | return_ACPI_STATUS(status); | ||
243 | } | ||
244 | |||
245 | /******************************************************************************* | 142 | /******************************************************************************* |
246 | * | 143 | * |
247 | * FUNCTION: acpi_load_namespace | 144 | * FUNCTION: acpi_load_namespace |
@@ -288,6 +185,7 @@ acpi_status acpi_ns_load_namespace(void) | |||
288 | 185 | ||
289 | return_ACPI_STATUS(status); | 186 | return_ACPI_STATUS(status); |
290 | } | 187 | } |
188 | #endif | ||
291 | 189 | ||
292 | #ifdef ACPI_FUTURE_IMPLEMENTATION | 190 | #ifdef ACPI_FUTURE_IMPLEMENTATION |
293 | /******************************************************************************* | 191 | /******************************************************************************* |
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index 97b8332c9746..cbd94af08cc5 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c index aabe8794b908..d9d7377bc6e6 100644 --- a/drivers/acpi/namespace/nsobject.c +++ b/drivers/acpi/namespace/nsobject.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c index 155505a4ef69..e696aa847990 100644 --- a/drivers/acpi/namespace/nsparse.c +++ b/drivers/acpi/namespace/nsparse.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -45,6 +45,7 @@ | |||
45 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
46 | #include <acpi/acparser.h> | 46 | #include <acpi/acparser.h> |
47 | #include <acpi/acdispat.h> | 47 | #include <acpi/acdispat.h> |
48 | #include <acpi/actables.h> | ||
48 | 49 | ||
49 | #define _COMPONENT ACPI_NAMESPACE | 50 | #define _COMPONENT ACPI_NAMESPACE |
50 | ACPI_MODULE_NAME("nsparse") | 51 | ACPI_MODULE_NAME("nsparse") |
@@ -62,14 +63,24 @@ ACPI_MODULE_NAME("nsparse") | |||
62 | * | 63 | * |
63 | ******************************************************************************/ | 64 | ******************************************************************************/ |
64 | acpi_status | 65 | acpi_status |
65 | acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) | 66 | acpi_ns_one_complete_parse(acpi_native_uint pass_number, |
67 | acpi_native_uint table_index) | ||
66 | { | 68 | { |
67 | union acpi_parse_object *parse_root; | 69 | union acpi_parse_object *parse_root; |
68 | acpi_status status; | 70 | acpi_status status; |
71 | acpi_native_uint aml_length; | ||
72 | u8 *aml_start; | ||
69 | struct acpi_walk_state *walk_state; | 73 | struct acpi_walk_state *walk_state; |
74 | struct acpi_table_header *table; | ||
75 | acpi_owner_id owner_id; | ||
70 | 76 | ||
71 | ACPI_FUNCTION_TRACE(ns_one_complete_parse); | 77 | ACPI_FUNCTION_TRACE(ns_one_complete_parse); |
72 | 78 | ||
79 | status = acpi_tb_get_owner_id(table_index, &owner_id); | ||
80 | if (ACPI_FAILURE(status)) { | ||
81 | return_ACPI_STATUS(status); | ||
82 | } | ||
83 | |||
73 | /* Create and init a Root Node */ | 84 | /* Create and init a Root Node */ |
74 | 85 | ||
75 | parse_root = acpi_ps_create_scope_op(); | 86 | parse_root = acpi_ps_create_scope_op(); |
@@ -79,26 +90,41 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) | |||
79 | 90 | ||
80 | /* Create and initialize a new walk state */ | 91 | /* Create and initialize a new walk state */ |
81 | 92 | ||
82 | walk_state = acpi_ds_create_walk_state(table_desc->owner_id, | 93 | walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL); |
83 | NULL, NULL, NULL); | ||
84 | if (!walk_state) { | 94 | if (!walk_state) { |
85 | acpi_ps_free_op(parse_root); | 95 | acpi_ps_free_op(parse_root); |
86 | return_ACPI_STATUS(AE_NO_MEMORY); | 96 | return_ACPI_STATUS(AE_NO_MEMORY); |
87 | } | 97 | } |
88 | 98 | ||
89 | status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, | 99 | status = acpi_get_table_by_index(table_index, &table); |
90 | table_desc->aml_start, | 100 | if (ACPI_FAILURE(status)) { |
91 | table_desc->aml_length, NULL, | 101 | acpi_ds_delete_walk_state(walk_state); |
92 | pass_number); | 102 | acpi_ps_free_op(parse_root); |
103 | return_ACPI_STATUS(status); | ||
104 | } | ||
105 | |||
106 | /* Table must consist of at least a complete header */ | ||
107 | |||
108 | if (table->length < sizeof(struct acpi_table_header)) { | ||
109 | status = AE_BAD_HEADER; | ||
110 | } else { | ||
111 | aml_start = (u8 *) table + sizeof(struct acpi_table_header); | ||
112 | aml_length = table->length - sizeof(struct acpi_table_header); | ||
113 | status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, | ||
114 | aml_start, aml_length, NULL, | ||
115 | (u8) pass_number); | ||
116 | } | ||
117 | |||
93 | if (ACPI_FAILURE(status)) { | 118 | if (ACPI_FAILURE(status)) { |
94 | acpi_ds_delete_walk_state(walk_state); | 119 | acpi_ds_delete_walk_state(walk_state); |
120 | acpi_ps_delete_parse_tree(parse_root); | ||
95 | return_ACPI_STATUS(status); | 121 | return_ACPI_STATUS(status); |
96 | } | 122 | } |
97 | 123 | ||
98 | /* Parse the AML */ | 124 | /* Parse the AML */ |
99 | 125 | ||
100 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", | 126 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", |
101 | pass_number)); | 127 | (unsigned)pass_number)); |
102 | status = acpi_ps_parse_aml(walk_state); | 128 | status = acpi_ps_parse_aml(walk_state); |
103 | 129 | ||
104 | acpi_ps_delete_parse_tree(parse_root); | 130 | acpi_ps_delete_parse_tree(parse_root); |
@@ -119,7 +145,7 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) | |||
119 | ******************************************************************************/ | 145 | ******************************************************************************/ |
120 | 146 | ||
121 | acpi_status | 147 | acpi_status |
122 | acpi_ns_parse_table(struct acpi_table_desc *table_desc, | 148 | acpi_ns_parse_table(acpi_native_uint table_index, |
123 | struct acpi_namespace_node *start_node) | 149 | struct acpi_namespace_node *start_node) |
124 | { | 150 | { |
125 | acpi_status status; | 151 | acpi_status status; |
@@ -134,10 +160,10 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc, | |||
134 | * each Parser Op subtree is deleted when it is finished. This saves | 160 | * each Parser Op subtree is deleted when it is finished. This saves |
135 | * a great deal of memory, and allows a small cache of parse objects | 161 | * a great deal of memory, and allows a small cache of parse objects |
136 | * to service the entire parse. The second pass of the parse then | 162 | * to service the entire parse. The second pass of the parse then |
137 | * performs another complete parse of the AML.. | 163 | * performs another complete parse of the AML. |
138 | */ | 164 | */ |
139 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); | 165 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); |
140 | status = acpi_ns_one_complete_parse(1, table_desc); | 166 | status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index); |
141 | if (ACPI_FAILURE(status)) { | 167 | if (ACPI_FAILURE(status)) { |
142 | return_ACPI_STATUS(status); | 168 | return_ACPI_STATUS(status); |
143 | } | 169 | } |
@@ -152,7 +178,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc, | |||
152 | * parse objects are all cached. | 178 | * parse objects are all cached. |
153 | */ | 179 | */ |
154 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); | 180 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); |
155 | status = acpi_ns_one_complete_parse(2, table_desc); | 181 | status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index); |
156 | if (ACPI_FAILURE(status)) { | 182 | if (ACPI_FAILURE(status)) { |
157 | return_ACPI_STATUS(status); | 183 | return_ACPI_STATUS(status); |
158 | } | 184 | } |
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index 500e2bbcfaf7..e863be665ce8 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -321,7 +321,8 @@ acpi_ns_search_and_enter(u32 target_name, | |||
321 | * even though there are a few bad names. | 321 | * even though there are a few bad names. |
322 | */ | 322 | */ |
323 | if (!acpi_ut_valid_acpi_name(target_name)) { | 323 | if (!acpi_ut_valid_acpi_name(target_name)) { |
324 | target_name = acpi_ut_repair_name(target_name); | 324 | target_name = |
325 | acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name)); | ||
325 | 326 | ||
326 | /* Report warning only if in strict mode or debug mode */ | 327 | /* Report warning only if in strict mode or debug mode */ |
327 | 328 | ||
@@ -401,6 +402,10 @@ acpi_ns_search_and_enter(u32 target_name, | |||
401 | } | 402 | } |
402 | #endif | 403 | #endif |
403 | 404 | ||
405 | if (flags & ACPI_NS_TEMPORARY) { | ||
406 | new_node->flags |= ANOBJ_TEMPORARY; | ||
407 | } | ||
408 | |||
404 | /* Install the new object into the parent's list of children */ | 409 | /* Install the new object into the parent's list of children */ |
405 | 410 | ||
406 | acpi_ns_install_node(walk_state, node, new_node, type); | 411 | acpi_ns_install_node(walk_state, node, new_node, type); |
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index aa4e799d9a8c..90fd059615ff 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -770,13 +770,6 @@ void acpi_ns_terminate(void) | |||
770 | } | 770 | } |
771 | 771 | ||
772 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); | 772 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); |
773 | |||
774 | /* | ||
775 | * 2) Now we can delete the ACPI tables | ||
776 | */ | ||
777 | acpi_tb_delete_all_tables(); | ||
778 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); | ||
779 | |||
780 | return_VOID; | 773 | return_VOID; |
781 | } | 774 | } |
782 | 775 | ||
diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c index c8f6bef16ed0..94eb8f332d94 100644 --- a/drivers/acpi/namespace/nswalk.c +++ b/drivers/acpi/namespace/nswalk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -126,7 +126,7 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, | |||
126 | * PARAMETERS: Type - acpi_object_type to search for | 126 | * PARAMETERS: Type - acpi_object_type to search for |
127 | * start_node - Handle in namespace where search begins | 127 | * start_node - Handle in namespace where search begins |
128 | * max_depth - Depth to which search is to reach | 128 | * max_depth - Depth to which search is to reach |
129 | * unlock_before_callback- Whether to unlock the NS before invoking | 129 | * Flags - Whether to unlock the NS before invoking |
130 | * the callback routine | 130 | * the callback routine |
131 | * user_function - Called when an object of "Type" is found | 131 | * user_function - Called when an object of "Type" is found |
132 | * Context - Passed to user function | 132 | * Context - Passed to user function |
@@ -153,7 +153,7 @@ acpi_status | |||
153 | acpi_ns_walk_namespace(acpi_object_type type, | 153 | acpi_ns_walk_namespace(acpi_object_type type, |
154 | acpi_handle start_node, | 154 | acpi_handle start_node, |
155 | u32 max_depth, | 155 | u32 max_depth, |
156 | u8 unlock_before_callback, | 156 | u32 flags, |
157 | acpi_walk_callback user_function, | 157 | acpi_walk_callback user_function, |
158 | void *context, void **return_value) | 158 | void *context, void **return_value) |
159 | { | 159 | { |
@@ -193,20 +193,34 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
193 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | 193 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, |
194 | child_node); | 194 | child_node); |
195 | if (child_node) { | 195 | if (child_node) { |
196 | /* | 196 | |
197 | * Found node, Get the type if we are not | 197 | /* Found next child, get the type if we are not searching for ANY */ |
198 | * searching for ANY | 198 | |
199 | */ | ||
200 | if (type != ACPI_TYPE_ANY) { | 199 | if (type != ACPI_TYPE_ANY) { |
201 | child_type = child_node->type; | 200 | child_type = child_node->type; |
202 | } | 201 | } |
203 | 202 | ||
204 | if (child_type == type) { | 203 | /* |
204 | * Ignore all temporary namespace nodes (created during control | ||
205 | * method execution) unless told otherwise. These temporary nodes | ||
206 | * can cause a race condition because they can be deleted during the | ||
207 | * execution of the user function (if the namespace is unlocked before | ||
208 | * invocation of the user function.) Only the debugger namespace dump | ||
209 | * will examine the temporary nodes. | ||
210 | */ | ||
211 | if ((child_node->flags & ANOBJ_TEMPORARY) && | ||
212 | !(flags & ACPI_NS_WALK_TEMP_NODES)) { | ||
213 | status = AE_CTRL_DEPTH; | ||
214 | } | ||
215 | |||
216 | /* Type must match requested type */ | ||
217 | |||
218 | else if (child_type == type) { | ||
205 | /* | 219 | /* |
206 | * Found a matching node, invoke the user | 220 | * Found a matching node, invoke the user callback function. |
207 | * callback function | 221 | * Unlock the namespace if flag is set. |
208 | */ | 222 | */ |
209 | if (unlock_before_callback) { | 223 | if (flags & ACPI_NS_WALK_UNLOCK) { |
210 | mutex_status = | 224 | mutex_status = |
211 | acpi_ut_release_mutex | 225 | acpi_ut_release_mutex |
212 | (ACPI_MTX_NAMESPACE); | 226 | (ACPI_MTX_NAMESPACE); |
@@ -216,10 +230,11 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
216 | } | 230 | } |
217 | } | 231 | } |
218 | 232 | ||
219 | status = user_function(child_node, level, | 233 | status = |
220 | context, return_value); | 234 | user_function(child_node, level, context, |
235 | return_value); | ||
221 | 236 | ||
222 | if (unlock_before_callback) { | 237 | if (flags & ACPI_NS_WALK_UNLOCK) { |
223 | mutex_status = | 238 | mutex_status = |
224 | acpi_ut_acquire_mutex | 239 | acpi_ut_acquire_mutex |
225 | (ACPI_MTX_NAMESPACE); | 240 | (ACPI_MTX_NAMESPACE); |
@@ -251,20 +266,17 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
251 | } | 266 | } |
252 | 267 | ||
253 | /* | 268 | /* |
254 | * Depth first search: | 269 | * Depth first search: Attempt to go down another level in the |
255 | * Attempt to go down another level in the namespace | 270 | * namespace if we are allowed to. Don't go any further if we have |
256 | * if we are allowed to. Don't go any further if we | 271 | * reached the caller specified maximum depth or if the user |
257 | * have reached the caller specified maximum depth | 272 | * function has specified that the maximum depth has been reached. |
258 | * or if the user function has specified that the | ||
259 | * maximum depth has been reached. | ||
260 | */ | 273 | */ |
261 | if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { | 274 | if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { |
262 | if (acpi_ns_get_next_node | 275 | if (acpi_ns_get_next_node |
263 | (ACPI_TYPE_ANY, child_node, NULL)) { | 276 | (ACPI_TYPE_ANY, child_node, NULL)) { |
264 | /* | 277 | |
265 | * There is at least one child of this | 278 | /* There is at least one child of this node, visit it */ |
266 | * node, visit the onde | 279 | |
267 | */ | ||
268 | level++; | 280 | level++; |
269 | parent_node = child_node; | 281 | parent_node = child_node; |
270 | child_node = NULL; | 282 | child_node = NULL; |
@@ -272,9 +284,8 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
272 | } | 284 | } |
273 | } else { | 285 | } else { |
274 | /* | 286 | /* |
275 | * No more children of this node (acpi_ns_get_next_node | 287 | * No more children of this node (acpi_ns_get_next_node failed), go |
276 | * failed), go back upwards in the namespace tree to | 288 | * back upwards in the namespace tree to the node's parent. |
277 | * the node's parent. | ||
278 | */ | 289 | */ |
279 | level--; | 290 | level--; |
280 | child_node = parent_node; | 291 | child_node = parent_node; |
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index dca6799ac678..7ac6ace50059 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -170,7 +170,6 @@ acpi_evaluate_object(acpi_handle handle, | |||
170 | struct acpi_buffer *return_buffer) | 170 | struct acpi_buffer *return_buffer) |
171 | { | 171 | { |
172 | acpi_status status; | 172 | acpi_status status; |
173 | acpi_status status2; | ||
174 | struct acpi_evaluate_info *info; | 173 | struct acpi_evaluate_info *info; |
175 | acpi_size buffer_space_needed; | 174 | acpi_size buffer_space_needed; |
176 | u32 i; | 175 | u32 i; |
@@ -329,14 +328,12 @@ acpi_evaluate_object(acpi_handle handle, | |||
329 | * Delete the internal return object. NOTE: Interpreter must be | 328 | * Delete the internal return object. NOTE: Interpreter must be |
330 | * locked to avoid race condition. | 329 | * locked to avoid race condition. |
331 | */ | 330 | */ |
332 | status2 = acpi_ex_enter_interpreter(); | 331 | acpi_ex_enter_interpreter(); |
333 | if (ACPI_SUCCESS(status2)) { | ||
334 | 332 | ||
335 | /* Remove one reference on the return object (should delete it) */ | 333 | /* Remove one reference on the return object (should delete it) */ |
336 | 334 | ||
337 | acpi_ut_remove_reference(info->return_object); | 335 | acpi_ut_remove_reference(info->return_object); |
338 | acpi_ex_exit_interpreter(); | 336 | acpi_ex_exit_interpreter(); |
339 | } | ||
340 | } | 337 | } |
341 | 338 | ||
342 | cleanup: | 339 | cleanup: |
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index 978213a6c19f..b489781b22a8 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -84,38 +84,41 @@ acpi_get_handle(acpi_handle parent, | |||
84 | /* Convert a parent handle to a prefix node */ | 84 | /* Convert a parent handle to a prefix node */ |
85 | 85 | ||
86 | if (parent) { | 86 | if (parent) { |
87 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
88 | if (ACPI_FAILURE(status)) { | ||
89 | return (status); | ||
90 | } | ||
91 | |||
92 | prefix_node = acpi_ns_map_handle_to_node(parent); | 87 | prefix_node = acpi_ns_map_handle_to_node(parent); |
93 | if (!prefix_node) { | 88 | if (!prefix_node) { |
94 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
95 | return (AE_BAD_PARAMETER); | 89 | return (AE_BAD_PARAMETER); |
96 | } | 90 | } |
91 | } | ||
92 | |||
93 | /* | ||
94 | * Valid cases are: | ||
95 | * 1) Fully qualified pathname | ||
96 | * 2) Parent + Relative pathname | ||
97 | * | ||
98 | * Error for <null Parent + relative path> | ||
99 | */ | ||
100 | if (acpi_ns_valid_root_prefix(pathname[0])) { | ||
97 | 101 | ||
98 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 102 | /* Pathname is fully qualified (starts with '\') */ |
99 | if (ACPI_FAILURE(status)) { | 103 | |
100 | return (status); | 104 | /* Special case for root-only, since we can't search for it */ |
105 | |||
106 | if (!ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH)) { | ||
107 | *ret_handle = | ||
108 | acpi_ns_convert_entry_to_handle(acpi_gbl_root_node); | ||
109 | return (AE_OK); | ||
101 | } | 110 | } |
102 | } | 111 | } else if (!prefix_node) { |
103 | 112 | ||
104 | /* Special case for root, since we can't search for it */ | 113 | /* Relative path with null prefix is disallowed */ |
105 | 114 | ||
106 | if (ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH) == 0) { | 115 | return (AE_BAD_PARAMETER); |
107 | *ret_handle = | ||
108 | acpi_ns_convert_entry_to_handle(acpi_gbl_root_node); | ||
109 | return (AE_OK); | ||
110 | } | 116 | } |
111 | 117 | ||
112 | /* | 118 | /* Find the Node and convert to a handle */ |
113 | * Find the Node and convert to a handle | ||
114 | */ | ||
115 | status = acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, | ||
116 | &node); | ||
117 | 119 | ||
118 | *ret_handle = NULL; | 120 | status = |
121 | acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node); | ||
119 | if (ACPI_SUCCESS(status)) { | 122 | if (ACPI_SUCCESS(status)) { |
120 | *ret_handle = acpi_ns_convert_entry_to_handle(node); | 123 | *ret_handle = acpi_ns_convert_entry_to_handle(node); |
121 | } | 124 | } |
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c index a163e1d3708d..faa375887201 100644 --- a/drivers/acpi/namespace/nsxfobj.c +++ b/drivers/acpi/namespace/nsxfobj.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -50,6 +50,50 @@ ACPI_MODULE_NAME("nsxfobj") | |||
50 | 50 | ||
51 | /******************************************************************************* | 51 | /******************************************************************************* |
52 | * | 52 | * |
53 | * FUNCTION: acpi_get_id | ||
54 | * | ||
55 | * PARAMETERS: Handle - Handle of object whose id is desired | ||
56 | * ret_id - Where the id will be placed | ||
57 | * | ||
58 | * RETURN: Status | ||
59 | * | ||
60 | * DESCRIPTION: This routine returns the owner id associated with a handle | ||
61 | * | ||
62 | ******************************************************************************/ | ||
63 | acpi_status acpi_get_id(acpi_handle handle, acpi_owner_id * ret_id) | ||
64 | { | ||
65 | struct acpi_namespace_node *node; | ||
66 | acpi_status status; | ||
67 | |||
68 | /* Parameter Validation */ | ||
69 | |||
70 | if (!ret_id) { | ||
71 | return (AE_BAD_PARAMETER); | ||
72 | } | ||
73 | |||
74 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
75 | if (ACPI_FAILURE(status)) { | ||
76 | return (status); | ||
77 | } | ||
78 | |||
79 | /* Convert and validate the handle */ | ||
80 | |||
81 | node = acpi_ns_map_handle_to_node(handle); | ||
82 | if (!node) { | ||
83 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
84 | return (AE_BAD_PARAMETER); | ||
85 | } | ||
86 | |||
87 | *ret_id = node->owner_id; | ||
88 | |||
89 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
90 | return (status); | ||
91 | } | ||
92 | |||
93 | ACPI_EXPORT_SYMBOL(acpi_get_id) | ||
94 | |||
95 | /******************************************************************************* | ||
96 | * | ||
53 | * FUNCTION: acpi_get_type | 97 | * FUNCTION: acpi_get_type |
54 | * | 98 | * |
55 | * PARAMETERS: Handle - Handle of object whose type is desired | 99 | * PARAMETERS: Handle - Handle of object whose type is desired |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index e5e448edca41..4a9faff4c01d 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -45,7 +45,7 @@ int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS] | |||
45 | int __cpuinitdata node_to_pxm_map[MAX_NUMNODES] | 45 | int __cpuinitdata node_to_pxm_map[MAX_NUMNODES] |
46 | = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; | 46 | = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; |
47 | 47 | ||
48 | extern int __init acpi_table_parse_madt_family(enum acpi_table_id id, | 48 | extern int __init acpi_table_parse_madt_family(char *id, |
49 | unsigned long madt_size, | 49 | unsigned long madt_size, |
50 | int entry_id, | 50 | int entry_id, |
51 | acpi_madt_entry_handler handler, | 51 | acpi_madt_entry_handler handler, |
@@ -89,7 +89,7 @@ void __cpuinit acpi_unmap_pxm_to_node(int node) | |||
89 | node_clear(node, nodes_found_map); | 89 | node_clear(node, nodes_found_map); |
90 | } | 90 | } |
91 | 91 | ||
92 | void __init acpi_table_print_srat_entry(acpi_table_entry_header * header) | 92 | void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header) |
93 | { | 93 | { |
94 | 94 | ||
95 | ACPI_FUNCTION_NAME("acpi_table_print_srat_entry"); | 95 | ACPI_FUNCTION_NAME("acpi_table_print_srat_entry"); |
@@ -99,36 +99,35 @@ void __init acpi_table_print_srat_entry(acpi_table_entry_header * header) | |||
99 | 99 | ||
100 | switch (header->type) { | 100 | switch (header->type) { |
101 | 101 | ||
102 | case ACPI_SRAT_PROCESSOR_AFFINITY: | 102 | case ACPI_SRAT_TYPE_CPU_AFFINITY: |
103 | #ifdef ACPI_DEBUG_OUTPUT | 103 | #ifdef ACPI_DEBUG_OUTPUT |
104 | { | 104 | { |
105 | struct acpi_table_processor_affinity *p = | 105 | struct acpi_srat_cpu_affinity *p = |
106 | (struct acpi_table_processor_affinity *)header; | 106 | (struct acpi_srat_cpu_affinity *)header; |
107 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 107 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
108 | "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n", | 108 | "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n", |
109 | p->apic_id, p->lsapic_eid, | 109 | p->apic_id, p->local_sapic_eid, |
110 | p->proximity_domain, | 110 | p->proximity_domain_lo, |
111 | p->flags. | 111 | (p->flags & ACPI_SRAT_CPU_ENABLED)? |
112 | enabled ? "enabled" : "disabled")); | 112 | "enabled" : "disabled")); |
113 | } | 113 | } |
114 | #endif /* ACPI_DEBUG_OUTPUT */ | 114 | #endif /* ACPI_DEBUG_OUTPUT */ |
115 | break; | 115 | break; |
116 | 116 | ||
117 | case ACPI_SRAT_MEMORY_AFFINITY: | 117 | case ACPI_SRAT_TYPE_MEMORY_AFFINITY: |
118 | #ifdef ACPI_DEBUG_OUTPUT | 118 | #ifdef ACPI_DEBUG_OUTPUT |
119 | { | 119 | { |
120 | struct acpi_table_memory_affinity *p = | 120 | struct acpi_srat_mem_affinity *p = |
121 | (struct acpi_table_memory_affinity *)header; | 121 | (struct acpi_srat_mem_affinity *)header; |
122 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 122 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
123 | "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n", | 123 | "SRAT Memory (0x%lx length 0x%lx type 0x%x) in proximity domain %d %s%s\n", |
124 | p->base_addr_hi, p->base_addr_lo, | 124 | (unsigned long)p->base_address, |
125 | p->length_hi, p->length_lo, | 125 | (unsigned long)p->length, |
126 | p->memory_type, p->proximity_domain, | 126 | p->memory_type, p->proximity_domain, |
127 | p->flags. | 127 | (p->flags & ACPI_SRAT_MEM_ENABLED)? |
128 | enabled ? "enabled" : "disabled", | 128 | "enabled" : "disabled", |
129 | p->flags. | 129 | (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)? |
130 | hot_pluggable ? " hot-pluggable" : | 130 | " hot-pluggable" : "")); |
131 | "")); | ||
132 | } | 131 | } |
133 | #endif /* ACPI_DEBUG_OUTPUT */ | 132 | #endif /* ACPI_DEBUG_OUTPUT */ |
134 | break; | 133 | break; |
@@ -141,18 +140,18 @@ void __init acpi_table_print_srat_entry(acpi_table_entry_header * header) | |||
141 | } | 140 | } |
142 | } | 141 | } |
143 | 142 | ||
144 | static int __init acpi_parse_slit(unsigned long phys_addr, unsigned long size) | 143 | static int __init acpi_parse_slit(struct acpi_table_header *table) |
145 | { | 144 | { |
146 | struct acpi_table_slit *slit; | 145 | struct acpi_table_slit *slit; |
147 | u32 localities; | 146 | u32 localities; |
148 | 147 | ||
149 | if (!phys_addr || !size) | 148 | if (!table) |
150 | return -EINVAL; | 149 | return -EINVAL; |
151 | 150 | ||
152 | slit = (struct acpi_table_slit *)__va(phys_addr); | 151 | slit = (struct acpi_table_slit *)table; |
153 | 152 | ||
154 | /* downcast just for %llu vs %lu for i386/ia64 */ | 153 | /* downcast just for %llu vs %lu for i386/ia64 */ |
155 | localities = (u32) slit->localities; | 154 | localities = (u32) slit->locality_count; |
156 | 155 | ||
157 | acpi_numa_slit_init(slit); | 156 | acpi_numa_slit_init(slit); |
158 | 157 | ||
@@ -160,12 +159,12 @@ static int __init acpi_parse_slit(unsigned long phys_addr, unsigned long size) | |||
160 | } | 159 | } |
161 | 160 | ||
162 | static int __init | 161 | static int __init |
163 | acpi_parse_processor_affinity(acpi_table_entry_header * header, | 162 | acpi_parse_processor_affinity(struct acpi_subtable_header * header, |
164 | const unsigned long end) | 163 | const unsigned long end) |
165 | { | 164 | { |
166 | struct acpi_table_processor_affinity *processor_affinity; | 165 | struct acpi_srat_cpu_affinity *processor_affinity; |
167 | 166 | ||
168 | processor_affinity = (struct acpi_table_processor_affinity *)header; | 167 | processor_affinity = (struct acpi_srat_cpu_affinity *)header; |
169 | if (!processor_affinity) | 168 | if (!processor_affinity) |
170 | return -EINVAL; | 169 | return -EINVAL; |
171 | 170 | ||
@@ -178,12 +177,12 @@ acpi_parse_processor_affinity(acpi_table_entry_header * header, | |||
178 | } | 177 | } |
179 | 178 | ||
180 | static int __init | 179 | static int __init |
181 | acpi_parse_memory_affinity(acpi_table_entry_header * header, | 180 | acpi_parse_memory_affinity(struct acpi_subtable_header * header, |
182 | const unsigned long end) | 181 | const unsigned long end) |
183 | { | 182 | { |
184 | struct acpi_table_memory_affinity *memory_affinity; | 183 | struct acpi_srat_mem_affinity *memory_affinity; |
185 | 184 | ||
186 | memory_affinity = (struct acpi_table_memory_affinity *)header; | 185 | memory_affinity = (struct acpi_srat_mem_affinity *)header; |
187 | if (!memory_affinity) | 186 | if (!memory_affinity) |
188 | return -EINVAL; | 187 | return -EINVAL; |
189 | 188 | ||
@@ -195,23 +194,23 @@ acpi_parse_memory_affinity(acpi_table_entry_header * header, | |||
195 | return 0; | 194 | return 0; |
196 | } | 195 | } |
197 | 196 | ||
198 | static int __init acpi_parse_srat(unsigned long phys_addr, unsigned long size) | 197 | static int __init acpi_parse_srat(struct acpi_table_header *table) |
199 | { | 198 | { |
200 | struct acpi_table_srat *srat; | 199 | struct acpi_table_srat *srat; |
201 | 200 | ||
202 | if (!phys_addr || !size) | 201 | if (!table) |
203 | return -EINVAL; | 202 | return -EINVAL; |
204 | 203 | ||
205 | srat = (struct acpi_table_srat *)__va(phys_addr); | 204 | srat = (struct acpi_table_srat *)table; |
206 | 205 | ||
207 | return 0; | 206 | return 0; |
208 | } | 207 | } |
209 | 208 | ||
210 | int __init | 209 | int __init |
211 | acpi_table_parse_srat(enum acpi_srat_entry_id id, | 210 | acpi_table_parse_srat(enum acpi_srat_type id, |
212 | acpi_madt_entry_handler handler, unsigned int max_entries) | 211 | acpi_madt_entry_handler handler, unsigned int max_entries) |
213 | { | 212 | { |
214 | return acpi_table_parse_madt_family(ACPI_SRAT, | 213 | return acpi_table_parse_madt_family(ACPI_SIG_SRAT, |
215 | sizeof(struct acpi_table_srat), id, | 214 | sizeof(struct acpi_table_srat), id, |
216 | handler, max_entries); | 215 | handler, max_entries); |
217 | } | 216 | } |
@@ -221,17 +220,17 @@ int __init acpi_numa_init(void) | |||
221 | int result; | 220 | int result; |
222 | 221 | ||
223 | /* SRAT: Static Resource Affinity Table */ | 222 | /* SRAT: Static Resource Affinity Table */ |
224 | result = acpi_table_parse(ACPI_SRAT, acpi_parse_srat); | 223 | result = acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat); |
225 | 224 | ||
226 | if (result > 0) { | 225 | if (result > 0) { |
227 | result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY, | 226 | result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, |
228 | acpi_parse_processor_affinity, | 227 | acpi_parse_processor_affinity, |
229 | NR_CPUS); | 228 | NR_CPUS); |
230 | result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific | 229 | result = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific |
231 | } | 230 | } |
232 | 231 | ||
233 | /* SLIT: System Locality Information Table */ | 232 | /* SLIT: System Locality Information Table */ |
234 | result = acpi_table_parse(ACPI_SLIT, acpi_parse_slit); | 233 | result = acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); |
235 | 234 | ||
236 | acpi_numa_arch_fixup(); | 235 | acpi_numa_arch_fixup(); |
237 | return 0; | 236 | return 0; |
@@ -248,7 +247,7 @@ int acpi_get_pxm(acpi_handle h) | |||
248 | handle = phandle; | 247 | handle = phandle; |
249 | status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm); | 248 | status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm); |
250 | if (ACPI_SUCCESS(status)) | 249 | if (ACPI_SUCCESS(status)) |
251 | return (int)pxm; | 250 | return pxm; |
252 | status = acpi_get_parent(handle, &phandle); | 251 | status = acpi_get_parent(handle, &phandle); |
253 | } while (ACPI_SUCCESS(status)); | 252 | } while (ACPI_SUCCESS(status)); |
254 | return -1; | 253 | return -1; |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 02b30ae6a68e..a28f5b8972b4 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
37 | #include <linux/workqueue.h> | 37 | #include <linux/workqueue.h> |
38 | #include <linux/nmi.h> | 38 | #include <linux/nmi.h> |
39 | #include <linux/acpi.h> | ||
39 | #include <acpi/acpi.h> | 40 | #include <acpi/acpi.h> |
40 | #include <asm/io.h> | 41 | #include <asm/io.h> |
41 | #include <acpi/acpi_bus.h> | 42 | #include <acpi/acpi_bus.h> |
@@ -136,53 +137,43 @@ void acpi_os_vprintf(const char *fmt, va_list args) | |||
136 | #endif | 137 | #endif |
137 | } | 138 | } |
138 | 139 | ||
139 | acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr) | 140 | acpi_physical_address __init acpi_os_get_root_pointer(void) |
140 | { | 141 | { |
141 | if (efi_enabled) { | 142 | if (efi_enabled) { |
142 | addr->pointer_type = ACPI_PHYSICAL_POINTER; | ||
143 | if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) | 143 | if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) |
144 | addr->pointer.physical = efi.acpi20; | 144 | return efi.acpi20; |
145 | else if (efi.acpi != EFI_INVALID_TABLE_ADDR) | 145 | else if (efi.acpi != EFI_INVALID_TABLE_ADDR) |
146 | addr->pointer.physical = efi.acpi; | 146 | return efi.acpi; |
147 | else { | 147 | else { |
148 | printk(KERN_ERR PREFIX | 148 | printk(KERN_ERR PREFIX |
149 | "System description tables not found\n"); | 149 | "System description tables not found\n"); |
150 | return AE_NOT_FOUND; | 150 | return 0; |
151 | } | 151 | } |
152 | } else { | 152 | } else |
153 | if (ACPI_FAILURE(acpi_find_root_pointer(flags, addr))) { | 153 | return acpi_find_rsdp(); |
154 | printk(KERN_ERR PREFIX | ||
155 | "System description tables not found\n"); | ||
156 | return AE_NOT_FOUND; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | return AE_OK; | ||
161 | } | 154 | } |
162 | 155 | ||
163 | acpi_status | 156 | void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size) |
164 | acpi_os_map_memory(acpi_physical_address phys, acpi_size size, | ||
165 | void __iomem ** virt) | ||
166 | { | 157 | { |
167 | if (phys > ULONG_MAX) { | 158 | if (phys > ULONG_MAX) { |
168 | printk(KERN_ERR PREFIX "Cannot map memory that high\n"); | 159 | printk(KERN_ERR PREFIX "Cannot map memory that high\n"); |
169 | return AE_BAD_PARAMETER; | 160 | return 0; |
170 | } | 161 | } |
171 | /* | 162 | if (acpi_gbl_permanent_mmap) |
172 | * ioremap checks to ensure this is in reserved space | 163 | /* |
173 | */ | 164 | * ioremap checks to ensure this is in reserved space |
174 | *virt = ioremap((unsigned long)phys, size); | 165 | */ |
175 | 166 | return ioremap((unsigned long)phys, size); | |
176 | if (!*virt) | 167 | else |
177 | return AE_NO_MEMORY; | 168 | return __acpi_map_table((unsigned long)phys, size); |
178 | |||
179 | return AE_OK; | ||
180 | } | 169 | } |
181 | EXPORT_SYMBOL_GPL(acpi_os_map_memory); | 170 | EXPORT_SYMBOL_GPL(acpi_os_map_memory); |
182 | 171 | ||
183 | void acpi_os_unmap_memory(void __iomem * virt, acpi_size size) | 172 | void acpi_os_unmap_memory(void __iomem * virt, acpi_size size) |
184 | { | 173 | { |
185 | iounmap(virt); | 174 | if (acpi_gbl_permanent_mmap) { |
175 | iounmap(virt); | ||
176 | } | ||
186 | } | 177 | } |
187 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); | 178 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); |
188 | 179 | ||
@@ -254,7 +245,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, | |||
254 | * FADT. It may not be the same if an interrupt source override exists | 245 | * FADT. It may not be the same if an interrupt source override exists |
255 | * for the SCI. | 246 | * for the SCI. |
256 | */ | 247 | */ |
257 | gsi = acpi_fadt.sci_int; | 248 | gsi = acpi_gbl_FADT.sci_interrupt; |
258 | if (acpi_gsi_to_irq(gsi, &irq) < 0) { | 249 | if (acpi_gsi_to_irq(gsi, &irq) < 0) { |
259 | printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", | 250 | printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", |
260 | gsi); | 251 | gsi); |
@@ -568,6 +559,7 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */ | |||
568 | static void acpi_os_execute_deferred(struct work_struct *work) | 559 | static void acpi_os_execute_deferred(struct work_struct *work) |
569 | { | 560 | { |
570 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | 561 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); |
562 | |||
571 | if (!dpc) { | 563 | if (!dpc) { |
572 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | 564 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); |
573 | return; | 565 | return; |
@@ -1031,7 +1023,7 @@ acpi_status | |||
1031 | acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) | 1023 | acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) |
1032 | { | 1024 | { |
1033 | *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL); | 1025 | *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL); |
1034 | if (cache == NULL) | 1026 | if (*cache == NULL) |
1035 | return AE_ERROR; | 1027 | return AE_ERROR; |
1036 | else | 1028 | else |
1037 | return AE_OK; | 1029 | return AE_OK; |
@@ -1051,7 +1043,7 @@ acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) | |||
1051 | 1043 | ||
1052 | acpi_status acpi_os_purge_cache(acpi_cache_t * cache) | 1044 | acpi_status acpi_os_purge_cache(acpi_cache_t * cache) |
1053 | { | 1045 | { |
1054 | (void)kmem_cache_shrink(cache); | 1046 | kmem_cache_shrink(cache); |
1055 | return (AE_OK); | 1047 | return (AE_OK); |
1056 | } | 1048 | } |
1057 | 1049 | ||
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index bf88e076c3e9..c2b9835c890b 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c index e1541db3753a..773aee82fbb8 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/parser/psloop.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -42,12 +42,11 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | /* | 44 | /* |
45 | * Parse the AML and build an operation tree as most interpreters, | 45 | * Parse the AML and build an operation tree as most interpreters, (such as |
46 | * like Perl, do. Parsing is done by hand rather than with a YACC | 46 | * Perl) do. Parsing is done by hand rather than with a YACC generated parser |
47 | * generated parser to tightly constrain stack and dynamic memory | 47 | * to tightly constrain stack and dynamic memory usage. Parsing is kept |
48 | * usage. At the same time, parsing is kept flexible and the code | 48 | * flexible and the code fairly compact by parsing based on a list of AML |
49 | * fairly compact by parsing based on a list of AML opcode | 49 | * opcode templates in aml_op_info[]. |
50 | * templates in aml_op_info[] | ||
51 | */ | 50 | */ |
52 | 51 | ||
53 | #include <acpi/acpi.h> | 52 | #include <acpi/acpi.h> |
@@ -60,766 +59,679 @@ ACPI_MODULE_NAME("psloop") | |||
60 | 59 | ||
61 | static u32 acpi_gbl_depth = 0; | 60 | static u32 acpi_gbl_depth = 0; |
62 | 61 | ||
62 | /* Local prototypes */ | ||
63 | |||
64 | static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state); | ||
65 | |||
66 | static acpi_status | ||
67 | acpi_ps_build_named_op(struct acpi_walk_state *walk_state, | ||
68 | u8 * aml_op_start, | ||
69 | union acpi_parse_object *unnamed_op, | ||
70 | union acpi_parse_object **op); | ||
71 | |||
72 | static acpi_status | ||
73 | acpi_ps_create_op(struct acpi_walk_state *walk_state, | ||
74 | u8 * aml_op_start, union acpi_parse_object **new_op); | ||
75 | |||
76 | static acpi_status | ||
77 | acpi_ps_get_arguments(struct acpi_walk_state *walk_state, | ||
78 | u8 * aml_op_start, union acpi_parse_object *op); | ||
79 | |||
80 | static acpi_status | ||
81 | acpi_ps_complete_op(struct acpi_walk_state *walk_state, | ||
82 | union acpi_parse_object **op, acpi_status status); | ||
83 | |||
84 | static acpi_status | ||
85 | acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, | ||
86 | union acpi_parse_object *op, acpi_status status); | ||
87 | |||
63 | /******************************************************************************* | 88 | /******************************************************************************* |
64 | * | 89 | * |
65 | * FUNCTION: acpi_ps_parse_loop | 90 | * FUNCTION: acpi_ps_get_aml_opcode |
66 | * | 91 | * |
67 | * PARAMETERS: walk_state - Current state | 92 | * PARAMETERS: walk_state - Current state |
68 | * | 93 | * |
69 | * RETURN: Status | 94 | * RETURN: Status |
70 | * | 95 | * |
71 | * DESCRIPTION: Parse AML (pointed to by the current parser state) and return | 96 | * DESCRIPTION: Extract the next AML opcode from the input stream. |
72 | * a tree of ops. | ||
73 | * | 97 | * |
74 | ******************************************************************************/ | 98 | ******************************************************************************/ |
75 | 99 | ||
76 | acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | 100 | static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) |
77 | { | 101 | { |
78 | acpi_status status = AE_OK; | ||
79 | acpi_status status2; | ||
80 | union acpi_parse_object *op = NULL; /* current op */ | ||
81 | union acpi_parse_object *arg = NULL; | ||
82 | union acpi_parse_object *pre_op = NULL; | ||
83 | struct acpi_parse_state *parser_state; | ||
84 | u8 *aml_op_start = NULL; | ||
85 | 102 | ||
86 | ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state); | 103 | ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state); |
87 | 104 | ||
88 | if (walk_state->descending_callback == NULL) { | 105 | walk_state->aml_offset = |
89 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 106 | (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml, |
90 | } | 107 | walk_state->parser_state.aml_start); |
108 | walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state)); | ||
91 | 109 | ||
92 | parser_state = &walk_state->parser_state; | 110 | /* |
93 | walk_state->arg_types = 0; | 111 | * First cut to determine what we have found: |
112 | * 1) A valid AML opcode | ||
113 | * 2) A name string | ||
114 | * 3) An unknown/invalid opcode | ||
115 | */ | ||
116 | walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode); | ||
94 | 117 | ||
95 | #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) | 118 | switch (walk_state->op_info->class) { |
119 | case AML_CLASS_ASCII: | ||
120 | case AML_CLASS_PREFIX: | ||
121 | /* | ||
122 | * Starts with a valid prefix or ASCII char, this is a name | ||
123 | * string. Convert the bare name string to a namepath. | ||
124 | */ | ||
125 | walk_state->opcode = AML_INT_NAMEPATH_OP; | ||
126 | walk_state->arg_types = ARGP_NAMESTRING; | ||
127 | break; | ||
96 | 128 | ||
97 | if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) { | 129 | case AML_CLASS_UNKNOWN: |
98 | 130 | ||
99 | /* We are restarting a preempted control method */ | 131 | /* The opcode is unrecognized. Just skip unknown opcodes */ |
100 | 132 | ||
101 | if (acpi_ps_has_completed_scope(parser_state)) { | 133 | ACPI_ERROR((AE_INFO, |
102 | /* | 134 | "Found unknown opcode %X at AML address %p offset %X, ignoring", |
103 | * We must check if a predicate to an IF or WHILE statement | 135 | walk_state->opcode, walk_state->parser_state.aml, |
104 | * was just completed | 136 | walk_state->aml_offset)); |
105 | */ | ||
106 | if ((parser_state->scope->parse_scope.op) && | ||
107 | ((parser_state->scope->parse_scope.op->common. | ||
108 | aml_opcode == AML_IF_OP) | ||
109 | || (parser_state->scope->parse_scope.op->common. | ||
110 | aml_opcode == AML_WHILE_OP)) | ||
111 | && (walk_state->control_state) | ||
112 | && (walk_state->control_state->common.state == | ||
113 | ACPI_CONTROL_PREDICATE_EXECUTING)) { | ||
114 | /* | ||
115 | * A predicate was just completed, get the value of the | ||
116 | * predicate and branch based on that value | ||
117 | */ | ||
118 | walk_state->op = NULL; | ||
119 | status = | ||
120 | acpi_ds_get_predicate_value(walk_state, | ||
121 | ACPI_TO_POINTER | ||
122 | (TRUE)); | ||
123 | if (ACPI_FAILURE(status) | ||
124 | && ((status & AE_CODE_MASK) != | ||
125 | AE_CODE_CONTROL)) { | ||
126 | if (status == AE_AML_NO_RETURN_VALUE) { | ||
127 | ACPI_EXCEPTION((AE_INFO, status, | ||
128 | "Invoked method did not return a value")); | ||
129 | 137 | ||
130 | } | 138 | ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128); |
131 | ACPI_EXCEPTION((AE_INFO, status, | ||
132 | "GetPredicate Failed")); | ||
133 | return_ACPI_STATUS(status); | ||
134 | } | ||
135 | 139 | ||
136 | status = | 140 | /* Assume one-byte bad opcode */ |
137 | acpi_ps_next_parse_state(walk_state, op, | ||
138 | status); | ||
139 | } | ||
140 | 141 | ||
141 | acpi_ps_pop_scope(parser_state, &op, | 142 | walk_state->parser_state.aml++; |
142 | &walk_state->arg_types, | 143 | return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); |
143 | &walk_state->arg_count); | ||
144 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | ||
145 | "Popped scope, Op=%p\n", op)); | ||
146 | } else if (walk_state->prev_op) { | ||
147 | 144 | ||
148 | /* We were in the middle of an op */ | 145 | default: |
149 | 146 | ||
150 | op = walk_state->prev_op; | 147 | /* Found opcode info, this is a normal opcode */ |
151 | walk_state->arg_types = walk_state->prev_arg_types; | 148 | |
152 | } | 149 | walk_state->parser_state.aml += |
150 | acpi_ps_get_opcode_size(walk_state->opcode); | ||
151 | walk_state->arg_types = walk_state->op_info->parse_args; | ||
152 | break; | ||
153 | } | 153 | } |
154 | #endif | ||
155 | 154 | ||
156 | /* Iterative parsing loop, while there is more AML to process: */ | 155 | return_ACPI_STATUS(AE_OK); |
156 | } | ||
157 | 157 | ||
158 | while ((parser_state->aml < parser_state->aml_end) || (op)) { | 158 | /******************************************************************************* |
159 | aml_op_start = parser_state->aml; | 159 | * |
160 | if (!op) { | 160 | * FUNCTION: acpi_ps_build_named_op |
161 | * | ||
162 | * PARAMETERS: walk_state - Current state | ||
163 | * aml_op_start - Begin of named Op in AML | ||
164 | * unnamed_op - Early Op (not a named Op) | ||
165 | * Op - Returned Op | ||
166 | * | ||
167 | * RETURN: Status | ||
168 | * | ||
169 | * DESCRIPTION: Parse a named Op | ||
170 | * | ||
171 | ******************************************************************************/ | ||
161 | 172 | ||
162 | /* Get the next opcode from the AML stream */ | 173 | static acpi_status |
174 | acpi_ps_build_named_op(struct acpi_walk_state *walk_state, | ||
175 | u8 * aml_op_start, | ||
176 | union acpi_parse_object *unnamed_op, | ||
177 | union acpi_parse_object **op) | ||
178 | { | ||
179 | acpi_status status = AE_OK; | ||
180 | union acpi_parse_object *arg = NULL; | ||
163 | 181 | ||
164 | walk_state->aml_offset = | 182 | ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state); |
165 | (u32) ACPI_PTR_DIFF(parser_state->aml, | ||
166 | parser_state->aml_start); | ||
167 | walk_state->opcode = acpi_ps_peek_opcode(parser_state); | ||
168 | 183 | ||
169 | /* | 184 | unnamed_op->common.value.arg = NULL; |
170 | * First cut to determine what we have found: | 185 | unnamed_op->common.aml_opcode = walk_state->opcode; |
171 | * 1) A valid AML opcode | ||
172 | * 2) A name string | ||
173 | * 3) An unknown/invalid opcode | ||
174 | */ | ||
175 | walk_state->op_info = | ||
176 | acpi_ps_get_opcode_info(walk_state->opcode); | ||
177 | switch (walk_state->op_info->class) { | ||
178 | case AML_CLASS_ASCII: | ||
179 | case AML_CLASS_PREFIX: | ||
180 | /* | ||
181 | * Starts with a valid prefix or ASCII char, this is a name | ||
182 | * string. Convert the bare name string to a namepath. | ||
183 | */ | ||
184 | walk_state->opcode = AML_INT_NAMEPATH_OP; | ||
185 | walk_state->arg_types = ARGP_NAMESTRING; | ||
186 | break; | ||
187 | 186 | ||
188 | case AML_CLASS_UNKNOWN: | 187 | /* |
188 | * Get and append arguments until we find the node that contains | ||
189 | * the name (the type ARGP_NAME). | ||
190 | */ | ||
191 | while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) && | ||
192 | (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) { | ||
193 | status = | ||
194 | acpi_ps_get_next_arg(walk_state, | ||
195 | &(walk_state->parser_state), | ||
196 | GET_CURRENT_ARG_TYPE(walk_state-> | ||
197 | arg_types), &arg); | ||
198 | if (ACPI_FAILURE(status)) { | ||
199 | return_ACPI_STATUS(status); | ||
200 | } | ||
189 | 201 | ||
190 | /* The opcode is unrecognized. Just skip unknown opcodes */ | 202 | acpi_ps_append_arg(unnamed_op, arg); |
203 | INCREMENT_ARG_LIST(walk_state->arg_types); | ||
204 | } | ||
191 | 205 | ||
192 | ACPI_ERROR((AE_INFO, | 206 | /* |
193 | "Found unknown opcode %X at AML address %p offset %X, ignoring", | 207 | * Make sure that we found a NAME and didn't run out of arguments |
194 | walk_state->opcode, | 208 | */ |
195 | parser_state->aml, | 209 | if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) { |
196 | walk_state->aml_offset)); | 210 | return_ACPI_STATUS(AE_AML_NO_OPERAND); |
211 | } | ||
197 | 212 | ||
198 | ACPI_DUMP_BUFFER(parser_state->aml, 128); | 213 | /* We know that this arg is a name, move to next arg */ |
199 | 214 | ||
200 | /* Assume one-byte bad opcode */ | 215 | INCREMENT_ARG_LIST(walk_state->arg_types); |
201 | 216 | ||
202 | parser_state->aml++; | 217 | /* |
203 | continue; | 218 | * Find the object. This will either insert the object into |
219 | * the namespace or simply look it up | ||
220 | */ | ||
221 | walk_state->op = NULL; | ||
204 | 222 | ||
205 | default: | 223 | status = walk_state->descending_callback(walk_state, op); |
224 | if (ACPI_FAILURE(status)) { | ||
225 | ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog")); | ||
226 | return_ACPI_STATUS(status); | ||
227 | } | ||
206 | 228 | ||
207 | /* Found opcode info, this is a normal opcode */ | 229 | if (!*op) { |
230 | return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); | ||
231 | } | ||
208 | 232 | ||
209 | parser_state->aml += | 233 | status = acpi_ps_next_parse_state(walk_state, *op, status); |
210 | acpi_ps_get_opcode_size(walk_state->opcode); | 234 | if (ACPI_FAILURE(status)) { |
211 | walk_state->arg_types = | 235 | if (status == AE_CTRL_PENDING) { |
212 | walk_state->op_info->parse_args; | 236 | return_ACPI_STATUS(AE_CTRL_PARSE_PENDING); |
213 | break; | 237 | } |
214 | } | 238 | return_ACPI_STATUS(status); |
239 | } | ||
215 | 240 | ||
216 | /* Create Op structure and append to parent's argument list */ | 241 | acpi_ps_append_arg(*op, unnamed_op->common.value.arg); |
242 | acpi_gbl_depth++; | ||
217 | 243 | ||
218 | if (walk_state->op_info->flags & AML_NAMED) { | 244 | if ((*op)->common.aml_opcode == AML_REGION_OP) { |
245 | /* | ||
246 | * Defer final parsing of an operation_region body, because we don't | ||
247 | * have enough info in the first pass to parse it correctly (i.e., | ||
248 | * there may be method calls within the term_arg elements of the body.) | ||
249 | * | ||
250 | * However, we must continue parsing because the opregion is not a | ||
251 | * standalone package -- we don't know where the end is at this point. | ||
252 | * | ||
253 | * (Length is unknown until parse of the body complete) | ||
254 | */ | ||
255 | (*op)->named.data = aml_op_start; | ||
256 | (*op)->named.length = 0; | ||
257 | } | ||
219 | 258 | ||
220 | /* Allocate a new pre_op if necessary */ | 259 | return_ACPI_STATUS(AE_OK); |
260 | } | ||
221 | 261 | ||
222 | if (!pre_op) { | 262 | /******************************************************************************* |
223 | pre_op = | 263 | * |
224 | acpi_ps_alloc_op(walk_state-> | 264 | * FUNCTION: acpi_ps_create_op |
225 | opcode); | 265 | * |
226 | if (!pre_op) { | 266 | * PARAMETERS: walk_state - Current state |
227 | status = AE_NO_MEMORY; | 267 | * aml_op_start - Op start in AML |
228 | goto close_this_op; | 268 | * new_op - Returned Op |
229 | } | 269 | * |
230 | } | 270 | * RETURN: Status |
271 | * | ||
272 | * DESCRIPTION: Get Op from AML | ||
273 | * | ||
274 | ******************************************************************************/ | ||
231 | 275 | ||
232 | pre_op->common.value.arg = NULL; | 276 | static acpi_status |
233 | pre_op->common.aml_opcode = walk_state->opcode; | 277 | acpi_ps_create_op(struct acpi_walk_state *walk_state, |
278 | u8 * aml_op_start, union acpi_parse_object **new_op) | ||
279 | { | ||
280 | acpi_status status = AE_OK; | ||
281 | union acpi_parse_object *op; | ||
282 | union acpi_parse_object *named_op = NULL; | ||
234 | 283 | ||
235 | /* | 284 | ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state); |
236 | * Get and append arguments until we find the node that contains | ||
237 | * the name (the type ARGP_NAME). | ||
238 | */ | ||
239 | while (GET_CURRENT_ARG_TYPE | ||
240 | (walk_state->arg_types) | ||
241 | && | ||
242 | (GET_CURRENT_ARG_TYPE | ||
243 | (walk_state->arg_types) != ARGP_NAME)) { | ||
244 | status = | ||
245 | acpi_ps_get_next_arg(walk_state, | ||
246 | parser_state, | ||
247 | GET_CURRENT_ARG_TYPE | ||
248 | (walk_state-> | ||
249 | arg_types), | ||
250 | &arg); | ||
251 | if (ACPI_FAILURE(status)) { | ||
252 | goto close_this_op; | ||
253 | } | ||
254 | 285 | ||
255 | acpi_ps_append_arg(pre_op, arg); | 286 | status = acpi_ps_get_aml_opcode(walk_state); |
256 | INCREMENT_ARG_LIST(walk_state-> | 287 | if (status == AE_CTRL_PARSE_CONTINUE) { |
257 | arg_types); | 288 | return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); |
258 | } | 289 | } |
259 | 290 | ||
260 | /* | 291 | /* Create Op structure and append to parent's argument list */ |
261 | * Make sure that we found a NAME and didn't run out of | ||
262 | * arguments | ||
263 | */ | ||
264 | if (!GET_CURRENT_ARG_TYPE | ||
265 | (walk_state->arg_types)) { | ||
266 | status = AE_AML_NO_OPERAND; | ||
267 | goto close_this_op; | ||
268 | } | ||
269 | 292 | ||
270 | /* We know that this arg is a name, move to next arg */ | 293 | walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode); |
294 | op = acpi_ps_alloc_op(walk_state->opcode); | ||
295 | if (!op) { | ||
296 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
297 | } | ||
271 | 298 | ||
272 | INCREMENT_ARG_LIST(walk_state->arg_types); | 299 | if (walk_state->op_info->flags & AML_NAMED) { |
300 | status = | ||
301 | acpi_ps_build_named_op(walk_state, aml_op_start, op, | ||
302 | &named_op); | ||
303 | acpi_ps_free_op(op); | ||
304 | if (ACPI_FAILURE(status)) { | ||
305 | return_ACPI_STATUS(status); | ||
306 | } | ||
273 | 307 | ||
274 | /* | 308 | *new_op = named_op; |
275 | * Find the object. This will either insert the object into | 309 | return_ACPI_STATUS(AE_OK); |
276 | * the namespace or simply look it up | 310 | } |
277 | */ | ||
278 | walk_state->op = NULL; | ||
279 | 311 | ||
280 | status = | 312 | /* Not a named opcode, just allocate Op and append to parent */ |
281 | walk_state->descending_callback(walk_state, | ||
282 | &op); | ||
283 | if (ACPI_FAILURE(status)) { | ||
284 | ACPI_EXCEPTION((AE_INFO, status, | ||
285 | "During name lookup/catalog")); | ||
286 | goto close_this_op; | ||
287 | } | ||
288 | 313 | ||
289 | if (!op) { | 314 | if (walk_state->op_info->flags & AML_CREATE) { |
290 | continue; | 315 | /* |
291 | } | 316 | * Backup to beginning of create_xXXfield declaration |
317 | * body_length is unknown until we parse the body | ||
318 | */ | ||
319 | op->named.data = aml_op_start; | ||
320 | op->named.length = 0; | ||
321 | } | ||
292 | 322 | ||
293 | status = | 323 | acpi_ps_append_arg(acpi_ps_get_parent_scope |
294 | acpi_ps_next_parse_state(walk_state, op, | 324 | (&(walk_state->parser_state)), op); |
295 | status); | ||
296 | if (status == AE_CTRL_PENDING) { | ||
297 | status = AE_OK; | ||
298 | goto close_this_op; | ||
299 | } | ||
300 | 325 | ||
301 | if (ACPI_FAILURE(status)) { | 326 | if (walk_state->descending_callback != NULL) { |
302 | goto close_this_op; | 327 | /* |
303 | } | 328 | * Find the object. This will either insert the object into |
329 | * the namespace or simply look it up | ||
330 | */ | ||
331 | walk_state->op = *new_op = op; | ||
304 | 332 | ||
305 | acpi_ps_append_arg(op, | 333 | status = walk_state->descending_callback(walk_state, &op); |
306 | pre_op->common.value.arg); | 334 | status = acpi_ps_next_parse_state(walk_state, op, status); |
307 | acpi_gbl_depth++; | 335 | if (status == AE_CTRL_PENDING) { |
308 | 336 | status = AE_CTRL_PARSE_PENDING; | |
309 | if (op->common.aml_opcode == AML_REGION_OP) { | 337 | } |
310 | /* | 338 | } |
311 | * Defer final parsing of an operation_region body, | ||
312 | * because we don't have enough info in the first pass | ||
313 | * to parse it correctly (i.e., there may be method | ||
314 | * calls within the term_arg elements of the body.) | ||
315 | * | ||
316 | * However, we must continue parsing because | ||
317 | * the opregion is not a standalone package -- | ||
318 | * we don't know where the end is at this point. | ||
319 | * | ||
320 | * (Length is unknown until parse of the body complete) | ||
321 | */ | ||
322 | op->named.data = aml_op_start; | ||
323 | op->named.length = 0; | ||
324 | } | ||
325 | } else { | ||
326 | /* Not a named opcode, just allocate Op and append to parent */ | ||
327 | 339 | ||
328 | walk_state->op_info = | 340 | return_ACPI_STATUS(status); |
329 | acpi_ps_get_opcode_info(walk_state->opcode); | 341 | } |
330 | op = acpi_ps_alloc_op(walk_state->opcode); | ||
331 | if (!op) { | ||
332 | status = AE_NO_MEMORY; | ||
333 | goto close_this_op; | ||
334 | } | ||
335 | 342 | ||
336 | if (walk_state->op_info->flags & AML_CREATE) { | 343 | /******************************************************************************* |
337 | /* | 344 | * |
338 | * Backup to beginning of create_xXXfield declaration | 345 | * FUNCTION: acpi_ps_get_arguments |
339 | * body_length is unknown until we parse the body | 346 | * |
340 | */ | 347 | * PARAMETERS: walk_state - Current state |
341 | op->named.data = aml_op_start; | 348 | * aml_op_start - Op start in AML |
342 | op->named.length = 0; | 349 | * Op - Current Op |
343 | } | 350 | * |
351 | * RETURN: Status | ||
352 | * | ||
353 | * DESCRIPTION: Get arguments for passed Op. | ||
354 | * | ||
355 | ******************************************************************************/ | ||
344 | 356 | ||
345 | acpi_ps_append_arg(acpi_ps_get_parent_scope | 357 | static acpi_status |
346 | (parser_state), op); | 358 | acpi_ps_get_arguments(struct acpi_walk_state *walk_state, |
359 | u8 * aml_op_start, union acpi_parse_object *op) | ||
360 | { | ||
361 | acpi_status status = AE_OK; | ||
362 | union acpi_parse_object *arg = NULL; | ||
347 | 363 | ||
348 | if ((walk_state->descending_callback != NULL)) { | 364 | ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state); |
349 | /* | ||
350 | * Find the object. This will either insert the object into | ||
351 | * the namespace or simply look it up | ||
352 | */ | ||
353 | walk_state->op = op; | ||
354 | 365 | ||
355 | status = | 366 | switch (op->common.aml_opcode) { |
356 | walk_state-> | 367 | case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ |
357 | descending_callback(walk_state, | 368 | case AML_WORD_OP: /* AML_WORDDATA_ARG */ |
358 | &op); | 369 | case AML_DWORD_OP: /* AML_DWORDATA_ARG */ |
359 | status = | 370 | case AML_QWORD_OP: /* AML_QWORDATA_ARG */ |
360 | acpi_ps_next_parse_state(walk_state, | 371 | case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ |
361 | op, | ||
362 | status); | ||
363 | if (status == AE_CTRL_PENDING) { | ||
364 | status = AE_OK; | ||
365 | goto close_this_op; | ||
366 | } | ||
367 | 372 | ||
368 | if (ACPI_FAILURE(status)) { | 373 | /* Fill in constant or string argument directly */ |
369 | goto close_this_op; | ||
370 | } | ||
371 | } | ||
372 | } | ||
373 | 374 | ||
374 | op->common.aml_offset = walk_state->aml_offset; | 375 | acpi_ps_get_next_simple_arg(&(walk_state->parser_state), |
376 | GET_CURRENT_ARG_TYPE(walk_state-> | ||
377 | arg_types), | ||
378 | op); | ||
379 | break; | ||
375 | 380 | ||
376 | if (walk_state->op_info) { | 381 | case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ |
377 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | 382 | |
378 | "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n", | 383 | status = |
379 | (u32) op->common.aml_opcode, | 384 | acpi_ps_get_next_namepath(walk_state, |
380 | walk_state->op_info->name, op, | 385 | &(walk_state->parser_state), op, |
381 | parser_state->aml, | 386 | 1); |
382 | op->common.aml_offset)); | 387 | if (ACPI_FAILURE(status)) { |
383 | } | 388 | return_ACPI_STATUS(status); |
384 | } | 389 | } |
385 | 390 | ||
391 | walk_state->arg_types = 0; | ||
392 | break; | ||
393 | |||
394 | default: | ||
386 | /* | 395 | /* |
387 | * Start arg_count at zero because we don't know if there are | 396 | * Op is not a constant or string, append each argument to the Op |
388 | * any args yet | ||
389 | */ | 397 | */ |
390 | walk_state->arg_count = 0; | 398 | while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) |
391 | 399 | && !walk_state->arg_count) { | |
392 | /* Are there any arguments that must be processed? */ | 400 | walk_state->aml_offset = |
393 | 401 | (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml, | |
394 | if (walk_state->arg_types) { | 402 | walk_state->parser_state. |
395 | 403 | aml_start); | |
396 | /* Get arguments */ | ||
397 | |||
398 | switch (op->common.aml_opcode) { | ||
399 | case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ | ||
400 | case AML_WORD_OP: /* AML_WORDDATA_ARG */ | ||
401 | case AML_DWORD_OP: /* AML_DWORDATA_ARG */ | ||
402 | case AML_QWORD_OP: /* AML_QWORDATA_ARG */ | ||
403 | case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ | ||
404 | |||
405 | /* Fill in constant or string argument directly */ | ||
406 | |||
407 | acpi_ps_get_next_simple_arg(parser_state, | ||
408 | GET_CURRENT_ARG_TYPE | ||
409 | (walk_state-> | ||
410 | arg_types), op); | ||
411 | break; | ||
412 | |||
413 | case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ | ||
414 | |||
415 | status = | ||
416 | acpi_ps_get_next_namepath(walk_state, | ||
417 | parser_state, op, | ||
418 | 1); | ||
419 | if (ACPI_FAILURE(status)) { | ||
420 | goto close_this_op; | ||
421 | } | ||
422 | |||
423 | walk_state->arg_types = 0; | ||
424 | break; | ||
425 | 404 | ||
426 | default: | 405 | status = |
427 | /* | 406 | acpi_ps_get_next_arg(walk_state, |
428 | * Op is not a constant or string, append each argument | 407 | &(walk_state->parser_state), |
429 | * to the Op | 408 | GET_CURRENT_ARG_TYPE |
430 | */ | 409 | (walk_state->arg_types), &arg); |
431 | while (GET_CURRENT_ARG_TYPE | 410 | if (ACPI_FAILURE(status)) { |
432 | (walk_state->arg_types) | 411 | return_ACPI_STATUS(status); |
433 | && !walk_state->arg_count) { | 412 | } |
434 | walk_state->aml_offset = (u32) | ||
435 | ACPI_PTR_DIFF(parser_state->aml, | ||
436 | parser_state-> | ||
437 | aml_start); | ||
438 | 413 | ||
439 | status = | 414 | if (arg) { |
440 | acpi_ps_get_next_arg(walk_state, | 415 | arg->common.aml_offset = walk_state->aml_offset; |
441 | parser_state, | 416 | acpi_ps_append_arg(op, arg); |
442 | GET_CURRENT_ARG_TYPE | 417 | } |
443 | (walk_state-> | ||
444 | arg_types), | ||
445 | &arg); | ||
446 | if (ACPI_FAILURE(status)) { | ||
447 | goto close_this_op; | ||
448 | } | ||
449 | 418 | ||
450 | if (arg) { | 419 | INCREMENT_ARG_LIST(walk_state->arg_types); |
451 | arg->common.aml_offset = | 420 | } |
452 | walk_state->aml_offset; | ||
453 | acpi_ps_append_arg(op, arg); | ||
454 | } | ||
455 | INCREMENT_ARG_LIST(walk_state-> | ||
456 | arg_types); | ||
457 | } | ||
458 | 421 | ||
459 | /* Special processing for certain opcodes */ | 422 | /* Special processing for certain opcodes */ |
460 | 423 | ||
461 | /* TBD (remove): Temporary mechanism to disable this code if needed */ | 424 | /* TBD (remove): Temporary mechanism to disable this code if needed */ |
462 | 425 | ||
463 | #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE | 426 | #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE |
464 | 427 | ||
465 | if ((walk_state->pass_number <= | 428 | if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) && |
466 | ACPI_IMODE_LOAD_PASS1) | 429 | ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) { |
467 | && | 430 | /* |
468 | ((walk_state-> | 431 | * We want to skip If/Else/While constructs during Pass1 because we |
469 | parse_flags & ACPI_PARSE_DISASSEMBLE) == | 432 | * want to actually conditionally execute the code during Pass2. |
470 | 0)) { | 433 | * |
471 | /* | 434 | * Except for disassembly, where we always want to walk the |
472 | * We want to skip If/Else/While constructs during Pass1 | 435 | * If/Else/While packages |
473 | * because we want to actually conditionally execute the | 436 | */ |
474 | * code during Pass2. | 437 | switch (op->common.aml_opcode) { |
475 | * | 438 | case AML_IF_OP: |
476 | * Except for disassembly, where we always want to | 439 | case AML_ELSE_OP: |
477 | * walk the If/Else/While packages | 440 | case AML_WHILE_OP: |
478 | */ | ||
479 | switch (op->common.aml_opcode) { | ||
480 | case AML_IF_OP: | ||
481 | case AML_ELSE_OP: | ||
482 | case AML_WHILE_OP: | ||
483 | |||
484 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | ||
485 | "Pass1: Skipping an If/Else/While body\n")); | ||
486 | |||
487 | /* Skip body of if/else/while in pass 1 */ | ||
488 | |||
489 | parser_state->aml = | ||
490 | parser_state->pkg_end; | ||
491 | walk_state->arg_count = 0; | ||
492 | break; | ||
493 | |||
494 | default: | ||
495 | break; | ||
496 | } | ||
497 | } | ||
498 | #endif | ||
499 | switch (op->common.aml_opcode) { | ||
500 | case AML_METHOD_OP: | ||
501 | |||
502 | /* | ||
503 | * Skip parsing of control method | ||
504 | * because we don't have enough info in the first pass | ||
505 | * to parse it correctly. | ||
506 | * | ||
507 | * Save the length and address of the body | ||
508 | */ | ||
509 | op->named.data = parser_state->aml; | ||
510 | op->named.length = | ||
511 | (u32) (parser_state->pkg_end - | ||
512 | parser_state->aml); | ||
513 | |||
514 | /* Skip body of method */ | ||
515 | |||
516 | parser_state->aml = | ||
517 | parser_state->pkg_end; | ||
518 | walk_state->arg_count = 0; | ||
519 | break; | ||
520 | |||
521 | case AML_BUFFER_OP: | ||
522 | case AML_PACKAGE_OP: | ||
523 | case AML_VAR_PACKAGE_OP: | ||
524 | |||
525 | if ((op->common.parent) && | ||
526 | (op->common.parent->common. | ||
527 | aml_opcode == AML_NAME_OP) | ||
528 | && (walk_state->pass_number <= | ||
529 | ACPI_IMODE_LOAD_PASS2)) { | ||
530 | /* | ||
531 | * Skip parsing of Buffers and Packages | ||
532 | * because we don't have enough info in the first pass | ||
533 | * to parse them correctly. | ||
534 | */ | ||
535 | op->named.data = aml_op_start; | ||
536 | op->named.length = | ||
537 | (u32) (parser_state-> | ||
538 | pkg_end - | ||
539 | aml_op_start); | ||
540 | |||
541 | /* Skip body */ | ||
542 | |||
543 | parser_state->aml = | ||
544 | parser_state->pkg_end; | ||
545 | walk_state->arg_count = 0; | ||
546 | } | ||
547 | break; | ||
548 | 441 | ||
549 | case AML_WHILE_OP: | 442 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
443 | "Pass1: Skipping an If/Else/While body\n")); | ||
550 | 444 | ||
551 | if (walk_state->control_state) { | 445 | /* Skip body of if/else/while in pass 1 */ |
552 | walk_state->control_state-> | ||
553 | control.package_end = | ||
554 | parser_state->pkg_end; | ||
555 | } | ||
556 | break; | ||
557 | 446 | ||
558 | default: | 447 | walk_state->parser_state.aml = |
448 | walk_state->parser_state.pkg_end; | ||
449 | walk_state->arg_count = 0; | ||
450 | break; | ||
559 | 451 | ||
560 | /* No action for all other opcodes */ | 452 | default: |
561 | break; | ||
562 | } | ||
563 | break; | 453 | break; |
564 | } | 454 | } |
565 | } | 455 | } |
456 | #endif | ||
566 | 457 | ||
567 | /* Check for arguments that need to be processed */ | 458 | switch (op->common.aml_opcode) { |
568 | 459 | case AML_METHOD_OP: | |
569 | if (walk_state->arg_count) { | ||
570 | /* | 460 | /* |
571 | * There are arguments (complex ones), push Op and | 461 | * Skip parsing of control method because we don't have enough |
572 | * prepare for argument | 462 | * info in the first pass to parse it correctly. |
463 | * | ||
464 | * Save the length and address of the body | ||
573 | */ | 465 | */ |
574 | status = acpi_ps_push_scope(parser_state, op, | 466 | op->named.data = walk_state->parser_state.aml; |
575 | walk_state->arg_types, | 467 | op->named.length = (u32) |
576 | walk_state->arg_count); | 468 | (walk_state->parser_state.pkg_end - |
577 | if (ACPI_FAILURE(status)) { | 469 | walk_state->parser_state.aml); |
578 | goto close_this_op; | ||
579 | } | ||
580 | op = NULL; | ||
581 | continue; | ||
582 | } | ||
583 | 470 | ||
584 | /* | 471 | /* Skip body of method */ |
585 | * All arguments have been processed -- Op is complete, | ||
586 | * prepare for next | ||
587 | */ | ||
588 | walk_state->op_info = | ||
589 | acpi_ps_get_opcode_info(op->common.aml_opcode); | ||
590 | if (walk_state->op_info->flags & AML_NAMED) { | ||
591 | if (acpi_gbl_depth) { | ||
592 | acpi_gbl_depth--; | ||
593 | } | ||
594 | 472 | ||
595 | if (op->common.aml_opcode == AML_REGION_OP) { | 473 | walk_state->parser_state.aml = |
474 | walk_state->parser_state.pkg_end; | ||
475 | walk_state->arg_count = 0; | ||
476 | break; | ||
477 | |||
478 | case AML_BUFFER_OP: | ||
479 | case AML_PACKAGE_OP: | ||
480 | case AML_VAR_PACKAGE_OP: | ||
481 | |||
482 | if ((op->common.parent) && | ||
483 | (op->common.parent->common.aml_opcode == | ||
484 | AML_NAME_OP) | ||
485 | && (walk_state->pass_number <= | ||
486 | ACPI_IMODE_LOAD_PASS2)) { | ||
596 | /* | 487 | /* |
597 | * Skip parsing of control method or opregion body, | 488 | * Skip parsing of Buffers and Packages because we don't have |
598 | * because we don't have enough info in the first pass | 489 | * enough info in the first pass to parse them correctly. |
599 | * to parse them correctly. | ||
600 | * | ||
601 | * Completed parsing an op_region declaration, we now | ||
602 | * know the length. | ||
603 | */ | 490 | */ |
604 | op->named.length = | 491 | op->named.data = aml_op_start; |
605 | (u32) (parser_state->aml - op->named.data); | 492 | op->named.length = (u32) |
606 | } | 493 | (walk_state->parser_state.pkg_end - |
607 | } | 494 | aml_op_start); |
608 | 495 | ||
609 | if (walk_state->op_info->flags & AML_CREATE) { | 496 | /* Skip body */ |
610 | /* | ||
611 | * Backup to beginning of create_xXXfield declaration (1 for | ||
612 | * Opcode) | ||
613 | * | ||
614 | * body_length is unknown until we parse the body | ||
615 | */ | ||
616 | op->named.length = | ||
617 | (u32) (parser_state->aml - op->named.data); | ||
618 | } | ||
619 | 497 | ||
620 | /* This op complete, notify the dispatcher */ | 498 | walk_state->parser_state.aml = |
499 | walk_state->parser_state.pkg_end; | ||
500 | walk_state->arg_count = 0; | ||
501 | } | ||
502 | break; | ||
621 | 503 | ||
622 | if (walk_state->ascending_callback != NULL) { | 504 | case AML_WHILE_OP: |
623 | walk_state->op = op; | ||
624 | walk_state->opcode = op->common.aml_opcode; | ||
625 | 505 | ||
626 | status = walk_state->ascending_callback(walk_state); | 506 | if (walk_state->control_state) { |
627 | status = | 507 | walk_state->control_state->control.package_end = |
628 | acpi_ps_next_parse_state(walk_state, op, status); | 508 | walk_state->parser_state.pkg_end; |
629 | if (status == AE_CTRL_PENDING) { | ||
630 | status = AE_OK; | ||
631 | goto close_this_op; | ||
632 | } | 509 | } |
633 | } | 510 | break; |
634 | |||
635 | close_this_op: | ||
636 | /* | ||
637 | * Finished one argument of the containing scope | ||
638 | */ | ||
639 | parser_state->scope->parse_scope.arg_count--; | ||
640 | 511 | ||
641 | /* Finished with pre_op */ | 512 | default: |
642 | 513 | ||
643 | if (pre_op) { | 514 | /* No action for all other opcodes */ |
644 | acpi_ps_free_op(pre_op); | 515 | break; |
645 | pre_op = NULL; | ||
646 | } | 516 | } |
647 | 517 | ||
648 | /* Close this Op (will result in parse subtree deletion) */ | 518 | break; |
519 | } | ||
649 | 520 | ||
650 | status2 = acpi_ps_complete_this_op(walk_state, op); | 521 | return_ACPI_STATUS(AE_OK); |
651 | if (ACPI_FAILURE(status2)) { | 522 | } |
652 | return_ACPI_STATUS(status2); | ||
653 | } | ||
654 | op = NULL; | ||
655 | 523 | ||
656 | switch (status) { | 524 | /******************************************************************************* |
657 | case AE_OK: | 525 | * |
658 | break; | 526 | * FUNCTION: acpi_ps_complete_op |
527 | * | ||
528 | * PARAMETERS: walk_state - Current state | ||
529 | * Op - Returned Op | ||
530 | * Status - Parse status before complete Op | ||
531 | * | ||
532 | * RETURN: Status | ||
533 | * | ||
534 | * DESCRIPTION: Complete Op | ||
535 | * | ||
536 | ******************************************************************************/ | ||
659 | 537 | ||
660 | case AE_CTRL_TRANSFER: | 538 | static acpi_status |
539 | acpi_ps_complete_op(struct acpi_walk_state *walk_state, | ||
540 | union acpi_parse_object **op, acpi_status status) | ||
541 | { | ||
542 | acpi_status status2; | ||
661 | 543 | ||
662 | /* We are about to transfer to a called method. */ | 544 | ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state); |
663 | 545 | ||
664 | walk_state->prev_op = op; | 546 | /* |
665 | walk_state->prev_arg_types = walk_state->arg_types; | 547 | * Finished one argument of the containing scope |
666 | return_ACPI_STATUS(status); | 548 | */ |
549 | walk_state->parser_state.scope->parse_scope.arg_count--; | ||
667 | 550 | ||
668 | case AE_CTRL_END: | 551 | /* Close this Op (will result in parse subtree deletion) */ |
669 | 552 | ||
670 | acpi_ps_pop_scope(parser_state, &op, | 553 | status2 = acpi_ps_complete_this_op(walk_state, *op); |
671 | &walk_state->arg_types, | 554 | if (ACPI_FAILURE(status2)) { |
672 | &walk_state->arg_count); | 555 | return_ACPI_STATUS(status2); |
556 | } | ||
673 | 557 | ||
674 | if (op) { | 558 | *op = NULL; |
675 | walk_state->op = op; | ||
676 | walk_state->op_info = | ||
677 | acpi_ps_get_opcode_info(op->common. | ||
678 | aml_opcode); | ||
679 | walk_state->opcode = op->common.aml_opcode; | ||
680 | 559 | ||
681 | status = | 560 | switch (status) { |
682 | walk_state->ascending_callback(walk_state); | 561 | case AE_OK: |
683 | status = | 562 | break; |
684 | acpi_ps_next_parse_state(walk_state, op, | ||
685 | status); | ||
686 | 563 | ||
687 | status2 = | 564 | case AE_CTRL_TRANSFER: |
688 | acpi_ps_complete_this_op(walk_state, op); | ||
689 | if (ACPI_FAILURE(status2)) { | ||
690 | return_ACPI_STATUS(status2); | ||
691 | } | ||
692 | op = NULL; | ||
693 | } | ||
694 | status = AE_OK; | ||
695 | break; | ||
696 | 565 | ||
697 | case AE_CTRL_BREAK: | 566 | /* We are about to transfer to a called method */ |
698 | case AE_CTRL_CONTINUE: | ||
699 | 567 | ||
700 | /* Pop off scopes until we find the While */ | 568 | walk_state->prev_op = NULL; |
569 | walk_state->prev_arg_types = walk_state->arg_types; | ||
570 | return_ACPI_STATUS(status); | ||
701 | 571 | ||
702 | while (!op || (op->common.aml_opcode != AML_WHILE_OP)) { | 572 | case AE_CTRL_END: |
703 | acpi_ps_pop_scope(parser_state, &op, | ||
704 | &walk_state->arg_types, | ||
705 | &walk_state->arg_count); | ||
706 | 573 | ||
707 | if (op->common.aml_opcode != AML_WHILE_OP) { | 574 | acpi_ps_pop_scope(&(walk_state->parser_state), op, |
708 | status2 = | 575 | &walk_state->arg_types, |
709 | acpi_ds_result_stack_pop | 576 | &walk_state->arg_count); |
710 | (walk_state); | ||
711 | if (ACPI_FAILURE(status2)) { | ||
712 | return_ACPI_STATUS(status2); | ||
713 | } | ||
714 | } | ||
715 | } | ||
716 | |||
717 | /* Close this iteration of the While loop */ | ||
718 | 577 | ||
719 | walk_state->op = op; | 578 | if (*op) { |
579 | walk_state->op = *op; | ||
720 | walk_state->op_info = | 580 | walk_state->op_info = |
721 | acpi_ps_get_opcode_info(op->common.aml_opcode); | 581 | acpi_ps_get_opcode_info((*op)->common.aml_opcode); |
722 | walk_state->opcode = op->common.aml_opcode; | 582 | walk_state->opcode = (*op)->common.aml_opcode; |
723 | 583 | ||
724 | status = walk_state->ascending_callback(walk_state); | 584 | status = walk_state->ascending_callback(walk_state); |
725 | status = | 585 | status = |
726 | acpi_ps_next_parse_state(walk_state, op, status); | 586 | acpi_ps_next_parse_state(walk_state, *op, status); |
727 | 587 | ||
728 | status2 = acpi_ps_complete_this_op(walk_state, op); | 588 | status2 = acpi_ps_complete_this_op(walk_state, *op); |
729 | if (ACPI_FAILURE(status2)) { | 589 | if (ACPI_FAILURE(status2)) { |
730 | return_ACPI_STATUS(status2); | 590 | return_ACPI_STATUS(status2); |
731 | } | 591 | } |
732 | op = NULL; | 592 | } |
733 | |||
734 | status = AE_OK; | ||
735 | break; | ||
736 | 593 | ||
737 | case AE_CTRL_TERMINATE: | 594 | status = AE_OK; |
595 | break; | ||
738 | 596 | ||
739 | status = AE_OK; | 597 | case AE_CTRL_BREAK: |
598 | case AE_CTRL_CONTINUE: | ||
740 | 599 | ||
741 | /* Clean up */ | 600 | /* Pop off scopes until we find the While */ |
742 | do { | ||
743 | if (op) { | ||
744 | status2 = | ||
745 | acpi_ps_complete_this_op(walk_state, | ||
746 | op); | ||
747 | if (ACPI_FAILURE(status2)) { | ||
748 | return_ACPI_STATUS(status2); | ||
749 | } | ||
750 | 601 | ||
751 | status2 = | 602 | while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) { |
752 | acpi_ds_result_stack_pop | 603 | acpi_ps_pop_scope(&(walk_state->parser_state), op, |
753 | (walk_state); | 604 | &walk_state->arg_types, |
754 | if (ACPI_FAILURE(status2)) { | 605 | &walk_state->arg_count); |
755 | return_ACPI_STATUS(status2); | ||
756 | } | ||
757 | 606 | ||
758 | acpi_ut_delete_generic_state | 607 | if ((*op)->common.aml_opcode != AML_WHILE_OP) { |
759 | (acpi_ut_pop_generic_state | 608 | status2 = acpi_ds_result_stack_pop(walk_state); |
760 | (&walk_state->control_state)); | 609 | if (ACPI_FAILURE(status2)) { |
610 | return_ACPI_STATUS(status2); | ||
761 | } | 611 | } |
612 | } | ||
613 | } | ||
762 | 614 | ||
763 | acpi_ps_pop_scope(parser_state, &op, | 615 | /* Close this iteration of the While loop */ |
764 | &walk_state->arg_types, | ||
765 | &walk_state->arg_count); | ||
766 | 616 | ||
767 | } while (op); | 617 | walk_state->op = *op; |
618 | walk_state->op_info = | ||
619 | acpi_ps_get_opcode_info((*op)->common.aml_opcode); | ||
620 | walk_state->opcode = (*op)->common.aml_opcode; | ||
768 | 621 | ||
769 | return_ACPI_STATUS(status); | 622 | status = walk_state->ascending_callback(walk_state); |
623 | status = acpi_ps_next_parse_state(walk_state, *op, status); | ||
770 | 624 | ||
771 | default: /* All other non-AE_OK status */ | 625 | status2 = acpi_ps_complete_this_op(walk_state, *op); |
626 | if (ACPI_FAILURE(status2)) { | ||
627 | return_ACPI_STATUS(status2); | ||
628 | } | ||
772 | 629 | ||
773 | do { | 630 | status = AE_OK; |
774 | if (op) { | 631 | break; |
775 | status2 = | 632 | |
776 | acpi_ps_complete_this_op(walk_state, | 633 | case AE_CTRL_TERMINATE: |
777 | op); | 634 | |
778 | if (ACPI_FAILURE(status2)) { | 635 | /* Clean up */ |
779 | return_ACPI_STATUS(status2); | 636 | do { |
780 | } | 637 | if (*op) { |
638 | status2 = | ||
639 | acpi_ps_complete_this_op(walk_state, *op); | ||
640 | if (ACPI_FAILURE(status2)) { | ||
641 | return_ACPI_STATUS(status2); | ||
642 | } | ||
643 | status2 = acpi_ds_result_stack_pop(walk_state); | ||
644 | if (ACPI_FAILURE(status2)) { | ||
645 | return_ACPI_STATUS(status2); | ||
781 | } | 646 | } |
782 | 647 | ||
783 | acpi_ps_pop_scope(parser_state, &op, | 648 | acpi_ut_delete_generic_state |
784 | &walk_state->arg_types, | 649 | (acpi_ut_pop_generic_state |
785 | &walk_state->arg_count); | 650 | (&walk_state->control_state)); |
651 | } | ||
786 | 652 | ||
787 | } while (op); | 653 | acpi_ps_pop_scope(&(walk_state->parser_state), op, |
654 | &walk_state->arg_types, | ||
655 | &walk_state->arg_count); | ||
788 | 656 | ||
789 | /* | 657 | } while (*op); |
790 | * TBD: Cleanup parse ops on error | 658 | |
791 | */ | 659 | return_ACPI_STATUS(AE_OK); |
792 | #if 0 | 660 | |
793 | if (op == NULL) { | 661 | default: /* All other non-AE_OK status */ |
794 | acpi_ps_pop_scope(parser_state, &op, | 662 | |
795 | &walk_state->arg_types, | 663 | do { |
796 | &walk_state->arg_count); | 664 | if (*op) { |
665 | status2 = | ||
666 | acpi_ps_complete_this_op(walk_state, *op); | ||
667 | if (ACPI_FAILURE(status2)) { | ||
668 | return_ACPI_STATUS(status2); | ||
669 | } | ||
797 | } | 670 | } |
798 | #endif | ||
799 | walk_state->prev_op = op; | ||
800 | walk_state->prev_arg_types = walk_state->arg_types; | ||
801 | return_ACPI_STATUS(status); | ||
802 | } | ||
803 | 671 | ||
804 | /* This scope complete? */ | 672 | acpi_ps_pop_scope(&(walk_state->parser_state), op, |
673 | &walk_state->arg_types, | ||
674 | &walk_state->arg_count); | ||
805 | 675 | ||
806 | if (acpi_ps_has_completed_scope(parser_state)) { | 676 | } while (*op); |
807 | acpi_ps_pop_scope(parser_state, &op, | 677 | |
678 | #if 0 | ||
679 | /* | ||
680 | * TBD: Cleanup parse ops on error | ||
681 | */ | ||
682 | if (*op == NULL) { | ||
683 | acpi_ps_pop_scope(parser_state, op, | ||
808 | &walk_state->arg_types, | 684 | &walk_state->arg_types, |
809 | &walk_state->arg_count); | 685 | &walk_state->arg_count); |
810 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | ||
811 | "Popped scope, Op=%p\n", op)); | ||
812 | } else { | ||
813 | op = NULL; | ||
814 | } | 686 | } |
687 | #endif | ||
688 | walk_state->prev_op = NULL; | ||
689 | walk_state->prev_arg_types = walk_state->arg_types; | ||
690 | return_ACPI_STATUS(status); | ||
691 | } | ||
815 | 692 | ||
816 | } /* while parser_state->Aml */ | 693 | /* This scope complete? */ |
694 | |||
695 | if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) { | ||
696 | acpi_ps_pop_scope(&(walk_state->parser_state), op, | ||
697 | &walk_state->arg_types, | ||
698 | &walk_state->arg_count); | ||
699 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op)); | ||
700 | } else { | ||
701 | *op = NULL; | ||
702 | } | ||
703 | |||
704 | return_ACPI_STATUS(AE_OK); | ||
705 | } | ||
706 | |||
707 | /******************************************************************************* | ||
708 | * | ||
709 | * FUNCTION: acpi_ps_complete_final_op | ||
710 | * | ||
711 | * PARAMETERS: walk_state - Current state | ||
712 | * Op - Current Op | ||
713 | * Status - Current parse status before complete last | ||
714 | * Op | ||
715 | * | ||
716 | * RETURN: Status | ||
717 | * | ||
718 | * DESCRIPTION: Complete last Op. | ||
719 | * | ||
720 | ******************************************************************************/ | ||
721 | |||
722 | static acpi_status | ||
723 | acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, | ||
724 | union acpi_parse_object *op, acpi_status status) | ||
725 | { | ||
726 | acpi_status status2; | ||
727 | |||
728 | ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state); | ||
817 | 729 | ||
818 | /* | 730 | /* |
819 | * Complete the last Op (if not completed), and clear the scope stack. | 731 | * Complete the last Op (if not completed), and clear the scope stack. |
820 | * It is easily possible to end an AML "package" with an unbounded number | 732 | * It is easily possible to end an AML "package" with an unbounded number |
821 | * of open scopes (such as when several ASL blocks are closed with | 733 | * of open scopes (such as when several ASL blocks are closed with |
822 | * sequential closing braces). We want to terminate each one cleanly. | 734 | * sequential closing braces). We want to terminate each one cleanly. |
823 | */ | 735 | */ |
824 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n", | 736 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n", |
825 | op)); | 737 | op)); |
@@ -838,8 +750,12 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | |||
838 | acpi_ps_next_parse_state(walk_state, op, | 750 | acpi_ps_next_parse_state(walk_state, op, |
839 | status); | 751 | status); |
840 | if (status == AE_CTRL_PENDING) { | 752 | if (status == AE_CTRL_PENDING) { |
841 | status = AE_OK; | 753 | status = |
842 | goto close_this_op; | 754 | acpi_ps_complete_op(walk_state, &op, |
755 | AE_OK); | ||
756 | if (ACPI_FAILURE(status)) { | ||
757 | return_ACPI_STATUS(status); | ||
758 | } | ||
843 | } | 759 | } |
844 | 760 | ||
845 | if (status == AE_CTRL_TERMINATE) { | 761 | if (status == AE_CTRL_TERMINATE) { |
@@ -858,7 +774,9 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | |||
858 | } | 774 | } |
859 | } | 775 | } |
860 | 776 | ||
861 | acpi_ps_pop_scope(parser_state, | 777 | acpi_ps_pop_scope(& |
778 | (walk_state-> | ||
779 | parser_state), | ||
862 | &op, | 780 | &op, |
863 | &walk_state-> | 781 | &walk_state-> |
864 | arg_types, | 782 | arg_types, |
@@ -887,10 +805,252 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | |||
887 | } | 805 | } |
888 | } | 806 | } |
889 | 807 | ||
890 | acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, | 808 | acpi_ps_pop_scope(&(walk_state->parser_state), &op, |
809 | &walk_state->arg_types, | ||
891 | &walk_state->arg_count); | 810 | &walk_state->arg_count); |
892 | 811 | ||
893 | } while (op); | 812 | } while (op); |
894 | 813 | ||
895 | return_ACPI_STATUS(status); | 814 | return_ACPI_STATUS(status); |
896 | } | 815 | } |
816 | |||
817 | /******************************************************************************* | ||
818 | * | ||
819 | * FUNCTION: acpi_ps_parse_loop | ||
820 | * | ||
821 | * PARAMETERS: walk_state - Current state | ||
822 | * | ||
823 | * RETURN: Status | ||
824 | * | ||
825 | * DESCRIPTION: Parse AML (pointed to by the current parser state) and return | ||
826 | * a tree of ops. | ||
827 | * | ||
828 | ******************************************************************************/ | ||
829 | |||
830 | acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | ||
831 | { | ||
832 | acpi_status status = AE_OK; | ||
833 | union acpi_parse_object *op = NULL; /* current op */ | ||
834 | struct acpi_parse_state *parser_state; | ||
835 | u8 *aml_op_start = NULL; | ||
836 | |||
837 | ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state); | ||
838 | |||
839 | if (walk_state->descending_callback == NULL) { | ||
840 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
841 | } | ||
842 | |||
843 | parser_state = &walk_state->parser_state; | ||
844 | walk_state->arg_types = 0; | ||
845 | |||
846 | #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) | ||
847 | |||
848 | if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) { | ||
849 | |||
850 | /* We are restarting a preempted control method */ | ||
851 | |||
852 | if (acpi_ps_has_completed_scope(parser_state)) { | ||
853 | /* | ||
854 | * We must check if a predicate to an IF or WHILE statement | ||
855 | * was just completed | ||
856 | */ | ||
857 | if ((parser_state->scope->parse_scope.op) && | ||
858 | ((parser_state->scope->parse_scope.op->common. | ||
859 | aml_opcode == AML_IF_OP) | ||
860 | || (parser_state->scope->parse_scope.op->common. | ||
861 | aml_opcode == AML_WHILE_OP)) | ||
862 | && (walk_state->control_state) | ||
863 | && (walk_state->control_state->common.state == | ||
864 | ACPI_CONTROL_PREDICATE_EXECUTING)) { | ||
865 | /* | ||
866 | * A predicate was just completed, get the value of the | ||
867 | * predicate and branch based on that value | ||
868 | */ | ||
869 | walk_state->op = NULL; | ||
870 | status = | ||
871 | acpi_ds_get_predicate_value(walk_state, | ||
872 | ACPI_TO_POINTER | ||
873 | (TRUE)); | ||
874 | if (ACPI_FAILURE(status) | ||
875 | && ((status & AE_CODE_MASK) != | ||
876 | AE_CODE_CONTROL)) { | ||
877 | if (status == AE_AML_NO_RETURN_VALUE) { | ||
878 | ACPI_EXCEPTION((AE_INFO, status, | ||
879 | "Invoked method did not return a value")); | ||
880 | |||
881 | } | ||
882 | |||
883 | ACPI_EXCEPTION((AE_INFO, status, | ||
884 | "GetPredicate Failed")); | ||
885 | return_ACPI_STATUS(status); | ||
886 | } | ||
887 | |||
888 | status = | ||
889 | acpi_ps_next_parse_state(walk_state, op, | ||
890 | status); | ||
891 | } | ||
892 | |||
893 | acpi_ps_pop_scope(parser_state, &op, | ||
894 | &walk_state->arg_types, | ||
895 | &walk_state->arg_count); | ||
896 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | ||
897 | "Popped scope, Op=%p\n", op)); | ||
898 | } else if (walk_state->prev_op) { | ||
899 | |||
900 | /* We were in the middle of an op */ | ||
901 | |||
902 | op = walk_state->prev_op; | ||
903 | walk_state->arg_types = walk_state->prev_arg_types; | ||
904 | } | ||
905 | } | ||
906 | #endif | ||
907 | |||
908 | /* Iterative parsing loop, while there is more AML to process: */ | ||
909 | |||
910 | while ((parser_state->aml < parser_state->aml_end) || (op)) { | ||
911 | aml_op_start = parser_state->aml; | ||
912 | if (!op) { | ||
913 | status = | ||
914 | acpi_ps_create_op(walk_state, aml_op_start, &op); | ||
915 | if (ACPI_FAILURE(status)) { | ||
916 | if (status == AE_CTRL_PARSE_CONTINUE) { | ||
917 | continue; | ||
918 | } | ||
919 | |||
920 | if (status == AE_CTRL_PARSE_PENDING) { | ||
921 | status = AE_OK; | ||
922 | } | ||
923 | |||
924 | status = | ||
925 | acpi_ps_complete_op(walk_state, &op, | ||
926 | status); | ||
927 | if (ACPI_FAILURE(status)) { | ||
928 | return_ACPI_STATUS(status); | ||
929 | } | ||
930 | |||
931 | continue; | ||
932 | } | ||
933 | |||
934 | op->common.aml_offset = walk_state->aml_offset; | ||
935 | |||
936 | if (walk_state->op_info) { | ||
937 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | ||
938 | "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n", | ||
939 | (u32) op->common.aml_opcode, | ||
940 | walk_state->op_info->name, op, | ||
941 | parser_state->aml, | ||
942 | op->common.aml_offset)); | ||
943 | } | ||
944 | } | ||
945 | |||
946 | /* | ||
947 | * Start arg_count at zero because we don't know if there are | ||
948 | * any args yet | ||
949 | */ | ||
950 | walk_state->arg_count = 0; | ||
951 | |||
952 | /* Are there any arguments that must be processed? */ | ||
953 | |||
954 | if (walk_state->arg_types) { | ||
955 | |||
956 | /* Get arguments */ | ||
957 | |||
958 | status = | ||
959 | acpi_ps_get_arguments(walk_state, aml_op_start, op); | ||
960 | if (ACPI_FAILURE(status)) { | ||
961 | status = | ||
962 | acpi_ps_complete_op(walk_state, &op, | ||
963 | status); | ||
964 | if (ACPI_FAILURE(status)) { | ||
965 | return_ACPI_STATUS(status); | ||
966 | } | ||
967 | |||
968 | continue; | ||
969 | } | ||
970 | } | ||
971 | |||
972 | /* Check for arguments that need to be processed */ | ||
973 | |||
974 | if (walk_state->arg_count) { | ||
975 | /* | ||
976 | * There are arguments (complex ones), push Op and | ||
977 | * prepare for argument | ||
978 | */ | ||
979 | status = acpi_ps_push_scope(parser_state, op, | ||
980 | walk_state->arg_types, | ||
981 | walk_state->arg_count); | ||
982 | if (ACPI_FAILURE(status)) { | ||
983 | status = | ||
984 | acpi_ps_complete_op(walk_state, &op, | ||
985 | status); | ||
986 | if (ACPI_FAILURE(status)) { | ||
987 | return_ACPI_STATUS(status); | ||
988 | } | ||
989 | |||
990 | continue; | ||
991 | } | ||
992 | |||
993 | op = NULL; | ||
994 | continue; | ||
995 | } | ||
996 | |||
997 | /* | ||
998 | * All arguments have been processed -- Op is complete, | ||
999 | * prepare for next | ||
1000 | */ | ||
1001 | walk_state->op_info = | ||
1002 | acpi_ps_get_opcode_info(op->common.aml_opcode); | ||
1003 | if (walk_state->op_info->flags & AML_NAMED) { | ||
1004 | if (acpi_gbl_depth) { | ||
1005 | acpi_gbl_depth--; | ||
1006 | } | ||
1007 | |||
1008 | if (op->common.aml_opcode == AML_REGION_OP) { | ||
1009 | /* | ||
1010 | * Skip parsing of control method or opregion body, | ||
1011 | * because we don't have enough info in the first pass | ||
1012 | * to parse them correctly. | ||
1013 | * | ||
1014 | * Completed parsing an op_region declaration, we now | ||
1015 | * know the length. | ||
1016 | */ | ||
1017 | op->named.length = | ||
1018 | (u32) (parser_state->aml - op->named.data); | ||
1019 | } | ||
1020 | } | ||
1021 | |||
1022 | if (walk_state->op_info->flags & AML_CREATE) { | ||
1023 | /* | ||
1024 | * Backup to beginning of create_xXXfield declaration (1 for | ||
1025 | * Opcode) | ||
1026 | * | ||
1027 | * body_length is unknown until we parse the body | ||
1028 | */ | ||
1029 | op->named.length = | ||
1030 | (u32) (parser_state->aml - op->named.data); | ||
1031 | } | ||
1032 | |||
1033 | /* This op complete, notify the dispatcher */ | ||
1034 | |||
1035 | if (walk_state->ascending_callback != NULL) { | ||
1036 | walk_state->op = op; | ||
1037 | walk_state->opcode = op->common.aml_opcode; | ||
1038 | |||
1039 | status = walk_state->ascending_callback(walk_state); | ||
1040 | status = | ||
1041 | acpi_ps_next_parse_state(walk_state, op, status); | ||
1042 | if (status == AE_CTRL_PENDING) { | ||
1043 | status = AE_OK; | ||
1044 | } | ||
1045 | } | ||
1046 | |||
1047 | status = acpi_ps_complete_op(walk_state, &op, status); | ||
1048 | if (ACPI_FAILURE(status)) { | ||
1049 | return_ACPI_STATUS(status); | ||
1050 | } | ||
1051 | |||
1052 | } /* while parser_state->Aml */ | ||
1053 | |||
1054 | status = acpi_ps_complete_final_op(walk_state, op, status); | ||
1055 | return_ACPI_STATUS(status); | ||
1056 | } | ||
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c index 4bd25e32769f..16d8b6cc3c22 100644 --- a/drivers/acpi/parser/psopcode.c +++ b/drivers/acpi/parser/psopcode.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index a02aa62fe1e5..5d63f48e56b5 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -540,6 +540,11 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
540 | 540 | ||
541 | if ((status == AE_ALREADY_EXISTS) && | 541 | if ((status == AE_ALREADY_EXISTS) && |
542 | (!walk_state->method_desc->method.mutex)) { | 542 | (!walk_state->method_desc->method.mutex)) { |
543 | ACPI_INFO((AE_INFO, | ||
544 | "Marking method %4.4s as Serialized", | ||
545 | walk_state->method_node->name. | ||
546 | ascii)); | ||
547 | |||
543 | /* | 548 | /* |
544 | * Method tried to create an object twice. The probable cause is | 549 | * Method tried to create an object twice. The probable cause is |
545 | * that the method cannot handle reentrancy. | 550 | * that the method cannot handle reentrancy. |
diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c index a3e0314de24d..77cfa4ed0cfe 100644 --- a/drivers/acpi/parser/psscope.c +++ b/drivers/acpi/parser/psscope.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c index 0015717ef096..966e7ea2a0c4 100644 --- a/drivers/acpi/parser/pstree.c +++ b/drivers/acpi/parser/pstree.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c index d405387b7414..8ca52002db55 100644 --- a/drivers/acpi/parser/psutils.c +++ b/drivers/acpi/parser/psutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c index a84a547a0f1b..49f9757434e4 100644 --- a/drivers/acpi/parser/pswalk.c +++ b/drivers/acpi/parser/pswalk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index 5d996c1140af..94103bced75e 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -54,8 +54,6 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info); | |||
54 | 54 | ||
55 | static void acpi_ps_stop_trace(struct acpi_evaluate_info *info); | 55 | static void acpi_ps_stop_trace(struct acpi_evaluate_info *info); |
56 | 56 | ||
57 | static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info); | ||
58 | |||
59 | static void | 57 | static void |
60 | acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action); | 58 | acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action); |
61 | 59 | ||
@@ -215,6 +213,8 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info) | |||
215 | acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) | 213 | acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) |
216 | { | 214 | { |
217 | acpi_status status; | 215 | acpi_status status; |
216 | union acpi_parse_object *op; | ||
217 | struct acpi_walk_state *walk_state; | ||
218 | 218 | ||
219 | ACPI_FUNCTION_TRACE(ps_execute_method); | 219 | ACPI_FUNCTION_TRACE(ps_execute_method); |
220 | 220 | ||
@@ -234,8 +234,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) | |||
234 | } | 234 | } |
235 | 235 | ||
236 | /* | 236 | /* |
237 | * The caller "owns" the parameters, so give each one an extra | 237 | * The caller "owns" the parameters, so give each one an extra reference |
238 | * reference | ||
239 | */ | 238 | */ |
240 | acpi_ps_update_parameter_list(info, REF_INCREMENT); | 239 | acpi_ps_update_parameter_list(info, REF_INCREMENT); |
241 | 240 | ||
@@ -244,30 +243,50 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) | |||
244 | acpi_ps_start_trace(info); | 243 | acpi_ps_start_trace(info); |
245 | 244 | ||
246 | /* | 245 | /* |
247 | * 1) Perform the first pass parse of the method to enter any | 246 | * Execute the method. Performs parse simultaneously |
248 | * named objects that it creates into the namespace | ||
249 | */ | 247 | */ |
250 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | 248 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
251 | "**** Begin Method Parse **** Entry=%p obj=%p\n", | 249 | "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n", |
252 | info->resolved_node, info->obj_desc)); | 250 | info->resolved_node->name.ascii, info->resolved_node, |
251 | info->obj_desc)); | ||
252 | |||
253 | /* Create and init a Root Node */ | ||
254 | |||
255 | op = acpi_ps_create_scope_op(); | ||
256 | if (!op) { | ||
257 | status = AE_NO_MEMORY; | ||
258 | goto cleanup; | ||
259 | } | ||
260 | |||
261 | /* Create and initialize a new walk state */ | ||
262 | |||
263 | info->pass_number = ACPI_IMODE_EXECUTE; | ||
264 | walk_state = | ||
265 | acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL, | ||
266 | NULL, NULL); | ||
267 | if (!walk_state) { | ||
268 | status = AE_NO_MEMORY; | ||
269 | goto cleanup; | ||
270 | } | ||
253 | 271 | ||
254 | info->pass_number = 1; | 272 | status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node, |
255 | status = acpi_ps_execute_pass(info); | 273 | info->obj_desc->method.aml_start, |
274 | info->obj_desc->method.aml_length, info, | ||
275 | info->pass_number); | ||
256 | if (ACPI_FAILURE(status)) { | 276 | if (ACPI_FAILURE(status)) { |
277 | acpi_ds_delete_walk_state(walk_state); | ||
257 | goto cleanup; | 278 | goto cleanup; |
258 | } | 279 | } |
259 | 280 | ||
260 | /* | 281 | /* Parse the AML */ |
261 | * 2) Execute the method. Performs second pass parse simultaneously | ||
262 | */ | ||
263 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | ||
264 | "**** Begin Method Execution **** Entry=%p obj=%p\n", | ||
265 | info->resolved_node, info->obj_desc)); | ||
266 | 282 | ||
267 | info->pass_number = 3; | 283 | status = acpi_ps_parse_aml(walk_state); |
268 | status = acpi_ps_execute_pass(info); | 284 | |
285 | /* walk_state was deleted by parse_aml */ | ||
269 | 286 | ||
270 | cleanup: | 287 | cleanup: |
288 | acpi_ps_delete_parse_tree(op); | ||
289 | |||
271 | /* End optional tracing */ | 290 | /* End optional tracing */ |
272 | 291 | ||
273 | acpi_ps_stop_trace(info); | 292 | acpi_ps_stop_trace(info); |
@@ -330,62 +349,3 @@ acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action) | |||
330 | } | 349 | } |
331 | } | 350 | } |
332 | } | 351 | } |
333 | |||
334 | /******************************************************************************* | ||
335 | * | ||
336 | * FUNCTION: acpi_ps_execute_pass | ||
337 | * | ||
338 | * PARAMETERS: Info - See struct acpi_evaluate_info | ||
339 | * (Used: pass_number, Node, and obj_desc) | ||
340 | * | ||
341 | * RETURN: Status | ||
342 | * | ||
343 | * DESCRIPTION: Single AML pass: Parse or Execute a control method | ||
344 | * | ||
345 | ******************************************************************************/ | ||
346 | |||
347 | static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info) | ||
348 | { | ||
349 | acpi_status status; | ||
350 | union acpi_parse_object *op; | ||
351 | struct acpi_walk_state *walk_state; | ||
352 | |||
353 | ACPI_FUNCTION_TRACE(ps_execute_pass); | ||
354 | |||
355 | /* Create and init a Root Node */ | ||
356 | |||
357 | op = acpi_ps_create_scope_op(); | ||
358 | if (!op) { | ||
359 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
360 | } | ||
361 | |||
362 | /* Create and initialize a new walk state */ | ||
363 | |||
364 | walk_state = | ||
365 | acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL, | ||
366 | NULL, NULL); | ||
367 | if (!walk_state) { | ||
368 | status = AE_NO_MEMORY; | ||
369 | goto cleanup; | ||
370 | } | ||
371 | |||
372 | status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node, | ||
373 | info->obj_desc->method.aml_start, | ||
374 | info->obj_desc->method.aml_length, | ||
375 | info->pass_number == 1 ? NULL : info, | ||
376 | info->pass_number); | ||
377 | if (ACPI_FAILURE(status)) { | ||
378 | acpi_ds_delete_walk_state(walk_state); | ||
379 | goto cleanup; | ||
380 | } | ||
381 | |||
382 | /* Parse the AML */ | ||
383 | |||
384 | status = acpi_ps_parse_aml(walk_state); | ||
385 | |||
386 | /* Walk state was deleted by parse_aml */ | ||
387 | |||
388 | cleanup: | ||
389 | acpi_ps_delete_parse_tree(op); | ||
390 | return_ACPI_STATUS(status); | ||
391 | } | ||
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index 1e2ae6e7a7e4..55f57a61c55e 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c | |||
@@ -122,19 +122,17 @@ int acpi_pci_bind(struct acpi_device *device) | |||
122 | if (!device || !device->parent) | 122 | if (!device || !device->parent) |
123 | return -EINVAL; | 123 | return -EINVAL; |
124 | 124 | ||
125 | pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); | 125 | pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); |
126 | if (!pathname) | 126 | if (!pathname) |
127 | return -ENOMEM; | 127 | return -ENOMEM; |
128 | memset(pathname, 0, ACPI_PATHNAME_MAX); | ||
129 | buffer.length = ACPI_PATHNAME_MAX; | 128 | buffer.length = ACPI_PATHNAME_MAX; |
130 | buffer.pointer = pathname; | 129 | buffer.pointer = pathname; |
131 | 130 | ||
132 | data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); | 131 | data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); |
133 | if (!data) { | 132 | if (!data) { |
134 | kfree(pathname); | 133 | kfree(pathname); |
135 | return -ENOMEM; | 134 | return -ENOMEM; |
136 | } | 135 | } |
137 | memset(data, 0, sizeof(struct acpi_pci_data)); | ||
138 | 136 | ||
139 | acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); | 137 | acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); |
140 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", | 138 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", |
@@ -281,10 +279,9 @@ int acpi_pci_unbind(struct acpi_device *device) | |||
281 | if (!device || !device->parent) | 279 | if (!device || !device->parent) |
282 | return -EINVAL; | 280 | return -EINVAL; |
283 | 281 | ||
284 | pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); | 282 | pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); |
285 | if (!pathname) | 283 | if (!pathname) |
286 | return -ENOMEM; | 284 | return -ENOMEM; |
287 | memset(pathname, 0, ACPI_PATHNAME_MAX); | ||
288 | 285 | ||
289 | buffer.length = ACPI_PATHNAME_MAX; | 286 | buffer.length = ACPI_PATHNAME_MAX; |
290 | buffer.pointer = pathname; | 287 | buffer.pointer = pathname; |
@@ -331,11 +328,9 @@ acpi_pci_bind_root(struct acpi_device *device, | |||
331 | char *pathname = NULL; | 328 | char *pathname = NULL; |
332 | struct acpi_buffer buffer = { 0, NULL }; | 329 | struct acpi_buffer buffer = { 0, NULL }; |
333 | 330 | ||
334 | 331 | pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); | |
335 | pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); | ||
336 | if (!pathname) | 332 | if (!pathname) |
337 | return -ENOMEM; | 333 | return -ENOMEM; |
338 | memset(pathname, 0, ACPI_PATHNAME_MAX); | ||
339 | 334 | ||
340 | buffer.length = ACPI_PATHNAME_MAX; | 335 | buffer.length = ACPI_PATHNAME_MAX; |
341 | buffer.pointer = pathname; | 336 | buffer.pointer = pathname; |
@@ -345,12 +340,11 @@ acpi_pci_bind_root(struct acpi_device *device, | |||
345 | return -EINVAL; | 340 | return -EINVAL; |
346 | } | 341 | } |
347 | 342 | ||
348 | data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); | 343 | data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); |
349 | if (!data) { | 344 | if (!data) { |
350 | kfree(pathname); | 345 | kfree(pathname); |
351 | return -ENOMEM; | 346 | return -ENOMEM; |
352 | } | 347 | } |
353 | memset(data, 0, sizeof(struct acpi_pci_data)); | ||
354 | 348 | ||
355 | data->id = *id; | 349 | data->id = *id; |
356 | data->bus = bus; | 350 | data->bus = bus; |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index feda0341f5a7..fe7d007833ad 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -89,10 +89,9 @@ acpi_pci_irq_add_entry(acpi_handle handle, | |||
89 | if (!prt) | 89 | if (!prt) |
90 | return -EINVAL; | 90 | return -EINVAL; |
91 | 91 | ||
92 | entry = kmalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); | 92 | entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); |
93 | if (!entry) | 93 | if (!entry) |
94 | return -ENOMEM; | 94 | return -ENOMEM; |
95 | memset(entry, 0, sizeof(struct acpi_prt_entry)); | ||
96 | 95 | ||
97 | entry->id.segment = segment; | 96 | entry->id.segment = segment; |
98 | entry->id.bus = bus; | 97 | entry->id.bus = bus; |
@@ -161,10 +160,9 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | |||
161 | static int first_time = 1; | 160 | static int first_time = 1; |
162 | 161 | ||
163 | 162 | ||
164 | pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); | 163 | pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); |
165 | if (!pathname) | 164 | if (!pathname) |
166 | return -ENOMEM; | 165 | return -ENOMEM; |
167 | memset(pathname, 0, ACPI_PATHNAME_MAX); | ||
168 | 166 | ||
169 | if (first_time) { | 167 | if (first_time) { |
170 | acpi_prt.count = 0; | 168 | acpi_prt.count = 0; |
@@ -198,11 +196,10 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | |||
198 | return -ENODEV; | 196 | return -ENODEV; |
199 | } | 197 | } |
200 | 198 | ||
201 | prt = kmalloc(buffer.length, GFP_KERNEL); | 199 | prt = kzalloc(buffer.length, GFP_KERNEL); |
202 | if (!prt) { | 200 | if (!prt) { |
203 | return -ENOMEM; | 201 | return -ENOMEM; |
204 | } | 202 | } |
205 | memset(prt, 0, buffer.length); | ||
206 | buffer.pointer = prt; | 203 | buffer.pointer = prt; |
207 | 204 | ||
208 | status = acpi_get_irq_routing_table(handle, &buffer); | 205 | status = acpi_get_irq_routing_table(handle, &buffer); |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index d53bd9878ca2..0f683c8c6fbc 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -103,7 +103,7 @@ DEFINE_MUTEX(acpi_link_lock); | |||
103 | static acpi_status | 103 | static acpi_status |
104 | acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) | 104 | acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) |
105 | { | 105 | { |
106 | struct acpi_pci_link *link = (struct acpi_pci_link *)context; | 106 | struct acpi_pci_link *link = context; |
107 | u32 i = 0; | 107 | u32 i = 0; |
108 | 108 | ||
109 | 109 | ||
@@ -307,11 +307,10 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) | |||
307 | if (!link || !irq) | 307 | if (!link || !irq) |
308 | return -EINVAL; | 308 | return -EINVAL; |
309 | 309 | ||
310 | resource = kmalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); | 310 | resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); |
311 | if (!resource) | 311 | if (!resource) |
312 | return -ENOMEM; | 312 | return -ENOMEM; |
313 | 313 | ||
314 | memset(resource, 0, sizeof(*resource) + 1); | ||
315 | buffer.length = sizeof(*resource) + 1; | 314 | buffer.length = sizeof(*resource) + 1; |
316 | buffer.pointer = resource; | 315 | buffer.pointer = resource; |
317 | 316 | ||
@@ -514,7 +513,7 @@ int __init acpi_irq_penalty_init(void) | |||
514 | } | 513 | } |
515 | } | 514 | } |
516 | /* Add a penalty for the SCI */ | 515 | /* Add a penalty for the SCI */ |
517 | acpi_irq_penalty[acpi_fadt.sci_int] += PIRQ_PENALTY_PCI_USING; | 516 | acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING; |
518 | 517 | ||
519 | return 0; | 518 | return 0; |
520 | } | 519 | } |
@@ -613,7 +612,7 @@ acpi_pci_link_allocate_irq(acpi_handle handle, | |||
613 | return -1; | 612 | return -1; |
614 | } | 613 | } |
615 | 614 | ||
616 | link = (struct acpi_pci_link *)acpi_driver_data(device); | 615 | link = acpi_driver_data(device); |
617 | if (!link) { | 616 | if (!link) { |
618 | printk(KERN_ERR PREFIX "Invalid link context\n"); | 617 | printk(KERN_ERR PREFIX "Invalid link context\n"); |
619 | return -1; | 618 | return -1; |
@@ -668,7 +667,7 @@ int acpi_pci_link_free_irq(acpi_handle handle) | |||
668 | return -1; | 667 | return -1; |
669 | } | 668 | } |
670 | 669 | ||
671 | link = (struct acpi_pci_link *)acpi_driver_data(device); | 670 | link = acpi_driver_data(device); |
672 | if (!link) { | 671 | if (!link) { |
673 | printk(KERN_ERR PREFIX "Invalid link context\n"); | 672 | printk(KERN_ERR PREFIX "Invalid link context\n"); |
674 | return -1; | 673 | return -1; |
@@ -718,10 +717,9 @@ static int acpi_pci_link_add(struct acpi_device *device) | |||
718 | if (!device) | 717 | if (!device) |
719 | return -EINVAL; | 718 | return -EINVAL; |
720 | 719 | ||
721 | link = kmalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); | 720 | link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); |
722 | if (!link) | 721 | if (!link) |
723 | return -ENOMEM; | 722 | return -ENOMEM; |
724 | memset(link, 0, sizeof(struct acpi_pci_link)); | ||
725 | 723 | ||
726 | link->device = device; | 724 | link->device = device; |
727 | strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME); | 725 | strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME); |
@@ -787,7 +785,7 @@ static int irqrouter_resume(struct sys_device *dev) | |||
787 | 785 | ||
788 | 786 | ||
789 | /* Make sure SCI is enabled again (Apple firmware bug?) */ | 787 | /* Make sure SCI is enabled again (Apple firmware bug?) */ |
790 | acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1, ACPI_MTX_DO_NOT_LOCK); | 788 | acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1); |
791 | 789 | ||
792 | list_for_each(node, &acpi_link.entries) { | 790 | list_for_each(node, &acpi_link.entries) { |
793 | link = list_entry(node, struct acpi_pci_link, node); | 791 | link = list_entry(node, struct acpi_pci_link, node); |
@@ -808,7 +806,7 @@ static int acpi_pci_link_remove(struct acpi_device *device, int type) | |||
808 | if (!device || !acpi_driver_data(device)) | 806 | if (!device || !acpi_driver_data(device)) |
809 | return -EINVAL; | 807 | return -EINVAL; |
810 | 808 | ||
811 | link = (struct acpi_pci_link *)acpi_driver_data(device); | 809 | link = acpi_driver_data(device); |
812 | 810 | ||
813 | mutex_lock(&acpi_link_lock); | 811 | mutex_lock(&acpi_link_lock); |
814 | list_del(&link->node); | 812 | list_del(&link->node); |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 2e1a74a967bb..4ecf701687e8 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -98,11 +98,12 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | |||
98 | 98 | ||
99 | struct acpi_pci_driver **pptr = &sub_driver; | 99 | struct acpi_pci_driver **pptr = &sub_driver; |
100 | while (*pptr) { | 100 | while (*pptr) { |
101 | if (*pptr != driver) | 101 | if (*pptr == driver) |
102 | continue; | 102 | break; |
103 | *pptr = (*pptr)->next; | 103 | pptr = &(*pptr)->next; |
104 | break; | ||
105 | } | 104 | } |
105 | BUG_ON(!*pptr); | ||
106 | *pptr = (*pptr)->next; | ||
106 | 107 | ||
107 | if (!driver->remove) | 108 | if (!driver->remove) |
108 | return; | 109 | return; |
@@ -116,10 +117,23 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | |||
116 | 117 | ||
117 | EXPORT_SYMBOL(acpi_pci_unregister_driver); | 118 | EXPORT_SYMBOL(acpi_pci_unregister_driver); |
118 | 119 | ||
120 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) | ||
121 | { | ||
122 | struct acpi_pci_root *tmp; | ||
123 | |||
124 | list_for_each_entry(tmp, &acpi_pci_roots, node) { | ||
125 | if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus)) | ||
126 | return tmp->device->handle; | ||
127 | } | ||
128 | return NULL; | ||
129 | } | ||
130 | |||
131 | EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); | ||
132 | |||
119 | static acpi_status | 133 | static acpi_status |
120 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | 134 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) |
121 | { | 135 | { |
122 | int *busnr = (int *)data; | 136 | int *busnr = data; |
123 | struct acpi_resource_address64 address; | 137 | struct acpi_resource_address64 address; |
124 | 138 | ||
125 | if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && | 139 | if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && |
@@ -180,10 +194,9 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
180 | if (!device) | 194 | if (!device) |
181 | return -EINVAL; | 195 | return -EINVAL; |
182 | 196 | ||
183 | root = kmalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); | 197 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); |
184 | if (!root) | 198 | if (!root) |
185 | return -ENOMEM; | 199 | return -ENOMEM; |
186 | memset(root, 0, sizeof(struct acpi_pci_root)); | ||
187 | INIT_LIST_HEAD(&root->node); | 200 | INIT_LIST_HEAD(&root->node); |
188 | 201 | ||
189 | root->device = device; | 202 | root->device = device; |
@@ -350,7 +363,7 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) | |||
350 | if (!device || !acpi_driver_data(device)) | 363 | if (!device || !acpi_driver_data(device)) |
351 | return -EINVAL; | 364 | return -EINVAL; |
352 | 365 | ||
353 | root = (struct acpi_pci_root *)acpi_driver_data(device); | 366 | root = acpi_driver_data(device); |
354 | 367 | ||
355 | kfree(root); | 368 | kfree(root); |
356 | 369 | ||
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index fe67a8af520e..0ba7dfbbb2ee 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -108,7 +108,7 @@ acpi_power_get_context(acpi_handle handle, | |||
108 | return result; | 108 | return result; |
109 | } | 109 | } |
110 | 110 | ||
111 | *resource = (struct acpi_power_resource *)acpi_driver_data(device); | 111 | *resource = acpi_driver_data(device); |
112 | if (!resource) | 112 | if (!resource) |
113 | return -ENODEV; | 113 | return -ENODEV; |
114 | 114 | ||
@@ -442,7 +442,7 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset) | |||
442 | struct acpi_power_resource *resource = NULL; | 442 | struct acpi_power_resource *resource = NULL; |
443 | 443 | ||
444 | 444 | ||
445 | resource = (struct acpi_power_resource *)seq->private; | 445 | resource = seq->private; |
446 | 446 | ||
447 | if (!resource) | 447 | if (!resource) |
448 | goto end; | 448 | goto end; |
@@ -532,10 +532,9 @@ static int acpi_power_add(struct acpi_device *device) | |||
532 | if (!device) | 532 | if (!device) |
533 | return -EINVAL; | 533 | return -EINVAL; |
534 | 534 | ||
535 | resource = kmalloc(sizeof(struct acpi_power_resource), GFP_KERNEL); | 535 | resource = kzalloc(sizeof(struct acpi_power_resource), GFP_KERNEL); |
536 | if (!resource) | 536 | if (!resource) |
537 | return -ENOMEM; | 537 | return -ENOMEM; |
538 | memset(resource, 0, sizeof(struct acpi_power_resource)); | ||
539 | 538 | ||
540 | resource->device = device; | 539 | resource->device = device; |
541 | strcpy(resource->name, device->pnp.bus_id); | 540 | strcpy(resource->name, device->pnp.bus_id); |
@@ -590,7 +589,7 @@ static int acpi_power_remove(struct acpi_device *device, int type) | |||
590 | if (!device || !acpi_driver_data(device)) | 589 | if (!device || !acpi_driver_data(device)) |
591 | return -EINVAL; | 590 | return -EINVAL; |
592 | 591 | ||
593 | resource = (struct acpi_power_resource *)acpi_driver_data(device); | 592 | resource = acpi_driver_data(device); |
594 | 593 | ||
595 | acpi_power_remove_fs(device); | 594 | acpi_power_remove_fs(device); |
596 | 595 | ||
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 46e72c388711..0079bc51082c 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -277,7 +277,7 @@ static struct proc_dir_entry *acpi_processor_dir = NULL; | |||
277 | 277 | ||
278 | static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) | 278 | static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) |
279 | { | 279 | { |
280 | struct acpi_processor *pr = (struct acpi_processor *)seq->private; | 280 | struct acpi_processor *pr = seq->private; |
281 | 281 | ||
282 | 282 | ||
283 | if (!pr) | 283 | if (!pr) |
@@ -375,30 +375,126 @@ static int acpi_processor_remove_fs(struct acpi_device *device) | |||
375 | } | 375 | } |
376 | 376 | ||
377 | /* Use the acpiid in MADT to map cpus in case of SMP */ | 377 | /* Use the acpiid in MADT to map cpus in case of SMP */ |
378 | |||
378 | #ifndef CONFIG_SMP | 379 | #ifndef CONFIG_SMP |
379 | #define convert_acpiid_to_cpu(acpi_id) (-1) | 380 | static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;} |
380 | #else | 381 | #else |
381 | 382 | ||
383 | static struct acpi_table_madt *madt; | ||
384 | |||
385 | static int map_lapic_id(struct acpi_subtable_header *entry, | ||
386 | u32 acpi_id, int *apic_id) | ||
387 | { | ||
388 | struct acpi_madt_local_apic *lapic = | ||
389 | (struct acpi_madt_local_apic *)entry; | ||
390 | if ((lapic->lapic_flags & ACPI_MADT_ENABLED) && | ||
391 | lapic->processor_id == acpi_id) { | ||
392 | *apic_id = lapic->id; | ||
393 | return 1; | ||
394 | } | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int map_lsapic_id(struct acpi_subtable_header *entry, | ||
399 | u32 acpi_id, int *apic_id) | ||
400 | { | ||
401 | struct acpi_madt_local_sapic *lsapic = | ||
402 | (struct acpi_madt_local_sapic *)entry; | ||
403 | /* Only check enabled APICs*/ | ||
404 | if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { | ||
405 | /* First check against id */ | ||
406 | if (lsapic->processor_id == acpi_id) { | ||
407 | *apic_id = lsapic->id; | ||
408 | return 1; | ||
409 | /* Check against optional uid */ | ||
410 | } else if (entry->length >= 16 && | ||
411 | lsapic->uid == acpi_id) { | ||
412 | *apic_id = lsapic->uid; | ||
413 | return 1; | ||
414 | } | ||
415 | } | ||
416 | return 0; | ||
417 | } | ||
418 | |||
382 | #ifdef CONFIG_IA64 | 419 | #ifdef CONFIG_IA64 |
383 | #define arch_acpiid_to_apicid ia64_acpiid_to_sapicid | ||
384 | #define arch_cpu_to_apicid ia64_cpu_to_sapicid | 420 | #define arch_cpu_to_apicid ia64_cpu_to_sapicid |
385 | #define ARCH_BAD_APICID (0xffff) | ||
386 | #else | 421 | #else |
387 | #define arch_acpiid_to_apicid x86_acpiid_to_apicid | ||
388 | #define arch_cpu_to_apicid x86_cpu_to_apicid | 422 | #define arch_cpu_to_apicid x86_cpu_to_apicid |
389 | #define ARCH_BAD_APICID (0xff) | ||
390 | #endif | 423 | #endif |
391 | 424 | ||
392 | static int convert_acpiid_to_cpu(u8 acpi_id) | 425 | static int map_madt_entry(u32 acpi_id) |
426 | { | ||
427 | unsigned long madt_end, entry; | ||
428 | int apic_id = -1; | ||
429 | |||
430 | if (!madt) | ||
431 | return apic_id; | ||
432 | |||
433 | entry = (unsigned long)madt; | ||
434 | madt_end = entry + madt->header.length; | ||
435 | |||
436 | /* Parse all entries looking for a match. */ | ||
437 | |||
438 | entry += sizeof(struct acpi_table_madt); | ||
439 | while (entry + sizeof(struct acpi_subtable_header) < madt_end) { | ||
440 | struct acpi_subtable_header *header = | ||
441 | (struct acpi_subtable_header *)entry; | ||
442 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { | ||
443 | if (map_lapic_id(header, acpi_id, &apic_id)) | ||
444 | break; | ||
445 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | ||
446 | if (map_lsapic_id(header, acpi_id, &apic_id)) | ||
447 | break; | ||
448 | } | ||
449 | entry += header->length; | ||
450 | } | ||
451 | return apic_id; | ||
452 | } | ||
453 | |||
454 | static int map_mat_entry(acpi_handle handle, u32 acpi_id) | ||
455 | { | ||
456 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
457 | union acpi_object *obj; | ||
458 | struct acpi_subtable_header *header; | ||
459 | int apic_id = -1; | ||
460 | |||
461 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) | ||
462 | goto exit; | ||
463 | |||
464 | if (!buffer.length || !buffer.pointer) | ||
465 | goto exit; | ||
466 | |||
467 | obj = buffer.pointer; | ||
468 | if (obj->type != ACPI_TYPE_BUFFER || | ||
469 | obj->buffer.length < sizeof(struct acpi_subtable_header)) { | ||
470 | goto exit; | ||
471 | } | ||
472 | |||
473 | header = (struct acpi_subtable_header *)obj->buffer.pointer; | ||
474 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { | ||
475 | map_lapic_id(header, acpi_id, &apic_id); | ||
476 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | ||
477 | map_lsapic_id(header, acpi_id, &apic_id); | ||
478 | } | ||
479 | |||
480 | exit: | ||
481 | if (buffer.pointer) | ||
482 | kfree(buffer.pointer); | ||
483 | return apic_id; | ||
484 | } | ||
485 | |||
486 | static int get_cpu_id(acpi_handle handle, u32 acpi_id) | ||
393 | { | 487 | { |
394 | u16 apic_id; | ||
395 | int i; | 488 | int i; |
489 | int apic_id = -1; | ||
396 | 490 | ||
397 | apic_id = arch_acpiid_to_apicid[acpi_id]; | 491 | apic_id = map_mat_entry(handle, acpi_id); |
398 | if (apic_id == ARCH_BAD_APICID) | 492 | if (apic_id == -1) |
399 | return -1; | 493 | apic_id = map_madt_entry(acpi_id); |
494 | if (apic_id == -1) | ||
495 | return apic_id; | ||
400 | 496 | ||
401 | for (i = 0; i < NR_CPUS; i++) { | 497 | for (i = 0; i < NR_CPUS; ++i) { |
402 | if (arch_cpu_to_apicid[i] == apic_id) | 498 | if (arch_cpu_to_apicid[i] == apic_id) |
403 | return i; | 499 | return i; |
404 | } | 500 | } |
@@ -410,7 +506,7 @@ static int convert_acpiid_to_cpu(u8 acpi_id) | |||
410 | Driver Interface | 506 | Driver Interface |
411 | -------------------------------------------------------------------------- */ | 507 | -------------------------------------------------------------------------- */ |
412 | 508 | ||
413 | static int acpi_processor_get_info(struct acpi_processor *pr) | 509 | static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) |
414 | { | 510 | { |
415 | acpi_status status = 0; | 511 | acpi_status status = 0; |
416 | union acpi_object object = { 0 }; | 512 | union acpi_object object = { 0 }; |
@@ -431,7 +527,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr) | |||
431 | * Check to see if we have bus mastering arbitration control. This | 527 | * Check to see if we have bus mastering arbitration control. This |
432 | * is required for proper C3 usage (to maintain cache coherency). | 528 | * is required for proper C3 usage (to maintain cache coherency). |
433 | */ | 529 | */ |
434 | if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) { | 530 | if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) { |
435 | pr->flags.bm_control = 1; | 531 | pr->flags.bm_control = 1; |
436 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 532 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
437 | "Bus mastering arbitration control present\n")); | 533 | "Bus mastering arbitration control present\n")); |
@@ -439,24 +535,35 @@ static int acpi_processor_get_info(struct acpi_processor *pr) | |||
439 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 535 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
440 | "No bus mastering arbitration control\n")); | 536 | "No bus mastering arbitration control\n")); |
441 | 537 | ||
442 | /* | 538 | /* Check if it is a Device with HID and UID */ |
443 | * Evalute the processor object. Note that it is common on SMP to | 539 | if (has_uid) { |
444 | * have the first (boot) processor with a valid PBLK address while | 540 | unsigned long value; |
445 | * all others have a NULL address. | 541 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, |
446 | */ | 542 | NULL, &value); |
447 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | 543 | if (ACPI_FAILURE(status)) { |
448 | if (ACPI_FAILURE(status)) { | 544 | printk(KERN_ERR PREFIX "Evaluating processor _UID\n"); |
449 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | 545 | return -ENODEV; |
450 | return -ENODEV; | 546 | } |
451 | } | 547 | pr->acpi_id = value; |
452 | 548 | } else { | |
453 | /* | 549 | /* |
454 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. | 550 | * Evalute the processor object. Note that it is common on SMP to |
455 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c | 551 | * have the first (boot) processor with a valid PBLK address while |
456 | */ | 552 | * all others have a NULL address. |
457 | pr->acpi_id = object.processor.proc_id; | 553 | */ |
554 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | ||
555 | if (ACPI_FAILURE(status)) { | ||
556 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | ||
557 | return -ENODEV; | ||
558 | } | ||
458 | 559 | ||
459 | cpu_index = convert_acpiid_to_cpu(pr->acpi_id); | 560 | /* |
561 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. | ||
562 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c | ||
563 | */ | ||
564 | pr->acpi_id = object.processor.proc_id; | ||
565 | } | ||
566 | cpu_index = get_cpu_id(pr->handle, pr->acpi_id); | ||
460 | 567 | ||
461 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | 568 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ |
462 | if (!cpu0_initialized && (cpu_index == -1) && | 569 | if (!cpu0_initialized && (cpu_index == -1) && |
@@ -473,12 +580,9 @@ static int acpi_processor_get_info(struct acpi_processor *pr) | |||
473 | * less than the max # of CPUs. They should be ignored _iff | 580 | * less than the max # of CPUs. They should be ignored _iff |
474 | * they are physically not present. | 581 | * they are physically not present. |
475 | */ | 582 | */ |
476 | if (cpu_index == -1) { | 583 | if (pr->id == -1) { |
477 | if (ACPI_FAILURE | 584 | if (ACPI_FAILURE |
478 | (acpi_processor_hotadd_init(pr->handle, &pr->id))) { | 585 | (acpi_processor_hotadd_init(pr->handle, &pr->id))) { |
479 | printk(KERN_ERR PREFIX | ||
480 | "Getting cpuindex for acpiid 0x%x\n", | ||
481 | pr->acpi_id); | ||
482 | return -ENODEV; | 586 | return -ENODEV; |
483 | } | 587 | } |
484 | } | 588 | } |
@@ -493,8 +597,8 @@ static int acpi_processor_get_info(struct acpi_processor *pr) | |||
493 | object.processor.pblk_length); | 597 | object.processor.pblk_length); |
494 | else { | 598 | else { |
495 | pr->throttling.address = object.processor.pblk_address; | 599 | pr->throttling.address = object.processor.pblk_address; |
496 | pr->throttling.duty_offset = acpi_fadt.duty_offset; | 600 | pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset; |
497 | pr->throttling.duty_width = acpi_fadt.duty_width; | 601 | pr->throttling.duty_width = acpi_gbl_FADT.duty_width; |
498 | 602 | ||
499 | pr->pblk = object.processor.pblk_address; | 603 | pr->pblk = object.processor.pblk_address; |
500 | 604 | ||
@@ -528,7 +632,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) | |||
528 | 632 | ||
529 | pr = acpi_driver_data(device); | 633 | pr = acpi_driver_data(device); |
530 | 634 | ||
531 | result = acpi_processor_get_info(pr); | 635 | result = acpi_processor_get_info(pr, device->flags.unique_id); |
532 | if (result) { | 636 | if (result) { |
533 | /* Processor is physically not present */ | 637 | /* Processor is physically not present */ |
534 | return 0; | 638 | return 0; |
@@ -542,12 +646,12 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) | |||
542 | * Don't trust it blindly | 646 | * Don't trust it blindly |
543 | */ | 647 | */ |
544 | if (processor_device_array[pr->id] != NULL && | 648 | if (processor_device_array[pr->id] != NULL && |
545 | processor_device_array[pr->id] != (void *)device) { | 649 | processor_device_array[pr->id] != device) { |
546 | printk(KERN_WARNING "BIOS reported wrong ACPI id" | 650 | printk(KERN_WARNING "BIOS reported wrong ACPI id" |
547 | "for the processor\n"); | 651 | "for the processor\n"); |
548 | return -ENODEV; | 652 | return -ENODEV; |
549 | } | 653 | } |
550 | processor_device_array[pr->id] = (void *)device; | 654 | processor_device_array[pr->id] = device; |
551 | 655 | ||
552 | processors[pr->id] = pr; | 656 | processors[pr->id] = pr; |
553 | 657 | ||
@@ -578,7 +682,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) | |||
578 | 682 | ||
579 | static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) | 683 | static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) |
580 | { | 684 | { |
581 | struct acpi_processor *pr = (struct acpi_processor *)data; | 685 | struct acpi_processor *pr = data; |
582 | struct acpi_device *device = NULL; | 686 | struct acpi_device *device = NULL; |
583 | 687 | ||
584 | 688 | ||
@@ -615,10 +719,9 @@ static int acpi_processor_add(struct acpi_device *device) | |||
615 | if (!device) | 719 | if (!device) |
616 | return -EINVAL; | 720 | return -EINVAL; |
617 | 721 | ||
618 | pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL); | 722 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); |
619 | if (!pr) | 723 | if (!pr) |
620 | return -ENOMEM; | 724 | return -ENOMEM; |
621 | memset(pr, 0, sizeof(struct acpi_processor)); | ||
622 | 725 | ||
623 | pr->handle = device->handle; | 726 | pr->handle = device->handle; |
624 | strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); | 727 | strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); |
@@ -637,7 +740,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type) | |||
637 | if (!device || !acpi_driver_data(device)) | 740 | if (!device || !acpi_driver_data(device)) |
638 | return -EINVAL; | 741 | return -EINVAL; |
639 | 742 | ||
640 | pr = (struct acpi_processor *)acpi_driver_data(device); | 743 | pr = acpi_driver_data(device); |
641 | 744 | ||
642 | if (pr->id >= NR_CPUS) { | 745 | if (pr->id >= NR_CPUS) { |
643 | kfree(pr); | 746 | kfree(pr); |
@@ -899,15 +1002,21 @@ static int __init acpi_processor_init(void) | |||
899 | memset(&processors, 0, sizeof(processors)); | 1002 | memset(&processors, 0, sizeof(processors)); |
900 | memset(&errata, 0, sizeof(errata)); | 1003 | memset(&errata, 0, sizeof(errata)); |
901 | 1004 | ||
1005 | #ifdef CONFIG_SMP | ||
1006 | if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, | ||
1007 | (struct acpi_table_header **)&madt))) | ||
1008 | madt = 0; | ||
1009 | #endif | ||
1010 | |||
902 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 1011 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
903 | if (!acpi_processor_dir) | 1012 | if (!acpi_processor_dir) |
904 | return 0; | 1013 | return -ENOMEM; |
905 | acpi_processor_dir->owner = THIS_MODULE; | 1014 | acpi_processor_dir->owner = THIS_MODULE; |
906 | 1015 | ||
907 | result = acpi_bus_register_driver(&acpi_processor_driver); | 1016 | result = acpi_bus_register_driver(&acpi_processor_driver); |
908 | if (result < 0) { | 1017 | if (result < 0) { |
909 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 1018 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
910 | return 0; | 1019 | return result; |
911 | } | 1020 | } |
912 | 1021 | ||
913 | acpi_processor_install_hotplug_notify(); | 1022 | acpi_processor_install_hotplug_notify(); |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 65b3f056ad89..6c6751b1405b 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -160,7 +160,7 @@ static inline u32 ticks_elapsed(u32 t1, u32 t2) | |||
160 | { | 160 | { |
161 | if (t2 >= t1) | 161 | if (t2 >= t1) |
162 | return (t2 - t1); | 162 | return (t2 - t1); |
163 | else if (!acpi_fadt.tmr_val_ext) | 163 | else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER)) |
164 | return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); | 164 | return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); |
165 | else | 165 | else |
166 | return ((0xFFFFFFFF - t1) + t2); | 166 | return ((0xFFFFFFFF - t1) + t2); |
@@ -187,8 +187,7 @@ acpi_processor_power_activate(struct acpi_processor *pr, | |||
187 | case ACPI_STATE_C3: | 187 | case ACPI_STATE_C3: |
188 | /* Disable bus master reload */ | 188 | /* Disable bus master reload */ |
189 | if (new->type != ACPI_STATE_C3 && pr->flags.bm_check) | 189 | if (new->type != ACPI_STATE_C3 && pr->flags.bm_check) |
190 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, | 190 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); |
191 | ACPI_MTX_DO_NOT_LOCK); | ||
192 | break; | 191 | break; |
193 | } | 192 | } |
194 | } | 193 | } |
@@ -198,8 +197,7 @@ acpi_processor_power_activate(struct acpi_processor *pr, | |||
198 | case ACPI_STATE_C3: | 197 | case ACPI_STATE_C3: |
199 | /* Enable bus master reload */ | 198 | /* Enable bus master reload */ |
200 | if (old->type != ACPI_STATE_C3 && pr->flags.bm_check) | 199 | if (old->type != ACPI_STATE_C3 && pr->flags.bm_check) |
201 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, | 200 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); |
202 | ACPI_MTX_DO_NOT_LOCK); | ||
203 | break; | 201 | break; |
204 | } | 202 | } |
205 | 203 | ||
@@ -211,7 +209,11 @@ acpi_processor_power_activate(struct acpi_processor *pr, | |||
211 | static void acpi_safe_halt(void) | 209 | static void acpi_safe_halt(void) |
212 | { | 210 | { |
213 | current_thread_info()->status &= ~TS_POLLING; | 211 | current_thread_info()->status &= ~TS_POLLING; |
214 | smp_mb__after_clear_bit(); | 212 | /* |
213 | * TS_POLLING-cleared state must be visible before we | ||
214 | * test NEED_RESCHED: | ||
215 | */ | ||
216 | smp_mb(); | ||
215 | if (!need_resched()) | 217 | if (!need_resched()) |
216 | safe_halt(); | 218 | safe_halt(); |
217 | current_thread_info()->status |= TS_POLLING; | 219 | current_thread_info()->status |= TS_POLLING; |
@@ -232,7 +234,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) | |||
232 | /* Dummy wait op - must do something useless after P_LVL2 read | 234 | /* Dummy wait op - must do something useless after P_LVL2 read |
233 | because chipsets cannot guarantee that STPCLK# signal | 235 | because chipsets cannot guarantee that STPCLK# signal |
234 | gets asserted in time to freeze execution properly. */ | 236 | gets asserted in time to freeze execution properly. */ |
235 | unused = inl(acpi_fadt.xpm_tmr_blk.address); | 237 | unused = inl(acpi_gbl_FADT.xpm_timer_block.address); |
236 | } | 238 | } |
237 | } | 239 | } |
238 | 240 | ||
@@ -287,12 +289,10 @@ static void acpi_processor_idle(void) | |||
287 | 289 | ||
288 | pr->power.bm_activity <<= diff; | 290 | pr->power.bm_activity <<= diff; |
289 | 291 | ||
290 | acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, | 292 | acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); |
291 | &bm_status, ACPI_MTX_DO_NOT_LOCK); | ||
292 | if (bm_status) { | 293 | if (bm_status) { |
293 | pr->power.bm_activity |= 0x1; | 294 | pr->power.bm_activity |= 0x1; |
294 | acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, | 295 | acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); |
295 | 1, ACPI_MTX_DO_NOT_LOCK); | ||
296 | } | 296 | } |
297 | /* | 297 | /* |
298 | * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect | 298 | * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect |
@@ -334,7 +334,7 @@ static void acpi_processor_idle(void) | |||
334 | * detection phase, to work cleanly with logical CPU hotplug. | 334 | * detection phase, to work cleanly with logical CPU hotplug. |
335 | */ | 335 | */ |
336 | if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && | 336 | if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && |
337 | !pr->flags.has_cst && !acpi_fadt.plvl2_up) | 337 | !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) |
338 | cx = &pr->power.states[ACPI_STATE_C1]; | 338 | cx = &pr->power.states[ACPI_STATE_C1]; |
339 | #endif | 339 | #endif |
340 | 340 | ||
@@ -345,7 +345,11 @@ static void acpi_processor_idle(void) | |||
345 | */ | 345 | */ |
346 | if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) { | 346 | if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) { |
347 | current_thread_info()->status &= ~TS_POLLING; | 347 | current_thread_info()->status &= ~TS_POLLING; |
348 | smp_mb__after_clear_bit(); | 348 | /* |
349 | * TS_POLLING-cleared state must be visible before we | ||
350 | * test NEED_RESCHED: | ||
351 | */ | ||
352 | smp_mb(); | ||
349 | if (need_resched()) { | 353 | if (need_resched()) { |
350 | current_thread_info()->status |= TS_POLLING; | 354 | current_thread_info()->status |= TS_POLLING; |
351 | local_irq_enable(); | 355 | local_irq_enable(); |
@@ -376,11 +380,11 @@ static void acpi_processor_idle(void) | |||
376 | 380 | ||
377 | case ACPI_STATE_C2: | 381 | case ACPI_STATE_C2: |
378 | /* Get start time (ticks) */ | 382 | /* Get start time (ticks) */ |
379 | t1 = inl(acpi_fadt.xpm_tmr_blk.address); | 383 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
380 | /* Invoke C2 */ | 384 | /* Invoke C2 */ |
381 | acpi_cstate_enter(cx); | 385 | acpi_cstate_enter(cx); |
382 | /* Get end time (ticks) */ | 386 | /* Get end time (ticks) */ |
383 | t2 = inl(acpi_fadt.xpm_tmr_blk.address); | 387 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
384 | 388 | ||
385 | #ifdef CONFIG_GENERIC_TIME | 389 | #ifdef CONFIG_GENERIC_TIME |
386 | /* TSC halts in C2, so notify users */ | 390 | /* TSC halts in C2, so notify users */ |
@@ -403,8 +407,7 @@ static void acpi_processor_idle(void) | |||
403 | * All CPUs are trying to go to C3 | 407 | * All CPUs are trying to go to C3 |
404 | * Disable bus master arbitration | 408 | * Disable bus master arbitration |
405 | */ | 409 | */ |
406 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, | 410 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); |
407 | ACPI_MTX_DO_NOT_LOCK); | ||
408 | } | 411 | } |
409 | } else { | 412 | } else { |
410 | /* SMP with no shared cache... Invalidate cache */ | 413 | /* SMP with no shared cache... Invalidate cache */ |
@@ -412,16 +415,15 @@ static void acpi_processor_idle(void) | |||
412 | } | 415 | } |
413 | 416 | ||
414 | /* Get start time (ticks) */ | 417 | /* Get start time (ticks) */ |
415 | t1 = inl(acpi_fadt.xpm_tmr_blk.address); | 418 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
416 | /* Invoke C3 */ | 419 | /* Invoke C3 */ |
417 | acpi_cstate_enter(cx); | 420 | acpi_cstate_enter(cx); |
418 | /* Get end time (ticks) */ | 421 | /* Get end time (ticks) */ |
419 | t2 = inl(acpi_fadt.xpm_tmr_blk.address); | 422 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
420 | if (pr->flags.bm_check) { | 423 | if (pr->flags.bm_check) { |
421 | /* Enable bus master arbitration */ | 424 | /* Enable bus master arbitration */ |
422 | atomic_dec(&c3_cpu_count); | 425 | atomic_dec(&c3_cpu_count); |
423 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, | 426 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); |
424 | ACPI_MTX_DO_NOT_LOCK); | ||
425 | } | 427 | } |
426 | 428 | ||
427 | #ifdef CONFIG_GENERIC_TIME | 429 | #ifdef CONFIG_GENERIC_TIME |
@@ -449,7 +451,7 @@ static void acpi_processor_idle(void) | |||
449 | #ifdef CONFIG_HOTPLUG_CPU | 451 | #ifdef CONFIG_HOTPLUG_CPU |
450 | /* Don't do promotion/demotion */ | 452 | /* Don't do promotion/demotion */ |
451 | if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) && | 453 | if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) && |
452 | !pr->flags.has_cst && !acpi_fadt.plvl2_up) { | 454 | !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) { |
453 | next_state = cx; | 455 | next_state = cx; |
454 | goto end; | 456 | goto end; |
455 | } | 457 | } |
@@ -619,7 +621,8 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | |||
619 | * Check for P_LVL2_UP flag before entering C2 and above on | 621 | * Check for P_LVL2_UP flag before entering C2 and above on |
620 | * an SMP system. | 622 | * an SMP system. |
621 | */ | 623 | */ |
622 | if ((num_online_cpus() > 1) && !acpi_fadt.plvl2_up) | 624 | if ((num_online_cpus() > 1) && |
625 | !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) | ||
623 | return -ENODEV; | 626 | return -ENODEV; |
624 | #endif | 627 | #endif |
625 | 628 | ||
@@ -628,8 +631,8 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | |||
628 | pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5; | 631 | pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5; |
629 | 632 | ||
630 | /* determine latencies from FADT */ | 633 | /* determine latencies from FADT */ |
631 | pr->power.states[ACPI_STATE_C2].latency = acpi_fadt.plvl2_lat; | 634 | pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.C2latency; |
632 | pr->power.states[ACPI_STATE_C3].latency = acpi_fadt.plvl3_lat; | 635 | pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.C3latency; |
633 | 636 | ||
634 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 637 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
635 | "lvl2[0x%08x] lvl3[0x%08x]\n", | 638 | "lvl2[0x%08x] lvl3[0x%08x]\n", |
@@ -673,7 +676,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
673 | return -ENODEV; | 676 | return -ENODEV; |
674 | } | 677 | } |
675 | 678 | ||
676 | cst = (union acpi_object *)buffer.pointer; | 679 | cst = buffer.pointer; |
677 | 680 | ||
678 | /* There must be at least 2 elements */ | 681 | /* There must be at least 2 elements */ |
679 | if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) { | 682 | if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) { |
@@ -702,14 +705,14 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
702 | 705 | ||
703 | memset(&cx, 0, sizeof(cx)); | 706 | memset(&cx, 0, sizeof(cx)); |
704 | 707 | ||
705 | element = (union acpi_object *)&(cst->package.elements[i]); | 708 | element = &(cst->package.elements[i]); |
706 | if (element->type != ACPI_TYPE_PACKAGE) | 709 | if (element->type != ACPI_TYPE_PACKAGE) |
707 | continue; | 710 | continue; |
708 | 711 | ||
709 | if (element->package.count != 4) | 712 | if (element->package.count != 4) |
710 | continue; | 713 | continue; |
711 | 714 | ||
712 | obj = (union acpi_object *)&(element->package.elements[0]); | 715 | obj = &(element->package.elements[0]); |
713 | 716 | ||
714 | if (obj->type != ACPI_TYPE_BUFFER) | 717 | if (obj->type != ACPI_TYPE_BUFFER) |
715 | continue; | 718 | continue; |
@@ -721,7 +724,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
721 | continue; | 724 | continue; |
722 | 725 | ||
723 | /* There should be an easy way to extract an integer... */ | 726 | /* There should be an easy way to extract an integer... */ |
724 | obj = (union acpi_object *)&(element->package.elements[1]); | 727 | obj = &(element->package.elements[1]); |
725 | if (obj->type != ACPI_TYPE_INTEGER) | 728 | if (obj->type != ACPI_TYPE_INTEGER) |
726 | continue; | 729 | continue; |
727 | 730 | ||
@@ -754,13 +757,13 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
754 | } | 757 | } |
755 | } | 758 | } |
756 | 759 | ||
757 | obj = (union acpi_object *)&(element->package.elements[2]); | 760 | obj = &(element->package.elements[2]); |
758 | if (obj->type != ACPI_TYPE_INTEGER) | 761 | if (obj->type != ACPI_TYPE_INTEGER) |
759 | continue; | 762 | continue; |
760 | 763 | ||
761 | cx.latency = obj->integer.value; | 764 | cx.latency = obj->integer.value; |
762 | 765 | ||
763 | obj = (union acpi_object *)&(element->package.elements[3]); | 766 | obj = &(element->package.elements[3]); |
764 | if (obj->type != ACPI_TYPE_INTEGER) | 767 | if (obj->type != ACPI_TYPE_INTEGER) |
765 | continue; | 768 | continue; |
766 | 769 | ||
@@ -875,14 +878,13 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | |||
875 | * WBINVD should be set in fadt, for C3 state to be | 878 | * WBINVD should be set in fadt, for C3 state to be |
876 | * supported on when bm_check is not required. | 879 | * supported on when bm_check is not required. |
877 | */ | 880 | */ |
878 | if (acpi_fadt.wb_invd != 1) { | 881 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_WBINVD)) { |
879 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 882 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
880 | "Cache invalidation should work properly" | 883 | "Cache invalidation should work properly" |
881 | " for C3 to be enabled on SMP systems\n")); | 884 | " for C3 to be enabled on SMP systems\n")); |
882 | return; | 885 | return; |
883 | } | 886 | } |
884 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, | 887 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); |
885 | 0, ACPI_MTX_DO_NOT_LOCK); | ||
886 | } | 888 | } |
887 | 889 | ||
888 | /* | 890 | /* |
@@ -1029,7 +1031,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
1029 | 1031 | ||
1030 | static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) | 1032 | static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) |
1031 | { | 1033 | { |
1032 | struct acpi_processor *pr = (struct acpi_processor *)seq->private; | 1034 | struct acpi_processor *pr = seq->private; |
1033 | unsigned int i; | 1035 | unsigned int i; |
1034 | 1036 | ||
1035 | 1037 | ||
@@ -1088,7 +1090,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) | |||
1088 | seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", | 1090 | seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", |
1089 | pr->power.states[i].latency, | 1091 | pr->power.states[i].latency, |
1090 | pr->power.states[i].usage, | 1092 | pr->power.states[i].usage, |
1091 | pr->power.states[i].time); | 1093 | (unsigned long long)pr->power.states[i].time); |
1092 | } | 1094 | } |
1093 | 1095 | ||
1094 | end: | 1096 | end: |
@@ -1156,9 +1158,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1156 | if (!pr) | 1158 | if (!pr) |
1157 | return -EINVAL; | 1159 | return -EINVAL; |
1158 | 1160 | ||
1159 | if (acpi_fadt.cst_cnt && !nocst) { | 1161 | if (acpi_gbl_FADT.cst_control && !nocst) { |
1160 | status = | 1162 | status = |
1161 | acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8); | 1163 | acpi_os_write_port(acpi_gbl_FADT.smi_command, acpi_gbl_FADT.cst_control, 8); |
1162 | if (ACPI_FAILURE(status)) { | 1164 | if (ACPI_FAILURE(status)) { |
1163 | ACPI_EXCEPTION((AE_INFO, status, | 1165 | ACPI_EXCEPTION((AE_INFO, status, |
1164 | "Notifying BIOS of _CST ability failed")); | 1166 | "Notifying BIOS of _CST ability failed")); |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 6fd174a37149..058f13cf3b79 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -236,7 +236,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) | |||
236 | return -ENODEV; | 236 | return -ENODEV; |
237 | } | 237 | } |
238 | 238 | ||
239 | pss = (union acpi_object *)buffer.pointer; | 239 | pss = buffer.pointer; |
240 | if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) { | 240 | if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) { |
241 | printk(KERN_ERR PREFIX "Invalid _PSS data\n"); | 241 | printk(KERN_ERR PREFIX "Invalid _PSS data\n"); |
242 | result = -EFAULT; | 242 | result = -EFAULT; |
@@ -322,10 +322,6 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) | |||
322 | if (result) | 322 | if (result) |
323 | return result; | 323 | return result; |
324 | 324 | ||
325 | result = acpi_processor_get_platform_limit(pr); | ||
326 | if (result) | ||
327 | return result; | ||
328 | |||
329 | return 0; | 325 | return 0; |
330 | } | 326 | } |
331 | 327 | ||
@@ -356,31 +352,24 @@ int acpi_processor_notify_smm(struct module *calling_module) | |||
356 | 352 | ||
357 | is_done = -EIO; | 353 | is_done = -EIO; |
358 | 354 | ||
359 | /* Can't write pstate_cnt to smi_cmd if either value is zero */ | 355 | /* Can't write pstate_control to smi_command if either value is zero */ |
360 | if ((!acpi_fadt.smi_cmd) || (!acpi_fadt.pstate_cnt)) { | 356 | if ((!acpi_gbl_FADT.smi_command) || (!acpi_gbl_FADT.pstate_control)) { |
361 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_cnt\n")); | 357 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_control\n")); |
362 | module_put(calling_module); | 358 | module_put(calling_module); |
363 | return 0; | 359 | return 0; |
364 | } | 360 | } |
365 | 361 | ||
366 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 362 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
367 | "Writing pstate_cnt [0x%x] to smi_cmd [0x%x]\n", | 363 | "Writing pstate_control [0x%x] to smi_command [0x%x]\n", |
368 | acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd)); | 364 | acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command)); |
369 | |||
370 | /* FADT v1 doesn't support pstate_cnt, many BIOS vendors use | ||
371 | * it anyway, so we need to support it... */ | ||
372 | if (acpi_fadt_is_v1) { | ||
373 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
374 | "Using v1.0 FADT reserved value for pstate_cnt\n")); | ||
375 | } | ||
376 | 365 | ||
377 | status = acpi_os_write_port(acpi_fadt.smi_cmd, | 366 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, |
378 | (u32) acpi_fadt.pstate_cnt, 8); | 367 | (u32) acpi_gbl_FADT.pstate_control, 8); |
379 | if (ACPI_FAILURE(status)) { | 368 | if (ACPI_FAILURE(status)) { |
380 | ACPI_EXCEPTION((AE_INFO, status, | 369 | ACPI_EXCEPTION((AE_INFO, status, |
381 | "Failed to write pstate_cnt [0x%x] to " | 370 | "Failed to write pstate_control [0x%x] to " |
382 | "smi_cmd [0x%x]", acpi_fadt.pstate_cnt, | 371 | "smi_command [0x%x]", acpi_gbl_FADT.pstate_control, |
383 | acpi_fadt.smi_cmd)); | 372 | acpi_gbl_FADT.smi_command)); |
384 | module_put(calling_module); | 373 | module_put(calling_module); |
385 | return status; | 374 | return status; |
386 | } | 375 | } |
@@ -410,7 +399,7 @@ static struct file_operations acpi_processor_perf_fops = { | |||
410 | 399 | ||
411 | static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) | 400 | static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) |
412 | { | 401 | { |
413 | struct acpi_processor *pr = (struct acpi_processor *)seq->private; | 402 | struct acpi_processor *pr = seq->private; |
414 | int i; | 403 | int i; |
415 | 404 | ||
416 | 405 | ||
@@ -451,8 +440,8 @@ acpi_processor_write_performance(struct file *file, | |||
451 | size_t count, loff_t * data) | 440 | size_t count, loff_t * data) |
452 | { | 441 | { |
453 | int result = 0; | 442 | int result = 0; |
454 | struct seq_file *m = (struct seq_file *)file->private_data; | 443 | struct seq_file *m = file->private_data; |
455 | struct acpi_processor *pr = (struct acpi_processor *)m->private; | 444 | struct acpi_processor *pr = m->private; |
456 | struct acpi_processor_performance *perf; | 445 | struct acpi_processor_performance *perf; |
457 | char state_string[12] = { '\0' }; | 446 | char state_string[12] = { '\0' }; |
458 | unsigned int new_state = 0; | 447 | unsigned int new_state = 0; |
@@ -551,7 +540,7 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) | |||
551 | return -ENODEV; | 540 | return -ENODEV; |
552 | } | 541 | } |
553 | 542 | ||
554 | psd = (union acpi_object *) buffer.pointer; | 543 | psd = buffer.pointer; |
555 | if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { | 544 | if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { |
556 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); | 545 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); |
557 | result = -EFAULT; | 546 | result = -EFAULT; |
@@ -736,10 +725,6 @@ int acpi_processor_preregister_performance( | |||
736 | } | 725 | } |
737 | 726 | ||
738 | err_ret: | 727 | err_ret: |
739 | if (retval) { | ||
740 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error while parsing _PSD domain information. Assuming no coordination\n")); | ||
741 | } | ||
742 | |||
743 | for_each_possible_cpu(i) { | 728 | for_each_possible_cpu(i) { |
744 | pr = processors[i]; | 729 | pr = processors[i]; |
745 | if (!pr || !pr->performance) | 730 | if (!pr || !pr->performance) |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index ef5e0f6efdba..40fecd67ad83 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -208,7 +208,7 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type) | |||
208 | if (result) | 208 | if (result) |
209 | return result; | 209 | return result; |
210 | 210 | ||
211 | pr = (struct acpi_processor *)acpi_driver_data(device); | 211 | pr = acpi_driver_data(device); |
212 | if (!pr) | 212 | if (!pr) |
213 | return -ENODEV; | 213 | return -ENODEV; |
214 | 214 | ||
@@ -348,8 +348,8 @@ static ssize_t acpi_processor_write_limit(struct file * file, | |||
348 | size_t count, loff_t * data) | 348 | size_t count, loff_t * data) |
349 | { | 349 | { |
350 | int result = 0; | 350 | int result = 0; |
351 | struct seq_file *m = (struct seq_file *)file->private_data; | 351 | struct seq_file *m = file->private_data; |
352 | struct acpi_processor *pr = (struct acpi_processor *)m->private; | 352 | struct acpi_processor *pr = m->private; |
353 | char limit_string[25] = { '\0' }; | 353 | char limit_string[25] = { '\0' }; |
354 | int px = 0; | 354 | int px = 0; |
355 | int tx = 0; | 355 | int tx = 0; |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index d044ec519db0..89dff3639abe 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -125,7 +125,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | |||
125 | /* Used to clear all duty_value bits */ | 125 | /* Used to clear all duty_value bits */ |
126 | duty_mask = pr->throttling.state_count - 1; | 126 | duty_mask = pr->throttling.state_count - 1; |
127 | 127 | ||
128 | duty_mask <<= acpi_fadt.duty_offset; | 128 | duty_mask <<= acpi_gbl_FADT.duty_offset; |
129 | duty_mask = ~duty_mask; | 129 | duty_mask = ~duty_mask; |
130 | } | 130 | } |
131 | 131 | ||
@@ -208,7 +208,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
208 | return 0; | 208 | return 0; |
209 | } | 209 | } |
210 | 210 | ||
211 | pr->throttling.state_count = 1 << acpi_fadt.duty_width; | 211 | pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width; |
212 | 212 | ||
213 | /* | 213 | /* |
214 | * Compute state values. Note that throttling displays a linear power/ | 214 | * Compute state values. Note that throttling displays a linear power/ |
@@ -259,7 +259,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
259 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, | 259 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, |
260 | void *offset) | 260 | void *offset) |
261 | { | 261 | { |
262 | struct acpi_processor *pr = (struct acpi_processor *)seq->private; | 262 | struct acpi_processor *pr = seq->private; |
263 | int i = 0; | 263 | int i = 0; |
264 | int result = 0; | 264 | int result = 0; |
265 | 265 | ||
@@ -307,8 +307,8 @@ static ssize_t acpi_processor_write_throttling(struct file * file, | |||
307 | size_t count, loff_t * data) | 307 | size_t count, loff_t * data) |
308 | { | 308 | { |
309 | int result = 0; | 309 | int result = 0; |
310 | struct seq_file *m = (struct seq_file *)file->private_data; | 310 | struct seq_file *m = file->private_data; |
311 | struct acpi_processor *pr = (struct acpi_processor *)m->private; | 311 | struct acpi_processor *pr = m->private; |
312 | char state_string[12] = { '\0' }; | 312 | char state_string[12] = { '\0' }; |
313 | 313 | ||
314 | 314 | ||
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 8fa3213ce000..271e61509eeb 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index cf87b0230026..8c6d3fdec38a 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 008058acdd39..1358c06a969c 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 9c99a723a860..de20a5d6decf 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c index 9e7ae2f8a1d3..7e3c335ab320 100644 --- a/drivers/acpi/resources/rsinfo.c +++ b/drivers/acpi/resources/rsinfo.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index ea567167c4f2..b297bc3e4419 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 1fa63bc2e36f..5657f7b95039 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 29423ce030ca..a92755c8877d 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c index a5131936d690..521eab7dd8df 100644 --- a/drivers/acpi/resources/rsmemory.c +++ b/drivers/acpi/resources/rsmemory.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index faf6e106b785..3b63b561b94e 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index a9cbee8e8b44..2442a8f8df57 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index 1999e2ab7daa..991f8901498c 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 8908a975e575..f58fc7447ab4 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -923,7 +923,7 @@ static struct proc_dir_entry *acpi_battery_dir = NULL; | |||
923 | 923 | ||
924 | static int acpi_battery_read_info(struct seq_file *seq, void *offset) | 924 | static int acpi_battery_read_info(struct seq_file *seq, void *offset) |
925 | { | 925 | { |
926 | struct acpi_battery *battery = (struct acpi_battery *)seq->private; | 926 | struct acpi_battery *battery = seq->private; |
927 | int cscale; | 927 | int cscale; |
928 | int result = 0; | 928 | int result = 0; |
929 | 929 | ||
@@ -1076,7 +1076,7 @@ static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) | |||
1076 | 1076 | ||
1077 | static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) | 1077 | static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) |
1078 | { | 1078 | { |
1079 | struct acpi_battery *battery = (struct acpi_battery *)seq->private; | 1079 | struct acpi_battery *battery = seq->private; |
1080 | int result = 0; | 1080 | int result = 0; |
1081 | int cscale; | 1081 | int cscale; |
1082 | 1082 | ||
@@ -1125,8 +1125,8 @@ static ssize_t | |||
1125 | acpi_battery_write_alarm(struct file *file, const char __user * buffer, | 1125 | acpi_battery_write_alarm(struct file *file, const char __user * buffer, |
1126 | size_t count, loff_t * ppos) | 1126 | size_t count, loff_t * ppos) |
1127 | { | 1127 | { |
1128 | struct seq_file *seq = (struct seq_file *)file->private_data; | 1128 | struct seq_file *seq = file->private_data; |
1129 | struct acpi_battery *battery = (struct acpi_battery *)seq->private; | 1129 | struct acpi_battery *battery = seq->private; |
1130 | char alarm_string[12] = { '\0' }; | 1130 | char alarm_string[12] = { '\0' }; |
1131 | int result, old_alarm, new_alarm; | 1131 | int result, old_alarm, new_alarm; |
1132 | 1132 | ||
@@ -1160,14 +1160,14 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer, | |||
1160 | if (result) { | 1160 | if (result) { |
1161 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1161 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
1162 | "acpi_battery_set_alarm() failed\n")); | 1162 | "acpi_battery_set_alarm() failed\n")); |
1163 | (void)acpi_battery_set_alarm(battery, old_alarm); | 1163 | acpi_battery_set_alarm(battery, old_alarm); |
1164 | goto end; | 1164 | goto end; |
1165 | } | 1165 | } |
1166 | result = acpi_battery_get_alarm(battery); | 1166 | result = acpi_battery_get_alarm(battery); |
1167 | if (result) { | 1167 | if (result) { |
1168 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1168 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
1169 | "acpi_battery_get_alarm() failed\n")); | 1169 | "acpi_battery_get_alarm() failed\n")); |
1170 | (void)acpi_battery_set_alarm(battery, old_alarm); | 1170 | acpi_battery_set_alarm(battery, old_alarm); |
1171 | goto end; | 1171 | goto end; |
1172 | } | 1172 | } |
1173 | 1173 | ||
@@ -1217,7 +1217,7 @@ static struct proc_dir_entry *acpi_ac_dir = NULL; | |||
1217 | 1217 | ||
1218 | static int acpi_ac_read_state(struct seq_file *seq, void *offset) | 1218 | static int acpi_ac_read_state(struct seq_file *seq, void *offset) |
1219 | { | 1219 | { |
1220 | struct acpi_sbs *sbs = (struct acpi_sbs *)seq->private; | 1220 | struct acpi_sbs *sbs = seq->private; |
1221 | int result; | 1221 | int result; |
1222 | 1222 | ||
1223 | if (sbs->zombie) { | 1223 | if (sbs->zombie) { |
@@ -1302,7 +1302,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) | |||
1302 | battery->init_state = 1; | 1302 | battery->init_state = 1; |
1303 | } | 1303 | } |
1304 | 1304 | ||
1305 | (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); | 1305 | sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); |
1306 | 1306 | ||
1307 | result = acpi_sbs_generic_add_fs(&battery->battery_entry, | 1307 | result = acpi_sbs_generic_add_fs(&battery->battery_entry, |
1308 | acpi_battery_dir, | 1308 | acpi_battery_dir, |
@@ -1485,7 +1485,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type) | |||
1485 | } | 1485 | } |
1486 | 1486 | ||
1487 | if (old_battery_present != new_battery_present) { | 1487 | if (old_battery_present != new_battery_present) { |
1488 | (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); | 1488 | sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); |
1489 | result = acpi_sbs_generate_event(sbs->device, | 1489 | result = acpi_sbs_generate_event(sbs->device, |
1490 | ACPI_SBS_BATTERY_NOTIFY_STATUS, | 1490 | ACPI_SBS_BATTERY_NOTIFY_STATUS, |
1491 | new_battery_present, | 1491 | new_battery_present, |
@@ -1498,7 +1498,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type) | |||
1498 | } | 1498 | } |
1499 | } | 1499 | } |
1500 | if (old_remaining_capacity != battery->state.remaining_capacity) { | 1500 | if (old_remaining_capacity != battery->state.remaining_capacity) { |
1501 | (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); | 1501 | sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); |
1502 | result = acpi_sbs_generate_event(sbs->device, | 1502 | result = acpi_sbs_generate_event(sbs->device, |
1503 | ACPI_SBS_BATTERY_NOTIFY_STATUS, | 1503 | ACPI_SBS_BATTERY_NOTIFY_STATUS, |
1504 | new_battery_present, | 1504 | new_battery_present, |
@@ -1576,12 +1576,11 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1576 | int id, cnt; | 1576 | int id, cnt; |
1577 | acpi_status status = AE_OK; | 1577 | acpi_status status = AE_OK; |
1578 | 1578 | ||
1579 | sbs = kmalloc(sizeof(struct acpi_sbs), GFP_KERNEL); | 1579 | sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL); |
1580 | if (!sbs) { | 1580 | if (!sbs) { |
1581 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "kmalloc() failed\n")); | 1581 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "kmalloc() failed\n")); |
1582 | return -ENOMEM; | 1582 | return -ENOMEM; |
1583 | } | 1583 | } |
1584 | memset(sbs, 0, sizeof(struct acpi_sbs)); | ||
1585 | 1584 | ||
1586 | cnt = 0; | 1585 | cnt = 0; |
1587 | while (cnt < 10) { | 1586 | while (cnt < 10) { |
@@ -1659,7 +1658,7 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1659 | init_timer(&sbs->update_timer); | 1658 | init_timer(&sbs->update_timer); |
1660 | if (update_mode == QUEUE_UPDATE_MODE) { | 1659 | if (update_mode == QUEUE_UPDATE_MODE) { |
1661 | status = acpi_os_execute(OSL_GPE_HANDLER, | 1660 | status = acpi_os_execute(OSL_GPE_HANDLER, |
1662 | acpi_sbs_update_queue, (void *)sbs); | 1661 | acpi_sbs_update_queue, sbs); |
1663 | if (status != AE_OK) { | 1662 | if (status != AE_OK) { |
1664 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1663 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
1665 | "acpi_os_execute() failed\n")); | 1664 | "acpi_os_execute() failed\n")); |
@@ -1685,7 +1684,7 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1685 | 1684 | ||
1686 | int acpi_sbs_remove(struct acpi_device *device, int type) | 1685 | int acpi_sbs_remove(struct acpi_device *device, int type) |
1687 | { | 1686 | { |
1688 | struct acpi_sbs *sbs = NULL; | 1687 | struct acpi_sbs *sbs; |
1689 | int id; | 1688 | int id; |
1690 | 1689 | ||
1691 | if (!device) { | 1690 | if (!device) { |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 4139e65d0ff5..5049230ccf49 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -1027,12 +1027,11 @@ acpi_add_single_object(struct acpi_device **child, | |||
1027 | if (!child) | 1027 | if (!child) |
1028 | return -EINVAL; | 1028 | return -EINVAL; |
1029 | 1029 | ||
1030 | device = kmalloc(sizeof(struct acpi_device), GFP_KERNEL); | 1030 | device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); |
1031 | if (!device) { | 1031 | if (!device) { |
1032 | printk(KERN_ERR PREFIX "Memory allocation error\n"); | 1032 | printk(KERN_ERR PREFIX "Memory allocation error\n"); |
1033 | return -ENOMEM; | 1033 | return -ENOMEM; |
1034 | } | 1034 | } |
1035 | memset(device, 0, sizeof(struct acpi_device)); | ||
1036 | 1035 | ||
1037 | device->handle = handle; | 1036 | device->handle = handle; |
1038 | device->parent = parent; | 1037 | device->parent = parent; |
@@ -1368,14 +1367,14 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) | |||
1368 | /* | 1367 | /* |
1369 | * Enumerate all fixed-feature devices. | 1368 | * Enumerate all fixed-feature devices. |
1370 | */ | 1369 | */ |
1371 | if (acpi_fadt.pwr_button == 0) { | 1370 | if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { |
1372 | result = acpi_add_single_object(&device, acpi_root, | 1371 | result = acpi_add_single_object(&device, acpi_root, |
1373 | NULL, | 1372 | NULL, |
1374 | ACPI_BUS_TYPE_POWER_BUTTON, | 1373 | ACPI_BUS_TYPE_POWER_BUTTON, |
1375 | &ops); | 1374 | &ops); |
1376 | } | 1375 | } |
1377 | 1376 | ||
1378 | if (acpi_fadt.sleep_button == 0) { | 1377 | if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { |
1379 | result = acpi_add_single_object(&device, acpi_root, | 1378 | result = acpi_add_single_object(&device, acpi_root, |
1380 | NULL, | 1379 | NULL, |
1381 | ACPI_BUS_TYPE_SLEEP_BUTTON, | 1380 | ACPI_BUS_TYPE_SLEEP_BUTTON, |
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 34962578039d..ccc11b33d89c 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c | |||
@@ -73,7 +73,7 @@ acpi_system_write_sleep(struct file *file, | |||
73 | static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) | 73 | static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) |
74 | { | 74 | { |
75 | u32 sec, min, hr; | 75 | u32 sec, min, hr; |
76 | u32 day, mo, yr; | 76 | u32 day, mo, yr, cent = 0; |
77 | unsigned char rtc_control = 0; | 77 | unsigned char rtc_control = 0; |
78 | unsigned long flags; | 78 | unsigned long flags; |
79 | 79 | ||
@@ -87,20 +87,19 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) | |||
87 | rtc_control = CMOS_READ(RTC_CONTROL); | 87 | rtc_control = CMOS_READ(RTC_CONTROL); |
88 | 88 | ||
89 | /* If we ever get an FACP with proper values... */ | 89 | /* If we ever get an FACP with proper values... */ |
90 | if (acpi_gbl_FADT->day_alrm) | 90 | if (acpi_gbl_FADT.day_alarm) |
91 | /* ACPI spec: only low 6 its should be cared */ | 91 | /* ACPI spec: only low 6 its should be cared */ |
92 | day = CMOS_READ(acpi_gbl_FADT->day_alrm) & 0x3F; | 92 | day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F; |
93 | else | 93 | else |
94 | day = CMOS_READ(RTC_DAY_OF_MONTH); | 94 | day = CMOS_READ(RTC_DAY_OF_MONTH); |
95 | if (acpi_gbl_FADT->mon_alrm) | 95 | if (acpi_gbl_FADT.month_alarm) |
96 | mo = CMOS_READ(acpi_gbl_FADT->mon_alrm); | 96 | mo = CMOS_READ(acpi_gbl_FADT.month_alarm); |
97 | else | 97 | else |
98 | mo = CMOS_READ(RTC_MONTH); | 98 | mo = CMOS_READ(RTC_MONTH); |
99 | if (acpi_gbl_FADT->century) | 99 | if (acpi_gbl_FADT.century) |
100 | yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + | 100 | cent = CMOS_READ(acpi_gbl_FADT.century); |
101 | CMOS_READ(RTC_YEAR); | 101 | |
102 | else | 102 | yr = CMOS_READ(RTC_YEAR); |
103 | yr = CMOS_READ(RTC_YEAR); | ||
104 | 103 | ||
105 | spin_unlock_irqrestore(&rtc_lock, flags); | 104 | spin_unlock_irqrestore(&rtc_lock, flags); |
106 | 105 | ||
@@ -111,10 +110,11 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) | |||
111 | BCD_TO_BIN(day); | 110 | BCD_TO_BIN(day); |
112 | BCD_TO_BIN(mo); | 111 | BCD_TO_BIN(mo); |
113 | BCD_TO_BIN(yr); | 112 | BCD_TO_BIN(yr); |
113 | BCD_TO_BIN(cent); | ||
114 | } | 114 | } |
115 | 115 | ||
116 | /* we're trusting the FADT (see above) */ | 116 | /* we're trusting the FADT (see above) */ |
117 | if (!acpi_gbl_FADT->century) | 117 | if (!acpi_gbl_FADT.century) |
118 | /* If we're not trusting the FADT, we should at least make it | 118 | /* If we're not trusting the FADT, we should at least make it |
119 | * right for _this_ century... ehm, what is _this_ century? | 119 | * right for _this_ century... ehm, what is _this_ century? |
120 | * | 120 | * |
@@ -134,6 +134,8 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) | |||
134 | * | 134 | * |
135 | */ | 135 | */ |
136 | yr += 2000; | 136 | yr += 2000; |
137 | else | ||
138 | yr += cent * 100; | ||
137 | 139 | ||
138 | seq_printf(seq, "%4.4u-", yr); | 140 | seq_printf(seq, "%4.4u-", yr); |
139 | (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); | 141 | (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); |
@@ -317,12 +319,12 @@ acpi_system_write_alarm(struct file *file, | |||
317 | * offsets into the CMOS RAM here -- which for some reason are pointing | 319 | * offsets into the CMOS RAM here -- which for some reason are pointing |
318 | * to the RTC area of memory. | 320 | * to the RTC area of memory. |
319 | */ | 321 | */ |
320 | if (acpi_gbl_FADT->day_alrm) | 322 | if (acpi_gbl_FADT.day_alarm) |
321 | CMOS_WRITE(day, acpi_gbl_FADT->day_alrm); | 323 | CMOS_WRITE(day, acpi_gbl_FADT.day_alarm); |
322 | if (acpi_gbl_FADT->mon_alrm) | 324 | if (acpi_gbl_FADT.month_alarm) |
323 | CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm); | 325 | CMOS_WRITE(mo, acpi_gbl_FADT.month_alarm); |
324 | if (acpi_gbl_FADT->century) | 326 | if (acpi_gbl_FADT.century) |
325 | CMOS_WRITE(yr / 100, acpi_gbl_FADT->century); | 327 | CMOS_WRITE(yr / 100, acpi_gbl_FADT.century); |
326 | /* enable the rtc alarm interrupt */ | 328 | /* enable the rtc alarm interrupt */ |
327 | rtc_control |= RTC_AIE; | 329 | rtc_control |= RTC_AIE; |
328 | CMOS_WRITE(rtc_control, RTC_CONTROL); | 330 | CMOS_WRITE(rtc_control, RTC_CONTROL); |
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c index af1dbabaf0b1..fab8f2694f03 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/sleep/wakeup.c | |||
@@ -183,11 +183,11 @@ late_initcall(acpi_wakeup_device_init); | |||
183 | #endif | 183 | #endif |
184 | 184 | ||
185 | /* | 185 | /* |
186 | * Disable all wakeup GPEs before power off. | 186 | * Disable all wakeup GPEs before entering requested sleep state. |
187 | * | 187 | * @sleep_state: ACPI state |
188 | * Since acpi_enter_sleep_state() will disable all | 188 | * Since acpi_enter_sleep_state() will disable all |
189 | * RUNTIME GPEs, we simply mark all GPES that | 189 | * RUNTIME GPEs, we simply mark all GPES that |
190 | * are not enabled for wakeup from S5 as RUNTIME. | 190 | * are not enabled for wakeup from requested state as RUNTIME. |
191 | */ | 191 | */ |
192 | void acpi_gpe_sleep_prepare(u32 sleep_state) | 192 | void acpi_gpe_sleep_prepare(u32 sleep_state) |
193 | { | 193 | { |
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 407b0e0281db..7147b0bdab0a 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -44,7 +44,6 @@ ACPI_MODULE_NAME("acpi_system") | |||
44 | #define ACPI_SYSTEM_FILE_EVENT "event" | 44 | #define ACPI_SYSTEM_FILE_EVENT "event" |
45 | #define ACPI_SYSTEM_FILE_DSDT "dsdt" | 45 | #define ACPI_SYSTEM_FILE_DSDT "dsdt" |
46 | #define ACPI_SYSTEM_FILE_FADT "fadt" | 46 | #define ACPI_SYSTEM_FILE_FADT "fadt" |
47 | extern struct fadt_descriptor acpi_fadt; | ||
48 | 47 | ||
49 | /* | 48 | /* |
50 | * Make ACPICA version work as module param | 49 | * Make ACPICA version work as module param |
@@ -96,17 +95,16 @@ acpi_system_read_dsdt(struct file *file, | |||
96 | char __user * buffer, size_t count, loff_t * ppos) | 95 | char __user * buffer, size_t count, loff_t * ppos) |
97 | { | 96 | { |
98 | acpi_status status = AE_OK; | 97 | acpi_status status = AE_OK; |
99 | struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; | 98 | struct acpi_table_header *dsdt = NULL; |
100 | ssize_t res; | 99 | ssize_t res; |
101 | 100 | ||
102 | 101 | ||
103 | status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt); | 102 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); |
104 | if (ACPI_FAILURE(status)) | 103 | if (ACPI_FAILURE(status)) |
105 | return -ENODEV; | 104 | return -ENODEV; |
106 | 105 | ||
107 | res = simple_read_from_buffer(buffer, count, ppos, | 106 | res = simple_read_from_buffer(buffer, count, ppos, |
108 | dsdt.pointer, dsdt.length); | 107 | dsdt, dsdt->length); |
109 | kfree(dsdt.pointer); | ||
110 | 108 | ||
111 | return res; | 109 | return res; |
112 | } | 110 | } |
@@ -123,17 +121,16 @@ acpi_system_read_fadt(struct file *file, | |||
123 | char __user * buffer, size_t count, loff_t * ppos) | 121 | char __user * buffer, size_t count, loff_t * ppos) |
124 | { | 122 | { |
125 | acpi_status status = AE_OK; | 123 | acpi_status status = AE_OK; |
126 | struct acpi_buffer fadt = { ACPI_ALLOCATE_BUFFER, NULL }; | 124 | struct acpi_table_header *fadt = NULL; |
127 | ssize_t res; | 125 | ssize_t res; |
128 | 126 | ||
129 | 127 | ||
130 | status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &fadt); | 128 | status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); |
131 | if (ACPI_FAILURE(status)) | 129 | if (ACPI_FAILURE(status)) |
132 | return -ENODEV; | 130 | return -ENODEV; |
133 | 131 | ||
134 | res = simple_read_from_buffer(buffer, count, ppos, | 132 | res = simple_read_from_buffer(buffer, count, ppos, |
135 | fadt.pointer, fadt.length); | 133 | fadt, fadt->length); |
136 | kfree(fadt.pointer); | ||
137 | 134 | ||
138 | return res; | 135 | return res; |
139 | } | 136 | } |
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index bfb3bfcf9e91..ba4cb200314a 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -38,154 +38,97 @@ | |||
38 | 38 | ||
39 | #define ACPI_MAX_TABLES 128 | 39 | #define ACPI_MAX_TABLES 128 |
40 | 40 | ||
41 | static char *acpi_table_signatures[ACPI_TABLE_COUNT] = { | ||
42 | [ACPI_TABLE_UNKNOWN] = "????", | ||
43 | [ACPI_APIC] = "APIC", | ||
44 | [ACPI_BOOT] = "BOOT", | ||
45 | [ACPI_DBGP] = "DBGP", | ||
46 | [ACPI_DSDT] = "DSDT", | ||
47 | [ACPI_ECDT] = "ECDT", | ||
48 | [ACPI_ETDT] = "ETDT", | ||
49 | [ACPI_FADT] = "FACP", | ||
50 | [ACPI_FACS] = "FACS", | ||
51 | [ACPI_OEMX] = "OEM", | ||
52 | [ACPI_PSDT] = "PSDT", | ||
53 | [ACPI_SBST] = "SBST", | ||
54 | [ACPI_SLIT] = "SLIT", | ||
55 | [ACPI_SPCR] = "SPCR", | ||
56 | [ACPI_SRAT] = "SRAT", | ||
57 | [ACPI_SSDT] = "SSDT", | ||
58 | [ACPI_SPMI] = "SPMI", | ||
59 | [ACPI_HPET] = "HPET", | ||
60 | [ACPI_MCFG] = "MCFG", | ||
61 | }; | ||
62 | |||
63 | static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; | 41 | static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; |
64 | static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; | 42 | static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; |
65 | 43 | ||
66 | /* System Description Table (RSDT/XSDT) */ | 44 | static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; |
67 | struct acpi_table_sdt { | ||
68 | unsigned long pa; | ||
69 | enum acpi_table_id id; | ||
70 | unsigned long size; | ||
71 | } __attribute__ ((packed)); | ||
72 | |||
73 | static unsigned long sdt_pa; /* Physical Address */ | ||
74 | static unsigned long sdt_count; /* Table count */ | ||
75 | 45 | ||
76 | static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata; | 46 | void acpi_table_print_madt_entry(struct acpi_subtable_header * header) |
77 | |||
78 | void acpi_table_print(struct acpi_table_header *header, unsigned long phys_addr) | ||
79 | { | ||
80 | char *name = NULL; | ||
81 | |||
82 | if (!header) | ||
83 | return; | ||
84 | |||
85 | /* Some table signatures aren't good table names */ | ||
86 | |||
87 | if (!strncmp((char *)&header->signature, | ||
88 | acpi_table_signatures[ACPI_APIC], | ||
89 | sizeof(header->signature))) { | ||
90 | name = "MADT"; | ||
91 | } else if (!strncmp((char *)&header->signature, | ||
92 | acpi_table_signatures[ACPI_FADT], | ||
93 | sizeof(header->signature))) { | ||
94 | name = "FADT"; | ||
95 | } else | ||
96 | name = header->signature; | ||
97 | |||
98 | printk(KERN_DEBUG PREFIX | ||
99 | "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n", name, | ||
100 | header->revision, header->oem_id, header->oem_table_id, | ||
101 | header->oem_revision, header->asl_compiler_id, | ||
102 | header->asl_compiler_revision, (void *)phys_addr); | ||
103 | } | ||
104 | |||
105 | void acpi_table_print_madt_entry(acpi_table_entry_header * header) | ||
106 | { | 47 | { |
107 | if (!header) | 48 | if (!header) |
108 | return; | 49 | return; |
109 | 50 | ||
110 | switch (header->type) { | 51 | switch (header->type) { |
111 | 52 | ||
112 | case ACPI_MADT_LAPIC: | 53 | case ACPI_MADT_TYPE_LOCAL_APIC: |
113 | { | 54 | { |
114 | struct acpi_table_lapic *p = | 55 | struct acpi_madt_local_apic *p = |
115 | (struct acpi_table_lapic *)header; | 56 | (struct acpi_madt_local_apic *)header; |
116 | printk(KERN_INFO PREFIX | 57 | printk(KERN_INFO PREFIX |
117 | "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", | 58 | "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", |
118 | p->acpi_id, p->id, | 59 | p->processor_id, p->id, |
119 | p->flags.enabled ? "enabled" : "disabled"); | 60 | (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); |
120 | } | 61 | } |
121 | break; | 62 | break; |
122 | 63 | ||
123 | case ACPI_MADT_IOAPIC: | 64 | case ACPI_MADT_TYPE_IO_APIC: |
124 | { | 65 | { |
125 | struct acpi_table_ioapic *p = | 66 | struct acpi_madt_io_apic *p = |
126 | (struct acpi_table_ioapic *)header; | 67 | (struct acpi_madt_io_apic *)header; |
127 | printk(KERN_INFO PREFIX | 68 | printk(KERN_INFO PREFIX |
128 | "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", | 69 | "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", |
129 | p->id, p->address, p->global_irq_base); | 70 | p->id, p->address, p->global_irq_base); |
130 | } | 71 | } |
131 | break; | 72 | break; |
132 | 73 | ||
133 | case ACPI_MADT_INT_SRC_OVR: | 74 | case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: |
134 | { | 75 | { |
135 | struct acpi_table_int_src_ovr *p = | 76 | struct acpi_madt_interrupt_override *p = |
136 | (struct acpi_table_int_src_ovr *)header; | 77 | (struct acpi_madt_interrupt_override *)header; |
137 | printk(KERN_INFO PREFIX | 78 | printk(KERN_INFO PREFIX |
138 | "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n", | 79 | "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n", |
139 | p->bus, p->bus_irq, p->global_irq, | 80 | p->bus, p->source_irq, p->global_irq, |
140 | mps_inti_flags_polarity[p->flags.polarity], | 81 | mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], |
141 | mps_inti_flags_trigger[p->flags.trigger]); | 82 | mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2]); |
142 | if (p->flags.reserved) | 83 | if (p->inti_flags & |
84 | ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK)) | ||
143 | printk(KERN_INFO PREFIX | 85 | printk(KERN_INFO PREFIX |
144 | "INT_SRC_OVR unexpected reserved flags: 0x%x\n", | 86 | "INT_SRC_OVR unexpected reserved flags: 0x%x\n", |
145 | p->flags.reserved); | 87 | p->inti_flags & |
88 | ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK)); | ||
146 | 89 | ||
147 | } | 90 | } |
148 | break; | 91 | break; |
149 | 92 | ||
150 | case ACPI_MADT_NMI_SRC: | 93 | case ACPI_MADT_TYPE_NMI_SOURCE: |
151 | { | 94 | { |
152 | struct acpi_table_nmi_src *p = | 95 | struct acpi_madt_nmi_source *p = |
153 | (struct acpi_table_nmi_src *)header; | 96 | (struct acpi_madt_nmi_source *)header; |
154 | printk(KERN_INFO PREFIX | 97 | printk(KERN_INFO PREFIX |
155 | "NMI_SRC (%s %s global_irq %d)\n", | 98 | "NMI_SRC (%s %s global_irq %d)\n", |
156 | mps_inti_flags_polarity[p->flags.polarity], | 99 | mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], |
157 | mps_inti_flags_trigger[p->flags.trigger], | 100 | mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], |
158 | p->global_irq); | 101 | p->global_irq); |
159 | } | 102 | } |
160 | break; | 103 | break; |
161 | 104 | ||
162 | case ACPI_MADT_LAPIC_NMI: | 105 | case ACPI_MADT_TYPE_LOCAL_APIC_NMI: |
163 | { | 106 | { |
164 | struct acpi_table_lapic_nmi *p = | 107 | struct acpi_madt_local_apic_nmi *p = |
165 | (struct acpi_table_lapic_nmi *)header; | 108 | (struct acpi_madt_local_apic_nmi *)header; |
166 | printk(KERN_INFO PREFIX | 109 | printk(KERN_INFO PREFIX |
167 | "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n", | 110 | "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n", |
168 | p->acpi_id, | 111 | p->processor_id, |
169 | mps_inti_flags_polarity[p->flags.polarity], | 112 | mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK ], |
170 | mps_inti_flags_trigger[p->flags.trigger], | 113 | mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], |
171 | p->lint); | 114 | p->lint); |
172 | } | 115 | } |
173 | break; | 116 | break; |
174 | 117 | ||
175 | case ACPI_MADT_LAPIC_ADDR_OVR: | 118 | case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: |
176 | { | 119 | { |
177 | struct acpi_table_lapic_addr_ovr *p = | 120 | struct acpi_madt_local_apic_override *p = |
178 | (struct acpi_table_lapic_addr_ovr *)header; | 121 | (struct acpi_madt_local_apic_override *)header; |
179 | printk(KERN_INFO PREFIX | 122 | printk(KERN_INFO PREFIX |
180 | "LAPIC_ADDR_OVR (address[%p])\n", | 123 | "LAPIC_ADDR_OVR (address[%p])\n", |
181 | (void *)(unsigned long)p->address); | 124 | (void *)(unsigned long)p->address); |
182 | } | 125 | } |
183 | break; | 126 | break; |
184 | 127 | ||
185 | case ACPI_MADT_IOSAPIC: | 128 | case ACPI_MADT_TYPE_IO_SAPIC: |
186 | { | 129 | { |
187 | struct acpi_table_iosapic *p = | 130 | struct acpi_madt_io_sapic *p = |
188 | (struct acpi_table_iosapic *)header; | 131 | (struct acpi_madt_io_sapic *)header; |
189 | printk(KERN_INFO PREFIX | 132 | printk(KERN_INFO PREFIX |
190 | "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", | 133 | "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", |
191 | p->id, (void *)(unsigned long)p->address, | 134 | p->id, (void *)(unsigned long)p->address, |
@@ -193,26 +136,26 @@ void acpi_table_print_madt_entry(acpi_table_entry_header * header) | |||
193 | } | 136 | } |
194 | break; | 137 | break; |
195 | 138 | ||
196 | case ACPI_MADT_LSAPIC: | 139 | case ACPI_MADT_TYPE_LOCAL_SAPIC: |
197 | { | 140 | { |
198 | struct acpi_table_lsapic *p = | 141 | struct acpi_madt_local_sapic *p = |
199 | (struct acpi_table_lsapic *)header; | 142 | (struct acpi_madt_local_sapic *)header; |
200 | printk(KERN_INFO PREFIX | 143 | printk(KERN_INFO PREFIX |
201 | "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", | 144 | "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", |
202 | p->acpi_id, p->id, p->eid, | 145 | p->processor_id, p->id, p->eid, |
203 | p->flags.enabled ? "enabled" : "disabled"); | 146 | (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); |
204 | } | 147 | } |
205 | break; | 148 | break; |
206 | 149 | ||
207 | case ACPI_MADT_PLAT_INT_SRC: | 150 | case ACPI_MADT_TYPE_INTERRUPT_SOURCE: |
208 | { | 151 | { |
209 | struct acpi_table_plat_int_src *p = | 152 | struct acpi_madt_interrupt_source *p = |
210 | (struct acpi_table_plat_int_src *)header; | 153 | (struct acpi_madt_interrupt_source *)header; |
211 | printk(KERN_INFO PREFIX | 154 | printk(KERN_INFO PREFIX |
212 | "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", | 155 | "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", |
213 | mps_inti_flags_polarity[p->flags.polarity], | 156 | mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], |
214 | mps_inti_flags_trigger[p->flags.trigger], | 157 | mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], |
215 | p->type, p->id, p->eid, p->iosapic_vector, | 158 | p->type, p->id, p->eid, p->io_sapic_vector, |
216 | p->global_irq); | 159 | p->global_irq); |
217 | } | 160 | } |
218 | break; | 161 | break; |
@@ -225,342 +168,76 @@ void acpi_table_print_madt_entry(acpi_table_entry_header * header) | |||
225 | } | 168 | } |
226 | } | 169 | } |
227 | 170 | ||
228 | static int | ||
229 | acpi_table_compute_checksum(void *table_pointer, unsigned long length) | ||
230 | { | ||
231 | u8 *p = (u8 *) table_pointer; | ||
232 | unsigned long remains = length; | ||
233 | unsigned long sum = 0; | ||
234 | |||
235 | if (!p || !length) | ||
236 | return -EINVAL; | ||
237 | |||
238 | while (remains--) | ||
239 | sum += *p++; | ||
240 | |||
241 | return (sum & 0xFF); | ||
242 | } | ||
243 | 171 | ||
244 | /* | ||
245 | * acpi_get_table_header_early() | ||
246 | * for acpi_blacklisted(), acpi_table_get_sdt() | ||
247 | */ | ||
248 | int __init | 172 | int __init |
249 | acpi_get_table_header_early(enum acpi_table_id id, | 173 | acpi_table_parse_madt_family(char *id, |
250 | struct acpi_table_header **header) | ||
251 | { | ||
252 | unsigned int i; | ||
253 | enum acpi_table_id temp_id; | ||
254 | |||
255 | /* DSDT is different from the rest */ | ||
256 | if (id == ACPI_DSDT) | ||
257 | temp_id = ACPI_FADT; | ||
258 | else | ||
259 | temp_id = id; | ||
260 | |||
261 | /* Locate the table. */ | ||
262 | |||
263 | for (i = 0; i < sdt_count; i++) { | ||
264 | if (sdt_entry[i].id != temp_id) | ||
265 | continue; | ||
266 | *header = (void *) | ||
267 | __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); | ||
268 | if (!*header) { | ||
269 | printk(KERN_WARNING PREFIX "Unable to map %s\n", | ||
270 | acpi_table_signatures[temp_id]); | ||
271 | return -ENODEV; | ||
272 | } | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | if (!*header) { | ||
277 | printk(KERN_WARNING PREFIX "%s not present\n", | ||
278 | acpi_table_signatures[id]); | ||
279 | return -ENODEV; | ||
280 | } | ||
281 | |||
282 | /* Map the DSDT header via the pointer in the FADT */ | ||
283 | if (id == ACPI_DSDT) { | ||
284 | struct fadt_descriptor *fadt = | ||
285 | (struct fadt_descriptor *)*header; | ||
286 | |||
287 | if (fadt->revision == 3 && fadt->Xdsdt) { | ||
288 | *header = (void *)__acpi_map_table(fadt->Xdsdt, | ||
289 | sizeof(struct | ||
290 | acpi_table_header)); | ||
291 | } else if (fadt->V1_dsdt) { | ||
292 | *header = (void *)__acpi_map_table(fadt->V1_dsdt, | ||
293 | sizeof(struct | ||
294 | acpi_table_header)); | ||
295 | } else | ||
296 | *header = NULL; | ||
297 | |||
298 | if (!*header) { | ||
299 | printk(KERN_WARNING PREFIX "Unable to map DSDT\n"); | ||
300 | return -ENODEV; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | int __init | ||
308 | acpi_table_parse_madt_family(enum acpi_table_id id, | ||
309 | unsigned long madt_size, | 174 | unsigned long madt_size, |
310 | int entry_id, | 175 | int entry_id, |
311 | acpi_madt_entry_handler handler, | 176 | acpi_madt_entry_handler handler, |
312 | unsigned int max_entries) | 177 | unsigned int max_entries) |
313 | { | 178 | { |
314 | void *madt = NULL; | 179 | struct acpi_table_header *madt = NULL; |
315 | acpi_table_entry_header *entry; | 180 | struct acpi_subtable_header *entry; |
316 | unsigned int count = 0; | 181 | unsigned int count = 0; |
317 | unsigned long madt_end; | 182 | unsigned long madt_end; |
318 | unsigned int i; | ||
319 | 183 | ||
320 | if (!handler) | 184 | if (!handler) |
321 | return -EINVAL; | 185 | return -EINVAL; |
322 | 186 | ||
323 | /* Locate the MADT (if exists). There should only be one. */ | 187 | /* Locate the MADT (if exists). There should only be one. */ |
324 | 188 | acpi_get_table(id, 0, &madt); | |
325 | for (i = 0; i < sdt_count; i++) { | ||
326 | if (sdt_entry[i].id != id) | ||
327 | continue; | ||
328 | madt = (void *) | ||
329 | __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); | ||
330 | if (!madt) { | ||
331 | printk(KERN_WARNING PREFIX "Unable to map %s\n", | ||
332 | acpi_table_signatures[id]); | ||
333 | return -ENODEV; | ||
334 | } | ||
335 | break; | ||
336 | } | ||
337 | 189 | ||
338 | if (!madt) { | 190 | if (!madt) { |
339 | printk(KERN_WARNING PREFIX "%s not present\n", | 191 | printk(KERN_WARNING PREFIX "%4.4s not present\n", id); |
340 | acpi_table_signatures[id]); | ||
341 | return -ENODEV; | 192 | return -ENODEV; |
342 | } | 193 | } |
343 | 194 | ||
344 | madt_end = (unsigned long)madt + sdt_entry[i].size; | 195 | madt_end = (unsigned long)madt + madt->length; |
345 | 196 | ||
346 | /* Parse all entries looking for a match. */ | 197 | /* Parse all entries looking for a match. */ |
347 | 198 | ||
348 | entry = (acpi_table_entry_header *) | 199 | entry = (struct acpi_subtable_header *) |
349 | ((unsigned long)madt + madt_size); | 200 | ((unsigned long)madt + madt_size); |
350 | 201 | ||
351 | while (((unsigned long)entry) + sizeof(acpi_table_entry_header) < | 202 | while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < |
352 | madt_end) { | 203 | madt_end) { |
353 | if (entry->type == entry_id | 204 | if (entry->type == entry_id |
354 | && (!max_entries || count++ < max_entries)) | 205 | && (!max_entries || count++ < max_entries)) |
355 | if (handler(entry, madt_end)) | 206 | if (handler(entry, madt_end)) |
356 | return -EINVAL; | 207 | return -EINVAL; |
357 | 208 | ||
358 | entry = (acpi_table_entry_header *) | 209 | entry = (struct acpi_subtable_header *) |
359 | ((unsigned long)entry + entry->length); | 210 | ((unsigned long)entry + entry->length); |
360 | } | 211 | } |
361 | if (max_entries && count > max_entries) { | 212 | if (max_entries && count > max_entries) { |
362 | printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of " | 213 | printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of " |
363 | "%i found\n", acpi_table_signatures[id], entry_id, | 214 | "%i found\n", id, entry_id, count - max_entries, count); |
364 | count - max_entries, count); | ||
365 | } | 215 | } |
366 | 216 | ||
367 | return count; | 217 | return count; |
368 | } | 218 | } |
369 | 219 | ||
370 | int __init | 220 | int __init |
371 | acpi_table_parse_madt(enum acpi_madt_entry_id id, | 221 | acpi_table_parse_madt(enum acpi_madt_type id, |
372 | acpi_madt_entry_handler handler, unsigned int max_entries) | 222 | acpi_madt_entry_handler handler, unsigned int max_entries) |
373 | { | 223 | { |
374 | return acpi_table_parse_madt_family(ACPI_APIC, | 224 | return acpi_table_parse_madt_family(ACPI_SIG_MADT, |
375 | sizeof(struct acpi_table_madt), id, | 225 | sizeof(struct acpi_table_madt), id, |
376 | handler, max_entries); | 226 | handler, max_entries); |
377 | } | 227 | } |
378 | 228 | ||
379 | int __init acpi_table_parse(enum acpi_table_id id, acpi_table_handler handler) | 229 | int __init acpi_table_parse(char *id, acpi_table_handler handler) |
380 | { | 230 | { |
381 | int count = 0; | 231 | struct acpi_table_header *table = NULL; |
382 | unsigned int i = 0; | ||
383 | |||
384 | if (!handler) | 232 | if (!handler) |
385 | return -EINVAL; | 233 | return -EINVAL; |
386 | 234 | ||
387 | for (i = 0; i < sdt_count; i++) { | 235 | acpi_get_table(id, 0, &table); |
388 | if (sdt_entry[i].id != id) | 236 | if (table) { |
389 | continue; | 237 | handler(table); |
390 | count++; | 238 | return 1; |
391 | if (count == 1) | 239 | } else |
392 | handler(sdt_entry[i].pa, sdt_entry[i].size); | 240 | return 0; |
393 | |||
394 | else | ||
395 | printk(KERN_WARNING PREFIX | ||
396 | "%d duplicate %s table ignored.\n", count, | ||
397 | acpi_table_signatures[id]); | ||
398 | } | ||
399 | |||
400 | return count; | ||
401 | } | ||
402 | |||
403 | static int __init acpi_table_get_sdt(struct acpi_table_rsdp *rsdp) | ||
404 | { | ||
405 | struct acpi_table_header *header = NULL; | ||
406 | unsigned int i, id = 0; | ||
407 | |||
408 | if (!rsdp) | ||
409 | return -EINVAL; | ||
410 | |||
411 | /* First check XSDT (but only on ACPI 2.0-compatible systems) */ | ||
412 | |||
413 | if ((rsdp->revision >= 2) && | ||
414 | (((struct acpi20_table_rsdp *)rsdp)->xsdt_address)) { | ||
415 | |||
416 | struct acpi_table_xsdt *mapped_xsdt = NULL; | ||
417 | |||
418 | sdt_pa = ((struct acpi20_table_rsdp *)rsdp)->xsdt_address; | ||
419 | |||
420 | /* map in just the header */ | ||
421 | header = (struct acpi_table_header *) | ||
422 | __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); | ||
423 | |||
424 | if (!header) { | ||
425 | printk(KERN_WARNING PREFIX | ||
426 | "Unable to map XSDT header\n"); | ||
427 | return -ENODEV; | ||
428 | } | ||
429 | |||
430 | /* remap in the entire table before processing */ | ||
431 | mapped_xsdt = (struct acpi_table_xsdt *) | ||
432 | __acpi_map_table(sdt_pa, header->length); | ||
433 | if (!mapped_xsdt) { | ||
434 | printk(KERN_WARNING PREFIX "Unable to map XSDT\n"); | ||
435 | return -ENODEV; | ||
436 | } | ||
437 | header = &mapped_xsdt->header; | ||
438 | |||
439 | if (strncmp(header->signature, "XSDT", 4)) { | ||
440 | printk(KERN_WARNING PREFIX | ||
441 | "XSDT signature incorrect\n"); | ||
442 | return -ENODEV; | ||
443 | } | ||
444 | |||
445 | if (acpi_table_compute_checksum(header, header->length)) { | ||
446 | printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n"); | ||
447 | return -ENODEV; | ||
448 | } | ||
449 | |||
450 | sdt_count = | ||
451 | (header->length - sizeof(struct acpi_table_header)) >> 3; | ||
452 | if (sdt_count > ACPI_MAX_TABLES) { | ||
453 | printk(KERN_WARNING PREFIX | ||
454 | "Truncated %lu XSDT entries\n", | ||
455 | (sdt_count - ACPI_MAX_TABLES)); | ||
456 | sdt_count = ACPI_MAX_TABLES; | ||
457 | } | ||
458 | |||
459 | for (i = 0; i < sdt_count; i++) | ||
460 | sdt_entry[i].pa = (unsigned long)mapped_xsdt->entry[i]; | ||
461 | } | ||
462 | |||
463 | /* Then check RSDT */ | ||
464 | |||
465 | else if (rsdp->rsdt_address) { | ||
466 | |||
467 | struct acpi_table_rsdt *mapped_rsdt = NULL; | ||
468 | |||
469 | sdt_pa = rsdp->rsdt_address; | ||
470 | |||
471 | /* map in just the header */ | ||
472 | header = (struct acpi_table_header *) | ||
473 | __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); | ||
474 | if (!header) { | ||
475 | printk(KERN_WARNING PREFIX | ||
476 | "Unable to map RSDT header\n"); | ||
477 | return -ENODEV; | ||
478 | } | ||
479 | |||
480 | /* remap in the entire table before processing */ | ||
481 | mapped_rsdt = (struct acpi_table_rsdt *) | ||
482 | __acpi_map_table(sdt_pa, header->length); | ||
483 | if (!mapped_rsdt) { | ||
484 | printk(KERN_WARNING PREFIX "Unable to map RSDT\n"); | ||
485 | return -ENODEV; | ||
486 | } | ||
487 | header = &mapped_rsdt->header; | ||
488 | |||
489 | if (strncmp(header->signature, "RSDT", 4)) { | ||
490 | printk(KERN_WARNING PREFIX | ||
491 | "RSDT signature incorrect\n"); | ||
492 | return -ENODEV; | ||
493 | } | ||
494 | |||
495 | if (acpi_table_compute_checksum(header, header->length)) { | ||
496 | printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n"); | ||
497 | return -ENODEV; | ||
498 | } | ||
499 | |||
500 | sdt_count = | ||
501 | (header->length - sizeof(struct acpi_table_header)) >> 2; | ||
502 | if (sdt_count > ACPI_MAX_TABLES) { | ||
503 | printk(KERN_WARNING PREFIX | ||
504 | "Truncated %lu RSDT entries\n", | ||
505 | (sdt_count - ACPI_MAX_TABLES)); | ||
506 | sdt_count = ACPI_MAX_TABLES; | ||
507 | } | ||
508 | |||
509 | for (i = 0; i < sdt_count; i++) | ||
510 | sdt_entry[i].pa = (unsigned long)mapped_rsdt->entry[i]; | ||
511 | } | ||
512 | |||
513 | else { | ||
514 | printk(KERN_WARNING PREFIX | ||
515 | "No System Description Table (RSDT/XSDT) specified in RSDP\n"); | ||
516 | return -ENODEV; | ||
517 | } | ||
518 | |||
519 | acpi_table_print(header, sdt_pa); | ||
520 | |||
521 | for (i = 0; i < sdt_count; i++) { | ||
522 | |||
523 | /* map in just the header */ | ||
524 | header = (struct acpi_table_header *) | ||
525 | __acpi_map_table(sdt_entry[i].pa, | ||
526 | sizeof(struct acpi_table_header)); | ||
527 | if (!header) | ||
528 | continue; | ||
529 | |||
530 | /* remap in the entire table before processing */ | ||
531 | header = (struct acpi_table_header *) | ||
532 | __acpi_map_table(sdt_entry[i].pa, header->length); | ||
533 | if (!header) | ||
534 | continue; | ||
535 | |||
536 | acpi_table_print(header, sdt_entry[i].pa); | ||
537 | |||
538 | if (acpi_table_compute_checksum(header, header->length)) { | ||
539 | printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); | ||
540 | continue; | ||
541 | } | ||
542 | |||
543 | sdt_entry[i].size = header->length; | ||
544 | |||
545 | for (id = 0; id < ACPI_TABLE_COUNT; id++) { | ||
546 | if (!strncmp((char *)&header->signature, | ||
547 | acpi_table_signatures[id], | ||
548 | sizeof(header->signature))) { | ||
549 | sdt_entry[i].id = id; | ||
550 | } | ||
551 | } | ||
552 | } | ||
553 | |||
554 | /* | ||
555 | * The DSDT is *not* in the RSDT (why not? no idea.) but we want | ||
556 | * to print its info, because this is what people usually blacklist | ||
557 | * against. Unfortunately, we don't know the phys_addr, so just | ||
558 | * print 0. Maybe no one will notice. | ||
559 | */ | ||
560 | if (!acpi_get_table_header_early(ACPI_DSDT, &header)) | ||
561 | acpi_table_print(header, 0); | ||
562 | |||
563 | return 0; | ||
564 | } | 241 | } |
565 | 242 | ||
566 | /* | 243 | /* |
@@ -568,54 +245,13 @@ static int __init acpi_table_get_sdt(struct acpi_table_rsdp *rsdp) | |||
568 | * | 245 | * |
569 | * find RSDP, find and checksum SDT/XSDT. | 246 | * find RSDP, find and checksum SDT/XSDT. |
570 | * checksum all tables, print SDT/XSDT | 247 | * checksum all tables, print SDT/XSDT |
571 | * | 248 | * |
572 | * result: sdt_entry[] is initialized | 249 | * result: sdt_entry[] is initialized |
573 | */ | 250 | */ |
574 | 251 | ||
252 | |||
575 | int __init acpi_table_init(void) | 253 | int __init acpi_table_init(void) |
576 | { | 254 | { |
577 | struct acpi_table_rsdp *rsdp = NULL; | 255 | acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); |
578 | unsigned long rsdp_phys = 0; | ||
579 | int result = 0; | ||
580 | |||
581 | /* Locate and map the Root System Description Table (RSDP) */ | ||
582 | |||
583 | rsdp_phys = acpi_find_rsdp(); | ||
584 | if (!rsdp_phys) { | ||
585 | printk(KERN_ERR PREFIX "Unable to locate RSDP\n"); | ||
586 | return -ENODEV; | ||
587 | } | ||
588 | |||
589 | rsdp = (struct acpi_table_rsdp *)__acpi_map_table(rsdp_phys, | ||
590 | sizeof(struct acpi_table_rsdp)); | ||
591 | if (!rsdp) { | ||
592 | printk(KERN_WARNING PREFIX "Unable to map RSDP\n"); | ||
593 | return -ENODEV; | ||
594 | } | ||
595 | |||
596 | printk(KERN_DEBUG PREFIX | ||
597 | "RSDP (v%3.3d %6.6s ) @ 0x%p\n", | ||
598 | rsdp->revision, rsdp->oem_id, (void *)rsdp_phys); | ||
599 | |||
600 | if (rsdp->revision < 2) | ||
601 | result = | ||
602 | acpi_table_compute_checksum(rsdp, | ||
603 | sizeof(struct acpi_table_rsdp)); | ||
604 | else | ||
605 | result = | ||
606 | acpi_table_compute_checksum(rsdp, | ||
607 | ((struct acpi20_table_rsdp *) | ||
608 | rsdp)->length); | ||
609 | |||
610 | if (result) { | ||
611 | printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); | ||
612 | return -ENODEV; | ||
613 | } | ||
614 | |||
615 | /* Locate and map the System Description table (RSDT/XSDT) */ | ||
616 | |||
617 | if (acpi_table_get_sdt(rsdp)) | ||
618 | return -ENODEV; | ||
619 | |||
620 | return 0; | 256 | return 0; |
621 | } | 257 | } |
diff --git a/drivers/acpi/tables/Makefile b/drivers/acpi/tables/Makefile index aa4c69594d97..0a7d7afac255 100644 --- a/drivers/acpi/tables/Makefile +++ b/drivers/acpi/tables/Makefile | |||
@@ -2,7 +2,6 @@ | |||
2 | # Makefile for all Linux ACPI interpreter subdirectories | 2 | # Makefile for all Linux ACPI interpreter subdirectories |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := tbconvrt.o tbget.o tbrsdt.o tbxface.o \ | 5 | obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o |
6 | tbgetall.o tbinstal.o tbutils.o tbxfroot.o | ||
7 | 6 | ||
8 | EXTRA_CFLAGS += $(ACPI_CFLAGS) | 7 | EXTRA_CFLAGS += $(ACPI_CFLAGS) |
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c deleted file mode 100644 index d697fcb35d52..000000000000 --- a/drivers/acpi/tables/tbconvrt.c +++ /dev/null | |||
@@ -1,622 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbconvrt - ACPI Table conversion utilities | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbconvrt") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | static void | ||
52 | acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, | ||
53 | u8 register_bit_width, | ||
54 | acpi_physical_address address); | ||
55 | |||
56 | static void | ||
57 | acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, | ||
58 | struct fadt_descriptor_rev1 *original_fadt); | ||
59 | |||
60 | static void | ||
61 | acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, | ||
62 | struct fadt_descriptor *original_fadt); | ||
63 | |||
64 | u8 acpi_fadt_is_v1; | ||
65 | ACPI_EXPORT_SYMBOL(acpi_fadt_is_v1) | ||
66 | |||
67 | /******************************************************************************* | ||
68 | * | ||
69 | * FUNCTION: acpi_tb_get_table_count | ||
70 | * | ||
71 | * PARAMETERS: RSDP - Pointer to the RSDP | ||
72 | * RSDT - Pointer to the RSDT/XSDT | ||
73 | * | ||
74 | * RETURN: The number of tables pointed to by the RSDT or XSDT. | ||
75 | * | ||
76 | * DESCRIPTION: Calculate the number of tables. Automatically handles either | ||
77 | * an RSDT or XSDT. | ||
78 | * | ||
79 | ******************************************************************************/ | ||
80 | |||
81 | u32 | ||
82 | acpi_tb_get_table_count(struct rsdp_descriptor *RSDP, | ||
83 | struct acpi_table_header *RSDT) | ||
84 | { | ||
85 | u32 pointer_size; | ||
86 | |||
87 | ACPI_FUNCTION_ENTRY(); | ||
88 | |||
89 | /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ | ||
90 | |||
91 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
92 | pointer_size = sizeof(u32); | ||
93 | } else { | ||
94 | pointer_size = sizeof(u64); | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Determine the number of tables pointed to by the RSDT/XSDT. | ||
99 | * This is defined by the ACPI Specification to be the number of | ||
100 | * pointers contained within the RSDT/XSDT. The size of the pointers | ||
101 | * is architecture-dependent. | ||
102 | */ | ||
103 | return ((RSDT->length - | ||
104 | sizeof(struct acpi_table_header)) / pointer_size); | ||
105 | } | ||
106 | |||
107 | /******************************************************************************* | ||
108 | * | ||
109 | * FUNCTION: acpi_tb_convert_to_xsdt | ||
110 | * | ||
111 | * PARAMETERS: table_info - Info about the RSDT | ||
112 | * | ||
113 | * RETURN: Status | ||
114 | * | ||
115 | * DESCRIPTION: Convert an RSDT to an XSDT (internal common format) | ||
116 | * | ||
117 | ******************************************************************************/ | ||
118 | |||
119 | acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info) | ||
120 | { | ||
121 | acpi_size table_size; | ||
122 | u32 i; | ||
123 | struct xsdt_descriptor *new_table; | ||
124 | |||
125 | ACPI_FUNCTION_ENTRY(); | ||
126 | |||
127 | /* Compute size of the converted XSDT */ | ||
128 | |||
129 | table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof(u64)) + | ||
130 | sizeof(struct acpi_table_header); | ||
131 | |||
132 | /* Allocate an XSDT */ | ||
133 | |||
134 | new_table = ACPI_ALLOCATE_ZEROED(table_size); | ||
135 | if (!new_table) { | ||
136 | return (AE_NO_MEMORY); | ||
137 | } | ||
138 | |||
139 | /* Copy the header and set the length */ | ||
140 | |||
141 | ACPI_MEMCPY(new_table, table_info->pointer, | ||
142 | sizeof(struct acpi_table_header)); | ||
143 | new_table->length = (u32) table_size; | ||
144 | |||
145 | /* Copy the table pointers */ | ||
146 | |||
147 | for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { | ||
148 | |||
149 | /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ | ||
150 | |||
151 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
152 | ACPI_STORE_ADDRESS(new_table->table_offset_entry[i], | ||
153 | (ACPI_CAST_PTR | ||
154 | (struct rsdt_descriptor, | ||
155 | table_info->pointer))-> | ||
156 | table_offset_entry[i]); | ||
157 | } else { | ||
158 | new_table->table_offset_entry[i] = | ||
159 | (ACPI_CAST_PTR(struct xsdt_descriptor, | ||
160 | table_info->pointer))-> | ||
161 | table_offset_entry[i]; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | /* Delete the original table (either mapped or in a buffer) */ | ||
166 | |||
167 | acpi_tb_delete_single_table(table_info); | ||
168 | |||
169 | /* Point the table descriptor to the new table */ | ||
170 | |||
171 | table_info->pointer = | ||
172 | ACPI_CAST_PTR(struct acpi_table_header, new_table); | ||
173 | table_info->length = table_size; | ||
174 | table_info->allocation = ACPI_MEM_ALLOCATED; | ||
175 | |||
176 | return (AE_OK); | ||
177 | } | ||
178 | |||
179 | /******************************************************************************* | ||
180 | * | ||
181 | * FUNCTION: acpi_tb_init_generic_address | ||
182 | * | ||
183 | * PARAMETERS: new_gas_struct - GAS struct to be initialized | ||
184 | * register_bit_width - Width of this register | ||
185 | * Address - Address of the register | ||
186 | * | ||
187 | * RETURN: None | ||
188 | * | ||
189 | * DESCRIPTION: Initialize a GAS structure. | ||
190 | * | ||
191 | ******************************************************************************/ | ||
192 | |||
193 | static void | ||
194 | acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, | ||
195 | u8 register_bit_width, | ||
196 | acpi_physical_address address) | ||
197 | { | ||
198 | |||
199 | ACPI_STORE_ADDRESS(new_gas_struct->address, address); | ||
200 | |||
201 | new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; | ||
202 | new_gas_struct->register_bit_width = register_bit_width; | ||
203 | new_gas_struct->register_bit_offset = 0; | ||
204 | new_gas_struct->access_width = 0; | ||
205 | } | ||
206 | |||
207 | /******************************************************************************* | ||
208 | * | ||
209 | * FUNCTION: acpi_tb_convert_fadt1 | ||
210 | * | ||
211 | * PARAMETERS: local_fadt - Pointer to new FADT | ||
212 | * original_fadt - Pointer to old FADT | ||
213 | * | ||
214 | * RETURN: None, populates local_fadt | ||
215 | * | ||
216 | * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format | ||
217 | * | ||
218 | ******************************************************************************/ | ||
219 | |||
220 | static void | ||
221 | acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, | ||
222 | struct fadt_descriptor_rev1 *original_fadt) | ||
223 | { | ||
224 | |||
225 | /* ACPI 1.0 FACS */ | ||
226 | /* The BIOS stored FADT should agree with Revision 1.0 */ | ||
227 | acpi_fadt_is_v1 = 1; | ||
228 | |||
229 | /* | ||
230 | * Copy the table header and the common part of the tables. | ||
231 | * | ||
232 | * The 2.0 table is an extension of the 1.0 table, so the entire 1.0 | ||
233 | * table can be copied first, then expand some fields to 64 bits. | ||
234 | */ | ||
235 | ACPI_MEMCPY(local_fadt, original_fadt, | ||
236 | sizeof(struct fadt_descriptor_rev1)); | ||
237 | |||
238 | /* Convert table pointers to 64-bit fields */ | ||
239 | |||
240 | ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl, | ||
241 | local_fadt->V1_firmware_ctrl); | ||
242 | ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt); | ||
243 | |||
244 | /* | ||
245 | * System Interrupt Model isn't used in ACPI 2.0 | ||
246 | * (local_fadt->Reserved1 = 0;) | ||
247 | */ | ||
248 | |||
249 | /* | ||
250 | * This field is set by the OEM to convey the preferred power management | ||
251 | * profile to OSPM. It doesn't have any 1.0 equivalence. Since we don't | ||
252 | * know what kind of 32-bit system this is, we will use "unspecified". | ||
253 | */ | ||
254 | local_fadt->prefer_PM_profile = PM_UNSPECIFIED; | ||
255 | |||
256 | /* | ||
257 | * Processor Performance State Control. This is the value OSPM writes to | ||
258 | * the SMI_CMD register to assume processor performance state control | ||
259 | * responsibility. There isn't any equivalence in 1.0, but as many 1.x | ||
260 | * ACPI tables contain _PCT and _PSS we also keep this value, unless | ||
261 | * acpi_strict is set. | ||
262 | */ | ||
263 | if (acpi_strict) | ||
264 | local_fadt->pstate_cnt = 0; | ||
265 | |||
266 | /* | ||
267 | * Support for the _CST object and C States change notification. | ||
268 | * This data item hasn't any 1.0 equivalence so leave it zero. | ||
269 | */ | ||
270 | local_fadt->cst_cnt = 0; | ||
271 | |||
272 | /* | ||
273 | * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0. | ||
274 | * It primarily adds the FADT reset mechanism. | ||
275 | */ | ||
276 | if ((original_fadt->revision == 2) && | ||
277 | (original_fadt->length == | ||
278 | sizeof(struct fadt_descriptor_rev2_minus))) { | ||
279 | /* | ||
280 | * Grab the entire generic address struct, plus the 1-byte reset value | ||
281 | * that immediately follows. | ||
282 | */ | ||
283 | ACPI_MEMCPY(&local_fadt->reset_register, | ||
284 | &(ACPI_CAST_PTR(struct fadt_descriptor_rev2_minus, | ||
285 | original_fadt))->reset_register, | ||
286 | sizeof(struct acpi_generic_address) + 1); | ||
287 | } else { | ||
288 | /* | ||
289 | * Since there isn't any equivalence in 1.0 and since it is highly | ||
290 | * likely that a 1.0 system has legacy support. | ||
291 | */ | ||
292 | local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES; | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * Convert the V1.0 block addresses to V2.0 GAS structures | ||
297 | */ | ||
298 | acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk, | ||
299 | local_fadt->pm1_evt_len, | ||
300 | (acpi_physical_address) local_fadt-> | ||
301 | V1_pm1a_evt_blk); | ||
302 | acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk, | ||
303 | local_fadt->pm1_evt_len, | ||
304 | (acpi_physical_address) local_fadt-> | ||
305 | V1_pm1b_evt_blk); | ||
306 | acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk, | ||
307 | local_fadt->pm1_cnt_len, | ||
308 | (acpi_physical_address) local_fadt-> | ||
309 | V1_pm1a_cnt_blk); | ||
310 | acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk, | ||
311 | local_fadt->pm1_cnt_len, | ||
312 | (acpi_physical_address) local_fadt-> | ||
313 | V1_pm1b_cnt_blk); | ||
314 | acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk, | ||
315 | local_fadt->pm2_cnt_len, | ||
316 | (acpi_physical_address) local_fadt-> | ||
317 | V1_pm2_cnt_blk); | ||
318 | acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk, | ||
319 | local_fadt->pm_tm_len, | ||
320 | (acpi_physical_address) local_fadt-> | ||
321 | V1_pm_tmr_blk); | ||
322 | acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, 0, | ||
323 | (acpi_physical_address) local_fadt-> | ||
324 | V1_gpe0_blk); | ||
325 | acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, 0, | ||
326 | (acpi_physical_address) local_fadt-> | ||
327 | V1_gpe1_blk); | ||
328 | |||
329 | /* Create separate GAS structs for the PM1 Enable registers */ | ||
330 | |||
331 | acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, | ||
332 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
333 | pm1_evt_len), | ||
334 | (acpi_physical_address) | ||
335 | (local_fadt->xpm1a_evt_blk.address + | ||
336 | ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len))); | ||
337 | |||
338 | /* PM1B is optional; leave null if not present */ | ||
339 | |||
340 | if (local_fadt->xpm1b_evt_blk.address) { | ||
341 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, | ||
342 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
343 | pm1_evt_len), | ||
344 | (acpi_physical_address) | ||
345 | (local_fadt->xpm1b_evt_blk. | ||
346 | address + | ||
347 | ACPI_DIV_2(acpi_gbl_FADT-> | ||
348 | pm1_evt_len))); | ||
349 | } | ||
350 | } | ||
351 | |||
352 | /******************************************************************************* | ||
353 | * | ||
354 | * FUNCTION: acpi_tb_convert_fadt2 | ||
355 | * | ||
356 | * PARAMETERS: local_fadt - Pointer to new FADT | ||
357 | * original_fadt - Pointer to old FADT | ||
358 | * | ||
359 | * RETURN: None, populates local_fadt | ||
360 | * | ||
361 | * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format. | ||
362 | * Handles optional "X" fields. | ||
363 | * | ||
364 | ******************************************************************************/ | ||
365 | |||
366 | static void | ||
367 | acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, | ||
368 | struct fadt_descriptor *original_fadt) | ||
369 | { | ||
370 | |||
371 | /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ | ||
372 | |||
373 | ACPI_MEMCPY(local_fadt, original_fadt, sizeof(struct fadt_descriptor)); | ||
374 | |||
375 | /* | ||
376 | * "X" fields are optional extensions to the original V1.0 fields, so | ||
377 | * we must selectively expand V1.0 fields if the corresponding X field | ||
378 | * is zero. | ||
379 | */ | ||
380 | if (!(local_fadt->xfirmware_ctrl)) { | ||
381 | ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl, | ||
382 | local_fadt->V1_firmware_ctrl); | ||
383 | } | ||
384 | |||
385 | if (!(local_fadt->Xdsdt)) { | ||
386 | ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt); | ||
387 | } | ||
388 | |||
389 | if (!(local_fadt->xpm1a_evt_blk.address)) { | ||
390 | acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk, | ||
391 | local_fadt->pm1_evt_len, | ||
392 | (acpi_physical_address) | ||
393 | local_fadt->V1_pm1a_evt_blk); | ||
394 | } | ||
395 | |||
396 | if (!(local_fadt->xpm1b_evt_blk.address)) { | ||
397 | acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk, | ||
398 | local_fadt->pm1_evt_len, | ||
399 | (acpi_physical_address) | ||
400 | local_fadt->V1_pm1b_evt_blk); | ||
401 | } | ||
402 | |||
403 | if (!(local_fadt->xpm1a_cnt_blk.address)) { | ||
404 | acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk, | ||
405 | local_fadt->pm1_cnt_len, | ||
406 | (acpi_physical_address) | ||
407 | local_fadt->V1_pm1a_cnt_blk); | ||
408 | } | ||
409 | |||
410 | if (!(local_fadt->xpm1b_cnt_blk.address)) { | ||
411 | acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk, | ||
412 | local_fadt->pm1_cnt_len, | ||
413 | (acpi_physical_address) | ||
414 | local_fadt->V1_pm1b_cnt_blk); | ||
415 | } | ||
416 | |||
417 | if (!(local_fadt->xpm2_cnt_blk.address)) { | ||
418 | acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk, | ||
419 | local_fadt->pm2_cnt_len, | ||
420 | (acpi_physical_address) | ||
421 | local_fadt->V1_pm2_cnt_blk); | ||
422 | } | ||
423 | |||
424 | if (!(local_fadt->xpm_tmr_blk.address)) { | ||
425 | acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk, | ||
426 | local_fadt->pm_tm_len, | ||
427 | (acpi_physical_address) | ||
428 | local_fadt->V1_pm_tmr_blk); | ||
429 | } | ||
430 | |||
431 | if (!(local_fadt->xgpe0_blk.address)) { | ||
432 | acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, | ||
433 | 0, | ||
434 | (acpi_physical_address) | ||
435 | local_fadt->V1_gpe0_blk); | ||
436 | } | ||
437 | |||
438 | if (!(local_fadt->xgpe1_blk.address)) { | ||
439 | acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, | ||
440 | 0, | ||
441 | (acpi_physical_address) | ||
442 | local_fadt->V1_gpe1_blk); | ||
443 | } | ||
444 | |||
445 | /* Create separate GAS structs for the PM1 Enable registers */ | ||
446 | |||
447 | acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, | ||
448 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
449 | pm1_evt_len), | ||
450 | (acpi_physical_address) | ||
451 | (local_fadt->xpm1a_evt_blk.address + | ||
452 | ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len))); | ||
453 | |||
454 | acpi_gbl_xpm1a_enable.address_space_id = | ||
455 | local_fadt->xpm1a_evt_blk.address_space_id; | ||
456 | |||
457 | /* PM1B is optional; leave null if not present */ | ||
458 | |||
459 | if (local_fadt->xpm1b_evt_blk.address) { | ||
460 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, | ||
461 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
462 | pm1_evt_len), | ||
463 | (acpi_physical_address) | ||
464 | (local_fadt->xpm1b_evt_blk. | ||
465 | address + | ||
466 | ACPI_DIV_2(acpi_gbl_FADT-> | ||
467 | pm1_evt_len))); | ||
468 | |||
469 | acpi_gbl_xpm1b_enable.address_space_id = | ||
470 | local_fadt->xpm1b_evt_blk.address_space_id; | ||
471 | } | ||
472 | } | ||
473 | |||
474 | /******************************************************************************* | ||
475 | * | ||
476 | * FUNCTION: acpi_tb_convert_table_fadt | ||
477 | * | ||
478 | * PARAMETERS: None | ||
479 | * | ||
480 | * RETURN: Status | ||
481 | * | ||
482 | * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local | ||
483 | * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply | ||
484 | * copied to the local FADT. The ACPI CA software uses this | ||
485 | * local FADT. Thus a significant amount of special #ifdef | ||
486 | * type codeing is saved. | ||
487 | * | ||
488 | ******************************************************************************/ | ||
489 | |||
490 | acpi_status acpi_tb_convert_table_fadt(void) | ||
491 | { | ||
492 | struct fadt_descriptor *local_fadt; | ||
493 | struct acpi_table_desc *table_desc; | ||
494 | |||
495 | ACPI_FUNCTION_TRACE(tb_convert_table_fadt); | ||
496 | |||
497 | /* | ||
498 | * acpi_gbl_FADT is valid. Validate the FADT length. The table must be | ||
499 | * at least as long as the version 1.0 FADT | ||
500 | */ | ||
501 | if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev1)) { | ||
502 | ACPI_ERROR((AE_INFO, "FADT is invalid, too short: 0x%X", | ||
503 | acpi_gbl_FADT->length)); | ||
504 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
505 | } | ||
506 | |||
507 | /* Allocate buffer for the ACPI 2.0(+) FADT */ | ||
508 | |||
509 | local_fadt = ACPI_ALLOCATE_ZEROED(sizeof(struct fadt_descriptor)); | ||
510 | if (!local_fadt) { | ||
511 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
512 | } | ||
513 | |||
514 | if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) { | ||
515 | if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor)) { | ||
516 | |||
517 | /* Length is too short to be a V2.0 table */ | ||
518 | |||
519 | ACPI_WARNING((AE_INFO, | ||
520 | "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table", | ||
521 | acpi_gbl_FADT->length, | ||
522 | acpi_gbl_FADT->revision)); | ||
523 | |||
524 | acpi_tb_convert_fadt1(local_fadt, | ||
525 | (void *)acpi_gbl_FADT); | ||
526 | } else { | ||
527 | /* Valid V2.0 table */ | ||
528 | |||
529 | acpi_tb_convert_fadt2(local_fadt, acpi_gbl_FADT); | ||
530 | } | ||
531 | } else { | ||
532 | /* Valid V1.0 table */ | ||
533 | |||
534 | acpi_tb_convert_fadt1(local_fadt, (void *)acpi_gbl_FADT); | ||
535 | } | ||
536 | |||
537 | /* Global FADT pointer will point to the new common V2.0 FADT */ | ||
538 | |||
539 | acpi_gbl_FADT = local_fadt; | ||
540 | acpi_gbl_FADT->length = sizeof(struct fadt_descriptor); | ||
541 | |||
542 | /* Free the original table */ | ||
543 | |||
544 | table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_FADT].next; | ||
545 | acpi_tb_delete_single_table(table_desc); | ||
546 | |||
547 | /* Install the new table */ | ||
548 | |||
549 | table_desc->pointer = | ||
550 | ACPI_CAST_PTR(struct acpi_table_header, acpi_gbl_FADT); | ||
551 | table_desc->allocation = ACPI_MEM_ALLOCATED; | ||
552 | table_desc->length = sizeof(struct fadt_descriptor); | ||
553 | |||
554 | /* Dump the entire FADT */ | ||
555 | |||
556 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
557 | "Hex dump of common internal FADT, size %d (%X)\n", | ||
558 | acpi_gbl_FADT->length, acpi_gbl_FADT->length)); | ||
559 | |||
560 | ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_FADT), | ||
561 | acpi_gbl_FADT->length); | ||
562 | |||
563 | return_ACPI_STATUS(AE_OK); | ||
564 | } | ||
565 | |||
566 | /******************************************************************************* | ||
567 | * | ||
568 | * FUNCTION: acpi_tb_build_common_facs | ||
569 | * | ||
570 | * PARAMETERS: table_info - Info for currently installed FACS | ||
571 | * | ||
572 | * RETURN: Status | ||
573 | * | ||
574 | * DESCRIPTION: Convert ACPI 1.0 and ACPI 2.0 FACS to a common internal | ||
575 | * table format. | ||
576 | * | ||
577 | ******************************************************************************/ | ||
578 | |||
579 | acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info) | ||
580 | { | ||
581 | |||
582 | ACPI_FUNCTION_TRACE(tb_build_common_facs); | ||
583 | |||
584 | /* Absolute minimum length is 24, but the ACPI spec says 64 */ | ||
585 | |||
586 | if (acpi_gbl_FACS->length < 24) { | ||
587 | ACPI_ERROR((AE_INFO, "Invalid FACS table length: 0x%X", | ||
588 | acpi_gbl_FACS->length)); | ||
589 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
590 | } | ||
591 | |||
592 | if (acpi_gbl_FACS->length < 64) { | ||
593 | ACPI_WARNING((AE_INFO, | ||
594 | "FACS is shorter than the ACPI specification allows: 0x%X, using anyway", | ||
595 | acpi_gbl_FACS->length)); | ||
596 | } | ||
597 | |||
598 | /* Copy fields to the new FACS */ | ||
599 | |||
600 | acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock); | ||
601 | |||
602 | if ((acpi_gbl_RSDP->revision < 2) || | ||
603 | (acpi_gbl_FACS->length < 32) || | ||
604 | (!(acpi_gbl_FACS->xfirmware_waking_vector))) { | ||
605 | |||
606 | /* ACPI 1.0 FACS or short table or optional X_ field is zero */ | ||
607 | |||
608 | acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR(u64, | ||
609 | & | ||
610 | (acpi_gbl_FACS-> | ||
611 | firmware_waking_vector)); | ||
612 | acpi_gbl_common_fACS.vector_width = 32; | ||
613 | } else { | ||
614 | /* ACPI 2.0 FACS with valid X_ field */ | ||
615 | |||
616 | acpi_gbl_common_fACS.firmware_waking_vector = | ||
617 | &acpi_gbl_FACS->xfirmware_waking_vector; | ||
618 | acpi_gbl_common_fACS.vector_width = 64; | ||
619 | } | ||
620 | |||
621 | return_ACPI_STATUS(AE_OK); | ||
622 | } | ||
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c new file mode 100644 index 000000000000..807c7116e94b --- /dev/null +++ b/drivers/acpi/tables/tbfadt.c | |||
@@ -0,0 +1,434 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbfadt - FADT table utilities | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbfadt") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | static void inline | ||
52 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | ||
53 | u8 bit_width, u64 address); | ||
54 | |||
55 | static void acpi_tb_convert_fadt(void); | ||
56 | |||
57 | static void acpi_tb_validate_fadt(void); | ||
58 | |||
59 | /* Table for conversion of FADT to common internal format and FADT validation */ | ||
60 | |||
61 | typedef struct acpi_fadt_info { | ||
62 | char *name; | ||
63 | u8 target; | ||
64 | u8 source; | ||
65 | u8 length; | ||
66 | u8 type; | ||
67 | |||
68 | } acpi_fadt_info; | ||
69 | |||
70 | #define ACPI_FADT_REQUIRED 1 | ||
71 | #define ACPI_FADT_SEPARATE_LENGTH 2 | ||
72 | |||
73 | static struct acpi_fadt_info fadt_info_table[] = { | ||
74 | {"Pm1aEventBlock", ACPI_FADT_OFFSET(xpm1a_event_block), | ||
75 | ACPI_FADT_OFFSET(pm1a_event_block), | ||
76 | ACPI_FADT_OFFSET(pm1_event_length), ACPI_FADT_REQUIRED}, | ||
77 | |||
78 | {"Pm1bEventBlock", ACPI_FADT_OFFSET(xpm1b_event_block), | ||
79 | ACPI_FADT_OFFSET(pm1b_event_block), | ||
80 | ACPI_FADT_OFFSET(pm1_event_length), 0}, | ||
81 | |||
82 | {"Pm1aControlBlock", ACPI_FADT_OFFSET(xpm1a_control_block), | ||
83 | ACPI_FADT_OFFSET(pm1a_control_block), | ||
84 | ACPI_FADT_OFFSET(pm1_control_length), ACPI_FADT_REQUIRED}, | ||
85 | |||
86 | {"Pm1bControlBlock", ACPI_FADT_OFFSET(xpm1b_control_block), | ||
87 | ACPI_FADT_OFFSET(pm1b_control_block), | ||
88 | ACPI_FADT_OFFSET(pm1_control_length), 0}, | ||
89 | |||
90 | {"Pm2ControlBlock", ACPI_FADT_OFFSET(xpm2_control_block), | ||
91 | ACPI_FADT_OFFSET(pm2_control_block), | ||
92 | ACPI_FADT_OFFSET(pm2_control_length), ACPI_FADT_SEPARATE_LENGTH}, | ||
93 | |||
94 | {"PmTimerBlock", ACPI_FADT_OFFSET(xpm_timer_block), | ||
95 | ACPI_FADT_OFFSET(pm_timer_block), | ||
96 | ACPI_FADT_OFFSET(pm_timer_length), ACPI_FADT_REQUIRED}, | ||
97 | |||
98 | {"Gpe0Block", ACPI_FADT_OFFSET(xgpe0_block), | ||
99 | ACPI_FADT_OFFSET(gpe0_block), | ||
100 | ACPI_FADT_OFFSET(gpe0_block_length), ACPI_FADT_SEPARATE_LENGTH}, | ||
101 | |||
102 | {"Gpe1Block", ACPI_FADT_OFFSET(xgpe1_block), | ||
103 | ACPI_FADT_OFFSET(gpe1_block), | ||
104 | ACPI_FADT_OFFSET(gpe1_block_length), ACPI_FADT_SEPARATE_LENGTH} | ||
105 | }; | ||
106 | |||
107 | #define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) | ||
108 | |||
109 | /******************************************************************************* | ||
110 | * | ||
111 | * FUNCTION: acpi_tb_init_generic_address | ||
112 | * | ||
113 | * PARAMETERS: generic_address - GAS struct to be initialized | ||
114 | * bit_width - Width of this register | ||
115 | * Address - Address of the register | ||
116 | * | ||
117 | * RETURN: None | ||
118 | * | ||
119 | * DESCRIPTION: Initialize a Generic Address Structure (GAS) | ||
120 | * See the ACPI specification for a full description and | ||
121 | * definition of this structure. | ||
122 | * | ||
123 | ******************************************************************************/ | ||
124 | |||
125 | static void inline | ||
126 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | ||
127 | u8 bit_width, u64 address) | ||
128 | { | ||
129 | |||
130 | /* | ||
131 | * The 64-bit Address field is non-aligned in the byte packed | ||
132 | * GAS struct. | ||
133 | */ | ||
134 | ACPI_MOVE_64_TO_64(&generic_address->address, &address); | ||
135 | |||
136 | /* All other fields are byte-wide */ | ||
137 | |||
138 | generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO; | ||
139 | generic_address->bit_width = bit_width; | ||
140 | generic_address->bit_offset = 0; | ||
141 | generic_address->access_width = 0; | ||
142 | } | ||
143 | |||
144 | /******************************************************************************* | ||
145 | * | ||
146 | * FUNCTION: acpi_tb_parse_fadt | ||
147 | * | ||
148 | * PARAMETERS: table_index - Index for the FADT | ||
149 | * Flags - Flags | ||
150 | * | ||
151 | * RETURN: None | ||
152 | * | ||
153 | * DESCRIPTION: Initialize the FADT, DSDT and FACS tables | ||
154 | * (FADT contains the addresses of the DSDT and FACS) | ||
155 | * | ||
156 | ******************************************************************************/ | ||
157 | |||
158 | void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags) | ||
159 | { | ||
160 | u32 length; | ||
161 | struct acpi_table_header *table; | ||
162 | |||
163 | /* | ||
164 | * The FADT has multiple versions with different lengths, | ||
165 | * and it contains pointers to both the DSDT and FACS tables. | ||
166 | * | ||
167 | * Get a local copy of the FADT and convert it to a common format | ||
168 | * Map entire FADT, assumed to be smaller than one page. | ||
169 | */ | ||
170 | length = acpi_gbl_root_table_list.tables[table_index].length; | ||
171 | |||
172 | table = | ||
173 | acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index]. | ||
174 | address, length); | ||
175 | if (!table) { | ||
176 | return; | ||
177 | } | ||
178 | |||
179 | /* | ||
180 | * Validate the FADT checksum before we copy the table. Ignore | ||
181 | * checksum error as we want to try to get the DSDT and FACS. | ||
182 | */ | ||
183 | (void)acpi_tb_verify_checksum(table, length); | ||
184 | |||
185 | /* Obtain a local copy of the FADT in common ACPI 2.0+ format */ | ||
186 | |||
187 | acpi_tb_create_local_fadt(table, length); | ||
188 | |||
189 | /* All done with the real FADT, unmap it */ | ||
190 | |||
191 | acpi_os_unmap_memory(table, length); | ||
192 | |||
193 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ | ||
194 | |||
195 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, | ||
196 | flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); | ||
197 | |||
198 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, | ||
199 | flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); | ||
200 | } | ||
201 | |||
202 | /******************************************************************************* | ||
203 | * | ||
204 | * FUNCTION: acpi_tb_create_local_fadt | ||
205 | * | ||
206 | * PARAMETERS: Table - Pointer to BIOS FADT | ||
207 | * Length - Length of the table | ||
208 | * | ||
209 | * RETURN: None | ||
210 | * | ||
211 | * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. | ||
212 | * Performs validation on some important FADT fields. | ||
213 | * | ||
214 | ******************************************************************************/ | ||
215 | |||
216 | void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | ||
217 | { | ||
218 | |||
219 | /* | ||
220 | * Check if the FADT is larger than what we know about (ACPI 2.0 version). | ||
221 | * Truncate the table, but make some noise. | ||
222 | */ | ||
223 | if (length > sizeof(struct acpi_table_fadt)) { | ||
224 | ACPI_WARNING((AE_INFO, | ||
225 | "FADT (revision %u) is longer than ACPI 2.0 version, truncating length 0x%X to 0x%zX", | ||
226 | table->revision, (unsigned)length, | ||
227 | sizeof(struct acpi_table_fadt))); | ||
228 | } | ||
229 | |||
230 | /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ | ||
231 | |||
232 | ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); | ||
233 | |||
234 | ACPI_MEMCPY(&acpi_gbl_FADT, table, | ||
235 | ACPI_MIN(length, sizeof(struct acpi_table_fadt))); | ||
236 | |||
237 | /* | ||
238 | * 1) Convert the local copy of the FADT to the common internal format | ||
239 | * 2) Validate some of the important values within the FADT | ||
240 | */ | ||
241 | acpi_tb_convert_fadt(); | ||
242 | acpi_tb_validate_fadt(); | ||
243 | } | ||
244 | |||
245 | /******************************************************************************* | ||
246 | * | ||
247 | * FUNCTION: acpi_tb_convert_fadt | ||
248 | * | ||
249 | * PARAMETERS: None, uses acpi_gbl_FADT | ||
250 | * | ||
251 | * RETURN: None | ||
252 | * | ||
253 | * DESCRIPTION: Converts all versions of the FADT to a common internal format. | ||
254 | * -> Expand all 32-bit addresses to 64-bit. | ||
255 | * | ||
256 | * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), | ||
257 | * and must contain a copy of the actual FADT. | ||
258 | * | ||
259 | * ACPICA will use the "X" fields of the FADT for all addresses. | ||
260 | * | ||
261 | * "X" fields are optional extensions to the original V1.0 fields. Even if | ||
262 | * they are present in the structure, they can be optionally not used by | ||
263 | * setting them to zero. Therefore, we must selectively expand V1.0 fields | ||
264 | * if the corresponding X field is zero. | ||
265 | * | ||
266 | * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding | ||
267 | * "X" fields. | ||
268 | * | ||
269 | * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by | ||
270 | * expanding the corresponding ACPI 1.0 field. | ||
271 | * | ||
272 | ******************************************************************************/ | ||
273 | |||
274 | static void acpi_tb_convert_fadt(void) | ||
275 | { | ||
276 | u8 pm1_register_length; | ||
277 | struct acpi_generic_address *target; | ||
278 | acpi_native_uint i; | ||
279 | |||
280 | /* Update the local FADT table header length */ | ||
281 | |||
282 | acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); | ||
283 | |||
284 | /* Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary */ | ||
285 | |||
286 | if (!acpi_gbl_FADT.Xfacs) { | ||
287 | acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; | ||
288 | } | ||
289 | |||
290 | if (!acpi_gbl_FADT.Xdsdt) { | ||
291 | acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address | ||
296 | * structures as necessary. | ||
297 | */ | ||
298 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | ||
299 | target = | ||
300 | ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, | ||
301 | fadt_info_table[i].target); | ||
302 | |||
303 | /* Expand only if the X target is null */ | ||
304 | |||
305 | if (!target->address) { | ||
306 | acpi_tb_init_generic_address(target, | ||
307 | *ACPI_ADD_PTR(u8, | ||
308 | &acpi_gbl_FADT, | ||
309 | fadt_info_table | ||
310 | [i].length), | ||
311 | (u64) * ACPI_ADD_PTR(u32, | ||
312 | &acpi_gbl_FADT, | ||
313 | fadt_info_table | ||
314 | [i]. | ||
315 | source)); | ||
316 | } | ||
317 | } | ||
318 | |||
319 | /* | ||
320 | * Calculate separate GAS structs for the PM1 Enable registers. | ||
321 | * These addresses do not appear (directly) in the FADT, so it is | ||
322 | * useful to calculate them once, here. | ||
323 | * | ||
324 | * The PM event blocks are split into two register blocks, first is the | ||
325 | * PM Status Register block, followed immediately by the PM Enable Register | ||
326 | * block. Each is of length (pm1_event_length/2) | ||
327 | */ | ||
328 | pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length); | ||
329 | |||
330 | /* The PM1A register block is required */ | ||
331 | |||
332 | acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, | ||
333 | pm1_register_length, | ||
334 | (acpi_gbl_FADT.xpm1a_event_block.address + | ||
335 | pm1_register_length)); | ||
336 | /* Don't forget to copy space_id of the GAS */ | ||
337 | acpi_gbl_xpm1a_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id; | ||
338 | |||
339 | /* The PM1B register block is optional, ignore if not present */ | ||
340 | |||
341 | if (acpi_gbl_FADT.xpm1b_event_block.address) { | ||
342 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, | ||
343 | pm1_register_length, | ||
344 | (acpi_gbl_FADT.xpm1b_event_block. | ||
345 | address + pm1_register_length)); | ||
346 | /* Don't forget to copy space_id of the GAS */ | ||
347 | acpi_gbl_xpm1b_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id; | ||
348 | |||
349 | } | ||
350 | } | ||
351 | |||
352 | /****************************************************************************** | ||
353 | * | ||
354 | * FUNCTION: acpi_tb_validate_fadt | ||
355 | * | ||
356 | * PARAMETERS: Table - Pointer to the FADT to be validated | ||
357 | * | ||
358 | * RETURN: None | ||
359 | * | ||
360 | * DESCRIPTION: Validate various important fields within the FADT. If a problem | ||
361 | * is found, issue a message, but no status is returned. | ||
362 | * Used by both the table manager and the disassembler. | ||
363 | * | ||
364 | * Possible additional checks: | ||
365 | * (acpi_gbl_FADT.pm1_event_length >= 4) | ||
366 | * (acpi_gbl_FADT.pm1_control_length >= 2) | ||
367 | * (acpi_gbl_FADT.pm_timer_length >= 4) | ||
368 | * Gpe block lengths must be multiple of 2 | ||
369 | * | ||
370 | ******************************************************************************/ | ||
371 | |||
372 | static void acpi_tb_validate_fadt(void) | ||
373 | { | ||
374 | u32 *address32; | ||
375 | struct acpi_generic_address *address64; | ||
376 | u8 length; | ||
377 | acpi_native_uint i; | ||
378 | |||
379 | /* Examine all of the 64-bit extended address fields (X fields) */ | ||
380 | |||
381 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | ||
382 | |||
383 | /* Generate pointers to the 32-bit and 64-bit addresses and get the length */ | ||
384 | |||
385 | address64 = | ||
386 | ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, | ||
387 | fadt_info_table[i].target); | ||
388 | address32 = | ||
389 | ACPI_ADD_PTR(u32, &acpi_gbl_FADT, | ||
390 | fadt_info_table[i].source); | ||
391 | length = | ||
392 | *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, | ||
393 | fadt_info_table[i].length); | ||
394 | |||
395 | if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { | ||
396 | /* | ||
397 | * Field is required (Pm1a_event, Pm1a_control, pm_timer). | ||
398 | * Both the address and length must be non-zero. | ||
399 | */ | ||
400 | if (!address64->address || !length) { | ||
401 | ACPI_ERROR((AE_INFO, | ||
402 | "Required field \"%s\" has zero address and/or length: %8.8X%8.8X/%X", | ||
403 | fadt_info_table[i].name, | ||
404 | ACPI_FORMAT_UINT64(address64-> | ||
405 | address), | ||
406 | length)); | ||
407 | } | ||
408 | } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) { | ||
409 | /* | ||
410 | * Field is optional (PM2Control, GPE0, GPE1) AND has its own | ||
411 | * length field. If present, both the address and length must be valid. | ||
412 | */ | ||
413 | if ((address64->address && !length) | ||
414 | || (!address64->address && length)) { | ||
415 | ACPI_WARNING((AE_INFO, | ||
416 | "Optional field \"%s\" has zero address or length: %8.8X%8.8X/%X", | ||
417 | fadt_info_table[i].name, | ||
418 | ACPI_FORMAT_UINT64(address64-> | ||
419 | address), | ||
420 | length)); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | /* If both 32- and 64-bit addresses are valid (non-zero), they must match */ | ||
425 | |||
426 | if (address64->address && *address32 && | ||
427 | (address64->address != (u64) * address32)) { | ||
428 | ACPI_ERROR((AE_INFO, | ||
429 | "32/64X address mismatch in \"%s\": [%8.8X] [%8.8X%8.8X], using 64X", | ||
430 | fadt_info_table[i].name, *address32, | ||
431 | ACPI_FORMAT_UINT64(address64->address))); | ||
432 | } | ||
433 | } | ||
434 | } | ||
diff --git a/drivers/acpi/tables/tbfind.c b/drivers/acpi/tables/tbfind.c new file mode 100644 index 000000000000..058c064948e1 --- /dev/null +++ b/drivers/acpi/tables/tbfind.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbfind - find table | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbfind") | ||
49 | |||
50 | /******************************************************************************* | ||
51 | * | ||
52 | * FUNCTION: acpi_tb_find_table | ||
53 | * | ||
54 | * PARAMETERS: Signature - String with ACPI table signature | ||
55 | * oem_id - String with the table OEM ID | ||
56 | * oem_table_id - String with the OEM Table ID | ||
57 | * table_index - Where the table index is returned | ||
58 | * | ||
59 | * RETURN: Status and table index | ||
60 | * | ||
61 | * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the | ||
62 | * Signature, OEM ID and OEM Table ID. Returns an index that can | ||
63 | * be used to get the table header or entire table. | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | acpi_status | ||
67 | acpi_tb_find_table(char *signature, | ||
68 | char *oem_id, | ||
69 | char *oem_table_id, acpi_native_uint * table_index) | ||
70 | { | ||
71 | acpi_native_uint i; | ||
72 | acpi_status status; | ||
73 | |||
74 | ACPI_FUNCTION_TRACE(tb_find_table); | ||
75 | |||
76 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { | ||
77 | if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature), | ||
78 | signature, ACPI_NAME_SIZE)) { | ||
79 | |||
80 | /* Not the requested table */ | ||
81 | |||
82 | continue; | ||
83 | } | ||
84 | |||
85 | /* Table with matching signature has been found */ | ||
86 | |||
87 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | ||
88 | |||
89 | /* Table is not currently mapped, map it */ | ||
90 | |||
91 | status = | ||
92 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
93 | tables[i]); | ||
94 | if (ACPI_FAILURE(status)) { | ||
95 | return_ACPI_STATUS(status); | ||
96 | } | ||
97 | |||
98 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | ||
99 | continue; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /* Check for table match on all IDs */ | ||
104 | |||
105 | if (!ACPI_MEMCMP | ||
106 | (acpi_gbl_root_table_list.tables[i].pointer->signature, | ||
107 | signature, ACPI_NAME_SIZE) && (!oem_id[0] | ||
108 | || | ||
109 | !ACPI_MEMCMP | ||
110 | (acpi_gbl_root_table_list. | ||
111 | tables[i].pointer->oem_id, | ||
112 | oem_id, ACPI_OEM_ID_SIZE)) | ||
113 | && (!oem_table_id[0] | ||
114 | || !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i]. | ||
115 | pointer->oem_table_id, oem_table_id, | ||
116 | ACPI_OEM_TABLE_ID_SIZE))) { | ||
117 | *table_index = i; | ||
118 | |||
119 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
120 | "Found table [%4.4s]\n", signature)); | ||
121 | return_ACPI_STATUS(AE_OK); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
126 | } | ||
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c deleted file mode 100644 index 11e2d4454e05..000000000000 --- a/drivers/acpi/tables/tbget.c +++ /dev/null | |||
@@ -1,471 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbget - ACPI Table get* routines | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbget") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | static acpi_status | ||
52 | acpi_tb_get_this_table(struct acpi_pointer *address, | ||
53 | struct acpi_table_header *header, | ||
54 | struct acpi_table_desc *table_info); | ||
55 | |||
56 | static acpi_status | ||
57 | acpi_tb_table_override(struct acpi_table_header *header, | ||
58 | struct acpi_table_desc *table_info); | ||
59 | |||
60 | /******************************************************************************* | ||
61 | * | ||
62 | * FUNCTION: acpi_tb_get_table | ||
63 | * | ||
64 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
65 | * Logical or Physical | ||
66 | * table_info - Where table info is returned | ||
67 | * | ||
68 | * RETURN: None | ||
69 | * | ||
70 | * DESCRIPTION: Get entire table of unknown size. | ||
71 | * | ||
72 | ******************************************************************************/ | ||
73 | |||
74 | acpi_status | ||
75 | acpi_tb_get_table(struct acpi_pointer *address, | ||
76 | struct acpi_table_desc *table_info) | ||
77 | { | ||
78 | acpi_status status; | ||
79 | struct acpi_table_header header; | ||
80 | |||
81 | ACPI_FUNCTION_TRACE(tb_get_table); | ||
82 | |||
83 | /* Get the header in order to get signature and table size */ | ||
84 | |||
85 | status = acpi_tb_get_table_header(address, &header); | ||
86 | if (ACPI_FAILURE(status)) { | ||
87 | return_ACPI_STATUS(status); | ||
88 | } | ||
89 | |||
90 | /* Get the entire table */ | ||
91 | |||
92 | status = acpi_tb_get_table_body(address, &header, table_info); | ||
93 | if (ACPI_FAILURE(status)) { | ||
94 | ACPI_EXCEPTION((AE_INFO, status, | ||
95 | "Could not get ACPI table (size %X)", | ||
96 | header.length)); | ||
97 | return_ACPI_STATUS(status); | ||
98 | } | ||
99 | |||
100 | return_ACPI_STATUS(AE_OK); | ||
101 | } | ||
102 | |||
103 | /******************************************************************************* | ||
104 | * | ||
105 | * FUNCTION: acpi_tb_get_table_header | ||
106 | * | ||
107 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
108 | * Logical or Physical | ||
109 | * return_header - Where the table header is returned | ||
110 | * | ||
111 | * RETURN: Status | ||
112 | * | ||
113 | * DESCRIPTION: Get an ACPI table header. Works in both physical or virtual | ||
114 | * addressing mode. Works with both physical or logical pointers. | ||
115 | * Table is either copied or mapped, depending on the pointer | ||
116 | * type and mode of the processor. | ||
117 | * | ||
118 | ******************************************************************************/ | ||
119 | |||
120 | acpi_status | ||
121 | acpi_tb_get_table_header(struct acpi_pointer *address, | ||
122 | struct acpi_table_header *return_header) | ||
123 | { | ||
124 | acpi_status status = AE_OK; | ||
125 | struct acpi_table_header *header = NULL; | ||
126 | |||
127 | ACPI_FUNCTION_TRACE(tb_get_table_header); | ||
128 | |||
129 | /* | ||
130 | * Flags contains the current processor mode (Virtual or Physical | ||
131 | * addressing) The pointer_type is either Logical or Physical | ||
132 | */ | ||
133 | switch (address->pointer_type) { | ||
134 | case ACPI_PHYSMODE_PHYSPTR: | ||
135 | case ACPI_LOGMODE_LOGPTR: | ||
136 | |||
137 | /* Pointer matches processor mode, copy the header */ | ||
138 | |||
139 | ACPI_MEMCPY(return_header, address->pointer.logical, | ||
140 | sizeof(struct acpi_table_header)); | ||
141 | break; | ||
142 | |||
143 | case ACPI_LOGMODE_PHYSPTR: | ||
144 | |||
145 | /* Create a logical address for the physical pointer */ | ||
146 | |||
147 | status = acpi_os_map_memory(address->pointer.physical, | ||
148 | sizeof(struct acpi_table_header), | ||
149 | (void *)&header); | ||
150 | if (ACPI_FAILURE(status)) { | ||
151 | ACPI_ERROR((AE_INFO, | ||
152 | "Could not map memory at %8.8X%8.8X for table header", | ||
153 | ACPI_FORMAT_UINT64(address->pointer. | ||
154 | physical))); | ||
155 | return_ACPI_STATUS(status); | ||
156 | } | ||
157 | |||
158 | /* Copy header and delete mapping */ | ||
159 | |||
160 | ACPI_MEMCPY(return_header, header, | ||
161 | sizeof(struct acpi_table_header)); | ||
162 | acpi_os_unmap_memory(header, sizeof(struct acpi_table_header)); | ||
163 | break; | ||
164 | |||
165 | default: | ||
166 | |||
167 | ACPI_ERROR((AE_INFO, "Invalid address flags %X", | ||
168 | address->pointer_type)); | ||
169 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
170 | } | ||
171 | |||
172 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n", | ||
173 | return_header->signature)); | ||
174 | |||
175 | return_ACPI_STATUS(AE_OK); | ||
176 | } | ||
177 | |||
178 | /******************************************************************************* | ||
179 | * | ||
180 | * FUNCTION: acpi_tb_get_table_body | ||
181 | * | ||
182 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
183 | * Logical or Physical | ||
184 | * Header - Header of the table to retrieve | ||
185 | * table_info - Where the table info is returned | ||
186 | * | ||
187 | * RETURN: Status | ||
188 | * | ||
189 | * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to | ||
190 | * replace the table with a newer version (table override.) | ||
191 | * Works in both physical or virtual | ||
192 | * addressing mode. Works with both physical or logical pointers. | ||
193 | * Table is either copied or mapped, depending on the pointer | ||
194 | * type and mode of the processor. | ||
195 | * | ||
196 | ******************************************************************************/ | ||
197 | |||
198 | acpi_status | ||
199 | acpi_tb_get_table_body(struct acpi_pointer *address, | ||
200 | struct acpi_table_header *header, | ||
201 | struct acpi_table_desc *table_info) | ||
202 | { | ||
203 | acpi_status status; | ||
204 | |||
205 | ACPI_FUNCTION_TRACE(tb_get_table_body); | ||
206 | |||
207 | if (!table_info || !address) { | ||
208 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
209 | } | ||
210 | |||
211 | /* Attempt table override. */ | ||
212 | |||
213 | status = acpi_tb_table_override(header, table_info); | ||
214 | if (ACPI_SUCCESS(status)) { | ||
215 | |||
216 | /* Table was overridden by the host OS */ | ||
217 | |||
218 | return_ACPI_STATUS(status); | ||
219 | } | ||
220 | |||
221 | /* No override, get the original table */ | ||
222 | |||
223 | status = acpi_tb_get_this_table(address, header, table_info); | ||
224 | return_ACPI_STATUS(status); | ||
225 | } | ||
226 | |||
227 | /******************************************************************************* | ||
228 | * | ||
229 | * FUNCTION: acpi_tb_table_override | ||
230 | * | ||
231 | * PARAMETERS: Header - Pointer to table header | ||
232 | * table_info - Return info if table is overridden | ||
233 | * | ||
234 | * RETURN: None | ||
235 | * | ||
236 | * DESCRIPTION: Attempts override of current table with a new one if provided | ||
237 | * by the host OS. | ||
238 | * | ||
239 | ******************************************************************************/ | ||
240 | |||
241 | static acpi_status | ||
242 | acpi_tb_table_override(struct acpi_table_header *header, | ||
243 | struct acpi_table_desc *table_info) | ||
244 | { | ||
245 | struct acpi_table_header *new_table; | ||
246 | acpi_status status; | ||
247 | struct acpi_pointer address; | ||
248 | |||
249 | ACPI_FUNCTION_TRACE(tb_table_override); | ||
250 | |||
251 | /* | ||
252 | * The OSL will examine the header and decide whether to override this | ||
253 | * table. If it decides to override, a table will be returned in new_table, | ||
254 | * which we will then copy. | ||
255 | */ | ||
256 | status = acpi_os_table_override(header, &new_table); | ||
257 | if (ACPI_FAILURE(status)) { | ||
258 | |||
259 | /* Some severe error from the OSL, but we basically ignore it */ | ||
260 | |||
261 | ACPI_EXCEPTION((AE_INFO, status, | ||
262 | "Could not override ACPI table")); | ||
263 | return_ACPI_STATUS(status); | ||
264 | } | ||
265 | |||
266 | if (!new_table) { | ||
267 | |||
268 | /* No table override */ | ||
269 | |||
270 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * We have a new table to override the old one. Get a copy of | ||
275 | * the new one. We know that the new table has a logical pointer. | ||
276 | */ | ||
277 | address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; | ||
278 | address.pointer.logical = new_table; | ||
279 | |||
280 | status = acpi_tb_get_this_table(&address, new_table, table_info); | ||
281 | if (ACPI_FAILURE(status)) { | ||
282 | ACPI_EXCEPTION((AE_INFO, status, "Could not copy ACPI table")); | ||
283 | return_ACPI_STATUS(status); | ||
284 | } | ||
285 | |||
286 | /* Copy the table info */ | ||
287 | |||
288 | ACPI_INFO((AE_INFO, "Table [%4.4s] replaced by host OS", | ||
289 | table_info->pointer->signature)); | ||
290 | |||
291 | return_ACPI_STATUS(AE_OK); | ||
292 | } | ||
293 | |||
294 | /******************************************************************************* | ||
295 | * | ||
296 | * FUNCTION: acpi_tb_get_this_table | ||
297 | * | ||
298 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
299 | * Logical or Physical | ||
300 | * Header - Header of the table to retrieve | ||
301 | * table_info - Where the table info is returned | ||
302 | * | ||
303 | * RETURN: Status | ||
304 | * | ||
305 | * DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual | ||
306 | * addressing mode. Works with both physical or logical pointers. | ||
307 | * Table is either copied or mapped, depending on the pointer | ||
308 | * type and mode of the processor. | ||
309 | * | ||
310 | ******************************************************************************/ | ||
311 | |||
312 | static acpi_status | ||
313 | acpi_tb_get_this_table(struct acpi_pointer *address, | ||
314 | struct acpi_table_header *header, | ||
315 | struct acpi_table_desc *table_info) | ||
316 | { | ||
317 | struct acpi_table_header *full_table = NULL; | ||
318 | u8 allocation; | ||
319 | acpi_status status = AE_OK; | ||
320 | |||
321 | ACPI_FUNCTION_TRACE(tb_get_this_table); | ||
322 | |||
323 | /* Validate minimum length */ | ||
324 | |||
325 | if (header->length < sizeof(struct acpi_table_header)) { | ||
326 | ACPI_ERROR((AE_INFO, | ||
327 | "Table length (%X) is smaller than minimum (%zX)", | ||
328 | header->length, sizeof(struct acpi_table_header))); | ||
329 | |||
330 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * Flags contains the current processor mode (Virtual or Physical | ||
335 | * addressing) The pointer_type is either Logical or Physical | ||
336 | */ | ||
337 | switch (address->pointer_type) { | ||
338 | case ACPI_PHYSMODE_PHYSPTR: | ||
339 | case ACPI_LOGMODE_LOGPTR: | ||
340 | |||
341 | /* Pointer matches processor mode, copy the table to a new buffer */ | ||
342 | |||
343 | full_table = ACPI_ALLOCATE(header->length); | ||
344 | if (!full_table) { | ||
345 | ACPI_ERROR((AE_INFO, | ||
346 | "Could not allocate table memory for [%4.4s] length %X", | ||
347 | header->signature, header->length)); | ||
348 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
349 | } | ||
350 | |||
351 | /* Copy the entire table (including header) to the local buffer */ | ||
352 | |||
353 | ACPI_MEMCPY(full_table, address->pointer.logical, | ||
354 | header->length); | ||
355 | |||
356 | /* Save allocation type */ | ||
357 | |||
358 | allocation = ACPI_MEM_ALLOCATED; | ||
359 | break; | ||
360 | |||
361 | case ACPI_LOGMODE_PHYSPTR: | ||
362 | |||
363 | /* | ||
364 | * Just map the table's physical memory | ||
365 | * into our address space. | ||
366 | */ | ||
367 | status = acpi_os_map_memory(address->pointer.physical, | ||
368 | (acpi_size) header->length, | ||
369 | ACPI_CAST_PTR(void, &full_table)); | ||
370 | if (ACPI_FAILURE(status)) { | ||
371 | ACPI_ERROR((AE_INFO, | ||
372 | "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X", | ||
373 | header->signature, | ||
374 | ACPI_FORMAT_UINT64(address->pointer. | ||
375 | physical), | ||
376 | header->length)); | ||
377 | return (status); | ||
378 | } | ||
379 | |||
380 | /* Save allocation type */ | ||
381 | |||
382 | allocation = ACPI_MEM_MAPPED; | ||
383 | break; | ||
384 | |||
385 | default: | ||
386 | |||
387 | ACPI_ERROR((AE_INFO, "Invalid address flags %X", | ||
388 | address->pointer_type)); | ||
389 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
390 | } | ||
391 | |||
392 | /* | ||
393 | * Validate checksum for _most_ tables, | ||
394 | * even the ones whose signature we don't recognize | ||
395 | */ | ||
396 | if (table_info->type != ACPI_TABLE_ID_FACS) { | ||
397 | status = acpi_tb_verify_table_checksum(full_table); | ||
398 | |||
399 | #if (!ACPI_CHECKSUM_ABORT) | ||
400 | if (ACPI_FAILURE(status)) { | ||
401 | |||
402 | /* Ignore the error if configuration says so */ | ||
403 | |||
404 | status = AE_OK; | ||
405 | } | ||
406 | #endif | ||
407 | } | ||
408 | |||
409 | /* Return values */ | ||
410 | |||
411 | table_info->pointer = full_table; | ||
412 | table_info->length = (acpi_size) header->length; | ||
413 | table_info->allocation = allocation; | ||
414 | |||
415 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
416 | "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n", | ||
417 | full_table->signature, | ||
418 | ACPI_FORMAT_UINT64(address->pointer.physical), | ||
419 | full_table)); | ||
420 | |||
421 | return_ACPI_STATUS(status); | ||
422 | } | ||
423 | |||
424 | /******************************************************************************* | ||
425 | * | ||
426 | * FUNCTION: acpi_tb_get_table_ptr | ||
427 | * | ||
428 | * PARAMETERS: table_type - one of the defined table types | ||
429 | * Instance - Which table of this type | ||
430 | * return_table - pointer to location to place the pointer for | ||
431 | * return | ||
432 | * | ||
433 | * RETURN: Status | ||
434 | * | ||
435 | * DESCRIPTION: This function is called to get the pointer to an ACPI table. | ||
436 | * | ||
437 | ******************************************************************************/ | ||
438 | |||
439 | acpi_status | ||
440 | acpi_tb_get_table_ptr(acpi_table_type table_type, | ||
441 | u32 instance, struct acpi_table_header **return_table) | ||
442 | { | ||
443 | struct acpi_table_desc *table_desc; | ||
444 | u32 i; | ||
445 | |||
446 | ACPI_FUNCTION_TRACE(tb_get_table_ptr); | ||
447 | |||
448 | if (table_type > ACPI_TABLE_ID_MAX) { | ||
449 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
450 | } | ||
451 | |||
452 | /* Check for instance out of range of the current table count */ | ||
453 | |||
454 | if (instance > acpi_gbl_table_lists[table_type].count) { | ||
455 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
456 | } | ||
457 | |||
458 | /* | ||
459 | * Walk the list to get the desired table | ||
460 | * Note: Instance is one-based | ||
461 | */ | ||
462 | table_desc = acpi_gbl_table_lists[table_type].next; | ||
463 | for (i = 1; i < instance; i++) { | ||
464 | table_desc = table_desc->next; | ||
465 | } | ||
466 | |||
467 | /* We are now pointing to the requested table's descriptor */ | ||
468 | |||
469 | *return_table = table_desc->pointer; | ||
470 | return_ACPI_STATUS(AE_OK); | ||
471 | } | ||
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c deleted file mode 100644 index ad982112e4c6..000000000000 --- a/drivers/acpi/tables/tbgetall.c +++ /dev/null | |||
@@ -1,311 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbgetall - Get all required ACPI tables | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbgetall") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | static acpi_status | ||
52 | acpi_tb_get_primary_table(struct acpi_pointer *address, | ||
53 | struct acpi_table_desc *table_info); | ||
54 | |||
55 | static acpi_status | ||
56 | acpi_tb_get_secondary_table(struct acpi_pointer *address, | ||
57 | acpi_string signature, | ||
58 | struct acpi_table_desc *table_info); | ||
59 | |||
60 | /******************************************************************************* | ||
61 | * | ||
62 | * FUNCTION: acpi_tb_get_primary_table | ||
63 | * | ||
64 | * PARAMETERS: Address - Physical address of table to retrieve | ||
65 | * *table_info - Where the table info is returned | ||
66 | * | ||
67 | * RETURN: Status | ||
68 | * | ||
69 | * DESCRIPTION: Maps the physical address of table into a logical address | ||
70 | * | ||
71 | ******************************************************************************/ | ||
72 | |||
73 | static acpi_status | ||
74 | acpi_tb_get_primary_table(struct acpi_pointer *address, | ||
75 | struct acpi_table_desc *table_info) | ||
76 | { | ||
77 | acpi_status status; | ||
78 | struct acpi_table_header header; | ||
79 | |||
80 | ACPI_FUNCTION_TRACE(tb_get_primary_table); | ||
81 | |||
82 | /* Ignore a NULL address in the RSDT */ | ||
83 | |||
84 | if (!address->pointer.value) { | ||
85 | return_ACPI_STATUS(AE_OK); | ||
86 | } | ||
87 | |||
88 | /* Get the header in order to get signature and table size */ | ||
89 | |||
90 | status = acpi_tb_get_table_header(address, &header); | ||
91 | if (ACPI_FAILURE(status)) { | ||
92 | return_ACPI_STATUS(status); | ||
93 | } | ||
94 | |||
95 | /* Clear the table_info */ | ||
96 | |||
97 | ACPI_MEMSET(table_info, 0, sizeof(struct acpi_table_desc)); | ||
98 | |||
99 | /* | ||
100 | * Check the table signature and make sure it is recognized. | ||
101 | * Also checks the header checksum | ||
102 | */ | ||
103 | table_info->pointer = &header; | ||
104 | status = acpi_tb_recognize_table(table_info, ACPI_TABLE_PRIMARY); | ||
105 | if (ACPI_FAILURE(status)) { | ||
106 | return_ACPI_STATUS(status); | ||
107 | } | ||
108 | |||
109 | /* Get the entire table */ | ||
110 | |||
111 | status = acpi_tb_get_table_body(address, &header, table_info); | ||
112 | if (ACPI_FAILURE(status)) { | ||
113 | return_ACPI_STATUS(status); | ||
114 | } | ||
115 | |||
116 | /* Install the table */ | ||
117 | |||
118 | status = acpi_tb_install_table(table_info); | ||
119 | return_ACPI_STATUS(status); | ||
120 | } | ||
121 | |||
122 | /******************************************************************************* | ||
123 | * | ||
124 | * FUNCTION: acpi_tb_get_secondary_table | ||
125 | * | ||
126 | * PARAMETERS: Address - Physical address of table to retrieve | ||
127 | * *table_info - Where the table info is returned | ||
128 | * | ||
129 | * RETURN: Status | ||
130 | * | ||
131 | * DESCRIPTION: Maps the physical address of table into a logical address | ||
132 | * | ||
133 | ******************************************************************************/ | ||
134 | |||
135 | static acpi_status | ||
136 | acpi_tb_get_secondary_table(struct acpi_pointer *address, | ||
137 | acpi_string signature, | ||
138 | struct acpi_table_desc *table_info) | ||
139 | { | ||
140 | acpi_status status; | ||
141 | struct acpi_table_header header; | ||
142 | |||
143 | ACPI_FUNCTION_TRACE_STR(tb_get_secondary_table, signature); | ||
144 | |||
145 | /* Get the header in order to match the signature */ | ||
146 | |||
147 | status = acpi_tb_get_table_header(address, &header); | ||
148 | if (ACPI_FAILURE(status)) { | ||
149 | return_ACPI_STATUS(status); | ||
150 | } | ||
151 | |||
152 | /* Signature must match request */ | ||
153 | |||
154 | if (!ACPI_COMPARE_NAME(header.signature, signature)) { | ||
155 | ACPI_ERROR((AE_INFO, | ||
156 | "Incorrect table signature - wanted [%s] found [%4.4s]", | ||
157 | signature, header.signature)); | ||
158 | return_ACPI_STATUS(AE_BAD_SIGNATURE); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * Check the table signature and make sure it is recognized. | ||
163 | * Also checks the header checksum | ||
164 | */ | ||
165 | table_info->pointer = &header; | ||
166 | status = acpi_tb_recognize_table(table_info, ACPI_TABLE_SECONDARY); | ||
167 | if (ACPI_FAILURE(status)) { | ||
168 | return_ACPI_STATUS(status); | ||
169 | } | ||
170 | |||
171 | /* Get the entire table */ | ||
172 | |||
173 | status = acpi_tb_get_table_body(address, &header, table_info); | ||
174 | if (ACPI_FAILURE(status)) { | ||
175 | return_ACPI_STATUS(status); | ||
176 | } | ||
177 | |||
178 | /* Install the table */ | ||
179 | |||
180 | status = acpi_tb_install_table(table_info); | ||
181 | return_ACPI_STATUS(status); | ||
182 | } | ||
183 | |||
184 | /******************************************************************************* | ||
185 | * | ||
186 | * FUNCTION: acpi_tb_get_required_tables | ||
187 | * | ||
188 | * PARAMETERS: None | ||
189 | * | ||
190 | * RETURN: Status | ||
191 | * | ||
192 | * DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must | ||
193 | * already be loaded and validated. | ||
194 | * | ||
195 | * Get the minimum set of ACPI tables, namely: | ||
196 | * | ||
197 | * 1) FADT (via RSDT in loop below) | ||
198 | * 2) FACS (via FADT) | ||
199 | * 3) DSDT (via FADT) | ||
200 | * | ||
201 | ******************************************************************************/ | ||
202 | |||
203 | acpi_status acpi_tb_get_required_tables(void) | ||
204 | { | ||
205 | acpi_status status = AE_OK; | ||
206 | u32 i; | ||
207 | struct acpi_table_desc table_info; | ||
208 | struct acpi_pointer address; | ||
209 | |||
210 | ACPI_FUNCTION_TRACE(tb_get_required_tables); | ||
211 | |||
212 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%d ACPI tables in RSDT\n", | ||
213 | acpi_gbl_rsdt_table_count)); | ||
214 | |||
215 | address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; | ||
216 | |||
217 | /* | ||
218 | * Loop through all table pointers found in RSDT. | ||
219 | * This will NOT include the FACS and DSDT - we must get | ||
220 | * them after the loop. | ||
221 | * | ||
222 | * The only tables we are interested in getting here is the FADT and | ||
223 | * any SSDTs. | ||
224 | */ | ||
225 | for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { | ||
226 | |||
227 | /* Get the table address from the common internal XSDT */ | ||
228 | |||
229 | address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i]; | ||
230 | |||
231 | /* | ||
232 | * Get the tables needed by this subsystem (FADT and any SSDTs). | ||
233 | * NOTE: All other tables are completely ignored at this time. | ||
234 | */ | ||
235 | status = acpi_tb_get_primary_table(&address, &table_info); | ||
236 | if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) { | ||
237 | ACPI_WARNING((AE_INFO, | ||
238 | "%s, while getting table at %8.8X%8.8X", | ||
239 | acpi_format_exception(status), | ||
240 | ACPI_FORMAT_UINT64(address.pointer. | ||
241 | value))); | ||
242 | } | ||
243 | } | ||
244 | |||
245 | /* We must have a FADT to continue */ | ||
246 | |||
247 | if (!acpi_gbl_FADT) { | ||
248 | ACPI_ERROR((AE_INFO, "No FADT present in RSDT/XSDT")); | ||
249 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * Convert the FADT to a common format. This allows earlier revisions of | ||
254 | * the table to coexist with newer versions, using common access code. | ||
255 | */ | ||
256 | status = acpi_tb_convert_table_fadt(); | ||
257 | if (ACPI_FAILURE(status)) { | ||
258 | ACPI_ERROR((AE_INFO, | ||
259 | "Could not convert FADT to internal common format")); | ||
260 | return_ACPI_STATUS(status); | ||
261 | } | ||
262 | |||
263 | /* Get the FACS (Pointed to by the FADT) */ | ||
264 | |||
265 | address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl; | ||
266 | |||
267 | status = acpi_tb_get_secondary_table(&address, FACS_SIG, &table_info); | ||
268 | if (ACPI_FAILURE(status)) { | ||
269 | ACPI_EXCEPTION((AE_INFO, status, | ||
270 | "Could not get/install the FACS")); | ||
271 | return_ACPI_STATUS(status); | ||
272 | } | ||
273 | |||
274 | /* | ||
275 | * Create the common FACS pointer table | ||
276 | * (Contains pointers to the original table) | ||
277 | */ | ||
278 | status = acpi_tb_build_common_facs(&table_info); | ||
279 | if (ACPI_FAILURE(status)) { | ||
280 | return_ACPI_STATUS(status); | ||
281 | } | ||
282 | |||
283 | /* Get/install the DSDT (Pointed to by the FADT) */ | ||
284 | |||
285 | address.pointer.value = acpi_gbl_FADT->Xdsdt; | ||
286 | |||
287 | status = acpi_tb_get_secondary_table(&address, DSDT_SIG, &table_info); | ||
288 | if (ACPI_FAILURE(status)) { | ||
289 | ACPI_ERROR((AE_INFO, "Could not get/install the DSDT")); | ||
290 | return_ACPI_STATUS(status); | ||
291 | } | ||
292 | |||
293 | /* Set Integer Width (32/64) based upon DSDT revision */ | ||
294 | |||
295 | acpi_ut_set_integer_width(acpi_gbl_DSDT->revision); | ||
296 | |||
297 | /* Dump the entire DSDT */ | ||
298 | |||
299 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
300 | "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n", | ||
301 | acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, | ||
302 | acpi_gbl_integer_bit_width)); | ||
303 | |||
304 | ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_DSDT), | ||
305 | acpi_gbl_DSDT->length); | ||
306 | |||
307 | /* Always delete the RSDP mapping, we are done with it */ | ||
308 | |||
309 | acpi_tb_delete_tables_by_type(ACPI_TABLE_ID_RSDP); | ||
310 | return_ACPI_STATUS(status); | ||
311 | } | ||
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 1668a232fb67..0e7b121a99ce 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -42,510 +42,498 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | ||
45 | #include <acpi/actables.h> | 46 | #include <acpi/actables.h> |
46 | 47 | ||
47 | #define _COMPONENT ACPI_TABLES | 48 | #define _COMPONENT ACPI_TABLES |
48 | ACPI_MODULE_NAME("tbinstal") | 49 | ACPI_MODULE_NAME("tbinstal") |
49 | 50 | ||
50 | /* Local prototypes */ | 51 | /****************************************************************************** |
51 | static acpi_status | ||
52 | acpi_tb_match_signature(char *signature, | ||
53 | struct acpi_table_desc *table_info, u8 search_type); | ||
54 | |||
55 | /******************************************************************************* | ||
56 | * | 52 | * |
57 | * FUNCTION: acpi_tb_match_signature | 53 | * FUNCTION: acpi_tb_verify_table |
58 | * | 54 | * |
59 | * PARAMETERS: Signature - Table signature to match | 55 | * PARAMETERS: table_desc - table |
60 | * table_info - Return data | ||
61 | * search_type - Table type to match (primary/secondary) | ||
62 | * | 56 | * |
63 | * RETURN: Status | 57 | * RETURN: Status |
64 | * | 58 | * |
65 | * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned" | 59 | * DESCRIPTION: this function is called to verify and map table |
66 | * tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match. | ||
67 | * | 60 | * |
68 | ******************************************************************************/ | 61 | *****************************************************************************/ |
69 | 62 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | |
70 | static acpi_status | ||
71 | acpi_tb_match_signature(char *signature, | ||
72 | struct acpi_table_desc *table_info, u8 search_type) | ||
73 | { | 63 | { |
74 | acpi_native_uint i; | 64 | acpi_status status = AE_OK; |
75 | 65 | ||
76 | ACPI_FUNCTION_TRACE(tb_match_signature); | 66 | ACPI_FUNCTION_TRACE(tb_verify_table); |
77 | 67 | ||
78 | /* Search for a signature match among the known table types */ | 68 | /* Map the table if necessary */ |
79 | 69 | ||
80 | for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { | 70 | if (!table_desc->pointer) { |
81 | if (!(acpi_gbl_table_data[i].flags & search_type)) { | 71 | if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == |
82 | continue; | 72 | ACPI_TABLE_ORIGIN_MAPPED) { |
73 | table_desc->pointer = | ||
74 | acpi_os_map_memory(table_desc->address, | ||
75 | table_desc->length); | ||
83 | } | 76 | } |
77 | if (!table_desc->pointer) { | ||
78 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
79 | } | ||
80 | } | ||
84 | 81 | ||
85 | if (!ACPI_STRNCMP(signature, acpi_gbl_table_data[i].signature, | 82 | /* FACS is the odd table, has no standard ACPI header and no checksum */ |
86 | acpi_gbl_table_data[i].sig_length)) { | ||
87 | |||
88 | /* Found a signature match, return index if requested */ | ||
89 | 83 | ||
90 | if (table_info) { | 84 | if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) { |
91 | table_info->type = (u8) i; | ||
92 | } | ||
93 | 85 | ||
94 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 86 | /* Always calculate checksum, ignore bad checksum if requested */ |
95 | "Table [%4.4s] is an ACPI table consumed by the core subsystem\n", | ||
96 | (char *)acpi_gbl_table_data[i]. | ||
97 | signature)); | ||
98 | 87 | ||
99 | return_ACPI_STATUS(AE_OK); | 88 | status = |
100 | } | 89 | acpi_tb_verify_checksum(table_desc->pointer, |
90 | table_desc->length); | ||
101 | } | 91 | } |
102 | 92 | ||
103 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 93 | return_ACPI_STATUS(status); |
104 | "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n", | ||
105 | (char *)signature)); | ||
106 | |||
107 | return_ACPI_STATUS(AE_TABLE_NOT_SUPPORTED); | ||
108 | } | 94 | } |
109 | 95 | ||
110 | /******************************************************************************* | 96 | /******************************************************************************* |
111 | * | 97 | * |
112 | * FUNCTION: acpi_tb_install_table | 98 | * FUNCTION: acpi_tb_add_table |
113 | * | 99 | * |
114 | * PARAMETERS: table_info - Return value from acpi_tb_get_table_body | 100 | * PARAMETERS: table_desc - Table descriptor |
101 | * table_index - Where the table index is returned | ||
115 | * | 102 | * |
116 | * RETURN: Status | 103 | * RETURN: Status |
117 | * | 104 | * |
118 | * DESCRIPTION: Install the table into the global data structures. | 105 | * DESCRIPTION: This function is called to add the ACPI table |
119 | * | 106 | * |
120 | ******************************************************************************/ | 107 | ******************************************************************************/ |
121 | 108 | ||
122 | acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info) | 109 | acpi_status |
110 | acpi_tb_add_table(struct acpi_table_desc *table_desc, | ||
111 | acpi_native_uint * table_index) | ||
123 | { | 112 | { |
124 | acpi_status status; | 113 | acpi_native_uint i; |
125 | 114 | acpi_native_uint length; | |
126 | ACPI_FUNCTION_TRACE(tb_install_table); | 115 | acpi_status status = AE_OK; |
127 | 116 | ||
128 | /* Lock tables while installing */ | 117 | ACPI_FUNCTION_TRACE(tb_add_table); |
129 | 118 | ||
130 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 119 | if (!table_desc->pointer) { |
131 | if (ACPI_FAILURE(status)) { | 120 | status = acpi_tb_verify_table(table_desc); |
132 | ACPI_EXCEPTION((AE_INFO, status, | 121 | if (ACPI_FAILURE(status) || !table_desc->pointer) { |
133 | "Could not acquire table mutex")); | 122 | return_ACPI_STATUS(status); |
134 | return_ACPI_STATUS(status); | 123 | } |
135 | } | 124 | } |
136 | 125 | ||
137 | /* | 126 | /* The table must be either an SSDT or a PSDT */ |
138 | * Ignore a table that is already installed. For example, some BIOS | 127 | |
139 | * ASL code will repeatedly attempt to load the same SSDT. | 128 | if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)) |
140 | */ | 129 | && |
141 | status = acpi_tb_is_table_installed(table_info); | 130 | (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))) |
142 | if (ACPI_FAILURE(status)) { | 131 | { |
143 | goto unlock_and_exit; | 132 | ACPI_ERROR((AE_INFO, |
133 | "Table has invalid signature [%4.4s], must be SSDT or PSDT", | ||
134 | table_desc->pointer->signature)); | ||
135 | return_ACPI_STATUS(AE_BAD_SIGNATURE); | ||
144 | } | 136 | } |
145 | 137 | ||
146 | /* Install the table into the global data structure */ | 138 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
139 | |||
140 | /* Check if table is already registered */ | ||
141 | |||
142 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { | ||
143 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | ||
144 | status = | ||
145 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
146 | tables[i]); | ||
147 | if (ACPI_FAILURE(status) | ||
148 | || !acpi_gbl_root_table_list.tables[i].pointer) { | ||
149 | continue; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | length = ACPI_MIN(table_desc->length, | ||
154 | acpi_gbl_root_table_list.tables[i].length); | ||
155 | if (ACPI_MEMCMP(table_desc->pointer, | ||
156 | acpi_gbl_root_table_list.tables[i].pointer, | ||
157 | length)) { | ||
158 | continue; | ||
159 | } | ||
160 | |||
161 | /* Table is already registered */ | ||
162 | |||
163 | acpi_tb_delete_table(table_desc); | ||
164 | *table_index = i; | ||
165 | goto release; | ||
166 | } | ||
147 | 167 | ||
148 | status = acpi_tb_init_table_descriptor(table_info->type, table_info); | 168 | /* |
169 | * Add the table to the global table list | ||
170 | */ | ||
171 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, | ||
172 | table_desc->length, table_desc->flags, | ||
173 | table_index); | ||
149 | if (ACPI_FAILURE(status)) { | 174 | if (ACPI_FAILURE(status)) { |
150 | ACPI_EXCEPTION((AE_INFO, status, | 175 | goto release; |
151 | "Could not install table [%4.4s]", | ||
152 | table_info->pointer->signature)); | ||
153 | } | 176 | } |
154 | 177 | ||
155 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n", | 178 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); |
156 | acpi_gbl_table_data[table_info->type].name, | ||
157 | table_info->pointer)); | ||
158 | 179 | ||
159 | unlock_and_exit: | 180 | release: |
160 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 181 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
161 | return_ACPI_STATUS(status); | 182 | return_ACPI_STATUS(status); |
162 | } | 183 | } |
163 | 184 | ||
164 | /******************************************************************************* | 185 | /******************************************************************************* |
165 | * | 186 | * |
166 | * FUNCTION: acpi_tb_recognize_table | 187 | * FUNCTION: acpi_tb_resize_root_table_list |
167 | * | 188 | * |
168 | * PARAMETERS: table_info - Return value from acpi_tb_get_table_body | 189 | * PARAMETERS: None |
169 | * search_type - Table type to match (primary/secondary) | ||
170 | * | 190 | * |
171 | * RETURN: Status | 191 | * RETURN: Status |
172 | * | 192 | * |
173 | * DESCRIPTION: Check a table signature for a match against known table types | 193 | * DESCRIPTION: Expand the size of global table array |
174 | * | ||
175 | * NOTE: All table pointers are validated as follows: | ||
176 | * 1) Table pointer must point to valid physical memory | ||
177 | * 2) Signature must be 4 ASCII chars, even if we don't recognize the | ||
178 | * name | ||
179 | * 3) Table must be readable for length specified in the header | ||
180 | * 4) Table checksum must be valid (with the exception of the FACS | ||
181 | * which has no checksum for some odd reason) | ||
182 | * | 194 | * |
183 | ******************************************************************************/ | 195 | ******************************************************************************/ |
184 | 196 | ||
185 | acpi_status | 197 | acpi_status acpi_tb_resize_root_table_list(void) |
186 | acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type) | ||
187 | { | 198 | { |
188 | struct acpi_table_header *table_header; | 199 | struct acpi_table_desc *tables; |
189 | acpi_status status; | ||
190 | 200 | ||
191 | ACPI_FUNCTION_TRACE(tb_recognize_table); | 201 | ACPI_FUNCTION_TRACE(tb_resize_root_table_list); |
192 | 202 | ||
193 | /* Ensure that we have a valid table pointer */ | 203 | /* allow_resize flag is a parameter to acpi_initialize_tables */ |
194 | 204 | ||
195 | table_header = (struct acpi_table_header *)table_info->pointer; | 205 | if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { |
196 | if (!table_header) { | 206 | ACPI_ERROR((AE_INFO, |
197 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 207 | "Resize of Root Table Array is not allowed")); |
208 | return_ACPI_STATUS(AE_SUPPORT); | ||
198 | } | 209 | } |
199 | 210 | ||
200 | /* | 211 | /* Increase the Table Array size */ |
201 | * We only "recognize" a limited number of ACPI tables -- namely, the | 212 | |
202 | * ones that are used by the subsystem (DSDT, FADT, etc.) | 213 | tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size + |
203 | * | 214 | ACPI_ROOT_TABLE_SIZE_INCREMENT) |
204 | * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized. | 215 | * sizeof(struct acpi_table_desc)); |
205 | * This can be any one of many valid ACPI tables, it just isn't one of | 216 | if (!tables) { |
206 | * the tables that is consumed by the core subsystem | 217 | ACPI_ERROR((AE_INFO, |
207 | */ | 218 | "Could not allocate new root table array")); |
208 | status = acpi_tb_match_signature(table_header->signature, | 219 | return_ACPI_STATUS(AE_NO_MEMORY); |
209 | table_info, search_type); | ||
210 | if (ACPI_FAILURE(status)) { | ||
211 | return_ACPI_STATUS(status); | ||
212 | } | 220 | } |
213 | 221 | ||
214 | status = acpi_tb_validate_table_header(table_header); | 222 | /* Copy and free the previous table array */ |
215 | if (ACPI_FAILURE(status)) { | 223 | |
216 | return_ACPI_STATUS(status); | 224 | if (acpi_gbl_root_table_list.tables) { |
225 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, | ||
226 | acpi_gbl_root_table_list.size * | ||
227 | sizeof(struct acpi_table_desc)); | ||
228 | |||
229 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | ||
230 | ACPI_FREE(acpi_gbl_root_table_list.tables); | ||
231 | } | ||
217 | } | 232 | } |
218 | 233 | ||
219 | /* Return the table type and length via the info struct */ | 234 | acpi_gbl_root_table_list.tables = tables; |
235 | acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT; | ||
236 | acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED; | ||
220 | 237 | ||
221 | table_info->length = (acpi_size) table_header->length; | 238 | return_ACPI_STATUS(AE_OK); |
222 | return_ACPI_STATUS(status); | ||
223 | } | 239 | } |
224 | 240 | ||
225 | /******************************************************************************* | 241 | /******************************************************************************* |
226 | * | 242 | * |
227 | * FUNCTION: acpi_tb_init_table_descriptor | 243 | * FUNCTION: acpi_tb_store_table |
228 | * | 244 | * |
229 | * PARAMETERS: table_type - The type of the table | 245 | * PARAMETERS: Address - Table address |
230 | * table_info - A table info struct | 246 | * Table - Table header |
247 | * Length - Table length | ||
248 | * Flags - flags | ||
231 | * | 249 | * |
232 | * RETURN: None. | 250 | * RETURN: Status and table index. |
233 | * | 251 | * |
234 | * DESCRIPTION: Install a table into the global data structs. | 252 | * DESCRIPTION: Add an ACPI table to the global table list |
235 | * | 253 | * |
236 | ******************************************************************************/ | 254 | ******************************************************************************/ |
237 | 255 | ||
238 | acpi_status | 256 | acpi_status |
239 | acpi_tb_init_table_descriptor(acpi_table_type table_type, | 257 | acpi_tb_store_table(acpi_physical_address address, |
240 | struct acpi_table_desc *table_info) | 258 | struct acpi_table_header *table, |
259 | u32 length, u8 flags, acpi_native_uint * table_index) | ||
241 | { | 260 | { |
242 | struct acpi_table_list *list_head; | 261 | acpi_status status = AE_OK; |
243 | struct acpi_table_desc *table_desc; | ||
244 | acpi_status status; | ||
245 | |||
246 | ACPI_FUNCTION_TRACE_U32(tb_init_table_descriptor, table_type); | ||
247 | 262 | ||
248 | /* Allocate a descriptor for this table */ | 263 | /* Ensure that there is room for the table in the Root Table List */ |
249 | 264 | ||
250 | table_desc = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); | 265 | if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) { |
251 | if (!table_desc) { | 266 | status = acpi_tb_resize_root_table_list(); |
252 | return_ACPI_STATUS(AE_NO_MEMORY); | 267 | if (ACPI_FAILURE(status)) { |
268 | return (status); | ||
269 | } | ||
253 | } | 270 | } |
254 | 271 | ||
255 | /* Get a new owner ID for the table */ | 272 | /* Initialize added table */ |
273 | |||
274 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. | ||
275 | address = address; | ||
276 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. | ||
277 | pointer = table; | ||
278 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length = | ||
279 | length; | ||
280 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. | ||
281 | owner_id = 0; | ||
282 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags = | ||
283 | flags; | ||
284 | |||
285 | ACPI_MOVE_32_TO_32(& | ||
286 | (acpi_gbl_root_table_list. | ||
287 | tables[acpi_gbl_root_table_list.count].signature), | ||
288 | table->signature); | ||
289 | |||
290 | *table_index = acpi_gbl_root_table_list.count; | ||
291 | acpi_gbl_root_table_list.count++; | ||
292 | return (status); | ||
293 | } | ||
256 | 294 | ||
257 | status = acpi_ut_allocate_owner_id(&table_desc->owner_id); | 295 | /******************************************************************************* |
258 | if (ACPI_FAILURE(status)) { | 296 | * |
259 | goto error_exit1; | 297 | * FUNCTION: acpi_tb_delete_table |
260 | } | 298 | * |
299 | * PARAMETERS: table_index - Table index | ||
300 | * | ||
301 | * RETURN: None | ||
302 | * | ||
303 | * DESCRIPTION: Delete one internal ACPI table | ||
304 | * | ||
305 | ******************************************************************************/ | ||
261 | 306 | ||
262 | /* Install the table into the global data structure */ | 307 | void acpi_tb_delete_table(struct acpi_table_desc *table_desc) |
308 | { | ||
309 | /* Table must be mapped or allocated */ | ||
310 | if (!table_desc->pointer) { | ||
311 | return; | ||
312 | } | ||
313 | switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { | ||
314 | case ACPI_TABLE_ORIGIN_MAPPED: | ||
315 | acpi_os_unmap_memory(table_desc->pointer, table_desc->length); | ||
316 | break; | ||
317 | case ACPI_TABLE_ORIGIN_ALLOCATED: | ||
318 | ACPI_FREE(table_desc->pointer); | ||
319 | break; | ||
320 | default:; | ||
321 | } | ||
263 | 322 | ||
264 | list_head = &acpi_gbl_table_lists[table_type]; | 323 | table_desc->pointer = NULL; |
324 | } | ||
265 | 325 | ||
266 | /* | 326 | /******************************************************************************* |
267 | * Two major types of tables: 1) Only one instance is allowed. This | 327 | * |
268 | * includes most ACPI tables such as the DSDT. 2) Multiple instances of | 328 | * FUNCTION: acpi_tb_terminate |
269 | * the table are allowed. This includes SSDT and PSDTs. | 329 | * |
270 | */ | 330 | * PARAMETERS: None |
271 | if (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags)) { | 331 | * |
272 | /* | 332 | * RETURN: None |
273 | * Only one table allowed, and a table has alread been installed | 333 | * |
274 | * at this location, so return an error. | 334 | * DESCRIPTION: Delete all internal ACPI tables |
275 | */ | 335 | * |
276 | if (list_head->next) { | 336 | ******************************************************************************/ |
277 | status = AE_ALREADY_EXISTS; | ||
278 | goto error_exit2; | ||
279 | } | ||
280 | 337 | ||
281 | table_desc->next = list_head->next; | 338 | void acpi_tb_terminate(void) |
282 | list_head->next = table_desc; | 339 | { |
340 | acpi_native_uint i; | ||
283 | 341 | ||
284 | if (table_desc->next) { | 342 | ACPI_FUNCTION_TRACE(tb_terminate); |
285 | table_desc->next->prev = table_desc; | ||
286 | } | ||
287 | 343 | ||
288 | list_head->count++; | 344 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
289 | } else { | ||
290 | /* | ||
291 | * Link the new table in to the list of tables of this type. | ||
292 | * Insert at the end of the list, order IS IMPORTANT. | ||
293 | * | ||
294 | * table_desc->Prev & Next are already NULL from calloc() | ||
295 | */ | ||
296 | list_head->count++; | ||
297 | |||
298 | if (!list_head->next) { | ||
299 | list_head->next = table_desc; | ||
300 | } else { | ||
301 | table_desc->next = list_head->next; | ||
302 | 345 | ||
303 | while (table_desc->next->next) { | 346 | /* Delete the individual tables */ |
304 | table_desc->next = table_desc->next->next; | ||
305 | } | ||
306 | 347 | ||
307 | table_desc->next->next = table_desc; | 348 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { |
308 | table_desc->prev = table_desc->next; | 349 | acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); |
309 | table_desc->next = NULL; | ||
310 | } | ||
311 | } | 350 | } |
312 | 351 | ||
313 | /* Finish initialization of the table descriptor */ | ||
314 | |||
315 | table_desc->loaded_into_namespace = FALSE; | ||
316 | table_desc->type = (u8) table_type; | ||
317 | table_desc->pointer = table_info->pointer; | ||
318 | table_desc->length = table_info->length; | ||
319 | table_desc->allocation = table_info->allocation; | ||
320 | table_desc->aml_start = (u8 *) (table_desc->pointer + 1), | ||
321 | table_desc->aml_length = (u32) | ||
322 | (table_desc->length - (u32) sizeof(struct acpi_table_header)); | ||
323 | |||
324 | /* | 352 | /* |
325 | * Set the appropriate global pointer (if there is one) to point to the | 353 | * Delete the root table array if allocated locally. Array cannot be |
326 | * newly installed table | 354 | * mapped, so we don't need to check for that flag. |
327 | */ | 355 | */ |
328 | if (acpi_gbl_table_data[table_type].global_ptr) { | 356 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { |
329 | *(acpi_gbl_table_data[table_type].global_ptr) = | 357 | ACPI_FREE(acpi_gbl_root_table_list.tables); |
330 | table_info->pointer; | ||
331 | } | 358 | } |
332 | 359 | ||
333 | /* Return Data */ | 360 | acpi_gbl_root_table_list.tables = NULL; |
334 | 361 | acpi_gbl_root_table_list.flags = 0; | |
335 | table_info->owner_id = table_desc->owner_id; | 362 | acpi_gbl_root_table_list.count = 0; |
336 | table_info->installed_desc = table_desc; | ||
337 | return_ACPI_STATUS(AE_OK); | ||
338 | |||
339 | /* Error exit with cleanup */ | ||
340 | |||
341 | error_exit2: | ||
342 | |||
343 | acpi_ut_release_owner_id(&table_desc->owner_id); | ||
344 | 363 | ||
345 | error_exit1: | 364 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); |
346 | 365 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | |
347 | ACPI_FREE(table_desc); | ||
348 | return_ACPI_STATUS(status); | ||
349 | } | 366 | } |
350 | 367 | ||
351 | /******************************************************************************* | 368 | /******************************************************************************* |
352 | * | 369 | * |
353 | * FUNCTION: acpi_tb_delete_all_tables | 370 | * FUNCTION: acpi_tb_delete_namespace_by_owner |
354 | * | 371 | * |
355 | * PARAMETERS: None. | 372 | * PARAMETERS: table_index - Table index |
356 | * | 373 | * |
357 | * RETURN: None. | 374 | * RETURN: None |
358 | * | 375 | * |
359 | * DESCRIPTION: Delete all internal ACPI tables | 376 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. |
360 | * | 377 | * |
361 | ******************************************************************************/ | 378 | ******************************************************************************/ |
362 | 379 | ||
363 | void acpi_tb_delete_all_tables(void) | 380 | void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index) |
364 | { | 381 | { |
365 | acpi_table_type type; | 382 | acpi_owner_id owner_id; |
366 | 383 | ||
367 | /* | 384 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
368 | * Free memory allocated for ACPI tables | 385 | if (table_index < acpi_gbl_root_table_list.count) { |
369 | * Memory can either be mapped or allocated | 386 | owner_id = |
370 | */ | 387 | acpi_gbl_root_table_list.tables[table_index].owner_id; |
371 | for (type = 0; type < (ACPI_TABLE_ID_MAX + 1); type++) { | 388 | } else { |
372 | acpi_tb_delete_tables_by_type(type); | 389 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
390 | return; | ||
373 | } | 391 | } |
392 | |||
393 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
394 | acpi_ns_delete_namespace_by_owner(owner_id); | ||
374 | } | 395 | } |
375 | 396 | ||
376 | /******************************************************************************* | 397 | /******************************************************************************* |
377 | * | 398 | * |
378 | * FUNCTION: acpi_tb_delete_tables_by_type | 399 | * FUNCTION: acpi_tb_allocate_owner_id |
379 | * | 400 | * |
380 | * PARAMETERS: Type - The table type to be deleted | 401 | * PARAMETERS: table_index - Table index |
381 | * | 402 | * |
382 | * RETURN: None. | 403 | * RETURN: Status |
383 | * | 404 | * |
384 | * DESCRIPTION: Delete an internal ACPI table | 405 | * DESCRIPTION: Allocates owner_id in table_desc |
385 | * Locks the ACPI table mutex | ||
386 | * | 406 | * |
387 | ******************************************************************************/ | 407 | ******************************************************************************/ |
388 | 408 | ||
389 | void acpi_tb_delete_tables_by_type(acpi_table_type type) | 409 | acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index) |
390 | { | 410 | { |
391 | struct acpi_table_desc *table_desc; | 411 | acpi_status status = AE_BAD_PARAMETER; |
392 | u32 count; | ||
393 | u32 i; | ||
394 | 412 | ||
395 | ACPI_FUNCTION_TRACE_U32(tb_delete_tables_by_type, type); | 413 | ACPI_FUNCTION_TRACE(tb_allocate_owner_id); |
396 | 414 | ||
397 | if (type > ACPI_TABLE_ID_MAX) { | 415 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
398 | return_VOID; | 416 | if (table_index < acpi_gbl_root_table_list.count) { |
399 | } | 417 | status = acpi_ut_allocate_owner_id |
400 | 418 | (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); | |
401 | if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_TABLES))) { | ||
402 | return; | ||
403 | } | ||
404 | |||
405 | /* Clear the appropriate "typed" global table pointer */ | ||
406 | |||
407 | switch (type) { | ||
408 | case ACPI_TABLE_ID_RSDP: | ||
409 | acpi_gbl_RSDP = NULL; | ||
410 | break; | ||
411 | |||
412 | case ACPI_TABLE_ID_DSDT: | ||
413 | acpi_gbl_DSDT = NULL; | ||
414 | break; | ||
415 | |||
416 | case ACPI_TABLE_ID_FADT: | ||
417 | acpi_gbl_FADT = NULL; | ||
418 | break; | ||
419 | |||
420 | case ACPI_TABLE_ID_FACS: | ||
421 | acpi_gbl_FACS = NULL; | ||
422 | break; | ||
423 | |||
424 | case ACPI_TABLE_ID_XSDT: | ||
425 | acpi_gbl_XSDT = NULL; | ||
426 | break; | ||
427 | |||
428 | case ACPI_TABLE_ID_SSDT: | ||
429 | case ACPI_TABLE_ID_PSDT: | ||
430 | default: | ||
431 | break; | ||
432 | } | ||
433 | |||
434 | /* | ||
435 | * Free the table | ||
436 | * 1) Get the head of the list | ||
437 | */ | ||
438 | table_desc = acpi_gbl_table_lists[type].next; | ||
439 | count = acpi_gbl_table_lists[type].count; | ||
440 | |||
441 | /* | ||
442 | * 2) Walk the entire list, deleting both the allocated tables | ||
443 | * and the table descriptors | ||
444 | */ | ||
445 | for (i = 0; i < count; i++) { | ||
446 | table_desc = acpi_tb_uninstall_table(table_desc); | ||
447 | } | 419 | } |
448 | 420 | ||
449 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 421 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
450 | return_VOID; | 422 | return_ACPI_STATUS(status); |
451 | } | 423 | } |
452 | 424 | ||
453 | /******************************************************************************* | 425 | /******************************************************************************* |
454 | * | 426 | * |
455 | * FUNCTION: acpi_tb_delete_single_table | 427 | * FUNCTION: acpi_tb_release_owner_id |
456 | * | 428 | * |
457 | * PARAMETERS: table_info - A table info struct | 429 | * PARAMETERS: table_index - Table index |
458 | * | 430 | * |
459 | * RETURN: None. | 431 | * RETURN: Status |
460 | * | 432 | * |
461 | * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where | 433 | * DESCRIPTION: Releases owner_id in table_desc |
462 | * the table was allocated a buffer or was mapped. | ||
463 | * | 434 | * |
464 | ******************************************************************************/ | 435 | ******************************************************************************/ |
465 | 436 | ||
466 | void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc) | 437 | acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index) |
467 | { | 438 | { |
439 | acpi_status status = AE_BAD_PARAMETER; | ||
468 | 440 | ||
469 | /* Must have a valid table descriptor and pointer */ | 441 | ACPI_FUNCTION_TRACE(tb_release_owner_id); |
470 | 442 | ||
471 | if ((!table_desc) || (!table_desc->pointer)) { | 443 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
472 | return; | 444 | if (table_index < acpi_gbl_root_table_list.count) { |
445 | acpi_ut_release_owner_id(& | ||
446 | (acpi_gbl_root_table_list. | ||
447 | tables[table_index].owner_id)); | ||
448 | status = AE_OK; | ||
473 | } | 449 | } |
474 | 450 | ||
475 | /* Valid table, determine type of memory allocation */ | 451 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
476 | 452 | return_ACPI_STATUS(status); | |
477 | switch (table_desc->allocation) { | ||
478 | case ACPI_MEM_NOT_ALLOCATED: | ||
479 | break; | ||
480 | |||
481 | case ACPI_MEM_ALLOCATED: | ||
482 | |||
483 | ACPI_FREE(table_desc->pointer); | ||
484 | break; | ||
485 | |||
486 | case ACPI_MEM_MAPPED: | ||
487 | |||
488 | acpi_os_unmap_memory(table_desc->pointer, table_desc->length); | ||
489 | break; | ||
490 | |||
491 | default: | ||
492 | break; | ||
493 | } | ||
494 | } | 453 | } |
495 | 454 | ||
496 | /******************************************************************************* | 455 | /******************************************************************************* |
497 | * | 456 | * |
498 | * FUNCTION: acpi_tb_uninstall_table | 457 | * FUNCTION: acpi_tb_get_owner_id |
499 | * | 458 | * |
500 | * PARAMETERS: table_info - A table info struct | 459 | * PARAMETERS: table_index - Table index |
460 | * owner_id - Where the table owner_id is returned | ||
501 | * | 461 | * |
502 | * RETURN: Pointer to the next table in the list (of same type) | 462 | * RETURN: Status |
503 | * | 463 | * |
504 | * DESCRIPTION: Free the memory associated with an internal ACPI table that | 464 | * DESCRIPTION: returns owner_id for the ACPI table |
505 | * is either installed or has never been installed. | ||
506 | * Table mutex should be locked. | ||
507 | * | 465 | * |
508 | ******************************************************************************/ | 466 | ******************************************************************************/ |
509 | 467 | ||
510 | struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc | 468 | acpi_status |
511 | *table_desc) | 469 | acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id) |
512 | { | 470 | { |
513 | struct acpi_table_desc *next_desc; | 471 | acpi_status status = AE_BAD_PARAMETER; |
514 | 472 | ||
515 | ACPI_FUNCTION_TRACE_PTR(tb_uninstall_table, table_desc); | 473 | ACPI_FUNCTION_TRACE(tb_get_owner_id); |
516 | 474 | ||
517 | if (!table_desc) { | 475 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
518 | return_PTR(NULL); | 476 | if (table_index < acpi_gbl_root_table_list.count) { |
477 | *owner_id = | ||
478 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
479 | status = AE_OK; | ||
519 | } | 480 | } |
520 | 481 | ||
521 | /* Unlink the descriptor from the doubly linked list */ | 482 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
483 | return_ACPI_STATUS(status); | ||
484 | } | ||
522 | 485 | ||
523 | if (table_desc->prev) { | 486 | /******************************************************************************* |
524 | table_desc->prev->next = table_desc->next; | 487 | * |
525 | } else { | 488 | * FUNCTION: acpi_tb_is_table_loaded |
526 | /* Is first on list, update list head */ | 489 | * |
490 | * PARAMETERS: table_index - Table index | ||
491 | * | ||
492 | * RETURN: Table Loaded Flag | ||
493 | * | ||
494 | ******************************************************************************/ | ||
527 | 495 | ||
528 | acpi_gbl_table_lists[table_desc->type].next = table_desc->next; | 496 | u8 acpi_tb_is_table_loaded(acpi_native_uint table_index) |
529 | } | 497 | { |
498 | u8 is_loaded = FALSE; | ||
530 | 499 | ||
531 | if (table_desc->next) { | 500 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
532 | table_desc->next->prev = table_desc->prev; | 501 | if (table_index < acpi_gbl_root_table_list.count) { |
502 | is_loaded = (u8) | ||
503 | (acpi_gbl_root_table_list.tables[table_index]. | ||
504 | flags & ACPI_TABLE_IS_LOADED); | ||
533 | } | 505 | } |
534 | 506 | ||
535 | /* Free the memory allocated for the table itself */ | 507 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
536 | 508 | return (is_loaded); | |
537 | acpi_tb_delete_single_table(table_desc); | 509 | } |
538 | |||
539 | /* Free the owner ID associated with this table */ | ||
540 | |||
541 | acpi_ut_release_owner_id(&table_desc->owner_id); | ||
542 | 510 | ||
543 | /* Free the table descriptor */ | 511 | /******************************************************************************* |
512 | * | ||
513 | * FUNCTION: acpi_tb_set_table_loaded_flag | ||
514 | * | ||
515 | * PARAMETERS: table_index - Table index | ||
516 | * is_loaded - TRUE if table is loaded, FALSE otherwise | ||
517 | * | ||
518 | * RETURN: None | ||
519 | * | ||
520 | * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. | ||
521 | * | ||
522 | ******************************************************************************/ | ||
544 | 523 | ||
545 | next_desc = table_desc->next; | 524 | void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded) |
546 | ACPI_FREE(table_desc); | 525 | { |
547 | 526 | ||
548 | /* Return pointer to the next descriptor */ | 527 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
528 | if (table_index < acpi_gbl_root_table_list.count) { | ||
529 | if (is_loaded) { | ||
530 | acpi_gbl_root_table_list.tables[table_index].flags |= | ||
531 | ACPI_TABLE_IS_LOADED; | ||
532 | } else { | ||
533 | acpi_gbl_root_table_list.tables[table_index].flags &= | ||
534 | ~ACPI_TABLE_IS_LOADED; | ||
535 | } | ||
536 | } | ||
549 | 537 | ||
550 | return_PTR(next_desc); | 538 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
551 | } | 539 | } |
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c deleted file mode 100644 index 86a5fca9b739..000000000000 --- a/drivers/acpi/tables/tbrsdt.c +++ /dev/null | |||
@@ -1,307 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbrsdt - ACPI RSDT table utilities | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbrsdt") | ||
49 | |||
50 | /******************************************************************************* | ||
51 | * | ||
52 | * FUNCTION: acpi_tb_verify_rsdp | ||
53 | * | ||
54 | * PARAMETERS: Address - RSDP (Pointer to RSDT) | ||
55 | * | ||
56 | * RETURN: Status | ||
57 | * | ||
58 | * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) | ||
59 | * | ||
60 | ******************************************************************************/ | ||
61 | acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address) | ||
62 | { | ||
63 | struct acpi_table_desc table_info; | ||
64 | acpi_status status; | ||
65 | struct rsdp_descriptor *rsdp; | ||
66 | |||
67 | ACPI_FUNCTION_TRACE(tb_verify_rsdp); | ||
68 | |||
69 | switch (address->pointer_type) { | ||
70 | case ACPI_LOGICAL_POINTER: | ||
71 | |||
72 | rsdp = address->pointer.logical; | ||
73 | break; | ||
74 | |||
75 | case ACPI_PHYSICAL_POINTER: | ||
76 | /* | ||
77 | * Obtain access to the RSDP structure | ||
78 | */ | ||
79 | status = acpi_os_map_memory(address->pointer.physical, | ||
80 | sizeof(struct rsdp_descriptor), | ||
81 | ACPI_CAST_PTR(void, &rsdp)); | ||
82 | if (ACPI_FAILURE(status)) { | ||
83 | return_ACPI_STATUS(status); | ||
84 | } | ||
85 | break; | ||
86 | |||
87 | default: | ||
88 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
89 | } | ||
90 | |||
91 | /* Verify RSDP signature and checksum */ | ||
92 | |||
93 | status = acpi_tb_validate_rsdp(rsdp); | ||
94 | if (ACPI_FAILURE(status)) { | ||
95 | goto cleanup; | ||
96 | } | ||
97 | |||
98 | /* RSDP is ok. Init the table info */ | ||
99 | |||
100 | table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp); | ||
101 | table_info.length = sizeof(struct rsdp_descriptor); | ||
102 | |||
103 | if (address->pointer_type == ACPI_PHYSICAL_POINTER) { | ||
104 | table_info.allocation = ACPI_MEM_MAPPED; | ||
105 | } else { | ||
106 | table_info.allocation = ACPI_MEM_NOT_ALLOCATED; | ||
107 | } | ||
108 | |||
109 | /* Save the table pointers and allocation info */ | ||
110 | |||
111 | status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_RSDP, &table_info); | ||
112 | if (ACPI_FAILURE(status)) { | ||
113 | goto cleanup; | ||
114 | } | ||
115 | |||
116 | /* Save the RSDP in a global for easy access */ | ||
117 | |||
118 | acpi_gbl_RSDP = | ||
119 | ACPI_CAST_PTR(struct rsdp_descriptor, table_info.pointer); | ||
120 | return_ACPI_STATUS(status); | ||
121 | |||
122 | /* Error exit */ | ||
123 | cleanup: | ||
124 | |||
125 | if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) { | ||
126 | acpi_os_unmap_memory(rsdp, sizeof(struct rsdp_descriptor)); | ||
127 | } | ||
128 | return_ACPI_STATUS(status); | ||
129 | } | ||
130 | |||
131 | /******************************************************************************* | ||
132 | * | ||
133 | * FUNCTION: acpi_tb_get_rsdt_address | ||
134 | * | ||
135 | * PARAMETERS: out_address - Where the address is returned | ||
136 | * | ||
137 | * RETURN: None, Address | ||
138 | * | ||
139 | * DESCRIPTION: Extract the address of either the RSDT or XSDT, depending on the | ||
140 | * version of the RSDP and whether the XSDT pointer is valid | ||
141 | * | ||
142 | ******************************************************************************/ | ||
143 | |||
144 | void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address) | ||
145 | { | ||
146 | |||
147 | ACPI_FUNCTION_ENTRY(); | ||
148 | |||
149 | out_address->pointer_type = | ||
150 | acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; | ||
151 | |||
152 | /* Use XSDT if it is present */ | ||
153 | |||
154 | if ((acpi_gbl_RSDP->revision >= 2) && | ||
155 | acpi_gbl_RSDP->xsdt_physical_address) { | ||
156 | out_address->pointer.value = | ||
157 | acpi_gbl_RSDP->xsdt_physical_address; | ||
158 | acpi_gbl_root_table_type = ACPI_TABLE_TYPE_XSDT; | ||
159 | } else { | ||
160 | /* No XSDT, use the RSDT */ | ||
161 | |||
162 | out_address->pointer.value = | ||
163 | acpi_gbl_RSDP->rsdt_physical_address; | ||
164 | acpi_gbl_root_table_type = ACPI_TABLE_TYPE_RSDT; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | /******************************************************************************* | ||
169 | * | ||
170 | * FUNCTION: acpi_tb_validate_rsdt | ||
171 | * | ||
172 | * PARAMETERS: table_ptr - Addressable pointer to the RSDT. | ||
173 | * | ||
174 | * RETURN: Status | ||
175 | * | ||
176 | * DESCRIPTION: Validate signature for the RSDT or XSDT | ||
177 | * | ||
178 | ******************************************************************************/ | ||
179 | |||
180 | acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) | ||
181 | { | ||
182 | char *signature; | ||
183 | |||
184 | ACPI_FUNCTION_ENTRY(); | ||
185 | |||
186 | /* Validate minimum length */ | ||
187 | |||
188 | if (table_ptr->length < sizeof(struct acpi_table_header)) { | ||
189 | ACPI_ERROR((AE_INFO, | ||
190 | "RSDT/XSDT length (%X) is smaller than minimum (%zX)", | ||
191 | table_ptr->length, | ||
192 | sizeof(struct acpi_table_header))); | ||
193 | |||
194 | return (AE_INVALID_TABLE_LENGTH); | ||
195 | } | ||
196 | |||
197 | /* Search for appropriate signature, RSDT or XSDT */ | ||
198 | |||
199 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
200 | signature = RSDT_SIG; | ||
201 | } else { | ||
202 | signature = XSDT_SIG; | ||
203 | } | ||
204 | |||
205 | if (!ACPI_COMPARE_NAME(table_ptr->signature, signature)) { | ||
206 | |||
207 | /* Invalid RSDT or XSDT signature */ | ||
208 | |||
209 | ACPI_ERROR((AE_INFO, | ||
210 | "Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:")); | ||
211 | |||
212 | ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20); | ||
213 | |||
214 | ACPI_ERROR((AE_INFO, | ||
215 | "RSDT/XSDT signature at %X is invalid", | ||
216 | acpi_gbl_RSDP->rsdt_physical_address)); | ||
217 | |||
218 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
219 | ACPI_ERROR((AE_INFO, "Looking for RSDT")); | ||
220 | } else { | ||
221 | ACPI_ERROR((AE_INFO, "Looking for XSDT")); | ||
222 | } | ||
223 | |||
224 | ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48); | ||
225 | return (AE_BAD_SIGNATURE); | ||
226 | } | ||
227 | |||
228 | return (AE_OK); | ||
229 | } | ||
230 | |||
231 | /******************************************************************************* | ||
232 | * | ||
233 | * FUNCTION: acpi_tb_get_table_rsdt | ||
234 | * | ||
235 | * PARAMETERS: None | ||
236 | * | ||
237 | * RETURN: Status | ||
238 | * | ||
239 | * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) | ||
240 | * | ||
241 | ******************************************************************************/ | ||
242 | |||
243 | acpi_status acpi_tb_get_table_rsdt(void) | ||
244 | { | ||
245 | struct acpi_table_desc table_info; | ||
246 | acpi_status status; | ||
247 | struct acpi_pointer address; | ||
248 | |||
249 | ACPI_FUNCTION_TRACE(tb_get_table_rsdt); | ||
250 | |||
251 | /* Get the RSDT/XSDT via the RSDP */ | ||
252 | |||
253 | acpi_tb_get_rsdt_address(&address); | ||
254 | |||
255 | table_info.type = ACPI_TABLE_ID_XSDT; | ||
256 | status = acpi_tb_get_table(&address, &table_info); | ||
257 | if (ACPI_FAILURE(status)) { | ||
258 | ACPI_EXCEPTION((AE_INFO, status, | ||
259 | "Could not get the RSDT/XSDT")); | ||
260 | return_ACPI_STATUS(status); | ||
261 | } | ||
262 | |||
263 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
264 | "RSDP located at %p, points to RSDT physical=%8.8X%8.8X\n", | ||
265 | acpi_gbl_RSDP, | ||
266 | ACPI_FORMAT_UINT64(address.pointer.value))); | ||
267 | |||
268 | /* Check the RSDT or XSDT signature */ | ||
269 | |||
270 | status = acpi_tb_validate_rsdt(table_info.pointer); | ||
271 | if (ACPI_FAILURE(status)) { | ||
272 | goto error_cleanup; | ||
273 | } | ||
274 | |||
275 | /* Get the number of tables defined in the RSDT or XSDT */ | ||
276 | |||
277 | acpi_gbl_rsdt_table_count = acpi_tb_get_table_count(acpi_gbl_RSDP, | ||
278 | table_info.pointer); | ||
279 | |||
280 | /* Convert and/or copy to an XSDT structure */ | ||
281 | |||
282 | status = acpi_tb_convert_to_xsdt(&table_info); | ||
283 | if (ACPI_FAILURE(status)) { | ||
284 | goto error_cleanup; | ||
285 | } | ||
286 | |||
287 | /* Save the table pointers and allocation info */ | ||
288 | |||
289 | status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info); | ||
290 | if (ACPI_FAILURE(status)) { | ||
291 | goto error_cleanup; | ||
292 | } | ||
293 | |||
294 | acpi_gbl_XSDT = | ||
295 | ACPI_CAST_PTR(struct xsdt_descriptor, table_info.pointer); | ||
296 | |||
297 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); | ||
298 | return_ACPI_STATUS(status); | ||
299 | |||
300 | error_cleanup: | ||
301 | |||
302 | /* Free table allocated by acpi_tb_get_table */ | ||
303 | |||
304 | acpi_tb_delete_single_table(&table_info); | ||
305 | |||
306 | return_ACPI_STATUS(status); | ||
307 | } | ||
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 209a401801e3..4a2f99e2fc44 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c | |||
@@ -1,11 +1,11 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Module Name: tbutils - Table manipulation utilities | 3 | * Module Name: tbutils - table utilities |
4 | * | 4 | * |
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -48,137 +48,119 @@ | |||
48 | ACPI_MODULE_NAME("tbutils") | 48 | ACPI_MODULE_NAME("tbutils") |
49 | 49 | ||
50 | /* Local prototypes */ | 50 | /* Local prototypes */ |
51 | #ifdef ACPI_OBSOLETE_FUNCTIONS | 51 | static acpi_physical_address |
52 | acpi_status | 52 | acpi_tb_get_root_table_entry(u8 * table_entry, |
53 | acpi_tb_handle_to_object(u16 table_id, struct acpi_table_desc **table_desc); | 53 | acpi_native_uint table_entry_size); |
54 | #endif | ||
55 | 54 | ||
56 | /******************************************************************************* | 55 | /******************************************************************************* |
57 | * | 56 | * |
58 | * FUNCTION: acpi_tb_is_table_installed | 57 | * FUNCTION: acpi_tb_tables_loaded |
59 | * | ||
60 | * PARAMETERS: new_table_desc - Descriptor for new table being installed | ||
61 | * | 58 | * |
62 | * RETURN: Status - AE_ALREADY_EXISTS if the table is already installed | 59 | * PARAMETERS: None |
63 | * | 60 | * |
64 | * DESCRIPTION: Determine if an ACPI table is already installed | 61 | * RETURN: TRUE if required ACPI tables are loaded |
65 | * | 62 | * |
66 | * MUTEX: Table data structures should be locked | 63 | * DESCRIPTION: Determine if the minimum required ACPI tables are present |
64 | * (FADT, FACS, DSDT) | ||
67 | * | 65 | * |
68 | ******************************************************************************/ | 66 | ******************************************************************************/ |
69 | 67 | ||
70 | acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) | 68 | u8 acpi_tb_tables_loaded(void) |
71 | { | 69 | { |
72 | struct acpi_table_desc *table_desc; | ||
73 | |||
74 | ACPI_FUNCTION_TRACE(tb_is_table_installed); | ||
75 | 70 | ||
76 | /* Get the list descriptor and first table descriptor */ | 71 | if (acpi_gbl_root_table_list.count >= 3) { |
77 | 72 | return (TRUE); | |
78 | table_desc = acpi_gbl_table_lists[new_table_desc->type].next; | 73 | } |
79 | 74 | ||
80 | /* Examine all installed tables of this type */ | 75 | return (FALSE); |
76 | } | ||
81 | 77 | ||
82 | while (table_desc) { | 78 | /******************************************************************************* |
83 | /* | 79 | * |
84 | * If the table lengths match, perform a full bytewise compare. This | 80 | * FUNCTION: acpi_tb_print_table_header |
85 | * means that we will allow tables with duplicate oem_table_id(s), as | 81 | * |
86 | * long as the tables are different in some way. | 82 | * PARAMETERS: Address - Table physical address |
87 | * | 83 | * Header - Table header |
88 | * Checking if the table has been loaded into the namespace means that | 84 | * |
89 | * we don't check for duplicate tables during the initial installation | 85 | * RETURN: None |
90 | * of tables within the RSDT/XSDT. | 86 | * |
91 | */ | 87 | * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP. |
92 | if ((table_desc->loaded_into_namespace) && | 88 | * |
93 | (table_desc->pointer->length == | 89 | ******************************************************************************/ |
94 | new_table_desc->pointer->length) | ||
95 | && | ||
96 | (!ACPI_MEMCMP | ||
97 | (table_desc->pointer, new_table_desc->pointer, | ||
98 | new_table_desc->pointer->length))) { | ||
99 | |||
100 | /* Match: this table is already installed */ | ||
101 | |||
102 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
103 | "Table [%4.4s] already installed: Rev %X OemTableId [%8.8s]\n", | ||
104 | new_table_desc->pointer->signature, | ||
105 | new_table_desc->pointer->revision, | ||
106 | new_table_desc->pointer-> | ||
107 | oem_table_id)); | ||
108 | |||
109 | new_table_desc->owner_id = table_desc->owner_id; | ||
110 | new_table_desc->installed_desc = table_desc; | ||
111 | |||
112 | return_ACPI_STATUS(AE_ALREADY_EXISTS); | ||
113 | } | ||
114 | 90 | ||
115 | /* Get next table on the list */ | 91 | void |
92 | acpi_tb_print_table_header(acpi_physical_address address, | ||
93 | struct acpi_table_header *header) | ||
94 | { | ||
116 | 95 | ||
117 | table_desc = table_desc->next; | 96 | if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { |
97 | |||
98 | /* FACS only has signature and length fields of common table header */ | ||
99 | |||
100 | ACPI_INFO((AE_INFO, "%4.4s @ 0x%p/0x%04X", | ||
101 | header->signature, ACPI_CAST_PTR(void, address), | ||
102 | header->length)); | ||
103 | } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) { | ||
104 | |||
105 | /* RSDP has no common fields */ | ||
106 | |||
107 | ACPI_INFO((AE_INFO, "RSDP @ 0x%p/0x%04X (v%3.3d %6.6s)", | ||
108 | ACPI_CAST_PTR(void, address), | ||
109 | (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> | ||
110 | revision > | ||
111 | 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, | ||
112 | header)->length : 20, | ||
113 | ACPI_CAST_PTR(struct acpi_table_rsdp, | ||
114 | header)->revision, | ||
115 | ACPI_CAST_PTR(struct acpi_table_rsdp, | ||
116 | header)->oem_id)); | ||
117 | } else { | ||
118 | /* Standard ACPI table with full common header */ | ||
119 | |||
120 | ACPI_INFO((AE_INFO, | ||
121 | "%4.4s @ 0x%p/0x%04X (v%3.3d %6.6s %8.8s 0x%08X %4.4s 0x%08X)", | ||
122 | header->signature, ACPI_CAST_PTR(void, address), | ||
123 | header->length, header->revision, header->oem_id, | ||
124 | header->oem_table_id, header->oem_revision, | ||
125 | header->asl_compiler_id, | ||
126 | header->asl_compiler_revision)); | ||
118 | } | 127 | } |
119 | |||
120 | return_ACPI_STATUS(AE_OK); | ||
121 | } | 128 | } |
122 | 129 | ||
123 | /******************************************************************************* | 130 | /******************************************************************************* |
124 | * | 131 | * |
125 | * FUNCTION: acpi_tb_validate_table_header | 132 | * FUNCTION: acpi_tb_validate_checksum |
126 | * | 133 | * |
127 | * PARAMETERS: table_header - Logical pointer to the table | 134 | * PARAMETERS: Table - ACPI table to verify |
135 | * Length - Length of entire table | ||
128 | * | 136 | * |
129 | * RETURN: Status | 137 | * RETURN: Status |
130 | * | 138 | * |
131 | * DESCRIPTION: Check an ACPI table header for validity | 139 | * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns |
132 | * | 140 | * exception on bad checksum. |
133 | * NOTE: Table pointers are validated as follows: | ||
134 | * 1) Table pointer must point to valid physical memory | ||
135 | * 2) Signature must be 4 ASCII chars, even if we don't recognize the | ||
136 | * name | ||
137 | * 3) Table must be readable for length specified in the header | ||
138 | * 4) Table checksum must be valid (with the exception of the FACS | ||
139 | * which has no checksum because it contains variable fields) | ||
140 | * | 141 | * |
141 | ******************************************************************************/ | 142 | ******************************************************************************/ |
142 | 143 | ||
143 | acpi_status | 144 | acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) |
144 | acpi_tb_validate_table_header(struct acpi_table_header *table_header) | ||
145 | { | 145 | { |
146 | acpi_name signature; | 146 | u8 checksum; |
147 | |||
148 | ACPI_FUNCTION_ENTRY(); | ||
149 | |||
150 | /* Verify that this is a valid address */ | ||
151 | |||
152 | if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) { | ||
153 | ACPI_ERROR((AE_INFO, | ||
154 | "Cannot read table header at %p", table_header)); | ||
155 | |||
156 | return (AE_BAD_ADDRESS); | ||
157 | } | ||
158 | 147 | ||
159 | /* Ensure that the signature is 4 ASCII characters */ | 148 | /* Compute the checksum on the table */ |
160 | 149 | ||
161 | ACPI_MOVE_32_TO_32(&signature, table_header->signature); | 150 | checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); |
162 | if (!acpi_ut_valid_acpi_name(signature)) { | ||
163 | ACPI_ERROR((AE_INFO, "Invalid table signature 0x%8.8X", | ||
164 | signature)); | ||
165 | 151 | ||
166 | ACPI_DUMP_BUFFER(table_header, | 152 | /* Checksum ok? (should be zero) */ |
167 | sizeof(struct acpi_table_header)); | ||
168 | return (AE_BAD_SIGNATURE); | ||
169 | } | ||
170 | 153 | ||
171 | /* Validate the table length */ | 154 | if (checksum) { |
155 | ACPI_WARNING((AE_INFO, | ||
156 | "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X", | ||
157 | table->signature, table->checksum, | ||
158 | (u8) (table->checksum - checksum))); | ||
172 | 159 | ||
173 | if (table_header->length < sizeof(struct acpi_table_header)) { | 160 | #if (ACPI_CHECKSUM_ABORT) |
174 | ACPI_ERROR((AE_INFO, | ||
175 | "Invalid length 0x%X in table with signature %4.4s", | ||
176 | (u32) table_header->length, | ||
177 | ACPI_CAST_PTR(char, &signature))); | ||
178 | 161 | ||
179 | ACPI_DUMP_BUFFER(table_header, | 162 | return (AE_BAD_CHECKSUM); |
180 | sizeof(struct acpi_table_header)); | 163 | #endif |
181 | return (AE_BAD_HEADER); | ||
182 | } | 164 | } |
183 | 165 | ||
184 | return (AE_OK); | 166 | return (AE_OK); |
@@ -186,157 +168,320 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) | |||
186 | 168 | ||
187 | /******************************************************************************* | 169 | /******************************************************************************* |
188 | * | 170 | * |
189 | * FUNCTION: acpi_tb_sum_table | 171 | * FUNCTION: acpi_tb_checksum |
190 | * | 172 | * |
191 | * PARAMETERS: Buffer - Buffer to sum | 173 | * PARAMETERS: Buffer - Pointer to memory region to be checked |
192 | * Length - Size of the buffer | 174 | * Length - Length of this memory region |
193 | * | 175 | * |
194 | * RETURN: 8 bit sum of buffer | 176 | * RETURN: Checksum (u8) |
195 | * | 177 | * |
196 | * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it. | 178 | * DESCRIPTION: Calculates circular checksum of memory region. |
197 | * | 179 | * |
198 | ******************************************************************************/ | 180 | ******************************************************************************/ |
199 | 181 | ||
200 | u8 acpi_tb_sum_table(void *buffer, u32 length) | 182 | u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length) |
201 | { | 183 | { |
202 | acpi_native_uint i; | ||
203 | u8 sum = 0; | 184 | u8 sum = 0; |
185 | u8 *end = buffer + length; | ||
204 | 186 | ||
205 | if (!buffer || !length) { | 187 | while (buffer < end) { |
206 | return (0); | 188 | sum = (u8) (sum + *(buffer++)); |
207 | } | 189 | } |
208 | 190 | ||
209 | for (i = 0; i < length; i++) { | 191 | return sum; |
210 | sum = (u8) (sum + ((u8 *) buffer)[i]); | ||
211 | } | ||
212 | return (sum); | ||
213 | } | 192 | } |
214 | 193 | ||
215 | /******************************************************************************* | 194 | /******************************************************************************* |
216 | * | 195 | * |
217 | * FUNCTION: acpi_tb_generate_checksum | 196 | * FUNCTION: acpi_tb_install_table |
218 | * | 197 | * |
219 | * PARAMETERS: Table - Pointer to a valid ACPI table (with a | 198 | * PARAMETERS: Address - Physical address of DSDT or FACS |
220 | * standard ACPI header) | 199 | * Flags - Flags |
200 | * Signature - Table signature, NULL if no need to | ||
201 | * match | ||
202 | * table_index - Index into root table array | ||
221 | * | 203 | * |
222 | * RETURN: 8 bit checksum of buffer | 204 | * RETURN: None |
223 | * | 205 | * |
224 | * DESCRIPTION: Computes an 8 bit checksum of the table. | 206 | * DESCRIPTION: Install an ACPI table into the global data structure. |
225 | * | 207 | * |
226 | ******************************************************************************/ | 208 | ******************************************************************************/ |
227 | 209 | ||
228 | u8 acpi_tb_generate_checksum(struct acpi_table_header * table) | 210 | void |
211 | acpi_tb_install_table(acpi_physical_address address, | ||
212 | u8 flags, char *signature, acpi_native_uint table_index) | ||
229 | { | 213 | { |
230 | u8 checksum; | 214 | struct acpi_table_header *table; |
215 | |||
216 | if (!address) { | ||
217 | ACPI_ERROR((AE_INFO, | ||
218 | "Null physical address for ACPI table [%s]", | ||
219 | signature)); | ||
220 | return; | ||
221 | } | ||
222 | |||
223 | /* Map just the table header */ | ||
224 | |||
225 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | ||
226 | if (!table) { | ||
227 | return; | ||
228 | } | ||
229 | |||
230 | /* If a particular signature is expected, signature must match */ | ||
231 | |||
232 | if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { | ||
233 | ACPI_ERROR((AE_INFO, | ||
234 | "Invalid signature 0x%X for ACPI table [%s]", | ||
235 | *ACPI_CAST_PTR(u32, table->signature), signature)); | ||
236 | goto unmap_and_exit; | ||
237 | } | ||
231 | 238 | ||
232 | /* Sum the entire table as-is */ | 239 | /* Initialize the table entry */ |
233 | 240 | ||
234 | checksum = acpi_tb_sum_table(table, table->length); | 241 | acpi_gbl_root_table_list.tables[table_index].address = address; |
242 | acpi_gbl_root_table_list.tables[table_index].length = table->length; | ||
243 | acpi_gbl_root_table_list.tables[table_index].flags = flags; | ||
235 | 244 | ||
236 | /* Subtract off the existing checksum value in the table */ | 245 | ACPI_MOVE_32_TO_32(& |
246 | (acpi_gbl_root_table_list.tables[table_index]. | ||
247 | signature), table->signature); | ||
237 | 248 | ||
238 | checksum = (u8) (checksum - table->checksum); | 249 | acpi_tb_print_table_header(address, table); |
239 | 250 | ||
240 | /* Compute the final checksum */ | 251 | if (table_index == ACPI_TABLE_INDEX_DSDT) { |
241 | 252 | ||
242 | checksum = (u8) (0 - checksum); | 253 | /* Global integer width is based upon revision of the DSDT */ |
243 | return (checksum); | 254 | |
255 | acpi_ut_set_integer_width(table->revision); | ||
256 | } | ||
257 | |||
258 | unmap_and_exit: | ||
259 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
244 | } | 260 | } |
245 | 261 | ||
246 | /******************************************************************************* | 262 | /******************************************************************************* |
247 | * | 263 | * |
248 | * FUNCTION: acpi_tb_set_checksum | 264 | * FUNCTION: acpi_tb_get_root_table_entry |
249 | * | 265 | * |
250 | * PARAMETERS: Table - Pointer to a valid ACPI table (with a | 266 | * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry |
251 | * standard ACPI header) | 267 | * table_entry_size - sizeof 32 or 64 (RSDT or XSDT) |
252 | * | 268 | * |
253 | * RETURN: None. Sets the table checksum field | 269 | * RETURN: Physical address extracted from the root table |
254 | * | 270 | * |
255 | * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the | 271 | * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on |
256 | * checksum into the table header. | 272 | * both 32-bit and 64-bit platforms |
273 | * | ||
274 | * NOTE: acpi_physical_address is 32-bit on 32-bit platforms, 64-bit on | ||
275 | * 64-bit platforms. | ||
257 | * | 276 | * |
258 | ******************************************************************************/ | 277 | ******************************************************************************/ |
259 | 278 | ||
260 | void acpi_tb_set_checksum(struct acpi_table_header *table) | 279 | static acpi_physical_address |
280 | acpi_tb_get_root_table_entry(u8 * table_entry, | ||
281 | acpi_native_uint table_entry_size) | ||
261 | { | 282 | { |
283 | u64 address64; | ||
284 | |||
285 | /* | ||
286 | * Get the table physical address (32-bit for RSDT, 64-bit for XSDT): | ||
287 | * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT | ||
288 | */ | ||
289 | if (table_entry_size == sizeof(u32)) { | ||
290 | /* | ||
291 | * 32-bit platform, RSDT: Return 32-bit table entry | ||
292 | * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return | ||
293 | */ | ||
294 | return ((acpi_physical_address) | ||
295 | (*ACPI_CAST_PTR(u32, table_entry))); | ||
296 | } else { | ||
297 | /* | ||
298 | * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return | ||
299 | * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit | ||
300 | */ | ||
301 | ACPI_MOVE_64_TO_64(&address64, table_entry); | ||
262 | 302 | ||
263 | table->checksum = acpi_tb_generate_checksum(table); | 303 | #if ACPI_MACHINE_WIDTH == 32 |
304 | if (address64 > ACPI_UINT32_MAX) { | ||
305 | |||
306 | /* Will truncate 64-bit address to 32 bits, issue warning */ | ||
307 | |||
308 | ACPI_WARNING((AE_INFO, | ||
309 | "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating", | ||
310 | ACPI_FORMAT_UINT64(address64))); | ||
311 | } | ||
312 | #endif | ||
313 | return ((acpi_physical_address) (address64)); | ||
314 | } | ||
264 | } | 315 | } |
265 | 316 | ||
266 | /******************************************************************************* | 317 | /******************************************************************************* |
267 | * | 318 | * |
268 | * FUNCTION: acpi_tb_verify_table_checksum | 319 | * FUNCTION: acpi_tb_parse_root_table |
320 | * | ||
321 | * PARAMETERS: Rsdp - Pointer to the RSDP | ||
322 | * Flags - Flags | ||
269 | * | 323 | * |
270 | * PARAMETERS: *table_header - ACPI table to verify | 324 | * RETURN: Status |
271 | * | 325 | * |
272 | * RETURN: 8 bit checksum of table | 326 | * DESCRIPTION: This function is called to parse the Root System Description |
327 | * Table (RSDT or XSDT) | ||
273 | * | 328 | * |
274 | * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares | 329 | * NOTE: Tables are mapped (not copied) for efficiency. The FACS must |
275 | * it to the existing checksum value. | 330 | * be mapped and cannot be copied because it contains the actual |
331 | * memory location of the ACPI Global Lock. | ||
276 | * | 332 | * |
277 | ******************************************************************************/ | 333 | ******************************************************************************/ |
278 | 334 | ||
279 | acpi_status | 335 | acpi_status __init |
280 | acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) | 336 | acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) |
281 | { | 337 | { |
282 | u8 checksum; | 338 | struct acpi_table_rsdp *rsdp; |
339 | acpi_native_uint table_entry_size; | ||
340 | acpi_native_uint i; | ||
341 | u32 table_count; | ||
342 | struct acpi_table_header *table; | ||
343 | acpi_physical_address address; | ||
344 | u32 length; | ||
345 | u8 *table_entry; | ||
346 | acpi_status status; | ||
347 | |||
348 | ACPI_FUNCTION_TRACE(tb_parse_root_table); | ||
349 | |||
350 | /* | ||
351 | * Map the entire RSDP and extract the address of the RSDT or XSDT | ||
352 | */ | ||
353 | rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp)); | ||
354 | if (!rsdp) { | ||
355 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
356 | } | ||
283 | 357 | ||
284 | ACPI_FUNCTION_TRACE(tb_verify_table_checksum); | 358 | acpi_tb_print_table_header(rsdp_address, |
359 | ACPI_CAST_PTR(struct acpi_table_header, | ||
360 | rsdp)); | ||
285 | 361 | ||
286 | /* Compute the checksum on the table */ | 362 | /* Differentiate between RSDT and XSDT root tables */ |
287 | 363 | ||
288 | checksum = acpi_tb_generate_checksum(table_header); | 364 | if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { |
365 | /* | ||
366 | * Root table is an XSDT (64-bit physical addresses). We must use the | ||
367 | * XSDT if the revision is > 1 and the XSDT pointer is present, as per | ||
368 | * the ACPI specification. | ||
369 | */ | ||
370 | address = (acpi_physical_address) rsdp->xsdt_physical_address; | ||
371 | table_entry_size = sizeof(u64); | ||
372 | } else { | ||
373 | /* Root table is an RSDT (32-bit physical addresses) */ | ||
289 | 374 | ||
290 | /* Checksum ok? */ | 375 | address = (acpi_physical_address) rsdp->rsdt_physical_address; |
376 | table_entry_size = sizeof(u32); | ||
377 | } | ||
291 | 378 | ||
292 | if (checksum == table_header->checksum) { | 379 | /* |
293 | return_ACPI_STATUS(AE_OK); | 380 | * It is not possible to map more than one entry in some environments, |
381 | * so unmap the RSDP here before mapping other tables | ||
382 | */ | ||
383 | acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); | ||
384 | |||
385 | /* Map the RSDT/XSDT table header to get the full table length */ | ||
386 | |||
387 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | ||
388 | if (!table) { | ||
389 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
294 | } | 390 | } |
295 | 391 | ||
296 | ACPI_WARNING((AE_INFO, | 392 | acpi_tb_print_table_header(address, table); |
297 | "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X", | ||
298 | table_header->signature, table_header->checksum, | ||
299 | checksum)); | ||
300 | 393 | ||
301 | return_ACPI_STATUS(AE_BAD_CHECKSUM); | 394 | /* Get the length of the full table, verify length and map entire table */ |
302 | } | ||
303 | 395 | ||
304 | #ifdef ACPI_OBSOLETE_FUNCTIONS | 396 | length = table->length; |
305 | /******************************************************************************* | 397 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); |
306 | * | ||
307 | * FUNCTION: acpi_tb_handle_to_object | ||
308 | * | ||
309 | * PARAMETERS: table_id - Id for which the function is searching | ||
310 | * table_desc - Pointer to return the matching table | ||
311 | * descriptor. | ||
312 | * | ||
313 | * RETURN: Search the tables to find one with a matching table_id and | ||
314 | * return a pointer to that table descriptor. | ||
315 | * | ||
316 | ******************************************************************************/ | ||
317 | 398 | ||
318 | acpi_status | 399 | if (length < sizeof(struct acpi_table_header)) { |
319 | acpi_tb_handle_to_object(u16 table_id, | 400 | ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", |
320 | struct acpi_table_desc **return_table_desc) | 401 | length)); |
321 | { | 402 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); |
322 | u32 i; | 403 | } |
323 | struct acpi_table_desc *table_desc; | ||
324 | 404 | ||
325 | ACPI_FUNCTION_NAME(tb_handle_to_object); | 405 | table = acpi_os_map_memory(address, length); |
406 | if (!table) { | ||
407 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
408 | } | ||
409 | |||
410 | /* Validate the root table checksum */ | ||
411 | |||
412 | status = acpi_tb_verify_checksum(table, length); | ||
413 | if (ACPI_FAILURE(status)) { | ||
414 | acpi_os_unmap_memory(table, length); | ||
415 | return_ACPI_STATUS(status); | ||
416 | } | ||
326 | 417 | ||
327 | for (i = 0; i < ACPI_TABLE_MAX; i++) { | 418 | /* Calculate the number of tables described in the root table */ |
328 | table_desc = acpi_gbl_table_lists[i].next; | 419 | |
329 | while (table_desc) { | 420 | table_count = |
330 | if (table_desc->table_id == table_id) { | 421 | (u32) ((table->length - |
331 | *return_table_desc = table_desc; | 422 | sizeof(struct acpi_table_header)) / table_entry_size); |
332 | return (AE_OK); | 423 | |
424 | /* | ||
425 | * First two entries in the table array are reserved for the DSDT and FACS, | ||
426 | * which are not actually present in the RSDT/XSDT - they come from the FADT | ||
427 | */ | ||
428 | table_entry = | ||
429 | ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); | ||
430 | acpi_gbl_root_table_list.count = 2; | ||
431 | |||
432 | /* | ||
433 | * Initialize the root table array from the RSDT/XSDT | ||
434 | */ | ||
435 | for (i = 0; i < table_count; i++) { | ||
436 | if (acpi_gbl_root_table_list.count >= | ||
437 | acpi_gbl_root_table_list.size) { | ||
438 | |||
439 | /* There is no more room in the root table array, attempt resize */ | ||
440 | |||
441 | status = acpi_tb_resize_root_table_list(); | ||
442 | if (ACPI_FAILURE(status)) { | ||
443 | ACPI_WARNING((AE_INFO, | ||
444 | "Truncating %u table entries!", | ||
445 | (unsigned) | ||
446 | (acpi_gbl_root_table_list.size - | ||
447 | acpi_gbl_root_table_list. | ||
448 | count))); | ||
449 | break; | ||
333 | } | 450 | } |
451 | } | ||
452 | |||
453 | /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ | ||
334 | 454 | ||
335 | table_desc = table_desc->next; | 455 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. |
456 | address = | ||
457 | acpi_tb_get_root_table_entry(table_entry, table_entry_size); | ||
458 | |||
459 | table_entry += table_entry_size; | ||
460 | acpi_gbl_root_table_list.count++; | ||
461 | } | ||
462 | |||
463 | /* | ||
464 | * It is not possible to map more than one entry in some environments, | ||
465 | * so unmap the root table here before mapping other tables | ||
466 | */ | ||
467 | acpi_os_unmap_memory(table, length); | ||
468 | |||
469 | /* | ||
470 | * Complete the initialization of the root table array by examining | ||
471 | * the header of each table | ||
472 | */ | ||
473 | for (i = 2; i < acpi_gbl_root_table_list.count; i++) { | ||
474 | acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. | ||
475 | address, flags, NULL, i); | ||
476 | |||
477 | /* Special case for FADT - get the DSDT and FACS */ | ||
478 | |||
479 | if (ACPI_COMPARE_NAME | ||
480 | (&acpi_gbl_root_table_list.tables[i].signature, | ||
481 | ACPI_SIG_FADT)) { | ||
482 | acpi_tb_parse_fadt(i, flags); | ||
336 | } | 483 | } |
337 | } | 484 | } |
338 | 485 | ||
339 | ACPI_ERROR((AE_INFO, "TableId=%X does not exist", table_id)); | 486 | return_ACPI_STATUS(AE_OK); |
340 | return (AE_BAD_PARAMETER); | ||
341 | } | 487 | } |
342 | #endif | ||
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 7767987be15a..807978d5381a 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2006, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -49,81 +49,158 @@ | |||
49 | #define _COMPONENT ACPI_TABLES | 49 | #define _COMPONENT ACPI_TABLES |
50 | ACPI_MODULE_NAME("tbxface") | 50 | ACPI_MODULE_NAME("tbxface") |
51 | 51 | ||
52 | /* Local prototypes */ | ||
53 | static acpi_status acpi_tb_load_namespace(void); | ||
54 | |||
52 | /******************************************************************************* | 55 | /******************************************************************************* |
53 | * | 56 | * |
54 | * FUNCTION: acpi_load_tables | 57 | * FUNCTION: acpi_allocate_root_table |
55 | * | 58 | * |
56 | * PARAMETERS: None | 59 | * PARAMETERS: initial_table_count - Size of initial_table_array, in number of |
60 | * struct acpi_table_desc structures | ||
57 | * | 61 | * |
58 | * RETURN: Status | 62 | * RETURN: Status |
59 | * | 63 | * |
60 | * DESCRIPTION: This function is called to load the ACPI tables from the | 64 | * DESCRIPTION: Allocate a root table array. Used by i_aSL compiler and |
61 | * provided RSDT | 65 | * acpi_initialize_tables. |
62 | * | 66 | * |
63 | ******************************************************************************/ | 67 | ******************************************************************************/ |
64 | acpi_status acpi_load_tables(void) | 68 | |
69 | acpi_status acpi_allocate_root_table(u32 initial_table_count) | ||
65 | { | 70 | { |
66 | struct acpi_pointer rsdp_address; | ||
67 | acpi_status status; | ||
68 | 71 | ||
69 | ACPI_FUNCTION_TRACE(acpi_load_tables); | 72 | acpi_gbl_root_table_list.size = initial_table_count; |
73 | acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE; | ||
70 | 74 | ||
71 | /* Get the RSDP */ | 75 | return (acpi_tb_resize_root_table_list()); |
76 | } | ||
72 | 77 | ||
73 | status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING, | 78 | /******************************************************************************* |
74 | &rsdp_address); | 79 | * |
75 | if (ACPI_FAILURE(status)) { | 80 | * FUNCTION: acpi_initialize_tables |
76 | ACPI_EXCEPTION((AE_INFO, status, "Could not get the RSDP")); | 81 | * |
77 | goto error_exit; | 82 | * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated |
78 | } | 83 | * struct acpi_table_desc structures. If NULL, the |
84 | * array is dynamically allocated. | ||
85 | * initial_table_count - Size of initial_table_array, in number of | ||
86 | * struct acpi_table_desc structures | ||
87 | * allow_realloc - Flag to tell Table Manager if resize of | ||
88 | * pre-allocated array is allowed. Ignored | ||
89 | * if initial_table_array is NULL. | ||
90 | * | ||
91 | * RETURN: Status | ||
92 | * | ||
93 | * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT. | ||
94 | * | ||
95 | * NOTE: Allows static allocation of the initial table array in order | ||
96 | * to avoid the use of dynamic memory in confined environments | ||
97 | * such as the kernel boot sequence where it may not be available. | ||
98 | * | ||
99 | * If the host OS memory managers are initialized, use NULL for | ||
100 | * initial_table_array, and the table will be dynamically allocated. | ||
101 | * | ||
102 | ******************************************************************************/ | ||
79 | 103 | ||
80 | /* Map and validate the RSDP */ | 104 | acpi_status __init |
105 | acpi_initialize_tables(struct acpi_table_desc * initial_table_array, | ||
106 | u32 initial_table_count, u8 allow_resize) | ||
107 | { | ||
108 | acpi_physical_address rsdp_address; | ||
109 | acpi_status status; | ||
81 | 110 | ||
82 | acpi_gbl_table_flags = rsdp_address.pointer_type; | 111 | ACPI_FUNCTION_TRACE(acpi_initialize_tables); |
83 | 112 | ||
84 | status = acpi_tb_verify_rsdp(&rsdp_address); | 113 | /* |
85 | if (ACPI_FAILURE(status)) { | 114 | * Set up the Root Table Array |
86 | ACPI_EXCEPTION((AE_INFO, status, "During RSDP validation")); | 115 | * Allocate the table array if requested |
87 | goto error_exit; | 116 | */ |
117 | if (!initial_table_array) { | ||
118 | status = acpi_allocate_root_table(initial_table_count); | ||
119 | if (ACPI_FAILURE(status)) { | ||
120 | return_ACPI_STATUS(status); | ||
121 | } | ||
122 | } else { | ||
123 | /* Root Table Array has been statically allocated by the host */ | ||
124 | |||
125 | ACPI_MEMSET(initial_table_array, 0, | ||
126 | initial_table_count * | ||
127 | sizeof(struct acpi_table_desc)); | ||
128 | |||
129 | acpi_gbl_root_table_list.tables = initial_table_array; | ||
130 | acpi_gbl_root_table_list.size = initial_table_count; | ||
131 | acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN; | ||
132 | if (allow_resize) { | ||
133 | acpi_gbl_root_table_list.flags |= | ||
134 | ACPI_ROOT_ALLOW_RESIZE; | ||
135 | } | ||
88 | } | 136 | } |
89 | 137 | ||
90 | /* Get the RSDT via the RSDP */ | 138 | /* Get the address of the RSDP */ |
91 | 139 | ||
92 | status = acpi_tb_get_table_rsdt(); | 140 | rsdp_address = acpi_os_get_root_pointer(); |
93 | if (ACPI_FAILURE(status)) { | 141 | if (!rsdp_address) { |
94 | ACPI_EXCEPTION((AE_INFO, status, "Could not load RSDT")); | 142 | return_ACPI_STATUS(AE_NOT_FOUND); |
95 | goto error_exit; | ||
96 | } | 143 | } |
97 | 144 | ||
98 | /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */ | 145 | /* |
146 | * Get the root table (RSDT or XSDT) and extract all entries to the local | ||
147 | * Root Table Array. This array contains the information of the RSDT/XSDT | ||
148 | * in a common, more useable format. | ||
149 | */ | ||
150 | status = | ||
151 | acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED); | ||
152 | return_ACPI_STATUS(status); | ||
153 | } | ||
99 | 154 | ||
100 | status = acpi_tb_get_required_tables(); | 155 | /******************************************************************************* |
101 | if (ACPI_FAILURE(status)) { | 156 | * |
102 | ACPI_EXCEPTION((AE_INFO, status, | 157 | * FUNCTION: acpi_reallocate_root_table |
103 | "Could not get all required tables (DSDT/FADT/FACS)")); | 158 | * |
104 | goto error_exit; | 159 | * PARAMETERS: None |
160 | * | ||
161 | * RETURN: Status | ||
162 | * | ||
163 | * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the | ||
164 | * root list from the previously provided scratch area. Should | ||
165 | * be called once dynamic memory allocation is available in the | ||
166 | * kernel | ||
167 | * | ||
168 | ******************************************************************************/ | ||
169 | acpi_status acpi_reallocate_root_table(void) | ||
170 | { | ||
171 | struct acpi_table_desc *tables; | ||
172 | acpi_size new_size; | ||
173 | |||
174 | ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); | ||
175 | |||
176 | /* | ||
177 | * Only reallocate the root table if the host provided a static buffer | ||
178 | * for the table array in the call to acpi_initialize_tables. | ||
179 | */ | ||
180 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | ||
181 | return_ACPI_STATUS(AE_SUPPORT); | ||
105 | } | 182 | } |
106 | 183 | ||
107 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); | 184 | new_size = |
185 | (acpi_gbl_root_table_list.count + | ||
186 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc); | ||
108 | 187 | ||
109 | /* Load the namespace from the tables */ | 188 | /* Create new array and copy the old array */ |
110 | 189 | ||
111 | status = acpi_ns_load_namespace(); | 190 | tables = ACPI_ALLOCATE_ZEROED(new_size); |
112 | if (ACPI_FAILURE(status)) { | 191 | if (!tables) { |
113 | ACPI_EXCEPTION((AE_INFO, status, "Could not load namespace")); | 192 | return_ACPI_STATUS(AE_NO_MEMORY); |
114 | goto error_exit; | ||
115 | } | 193 | } |
116 | 194 | ||
117 | return_ACPI_STATUS(AE_OK); | 195 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size); |
118 | 196 | ||
119 | error_exit: | 197 | acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count; |
120 | ACPI_EXCEPTION((AE_INFO, status, "Could not load tables")); | 198 | acpi_gbl_root_table_list.tables = tables; |
121 | return_ACPI_STATUS(status); | 199 | acpi_gbl_root_table_list.flags = |
122 | } | 200 | ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE; |
123 | 201 | ||
124 | ACPI_EXPORT_SYMBOL(acpi_load_tables) | 202 | return_ACPI_STATUS(AE_OK); |
125 | 203 | } | |
126 | #ifdef ACPI_FUTURE_USAGE | ||
127 | /******************************************************************************* | 204 | /******************************************************************************* |
128 | * | 205 | * |
129 | * FUNCTION: acpi_load_table | 206 | * FUNCTION: acpi_load_table |
@@ -142,289 +219,405 @@ ACPI_EXPORT_SYMBOL(acpi_load_tables) | |||
142 | acpi_status acpi_load_table(struct acpi_table_header *table_ptr) | 219 | acpi_status acpi_load_table(struct acpi_table_header *table_ptr) |
143 | { | 220 | { |
144 | acpi_status status; | 221 | acpi_status status; |
145 | struct acpi_table_desc table_info; | 222 | acpi_native_uint table_index; |
146 | struct acpi_pointer address; | 223 | struct acpi_table_desc table_desc; |
147 | 224 | ||
148 | ACPI_FUNCTION_TRACE(acpi_load_table); | 225 | if (!table_ptr) |
226 | return AE_BAD_PARAMETER; | ||
149 | 227 | ||
150 | if (!table_ptr) { | 228 | ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); |
151 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 229 | table_desc.pointer = table_ptr; |
152 | } | 230 | table_desc.length = table_ptr->length; |
153 | 231 | table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN; | |
154 | /* Copy the table to a local buffer */ | ||
155 | 232 | ||
156 | address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; | 233 | /* |
157 | address.pointer.logical = table_ptr; | 234 | * Install the new table into the local data structures |
158 | 235 | */ | |
159 | status = acpi_tb_get_table_body(&address, table_ptr, &table_info); | 236 | status = acpi_tb_add_table(&table_desc, &table_index); |
160 | if (ACPI_FAILURE(status)) { | 237 | if (ACPI_FAILURE(status)) { |
161 | return_ACPI_STATUS(status); | 238 | return status; |
162 | } | 239 | } |
240 | status = acpi_ns_load_table(table_index, acpi_gbl_root_node); | ||
241 | return status; | ||
242 | } | ||
163 | 243 | ||
164 | /* Check signature for a valid table type */ | 244 | ACPI_EXPORT_SYMBOL(acpi_load_table) |
165 | |||
166 | status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL); | ||
167 | if (ACPI_FAILURE(status)) { | ||
168 | return_ACPI_STATUS(status); | ||
169 | } | ||
170 | 245 | ||
171 | /* Install the new table into the local data structures */ | 246 | /****************************************************************************** |
247 | * | ||
248 | * FUNCTION: acpi_get_table_header | ||
249 | * | ||
250 | * PARAMETERS: Signature - ACPI signature of needed table | ||
251 | * Instance - Which instance (for SSDTs) | ||
252 | * out_table_header - The pointer to the table header to fill | ||
253 | * | ||
254 | * RETURN: Status and pointer to mapped table header | ||
255 | * | ||
256 | * DESCRIPTION: Finds an ACPI table header. | ||
257 | * | ||
258 | * NOTE: Caller is responsible in unmapping the header with | ||
259 | * acpi_os_unmap_memory | ||
260 | * | ||
261 | *****************************************************************************/ | ||
262 | acpi_status | ||
263 | acpi_get_table_header(char *signature, | ||
264 | acpi_native_uint instance, | ||
265 | struct acpi_table_header *out_table_header) | ||
266 | { | ||
267 | acpi_native_uint i; | ||
268 | acpi_native_uint j; | ||
269 | struct acpi_table_header *header; | ||
172 | 270 | ||
173 | status = acpi_tb_install_table(&table_info); | 271 | /* Parameter validation */ |
174 | if (ACPI_FAILURE(status)) { | ||
175 | if (status == AE_ALREADY_EXISTS) { | ||
176 | 272 | ||
177 | /* Table already exists, no error */ | 273 | if (!signature || !out_table_header) { |
274 | return (AE_BAD_PARAMETER); | ||
275 | } | ||
178 | 276 | ||
179 | status = AE_OK; | 277 | /* |
278 | * Walk the root table list | ||
279 | */ | ||
280 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { | ||
281 | if (!ACPI_COMPARE_NAME | ||
282 | (&(acpi_gbl_root_table_list.tables[i].signature), | ||
283 | signature)) { | ||
284 | continue; | ||
180 | } | 285 | } |
181 | 286 | ||
182 | /* Free table allocated by acpi_tb_get_table_body */ | 287 | if (++j < instance) { |
288 | continue; | ||
289 | } | ||
183 | 290 | ||
184 | acpi_tb_delete_single_table(&table_info); | 291 | if (!acpi_gbl_root_table_list.tables[i].pointer) { |
185 | return_ACPI_STATUS(status); | 292 | if ((acpi_gbl_root_table_list.tables[i]. |
293 | flags & ACPI_TABLE_ORIGIN_MASK) == | ||
294 | ACPI_TABLE_ORIGIN_MAPPED) { | ||
295 | header = | ||
296 | acpi_os_map_memory(acpi_gbl_root_table_list. | ||
297 | tables[i].address, | ||
298 | sizeof(struct | ||
299 | acpi_table_header)); | ||
300 | if (!header) { | ||
301 | return AE_NO_MEMORY; | ||
302 | } | ||
303 | ACPI_MEMCPY(out_table_header, header, | ||
304 | sizeof(struct acpi_table_header)); | ||
305 | acpi_os_unmap_memory(header, | ||
306 | sizeof(struct | ||
307 | acpi_table_header)); | ||
308 | } else { | ||
309 | return AE_NOT_FOUND; | ||
310 | } | ||
311 | } else { | ||
312 | ACPI_MEMCPY(out_table_header, | ||
313 | acpi_gbl_root_table_list.tables[i].pointer, | ||
314 | sizeof(struct acpi_table_header)); | ||
315 | } | ||
316 | return (AE_OK); | ||
186 | } | 317 | } |
187 | 318 | ||
188 | /* Convert the table to common format if necessary */ | 319 | return (AE_NOT_FOUND); |
189 | 320 | } | |
190 | switch (table_info.type) { | ||
191 | case ACPI_TABLE_ID_FADT: | ||
192 | |||
193 | status = acpi_tb_convert_table_fadt(); | ||
194 | break; | ||
195 | |||
196 | case ACPI_TABLE_ID_FACS: | ||
197 | |||
198 | status = acpi_tb_build_common_facs(&table_info); | ||
199 | break; | ||
200 | 321 | ||
201 | default: | 322 | ACPI_EXPORT_SYMBOL(acpi_get_table_header) |
202 | /* Load table into namespace if it contains executable AML */ | ||
203 | 323 | ||
204 | status = | ||
205 | acpi_ns_load_table(table_info.installed_desc, | ||
206 | acpi_gbl_root_node); | ||
207 | break; | ||
208 | } | ||
209 | 324 | ||
210 | if (ACPI_FAILURE(status)) { | 325 | /****************************************************************************** |
326 | * | ||
327 | * FUNCTION: acpi_unload_table_id | ||
328 | * | ||
329 | * PARAMETERS: id - Owner ID of the table to be removed. | ||
330 | * | ||
331 | * RETURN: Status | ||
332 | * | ||
333 | * DESCRIPTION: This routine is used to force the unload of a table (by id) | ||
334 | * | ||
335 | ******************************************************************************/ | ||
336 | acpi_status acpi_unload_table_id(acpi_owner_id id) | ||
337 | { | ||
338 | int i; | ||
339 | acpi_status status = AE_NOT_EXIST; | ||
211 | 340 | ||
212 | /* Uninstall table and free the buffer */ | 341 | ACPI_FUNCTION_TRACE(acpi_unload_table); |
213 | 342 | ||
214 | (void)acpi_tb_uninstall_table(table_info.installed_desc); | 343 | /* Find table from the requested type list */ |
344 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { | ||
345 | if (id != acpi_gbl_root_table_list.tables[i].owner_id) { | ||
346 | continue; | ||
347 | } | ||
348 | /* | ||
349 | * Delete all namespace objects owned by this table. Note that these | ||
350 | * objects can appear anywhere in the namespace by virtue of the AML | ||
351 | * "Scope" operator. Thus, we need to track ownership by an ID, not | ||
352 | * simply a position within the hierarchy | ||
353 | */ | ||
354 | acpi_tb_delete_namespace_by_owner(i); | ||
355 | acpi_tb_release_owner_id(i); | ||
356 | acpi_tb_set_table_loaded_flag(i, FALSE); | ||
215 | } | 357 | } |
216 | |||
217 | return_ACPI_STATUS(status); | 358 | return_ACPI_STATUS(status); |
218 | } | 359 | } |
219 | 360 | ||
220 | ACPI_EXPORT_SYMBOL(acpi_load_table) | 361 | ACPI_EXPORT_SYMBOL(acpi_unload_table_id) |
221 | 362 | ||
222 | /******************************************************************************* | 363 | /******************************************************************************* |
223 | * | 364 | * |
224 | * FUNCTION: acpi_unload_table | 365 | * FUNCTION: acpi_get_table |
225 | * | 366 | * |
226 | * PARAMETERS: table_type - Type of table to be unloaded | 367 | * PARAMETERS: Signature - ACPI signature of needed table |
368 | * Instance - Which instance (for SSDTs) | ||
369 | * out_table - Where the pointer to the table is returned | ||
227 | * | 370 | * |
228 | * RETURN: Status | 371 | * RETURN: Status and pointer to table |
229 | * | 372 | * |
230 | * DESCRIPTION: This routine is used to force the unload of a table | 373 | * DESCRIPTION: Finds and verifies an ACPI table. |
231 | * | 374 | * |
232 | ******************************************************************************/ | 375 | *****************************************************************************/ |
233 | acpi_status acpi_unload_table(acpi_table_type table_type) | 376 | acpi_status |
377 | acpi_get_table(char *signature, | ||
378 | acpi_native_uint instance, struct acpi_table_header ** out_table) | ||
234 | { | 379 | { |
235 | struct acpi_table_desc *table_desc; | 380 | acpi_native_uint i; |
236 | 381 | acpi_native_uint j; | |
237 | ACPI_FUNCTION_TRACE(acpi_unload_table); | 382 | acpi_status status; |
238 | 383 | ||
239 | /* Parameter validation */ | 384 | /* Parameter validation */ |
240 | 385 | ||
241 | if (table_type > ACPI_TABLE_ID_MAX) { | 386 | if (!signature || !out_table) { |
242 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 387 | return (AE_BAD_PARAMETER); |
243 | } | 388 | } |
244 | 389 | ||
245 | /* Find all tables of the requested type */ | 390 | /* |
391 | * Walk the root table list | ||
392 | */ | ||
393 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { | ||
394 | if (!ACPI_COMPARE_NAME | ||
395 | (&(acpi_gbl_root_table_list.tables[i].signature), | ||
396 | signature)) { | ||
397 | continue; | ||
398 | } | ||
246 | 399 | ||
247 | table_desc = acpi_gbl_table_lists[table_type].next; | 400 | if (++j < instance) { |
248 | if (!table_desc) { | 401 | continue; |
249 | return_ACPI_STATUS(AE_NOT_EXIST); | 402 | } |
250 | } | ||
251 | 403 | ||
252 | while (table_desc) { | 404 | status = |
253 | /* | 405 | acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); |
254 | * Delete all namespace objects owned by this table. Note that these | 406 | if (ACPI_SUCCESS(status)) { |
255 | * objects can appear anywhere in the namespace by virtue of the AML | 407 | *out_table = acpi_gbl_root_table_list.tables[i].pointer; |
256 | * "Scope" operator. Thus, we need to track ownership by an ID, not | 408 | } |
257 | * simply a position within the hierarchy | ||
258 | */ | ||
259 | acpi_ns_delete_namespace_by_owner(table_desc->owner_id); | ||
260 | table_desc = table_desc->next; | ||
261 | } | ||
262 | 409 | ||
263 | /* Delete (or unmap) all tables of this type */ | 410 | if (!acpi_gbl_permanent_mmap) { |
411 | acpi_gbl_root_table_list.tables[i].pointer = 0; | ||
412 | } | ||
264 | 413 | ||
265 | acpi_tb_delete_tables_by_type(table_type); | 414 | return (status); |
266 | return_ACPI_STATUS(AE_OK); | 415 | } |
416 | |||
417 | return (AE_NOT_FOUND); | ||
267 | } | 418 | } |
268 | 419 | ||
269 | ACPI_EXPORT_SYMBOL(acpi_unload_table) | 420 | ACPI_EXPORT_SYMBOL(acpi_get_table) |
270 | 421 | ||
271 | /******************************************************************************* | 422 | /******************************************************************************* |
272 | * | 423 | * |
273 | * FUNCTION: acpi_get_table_header | 424 | * FUNCTION: acpi_get_table_by_index |
274 | * | 425 | * |
275 | * PARAMETERS: table_type - one of the defined table types | 426 | * PARAMETERS: table_index - Table index |
276 | * Instance - the non zero instance of the table, allows | 427 | * Table - Where the pointer to the table is returned |
277 | * support for multiple tables of the same type | ||
278 | * see acpi_gbl_acpi_table_flag | ||
279 | * out_table_header - pointer to the struct acpi_table_header if successful | ||
280 | * | 428 | * |
281 | * DESCRIPTION: This function is called to get an ACPI table header. The caller | 429 | * RETURN: Status and pointer to the table |
282 | * supplies an pointer to a data area sufficient to contain an ACPI | ||
283 | * struct acpi_table_header structure. | ||
284 | * | 430 | * |
285 | * The header contains a length field that can be used to determine | 431 | * DESCRIPTION: Obtain a table by an index into the global table list. |
286 | * the size of the buffer needed to contain the entire table. This | ||
287 | * function is not valid for the RSD PTR table since it does not | ||
288 | * have a standard header and is fixed length. | ||
289 | * | 432 | * |
290 | ******************************************************************************/ | 433 | ******************************************************************************/ |
291 | acpi_status | 434 | acpi_status |
292 | acpi_get_table_header(acpi_table_type table_type, | 435 | acpi_get_table_by_index(acpi_native_uint table_index, |
293 | u32 instance, struct acpi_table_header *out_table_header) | 436 | struct acpi_table_header ** table) |
294 | { | 437 | { |
295 | struct acpi_table_header *tbl_ptr; | ||
296 | acpi_status status; | 438 | acpi_status status; |
297 | 439 | ||
298 | ACPI_FUNCTION_TRACE(acpi_get_table_header); | 440 | ACPI_FUNCTION_TRACE(acpi_get_table_by_index); |
441 | |||
442 | /* Parameter validation */ | ||
299 | 443 | ||
300 | if ((instance == 0) || | 444 | if (!table) { |
301 | (table_type == ACPI_TABLE_ID_RSDP) || (!out_table_header)) { | ||
302 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 445 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
303 | } | 446 | } |
304 | 447 | ||
305 | /* Check the table type and instance */ | 448 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
306 | 449 | ||
307 | if ((table_type > ACPI_TABLE_ID_MAX) || | 450 | /* Validate index */ |
308 | (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && | 451 | |
309 | instance > 1)) { | 452 | if (table_index >= acpi_gbl_root_table_list.count) { |
453 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
310 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 454 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
311 | } | 455 | } |
312 | 456 | ||
313 | /* Get a pointer to the entire table */ | 457 | if (!acpi_gbl_root_table_list.tables[table_index].pointer) { |
314 | |||
315 | status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); | ||
316 | if (ACPI_FAILURE(status)) { | ||
317 | return_ACPI_STATUS(status); | ||
318 | } | ||
319 | 458 | ||
320 | /* The function will return a NULL pointer if the table is not loaded */ | 459 | /* Table is not mapped, map it */ |
321 | 460 | ||
322 | if (tbl_ptr == NULL) { | 461 | status = |
323 | return_ACPI_STATUS(AE_NOT_EXIST); | 462 | acpi_tb_verify_table(&acpi_gbl_root_table_list. |
463 | tables[table_index]); | ||
464 | if (ACPI_FAILURE(status)) { | ||
465 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
466 | return_ACPI_STATUS(status); | ||
467 | } | ||
324 | } | 468 | } |
325 | 469 | ||
326 | /* Copy the header to the caller's buffer */ | 470 | *table = acpi_gbl_root_table_list.tables[table_index].pointer; |
327 | 471 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | |
328 | ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header), | 472 | return_ACPI_STATUS(AE_OK); |
329 | ACPI_CAST_PTR(void, tbl_ptr), | ||
330 | sizeof(struct acpi_table_header)); | ||
331 | |||
332 | return_ACPI_STATUS(status); | ||
333 | } | 473 | } |
334 | 474 | ||
335 | ACPI_EXPORT_SYMBOL(acpi_get_table_header) | 475 | ACPI_EXPORT_SYMBOL(acpi_get_table_by_index) |
336 | #endif /* ACPI_FUTURE_USAGE */ | ||
337 | 476 | ||
338 | /******************************************************************************* | 477 | /******************************************************************************* |
339 | * | 478 | * |
340 | * FUNCTION: acpi_get_table | 479 | * FUNCTION: acpi_tb_load_namespace |
341 | * | 480 | * |
342 | * PARAMETERS: table_type - one of the defined table types | 481 | * PARAMETERS: None |
343 | * Instance - the non zero instance of the table, allows | ||
344 | * support for multiple tables of the same type | ||
345 | * see acpi_gbl_acpi_table_flag | ||
346 | * ret_buffer - pointer to a structure containing a buffer to | ||
347 | * receive the table | ||
348 | * | 482 | * |
349 | * RETURN: Status | 483 | * RETURN: Status |
350 | * | 484 | * |
351 | * DESCRIPTION: This function is called to get an ACPI table. The caller | 485 | * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in |
352 | * supplies an out_buffer large enough to contain the entire ACPI | 486 | * the RSDT/XSDT. |
353 | * table. The caller should call the acpi_get_table_header function | ||
354 | * first to determine the buffer size needed. Upon completion | ||
355 | * the out_buffer->Length field will indicate the number of bytes | ||
356 | * copied into the out_buffer->buf_ptr buffer. This table will be | ||
357 | * a complete table including the header. | ||
358 | * | 487 | * |
359 | ******************************************************************************/ | 488 | ******************************************************************************/ |
360 | acpi_status | 489 | static acpi_status acpi_tb_load_namespace(void) |
361 | acpi_get_table(acpi_table_type table_type, | ||
362 | u32 instance, struct acpi_buffer *ret_buffer) | ||
363 | { | 490 | { |
364 | struct acpi_table_header *tbl_ptr; | ||
365 | acpi_status status; | 491 | acpi_status status; |
366 | acpi_size table_length; | 492 | struct acpi_table_header *table; |
493 | acpi_native_uint i; | ||
367 | 494 | ||
368 | ACPI_FUNCTION_TRACE(acpi_get_table); | 495 | ACPI_FUNCTION_TRACE(tb_load_namespace); |
369 | 496 | ||
370 | /* Parameter validation */ | 497 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
371 | 498 | ||
372 | if (instance == 0) { | 499 | /* |
373 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 500 | * Load the namespace. The DSDT is required, but any SSDT and PSDT tables |
501 | * are optional. | ||
502 | */ | ||
503 | if (!acpi_gbl_root_table_list.count || | ||
504 | !ACPI_COMPARE_NAME(& | ||
505 | (acpi_gbl_root_table_list. | ||
506 | tables[ACPI_TABLE_INDEX_DSDT].signature), | ||
507 | ACPI_SIG_DSDT) | ||
508 | || | ||
509 | ACPI_FAILURE(acpi_tb_verify_table | ||
510 | (&acpi_gbl_root_table_list. | ||
511 | tables[ACPI_TABLE_INDEX_DSDT]))) { | ||
512 | status = AE_NO_ACPI_TABLES; | ||
513 | goto unlock_and_exit; | ||
374 | } | 514 | } |
375 | 515 | ||
376 | status = acpi_ut_validate_buffer(ret_buffer); | 516 | /* |
377 | if (ACPI_FAILURE(status)) { | 517 | * Find DSDT table |
378 | return_ACPI_STATUS(status); | 518 | */ |
519 | status = | ||
520 | acpi_os_table_override(acpi_gbl_root_table_list. | ||
521 | tables[ACPI_TABLE_INDEX_DSDT].pointer, | ||
522 | &table); | ||
523 | if (ACPI_SUCCESS(status) && table) { | ||
524 | /* | ||
525 | * DSDT table has been found | ||
526 | */ | ||
527 | acpi_tb_delete_table(&acpi_gbl_root_table_list. | ||
528 | tables[ACPI_TABLE_INDEX_DSDT]); | ||
529 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer = | ||
530 | table; | ||
531 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length = | ||
532 | table->length; | ||
533 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = | ||
534 | ACPI_TABLE_ORIGIN_UNKNOWN; | ||
535 | |||
536 | ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS")); | ||
537 | acpi_tb_print_table_header(0, table); | ||
379 | } | 538 | } |
380 | 539 | ||
381 | /* Check the table type and instance */ | 540 | status = |
541 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
542 | tables[ACPI_TABLE_INDEX_DSDT]); | ||
543 | if (ACPI_FAILURE(status)) { | ||
382 | 544 | ||
383 | if ((table_type > ACPI_TABLE_ID_MAX) || | 545 | /* A valid DSDT is required */ |
384 | (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && | 546 | |
385 | instance > 1)) { | 547 | status = AE_NO_ACPI_TABLES; |
386 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 548 | goto unlock_and_exit; |
387 | } | 549 | } |
388 | 550 | ||
389 | /* Get a pointer to the entire table */ | 551 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
390 | 552 | ||
391 | status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); | 553 | /* |
554 | * Load and parse tables. | ||
555 | */ | ||
556 | status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); | ||
392 | if (ACPI_FAILURE(status)) { | 557 | if (ACPI_FAILURE(status)) { |
393 | return_ACPI_STATUS(status); | 558 | return_ACPI_STATUS(status); |
394 | } | 559 | } |
395 | 560 | ||
396 | /* | 561 | /* |
397 | * acpi_tb_get_table_ptr will return a NULL pointer if the | 562 | * Load any SSDT or PSDT tables. Note: Loop leaves tables locked |
398 | * table is not loaded. | ||
399 | */ | 563 | */ |
400 | if (tbl_ptr == NULL) { | 564 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
401 | return_ACPI_STATUS(AE_NOT_EXIST); | 565 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { |
566 | if ((!ACPI_COMPARE_NAME | ||
567 | (&(acpi_gbl_root_table_list.tables[i].signature), | ||
568 | ACPI_SIG_SSDT) | ||
569 | && | ||
570 | !ACPI_COMPARE_NAME(& | ||
571 | (acpi_gbl_root_table_list.tables[i]. | ||
572 | signature), ACPI_SIG_PSDT)) | ||
573 | || | ||
574 | ACPI_FAILURE(acpi_tb_verify_table | ||
575 | (&acpi_gbl_root_table_list.tables[i]))) { | ||
576 | continue; | ||
577 | } | ||
578 | |||
579 | /* Ignore errors while loading tables, get as many as possible */ | ||
580 | |||
581 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
582 | (void)acpi_ns_load_table(i, acpi_gbl_root_node); | ||
583 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
402 | } | 584 | } |
403 | 585 | ||
404 | /* Get the table length */ | 586 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); |
405 | 587 | ||
406 | if (table_type == ACPI_TABLE_ID_RSDP) { | 588 | unlock_and_exit: |
589 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
590 | return_ACPI_STATUS(status); | ||
591 | } | ||
407 | 592 | ||
408 | /* RSD PTR is the only "table" without a header */ | 593 | /******************************************************************************* |
594 | * | ||
595 | * FUNCTION: acpi_load_tables | ||
596 | * | ||
597 | * PARAMETERS: None | ||
598 | * | ||
599 | * RETURN: Status | ||
600 | * | ||
601 | * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT | ||
602 | * | ||
603 | ******************************************************************************/ | ||
409 | 604 | ||
410 | table_length = sizeof(struct rsdp_descriptor); | 605 | acpi_status acpi_load_tables(void) |
411 | } else { | 606 | { |
412 | table_length = (acpi_size) tbl_ptr->length; | 607 | acpi_status status; |
413 | } | ||
414 | 608 | ||
415 | /* Validate/Allocate/Clear caller buffer */ | 609 | ACPI_FUNCTION_TRACE(acpi_load_tables); |
416 | 610 | ||
417 | status = acpi_ut_initialize_buffer(ret_buffer, table_length); | 611 | /* |
612 | * Load the namespace from the tables | ||
613 | */ | ||
614 | status = acpi_tb_load_namespace(); | ||
418 | if (ACPI_FAILURE(status)) { | 615 | if (ACPI_FAILURE(status)) { |
419 | return_ACPI_STATUS(status); | 616 | ACPI_EXCEPTION((AE_INFO, status, |
617 | "While loading namespace from ACPI tables")); | ||
420 | } | 618 | } |
421 | 619 | ||
422 | /* Copy the table to the buffer */ | 620 | return_ACPI_STATUS(status); |
423 | |||
424 | ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer), | ||
425 | ACPI_CAST_PTR(void, tbl_ptr), table_length); | ||
426 | |||
427 | return_ACPI_STATUS(AE_OK); | ||
428 | } | 621 | } |
429 | 622 | ||
430 | ACPI_EXPORT_SYMBOL(acpi_get_table) | 623 | ACPI_EXPORT_SYMBOL(acpi_load_tables) |
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index da2648bbdbc0..cf8fa514189f 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -48,16 +48,15 @@ | |||
48 | ACPI_MODULE_NAME("tbxfroot") | 48 | ACPI_MODULE_NAME("tbxfroot") |
49 | 49 | ||
50 | /* Local prototypes */ | 50 | /* Local prototypes */ |
51 | static acpi_status | ||
52 | acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags); | ||
53 | |||
54 | static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); | 51 | static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); |
55 | 52 | ||
53 | static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); | ||
54 | |||
56 | /******************************************************************************* | 55 | /******************************************************************************* |
57 | * | 56 | * |
58 | * FUNCTION: acpi_tb_validate_rsdp | 57 | * FUNCTION: acpi_tb_validate_rsdp |
59 | * | 58 | * |
60 | * PARAMETERS: Rsdp - Pointer to unvalidated RSDP | 59 | * PARAMETERS: Rsdp - Pointer to unvalidated RSDP |
61 | * | 60 | * |
62 | * RETURN: Status | 61 | * RETURN: Status |
63 | * | 62 | * |
@@ -65,14 +64,18 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); | |||
65 | * | 64 | * |
66 | ******************************************************************************/ | 65 | ******************************************************************************/ |
67 | 66 | ||
68 | acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) | 67 | static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) |
69 | { | 68 | { |
70 | ACPI_FUNCTION_ENTRY(); | 69 | ACPI_FUNCTION_ENTRY(); |
71 | 70 | ||
72 | /* | 71 | /* |
73 | * The signature and checksum must both be correct | 72 | * The signature and checksum must both be correct |
73 | * | ||
74 | * Note: Sometimes there exists more than one RSDP in memory; the valid | ||
75 | * RSDP has a valid checksum, all others have an invalid checksum. | ||
74 | */ | 76 | */ |
75 | if (ACPI_STRNCMP((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) { | 77 | if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1) |
78 | != 0) { | ||
76 | 79 | ||
77 | /* Nope, BAD Signature */ | 80 | /* Nope, BAD Signature */ |
78 | 81 | ||
@@ -81,14 +84,14 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) | |||
81 | 84 | ||
82 | /* Check the standard checksum */ | 85 | /* Check the standard checksum */ |
83 | 86 | ||
84 | if (acpi_tb_sum_table(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { | 87 | if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { |
85 | return (AE_BAD_CHECKSUM); | 88 | return (AE_BAD_CHECKSUM); |
86 | } | 89 | } |
87 | 90 | ||
88 | /* Check extended checksum if table version >= 2 */ | 91 | /* Check extended checksum if table version >= 2 */ |
89 | 92 | ||
90 | if ((rsdp->revision >= 2) && | 93 | if ((rsdp->revision >= 2) && |
91 | (acpi_tb_sum_table(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { | 94 | (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { |
92 | return (AE_BAD_CHECKSUM); | 95 | return (AE_BAD_CHECKSUM); |
93 | } | 96 | } |
94 | 97 | ||
@@ -97,314 +100,123 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) | |||
97 | 100 | ||
98 | /******************************************************************************* | 101 | /******************************************************************************* |
99 | * | 102 | * |
100 | * FUNCTION: acpi_tb_find_table | 103 | * FUNCTION: acpi_tb_find_rsdp |
101 | * | ||
102 | * PARAMETERS: Signature - String with ACPI table signature | ||
103 | * oem_id - String with the table OEM ID | ||
104 | * oem_table_id - String with the OEM Table ID | ||
105 | * table_ptr - Where the table pointer is returned | ||
106 | * | ||
107 | * RETURN: Status | ||
108 | * | 104 | * |
109 | * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the | 105 | * PARAMETERS: table_address - Where the table pointer is returned |
110 | * Signature, OEM ID and OEM Table ID. | ||
111 | * | 106 | * |
112 | ******************************************************************************/ | 107 | * RETURN: Status, RSDP physical address |
113 | |||
114 | acpi_status | ||
115 | acpi_tb_find_table(char *signature, | ||
116 | char *oem_id, | ||
117 | char *oem_table_id, struct acpi_table_header ** table_ptr) | ||
118 | { | ||
119 | acpi_status status; | ||
120 | struct acpi_table_header *table; | ||
121 | |||
122 | ACPI_FUNCTION_TRACE(tb_find_table); | ||
123 | |||
124 | /* Validate string lengths */ | ||
125 | |||
126 | if ((ACPI_STRLEN(signature) > ACPI_NAME_SIZE) || | ||
127 | (ACPI_STRLEN(oem_id) > sizeof(table->oem_id)) || | ||
128 | (ACPI_STRLEN(oem_table_id) > sizeof(table->oem_table_id))) { | ||
129 | return_ACPI_STATUS(AE_AML_STRING_LIMIT); | ||
130 | } | ||
131 | |||
132 | if (ACPI_COMPARE_NAME(signature, DSDT_SIG)) { | ||
133 | /* | ||
134 | * The DSDT pointer is contained in the FADT, not the RSDT. | ||
135 | * This code should suffice, because the only code that would perform | ||
136 | * a "find" on the DSDT is the data_table_region() AML opcode -- in | ||
137 | * which case, the DSDT is guaranteed to be already loaded. | ||
138 | * If this becomes insufficient, the FADT will have to be found first. | ||
139 | */ | ||
140 | if (!acpi_gbl_DSDT) { | ||
141 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
142 | } | ||
143 | table = acpi_gbl_DSDT; | ||
144 | } else { | ||
145 | /* Find the table */ | ||
146 | |||
147 | status = acpi_get_firmware_table(signature, 1, | ||
148 | ACPI_LOGICAL_ADDRESSING, | ||
149 | &table); | ||
150 | if (ACPI_FAILURE(status)) { | ||
151 | return_ACPI_STATUS(status); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /* Check oem_id and oem_table_id */ | ||
156 | |||
157 | if ((oem_id[0] && | ||
158 | ACPI_STRNCMP(oem_id, table->oem_id, | ||
159 | sizeof(table->oem_id))) || | ||
160 | (oem_table_id[0] && | ||
161 | ACPI_STRNCMP(oem_table_id, table->oem_table_id, | ||
162 | sizeof(table->oem_table_id)))) { | ||
163 | return_ACPI_STATUS(AE_AML_NAME_NOT_FOUND); | ||
164 | } | ||
165 | |||
166 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Found table [%4.4s]\n", | ||
167 | table->signature)); | ||
168 | |||
169 | *table_ptr = table; | ||
170 | return_ACPI_STATUS(AE_OK); | ||
171 | } | ||
172 | |||
173 | /******************************************************************************* | ||
174 | * | ||
175 | * FUNCTION: acpi_get_firmware_table | ||
176 | * | 108 | * |
177 | * PARAMETERS: Signature - Any ACPI table signature | 109 | * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor |
178 | * Instance - the non zero instance of the table, allows | 110 | * pointer structure. If it is found, set *RSDP to point to it. |
179 | * support for multiple tables of the same type | ||
180 | * Flags - Physical/Virtual support | ||
181 | * table_pointer - Where a buffer containing the table is | ||
182 | * returned | ||
183 | * | 111 | * |
184 | * RETURN: Status | 112 | * NOTE1: The RSDP must be either in the first 1_k of the Extended |
113 | * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) | ||
114 | * Only a 32-bit physical address is necessary. | ||
185 | * | 115 | * |
186 | * DESCRIPTION: This function is called to get an ACPI table. A buffer is | 116 | * NOTE2: This function is always available, regardless of the |
187 | * allocated for the table and returned in table_pointer. | 117 | * initialization state of the rest of ACPI. |
188 | * This table will be a complete table including the header. | ||
189 | * | 118 | * |
190 | ******************************************************************************/ | 119 | ******************************************************************************/ |
191 | 120 | ||
192 | acpi_status | 121 | acpi_status acpi_find_root_pointer(acpi_native_uint * table_address) |
193 | acpi_get_firmware_table(acpi_string signature, | ||
194 | u32 instance, | ||
195 | u32 flags, struct acpi_table_header **table_pointer) | ||
196 | { | 122 | { |
197 | acpi_status status; | 123 | u8 *table_ptr; |
198 | struct acpi_pointer address; | 124 | u8 *mem_rover; |
199 | struct acpi_table_header *header = NULL; | 125 | u32 physical_address; |
200 | struct acpi_table_desc *table_info = NULL; | ||
201 | struct acpi_table_desc *rsdt_info; | ||
202 | u32 table_count; | ||
203 | u32 i; | ||
204 | u32 j; | ||
205 | |||
206 | ACPI_FUNCTION_TRACE(acpi_get_firmware_table); | ||
207 | |||
208 | /* | ||
209 | * Ensure that at least the table manager is initialized. We don't | ||
210 | * require that the entire ACPI subsystem is up for this interface. | ||
211 | * If we have a buffer, we must have a length too | ||
212 | */ | ||
213 | if ((instance == 0) || (!signature) || (!table_pointer)) { | ||
214 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
215 | } | ||
216 | |||
217 | /* Ensure that we have a RSDP */ | ||
218 | |||
219 | if (!acpi_gbl_RSDP) { | ||
220 | |||
221 | /* Get the RSDP */ | ||
222 | |||
223 | status = acpi_os_get_root_pointer(flags, &address); | ||
224 | if (ACPI_FAILURE(status)) { | ||
225 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "RSDP not found\n")); | ||
226 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
227 | } | ||
228 | |||
229 | /* Map and validate the RSDP */ | ||
230 | |||
231 | if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { | ||
232 | status = acpi_os_map_memory(address.pointer.physical, | ||
233 | sizeof(struct | ||
234 | rsdp_descriptor), | ||
235 | (void *)&acpi_gbl_RSDP); | ||
236 | if (ACPI_FAILURE(status)) { | ||
237 | return_ACPI_STATUS(status); | ||
238 | } | ||
239 | } else { | ||
240 | acpi_gbl_RSDP = address.pointer.logical; | ||
241 | } | ||
242 | |||
243 | /* The RDSP signature and checksum must both be correct */ | ||
244 | |||
245 | status = acpi_tb_validate_rsdp(acpi_gbl_RSDP); | ||
246 | if (ACPI_FAILURE(status)) { | ||
247 | return_ACPI_STATUS(status); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | /* Get the RSDT address via the RSDP */ | ||
252 | |||
253 | acpi_tb_get_rsdt_address(&address); | ||
254 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
255 | "RSDP located at %p, RSDT physical=%8.8X%8.8X\n", | ||
256 | acpi_gbl_RSDP, | ||
257 | ACPI_FORMAT_UINT64(address.pointer.value))); | ||
258 | 126 | ||
259 | /* Insert processor_mode flags */ | 127 | ACPI_FUNCTION_TRACE(acpi_find_root_pointer); |
260 | 128 | ||
261 | address.pointer_type |= flags; | 129 | /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ |
262 | 130 | ||
263 | /* Get and validate the RSDT */ | 131 | table_ptr = acpi_os_map_memory((acpi_physical_address) |
132 | ACPI_EBDA_PTR_LOCATION, | ||
133 | ACPI_EBDA_PTR_LENGTH); | ||
134 | if (!table_ptr) { | ||
135 | ACPI_ERROR((AE_INFO, | ||
136 | "Could not map memory at %8.8X for length %X", | ||
137 | ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); | ||
264 | 138 | ||
265 | rsdt_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); | ||
266 | if (!rsdt_info) { | ||
267 | return_ACPI_STATUS(AE_NO_MEMORY); | 139 | return_ACPI_STATUS(AE_NO_MEMORY); |
268 | } | 140 | } |
269 | 141 | ||
270 | status = acpi_tb_get_table(&address, rsdt_info); | 142 | ACPI_MOVE_16_TO_32(&physical_address, table_ptr); |
271 | if (ACPI_FAILURE(status)) { | ||
272 | goto cleanup; | ||
273 | } | ||
274 | |||
275 | status = acpi_tb_validate_rsdt(rsdt_info->pointer); | ||
276 | if (ACPI_FAILURE(status)) { | ||
277 | goto cleanup; | ||
278 | } | ||
279 | 143 | ||
280 | /* Allocate a scratch table header and table descriptor */ | 144 | /* Convert segment part to physical address */ |
281 | 145 | ||
282 | header = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); | 146 | physical_address <<= 4; |
283 | if (!header) { | 147 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); |
284 | status = AE_NO_MEMORY; | ||
285 | goto cleanup; | ||
286 | } | ||
287 | 148 | ||
288 | table_info = ACPI_ALLOCATE(sizeof(struct acpi_table_desc)); | 149 | /* EBDA present? */ |
289 | if (!table_info) { | ||
290 | status = AE_NO_MEMORY; | ||
291 | goto cleanup; | ||
292 | } | ||
293 | 150 | ||
294 | /* Get the number of table pointers within the RSDT */ | 151 | if (physical_address > 0x400) { |
295 | |||
296 | table_count = | ||
297 | acpi_tb_get_table_count(acpi_gbl_RSDP, rsdt_info->pointer); | ||
298 | address.pointer_type = acpi_gbl_table_flags | flags; | ||
299 | |||
300 | /* | ||
301 | * Search the RSDT/XSDT for the correct instance of the | ||
302 | * requested table | ||
303 | */ | ||
304 | for (i = 0, j = 0; i < table_count; i++) { | ||
305 | /* | 152 | /* |
306 | * Get the next table pointer, handle RSDT vs. XSDT | 153 | * 1b) Search EBDA paragraphs (EBDA is required to be a |
307 | * RSDT pointers are 32 bits, XSDT pointers are 64 bits | 154 | * minimum of 1_k length) |
308 | */ | 155 | */ |
309 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | 156 | table_ptr = acpi_os_map_memory((acpi_native_uint) |
310 | address.pointer.value = | 157 | physical_address, |
311 | (ACPI_CAST_PTR | 158 | ACPI_EBDA_WINDOW_SIZE); |
312 | (struct rsdt_descriptor, | 159 | if (!table_ptr) { |
313 | rsdt_info->pointer))->table_offset_entry[i]; | 160 | ACPI_ERROR((AE_INFO, |
314 | } else { | 161 | "Could not map memory at %8.8X for length %X", |
315 | address.pointer.value = | 162 | physical_address, ACPI_EBDA_WINDOW_SIZE)); |
316 | (ACPI_CAST_PTR | ||
317 | (struct xsdt_descriptor, | ||
318 | rsdt_info->pointer))->table_offset_entry[i]; | ||
319 | } | ||
320 | |||
321 | /* Get the table header */ | ||
322 | 163 | ||
323 | status = acpi_tb_get_table_header(&address, header); | 164 | return_ACPI_STATUS(AE_NO_MEMORY); |
324 | if (ACPI_FAILURE(status)) { | ||
325 | goto cleanup; | ||
326 | } | 165 | } |
327 | 166 | ||
328 | /* Compare table signatures and table instance */ | 167 | mem_rover = |
329 | 168 | acpi_tb_scan_memory_for_rsdp(table_ptr, | |
330 | if (ACPI_COMPARE_NAME(header->signature, signature)) { | 169 | ACPI_EBDA_WINDOW_SIZE); |
331 | 170 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); | |
332 | /* An instance of the table was found */ | ||
333 | 171 | ||
334 | j++; | 172 | if (mem_rover) { |
335 | if (j >= instance) { | ||
336 | 173 | ||
337 | /* Found the correct instance, get the entire table */ | 174 | /* Return the physical address */ |
338 | 175 | ||
339 | status = | 176 | physical_address += |
340 | acpi_tb_get_table_body(&address, header, | 177 | (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); |
341 | table_info); | ||
342 | if (ACPI_FAILURE(status)) { | ||
343 | goto cleanup; | ||
344 | } | ||
345 | 178 | ||
346 | *table_pointer = table_info->pointer; | 179 | *table_address = physical_address; |
347 | goto cleanup; | 180 | return_ACPI_STATUS(AE_OK); |
348 | } | ||
349 | } | 181 | } |
350 | } | 182 | } |
351 | 183 | ||
352 | /* Did not find the table */ | 184 | /* |
185 | * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh | ||
186 | */ | ||
187 | table_ptr = acpi_os_map_memory((acpi_physical_address) | ||
188 | ACPI_HI_RSDP_WINDOW_BASE, | ||
189 | ACPI_HI_RSDP_WINDOW_SIZE); | ||
353 | 190 | ||
354 | status = AE_NOT_EXIST; | 191 | if (!table_ptr) { |
192 | ACPI_ERROR((AE_INFO, | ||
193 | "Could not map memory at %8.8X for length %X", | ||
194 | ACPI_HI_RSDP_WINDOW_BASE, | ||
195 | ACPI_HI_RSDP_WINDOW_SIZE)); | ||
355 | 196 | ||
356 | cleanup: | 197 | return_ACPI_STATUS(AE_NO_MEMORY); |
357 | if (rsdt_info->pointer) { | ||
358 | acpi_os_unmap_memory(rsdt_info->pointer, | ||
359 | (acpi_size) rsdt_info->pointer->length); | ||
360 | } | 198 | } |
361 | ACPI_FREE(rsdt_info); | ||
362 | 199 | ||
363 | if (header) { | 200 | mem_rover = |
364 | ACPI_FREE(header); | 201 | acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); |
365 | } | 202 | acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); |
366 | if (table_info) { | ||
367 | ACPI_FREE(table_info); | ||
368 | } | ||
369 | return_ACPI_STATUS(status); | ||
370 | } | ||
371 | 203 | ||
372 | ACPI_EXPORT_SYMBOL(acpi_get_firmware_table) | 204 | if (mem_rover) { |
373 | 205 | ||
374 | /* TBD: Move to a new file */ | 206 | /* Return the physical address */ |
375 | #if ACPI_MACHINE_WIDTH != 16 | ||
376 | /******************************************************************************* | ||
377 | * | ||
378 | * FUNCTION: acpi_find_root_pointer | ||
379 | * | ||
380 | * PARAMETERS: Flags - Logical/Physical addressing | ||
381 | * rsdp_address - Where to place the RSDP address | ||
382 | * | ||
383 | * RETURN: Status, Physical address of the RSDP | ||
384 | * | ||
385 | * DESCRIPTION: Find the RSDP | ||
386 | * | ||
387 | ******************************************************************************/ | ||
388 | acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address) | ||
389 | { | ||
390 | struct acpi_table_desc table_info; | ||
391 | acpi_status status; | ||
392 | |||
393 | ACPI_FUNCTION_TRACE(acpi_find_root_pointer); | ||
394 | |||
395 | /* Get the RSDP */ | ||
396 | 207 | ||
397 | status = acpi_tb_find_rsdp(&table_info, flags); | 208 | physical_address = (u32) |
398 | if (ACPI_FAILURE(status)) { | 209 | (ACPI_HI_RSDP_WINDOW_BASE + |
399 | ACPI_EXCEPTION((AE_INFO, status, | 210 | ACPI_PTR_DIFF(mem_rover, table_ptr)); |
400 | "RSDP structure not found - Flags=%X", flags)); | ||
401 | 211 | ||
402 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | 212 | *table_address = physical_address; |
213 | return_ACPI_STATUS(AE_OK); | ||
403 | } | 214 | } |
404 | 215 | ||
405 | rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER; | 216 | /* A valid RSDP was not found */ |
406 | rsdp_address->pointer.physical = table_info.physical_address; | 217 | |
407 | return_ACPI_STATUS(AE_OK); | 218 | ACPI_ERROR((AE_INFO, "A valid RSDP was not found")); |
219 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
408 | } | 220 | } |
409 | 221 | ||
410 | ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) | 222 | ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) |
@@ -440,7 +252,7 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) | |||
440 | 252 | ||
441 | status = | 253 | status = |
442 | acpi_tb_validate_rsdp(ACPI_CAST_PTR | 254 | acpi_tb_validate_rsdp(ACPI_CAST_PTR |
443 | (struct rsdp_descriptor, mem_rover)); | 255 | (struct acpi_table_rsdp, mem_rover)); |
444 | if (ACPI_SUCCESS(status)) { | 256 | if (ACPI_SUCCESS(status)) { |
445 | 257 | ||
446 | /* Sig and checksum valid, we have found a real RSDP */ | 258 | /* Sig and checksum valid, we have found a real RSDP */ |
@@ -461,189 +273,3 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) | |||
461 | start_address)); | 273 | start_address)); |
462 | return_PTR(NULL); | 274 | return_PTR(NULL); |
463 | } | 275 | } |
464 | |||
465 | /******************************************************************************* | ||
466 | * | ||
467 | * FUNCTION: acpi_tb_find_rsdp | ||
468 | * | ||
469 | * PARAMETERS: table_info - Where the table info is returned | ||
470 | * Flags - Current memory mode (logical vs. | ||
471 | * physical addressing) | ||
472 | * | ||
473 | * RETURN: Status, RSDP physical address | ||
474 | * | ||
475 | * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor | ||
476 | * pointer structure. If it is found, set *RSDP to point to it. | ||
477 | * | ||
478 | * NOTE1: The RSDP must be either in the first 1_k of the Extended | ||
479 | * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) | ||
480 | * Only a 32-bit physical address is necessary. | ||
481 | * | ||
482 | * NOTE2: This function is always available, regardless of the | ||
483 | * initialization state of the rest of ACPI. | ||
484 | * | ||
485 | ******************************************************************************/ | ||
486 | |||
487 | static acpi_status | ||
488 | acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) | ||
489 | { | ||
490 | u8 *table_ptr; | ||
491 | u8 *mem_rover; | ||
492 | u32 physical_address; | ||
493 | acpi_status status; | ||
494 | |||
495 | ACPI_FUNCTION_TRACE(tb_find_rsdp); | ||
496 | |||
497 | /* | ||
498 | * Scan supports either logical addressing or physical addressing | ||
499 | */ | ||
500 | if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { | ||
501 | |||
502 | /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ | ||
503 | |||
504 | status = acpi_os_map_memory((acpi_physical_address) | ||
505 | ACPI_EBDA_PTR_LOCATION, | ||
506 | ACPI_EBDA_PTR_LENGTH, | ||
507 | (void *)&table_ptr); | ||
508 | if (ACPI_FAILURE(status)) { | ||
509 | ACPI_ERROR((AE_INFO, | ||
510 | "Could not map memory at %8.8X for length %X", | ||
511 | ACPI_EBDA_PTR_LOCATION, | ||
512 | ACPI_EBDA_PTR_LENGTH)); | ||
513 | |||
514 | return_ACPI_STATUS(status); | ||
515 | } | ||
516 | |||
517 | ACPI_MOVE_16_TO_32(&physical_address, table_ptr); | ||
518 | |||
519 | /* Convert segment part to physical address */ | ||
520 | |||
521 | physical_address <<= 4; | ||
522 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); | ||
523 | |||
524 | /* EBDA present? */ | ||
525 | |||
526 | if (physical_address > 0x400) { | ||
527 | /* | ||
528 | * 1b) Search EBDA paragraphs (EBDA is required to be a | ||
529 | * minimum of 1_k length) | ||
530 | */ | ||
531 | status = acpi_os_map_memory((acpi_physical_address) | ||
532 | physical_address, | ||
533 | ACPI_EBDA_WINDOW_SIZE, | ||
534 | (void *)&table_ptr); | ||
535 | if (ACPI_FAILURE(status)) { | ||
536 | ACPI_ERROR((AE_INFO, | ||
537 | "Could not map memory at %8.8X for length %X", | ||
538 | physical_address, | ||
539 | ACPI_EBDA_WINDOW_SIZE)); | ||
540 | |||
541 | return_ACPI_STATUS(status); | ||
542 | } | ||
543 | |||
544 | mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr, | ||
545 | ACPI_EBDA_WINDOW_SIZE); | ||
546 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); | ||
547 | |||
548 | if (mem_rover) { | ||
549 | |||
550 | /* Return the physical address */ | ||
551 | |||
552 | physical_address += | ||
553 | (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); | ||
554 | |||
555 | table_info->physical_address = | ||
556 | (acpi_physical_address) physical_address; | ||
557 | return_ACPI_STATUS(AE_OK); | ||
558 | } | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh | ||
563 | */ | ||
564 | status = acpi_os_map_memory((acpi_physical_address) | ||
565 | ACPI_HI_RSDP_WINDOW_BASE, | ||
566 | ACPI_HI_RSDP_WINDOW_SIZE, | ||
567 | (void *)&table_ptr); | ||
568 | |||
569 | if (ACPI_FAILURE(status)) { | ||
570 | ACPI_ERROR((AE_INFO, | ||
571 | "Could not map memory at %8.8X for length %X", | ||
572 | ACPI_HI_RSDP_WINDOW_BASE, | ||
573 | ACPI_HI_RSDP_WINDOW_SIZE)); | ||
574 | |||
575 | return_ACPI_STATUS(status); | ||
576 | } | ||
577 | |||
578 | mem_rover = | ||
579 | acpi_tb_scan_memory_for_rsdp(table_ptr, | ||
580 | ACPI_HI_RSDP_WINDOW_SIZE); | ||
581 | acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); | ||
582 | |||
583 | if (mem_rover) { | ||
584 | |||
585 | /* Return the physical address */ | ||
586 | |||
587 | physical_address = (u32) | ||
588 | (ACPI_HI_RSDP_WINDOW_BASE + | ||
589 | ACPI_PTR_DIFF(mem_rover, table_ptr)); | ||
590 | |||
591 | table_info->physical_address = | ||
592 | (acpi_physical_address) physical_address; | ||
593 | return_ACPI_STATUS(AE_OK); | ||
594 | } | ||
595 | } | ||
596 | |||
597 | /* | ||
598 | * Physical addressing | ||
599 | */ | ||
600 | else { | ||
601 | /* 1a) Get the location of the EBDA */ | ||
602 | |||
603 | ACPI_MOVE_16_TO_32(&physical_address, ACPI_EBDA_PTR_LOCATION); | ||
604 | physical_address <<= 4; /* Convert segment to physical address */ | ||
605 | |||
606 | /* EBDA present? */ | ||
607 | |||
608 | if (physical_address > 0x400) { | ||
609 | /* | ||
610 | * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of | ||
611 | * 1_k length) | ||
612 | */ | ||
613 | mem_rover = | ||
614 | acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR | ||
615 | (physical_address), | ||
616 | ACPI_EBDA_WINDOW_SIZE); | ||
617 | if (mem_rover) { | ||
618 | |||
619 | /* Return the physical address */ | ||
620 | |||
621 | table_info->physical_address = | ||
622 | ACPI_TO_INTEGER(mem_rover); | ||
623 | return_ACPI_STATUS(AE_OK); | ||
624 | } | ||
625 | } | ||
626 | |||
627 | /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ | ||
628 | |||
629 | mem_rover = | ||
630 | acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR | ||
631 | (ACPI_HI_RSDP_WINDOW_BASE), | ||
632 | ACPI_HI_RSDP_WINDOW_SIZE); | ||
633 | if (mem_rover) { | ||
634 | |||
635 | /* Found it, return the physical address */ | ||
636 | |||
637 | table_info->physical_address = | ||
638 | ACPI_TO_INTEGER(mem_rover); | ||
639 | return_ACPI_STATUS(AE_OK); | ||
640 | } | ||
641 | } | ||
642 | |||
643 | /* A valid RSDP was not found */ | ||
644 | |||
645 | ACPI_ERROR((AE_INFO, "No valid RSDP was found")); | ||
646 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
647 | } | ||
648 | |||
649 | #endif | ||
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 3650654f878e..f76d3168c2b2 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -663,7 +663,7 @@ static void acpi_thermal_run(unsigned long data) | |||
663 | static void acpi_thermal_check(void *data) | 663 | static void acpi_thermal_check(void *data) |
664 | { | 664 | { |
665 | int result = 0; | 665 | int result = 0; |
666 | struct acpi_thermal *tz = (struct acpi_thermal *)data; | 666 | struct acpi_thermal *tz = data; |
667 | unsigned long sleep_time = 0; | 667 | unsigned long sleep_time = 0; |
668 | int i = 0; | 668 | int i = 0; |
669 | struct acpi_thermal_state state; | 669 | struct acpi_thermal_state state; |
@@ -778,7 +778,7 @@ static struct proc_dir_entry *acpi_thermal_dir; | |||
778 | 778 | ||
779 | static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) | 779 | static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) |
780 | { | 780 | { |
781 | struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; | 781 | struct acpi_thermal *tz = seq->private; |
782 | 782 | ||
783 | 783 | ||
784 | if (!tz) | 784 | if (!tz) |
@@ -813,7 +813,7 @@ static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file) | |||
813 | static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) | 813 | static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) |
814 | { | 814 | { |
815 | int result = 0; | 815 | int result = 0; |
816 | struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; | 816 | struct acpi_thermal *tz = seq->private; |
817 | 817 | ||
818 | 818 | ||
819 | if (!tz) | 819 | if (!tz) |
@@ -837,7 +837,7 @@ static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file) | |||
837 | 837 | ||
838 | static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) | 838 | static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) |
839 | { | 839 | { |
840 | struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; | 840 | struct acpi_thermal *tz = seq->private; |
841 | int i = 0; | 841 | int i = 0; |
842 | int j = 0; | 842 | int j = 0; |
843 | 843 | ||
@@ -893,8 +893,8 @@ acpi_thermal_write_trip_points(struct file *file, | |||
893 | const char __user * buffer, | 893 | const char __user * buffer, |
894 | size_t count, loff_t * ppos) | 894 | size_t count, loff_t * ppos) |
895 | { | 895 | { |
896 | struct seq_file *m = (struct seq_file *)file->private_data; | 896 | struct seq_file *m = file->private_data; |
897 | struct acpi_thermal *tz = (struct acpi_thermal *)m->private; | 897 | struct acpi_thermal *tz = m->private; |
898 | 898 | ||
899 | char *limit_string; | 899 | char *limit_string; |
900 | int num, critical, hot, passive; | 900 | int num, critical, hot, passive; |
@@ -902,12 +902,10 @@ acpi_thermal_write_trip_points(struct file *file, | |||
902 | int i = 0; | 902 | int i = 0; |
903 | 903 | ||
904 | 904 | ||
905 | limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL); | 905 | limit_string = kzalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL); |
906 | if (!limit_string) | 906 | if (!limit_string) |
907 | return -ENOMEM; | 907 | return -ENOMEM; |
908 | 908 | ||
909 | memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN); | ||
910 | |||
911 | active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL); | 909 | active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL); |
912 | if (!active) { | 910 | if (!active) { |
913 | kfree(limit_string); | 911 | kfree(limit_string); |
@@ -953,7 +951,7 @@ acpi_thermal_write_trip_points(struct file *file, | |||
953 | 951 | ||
954 | static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) | 952 | static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) |
955 | { | 953 | { |
956 | struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; | 954 | struct acpi_thermal *tz = seq->private; |
957 | 955 | ||
958 | 956 | ||
959 | if (!tz) | 957 | if (!tz) |
@@ -984,8 +982,8 @@ acpi_thermal_write_cooling_mode(struct file *file, | |||
984 | const char __user * buffer, | 982 | const char __user * buffer, |
985 | size_t count, loff_t * ppos) | 983 | size_t count, loff_t * ppos) |
986 | { | 984 | { |
987 | struct seq_file *m = (struct seq_file *)file->private_data; | 985 | struct seq_file *m = file->private_data; |
988 | struct acpi_thermal *tz = (struct acpi_thermal *)m->private; | 986 | struct acpi_thermal *tz = m->private; |
989 | int result = 0; | 987 | int result = 0; |
990 | char mode_string[12] = { '\0' }; | 988 | char mode_string[12] = { '\0' }; |
991 | 989 | ||
@@ -1014,7 +1012,7 @@ acpi_thermal_write_cooling_mode(struct file *file, | |||
1014 | 1012 | ||
1015 | static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) | 1013 | static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) |
1016 | { | 1014 | { |
1017 | struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; | 1015 | struct acpi_thermal *tz = seq->private; |
1018 | 1016 | ||
1019 | 1017 | ||
1020 | if (!tz) | 1018 | if (!tz) |
@@ -1043,8 +1041,8 @@ acpi_thermal_write_polling(struct file *file, | |||
1043 | const char __user * buffer, | 1041 | const char __user * buffer, |
1044 | size_t count, loff_t * ppos) | 1042 | size_t count, loff_t * ppos) |
1045 | { | 1043 | { |
1046 | struct seq_file *m = (struct seq_file *)file->private_data; | 1044 | struct seq_file *m = file->private_data; |
1047 | struct acpi_thermal *tz = (struct acpi_thermal *)m->private; | 1045 | struct acpi_thermal *tz = m->private; |
1048 | int result = 0; | 1046 | int result = 0; |
1049 | char polling_string[12] = { '\0' }; | 1047 | char polling_string[12] = { '\0' }; |
1050 | int seconds = 0; | 1048 | int seconds = 0; |
@@ -1170,7 +1168,7 @@ static int acpi_thermal_remove_fs(struct acpi_device *device) | |||
1170 | 1168 | ||
1171 | static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) | 1169 | static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) |
1172 | { | 1170 | { |
1173 | struct acpi_thermal *tz = (struct acpi_thermal *)data; | 1171 | struct acpi_thermal *tz = data; |
1174 | struct acpi_device *device = NULL; | 1172 | struct acpi_device *device = NULL; |
1175 | 1173 | ||
1176 | 1174 | ||
@@ -1271,10 +1269,9 @@ static int acpi_thermal_add(struct acpi_device *device) | |||
1271 | if (!device) | 1269 | if (!device) |
1272 | return -EINVAL; | 1270 | return -EINVAL; |
1273 | 1271 | ||
1274 | tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL); | 1272 | tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); |
1275 | if (!tz) | 1273 | if (!tz) |
1276 | return -ENOMEM; | 1274 | return -ENOMEM; |
1277 | memset(tz, 0, sizeof(struct acpi_thermal)); | ||
1278 | 1275 | ||
1279 | tz->device = device; | 1276 | tz->device = device; |
1280 | strcpy(tz->name, device->pnp.bus_id); | 1277 | strcpy(tz->name, device->pnp.bus_id); |
@@ -1324,7 +1321,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) | |||
1324 | if (!device || !acpi_driver_data(device)) | 1321 | if (!device || !acpi_driver_data(device)) |
1325 | return -EINVAL; | 1322 | return -EINVAL; |
1326 | 1323 | ||
1327 | tz = (struct acpi_thermal *)acpi_driver_data(device); | 1324 | tz = acpi_driver_data(device); |
1328 | 1325 | ||
1329 | /* avoid timer adding new defer task */ | 1326 | /* avoid timer adding new defer task */ |
1330 | tz->zombie = 1; | 1327 | tz->zombie = 1; |
@@ -1364,7 +1361,7 @@ static int acpi_thermal_resume(struct acpi_device *device) | |||
1364 | if (!device || !acpi_driver_data(device)) | 1361 | if (!device || !acpi_driver_data(device)) |
1365 | return -EINVAL; | 1362 | return -EINVAL; |
1366 | 1363 | ||
1367 | tz = (struct acpi_thermal *)acpi_driver_data(device); | 1364 | tz = acpi_driver_data(device); |
1368 | 1365 | ||
1369 | acpi_thermal_get_temperature(tz); | 1366 | acpi_thermal_get_temperature(tz); |
1370 | 1367 | ||
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c index 7fe0b7ae9733..d9b651ffcdc0 100644 --- a/drivers/acpi/toshiba_acpi.c +++ b/drivers/acpi/toshiba_acpi.c | |||
@@ -41,6 +41,8 @@ | |||
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/types.h> | 42 | #include <linux/types.h> |
43 | #include <linux/proc_fs.h> | 43 | #include <linux/proc_fs.h> |
44 | #include <linux/backlight.h> | ||
45 | |||
44 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
45 | 47 | ||
46 | #include <acpi/acpi_drivers.h> | 48 | #include <acpi/acpi_drivers.h> |
@@ -210,6 +212,7 @@ static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result) | |||
210 | } | 212 | } |
211 | 213 | ||
212 | static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; | 214 | static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; |
215 | static struct backlight_device *toshiba_backlight_device; | ||
213 | static int force_fan; | 216 | static int force_fan; |
214 | static int last_key_event; | 217 | static int last_key_event; |
215 | static int key_event_valid; | 218 | static int key_event_valid; |
@@ -271,14 +274,23 @@ dispatch_write(struct file *file, const char __user * buffer, | |||
271 | return result; | 274 | return result; |
272 | } | 275 | } |
273 | 276 | ||
274 | static char *read_lcd(char *p) | 277 | static int get_lcd(struct backlight_device *bd) |
275 | { | 278 | { |
276 | u32 hci_result; | 279 | u32 hci_result; |
277 | u32 value; | 280 | u32 value; |
278 | 281 | ||
279 | hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result); | 282 | hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result); |
280 | if (hci_result == HCI_SUCCESS) { | 283 | if (hci_result == HCI_SUCCESS) { |
281 | value = value >> HCI_LCD_BRIGHTNESS_SHIFT; | 284 | return (value >> HCI_LCD_BRIGHTNESS_SHIFT); |
285 | } else | ||
286 | return -EFAULT; | ||
287 | } | ||
288 | |||
289 | static char *read_lcd(char *p) | ||
290 | { | ||
291 | int value = get_lcd(NULL); | ||
292 | |||
293 | if (value >= 0) { | ||
282 | p += sprintf(p, "brightness: %d\n", value); | 294 | p += sprintf(p, "brightness: %d\n", value); |
283 | p += sprintf(p, "brightness_levels: %d\n", | 295 | p += sprintf(p, "brightness_levels: %d\n", |
284 | HCI_LCD_BRIGHTNESS_LEVELS); | 296 | HCI_LCD_BRIGHTNESS_LEVELS); |
@@ -289,22 +301,37 @@ static char *read_lcd(char *p) | |||
289 | return p; | 301 | return p; |
290 | } | 302 | } |
291 | 303 | ||
304 | static int set_lcd(int value) | ||
305 | { | ||
306 | u32 hci_result; | ||
307 | |||
308 | value = value << HCI_LCD_BRIGHTNESS_SHIFT; | ||
309 | hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result); | ||
310 | if (hci_result != HCI_SUCCESS) | ||
311 | return -EFAULT; | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int set_lcd_status(struct backlight_device *bd) | ||
317 | { | ||
318 | return set_lcd(bd->props->brightness); | ||
319 | } | ||
320 | |||
292 | static unsigned long write_lcd(const char *buffer, unsigned long count) | 321 | static unsigned long write_lcd(const char *buffer, unsigned long count) |
293 | { | 322 | { |
294 | int value; | 323 | int value; |
295 | u32 hci_result; | 324 | int ret; |
296 | 325 | ||
297 | if (sscanf(buffer, " brightness : %i", &value) == 1 && | 326 | if (sscanf(buffer, " brightness : %i", &value) == 1 && |
298 | value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { | 327 | value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { |
299 | value = value << HCI_LCD_BRIGHTNESS_SHIFT; | 328 | ret = set_lcd(value); |
300 | hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result); | 329 | if (ret == 0) |
301 | if (hci_result != HCI_SUCCESS) | 330 | ret = count; |
302 | return -EFAULT; | ||
303 | } else { | 331 | } else { |
304 | return -EINVAL; | 332 | ret = -EINVAL; |
305 | } | 333 | } |
306 | 334 | return ret; | |
307 | return count; | ||
308 | } | 335 | } |
309 | 336 | ||
310 | static char *read_video(char *p) | 337 | static char *read_video(char *p) |
@@ -506,6 +533,26 @@ static acpi_status __exit remove_device(void) | |||
506 | return AE_OK; | 533 | return AE_OK; |
507 | } | 534 | } |
508 | 535 | ||
536 | static struct backlight_properties toshiba_backlight_data = { | ||
537 | .owner = THIS_MODULE, | ||
538 | .get_brightness = get_lcd, | ||
539 | .update_status = set_lcd_status, | ||
540 | .max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1, | ||
541 | }; | ||
542 | |||
543 | static void __exit toshiba_acpi_exit(void) | ||
544 | { | ||
545 | if (toshiba_backlight_device) | ||
546 | backlight_device_unregister(toshiba_backlight_device); | ||
547 | |||
548 | remove_device(); | ||
549 | |||
550 | if (toshiba_proc_dir) | ||
551 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); | ||
552 | |||
553 | return; | ||
554 | } | ||
555 | |||
509 | static int __init toshiba_acpi_init(void) | 556 | static int __init toshiba_acpi_init(void) |
510 | { | 557 | { |
511 | acpi_status status = AE_OK; | 558 | acpi_status status = AE_OK; |
@@ -546,17 +593,16 @@ static int __init toshiba_acpi_init(void) | |||
546 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); | 593 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); |
547 | } | 594 | } |
548 | 595 | ||
549 | return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; | 596 | toshiba_backlight_device = backlight_device_register("toshiba",NULL, |
550 | } | 597 | NULL, |
551 | 598 | &toshiba_backlight_data); | |
552 | static void __exit toshiba_acpi_exit(void) | 599 | if (IS_ERR(toshiba_backlight_device)) { |
553 | { | 600 | printk(KERN_ERR "Could not register toshiba backlight device\n"); |
554 | remove_device(); | 601 | toshiba_backlight_device = NULL; |
555 | 602 | toshiba_acpi_exit(); | |
556 | if (toshiba_proc_dir) | 603 | } |
557 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); | ||
558 | 604 | ||
559 | return; | 605 | return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; |
560 | } | 606 | } |
561 | 607 | ||
562 | module_init(toshiba_acpi_init); | 608 | module_init(toshiba_acpi_init); |
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index f6cbc0b1bfd0..55a764807499 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -42,6 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acdebug.h> | ||
45 | 46 | ||
46 | #define _COMPONENT ACPI_UTILITIES | 47 | #define _COMPONENT ACPI_UTILITIES |
47 | ACPI_MODULE_NAME("utalloc") | 48 | ACPI_MODULE_NAME("utalloc") |
@@ -142,6 +143,14 @@ acpi_status acpi_ut_create_caches(void) | |||
142 | 143 | ||
143 | acpi_status acpi_ut_delete_caches(void) | 144 | acpi_status acpi_ut_delete_caches(void) |
144 | { | 145 | { |
146 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
147 | char buffer[7]; | ||
148 | |||
149 | if (acpi_gbl_display_final_mem_stats) { | ||
150 | ACPI_STRCPY(buffer, "MEMORY"); | ||
151 | acpi_db_display_statistics(buffer); | ||
152 | } | ||
153 | #endif | ||
145 | 154 | ||
146 | (void)acpi_os_delete_cache(acpi_gbl_namespace_cache); | 155 | (void)acpi_os_delete_cache(acpi_gbl_namespace_cache); |
147 | acpi_gbl_namespace_cache = NULL; | 156 | acpi_gbl_namespace_cache = NULL; |
diff --git a/drivers/acpi/utilities/utcache.c b/drivers/acpi/utilities/utcache.c index 1a1f8109159c..870f6edeb5f2 100644 --- a/drivers/acpi/utilities/utcache.c +++ b/drivers/acpi/utilities/utcache.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -289,6 +289,14 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) | |||
289 | 289 | ||
290 | ACPI_MEM_TRACKING(cache->total_allocated++); | 290 | ACPI_MEM_TRACKING(cache->total_allocated++); |
291 | 291 | ||
292 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
293 | if ((cache->total_allocated - cache->total_freed) > | ||
294 | cache->max_occupied) { | ||
295 | cache->max_occupied = | ||
296 | cache->total_allocated - cache->total_freed; | ||
297 | } | ||
298 | #endif | ||
299 | |||
292 | /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */ | 300 | /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */ |
293 | 301 | ||
294 | status = acpi_ut_release_mutex(ACPI_MTX_CACHES); | 302 | status = acpi_ut_release_mutex(ACPI_MTX_CACHES); |
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index 5e1a80d1bc36..84d529db0a66 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -719,6 +719,15 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | |||
719 | acpi_ut_add_reference(source_desc->reference.object); | 719 | acpi_ut_add_reference(source_desc->reference.object); |
720 | break; | 720 | break; |
721 | 721 | ||
722 | case ACPI_TYPE_REGION: | ||
723 | /* | ||
724 | * We copied the Region Handler, so we now must add a reference | ||
725 | */ | ||
726 | if (dest_desc->region.handler) { | ||
727 | acpi_ut_add_reference(dest_desc->region.handler); | ||
728 | } | ||
729 | break; | ||
730 | |||
722 | default: | 731 | default: |
723 | /* Nothing to do for other simple objects */ | 732 | /* Nothing to do for other simple objects */ |
724 | break; | 733 | break; |
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c index bb1eaf9aa653..61ad4f2daee2 100644 --- a/drivers/acpi/utilities/utdebug.c +++ b/drivers/acpi/utilities/utdebug.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -180,8 +180,8 @@ acpi_ut_debug_print(u32 requested_debug_level, | |||
180 | if (thread_id != acpi_gbl_prev_thread_id) { | 180 | if (thread_id != acpi_gbl_prev_thread_id) { |
181 | if (ACPI_LV_THREADS & acpi_dbg_level) { | 181 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
182 | acpi_os_printf | 182 | acpi_os_printf |
183 | ("\n**** Context Switch from TID %X to TID %X ****\n\n", | 183 | ("\n**** Context Switch from TID %lX to TID %lX ****\n\n", |
184 | (u32) acpi_gbl_prev_thread_id, (u32) thread_id); | 184 | (unsigned long)acpi_gbl_prev_thread_id, (unsigned long)thread_id); |
185 | } | 185 | } |
186 | 186 | ||
187 | acpi_gbl_prev_thread_id = thread_id; | 187 | acpi_gbl_prev_thread_id = thread_id; |
@@ -194,7 +194,7 @@ acpi_ut_debug_print(u32 requested_debug_level, | |||
194 | acpi_os_printf("%8s-%04ld ", module_name, line_number); | 194 | acpi_os_printf("%8s-%04ld ", module_name, line_number); |
195 | 195 | ||
196 | if (ACPI_LV_THREADS & acpi_dbg_level) { | 196 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
197 | acpi_os_printf("[%04lX] ", thread_id); | 197 | acpi_os_printf("[%04lX] ", (unsigned long)thread_id); |
198 | } | 198 | } |
199 | 199 | ||
200 | acpi_os_printf("[%02ld] %-22.22s: ", | 200 | acpi_os_printf("[%02ld] %-22.22s: ", |
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 9d3f1149ba21..f777cebdc46d 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -158,16 +158,20 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
158 | "***** Mutex %p, OS Mutex %p\n", | 158 | "***** Mutex %p, OS Mutex %p\n", |
159 | object, object->mutex.os_mutex)); | 159 | object, object->mutex.os_mutex)); |
160 | 160 | ||
161 | if (object->mutex.os_mutex != ACPI_GLOBAL_LOCK) { | 161 | if (object->mutex.os_mutex == acpi_gbl_global_lock_mutex) { |
162 | acpi_ex_unlink_mutex(object); | 162 | |
163 | acpi_os_delete_mutex(object->mutex.os_mutex); | 163 | /* Global Lock has extra semaphore */ |
164 | } else { | ||
165 | /* Global Lock "mutex" is actually a counting semaphore */ | ||
166 | 164 | ||
167 | (void) | 165 | (void) |
168 | acpi_os_delete_semaphore | 166 | acpi_os_delete_semaphore |
169 | (acpi_gbl_global_lock_semaphore); | 167 | (acpi_gbl_global_lock_semaphore); |
170 | acpi_gbl_global_lock_semaphore = NULL; | 168 | acpi_gbl_global_lock_semaphore = NULL; |
169 | |||
170 | acpi_os_delete_mutex(object->mutex.os_mutex); | ||
171 | acpi_gbl_global_lock_mutex = NULL; | ||
172 | } else { | ||
173 | acpi_ex_unlink_mutex(object); | ||
174 | acpi_os_delete_mutex(object->mutex.os_mutex); | ||
171 | } | 175 | } |
172 | break; | 176 | break; |
173 | 177 | ||
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index d6d7121583c0..13d5879cd98b 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 014030af8b50..af33358a964b 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -46,89 +46,9 @@ | |||
46 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
47 | #include <acpi/acnamesp.h> | 47 | #include <acpi/acnamesp.h> |
48 | 48 | ||
49 | ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) | ||
49 | #define _COMPONENT ACPI_UTILITIES | 50 | #define _COMPONENT ACPI_UTILITIES |
50 | ACPI_MODULE_NAME("utglobal") | 51 | ACPI_MODULE_NAME("utglobal") |
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_format_exception | ||
55 | * | ||
56 | * PARAMETERS: Status - The acpi_status code to be formatted | ||
57 | * | ||
58 | * RETURN: A string containing the exception text. A valid pointer is | ||
59 | * always returned. | ||
60 | * | ||
61 | * DESCRIPTION: This function translates an ACPI exception into an ASCII string. | ||
62 | * | ||
63 | ******************************************************************************/ | ||
64 | const char *acpi_format_exception(acpi_status status) | ||
65 | { | ||
66 | acpi_status sub_status; | ||
67 | const char *exception = NULL; | ||
68 | |||
69 | ACPI_FUNCTION_ENTRY(); | ||
70 | |||
71 | /* | ||
72 | * Status is composed of two parts, a "type" and an actual code | ||
73 | */ | ||
74 | sub_status = (status & ~AE_CODE_MASK); | ||
75 | |||
76 | switch (status & AE_CODE_MASK) { | ||
77 | case AE_CODE_ENVIRONMENTAL: | ||
78 | |||
79 | if (sub_status <= AE_CODE_ENV_MAX) { | ||
80 | exception = acpi_gbl_exception_names_env[sub_status]; | ||
81 | } | ||
82 | break; | ||
83 | |||
84 | case AE_CODE_PROGRAMMER: | ||
85 | |||
86 | if (sub_status <= AE_CODE_PGM_MAX) { | ||
87 | exception = | ||
88 | acpi_gbl_exception_names_pgm[sub_status - 1]; | ||
89 | } | ||
90 | break; | ||
91 | |||
92 | case AE_CODE_ACPI_TABLES: | ||
93 | |||
94 | if (sub_status <= AE_CODE_TBL_MAX) { | ||
95 | exception = | ||
96 | acpi_gbl_exception_names_tbl[sub_status - 1]; | ||
97 | } | ||
98 | break; | ||
99 | |||
100 | case AE_CODE_AML: | ||
101 | |||
102 | if (sub_status <= AE_CODE_AML_MAX) { | ||
103 | exception = | ||
104 | acpi_gbl_exception_names_aml[sub_status - 1]; | ||
105 | } | ||
106 | break; | ||
107 | |||
108 | case AE_CODE_CONTROL: | ||
109 | |||
110 | if (sub_status <= AE_CODE_CTRL_MAX) { | ||
111 | exception = | ||
112 | acpi_gbl_exception_names_ctrl[sub_status - 1]; | ||
113 | } | ||
114 | break; | ||
115 | |||
116 | default: | ||
117 | break; | ||
118 | } | ||
119 | |||
120 | if (!exception) { | ||
121 | |||
122 | /* Exception code was not recognized */ | ||
123 | |||
124 | ACPI_ERROR((AE_INFO, | ||
125 | "Unknown exception code: 0x%8.8X", status)); | ||
126 | |||
127 | exception = "UNKNOWN_STATUS_CODE"; | ||
128 | } | ||
129 | |||
130 | return (ACPI_CAST_PTR(const char, exception)); | ||
131 | } | ||
132 | 52 | ||
133 | /******************************************************************************* | 53 | /******************************************************************************* |
134 | * | 54 | * |
@@ -163,8 +83,6 @@ u32 acpi_gbl_startup_flags = 0; | |||
163 | 83 | ||
164 | u8 acpi_gbl_shutdown = TRUE; | 84 | u8 acpi_gbl_shutdown = TRUE; |
165 | 85 | ||
166 | const u8 acpi_gbl_decode_to8bit[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; | ||
167 | |||
168 | const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { | 86 | const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { |
169 | "\\_S0_", | 87 | "\\_S0_", |
170 | "\\_S1_", | 88 | "\\_S1_", |
@@ -183,10 +101,45 @@ const char *acpi_gbl_highest_dstate_names[4] = { | |||
183 | 101 | ||
184 | /******************************************************************************* | 102 | /******************************************************************************* |
185 | * | 103 | * |
186 | * Namespace globals | 104 | * FUNCTION: acpi_format_exception |
105 | * | ||
106 | * PARAMETERS: Status - The acpi_status code to be formatted | ||
107 | * | ||
108 | * RETURN: A string containing the exception text. A valid pointer is | ||
109 | * always returned. | ||
110 | * | ||
111 | * DESCRIPTION: This function translates an ACPI exception into an ASCII string | ||
112 | * It is here instead of utxface.c so it is always present. | ||
187 | * | 113 | * |
188 | ******************************************************************************/ | 114 | ******************************************************************************/ |
189 | 115 | ||
116 | const char *acpi_format_exception(acpi_status status) | ||
117 | { | ||
118 | const char *exception = NULL; | ||
119 | |||
120 | ACPI_FUNCTION_ENTRY(); | ||
121 | |||
122 | exception = acpi_ut_validate_exception(status); | ||
123 | if (!exception) { | ||
124 | |||
125 | /* Exception code was not recognized */ | ||
126 | |||
127 | ACPI_ERROR((AE_INFO, | ||
128 | "Unknown exception code: 0x%8.8X", status)); | ||
129 | |||
130 | exception = "UNKNOWN_STATUS_CODE"; | ||
131 | } | ||
132 | |||
133 | return (ACPI_CAST_PTR(const char, exception)); | ||
134 | } | ||
135 | |||
136 | ACPI_EXPORT_SYMBOL(acpi_format_exception) | ||
137 | |||
138 | /******************************************************************************* | ||
139 | * | ||
140 | * Namespace globals | ||
141 | * | ||
142 | ******************************************************************************/ | ||
190 | /* | 143 | /* |
191 | * Predefined ACPI Names (Built-in to the Interpreter) | 144 | * Predefined ACPI Names (Built-in to the Interpreter) |
192 | * | 145 | * |
@@ -280,53 +233,6 @@ char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position) | |||
280 | return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); | 233 | return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); |
281 | } | 234 | } |
282 | 235 | ||
283 | /******************************************************************************* | ||
284 | * | ||
285 | * Table name globals | ||
286 | * | ||
287 | * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes. | ||
288 | * it is NOT an exhaustive list of all possible ACPI tables. All ACPI tables | ||
289 | * that are not used by the subsystem are simply ignored. | ||
290 | * | ||
291 | * Do NOT add any table to this list that is not consumed directly by this | ||
292 | * subsystem (No MADT, ECDT, SBST, etc.) | ||
293 | * | ||
294 | ******************************************************************************/ | ||
295 | |||
296 | struct acpi_table_list acpi_gbl_table_lists[ACPI_TABLE_ID_MAX + 1]; | ||
297 | |||
298 | struct acpi_table_support acpi_gbl_table_data[ACPI_TABLE_ID_MAX + 1] = { | ||
299 | /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */ | ||
300 | |||
301 | /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof(RSDP_SIG) - 1, | ||
302 | ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE} | ||
303 | , | ||
304 | /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *)&acpi_gbl_DSDT, | ||
305 | sizeof(DSDT_SIG) - 1, | ||
306 | ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE | | ||
307 | ACPI_TABLE_EXECUTABLE} | ||
308 | , | ||
309 | /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *)&acpi_gbl_FADT, | ||
310 | sizeof(FADT_SIG) - 1, | ||
311 | ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE} | ||
312 | , | ||
313 | /* FACS 3 */ {FACS_SIG, FACS_SIG, (void *)&acpi_gbl_FACS, | ||
314 | sizeof(FACS_SIG) - 1, | ||
315 | ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE} | ||
316 | , | ||
317 | /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof(PSDT_SIG) - 1, | ||
318 | ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | | ||
319 | ACPI_TABLE_EXECUTABLE} | ||
320 | , | ||
321 | /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof(SSDT_SIG) - 1, | ||
322 | ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | | ||
323 | ACPI_TABLE_EXECUTABLE} | ||
324 | , | ||
325 | /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof(RSDT_SIG) - 1, | ||
326 | ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE} | ||
327 | , | ||
328 | }; | ||
329 | |||
330 | /****************************************************************************** | 236 | /****************************************************************************** |
331 | * | 237 | * |
332 | * Event and Hardware globals | 238 | * Event and Hardware globals |
@@ -612,7 +518,7 @@ char *acpi_ut_get_node_name(void *object) | |||
612 | /* Name must be a valid ACPI name */ | 518 | /* Name must be a valid ACPI name */ |
613 | 519 | ||
614 | if (!acpi_ut_valid_acpi_name(node->name.integer)) { | 520 | if (!acpi_ut_valid_acpi_name(node->name.integer)) { |
615 | node->name.integer = acpi_ut_repair_name(node->name.integer); | 521 | node->name.integer = acpi_ut_repair_name(node->name.ascii); |
616 | } | 522 | } |
617 | 523 | ||
618 | /* Return the name */ | 524 | /* Return the name */ |
@@ -751,13 +657,6 @@ void acpi_ut_init_globals(void) | |||
751 | return; | 657 | return; |
752 | } | 658 | } |
753 | 659 | ||
754 | /* ACPI table structure */ | ||
755 | |||
756 | for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { | ||
757 | acpi_gbl_table_lists[i].next = NULL; | ||
758 | acpi_gbl_table_lists[i].count = 0; | ||
759 | } | ||
760 | |||
761 | /* Mutex locked flags */ | 660 | /* Mutex locked flags */ |
762 | 661 | ||
763 | for (i = 0; i < ACPI_NUM_MUTEX; i++) { | 662 | for (i = 0; i < ACPI_NUM_MUTEX; i++) { |
@@ -773,6 +672,7 @@ void acpi_ut_init_globals(void) | |||
773 | 672 | ||
774 | /* GPE support */ | 673 | /* GPE support */ |
775 | 674 | ||
675 | acpi_gpe_count = 0; | ||
776 | acpi_gbl_gpe_xrupt_list_head = NULL; | 676 | acpi_gbl_gpe_xrupt_list_head = NULL; |
777 | acpi_gbl_gpe_fadt_blocks[0] = NULL; | 677 | acpi_gbl_gpe_fadt_blocks[0] = NULL; |
778 | acpi_gbl_gpe_fadt_blocks[1] = NULL; | 678 | acpi_gbl_gpe_fadt_blocks[1] = NULL; |
@@ -784,25 +684,15 @@ void acpi_ut_init_globals(void) | |||
784 | acpi_gbl_exception_handler = NULL; | 684 | acpi_gbl_exception_handler = NULL; |
785 | acpi_gbl_init_handler = NULL; | 685 | acpi_gbl_init_handler = NULL; |
786 | 686 | ||
787 | /* Global "typed" ACPI table pointers */ | ||
788 | |||
789 | acpi_gbl_RSDP = NULL; | ||
790 | acpi_gbl_XSDT = NULL; | ||
791 | acpi_gbl_FACS = NULL; | ||
792 | acpi_gbl_FADT = NULL; | ||
793 | acpi_gbl_DSDT = NULL; | ||
794 | |||
795 | /* Global Lock support */ | 687 | /* Global Lock support */ |
796 | 688 | ||
797 | acpi_gbl_global_lock_semaphore = NULL; | 689 | acpi_gbl_global_lock_semaphore = NULL; |
690 | acpi_gbl_global_lock_mutex = NULL; | ||
798 | acpi_gbl_global_lock_acquired = FALSE; | 691 | acpi_gbl_global_lock_acquired = FALSE; |
799 | acpi_gbl_global_lock_thread_count = 0; | ||
800 | acpi_gbl_global_lock_handle = 0; | 692 | acpi_gbl_global_lock_handle = 0; |
801 | 693 | ||
802 | /* Miscellaneous variables */ | 694 | /* Miscellaneous variables */ |
803 | 695 | ||
804 | acpi_gbl_table_flags = ACPI_PHYSICAL_POINTER; | ||
805 | acpi_gbl_rsdp_original_location = 0; | ||
806 | acpi_gbl_cm_single_step = FALSE; | 696 | acpi_gbl_cm_single_step = FALSE; |
807 | acpi_gbl_db_terminate_threads = FALSE; | 697 | acpi_gbl_db_terminate_threads = FALSE; |
808 | acpi_gbl_shutdown = FALSE; | 698 | acpi_gbl_shutdown = FALSE; |
@@ -837,8 +727,13 @@ void acpi_ut_init_globals(void) | |||
837 | acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX; | 727 | acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX; |
838 | #endif | 728 | #endif |
839 | 729 | ||
730 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
731 | acpi_gbl_display_final_mem_stats = FALSE; | ||
732 | #endif | ||
733 | |||
840 | return_VOID; | 734 | return_VOID; |
841 | } | 735 | } |
842 | 736 | ||
843 | ACPI_EXPORT_SYMBOL(acpi_dbg_level) | 737 | ACPI_EXPORT_SYMBOL(acpi_dbg_level) |
844 | ACPI_EXPORT_SYMBOL(acpi_dbg_layer) | 738 | ACPI_EXPORT_SYMBOL(acpi_dbg_layer) |
739 | ACPI_EXPORT_SYMBOL(acpi_gpe_count) | ||
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c index ff76055eb7d6..ad3c0d0a5cf8 100644 --- a/drivers/acpi/utilities/utinit.c +++ b/drivers/acpi/utilities/utinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -44,119 +44,14 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
46 | #include <acpi/acevents.h> | 46 | #include <acpi/acevents.h> |
47 | #include <acpi/actables.h> | ||
47 | 48 | ||
48 | #define _COMPONENT ACPI_UTILITIES | 49 | #define _COMPONENT ACPI_UTILITIES |
49 | ACPI_MODULE_NAME("utinit") | 50 | ACPI_MODULE_NAME("utinit") |
50 | 51 | ||
51 | /* Local prototypes */ | 52 | /* Local prototypes */ |
52 | static void | ||
53 | acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset); | ||
54 | |||
55 | static void acpi_ut_terminate(void); | 53 | static void acpi_ut_terminate(void); |
56 | 54 | ||
57 | /******************************************************************************* | ||
58 | * | ||
59 | * FUNCTION: acpi_ut_fadt_register_error | ||
60 | * | ||
61 | * PARAMETERS: register_name - Pointer to string identifying register | ||
62 | * Value - Actual register contents value | ||
63 | * Offset - Byte offset in the FADT | ||
64 | * | ||
65 | * RETURN: AE_BAD_VALUE | ||
66 | * | ||
67 | * DESCRIPTION: Display failure message | ||
68 | * | ||
69 | ******************************************************************************/ | ||
70 | |||
71 | static void | ||
72 | acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset) | ||
73 | { | ||
74 | |||
75 | ACPI_WARNING((AE_INFO, | ||
76 | "Invalid FADT value %s=%X at offset %X FADT=%p", | ||
77 | register_name, value, offset, acpi_gbl_FADT)); | ||
78 | } | ||
79 | |||
80 | /****************************************************************************** | ||
81 | * | ||
82 | * FUNCTION: acpi_ut_validate_fadt | ||
83 | * | ||
84 | * PARAMETERS: None | ||
85 | * | ||
86 | * RETURN: Status | ||
87 | * | ||
88 | * DESCRIPTION: Validate various ACPI registers in the FADT | ||
89 | * | ||
90 | ******************************************************************************/ | ||
91 | |||
92 | acpi_status acpi_ut_validate_fadt(void) | ||
93 | { | ||
94 | |||
95 | /* | ||
96 | * Verify Fixed ACPI Description Table fields, | ||
97 | * but don't abort on any problems, just display error | ||
98 | */ | ||
99 | if (acpi_gbl_FADT->pm1_evt_len < 4) { | ||
100 | acpi_ut_fadt_register_error("PM1_EVT_LEN", | ||
101 | (u32) acpi_gbl_FADT->pm1_evt_len, | ||
102 | ACPI_FADT_OFFSET(pm1_evt_len)); | ||
103 | } | ||
104 | |||
105 | if (!acpi_gbl_FADT->pm1_cnt_len) { | ||
106 | acpi_ut_fadt_register_error("PM1_CNT_LEN", 0, | ||
107 | ACPI_FADT_OFFSET(pm1_cnt_len)); | ||
108 | } | ||
109 | |||
110 | if (!acpi_gbl_FADT->xpm1a_evt_blk.address) { | ||
111 | acpi_ut_fadt_register_error("X_PM1a_EVT_BLK", 0, | ||
112 | ACPI_FADT_OFFSET(xpm1a_evt_blk. | ||
113 | address)); | ||
114 | } | ||
115 | |||
116 | if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) { | ||
117 | acpi_ut_fadt_register_error("X_PM1a_CNT_BLK", 0, | ||
118 | ACPI_FADT_OFFSET(xpm1a_cnt_blk. | ||
119 | address)); | ||
120 | } | ||
121 | |||
122 | if (!acpi_gbl_FADT->xpm_tmr_blk.address) { | ||
123 | acpi_ut_fadt_register_error("X_PM_TMR_BLK", 0, | ||
124 | ACPI_FADT_OFFSET(xpm_tmr_blk. | ||
125 | address)); | ||
126 | } | ||
127 | |||
128 | if ((acpi_gbl_FADT->xpm2_cnt_blk.address && | ||
129 | !acpi_gbl_FADT->pm2_cnt_len)) { | ||
130 | acpi_ut_fadt_register_error("PM2_CNT_LEN", | ||
131 | (u32) acpi_gbl_FADT->pm2_cnt_len, | ||
132 | ACPI_FADT_OFFSET(pm2_cnt_len)); | ||
133 | } | ||
134 | |||
135 | if (acpi_gbl_FADT->pm_tm_len < 4) { | ||
136 | acpi_ut_fadt_register_error("PM_TM_LEN", | ||
137 | (u32) acpi_gbl_FADT->pm_tm_len, | ||
138 | ACPI_FADT_OFFSET(pm_tm_len)); | ||
139 | } | ||
140 | |||
141 | /* Length of GPE blocks must be a multiple of 2 */ | ||
142 | |||
143 | if (acpi_gbl_FADT->xgpe0_blk.address && | ||
144 | (acpi_gbl_FADT->gpe0_blk_len & 1)) { | ||
145 | acpi_ut_fadt_register_error("(x)GPE0_BLK_LEN", | ||
146 | (u32) acpi_gbl_FADT->gpe0_blk_len, | ||
147 | ACPI_FADT_OFFSET(gpe0_blk_len)); | ||
148 | } | ||
149 | |||
150 | if (acpi_gbl_FADT->xgpe1_blk.address && | ||
151 | (acpi_gbl_FADT->gpe1_blk_len & 1)) { | ||
152 | acpi_ut_fadt_register_error("(x)GPE1_BLK_LEN", | ||
153 | (u32) acpi_gbl_FADT->gpe1_blk_len, | ||
154 | ACPI_FADT_OFFSET(gpe1_blk_len)); | ||
155 | } | ||
156 | |||
157 | return (AE_OK); | ||
158 | } | ||
159 | |||
160 | /****************************************************************************** | 55 | /****************************************************************************** |
161 | * | 56 | * |
162 | * FUNCTION: acpi_ut_terminate | 57 | * FUNCTION: acpi_ut_terminate |
@@ -178,7 +73,6 @@ static void acpi_ut_terminate(void) | |||
178 | 73 | ||
179 | ACPI_FUNCTION_TRACE(ut_terminate); | 74 | ACPI_FUNCTION_TRACE(ut_terminate); |
180 | 75 | ||
181 | /* Free global tables, etc. */ | ||
182 | /* Free global GPE blocks and related info structures */ | 76 | /* Free global GPE blocks and related info structures */ |
183 | 77 | ||
184 | gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; | 78 | gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; |
@@ -239,6 +133,10 @@ void acpi_ut_subsystem_shutdown(void) | |||
239 | 133 | ||
240 | acpi_ns_terminate(); | 134 | acpi_ns_terminate(); |
241 | 135 | ||
136 | /* Delete the ACPI tables */ | ||
137 | |||
138 | acpi_tb_terminate(); | ||
139 | |||
242 | /* Close the globals */ | 140 | /* Close the globals */ |
243 | 141 | ||
244 | acpi_ut_terminate(); | 142 | acpi_ut_terminate(); |
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c index 19d74bedce27..0c56a0d20b29 100644 --- a/drivers/acpi/utilities/utmath.c +++ b/drivers/acpi/utilities/utmath.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 6d8a8211be90..50133fffe420 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -51,6 +51,78 @@ ACPI_MODULE_NAME("utmisc") | |||
51 | 51 | ||
52 | /******************************************************************************* | 52 | /******************************************************************************* |
53 | * | 53 | * |
54 | * FUNCTION: acpi_ut_validate_exception | ||
55 | * | ||
56 | * PARAMETERS: Status - The acpi_status code to be formatted | ||
57 | * | ||
58 | * RETURN: A string containing the exception text. NULL if exception is | ||
59 | * not valid. | ||
60 | * | ||
61 | * DESCRIPTION: This function validates and translates an ACPI exception into | ||
62 | * an ASCII string. | ||
63 | * | ||
64 | ******************************************************************************/ | ||
65 | const char *acpi_ut_validate_exception(acpi_status status) | ||
66 | { | ||
67 | acpi_status sub_status; | ||
68 | const char *exception = NULL; | ||
69 | |||
70 | ACPI_FUNCTION_ENTRY(); | ||
71 | |||
72 | /* | ||
73 | * Status is composed of two parts, a "type" and an actual code | ||
74 | */ | ||
75 | sub_status = (status & ~AE_CODE_MASK); | ||
76 | |||
77 | switch (status & AE_CODE_MASK) { | ||
78 | case AE_CODE_ENVIRONMENTAL: | ||
79 | |||
80 | if (sub_status <= AE_CODE_ENV_MAX) { | ||
81 | exception = acpi_gbl_exception_names_env[sub_status]; | ||
82 | } | ||
83 | break; | ||
84 | |||
85 | case AE_CODE_PROGRAMMER: | ||
86 | |||
87 | if (sub_status <= AE_CODE_PGM_MAX) { | ||
88 | exception = | ||
89 | acpi_gbl_exception_names_pgm[sub_status - 1]; | ||
90 | } | ||
91 | break; | ||
92 | |||
93 | case AE_CODE_ACPI_TABLES: | ||
94 | |||
95 | if (sub_status <= AE_CODE_TBL_MAX) { | ||
96 | exception = | ||
97 | acpi_gbl_exception_names_tbl[sub_status - 1]; | ||
98 | } | ||
99 | break; | ||
100 | |||
101 | case AE_CODE_AML: | ||
102 | |||
103 | if (sub_status <= AE_CODE_AML_MAX) { | ||
104 | exception = | ||
105 | acpi_gbl_exception_names_aml[sub_status - 1]; | ||
106 | } | ||
107 | break; | ||
108 | |||
109 | case AE_CODE_CONTROL: | ||
110 | |||
111 | if (sub_status <= AE_CODE_CTRL_MAX) { | ||
112 | exception = | ||
113 | acpi_gbl_exception_names_ctrl[sub_status - 1]; | ||
114 | } | ||
115 | break; | ||
116 | |||
117 | default: | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | return (ACPI_CAST_PTR(const char, exception)); | ||
122 | } | ||
123 | |||
124 | /******************************************************************************* | ||
125 | * | ||
54 | * FUNCTION: acpi_ut_is_aml_table | 126 | * FUNCTION: acpi_ut_is_aml_table |
55 | * | 127 | * |
56 | * PARAMETERS: Table - An ACPI table | 128 | * PARAMETERS: Table - An ACPI table |
@@ -62,14 +134,15 @@ ACPI_MODULE_NAME("utmisc") | |||
62 | * data tables that do not contain AML code. | 134 | * data tables that do not contain AML code. |
63 | * | 135 | * |
64 | ******************************************************************************/ | 136 | ******************************************************************************/ |
137 | |||
65 | u8 acpi_ut_is_aml_table(struct acpi_table_header *table) | 138 | u8 acpi_ut_is_aml_table(struct acpi_table_header *table) |
66 | { | 139 | { |
67 | 140 | ||
68 | /* These are the only tables that contain executable AML */ | 141 | /* These are the only tables that contain executable AML */ |
69 | 142 | ||
70 | if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) || | 143 | if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) || |
71 | ACPI_COMPARE_NAME(table->signature, PSDT_SIG) || | 144 | ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) || |
72 | ACPI_COMPARE_NAME(table->signature, SSDT_SIG)) { | 145 | ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) { |
73 | return (TRUE); | 146 | return (TRUE); |
74 | } | 147 | } |
75 | 148 | ||
@@ -418,7 +491,7 @@ u32 acpi_ut_dword_byte_swap(u32 value) | |||
418 | void acpi_ut_set_integer_width(u8 revision) | 491 | void acpi_ut_set_integer_width(u8 revision) |
419 | { | 492 | { |
420 | 493 | ||
421 | if (revision <= 1) { | 494 | if (revision < 2) { |
422 | 495 | ||
423 | /* 32-bit case */ | 496 | /* 32-bit case */ |
424 | 497 | ||
@@ -582,26 +655,25 @@ u8 acpi_ut_valid_acpi_name(u32 name) | |||
582 | * | 655 | * |
583 | ******************************************************************************/ | 656 | ******************************************************************************/ |
584 | 657 | ||
585 | acpi_name acpi_ut_repair_name(acpi_name name) | 658 | acpi_name acpi_ut_repair_name(char *name) |
586 | { | 659 | { |
587 | char *name_ptr = ACPI_CAST_PTR(char, &name); | ||
588 | char new_name[ACPI_NAME_SIZE]; | ||
589 | acpi_native_uint i; | 660 | acpi_native_uint i; |
661 | char new_name[ACPI_NAME_SIZE]; | ||
590 | 662 | ||
591 | for (i = 0; i < ACPI_NAME_SIZE; i++) { | 663 | for (i = 0; i < ACPI_NAME_SIZE; i++) { |
592 | new_name[i] = name_ptr[i]; | 664 | new_name[i] = name[i]; |
593 | 665 | ||
594 | /* | 666 | /* |
595 | * Replace a bad character with something printable, yet technically | 667 | * Replace a bad character with something printable, yet technically |
596 | * still invalid. This prevents any collisions with existing "good" | 668 | * still invalid. This prevents any collisions with existing "good" |
597 | * names in the namespace. | 669 | * names in the namespace. |
598 | */ | 670 | */ |
599 | if (!acpi_ut_valid_acpi_char(name_ptr[i], i)) { | 671 | if (!acpi_ut_valid_acpi_char(name[i], i)) { |
600 | new_name[i] = '*'; | 672 | new_name[i] = '*'; |
601 | } | 673 | } |
602 | } | 674 | } |
603 | 675 | ||
604 | return (*ACPI_CAST_PTR(u32, new_name)); | 676 | return (*(u32 *) new_name); |
605 | } | 677 | } |
606 | 678 | ||
607 | /******************************************************************************* | 679 | /******************************************************************************* |
@@ -996,9 +1068,13 @@ acpi_ut_info(char *module_name, u32 line_number, char *format, ...) | |||
996 | { | 1068 | { |
997 | va_list args; | 1069 | va_list args; |
998 | 1070 | ||
999 | acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number); | 1071 | /* |
1072 | * Removed module_name, line_number, and acpica version, not needed | ||
1073 | * for info output | ||
1074 | */ | ||
1075 | acpi_os_printf("ACPI: "); | ||
1000 | 1076 | ||
1001 | va_start(args, format); | 1077 | va_start(args, format); |
1002 | acpi_os_vprintf(format, args); | 1078 | acpi_os_vprintf(format, args); |
1003 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1079 | acpi_os_printf("\n"); |
1004 | } | 1080 | } |
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c index c39062a047cd..cbad2ef5987d 100644 --- a/drivers/acpi/utilities/utmutex.c +++ b/drivers/acpi/utilities/utmutex.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -243,23 +243,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
243 | #endif | 243 | #endif |
244 | 244 | ||
245 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 245 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
246 | "Thread %X attempting to acquire Mutex [%s]\n", | 246 | "Thread %lX attempting to acquire Mutex [%s]\n", |
247 | (u32) this_thread_id, acpi_ut_get_mutex_name(mutex_id))); | 247 | (unsigned long) this_thread_id, |
248 | acpi_ut_get_mutex_name(mutex_id))); | ||
248 | 249 | ||
249 | status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, | 250 | status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, |
250 | ACPI_WAIT_FOREVER); | 251 | ACPI_WAIT_FOREVER); |
251 | if (ACPI_SUCCESS(status)) { | 252 | if (ACPI_SUCCESS(status)) { |
252 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 253 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
253 | "Thread %X acquired Mutex [%s]\n", | 254 | "Thread %lX acquired Mutex [%s]\n", |
254 | (u32) this_thread_id, | 255 | (unsigned long) this_thread_id, |
255 | acpi_ut_get_mutex_name(mutex_id))); | 256 | acpi_ut_get_mutex_name(mutex_id))); |
256 | 257 | ||
257 | acpi_gbl_mutex_info[mutex_id].use_count++; | 258 | acpi_gbl_mutex_info[mutex_id].use_count++; |
258 | acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; | 259 | acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; |
259 | } else { | 260 | } else { |
260 | ACPI_EXCEPTION((AE_INFO, status, | 261 | ACPI_EXCEPTION((AE_INFO, status, |
261 | "Thread %X could not acquire Mutex [%X]", | 262 | "Thread %lX could not acquire Mutex [%X]", |
262 | (u32) this_thread_id, mutex_id)); | 263 | (unsigned long) this_thread_id, mutex_id)); |
263 | } | 264 | } |
264 | 265 | ||
265 | return (status); | 266 | return (status); |
@@ -285,7 +286,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) | |||
285 | 286 | ||
286 | this_thread_id = acpi_os_get_thread_id(); | 287 | this_thread_id = acpi_os_get_thread_id(); |
287 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 288 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
288 | "Thread %X releasing Mutex [%s]\n", (u32) this_thread_id, | 289 | "Thread %lX releasing Mutex [%s]\n", |
290 | (unsigned long) this_thread_id, | ||
289 | acpi_ut_get_mutex_name(mutex_id))); | 291 | acpi_ut_get_mutex_name(mutex_id))); |
290 | 292 | ||
291 | if (mutex_id > ACPI_MAX_MUTEX) { | 293 | if (mutex_id > ACPI_MAX_MUTEX) { |
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index ba7d8ac702df..4696124759e1 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c index 5a2de92831d3..e8fe1ba6cc24 100644 --- a/drivers/acpi/utilities/utresrc.c +++ b/drivers/acpi/utilities/utresrc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c index eaa13d05c859..edcaafad0a31 100644 --- a/drivers/acpi/utilities/utstate.c +++ b/drivers/acpi/utilities/utstate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index 3538f69c82a1..de3276f4f468 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -67,6 +67,7 @@ acpi_status acpi_initialize_subsystem(void) | |||
67 | 67 | ||
68 | ACPI_FUNCTION_TRACE(acpi_initialize_subsystem); | 68 | ACPI_FUNCTION_TRACE(acpi_initialize_subsystem); |
69 | 69 | ||
70 | acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE; | ||
70 | ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace()); | 71 | ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace()); |
71 | 72 | ||
72 | /* Initialize the OS-Dependent layer */ | 73 | /* Initialize the OS-Dependent layer */ |
@@ -127,20 +128,6 @@ acpi_status acpi_enable_subsystem(u32 flags) | |||
127 | 128 | ||
128 | ACPI_FUNCTION_TRACE(acpi_enable_subsystem); | 129 | ACPI_FUNCTION_TRACE(acpi_enable_subsystem); |
129 | 130 | ||
130 | /* | ||
131 | * We must initialize the hardware before we can enable ACPI. | ||
132 | * The values from the FADT are validated here. | ||
133 | */ | ||
134 | if (!(flags & ACPI_NO_HARDWARE_INIT)) { | ||
135 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
136 | "[Init] Initializing ACPI hardware\n")); | ||
137 | |||
138 | status = acpi_hw_initialize(); | ||
139 | if (ACPI_FAILURE(status)) { | ||
140 | return_ACPI_STATUS(status); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | /* Enable ACPI mode */ | 131 | /* Enable ACPI mode */ |
145 | 132 | ||
146 | if (!(flags & ACPI_NO_ACPI_ENABLE)) { | 133 | if (!(flags & ACPI_NO_ACPI_ENABLE)) { |
@@ -398,7 +385,6 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) | |||
398 | { | 385 | { |
399 | struct acpi_system_info *info_ptr; | 386 | struct acpi_system_info *info_ptr; |
400 | acpi_status status; | 387 | acpi_status status; |
401 | u32 i; | ||
402 | 388 | ||
403 | ACPI_FUNCTION_TRACE(acpi_get_system_info); | 389 | ACPI_FUNCTION_TRACE(acpi_get_system_info); |
404 | 390 | ||
@@ -431,9 +417,7 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) | |||
431 | 417 | ||
432 | /* Timer resolution - 24 or 32 bits */ | 418 | /* Timer resolution - 24 or 32 bits */ |
433 | 419 | ||
434 | if (!acpi_gbl_FADT) { | 420 | if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) { |
435 | info_ptr->timer_resolution = 0; | ||
436 | } else if (acpi_gbl_FADT->tmr_val_ext == 0) { | ||
437 | info_ptr->timer_resolution = 24; | 421 | info_ptr->timer_resolution = 24; |
438 | } else { | 422 | } else { |
439 | info_ptr->timer_resolution = 32; | 423 | info_ptr->timer_resolution = 32; |
@@ -449,13 +433,6 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) | |||
449 | info_ptr->debug_layer = acpi_dbg_layer; | 433 | info_ptr->debug_layer = acpi_dbg_layer; |
450 | info_ptr->debug_level = acpi_dbg_level; | 434 | info_ptr->debug_level = acpi_dbg_level; |
451 | 435 | ||
452 | /* Current status of the ACPI tables, per table type */ | ||
453 | |||
454 | info_ptr->num_table_types = ACPI_TABLE_ID_MAX + 1; | ||
455 | for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { | ||
456 | info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count; | ||
457 | } | ||
458 | |||
459 | return_ACPI_STATUS(AE_OK); | 436 | return_ACPI_STATUS(AE_OK); |
460 | } | 437 | } |
461 | 438 | ||
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index d0d84c43a9d4..68a809fa7b19 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -83,7 +83,7 @@ acpi_extract_package(union acpi_object *package, | |||
83 | return AE_BAD_DATA; | 83 | return AE_BAD_DATA; |
84 | } | 84 | } |
85 | 85 | ||
86 | format_string = (char *)format->pointer; | 86 | format_string = format->pointer; |
87 | 87 | ||
88 | /* | 88 | /* |
89 | * Calculate size_required. | 89 | * Calculate size_required. |
@@ -262,11 +262,10 @@ acpi_evaluate_integer(acpi_handle handle, | |||
262 | if (!data) | 262 | if (!data) |
263 | return AE_BAD_PARAMETER; | 263 | return AE_BAD_PARAMETER; |
264 | 264 | ||
265 | element = kmalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); | 265 | element = kzalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); |
266 | if (!element) | 266 | if (!element) |
267 | return AE_NO_MEMORY; | 267 | return AE_NO_MEMORY; |
268 | 268 | ||
269 | memset(element, 0, sizeof(union acpi_object)); | ||
270 | buffer.length = sizeof(union acpi_object); | 269 | buffer.length = sizeof(union acpi_object); |
271 | buffer.pointer = element; | 270 | buffer.pointer = element; |
272 | status = acpi_evaluate_object(handle, pathname, arguments, &buffer); | 271 | status = acpi_evaluate_object(handle, pathname, arguments, &buffer); |
@@ -321,12 +320,11 @@ acpi_evaluate_string(acpi_handle handle, | |||
321 | return AE_BAD_DATA; | 320 | return AE_BAD_DATA; |
322 | } | 321 | } |
323 | 322 | ||
324 | *data = kmalloc(element->string.length + 1, GFP_KERNEL); | 323 | *data = kzalloc(element->string.length + 1, GFP_KERNEL); |
325 | if (!data) { | 324 | if (!data) { |
326 | printk(KERN_ERR PREFIX "Memory allocation\n"); | 325 | printk(KERN_ERR PREFIX "Memory allocation\n"); |
327 | return -ENOMEM; | 326 | return -ENOMEM; |
328 | } | 327 | } |
329 | memset(*data, 0, element->string.length + 1); | ||
330 | 328 | ||
331 | memcpy(*data, element->string.pointer, element->string.length); | 329 | memcpy(*data, element->string.pointer, element->string.length); |
332 | 330 | ||
@@ -361,7 +359,7 @@ acpi_evaluate_reference(acpi_handle handle, | |||
361 | if (ACPI_FAILURE(status)) | 359 | if (ACPI_FAILURE(status)) |
362 | goto end; | 360 | goto end; |
363 | 361 | ||
364 | package = (union acpi_object *)buffer.pointer; | 362 | package = buffer.pointer; |
365 | 363 | ||
366 | if ((buffer.length == 0) || !package) { | 364 | if ((buffer.length == 0) || !package) { |
367 | printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n", | 365 | printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n", |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 6e99eea689c8..e0b97add8c63 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> | 4 | * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> |
5 | * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> | 5 | * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> |
6 | * Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net> | ||
6 | * | 7 | * |
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 8 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
8 | * | 9 | * |
@@ -31,6 +32,7 @@ | |||
31 | #include <linux/proc_fs.h> | 32 | #include <linux/proc_fs.h> |
32 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
33 | 34 | ||
35 | #include <linux/backlight.h> | ||
34 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
35 | 37 | ||
36 | #include <acpi/acpi_bus.h> | 38 | #include <acpi/acpi_bus.h> |
@@ -47,14 +49,20 @@ | |||
47 | #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 | 49 | #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 |
48 | #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 | 50 | #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 |
49 | 51 | ||
50 | #define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82 | 52 | #define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85 |
51 | #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83 | 53 | #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 |
52 | #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84 | 54 | #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 |
53 | #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85 | 55 | #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 |
54 | #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86 | 56 | #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 |
55 | 57 | ||
56 | #define ACPI_VIDEO_HEAD_INVALID (~0u - 1) | 58 | #define ACPI_VIDEO_HEAD_INVALID (~0u - 1) |
57 | #define ACPI_VIDEO_HEAD_END (~0u) | 59 | #define ACPI_VIDEO_HEAD_END (~0u) |
60 | #define MAX_NAME_LEN 20 | ||
61 | |||
62 | #define ACPI_VIDEO_DISPLAY_CRT 1 | ||
63 | #define ACPI_VIDEO_DISPLAY_TV 2 | ||
64 | #define ACPI_VIDEO_DISPLAY_DVI 3 | ||
65 | #define ACPI_VIDEO_DISPLAY_LCD 4 | ||
58 | 66 | ||
59 | #define _COMPONENT ACPI_VIDEO_COMPONENT | 67 | #define _COMPONENT ACPI_VIDEO_COMPONENT |
60 | ACPI_MODULE_NAME("acpi_video") | 68 | ACPI_MODULE_NAME("acpi_video") |
@@ -130,20 +138,21 @@ struct acpi_video_device_flags { | |||
130 | u8 crt:1; | 138 | u8 crt:1; |
131 | u8 lcd:1; | 139 | u8 lcd:1; |
132 | u8 tvout:1; | 140 | u8 tvout:1; |
141 | u8 dvi:1; | ||
133 | u8 bios:1; | 142 | u8 bios:1; |
134 | u8 unknown:1; | 143 | u8 unknown:1; |
135 | u8 reserved:3; | 144 | u8 reserved:2; |
136 | }; | 145 | }; |
137 | 146 | ||
138 | struct acpi_video_device_cap { | 147 | struct acpi_video_device_cap { |
139 | u8 _ADR:1; /*Return the unique ID */ | 148 | u8 _ADR:1; /*Return the unique ID */ |
140 | u8 _BCL:1; /*Query list of brightness control levels supported */ | 149 | u8 _BCL:1; /*Query list of brightness control levels supported */ |
141 | u8 _BCM:1; /*Set the brightness level */ | 150 | u8 _BCM:1; /*Set the brightness level */ |
151 | u8 _BQC:1; /* Get current brightness level */ | ||
142 | u8 _DDC:1; /*Return the EDID for this device */ | 152 | u8 _DDC:1; /*Return the EDID for this device */ |
143 | u8 _DCS:1; /*Return status of output device */ | 153 | u8 _DCS:1; /*Return status of output device */ |
144 | u8 _DGS:1; /*Query graphics state */ | 154 | u8 _DGS:1; /*Query graphics state */ |
145 | u8 _DSS:1; /*Device state set */ | 155 | u8 _DSS:1; /*Device state set */ |
146 | u8 _reserved:1; | ||
147 | }; | 156 | }; |
148 | 157 | ||
149 | struct acpi_video_device_brightness { | 158 | struct acpi_video_device_brightness { |
@@ -160,6 +169,8 @@ struct acpi_video_device { | |||
160 | struct acpi_video_bus *video; | 169 | struct acpi_video_bus *video; |
161 | struct acpi_device *dev; | 170 | struct acpi_device *dev; |
162 | struct acpi_video_device_brightness *brightness; | 171 | struct acpi_video_device_brightness *brightness; |
172 | struct backlight_device *backlight; | ||
173 | struct backlight_properties *data; | ||
163 | }; | 174 | }; |
164 | 175 | ||
165 | /* bus */ | 176 | /* bus */ |
@@ -254,11 +265,35 @@ static void acpi_video_device_bind(struct acpi_video_bus *video, | |||
254 | struct acpi_video_device *device); | 265 | struct acpi_video_device *device); |
255 | static int acpi_video_device_enumerate(struct acpi_video_bus *video); | 266 | static int acpi_video_device_enumerate(struct acpi_video_bus *video); |
256 | static int acpi_video_switch_output(struct acpi_video_bus *video, int event); | 267 | static int acpi_video_switch_output(struct acpi_video_bus *video, int event); |
268 | static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, | ||
269 | int level); | ||
270 | static int acpi_video_device_lcd_get_level_current( | ||
271 | struct acpi_video_device *device, | ||
272 | unsigned long *level); | ||
257 | static int acpi_video_get_next_level(struct acpi_video_device *device, | 273 | static int acpi_video_get_next_level(struct acpi_video_device *device, |
258 | u32 level_current, u32 event); | 274 | u32 level_current, u32 event); |
259 | static void acpi_video_switch_brightness(struct acpi_video_device *device, | 275 | static void acpi_video_switch_brightness(struct acpi_video_device *device, |
260 | int event); | 276 | int event); |
261 | 277 | ||
278 | /*backlight device sysfs support*/ | ||
279 | static int acpi_video_get_brightness(struct backlight_device *bd) | ||
280 | { | ||
281 | unsigned long cur_level; | ||
282 | struct acpi_video_device *vd = | ||
283 | (struct acpi_video_device *)class_get_devdata(&bd->class_dev); | ||
284 | acpi_video_device_lcd_get_level_current(vd, &cur_level); | ||
285 | return (int) cur_level; | ||
286 | } | ||
287 | |||
288 | static int acpi_video_set_brightness(struct backlight_device *bd) | ||
289 | { | ||
290 | int request_level = bd->props->brightness; | ||
291 | struct acpi_video_device *vd = | ||
292 | (struct acpi_video_device *)class_get_devdata(&bd->class_dev); | ||
293 | acpi_video_device_lcd_set_level(vd, request_level); | ||
294 | return 0; | ||
295 | } | ||
296 | |||
262 | /* -------------------------------------------------------------------------- | 297 | /* -------------------------------------------------------------------------- |
263 | Video Management | 298 | Video Management |
264 | -------------------------------------------------------------------------- */ | 299 | -------------------------------------------------------------------------- */ |
@@ -384,7 +419,7 @@ acpi_video_device_EDID(struct acpi_video_device *device, | |||
384 | if (ACPI_FAILURE(status)) | 419 | if (ACPI_FAILURE(status)) |
385 | return -ENODEV; | 420 | return -ENODEV; |
386 | 421 | ||
387 | obj = (union acpi_object *)buffer.pointer; | 422 | obj = buffer.pointer; |
388 | 423 | ||
389 | if (obj && obj->type == ACPI_TYPE_BUFFER) | 424 | if (obj && obj->type == ACPI_TYPE_BUFFER) |
390 | *edid = obj; | 425 | *edid = obj; |
@@ -496,6 +531,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
496 | acpi_integer status; | 531 | acpi_integer status; |
497 | acpi_handle h_dummy1; | 532 | acpi_handle h_dummy1; |
498 | int i; | 533 | int i; |
534 | u32 max_level = 0; | ||
499 | union acpi_object *obj = NULL; | 535 | union acpi_object *obj = NULL; |
500 | struct acpi_video_device_brightness *br = NULL; | 536 | struct acpi_video_device_brightness *br = NULL; |
501 | 537 | ||
@@ -511,6 +547,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
511 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { | 547 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { |
512 | device->cap._BCM = 1; | 548 | device->cap._BCM = 1; |
513 | } | 549 | } |
550 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) | ||
551 | device->cap._BQC = 1; | ||
514 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { | 552 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { |
515 | device->cap._DDC = 1; | 553 | device->cap._DDC = 1; |
516 | } | 554 | } |
@@ -530,11 +568,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
530 | int count = 0; | 568 | int count = 0; |
531 | union acpi_object *o; | 569 | union acpi_object *o; |
532 | 570 | ||
533 | br = kmalloc(sizeof(*br), GFP_KERNEL); | 571 | br = kzalloc(sizeof(*br), GFP_KERNEL); |
534 | if (!br) { | 572 | if (!br) { |
535 | printk(KERN_ERR "can't allocate memory\n"); | 573 | printk(KERN_ERR "can't allocate memory\n"); |
536 | } else { | 574 | } else { |
537 | memset(br, 0, sizeof(*br)); | ||
538 | br->levels = kmalloc(obj->package.count * | 575 | br->levels = kmalloc(obj->package.count * |
539 | sizeof *(br->levels), GFP_KERNEL); | 576 | sizeof *(br->levels), GFP_KERNEL); |
540 | if (!br->levels) | 577 | if (!br->levels) |
@@ -548,6 +585,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
548 | continue; | 585 | continue; |
549 | } | 586 | } |
550 | br->levels[count] = (u32) o->integer.value; | 587 | br->levels[count] = (u32) o->integer.value; |
588 | if (br->levels[count] > max_level) | ||
589 | max_level = br->levels[count]; | ||
551 | count++; | 590 | count++; |
552 | } | 591 | } |
553 | out: | 592 | out: |
@@ -566,6 +605,37 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
566 | 605 | ||
567 | kfree(obj); | 606 | kfree(obj); |
568 | 607 | ||
608 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC){ | ||
609 | unsigned long tmp; | ||
610 | static int count = 0; | ||
611 | char *name; | ||
612 | struct backlight_properties *acpi_video_data; | ||
613 | |||
614 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); | ||
615 | if (!name) | ||
616 | return; | ||
617 | |||
618 | acpi_video_data = kzalloc( | ||
619 | sizeof(struct backlight_properties), | ||
620 | GFP_KERNEL); | ||
621 | if (!acpi_video_data){ | ||
622 | kfree(name); | ||
623 | return; | ||
624 | } | ||
625 | acpi_video_data->owner = THIS_MODULE; | ||
626 | acpi_video_data->get_brightness = | ||
627 | acpi_video_get_brightness; | ||
628 | acpi_video_data->update_status = | ||
629 | acpi_video_set_brightness; | ||
630 | sprintf(name, "acpi_video%d", count++); | ||
631 | device->data = acpi_video_data; | ||
632 | acpi_video_data->max_brightness = max_level; | ||
633 | acpi_video_device_lcd_get_level_current(device, &tmp); | ||
634 | acpi_video_data->brightness = (int)tmp; | ||
635 | device->backlight = backlight_device_register(name, | ||
636 | NULL, device, acpi_video_data); | ||
637 | kfree(name); | ||
638 | } | ||
569 | return; | 639 | return; |
570 | } | 640 | } |
571 | 641 | ||
@@ -652,8 +722,7 @@ static struct proc_dir_entry *acpi_video_dir; | |||
652 | 722 | ||
653 | static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) | 723 | static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) |
654 | { | 724 | { |
655 | struct acpi_video_device *dev = | 725 | struct acpi_video_device *dev = seq->private; |
656 | (struct acpi_video_device *)seq->private; | ||
657 | 726 | ||
658 | 727 | ||
659 | if (!dev) | 728 | if (!dev) |
@@ -667,6 +736,8 @@ static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) | |||
667 | seq_printf(seq, "LCD\n"); | 736 | seq_printf(seq, "LCD\n"); |
668 | else if (dev->flags.tvout) | 737 | else if (dev->flags.tvout) |
669 | seq_printf(seq, "TVOUT\n"); | 738 | seq_printf(seq, "TVOUT\n"); |
739 | else if (dev->flags.dvi) | ||
740 | seq_printf(seq, "DVI\n"); | ||
670 | else | 741 | else |
671 | seq_printf(seq, "UNKNOWN\n"); | 742 | seq_printf(seq, "UNKNOWN\n"); |
672 | 743 | ||
@@ -686,8 +757,7 @@ acpi_video_device_info_open_fs(struct inode *inode, struct file *file) | |||
686 | static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) | 757 | static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) |
687 | { | 758 | { |
688 | int status; | 759 | int status; |
689 | struct acpi_video_device *dev = | 760 | struct acpi_video_device *dev = seq->private; |
690 | (struct acpi_video_device *)seq->private; | ||
691 | unsigned long state; | 761 | unsigned long state; |
692 | 762 | ||
693 | 763 | ||
@@ -725,8 +795,8 @@ acpi_video_device_write_state(struct file *file, | |||
725 | size_t count, loff_t * data) | 795 | size_t count, loff_t * data) |
726 | { | 796 | { |
727 | int status; | 797 | int status; |
728 | struct seq_file *m = (struct seq_file *)file->private_data; | 798 | struct seq_file *m = file->private_data; |
729 | struct acpi_video_device *dev = (struct acpi_video_device *)m->private; | 799 | struct acpi_video_device *dev = m->private; |
730 | char str[12] = { 0 }; | 800 | char str[12] = { 0 }; |
731 | u32 state = 0; | 801 | u32 state = 0; |
732 | 802 | ||
@@ -752,8 +822,7 @@ acpi_video_device_write_state(struct file *file, | |||
752 | static int | 822 | static int |
753 | acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) | 823 | acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) |
754 | { | 824 | { |
755 | struct acpi_video_device *dev = | 825 | struct acpi_video_device *dev = seq->private; |
756 | (struct acpi_video_device *)seq->private; | ||
757 | int i; | 826 | int i; |
758 | 827 | ||
759 | 828 | ||
@@ -782,8 +851,8 @@ acpi_video_device_write_brightness(struct file *file, | |||
782 | const char __user * buffer, | 851 | const char __user * buffer, |
783 | size_t count, loff_t * data) | 852 | size_t count, loff_t * data) |
784 | { | 853 | { |
785 | struct seq_file *m = (struct seq_file *)file->private_data; | 854 | struct seq_file *m = file->private_data; |
786 | struct acpi_video_device *dev = (struct acpi_video_device *)m->private; | 855 | struct acpi_video_device *dev = m->private; |
787 | char str[4] = { 0 }; | 856 | char str[4] = { 0 }; |
788 | unsigned int level = 0; | 857 | unsigned int level = 0; |
789 | int i; | 858 | int i; |
@@ -815,8 +884,7 @@ acpi_video_device_write_brightness(struct file *file, | |||
815 | 884 | ||
816 | static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) | 885 | static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) |
817 | { | 886 | { |
818 | struct acpi_video_device *dev = | 887 | struct acpi_video_device *dev = seq->private; |
819 | (struct acpi_video_device *)seq->private; | ||
820 | int status; | 888 | int status; |
821 | int i; | 889 | int i; |
822 | union acpi_object *edid = NULL; | 890 | union acpi_object *edid = NULL; |
@@ -864,7 +932,7 @@ static int acpi_video_device_add_fs(struct acpi_device *device) | |||
864 | if (!device) | 932 | if (!device) |
865 | return -ENODEV; | 933 | return -ENODEV; |
866 | 934 | ||
867 | vid_dev = (struct acpi_video_device *)acpi_driver_data(device); | 935 | vid_dev = acpi_driver_data(device); |
868 | if (!vid_dev) | 936 | if (!vid_dev) |
869 | return -ENODEV; | 937 | return -ENODEV; |
870 | 938 | ||
@@ -929,7 +997,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device) | |||
929 | { | 997 | { |
930 | struct acpi_video_device *vid_dev; | 998 | struct acpi_video_device *vid_dev; |
931 | 999 | ||
932 | vid_dev = (struct acpi_video_device *)acpi_driver_data(device); | 1000 | vid_dev = acpi_driver_data(device); |
933 | if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) | 1001 | if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) |
934 | return -ENODEV; | 1002 | return -ENODEV; |
935 | 1003 | ||
@@ -948,7 +1016,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device) | |||
948 | /* video bus */ | 1016 | /* video bus */ |
949 | static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) | 1017 | static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) |
950 | { | 1018 | { |
951 | struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; | 1019 | struct acpi_video_bus *video = seq->private; |
952 | 1020 | ||
953 | 1021 | ||
954 | if (!video) | 1022 | if (!video) |
@@ -973,7 +1041,7 @@ static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file) | |||
973 | 1041 | ||
974 | static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) | 1042 | static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) |
975 | { | 1043 | { |
976 | struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; | 1044 | struct acpi_video_bus *video = seq->private; |
977 | 1045 | ||
978 | 1046 | ||
979 | if (!video) | 1047 | if (!video) |
@@ -993,7 +1061,7 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file) | |||
993 | 1061 | ||
994 | static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) | 1062 | static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) |
995 | { | 1063 | { |
996 | struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; | 1064 | struct acpi_video_bus *video = seq->private; |
997 | unsigned long options; | 1065 | unsigned long options; |
998 | int status; | 1066 | int status; |
999 | 1067 | ||
@@ -1031,7 +1099,7 @@ acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file) | |||
1031 | 1099 | ||
1032 | static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) | 1100 | static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) |
1033 | { | 1101 | { |
1034 | struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; | 1102 | struct acpi_video_bus *video = seq->private; |
1035 | int status; | 1103 | int status; |
1036 | unsigned long id; | 1104 | unsigned long id; |
1037 | 1105 | ||
@@ -1052,7 +1120,7 @@ static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) | |||
1052 | 1120 | ||
1053 | static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) | 1121 | static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) |
1054 | { | 1122 | { |
1055 | struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; | 1123 | struct acpi_video_bus *video = seq->private; |
1056 | 1124 | ||
1057 | 1125 | ||
1058 | seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); | 1126 | seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); |
@@ -1077,8 +1145,8 @@ acpi_video_bus_write_POST(struct file *file, | |||
1077 | size_t count, loff_t * data) | 1145 | size_t count, loff_t * data) |
1078 | { | 1146 | { |
1079 | int status; | 1147 | int status; |
1080 | struct seq_file *m = (struct seq_file *)file->private_data; | 1148 | struct seq_file *m = file->private_data; |
1081 | struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; | 1149 | struct acpi_video_bus *video = m->private; |
1082 | char str[12] = { 0 }; | 1150 | char str[12] = { 0 }; |
1083 | unsigned long opt, options; | 1151 | unsigned long opt, options; |
1084 | 1152 | ||
@@ -1117,8 +1185,8 @@ acpi_video_bus_write_DOS(struct file *file, | |||
1117 | size_t count, loff_t * data) | 1185 | size_t count, loff_t * data) |
1118 | { | 1186 | { |
1119 | int status; | 1187 | int status; |
1120 | struct seq_file *m = (struct seq_file *)file->private_data; | 1188 | struct seq_file *m = file->private_data; |
1121 | struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; | 1189 | struct acpi_video_bus *video = m->private; |
1122 | char str[12] = { 0 }; | 1190 | char str[12] = { 0 }; |
1123 | unsigned long opt; | 1191 | unsigned long opt; |
1124 | 1192 | ||
@@ -1148,7 +1216,7 @@ static int acpi_video_bus_add_fs(struct acpi_device *device) | |||
1148 | struct acpi_video_bus *video; | 1216 | struct acpi_video_bus *video; |
1149 | 1217 | ||
1150 | 1218 | ||
1151 | video = (struct acpi_video_bus *)acpi_driver_data(device); | 1219 | video = acpi_driver_data(device); |
1152 | 1220 | ||
1153 | if (!acpi_device_dir(device)) { | 1221 | if (!acpi_device_dir(device)) { |
1154 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | 1222 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), |
@@ -1224,7 +1292,7 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device) | |||
1224 | struct acpi_video_bus *video; | 1292 | struct acpi_video_bus *video; |
1225 | 1293 | ||
1226 | 1294 | ||
1227 | video = (struct acpi_video_bus *)acpi_driver_data(device); | 1295 | video = acpi_driver_data(device); |
1228 | 1296 | ||
1229 | if (acpi_device_dir(device)) { | 1297 | if (acpi_device_dir(device)) { |
1230 | remove_proc_entry("info", acpi_device_dir(device)); | 1298 | remove_proc_entry("info", acpi_device_dir(device)); |
@@ -1244,6 +1312,16 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device) | |||
1244 | -------------------------------------------------------------------------- */ | 1312 | -------------------------------------------------------------------------- */ |
1245 | 1313 | ||
1246 | /* device interface */ | 1314 | /* device interface */ |
1315 | static struct acpi_video_device_attrib* | ||
1316 | acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) | ||
1317 | { | ||
1318 | int count; | ||
1319 | |||
1320 | for(count = 0; count < video->attached_count; count++) | ||
1321 | if((video->attached_array[count].value.int_val & 0xffff) == device_id) | ||
1322 | return &(video->attached_array[count].value.attrib); | ||
1323 | return NULL; | ||
1324 | } | ||
1247 | 1325 | ||
1248 | static int | 1326 | static int |
1249 | acpi_video_bus_get_one_device(struct acpi_device *device, | 1327 | acpi_video_bus_get_one_device(struct acpi_device *device, |
@@ -1252,7 +1330,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1252 | unsigned long device_id; | 1330 | unsigned long device_id; |
1253 | int status; | 1331 | int status; |
1254 | struct acpi_video_device *data; | 1332 | struct acpi_video_device *data; |
1255 | 1333 | struct acpi_video_device_attrib* attribute; | |
1256 | 1334 | ||
1257 | if (!device || !video) | 1335 | if (!device || !video) |
1258 | return -EINVAL; | 1336 | return -EINVAL; |
@@ -1261,12 +1339,10 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1261 | acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); | 1339 | acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); |
1262 | if (ACPI_SUCCESS(status)) { | 1340 | if (ACPI_SUCCESS(status)) { |
1263 | 1341 | ||
1264 | data = kmalloc(sizeof(struct acpi_video_device), GFP_KERNEL); | 1342 | data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL); |
1265 | if (!data) | 1343 | if (!data) |
1266 | return -ENOMEM; | 1344 | return -ENOMEM; |
1267 | 1345 | ||
1268 | memset(data, 0, sizeof(struct acpi_video_device)); | ||
1269 | |||
1270 | strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); | 1346 | strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); |
1271 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); | 1347 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); |
1272 | acpi_driver_data(device) = data; | 1348 | acpi_driver_data(device) = data; |
@@ -1275,20 +1351,30 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1275 | data->video = video; | 1351 | data->video = video; |
1276 | data->dev = device; | 1352 | data->dev = device; |
1277 | 1353 | ||
1278 | switch (device_id & 0xffff) { | 1354 | attribute = acpi_video_get_device_attr(video, device_id); |
1279 | case 0x0100: | 1355 | |
1280 | data->flags.crt = 1; | 1356 | if((attribute != NULL) && attribute->device_id_scheme) { |
1281 | break; | 1357 | switch (attribute->display_type) { |
1282 | case 0x0400: | 1358 | case ACPI_VIDEO_DISPLAY_CRT: |
1283 | data->flags.lcd = 1; | 1359 | data->flags.crt = 1; |
1284 | break; | 1360 | break; |
1285 | case 0x0200: | 1361 | case ACPI_VIDEO_DISPLAY_TV: |
1286 | data->flags.tvout = 1; | 1362 | data->flags.tvout = 1; |
1287 | break; | 1363 | break; |
1288 | default: | 1364 | case ACPI_VIDEO_DISPLAY_DVI: |
1365 | data->flags.dvi = 1; | ||
1366 | break; | ||
1367 | case ACPI_VIDEO_DISPLAY_LCD: | ||
1368 | data->flags.lcd = 1; | ||
1369 | break; | ||
1370 | default: | ||
1371 | data->flags.unknown = 1; | ||
1372 | break; | ||
1373 | } | ||
1374 | if(attribute->bios_can_detect) | ||
1375 | data->flags.bios = 1; | ||
1376 | } else | ||
1289 | data->flags.unknown = 1; | 1377 | data->flags.unknown = 1; |
1290 | break; | ||
1291 | } | ||
1292 | 1378 | ||
1293 | acpi_video_device_bind(video, data); | 1379 | acpi_video_device_bind(video, data); |
1294 | acpi_video_device_find_cap(data); | 1380 | acpi_video_device_find_cap(data); |
@@ -1401,7 +1487,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1401 | return status; | 1487 | return status; |
1402 | } | 1488 | } |
1403 | 1489 | ||
1404 | dod = (union acpi_object *)buffer.pointer; | 1490 | dod = buffer.pointer; |
1405 | if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { | 1491 | if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { |
1406 | ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); | 1492 | ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); |
1407 | status = -EFAULT; | 1493 | status = -EFAULT; |
@@ -1424,7 +1510,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1424 | 1510 | ||
1425 | count = 0; | 1511 | count = 0; |
1426 | for (i = 0; i < dod->package.count; i++) { | 1512 | for (i = 0; i < dod->package.count; i++) { |
1427 | obj = (union acpi_object *)&dod->package.elements[i]; | 1513 | obj = &dod->package.elements[i]; |
1428 | 1514 | ||
1429 | if (obj->type != ACPI_TYPE_INTEGER) { | 1515 | if (obj->type != ACPI_TYPE_INTEGER) { |
1430 | printk(KERN_ERR PREFIX "Invalid _DOD data\n"); | 1516 | printk(KERN_ERR PREFIX "Invalid _DOD data\n"); |
@@ -1507,8 +1593,34 @@ static int | |||
1507 | acpi_video_get_next_level(struct acpi_video_device *device, | 1593 | acpi_video_get_next_level(struct acpi_video_device *device, |
1508 | u32 level_current, u32 event) | 1594 | u32 level_current, u32 event) |
1509 | { | 1595 | { |
1510 | /*Fix me */ | 1596 | int min, max, min_above, max_below, i, l; |
1511 | return level_current; | 1597 | max = max_below = 0; |
1598 | min = min_above = 255; | ||
1599 | for (i = 0; i < device->brightness->count; i++) { | ||
1600 | l = device->brightness->levels[i]; | ||
1601 | if (l < min) | ||
1602 | min = l; | ||
1603 | if (l > max) | ||
1604 | max = l; | ||
1605 | if (l < min_above && l > level_current) | ||
1606 | min_above = l; | ||
1607 | if (l > max_below && l < level_current) | ||
1608 | max_below = l; | ||
1609 | } | ||
1610 | |||
1611 | switch (event) { | ||
1612 | case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: | ||
1613 | return (level_current < max) ? min_above : min; | ||
1614 | case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: | ||
1615 | return (level_current < max) ? min_above : max; | ||
1616 | case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: | ||
1617 | return (level_current > min) ? max_below : min; | ||
1618 | case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: | ||
1619 | case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: | ||
1620 | return 0; | ||
1621 | default: | ||
1622 | return level_current; | ||
1623 | } | ||
1512 | } | 1624 | } |
1513 | 1625 | ||
1514 | static void | 1626 | static void |
@@ -1566,7 +1678,10 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1566 | status = acpi_remove_notify_handler(device->dev->handle, | 1678 | status = acpi_remove_notify_handler(device->dev->handle, |
1567 | ACPI_DEVICE_NOTIFY, | 1679 | ACPI_DEVICE_NOTIFY, |
1568 | acpi_video_device_notify); | 1680 | acpi_video_device_notify); |
1569 | 1681 | if (device->backlight){ | |
1682 | backlight_device_unregister(device->backlight); | ||
1683 | kfree(device->data); | ||
1684 | } | ||
1570 | return 0; | 1685 | return 0; |
1571 | } | 1686 | } |
1572 | 1687 | ||
@@ -1610,7 +1725,7 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) | |||
1610 | 1725 | ||
1611 | static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) | 1726 | static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) |
1612 | { | 1727 | { |
1613 | struct acpi_video_bus *video = (struct acpi_video_bus *)data; | 1728 | struct acpi_video_bus *video = data; |
1614 | struct acpi_device *device = NULL; | 1729 | struct acpi_device *device = NULL; |
1615 | 1730 | ||
1616 | printk("video bus notify\n"); | 1731 | printk("video bus notify\n"); |
@@ -1652,12 +1767,9 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) | |||
1652 | 1767 | ||
1653 | static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | 1768 | static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) |
1654 | { | 1769 | { |
1655 | struct acpi_video_device *video_device = | 1770 | struct acpi_video_device *video_device = data; |
1656 | (struct acpi_video_device *)data; | ||
1657 | struct acpi_device *device = NULL; | 1771 | struct acpi_device *device = NULL; |
1658 | 1772 | ||
1659 | |||
1660 | printk("video device notify\n"); | ||
1661 | if (!video_device) | 1773 | if (!video_device) |
1662 | return; | 1774 | return; |
1663 | 1775 | ||
@@ -1694,10 +1806,9 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1694 | if (!device) | 1806 | if (!device) |
1695 | return -EINVAL; | 1807 | return -EINVAL; |
1696 | 1808 | ||
1697 | video = kmalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); | 1809 | video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); |
1698 | if (!video) | 1810 | if (!video) |
1699 | return -ENOMEM; | 1811 | return -ENOMEM; |
1700 | memset(video, 0, sizeof(struct acpi_video_bus)); | ||
1701 | 1812 | ||
1702 | video->device = device; | 1813 | video->device = device; |
1703 | strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); | 1814 | strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); |
@@ -1755,7 +1866,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) | |||
1755 | if (!device || !acpi_driver_data(device)) | 1866 | if (!device || !acpi_driver_data(device)) |
1756 | return -EINVAL; | 1867 | return -EINVAL; |
1757 | 1868 | ||
1758 | video = (struct acpi_video_bus *)acpi_driver_data(device); | 1869 | video = acpi_driver_data(device); |
1759 | 1870 | ||
1760 | acpi_video_bus_stop_devices(video); | 1871 | acpi_video_bus_stop_devices(video); |
1761 | 1872 | ||