Commit 08acd4f8 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6

* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (179 commits)
  ACPI: Fix acpi_processor_idle and idle= boot parameters interaction
  acpi: fix section mismatch warning in pnpacpi
  intel_menlo: fix build warning
  ACPI: Cleanup: Remove unneeded, multiple local dummy variables
  ACPI: video - fix permissions on some proc entries
  ACPI: video - properly handle errors when registering proc elements
  ACPI: video - do not store invalid entries in attached_array list
  ACPI: re-name acpi_pm_ops to acpi_suspend_ops
  ACER_WMI/ASUS_LAPTOP: fix build bug
  thinkpad_acpi: fix possible NULL pointer dereference if kstrdup failed
  ACPI: check a return value correctly in acpi_power_get_context()
  #if 0 acpi/bay.c:eject_removable_drive()
  eeepc-laptop: add hwmon fan control
  eeepc-laptop: add backlight
  eeepc-laptop: add base driver
  ACPI: thinkpad-acpi: bump up version to 0.20
  ACPI: thinkpad-acpi: fix selects in Kconfig
  ACPI: thinkpad-acpi: use a private workqueue
  ACPI: thinkpad-acpi: fluff really minor fix
  ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation
  ...

Fixed conflicts in drivers/acpi/video.c and drivers/misc/intel_menlow.c
manually.
parents ccf27795 008238b5
ThinkPad ACPI Extras Driver ThinkPad ACPI Extras Driver
Version 0.19 Version 0.20
January 06th, 2008 April 09th, 2008
Borislav Deianov <borislav@users.sf.net> Borislav Deianov <borislav@users.sf.net>
Henrique de Moraes Holschuh <hmh@hmh.eng.br> Henrique de Moraes Holschuh <hmh@hmh.eng.br>
...@@ -18,6 +18,11 @@ This driver used to be named ibm-acpi until kernel 2.6.21 and release ...@@ -18,6 +18,11 @@ This driver used to be named ibm-acpi until kernel 2.6.21 and release
moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel
2.6.22, and release 0.14. 2.6.22, and release 0.14.
The driver is named "thinkpad-acpi". In some places, like module
names, "thinkpad_acpi" is used because of userspace issues.
"tpacpi" is used as a shorthand where "thinkpad-acpi" would be too
long due to length limitations on some Linux kernel versions.
Status Status
------ ------
...@@ -571,6 +576,47 @@ netlink interface and the input layer interface, and don't bother at all ...@@ -571,6 +576,47 @@ netlink interface and the input layer interface, and don't bother at all
with hotkey_report_mode. with hotkey_report_mode.
Brightness hotkey notes:
These are the current sane choices for brightness key mapping in
thinkpad-acpi:
For IBM and Lenovo models *without* ACPI backlight control (the ones on
which thinkpad-acpi will autoload its backlight interface by default,
and on which ACPI video does not export a backlight interface):
1. Don't enable or map the brightness hotkeys in thinkpad-acpi, as
these older firmware versions unfortunately won't respect the hotkey
mask for brightness keys anyway, and always reacts to them. This
usually work fine, unless X.org drivers are doing something to block
the BIOS. In that case, use (3) below. This is the default mode of
operation.
2. Enable the hotkeys, but map them to something else that is NOT
KEY_BRIGHTNESS_UP/DOWN or any other keycode that would cause
userspace to try to change the backlight level, and use that as an
on-screen-display hint.
3. IF AND ONLY IF X.org drivers find a way to block the firmware from
automatically changing the brightness, enable the hotkeys and map
them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN, and feed that to
something that calls xbacklight. thinkpad-acpi will not be able to
change brightness in that case either, so you should disable its
backlight interface.
For Lenovo models *with* ACPI backlight control:
1. Load up ACPI video and use that. ACPI video will report ACPI
events for brightness change keys. Do not mess with thinkpad-acpi
defaults in this case. thinkpad-acpi should not have anything to do
with backlight events in a scenario where ACPI video is loaded:
brightness hotkeys must be disabled, and the backlight interface is
to be kept disabled as well. This is the default mode of operation.
2. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi,
and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process
these keys on userspace somehow (e.g. by calling xbacklight).
Bluetooth Bluetooth
--------- ---------
...@@ -647,16 +693,31 @@ while others are still having problems. For more information: ...@@ -647,16 +693,31 @@ while others are still having problems. For more information:
https://bugs.freedesktop.org/show_bug.cgi?id=2000 https://bugs.freedesktop.org/show_bug.cgi?id=2000
ThinkLight control -- /proc/acpi/ibm/light ThinkLight control
------------------------------------------ ------------------
procfs: /proc/acpi/ibm/light
sysfs attributes: as per LED class, for the "tpacpi::thinklight" LED
The current status of the ThinkLight can be found in this file. A few procfs notes:
models which do not make the status available will show it as
"unknown". The available commands are: The ThinkLight status can be read and set through the procfs interface. A
few models which do not make the status available will show the ThinkLight
status as "unknown". The available commands are:
echo on > /proc/acpi/ibm/light echo on > /proc/acpi/ibm/light
echo off > /proc/acpi/ibm/light echo off > /proc/acpi/ibm/light
sysfs notes:
The ThinkLight sysfs interface is documented by the LED class
documentation, in Documentation/leds-class.txt. The ThinkLight LED name
is "tpacpi::thinklight".
Due to limitations in the sysfs LED class, if the status of the thinklight
cannot be read or if it is unknown, thinkpad-acpi will report it as "off".
It is impossible to know if the status returned through sysfs is valid.
Docking / undocking -- /proc/acpi/ibm/dock Docking / undocking -- /proc/acpi/ibm/dock
------------------------------------------ ------------------------------------------
...@@ -815,28 +876,63 @@ The cmos command interface is prone to firmware split-brain problems, as ...@@ -815,28 +876,63 @@ The cmos command interface is prone to firmware split-brain problems, as
in newer ThinkPads it is just a compatibility layer. Do not use it, it is in newer ThinkPads it is just a compatibility layer. Do not use it, it is
exported just as a debug tool. exported just as a debug tool.
LED control -- /proc/acpi/ibm/led LED control
--------------------------------- -----------
procfs: /proc/acpi/ibm/led
sysfs attributes: as per LED class, see below for names
Some of the LED indicators can be controlled through this feature. On
some older ThinkPad models, it is possible to query the status of the
LED indicators as well. Newer ThinkPads cannot query the real status
of the LED indicators.
Some of the LED indicators can be controlled through this feature. The procfs notes:
available commands are:
The available commands are:
echo '<led number> on' >/proc/acpi/ibm/led echo '<LED number> on' >/proc/acpi/ibm/led
echo '<led number> off' >/proc/acpi/ibm/led echo '<LED number> off' >/proc/acpi/ibm/led
echo '<led number> blink' >/proc/acpi/ibm/led echo '<LED number> blink' >/proc/acpi/ibm/led
The <led number> range is 0 to 7. The set of LEDs that can be The <LED number> range is 0 to 7. The set of LEDs that can be
controlled varies from model to model. Here is the mapping on the X40: controlled varies from model to model. Here is the common ThinkPad
mapping:
0 - power 0 - power
1 - battery (orange) 1 - battery (orange)
2 - battery (green) 2 - battery (green)
3 - UltraBase 3 - UltraBase/dock
4 - UltraBay 4 - UltraBay
5 - UltraBase battery slot
6 - (unknown)
7 - standby 7 - standby
All of the above can be turned on and off and can be made to blink. All of the above can be turned on and off and can be made to blink.
sysfs notes:
The ThinkPad LED sysfs interface is described in detail by the LED class
documentation, in Documentation/leds-class.txt.
The leds are named (in LED ID order, from 0 to 7):
"tpacpi::power", "tpacpi:orange:batt", "tpacpi:green:batt",
"tpacpi::dock_active", "tpacpi::bay_active", "tpacpi::dock_batt",
"tpacpi::unknown_led", "tpacpi::standby".
Due to limitations in the sysfs LED class, if the status of the LED
indicators cannot be read due to an error, thinkpad-acpi will report it as
a brightness of zero (same as LED off).
If the thinkpad firmware doesn't support reading the current status,
trying to read the current LED brightness will just return whatever
brightness was last written to that attribute.
These LEDs can blink using hardware acceleration. To request that a
ThinkPad indicator LED should blink in hardware accelerated mode, use the
"timer" trigger, and leave the delay_on and delay_off parameters set to
zero (to request hardware acceleration autodetection).
ACPI sounds -- /proc/acpi/ibm/beep ACPI sounds -- /proc/acpi/ibm/beep
---------------------------------- ----------------------------------
...@@ -1090,6 +1186,15 @@ it there will be the following attributes: ...@@ -1090,6 +1186,15 @@ it there will be the following attributes:
dim the display. dim the display.
WARNING:
Whatever you do, do NOT ever call thinkpad-acpi backlight-level change
interface and the ACPI-based backlight level change interface
(available on newer BIOSes, and driven by the Linux ACPI video driver)
at the same time. The two will interact in bad ways, do funny things,
and maybe reduce the life of the backlight lamps by needlessly kicking
its level up and down at every change.
Volume control -- /proc/acpi/ibm/volume Volume control -- /proc/acpi/ibm/volume
--------------------------------------- ---------------------------------------
......
...@@ -108,10 +108,12 @@ and throttle appropriate devices. ...@@ -108,10 +108,12 @@ and throttle appropriate devices.
RO read only value RO read only value
RW read/write value RW read/write value
All thermal sysfs attributes will be represented under /sys/class/thermal Thermal sysfs attributes will be represented under /sys/class/thermal.
Hwmon sysfs I/F extension is also available under /sys/class/hwmon
if hwmon is compiled in or built as a module.
Thermal zone device sys I/F, created once it's registered: Thermal zone device sys I/F, created once it's registered:
|thermal_zone[0-*]: /sys/class/thermal/thermal_zone[0-*]:
|-----type: Type of the thermal zone |-----type: Type of the thermal zone
|-----temp: Current temperature |-----temp: Current temperature
|-----mode: Working mode of the thermal zone |-----mode: Working mode of the thermal zone
...@@ -119,7 +121,7 @@ Thermal zone device sys I/F, created once it's registered: ...@@ -119,7 +121,7 @@ Thermal zone device sys I/F, created once it's registered:
|-----trip_point_[0-*]_type: Trip point type |-----trip_point_[0-*]_type: Trip point type
Thermal cooling device sys I/F, created once it's registered: Thermal cooling device sys I/F, created once it's registered:
|cooling_device[0-*]: /sys/class/thermal/cooling_device[0-*]:
|-----type : Type of the cooling device(processor/fan/...) |-----type : Type of the cooling device(processor/fan/...)
|-----max_state: Maximum cooling state of the cooling device |-----max_state: Maximum cooling state of the cooling device
|-----cur_state: Current cooling state of the cooling device |-----cur_state: Current cooling state of the cooling device
...@@ -130,10 +132,19 @@ They represent the relationship between a thermal zone and its associated coolin ...@@ -130,10 +132,19 @@ They represent the relationship between a thermal zone and its associated coolin
They are created/removed for each They are created/removed for each
thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device successful execution. thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device successful execution.
|thermal_zone[0-*] /sys/class/thermal/thermal_zone[0-*]
|-----cdev[0-*]: The [0-*]th cooling device in the current thermal zone |-----cdev[0-*]: The [0-*]th cooling device in the current thermal zone
|-----cdev[0-*]_trip_point: Trip point that cdev[0-*] is associated with |-----cdev[0-*]_trip_point: Trip point that cdev[0-*] is associated with
Besides the thermal zone device sysfs I/F and cooling device sysfs I/F,
the generic thermal driver also creates a hwmon sysfs I/F for each _type_ of
thermal zone device. E.g. the generic thermal driver registers one hwmon class device
and build the associated hwmon sysfs I/F for all the registered ACPI thermal zones.
/sys/class/hwmon/hwmon[0-*]:
|-----name: The type of the thermal zone devices.
|-----temp[1-*]_input: The current temperature of thermal zone [1-*].
|-----temp[1-*]_critical: The critical trip point of thermal zone [1-*].
Please read Documentation/hwmon/sysfs-interface for additional information.
*************************** ***************************
* Thermal zone attributes * * Thermal zone attributes *
...@@ -141,7 +152,10 @@ thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device successful e ...@@ -141,7 +152,10 @@ thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device successful e
type Strings which represent the thermal zone type. type Strings which represent the thermal zone type.
This is given by thermal zone driver as part of registration. This is given by thermal zone driver as part of registration.
Eg: "ACPI thermal zone" indicates it's a ACPI thermal device Eg: "acpitz" indicates it's an ACPI thermal device.
In order to keep it consistent with hwmon sys attribute,
this should be a short, lowercase string,
not containing spaces nor dashes.
RO RO
Required Required
...@@ -218,7 +232,7 @@ the sys I/F structure will be built like this: ...@@ -218,7 +232,7 @@ the sys I/F structure will be built like this:
/sys/class/thermal: /sys/class/thermal:
|thermal_zone1: |thermal_zone1:
|-----type: ACPI thermal zone |-----type: acpitz
|-----temp: 37000 |-----temp: 37000
|-----mode: kernel |-----mode: kernel
|-----trip_point_0_temp: 100000 |-----trip_point_0_temp: 100000
...@@ -243,3 +257,10 @@ the sys I/F structure will be built like this: ...@@ -243,3 +257,10 @@ the sys I/F structure will be built like this:
|-----type: Fan |-----type: Fan
|-----max_state: 2 |-----max_state: 2
|-----cur_state: 0 |-----cur_state: 0
/sys/class/hwmon:
|hwmon0:
|-----name: acpitz
|-----temp1_input: 37000
|-----temp1_crit: 100000
...@@ -1533,6 +1533,13 @@ L: bluesmoke-devel@lists.sourceforge.net ...@@ -1533,6 +1533,13 @@ L: bluesmoke-devel@lists.sourceforge.net
W: bluesmoke.sourceforge.net W: bluesmoke.sourceforge.net
S: Maintained S: Maintained
EEEPC LAPTOP EXTRAS DRIVER
P: Corentin Chary
M: corentincj@iksaif.net
L: acpi4asus-user@lists.sourceforge.net
W: http://sourceforge.net/projects/acpi4asus
S: Maintained
EEPRO100 NETWORK DRIVER EEPRO100 NETWORK DRIVER
P: Andrey V. Savochkin P: Andrey V. Savochkin
M: saw@saw.sw.com.sg M: saw@saw.sw.com.sg
......
...@@ -163,14 +163,11 @@ static int sysctl_pm_do_suspend(ctl_table *ctl, int write, struct file *filp, ...@@ -163,14 +163,11 @@ static int sysctl_pm_do_suspend(ctl_table *ctl, int write, struct file *filp,
if ((mode != 1) && (mode != 5)) if ((mode != 1) && (mode != 5))
return -EINVAL; return -EINVAL;
retval = pm_send_all(PM_SUSPEND, (void *)3);
if (retval == 0) { if (retval == 0) {
if (mode == 5) if (mode == 5)
retval = pm_do_bus_sleep(); retval = pm_do_bus_sleep();
else else
retval = pm_do_suspend(); retval = pm_do_suspend();
pm_send_all(PM_RESUME, (void *)0);
} }
return retval; return retval;
...@@ -183,9 +180,6 @@ static int try_set_cmode(int new_cmode) ...@@ -183,9 +180,6 @@ static int try_set_cmode(int new_cmode)
if (!(clock_cmodes_permitted & (1<<new_cmode))) if (!(clock_cmodes_permitted & (1<<new_cmode)))
return -EINVAL; return -EINVAL;
/* tell all the drivers we're suspending */
pm_send_all(PM_SUSPEND, (void *)3);
/* now change cmode */ /* now change cmode */
local_irq_disable(); local_irq_disable();
frv_dma_pause_all(); frv_dma_pause_all();
...@@ -201,8 +195,6 @@ static int try_set_cmode(int new_cmode) ...@@ -201,8 +195,6 @@ static int try_set_cmode(int new_cmode)
frv_dma_resume_all(); frv_dma_resume_all();
local_irq_enable(); local_irq_enable();
/* tell all the drivers we're resuming */
pm_send_all(PM_RESUME, (void *)0);
return 0; return 0;
} }
......
...@@ -251,7 +251,6 @@ int au_sleep(void) ...@@ -251,7 +251,6 @@ int au_sleep(void)
static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
void __user *buffer, size_t * len, loff_t *ppos) void __user *buffer, size_t * len, loff_t *ppos)
{ {
int retval = 0;
#ifdef SLEEP_TEST_TIMEOUT #ifdef SLEEP_TEST_TIMEOUT
#define TMPBUFLEN2 16 #define TMPBUFLEN2 16
char buf[TMPBUFLEN2], *p; char buf[TMPBUFLEN2], *p;
...@@ -271,36 +270,12 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, ...@@ -271,36 +270,12 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
p = buf; p = buf;
sleep_ticks = simple_strtoul(p, &p, 0); sleep_ticks = simple_strtoul(p, &p, 0);
#endif #endif
retval = pm_send_all(PM_SUSPEND, (void *) 2);
if (retval)
return retval;
au_sleep(); au_sleep();
retval = pm_send_all(PM_RESUME, (void *) 0);
} }
return retval; return 0;
}
static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
void __user *buffer, size_t * len, loff_t *ppos)
{
int retval = 0;
if (!write) {
*len = 0;
} else {
retval = pm_send_all(PM_SUSPEND, (void *) 2);
if (retval)
return retval;
suspend_mode = 1;
retval = pm_send_all(PM_RESUME, (void *) 0);
}
return retval;
} }
static int pm_do_freq(ctl_table * ctl, int write, struct file *file, static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
void __user *buffer, size_t * len, loff_t *ppos) void __user *buffer, size_t * len, loff_t *ppos)
{ {
...@@ -413,14 +388,6 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file, ...@@ -413,14 +388,6 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
static struct ctl_table pm_table[] = { static struct ctl_table pm_table[] = {
{
.ctl_name = CTL_UNNUMBERED,
.procname = "suspend",
.data = NULL,
.maxlen = 0,
.mode = 0600,
.proc_handler = &pm_do_suspend
},
{ {
.ctl_name = CTL_UNNUMBERED, .ctl_name = CTL_UNNUMBERED,
.procname = "sleep", .procname = "sleep",
......
...@@ -1192,19 +1192,6 @@ static int suspend(int vetoable) ...@@ -1192,19 +1192,6 @@ static int suspend(int vetoable)
int err; int err;
struct apm_user *as; struct apm_user *as;
if (pm_send_all(PM_SUSPEND, (void *)3)) {
/* Vetoed */
if (vetoable) {
if (apm_info.connection_version > 0x100)
set_system_power_state(APM_STATE_REJECT);
err = -EBUSY;
ignore_sys_suspend = 0;
printk(KERN_WARNING "apm: suspend was vetoed.\n");
goto out;
}
printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
}
device_suspend(PMSG_SUSPEND); device_suspend(PMSG_SUSPEND);
local_irq_disable(); local_irq_disable();
device_power_down(PMSG_SUSPEND); device_power_down(PMSG_SUSPEND);
...@@ -1227,9 +1214,7 @@ static int suspend(int vetoable) ...@@ -1227,9 +1214,7 @@ static int suspend(int vetoable)
device_power_up(); device_power_up();
local_irq_enable(); local_irq_enable();
device_resume(); device_resume();
pm_send_all(PM_RESUME, (void *)0);
queue_event(APM_NORMAL_RESUME, NULL); queue_event(APM_NORMAL_RESUME, NULL);
out:
spin_lock(&user_list_lock); spin_lock(&user_list_lock);
for (as = user_list; as != NULL; as = as->next) { for (as = user_list; as != NULL; as = as->next) {
as->suspend_wait = 0; as->suspend_wait = 0;
...@@ -1340,7 +1325,6 @@ static void check_events(void) ...@@ -1340,7 +1325,6 @@ static void check_events(void)
if ((event != APM_NORMAL_RESUME) if ((event != APM_NORMAL_RESUME)
|| (ignore_normal_resume == 0)) { || (ignore_normal_resume == 0)) {
device_resume(); device_resume();
pm_send_all(PM_RESUME, (void *)0);
queue_event(event, NULL); queue_event(event, NULL);
} }
ignore_normal_resume = 0; ignore_normal_resume = 0;
......
...@@ -140,6 +140,7 @@ config ACPI_VIDEO ...@@ -140,6 +140,7 @@ config ACPI_VIDEO
tristate "Video" tristate "Video"
depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
depends on INPUT depends on INPUT
select THERMAL
help help
This driver implement the ACPI Extensions For Display Adapters This driver implement the ACPI Extensions For Display Adapters
for integrated graphics devices on motherboard, as specified in for integrated graphics devices on motherboard, as specified in
...@@ -151,6 +152,7 @@ config ACPI_VIDEO ...@@ -151,6 +152,7 @@ config ACPI_VIDEO
config ACPI_FAN config ACPI_FAN
tristate "Fan" tristate "Fan"
select THERMAL
default y default y
help help
This driver adds support for ACPI fan devices, allowing user-mode This driver adds support for ACPI fan devices, allowing user-mode
...@@ -172,6 +174,7 @@ config ACPI_BAY ...@@ -172,6 +174,7 @@ config ACPI_BAY
config ACPI_PROCESSOR config ACPI_PROCESSOR
tristate "Processor" tristate "Processor"
select THERMAL
default y default y
help help
This driver installs ACPI as the idle handler for Linux, and uses This driver installs ACPI as the idle handler for Linux, and uses
......
...@@ -201,6 +201,7 @@ static int is_ejectable_bay(acpi_handle handle) ...@@ -201,6 +201,7 @@ static int is_ejectable_bay(acpi_handle handle)
return 0; return 0;
} }
#if 0
/** /**
* eject_removable_drive - try to eject this drive * eject_removable_drive - try to eject this drive
* @dev : the device structure of the drive * @dev : the device structure of the drive
...@@ -225,6 +226,7 @@ int eject_removable_drive(struct device *dev) ...@@ -225,6 +226,7 @@ int eject_removable_drive(struct device *dev)
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(eject_removable_drive); EXPORT_SYMBOL_GPL(eject_removable_drive);
#endif /* 0 */
static int acpi_bay_add_fs(struct bay *bay) static int acpi_bay_add_fs(struct bay *bay)
{ {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -89,12 +89,16 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, ...@@ -89,12 +89,16 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
ACPI_FUNCTION_TRACE(ds_create_buffer_field); ACPI_FUNCTION_TRACE(ds_create_buffer_field);
/* Get the name_string argument */ /*
* Get the name_string argument (name of the new buffer_field)
*/
if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
/* For create_field, name is the 4th argument */
arg = acpi_ps_get_arg(op, 3); arg = acpi_ps_get_arg(op, 3);
} else { } else {
/* Create Bit/Byte/Word/Dword field */ /* For all other create_xXXField operators, name is the 3rd argument */
arg = acpi_ps_get_arg(op, 2); arg = acpi_ps_get_arg(op, 2);
} }
...@@ -107,26 +111,30 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, ...@@ -107,26 +111,30 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
node = walk_state->deferred_node; node = walk_state->deferred_node;
status = AE_OK; status = AE_OK;
} else { } else {
/* /* Execute flag should always be set when this function is entered */
* During the load phase, we want to enter the name of the field into
* the namespace. During the execute phase (when we evaluate the size if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
* operand), we want to lookup the name return_ACPI_STATUS(AE_AML_INTERNAL);
*/
if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) {
flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
} else {
flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
ACPI_NS_ERROR_IF_FOUND;
} }
/* /* Creating new namespace node, should not already exist */
* Enter the name_string into the namespace
*/ flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
ACPI_NS_ERROR_IF_FOUND;
/* Mark node temporary if we are executing a method */
if (walk_state->method_node) {
flags |= ACPI_NS_TEMPORARY;
}
/* Enter the name_string into the namespace */
status = status =
acpi_ns_lookup(walk_state->scope_info, acpi_ns_lookup(walk_state->scope_info,
arg->common.value.string, ACPI_TYPE_ANY, arg->common.value.string, ACPI_TYPE_ANY,
ACPI_IMODE_LOAD_PASS1, flags, walk_state, ACPI_IMODE_LOAD_PASS1, flags, walk_state,
&(node)); &node);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_ERROR_NAMESPACE(arg->common.value.string, status); ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -136,13 +144,13 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, ...@@ -136,13 +144,13 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
/* /*
* We could put the returned object (Node) on the object stack for later, * We could put the returned object (Node) on the object stack for later,
* but for now, we will put it in the "op" object that the parser uses, * but for now, we will put it in the "op" object that the parser uses,
* so we can get it again at the end of this scope * so we can get it again at the end of this scope.
*/ */
op->common.node = node; op->common.node = node;
/* /*
* If there is no object attached to the node, this node was just created * If there is no object attached to the node, this node was just created
* and we need to create the field object. Otherwise, this was a lookup * and we need to create the field object. Otherwise, this was a lookup
* of an existing node and we don't want to create the field object again. * of an existing node and we don't want to create the field object again.
*/ */
obj_desc = acpi_ns_get_attached_object(node); obj_desc = acpi_ns_get_attached_object(node);
...@@ -164,9 +172,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, ...@@ -164,9 +172,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
} }
/* /*
* Remember location in AML stream of the field unit * Remember location in AML stream of the field unit opcode and operands --
* opcode and operands -- since the buffer and index * since the buffer and index operands must be evaluated.
* operands must be evaluated.
*/ */
second_desc = obj_desc->common.next_object; second_desc = obj_desc->common.next_object;
second_desc->extra.aml_start = op->named.data; second_desc->extra.aml_start = op->named.data;
...@@ -261,7 +268,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, ...@@ -261,7 +268,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
case AML_INT_NAMEDFIELD_OP: case AML_INT_NAMEDFIELD_OP:
/* Lookup the name */ /* Lookup the name, it should already exist */
status = acpi_ns_lookup(walk_state->scope_info, status = acpi_ns_lookup(walk_state->scope_info,
(char *)&arg->named.name, (char *)&arg->named.name,
...@@ -272,20 +279,23 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, ...@@ -272,20 +279,23 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_ERROR_NAMESPACE((char *)&arg->named.name, ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
status); status);
if (status != AE_ALREADY_EXISTS) { return_ACPI_STATUS(status);
return_ACPI_STATUS(status);
}
/* Already exists, ignore error */
} else { } else {
arg->common.node = info->field_node; arg->common.node = info->field_node;
info->field_bit_length = arg->common.value.size; info->field_bit_length = arg->common.value.size;
/* Create and initialize an object for the new Field Node */ /*
* If there is no object attached to the node, this node was
status = acpi_ex_prep_field_value(info); * just created and we need to create the field object.
if (ACPI_FAILURE(status)) { * Otherwise, this was a lookup of an existing node and we
return_ACPI_STATUS(status); * don't want to create the field object again.
*/
if (!acpi_ns_get_attached_object
(info->field_node)) {
status = acpi_ex_prep_field_value(info);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
} }
} }
...@@ -399,9 +409,27 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, ...@@ -399,9 +409,27 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
union acpi_parse_object *arg = NULL; union acpi_parse_object *arg = NULL;
struct acpi_namespace_node *node; struct acpi_namespace_node *node;
u8 type = 0; u8 type = 0;
u32 flags;
ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
/* Execute flag should always be set when this function is entered */
if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
/* bank_field Op is deferred, just return OK */
return_ACPI_STATUS(AE_OK);
}
return_ACPI_STATUS(AE_AML_INTERNAL);
}
/*
* Get the field_list argument for this opcode. This is the start of the
* list of field elements.
*/
switch (walk_state->opcode) { switch (walk_state->opcode) {
case AML_FIELD_OP: case AML_FIELD_OP:
arg = acpi_ps_get_arg(op, 2); arg = acpi_ps_get_arg(op, 2);
...@@ -422,20 +450,33 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, ...@@ -422,20 +450,33 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
return_ACPI_STATUS(AE_BAD_PARAMETER); return_ACPI_STATUS(AE_BAD_PARAMETER);
} }
if (!arg) {
return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
/* Creating new namespace node(s), should not already exist */
flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
ACPI_NS_ERROR_IF_FOUND;
/* Mark node(s) temporary if we are executing a method */
if (walk_state->method_node) {
flags |= ACPI_NS_TEMPORARY;
}
/* /*
* Walk the list of entries in the field_list * Walk the list of entries in the field_list
*/ */
while (arg) { while (arg) {
/*
/* Ignore OFFSET and ACCESSAS terms here */ * Ignore OFFSET and ACCESSAS terms here; we are only interested in the
* field names in order to enter them into the namespace.
*/
if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
status = acpi_ns_lookup(walk_state->scope_info, status = acpi_ns_lookup(walk_state->scope_info,
(char *)&arg->named.name, (char *)&arg->named.name, type,
type, ACPI_IMODE_LOAD_PASS1, ACPI_IMODE_LOAD_PASS1, flags,
ACPI_NS_NO_UPSEARCH |
ACPI_NS_DONT_OPEN_SCOPE |
ACPI_NS_ERROR_IF_FOUND,
walk_state, &node); walk_state, &node);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_ERROR_NAMESPACE((char *)&arg->named.name, ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
...@@ -452,7 +493,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, ...@@ -452,7 +493,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
arg->common.node = node; arg->common.node = node;
} }
/* Move to next field in the list */ /* Get the next field element in the list */
arg = arg->common.next; arg = arg->common.next;
} }
...@@ -466,7 +507,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, ...@@ -466,7 +507,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
* *
* PARAMETERS: Op - Op containing the Field definition and args * PARAMETERS: Op - Op containing the Field definition and args
* region_node - Object for the containing Operation Region * region_node - Object for the containing Operation Region
* ` walk_state - Current method state * walk_state - Current method state
* *
* RETURN: Status * RETURN: Status
* *
...@@ -513,36 +554,13 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, ...@@ -513,36 +554,13 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
/* Third arg is the bank_value */ /*
* Third arg is the bank_value
/* TBD: This arg is a term_arg, not a constant, and must be evaluated */ * This arg is a term_arg, not a constant
* It will be evaluated later, by acpi_ds_eval_bank_field_operands
*/
arg = arg->common.next; arg = arg->common.next;
/* Currently, only the following constants are supported */
switch (arg->common.aml_opcode) {
case AML_ZERO_OP:
info.bank_value = 0;
break;
case AML_ONE_OP:
info.bank_value = 1;
break;
case AML_BYTE_OP:
case AML_WORD_OP:
case AML_DWORD_OP:
case AML_QWORD_OP:
info.bank_value = (u32) arg->common.value.integer;
break;
default:
info.bank_value = 0;
ACPI_ERROR((AE_INFO,
"Non-constant BankValue for BankField is not implemented"));
}
/* Fourth arg is the field flags */ /* Fourth arg is the field flags */
arg = arg->common.next; arg = arg->common.next;
...@@ -553,8 +571,17 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, ...@@ -553,8 +571,17 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
info.region_node = region_node; info.region_node = region_node;
status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); /*
* Use Info.data_register_node to store bank_field Op
* It's safe because data_register_node will never be used when create bank field
* We store aml_start and aml_length in the bank_field Op for late evaluation
* Used in acpi_ex_prep_field_value(Info)
*
* TBD: Or, should we add a field in struct acpi_create_field_info, like "void *ParentOp"?
*/
info.data_register_node = (struct acpi_namespace_node *)op;
status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
*/ */
#include <acpi/acpi.h> #include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h> #include <acpi/amlcode.h>
#include <acpi/acdispat.h> #include <acpi/acdispat.h>
#include <acpi/acinterp.h> #include <acpi/acinterp.h>
...@@ -102,7 +101,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state) ...@@ -102,7 +101,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state)
walk_state->opcode, walk_state->opcode,
walk_state->aml_offset, walk_state->aml_offset,
NULL); NULL);
(void)acpi_ex_enter_interpreter(); acpi_ex_enter_interpreter();
} }
#ifdef ACPI_DISASSEMBLER #ifdef ACPI_DISASSEMBLER
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
...@@ -232,9 +231,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, ...@@ -232,9 +231,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
* recursive call. * recursive call.
*/ */
if (!walk_state || if (!walk_state ||
!obj_desc->method.mutex->mutex.owner_thread || !obj_desc->method.mutex->mutex.thread_id ||
(walk_state->thread != (walk_state->thread->thread_id !=
obj_desc->method.mutex->mutex.owner_thread)) { obj_desc->method.mutex->mutex.thread_id)) {
/* /*
* Acquire the method mutex. This releases the interpreter if we * Acquire the method mutex. This releases the interpreter if we
* block (and reacquires it before it returns) * block (and reacquires it before it returns)
...@@ -254,8 +253,8 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, ...@@ -254,8 +253,8 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
original_sync_level = original_sync_level =
walk_state->thread->current_sync_level; walk_state->thread->current_sync_level;
obj_desc->method.mutex->mutex.owner_thread = obj_desc->method.mutex->mutex.thread_id =
walk_state->thread; walk_state->thread->thread_id;
walk_state->thread->current_sync_level = walk_state->thread->current_sync_level =
obj_desc->method.sync_level; obj_desc->method.sync_level;
} else { } else {
...@@ -535,8 +534,6 @@ void ...@@ -535,8 +534,6 @@ void
acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
struct acpi_walk_state *walk_state) struct acpi_walk_state *walk_state)
{ {
struct acpi_namespace_node *method_node;
acpi_status status;
ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state); ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state);
...@@ -551,34 +548,26 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, ...@@ -551,34 +548,26 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
/* Delete all arguments and locals */ /* Delete all arguments and locals */
acpi_ds_method_data_delete_all(walk_state); acpi_ds_method_data_delete_all(walk_state);
}
/* /*
* If method is serialized, release the mutex and restore the * If method is serialized, release the mutex and restore the
* current sync level for this thread * current sync level for this thread
*/ */
if (method_desc->method.mutex) { if (method_desc->method.mutex) {
/* Acquisition Depth handles recursive calls */ /* Acquisition Depth handles recursive calls */
method_desc->method.mutex->mutex.acquisition_depth--; method_desc->method.mutex->mutex.acquisition_depth--;
if (!method_desc->method.mutex->mutex.acquisition_depth) { if (!method_desc->method.mutex->mutex.acquisition_depth) {
walk_state->thread->current_sync_level = walk_state->thread->current_sync_level =
method_desc->method.mutex->mutex. method_desc->method.mutex->mutex.
original_sync_level; original_sync_level;
acpi_os_release_mutex(method_desc->method.mutex->mutex. acpi_os_release_mutex(method_desc->method.
os_mutex); mutex->mutex.os_mutex);
method_desc->method.mutex->mutex.owner_thread = NULL; method_desc->method.mutex->mutex.thread_id = 0;
}
} }
}
if (walk_state) {
/*
* Delete any objects created by this method during execution.
* The method Node is stored in the walk state
*/
method_node = walk_state->method_node;
/* /*
* Delete any namespace objects created anywhere within * Delete any namespace objects created anywhere within
...@@ -620,7 +609,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, ...@@ -620,7 +609,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
*/ */
if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED) if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED)
&& (!method_desc->method.mutex)) { && (!method_desc->method.mutex)) {
status = acpi_ds_create_method_mutex(method_desc); (void)acpi_ds_create_method_mutex(method_desc);
} }
/* No more threads, we can free the owner_id */ /* No more threads, we can free the owner_id */
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
******************************************************************************/ ******************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -157,7 +157,9 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, ...@@ -157,7 +157,9 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
* will remain as named references. This behavior is not described * will remain as named references. This behavior is not described
* in the ACPI spec, but it appears to be an oversight. * in the ACPI spec, but it appears to be an oversight.
*/ */
obj_desc = (union acpi_operand_object *)op->common.node; obj_desc =
ACPI_CAST_PTR(union acpi_operand_object,
op->common.node);
status = status =
acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
...@@ -172,7 +174,19 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, ...@@ -172,7 +174,19 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
switch (op->common.node->type) { switch (op->common.node->type) {
/* /*
* For these types, we need the actual node, not the subobject. * For these types, we need the actual node, not the subobject.
* However, the subobject got an extra reference count above. * However, the subobject did not get an extra reference count above.
*
* TBD: should ex_resolve_node_to_value be changed to fix this?
*/
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_THERMAL:
acpi_ut_add_reference(op->common.node->object);
/*lint -fallthrough */
/*
* For these types, we need the actual node, not the subobject.
* The subobject got an extra reference count in ex_resolve_node_to_value.
*/ */
case ACPI_TYPE_MUTEX: case ACPI_TYPE_MUTEX:
case ACPI_TYPE_METHOD: case ACPI_TYPE_METHOD:
...@@ -180,25 +194,15 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, ...@@ -180,25 +194,15 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_EVENT: case ACPI_TYPE_EVENT:
case ACPI_TYPE_REGION: case ACPI_TYPE_REGION:
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_THERMAL:
obj_desc = /* We will create a reference object for these types below */
(union acpi_operand_object *)op->common.
node;
break; break;
default: default:
break; /*
} * All other types - the node was resolved to an actual
* object, we are done.
/* */
* If above resolved to an operand object, we are done. Otherwise,
* we have a NS node, we must create the package entry as a named
* reference.
*/
if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) !=
ACPI_DESC_TYPE_NAMED) {
goto exit; goto exit;
} }
} }
...@@ -223,7 +227,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, ...@@ -223,7 +227,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
exit: exit:
*obj_desc_ptr = obj_desc; *obj_desc_ptr = obj_desc;
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(status);
} }
/******************************************************************************* /*******************************************************************************
...@@ -369,7 +373,9 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, ...@@ -369,7 +373,9 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
union acpi_parse_object *parent; union acpi_parse_object *parent;
union acpi_operand_object *obj_desc = NULL; union acpi_operand_object *obj_desc = NULL;
acpi_status status = AE_OK; acpi_status status = AE_OK;
acpi_native_uint i; unsigned i;
u16 index;
u16 reference_count;
ACPI_FUNCTION_TRACE(ds_build_internal_package_obj); ACPI_FUNCTION_TRACE(ds_build_internal_package_obj);
...@@ -447,13 +453,60 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, ...@@ -447,13 +453,60 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
package. package.
elements[i]); elements[i]);
} }
if (*obj_desc_ptr) {
/* Existing package, get existing reference count */
reference_count =
(*obj_desc_ptr)->common.reference_count;
if (reference_count > 1) {
/* Make new element ref count match original ref count */
for (index = 0; index < (reference_count - 1);
index++) {
acpi_ut_add_reference((obj_desc->
package.
elements[i]));
}
}
}
arg = arg->common.next; arg = arg->common.next;
} }
if (!arg) { /* Check for match between num_elements and actual length of package_list */
if (arg) {
/*
* num_elements was exhausted, but there are remaining elements in the
* package_list.
*
* Note: technically, this is an error, from ACPI spec: "It is an error
* for NumElements to be less than the number of elements in the
* PackageList". However, for now, we just print an error message and
* no exception is returned.
*/
while (arg) {
/* Find out how many elements there really are */
i++;
arg = arg->common.next;
}
ACPI_ERROR((AE_INFO,
"Package List length (%X) larger than NumElements count (%X), truncated\n",
i, element_count));
} else if (i < element_count) {
/*
* Arg list (elements) was exhausted, but we did not reach num_elements count.
* Note: this is not an error, the package is padded out with NULLs.
*/
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Package List length larger than NumElements count (%X), truncated\n", "Package List length (%X) smaller than NumElements count (%X), padded with null elements\n",
element_count)); i, element_count));
} }
obj_desc->package.flags |= AOPOBJ_DATA_VALID; obj_desc->package.flags |= AOPOBJ_DATA_VALID;
...@@ -721,6 +774,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, ...@@ -721,6 +774,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
/* Node was saved in Op */ /* Node was saved in Op */
obj_desc->reference.node = op->common.node; obj_desc->reference.node = op->common.node;
obj_desc->reference.object =
op->common.node->object;
} }
obj_desc->reference.opcode = opcode; obj_desc->reference.opcode = opcode;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include <acpi/acinterp.h> #include <acpi/acinterp.h>
#include <acpi/acnamesp.h> #include <acpi/acnamesp.h>
#include <acpi/acevents.h> #include <acpi/acevents.h>
#include <acpi/actables.h>
#define _COMPONENT ACPI_DISPATCHER #define _COMPONENT ACPI_DISPATCHER
ACPI_MODULE_NAME("dsopcode") ACPI_MODULE_NAME("dsopcode")
...@@ -217,6 +218,50 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) ...@@ -217,6 +218,50 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ds_get_bank_field_arguments
*
* PARAMETERS: obj_desc - A valid bank_field object
*
* RETURN: Status.
*
* DESCRIPTION: Get bank_field bank_value. This implements the late
* evaluation of these field attributes.
*
******************************************************************************/
acpi_status
acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
{
union acpi_operand_object *extra_desc;
struct acpi_namespace_node *node;
acpi_status status;
ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
return_ACPI_STATUS(AE_OK);
}
/* Get the AML pointer (method object) and bank_field node */
extra_desc = acpi_ns_get_secondary_object(obj_desc);
node = obj_desc->bank_field.node;
ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
(ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
acpi_ut_get_node_name(node)));
/* Execute the AML code for the term_arg arguments */
status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
extra_desc->extra.aml_length,
extra_desc->extra.aml_start);
return_ACPI_STATUS(status);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ds_get_buffer_arguments * FUNCTION: acpi_ds_get_buffer_arguments
...@@ -770,7 +815,109 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, ...@@ -770,7 +815,109 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
obj_desc, obj_desc,
ACPI_FORMAT_UINT64(obj_desc->region.address), ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address),
obj_desc->region.length));
/* Now the address and length are valid for this opregion */
obj_desc->region.flags |= AOPOBJ_DATA_VALID;
return_ACPI_STATUS(status);
}
/*******************************************************************************
*
* FUNCTION: acpi_ds_eval_table_region_operands
*
* PARAMETERS: walk_state - Current walk
* Op - A valid region Op object
*
* RETURN: Status
*
* DESCRIPTION: Get region address and length
* Called from acpi_ds_exec_end_op during data_table_region parse tree walk
*
******************************************************************************/
acpi_status
acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
union acpi_parse_object *op)
{
acpi_status status;
union acpi_operand_object *obj_desc;
union acpi_operand_object **operand;
struct acpi_namespace_node *node;
union acpi_parse_object *next_op;
acpi_native_uint table_index;
struct acpi_table_header *table;
ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
/*
* This is where we evaluate the signature_string and oem_iDString
* and oem_table_iDString of the data_table_region declaration
*/
node = op->common.node;
/* next_op points to signature_string op */
next_op = op->common.value.arg;
/*
* Evaluate/create the signature_string and oem_iDString
* and oem_table_iDString operands
*/
status = acpi_ds_create_operands(walk_state, next_op);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/*
* Resolve the signature_string and oem_iDString
* and oem_table_iDString operands
*/
status = acpi_ex_resolve_operands(op->common.aml_opcode,
ACPI_WALK_OPERANDS, walk_state);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
acpi_ps_get_opcode_name(op->common.aml_opcode),
1, "after AcpiExResolveOperands");
operand = &walk_state->operands[0];
/* Find the ACPI table */
status = acpi_tb_find_table(operand[0]->string.pointer,
operand[1]->string.pointer,
operand[2]->string.pointer, &table_index);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
acpi_ut_remove_reference(operand[0]);
acpi_ut_remove_reference(operand[1]);
acpi_ut_remove_reference(operand[2]);
status = acpi_get_table_by_index(table_index, &table);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
return_ACPI_STATUS(AE_NOT_EXIST);
}
obj_desc->region.address =
(acpi_physical_address) ACPI_TO_INTEGER(table);
obj_desc->region.length = table->length;
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
obj_desc,
ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address),
obj_desc->region.length)); obj_desc->region.length));
/* Now the address and length are valid for this opregion */ /* Now the address and length are valid for this opregion */
...@@ -808,6 +955,12 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, ...@@ -808,6 +955,12 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
/* The first operand (for all of these data objects) is the length */ /* The first operand (for all of these data objects) is the length */
/*
* Set proper index into operand stack for acpi_ds_obj_stack_push
* invoked inside acpi_ds_create_operand.
*/
walk_state->operand_index = walk_state->num_operands;
status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -876,6 +1029,106 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, ...@@ -876,6 +1029,106 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ds_eval_bank_field_operands
*
* PARAMETERS: walk_state - Current walk
* Op - A valid bank_field Op object
*
* RETURN: Status
*
* DESCRIPTION: Get bank_field bank_value
* Called from acpi_ds_exec_end_op during bank_field parse tree walk
*
******************************************************************************/
acpi_status
acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
union acpi_parse_object *op)
{
acpi_status status;
union acpi_operand_object *obj_desc;
union acpi_operand_object *operand_desc;
struct acpi_namespace_node *node;
union acpi_parse_object *next_op;
union acpi_parse_object *arg;
ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op);
/*
* This is where we evaluate the bank_value field of the
* bank_field declaration
*/
/* next_op points to the op that holds the Region */
next_op = op->common.value.arg;
/* next_op points to the op that holds the Bank Register */
next_op = next_op->common.next;
/* next_op points to the op that holds the Bank Value */
next_op = next_op->common.next;
/*
* Set proper index into operand stack for acpi_ds_obj_stack_push
* invoked inside acpi_ds_create_operand.
*
* We use walk_state->Operands[0] to store the evaluated bank_value
*/
walk_state->operand_index = 0;
status = acpi_ds_create_operand(walk_state, next_op, 0);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
acpi_ps_get_opcode_name(op->common.aml_opcode),
1, "after AcpiExResolveOperands");
/*
* Get the bank_value operand and save it
* (at Top of stack)
*/
operand_desc = walk_state->operands[0];
/* Arg points to the start Bank Field */
arg = acpi_ps_get_arg(op, 4);
while (arg) {
/* Ignore OFFSET and ACCESSAS terms here */
if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
node = arg->common.node;
obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
return_ACPI_STATUS(AE_NOT_EXIST);
}
obj_desc->bank_field.value =
(u32) operand_desc->integer.value;
}
/* Move to next field in the list */
arg = arg->common.next;
}
acpi_ut_remove_reference(operand_desc);
return_ACPI_STATUS(status);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ds_exec_begin_control_op * FUNCTION: acpi_ds_exec_begin_control_op
...@@ -1070,8 +1323,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, ...@@ -1070,8 +1323,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
* is set to anything other than zero! * is set to anything other than zero!
*/ */
walk_state->return_desc = walk_state->operands[0]; walk_state->return_desc = walk_state->operands[0];
} else if ((walk_state->results) && } else if (walk_state->result_count) {
(walk_state->results->results.num_results > 0)) {
/* Since we have a real Return(), delete any implicit return */ /* Since we have a real Return(), delete any implicit return */
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
******************************************************************************/ ******************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -278,7 +278,9 @@ acpi_ds_is_result_used(union acpi_parse_object * op, ...@@ -278,7 +278,9 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
AML_VAR_PACKAGE_OP) AML_VAR_PACKAGE_OP)
|| (op->common.parent->common.aml_opcode == AML_BUFFER_OP) || (op->common.parent->common.aml_opcode == AML_BUFFER_OP)
|| (op->common.parent->common.aml_opcode == || (op->common.parent->common.aml_opcode ==
AML_INT_EVAL_SUBTREE_OP)) { AML_INT_EVAL_SUBTREE_OP)
|| (op->common.parent->common.aml_opcode ==
AML_BANK_FIELD_OP)) {
/* /*
* These opcodes allow term_arg(s) as operands and therefore * These opcodes allow term_arg(s) as operands and therefore
* the operands can be method calls. The result is used. * the operands can be method calls. The result is used.
...@@ -472,7 +474,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, ...@@ -472,7 +474,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
/* A valid name must be looked up in the namespace */ /* A valid name must be looked up in the namespace */
if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
(arg->common.value.string)) { (arg->common.value.string) &&
!(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n",
arg)); arg));
...@@ -595,7 +598,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, ...@@ -595,7 +598,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
} else { } else {
/* Check for null name case */ /* Check for null name case */
if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) { if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
!(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
/* /*
* If the name is null, this means that this is an * If the name is null, this means that this is an
* optional result parameter that was not specified * optional result parameter that was not specified
...@@ -617,7 +621,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, ...@@ -617,7 +621,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(AE_NOT_IMPLEMENTED); return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
} }
if (op_info->flags & AML_HAS_RETVAL) { if ((op_info->flags & AML_HAS_RETVAL)
|| (arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
"Argument previously created, already stacked\n")); "Argument previously created, already stacked\n"));
...@@ -630,9 +635,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, ...@@ -630,9 +635,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
* Use value that was already previously returned * Use value that was already previously returned
* by the evaluation of this argument * by the evaluation of this argument
*/ */
status = status = acpi_ds_result_pop(&obj_desc, walk_state);
acpi_ds_result_pop_from_bottom(&obj_desc,
walk_state);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
/* /*
* Only error is underflow, and this indicates * Only error is underflow, and this indicates
...@@ -698,27 +701,52 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, ...@@ -698,27 +701,52 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
union acpi_parse_object *arg; union acpi_parse_object *arg;
union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS];
u32 arg_count = 0; u32 arg_count = 0;
u32 index = walk_state->num_operands;
u32 i;
ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg);
/* For all arguments in the list... */ /* Get all arguments in the list */
arg = first_arg; arg = first_arg;
while (arg) { while (arg) {
status = acpi_ds_create_operand(walk_state, arg, arg_count); if (index >= ACPI_OBJ_NUM_OPERANDS) {
if (ACPI_FAILURE(status)) { return_ACPI_STATUS(AE_BAD_DATA);
goto cleanup;
} }
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, arguments[index] = arg;
"Arg #%d (%p) done, Arg1=%p\n", arg_count, walk_state->operands[index] = NULL;
arg, first_arg));
/* Move on to next argument, if any */ /* Move on to next argument, if any */
arg = arg->common.next; arg = arg->common.next;
arg_count++; arg_count++;
index++;
}
index--;
/* It is the appropriate order to get objects from the Result stack */
for (i = 0; i < arg_count; i++) {
arg = arguments[index];
/* Force the filling of the operand stack in inverse order */
walk_state->operand_index = (u8) index;
status = acpi_ds_create_operand(walk_state, arg, index);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
index--;
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
"Arg #%d (%p) done, Arg1=%p\n", index, arg,
first_arg));
} }
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -729,9 +757,112 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, ...@@ -729,9 +757,112 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
* pop everything off of the operand stack and delete those * pop everything off of the operand stack and delete those
* objects * objects
*/ */
(void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index));
return_ACPI_STATUS(status);
}
/*****************************************************************************
*
* FUNCTION: acpi_ds_evaluate_name_path
*
* PARAMETERS: walk_state - Current state of the parse tree walk,
* the opcode of current operation should be
* AML_INT_NAMEPATH_OP
*
* RETURN: Status
*
* DESCRIPTION: Translate the -name_path- parse tree object to the equivalent
* interpreter object, convert it to value, if needed, duplicate
* it, if needed, and push it onto the current result stack.
*
****************************************************************************/
acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state)
{
acpi_status status = AE_OK;
union acpi_parse_object *op = walk_state->op;
union acpi_operand_object **operand = &walk_state->operands[0];
union acpi_operand_object *new_obj_desc;
u8 type;
ACPI_FUNCTION_TRACE_PTR(ds_evaluate_name_path, walk_state);
if (!op->common.parent) {
/* This happens after certain exception processing */
goto exit;
}
if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
(op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) ||
(op->common.parent->common.aml_opcode == AML_REF_OF_OP)) {
/* TBD: Should we specify this feature as a bit of op_info->Flags of these opcodes? */
goto exit;
}
status = acpi_ds_create_operand(walk_state, op, 0);
if (ACPI_FAILURE(status)) {
goto exit;
}
if (op->common.flags & ACPI_PARSEOP_TARGET) {
new_obj_desc = *operand;
goto push_result;
}
type = ACPI_GET_OBJECT_TYPE(*operand);
status = acpi_ex_resolve_to_value(operand, walk_state);
if (ACPI_FAILURE(status)) {
goto exit;
}
if (type == ACPI_TYPE_INTEGER) {
/* It was incremented by acpi_ex_resolve_to_value */
acpi_ut_remove_reference(*operand);
status =
acpi_ut_copy_iobject_to_iobject(*operand, &new_obj_desc,
walk_state);
if (ACPI_FAILURE(status)) {
goto exit;
}
} else {
/*
* The object either was anew created or is
* a Namespace node - don't decrement it.
*/
new_obj_desc = *operand;
}
/* Cleanup for name-path operand */
status = acpi_ds_obj_stack_pop(1, walk_state);
if (ACPI_FAILURE(status)) {
walk_state->result_obj = new_obj_desc;
goto exit;
}
push_result:
walk_state->result_obj = new_obj_desc;
status = acpi_ds_result_push(walk_state->result_obj, walk_state);
if (ACPI_SUCCESS(status)) {
/* Force to take it from stack */
op->common.flags |= ACPI_PARSEOP_IN_STACK;
}
exit:
ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d",
(arg_count + 1)));
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -285,11 +285,6 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, ...@@ -285,11 +285,6 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
switch (opcode_class) { switch (opcode_class) {
case AML_CLASS_CONTROL: case AML_CLASS_CONTROL:
status = acpi_ds_result_stack_push(walk_state);
if (ACPI_FAILURE(status)) {
goto error_exit;
}
status = acpi_ds_exec_begin_control_op(walk_state, op); status = acpi_ds_exec_begin_control_op(walk_state, op);
break; break;
...@@ -305,20 +300,11 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, ...@@ -305,20 +300,11 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
status = acpi_ds_load2_begin_op(walk_state, NULL); status = acpi_ds_load2_begin_op(walk_state, NULL);
} }
if (op->common.aml_opcode == AML_REGION_OP) {
status = acpi_ds_result_stack_push(walk_state);
}
break; break;
case AML_CLASS_EXECUTE: case AML_CLASS_EXECUTE:
case AML_CLASS_CREATE: case AML_CLASS_CREATE:
/*
* Most operators with arguments (except create_xxx_field operators)
* Start a new result/operand state
*/
if (walk_state->op_info->object_type != ACPI_TYPE_BUFFER_FIELD) {
status = acpi_ds_result_stack_push(walk_state);
}
break; break;
default: default:
...@@ -374,6 +360,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) ...@@ -374,6 +360,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
/* Init the walk state */ /* Init the walk state */
walk_state->num_operands = 0; walk_state->num_operands = 0;
walk_state->operand_index = 0;
walk_state->return_desc = NULL; walk_state->return_desc = NULL;
walk_state->result_obj = NULL; walk_state->result_obj = NULL;
...@@ -388,10 +375,17 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) ...@@ -388,10 +375,17 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
/* Decode the Opcode Class */ /* Decode the Opcode Class */
switch (op_class) { switch (op_class) {
case AML_CLASS_ARGUMENT: /* constants, literals, etc. - do nothing */ case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */
if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
status = acpi_ds_evaluate_name_path(walk_state);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
}
break; break;
case AML_CLASS_EXECUTE: /* most operators with arguments */ case AML_CLASS_EXECUTE: /* Most operators with arguments */
/* Build resolved operand stack */ /* Build resolved operand stack */
...@@ -400,13 +394,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) ...@@ -400,13 +394,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
goto cleanup; goto cleanup;
} }
/* Done with this result state (Now that operand stack is built) */
status = acpi_ds_result_stack_pop(walk_state);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* /*
* All opcodes require operand resolution, with the only exceptions * All opcodes require operand resolution, with the only exceptions
* being the object_type and size_of operators. * being the object_type and size_of operators.
...@@ -487,16 +474,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) ...@@ -487,16 +474,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
status = acpi_ds_exec_end_control_op(walk_state, op); status = acpi_ds_exec_end_control_op(walk_state, op);
/* Make sure to properly pop the result stack */
if (ACPI_SUCCESS(status)) {
status = acpi_ds_result_stack_pop(walk_state);
} else if (status == AE_CTRL_PENDING) {
status = acpi_ds_result_stack_pop(walk_state);
if (ACPI_SUCCESS(status)) {
status = AE_CTRL_PENDING;
}
}
break; break;
case AML_TYPE_METHOD_CALL: case AML_TYPE_METHOD_CALL:
...@@ -516,7 +493,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) ...@@ -516,7 +493,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
op->common.node = op->common.node =
(struct acpi_namespace_node *)op->asl.value. (struct acpi_namespace_node *)op->asl.value.
arg->asl.node->object; arg->asl.node;
acpi_ut_add_reference(op->asl.value.arg->asl. acpi_ut_add_reference(op->asl.value.arg->asl.
node->object); node->object);
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
...@@ -632,13 +609,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) ...@@ -632,13 +609,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
break; break;
} }
/* Done with result state (Now that operand stack is built) */
status = acpi_ds_result_stack_pop(walk_state);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* /*
* If a result object was returned from above, push it on the * If a result object was returned from above, push it on the
* current result stack * current result stack
...@@ -671,8 +641,28 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) ...@@ -671,8 +641,28 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
break; break;
} }
} else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Executing DataTableRegion Strings Op=%p\n",
op));
status =
acpi_ds_eval_table_region_operands
(walk_state, op);
if (ACPI_FAILURE(status)) {
break;
}
} else if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Executing BankField Op=%p\n",
op));
status = acpi_ds_result_stack_pop(walk_state); status =
acpi_ds_eval_bank_field_operands(walk_state,
op);
if (ACPI_FAILURE(status)) {
break;
}
} }
break; break;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -443,6 +443,15 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) ...@@ -443,6 +443,15 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
} else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
status =
acpi_ex_create_region(op->named.data,
op->named.length,
REGION_DATA_TABLE,
walk_state);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
} }
} }
#endif #endif
...@@ -767,6 +776,12 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, ...@@ -767,6 +776,12 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
acpi_ns_lookup(walk_state->scope_info, buffer_ptr, acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
object_type, ACPI_IMODE_LOAD_PASS2, flags, object_type, ACPI_IMODE_LOAD_PASS2, flags,
walk_state, &node); walk_state, &node);
if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
"***New Node [%4.4s] %p is temporary\n",
acpi_ut_get_node_name(node), node));
}
break; break;
} }
...@@ -823,6 +838,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) ...@@ -823,6 +838,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
struct acpi_namespace_node *new_node; struct acpi_namespace_node *new_node;
#ifndef ACPI_NO_METHOD_EXECUTION #ifndef ACPI_NO_METHOD_EXECUTION
u32 i; u32 i;
u8 region_space;
#endif #endif
ACPI_FUNCTION_TRACE(ds_load2_end_op); ACPI_FUNCTION_TRACE(ds_load2_end_op);
...@@ -1003,11 +1019,6 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) ...@@ -1003,11 +1019,6 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
status = acpi_ex_create_event(walk_state); status = acpi_ex_create_event(walk_state);
break; break;
case AML_DATA_REGION_OP:
status = acpi_ex_create_table_region(walk_state);
break;
case AML_ALIAS_OP: case AML_ALIAS_OP:
status = acpi_ex_create_alias(walk_state); status = acpi_ex_create_alias(walk_state);
...@@ -1035,6 +1046,15 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) ...@@ -1035,6 +1046,15 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
switch (op->common.aml_opcode) { switch (op->common.aml_opcode) {
#ifndef ACPI_NO_METHOD_EXECUTION #ifndef ACPI_NO_METHOD_EXECUTION
case AML_REGION_OP: case AML_REGION_OP:
case AML_DATA_REGION_OP:
if (op->common.aml_opcode == AML_REGION_OP) {
region_space = (acpi_adr_space_type)
((op->common.value.arg)->common.value.
integer);
} else {
region_space = REGION_DATA_TABLE;
}
/* /*
* If we are executing a method, initialize the region * If we are executing a method, initialize the region
...@@ -1043,10 +1063,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) ...@@ -1043,10 +1063,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
status = status =
acpi_ex_create_region(op->named.data, acpi_ex_create_region(op->named.data,
op->named.length, op->named.length,
(acpi_adr_space_type) region_space,
((op->common.value.
arg)->common.value.
integer),
walk_state); walk_state);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return (status); return (status);
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
This diff is collapsed.
This diff is collapsed.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -248,10 +248,6 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) ...@@ -248,10 +248,6 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
ACPI_FUNCTION_TRACE(ev_disable_gpe); ACPI_FUNCTION_TRACE(ev_disable_gpe);
if (!(gpe_event_info->flags & ACPI_GPE_ENABLE_MASK)) {
return_ACPI_STATUS(AE_OK);
}
/* Make sure HW enable masks are updated */ /* Make sure HW enable masks are updated */
status = status =
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -49,22 +49,7 @@ ...@@ -49,22 +49,7 @@
#define _COMPONENT ACPI_EVENTS #define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME("evmisc") ACPI_MODULE_NAME("evmisc")
/* Names for Notify() values, used for debug output */
#ifdef ACPI_DEBUG_OUTPUT
static const char *acpi_notify_value_names[] = {
"Bus Check",
"Device Check",
"Device Wake",
"Eject Request",
"Device Check Light",
"Frequency Mismatch",
"Bus Mode Mismatch",
"Power Fault"
};
#endif
/* Pointer to FACS needed for the Global Lock */ /* Pointer to FACS needed for the Global Lock */
static struct acpi_table_facs *facs = NULL; static struct acpi_table_facs *facs = NULL;
/* Local prototypes */ /* Local prototypes */
...@@ -94,7 +79,6 @@ u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node) ...@@ -94,7 +79,6 @@ u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node)
switch (node->type) { switch (node->type) {
case ACPI_TYPE_DEVICE: case ACPI_TYPE_DEVICE:
case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_POWER:
case ACPI_TYPE_THERMAL: case ACPI_TYPE_THERMAL:
/* /*
* These are the ONLY objects that can receive ACPI notifications * These are the ONLY objects that can receive ACPI notifications
...@@ -139,17 +123,9 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, ...@@ -139,17 +123,9 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
* initiate soft-off or sleep operation? * initiate soft-off or sleep operation?
*/ */
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Dispatching Notify(%X) on node %p\n", notify_value, "Dispatching Notify on [%4.4s] Node %p Value 0x%2.2X (%s)\n",
node)); acpi_ut_get_node_name(node), node, notify_value,
acpi_ut_get_notify_name(notify_value)));
if (notify_value <= 7) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notify value: %s\n",
acpi_notify_value_names[notify_value]));
} else {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Notify value: 0x%2.2X **Device Specific**\n",
notify_value));
}
/* Get the notify object attached to the NS Node */ /* Get the notify object attached to the NS Node */
...@@ -159,10 +135,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, ...@@ -159,10 +135,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
/* We have the notify object, Get the right handler */ /* We have the notify object, Get the right handler */
switch (node->type) { switch (node->type) {
/* Notify allowed only on these types */
case ACPI_TYPE_DEVICE: case ACPI_TYPE_DEVICE:
case ACPI_TYPE_THERMAL: case ACPI_TYPE_THERMAL:
case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_POWER:
if (notify_value <= ACPI_MAX_SYS_NOTIFY) { if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
handler_obj = handler_obj =
...@@ -179,8 +157,13 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, ...@@ -179,8 +157,13 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
} }
} }
/* If there is any handler to run, schedule the dispatcher */ /*
* If there is any handler to run, schedule the dispatcher.
* Check for:
* 1) Global system notify handler
* 2) Global device notify handler
* 3) Per-device notify handler
*/
if ((acpi_gbl_system_notify.handler if ((acpi_gbl_system_notify.handler
&& (notify_value <= ACPI_MAX_SYS_NOTIFY)) && (notify_value <= ACPI_MAX_SYS_NOTIFY))
|| (acpi_gbl_device_notify.handler || (acpi_gbl_device_notify.handler
...@@ -190,6 +173,13 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, ...@@ -190,6 +173,13 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
return (AE_NO_MEMORY); return (AE_NO_MEMORY);
} }
if (!handler_obj) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Executing system notify handler for Notify (%4.4s, %X) node %p\n",
acpi_ut_get_node_name(node),
notify_value, node));
}
notify_info->common.descriptor_type = notify_info->common.descriptor_type =
ACPI_DESC_TYPE_STATE_NOTIFY; ACPI_DESC_TYPE_STATE_NOTIFY;
notify_info->notify.node = node; notify_info->notify.node = node;
...@@ -202,15 +192,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, ...@@ -202,15 +192,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
acpi_ut_delete_generic_state(notify_info); acpi_ut_delete_generic_state(notify_info);
} }
} } else {
if (!handler_obj) {
/* /*
* There is no per-device notify handler for this device. * There is no notify handler (per-device or system) for this device.
* This may or may not be a problem.
*/ */
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"No notify handler for Notify(%4.4s, %X) node %p\n", "No notify handler for Notify (%4.4s, %X) node %p\n",
acpi_ut_get_node_name(node), notify_value, acpi_ut_get_node_name(node), notify_value,
node)); node));
} }
...@@ -349,9 +336,10 @@ acpi_status acpi_ev_init_global_lock_handler(void) ...@@ -349,9 +336,10 @@ acpi_status acpi_ev_init_global_lock_handler(void)
ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
status = status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, ACPI_CAST_INDIRECT_PTR(struct
(struct acpi_table_header **)&facs); acpi_table_header,
&facs));
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -439,7 +427,8 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) ...@@ -439,7 +427,8 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
* Only one thread can acquire the GL at a time, the global_lock_mutex * Only one thread can acquire the GL at a time, the global_lock_mutex
* enforces this. This interface releases the interpreter if we must wait. * enforces this. This interface releases the interpreter if we must wait.
*/ */
status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0); status = acpi_ex_system_wait_mutex(
acpi_gbl_global_lock_mutex->mutex.os_mutex, 0);
if (status == AE_TIME) { if (status == AE_TIME) {
if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) { if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
acpi_ev_global_lock_acquired++; acpi_ev_global_lock_acquired++;
...@@ -448,9 +437,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) ...@@ -448,9 +437,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
} }
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
status = status = acpi_ex_system_wait_mutex(
acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, acpi_gbl_global_lock_mutex->mutex.os_mutex,
timeout); timeout);
} }
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -459,6 +448,19 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) ...@@ -459,6 +448,19 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
acpi_ev_global_lock_thread_id = acpi_os_get_thread_id(); acpi_ev_global_lock_thread_id = acpi_os_get_thread_id();
acpi_ev_global_lock_acquired++; acpi_ev_global_lock_acquired++;
/*
* Update the global lock handle and check for wraparound. The handle is
* only used for the external global lock interfaces, but it is updated
* here to properly handle the case where a single thread may acquire the
* lock via both the AML and the acpi_acquire_global_lock interfaces. The
* handle is therefore updated on the first acquire from a given thread
* regardless of where the acquisition request originated.
*/
acpi_gbl_global_lock_handle++;
if (acpi_gbl_global_lock_handle == 0) {
acpi_gbl_global_lock_handle = 1;
}
/* /*
* Make sure that a global lock actually exists. If not, just treat * Make sure that a global lock actually exists. If not, just treat
* the lock as a standard mutex. * the lock as a standard mutex.
...@@ -555,7 +557,7 @@ acpi_status acpi_ev_release_global_lock(void) ...@@ -555,7 +557,7 @@ acpi_status acpi_ev_release_global_lock(void)
/* Release the local GL mutex */ /* Release the local GL mutex */
acpi_ev_global_lock_thread_id = NULL; acpi_ev_global_lock_thread_id = NULL;
acpi_ev_global_lock_acquired = 0; acpi_ev_global_lock_acquired = 0;
acpi_os_release_mutex(acpi_gbl_global_lock_mutex); acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -394,7 +394,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, ...@@ -394,7 +394,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
"Handler %p (@%p) Address %8.8X%8.8X [%s]\n", "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
&region_obj->region.handler->address_space, handler, &region_obj->region.handler->address_space, handler,
ACPI_FORMAT_UINT64(address), ACPI_FORMAT_NATIVE_UINT(address),
acpi_ut_get_region_name(region_obj->region. acpi_ut_get_region_name(region_obj->region.
space_id))); space_id)));
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
******************************************************************************/ ******************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -758,6 +758,12 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler) ...@@ -758,6 +758,12 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
* *
* DESCRIPTION: Acquire the ACPI Global Lock * DESCRIPTION: Acquire the ACPI Global Lock
* *
* Note: Allows callers with the same thread ID to acquire the global lock
* multiple times. In other words, externally, the behavior of the global lock
* is identical to an AML mutex. On the first acquire, a new handle is
* returned. On any subsequent calls to acquire by the same thread, the same
* handle is returned.
*
******************************************************************************/ ******************************************************************************/
acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
{ {
...@@ -770,14 +776,19 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) ...@@ -770,14 +776,19 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
/* Must lock interpreter to prevent race conditions */ /* Must lock interpreter to prevent race conditions */
acpi_ex_enter_interpreter(); acpi_ex_enter_interpreter();
status = acpi_ev_acquire_global_lock(timeout);
acpi_ex_exit_interpreter(); status = acpi_ex_acquire_mutex_object(timeout,
acpi_gbl_global_lock_mutex,
acpi_os_get_thread_id());
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
acpi_gbl_global_lock_handle++;
/* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */
*handle = acpi_gbl_global_lock_handle; *handle = acpi_gbl_global_lock_handle;
} }
acpi_ex_exit_interpreter();
return (status); return (status);
} }
...@@ -798,11 +809,11 @@ acpi_status acpi_release_global_lock(u32 handle) ...@@ -798,11 +809,11 @@ acpi_status acpi_release_global_lock(u32 handle)
{ {
acpi_status status; acpi_status status;
if (handle != acpi_gbl_global_lock_handle) { if (!handle || (handle != acpi_gbl_global_lock_handle)) {
return (AE_NOT_ACQUIRED); return (AE_NOT_ACQUIRED);
} }
status = acpi_ev_release_global_lock(); status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
return (status); return (status);
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
#include <acpi/acinterp.h> #include <acpi/acinterp.h>
#include <acpi/amlcode.h> #include <acpi/amlcode.h>
#include <acpi/acnamesp.h> #include <acpi/acnamesp.h>
#include <acpi/acevents.h>
#include <acpi/actables.h> #include <acpi/actables.h>
#include <acpi/acdispat.h> #include <acpi/acdispat.h>
...@@ -138,6 +137,14 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, ...@@ -138,6 +137,14 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
ACPI_FUNCTION_TRACE(ex_load_table_op); ACPI_FUNCTION_TRACE(ex_load_table_op);
/* Validate lengths for the signature_string, OEMIDString, OEMtable_iD */
if ((operand[0]->string.length > ACPI_NAME_SIZE) ||
(operand[1]->string.length > ACPI_OEM_ID_SIZE) ||
(operand[2]->string.length > ACPI_OEM_TABLE_ID_SIZE)) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Find the ACPI table in the RSDT/XSDT */ /* Find the ACPI table in the RSDT/XSDT */
status = acpi_tb_find_table(operand[0]->string.pointer, status = acpi_tb_find_table(operand[0]->string.pointer,
...@@ -229,11 +236,18 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, ...@@ -229,11 +236,18 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
status = acpi_get_table_by_index(table_index, &table); status = acpi_get_table_by_index(table_index, &table);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
ACPI_INFO((AE_INFO, ACPI_INFO((AE_INFO,
"Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", "Dynamic OEM Table Load - [%.4s] OemId [%.6s] OemTableId [%.8s]",
table->signature, table->oem_id, table->signature, table->oem_id,
table->oem_table_id)); table->oem_table_id));
} }
/* Invoke table handler if present */
if (acpi_gbl_table_handler) {
(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
acpi_gbl_table_handler_context);
}
*return_desc = ddb_handle; *return_desc = ddb_handle;
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -268,6 +282,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -268,6 +282,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
struct acpi_table_desc table_desc; struct acpi_table_desc table_desc;
acpi_native_uint table_index; acpi_native_uint table_index;
acpi_status status; acpi_status status;
u32 length;
ACPI_FUNCTION_TRACE(ex_load_op); ACPI_FUNCTION_TRACE(ex_load_op);
...@@ -278,16 +293,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -278,16 +293,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_REGION: case ACPI_TYPE_REGION:
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
obj_desc,
acpi_ut_get_object_type_name(obj_desc)));
/* Region must be system_memory (from ACPI spec) */ /* Region must be system_memory (from ACPI spec) */
if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
return_ACPI_STATUS(AE_AML_OPERAND_TYPE); return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
} }
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
obj_desc,
acpi_ut_get_object_type_name(obj_desc)));
/* /*
* If the Region Address and Length have not been previously evaluated, * If the Region Address and Length have not been previously evaluated,
* evaluate them now and save the results. * evaluate them now and save the results.
...@@ -299,6 +314,11 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -299,6 +314,11 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
} }
} }
/*
* We will simply map the memory region for the table. However, the
* memory region is technically not guaranteed to remain stable and
* we may eventually have to copy the table to a local buffer.
*/
table_desc.address = obj_desc->region.address; table_desc.address = obj_desc->region.address;
table_desc.length = obj_desc->region.length; table_desc.length = obj_desc->region.length;
table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
...@@ -306,18 +326,41 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -306,18 +326,41 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */
/* Simply extract the buffer from the buffer object */
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Load from Buffer or Field %p %s\n", obj_desc, "Load from Buffer or Field %p %s\n", obj_desc,
acpi_ut_get_object_type_name(obj_desc))); acpi_ut_get_object_type_name(obj_desc)));
table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header, length = obj_desc->buffer.length;
obj_desc->buffer.pointer);
table_desc.length = table_desc.pointer->length; /* Must have at least an ACPI table header */
table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
if (length < sizeof(struct acpi_table_header)) {
return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
}
/* Validate checksum here. It won't get validated in tb_add_table */
obj_desc->buffer.pointer = NULL; status =
acpi_tb_verify_checksum(ACPI_CAST_PTR
(struct acpi_table_header,
obj_desc->buffer.pointer), length);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/*
* We need to copy the buffer since the original buffer could be
* changed or deleted in the future
*/
table_desc.pointer = ACPI_ALLOCATE(length);
if (!table_desc.pointer) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer,
length);
table_desc.length = length;
table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
break; break;
default: default:
...@@ -333,7 +376,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -333,7 +376,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
} }
status = status =
acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); acpi_ex_add_table(table_index, walk_state->scope_info->scope.node,
&ddb_handle);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
/* On error, table_ptr was deallocated above */ /* On error, table_ptr was deallocated above */
...@@ -349,11 +393,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -349,11 +393,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* table_ptr was deallocated above */ /* table_ptr was deallocated above */
acpi_ut_remove_reference(ddb_handle);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
/* Invoke table handler if present */
if (acpi_gbl_table_handler) {
(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD,
table_desc.pointer,
acpi_gbl_table_handler_context);
}
cleanup: cleanup:
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
/* Delete allocated buffer or mapping */
acpi_tb_delete_table(&table_desc); acpi_tb_delete_table(&table_desc);
} }
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -376,6 +432,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) ...@@ -376,6 +432,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
acpi_status status = AE_OK; acpi_status status = AE_OK;
union acpi_operand_object *table_desc = ddb_handle; union acpi_operand_object *table_desc = ddb_handle;
acpi_native_uint table_index; acpi_native_uint table_index;
struct acpi_table_header *table;
ACPI_FUNCTION_TRACE(ex_unload_table); ACPI_FUNCTION_TRACE(ex_unload_table);
...@@ -395,17 +452,25 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) ...@@ -395,17 +452,25 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
table_index = (acpi_native_uint) table_desc->reference.object; table_index = (acpi_native_uint) table_desc->reference.object;
/* Invoke table handler if present */
if (acpi_gbl_table_handler) {
status = acpi_get_table_by_index(table_index, &table);
if (ACPI_SUCCESS(status)) {
(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
table,
acpi_gbl_table_handler_context);
}
}
/* /*
* Delete the entire namespace under this table Node * Delete the entire namespace under this table Node
* (Offset contains the table_id) * (Offset contains the table_id)
*/ */
acpi_tb_delete_namespace_by_owner(table_index); acpi_tb_delete_namespace_by_owner(table_index);
acpi_tb_release_owner_id(table_index); (void)acpi_tb_release_owner_id(table_index);
acpi_tb_set_table_loaded_flag(table_index, FALSE); acpi_tb_set_table_loaded_flag(table_index, FALSE);
/* Delete the table descriptor (ddb_handle) */ return_ACPI_STATUS(AE_OK);
acpi_ut_remove_reference(table_desc);
return_ACPI_STATUS(status);
} }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -96,16 +96,28 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state) ...@@ -96,16 +96,28 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
* to the original Node. * to the original Node.
*/ */
switch (target_node->type) { switch (target_node->type) {
/* For these types, the sub-object can change dynamically via a Store */
case ACPI_TYPE_INTEGER: case ACPI_TYPE_INTEGER:
case ACPI_TYPE_STRING: case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER: case ACPI_TYPE_BUFFER:
case ACPI_TYPE_PACKAGE: case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_BUFFER_FIELD:
/*
* These types open a new scope, so we need the NS node in order to access
* any children.
*/
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_POWER:
case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_THERMAL:
case ACPI_TYPE_LOCAL_SCOPE:
/* /*
* The new alias has the type ALIAS and points to the original * The new alias has the type ALIAS and points to the original
* NS node, not the object itself. This is because for these * NS node, not the object itself.
* types, the object can change dynamically via a Store.
*/ */
alias_node->type = ACPI_TYPE_LOCAL_ALIAS; alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
alias_node->object = alias_node->object =
...@@ -115,9 +127,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state) ...@@ -115,9 +127,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
case ACPI_TYPE_METHOD: case ACPI_TYPE_METHOD:
/* /*
* The new alias has the type ALIAS and points to the original * Control method aliases need to be differentiated
* NS node, not the object itself. This is because for these
* types, the object can change dynamically via a Store.
*/ */
alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS; alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
alias_node->object = alias_node->object =
...@@ -340,101 +350,6 @@ acpi_ex_create_region(u8 * aml_start, ...@@ -340,101 +350,6 @@ acpi_ex_create_region(u8 * aml_start,
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ex_create_table_region
*
* PARAMETERS: walk_state - Current state
*
* RETURN: Status
*
* DESCRIPTION: Create a new data_table_region object
*
******************************************************************************/
acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
{
acpi_status status;
union acpi_operand_object **operand = &walk_state->operands[0];
union acpi_operand_object *obj_desc;
struct acpi_namespace_node *node;
union acpi_operand_object *region_obj2;
acpi_native_uint table_index;
struct acpi_table_header *table;
ACPI_FUNCTION_TRACE(ex_create_table_region);
/* Get the Node from the object stack */
node = walk_state->op->common.node;
/*
* If the region object is already attached to this node,
* just return
*/
if (acpi_ns_get_attached_object(node)) {
return_ACPI_STATUS(AE_OK);
}
/* Find the ACPI table */
status = acpi_tb_find_table(operand[1]->string.pointer,
operand[2]->string.pointer,
operand[3]->string.pointer, &table_index);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Create the region descriptor */
obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
if (!obj_desc) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
region_obj2 = obj_desc->common.next_object;
region_obj2->extra.region_context = NULL;
status = acpi_get_table_by_index(table_index, &table);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Init the region from the operands */
obj_desc->region.space_id = REGION_DATA_TABLE;
obj_desc->region.address =
(acpi_physical_address) ACPI_TO_INTEGER(table);
obj_desc->region.length = table->length;
obj_desc->region.node = node;
obj_desc->region.flags = AOPOBJ_DATA_VALID;
/* Install the new region object in the parent Node */
status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_REGION);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
status = acpi_ev_initialize_region(obj_desc, FALSE);
if (ACPI_FAILURE(status)) {
if (status == AE_NOT_EXIST) {
status = AE_OK;
} else {
goto cleanup;
}
}
obj_desc->region.flags |= AOPOBJ_SETUP_COMPLETE;
cleanup:
/* Remove local reference to the object */
acpi_ut_remove_reference(obj_desc);
return_ACPI_STATUS(status);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ex_create_processor * FUNCTION: acpi_ex_create_processor
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -500,25 +500,28 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) ...@@ -500,25 +500,28 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
acpi_os_printf("Reference: Debug\n"); acpi_os_printf("Reference: Debug\n");
break; break;
case AML_NAME_OP: case AML_INDEX_OP:
ACPI_DUMP_PATHNAME(obj_desc->reference.object, acpi_os_printf("Reference: Index %p\n",
"Reference: Name: ", ACPI_LV_INFO, obj_desc->reference.object);
_COMPONENT);
ACPI_DUMP_ENTRY(obj_desc->reference.object,
ACPI_LV_INFO);
break; break;
case AML_INDEX_OP: case AML_LOAD_OP:
acpi_os_printf("Reference: Index %p\n", acpi_os_printf("Reference: [DdbHandle] TableIndex %p\n",
obj_desc->reference.object); obj_desc->reference.object);
break; break;
case AML_REF_OF_OP: case AML_REF_OF_OP:
acpi_os_printf("Reference: (RefOf) %p\n", acpi_os_printf("Reference: (RefOf) %p [%s]\n",
obj_desc->reference.object); obj_desc->reference.object,
acpi_ut_get_type_name(((union
acpi_operand_object
*)obj_desc->
reference.
object)->common.
type));
break; break;
case AML_ARG_OP: case AML_ARG_OP:
...@@ -559,8 +562,9 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) ...@@ -559,8 +562,9 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
case AML_INT_NAMEPATH_OP: case AML_INT_NAMEPATH_OP:
acpi_os_printf("Reference.Node->Name %X\n", acpi_os_printf("Reference: Namepath %X [%4.4s]\n",
obj_desc->reference.node->name.integer); obj_desc->reference.node->name.integer,
obj_desc->reference.node->name.ascii);
break; break;
default: default:
...@@ -640,8 +644,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) ...@@ -640,8 +644,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
acpi_os_printf("\n"); acpi_os_printf("\n");
} else { } else {
acpi_os_printf(" base %8.8X%8.8X Length %X\n", acpi_os_printf(" base %8.8X%8.8X Length %X\n",
ACPI_FORMAT_UINT64(obj_desc->region. ACPI_FORMAT_NATIVE_UINT(obj_desc->region.
address), address),
obj_desc->region.length); obj_desc->region.length);
} }
break; break;
...@@ -877,20 +881,43 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) ...@@ -877,20 +881,43 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER;
if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) { if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) {
acpi_os_printf("Named Object %p ", obj_desc->reference.node); acpi_os_printf(" Named Object %p ", obj_desc->reference.node);
status = status =
acpi_ns_handle_to_pathname(obj_desc->reference.node, acpi_ns_handle_to_pathname(obj_desc->reference.node,
&ret_buf); &ret_buf);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
acpi_os_printf("Could not convert name to pathname\n"); acpi_os_printf(" Could not convert name to pathname\n");
} else { } else {
acpi_os_printf("%s\n", (char *)ret_buf.pointer); acpi_os_printf("%s\n", (char *)ret_buf.pointer);
ACPI_FREE(ret_buf.pointer); ACPI_FREE(ret_buf.pointer);
} }
} else if (obj_desc->reference.object) { } else if (obj_desc->reference.object) {
acpi_os_printf("\nReferenced Object: %p\n", if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
obj_desc->reference.object); ACPI_DESC_TYPE_OPERAND) {
acpi_os_printf(" Target: %p",
obj_desc->reference.object);
if (obj_desc->reference.opcode == AML_LOAD_OP) {
/*
* For DDBHandle reference,
* obj_desc->Reference.Object is the table index
*/
acpi_os_printf(" [DDBHandle]\n");
} else {
acpi_os_printf(" [%s]\n",
acpi_ut_get_type_name(((union
acpi_operand_object
*)
obj_desc->
reference.
object)->
common.
type));
}
} else {
acpi_os_printf(" Target: %p\n",
obj_desc->reference.object);
}
} }
} }
...@@ -976,7 +1003,9 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, ...@@ -976,7 +1003,9 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
case ACPI_TYPE_LOCAL_REFERENCE: case ACPI_TYPE_LOCAL_REFERENCE:
acpi_os_printf("[Object Reference] "); acpi_os_printf("[Object Reference] %s",
(acpi_ps_get_opcode_info
(obj_desc->reference.opcode))->name);
acpi_ex_dump_reference_obj(obj_desc); acpi_ex_dump_reference_obj(obj_desc);
break; break;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -71,7 +71,6 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, ...@@ -71,7 +71,6 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
union acpi_operand_object *buffer_desc; union acpi_operand_object *buffer_desc;
acpi_size length; acpi_size length;
void *buffer; void *buffer;
u8 locked;
ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc);
...@@ -111,9 +110,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, ...@@ -111,9 +110,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
/* Lock entire transaction if requested */ /* Lock entire transaction if requested */
locked = acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
acpi_ex_acquire_global_lock(obj_desc->common_field.
field_flags);
/* /*
* Perform the read. * Perform the read.
...@@ -125,7 +122,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, ...@@ -125,7 +122,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
buffer.pointer), buffer.pointer),
ACPI_READ | (obj_desc->field. ACPI_READ | (obj_desc->field.
attribute << 16)); attribute << 16));
acpi_ex_release_global_lock(locked); acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
goto exit; goto exit;
} }
...@@ -175,13 +172,12 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, ...@@ -175,13 +172,12 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
/* Lock entire transaction if requested */ /* Lock entire transaction if requested */
locked = acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
/* Read from the field */ /* Read from the field */
status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length); status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length);
acpi_ex_release_global_lock(locked); acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
exit: exit:
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
...@@ -214,10 +210,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, ...@@ -214,10 +210,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
{ {
acpi_status status; acpi_status status;
u32 length; u32 length;
u32 required_length;
void *buffer; void *buffer;
void *new_buffer;
u8 locked;
union acpi_operand_object *buffer_desc; union acpi_operand_object *buffer_desc;
ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc);
...@@ -278,9 +271,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, ...@@ -278,9 +271,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
/* Lock entire transaction if requested */ /* Lock entire transaction if requested */
locked = acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
acpi_ex_acquire_global_lock(obj_desc->common_field.
field_flags);
/* /*
* Perform the write (returns status and perhaps data in the * Perform the write (returns status and perhaps data in the
...@@ -291,7 +282,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, ...@@ -291,7 +282,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
(acpi_integer *) buffer, (acpi_integer *) buffer,
ACPI_WRITE | (obj_desc->field. ACPI_WRITE | (obj_desc->field.
attribute << 16)); attribute << 16));
acpi_ex_release_global_lock(locked); acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
*result_desc = buffer_desc; *result_desc = buffer_desc;
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -319,35 +310,6 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, ...@@ -319,35 +310,6 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
return_ACPI_STATUS(AE_AML_OPERAND_TYPE); return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
} }
/*
* We must have a buffer that is at least as long as the field
* we are writing to. This is because individual fields are
* indivisible and partial writes are not supported -- as per
* the ACPI specification.
*/
new_buffer = NULL;
required_length =
ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
if (length < required_length) {
/* We need to create a new buffer */
new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
if (!new_buffer) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
/*
* Copy the original data to the new buffer, starting
* at Byte zero. All unused (upper) bytes of the
* buffer will be 0.
*/
ACPI_MEMCPY((char *)new_buffer, (char *)buffer, length);
buffer = new_buffer;
length = required_length;
}
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n", "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
source_desc, source_desc,
...@@ -366,19 +328,12 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, ...@@ -366,19 +328,12 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
/* Lock entire transaction if requested */ /* Lock entire transaction if requested */
locked = acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
/* Write to the field */ /* Write to the field */
status = acpi_ex_insert_into_field(obj_desc, buffer, length); status = acpi_ex_insert_into_field(obj_desc, buffer, length);
acpi_ex_release_global_lock(locked); acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
/* Free temporary buffer if we used one */
if (new_buffer) {
ACPI_FREE(new_buffer);
}
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -263,7 +263,8 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, ...@@ -263,7 +263,8 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
rgn_desc->region.space_id, rgn_desc->region.space_id,
obj_desc->common_field.access_byte_width, obj_desc->common_field.access_byte_width,
obj_desc->common_field.base_byte_offset, obj_desc->common_field.base_byte_offset,
field_datum_byte_offset, (void *)address)); field_datum_byte_offset, ACPI_CAST_PTR(void,
address)));
/* Invoke the appropriate address_space/op_region handler */ /* Invoke the appropriate address_space/op_region handler */
...@@ -805,18 +806,39 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, ...@@ -805,18 +806,39 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
u32 datum_count; u32 datum_count;
u32 field_datum_count; u32 field_datum_count;
u32 i; u32 i;
u32 required_length;
void *new_buffer;
ACPI_FUNCTION_TRACE(ex_insert_into_field); ACPI_FUNCTION_TRACE(ex_insert_into_field);
/* Validate input buffer */ /* Validate input buffer */
if (buffer_length < new_buffer = NULL;
ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) { required_length =
ACPI_ERROR((AE_INFO, ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
"Field size %X (bits) is too large for buffer (%X)", /*
obj_desc->common_field.bit_length, buffer_length)); * We must have a buffer that is at least as long as the field
* we are writing to. This is because individual fields are
* indivisible and partial writes are not supported -- as per
* the ACPI specification.
*/
if (buffer_length < required_length) {
return_ACPI_STATUS(AE_BUFFER_OVERFLOW); /* We need to create a new buffer */
new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
if (!new_buffer) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
/*
* Copy the original data to the new buffer, starting
* at Byte zero. All unused (upper) bytes of the
* buffer will be 0.
*/
ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length);
buffer = new_buffer;
buffer_length = required_length;
} }
/* /*
...@@ -866,7 +888,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, ...@@ -866,7 +888,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
merged_datum, merged_datum,
field_offset); field_offset);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); goto exit;
} }
field_offset += obj_desc->common_field.access_byte_width; field_offset += obj_desc->common_field.access_byte_width;
...@@ -924,5 +946,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, ...@@ -924,5 +946,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
mask, merged_datum, mask, merged_datum,
field_offset); field_offset);
exit:
/* Free temporary buffer if we used one */
if (new_buffer) {
ACPI_FREE(new_buffer);
}
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -121,6 +121,7 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state) ...@@ -121,6 +121,7 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state)
if ((ACPI_FAILURE(status)) || walk_state->result_obj) { if ((ACPI_FAILURE(status)) || walk_state->result_obj) {
acpi_ut_remove_reference(return_desc); acpi_ut_remove_reference(return_desc);
walk_state->result_obj = NULL;
} else { } else {
/* Save the return value */ /* Save the return value */
...@@ -739,26 +740,38 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) ...@@ -739,26 +740,38 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
value = acpi_gbl_integer_byte_width; value = acpi_gbl_integer_byte_width;
break; break;
case ACPI_TYPE_BUFFER:
value = temp_desc->buffer.length;
break;
case ACPI_TYPE_STRING: case ACPI_TYPE_STRING:
value = temp_desc->string.length; value = temp_desc->string.length;
break; break;
case ACPI_TYPE_BUFFER:
/* Buffer arguments may not be evaluated at this point */
status = acpi_ds_get_buffer_arguments(temp_desc);
value = temp_desc->buffer.length;
break;
case ACPI_TYPE_PACKAGE: case ACPI_TYPE_PACKAGE:
/* Package arguments may not be evaluated at this point */
status = acpi_ds_get_package_arguments(temp_desc);
value = temp_desc->package.count; value = temp_desc->package.count;
break; break;
default: default:
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"Operand is not Buf/Int/Str/Pkg - found type %s", "Operand must be Buffer/Integer/String/Package - found type %s",
acpi_ut_get_type_name(type))); acpi_ut_get_type_name(type)));
status = AE_AML_OPERAND_TYPE; status = AE_AML_OPERAND_TYPE;
goto cleanup; goto cleanup;
} }
if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* /*
* Now that we have the size of the object, create a result * Now that we have the size of the object, create a result
* object to hold the value * object to hold the value
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -241,10 +241,6 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state) ...@@ -241,10 +241,6 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state)
goto cleanup; goto cleanup;
} }
/* Return the remainder */
walk_state->result_obj = return_desc1;
cleanup: cleanup:
/* /*
* Since the remainder is not returned indirectly, remove a reference to * Since the remainder is not returned indirectly, remove a reference to
...@@ -259,6 +255,12 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state) ...@@ -259,6 +255,12 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state)
acpi_ut_remove_reference(return_desc1); acpi_ut_remove_reference(return_desc1);
} }
/* Save return object (the remainder) on success */
else {
walk_state->result_obj = return_desc1;
}
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -490,6 +492,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) ...@@ -490,6 +492,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
acpi_ut_remove_reference(return_desc); acpi_ut_remove_reference(return_desc);
walk_state->result_obj = NULL;
} }
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -583,8 +586,6 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) ...@@ -583,8 +586,6 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state)
return_desc->integer.value = ACPI_INTEGER_MAX; return_desc->integer.value = ACPI_INTEGER_MAX;
} }
walk_state->result_obj = return_desc;
cleanup: cleanup:
/* Delete return object on error */ /* Delete return object on error */
...@@ -593,5 +594,11 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) ...@@ -593,5 +594,11 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state)
acpi_ut_remove_reference(return_desc); acpi_ut_remove_reference(return_desc);
} }
/* Save return object on success */
else {
walk_state->result_obj = return_desc;
}
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -260,6 +260,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) ...@@ -260,6 +260,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
if (ACPI_FAILURE(status) || walk_state->result_obj) { if (ACPI_FAILURE(status) || walk_state->result_obj) {
acpi_ut_remove_reference(return_desc); acpi_ut_remove_reference(return_desc);
walk_state->result_obj = NULL;
} }
/* Set the return object and exit */ /* Set the return object and exit */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -322,8 +322,6 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) ...@@ -322,8 +322,6 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state)
goto cleanup; goto cleanup;
} }
walk_state->result_obj = return_desc;
cleanup: cleanup:
/* Delete return object on error */ /* Delete return object on error */
...@@ -332,5 +330,11 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) ...@@ -332,5 +330,11 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state)
acpi_ut_remove_reference(return_desc); acpi_ut_remove_reference(return_desc);
} }
/* Save return object on success */
else {
walk_state->result_obj = return_desc;
}
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -412,6 +412,7 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, ...@@ -412,6 +412,7 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
{ {
union acpi_operand_object *obj_desc; union acpi_operand_object *obj_desc;
union acpi_operand_object *second_desc = NULL;
u32 type; u32 type;
acpi_status status; acpi_status status;
...@@ -494,6 +495,20 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) ...@@ -494,6 +495,20 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
obj_desc->field.access_byte_width, obj_desc->field.access_byte_width,
obj_desc->bank_field.region_obj, obj_desc->bank_field.region_obj,
obj_desc->bank_field.bank_obj)); obj_desc->bank_field.bank_obj));
/*
* Remember location in AML stream of the field unit
* opcode and operands -- since the bank_value
* operands must be evaluated.
*/
second_desc = obj_desc->common.next_object;
second_desc->extra.aml_start =
((union acpi_parse_object *)(info->data_register_node))->
named.data;
second_desc->extra.aml_length =
((union acpi_parse_object *)(info->data_register_node))->
named.length;
break; break;
case ACPI_TYPE_LOCAL_INDEX_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD:
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -160,7 +160,7 @@ acpi_ex_system_memory_space_handler(u32 function, ...@@ -160,7 +160,7 @@ acpi_ex_system_memory_space_handler(u32 function,
if (!mem_info->mapped_logical_address) { if (!mem_info->mapped_logical_address) {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"Could not map memory at %8.8X%8.8X, size %X", "Could not map memory at %8.8X%8.8X, size %X",
ACPI_FORMAT_UINT64(address), ACPI_FORMAT_NATIVE_UINT(address),
(u32) window_size)); (u32) window_size));
mem_info->mapped_length = 0; mem_info->mapped_length = 0;
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
...@@ -182,7 +182,8 @@ acpi_ex_system_memory_space_handler(u32 function, ...@@ -182,7 +182,8 @@ acpi_ex_system_memory_space_handler(u32 function,
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n",
bit_width, function, ACPI_FORMAT_UINT64(address))); bit_width, function,
ACPI_FORMAT_NATIVE_UINT(address)));
/* /*
* Perform the memory read or write * Perform the memory read or write
...@@ -284,7 +285,8 @@ acpi_ex_system_io_space_handler(u32 function, ...@@ -284,7 +285,8 @@ acpi_ex_system_io_space_handler(u32 function,
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"System-IO (width %d) R/W %d Address=%8.8X%8.8X\n", "System-IO (width %d) R/W %d Address=%8.8X%8.8X\n",
bit_width, function, ACPI_FORMAT_UINT64(address))); bit_width, function,
ACPI_FORMAT_NATIVE_UINT(address)));
/* Decode the function parameter */ /* Decode the function parameter */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -116,9 +116,11 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, ...@@ -116,9 +116,11 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
* Several object types require no further processing: * Several object types require no further processing:
* 1) Device/Thermal objects don't have a "real" subobject, return the Node * 1) Device/Thermal objects don't have a "real" subobject, return the Node
* 2) Method locals and arguments have a pseudo-Node * 2) Method locals and arguments have a pseudo-Node
* 3) 10/2007: Added method type to assist with Package construction.
*/ */
if ((entry_type == ACPI_TYPE_DEVICE) || if ((entry_type == ACPI_TYPE_DEVICE) ||
(entry_type == ACPI_TYPE_THERMAL) || (entry_type == ACPI_TYPE_THERMAL) ||
(entry_type == ACPI_TYPE_METHOD) ||
(node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) { (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
...@@ -214,7 +216,6 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, ...@@ -214,7 +216,6 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
/* For these objects, just return the object attached to the Node */ /* For these objects, just return the object attached to the Node */
case ACPI_TYPE_MUTEX: case ACPI_TYPE_MUTEX:
case ACPI_TYPE_METHOD:
case ACPI_TYPE_POWER: case ACPI_TYPE_POWER:
case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_EVENT: case ACPI_TYPE_EVENT:
...@@ -238,13 +239,12 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, ...@@ -238,13 +239,12 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
case ACPI_TYPE_LOCAL_REFERENCE: case ACPI_TYPE_LOCAL_REFERENCE:
switch (source_desc->reference.opcode) { switch (source_desc->reference.opcode) {
case AML_LOAD_OP: case AML_LOAD_OP: /* This is a ddb_handle */
case AML_REF_OF_OP:
case AML_INDEX_OP:
/* This is a ddb_handle */
/* Return an additional reference to the object */ /* Return an additional reference to the object */
case AML_REF_OF_OP:
obj_desc = source_desc; obj_desc = source_desc;
acpi_ut_add_reference(obj_desc); acpi_ut_add_reference(obj_desc);
break; break;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -140,7 +140,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, ...@@ -140,7 +140,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
union acpi_operand_object *stack_desc; union acpi_operand_object *stack_desc;
void *temp_node;
union acpi_operand_object *obj_desc = NULL; union acpi_operand_object *obj_desc = NULL;
u16 opcode; u16 opcode;
...@@ -156,23 +155,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, ...@@ -156,23 +155,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
opcode = stack_desc->reference.opcode; opcode = stack_desc->reference.opcode;
switch (opcode) { switch (opcode) {
case AML_NAME_OP:
/*
* Convert name reference to a namespace node
* Then, acpi_ex_resolve_node_to_value can be used to get the value
*/
temp_node = stack_desc->reference.object;
/* Delete the Reference Object */
acpi_ut_remove_reference(stack_desc);
/* Return the namespace node */
(*stack_ptr) = temp_node;
break;
case AML_LOCAL_OP: case AML_LOCAL_OP:
case AML_ARG_OP: case AML_ARG_OP:
...@@ -207,15 +189,25 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, ...@@ -207,15 +189,25 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
switch (stack_desc->reference.target_type) { switch (stack_desc->reference.target_type) {
case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_BUFFER_FIELD:
/* Just return - leave the Reference on the stack */ /* Just return - do not dereference */
break; break;
case ACPI_TYPE_PACKAGE: case ACPI_TYPE_PACKAGE:
/* If method call or copy_object - do not dereference */
if ((walk_state->opcode ==
AML_INT_METHODCALL_OP)
|| (walk_state->opcode == AML_COPY_OP)) {
break;
}
/* Otherwise, dereference the package_index to a package element */
obj_desc = *stack_desc->reference.where; obj_desc = *stack_desc->reference.where;
if (obj_desc) { if (obj_desc) {
/* /*
* Valid obj descriptor, copy pointer to return value * Valid object descriptor, copy pointer to return value
* (i.e., dereference the package index) * (i.e., dereference the package index)
* Delete the ref object, increment the returned object * Delete the ref object, increment the returned object
*/ */
...@@ -224,11 +216,11 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, ...@@ -224,11 +216,11 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
*stack_ptr = obj_desc; *stack_ptr = obj_desc;
} else { } else {
/* /*
* A NULL object descriptor means an unitialized element of * A NULL object descriptor means an uninitialized element of
* the package, can't dereference it * the package, can't dereference it
*/ */
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"Attempt to deref an Index to NULL pkg element Idx=%p", "Attempt to dereference an Index to NULL package element Idx=%p",
stack_desc)); stack_desc));
status = AE_AML_UNINITIALIZED_ELEMENT; status = AE_AML_UNINITIALIZED_ELEMENT;
} }
...@@ -239,7 +231,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, ...@@ -239,7 +231,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
/* Invalid reference object */ /* Invalid reference object */
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"Unknown TargetType %X in Index/Reference obj %p", "Unknown TargetType %X in Index/Reference object %p",
stack_desc->reference.target_type, stack_desc->reference.target_type,
stack_desc)); stack_desc));
status = AE_AML_INTERNAL; status = AE_AML_INTERNAL;
...@@ -251,7 +243,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, ...@@ -251,7 +243,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
case AML_DEBUG_OP: case AML_DEBUG_OP:
case AML_LOAD_OP: case AML_LOAD_OP:
/* Just leave the object as-is */ /* Just leave the object as-is, do not dereference */
break; break;
...@@ -390,10 +382,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, ...@@ -390,10 +382,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
} }
/* /*
* For reference objects created via the ref_of or Index operators, * For reference objects created via the ref_of, Index, or Load/load_table
* we need to get to the base object (as per the ACPI specification * operators, we need to get to the base object (as per the ACPI
* of the object_type and size_of operators). This means traversing * specification of the object_type and size_of operators). This means
* the list of possibly many nested references. * traversing the list of possibly many nested references.
*/ */
while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
switch (obj_desc->reference.opcode) { switch (obj_desc->reference.opcode) {
...@@ -463,6 +455,11 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, ...@@ -463,6 +455,11 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
} }
break; break;
case AML_LOAD_OP:
type = ACPI_TYPE_DDB_HANDLE;
goto exit;
case AML_LOCAL_OP: case AML_LOCAL_OP:
case AML_ARG_OP: case AML_ARG_OP:
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -137,7 +137,6 @@ acpi_ex_resolve_operands(u16 opcode, ...@@ -137,7 +137,6 @@ acpi_ex_resolve_operands(u16 opcode,
union acpi_operand_object *obj_desc; union acpi_operand_object *obj_desc;
acpi_status status = AE_OK; acpi_status status = AE_OK;
u8 object_type; u8 object_type;
void *temp_node;
u32 arg_types; u32 arg_types;
const struct acpi_opcode_info *op_info; const struct acpi_opcode_info *op_info;
u32 this_arg_type; u32 this_arg_type;
...@@ -239,7 +238,6 @@ acpi_ex_resolve_operands(u16 opcode, ...@@ -239,7 +238,6 @@ acpi_ex_resolve_operands(u16 opcode,
/*lint -fallthrough */ /*lint -fallthrough */
case AML_NAME_OP:
case AML_INDEX_OP: case AML_INDEX_OP:
case AML_REF_OF_OP: case AML_REF_OF_OP:
case AML_ARG_OP: case AML_ARG_OP:
...@@ -332,15 +330,6 @@ acpi_ex_resolve_operands(u16 opcode, ...@@ -332,15 +330,6 @@ acpi_ex_resolve_operands(u16 opcode,
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
if (obj_desc->reference.opcode == AML_NAME_OP) {
/* Convert a named reference to the actual named object */
temp_node = obj_desc->reference.object;
acpi_ut_remove_reference(obj_desc);
(*stack_ptr) = temp_node;
}
goto next_operand; goto next_operand;
case ARGI_DATAREFOBJ: /* Store operator only */ case ARGI_DATAREFOBJ: /* Store operator only */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -84,8 +84,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, ...@@ -84,8 +84,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc); ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc);
ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s", /* Print line header as long as we are not in the middle of an object display */
level, " "));
if (!((level > 0) && index == 0)) {
ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
level, " "));
}
/* Display index for package output only */ /* Display index for package output only */
...@@ -95,12 +99,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, ...@@ -95,12 +99,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
} }
if (!source_desc) { if (!source_desc) {
ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "<Null Object>\n")); ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[Null Object]\n"));
return_VOID; return_VOID;
} }
if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) { if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) {
ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s: ", ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s ",
acpi_ut_get_object_type_name acpi_ut_get_object_type_name
(source_desc))); (source_desc)));
...@@ -123,6 +127,8 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, ...@@ -123,6 +127,8 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
return_VOID; return_VOID;
} }
/* source_desc is of type ACPI_DESC_TYPE_OPERAND */
switch (ACPI_GET_OBJECT_TYPE(source_desc)) { switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
case ACPI_TYPE_INTEGER: case ACPI_TYPE_INTEGER:
...@@ -147,7 +153,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, ...@@ -147,7 +153,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
(u32) source_desc->buffer.length)); (u32) source_desc->buffer.length));
ACPI_DUMP_BUFFER(source_desc->buffer.pointer, ACPI_DUMP_BUFFER(source_desc->buffer.pointer,
(source_desc->buffer.length < (source_desc->buffer.length <
32) ? source_desc->buffer.length : 32); 256) ? source_desc->buffer.length : 256);
break; break;
case ACPI_TYPE_STRING: case ACPI_TYPE_STRING:
...@@ -160,7 +166,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, ...@@ -160,7 +166,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
case ACPI_TYPE_PACKAGE: case ACPI_TYPE_PACKAGE:
ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
"[0x%.2X Elements]\n", "[Contains 0x%.2X Elements]\n",
source_desc->package.count)); source_desc->package.count));
/* Output the entire contents of the package */ /* Output the entire contents of the package */
...@@ -180,12 +186,59 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, ...@@ -180,12 +186,59 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
(source_desc->reference.opcode), (source_desc->reference.opcode),
source_desc->reference.offset)); source_desc->reference.offset));
} else { } else {
ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]\n", ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]",
acpi_ps_get_opcode_name acpi_ps_get_opcode_name
(source_desc->reference.opcode))); (source_desc->reference.opcode)));
} }
if (source_desc->reference.object) { if (source_desc->reference.opcode == AML_LOAD_OP) { /* Load and load_table */
ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
" Table OwnerId %p\n",
source_desc->reference.object));
break;
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, " "));
/* Check for valid node first, then valid object */
if (source_desc->reference.node) {
if (ACPI_GET_DESCRIPTOR_TYPE
(source_desc->reference.node) !=
ACPI_DESC_TYPE_NAMED) {
ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
" %p - Not a valid namespace node\n",
source_desc->reference.
node));
} else {
ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
"Node %p [%4.4s] ",
source_desc->reference.
node,
(source_desc->reference.
node)->name.ascii));
switch ((source_desc->reference.node)->type) {
/* These types have no attached object */
case ACPI_TYPE_DEVICE:
acpi_os_printf("Device\n");
break;
case ACPI_TYPE_THERMAL:
acpi_os_printf("Thermal Zone\n");
break;
default:
acpi_ex_do_debug_object((source_desc->
reference.
node)->object,
level + 4, 0);
break;
}
}
} else if (source_desc->reference.object) {
if (ACPI_GET_DESCRIPTOR_TYPE if (ACPI_GET_DESCRIPTOR_TYPE
(source_desc->reference.object) == (source_desc->reference.object) ==
ACPI_DESC_TYPE_NAMED) { ACPI_DESC_TYPE_NAMED) {
...@@ -198,18 +251,13 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, ...@@ -198,18 +251,13 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
acpi_ex_do_debug_object(source_desc->reference. acpi_ex_do_debug_object(source_desc->reference.
object, level + 4, 0); object, level + 4, 0);
} }
} else if (source_desc->reference.node) {
acpi_ex_do_debug_object((source_desc->reference.node)->
object, level + 4, 0);
} }
break; break;
default: default:
ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p %s\n", ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p\n",
source_desc, source_desc));
acpi_ut_get_object_type_name
(source_desc)));
break; break;
} }
...@@ -313,7 +361,6 @@ acpi_ex_store(union acpi_operand_object *source_desc, ...@@ -313,7 +361,6 @@ acpi_ex_store(union acpi_operand_object *source_desc,
* 4) Store to the debug object * 4) Store to the debug object
*/ */
switch (ref_desc->reference.opcode) { switch (ref_desc->reference.opcode) {
case AML_NAME_OP:
case AML_REF_OF_OP: case AML_REF_OF_OP:
/* Storing an object into a Name "container" */ /* Storing an object into a Name "container" */
...@@ -415,11 +462,24 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, ...@@ -415,11 +462,24 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
*/ */
obj_desc = *(index_desc->reference.where); obj_desc = *(index_desc->reference.where);
status = if (ACPI_GET_OBJECT_TYPE(source_desc) ==
acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, ACPI_TYPE_LOCAL_REFERENCE
walk_state); && source_desc->reference.opcode == AML_LOAD_OP) {
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); /* This is a DDBHandle, just add a reference to it */
acpi_ut_add_reference(source_desc);
new_desc = source_desc;
} else {
/* Normal object, copy it */
status =
acpi_ut_copy_iobject_to_iobject(source_desc,
&new_desc,
walk_state);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
} }
if (obj_desc) { if (obj_desc) {
...@@ -571,10 +631,17 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, ...@@ -571,10 +631,17 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
/* If no implicit conversion, drop into the default case below */ /* If no implicit conversion, drop into the default case below */
if ((!implicit_conversion) || (walk_state->opcode == AML_COPY_OP)) { if ((!implicit_conversion) ||
((walk_state->opcode == AML_COPY_OP) &&
/* Force execution of default (no implicit conversion) */ (target_type != ACPI_TYPE_LOCAL_REGION_FIELD) &&
(target_type != ACPI_TYPE_LOCAL_BANK_FIELD) &&
(target_type != ACPI_TYPE_LOCAL_INDEX_FIELD))) {
/*
* Force execution of default (no implicit conversion). Note:
* copy_object does not perform an implicit conversion, as per the ACPI
* spec -- except in case of region/bank/index fields -- because these
* objects must retain their original type permanently.
*/
target_type = ACPI_TYPE_ANY; target_type = ACPI_TYPE_ANY;
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -44,7 +44,6 @@ ...@@ -44,7 +44,6 @@
#include <acpi/acpi.h> #include <acpi/acpi.h>
#include <acpi/acinterp.h> #include <acpi/acinterp.h>
#include <acpi/acevents.h>
#define _COMPONENT ACPI_EXECUTER #define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME("exsystem") ACPI_MODULE_NAME("exsystem")
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -61,7 +61,6 @@ ...@@ -61,7 +61,6 @@
#include <acpi/acpi.h> #include <acpi/acpi.h>
#include <acpi/acinterp.h> #include <acpi/acinterp.h>
#include <acpi/amlcode.h> #include <acpi/amlcode.h>
#include <acpi/acevents.h>
#define _COMPONENT ACPI_EXECUTER #define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME("exutils") ACPI_MODULE_NAME("exutils")
...@@ -217,9 +216,10 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc) ...@@ -217,9 +216,10 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
/* /*
* Object must be a valid number and we must be executing * Object must be a valid number and we must be executing
* a control method * a control method. NS node could be there for AML_INT_NAMEPATH_OP.
*/ */
if ((!obj_desc) || if ((!obj_desc) ||
(ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
(ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) { (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
return; return;
} }
...@@ -240,72 +240,73 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc) ...@@ -240,72 +240,73 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
* PARAMETERS: field_flags - Flags with Lock rule: * PARAMETERS: field_flags - Flags with Lock rule:
* always_lock or never_lock * always_lock or never_lock
* *
* RETURN: TRUE/FALSE indicating whether the lock was actually acquired * RETURN: None
* *
* DESCRIPTION: Obtain the global lock and keep track of this fact via two * DESCRIPTION: Obtain the ACPI hardware Global Lock, only if the field
* methods. A global variable keeps the state of the lock, and * flags specifiy that it is to be obtained before field access.
* the state is returned to the caller.
* *
******************************************************************************/ ******************************************************************************/
u8 acpi_ex_acquire_global_lock(u32 field_flags) void acpi_ex_acquire_global_lock(u32 field_flags)
{ {
u8 locked = FALSE;
acpi_status status; acpi_status status;
ACPI_FUNCTION_TRACE(ex_acquire_global_lock); ACPI_FUNCTION_TRACE(ex_acquire_global_lock);
/* Only attempt lock if the always_lock bit is set */ /* Only use the lock if the always_lock bit is set */
if (!(field_flags & AML_FIELD_LOCK_RULE_MASK)) {
return_VOID;
}
if (field_flags & AML_FIELD_LOCK_RULE_MASK) { /* Attempt to get the global lock, wait forever */
/* We should attempt to get the lock, wait forever */ status = acpi_ex_acquire_mutex_object(ACPI_WAIT_FOREVER,
acpi_gbl_global_lock_mutex,
acpi_os_get_thread_id());
status = acpi_ev_acquire_global_lock(ACPI_WAIT_FOREVER); if (ACPI_FAILURE(status)) {
if (ACPI_SUCCESS(status)) { ACPI_EXCEPTION((AE_INFO, status,
locked = TRUE; "Could not acquire Global Lock"));
} else {
ACPI_EXCEPTION((AE_INFO, status,
"Could not acquire Global Lock"));
}
} }
return_UINT8(locked); return_VOID;
} }
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ex_release_global_lock * FUNCTION: acpi_ex_release_global_lock
* *
* PARAMETERS: locked_by_me - Return value from corresponding call to * PARAMETERS: field_flags - Flags with Lock rule:
* acquire_global_lock. * always_lock or never_lock
* *
* RETURN: None * RETURN: None
* *
* DESCRIPTION: Release the global lock if it is locked. * DESCRIPTION: Release the ACPI hardware Global Lock
* *
******************************************************************************/ ******************************************************************************/
void acpi_ex_release_global_lock(u8 locked_by_me) void acpi_ex_release_global_lock(u32 field_flags)
{ {
acpi_status status; acpi_status status;
ACPI_FUNCTION_TRACE(ex_release_global_lock); ACPI_FUNCTION_TRACE(ex_release_global_lock);
/* Only attempt unlock if the caller locked it */ /* Only use the lock if the always_lock bit is set */
if (locked_by_me) { if (!(field_flags & AML_FIELD_LOCK_RULE_MASK)) {
return_VOID;
}
/* OK, now release the lock */ /* Release the global lock */
status = acpi_ev_release_global_lock(); status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
/* Report the error, but there isn't much else we can do */ /* Report the error, but there isn't much else we can do */
ACPI_EXCEPTION((AE_INFO, status, ACPI_EXCEPTION((AE_INFO, status,
"Could not release ACPI Global Lock")); "Could not release Global Lock"));
}
} }
return_VOID; return_VOID;
......
This diff is collapsed.
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
******************************************************************************/ ******************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* Copyright (C) 2000 - 2007, R. Byron Moore * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment