]> nv-tegra.nvidia Code Review - linux-2.6.git/commitdiff
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 30 Apr 2008 18:52:52 +0000 (11:52 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 30 Apr 2008 18:52:52 +0000 (11:52 -0700)
* '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.

196 files changed:
Documentation/laptops/thinkpad-acpi.txt
Documentation/thermal/sysfs-api.txt
MAINTAINERS
arch/frv/kernel/pm.c
arch/mips/au1000/common/power.c
arch/x86/kernel/apm_32.c
drivers/acpi/Kconfig
drivers/acpi/bay.c
drivers/acpi/dispatcher/dsfield.c
drivers/acpi/dispatcher/dsinit.c
drivers/acpi/dispatcher/dsmethod.c
drivers/acpi/dispatcher/dsmthdat.c
drivers/acpi/dispatcher/dsobject.c
drivers/acpi/dispatcher/dsopcode.c
drivers/acpi/dispatcher/dsutils.c
drivers/acpi/dispatcher/dswexec.c
drivers/acpi/dispatcher/dswload.c
drivers/acpi/dispatcher/dswscope.c
drivers/acpi/dispatcher/dswstate.c
drivers/acpi/ec.c
drivers/acpi/events/evevent.c
drivers/acpi/events/evgpe.c
drivers/acpi/events/evgpeblk.c
drivers/acpi/events/evmisc.c
drivers/acpi/events/evregion.c
drivers/acpi/events/evrgnini.c
drivers/acpi/events/evsci.c
drivers/acpi/events/evxface.c
drivers/acpi/events/evxfevnt.c
drivers/acpi/events/evxfregn.c
drivers/acpi/executer/exconfig.c
drivers/acpi/executer/exconvrt.c
drivers/acpi/executer/excreate.c
drivers/acpi/executer/exdump.c
drivers/acpi/executer/exfield.c
drivers/acpi/executer/exfldio.c
drivers/acpi/executer/exmisc.c
drivers/acpi/executer/exmutex.c
drivers/acpi/executer/exnames.c
drivers/acpi/executer/exoparg1.c
drivers/acpi/executer/exoparg2.c
drivers/acpi/executer/exoparg3.c
drivers/acpi/executer/exoparg6.c
drivers/acpi/executer/exprep.c
drivers/acpi/executer/exregion.c
drivers/acpi/executer/exresnte.c
drivers/acpi/executer/exresolv.c
drivers/acpi/executer/exresop.c
drivers/acpi/executer/exstore.c
drivers/acpi/executer/exstoren.c
drivers/acpi/executer/exstorob.c
drivers/acpi/executer/exsystem.c
drivers/acpi/executer/exutils.c
drivers/acpi/fan.c
drivers/acpi/glue.c
drivers/acpi/hardware/hwacpi.c
drivers/acpi/hardware/hwgpe.c
drivers/acpi/hardware/hwregs.c
drivers/acpi/hardware/hwsleep.c
drivers/acpi/hardware/hwtimer.c
drivers/acpi/namespace/nsaccess.c
drivers/acpi/namespace/nsalloc.c
drivers/acpi/namespace/nsdump.c
drivers/acpi/namespace/nsdumpdv.c
drivers/acpi/namespace/nseval.c
drivers/acpi/namespace/nsinit.c
drivers/acpi/namespace/nsload.c
drivers/acpi/namespace/nsnames.c
drivers/acpi/namespace/nsobject.c
drivers/acpi/namespace/nsparse.c
drivers/acpi/namespace/nssearch.c
drivers/acpi/namespace/nsutils.c
drivers/acpi/namespace/nswalk.c
drivers/acpi/namespace/nsxfeval.c
drivers/acpi/namespace/nsxfname.c
drivers/acpi/namespace/nsxfobj.c
drivers/acpi/osl.c
drivers/acpi/parser/psargs.c
drivers/acpi/parser/psloop.c
drivers/acpi/parser/psopcode.c
drivers/acpi/parser/psparse.c
drivers/acpi/parser/psscope.c
drivers/acpi/parser/pstree.c
drivers/acpi/parser/psutils.c
drivers/acpi/parser/pswalk.c
drivers/acpi/parser/psxface.c
drivers/acpi/power.c
drivers/acpi/processor_core.c
drivers/acpi/processor_idle.c
drivers/acpi/resources/rsaddr.c
drivers/acpi/resources/rscalc.c
drivers/acpi/resources/rscreate.c
drivers/acpi/resources/rsdump.c
drivers/acpi/resources/rsinfo.c
drivers/acpi/resources/rsio.c
drivers/acpi/resources/rsirq.c
drivers/acpi/resources/rslist.c
drivers/acpi/resources/rsmemory.c
drivers/acpi/resources/rsmisc.c
drivers/acpi/resources/rsutils.c
drivers/acpi/resources/rsxface.c
drivers/acpi/scan.c
drivers/acpi/sleep/main.c
drivers/acpi/tables/tbfadt.c
drivers/acpi/tables/tbfind.c
drivers/acpi/tables/tbinstal.c
drivers/acpi/tables/tbutils.c
drivers/acpi/tables/tbxface.c
drivers/acpi/tables/tbxfroot.c
drivers/acpi/thermal.c
drivers/acpi/utilities/utalloc.c
drivers/acpi/utilities/utcache.c
drivers/acpi/utilities/utcopy.c
drivers/acpi/utilities/utdebug.c
drivers/acpi/utilities/utdelete.c
drivers/acpi/utilities/uteval.c
drivers/acpi/utilities/utglobal.c
drivers/acpi/utilities/utinit.c
drivers/acpi/utilities/utmath.c
drivers/acpi/utilities/utmisc.c
drivers/acpi/utilities/utmutex.c
drivers/acpi/utilities/utobject.c
drivers/acpi/utilities/utresrc.c
drivers/acpi/utilities/utstate.c
drivers/acpi/utilities/utxface.c
drivers/acpi/utils.c
drivers/acpi/video.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/eeepc-laptop.c [new file with mode: 0644]
drivers/misc/thinkpad_acpi.c
drivers/pnp/base.h
drivers/pnp/card.c
drivers/pnp/core.c
drivers/pnp/driver.c
drivers/pnp/interface.c
drivers/pnp/isapnp/Makefile
drivers/pnp/isapnp/core.c
drivers/pnp/manager.c
drivers/pnp/pnpacpi/Makefile
drivers/pnp/pnpacpi/core.c
drivers/pnp/pnpacpi/pnpacpi.h
drivers/pnp/pnpacpi/rsparser.c
drivers/pnp/pnpbios/Makefile
drivers/pnp/pnpbios/bioscalls.c
drivers/pnp/pnpbios/core.c
drivers/pnp/pnpbios/pnpbios.h
drivers/pnp/pnpbios/proc.c
drivers/pnp/pnpbios/rsparser.c
drivers/pnp/quirks.c
drivers/pnp/resource.c
drivers/pnp/support.c
drivers/pnp/system.c
drivers/rtc/rtc-cmos.c
drivers/thermal/Kconfig
drivers/thermal/Makefile
drivers/thermal/thermal_sys.c [moved from drivers/thermal/thermal.c with 81% similarity]
include/acpi/acconfig.h
include/acpi/acdebug.h
include/acpi/acdisasm.h
include/acpi/acdispat.h
include/acpi/acevents.h
include/acpi/acexcep.h
include/acpi/acglobal.h
include/acpi/achware.h
include/acpi/acinterp.h
include/acpi/aclocal.h
include/acpi/acmacros.h
include/acpi/acnames.h
include/acpi/acnamesp.h
include/acpi/acobject.h
include/acpi/acopcode.h
include/acpi/acoutput.h
include/acpi/acparser.h
include/acpi/acpi.h
include/acpi/acpiosxf.h
include/acpi/acpixf.h
include/acpi/acresrc.h
include/acpi/acstruct.h
include/acpi/actables.h
include/acpi/actbl.h
include/acpi/actbl1.h
include/acpi/actypes.h
include/acpi/acutils.h
include/acpi/amlcode.h
include/acpi/amlresrc.h
include/acpi/platform/acenv.h
include/acpi/platform/acgcc.h
include/acpi/platform/aclinux.h
include/linux/isapnp.h
include/linux/pnp.h
include/linux/pnpbios.h [deleted file]
include/linux/thermal.h
kernel/power/Kconfig
kernel/power/Makefile
kernel/power/pm.c [deleted file]

index 76cb428435daf4c1dfe9d611fd6a155483e447a2..01c6c3d8a7e3fe61ee007182b9c45841e6857973 100644 (file)
@@ -1,7 +1,7 @@
                     ThinkPad ACPI Extras Driver
 
-                            Version 0.19
-                         January 06th, 2008
+                            Version 0.20
+                          April 09th, 2008
 
                Borislav Deianov <borislav@users.sf.net>
              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
 moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel
 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
 ------
@@ -571,6 +576,47 @@ netlink interface and the input layer interface, and don't bother at all
 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
 ---------
 
@@ -647,16 +693,31 @@ while others are still having problems. For more information:
 
 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
-models which do not make the status available will show it as
-"unknown". The available commands are:
+procfs notes:
+
+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 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
 ------------------------------------------
 
@@ -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
 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
-available commands are:
+procfs notes:
+
+The available commands are:
 
-       echo '<led number> on' >/proc/acpi/ibm/led
-       echo '<led number> off' >/proc/acpi/ibm/led
-       echo '<led number> blink' >/proc/acpi/ibm/led
+       echo '<LED number> on' >/proc/acpi/ibm/led
+       echo '<LED number> off' >/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
-controlled varies from model to model. Here is the mapping on the X40:
+The <LED number> range is 0 to 7. The set of LEDs that can be
+controlled varies from model to model. Here is the common ThinkPad
+mapping:
 
        0 - power
        1 - battery (orange)
        2 - battery (green)
-       3 - UltraBase
+       3 - UltraBase/dock
        4 - UltraBay
+       5 - UltraBase battery slot
+       6 - (unknown)
        7 - standby
 
 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
 ----------------------------------
 
@@ -1090,6 +1186,15 @@ it there will be the following attributes:
                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
 ---------------------------------------
 
index d9f28be75403cea53c07cfe8e965074a71037619..70d68ce8640a0f1490f3e126f6526ab58a62a581 100644 (file)
@@ -108,10 +108,12 @@ and throttle appropriate devices.
 RO     read only 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[0-*]:
+/sys/class/thermal/thermal_zone[0-*]:
        |-----type:                     Type of the thermal zone
        |-----temp:                     Current temperature
        |-----mode:                     Working mode of the thermal zone
@@ -119,7 +121,7 @@ Thermal zone device sys I/F, created once it's registered:
        |-----trip_point_[0-*]_type:    Trip point type
 
 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/...)
        |-----max_state:                Maximum 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
 They are created/removed for each
 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-*]_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 *
@@ -141,7 +152,10 @@ thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device successful e
 
 type                           Strings which represent the thermal zone type.
                                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
                                Required
 
@@ -218,7 +232,7 @@ the sys I/F structure will be built like this:
 /sys/class/thermal:
 
 |thermal_zone1:
-       |-----type:                     ACPI thermal zone
+       |-----type:                     acpitz
        |-----temp:                     37000
        |-----mode:                     kernel
        |-----trip_point_0_temp:        100000
@@ -243,3 +257,10 @@ the sys I/F structure will be built like this:
        |-----type:                     Fan
        |-----max_state:                2
        |-----cur_state:                0
+
+/sys/class/hwmon:
+
+|hwmon0:
+       |-----name:                     acpitz
+       |-----temp1_input:              37000
+       |-----temp1_crit:               100000
index f8d6de111479dad7fc91561bba6ae22298b1f64a..c3a533d5d3824ce0bd7d4c78e1a5d5a6824e1078 100644 (file)
@@ -1533,6 +1533,13 @@ L:       bluesmoke-devel@lists.sourceforge.net
 W:     bluesmoke.sourceforge.net
 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
 P:     Andrey V. Savochkin
 M:     saw@saw.sw.com.sg
index c57ce3f1f2e281b2c38a7de860d390cbc08e5fd0..73f3aeefd2034ac0b0f35d8268ad7adac631d314 100644 (file)
@@ -163,14 +163,11 @@ static int sysctl_pm_do_suspend(ctl_table *ctl, int write, struct file *filp,
        if ((mode != 1) && (mode != 5))
                return -EINVAL;
 
-       retval = pm_send_all(PM_SUSPEND, (void *)3);
-
        if (retval == 0) {
                if (mode == 5)
                    retval = pm_do_bus_sleep();
                else
                    retval = pm_do_suspend();
-               pm_send_all(PM_RESUME, (void *)0);
        }
 
        return retval;
@@ -183,9 +180,6 @@ static int try_set_cmode(int new_cmode)
        if (!(clock_cmodes_permitted & (1<<new_cmode)))
                return -EINVAL;
 
-       /* tell all the drivers we're suspending */
-       pm_send_all(PM_SUSPEND, (void *)3);
-
        /* now change cmode */
        local_irq_disable();
        frv_dma_pause_all();
@@ -201,8 +195,6 @@ static int try_set_cmode(int new_cmode)
        frv_dma_resume_all();
        local_irq_enable();
 
-       /* tell all the drivers we're resuming */
-       pm_send_all(PM_RESUME, (void *)0);
        return 0;
 }
 
index 812a5f8b7d2672ac4cab47eaa4583653d44b7da9..a8cd2c1b9e1b59f313ae98a0c6e8579e0afc6dca 100644 (file)
@@ -251,7 +251,6 @@ int au_sleep(void)
 static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
                       void __user *buffer, size_t * len, loff_t *ppos)
 {
-       int retval = 0;
 #ifdef SLEEP_TEST_TIMEOUT
 #define TMPBUFLEN2 16
        char buf[TMPBUFLEN2], *p;
@@ -271,36 +270,12 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
                p = buf;
                sleep_ticks = simple_strtoul(p, &p, 0);
 #endif
-               retval = pm_send_all(PM_SUSPEND, (void *) 2);
-
-               if (retval)
-                       return retval;
 
                au_sleep();
-               retval = pm_send_all(PM_RESUME, (void *) 0);
        }
-       return retval;
-}
-
-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;
+       return 0;
 }
 
-
 static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
                      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,
 
 
 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,
                .procname       = "sleep",
index e4ea362e84800a6c28bf8056ec340aff5fea4bad..bf9290e290136a36d6006d032c1ca4fe392f84bd 100644 (file)
@@ -1192,19 +1192,6 @@ static int suspend(int vetoable)
        int err;
        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);
        local_irq_disable();
        device_power_down(PMSG_SUSPEND);
@@ -1227,9 +1214,7 @@ static int suspend(int vetoable)
        device_power_up();
        local_irq_enable();
        device_resume();
-       pm_send_all(PM_RESUME, (void *)0);
        queue_event(APM_NORMAL_RESUME, NULL);
- out:
        spin_lock(&user_list_lock);
        for (as = user_list; as != NULL; as = as->next) {
                as->suspend_wait = 0;
@@ -1340,7 +1325,6 @@ static void check_events(void)
                        if ((event != APM_NORMAL_RESUME)
                            || (ignore_normal_resume == 0)) {
                                device_resume();
-                               pm_send_all(PM_RESUME, (void *)0);
                                queue_event(event, NULL);
                        }
                        ignore_normal_resume = 0;
index b4f5e85428294eed21bb8f342af5a7a7c3fac87b..c52fca833268c7f1eaf53c091fa2f41e49d5d4a0 100644 (file)
@@ -140,6 +140,7 @@ config ACPI_VIDEO
        tristate "Video"
        depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
        depends on INPUT
+       select THERMAL
        help
          This driver implement the ACPI Extensions For Display Adapters
          for integrated graphics devices on motherboard, as specified in
@@ -151,6 +152,7 @@ config ACPI_VIDEO
 
 config ACPI_FAN
        tristate "Fan"
+       select THERMAL
        default y
        help
          This driver adds support for ACPI fan devices, allowing user-mode 
@@ -172,6 +174,7 @@ config ACPI_BAY
 
 config ACPI_PROCESSOR
        tristate "Processor"
+       select THERMAL
        default y
        help
          This driver installs ACPI as the idle handler for Linux, and uses
index 1fa86811b8ee6ee8e5e675666fc1092f0b4c6eb5..d2fc94161848ff91e424b08df40f5a0d9643aafe 100644 (file)
@@ -201,6 +201,7 @@ static int is_ejectable_bay(acpi_handle handle)
        return 0;
 }
 
+#if 0
 /**
  * eject_removable_drive - try to eject this drive
  * @dev : the device structure of the drive
@@ -225,6 +226,7 @@ int eject_removable_drive(struct device *dev)
        return 0;
 }
 EXPORT_SYMBOL_GPL(eject_removable_drive);
+#endif  /*  0  */
 
 static int acpi_bay_add_fs(struct bay *bay)
 {
index f049639bac355db3e6996505037624d0e742e92b..c78078315be9f707c8adc3b88184e4c70c5a097e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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,
 
        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) {
+
+               /* For create_field, name is the 4th argument */
+
                arg = acpi_ps_get_arg(op, 3);
        } 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);
        }
@@ -107,26 +111,30 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
                node = walk_state->deferred_node;
                status = AE_OK;
        } else {
-               /*
-                * 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
-                * operand), we want to lookup the name
-                */
-               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;
+               /* Execute flag should always be set when this function is entered */
+
+               if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
+                       return_ACPI_STATUS(AE_AML_INTERNAL);
                }
 
-               /*
-                * Enter the name_string into the namespace
-                */
+               /* Creating new namespace node, should not already exist */
+
+               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 =
                    acpi_ns_lookup(walk_state->scope_info,
                                   arg->common.value.string, ACPI_TYPE_ANY,
                                   ACPI_IMODE_LOAD_PASS1, flags, walk_state,
-                                  &(node));
+                                  &node);
                if (ACPI_FAILURE(status)) {
                        ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
                        return_ACPI_STATUS(status);
@@ -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,
         * 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;
 
        /*
         * 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.
         */
        obj_desc = acpi_ns_get_attached_object(node);
@@ -164,9 +172,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
        }
 
        /*
-        * Remember location in AML stream of the field unit
-        * opcode and operands -- since the buffer and index
-        * operands must be evaluated.
+        * Remember location in AML stream of the field unit opcode and operands --
+        * since the buffer and index operands must be evaluated.
         */
        second_desc = obj_desc->common.next_object;
        second_desc->extra.aml_start = op->named.data;
@@ -261,7 +268,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
 
                case AML_INT_NAMEDFIELD_OP:
 
-                       /* Lookup the name */
+                       /* Lookup the name, it should already exist */
 
                        status = acpi_ns_lookup(walk_state->scope_info,
                                                (char *)&arg->named.name,
@@ -272,20 +279,23 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
                        if (ACPI_FAILURE(status)) {
                                ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
                                                     status);
-                               if (status != AE_ALREADY_EXISTS) {
-                                       return_ACPI_STATUS(status);
-                               }
-
-                               /* Already exists, ignore error */
+                               return_ACPI_STATUS(status);
                        } else {
                                arg->common.node = info->field_node;
                                info->field_bit_length = arg->common.value.size;
 
-                               /* Create and initialize an object for the new Field Node */
-
-                               status = acpi_ex_prep_field_value(info);
-                               if (ACPI_FAILURE(status)) {
-                                       return_ACPI_STATUS(status);
+                               /*
+                                * 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 of an existing node and we
+                                * 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,
        union acpi_parse_object *arg = NULL;
        struct acpi_namespace_node *node;
        u8 type = 0;
+       u32 flags;
 
        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) {
        case AML_FIELD_OP:
                arg = acpi_ps_get_arg(op, 2);
@@ -422,20 +450,33 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
                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
         */
        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) {
                        status = acpi_ns_lookup(walk_state->scope_info,
-                                               (char *)&arg->named.name,
-                                               type, ACPI_IMODE_LOAD_PASS1,
-                                               ACPI_NS_NO_UPSEARCH |
-                                               ACPI_NS_DONT_OPEN_SCOPE |
-                                               ACPI_NS_ERROR_IF_FOUND,
+                                               (char *)&arg->named.name, type,
+                                               ACPI_IMODE_LOAD_PASS1, flags,
                                                walk_state, &node);
                        if (ACPI_FAILURE(status)) {
                                ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
@@ -452,7 +493,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
                        arg->common.node = node;
                }
 
-               /* Move to next field in the list */
+               /* Get the next field element in the list */
 
                arg = arg->common.next;
        }
@@ -466,7 +507,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
  *
  * PARAMETERS:  Op              - Op containing the Field definition and args
  *              region_node     - Object for the containing Operation Region
- *  `           walk_state      - Current method state
+ *              walk_state      - Current method state
  *
  * RETURN:      Status
  *
@@ -513,36 +554,13 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
                return_ACPI_STATUS(status);
        }
 
-       /* Third arg is the bank_value */
-
-       /* TBD: This arg is a term_arg, not a constant, and must be evaluated */
-
+       /*
+        * Third arg is the bank_value
+        * 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;
 
-       /* 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 */
 
        arg = arg->common.next;
@@ -553,8 +571,17 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
        info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
        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);
 }
 
index af923c3885205ef70c7313aee98611a9c3b7656c..610b1ee102b02c9b9e3bdb6f3a5fea8599a7cb1b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 1cbe6190582494ed9f3557c58a17b659644f4979..e48a3ea03117ab3cdc7cc993ebbcb6dd019889e4 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,6 @@
  */
 
 #include <acpi/acpi.h>
-#include <acpi/acparser.h>
 #include <acpi/amlcode.h>
 #include <acpi/acdispat.h>
 #include <acpi/acinterp.h>
@@ -102,7 +101,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state)
                                                    walk_state->opcode,
                                                    walk_state->aml_offset,
                                                    NULL);
-               (void)acpi_ex_enter_interpreter();
+               acpi_ex_enter_interpreter();
        }
 #ifdef ACPI_DISASSEMBLER
        if (ACPI_FAILURE(status)) {
@@ -232,9 +231,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
                 * recursive call.
                 */
                if (!walk_state ||
-                   !obj_desc->method.mutex->mutex.owner_thread ||
-                   (walk_state->thread !=
-                    obj_desc->method.mutex->mutex.owner_thread)) {
+                   !obj_desc->method.mutex->mutex.thread_id ||
+                   (walk_state->thread->thread_id !=
+                    obj_desc->method.mutex->mutex.thread_id)) {
                        /*
                         * Acquire the method mutex. This releases the interpreter if we
                         * block (and reacquires it before it returns)
@@ -254,8 +253,8 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
                                    original_sync_level =
                                    walk_state->thread->current_sync_level;
 
-                               obj_desc->method.mutex->mutex.owner_thread =
-                                   walk_state->thread;
+                               obj_desc->method.mutex->mutex.thread_id =
+                                   walk_state->thread->thread_id;
                                walk_state->thread->current_sync_level =
                                    obj_desc->method.sync_level;
                        } else {
@@ -535,8 +534,6 @@ void
 acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
                                 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);
 
@@ -551,34 +548,26 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
                /* Delete all arguments and locals */
 
                acpi_ds_method_data_delete_all(walk_state);
-       }
 
-       /*
-        * If method is serialized, release the mutex and restore the
-        * current sync level for this thread
-        */
-       if (method_desc->method.mutex) {
+               /*
+                * If method is serialized, release the mutex and restore the
+                * current sync level for this thread
+                */
+               if (method_desc->method.mutex) {
 
-               /* Acquisition Depth handles recursive calls */
+                       /* Acquisition Depth handles recursive calls */
 
-               method_desc->method.mutex->mutex.acquisition_depth--;
-               if (!method_desc->method.mutex->mutex.acquisition_depth) {
-                       walk_state->thread->current_sync_level =
-                           method_desc->method.mutex->mutex.
-                           original_sync_level;
+                       method_desc->method.mutex->mutex.acquisition_depth--;
+                       if (!method_desc->method.mutex->mutex.acquisition_depth) {
+                               walk_state->thread->current_sync_level =
+                                   method_desc->method.mutex->mutex.
+                                   original_sync_level;
 
-                       acpi_os_release_mutex(method_desc->method.mutex->mutex.
-                                             os_mutex);
-                       method_desc->method.mutex->mutex.owner_thread = NULL;
+                               acpi_os_release_mutex(method_desc->method.
+                                                     mutex->mutex.os_mutex);
+                               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
@@ -620,7 +609,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
                 */
                if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED)
                    && (!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 */
index ba4626e06a5e816867a9e1a114a3edb485de1fa9..13c43eac35dba9570b0dc2ad8bf9a0c866a2d312 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 954ac8ce958a63c55a6740a4dcc1bbab5e4071bc..1022e38994c2bffcdd8a52d676e9ecf951cc49f7 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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,
                         * will remain as named references. This behavior is not described
                         * 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 =
                            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,
                        switch (op->common.node->type) {
                                /*
                                 * 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_METHOD:
@@ -180,25 +194,15 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
                        case ACPI_TYPE_PROCESSOR:
                        case ACPI_TYPE_EVENT:
                        case ACPI_TYPE_REGION:
-                       case ACPI_TYPE_DEVICE:
-                       case ACPI_TYPE_THERMAL:
 
-                               obj_desc =
-                                   (union acpi_operand_object *)op->common.
-                                   node;
+                               /* We will create a reference object for these types below */
                                break;
 
                        default:
-                               break;
-                       }
-
-                       /*
-                        * 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) {
+                               /*
+                                * All other types - the node was resolved to an actual
+                                * object, we are done.
+                                */
                                goto exit;
                        }
                }
@@ -223,7 +227,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
 
       exit:
        *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,
        union acpi_parse_object *parent;
        union acpi_operand_object *obj_desc = NULL;
        acpi_status status = AE_OK;
-       acpi_native_uint i;
+       unsigned i;
+       u16 index;
+       u16 reference_count;
 
        ACPI_FUNCTION_TRACE(ds_build_internal_package_obj);
 
@@ -447,13 +453,60 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
                                                               package.
                                                               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;
        }
 
-       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,
-                                 "Package List length larger than NumElements count (%X), truncated\n",
-                                 element_count));
+                                 "Package List length (%X) smaller than NumElements count (%X), padded with null elements\n",
+                                 i, element_count));
        }
 
        obj_desc->package.flags |= AOPOBJ_DATA_VALID;
@@ -721,6 +774,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
                                /* Node was saved in Op */
 
                                obj_desc->reference.node = op->common.node;
+                               obj_desc->reference.object =
+                                   op->common.node->object;
                        }
 
                        obj_desc->reference.opcode = opcode;
index f501e083aac78779c6f5a0f4f0012bc505f6d6b1..a818e0ddb996c0bf124a6060adc25cf74f5f2cd4 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,6 +49,7 @@
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acevents.h>
+#include <acpi/actables.h>
 
 #define _COMPONENT          ACPI_DISPATCHER
 ACPI_MODULE_NAME("dsopcode")
@@ -217,6 +218,50 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
        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
@@ -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",
                          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));
 
        /* 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,
 
        /* 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);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
@@ -876,6 +1029,106 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
        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
@@ -1070,8 +1323,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
                         * is set to anything other than zero!
                         */
                        walk_state->return_desc = walk_state->operands[0];
-               } else if ((walk_state->results) &&
-                          (walk_state->results->results.num_results > 0)) {
+               } else if (walk_state->result_count) {
 
                        /* Since we have a real Return(), delete any implicit return */
 
index 71503c036f7c1496c2cd873a55a5e4bba676d6f2..b398982f0d8baef2e534efc85108a5b338fa0f1a 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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,
                        AML_VAR_PACKAGE_OP)
                    || (op->common.parent->common.aml_opcode == AML_BUFFER_OP)
                    || (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
                         * the operands can be method calls.  The result is used.
@@ -472,7 +474,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
        /* A valid name must be looked up in the namespace */
 
        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",
                                  arg));
 
@@ -595,7 +598,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
        } else {
                /* 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
                         * optional result parameter that was not specified
@@ -617,7 +621,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
                        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,
                                          "Argument previously created, already stacked\n"));
 
@@ -630,9 +635,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
                         * Use value that was already previously returned
                         * by the evaluation of this argument
                         */
-                       status =
-                           acpi_ds_result_pop_from_bottom(&obj_desc,
-                                                          walk_state);
+                       status = acpi_ds_result_pop(&obj_desc, walk_state);
                        if (ACPI_FAILURE(status)) {
                                /*
                                 * Only error is underflow, and this indicates
@@ -698,27 +701,52 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
 {
        acpi_status status = AE_OK;
        union acpi_parse_object *arg;
+       union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS];
        u32 arg_count = 0;
+       u32 index = walk_state->num_operands;
+       u32 i;
 
        ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg);
 
-       /* For all arguments in the list... */
+       /* Get all arguments in the list */
 
        arg = first_arg;
        while (arg) {
-               status = acpi_ds_create_operand(walk_state, arg, arg_count);
-               if (ACPI_FAILURE(status)) {
-                       goto cleanup;
+               if (index >= ACPI_OBJ_NUM_OPERANDS) {
+                       return_ACPI_STATUS(AE_BAD_DATA);
                }
 
-               ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-                                 "Arg #%d (%p) done, Arg1=%p\n", arg_count,
-                                 arg, first_arg));
+               arguments[index] = arg;
+               walk_state->operands[index] = NULL;
 
                /* Move on to next argument, if any */
 
                arg = arg->common.next;
                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);
@@ -729,9 +757,112 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
         * pop everything off of the operand stack and delete those
         * 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);
 }
index 69693fa07224b8514e5c6c05b3bb7e81a12ce7ed..b246b9657eada3b0c2f7e2fd55eb156ce78ed7a9 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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,
        switch (opcode_class) {
        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);
                break;
 
@@ -305,20 +300,11 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
                        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;
 
        case AML_CLASS_EXECUTE:
        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;
 
        default:
@@ -374,6 +360,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
        /* Init the walk state */
 
        walk_state->num_operands = 0;
+       walk_state->operand_index = 0;
        walk_state->return_desc = NULL;
        walk_state->result_obj = NULL;
 
@@ -388,10 +375,17 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
        /* Decode the Opcode 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;
 
-       case AML_CLASS_EXECUTE: /* most operators with arguments */
+       case AML_CLASS_EXECUTE: /* Most operators with arguments */
 
                /* Build resolved operand stack */
 
@@ -400,13 +394,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
                        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
                 * 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)
 
                        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;
 
                case AML_TYPE_METHOD_CALL:
@@ -516,7 +493,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
 
                                op->common.node =
                                    (struct acpi_namespace_node *)op->asl.value.
-                                   arg->asl.node->object;
+                                   arg->asl.node;
                                acpi_ut_add_reference(op->asl.value.arg->asl.
                                                      node->object);
                                return_ACPI_STATUS(AE_OK);
@@ -632,13 +609,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
                                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
                         * current result stack
@@ -671,8 +641,28 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
                                if (ACPI_FAILURE(status)) {
                                        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;
 
index 8ab9d1b29a4ce4062f1163ed746a16a258c4cd4f..dff7a3e445a88e7dbd694f858536a7fd5dba3612 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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)
                        if (ACPI_FAILURE(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
@@ -767,6 +776,12 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
                    acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
                                   object_type, ACPI_IMODE_LOAD_PASS2, flags,
                                   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;
        }
 
@@ -823,6 +838,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
        struct acpi_namespace_node *new_node;
 #ifndef ACPI_NO_METHOD_EXECUTION
        u32 i;
+       u8 region_space;
 #endif
 
        ACPI_FUNCTION_TRACE(ds_load2_end_op);
@@ -1003,11 +1019,6 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
                        status = acpi_ex_create_event(walk_state);
                        break;
 
-               case AML_DATA_REGION_OP:
-
-                       status = acpi_ex_create_table_region(walk_state);
-                       break;
-
                case AML_ALIAS_OP:
 
                        status = acpi_ex_create_alias(walk_state);
@@ -1035,6 +1046,15 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
                switch (op->common.aml_opcode) {
 #ifndef ACPI_NO_METHOD_EXECUTION
                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
@@ -1043,10 +1063,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
                                status =
                                    acpi_ex_create_region(op->named.data,
                                                          op->named.length,
-                                                         (acpi_adr_space_type)
-                                                         ((op->common.value.
-                                                           arg)->common.value.
-                                                          integer),
+                                                         region_space,
                                                          walk_state);
                                if (ACPI_FAILURE(status)) {
                                        return (status);
index 3927c495e4bfef7a12374f80e3aa0f672f2477ad..9e60732658734c4c1741f32c3eb1ff236da20e61 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 5afcdd9c74492aedd4eda84deeb3a9f3882e36c7..1386ced332ecedcacdd0a7c3d61fdcf89f409b20 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #define _COMPONENT          ACPI_DISPATCHER
 ACPI_MODULE_NAME("dswstate")
 
-/* Local prototypes */
-#ifdef ACPI_OBSOLETE_FUNCTIONS
-acpi_status
-acpi_ds_result_insert(void *object,
-                     u32 index, struct acpi_walk_state *walk_state);
-
-acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state *walk_state);
-
-acpi_status
-acpi_ds_obj_stack_pop_object(union acpi_operand_object **object,
-                            struct acpi_walk_state *walk_state);
-
-void *acpi_ds_obj_stack_get_value(u32 index,
-                                 struct acpi_walk_state *walk_state);
-#endif
-
-#ifdef ACPI_FUTURE_USAGE
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ds_result_remove
- *
- * PARAMETERS:  Object              - Where to return the popped object
- *              Index               - Where to extract the object
- *              walk_state          - Current Walk state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
- *              other words, this is a FIFO.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ds_result_remove(union acpi_operand_object **object,
-                     u32 index, struct acpi_walk_state *walk_state)
-{
-       union acpi_generic_state *state;
-
-       ACPI_FUNCTION_NAME(ds_result_remove);
-
-       state = walk_state->results;
-       if (!state) {
-               ACPI_ERROR((AE_INFO, "No result object pushed! State=%p",
-                           walk_state));
-               return (AE_NOT_EXIST);
-       }
-
-       if (index >= ACPI_OBJ_MAX_OPERAND) {
-               ACPI_ERROR((AE_INFO,
-                           "Index out of range: %X State=%p Num=%X",
-                           index, walk_state, state->results.num_results));
-       }
-
-       /* Check for a valid result object */
-
-       if (!state->results.obj_desc[index]) {
-               ACPI_ERROR((AE_INFO,
-                           "Null operand! State=%p #Ops=%X, Index=%X",
-                           walk_state, state->results.num_results, index));
-               return (AE_AML_NO_RETURN_VALUE);
-       }
-
-       /* Remove the object */
-
-       state->results.num_results--;
-
-       *object = state->results.obj_desc[index];
-       state->results.obj_desc[index] = NULL;
-
-       ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                         "Obj=%p [%s] Index=%X State=%p Num=%X\n",
-                         *object,
-                         (*object) ? acpi_ut_get_object_type_name(*object) :
-                         "NULL", index, walk_state,
-                         state->results.num_results));
-
-       return (AE_OK);
-}
-#endif                         /*  ACPI_FUTURE_USAGE  */
+  /* Local prototypes */
+static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *ws);
+static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *ws);
 
 /*******************************************************************************
  *
@@ -138,122 +62,67 @@ acpi_ds_result_remove(union acpi_operand_object **object,
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
- *              other words, this is a FIFO.
+ * DESCRIPTION: Pop an object off the top of this walk's result stack
  *
  ******************************************************************************/
 
 acpi_status
-acpi_ds_result_pop(union acpi_operand_object ** object,
-                  struct acpi_walk_state * walk_state)
+acpi_ds_result_pop(union acpi_operand_object **object,
+                  struct acpi_walk_state *walk_state)
 {
        acpi_native_uint index;
        union acpi_generic_state *state;
+       acpi_status status;
 
        ACPI_FUNCTION_NAME(ds_result_pop);
 
        state = walk_state->results;
-       if (!state) {
-               return (AE_OK);
-       }
-
-       if (!state->results.num_results) {
-               ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p",
-                           walk_state));
-               return (AE_AML_NO_RETURN_VALUE);
-       }
 
-       /* Remove top element */
+       /* Incorrect state of result stack */
 
-       state->results.num_results--;
-
-       for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) {
-
-               /* Check for a valid result object */
-
-               if (state->results.obj_desc[index - 1]) {
-                       *object = state->results.obj_desc[index - 1];
-                       state->results.obj_desc[index - 1] = NULL;
-
-                       ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                         "Obj=%p [%s] Index=%X State=%p Num=%X\n",
-                                         *object,
-                                         (*object) ?
-                                         acpi_ut_get_object_type_name(*object)
-                                         : "NULL", (u32) index - 1, walk_state,
-                                         state->results.num_results));
-
-                       return (AE_OK);
-               }
+       if (state && !walk_state->result_count) {
+               ACPI_ERROR((AE_INFO, "No results on result stack"));
+               return (AE_AML_INTERNAL);
        }
 
-       ACPI_ERROR((AE_INFO, "No result objects! State=%p", walk_state));
-       return (AE_AML_NO_RETURN_VALUE);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ds_result_pop_from_bottom
- *
- * PARAMETERS:  Object              - Where to return the popped object
- *              walk_state          - Current Walk state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
- *              other words, this is a FIFO.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object,
-                              struct acpi_walk_state * walk_state)
-{
-       acpi_native_uint index;
-       union acpi_generic_state *state;
+       if (!state && walk_state->result_count) {
+               ACPI_ERROR((AE_INFO, "No result state for result stack"));
+               return (AE_AML_INTERNAL);
+       }
 
-       ACPI_FUNCTION_NAME(ds_result_pop_from_bottom);
+       /* Empty result stack */
 
-       state = walk_state->results;
        if (!state) {
-               ACPI_ERROR((AE_INFO,
-                           "No result object pushed! State=%p", walk_state));
-               return (AE_NOT_EXIST);
-       }
-
-       if (!state->results.num_results) {
-               ACPI_ERROR((AE_INFO, "No result objects! State=%p",
+               ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p",
                            walk_state));
                return (AE_AML_NO_RETURN_VALUE);
        }
 
-       /* Remove Bottom element */
-
-       *object = state->results.obj_desc[0];
-
-       /* Push entire stack down one element */
-
-       for (index = 0; index < state->results.num_results; index++) {
-               state->results.obj_desc[index] =
-                   state->results.obj_desc[index + 1];
-       }
+       /* Return object of the top element and clean that top element result stack */
 
-       state->results.num_results--;
-
-       /* Check for a valid result object */
+       walk_state->result_count--;
+       index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
 
+       *object = state->results.obj_desc[index];
        if (!*object) {
                ACPI_ERROR((AE_INFO,
-                           "Null operand! State=%p #Ops=%X Index=%X",
-                           walk_state, state->results.num_results,
-                           (u32) index));
+                           "No result objects on result stack, State=%p",
+                           walk_state));
                return (AE_AML_NO_RETURN_VALUE);
        }
 
-       ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] Results=%p State=%p\n",
-                         *object,
-                         (*object) ? acpi_ut_get_object_type_name(*object) :
-                         "NULL", state, walk_state));
+       state->results.obj_desc[index] = NULL;
+       if (index == 0) {
+               status = acpi_ds_result_stack_pop(walk_state);
+               if (ACPI_FAILURE(status)) {
+                       return (status);
+               }
+       }
+
+       ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                         "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object,
+                         acpi_ut_get_object_type_name(*object),
+                         (u32) index, walk_state, walk_state->result_count));
 
        return (AE_OK);
 }
@@ -276,39 +145,56 @@ acpi_ds_result_push(union acpi_operand_object * object,
                    struct acpi_walk_state * walk_state)
 {
        union acpi_generic_state *state;
+       acpi_status status;
+       acpi_native_uint index;
 
        ACPI_FUNCTION_NAME(ds_result_push);
 
+       if (walk_state->result_count > walk_state->result_size) {
+               ACPI_ERROR((AE_INFO, "Result stack is full"));
+               return (AE_AML_INTERNAL);
+       } else if (walk_state->result_count == walk_state->result_size) {
+
+               /* Extend the result stack */
+
+               status = acpi_ds_result_stack_push(walk_state);
+               if (ACPI_FAILURE(status)) {
+                       ACPI_ERROR((AE_INFO,
+                                   "Failed to extend the result stack"));
+                       return (status);
+               }
+       }
+
+       if (!(walk_state->result_count < walk_state->result_size)) {
+               ACPI_ERROR((AE_INFO, "No free elements in result stack"));
+               return (AE_AML_INTERNAL);
+       }
+
        state = walk_state->results;
        if (!state) {
                ACPI_ERROR((AE_INFO, "No result stack frame during push"));
                return (AE_AML_INTERNAL);
        }
 
-       if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) {
-               ACPI_ERROR((AE_INFO,
-                           "Result stack overflow: Obj=%p State=%p Num=%X",
-                           object, walk_state, state->results.num_results));
-               return (AE_STACK_OVERFLOW);
-       }
-
        if (!object) {
                ACPI_ERROR((AE_INFO,
                            "Null Object! Obj=%p State=%p Num=%X",
-                           object, walk_state, state->results.num_results));
+                           object, walk_state, walk_state->result_count));
                return (AE_BAD_PARAMETER);
        }
 
-       state->results.obj_desc[state->results.num_results] = object;
-       state->results.num_results++;
+       /* Assign the address of object to the top free element of result stack */
+
+       index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
+       state->results.obj_desc[index] = object;
+       walk_state->result_count++;
 
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
                          object,
-                         object ?
                          acpi_ut_get_object_type_name((union
                                                        acpi_operand_object *)
-                                                      object) : "NULL",
-                         walk_state, state->results.num_results,
+                                                      object), walk_state,
+                         walk_state->result_count,
                          walk_state->current_result));
 
        return (AE_OK);
@@ -322,16 +208,25 @@ acpi_ds_result_push(union acpi_operand_object * object,
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Push an object onto the walk_state result stack.
+ * DESCRIPTION: Push an object onto the walk_state result stack
  *
  ******************************************************************************/
 
-acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state)
+static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state)
 {
        union acpi_generic_state *state;
 
        ACPI_FUNCTION_NAME(ds_result_stack_push);
 
+       /* Check for stack overflow */
+
+       if (((u32) walk_state->result_size + ACPI_RESULTS_FRAME_OBJ_NUM) >
+           ACPI_RESULTS_OBJ_NUM_MAX) {
+               ACPI_ERROR((AE_INFO, "Result stack overflow: State=%p Num=%X",
+                           walk_state, walk_state->result_size));
+               return (AE_STACK_OVERFLOW);
+       }
+
        state = acpi_ut_create_generic_state();
        if (!state) {
                return (AE_NO_MEMORY);
@@ -340,6 +235,10 @@ acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state)
        state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT;
        acpi_ut_push_generic_state(&walk_state->results, state);
 
+       /* Increase the length of the result stack by the length of frame */
+
+       walk_state->result_size += ACPI_RESULTS_FRAME_OBJ_NUM;
+
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n",
                          state, walk_state));
 
@@ -354,11 +253,11 @@ acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state)
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Pop an object off of the walk_state result stack.
+ * DESCRIPTION: Pop an object off of the walk_state result stack
  *
  ******************************************************************************/
 
-acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state)
+static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state)
 {
        union acpi_generic_state *state;
 
@@ -367,18 +266,27 @@ acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state)
        /* Check for stack underflow */
 
        if (walk_state->results == NULL) {
-               ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Underflow - State=%p\n",
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                 "Result stack underflow - State=%p\n",
                                  walk_state));
                return (AE_AML_NO_OPERAND);
        }
 
+       if (walk_state->result_size < ACPI_RESULTS_FRAME_OBJ_NUM) {
+               ACPI_ERROR((AE_INFO, "Insufficient result stack size"));
+               return (AE_AML_INTERNAL);
+       }
+
        state = acpi_ut_pop_generic_state(&walk_state->results);
+       acpi_ut_delete_generic_state(state);
+
+       /* Decrease the length of result stack by the length of frame */
+
+       walk_state->result_size -= ACPI_RESULTS_FRAME_OBJ_NUM;
 
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                          "Result=%p RemainingResults=%X State=%p\n",
-                         state, state->results.num_results, walk_state));
-
-       acpi_ut_delete_generic_state(state);
+                         state, walk_state->result_count, walk_state));
 
        return (AE_OK);
 }
@@ -412,9 +320,13 @@ acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state)
 
        /* Put the object onto the stack */
 
-       walk_state->operands[walk_state->num_operands] = object;
+       walk_state->operands[walk_state->operand_index] = object;
        walk_state->num_operands++;
 
+       /* For the usual order of filling the operand stack */
+
+       walk_state->operand_index++;
+
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
                          object,
                          acpi_ut_get_object_type_name((union
@@ -484,43 +396,36 @@ acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state)
  *
  ******************************************************************************/
 
-acpi_status
+void
 acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
-                                struct acpi_walk_state * walk_state)
+                                struct acpi_walk_state *walk_state)
 {
-       u32 i;
+       acpi_native_int i;
        union acpi_operand_object *obj_desc;
 
        ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete);
 
-       for (i = 0; i < pop_count; i++) {
-
-               /* Check for stack underflow */
+       if (pop_count == 0) {
+               return;
+       }
 
+       for (i = (acpi_native_int) (pop_count - 1); i >= 0; i--) {
                if (walk_state->num_operands == 0) {
-                       ACPI_ERROR((AE_INFO,
-                                   "Object stack underflow! Count=%X State=%p #Ops=%X",
-                                   pop_count, walk_state,
-                                   walk_state->num_operands));
-                       return (AE_STACK_UNDERFLOW);
+                       return;
                }
 
                /* Pop the stack and delete an object if present in this stack entry */
 
                walk_state->num_operands--;
-               obj_desc = walk_state->operands[walk_state->num_operands];
+               obj_desc = walk_state->operands[i];
                if (obj_desc) {
-                       acpi_ut_remove_reference(walk_state->
-                                                operands[walk_state->
-                                                         num_operands]);
-                       walk_state->operands[walk_state->num_operands] = NULL;
+                       acpi_ut_remove_reference(walk_state->operands[i]);
+                       walk_state->operands[i] = NULL;
                }
        }
 
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
                          pop_count, walk_state, walk_state->num_operands));
-
-       return (AE_OK);
 }
 
 /*******************************************************************************
@@ -560,7 +465,7 @@ struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state
  *
  * RETURN:      None
  *
- * DESCRIPTION: Place the Thread state at the head of the state list.
+ * DESCRIPTION: Place the Thread state at the head of the state list
  *
  ******************************************************************************/
 
@@ -636,7 +541,6 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union
                                                  *thread)
 {
        struct acpi_walk_state *walk_state;
-       acpi_status status;
 
        ACPI_FUNCTION_TRACE(ds_create_walk_state);
 
@@ -659,14 +563,6 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union
        acpi_ds_method_data_init(walk_state);
 #endif
 
-       /* Create an initial result stack entry */
-
-       status = acpi_ds_result_stack_push(walk_state);
-       if (ACPI_FAILURE(status)) {
-               ACPI_FREE(walk_state);
-               return_PTR(NULL);
-       }
-
        /* Put the new state at the head of the walk list */
 
        if (thread) {
@@ -860,190 +756,3 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state)
        ACPI_FREE(walk_state);
        return_VOID;
 }
-
-#ifdef ACPI_OBSOLETE_FUNCTIONS
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ds_result_insert
- *
- * PARAMETERS:  Object              - Object to push
- *              Index               - Where to insert the object
- *              walk_state          - Current Walk state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Insert an object onto this walk's result stack
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ds_result_insert(void *object,
-                     u32 index, struct acpi_walk_state *walk_state)
-{
-       union acpi_generic_state *state;
-
-       ACPI_FUNCTION_NAME(ds_result_insert);
-
-       state = walk_state->results;
-       if (!state) {
-               ACPI_ERROR((AE_INFO, "No result object pushed! State=%p",
-                           walk_state));
-               return (AE_NOT_EXIST);
-       }
-
-       if (index >= ACPI_OBJ_NUM_OPERANDS) {
-               ACPI_ERROR((AE_INFO,
-                           "Index out of range: %X Obj=%p State=%p Num=%X",
-                           index, object, walk_state,
-                           state->results.num_results));
-               return (AE_BAD_PARAMETER);
-       }
-
-       if (!object) {
-               ACPI_ERROR((AE_INFO,
-                           "Null Object! Index=%X Obj=%p State=%p Num=%X",
-                           index, object, walk_state,
-                           state->results.num_results));
-               return (AE_BAD_PARAMETER);
-       }
-
-       state->results.obj_desc[index] = object;
-       state->results.num_results++;
-
-       ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                         "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
-                         object,
-                         object ?
-                         acpi_ut_get_object_type_name((union
-                                                       acpi_operand_object *)
-                                                      object) : "NULL",
-                         walk_state, state->results.num_results,
-                         walk_state->current_result));
-
-       return (AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ds_obj_stack_delete_all
- *
- * PARAMETERS:  walk_state          - Current Walk state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
- *              Should be used with great care, if at all!
- *
- ******************************************************************************/
-
-acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state * walk_state)
-{
-       u32 i;
-
-       ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_delete_all, walk_state);
-
-       /* The stack size is configurable, but fixed */
-
-       for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
-               if (walk_state->operands[i]) {
-                       acpi_ut_remove_reference(walk_state->operands[i]);
-                       walk_state->operands[i] = NULL;
-               }
-       }
-
-       return_ACPI_STATUS(AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ds_obj_stack_pop_object
- *
- * PARAMETERS:  Object              - Where to return the popped object
- *              walk_state          - Current Walk state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
- *              deleted by this routine.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ds_obj_stack_pop_object(union acpi_operand_object **object,
-                            struct acpi_walk_state *walk_state)
-{
-       ACPI_FUNCTION_NAME(ds_obj_stack_pop_object);
-
-       /* Check for stack underflow */
-
-       if (walk_state->num_operands == 0) {
-               ACPI_ERROR((AE_INFO,
-                           "Missing operand/stack empty! State=%p #Ops=%X",
-                           walk_state, walk_state->num_operands));
-               *object = NULL;
-               return (AE_AML_NO_OPERAND);
-       }
-
-       /* Pop the stack */
-
-       walk_state->num_operands--;
-
-       /* Check for a valid operand */
-
-       if (!walk_state->operands[walk_state->num_operands]) {
-               ACPI_ERROR((AE_INFO,
-                           "Null operand! State=%p #Ops=%X",
-                           walk_state, walk_state->num_operands));
-               *object = NULL;
-               return (AE_AML_NO_OPERAND);
-       }
-
-       /* Get operand and set stack entry to null */
-
-       *object = walk_state->operands[walk_state->num_operands];
-       walk_state->operands[walk_state->num_operands] = NULL;
-
-       ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
-                         *object, acpi_ut_get_object_type_name(*object),
-                         walk_state, walk_state->num_operands));
-
-       return (AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ds_obj_stack_get_value
- *
- * PARAMETERS:  Index               - Stack index whose value is desired.  Based
- *                                    on the top of the stack (index=0 == top)
- *              walk_state          - Current Walk state
- *
- * RETURN:      Pointer to the requested operand
- *
- * DESCRIPTION: Retrieve an object from this walk's operand stack.  Index must
- *              be within the range of the current stack pointer.
- *
- ******************************************************************************/
-
-void *acpi_ds_obj_stack_get_value(u32 index, struct acpi_walk_state *walk_state)
-{
-
-       ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_get_value, walk_state);
-
-       /* Can't do it if the stack is empty */
-
-       if (walk_state->num_operands == 0) {
-               return_PTR(NULL);
-       }
-
-       /* or if the index is past the top of the stack */
-
-       if (index > (walk_state->num_operands - (u32) 1)) {
-               return_PTR(NULL);
-       }
-
-       return_PTR(walk_state->
-                  operands[(acpi_native_uint) (walk_state->num_operands - 1) -
-                           index]);
-}
-#endif
index e3f04b272f3f23829cac4a555677c495ea290cc5..0924992187e87031809bf70c1b75c6367cc38a64 100644 (file)
@@ -73,38 +73,14 @@ enum ec_event {
 
 #define ACPI_EC_DELAY          500     /* Wait 500ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK     1000    /* Wait 1ms max. to get global lock */
+#define ACPI_EC_UDELAY         100     /* Wait 100us before polling EC again */
 
 enum {
        EC_FLAGS_WAIT_GPE = 0,          /* Don't check status until GPE arrives */
        EC_FLAGS_QUERY_PENDING,         /* Query is pending */
        EC_FLAGS_GPE_MODE,              /* Expect GPE to be sent for status change */
-       EC_FLAGS_NO_ADDRESS_GPE,        /* Expect GPE only for non-address event */
-       EC_FLAGS_ADDRESS,               /* Address is being written */
-       EC_FLAGS_NO_WDATA_GPE,          /* Don't expect WDATA GPE event */
-       EC_FLAGS_WDATA,                 /* Data is being written */
-       EC_FLAGS_NO_OBF1_GPE,           /* Don't expect GPE before read */
-};
-
-static int acpi_ec_remove(struct acpi_device *device, int type);
-static int acpi_ec_start(struct acpi_device *device);
-static int acpi_ec_stop(struct acpi_device *device, int type);
-static int acpi_ec_add(struct acpi_device *device);
-
-static const struct acpi_device_id ec_device_ids[] = {
-       {"PNP0C09", 0},
-       {"", 0},
-};
-
-static struct acpi_driver acpi_ec_driver = {
-       .name = "ec",
-       .class = ACPI_EC_CLASS,
-       .ids = ec_device_ids,
-       .ops = {
-               .add = acpi_ec_add,
-               .remove = acpi_ec_remove,
-               .start = acpi_ec_start,
-               .stop = acpi_ec_stop,
-               },
+       EC_FLAGS_NO_GPE,                /* Don't use GPE mode */
+       EC_FLAGS_RESCHEDULE_POLL        /* Re-schedule poll */
 };
 
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -129,6 +105,8 @@ static struct acpi_ec {
        struct mutex lock;
        wait_queue_head_t wait;
        struct list_head list;
+       struct delayed_work work;
+       atomic_t irq_count;
        u8 handlers_installed;
 } *boot_ec, *first_ec;
 
@@ -177,65 +155,52 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
        return 0;
 }
 
-static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
+static void ec_schedule_ec_poll(struct acpi_ec *ec)
 {
-       int ret = 0;
+       if (test_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags))
+               schedule_delayed_work(&ec->work,
+                                     msecs_to_jiffies(ACPI_EC_DELAY));
+}
 
-       if (unlikely(event == ACPI_EC_EVENT_OBF_1 &&
-                    test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags)))
-               force_poll = 1;
-       if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) &&
-                    test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags)))
-               force_poll = 1;
-       if (unlikely(test_bit(EC_FLAGS_WDATA, &ec->flags) &&
-                    test_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags)))
-               force_poll = 1;
+static void ec_switch_to_poll_mode(struct acpi_ec *ec)
+{
+       set_bit(EC_FLAGS_NO_GPE, &ec->flags);
+       clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+       acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+       set_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
+}
+
+static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
+{
+       atomic_set(&ec->irq_count, 0);
        if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
            likely(!force_poll)) {
                if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
                                       msecs_to_jiffies(ACPI_EC_DELAY)))
-                       goto end;
+                       return 0;
                clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                if (acpi_ec_check_status(ec, event)) {
-                       if (event == ACPI_EC_EVENT_OBF_1) {
-                               /* miss OBF_1 GPE, don't expect it */
-                               pr_info(PREFIX "missing OBF confirmation, "
-                                       "don't expect it any longer.\n");
-                               set_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags);
-                       } else if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) {
-                               /* miss address GPE, don't expect it anymore */
-                               pr_info(PREFIX "missing address confirmation, "
-                                       "don't expect it any longer.\n");
-                               set_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags);
-                       } else if (test_bit(EC_FLAGS_WDATA, &ec->flags)) {
-                               /* miss write data GPE, don't expect it */
-                               pr_info(PREFIX "missing write data confirmation, "
-                                       "don't expect it any longer.\n");
-                               set_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags);
-                       } else {
-                               /* missing GPEs, switch back to poll mode */
-                               if (printk_ratelimit())
-                                       pr_info(PREFIX "missing confirmations, "
+                       /* missing GPEs, switch back to poll mode */
+                       if (printk_ratelimit())
+                               pr_info(PREFIX "missing confirmations, "
                                                "switch off interrupt mode.\n");
-                               clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
-                       }
-                       goto end;
+                       ec_switch_to_poll_mode(ec);
+                       ec_schedule_ec_poll(ec);
+                       return 0;
                }
        } else {
                unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
                clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                while (time_before(jiffies, delay)) {
                        if (acpi_ec_check_status(ec, event))
-                               goto end;
+                               return 0;
+                       udelay(ACPI_EC_UDELAY);
                }
        }
-       pr_err(PREFIX "acpi_ec_wait timeout,"
-                              " status = %d, expect_event = %d\n",
-                              acpi_ec_read_status(ec), event);
-       ret = -ETIME;
-      end:
-       clear_bit(EC_FLAGS_ADDRESS, &ec->flags);
-       return ret;
+       pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n",
+               acpi_ec_read_status(ec),
+               (event == ACPI_EC_EVENT_OBF_1) ? "\"b0=1\"" : "\"b1=0\"");
+       return -ETIME;
 }
 
 static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
@@ -245,8 +210,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
 {
        int result = 0;
        set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-       acpi_ec_write_cmd(ec, command);
        pr_debug(PREFIX "transaction start\n");
+       acpi_ec_write_cmd(ec, command);
        for (; wdata_len > 0; --wdata_len) {
                result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
                if (result) {
@@ -254,15 +219,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
                               "write_cmd timeout, command = %d\n", command);
                        goto end;
                }
-               /* mark the address byte written to EC */
-               if (rdata_len + wdata_len > 1)
-                       set_bit(EC_FLAGS_ADDRESS, &ec->flags);
                set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                acpi_ec_write_data(ec, *(wdata++));
        }
 
        if (!rdata_len) {
-               set_bit(EC_FLAGS_WDATA, &ec->flags);
                result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
                if (result) {
                        pr_err(PREFIX
@@ -527,46 +488,50 @@ static u32 acpi_ec_gpe_handler(void *data)
 {
        acpi_status status = AE_OK;
        struct acpi_ec *ec = data;
+       u8 state = acpi_ec_read_status(ec);
 
        pr_debug(PREFIX "~~~> interrupt\n");
+       atomic_inc(&ec->irq_count);
+       if (atomic_read(&ec->irq_count) > 5) {
+               pr_err(PREFIX "GPE storm detected, disabling EC GPE\n");
+               ec_switch_to_poll_mode(ec);
+               goto end;
+       }
        clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
        if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
                wake_up(&ec->wait);
 
-       if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) {
+       if (state & ACPI_EC_FLAG_SCI) {
                if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
                        status = acpi_os_execute(OSL_EC_BURST_HANDLER,
                                acpi_ec_gpe_query, ec);
-       } else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) {
+       } else if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+                  !test_bit(EC_FLAGS_NO_GPE, &ec->flags) &&
+                  in_interrupt()) {
                /* this is non-query, must be confirmation */
                if (printk_ratelimit())
                        pr_info(PREFIX "non-query interrupt received,"
                                " switching to interrupt mode\n");
                set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+               clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
        }
-
+end:
+       ec_schedule_ec_poll(ec);
        return ACPI_SUCCESS(status) ?
            ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
 }
 
+static void do_ec_poll(struct work_struct *work)
+{
+       struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work);
+       atomic_set(&ec->irq_count, 0);
+       (void)acpi_ec_gpe_handler(ec);
+}
+
 /* --------------------------------------------------------------------------
                              Address Space Management
    -------------------------------------------------------------------------- */
 
-static acpi_status
-acpi_ec_space_setup(acpi_handle region_handle,
-                   u32 function, void *handler_context, void **return_context)
-{
-       /*
-        * The EC object is in the handler context and is needed
-        * when calling the acpi_ec_space_handler.
-        */
-       *return_context = (function != ACPI_REGION_DEACTIVATE) ?
-           handler_context : NULL;
-
-       return AE_OK;
-}
-
 static acpi_status
 acpi_ec_space_handler(u32 function, acpi_physical_address address,
                      u32 bits, acpi_integer *value,
@@ -704,6 +669,8 @@ static struct acpi_ec *make_acpi_ec(void)
        mutex_init(&ec->lock);
        init_waitqueue_head(&ec->wait);
        INIT_LIST_HEAD(&ec->list);
+       INIT_DELAYED_WORK_DEFERRABLE(&ec->work, do_ec_poll);
+       atomic_set(&ec->irq_count, 0);
        return ec;
 }
 
@@ -736,17 +703,21 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
        status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
        if (ACPI_FAILURE(status))
                return status;
-       /* Find and register all query methods */
-       acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
-                           acpi_ec_register_query_methods, ec, NULL);
        /* Use the global lock for all EC transactions? */
        acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
        ec->handle = handle;
        return AE_CTRL_TERMINATE;
 }
 
+static void ec_poll_stop(struct acpi_ec *ec)
+{
+       clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
+       cancel_delayed_work(&ec->work);
+}
+
 static void ec_remove_handlers(struct acpi_ec *ec)
 {
+       ec_poll_stop(ec);
        if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
                                ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
                pr_err(PREFIX "failed to remove space handler\n");
@@ -766,31 +737,28 @@ static int acpi_ec_add(struct acpi_device *device)
        strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 
        /* Check for boot EC */
-       if (boot_ec) {
-               if (boot_ec->handle == device->handle) {
-                       /* Pre-loaded EC from DSDT, just move pointer */
-                       ec = boot_ec;
-                       boot_ec = NULL;
-                       goto end;
-               } else if (boot_ec->handle == ACPI_ROOT_OBJECT) {
-                       /* ECDT-based EC, time to shut it down */
-                       ec_remove_handlers(boot_ec);
-                       kfree(boot_ec);
-                       first_ec = boot_ec = NULL;
+       if (boot_ec &&
+           (boot_ec->handle == device->handle ||
+            boot_ec->handle == ACPI_ROOT_OBJECT)) {
+               ec = boot_ec;
+               boot_ec = NULL;
+       } else {
+               ec = make_acpi_ec();
+               if (!ec)
+                       return -ENOMEM;
+               if (ec_parse_device(device->handle, 0, ec, NULL) !=
+                   AE_CTRL_TERMINATE) {
+                       kfree(ec);
+                       return -EINVAL;
                }
        }
 
-       ec = make_acpi_ec();
-       if (!ec)
-               return -ENOMEM;
-
-       if (ec_parse_device(device->handle, 0, ec, NULL) !=
-           AE_CTRL_TERMINATE) {
-               kfree(ec);
-               return -EINVAL;
-       }
        ec->handle = device->handle;
-      end:
+
+       /* Find and register all query methods */
+       acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
+                           acpi_ec_register_query_methods, ec, NULL);
+
        if (!first_ec)
                first_ec = ec;
        acpi_driver_data(device) = ec;
@@ -865,7 +833,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
        status = acpi_install_address_space_handler(ec->handle,
                                                    ACPI_ADR_SPACE_EC,
                                                    &acpi_ec_space_handler,
-                                                   &acpi_ec_space_setup, ec);
+                                                   NULL, ec);
        if (ACPI_FAILURE(status)) {
                acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
                return -ENODEV;
@@ -892,6 +860,7 @@ static int acpi_ec_start(struct acpi_device *device)
 
        /* EC is fully operational, allow queries */
        clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+       ec_schedule_ec_poll(ec);
        return ret;
 }
 
@@ -919,6 +888,11 @@ int __init acpi_boot_ec_enable(void)
        return -EFAULT;
 }
 
+static const struct acpi_device_id ec_device_ids[] = {
+       {"PNP0C09", 0},
+       {"", 0},
+};
+
 int __init acpi_ec_ecdt_probe(void)
 {
        int ret;
@@ -939,6 +913,7 @@ int __init acpi_ec_ecdt_probe(void)
                boot_ec->data_addr = ecdt_ptr->data.address;
                boot_ec->gpe = ecdt_ptr->gpe;
                boot_ec->handle = ACPI_ROOT_OBJECT;
+               acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
        } else {
                /* This workaround is needed only on some broken machines,
                 * which require early EC, but fail to provide ECDT */
@@ -968,6 +943,39 @@ int __init acpi_ec_ecdt_probe(void)
        return -ENODEV;
 }
 
+static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
+{
+       struct acpi_ec *ec = acpi_driver_data(device);
+       /* Stop using GPE */
+       set_bit(EC_FLAGS_NO_GPE, &ec->flags);
+       clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+       acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+       return 0;
+}
+
+static int acpi_ec_resume(struct acpi_device *device)
+{
+       struct acpi_ec *ec = acpi_driver_data(device);
+       /* Enable use of GPE back */
+       clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
+       acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+       return 0;
+}
+
+static struct acpi_driver acpi_ec_driver = {
+       .name = "ec",
+       .class = ACPI_EC_CLASS,
+       .ids = ec_device_ids,
+       .ops = {
+               .add = acpi_ec_add,
+               .remove = acpi_ec_remove,
+               .start = acpi_ec_start,
+               .stop = acpi_ec_stop,
+               .suspend = acpi_ec_suspend,
+               .resume = acpi_ec_resume,
+               },
+};
+
 static int __init acpi_ec_init(void)
 {
        int result = 0;
index 3048801a37b5e1e91dfd6a7595b560cfe27531c2..5d30e5be1b1c73edad8df547dfa1f7ce9eb55809 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 0dadd2adc8001a109669b4ae62c673da60f4747b..5354be44f87678beda3531645527a8e95a02edaf 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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)
 
        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 */
 
        status =
index 361ebe6c4a6f0b40cdf9c86acb484eb235862dbd..e6c4d4c49e79ee1f1fb4d409e60b949b2cff5e05 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 21cb749d0c75567534ebee05c78551bb289f1972..2113e58e2221520b6091155b84ac3ab8b9956197 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #define _COMPONENT          ACPI_EVENTS
 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 */
-
 static struct acpi_table_facs *facs = NULL;
 
 /* Local prototypes */
@@ -94,7 +79,6 @@ u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node)
        switch (node->type) {
        case ACPI_TYPE_DEVICE:
        case ACPI_TYPE_PROCESSOR:
-       case ACPI_TYPE_POWER:
        case ACPI_TYPE_THERMAL:
                /*
                 * These are the ONLY objects that can receive ACPI notifications
@@ -139,17 +123,9 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
         *   initiate soft-off or sleep operation?
         */
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                         "Dispatching Notify(%X) on node %p\n", notify_value,
-                         node));
-
-       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));
-       }
+                         "Dispatching Notify on [%4.4s] Node %p Value 0x%2.2X (%s)\n",
+                         acpi_ut_get_node_name(node), node, notify_value,
+                         acpi_ut_get_notify_name(notify_value)));
 
        /* Get the notify object attached to the NS Node */
 
@@ -159,10 +135,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
                /* We have the notify object, Get the right handler */
 
                switch (node->type) {
+
+                       /* Notify allowed only on these types */
+
                case ACPI_TYPE_DEVICE:
                case ACPI_TYPE_THERMAL:
                case ACPI_TYPE_PROCESSOR:
-               case ACPI_TYPE_POWER:
 
                        if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
                                handler_obj =
@@ -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
             && (notify_value <= ACPI_MAX_SYS_NOTIFY))
            || (acpi_gbl_device_notify.handler
@@ -190,6 +173,13 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
                        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 =
                    ACPI_DESC_TYPE_STATE_NOTIFY;
                notify_info->notify.node = node;
@@ -202,15 +192,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
                if (ACPI_FAILURE(status)) {
                        acpi_ut_delete_generic_state(notify_info);
                }
-       }
-
-       if (!handler_obj) {
+       } else {
                /*
-                * There is no per-device notify handler for this device.
-                * This may or may not be a problem.
+                * There is no notify handler (per-device or system) for this device.
                 */
                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,
                                  node));
        }
@@ -349,9 +336,10 @@ acpi_status acpi_ev_init_global_lock_handler(void)
 
        ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
 
-       status =
-           acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
-                                   (struct acpi_table_header **)&facs);
+       status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
+                                        ACPI_CAST_INDIRECT_PTR(struct
+                                                               acpi_table_header,
+                                                               &facs));
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
@@ -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
         * 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 (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
                        acpi_ev_global_lock_acquired++;
@@ -448,9 +437,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
        }
 
        if (ACPI_FAILURE(status)) {
-               status =
-                   acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex,
-                                             timeout);
+               status = acpi_ex_system_wait_mutex(
+                               acpi_gbl_global_lock_mutex->mutex.os_mutex,
+                               timeout);
        }
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
@@ -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_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
         * the lock as a standard mutex.
@@ -555,7 +557,7 @@ acpi_status acpi_ev_release_global_lock(void)
        /* Release the local GL mutex */
        acpi_ev_global_lock_thread_id = NULL;
        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);
 }
 
index 58ad09725dd2a69dcac8f1f45fa3226041981bf3..1628f59347524c9bbf49bc800581b93a224fb5c2 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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,
        ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
                          "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
                          &region_obj->region.handler->address_space, handler,
-                         ACPI_FORMAT_UINT64(address),
+                         ACPI_FORMAT_NATIVE_UINT(address),
                          acpi_ut_get_region_name(region_obj->region.
                                                  space_id)));
 
index b1aaa0e84588f136b0d17b4bb7f71a78fe4313aa..2e3d2c5e4f4d2a7a7b4571475646fe970733f1e3 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7e5d15ce2395fd0cec232c0146ef8253c658495a..2a8b77877610a13df05762d10a9a77ce4adf8eb1 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6d866a01f5f439e06f79624de1bd268267b93f2a..94a6efe020bed116118c408e92f35f30a0d23a2e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -758,6 +758,12 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
  *
  * 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)
 {
@@ -770,14 +776,19 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
        /* Must lock interpreter to prevent race conditions */
 
        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)) {
-               acpi_gbl_global_lock_handle++;
+
+               /* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */
+
                *handle = acpi_gbl_global_lock_handle;
        }
 
+       acpi_ex_exit_interpreter();
        return (status);
 }
 
@@ -798,11 +809,11 @@ acpi_status acpi_release_global_lock(u32 handle)
 {
        acpi_status status;
 
-       if (handle != acpi_gbl_global_lock_handle) {
+       if (!handle || (handle != acpi_gbl_global_lock_handle)) {
                return (AE_NOT_ACQUIRED);
        }
 
-       status = acpi_ev_release_global_lock();
+       status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
        return (status);
 }
 
index 9cbd3414a574ebf4cad5c94f54a7f95883363189..99a7502e6a87465894e262b566b99f2a8dec35bf 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7bf09c5fb2421a5fa42a6a9001115aa3f4490665..e8750807e57d004151fab56cc56198f73acb29b6 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 25802f302ffe18c00608ff5ae347f79931b57645..24da921d13e3b2112048b428f97a43298bb7c1c9 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,6 @@
 #include <acpi/acinterp.h>
 #include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acevents.h>
 #include <acpi/actables.h>
 #include <acpi/acdispat.h>
 
@@ -138,6 +137,14 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
 
        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 */
 
        status = acpi_tb_find_table(operand[0]->string.pointer,
@@ -229,11 +236,18 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
        status = acpi_get_table_by_index(table_index, &table);
        if (ACPI_SUCCESS(status)) {
                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->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_ACPI_STATUS(status);
 }
@@ -268,6 +282,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
        struct acpi_table_desc table_desc;
        acpi_native_uint table_index;
        acpi_status status;
+       u32 length;
 
        ACPI_FUNCTION_TRACE(ex_load_op);
 
@@ -278,16 +293,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
        switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
        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) */
 
                if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
                        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,
                 * evaluate them now and save the results.
@@ -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.length = obj_desc->region.length;
                table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
@@ -306,18 +326,41 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 
        case ACPI_TYPE_BUFFER:  /* Buffer or resolved region_field */
 
-               /* Simply extract the buffer from the buffer object */
-
                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                                  "Load from Buffer or Field %p %s\n", obj_desc,
                                  acpi_ut_get_object_type_name(obj_desc)));
 
-               table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header,
-                                                  obj_desc->buffer.pointer);
-               table_desc.length = table_desc.pointer->length;
-               table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
+               length = obj_desc->buffer.length;
+
+               /* Must have at least an ACPI table header */
+
+               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;
 
        default:
@@ -333,7 +376,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
        }
 
        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)) {
 
                /* On error, table_ptr was deallocated above */
@@ -349,11 +393,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 
                /* table_ptr was deallocated above */
 
+               acpi_ut_remove_reference(ddb_handle);
                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:
        if (ACPI_FAILURE(status)) {
+
+               /* Delete allocated buffer or mapping */
+
                acpi_tb_delete_table(&table_desc);
        }
        return_ACPI_STATUS(status);
@@ -376,6 +432,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
        acpi_status status = AE_OK;
        union acpi_operand_object *table_desc = ddb_handle;
        acpi_native_uint table_index;
+       struct acpi_table_header *table;
 
        ACPI_FUNCTION_TRACE(ex_unload_table);
 
@@ -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;
 
+       /* 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
         * (Offset contains the table_id)
         */
        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);
 
-       /* Delete the table descriptor (ddb_handle) */
-
-       acpi_ut_remove_reference(table_desc);
-       return_ACPI_STATUS(status);
+       return_ACPI_STATUS(AE_OK);
 }
index 79f2c0d42c06a59ff5a56b8c4062371aeb18362b..fd954b4ed83d7fc1cfdbaaa4a42c41e9fbc89473 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6e9a23e47fef38e5c39497daa0c46a713d3ee726..60e62c4f0577aae22c5171500bfc6236b0b75285 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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)
         * to the original Node.
         */
        switch (target_node->type) {
+
+               /* For these types, the sub-object can change dynamically via a Store */
+
        case ACPI_TYPE_INTEGER:
        case ACPI_TYPE_STRING:
        case ACPI_TYPE_BUFFER:
        case ACPI_TYPE_PACKAGE:
        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
-                * NS node, not the object itself.  This is because for these
-                * types, the object can change dynamically via a Store.
+                * NS node, not the object itself.
                 */
                alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
                alias_node->object =
@@ -115,9 +127,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
        case ACPI_TYPE_METHOD:
 
                /*
-                * The new alias has the type ALIAS and points to the original
-                * NS node, not the object itself.  This is because for these
-                * types, the object can change dynamically via a Store.
+                * Control method aliases need to be differentiated
                 */
                alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
                alias_node->object =
@@ -340,101 +350,6 @@ acpi_ex_create_region(u8 * aml_start,
        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
index 51c9c29987c3d102a857ecf8d30f937771b27da4..74f1b22601b39b4b5106966d211c12fdd62946ee 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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)
                        acpi_os_printf("Reference: Debug\n");
                        break;
 
-               case AML_NAME_OP:
+               case AML_INDEX_OP:
 
-                       ACPI_DUMP_PATHNAME(obj_desc->reference.object,
-                                          "Reference: Name: ", ACPI_LV_INFO,
-                                          _COMPONENT);
-                       ACPI_DUMP_ENTRY(obj_desc->reference.object,
-                                       ACPI_LV_INFO);
+                       acpi_os_printf("Reference: Index %p\n",
+                                      obj_desc->reference.object);
                        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);
                        break;
 
                case AML_REF_OF_OP:
 
-                       acpi_os_printf("Reference: (RefOf) %p\n",
-                                      obj_desc->reference.object);
+                       acpi_os_printf("Reference: (RefOf) %p [%s]\n",
+                                      obj_desc->reference.object,
+                                      acpi_ut_get_type_name(((union
+                                                              acpi_operand_object
+                                                              *)obj_desc->
+                                                             reference.
+                                                             object)->common.
+                                                            type));
                        break;
 
                case AML_ARG_OP:
@@ -559,8 +562,9 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
 
                case AML_INT_NAMEPATH_OP:
 
-                       acpi_os_printf("Reference.Node->Name %X\n",
-                                      obj_desc->reference.node->name.integer);
+                       acpi_os_printf("Reference: Namepath %X [%4.4s]\n",
+                                      obj_desc->reference.node->name.integer,
+                                      obj_desc->reference.node->name.ascii);
                        break;
 
                default:
@@ -640,8 +644,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
                        acpi_os_printf("\n");
                } else {
                        acpi_os_printf(" base %8.8X%8.8X Length %X\n",
-                                      ACPI_FORMAT_UINT64(obj_desc->region.
-                                                         address),
+                                      ACPI_FORMAT_NATIVE_UINT(obj_desc->region.
+                                                              address),
                                       obj_desc->region.length);
                }
                break;
@@ -877,20 +881,43 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
        ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 
        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 =
                    acpi_ns_handle_to_pathname(obj_desc->reference.node,
                                               &ret_buf);
                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 {
                        acpi_os_printf("%s\n", (char *)ret_buf.pointer);
                        ACPI_FREE(ret_buf.pointer);
                }
        } else if (obj_desc->reference.object) {
-               acpi_os_printf("\nReferenced Object: %p\n",
-                              obj_desc->reference.object);
+               if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
+                   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,
 
        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);
                break;
 
index 2d88a3d8d1ad5f75815c5b5fcf0f0aec9ef48927..3e440d84226a4e85aea18a5b49156145e1bfbfd7 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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,
        union acpi_operand_object *buffer_desc;
        acpi_size length;
        void *buffer;
-       u8 locked;
 
        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,
 
                /* 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.
@@ -125,7 +122,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
                                                             buffer.pointer),
                                               ACPI_READ | (obj_desc->field.
                                                            attribute << 16));
-               acpi_ex_release_global_lock(locked);
+               acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
                goto exit;
        }
 
@@ -175,13 +172,12 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
 
        /* 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 */
 
        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:
        if (ACPI_FAILURE(status)) {
@@ -214,10 +210,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
 {
        acpi_status status;
        u32 length;
-       u32 required_length;
        void *buffer;
-       void *new_buffer;
-       u8 locked;
        union acpi_operand_object *buffer_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,
 
                /* 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
@@ -291,7 +282,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
                                               (acpi_integer *) buffer,
                                               ACPI_WRITE | (obj_desc->field.
                                                             attribute << 16));
-               acpi_ex_release_global_lock(locked);
+               acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
 
                *result_desc = buffer_desc;
                return_ACPI_STATUS(status);
@@ -319,35 +310,6 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
                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,
                          "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
                          source_desc,
@@ -366,19 +328,12 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
 
        /* 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 */
 
        status = acpi_ex_insert_into_field(obj_desc, buffer, length);
-       acpi_ex_release_global_lock(locked);
-
-       /* Free temporary buffer if we used one */
-
-       if (new_buffer) {
-               ACPI_FREE(new_buffer);
-       }
+       acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
 
        return_ACPI_STATUS(status);
 }
index 65a48b6170ee3c9803771cad7a58c2caecc04b77..e336b5dc7a50431720fa4aa437b85c5f1fd0ff94 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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,
                              rgn_desc->region.space_id,
                              obj_desc->common_field.access_byte_width,
                              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 */
 
@@ -805,18 +806,39 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
        u32 datum_count;
        u32 field_datum_count;
        u32 i;
+       u32 required_length;
+       void *new_buffer;
 
        ACPI_FUNCTION_TRACE(ex_insert_into_field);
 
        /* Validate input buffer */
 
-       if (buffer_length <
-           ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {
-               ACPI_ERROR((AE_INFO,
-                           "Field size %X (bits) is too large for buffer (%X)",
-                           obj_desc->common_field.bit_length, buffer_length));
+       new_buffer = NULL;
+       required_length =
+           ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_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,
                                                        merged_datum,
                                                        field_offset);
                if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
+                       goto exit;
                }
 
                field_offset += obj_desc->common_field.access_byte_width;
@@ -924,5 +946,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
                                                mask, merged_datum,
                                                field_offset);
 
+      exit:
+       /* Free temporary buffer if we used one */
+
+       if (new_buffer) {
+               ACPI_FREE(new_buffer);
+       }
        return_ACPI_STATUS(status);
 }
index f13d1cec2d6db1a3d277a916e10ea0f8564d4dda..cc956a5b5267b5e0564b2836b235803bfc170182 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6748e3ef09972472d9aeeaeaa1abf639773a77a8..c873ab40cd0ec59835a426d984eb0f261fe6deb6 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -124,6 +124,79 @@ acpi_ex_link_mutex(union acpi_operand_object *obj_desc,
        thread->acquired_mutex_list = obj_desc;
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_acquire_mutex_object
+ *
+ * PARAMETERS:  time_desc           - Timeout in milliseconds
+ *              obj_desc            - Mutex object
+ *              Thread              - Current thread state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Acquire an AML mutex, low-level interface. Provides a common
+ *              path that supports multiple acquires by the same thread.
+ *
+ * MUTEX:       Interpreter must be locked
+ *
+ * NOTE: This interface is called from three places:
+ * 1) From acpi_ex_acquire_mutex, via an AML Acquire() operator
+ * 2) From acpi_ex_acquire_global_lock when an AML Field access requires the
+ *    global lock
+ * 3) From the external interface, acpi_acquire_global_lock
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_acquire_mutex_object(u16 timeout,
+                            union acpi_operand_object *obj_desc,
+                            acpi_thread_id thread_id)
+{
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE_PTR(ex_acquire_mutex_object, obj_desc);
+
+       if (!obj_desc) {
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       /* Support for multiple acquires by the owning thread */
+
+       if (obj_desc->mutex.thread_id == thread_id) {
+               /*
+                * The mutex is already owned by this thread, just increment the
+                * acquisition depth
+                */
+               obj_desc->mutex.acquisition_depth++;
+               return_ACPI_STATUS(AE_OK);
+       }
+
+       /* Acquire the mutex, wait if necessary. Special case for Global Lock */
+
+       if (obj_desc == acpi_gbl_global_lock_mutex) {
+               status = acpi_ev_acquire_global_lock(timeout);
+       } else {
+               status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex,
+                                                  timeout);
+       }
+
+       if (ACPI_FAILURE(status)) {
+
+               /* Includes failure from a timeout on time_desc */
+
+               return_ACPI_STATUS(status);
+       }
+
+       /* Acquired the mutex: update mutex object */
+
+       obj_desc->mutex.thread_id = thread_id;
+       obj_desc->mutex.acquisition_depth = 1;
+       obj_desc->mutex.original_sync_level = 0;
+       obj_desc->mutex.owner_thread = NULL;    /* Used only for AML Acquire() */
+
+       return_ACPI_STATUS(AE_OK);
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ex_acquire_mutex
@@ -151,7 +224,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
-       /* Sanity check: we must have a valid thread ID */
+       /* Must have a valid thread ID */
 
        if (!walk_state->thread) {
                ACPI_ERROR((AE_INFO,
@@ -161,7 +234,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
        }
 
        /*
-        * Current Sync must be less than or equal to the sync level of the
+        * Current sync level must be less than or equal to the sync level of the
         * mutex. This mechanism provides some deadlock prevention
         */
        if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
@@ -172,51 +245,89 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
                return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
        }
 
-       /* Support for multiple acquires by the owning thread */
+       status = acpi_ex_acquire_mutex_object((u16) time_desc->integer.value,
+                                             obj_desc,
+                                             walk_state->thread->thread_id);
+       if (ACPI_SUCCESS(status) && obj_desc->mutex.acquisition_depth == 1) {
 
-       if (obj_desc->mutex.owner_thread) {
-               if (obj_desc->mutex.owner_thread->thread_id ==
-                   walk_state->thread->thread_id) {
-                       /*
-                        * The mutex is already owned by this thread, just increment the
-                        * acquisition depth
-                        */
-                       obj_desc->mutex.acquisition_depth++;
-                       return_ACPI_STATUS(AE_OK);
-               }
+               /* Save Thread object, original/current sync levels */
+
+               obj_desc->mutex.owner_thread = walk_state->thread;
+               obj_desc->mutex.original_sync_level =
+                   walk_state->thread->current_sync_level;
+               walk_state->thread->current_sync_level =
+                   obj_desc->mutex.sync_level;
+
+               /* Link the mutex to the current thread for force-unlock at method exit */
+
+               acpi_ex_link_mutex(obj_desc, walk_state->thread);
        }
 
-       /* Acquire the mutex, wait if necessary. Special case for Global Lock */
+       return_ACPI_STATUS(status);
+}
 
-       if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
-               status =
-                   acpi_ev_acquire_global_lock((u16) time_desc->integer.value);
-       } else {
-               status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex,
-                                                  (u16) time_desc->integer.
-                                                  value);
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_release_mutex_object
+ *
+ * PARAMETERS:  obj_desc            - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release a previously acquired Mutex, low level interface.
+ *              Provides a common path that supports multiple releases (after
+ *              previous multiple acquires) by the same thread.
+ *
+ * MUTEX:       Interpreter must be locked
+ *
+ * NOTE: This interface is called from three places:
+ * 1) From acpi_ex_release_mutex, via an AML Acquire() operator
+ * 2) From acpi_ex_release_global_lock when an AML Field access requires the
+ *    global lock
+ * 3) From the external interface, acpi_release_global_lock
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc)
+{
+       acpi_status status = AE_OK;
+
+       ACPI_FUNCTION_TRACE(ex_release_mutex_object);
+
+       if (obj_desc->mutex.acquisition_depth == 0) {
+               return (AE_NOT_ACQUIRED);
        }
 
-       if (ACPI_FAILURE(status)) {
+       /* Match multiple Acquires with multiple Releases */
 
-               /* Includes failure from a timeout on time_desc */
+       obj_desc->mutex.acquisition_depth--;
+       if (obj_desc->mutex.acquisition_depth != 0) {
 
-               return_ACPI_STATUS(status);
+               /* Just decrement the depth and return */
+
+               return_ACPI_STATUS(AE_OK);
        }
 
-       /* Have the mutex: update mutex and walk info and save the sync_level */
+       if (obj_desc->mutex.owner_thread) {
 
-       obj_desc->mutex.owner_thread = walk_state->thread;
-       obj_desc->mutex.acquisition_depth = 1;
-       obj_desc->mutex.original_sync_level =
-           walk_state->thread->current_sync_level;
+               /* Unlink the mutex from the owner's list */
 
-       walk_state->thread->current_sync_level = obj_desc->mutex.sync_level;
+               acpi_ex_unlink_mutex(obj_desc);
+               obj_desc->mutex.owner_thread = NULL;
+       }
 
-       /* Link the mutex to the current thread for force-unlock at method exit */
+       /* Release the mutex, special case for Global Lock */
 
-       acpi_ex_link_mutex(obj_desc, walk_state->thread);
-       return_ACPI_STATUS(AE_OK);
+       if (obj_desc == acpi_gbl_global_lock_mutex) {
+               status = acpi_ev_release_global_lock();
+       } else {
+               acpi_os_release_mutex(obj_desc->mutex.os_mutex);
+       }
+
+       /* Clear mutex info */
+
+       obj_desc->mutex.thread_id = 0;
+       return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -253,22 +364,13 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
                return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
        }
 
-       /* Sanity check: we must have a valid thread ID */
-
-       if (!walk_state->thread) {
-               ACPI_ERROR((AE_INFO,
-                           "Cannot release Mutex [%4.4s], null thread info",
-                           acpi_ut_get_node_name(obj_desc->mutex.node)));
-               return_ACPI_STATUS(AE_AML_INTERNAL);
-       }
-
        /*
         * The Mutex is owned, but this thread must be the owner.
         * Special case for Global Lock, any thread can release
         */
        if ((obj_desc->mutex.owner_thread->thread_id !=
             walk_state->thread->thread_id)
-           && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) {
+           && (obj_desc != acpi_gbl_global_lock_mutex)) {
                ACPI_ERROR((AE_INFO,
                            "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
                            (unsigned long)walk_state->thread->thread_id,
@@ -278,45 +380,37 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
                return_ACPI_STATUS(AE_AML_NOT_OWNER);
        }
 
+       /* Must have a valid thread ID */
+
+       if (!walk_state->thread) {
+               ACPI_ERROR((AE_INFO,
+                           "Cannot release Mutex [%4.4s], null thread info",
+                           acpi_ut_get_node_name(obj_desc->mutex.node)));
+               return_ACPI_STATUS(AE_AML_INTERNAL);
+       }
+
        /*
         * The sync level of the mutex must be less than or equal to the current
         * sync level
         */
        if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
                ACPI_ERROR((AE_INFO,
-                           "Cannot release Mutex [%4.4s], incorrect SyncLevel",
-                           acpi_ut_get_node_name(obj_desc->mutex.node)));
+                           "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d",
+                           acpi_ut_get_node_name(obj_desc->mutex.node),
+                           obj_desc->mutex.sync_level,
+                           walk_state->thread->current_sync_level));
                return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
        }
 
-       /* Match multiple Acquires with multiple Releases */
-
-       obj_desc->mutex.acquisition_depth--;
-       if (obj_desc->mutex.acquisition_depth != 0) {
-
-               /* Just decrement the depth and return */
-
-               return_ACPI_STATUS(AE_OK);
-       }
-
-       /* Unlink the mutex from the owner's list */
+       status = acpi_ex_release_mutex_object(obj_desc);
 
-       acpi_ex_unlink_mutex(obj_desc);
+       if (obj_desc->mutex.acquisition_depth == 0) {
 
-       /* Release the mutex, special case for Global Lock */
+               /* Restore the original sync_level */
 
-       if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
-               status = acpi_ev_release_global_lock();
-       } else {
-               acpi_os_release_mutex(obj_desc->mutex.os_mutex);
+               walk_state->thread->current_sync_level =
+                   obj_desc->mutex.original_sync_level;
        }
-
-       /* Update the mutex and restore sync_level */
-
-       obj_desc->mutex.owner_thread = NULL;
-       walk_state->thread->current_sync_level =
-           obj_desc->mutex.original_sync_level;
-
        return_ACPI_STATUS(status);
 }
 
@@ -357,7 +451,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
 
                /* Release the mutex, special case for Global Lock */
 
-               if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
+               if (obj_desc == acpi_gbl_global_lock_mutex) {
 
                        /* Ignore errors */
 
@@ -369,6 +463,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
                /* Mark mutex unowned */
 
                obj_desc->mutex.owner_thread = NULL;
+               obj_desc->mutex.thread_id = 0;
 
                /* Update Thread sync_level (Last mutex is the important one) */
 
index 308eae52dc054d72c670fb8bccc8a90f6dd7e93d..817e67be36977c12aa7db442217ecf25c87676f3 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 252f10acbbccc3436a4def9c1ac305509fc6f0e1..7c3bea575e02653c2960a472c4b994a48ce9574b 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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)
 
        if ((ACPI_FAILURE(status)) || walk_state->result_obj) {
                acpi_ut_remove_reference(return_desc);
+               walk_state->result_obj = NULL;
        } else {
                /* Save the return value */
 
@@ -739,26 +740,38 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
                        value = acpi_gbl_integer_byte_width;
                        break;
 
-               case ACPI_TYPE_BUFFER:
-                       value = temp_desc->buffer.length;
-                       break;
-
                case ACPI_TYPE_STRING:
                        value = temp_desc->string.length;
                        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:
+
+                       /* Package arguments may not be evaluated at this point */
+
+                       status = acpi_ds_get_package_arguments(temp_desc);
                        value = temp_desc->package.count;
                        break;
 
                default:
                        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)));
                        status = AE_AML_OPERAND_TYPE;
                        goto cleanup;
                }
 
+               if (ACPI_FAILURE(status)) {
+                       goto cleanup;
+               }
+
                /*
                 * Now that we have the size of the object, create a result
                 * object to hold the value
index 17e652e653799f97c9d88de6fd9e3d1a166f0ce3..8e8bbb6ccebd541008b0f15caa2ffacbe62eaf34 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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)
                goto cleanup;
        }
 
-       /* Return the remainder */
-
-       walk_state->result_obj = return_desc1;
-
       cleanup:
        /*
         * 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)
                acpi_ut_remove_reference(return_desc1);
        }
 
+       /* Save return object (the remainder) on success */
+
+       else {
+               walk_state->result_obj = return_desc1;
+       }
+
        return_ACPI_STATUS(status);
 }
 
@@ -490,6 +492,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
 
        if (ACPI_FAILURE(status)) {
                acpi_ut_remove_reference(return_desc);
+               walk_state->result_obj = NULL;
        }
 
        return_ACPI_STATUS(status);
@@ -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;
        }
 
-       walk_state->result_obj = return_desc;
-
       cleanup:
 
        /* Delete return object on error */
@@ -593,5 +594,11 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state)
                acpi_ut_remove_reference(return_desc);
        }
 
+       /* Save return object on success */
+
+       else {
+               walk_state->result_obj = return_desc;
+       }
+
        return_ACPI_STATUS(status);
 }
index 7fe67cf82cee016e47f3699aee0b2eb1d57ab407..9cb4197681af11a6d7e2d59904781cb3e0cee05e 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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)
 
        if (ACPI_FAILURE(status) || walk_state->result_obj) {
                acpi_ut_remove_reference(return_desc);
+               walk_state->result_obj = NULL;
        }
 
        /* Set the return object and exit */
index bd80a9cb3d6529bce2a2804800639e4d0578d93c..67d48737af5360011b7facec5aa909d62f2d9425 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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)
                goto cleanup;
        }
 
-       walk_state->result_obj = return_desc;
-
       cleanup:
 
        /* Delete return object on error */
@@ -332,5 +330,11 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state)
                acpi_ut_remove_reference(return_desc);
        }
 
+       /* Save return object on success */
+
+       else {
+               walk_state->result_obj = return_desc;
+       }
+
        return_ACPI_STATUS(status);
 }
index efe5d4b461a47a7c91351608ce876ffc76de1566..3a2f8cd4c62a9bffc6d27c25ed2b4bff3c112c0c 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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,
 acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
 {
        union acpi_operand_object *obj_desc;
+       union acpi_operand_object *second_desc = NULL;
        u32 type;
        acpi_status status;
 
@@ -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->bank_field.region_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;
 
        case ACPI_TYPE_LOCAL_INDEX_FIELD:
index 3f51b7e84a17f532801dd47bdff391f5252bcc55..7cd8bb54fa016ba38aa07a7f1109e8304a7a8c05 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -160,7 +160,7 @@ acpi_ex_system_memory_space_handler(u32 function,
                if (!mem_info->mapped_logical_address) {
                        ACPI_ERROR((AE_INFO,
                                    "Could not map memory at %8.8X%8.8X, size %X",
-                                   ACPI_FORMAT_UINT64(address),
+                                   ACPI_FORMAT_NATIVE_UINT(address),
                                    (u32) window_size));
                        mem_info->mapped_length = 0;
                        return_ACPI_STATUS(AE_NO_MEMORY);
@@ -182,7 +182,8 @@ acpi_ex_system_memory_space_handler(u32 function,
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                          "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
@@ -284,7 +285,8 @@ acpi_ex_system_io_space_handler(u32 function,
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                          "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 */
 
index 2b3a01cc4929e2bf9b0dbd7c2f22707a89d3fdd2..5596f42c9676038c329f6f3d0f473773adbfcb3f 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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,
         * Several object types require no further processing:
         * 1) Device/Thermal objects don't have a "real" subobject, return the 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) ||
            (entry_type == ACPI_TYPE_THERMAL) ||
+           (entry_type == ACPI_TYPE_METHOD) ||
            (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
                return_ACPI_STATUS(AE_OK);
        }
@@ -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 */
 
        case ACPI_TYPE_MUTEX:
-       case ACPI_TYPE_METHOD:
        case ACPI_TYPE_POWER:
        case ACPI_TYPE_PROCESSOR:
        case ACPI_TYPE_EVENT:
@@ -238,13 +239,12 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
        case ACPI_TYPE_LOCAL_REFERENCE:
 
                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 */
 
-               case AML_REF_OF_OP:
-
                        obj_desc = source_desc;
                        acpi_ut_add_reference(obj_desc);
                        break;
index 6c64e55dab0e467178948fb8082fc7f9e4e89041..b35f7c817acf169a244b21e052d09d26db074504 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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,
 {
        acpi_status status = AE_OK;
        union acpi_operand_object *stack_desc;
-       void *temp_node;
        union acpi_operand_object *obj_desc = NULL;
        u16 opcode;
 
@@ -156,23 +155,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                opcode = stack_desc->reference.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_ARG_OP:
 
@@ -207,15 +189,25 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                        switch (stack_desc->reference.target_type) {
                        case ACPI_TYPE_BUFFER_FIELD:
 
-                               /* Just return - leave the Reference on the stack */
+                               /* Just return - do not dereference */
                                break;
 
                        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;
                                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)
                                         * Delete the ref object, increment the returned object
                                         */
@@ -224,11 +216,11 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                                        *stack_ptr = obj_desc;
                                } 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
                                         */
                                        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));
                                        status = AE_AML_UNINITIALIZED_ELEMENT;
                                }
@@ -239,7 +231,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                                /* Invalid reference object */
 
                                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));
                                status = AE_AML_INTERNAL;
@@ -251,7 +243,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                case AML_DEBUG_OP:
                case AML_LOAD_OP:
 
-                       /* Just leave the object as-is */
+                       /* Just leave the object as-is, do not dereference */
 
                        break;
 
@@ -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,
-        * we need to get to the base object (as per the ACPI specification
-        * of the object_type and size_of operators). This means traversing
-        * the list of possibly many nested references.
+        * For reference objects created via the ref_of, Index, or Load/load_table
+        * operators, we need to get to the base object (as per the ACPI
+        * specification of the object_type and size_of operators). This means
+        * traversing the list of possibly many nested references.
         */
        while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
                switch (obj_desc->reference.opcode) {
@@ -463,6 +455,11 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
                        }
                        break;
 
+               case AML_LOAD_OP:
+
+                       type = ACPI_TYPE_DDB_HANDLE;
+                       goto exit;
+
                case AML_LOCAL_OP:
                case AML_ARG_OP:
 
index 09d897b3f6d5b1848490eac18b9d09370409f782..73e29e566a70450eca74348cbfa3a723316999f6 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -137,7 +137,6 @@ acpi_ex_resolve_operands(u16 opcode,
        union acpi_operand_object *obj_desc;
        acpi_status status = AE_OK;
        u8 object_type;
-       void *temp_node;
        u32 arg_types;
        const struct acpi_opcode_info *op_info;
        u32 this_arg_type;
@@ -239,7 +238,6 @@ acpi_ex_resolve_operands(u16 opcode,
 
                                        /*lint -fallthrough */
 
-                               case AML_NAME_OP:
                                case AML_INDEX_OP:
                                case AML_REF_OF_OP:
                                case AML_ARG_OP:
@@ -332,15 +330,6 @@ acpi_ex_resolve_operands(u16 opcode,
                        if (ACPI_FAILURE(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;
 
                case ARGI_DATAREFOBJ:   /* Store operator only */
index f4b69a63782091ffe4ba226c397793344bf6aede..76c875bc3154cf8ff799efd80fc6ae3d047aab0c 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * 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,
 
        ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc);
 
-       ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
-                             level, " "));
+       /* Print line header as long as we are not in the middle of an object display */
+
+       if (!((level > 0) && index == 0)) {
+               ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
+                                     level, " "));
+       }
 
        /* Display index for package output only */
 
@@ -95,12 +99,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *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;
        }
 
        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
                                      (source_desc)));
 
@@ -123,6 +127,8 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
                return_VOID;
        }
 
+       /* source_desc is of type ACPI_DESC_TYPE_OPERAND */
+
        switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
        case ACPI_TYPE_INTEGER:
 
@@ -147,7 +153,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
                                      (u32) source_desc->buffer.length));
                ACPI_DUMP_BUFFER(source_desc->buffer.pointer,
                                 (source_desc->buffer.length <
-                                 32) ? source_desc->buffer.length : 32);
+                                 256) ? source_desc->buffer.length : 256);
                break;
 
        case ACPI_TYPE_STRING:
@@ -160,7 +166,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
        case ACPI_TYPE_PACKAGE:
 
                ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
-                                     "[0x%.2X Elements]\n",
+                                     "[Contains 0x%.2X Elements]\n",
                                      source_desc->package.count));
 
                /* Output the entire contents of the package */
@@ -180,12 +186,59 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
                                              (source_desc->reference.opcode),
                                              source_desc->reference.offset));
                } 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
                                              (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
                            (source_desc->reference.object) ==
                            ACPI_DESC_TYPE_NAMED) {
@@ -198,18 +251,13 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
                                acpi_ex_do_debug_object(source_desc->reference.
                                                        object, level + 4, 0);
                        }
-               } else if (source_desc->reference.node) {
-                       acpi_ex_do_debug_object((source_desc->reference.node)->
-                                               object, level + 4, 0);
                }
                break;
 
        default:
 
-               ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p %s\n",
-                                     source_desc,
-                                     acpi_ut_get_object_type_name
-                                     (source_desc)));
+               ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p\n",
+                                     source_desc));
                break;
        }
 
@@ -313,7 +361,6 @@ acpi_ex_store(union acpi_operand_object *source_desc,
         * 4) Store to the debug object
         */
        switch (ref_desc->reference.opcode) {
-       case AML_NAME_OP:
        case AML_REF_OF_OP:
 
                /* Storing an object into a Name "container" */
@@ -415,11 +462,24 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
                 */
                obj_desc = *(index_desc->reference.where);
 
-               status =
-                   acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc,
-                                                   walk_state);
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
+               if (ACPI_GET_OBJECT_TYPE(source_desc) ==
+                   ACPI_TYPE_LOCAL_REFERENCE
+                   && source_desc->reference.opcode == AML_LOAD_OP) {
+
+                       /* 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) {
@@ -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 ((!implicit_conversion) || (walk_state->opcode == AML_COPY_OP)) {
-
-               /* Force execution of default (no implicit conversion) */
-
+       if ((!implicit_conversion) ||
+           ((walk_state->opcode == AML_COPY_OP) &&
+            (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;
        }
 
index 1d622c625c6406bc91a7e7b0f7542e4be107f955..a6d2168b81f99f9301f091ba3cf6ba4a0eb48b1d 100644 (file)
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 8233d40178eed88a5d6863578ff9f78451a7b2ea..9a75ff09fb0c46b38bf849261d6b860949251cf7 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9460baff30328f4c5565e2c5d671eabfdf4f634c..68990f1df371df76886f196ecbc5d42a7a867da3 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acinterp.h>
-#include <acpi/acevents.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exsystem")
index 6b0aeccbb69b3f59738d5a9dd22fe875a1a2d018..86c03880b5233a32a524d7efc5a583c4fb73ea7e 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -61,7 +61,6 @@
 #include <acpi/acpi.h>
 #include <acpi/acinterp.h>
 #include <acpi/amlcode.h>
-#include <acpi/acevents.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exutils")
@@ -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
-        * a control method
+        * a control method. NS node could be there for AML_INT_NAMEPATH_OP.
         */
        if ((!obj_desc) ||
+           (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
            (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
                return;
        }
@@ -240,72 +240,73 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
  * PARAMETERS:  field_flags           - Flags with Lock rule:
  *                                      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
- *              methods.  A global variable keeps the state of the lock, and
- *              the state is returned to the caller.
+ * DESCRIPTION: Obtain the ACPI hardware Global Lock, only if the field
+ *              flags specifiy that it is to be obtained before field access.
  *
  ******************************************************************************/
 
-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_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_SUCCESS(status)) {
-                       locked = TRUE;
-               } else {
-                       ACPI_EXCEPTION((AE_INFO, status,
-                                       "Could not acquire Global Lock"));
-               }
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status,
+                               "Could not acquire Global Lock"));
        }
 
-       return_UINT8(locked);
+       return_VOID;
 }
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ex_release_global_lock
  *
- * PARAMETERS:  locked_by_me    - Return value from corresponding call to
- *                                acquire_global_lock.
+ * PARAMETERS:  field_flags           - Flags with Lock rule:
+ *                                      always_lock or never_lock
  *
  * 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_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();
-               if (ACPI_FAILURE(status)) {
+       status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
+       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,
-                                       "Could not release ACPI Global Lock"));
-               }
+               ACPI_EXCEPTION((AE_INFO, status,
+                               "Could not release Global Lock"));
        }
 
        return_VOID;
index 194077ab9b85859c5077a9ec26ccf6a94d89be56..6cf10cbc1eee41687e462d14168827d6830b4cb0 100644 (file)
@@ -256,24 +256,23 @@ static int acpi_fan_add(struct acpi_device *device)
                result = PTR_ERR(cdev);
                goto end;
        }
-       if (cdev) {
-               printk(KERN_INFO PREFIX
-                       "%s is registered as cooling_device%d\n",
-                       device->dev.bus_id, cdev->id);
-
-               acpi_driver_data(device) = cdev;
-               result = sysfs_create_link(&device->dev.kobj,
-                                          &cdev->device.kobj,
-                                          "thermal_cooling");
-               if (result)
-                       return result;
-
-               result = sysfs_create_link(&cdev->device.kobj,
-                                          &device->dev.kobj,
-                                          "device");
-               if (result)
-                       return result;
-       }
+
+       printk(KERN_INFO PREFIX
+               "%s is registered as cooling_device%d\n",
+               device->dev.bus_id, cdev->id);
+
+       acpi_driver_data(device) = cdev;
+       result = sysfs_create_link(&device->dev.kobj,
+                                  &cdev->device.kobj,
+                                  "thermal_cooling");
+       if (result)
+               printk(KERN_ERR PREFIX "Create sysfs link\n");
+
+       result = sysfs_create_link(&cdev->device.kobj,
+                                  &device->dev.kobj,
+                                  "device");
+       if (result)
+               printk(KERN_ERR PREFIX "Create sysfs link\n");
 
        result = acpi_fan_add_fs(device);
        if (result)
index eda0978b57c6946b9580ab24869794a2bc14b2bd..06f8634fe58b192498ad73c5e4d4a4e715b01cf3 100644 (file)
@@ -142,6 +142,7 @@ EXPORT_SYMBOL(acpi_get_physical_device);
 
 static int acpi_bind_one(struct device *dev, acpi_handle handle)
 {
+       struct acpi_device *acpi_dev;
        acpi_status status;
 
        if (dev->archdata.acpi_handle) {
@@ -157,6 +158,16 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
        }
        dev->archdata.acpi_handle = handle;
 
+       status = acpi_bus_get_device(handle, &acpi_dev);
+       if (!ACPI_FAILURE(status)) {
+               int ret;
+
+               ret = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
+                               "firmware_node");
+               ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
+                               "physical_node");
+       }
+
        return 0;
 }
 
@@ -165,8 +176,17 @@ static int acpi_unbind_one(struct device *dev)
        if (!dev->archdata.acpi_handle)
                return 0;
        if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) {
+               struct acpi_device *acpi_dev;
+
                /* acpi_get_physical_device increase refcnt by one */
                put_device(dev);
+
+               if (!acpi_bus_get_device(dev->archdata.acpi_handle,
+                                       &acpi_dev)) {
+                       sysfs_remove_link(&dev->kobj, "firmware_node");
+                       sysfs_remove_link(&acpi_dev->dev.kobj, "physical_node");
+               }
+
                acpi_detach_data(dev->archdata.acpi_handle,
                                 acpi_glue_data_handler);
                dev->archdata.acpi_handle = NULL;
index 6031ca13dd2f2b9c73b66abb56aca71edd5f1d3b..816894ea839eba7fe21a85bd68f97f9329a715dc 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 117a05cadaaa9014ca2a6c5b29a5fa566accca08..14bc4f456ae8c3762889fef4c3badaf812f9977b 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 200