http://linux.bkbits.net/linux-2.5 torvalds@ppc970.osdl.org|ChangeSet|20040814105640|52346 torvalds # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/08/14 03:56:40-07:00 torvalds@ppc970.osdl.org # Merge ppc970.osdl.org:/home/torvalds/v2.6/v2.6.8.1 # into ppc970.osdl.org:/home/torvalds/v2.6/linux # # fs/nfs/file.c # 2004/08/14 03:56:19-07:00 torvalds@ppc970.osdl.org +0 -2 # Auto merged # # ChangeSet # 2004/08/14 03:44:08-07:00 torvalds@ppc970.osdl.org # Fix stupid thinkos in the fcntl f_op removal code. # # Tssk. # # fs/nfs/file.c # 2004/08/14 03:44:02-07:00 torvalds@ppc970.osdl.org +2 -2 # Fix stupid thinkos in the fcntl f_op removal code. # # Tssk. # # ChangeSet # 2004/08/14 03:24:55-07:00 torvalds@ppc970.osdl.org # Make 'WRITE_BUFFER' require CAP_RAWIO capability # # Pointed out by Kai Makisara. # # drivers/block/scsi_ioctl.c # 2004/08/14 03:24:49-07:00 torvalds@ppc970.osdl.org +0 -1 # Make 'WRITE_BUFFER' require CAP_RAWIO capability # # Pointed out by Kai Makisara. # # ChangeSet # 2004/08/14 02:32:45-04:00 len.brown@intel.com # merge # # arch/i386/kernel/dmi_scan.c # 2004/08/14 02:32:39-04:00 len.brown@intel.com +0 -6 # merge # # init/main.c # 2004/08/14 01:12:08-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/08/14 01:11:05-04:00 len.brown@intel.com # [ACPI] Enter ACPI mode earlier # Fixes two common boot failures due to buggy SMM BIOS code # # SMP boot crash if SMI_CMD=ACPI written from CPU1 # http://bugzilla.kernel.org/show_bug.cgi?id=2941 # # laptop crash due to LAPIC timer before SMI_CMD=ACPI # http://bugzilla.kernel.org/show_bug.cgi?id=1269 # # init/main.c # 2004/08/14 01:10:59-04:00 len.brown@intel.com +7 -0 # acpi_early_init() # # drivers/acpi/osl.c # 2004/08/14 01:10:58-04:00 len.brown@intel.com +10 -0 # defer acpi_os_initialize() to acpi_os_initialize1() # # drivers/acpi/bus.c # 2004/08/14 01:10:58-04:00 len.brown@intel.com +32 -6 # add acpi_early_init() # # arch/i386/kernel/dmi_scan.c # 2004/08/14 01:10:58-04:00 len.brown@intel.com +0 -44 # delete local_apic_kills_bios() # # ChangeSet # 2004/08/13 17:52:32-04:00 len.brown@intel.com # [ACPI] clean out blacklist entries that do nothing # # drivers/acpi/blacklist.c # 2004/08/13 17:52:26-04:00 len.brown@intel.com +0 -14 # delete blacklist entries that have no effect # # ChangeSet # 2004/08/11 12:05:47-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/linux-2.6.8 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # drivers/acpi/sleep/proc.c # 2004/08/11 12:05:44-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/08/09 13:03:19-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.7 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # drivers/acpi/scan.c # 2004/08/09 13:03:16-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/08/09 12:43:20-04:00 len.brown@intel.com # [ACPI] init wakeup devcies only if ACPI enabled (David Shaohua Li) # # drivers/acpi/sleep/wakeup.c # 2004/08/04 04:34:13-04:00 len.brown@intel.com +2 -0 # init wakeup devices only if ACPI enabled # # ChangeSet # 2004/08/09 12:23:17-04:00 len.brown@intel.com # [ACPI] acpi_bus_register_driver() now return a count # consistent with pnp_register_driver() and pci_register_driver() # # All existing callers of acpi_bus_register_driver() either ignore the # return value or check only for negative (error) return values. # # Signed-off-by: Bjorn Helgaas # # drivers/acpi/scan.c # 2004/07/29 13:43:17-04:00 len.brown@intel.com +15 -11 # acpi_bus_register_driver() now returns a count # # ChangeSet # 2004/08/09 12:11:05-04:00 len.brown@intel.com # [ACPI] acpi for asus update from Karol Kozimor # # support for L4R and M5N, moves some bits for M6N # and restores WLED functionality for M2N # comment and whitespace cleanups # fix get/set typo from /proc patch, delete trailing spaces # # drivers/acpi/asus_acpi.c # 2004/08/09 12:10:59-04:00 len.brown@intel.com +46 -19 # support for L4R and M5N, moves some bits for M6N # and restores WLED functionality for M2N # comment and whitespace cleanups # fix get/set typo from /proc patch, delete trailing spaces # # ChangeSet # 2004/08/08 01:28:20-04:00 len.brown@intel.com # [ACPI] acpi_system_write_wakeup_device() has the wrong return type # and is missing the __user attribution from its buffer argument. # This patch shuts up the resulting warnings on x86-64. # # From: William Lee Irwin III # Signed-off-by: Andrew Morton # # drivers/acpi/sleep/proc.c # 2004/08/08 01:02:39-04:00 len.brown@intel.com +2 -2 # acpi_system_write_wakeup_device() syntax # # ChangeSet # 2004/08/06 00:40:33-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/linux-2.6.8 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # arch/ia64/kernel/acpi.c # 2004/08/06 00:40:29-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/08/04 17:06:43-04:00 nbryant@optonline.net # [ACPI] restore PCI Interrupt Link Devices upon resume # # * register as as a sys_device so that we can get resume callbacks and restore # interrupt routing state. # * add acpi_pci_link_resume(), which will be called when resuming from a suspend # state that needs IRQ routing to be restored. This fixes issues reported on # the mailing lists, e.g.: # http://marc.theaimsgroup.com/?l=acpi4linux&m=109142999328643&w=2 # * rename setonboot --> initialized # * change to test acpi_noirq in init # # We want to initialize everything on S3 resume in case the BIOS points an # interrupt link somewhere we didn't expect. (Doing so avoids "missing interrupt" # or "irq x: nobody cared" problems.) According to Len, past experience has shown # that it's a good idea to initialize only devices that exist or were explicitly # asked for, so we try to initialize only the IRQ's that were previously # initialized at some point before suspend, by checking the "initialized" flag. # This corresponds to links that have PCI devices attached. Everything else, we # leave alone. Assuming the BIOS does the same thing on resume that it did on # boot, this will leave all the unused links in the same state that they were on # boot. # # We are registered as a sysdev in order to do this work fairly early during # resume, before devices are resumed; some devices may not call # pci_device_enable. # # Previous "setonboot once" behavior is left in place, to be conservative. # # drivers/acpi/pci_link.c # 2004/08/04 15:55:16-04:00 nbryant@optonline.net +72 -4 # acpi_pci_link_resume() # # ChangeSet # 2004/08/03 23:13:00-04:00 len.brown@intel.com # [ACPI] BIOS workaround allowing devices to use reserved IO ports # Author: David Shaohua Li # http://bugzilla.kernel.org/show_bug.cgi?id=3049 # # drivers/acpi/motherboard.c # 2004/08/03 23:12:54-04:00 len.brown@intel.com +16 -4 # BIOS workaround, allow devices to use reserved IOports if they insist.. # # ChangeSet # 2004/08/02 14:08:40-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/linux-2.6.8 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # arch/x86_64/kernel/i8259.c # 2004/08/02 14:08:35-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/io_apic.c # 2004/08/02 14:08:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/07/29 11:57:15-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/linux-2.6.8 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # arch/i386/kernel/io_apic.c # 2004/07/29 11:57:11-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/07/28 15:44:31-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/linux-2.6.8 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # arch/ia64/kernel/acpi.c # 2004/07/28 15:44:27-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/07/28 15:24:34-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.7 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # arch/x86_64/kernel/smpboot.c # 2004/07/28 15:24:29-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/07/28 15:17:02-04:00 len.brown@intel.com # [ACPI] fix build warning (Andrew Morton) # # arch/x86_64/kernel/smpboot.c # 2004/07/28 02:38:53-04:00 len.brown@intel.com +1 -0 # fix build warning (Andrew Morton) # # ChangeSet # 2004/07/28 14:46:34-04:00 len.brown@intel.com # [ACPI] synchronize_kernel for idle-loop unload (Zwane Mwaikambo) # http://bugzilla.kernel.org/show_bug.cgi?id=1716 # # drivers/acpi/processor.c # 2004/07/20 11:31:46-04:00 len.brown@intel.com +3 -1 # synchronize_kernel for idle-loop unload (Zwane Mwaikambo) # # ChangeSet # 2004/07/28 14:40:03-04:00 len.brown@intel.com # [ACPI] S3 is independent of CONFIG_X86_PAE (David Shaohua Li) # # arch/i386/kernel/acpi/sleep.c # 2004/07/28 05:15:45-04:00 len.brown@intel.com +1 -4 # S3 is independent of CONFIG_X86_PAE (David Shaohua Li) # # ChangeSet # 2004/07/26 16:47:18-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/linux-2.6.8 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # arch/x86_64/kernel/smpboot.c # 2004/07/26 16:47:15-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/mm/discontig.c # 2004/07/26 16:47:15-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/07/17 01:37:59-04:00 len.brown@intel.com # [ACPI] ACPICA 20040715 from Bob Moore # # Restructured the internal HW GPE interfaces to pass/track # the current state of interrupts (enabled/disabled) in # order to avoid possible deadlock and increase flexibility # of the interfaces. # # Implemented a "lexicographical compare" for String and # Buffer objects within the logical operators -- LGreater, # LLess, LGreaterEqual, and LLessEqual -- as per further # clarification to the ACPI specification. Behavior is # similar to C library "strcmp". # # Completed a major reduction in CPU stack use for the # acpi_get_firmware_table external function. In the 32-bit # non-debug case, the stack use has been reduced from 168 # bytes to 32 bytes. # # Deployed a new run-time configuration flag, # acpi_gbl_enable_interpeter_slack, whose purpose is to allow # the AML interpreter to forgive certain bad AML constructs. # Default setting is FALSE. # # Implemented the first use of acpi_gbl_enable_interpeter_slack # in the Field IO support code. If enabled, it allows field # access to go beyond the end of a region definition if the # field is within the region length rounded up to the next # access width boundary (a common coding error.) # # Renamed OSD_HANDLER to acpi_osd_handler, and # OSD_EXECUTION_CALLBACK to acpi_osd_exec_callback for # consistency with other ACPI symbols. Also, these symbols # are lowercased by the latest version of the acpisrc tool. # # The prototypes for the PCI interfaces in acpiosxf.h # have been updated to rename "register" to simply "reg" # to prevent certain compilers from complaining. # # include/acpi/actypes.h # 2004/07/17 01:37:53-04:00 len.brown@intel.com +2 -2 # ACPICA 20040715 # # include/acpi/acpiosxf.h # 2004/07/17 01:37:53-04:00 len.brown@intel.com +9 -6 # ACPICA 20040715 # # include/acpi/achware.h # 2004/07/17 01:37:53-04:00 len.brown@intel.com +3 -3 # ACPICA 20040715 # # include/acpi/acglobal.h # 2004/07/17 01:37:53-04:00 len.brown@intel.com +11 -4 # ACPICA 20040715 # # include/acpi/acevents.h # 2004/07/17 01:37:53-04:00 len.brown@intel.com +2 -1 # ACPICA 20040715 # # include/acpi/acconfig.h # 2004/07/17 01:37:53-04:00 len.brown@intel.com +1 -1 # ACPICA 20040715 # # drivers/acpi/tables/tbxfroot.c # 2004/07/17 01:37:53-04:00 len.brown@intel.com +63 -43 # ACPICA 20040715 # # drivers/acpi/osl.c # 2004/07/17 01:37:53-04:00 len.brown@intel.com +5 -5 # ACPICA 20040715 # # drivers/acpi/hardware/hwsleep.c # 2004/07/17 01:37:53-04:00 len.brown@intel.com +7 -6 # ACPICA 20040715 # # drivers/acpi/hardware/hwregs.c # 2004/07/17 01:37:53-04:00 len.brown@intel.com +2 -1 # ACPICA 20040715 # # drivers/acpi/hardware/hwgpe.c # 2004/07/17 01:37:53-04:00 len.brown@intel.com +10 -10 # ACPICA 20040715 # # drivers/acpi/executer/exmisc.c # 2004/07/17 01:37:53-04:00 len.brown@intel.com +20 -20 # ACPICA 20040715 # # drivers/acpi/executer/exfldio.c # 2004/07/17 01:37:53-04:00 len.brown@intel.com +15 -0 # ACPICA 20040715 # # drivers/acpi/events/evmisc.c # 2004/07/17 01:37:53-04:00 len.brown@intel.com +2 -2 # ACPICA 20040715 # # drivers/acpi/events/evgpeblk.c # 2004/07/17 01:37:53-04:00 len.brown@intel.com +5 -4 # ACPICA 20040715 # # ChangeSet # 2004/07/15 15:17:42-04:00 len.brown@intel.com # [ACPI] Enable run-time CM button/LID events (David Shaohua Li) # http://bugzilla.kernel.org/show_bug.cgi?id=1415 # # drivers/acpi/sleep/wakeup.c # 2004/07/15 05:05:42-04:00 len.brown@intel.com +41 -9 # Enable run-time CM button/LID events # # drivers/acpi/button.c # 2004/07/15 04:09:03-04:00 len.brown@intel.com +9 -0 # Enable run-time CM button/LID events # # drivers/acpi/acpi_ksyms.c # 2004/07/15 04:05:19-04:00 len.brown@intel.com +2 -0 # Enable run-time CM button/LID events # # ChangeSet # 2004/07/15 02:20:47-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.7 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # drivers/acpi/sleep/main.c # 2004/07/15 02:20:44-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/scan.c # 2004/07/15 02:20:44-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/io_apic.c # 2004/07/15 02:20:44-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/07/15 02:05:38-04:00 len.brown@intel.com # Merge # # include/asm-x86_64/acpi.h # 2004/07/15 02:05:37-04:00 len.brown@intel.com +0 -0 # SCCS merged # # ChangeSet # 2004/07/15 00:39:15-04:00 len.brown@intel.com # [ACPI] Create /proc/acpi/wakeup to allow enabling # the optional wakeup event sources. (David Shaohua Li) # http://bugzilla.kernel.org/show_bug.cgi?id=1415 # # drivers/acpi/sleep/wakeup.c # 2004/07/14 02:35:15-04:00 len.brown@intel.com +147 -0 # /proc/acpi/wakeup # # drivers/acpi/sleep/sleep.h # 2004/07/14 01:29:14-04:00 len.brown@intel.com +3 -0 # /proc/acpi/wakeup # # drivers/acpi/sleep/proc.c # 2004/07/14 02:14:03-04:00 len.brown@intel.com +86 -0 # /proc/acpi/wakeup # # drivers/acpi/sleep/main.c # 2004/07/14 01:29:13-04:00 len.brown@intel.com +3 -0 # /proc/acpi/wakeup # # drivers/acpi/sleep/Makefile # 2004/07/14 01:29:07-04:00 len.brown@intel.com +1 -1 # /proc/acpi/wakeup # # drivers/acpi/sleep/wakeup.c # 2004/07/14 02:35:15-04:00 len.brown@intel.com +0 -0 # BitKeeper file /home/lenb/src/linux-acpi-test-2.6.7/drivers/acpi/sleep/wakeup.c # # ChangeSet # 2004/07/15 00:37:33-04:00 len.brown@intel.com # [ACPI] ACPI bus support for wakeup GPE (David Shaohua Li) # http://bugzilla.kernel.org/show_bug.cgi?id=1415 # # include/acpi/acpi_drivers.h # 2004/07/14 01:22:19-04:00 len.brown@intel.com +2 -1 # ACPI bus support for wakeup GPE # # include/acpi/acpi_bus.h # 2004/07/14 01:22:19-04:00 len.brown@intel.com +24 -4 # ACPI bus support for wakeup GPE # # drivers/acpi/scan.c # 2004/07/14 01:24:56-04:00 len.brown@intel.com +137 -28 # ACPI bus support for wakeup GPE # # drivers/acpi/power.c # 2004/07/14 01:22:19-04:00 len.brown@intel.com +80 -0 # ACPI bus support for wakeup GPE # # ChangeSet # 2004/07/15 00:27:33-04:00 len.brown@intel.com # [ACPI] IOAPIC suspend/resume (David Shaohua Li) # http://bugzilla.kernel.org/show_bug.cgi?id=3037 # # arch/i386/kernel/io_apic.c # 2004/07/07 23:28:17-04:00 len.brown@intel.com +93 -0 # IOAPIC suspend/resume # # arch/x86_64/kernel/smpboot.c # 2004/07/14 16:00:16-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/i8259.c # 2004/07/14 16:00:16-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/smpboot.c # 2004/07/14 16:00:16-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/i8259.c # 2004/07/14 16:00:16-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/acpi/boot.c # 2004/07/14 16:00:16-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/07/14 15:47:04-04:00 len.brown@intel.com # [ACPI] Tell the BIOS Linux can handle # Enhanced Speed Step (EST). (Venkatesh Pallipadi) # http://bugzilla.kernel.org/show_bug.cgi?id=2712 # # include/asm-i386/acpi.h # 2004/05/18 18:45:51-04:00 len.brown@intel.com +6 -0 # use _PDC to enable Enhanced Speed Step (EST) # # drivers/acpi/processor.c # 2004/05/19 20:04:43-04:00 len.brown@intel.com +2 -2 # use _PDC to enable Enhanced Speed Step (EST) # # arch/i386/kernel/cpu/cpufreq/acpi.c # 2004/05/19 14:55:14-04:00 len.brown@intel.com +73 -0 # use _PDC to enable Enhanced Speed Step (EST) # # ChangeSet # 2004/07/14 15:39:55-04:00 len.brown@intel.com # [ACPI] add SMP suport to processor driver (Venkatesh Pallipadi) # http://bugzilla.kernel.org/show_bug.cgi?id=2615 # # include/asm-x86_64/acpi.h # 2004/06/25 01:40:47-04:00 len.brown@intel.com +2 -0 # add SMP support to processor driver # # include/asm-ia64/acpi.h # 2004/06/25 01:40:46-04:00 len.brown@intel.com +2 -0 # add SMP support to processor driver # # include/asm-i386/smp.h # 2004/06/25 01:40:47-04:00 len.brown@intel.com +1 -0 # add SMP support to processor driver # # include/asm-i386/acpi.h # 2004/06/25 01:40:47-04:00 len.brown@intel.com +2 -0 # add SMP support to processor driver # # drivers/acpi/processor.c # 2004/06/25 03:53:02-04:00 len.brown@intel.com +55 -10 # add SMP support to processor driver # # arch/x86_64/kernel/smpboot.c # 2004/06/25 01:40:50-04:00 len.brown@intel.com +1 -0 # add SMP support to processor driver # # arch/ia64/kernel/acpi.c # 2004/06/25 01:40:49-04:00 len.brown@intel.com +6 -0 # add SMP support to processor driver # # arch/i386/kernel/smpboot.c # 2004/06/25 01:40:49-04:00 len.brown@intel.com +6 -0 # add SMP support to processor driver # # arch/i386/kernel/cpu/cpufreq/acpi.c # 2004/06/25 01:40:43-04:00 len.brown@intel.com +25 -5 # add SMP support to processor driver # # arch/i386/kernel/acpi/boot.c # 2004/06/25 01:40:49-04:00 len.brown@intel.com +7 -0 # add SMP support to processor driver # # ChangeSet # 2004/07/14 15:35:54-04:00 len.brown@intel.com # [ACPI] save/restore ELCR on suspend/resume (David Shaohua Li) # http://bugzilla.kernel.org/show_bug.cgi?id=2643 # # arch/x86_64/kernel/i8259.c # 2004/07/14 15:35:49-04:00 len.brown@intel.com +52 -1 # save/restore ELCR on suspend/resume # # arch/i386/kernel/i8259.c # 2004/07/14 15:35:49-04:00 len.brown@intel.com +25 -0 # save/restore ELCR on suspend/resume # # ChangeSet # 2004/07/14 14:47:30-04:00 len.brown@intel.com # [ACPI] /proc/acpi/thermal_zone/THRM/cooling_mode # Add concept of (mandatory) "critical", when (optional) # "passive" and "active" are not present. (Zhenyu Z Wang) # http://bugzilla.kernel.org/show_bug.cgi?id=1770 # # drivers/acpi/thermal.c # 2004/07/08 01:56:01-04:00 len.brown@intel.com +32 -16 # create cooling_mode "critical" # # ChangeSet # 2004/07/14 00:34:54-04:00 len.brown@intel.com # [ACPI] fix ability to set thermal trip points (Hugo Haas, Stefan Seyfried) # eg. # echo -n "100:90:80:70:60:50" > /proc/acpi/thermal_zone/THRM/trip_points # http://bugzilla.kernel.org/show_bug.cgi?id=2588 # # drivers/acpi/thermal.c # 2004/06/29 17:43:00-04:00 len.brown@intel.com +14 -5 # fix ability to set thermal trip points # # ChangeSet # 2004/07/13 16:49:41-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.7 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # arch/x86_64/kernel/setup.c # 2004/07/13 16:49:38-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/mm/discontig.c # 2004/07/13 16:49:38-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/setup.c # 2004/07/13 16:49:37-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/07/11 22:05:34-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/linux-2.6.8 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # drivers/acpi/sleep/main.c # 2004/07/11 22:05:30-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/07/07 13:53:29-04:00 len.brown@intel.com # [ACPI] reserve EBDA for Dell BIOS that neglects to. (David Shaohua Li) # http://bugme.osdl.org/show_bug.cgi?id=2990 # # arch/x86_64/kernel/setup.c # 2004/06/30 23:30:27-04:00 len.brown@intel.com +17 -0 # reserve EBDA for Dell BIOS that neglects to. # # arch/i386/mm/discontig.c # 2004/06/30 22:51:37-04:00 len.brown@intel.com +15 -0 # reserve EBDA for Dell BIOS that neglects to. # # arch/i386/kernel/setup.c # 2004/06/30 22:51:37-04:00 len.brown@intel.com +15 -0 # reserve EBDA for Dell BIOS that neglects to. # # ChangeSet # 2004/07/02 23:13:23-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/linux-2.6.8 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.8 # # drivers/acpi/namespace/nsalloc.c # 2004/07/02 23:13:19-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/ec.c # 2004/06/24 06:39:53-04:00 len.brown@intel.com +2 -0 # enable GPE for ECDT # # ChangeSet # 2004/06/24 01:43:06-04:00 len.brown@intel.com # [ACPI] reserve IOPORTS for ACPI (David Shaohua Li) # http://bugzilla.kernel.org/show_bug.cgi?id=2641 # # drivers/acpi/processor.c # 2004/05/20 02:36:01-04:00 len.brown@intel.com +0 -1 # reserve IOPORTS for ACPI # # drivers/acpi/motherboard.c # 2004/05/20 05:01:24-04:00 len.brown@intel.com +161 -0 # reserve IOPORTS for ACPI # # drivers/acpi/Makefile # 2004/05/20 02:36:01-04:00 len.brown@intel.com +1 -1 # reserve IOPORTS for ACPI # # drivers/acpi/motherboard.c # 2004/05/20 05:01:24-04:00 len.brown@intel.com +0 -0 # BitKeeper file /home/lenb/bk/linux-acpi-test-2.6.7/drivers/acpi/motherboard.c # # ChangeSet # 2004/06/24 00:53:45-04:00 len.brown@intel.com # [ACPI] enable GPE for ECDT (David Shaohua Li) # # ChangeSet # 2004/06/23 17:01:29-04:00 len.brown@intel.com # [ACPI] enable Embedded Controller (EC)'s # General Purpose Event (GPE) from David Shaohua Li # # drivers/acpi/ec.c # 2004/06/07 13:35:25-04:00 len.brown@intel.com +2 -0 # enable EC GPE # # ChangeSet # 2004/06/23 01:22:23-04:00 len.brown@intel.com # [ACPI] fix return-from-sleep PM/ACPI state conversion bug (David Shaohua Li) # # drivers/acpi/sleep/main.c # 2004/06/23 01:22:17-04:00 len.brown@intel.com +16 -14 # fix conversion between pm_state and acpi_state on return from sleep # # ChangeSet # 2004/06/22 16:27:51-04:00 len.brown@intel.com # merge ACPICA # # drivers/acpi/events/evxface.c # 2004/06/22 16:27:46-04:00 len.brown@intel.com +22 -17 # merge # # drivers/acpi/events/evmisc.c # 2004/06/22 16:27:46-04:00 len.brown@intel.com +0 -2 # merge # # drivers/acpi/osl.c # 2004/06/22 16:05:25-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/ec.c # 2004/06/22 16:05:25-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/06/22 15:56:16-04:00 len.brown@intel.com # [ACPI] update EC GPE handler to new ACPICA handler type # # drivers/acpi/ec.c # 2004/06/22 15:13:22-04:00 len.brown@intel.com +7 -2 # An acpi_gpe_handler is an acpi_event_handler # as of ACPICA 20040427, and needs a return value. # # ChangeSet # 2004/06/22 13:48:26-04:00 len.brown@intel.com # [ACPI] ACPICA 20040615 from Bob Moore # # Implemented support for Buffer and String objects (as # per ACPI 2.0) for the following ASL operators: LEqual, # LGreater, LLess, LGreaterEqual, and LLessEqual. # # include/acpi/acinterp.h # 2004/06/21 20:35:19-04:00 len.brown@intel.com +2 -2 # ACPICA 20040615 # # include/acpi/acdebug.h # 2004/06/21 20:35:19-04:00 len.brown@intel.com +4 -0 # ACPICA 20040615 # # include/acpi/acconfig.h # 2004/06/21 20:35:20-04:00 len.brown@intel.com +1 -1 # ACPICA 20040615 # # drivers/acpi/utilities/utalloc.c # 2004/06/21 20:35:22-04:00 len.brown@intel.com +8 -5 # ACPICA 20040615 # # drivers/acpi/parser/psopcode.c # 2004/06/21 20:35:22-04:00 len.brown@intel.com +4 -4 # ACPICA 20040615 # # drivers/acpi/executer/exoparg2.c # 2004/06/21 20:35:22-04:00 len.brown@intel.com +10 -2 # ACPICA 20040615 # # drivers/acpi/executer/exmisc.c # 2004/06/21 20:35:22-04:00 len.brown@intel.com +119 -32 # ACPICA 20040615 # # drivers/acpi/events/evgpeblk.c # 2004/06/21 20:35:22-04:00 len.brown@intel.com +2 -1 # ACPICA 20040615 # # ChangeSet # 2004/06/22 13:42:17-04:00 len.brown@intel.com # [ACPI] ACPICA 20040527 from Bob Moore # # Completed a new design and implementation for EBDA # (Extended BIOS Data Area) support in the RSDP scan code. # The original code improperly scanned for the EBDA by simply # scanning from memory location 0 to 0x400. The correct # method is to first obtain the EBDA pointer from within # the BIOS data area, then scan 1K of memory starting at the # EBDA pointer. There appear to be few if any machines that # place the RSDP in the EBDA, however. # http://bugme.osdl.org/show_bug.cgi?id=2415 # # Integrated a fix for a possible fault during evaluation # of BufferField arguments. Obsolete code that was causing # the problem was removed. (Asus laptop boot crash) # https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=121760 # # Found and fixed a problem in the Field Support Code # where data could be corrupted on a bit field read that # starts on an aligned boundary but does not end on an # aligned boundary. Merged the read/write "datum length" # calculation code into a common procedure. # # include/acpi/acmacros.h # 2004/06/01 21:39:18-04:00 len.brown@intel.com +3 -0 # ACPICA 20040527 # # include/acpi/acinterp.h # 2004/06/01 21:39:18-04:00 len.brown@intel.com +6 -0 # ACPICA 20040527 # # include/acpi/acconfig.h # 2004/06/01 21:39:18-04:00 len.brown@intel.com +7 -6 # ACPICA 20040527 # # drivers/acpi/tables/tbxfroot.c # 2004/06/01 21:39:21-04:00 len.brown@intel.com +68 -35 # ACPICA 20040527 # # drivers/acpi/executer/exfldio.c # 2004/06/01 21:39:21-04:00 len.brown@intel.com +84 -64 # ACPICA 20040527 # # drivers/acpi/executer/exconfig.c # 2004/06/01 21:39:21-04:00 len.brown@intel.com +2 -2 # ACPICA 20040527 # # drivers/acpi/events/evgpeblk.c # 2004/06/01 21:39:21-04:00 len.brown@intel.com +2 -2 # ACPICA 20040527 # # drivers/acpi/events/evgpe.c # 2004/06/01 21:39:21-04:00 len.brown@intel.com +24 -20 # ACPICA 20040527 # # drivers/acpi/dispatcher/dsopcode.c # 2004/06/01 21:39:21-04:00 len.brown@intel.com +0 -3 # ACPICA 20040527 # # ChangeSet # 2004/06/22 13:15:18-04:00 len.brown@intel.com # [ACPI] ACPICA 20040514 from Bob Moore # # Fixed a problem where hardware GPE enable bits sometimes # not set properly during and after GPE method execution. # Result of ACPICA 20040427 changes. # # Removed extra "clear all GPEs" when sleeping/waking. # # Removed acpi_ht_enable_gpe and acpi_hw_disable_gpe, replaced # by the single acpi_hw_write_gpe_enable_reg. Changed a couple # of calls to the functions above to the new acpi_ev* calls # as appropriate. # # ACPI_OS_NAME was removed from the OS-specific headers. # The default name is now "Microsoft Windows NT" for maximum # compatibility. However this can be changed by modifying # the acconfig.h file. Fixes EHCI probe issue: # http://bugme.osdl.org/show_bug.cgi?id=1762 # # Allow a single invocation of acpi_install_notify_handler # for a handler that traps both types of notifies (System, # Device). Use ACPI_ALL_NOTIFY flag. # # Run _INI methods on ThermalZone objects. This is against # the ACPI specification, but there is apparently ASL code # in the field that has these _INI methods, and apparently # "other" AML interpreters execute them. # # Performed a full 16/32/64 bit lint that resulted in some # small changes. # # include/acpi/platform/aclinux.h # 2004/06/01 21:37:50-04:00 len.brown@intel.com +0 -2 # ACPICA 20040514 # # include/acpi/platform/acenv.h # 2004/06/01 21:37:50-04:00 len.brown@intel.com +2 -6 # ACPICA 20040514 # # include/acpi/actypes.h # 2004/06/01 21:37:50-04:00 len.brown@intel.com +4 -3 # ACPICA 20040514 # # include/acpi/acmacros.h # 2004/06/01 21:37:50-04:00 len.brown@intel.com +1 -1 # ACPICA 20040514 # # include/acpi/achware.h # 2004/06/01 21:37:50-04:00 len.brown@intel.com +6 -5 # ACPICA 20040514 # # include/acpi/acdebug.h # 2004/06/01 21:37:50-04:00 len.brown@intel.com +4 -0 # ACPICA 20040514 # # include/acpi/acconfig.h # 2004/06/01 21:37:50-04:00 len.brown@intel.com +11 -1 # ACPICA 20040514 # # drivers/acpi/utilities/utglobal.c # 2004/06/01 21:37:53-04:00 len.brown@intel.com +1 -1 # ACPICA 20040514 # # drivers/acpi/resources/rsxface.c # 2004/06/01 21:37:53-04:00 len.brown@intel.com +2 -1 # ACPICA 20040514 # # drivers/acpi/parser/psxface.c # 2004/06/01 21:37:52-04:00 len.brown@intel.com +2 -3 # ACPICA 20040514 # # drivers/acpi/namespace/nsinit.c # 2004/06/01 21:37:53-04:00 len.brown@intel.com +8 -7 # ACPICA 20040514 # # drivers/acpi/namespace/nseval.c # 2004/06/01 21:37:53-04:00 len.brown@intel.com +1 -1 # ACPICA 20040514 # # drivers/acpi/namespace/nsalloc.c # 2004/06/01 21:37:53-04:00 len.brown@intel.com +1 -1 # ACPICA 20040514 # # drivers/acpi/hardware/hwsleep.c # 2004/06/01 21:37:52-04:00 len.brown@intel.com +2 -2 # ACPICA 20040514 # # drivers/acpi/hardware/hwgpe.c # 2004/06/01 21:37:52-04:00 len.brown@intel.com +16 -51 # ACPICA 20040514 # # drivers/acpi/executer/exresolv.c # 2004/06/01 21:37:53-04:00 len.brown@intel.com +4 -4 # ACPICA 20040514 # # drivers/acpi/events/evxfregn.c # 2004/06/01 21:37:52-04:00 len.brown@intel.com +0 -1 # ACPICA 20040514 # # drivers/acpi/events/evxfevnt.c # 2004/06/01 21:37:52-04:00 len.brown@intel.com +1 -8 # ACPICA 20040514 # # drivers/acpi/events/evxface.c # 2004/06/01 21:37:52-04:00 len.brown@intel.com +45 -31 # ACPICA 20040514 # # drivers/acpi/events/evmisc.c # 2004/06/01 21:37:52-04:00 len.brown@intel.com +2 -2 # ACPICA 20040514 # # drivers/acpi/events/evgpeblk.c # 2004/06/01 21:37:52-04:00 len.brown@intel.com +14 -7 # ACPICA 20040514 # # drivers/acpi/events/evgpe.c # 2004/06/01 21:37:52-04:00 len.brown@intel.com +21 -14 # ACPICA 20040514 # # drivers/acpi/dispatcher/dsmethod.c # 2004/06/01 21:37:52-04:00 len.brown@intel.com +1 -1 # ACPICA 20040514 # # ChangeSet # 2004/05/07 17:24:44-04:00 len.brown@intel.com # [ACPI] ACPICA 20040427 from Bob Moore # # Completed a major overhaul of the GPE handling within ACPI CA. # There are now three types of GPEs: # wake-only; runtime-only; combination wake/run. # # The only GPEs allowed to be combination wake/run are for # button-style devices such as a control-method power button, # control-method sleep button, or a notebook lid switch. # GPEs that have an _Lxx or _Exx method and are not referenced # by any _PRW methods are marked for "runtime" and hardware enabled. # # Any GPE that is referenced by a _PRW method is marked for "wake" # (and disabled at runtime). However, at sleep time, only those # GPEs that have been specifically enabled for wake via the # acpi_enable_gpe() interface will actually be hardware enabled. # # A new external interface has been added, acpi_set_gpe_type() # that is meant to be used by device drivers to force a GPE # to a particular type. It will be especially useful for the # drivers for the button devices mentioned above. # # Completed restructuring of the ACPI CA initialization sequence # so that default operation region handlers are installed # before GPEs are initialized and the _PRW methods are executed. # This will prevent errors when the _PRW methods attempt to # access system memory or I/O space. # # GPE enable/disable no longer reads the GPE enable register. # We now keep the enable info for runtime and wake separate # and in the GPE_EVENT_INFO. We thus no longer depend on # the hardware to maintain these bits. # # Always clear the wake status and fixed/GPE status bits # before sleep, even for state S5. # # Improved the AML debugger output for displaying the # GPE blocks and their current status. # # Added new strings for the _OSI method, of the form # "Windows 2001 SPx" where x = 0,1,2,3,4. # # Fixed a problem where the physical address was incorrectly # calculated when the Load() operator was used to directly # load from an Operation Region (vs. loading from a Field object.) # Also added check for minimum table length for this case. # # Fix for multiple mutex acquisition. Restore original thread # SyncLevel on mutex release. # # Added ACPI_VALID_SXDS flag to the acpi_get_object_info interface # for consistency with the other fields returned. # # Shrunk the ACPI_GPE_EVENT_INFO structure by 40%. # There is one such structure for each GPE in the system, # so the size of this structure is important. # # CPU stack requirement reduction: # Cleaned up the method execution and object evaluation paths # so that now a parameter structure is passed, instead of copying # the various method parameters over and over again. # # In evregion.c: # Correctly exit and reenter the interpreter region if and only # if dispatching an operation region request to a user-installed # handler. Do not exit/reenter when dispatching to a default # handler (e.g., default system memory or I/O handlers) # # include/acpi/actypes.h # 2004/05/07 13:10:42-04:00 len.brown@intel.com +46 -27 # ACPICA 20040427 # # include/acpi/actbl.h # 2004/05/07 13:10:43-04:00 len.brown@intel.com +16 -13 # ACPICA 20040427 # # include/acpi/acstruct.h # 2004/05/07 13:10:42-04:00 len.brown@intel.com +21 -2 # ACPICA 20040427 # # include/acpi/acpixf.h # 2004/05/07 13:10:43-04:00 len.brown@intel.com +8 -2 # ACPICA 20040427 # # include/acpi/acparser.h # 2004/05/07 13:10:43-04:00 len.brown@intel.com +1 -3 # ACPICA 20040427 # # include/acpi/acobject.h # 2004/05/07 13:10:42-04:00 len.brown@intel.com +7 -6 # ACPICA 20040427 # # include/acpi/acnamesp.h # 2004/05/07 13:10:43-04:00 len.brown@intel.com +5 -13 # ACPICA 20040427 # # include/acpi/aclocal.h # 2004/05/07 13:10:43-04:00 len.brown@intel.com +25 -14 # ACPICA 20040427 # # include/acpi/achware.h # 2004/05/07 13:10:42-04:00 len.brown@intel.com +11 -10 # ACPICA 20040427 # # include/acpi/acglobal.h # 2004/05/07 13:10:43-04:00 len.brown@intel.com +1 -0 # ACPICA 20040427 # # include/acpi/acexcep.h # 2004/05/07 13:10:43-04:00 len.brown@intel.com +4 -2 # ACPICA 20040427 # # include/acpi/acevents.h # 2004/05/07 13:10:42-04:00 len.brown@intel.com +48 -3 # ACPICA 20040427 # # include/acpi/acdispat.h # 2004/05/07 13:10:43-04:00 len.brown@intel.com +1 -2 # ACPICA 20040427 # # include/acpi/acconfig.h # 2004/05/07 13:10:43-04:00 len.brown@intel.com +2 -2 # ACPICA 20040427 # # drivers/acpi/utilities/utxface.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +26 -15 # ACPICA 20040427 # # drivers/acpi/utilities/utglobal.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +35 -21 # ACPICA 20040427 # # drivers/acpi/utilities/uteval.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +11 -7 # ACPICA 20040427 # # drivers/acpi/resources/rsutils.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +6 -1 # ACPICA 20040427 # # drivers/acpi/parser/psxface.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +27 -25 # ACPICA 20040427 # # drivers/acpi/namespace/nsxfname.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +2 -2 # ACPICA 20040427 # # drivers/acpi/namespace/nsxfeval.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +28 -24 # ACPICA 20040427 # # drivers/acpi/namespace/nsparse.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +3 -2 # ACPICA 20040427 # # drivers/acpi/namespace/nsinit.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +17 -14 # ACPICA 20040427 # # drivers/acpi/namespace/nseval.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +32 -58 # ACPICA 20040427 # # drivers/acpi/namespace/nsaccess.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +1 -1 # ACPICA 20040427 # # drivers/acpi/hardware/hwsleep.c # 2004/05/07 13:10:45-04:00 len.brown@intel.com +36 -16 # ACPICA 20040427 # # drivers/acpi/hardware/hwregs.c # 2004/05/07 13:10:45-04:00 len.brown@intel.com +17 -14 # ACPICA 20040427 # # drivers/acpi/hardware/hwgpe.c # 2004/05/07 13:10:45-04:00 len.brown@intel.com +92 -212 # ACPICA 20040427 # # drivers/acpi/executer/exoparg2.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +33 -3 # ACPICA 20040427 # # drivers/acpi/executer/exmutex.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +25 -21 # ACPICA 20040427 # # drivers/acpi/executer/exconfig.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +35 -12 # ACPICA 20040427 # # drivers/acpi/events/evxfregn.c # 2004/05/07 13:10:45-04:00 len.brown@intel.com +5 -195 # ACPICA 20040427 # # drivers/acpi/events/evxfevnt.c # 2004/05/07 13:10:45-04:00 len.brown@intel.com +101 -75 # ACPICA 20040427 # # drivers/acpi/events/evxface.c # 2004/05/07 13:10:45-04:00 len.brown@intel.com +58 -25 # ACPICA 20040427 # # drivers/acpi/events/evregion.c # 2004/05/07 13:10:45-04:00 len.brown@intel.com +346 -27 # ACPICA 20040427 # # drivers/acpi/events/evmisc.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +4 -0 # ACPICA 20040427 # # drivers/acpi/events/evgpeblk.c # 2004/05/07 13:10:45-04:00 len.brown@intel.com +104 -46 # ACPICA 20040427 # # drivers/acpi/events/evgpe.c # 2004/05/07 13:10:45-04:00 len.brown@intel.com +343 -25 # ACPICA 20040427 # # drivers/acpi/events/evevent.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +6 -6 # ACPICA 20040427 # # drivers/acpi/dispatcher/dswstate.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +13 -5 # ACPICA 20040427 # # drivers/acpi/dispatcher/dsopcode.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +2 -2 # ACPICA 20040427 # # drivers/acpi/dispatcher/dsmethod.c # 2004/05/07 13:10:46-04:00 len.brown@intel.com +10 -6 # ACPICA 20040427 # # ChangeSet # 2004/05/07 17:21:19-04:00 len.brown@intel.com # [ACPI] ACPICA 20040402 from Bob Moore # # Fixed an interpreter problem where an indirect store through an # ArgX parameter was incorrectly applying the "implicit conversion # rules" during the store. From the ACPI specification: "If the # target is a method local or argument (LocalX or ArgX), no # conversion is performed and the result is stored directly to the # target". The new behavior is to disable implicit conversion # during ALL stores to an ArgX. # # Changed the behavior of the _PRW method scan to ignore any and # all errors returned by a given _PRW. This prevents the scan from # aborting from the failure of any single _PRW. # # Moved the runtime configuration parameters from the global init # procedure to static variables in acglobal.h. This will allow the # host to override the default values easily. # # include/acpi/acinterp.h # 2004/05/07 13:11:48-04:00 len.brown@intel.com +4 -1 # ACPICA 20040402 # # include/acpi/acglobal.h # 2004/05/07 13:11:49-04:00 len.brown@intel.com +29 -7 # ACPICA 20040402 # # include/acpi/acdisasm.h # 2004/05/07 13:11:49-04:00 len.brown@intel.com +15 -0 # ACPICA 20040402 # # include/acpi/acconfig.h # 2004/05/07 13:11:49-04:00 len.brown@intel.com +1 -1 # ACPICA 20040402 # # drivers/acpi/utilities/utglobal.c # 2004/05/07 13:11:52-04:00 len.brown@intel.com +16 -10 # ACPICA 20040402 # # drivers/acpi/executer/exstore.c # 2004/05/07 13:11:52-04:00 len.brown@intel.com +14 -3 # ACPICA 20040402 # # drivers/acpi/executer/exfldio.c # 2004/05/07 13:11:52-04:00 len.brown@intel.com +1 -1 # ACPICA 20040402 # # drivers/acpi/events/evmisc.c # 2004/05/07 13:11:51-04:00 len.brown@intel.com +1 -1 # ACPICA 20040402 # # drivers/acpi/events/evgpeblk.c # 2004/05/07 13:11:51-04:00 len.brown@intel.com +4 -6 # ACPICA 20040402 # # drivers/acpi/dispatcher/dswload.c # 2004/05/07 13:11:51-04:00 len.brown@intel.com +22 -0 # ACPICA 20040402 # # drivers/acpi/dispatcher/dsmthdat.c # 2004/05/07 13:11:51-04:00 len.brown@intel.com +5 -3 # ACPICA 20040402 # # ChangeSet # 2004/05/03 12:31:49-04:00 len.brown@intel.com # Cset exclude: torvalds@evo.osdl.org|ChangeSet|20040401021818|60003 # # drivers/acpi/utilities/utglobal.c # 2004/05/03 12:31:41-04:00 len.brown@intel.com +0 -0 # Exclude # # drivers/acpi/osl.c # 2004/05/03 12:31:41-04:00 len.brown@intel.com +0 -0 # Exclude # diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c --- a/arch/i386/kernel/acpi/boot.c 2004-08-21 23:40:16 -07:00 +++ b/arch/i386/kernel/acpi/boot.c 2004-08-21 23:40:16 -07:00 @@ -84,6 +84,11 @@ #warning ACPI uses CMPXCHG, i486 and later hardware #endif +#define MAX_MADT_ENTRIES 256 +u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = + { [0 ... MAX_MADT_ENTRIES-1] = 0xff }; +EXPORT_SYMBOL(x86_acpiid_to_apicid); + /* -------------------------------------------------------------------------- Boot-time Configuration -------------------------------------------------------------------------- */ @@ -224,6 +229,8 @@ /* no utility in registering a disabled processor */ if (processor->flags.enabled == 0) return 0; + + x86_acpiid_to_apicid[processor->acpi_id] = processor->id; mp_register_lapic ( processor->id, /* APIC ID */ diff -Nru a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c --- a/arch/i386/kernel/acpi/sleep.c 2004-08-21 23:40:16 -07:00 +++ b/arch/i386/kernel/acpi/sleep.c 2004-08-21 23:40:16 -07:00 @@ -77,10 +77,7 @@ printk(KERN_ERR "ACPI: Wakeup code way too big, S3 disabled.\n"); return; } -#ifdef CONFIG_X86_PAE - printk(KERN_ERR "ACPI: S3 and PAE do not like each other for now, S3 disabled.\n"); - return; -#endif + acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); if (!acpi_wakeup_address) printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n"); diff -Nru a/arch/i386/kernel/cpu/cpufreq/acpi.c b/arch/i386/kernel/cpu/cpufreq/acpi.c --- a/arch/i386/kernel/cpu/cpufreq/acpi.c 2004-08-21 23:40:16 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/acpi.c 2004-08-21 23:40:16 -07:00 @@ -108,13 +108,27 @@ u32 value = 0; int i = 0; struct cpufreq_freqs cpufreq_freqs; + cpumask_t saved_mask; + int retval; ACPI_FUNCTION_TRACE("acpi_processor_set_performance"); + /* + * TBD: Use something other than set_cpus_allowed. + * As set_cpus_allowed is a bit racy, + * with any other set_cpus_allowed for this process. + */ + saved_mask = current->cpus_allowed; + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + if (smp_processor_id() != cpu) { + return_VALUE(-EAGAIN); + } + if (state == data->acpi_data.state) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Already at target state (P%d)\n", state)); - return_VALUE(0); + retval = 0; + goto migrate_end; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n", @@ -144,7 +158,8 @@ if (ret) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid port width 0x%04x\n", bit_width)); - return_VALUE(ret); + retval = ret; + goto migrate_end; } /* @@ -166,7 +181,8 @@ if (ret) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid port width 0x%04x\n", bit_width)); - return_VALUE(ret); + retval = ret; + goto migrate_end; } if (value == (u32) data->acpi_data.states[state].status) break; @@ -183,7 +199,8 @@ cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n")); - return_VALUE(-ENODEV); + retval = -ENODEV; + goto migrate_end; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -192,7 +209,10 @@ data->acpi_data.state = state; - return_VALUE(0); + retval = 0; +migrate_end: + set_cpus_allowed(current, saved_mask); + return_VALUE(retval); } @@ -266,6 +286,69 @@ } + +/* + * acpi_processor_cpu_init_pdc_est - let BIOS know about the SMP capabilities + * of this driver + * @perf: processor-specific acpi_io_data struct + * @cpu: CPU being initialized + * + * To avoid issues with legacy OSes, some BIOSes require to be informed of + * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC + * accordingly, for Enhanced Speedstep. Actual call to _PDC is done in + * driver/acpi/processor.c + */ +static void +acpi_processor_cpu_init_pdc_est( + struct acpi_processor_performance *perf, + unsigned int cpu, + struct acpi_object_list *obj_list + ) +{ + union acpi_object *obj; + u32 *buf; + struct cpuinfo_x86 *c = cpu_data + cpu; + ACPI_FUNCTION_TRACE("acpi_processor_cpu_init_pdc_est"); + + if (!cpu_has(c, X86_FEATURE_EST)) + return_VOID; + + /* Initialize pdc. It will be used later. */ + if (!obj_list) + return_VOID; + + if (!(obj_list->count && obj_list->pointer)) + return_VOID; + + obj = obj_list->pointer; + if ((obj->buffer.length == 12) && obj->buffer.pointer) { + buf = (u32 *)obj->buffer.pointer; + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + buf[2] = ACPI_PDC_EST_CAPABILITY_SMP; + perf->pdc = obj_list; + } + return_VOID; +} + + +/* CPU specific PDC initialization */ +static void +acpi_processor_cpu_init_pdc( + struct acpi_processor_performance *perf, + unsigned int cpu, + struct acpi_object_list *obj_list + ) +{ + struct cpuinfo_x86 *c = cpu_data + cpu; + ACPI_FUNCTION_TRACE("acpi_processor_cpu_init_pdc"); + perf->pdc = NULL; + if (cpu_has(c, X86_FEATURE_EST)) + acpi_processor_cpu_init_pdc_est(perf, cpu, obj_list); + return_VOID; +} + + static int acpi_cpufreq_cpu_init ( struct cpufreq_policy *policy) @@ -275,7 +358,14 @@ struct cpufreq_acpi_io *data; unsigned int result = 0; + union acpi_object arg0 = {ACPI_TYPE_BUFFER}; + u32 arg0_buf[3]; + struct acpi_object_list arg_list = {1, &arg0}; + ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init"); + /* setup arg_list for _PDC settings */ + arg0.buffer.length = 12; + arg0.buffer.pointer = (u8 *) arg0_buf; data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); if (!data) @@ -284,7 +374,10 @@ acpi_io_data[cpu] = data; + acpi_processor_cpu_init_pdc(&data->acpi_data, cpu, &arg_list); result = acpi_processor_register_performance(&data->acpi_data, cpu); + data->acpi_data.pdc = NULL; + if (result) goto err_free; diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c --- a/arch/i386/kernel/dmi_scan.c 2004-08-21 23:40:16 -07:00 +++ b/arch/i386/kernel/dmi_scan.c 2004-08-21 23:40:16 -07:00 @@ -163,27 +163,6 @@ #define MATCH DMI_MATCH /* - * Some machines, usually laptops, can't handle an enabled local APIC. - * The symptoms include hangs or reboots when suspending or resuming, - * attaching or detaching the power cord, or entering BIOS setup screens - * through magic key sequences. - */ -static int __init local_apic_kills_bios(struct dmi_blacklist *d) -{ -#ifdef CONFIG_X86_LOCAL_APIC - extern int enable_local_apic; - if (enable_local_apic == 0) { - enable_local_apic = -1; - printk(KERN_WARNING "%s with broken BIOS detected. " - "Refusing to enable the local APIC.\n", - d->ident); - } -#endif - return 0; -} - - -/* * Toshiba keyboard likes to repeat keys when they are not repeated. */ @@ -283,32 +262,6 @@ */ static __initdata struct dmi_blacklist dmi_blacklist[]={ - - /* Machines which have problems handling enabled local APICs */ - - { local_apic_kills_bios, "Dell Inspiron", { - MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), - MATCH(DMI_PRODUCT_NAME, "Inspiron"), - NO_MATCH, NO_MATCH - } }, - - { local_apic_kills_bios, "Dell Latitude", { - MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), - MATCH(DMI_PRODUCT_NAME, "Latitude"), - NO_MATCH, NO_MATCH - } }, - - { local_apic_kills_bios, "IBM Thinkpad T20", { - MATCH(DMI_BOARD_VENDOR, "IBM"), - MATCH(DMI_BOARD_NAME, "264741U"), - NO_MATCH, NO_MATCH - } }, - - { local_apic_kills_bios, "ASUS L3C", { - MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - MATCH(DMI_BOARD_NAME, "P4_L3C"), - NO_MATCH, NO_MATCH - } }, { broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */ MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c --- a/arch/i386/kernel/i8259.c 2004-08-21 23:40:16 -07:00 +++ b/arch/i386/kernel/i8259.c 2004-08-21 23:40:16 -07:00 @@ -238,14 +238,39 @@ } } +static char irq_trigger[2]; +/** + * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ + */ +static void restore_ELCR(char *trigger) +{ + outb(trigger[0], 0x4d0); + outb(trigger[1], 0x4d1); +} + +static void save_ELCR(char *trigger) +{ + /* IRQ 0,1,2,8,13 are marked as reserved */ + trigger[0] = inb(0x4d0) & 0xF8; + trigger[1] = inb(0x4d1) & 0xDE; +} + static int i8259A_resume(struct sys_device *dev) { init_8259A(0); + restore_ELCR(irq_trigger); + return 0; +} + +static int i8259A_suspend(struct sys_device *dev, u32 state) +{ + save_ELCR(irq_trigger); return 0; } static struct sysdev_class i8259_sysdev_class = { set_kset_name("i8259"), + .suspend = i8259A_suspend, .resume = i8259A_resume, }; diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c --- a/arch/i386/kernel/io_apic.c 2004-08-21 23:40:16 -07:00 +++ b/arch/i386/kernel/io_apic.c 2004-08-21 23:40:16 -07:00 @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -2261,6 +2262,98 @@ } late_initcall(io_apic_bug_finalize); + +struct sysfs_ioapic_data { + struct sys_device dev; + struct IO_APIC_route_entry entry[0]; +}; +static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS]; + +static int ioapic_suspend(struct sys_device *dev, u32 state) +{ + struct IO_APIC_route_entry *entry; + struct sysfs_ioapic_data *data; + unsigned long flags; + int i; + + data = container_of(dev, struct sysfs_ioapic_data, dev); + entry = data->entry; + spin_lock_irqsave(&ioapic_lock, flags); + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { + *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i); + *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i); + } + spin_unlock_irqrestore(&ioapic_lock, flags); + + return 0; +} + +static int ioapic_resume(struct sys_device *dev) +{ + struct IO_APIC_route_entry *entry; + struct sysfs_ioapic_data *data; + unsigned long flags; + union IO_APIC_reg_00 reg_00; + int i; + + data = container_of(dev, struct sysfs_ioapic_data, dev); + entry = data->entry; + + spin_lock_irqsave(&ioapic_lock, flags); + reg_00.raw = io_apic_read(dev->id, 0); + if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) { + reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; + io_apic_write(dev->id, 0, reg_00.raw); + } + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { + io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1)); + io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0)); + } + spin_unlock_irqrestore(&ioapic_lock, flags); + + return 0; +} + +static struct sysdev_class ioapic_sysdev_class = { + set_kset_name("ioapic"), + .suspend = ioapic_suspend, + .resume = ioapic_resume, +}; + +static int __init ioapic_init_sysfs(void) +{ + struct sys_device * dev; + int i, size, error = 0; + + error = sysdev_class_register(&ioapic_sysdev_class); + if (error) + return error; + + for (i = 0; i < nr_ioapics; i++ ) { + size = sizeof(struct sys_device) + nr_ioapic_registers[i] + * sizeof(struct IO_APIC_route_entry); + mp_ioapic_data[i] = kmalloc(size, GFP_KERNEL); + if (!mp_ioapic_data[i]) { + printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); + continue; + } + memset(mp_ioapic_data[i], 0, size); + dev = &mp_ioapic_data[i]->dev; + dev->id = i; + dev->cls = &ioapic_sysdev_class; + error = sysdev_register(dev); + if (error) { + kfree(mp_ioapic_data[i]); + mp_ioapic_data[i] = NULL; + printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); + continue; + } + } + + return 0; +} + +device_initcall(ioapic_init_sysfs); /* -------------------------------------------------------------------------- ACPI-based IOAPIC Configuration diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c --- a/arch/i386/kernel/setup.c 2004-08-21 23:40:16 -07:00 +++ b/arch/i386/kernel/setup.c 2004-08-21 23:40:16 -07:00 @@ -49,6 +49,7 @@ #include #include #include "setup_arch_pre.h" +#include /* This value is set up by the early boot code to point to the value immediately after the boot time page tables. It contains a *physical* @@ -991,6 +992,17 @@ } } +/* + * workaround for Dell systems that neglect to reserve EBDA + */ +static void __init reserve_ebda_region(void) +{ + unsigned int addr; + addr = get_bios_ebda(); + if (addr) + reserve_bootmem(addr, PAGE_SIZE); +} + static unsigned long __init setup_memory(void) { unsigned long bootmap_size, start_pfn, max_low_pfn; @@ -1036,6 +1048,9 @@ * enabling clean reboots, SMP operation, laptop functions. */ reserve_bootmem(0, PAGE_SIZE); + + /* reserve EBDA region, it's a 4K region */ + reserve_ebda_region(); /* could be an AMD 768MPX chipset. Reserve a page before VGA to prevent PCI prefetch into it (errata #56). Usually the page is reserved anyways, diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c --- a/arch/i386/kernel/smpboot.c 2004-08-21 23:40:16 -07:00 +++ b/arch/i386/kernel/smpboot.c 2004-08-21 23:40:16 -07:00 @@ -72,6 +72,10 @@ /* Per CPU bogomips and other parameters */ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; +u8 x86_cpu_to_apicid[NR_CPUS] = + { [0 ... NR_CPUS-1] = 0xff }; +EXPORT_SYMBOL(x86_cpu_to_apicid); + /* Set when the idlers are all forked */ int smp_threads_ready; @@ -875,6 +879,7 @@ inquire_remote_apic(apicid); } } + x86_cpu_to_apicid[cpu] = apicid; if (boot_error) { /* Try to put things back the way they were before ... */ unmap_cpu_to_logical_apicid(cpu); @@ -957,6 +962,7 @@ boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); boot_cpu_logical_apicid = logical_smp_processor_id(); + x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; current_thread_info()->cpu = 0; smp_tune_scheduling(); diff -Nru a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c --- a/arch/i386/mm/discontig.c 2004-08-21 23:40:16 -07:00 +++ b/arch/i386/mm/discontig.c 2004-08-21 23:40:16 -07:00 @@ -31,6 +31,7 @@ #include #include #include +#include struct pglist_data *node_data[MAX_NUMNODES]; bootmem_data_t node0_bdata; @@ -219,6 +220,17 @@ return reserve_pages; } +/* + * workaround for Dell systems that neglect to reserve EBDA + */ +static void __init reserve_ebda_region_node(void) +{ + unsigned int addr; + addr = get_bios_ebda(); + if (addr) + reserve_bootmem_node(NODE_DATA(0), addr, PAGE_SIZE); +} + unsigned long __init setup_memory(void) { int nid; @@ -317,6 +329,9 @@ * trampoline before removing it. (see the GDT stuff) */ reserve_bootmem_node(NODE_DATA(0), PAGE_SIZE, PAGE_SIZE); + + /* reserve EBDA region, it's a 4K region */ + reserve_ebda_region_node(); #ifdef CONFIG_ACPI_SLEEP /* diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c --- a/arch/ia64/kernel/acpi.c 2004-08-21 23:40:16 -07:00 +++ b/arch/ia64/kernel/acpi.c 2004-08-21 23:40:16 -07:00 @@ -65,6 +65,11 @@ unsigned char acpi_kbd_controller_present = 1; unsigned char acpi_legacy_devices; +#define MAX_SAPICS 256 +u16 ia64_acpiid_to_sapicid[MAX_SAPICS] = + { [0 ... MAX_SAPICS - 1] = -1 }; +EXPORT_SYMBOL(ia64_acpiid_to_sapicid); + const char * acpi_get_sysname (void) { @@ -193,6 +198,7 @@ #ifdef CONFIG_SMP smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid; #endif + ia64_acpiid_to_sapicid[lsapic->acpi_id] = (lsapic->id << 8) | lsapic->eid; ++available_cpus; } diff -Nru a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c --- a/arch/x86_64/kernel/i8259.c 2004-08-21 23:40:16 -07:00 +++ b/arch/x86_64/kernel/i8259.c 2004-08-21 23:40:16 -07:00 @@ -342,7 +342,7 @@ } } -void __init init_8259A(int auto_eoi) +void init_8259A(int auto_eoi) { unsigned long flags; @@ -384,6 +384,57 @@ spin_unlock_irqrestore(&i8259A_lock, flags); } + +static char irq_trigger[2]; +/** + * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ + */ +static void restore_ELCR(char *trigger) +{ + outb(trigger[0], 0x4d0); + outb(trigger[1], 0x4d1); +} + +static void save_ELCR(char *trigger) +{ + /* IRQ 0,1,2,8,13 are marked as reserved */ + trigger[0] = inb(0x4d0) & 0xF8; + trigger[1] = inb(0x4d1) & 0xDE; +} + +static int i8259A_resume(struct sys_device *dev) +{ + init_8259A(0); + restore_ELCR(irq_trigger); + return 0; +} + +static int i8259A_suspend(struct sys_device *dev, u32 state) +{ + save_ELCR(irq_trigger); + return 0; +} + +static struct sysdev_class i8259_sysdev_class = { + set_kset_name("i8259"), + .suspend = i8259A_suspend, + .resume = i8259A_resume, +}; + +static struct sys_device device_i8259A = { + .id = 0, + .cls = &i8259_sysdev_class, +}; + +static int __init i8259A_init_sysfs(void) +{ + int error = sysdev_class_register(&i8259_sysdev_class); + if (!error) + error = sysdev_register(&device_i8259A); + return error; +} + +device_initcall(i8259A_init_sysfs); /* * IRQ2 is cascade interrupt to second interrupt controller diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c --- a/arch/x86_64/kernel/setup.c 2004-08-21 23:40:16 -07:00 +++ b/arch/x86_64/kernel/setup.c 2004-08-21 23:40:16 -07:00 @@ -423,6 +423,20 @@ } #endif +#define EBDA_ADDR_POINTER 0x40E +static void __init reserve_ebda_region(void) +{ + unsigned int addr; + /** + * there is a real-mode segmented pointer pointing to the + * 4K EBDA area at 0x40E + */ + addr = *(unsigned short *)phys_to_virt(EBDA_ADDR_POINTER); + addr <<= 4; + if (addr) + reserve_bootmem_generic(addr, PAGE_SIZE); +} + void __init setup_arch(char **cmdline_p) { unsigned long low_mem_size; @@ -486,6 +500,9 @@ * enabling clean reboots, SMP operation, laptop functions. */ reserve_bootmem_generic(0, PAGE_SIZE); + + /* reserve ebda region */ + reserve_ebda_region(); #ifdef CONFIG_SMP /* diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c --- a/arch/x86_64/kernel/smpboot.c 2004-08-21 23:40:16 -07:00 +++ b/arch/x86_64/kernel/smpboot.c 2004-08-21 23:40:16 -07:00 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -62,6 +63,7 @@ /* which logical CPU number maps to which CPU (physical APIC ID) */ volatile char x86_cpu_to_apicid[NR_CPUS]; +EXPORT_SYMBOL(x86_cpu_to_apicid); static cpumask_t cpu_callin_map; cpumask_t cpu_callout_map; diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile --- a/drivers/acpi/Makefile 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/Makefile 2004-08-21 23:40:16 -07:00 @@ -47,4 +47,4 @@ obj-$(CONFIG_ACPI_NUMA) += numa.o obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o -obj-$(CONFIG_ACPI_BUS) += scan.o +obj-$(CONFIG_ACPI_BUS) += scan.o motherboard.o diff -Nru a/drivers/acpi/acpi_ksyms.c b/drivers/acpi/acpi_ksyms.c --- a/drivers/acpi/acpi_ksyms.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/acpi_ksyms.c 2004-08-21 23:40:16 -07:00 @@ -84,6 +84,8 @@ EXPORT_SYMBOL(acpi_enable_event); EXPORT_SYMBOL(acpi_disable_event); EXPORT_SYMBOL(acpi_clear_event); +EXPORT_SYMBOL(acpi_set_gpe_type); +EXPORT_SYMBOL(acpi_enable_gpe); EXPORT_SYMBOL(acpi_get_timer_duration); EXPORT_SYMBOL(acpi_get_timer); EXPORT_SYMBOL(acpi_get_sleep_type_data); diff -Nru a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c --- a/drivers/acpi/asus_acpi.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/asus_acpi.c 2004-08-21 23:40:16 -07:00 @@ -123,14 +123,16 @@ L3C, //L3800C L3D, //L3400D L3H, //L3H, but also L2000E + L4R, //L4500R L5x, //L5800C L8L, //L8400L M1A, //M1300A M2E, //M2400E, L4400L + M6N, //M6800N P30, //Samsung P30 S1x, //S1300A, but also L1400B and M2400A (L84F) S2x, //S200 (J1 reported), Victor MP-XP7210 - xxN, //M2400N, M3700N, M6800N, S1300N, S5200N (Centrino) + xxN, //M2400N, M3700N, M5200N, S1300N, S5200N (Centrino) END_MODEL } model; //Models currently supported u16 event_count[128]; //count for each event TODO make this better @@ -247,6 +249,19 @@ }, { + .name = "L4R", + .mt_mled = "MLED", + .mt_wled = "WLED", + .wled_status = "\\_SB.PCI0.SBRG.SG13", + .mt_lcd_switch = xxN_PREFIX "_Q10", + .lcd_status = "\\_SB.PCI0.SBSM.SEO4", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\_SB.PCI0.P0P1.VGA.GETD" + }, + + { .name = "L5x", .mt_mled = "MLED", /* WLED present, but not controlled by ACPI */ @@ -289,6 +304,19 @@ }, { + .name = "M6N", + .mt_mled = "MLED", + .mt_wled = "WLED", + .wled_status = "\\_SB.PCI0.SBRG.SG13", + .mt_lcd_switch = xxN_PREFIX "_Q10", + .lcd_status = "\\_SB.BKLT", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\SSTE" + }, + + { .name = "P30", .mt_wled = "WLED", .mt_lcd_switch = P30_PREFIX "_Q0E", @@ -428,7 +456,7 @@ len += sprintf(page + len, "SFUN value : 0x%04x\n", temp); /* * Another value for userspace: the ASYM method returns 0x02 for - * battery low and 0x04 for battery critical, it's readings tend to be + * battery low and 0x04 for battery critical, its readings tend to be * more accurate than those provided by _BST. * Note: since not all the laptops provide this method, errors are * silently ignored. @@ -580,7 +608,6 @@ } - static int get_lcd_state(struct asus_hotk *hotk) { int lcd = 0; @@ -764,6 +791,7 @@ if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value)) printk(KERN_WARNING "Asus ACPI: Error reading display status\n"); + value &= 0x07; /* needed for some models, shouldn't hurt others */ return sprintf(page, "%d\n", value); } @@ -869,13 +897,12 @@ } if ((hotk->methods->brightness_up && hotk->methods->brightness_down) || - (hotk->methods->brightness_get && hotk->methods->brightness_get)) { + (hotk->methods->brightness_get && hotk->methods->brightness_set)) { asus_proc_add(PROC_BRN, &proc_write_brn, &proc_read_brn, mode, device); } if (hotk->methods->display_set) { asus_proc_add(PROC_DISP, &proc_write_disp, &proc_read_disp, mode, device); - } return 0; @@ -886,7 +913,7 @@ struct asus_hotk* hotk = acpi_driver_data(device); - if(acpi_device_dir(device)){ + if(acpi_device_dir(device)) { remove_proc_entry(PROC_INFO,acpi_device_dir(device)); if (hotk->methods->mt_wled) remove_proc_entry(PROC_WLED,acpi_device_dir(device)); @@ -894,11 +921,12 @@ remove_proc_entry(PROC_MLED,acpi_device_dir(device)); if (hotk->methods->mt_tled) remove_proc_entry(PROC_TLED,acpi_device_dir(device)); - if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) + if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) remove_proc_entry(PROC_LCD, acpi_device_dir(device)); - if ((hotk->methods->brightness_up && hotk->methods->brightness_down) || (hotk->methods->brightness_get && hotk->methods->brightness_get)) + if ((hotk->methods->brightness_up && hotk->methods->brightness_down) || + (hotk->methods->brightness_get && hotk->methods->brightness_set)) remove_proc_entry(PROC_BRN, acpi_device_dir(device)); - if (hotk->methods->display_set) + if (hotk->methods->display_set) remove_proc_entry(PROC_DISP, acpi_device_dir(device)); } return 0; @@ -998,8 +1026,13 @@ hotk->model = L3C; else if (strncmp(model->string.pointer, "L8L", 3) == 0) hotk->model = L8L; + else if (strncmp(model->string.pointer, "L4R", 3) == 0) + hotk->model = L4R; + else if (strncmp(model->string.pointer, "M6N", 3) == 0) + hotk->model = M6N; else if (strncmp(model->string.pointer, "M2N", 3) == 0 || strncmp(model->string.pointer, "M3N", 3) == 0 || + strncmp(model->string.pointer, "M5N", 3) == 0 || strncmp(model->string.pointer, "M6N", 3) == 0 || strncmp(model->string.pointer, "S1N", 3) == 0 || strncmp(model->string.pointer, "S5N", 3) == 0) @@ -1025,7 +1058,6 @@ hotk->model = L5x; if (hotk->model == END_MODEL) { - /* By default use the same values, as I don't know others */ printk("unsupported, trying default values, supply the " "developers with your DSDT\n"); hotk->model = M2E; @@ -1043,13 +1075,9 @@ else if (strncmp(model->string.pointer, "S5N", 3) == 0) hotk->methods->mt_mled = NULL; /* S5N has no MLED */ - else if (strncmp(model->string.pointer, "M6N", 3) == 0) { - hotk->methods->display_get = NULL; //TODO - hotk->methods->lcd_status = "\\_SB.BKLT"; - hotk->methods->mt_wled = "WLED"; - hotk->methods->wled_status = "\\_SB.PCI0.SBRG.SG13"; - /* M6N differs slightly and has a usable WLED */ - } + else if (strncmp(model->string.pointer, "M2N", 3) == 0) + hotk->methods->mt_wled = "WLED"; + /* M2N has a usable WLED */ else if (asus_info) { if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) hotk->methods->mled_status = NULL; @@ -1062,7 +1090,6 @@ } - static int __init asus_hotk_check(struct asus_hotk *hotk) { int result = 0; @@ -1085,7 +1112,6 @@ } - static int __init asus_hotk_add(struct acpi_device *device) { struct asus_hotk *hotk = NULL; @@ -1151,6 +1177,7 @@ return(result); } + static int asus_hotk_remove(struct acpi_device *device, int type) { diff -Nru a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c --- a/drivers/acpi/blacklist.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/blacklist.c 2004-08-21 23:40:16 -07:00 @@ -56,20 +56,6 @@ */ static struct acpi_blacklist_item acpi_blacklist[] __initdata = { - /* Portege 7020, BIOS 8.10 */ - {"TOSHIB", "7020CT ", 0x19991112, ACPI_DSDT, all_versions, "Implicit Return", 0}, - /* Portege 4030 */ - {"TOSHIB", "4030 ", 0x19991112, ACPI_DSDT, all_versions, "Implicit Return", 0}, - /* Portege 310/320, BIOS 7.1 */ - {"TOSHIB", "310 ", 0x19990511, ACPI_DSDT, all_versions, "Implicit Return", 0}, - /* Seattle 2, old bios rev. */ - {"INTEL ", "440BX ", 0x00001000, ACPI_DSDT, less_than_or_equal, "Field beyond end of region", 0}, - /* ASUS K7M */ - {"ASUS ", "K7M ", 0x00001000, ACPI_DSDT, less_than_or_equal, "Field beyond end of region", 0}, - /* Intel 810 Motherboard? */ - {"MNTRAL", "MO81010A", 0x00000012, ACPI_DSDT, less_than_or_equal, "Field beyond end of region", 0}, - /* Compaq Presario 711FR */ - {"COMAPQ", "EAGLES", 0x06040000, ACPI_DSDT, less_than_or_equal, "SCI issues (C2 disabled)", 0}, /* Compaq Presario 1700 */ {"PTLTD ", " DSDT ", 0x06040000, ACPI_DSDT, less_than_or_equal, "Multiple problems", 1}, /* Sony FX120, FX140, FX150? */ diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c --- a/drivers/acpi/bus.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/bus.c 2004-08-21 23:40:16 -07:00 @@ -590,10 +590,9 @@ } -static int __init -acpi_bus_init (void) +void __init +acpi_early_init (void) { - int result = 0; acpi_status status = AE_OK; struct acpi_buffer buffer = {sizeof(acpi_fadt), &acpi_fadt}; @@ -617,7 +616,7 @@ status = acpi_get_table(ACPI_TABLE_FADT, 1, &buffer); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "Unable to get the FADT\n"); - goto error1; + goto error0; } #ifdef CONFIG_X86 @@ -640,12 +639,40 @@ } #endif - status = acpi_enable_subsystem(ACPI_FULL_INITIALIZATION); + status = acpi_enable_subsystem(~(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE)); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to enable ACPI\n"); + goto error0; + } + + return; + +error0: + disable_acpi(); + return; +} + +static int __init +acpi_bus_init (void) +{ + int result = 0; + acpi_status status = AE_OK; + extern acpi_status acpi_os_initialize1(void); + + ACPI_FUNCTION_TRACE("acpi_bus_init"); + + status = acpi_os_initialize1(); + + status = acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "Unable to start the ACPI Interpreter\n"); goto error1; } + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to initialize ACPI OS objects\n"); + goto error1; + } #ifdef CONFIG_ACPI_EC /* * ACPI 2.0 requires the EC driver to be loaded and work before @@ -693,7 +720,6 @@ /* Mimic structured exception handling */ error1: acpi_terminate(); -error0: return_VALUE(-ENODEV); } diff -Nru a/drivers/acpi/button.c b/drivers/acpi/button.c --- a/drivers/acpi/button.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/button.c 2004-08-21 23:40:16 -07:00 @@ -456,6 +456,15 @@ goto end; } + if (device->wakeup.flags.valid) { + /* Button's GPE is run-wake GPE */ + acpi_set_gpe_type(device->wakeup.gpe_device, + device->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN); + acpi_enable_gpe(device->wakeup.gpe_device, + device->wakeup.gpe_number, ACPI_NOT_ISR); + device->wakeup.state.enabled = 1; + } + printk(KERN_INFO PREFIX "%s [%s]\n", acpi_device_name(device), acpi_device_bid(device)); diff -Nru a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c --- a/drivers/acpi/dispatcher/dsmethod.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/dispatcher/dsmethod.c 2004-08-21 23:40:16 -07:00 @@ -145,8 +145,9 @@ return_ACPI_STATUS (AE_NO_MEMORY); } - status = acpi_ds_init_aml_walk (walk_state, op, node, obj_desc->method.aml_start, - obj_desc->method.aml_length, NULL, NULL, 1); + status = acpi_ds_init_aml_walk (walk_state, op, node, + obj_desc->method.aml_start, + obj_desc->method.aml_length, NULL, 1); if (ACPI_FAILURE (status)) { acpi_ds_delete_walk_state (walk_state); return_ACPI_STATUS (status); @@ -267,8 +268,9 @@ { acpi_status status; struct acpi_namespace_node *method_node; - union acpi_operand_object *obj_desc; struct acpi_walk_state *next_walk_state; + union acpi_operand_object *obj_desc; + struct acpi_parameter_info info; u32 i; @@ -309,7 +311,6 @@ return_ACPI_STATUS (AE_NO_MEMORY); } - /* Create and init a Root Node */ op = acpi_ps_create_scope_op (); @@ -320,7 +321,7 @@ status = acpi_ds_init_aml_walk (next_walk_state, op, method_node, obj_desc->method.aml_start, obj_desc->method.aml_length, - NULL, NULL, 1); + NULL, 1); if (ACPI_FAILURE (status)) { acpi_ds_delete_walk_state (next_walk_state); goto cleanup; @@ -348,9 +349,12 @@ */ this_walk_state->operands [this_walk_state->num_operands] = NULL; + info.parameters = &this_walk_state->operands[0]; + info.parameter_type = ACPI_PARAM_ARGS; + status = acpi_ds_init_aml_walk (next_walk_state, NULL, method_node, obj_desc->method.aml_start, obj_desc->method.aml_length, - &this_walk_state->operands[0], NULL, 3); + &info, 3); if (ACPI_FAILURE (status)) { goto cleanup; } @@ -382,7 +386,7 @@ /* On error, we must delete the new walk state */ cleanup: - if (next_walk_state->method_desc) { + if (next_walk_state && (next_walk_state->method_desc)) { /* Decrement the thread count on the method parse tree */ next_walk_state->method_desc->method.thread_count--; diff -Nru a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c --- a/drivers/acpi/dispatcher/dsmthdat.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/dispatcher/dsmthdat.c 2004-08-21 23:40:16 -07:00 @@ -656,11 +656,13 @@ new_obj_desc, current_obj_desc)); /* - * Store this object to the Node - * (perform the indirect store) + * Store this object to the Node (perform the indirect store) + * NOTE: No implicit conversion is performed, as per the ACPI + * specification rules on storing to Locals/Args. */ status = acpi_ex_store_object_to_node (new_obj_desc, - current_obj_desc->reference.object, walk_state); + current_obj_desc->reference.object, walk_state, + ACPI_NO_IMPLICIT_CONVERSION); /* Remove local reference if we copied the object above */ diff -Nru a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c --- a/drivers/acpi/dispatcher/dsopcode.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/dispatcher/dsopcode.c 2004-08-21 23:40:16 -07:00 @@ -79,7 +79,6 @@ acpi_status status; union acpi_parse_object *op; struct acpi_walk_state *walk_state; - union acpi_parse_object *arg; ACPI_FUNCTION_TRACE ("ds_execute_arguments"); @@ -105,7 +104,7 @@ } status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, - aml_length, NULL, NULL, 1); + aml_length, NULL, 1); if (ACPI_FAILURE (status)) { acpi_ds_delete_walk_state (walk_state); return_ACPI_STATUS (status); @@ -126,9 +125,7 @@ /* Get and init the Op created above */ - arg = op->common.value.arg; op->common.node = node; - arg->common.node = node; acpi_ps_delete_parse_tree (op); /* Evaluate the deferred arguments */ @@ -150,7 +147,7 @@ /* Execute the opcode and arguments */ status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, - aml_length, NULL, NULL, 3); + aml_length, NULL, 3); if (ACPI_FAILURE (status)) { acpi_ds_delete_walk_state (walk_state); return_ACPI_STATUS (status); diff -Nru a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c --- a/drivers/acpi/dispatcher/dswload.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/dispatcher/dswload.c 2004-08-21 23:40:16 -07:00 @@ -50,6 +50,9 @@ #include #include +#ifdef _ACPI_ASL_COMPILER +#include +#endif #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dswload") @@ -180,7 +183,17 @@ status = acpi_ns_lookup (walk_state->scope_info, path, object_type, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node)); if (ACPI_FAILURE (status)) { +#ifdef _ACPI_ASL_COMPILER + if (status == AE_NOT_FOUND) { + acpi_dm_add_to_external_list (path); + status = AE_OK; + } + else { + ACPI_REPORT_NSERROR (path, status); + } +#else ACPI_REPORT_NSERROR (path, status); +#endif return (status); } @@ -529,7 +542,16 @@ status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node)); if (ACPI_FAILURE (status)) { +#ifdef _ACPI_ASL_COMPILER + if (status == AE_NOT_FOUND) { + status = AE_OK; + } + else { + ACPI_REPORT_NSERROR (buffer_ptr, status); + } +#else ACPI_REPORT_NSERROR (buffer_ptr, status); +#endif return_ACPI_STATUS (status); } /* diff -Nru a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c --- a/drivers/acpi/dispatcher/dswstate.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/dispatcher/dswstate.c 2004-08-21 23:40:16 -07:00 @@ -906,8 +906,7 @@ struct acpi_namespace_node *method_node, u8 *aml_start, u32 aml_length, - union acpi_operand_object **params, - union acpi_operand_object **return_obj_desc, + struct acpi_parameter_info *info, u32 pass_number) { acpi_status status; @@ -926,8 +925,17 @@ /* The next_op of the next_walk will be the beginning of the method */ walk_state->next_op = NULL; - walk_state->params = params; - walk_state->caller_return_desc = return_obj_desc; + + if (info) { + if (info->parameter_type == ACPI_PARAM_GPE) { + walk_state->gpe_event_info = ACPI_CAST_PTR (struct acpi_gpe_event_info, + info->parameters); + } + else { + walk_state->params = info->parameters; + walk_state->caller_return_desc = &info->return_object; + } + } status = acpi_ps_init_scope (&walk_state->parser_state, op); if (ACPI_FAILURE (status)) { @@ -949,7 +957,7 @@ /* Init the method arguments */ - status = acpi_ds_method_data_init_args (params, ACPI_METHOD_NUM_ARGS, walk_state); + status = acpi_ds_method_data_init_args (walk_state->params, ACPI_METHOD_NUM_ARGS, walk_state); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c --- a/drivers/acpi/ec.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/ec.c 2004-08-21 23:40:16 -07:00 @@ -381,7 +381,7 @@ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); } -static void +static u32 acpi_ec_gpe_handler ( void *data) { @@ -389,12 +389,17 @@ struct acpi_ec *ec = (struct acpi_ec *) data; if (!ec) - return; + return ACPI_INTERRUPT_NOT_HANDLED; acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR); status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, acpi_ec_gpe_query, ec); + + if (status == AE_OK) + return ACPI_INTERRUPT_HANDLED; + else + return ACPI_INTERRUPT_NOT_HANDLED; } /* -------------------------------------------------------------------------- @@ -729,6 +734,8 @@ if (ACPI_FAILURE(status)) { return_VALUE(-ENODEV); } + acpi_set_gpe_type (NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME); + acpi_enable_gpe (NULL, ec->gpe_bit, ACPI_NOT_ISR); status = acpi_install_address_space_handler (ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, @@ -814,6 +821,8 @@ if (ACPI_FAILURE(status)) { goto error; } + acpi_set_gpe_type (NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME); + acpi_enable_gpe (NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR); status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, diff -Nru a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c --- a/drivers/acpi/events/evevent.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/events/evevent.c 2004-08-21 23:40:16 -07:00 @@ -50,7 +50,7 @@ /******************************************************************************* * - * FUNCTION: acpi_ev_initialize + * FUNCTION: acpi_ev_initialize_events * * PARAMETERS: None * @@ -61,13 +61,13 @@ ******************************************************************************/ acpi_status -acpi_ev_initialize ( +acpi_ev_initialize_events ( void) { acpi_status status; - ACPI_FUNCTION_TRACE ("ev_initialize"); + ACPI_FUNCTION_TRACE ("ev_initialize_events"); /* Make sure we have ACPI tables */ @@ -104,7 +104,7 @@ /******************************************************************************* * - * FUNCTION: acpi_ev_handler_initialize + * FUNCTION: acpi_ev_install_xrupt_handlers * * PARAMETERS: None * @@ -115,13 +115,13 @@ ******************************************************************************/ acpi_status -acpi_ev_handler_initialize ( +acpi_ev_install_xrupt_handlers ( void) { acpi_status status; - ACPI_FUNCTION_TRACE ("ev_handler_initialize"); + ACPI_FUNCTION_TRACE ("ev_install_xrupt_handlers"); /* Install the SCI handler */ diff -Nru a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c --- a/drivers/acpi/events/evgpe.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/events/evgpe.c 2004-08-21 23:40:16 -07:00 @@ -51,6 +51,249 @@ /******************************************************************************* * + * FUNCTION: acpi_ev_set_gpe_type + * + * PARAMETERS: gpe_event_info - GPE to set + * Type - New type + * + * RETURN: Status + * + * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run) + * + ******************************************************************************/ + +acpi_status +acpi_ev_set_gpe_type ( + struct acpi_gpe_event_info *gpe_event_info, + u8 type) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_set_gpe_type"); + + + /* Validate type and update register enable masks */ + + switch (type) { + case ACPI_GPE_TYPE_WAKE: + case ACPI_GPE_TYPE_RUNTIME: + case ACPI_GPE_TYPE_WAKE_RUN: + break; + + default: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* Disable the GPE if currently enabled */ + + status = acpi_ev_disable_gpe (gpe_event_info); + + /* Type was validated above */ + + gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */ + gpe_event_info->flags |= type; /* Insert type */ + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_update_gpe_enable_masks + * + * PARAMETERS: gpe_event_info - GPE to update + * + * RETURN: Status + * + * DESCRIPTION: Updates GPE register enable masks based on the GPE type + * + ******************************************************************************/ + +acpi_status +acpi_ev_update_gpe_enable_masks ( + struct acpi_gpe_event_info *gpe_event_info, + u8 type) +{ + struct acpi_gpe_register_info *gpe_register_info; + u8 register_bit; + + + ACPI_FUNCTION_TRACE ("ev_update_gpe_enable_masks"); + + + gpe_register_info = gpe_event_info->register_info; + if (!gpe_register_info) { + return_ACPI_STATUS (AE_NOT_EXIST); + } + register_bit = gpe_event_info->register_bit; + + /* 1) Disable case. Simply clear all enable bits */ + + if (type == ACPI_GPE_DISABLE) { + ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit); + ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit); + return_ACPI_STATUS (AE_OK); + } + + /* 2) Enable case. Set/Clear the appropriate enable bits */ + + switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) { + case ACPI_GPE_TYPE_WAKE: + ACPI_SET_BIT (gpe_register_info->enable_for_wake, register_bit); + ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit); + break; + + case ACPI_GPE_TYPE_RUNTIME: + ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit); + ACPI_SET_BIT (gpe_register_info->enable_for_run, register_bit); + break; + + case ACPI_GPE_TYPE_WAKE_RUN: + ACPI_SET_BIT (gpe_register_info->enable_for_wake, register_bit); + ACPI_SET_BIT (gpe_register_info->enable_for_run, register_bit); + break; + + default: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_enable_gpe + * + * PARAMETERS: gpe_event_info - GPE to enable + * + * RETURN: Status + * + * DESCRIPTION: Enable a GPE based on the GPE type + * + ******************************************************************************/ + +acpi_status +acpi_ev_enable_gpe ( + struct acpi_gpe_event_info *gpe_event_info, + u8 write_to_hardware) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_enable_gpe"); + + + /* Make sure HW enable masks are updated */ + + status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_ENABLE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Mark wake-enabled or HW enable, or both */ + + switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) { + case ACPI_GPE_TYPE_WAKE: + + ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); + break; + + case ACPI_GPE_TYPE_WAKE_RUN: + + ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); + + /*lint -fallthrough */ + + case ACPI_GPE_TYPE_RUNTIME: + + ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED); + + if (write_to_hardware) { + /* Clear the GPE (of stale events), then enable it */ + + status = acpi_hw_clear_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Enable the requested runtime GPE */ + + status = acpi_hw_write_gpe_enable_reg (gpe_event_info); + } + break; + + default: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_disable_gpe + * + * PARAMETERS: gpe_event_info - GPE to disable + * + * RETURN: Status + * + * DESCRIPTION: Disable a GPE based on the GPE type + * + ******************************************************************************/ + +acpi_status +acpi_ev_disable_gpe ( + struct acpi_gpe_event_info *gpe_event_info) +{ + acpi_status status; + + + 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 = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_DISABLE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Mark wake-disabled or HW disable, or both */ + + switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) { + case ACPI_GPE_TYPE_WAKE: + ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); + break; + + case ACPI_GPE_TYPE_WAKE_RUN: + ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); + + /*lint -fallthrough */ + + case ACPI_GPE_TYPE_RUNTIME: + + /* Disable the requested runtime GPE */ + + ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED); + status = acpi_hw_write_gpe_enable_reg (gpe_event_info); + break; + + default: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * * FUNCTION: acpi_ev_get_gpe_event_info * * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1 @@ -139,11 +382,12 @@ u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; u8 enabled_status_byte; struct acpi_gpe_register_info *gpe_register_info; - u32 in_value; + u32 status_reg; + u32 enable_reg; acpi_status status; struct acpi_gpe_block_info *gpe_block; - u32 i; - u32 j; + acpi_native_uint i; + acpi_native_uint j; ACPI_FUNCTION_NAME ("ev_gpe_detect"); @@ -171,33 +415,32 @@ /* Read the Status Register */ - status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, + status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &status_reg, &gpe_register_info->status_address); - gpe_register_info->status = (u8) in_value; if (ACPI_FAILURE (status)) { goto unlock_and_exit; } /* Read the Enable Register */ - status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, + status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &enable_reg, &gpe_register_info->enable_address); - gpe_register_info->enable = (u8) in_value; if (ACPI_FAILURE (status)) { goto unlock_and_exit; } ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, "GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n", - ACPI_FORMAT_UINT64 (gpe_register_info->status_address.address), - gpe_register_info->status, - ACPI_FORMAT_UINT64 (gpe_register_info->enable_address.address), - gpe_register_info->enable)); + ACPI_FORMAT_UINT64 ( + gpe_register_info->status_address.address), + status_reg, + ACPI_FORMAT_UINT64 ( + gpe_register_info->enable_address.address), + enable_reg)); /* First check if there is anything active at all in this register */ - enabled_status_byte = (u8) (gpe_register_info->status & - gpe_register_info->enable); + enabled_status_byte = (u8) (status_reg & enable_reg); if (!enabled_status_byte) { /* No active GPEs in this register, move on */ @@ -216,7 +459,7 @@ */ int_status |= acpi_ev_gpe_dispatch ( &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j], - j + gpe_register_info->base_gpe_number); + (u32) j + gpe_register_info->base_gpe_number); } } } @@ -255,6 +498,7 @@ u32 gpe_number = 0; acpi_status status; struct acpi_gpe_event_info local_gpe_event_info; + struct acpi_parameter_info info; ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method"); @@ -272,6 +516,10 @@ return_VOID; } + /* Set the GPE flags for return to enabled state */ + + (void) acpi_ev_enable_gpe (gpe_event_info, FALSE); + /* * Take a snapshot of the GPE info for this level - we copy the * info to prevent a race condition with remove_handler/remove_block. @@ -283,23 +531,33 @@ return_VOID; } - if (local_gpe_event_info.method_node) { + /* + * Must check for control method type dispatch one more + * time to avoid race with ev_gpe_install_handler + */ + if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) { /* - * Invoke the GPE Method (_Lxx, _Exx): - * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.) + * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx + * control method that corresponds to this GPE */ - status = acpi_ns_evaluate_by_handle (local_gpe_event_info.method_node, NULL, NULL); + info.node = local_gpe_event_info.dispatch.method_node; + info.parameters = ACPI_CAST_PTR (union acpi_operand_object *, gpe_event_info); + info.parameter_type = ACPI_PARAM_GPE; + + status = acpi_ns_evaluate_by_handle (&info); if (ACPI_FAILURE (status)) { - ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n", + ACPI_REPORT_ERROR (( + "%s while evaluating method [%4.4s] for GPE[%2X]\n", acpi_format_exception (status), - acpi_ut_get_node_name (local_gpe_event_info.method_node), gpe_number)); + acpi_ut_get_node_name (local_gpe_event_info.dispatch.method_node), + gpe_number)); } } if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) { /* - * GPE is level-triggered, we clear the GPE status bit after handling - * the event. + * GPE is level-triggered, we clear the GPE status bit after + * handling the event. */ status = acpi_hw_clear_gpe (&local_gpe_event_info); if (ACPI_FAILURE (status)) { @@ -309,7 +567,7 @@ /* Enable this GPE */ - (void) acpi_hw_enable_gpe (&local_gpe_event_info); + (void) acpi_hw_write_gpe_enable_reg (&local_gpe_event_info); return_VOID; } @@ -354,6 +612,15 @@ } } + /* Save current system state */ + + if (acpi_gbl_system_awake_and_running) { + ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); + } + else { + ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); + } + /* * Dispatch the GPE to either an installed handler, or the control * method associated with this GPE (_Lxx or _Exx). @@ -361,10 +628,15 @@ * If there is neither a handler nor a method, we disable the level to * prevent further events from coming in here. */ - if (gpe_event_info->handler) { - /* Invoke the installed handler (at interrupt level) */ + switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { + case ACPI_GPE_DISPATCH_HANDLER: - gpe_event_info->handler (gpe_event_info->context); + /* + * Invoke the installed handler (at interrupt level) + * Ignore return status for now. TBD: leave GPE disabled on error? + */ + (void) gpe_event_info->dispatch.handler->address ( + gpe_event_info->dispatch.handler->context); /* It is now safe to clear level-triggered events. */ @@ -377,13 +649,15 @@ return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); } } - } - else if (gpe_event_info->method_node) { + break; + + case ACPI_GPE_DISPATCH_METHOD: + /* * Disable GPE, so it doesn't keep firing before the method has a * chance to run. */ - status = acpi_hw_disable_gpe (gpe_event_info); + status = acpi_ev_disable_gpe (gpe_event_info); if (ACPI_FAILURE (status)) { ACPI_REPORT_ERROR (( "acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n", @@ -402,8 +676,10 @@ "acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2X], event is disabled\n", gpe_number)); } - } - else { + break; + + default: + /* No handler or method to run! */ ACPI_REPORT_ERROR (( @@ -414,15 +690,68 @@ * Disable the GPE. The GPE will remain disabled until the ACPI * Core Subsystem is restarted, or a handler is installed. */ - status = acpi_hw_disable_gpe (gpe_event_info); + status = acpi_ev_disable_gpe (gpe_event_info); if (ACPI_FAILURE (status)) { ACPI_REPORT_ERROR (( "acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n", gpe_number)); return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); } + break; } return_VALUE (ACPI_INTERRUPT_HANDLED); } + + +#ifdef ACPI_GPE_NOTIFY_CHECK + +/******************************************************************************* + * NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED + * + * FUNCTION: acpi_ev_check_for_wake_only_gpe + * + * PARAMETERS: gpe_event_info - info for this GPE + * + * RETURN: Status + * + * DESCRIPTION: Determine if a a GPE is "wake-only". + * + * Called from Notify() code in interpreter when a "device_wake" + * Notify comes in. + * + ******************************************************************************/ + +acpi_status +acpi_ev_check_for_wake_only_gpe ( + struct acpi_gpe_event_info *gpe_event_info) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_check_for_wake_only_gpe"); + + + if ((gpe_event_info) && /* Only >0 for _Lxx/_Exx */ + ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) /* System state at GPE time */ { + /* This must be a wake-only GPE, disable it */ + + status = acpi_ev_disable_gpe (gpe_event_info); + + /* Set GPE to wake-only. Do not change wake disabled/enabled status */ + + acpi_ev_set_gpe_type (gpe_event_info, ACPI_GPE_TYPE_WAKE); + + ACPI_REPORT_INFO (("GPE %p was updated from wake/run to wake-only\n", + gpe_event_info)); + + /* This was a wake-only GPE */ + + return_ACPI_STATUS (AE_WAKE_ONLY_GPE); + } + + return_ACPI_STATUS (AE_OK); +} +#endif + diff -Nru a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c --- a/drivers/acpi/events/evgpeblk.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/events/evgpeblk.c 2004-08-21 23:40:16 -07:00 @@ -53,7 +53,7 @@ * * FUNCTION: acpi_ev_valid_gpe_event * - * PARAMETERS: gpe_event_info - Info for this GPE + * PARAMETERS: gpe_event_info - Info for this GPE * * RETURN: TRUE if the gpe_event is valid * @@ -105,17 +105,18 @@ * FUNCTION: acpi_ev_walk_gpe_list * * PARAMETERS: gpe_walk_callback - Routine called for each GPE block + * Flags - ACPI_NOT_ISR or ACPI_ISR * * RETURN: Status * * DESCRIPTION: Walk the GPE lists. - * FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED * ******************************************************************************/ acpi_status acpi_ev_walk_gpe_list ( - ACPI_GPE_CALLBACK gpe_walk_callback) + ACPI_GPE_CALLBACK gpe_walk_callback, + u32 flags) { struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_xrupt_info *gpe_xrupt_info; @@ -125,7 +126,7 @@ ACPI_FUNCTION_TRACE ("ev_walk_gpe_list"); - acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR); + acpi_os_acquire_lock (acpi_gbl_gpe_lock, flags); /* Walk the interrupt level descriptor list */ @@ -149,11 +150,58 @@ } unlock_and_exit: - acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR); + acpi_os_release_lock (acpi_gbl_gpe_lock, flags); return_ACPI_STATUS (status); } +/****************************************************************************** + * + * FUNCTION: acpi_ev_delete_gpe_handlers + * + * PARAMETERS: gpe_xrupt_info - GPE Interrupt info + * gpe_block - Gpe Block info + * + * RETURN: Status + * + * DESCRIPTION: Delete all Handler objects found in the GPE data structs. + * Used only prior to termination. + * + ******************************************************************************/ + +acpi_status +acpi_ev_delete_gpe_handlers ( + struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block) +{ + struct acpi_gpe_event_info *gpe_event_info; + acpi_native_uint i; + acpi_native_uint j; + + + ACPI_FUNCTION_TRACE ("ev_delete_gpe_handlers"); + + + /* Examine each GPE Register within the block */ + + for (i = 0; i < gpe_block->register_count; i++) { + /* Now look at the individual GPEs in this byte register */ + + for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { + gpe_event_info = &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j]; + + if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) { + ACPI_MEM_FREE (gpe_event_info->dispatch.handler); + gpe_event_info->dispatch.handler = NULL; + gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; + } + } + } + + return_ACPI_STATUS (AE_OK); +} + + /******************************************************************************* * * FUNCTION: acpi_ev_save_method_info @@ -188,6 +236,7 @@ u32 gpe_number; char name[ACPI_NAME_SIZE + 1]; u8 type; + acpi_status status; ACPI_FUNCTION_TRACE ("ev_save_method_info"); @@ -206,16 +255,16 @@ * 2) Edge/Level determination is based on the 2nd character * of the method name * - * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE if a - * _PRW object is found that points to this GPE. + * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE + * if a _PRW object is found that points to this GPE. */ switch (name[1]) { case 'L': - type = ACPI_GPE_LEVEL_TRIGGERED | ACPI_GPE_TYPE_RUNTIME; + type = ACPI_GPE_LEVEL_TRIGGERED; break; case 'E': - type = ACPI_GPE_EDGE_TRIGGERED | ACPI_GPE_TYPE_RUNTIME; + type = ACPI_GPE_EDGE_TRIGGERED; break; default: @@ -253,27 +302,35 @@ /* * Now we can add this information to the gpe_event_info block - * for use during dispatch of this GPE. + * for use during dispatch of this GPE. Default type is RUNTIME, although + * this may change when the _PRW methods are executed later. */ gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number]; - gpe_event_info->flags = type; - gpe_event_info->method_node = (struct acpi_namespace_node *) obj_handle; + gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD | + ACPI_GPE_TYPE_RUNTIME); + + gpe_event_info->dispatch.method_node = (struct acpi_namespace_node *) obj_handle; + + /* Update enable mask, but don't enable the HW GPE as of yet */ + + status = acpi_ev_enable_gpe (gpe_event_info, FALSE); ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Registered GPE method %s as GPE number 0x%.2X\n", name, gpe_number)); - return_ACPI_STATUS (AE_OK); + return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: acpi_ev_get_gpe_type + * FUNCTION: acpi_ev_match_prw_and_gpe * * PARAMETERS: Callback from walk_namespace * - * RETURN: Status + * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is + * not aborted on a single _PRW failure. * * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a * Device. Run the _PRW method. If present, extract the GPE @@ -282,7 +339,7 @@ ******************************************************************************/ static acpi_status -acpi_ev_get_gpe_type ( +acpi_ev_match_prw_and_gpe ( acpi_handle obj_handle, u32 level, void *info, @@ -299,19 +356,18 @@ acpi_status status; - ACPI_FUNCTION_TRACE ("ev_get_gpe_type"); + ACPI_FUNCTION_TRACE ("ev_match_prw_and_gpe"); /* Check for a _PRW method under this device */ status = acpi_ut_evaluate_object (obj_handle, METHOD_NAME__PRW, ACPI_BTYPE_PACKAGE, &pkg_desc); - if (status == AE_NOT_FOUND) { + if (ACPI_FAILURE (status)) { + /* Ignore all errors from _PRW, we don't want to abort the subsystem */ + return_ACPI_STATUS (AE_OK); } - else if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } /* The returned _PRW package must have at least two elements */ @@ -370,16 +426,21 @@ if ((gpe_device == target_gpe_device) && (gpe_number >= gpe_block->block_base_number) && (gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) { - /* Mark GPE for WAKE but DISABLED (even for wake) */ - gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number]; - gpe_event_info->flags |= ACPI_GPE_TYPE_WAKE; + + /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */ + + gpe_event_info->flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED); + status = acpi_ev_set_gpe_type (gpe_event_info, ACPI_GPE_TYPE_WAKE); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_DISABLE); } cleanup: acpi_ut_remove_reference (pkg_desc); - - return_ACPI_STATUS (status); + return_ACPI_STATUS (AE_OK); } @@ -742,7 +803,7 @@ /* Init the event_info for each GPE within this register */ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { - this_event->bit_mask = acpi_gbl_decode_to8bit[j]; + this_event->register_bit = acpi_gbl_decode_to8bit[j]; this_event->register_info = this_register; this_event++; } @@ -817,6 +878,7 @@ acpi_status status; struct acpi_gpe_walk_info gpe_info; + ACPI_FUNCTION_TRACE ("ev_create_gpe_block"); @@ -835,6 +897,7 @@ gpe_block->register_count = register_count; gpe_block->block_base_number = gpe_block_base_number; + gpe_block->node = gpe_device; ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address)); @@ -854,18 +917,6 @@ return_ACPI_STATUS (status); } - /* Dump info about this GPE block */ - - ACPI_DEBUG_PRINT ((ACPI_DB_INIT, - "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n", - gpe_block->block_base_number, - (u32) (gpe_block->block_base_number + - ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)), - gpe_device->name.ascii, - gpe_block->register_count, - ACPI_FORMAT_UINT64 (gpe_block->block_address.address), - interrupt_level)); - /* Find all GPE methods (_Lxx, _Exx) for this block */ status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device, @@ -873,27 +924,28 @@ gpe_block, NULL); /* - * Runtime option: Should Wake GPEs be enabled at runtime? The default is - * No,they should only be enabled just as the machine goes to sleep. + * Runtime option: Should Wake GPEs be enabled at runtime? The default + * is No,they should only be enabled just as the machine goes to sleep. */ if (acpi_gbl_leave_wake_gpes_disabled) { /* - * Differentiate RUNTIME vs WAKE GPEs, via the _PRW control methods. (Each - * GPE that has one or more _PRWs that reference it is by definition a - * WAKE GPE and will not be enabled while the machine is running.) + * Differentiate RUNTIME vs WAKE GPEs, via the _PRW control methods. + * (Each GPE that has one or more _PRWs that reference it is by + * definition a WAKE GPE and will not be enabled while the machine + * is running.) */ gpe_info.gpe_block = gpe_block; gpe_info.gpe_device = gpe_device; status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ev_get_gpe_type, + ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ev_match_prw_and_gpe, &gpe_info, NULL); } /* - * Enable all GPEs in this block that are 1) "runtime" GPEs, and 2) have - * a corresponding _Lxx or _Exx method. All other GPEs must be enabled via - * the acpi_enable_gpe() external interface. + * Enable all GPEs in this block that are 1) "runtime" or "run/wake" GPEs, + * and 2) have a corresponding _Lxx or _Exx method. All other GPEs must + * be enabled via the acpi_enable_gpe() external interface. */ wake_gpe_count = 0; gpe_enabled_count = 0; @@ -903,23 +955,35 @@ /* Get the info block for this particular GPE */ gpe_event_info = &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j]; - if ((gpe_event_info->method_node) && - ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == ACPI_GPE_TYPE_RUNTIME)) { - /* Enable this GPE, it is 1) RUNTIME and 2) has an _Lxx or _Exx method */ - - status = acpi_hw_enable_gpe (gpe_event_info); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + + if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) && + (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) { gpe_enabled_count++; } - if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == ACPI_GPE_TYPE_WAKE) { + if (gpe_event_info->flags & ACPI_GPE_TYPE_WAKE) { wake_gpe_count++; } } } + /* Dump info about this GPE block */ + + ACPI_DEBUG_PRINT ((ACPI_DB_INIT, + "GPE %02X to %02X [%4.4s] %u regs at %8.8X%8.8X on int 0x%X\n", + (u32) gpe_block->block_base_number, + (u32) (gpe_block->block_base_number + + ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)), + gpe_device->name.ascii, + gpe_block->register_count, + ACPI_FORMAT_UINT64 (gpe_block->block_address.address), + interrupt_level)); + + + /* Enable all valid GPEs found above */ + + status = acpi_hw_enable_runtime_gpe_block (NULL, gpe_block); + ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Found %u Wake, Enabled %u Runtime GPEs in this block\n", wake_gpe_count, gpe_enabled_count)); @@ -1056,7 +1120,8 @@ if ((register_count0 + register_count1) == 0) { /* GPEs are not required by ACPI, this is OK */ - ACPI_REPORT_INFO (("There are no GPE blocks defined in the FADT\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_INIT, + "There are no GPE blocks defined in the FADT\n")); status = AE_OK; goto cleanup; } diff -Nru a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c --- a/drivers/acpi/events/evmisc.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/events/evmisc.c 2004-08-21 23:40:16 -07:00 @@ -139,8 +139,7 @@ acpi_notify_value_names[notify_value])); } else { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "notify value: 0x%2.2x **Device Specific**\n", + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: 0x%2.2X **Device Specific**\n", notify_value)); } @@ -197,8 +196,8 @@ /* There is no per-device notify handler for this device */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "No notify handler for [%4.4s] node %p\n", - acpi_ut_get_node_name (node), node)); + "No notify handler for Notify(%4.4s, %X) node %p\n", + acpi_ut_get_node_name (node), notify_value, node)); } return (status); @@ -548,7 +547,7 @@ /* Disable all GPEs in all GPE blocks */ - status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block); + status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block, ACPI_NOT_ISR); /* Remove SCI handler */ @@ -557,6 +556,10 @@ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not remove SCI handler\n")); } } + + /* Deallocate all handler objects installed within GPE info structs */ + + status = acpi_ev_walk_gpe_list (acpi_ev_delete_gpe_handlers, ACPI_NOT_ISR); /* Return to original mode if necessary */ diff -Nru a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c --- a/drivers/acpi/events/evregion.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/events/evregion.c 2004-08-21 23:40:16 -07:00 @@ -61,7 +61,7 @@ /******************************************************************************* * - * FUNCTION: acpi_ev_init_address_spaces + * FUNCTION: acpi_ev_install_region_handlers * * PARAMETERS: None * @@ -72,15 +72,20 @@ ******************************************************************************/ acpi_status -acpi_ev_init_address_spaces ( +acpi_ev_install_region_handlers ( void) { acpi_status status; acpi_native_uint i; - ACPI_FUNCTION_TRACE ("ev_init_address_spaces"); + ACPI_FUNCTION_TRACE ("ev_install_region_handlers"); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + /* * All address spaces (PCI Config, EC, SMBus) are scope dependent * and registration must occur for a specific device. @@ -99,9 +104,8 @@ * has already been installed (via acpi_install_address_space_handler). * Similar for AE_SAME_HANDLER. */ - for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { - status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node, + status = acpi_ev_install_space_handler (acpi_gbl_root_node, acpi_gbl_default_address_spaces[i], ACPI_DEFAULT_HANDLER, NULL, NULL); switch (status) { @@ -111,15 +115,63 @@ /* These exceptions are all OK */ + status = AE_OK; break; default: - return_ACPI_STATUS (status); + goto unlock_and_exit; } } - return_ACPI_STATUS (AE_OK); +unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_initialize_op_regions + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Execute _REG methods for all Operation Regions that have + * an installed default region handler. + * + ******************************************************************************/ + +acpi_status +acpi_ev_initialize_op_regions ( + void) +{ + acpi_status status; + acpi_native_uint i; + + + ACPI_FUNCTION_TRACE ("ev_initialize_op_regions"); + + + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* + * Run the _REG methods for op_regions in each default address space + */ + for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { + /* TBD: Make sure handler is the DEFAULT handler, otherwise + * _REG will have already been run. + */ + status = acpi_ev_execute_reg_methods (acpi_gbl_root_node, + acpi_gbl_default_address_spaces[i]); + } + + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return_ACPI_STATUS (status); } @@ -138,11 +190,12 @@ acpi_status acpi_ev_execute_reg_method ( - union acpi_operand_object *region_obj, + union acpi_operand_object *region_obj, u32 function) { - union acpi_operand_object *params[3]; - union acpi_operand_object *region_obj2; + struct acpi_parameter_info info; + union acpi_operand_object *params[3]; + union acpi_operand_object *region_obj2; acpi_status status; @@ -159,10 +212,11 @@ } /* - * _REG method has two arguments - * Arg0: Integer: Operation region space ID + * The _REG method has two arguments: + * + * Arg0, Integer: Operation region space ID * Same value as region_obj->Region.space_id - * Arg1: Integer: connection status + * Arg1, Integer: connection status * 1 for connecting the handler, * 0 for disconnecting the handler * Passed as a parameter @@ -184,10 +238,15 @@ params[1]->integer.value = function; params[2] = NULL; + info.node = region_obj2->extra.method_REG; + info.parameters = params; + info.parameter_type = ACPI_PARAM_ARGS; + /* Execute the method, no return value */ - ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, region_obj2->extra.method_REG, NULL)); - status = acpi_ns_evaluate_by_handle (region_obj2->extra.method_REG, params, NULL); + ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname ( + ACPI_TYPE_METHOD, info.node, NULL)); + status = acpi_ns_evaluate_by_handle (&info); acpi_ut_remove_reference (params[1]); @@ -326,7 +385,7 @@ ACPI_FORMAT_UINT64 (address), acpi_ut_get_region_name (region_obj->region.space_id))); - if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { + if (!(handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * For handlers other than the default (supplied) handlers, we must * exit the interpreter because the handler *might* block -- we don't @@ -347,7 +406,7 @@ acpi_format_exception (status))); } - if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { + if (!(handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * We just returned from a non-default handler, we must re-enter the * interpreter @@ -676,6 +735,273 @@ return (status); } + +/******************************************************************************* + * + * FUNCTION: acpi_ev_install_space_handler + * + * PARAMETERS: Node - Namespace node for the device + * space_id - The address space ID + * Handler - Address of the handler + * Setup - Address of the setup function + * Context - Value passed to the handler on each access + * + * RETURN: Status + * + * DESCRIPTION: Install a handler for all op_regions of a given space_id. + * Assumes namespace is locked + * + ******************************************************************************/ + +acpi_status +acpi_ev_install_space_handler ( + struct acpi_namespace_node *node, + acpi_adr_space_type space_id, + acpi_adr_space_handler handler, + acpi_adr_space_setup setup, + void *context) +{ + union acpi_operand_object *obj_desc; + union acpi_operand_object *handler_obj; + acpi_status status; + acpi_object_type type; + u16 flags = 0; + + + ACPI_FUNCTION_TRACE ("ev_install_space_handler"); + + + /* + * This registration is valid for only the types below + * and the root. This is where the default handlers + * get placed. + */ + if ((node->type != ACPI_TYPE_DEVICE) && + (node->type != ACPI_TYPE_PROCESSOR) && + (node->type != ACPI_TYPE_THERMAL) && + (node != acpi_gbl_root_node)) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + if (handler == ACPI_DEFAULT_HANDLER) { + flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED; + + switch (space_id) { + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + handler = acpi_ex_system_memory_space_handler; + setup = acpi_ev_system_memory_region_setup; + break; + + case ACPI_ADR_SPACE_SYSTEM_IO: + handler = acpi_ex_system_io_space_handler; + setup = acpi_ev_io_space_region_setup; + break; + + case ACPI_ADR_SPACE_PCI_CONFIG: + handler = acpi_ex_pci_config_space_handler; + setup = acpi_ev_pci_config_region_setup; + break; + + case ACPI_ADR_SPACE_CMOS: + handler = acpi_ex_cmos_space_handler; + setup = acpi_ev_cmos_region_setup; + break; + + case ACPI_ADR_SPACE_PCI_BAR_TARGET: + handler = acpi_ex_pci_bar_space_handler; + setup = acpi_ev_pci_bar_region_setup; + break; + + case ACPI_ADR_SPACE_DATA_TABLE: + handler = acpi_ex_data_table_space_handler; + setup = NULL; + break; + + default: + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + } + + /* If the caller hasn't specified a setup routine, use the default */ + + if (!setup) { + setup = acpi_ev_default_region_setup; + } + + /* Check for an existing internal object */ + + obj_desc = acpi_ns_get_attached_object (node); + if (obj_desc) { + /* + * The attached device object already exists. + * Make sure the handler is not already installed. + */ + handler_obj = obj_desc->device.handler; + + /* Walk the handler list for this device */ + + while (handler_obj) { + /* Same space_id indicates a handler already installed */ + + if (handler_obj->address_space.space_id == space_id) { + if (handler_obj->address_space.handler == handler) { + /* + * It is (relatively) OK to attempt to install the SAME + * handler twice. This can easily happen with PCI_Config space. + */ + status = AE_SAME_HANDLER; + goto unlock_and_exit; + } + else { + /* A handler is already installed */ + + status = AE_ALREADY_EXISTS; + } + goto unlock_and_exit; + } + + /* Walk the linked list of handlers */ + + handler_obj = handler_obj->address_space.next; + } + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, + "Creating object on Device %p while installing handler\n", node)); + + /* obj_desc does not exist, create one */ + + if (node->type == ACPI_TYPE_ANY) { + type = ACPI_TYPE_DEVICE; + } + else { + type = node->type; + } + + obj_desc = acpi_ut_create_internal_object (type); + if (!obj_desc) { + status = AE_NO_MEMORY; + goto unlock_and_exit; + } + + /* Init new descriptor */ + + obj_desc->common.type = (u8) type; + + /* Attach the new object to the Node */ + + status = acpi_ns_attach_object (node, obj_desc, type); + + /* Remove local reference to the object */ + + acpi_ut_remove_reference (obj_desc); + + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } + } + + ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, + "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n", + acpi_ut_get_region_name (space_id), space_id, + acpi_ut_get_node_name (node), node, obj_desc)); + + /* + * Install the handler + * + * At this point there is no existing handler. + * Just allocate the object for the handler and link it + * into the list. + */ + handler_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_ADDRESS_HANDLER); + if (!handler_obj) { + status = AE_NO_MEMORY; + goto unlock_and_exit; + } + + /* Init handler obj */ + + handler_obj->address_space.space_id = (u8) space_id; + handler_obj->address_space.hflags = flags; + handler_obj->address_space.region_list = NULL; + handler_obj->address_space.node = node; + handler_obj->address_space.handler = handler; + handler_obj->address_space.context = context; + handler_obj->address_space.setup = setup; + + /* Install at head of Device.address_space list */ + + handler_obj->address_space.next = obj_desc->device.handler; + + /* + * The Device object is the first reference on the handler_obj. + * Each region that uses the handler adds a reference. + */ + obj_desc->device.handler = handler_obj; + + /* + * Walk the namespace finding all of the regions this + * handler will manage. + * + * Start at the device and search the branch toward + * the leaf nodes until either the leaf is encountered or + * a device is detected that has an address handler of the + * same type. + * + * In either case, back up and search down the remainder + * of the branch + */ + status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, + ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler, + handler_obj, NULL); + +unlock_and_exit: + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ev_execute_reg_methods + * + * PARAMETERS: Node - Namespace node for the device + * space_id - The address space ID + * + * RETURN: Status + * + * DESCRIPTION: Run _REG methods for the Space ID; + * Note: assumes namespace is locked, or system init time. + * + ******************************************************************************/ + +acpi_status +acpi_ev_execute_reg_methods ( + struct acpi_namespace_node *node, + acpi_adr_space_type space_id) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("ev_execute_reg_methods"); + + + /* + * Run all _REG methods for all Operation Regions for this + * space ID. This is a separate walk in order to handle any + * interdependencies between regions and _REG methods. (i.e. handlers + * must be installed for all regions of this Space ID before we + * can run any _REG methods) + */ + status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, + ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, + &space_id, NULL); + + return_ACPI_STATUS (status); +} + + /******************************************************************************* * * FUNCTION: acpi_ev_reg_run @@ -693,19 +1019,13 @@ void *context, void **return_value) { - union acpi_operand_object *handler_obj; union acpi_operand_object *obj_desc; struct acpi_namespace_node *node; + acpi_adr_space_type space_id; acpi_status status; - handler_obj = (union acpi_operand_object *) context; - - /* Parameter validation */ - - if (!handler_obj) { - return (AE_OK); - } + space_id = *ACPI_CAST_PTR (acpi_adr_space_type, context); /* Convert and validate the device handle */ @@ -732,10 +1052,9 @@ return (AE_OK); } - /* Object is a Region */ - if (obj_desc->region.space_id != handler_obj->address_space.space_id) { + if (obj_desc->region.space_id != space_id) { /* * This region is for a different address space * -- just ignore it diff -Nru a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c --- a/drivers/acpi/events/evxface.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/events/evxface.c 2004-08-21 23:40:16 -07:00 @@ -188,6 +188,7 @@ * handler_type - The type of handler: * ACPI_SYSTEM_NOTIFY: system_handler (00-7f) * ACPI_DEVICE_NOTIFY: driver_handler (80-ff) + * ACPI_ALL_NOTIFY: both system and device * Handler - Address of the handler * Context - Value passed to the handler on each GPE * @@ -243,20 +244,21 @@ if (device == ACPI_ROOT_OBJECT) { /* Make sure the handler is not already installed */ - if (((handler_type == ACPI_SYSTEM_NOTIFY) && - acpi_gbl_system_notify.handler) || - ((handler_type == ACPI_DEVICE_NOTIFY) && + if (((handler_type & ACPI_SYSTEM_NOTIFY) && + acpi_gbl_system_notify.handler) || + ((handler_type & ACPI_DEVICE_NOTIFY) && acpi_gbl_device_notify.handler)) { status = AE_ALREADY_EXISTS; goto unlock_and_exit; } - if (handler_type == ACPI_SYSTEM_NOTIFY) { + if (handler_type & ACPI_SYSTEM_NOTIFY) { acpi_gbl_system_notify.node = node; acpi_gbl_system_notify.handler = handler; acpi_gbl_system_notify.context = context; } - else /* ACPI_DEVICE_NOTIFY */ { + + if (handler_type & ACPI_DEVICE_NOTIFY) { acpi_gbl_device_notify.node = node; acpi_gbl_device_notify.handler = handler; acpi_gbl_device_notify.context = context; @@ -284,9 +286,9 @@ if (obj_desc) { /* Object exists - make sure there's no handler */ - if (((handler_type == ACPI_SYSTEM_NOTIFY) && + if (((handler_type & ACPI_SYSTEM_NOTIFY) && obj_desc->common_notify.system_notify) || - ((handler_type == ACPI_DEVICE_NOTIFY) && + ((handler_type & ACPI_DEVICE_NOTIFY) && obj_desc->common_notify.device_notify)) { status = AE_ALREADY_EXISTS; goto unlock_and_exit; @@ -308,7 +310,6 @@ /* Remove local reference to the object */ acpi_ut_remove_reference (obj_desc); - if (ACPI_FAILURE (status)) { goto unlock_and_exit; } @@ -326,12 +327,19 @@ notify_obj->notify.handler = handler; notify_obj->notify.context = context; - if (handler_type == ACPI_SYSTEM_NOTIFY) { + if (handler_type & ACPI_SYSTEM_NOTIFY) { obj_desc->common_notify.system_notify = notify_obj; } - else /* ACPI_DEVICE_NOTIFY */ { + + if (handler_type & ACPI_DEVICE_NOTIFY) { obj_desc->common_notify.device_notify = notify_obj; } + + if (handler_type == ACPI_ALL_NOTIFY) { + /* Extra ref if installed in both */ + + acpi_ut_add_reference (notify_obj); + } } @@ -349,6 +357,7 @@ * handler_type - The type of handler: * ACPI_SYSTEM_NOTIFY: system_handler (00-7f) * ACPI_DEVICE_NOTIFY: driver_handler (80-ff) + * ACPI_ALL_NOTIFY: both system and device * Handler - Address of the handler * RETURN: Status * @@ -398,9 +407,9 @@ if (device == ACPI_ROOT_OBJECT) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n")); - if (((handler_type == ACPI_SYSTEM_NOTIFY) && - !acpi_gbl_system_notify.handler) || - ((handler_type == ACPI_DEVICE_NOTIFY) && + if (((handler_type & ACPI_SYSTEM_NOTIFY) && + !acpi_gbl_system_notify.handler) || + ((handler_type & ACPI_DEVICE_NOTIFY) && !acpi_gbl_device_notify.handler)) { status = AE_NOT_EXIST; goto unlock_and_exit; @@ -415,12 +424,13 @@ return_ACPI_STATUS (status); } - if (handler_type == ACPI_SYSTEM_NOTIFY) { + if (handler_type & ACPI_SYSTEM_NOTIFY) { acpi_gbl_system_notify.node = NULL; acpi_gbl_system_notify.handler = NULL; acpi_gbl_system_notify.context = NULL; } - else { + + if (handler_type & ACPI_DEVICE_NOTIFY) { acpi_gbl_device_notify.node = NULL; acpi_gbl_device_notify.handler = NULL; acpi_gbl_device_notify.context = NULL; @@ -448,38 +458,47 @@ /* Object exists - make sure there's an existing handler */ - if (handler_type == ACPI_SYSTEM_NOTIFY) { + if (handler_type & ACPI_SYSTEM_NOTIFY) { notify_obj = obj_desc->common_notify.system_notify; - } - else { - notify_obj = obj_desc->common_notify.device_notify; - } + if ((!notify_obj) || + (notify_obj->notify.handler != handler)) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + /* Make sure all deferred tasks are completed */ - if ((!notify_obj) || - (notify_obj->notify.handler != handler)) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + acpi_os_wait_events_complete(NULL); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - /* Make sure all deferred tasks are completed */ + /* Remove the handler */ + obj_desc->common_notify.system_notify = NULL; + acpi_ut_remove_reference (notify_obj); + } - (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - acpi_os_wait_events_complete(NULL); - status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + if (handler_type & ACPI_DEVICE_NOTIFY) { + notify_obj = obj_desc->common_notify.device_notify; + if ((!notify_obj) || + (notify_obj->notify.handler != handler)) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + /* Make sure all deferred tasks are completed */ - /* Remove the handler */ + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + acpi_os_wait_events_complete(NULL); + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - if (handler_type == ACPI_SYSTEM_NOTIFY) { - obj_desc->common_notify.system_notify = NULL; - } - else { + /* Remove the handler */ obj_desc->common_notify.device_notify = NULL; + acpi_ut_remove_reference (notify_obj); } - - acpi_ut_remove_reference (notify_obj); } @@ -497,7 +516,7 @@ * gpe_block - GPE block (NULL == FADT GPEs) * Type - Whether this GPE should be treated as an * edge- or level-triggered interrupt. - * Handler - Address of the handler + * Address - Address of the handler * Context - Value passed to the handler on each GPE * * RETURN: Status @@ -511,11 +530,12 @@ acpi_handle gpe_device, u32 gpe_number, u32 type, - acpi_gpe_handler handler, + acpi_event_handler address, void *context) { - acpi_status status; struct acpi_gpe_event_info *gpe_event_info; + struct acpi_handler_info *handler; + acpi_status status; ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler"); @@ -523,7 +543,7 @@ /* Parameter validation */ - if (!handler) { + if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } @@ -542,27 +562,41 @@ /* Make sure that there isn't a handler there already */ - if (gpe_event_info->handler) { + if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) { status = AE_ALREADY_EXISTS; goto unlock_and_exit; } - /* Install the handler */ + /* Allocate and init handler object */ - acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); - gpe_event_info->handler = handler; - gpe_event_info->context = context; - gpe_event_info->flags = (u8) type; - acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + handler = ACPI_MEM_CALLOCATE (sizeof (struct acpi_handler_info)); + if (!handler) { + status = AE_NO_MEMORY; + goto unlock_and_exit; + } - /* Clear the GPE (of stale events), the enable it */ + handler->address = address; + handler->context = context; + handler->method_node = gpe_event_info->dispatch.method_node; - status = acpi_hw_clear_gpe (gpe_event_info); + /* Disable the GPE before installing the handler */ + + status = acpi_ev_disable_gpe (gpe_event_info); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } - status = acpi_hw_enable_gpe (gpe_event_info); + /* Install the handler */ + + acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + gpe_event_info->dispatch.handler = handler; + + /* Setup up dispatch flags to indicate handler (vs. method) */ + + gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */ + gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER); + + acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); unlock_and_exit: @@ -577,7 +611,7 @@ * * PARAMETERS: gpe_number - The event to remove a handler * gpe_block - GPE block (NULL == FADT GPEs) - * Handler - Address of the handler + * Address - Address of the handler * * RETURN: Status * @@ -589,10 +623,11 @@ acpi_remove_gpe_handler ( acpi_handle gpe_device, u32 gpe_number, - acpi_gpe_handler handler) + acpi_event_handler address) { - acpi_status status; struct acpi_gpe_event_info *gpe_event_info; + struct acpi_handler_info *handler; + acpi_status status; ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler"); @@ -600,7 +635,7 @@ /* Parameter validation */ - if (!handler) { + if (!address) { return_ACPI_STATUS (AE_BAD_PARAMETER); } @@ -617,21 +652,27 @@ goto unlock_and_exit; } - /* Disable the GPE before removing the handler */ + /* Make sure that a handler is indeed installed */ - status = acpi_hw_disable_gpe (gpe_event_info); - if (ACPI_FAILURE (status)) { + if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != ACPI_GPE_DISPATCH_HANDLER) { + status = AE_NOT_EXIST; goto unlock_and_exit; } /* Make sure that the installed handler is the same */ - if (gpe_event_info->handler != handler) { - (void) acpi_hw_enable_gpe (gpe_event_info); + if (gpe_event_info->dispatch.handler->address != address) { status = AE_BAD_PARAMETER; goto unlock_and_exit; } + /* Disable the GPE before removing the handler */ + + status = acpi_ev_disable_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } + /* Make sure all deferred tasks are completed */ (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); @@ -644,9 +685,20 @@ /* Remove the handler */ acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); - gpe_event_info->handler = NULL; - gpe_event_info->context = NULL; + handler = gpe_event_info->dispatch.handler; + + /* Restore Method node (if any), set dispatch flags */ + + gpe_event_info->dispatch.method_node = handler->method_node; + gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */ + if (handler->method_node) { + gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD; + } acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR); + + /* Now we can free the handler object */ + + ACPI_MEM_FREE (handler); unlock_and_exit: diff -Nru a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c --- a/drivers/acpi/events/evxfevnt.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/events/evxfevnt.c 2004-08-21 23:40:16 -07:00 @@ -204,12 +204,11 @@ /******************************************************************************* * - * FUNCTION: acpi_enable_gpe + * FUNCTION: acpi_set_gpe_type * * PARAMETERS: gpe_device - Parent GPE Device * gpe_number - GPE level within the GPE block - * Flags - Just enable, or also wake enable? - * Called from ISR or not + * Type - New GPE type * * RETURN: Status * @@ -218,26 +217,17 @@ ******************************************************************************/ acpi_status -acpi_enable_gpe ( +acpi_set_gpe_type ( acpi_handle gpe_device, u32 gpe_number, - u32 flags) + u8 type) { acpi_status status = AE_OK; struct acpi_gpe_event_info *gpe_event_info; - ACPI_FUNCTION_TRACE ("acpi_enable_gpe"); - - - /* Use semaphore lock if not executing at interrupt level */ + ACPI_FUNCTION_TRACE ("acpi_set_gpe_type"); - if (flags & ACPI_NOT_ISR) { - status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - } /* Ensure that we have a valid GPE number */ @@ -247,91 +237,72 @@ goto unlock_and_exit; } - /* Check for Wake vs Runtime GPE */ - - if (flags & ACPI_EVENT_WAKE_ENABLE) { - /* Ensure the requested wake GPE is disabled */ - - status = acpi_hw_disable_gpe (gpe_event_info); - if (ACPI_FAILURE (status)) { - goto unlock_and_exit; - } - - /* Defer Enable of Wake GPE until sleep time */ - - acpi_hw_enable_gpe_for_wakeup (gpe_event_info); + if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) { + return_ACPI_STATUS (AE_OK); } - else { - /* Enable the requested runtime GPE */ - status = acpi_hw_enable_gpe (gpe_event_info); - if (ACPI_FAILURE (status)) { - goto unlock_and_exit; - } - } + /* Set the new type (will disable GPE if currently enabled) */ + status = acpi_ev_set_gpe_type (gpe_event_info, type); unlock_and_exit: - if (flags & ACPI_NOT_ISR) { - (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); - } return_ACPI_STATUS (status); } /******************************************************************************* * - * FUNCTION: acpi_disable_event + * FUNCTION: acpi_enable_gpe * - * PARAMETERS: Event - The fixed eventto be enabled - * Flags - Reserved + * PARAMETERS: gpe_device - Parent GPE Device + * gpe_number - GPE level within the GPE block + * Flags - Just enable, or also wake enable? + * Called from ISR or not * * RETURN: Status * - * DESCRIPTION: Disable an ACPI event (fixed) + * DESCRIPTION: Enable an ACPI event (general purpose) * ******************************************************************************/ acpi_status -acpi_disable_event ( - u32 event, +acpi_enable_gpe ( + acpi_handle gpe_device, + u32 gpe_number, u32 flags) { acpi_status status = AE_OK; - u32 value; + struct acpi_gpe_event_info *gpe_event_info; - ACPI_FUNCTION_TRACE ("acpi_disable_event"); + ACPI_FUNCTION_TRACE ("acpi_enable_gpe"); - /* Decode the Fixed Event */ + /* Use semaphore lock if not executing at interrupt level */ - if (event > ACPI_EVENT_MAX) { - return_ACPI_STATUS (AE_BAD_PARAMETER); + if (flags & ACPI_NOT_ISR) { + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } - /* - * Disable the requested fixed event (by writing a zero to the - * enable register bit) - */ - status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id, - 0, ACPI_MTX_LOCK); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + /* Ensure that we have a valid GPE number */ - status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id, - &value, ACPI_MTX_LOCK); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; } - if (value != 0) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Could not disable %s events\n", acpi_ut_get_event_name (event))); - return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); - } + /* Perform the enable */ + + status = acpi_ev_enable_gpe (gpe_event_info, TRUE); +unlock_and_exit: + if (flags & ACPI_NOT_ISR) { + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); + } return_ACPI_STATUS (status); } @@ -342,7 +313,7 @@ * * PARAMETERS: gpe_device - Parent GPE Device * gpe_number - GPE level within the GPE block - * Flags - Just enable, or also wake enable? + * Flags - Just disable, or also wake disable? * Called from ISR or not * * RETURN: Status @@ -381,21 +352,69 @@ goto unlock_and_exit; } + status = acpi_ev_disable_gpe (gpe_event_info); + +unlock_and_exit: + if (flags & ACPI_NOT_ISR) { + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); + } + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_disable_event + * + * PARAMETERS: Event - The fixed eventto be enabled + * Flags - Reserved + * + * RETURN: Status + * + * DESCRIPTION: Disable an ACPI event (fixed) + * + ******************************************************************************/ + +acpi_status +acpi_disable_event ( + u32 event, + u32 flags) +{ + acpi_status status = AE_OK; + u32 value; + + + ACPI_FUNCTION_TRACE ("acpi_disable_event"); + + + /* Decode the Fixed Event */ + + if (event > ACPI_EVENT_MAX) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + /* - * Only disable the requested GPE number for wake if specified. - * Otherwise, turn it totally off + * Disable the requested fixed event (by writing a zero to the + * enable register bit) */ - if (flags & ACPI_EVENT_WAKE_DISABLE) { - acpi_hw_disable_gpe_for_wakeup (gpe_event_info); + status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id, + 0, ACPI_MTX_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - else { - status = acpi_hw_disable_gpe (gpe_event_info); + + status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id, + &value, ACPI_MTX_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } -unlock_and_exit: - if (flags & ACPI_NOT_ISR) { - (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); + if (value != 0) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not disable %s events\n", acpi_ut_get_event_name (event))); + return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); } + return_ACPI_STATUS (status); } diff -Nru a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c --- a/drivers/acpi/events/evxfregn.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/events/evxfregn.c 2004-08-21 23:40:16 -07:00 @@ -46,7 +46,6 @@ #include #include #include -#include #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evxfregn") @@ -76,12 +75,8 @@ acpi_adr_space_setup setup, void *context) { - union acpi_operand_object *obj_desc; - union acpi_operand_object *handler_obj; struct acpi_namespace_node *node; acpi_status status; - acpi_object_type type; - u16 flags = 0; ACPI_FUNCTION_TRACE ("acpi_install_address_space_handler"); @@ -106,202 +101,16 @@ goto unlock_and_exit; } - /* - * This registration is valid for only the types below - * and the root. This is where the default handlers - * get placed. - */ - if ((node->type != ACPI_TYPE_DEVICE) && - (node->type != ACPI_TYPE_PROCESSOR) && - (node->type != ACPI_TYPE_THERMAL) && - (node != acpi_gbl_root_node)) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - - if (handler == ACPI_DEFAULT_HANDLER) { - flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED; - - switch (space_id) { - case ACPI_ADR_SPACE_SYSTEM_MEMORY: - handler = acpi_ex_system_memory_space_handler; - setup = acpi_ev_system_memory_region_setup; - break; - - case ACPI_ADR_SPACE_SYSTEM_IO: - handler = acpi_ex_system_io_space_handler; - setup = acpi_ev_io_space_region_setup; - break; - - case ACPI_ADR_SPACE_PCI_CONFIG: - handler = acpi_ex_pci_config_space_handler; - setup = acpi_ev_pci_config_region_setup; - break; - - case ACPI_ADR_SPACE_CMOS: - handler = acpi_ex_cmos_space_handler; - setup = acpi_ev_cmos_region_setup; - break; - - case ACPI_ADR_SPACE_PCI_BAR_TARGET: - handler = acpi_ex_pci_bar_space_handler; - setup = acpi_ev_pci_bar_region_setup; - break; - - case ACPI_ADR_SPACE_DATA_TABLE: - handler = acpi_ex_data_table_space_handler; - setup = NULL; - break; - - default: - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - } - - /* If the caller hasn't specified a setup routine, use the default */ - - if (!setup) { - setup = acpi_ev_default_region_setup; - } - - /* Check for an existing internal object */ - - obj_desc = acpi_ns_get_attached_object (node); - if (obj_desc) { - /* - * The attached device object already exists. - * Make sure the handler is not already installed. - */ - handler_obj = obj_desc->device.handler; - - /* Walk the handler list for this device */ - - while (handler_obj) { - /* Same space_id indicates a handler already installed */ - - if(handler_obj->address_space.space_id == space_id) { - if (handler_obj->address_space.handler == handler) { - /* - * It is (relatively) OK to attempt to install the SAME - * handler twice. This can easily happen with PCI_Config space. - */ - status = AE_SAME_HANDLER; - goto unlock_and_exit; - } - else { - /* A handler is already installed */ - - status = AE_ALREADY_EXISTS; - } - goto unlock_and_exit; - } - - /* Walk the linked list of handlers */ - - handler_obj = handler_obj->address_space.next; - } - } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, - "Creating object on Device %p while installing handler\n", node)); - - /* obj_desc does not exist, create one */ - - if (node->type == ACPI_TYPE_ANY) { - type = ACPI_TYPE_DEVICE; - } - else { - type = node->type; - } - - obj_desc = acpi_ut_create_internal_object (type); - if (!obj_desc) { - status = AE_NO_MEMORY; - goto unlock_and_exit; - } - - /* Init new descriptor */ - - obj_desc->common.type = (u8) type; - - /* Attach the new object to the Node */ + /* Install the handler for all Regions for this Space ID */ - status = acpi_ns_attach_object (node, obj_desc, type); - - /* Remove local reference to the object */ - - acpi_ut_remove_reference (obj_desc); - - if (ACPI_FAILURE (status)) { - goto unlock_and_exit; - } - } - - ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, - "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n", - acpi_ut_get_region_name (space_id), space_id, - acpi_ut_get_node_name (node), node, obj_desc)); - - /* - * Install the handler - * - * At this point there is no existing handler. - * Just allocate the object for the handler and link it - * into the list. - */ - handler_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_ADDRESS_HANDLER); - if (!handler_obj) { - status = AE_NO_MEMORY; + status = acpi_ev_install_space_handler (node, space_id, handler, setup, context); + if (ACPI_FAILURE (status)) { goto unlock_and_exit; } - /* Init handler obj */ + /* Run all _REG methods for this address space */ - handler_obj->address_space.space_id = (u8) space_id; - handler_obj->address_space.hflags = flags; - handler_obj->address_space.region_list = NULL; - handler_obj->address_space.node = node; - handler_obj->address_space.handler = handler; - handler_obj->address_space.context = context; - handler_obj->address_space.setup = setup; - - /* Install at head of Device.address_space list */ - - handler_obj->address_space.next = obj_desc->device.handler; - - /* - * The Device object is the first reference on the handler_obj. - * Each region that uses the handler adds a reference. - */ - obj_desc->device.handler = handler_obj; - - /* - * Walk the namespace finding all of the regions this - * handler will manage. - * - * Start at the device and search the branch toward - * the leaf nodes until either the leaf is encountered or - * a device is detected that has an address handler of the - * same type. - * - * In either case, back up and search down the remainder - * of the branch - */ - status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX, - ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler, - handler_obj, NULL); - - /* - * Now we can run the _REG methods for all Regions for this - * space ID. This is a separate walk in order to handle any - * interdependencies between regions and _REG methods. (i.e. handlers - * must be installed for all regions of this Space ID before we - * can run any _REG methods. - */ - status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX, - ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, - handler_obj, NULL); + status = acpi_ev_execute_reg_methods (node, space_id); unlock_and_exit: (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); diff -Nru a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c --- a/drivers/acpi/executer/exconfig.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/executer/exconfig.c 2004-08-21 23:40:16 -07:00 @@ -48,6 +48,7 @@ #include #include #include +#include #define _COMPONENT ACPI_EXECUTER @@ -285,7 +286,7 @@ union acpi_operand_object *ddb_handle; union acpi_operand_object *buffer_desc = NULL; struct acpi_table_header *table_ptr = NULL; - u8 *table_data_ptr; + acpi_physical_address address; struct acpi_table_header table_header; u32 i; @@ -300,18 +301,39 @@ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Region %p %s\n", obj_desc, acpi_ut_get_object_type_name (obj_desc))); - /* Get the table header */ + /* + * If the Region Address and Length have not been previously evaluated, + * evaluate them now and save the results. + */ + if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) { + status = acpi_ds_get_region_arguments (obj_desc); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + + /* Get the base physical address of the region */ + + address = obj_desc->region.address; + + /* Get the table length from the table header */ table_header.length = 0; - for (i = 0; i < sizeof (struct acpi_table_header); i++) { + for (i = 0; i < 8; i++) { status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ, - (acpi_physical_address) i, 8, + (acpi_physical_address) (i + address), 8, ((u8 *) &table_header) + i); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } } + /* Sanity check the table length */ + + if (table_header.length < sizeof (struct acpi_table_header)) { + return_ACPI_STATUS (AE_BAD_HEADER); + } + /* Allocate a buffer for the entire table */ table_ptr = ACPI_MEM_ALLOCATE (table_header.length); @@ -319,17 +341,12 @@ return_ACPI_STATUS (AE_NO_MEMORY); } - /* Copy the header to the buffer */ - - ACPI_MEMCPY (table_ptr, &table_header, sizeof (struct acpi_table_header)); - table_data_ptr = ACPI_PTR_ADD (u8, table_ptr, sizeof (struct acpi_table_header)); - - /* Get the table from the op region */ + /* Get the entire table from the op region */ for (i = 0; i < table_header.length; i++) { status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ, - (acpi_physical_address) i, 8, - ((u8 *) table_data_ptr + i)); + (acpi_physical_address) (i + address), 8, + ((u8 *) table_ptr + i)); if (ACPI_FAILURE (status)) { goto cleanup; } @@ -355,6 +372,12 @@ } table_ptr = ACPI_CAST_PTR (struct acpi_table_header, buffer_desc->buffer.pointer); + + /* Sanity check the table length */ + + if (table_ptr->length < sizeof (struct acpi_table_header)) { + return_ACPI_STATUS (AE_BAD_HEADER); + } break; diff -Nru a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c --- a/drivers/acpi/executer/exfldio.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/executer/exfldio.c 2004-08-21 23:40:16 -07:00 @@ -130,6 +130,21 @@ if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset + field_datum_byte_offset + obj_desc->common_field.access_byte_width)) { + if (acpi_gbl_enable_interpeter_slack) { + /* + * Slack mode only: We will go ahead and allow access to this + * field if it is within the region length rounded up to the next + * access width boundary. + */ + if (ACPI_ROUND_UP (rgn_desc->region.length, + obj_desc->common_field.access_byte_width) >= + (obj_desc->common_field.base_byte_offset + + obj_desc->common_field.access_byte_width + + field_datum_byte_offset)) { + return_ACPI_STATUS (AE_OK); + } + } + if (rgn_desc->region.length < obj_desc->common_field.access_byte_width) { /* * This is the case where the access_type (acc_word, etc.) is wider @@ -277,7 +292,7 @@ rgn_desc->region.space_id)); } else if (status == AE_NOT_EXIST) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + ACPI_REPORT_ERROR (( "Region %s(%X) has no handler\n", acpi_ut_get_region_name (rgn_desc->region.space_id), rgn_desc->region.space_id)); @@ -766,14 +781,83 @@ /******************************************************************************* * + * FUNCTION: acpi_ex_common_buffer_setup + * + * PARAMETERS: obj_desc - Field object + * buffer_length - Length of caller's buffer + * datum_count - Where the datum_count is returned + * + * RETURN: Status, datum_count + * + * DESCRIPTION: Common code to validate the incoming buffer size and compute + * the number of field "datums" that must be read or written. + * A "datum" is the smallest unit that can be read or written + * to the field, it is either 1,2,4, or 8 bytes. + * + ******************************************************************************/ + +acpi_status +acpi_ex_common_buffer_setup ( + union acpi_operand_object *obj_desc, + u32 buffer_length, + u32 *datum_count) +{ + u32 byte_field_length; + u32 actual_byte_field_length; + + + ACPI_FUNCTION_TRACE ("ex_common_buffer_setup"); + + + /* + * Incoming buffer must be at least as long as the field, we do not + * allow "partial" field reads/writes. We do not care if the buffer is + * larger than the field, this typically happens when an integer is + * read/written to a field that is actually smaller than an integer. + */ + byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES ( + obj_desc->common_field.bit_length); + if (byte_field_length > buffer_length) { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Field size %X (bytes) is too large for buffer (%X)\n", + byte_field_length, buffer_length)); + + return_ACPI_STATUS (AE_BUFFER_OVERFLOW); + } + + /* + * Create "actual" field byte count (minimum number of bytes that + * must be read), then convert to datum count (minimum number + * of datum-sized units that must be read) + */ + actual_byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES ( + obj_desc->common_field.start_field_bit_offset + + obj_desc->common_field.bit_length); + + + *datum_count = ACPI_ROUND_UP_TO (actual_byte_field_length, + obj_desc->common_field.access_byte_width); + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "buffer_bytes %X, actual_bytes %X, Datums %X, byte_gran %X\n", + byte_field_length, actual_byte_field_length, + *datum_count, obj_desc->common_field.access_byte_width)); + + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * * FUNCTION: acpi_ex_extract_from_field * - * PARAMETERS: *obj_desc - Field to be read - * *Value - Where to store value + * PARAMETERS: obj_desc - Field to be read + * Buffer - Where to store the field data + * buffer_length - Length of Buffer * * RETURN: Status * - * DESCRIPTION: Retrieve the value of the given field + * DESCRIPTION: Retrieve the current value of the given field * ******************************************************************************/ @@ -789,7 +873,6 @@ acpi_integer previous_raw_datum = 0; acpi_integer this_raw_datum = 0; acpi_integer merged_datum = 0; - u32 byte_field_length; u32 datum_count; u32 i; @@ -797,39 +880,13 @@ ACPI_FUNCTION_TRACE ("ex_extract_from_field"); - /* - * The field must fit within the caller's buffer - */ - byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length); - if (byte_field_length > buffer_length) { - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "Field size %X (bytes) too large for buffer (%X)\n", - byte_field_length, buffer_length)); + /* Validate buffer, compute number of datums */ - return_ACPI_STATUS (AE_BUFFER_OVERFLOW); - } - - /* Convert field byte count to datum count, round up if necessary */ - - datum_count = ACPI_ROUND_UP_TO (byte_field_length, - obj_desc->common_field.access_byte_width); - - /* - * If the field is not aligned on a datum boundary and does not - * fit within a single datum, we must read an extra datum. - * - * We could just split the aligned and non-aligned cases since the - * aligned case is so very simple, but this would require more code. - */ - if ((obj_desc->common_field.end_field_valid_bits != 0) && - (!(obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM))) { - datum_count++; + status = acpi_ex_common_buffer_setup (obj_desc, buffer_length, &datum_count); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "byte_len %X, datum_len %X, byte_gran %X\n", - byte_field_length, datum_count,obj_desc->common_field.access_byte_width)); - /* * Clear the caller's buffer (the whole buffer length as given) * This is very important, especially in the cases where the buffer @@ -942,12 +999,13 @@ * * FUNCTION: acpi_ex_insert_into_field * - * PARAMETERS: *obj_desc - Field to be set - * Buffer - Value to store + * PARAMETERS: obj_desc - Field to be written + * Buffer - Data to be written + * buffer_length - Length of Buffer * * RETURN: Status * - * DESCRIPTION: Store the value into the given field + * DESCRIPTION: Store the Buffer contents into the given field * ******************************************************************************/ @@ -964,41 +1022,18 @@ acpi_integer merged_datum; acpi_integer previous_raw_datum; acpi_integer this_raw_datum; - u32 byte_field_length; u32 datum_count; ACPI_FUNCTION_TRACE ("ex_insert_into_field"); - /* - * Incoming buffer must be at least as long as the field, we do not - * allow "partial" field writes. We do not care if the buffer is - * larger than the field, this typically happens when an integer is - * written to a field that is actually smaller than an integer. - */ - byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES ( - obj_desc->common_field.bit_length); - if (buffer_length < byte_field_length) { - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "Buffer length %X too small for field %X\n", - buffer_length, byte_field_length)); + /* Validate buffer, compute number of datums */ - return_ACPI_STATUS (AE_BUFFER_OVERFLOW); + status = acpi_ex_common_buffer_setup (obj_desc, buffer_length, &datum_count); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } - - byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES ( - obj_desc->common_field.start_field_bit_offset + - obj_desc->common_field.bit_length); - - /* Convert byte count to datum count, round up if necessary */ - - datum_count = ACPI_ROUND_UP_TO (byte_field_length, - obj_desc->common_field.access_byte_width); - - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "Bytes %X, Datums %X, byte_gran %X\n", - byte_field_length, datum_count, obj_desc->common_field.access_byte_width)); /* * Break the request into up to three parts (similar to an I/O request): diff -Nru a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c --- a/drivers/acpi/executer/exmisc.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/executer/exmisc.c 2004-08-21 23:40:16 -07:00 @@ -389,6 +389,8 @@ acpi_integer operand1) { + ACPI_FUNCTION_ENTRY (); + switch (opcode) { case AML_ADD_OP: /* Add (Operand0, Operand1, Result) */ @@ -452,15 +454,17 @@ * FUNCTION: acpi_ex_do_logical_op * * PARAMETERS: Opcode - AML opcode - * Operand0 - Integer operand #0 - * Operand1 - Integer operand #1 + * obj_desc0 - operand #0 + * obj_desc1 - operand #1 * * RETURN: TRUE/FALSE result of the operation * * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the * functions here is to prevent a lot of pointer dereferencing * to obtain the operands and to simplify the generation of the - * logical value. + * logical value. Both operands must already be validated as + * 1) Both the same type, and + * 2) Either Integer, Buffer, or String type. * * Note: cleanest machine code seems to be produced by the code * below, rather than using statements of the form: @@ -471,54 +475,137 @@ u8 acpi_ex_do_logical_op ( u16 opcode, - acpi_integer operand0, - acpi_integer operand1) + union acpi_operand_object *obj_desc0, + union acpi_operand_object *obj_desc1) { + acpi_integer operand0; + acpi_integer operand1; + u8 *ptr0; + u8 *ptr1; + u32 length0; + u32 length1; + u32 i; - switch (opcode) { + ACPI_FUNCTION_ENTRY (); - case AML_LAND_OP: /* LAnd (Operand0, Operand1) */ - if (operand0 && operand1) { - return (TRUE); - } - break; + if (ACPI_GET_OBJECT_TYPE (obj_desc0) == ACPI_TYPE_INTEGER) { + /* Both operands are of type integer */ + operand0 = obj_desc0->integer.value; + operand1 = obj_desc1->integer.value; - case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ + switch (opcode) { + case AML_LAND_OP: /* LAnd (Operand0, Operand1) */ - if (operand0 == operand1) { - return (TRUE); - } - break; + if (operand0 && operand1) { + return (TRUE); + } + break; + case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ - case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ + if (operand0 == operand1) { + return (TRUE); + } + break; - if (operand0 > operand1) { - return (TRUE); - } - break; + case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ + if (operand0 > operand1) { + return (TRUE); + } + break; - case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ + case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ - if (operand0 < operand1) { - return (TRUE); - } - break; + if (operand0 < operand1) { + return (TRUE); + } + break; + case AML_LOR_OP: /* LOr (Operand0, Operand1) */ - case AML_LOR_OP: /* LOr (Operand0, Operand1) */ + if (operand0 || operand1) { + return (TRUE); + } + break; - if (operand0 || operand1) { - return (TRUE); + default: + break; } - break; + } + else { + /* + * Case for Buffer/String objects. + * NOTE: takes advantage of common Buffer/String object fields + */ + length0 = obj_desc0->buffer.length; + ptr0 = obj_desc0->buffer.pointer; + + length1 = obj_desc1->buffer.length; + ptr1 = obj_desc1->buffer.pointer; + + switch (opcode) { + case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ + + /* Length and all bytes must be equal */ + + if (length0 != length1) { + return (FALSE); + } + + for (i = 0; i < length0; i++) { + if (ptr0[i] != ptr1[i]) { + return (FALSE); + } + } + return (TRUE); - default: - break; + case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ + + /* Lexicographic compare: Scan the 1-to-1 data */ + + for (i = 0; (i < length0) && (i < length1); i++) { + if (ptr0[i] > ptr1[i]) { + return (TRUE); + } + } + + /* Bytes match, now check lengths */ + + if (length0 > length1) { + return (TRUE); + } + + /* Length0 <= Length1 */ + + return (FALSE); + + case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ + + /* Lexicographic compare: Scan the 1-to-1 data */ + + for (i = 0; (i < length0) && (i < length1); i++) { + if (ptr0[i] < ptr1[i]) { + return (TRUE); + } + } + + /* Bytes match, now check lengths */ + + if (length0 < length1) { + return (TRUE); + } + + /* Length0 >= Length1 */ + + return (FALSE); + + default: + break; + } } return (FALSE); diff -Nru a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c --- a/drivers/acpi/executer/exmutex.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/executer/exmutex.c 2004-08-21 23:40:16 -07:00 @@ -54,7 +54,7 @@ * * FUNCTION: acpi_ex_unlink_mutex * - * PARAMETERS: *obj_desc - The mutex to be unlinked + * PARAMETERS: obj_desc - The mutex to be unlinked * * RETURN: Status * @@ -73,6 +73,8 @@ return; } + /* Doubly linked list */ + if (obj_desc->mutex.next) { (obj_desc->mutex.next)->mutex.prev = obj_desc->mutex.prev; } @@ -90,8 +92,8 @@ * * FUNCTION: acpi_ex_link_mutex * - * PARAMETERS: *obj_desc - The mutex to be linked - * *list_head - head of the "acquired_mutex" list + * PARAMETERS: obj_desc - The mutex to be linked + * list_head - head of the "acquired_mutex" list * * RETURN: Status * @@ -130,8 +132,8 @@ * * FUNCTION: acpi_ex_acquire_mutex * - * PARAMETERS: *time_desc - The 'time to delay' object descriptor - * *obj_desc - The object descriptor for this op + * PARAMETERS: time_desc - The 'time to delay' object descriptor + * obj_desc - The object descriptor for this op * * RETURN: Status * @@ -173,9 +175,8 @@ return_ACPI_STATUS (AE_AML_MUTEX_ORDER); } - /* - * Support for multiple acquires by the owning thread - */ + /* Support for multiple acquires by the owning thread */ + if (obj_desc->mutex.owner_thread) { /* Special case for Global Lock, allow all threads */ @@ -199,10 +200,11 @@ return_ACPI_STATUS (status); } - /* Have the mutex, update mutex and walk info */ + /* Have the mutex: update mutex and walk info and save the sync_level */ - obj_desc->mutex.owner_thread = walk_state->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; walk_state->thread->current_sync_level = obj_desc->mutex.sync_level; @@ -218,7 +220,7 @@ * * FUNCTION: acpi_ex_release_mutex * - * PARAMETERS: *obj_desc - The object descriptor for this op + * PARAMETERS: obj_desc - The object descriptor for this op * * RETURN: Status * @@ -281,9 +283,8 @@ return_ACPI_STATUS (AE_AML_MUTEX_ORDER); } - /* - * Match multiple Acquires with multiple Releases - */ + /* Match multiple Acquires with multiple Releases */ + obj_desc->mutex.acquisition_depth--; if (obj_desc->mutex.acquisition_depth != 0) { /* Just decrement the depth and return */ @@ -299,10 +300,10 @@ status = acpi_ex_system_release_mutex (obj_desc); - /* Update the mutex and walk state */ + /* Update the mutex and walk state, restore sync_level before acquire */ obj_desc->mutex.owner_thread = NULL; - walk_state->thread->current_sync_level = obj_desc->mutex.sync_level; + walk_state->thread->current_sync_level = obj_desc->mutex.original_sync_level; return_ACPI_STATUS (status); } @@ -312,7 +313,7 @@ * * FUNCTION: acpi_ex_release_all_mutexes * - * PARAMETERS: *mutex_list - Head of the mutex list + * PARAMETERS: mutex_list - Head of the mutex list * * RETURN: Status * @@ -332,9 +333,8 @@ ACPI_FUNCTION_ENTRY (); - /* - * Traverse the list of owned mutexes, releasing each one. - */ + /* Traverse the list of owned mutexes, releasing each one */ + while (next) { this = next; next = this->mutex.next; @@ -352,7 +352,11 @@ /* Mark mutex unowned */ - this->mutex.owner_thread = NULL; + this->mutex.owner_thread = NULL; + + /* Update Thread sync_level (Last mutex is the important one) */ + + thread->current_sync_level = this->mutex.original_sync_level; } } diff -Nru a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c --- a/drivers/acpi/executer/exoparg2.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/executer/exoparg2.c 2004-08-21 23:40:16 -07:00 @@ -97,6 +97,7 @@ { union acpi_operand_object **operand = &walk_state->operands[0]; struct acpi_namespace_node *node; + u32 value; acpi_status status = AE_OK; @@ -113,16 +114,46 @@ node = (struct acpi_namespace_node *) operand[0]; + /* Second value is the notify value */ + + value = (u32) operand[1]->integer.value; + /* Notifies allowed on this object? */ if (!acpi_ev_is_notify_object (node)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unexpected notify object type [%s]\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unexpected notify object type [%s]\n", acpi_ut_get_type_name (node->type))); status = AE_AML_OPERAND_TYPE; break; } +#ifdef ACPI_GPE_NOTIFY_CHECK + /* + * GPE method wake/notify check. Here, we want to ensure that we + * don't receive any "device_wake" Notifies from a GPE _Lxx or _Exx + * GPE method during system runtime. If we do, the GPE is marked + * as "wake-only" and disabled. + * + * 1) Is the Notify() value == device_wake? + * 2) Is this a GPE deferred method? (An _Lxx or _Exx method) + * 3) Did the original GPE happen at system runtime? + * (versus during wake) + * + * If all three cases are true, this is a wake-only GPE that should + * be disabled at runtime. + */ + if (value == 2) /* device_wake */ { + status = acpi_ev_check_for_wake_only_gpe (walk_state->gpe_event_info); + if (ACPI_FAILURE (status)) { + /* AE_WAKE_ONLY_GPE only error, means ignore this notify */ + + return_ACPI_STATUS (AE_OK) + } + } +#endif + /* * Dispatch the notify to the appropriate handler * NOTE: the request is queued for execution after this method @@ -130,8 +161,7 @@ * from this thread -- because handlers may in turn run other * control methods. */ - status = acpi_ev_queue_notify_request (node, - (u32) operand[1]->integer.value); + status = acpi_ev_queue_notify_request (node, value); break; @@ -543,9 +573,17 @@ * Execute the Opcode */ if (walk_state->op_info->flags & AML_LOGICAL) /* logical_op (Operand0, Operand1) */ { + /* Both operands must be of the same type */ + + if (ACPI_GET_OBJECT_TYPE (operand[0]) != + ACPI_GET_OBJECT_TYPE (operand[1])) { + status = AE_AML_OPERAND_TYPE; + goto cleanup; + } + logical_result = acpi_ex_do_logical_op (walk_state->opcode, - operand[0]->integer.value, - operand[1]->integer.value); + operand[0], + operand[1]); goto store_logical_result; } diff -Nru a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c --- a/drivers/acpi/executer/exresolv.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/executer/exresolv.c 2004-08-21 23:40:16 -07:00 @@ -187,15 +187,15 @@ return_ACPI_STATUS (status); } + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] value_obj is %p\n", + stack_desc->reference.offset, obj_desc)); + /* * Now we can delete the original Reference Object and - * replace it with the resolve value + * replace it with the resolved value */ acpi_ut_remove_reference (stack_desc); *stack_ptr = obj_desc; - - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %d] value_obj is %p\n", - stack_desc->reference.offset, obj_desc)); break; diff -Nru a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c --- a/drivers/acpi/executer/exstore.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/executer/exstore.c 2004-08-21 23:40:16 -07:00 @@ -102,7 +102,8 @@ * Storing an object into a Named node. */ status = acpi_ex_store_object_to_node (source_desc, - (struct acpi_namespace_node *) dest_desc, walk_state); + (struct acpi_namespace_node *) dest_desc, walk_state, + ACPI_IMPLICIT_CONVERSION); return_ACPI_STATUS (status); } @@ -153,7 +154,7 @@ /* Storing an object into a Name "container" */ status = acpi_ex_store_object_to_node (source_desc, ref_desc->reference.object, - walk_state); + walk_state, ACPI_IMPLICIT_CONVERSION); break; @@ -399,6 +400,7 @@ * PARAMETERS: source_desc - Value to be stored * Node - Named object to receive the value * walk_state - Current walk state + * implicit_conversion - Perform implicit conversion (yes/no) * * RETURN: Status * @@ -421,7 +423,8 @@ acpi_ex_store_object_to_node ( union acpi_operand_object *source_desc, struct acpi_namespace_node *node, - struct acpi_walk_state *walk_state) + struct acpi_walk_state *walk_state, + u8 implicit_conversion) { acpi_status status = AE_OK; union acpi_operand_object *target_desc; @@ -449,6 +452,14 @@ status = acpi_ex_resolve_object (&source_desc, target_type, walk_state); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); + } + + /* If no implicit conversion, drop into the default case below */ + + if (!implicit_conversion) { + /* Force execution of default (no implicit conversion) */ + + target_type = ACPI_TYPE_ANY; } /* diff -Nru a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c --- a/drivers/acpi/hardware/hwgpe.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/hardware/hwgpe.c 2004-08-21 23:40:16 -07:00 @@ -51,104 +51,24 @@ /****************************************************************************** * - * FUNCTION: acpi_hw_enable_gpe + * FUNCTION: acpi_hw_write_gpe_enable_reg * * PARAMETERS: gpe_event_info - Info block for the GPE to be enabled * * RETURN: Status * - * DESCRIPTION: Enable a single GPE. + * DESCRIPTION: Write a GPE enable register. Note: The bit for this GPE must + * already be cleared or set in the parent register + * enable_for_run mask. * ******************************************************************************/ acpi_status -acpi_hw_enable_gpe ( - struct acpi_gpe_event_info *gpe_event_info) -{ - u32 in_byte; - acpi_status status; - - - ACPI_FUNCTION_ENTRY (); - - - /* - * Read the current value of the register, set the appropriate bit - * to enable the GPE, and write out the new register. - */ - status = acpi_hw_low_level_read (8, &in_byte, - &gpe_event_info->register_info->enable_address); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Write with the new GPE bit enabled */ - - status = acpi_hw_low_level_write (8, (in_byte | gpe_event_info->bit_mask), - &gpe_event_info->register_info->enable_address); - - return (status); -} - - -/****************************************************************************** - * - * FUNCTION: acpi_hw_enable_gpe_for_wakeup - * - * PARAMETERS: gpe_event_info - Info block for the GPE to be enabled - * - * RETURN: None - * - * DESCRIPTION: Keep track of which GPEs the OS has requested not be - * disabled when going to sleep. - * - ******************************************************************************/ - -void -acpi_hw_enable_gpe_for_wakeup ( +acpi_hw_write_gpe_enable_reg ( struct acpi_gpe_event_info *gpe_event_info) { struct acpi_gpe_register_info *gpe_register_info; - - - ACPI_FUNCTION_ENTRY (); - - - /* Get the info block for the entire GPE register */ - - gpe_register_info = gpe_event_info->register_info; - if (!gpe_register_info) { - return; - } - - /* - * Set the bit so we will not enable this GPE when sleeping (and disable - * it upon wake) - */ - gpe_register_info->wake_enable |= gpe_event_info->bit_mask; - gpe_event_info->flags |= (ACPI_GPE_TYPE_WAKE | ACPI_GPE_ENABLED); -} - - -/****************************************************************************** - * - * FUNCTION: acpi_hw_disable_gpe - * - * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled - * - * RETURN: Status - * - * DESCRIPTION: Disable a single GPE. - * - ******************************************************************************/ - -acpi_status -acpi_hw_disable_gpe ( - struct acpi_gpe_event_info *gpe_event_info) -{ - u32 in_byte; acpi_status status; - struct acpi_gpe_register_info *gpe_register_info; ACPI_FUNCTION_ENTRY (); @@ -158,67 +78,15 @@ gpe_register_info = gpe_event_info->register_info; if (!gpe_register_info) { - return (AE_BAD_PARAMETER); + return (AE_NOT_EXIST); } - /* - * Read the current value of the register, clear the appropriate bit, - * and write out the new register value to disable the GPE. - */ - status = acpi_hw_low_level_read (8, &in_byte, - &gpe_register_info->enable_address); - if (ACPI_FAILURE (status)) { - return (status); - } + /* Write the entire GPE (runtime) enable register */ - /* Write the byte with this GPE bit cleared */ - - status = acpi_hw_low_level_write (8, (in_byte & ~(gpe_event_info->bit_mask)), + status = acpi_hw_low_level_write (8, gpe_register_info->enable_for_run, &gpe_register_info->enable_address); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Make sure this GPE is disabled for wake, also */ - - acpi_hw_disable_gpe_for_wakeup (gpe_event_info); - return (AE_OK); -} - - -/****************************************************************************** - * - * FUNCTION: acpi_hw_disable_gpe_for_wakeup - * - * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled - * - * RETURN: None - * - * DESCRIPTION: Keep track of which GPEs the OS has requested not be - * disabled when going to sleep. - * - ******************************************************************************/ - -void -acpi_hw_disable_gpe_for_wakeup ( - struct acpi_gpe_event_info *gpe_event_info) -{ - struct acpi_gpe_register_info *gpe_register_info; - - - ACPI_FUNCTION_ENTRY (); - - - /* Get the info block for the entire GPE register */ - - gpe_register_info = gpe_event_info->register_info; - if (!gpe_register_info) { - return; - } - /* Clear the bit so we will disable this when sleeping */ - - gpe_register_info->wake_enable &= ~(gpe_event_info->bit_mask); + return (status); } @@ -248,7 +116,7 @@ * Write a one to the appropriate bit in the status register to * clear this GPE. */ - status = acpi_hw_low_level_write (8, gpe_event_info->bit_mask, + status = acpi_hw_low_level_write (8, gpe_event_info->register_bit, &gpe_event_info->register_info->status_address); return (status); @@ -274,7 +142,7 @@ acpi_event_status *event_status) { u32 in_byte; - u8 bit_mask; + u8 register_bit; struct acpi_gpe_register_info *gpe_register_info; acpi_status status; acpi_event_status local_event_status = 0; @@ -293,33 +161,28 @@ /* Get the register bitmask for this GPE */ - bit_mask = gpe_event_info->bit_mask; - - /* GPE Enabled? */ + register_bit = gpe_event_info->register_bit; - status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->enable_address); - if (ACPI_FAILURE (status)) { - goto unlock_and_exit; - } + /* GPE currently enabled? (enabled for runtime?) */ - if (bit_mask & in_byte) { + if (register_bit & gpe_register_info->enable_for_run) { local_event_status |= ACPI_EVENT_FLAG_ENABLED; } - /* GPE Enabled for wake? */ + /* GPE enabled for wake? */ - if (bit_mask & gpe_register_info->wake_enable) { + if (register_bit & gpe_register_info->enable_for_wake) { local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED; } - /* GPE active (set)? */ + /* GPE currently active (status bit == 1)? */ status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } - if (bit_mask & in_byte) { + if (register_bit & in_byte) { local_event_status |= ACPI_EVENT_FLAG_SET; } @@ -411,64 +274,43 @@ /****************************************************************************** * - * FUNCTION: acpi_hw_prepare_gpe_block_for_sleep + * FUNCTION: acpi_hw_enable_runtime_gpe_block * * PARAMETERS: gpe_xrupt_info - GPE Interrupt info * gpe_block - Gpe Block info * * RETURN: Status * - * DESCRIPTION: Disable all runtime GPEs and enable all wakeup GPEs -- within - * a single GPE block + * DESCRIPTION: Enable all "runtime" GPEs within a GPE block. (Includes + * combination wake/run GPEs.) * ******************************************************************************/ -static acpi_status -acpi_hw_prepare_gpe_block_for_sleep ( +acpi_status +acpi_hw_enable_runtime_gpe_block ( struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block) { u32 i; - struct acpi_gpe_register_info *gpe_register_info; - u32 in_value; acpi_status status; - /* Get the register info for the entire GPE block */ - - gpe_register_info = gpe_block->register_info; + /* NOTE: assumes that all GPEs are currently disabled */ /* Examine each GPE Register within the block */ for (i = 0; i < gpe_block->register_count; i++) { - /* - * Read the enabled/disabled status of all GPEs. We - * will be using it to restore all the GPEs later. - * - * NOTE: Wake GPEs are are ALL disabled at this time, so when we wake - * and restore this register, they will be automatically disabled. - */ - status = acpi_hw_low_level_read (8, &in_value, - &gpe_register_info->enable_address); - if (ACPI_FAILURE (status)) { - return (status); + if (!gpe_block->register_info[i].enable_for_run) { + continue; } - gpe_register_info->enable = (u8) in_value; + /* Enable all "runtime" GPEs in this register */ - /* - * 1) Disable all runtime GPEs - * 2) Enable all wakeup GPEs - */ - status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable, - &gpe_register_info->enable_address); + status = acpi_hw_low_level_write (8, gpe_block->register_info[i].enable_for_run, + &gpe_block->register_info[i].enable_address); if (ACPI_FAILURE (status)) { return (status); } - - /* Point to next GPE register */ - - gpe_register_info++; } return (AE_OK); @@ -477,122 +319,125 @@ /****************************************************************************** * - * FUNCTION: acpi_hw_prepare_gpes_for_sleep + * FUNCTION: acpi_hw_enable_wakeup_gpe_block * - * PARAMETERS: None + * PARAMETERS: gpe_xrupt_info - GPE Interrupt info + * gpe_block - Gpe Block info * * RETURN: Status * - * DESCRIPTION: Disable all runtime GPEs, enable all wake GPEs. - * Called with interrupts disabled. The interrupt handler also - * modifies gpe_register_info->Enable, so it should not be - * given the chance to run until after the runtime GPEs are - * re-enabled. + * DESCRIPTION: Enable all "wake" GPEs within a GPE block. (Includes + * combination wake/run GPEs.) * ******************************************************************************/ acpi_status -acpi_hw_prepare_gpes_for_sleep ( - void) +acpi_hw_enable_wakeup_gpe_block ( + struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block) { + u32 i; acpi_status status; - ACPI_FUNCTION_ENTRY (); + /* Examine each GPE Register within the block */ + for (i = 0; i < gpe_block->register_count; i++) { + if (!gpe_block->register_info[i].enable_for_wake) { + continue; + } - status = acpi_ev_walk_gpe_list (acpi_hw_prepare_gpe_block_for_sleep); - return (status); + /* Enable all "wake" GPEs in this register */ + + status = acpi_hw_low_level_write (8, gpe_block->register_info[i].enable_for_wake, + &gpe_block->register_info[i].enable_address); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + return (AE_OK); } /****************************************************************************** * - * FUNCTION: acpi_hw_restore_gpe_block_on_wake + * FUNCTION: acpi_hw_disable_all_gpes * - * PARAMETERS: gpe_xrupt_info - GPE Interrupt info - * gpe_block - Gpe Block info + * PARAMETERS: Flags - ACPI_NOT_ISR or ACPI_ISR * * RETURN: Status * - * DESCRIPTION: Enable all runtime GPEs and disable all wake GPEs -- in one - * GPE block + * DESCRIPTION: Disable and clear all GPEs * ******************************************************************************/ -static acpi_status -acpi_hw_restore_gpe_block_on_wake ( - struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block) +acpi_status +acpi_hw_disable_all_gpes ( + u32 flags) { - u32 i; - struct acpi_gpe_register_info *gpe_register_info; acpi_status status; - /* This callback processes one entire GPE block */ + ACPI_FUNCTION_TRACE ("hw_disable_all_gpes"); - /* Get the register info for the entire GPE block */ - gpe_register_info = gpe_block->register_info; + status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block, flags); + status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block, flags); + return_ACPI_STATUS (status); +} - /* Examine each GPE register within the block */ - for (i = 0; i < gpe_block->register_count; i++) { - /* Clear the entire status register */ +/****************************************************************************** + * + * FUNCTION: acpi_hw_enable_all_runtime_gpes + * + * PARAMETERS: Flags - ACPI_NOT_ISR or ACPI_ISR + * + * RETURN: Status + * + * DESCRIPTION: Enable all GPEs of the given type + * + ******************************************************************************/ - status = acpi_hw_low_level_write (8, 0xFF, - &gpe_block->register_info[i].status_address); - if (ACPI_FAILURE (status)) { - return (status); - } +acpi_status +acpi_hw_enable_all_runtime_gpes ( + u32 flags) +{ + acpi_status status; - /* - * Restore the GPE Enable register, which will do the following: - * - * 1) Disable all wakeup GPEs - * 2) Enable all runtime GPEs - * - * (On sleep, we saved the enabled status of all GPEs) - */ - status = acpi_hw_low_level_write (8, gpe_register_info->enable, - &gpe_register_info->enable_address); - if (ACPI_FAILURE (status)) { - return (status); - } - /* Point to next GPE register */ + ACPI_FUNCTION_TRACE ("hw_enable_all_runtime_gpes"); - gpe_register_info++; - } - return (AE_OK); + status = acpi_ev_walk_gpe_list (acpi_hw_enable_runtime_gpe_block, flags); + return_ACPI_STATUS (status); } /****************************************************************************** * - * FUNCTION: acpi_hw_restore_gpes_on_wake + * FUNCTION: acpi_hw_enable_all_wakeup_gpes * - * PARAMETERS: None + * PARAMETERS: Flags - ACPI_NOT_ISR or ACPI_ISR * * RETURN: Status * - * DESCRIPTION: Enable all runtime GPEs and disable all wake GPEs -- in all - * GPE blocks + * DESCRIPTION: Enable all GPEs of the given type * ******************************************************************************/ acpi_status -acpi_hw_restore_gpes_on_wake ( - void) +acpi_hw_enable_all_wakeup_gpes ( + u32 flags) { acpi_status status; - ACPI_FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE ("hw_enable_all_wakeup_gpes"); - status = acpi_ev_walk_gpe_list (acpi_hw_restore_gpe_block_on_wake); - return (status); + status = acpi_ev_walk_gpe_list (acpi_hw_enable_wakeup_gpe_block, flags); + return_ACPI_STATUS (status); } + diff -Nru a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c --- a/drivers/acpi/hardware/hwregs.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/hardware/hwregs.c 2004-08-21 23:40:16 -07:00 @@ -61,6 +61,7 @@ * RETURN: none * * DESCRIPTION: Clears all fixed and general purpose status bits + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED * ******************************************************************************/ @@ -103,7 +104,7 @@ /* Clear the GPE Bits in all GPE registers in all GPE blocks */ - status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block); + status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block, ACPI_ISR); unlock_and_exit: if (flags & ACPI_MTX_LOCK) { @@ -135,7 +136,7 @@ u8 *sleep_type_b) { acpi_status status = AE_OK; - union acpi_operand_object *obj_desc; + struct acpi_parameter_info info; ACPI_FUNCTION_TRACE ("acpi_get_sleep_type_data"); @@ -152,8 +153,9 @@ /* * Evaluate the namespace object containing the values for this state */ + info.parameters = NULL; status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_sleep_state_names[sleep_state], - NULL, &obj_desc); + &info); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n", acpi_format_exception (status), acpi_gbl_sleep_state_names[sleep_state])); @@ -163,48 +165,50 @@ /* Must have a return object */ - if (!obj_desc) { + if (!info.return_object) { ACPI_REPORT_ERROR (("Missing Sleep State object\n")); status = AE_NOT_EXIST; } /* It must be of type Package */ - else if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_PACKAGE) { + else if (ACPI_GET_OBJECT_TYPE (info.return_object) != ACPI_TYPE_PACKAGE) { ACPI_REPORT_ERROR (("Sleep State object not a Package\n")); status = AE_AML_OPERAND_TYPE; } /* The package must have at least two elements */ - else if (obj_desc->package.count < 2) { + else if (info.return_object->package.count < 2) { ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n")); status = AE_AML_NO_OPERAND; } /* The first two elements must both be of type Integer */ - else if ((ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[0]) != ACPI_TYPE_INTEGER) || - (ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[1]) != ACPI_TYPE_INTEGER)) { + else if ((ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[0]) != ACPI_TYPE_INTEGER) || + (ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[1]) != ACPI_TYPE_INTEGER)) { ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n", - acpi_ut_get_object_type_name (obj_desc->package.elements[0]), - acpi_ut_get_object_type_name (obj_desc->package.elements[1]))); + acpi_ut_get_object_type_name (info.return_object->package.elements[0]), + acpi_ut_get_object_type_name (info.return_object->package.elements[1]))); status = AE_AML_OPERAND_TYPE; } else { /* * Valid _Sx_ package size, type, and value */ - *sleep_type_a = (u8) (obj_desc->package.elements[0])->integer.value; - *sleep_type_b = (u8) (obj_desc->package.elements[1])->integer.value; + *sleep_type_a = (u8) (info.return_object->package.elements[0])->integer.value; + *sleep_type_b = (u8) (info.return_object->package.elements[1])->integer.value; } if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating sleep_state [%s], bad Sleep object %p type %s\n", - acpi_gbl_sleep_state_names[sleep_state], obj_desc, acpi_ut_get_object_type_name (obj_desc))); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "While evaluating sleep_state [%s], bad Sleep object %p type %s\n", + acpi_gbl_sleep_state_names[sleep_state], info.return_object, + acpi_ut_get_object_type_name (info.return_object))); } - acpi_ut_remove_reference (obj_desc); + acpi_ut_remove_reference (info.return_object); return_ACPI_STATUS (status); } diff -Nru a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c --- a/drivers/acpi/hardware/hwsleep.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/hardware/hwsleep.c 2004-08-21 23:40:16 -07:00 @@ -265,19 +265,21 @@ sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A); sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE); - if (sleep_state != ACPI_STATE_S5) { - /* Clear wake status */ + /* Clear wake status */ - status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + /* Clear all fixed and general purpose status bits */ + status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + if (sleep_state != ACPI_STATE_S5) { /* Disable BM arbitration */ status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK); @@ -287,10 +289,16 @@ } /* - * 1) Disable all runtime GPEs + * 1) Disable/Clear all GPEs * 2) Enable all wakeup GPEs */ - status = acpi_hw_prepare_gpes_for_sleep (); + status = acpi_hw_disable_all_gpes (ACPI_ISR); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + acpi_gbl_system_awake_and_running = FALSE; + + status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -420,10 +428,16 @@ } /* - * 1) Disable all runtime GPEs + * 1) Disable/Clear all GPEs * 2) Enable all wakeup GPEs */ - status = acpi_hw_prepare_gpes_for_sleep (); + status = acpi_hw_disable_all_gpes (ACPI_ISR); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + acpi_gbl_system_awake_and_running = FALSE; + + status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -453,6 +467,7 @@ * RETURN: Status * * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep + * Called with interrupts ENABLED. * ******************************************************************************/ @@ -540,19 +555,25 @@ /* * Restore the GPEs: - * 1) Disable all wakeup GPEs + * 1) Disable/Clear all GPEs * 2) Enable all runtime GPEs */ - status = acpi_hw_restore_gpes_on_wake (); + status = acpi_hw_disable_all_gpes (ACPI_NOT_ISR); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + acpi_gbl_system_awake_and_running = TRUE; + + status = acpi_hw_enable_all_runtime_gpes (ACPI_NOT_ISR); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Enable power button */ - acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id, + (void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id, 1, ACPI_MTX_DO_NOT_LOCK); - acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id, + (void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id, 1, ACPI_MTX_DO_NOT_LOCK); /* Enable BM arbitration */ diff -Nru a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/acpi/motherboard.c 2004-08-21 23:40:16 -07:00 @@ -0,0 +1,173 @@ +/* + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +/* Purpose: Prevent PCMCIA cards from using motherboard resources. */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define _COMPONENT ACPI_SYSTEM_COMPONENT +ACPI_MODULE_NAME ("acpi_motherboard") + +/* Dell use PNP0C01 instead of PNP0C02 */ +#define ACPI_MB_HID1 "PNP0C01" +#define ACPI_MB_HID2 "PNP0C02" + +/** + * Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved + * Doesn't care about the failure of 'request_region', since other may reserve + * the io ports as well + */ +#define IS_RESERVED_ADDR(base, len) \ + (((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \ + && ((base) + (len) > PCIBIOS_MIN_IO)) + +/* + * Clearing the flag (IORESOURCE_BUSY) allows drivers to use + * the io ports if they really know they can use it, while + * still preventing hotplug PCI devices from using it. + */ + +static acpi_status +acpi_reserve_io_ranges (struct acpi_resource *res, void *data) +{ + struct resource *requested_res = NULL; + + ACPI_FUNCTION_TRACE("acpi_reserve_io_ranges"); + + if (res->id == ACPI_RSTYPE_IO) { + struct acpi_resource_io *io_res = &res->data.io; + + if (io_res->min_base_address != io_res->max_base_address) + return AE_OK; + if (IS_RESERVED_ADDR(io_res->min_base_address, io_res->range_length)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n", + io_res->min_base_address, + io_res->min_base_address + io_res->range_length)); + requested_res = request_region(io_res->min_base_address, + io_res->range_length, "motherboard"); + } + } else if (res->id == ACPI_RSTYPE_FIXED_IO) { + struct acpi_resource_fixed_io *fixed_io_res = &res->data.fixed_io; + + if (IS_RESERVED_ADDR(fixed_io_res->base_address, fixed_io_res->range_length)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n", + fixed_io_res->base_address, + fixed_io_res->base_address + fixed_io_res->range_length)); + requested_res = request_region(fixed_io_res->base_address, + fixed_io_res->range_length, "motherboard"); + } + } else { + /* Memory mapped IO? */ + } + + if (requested_res) + requested_res->flags &= ~IORESOURCE_BUSY; + return AE_OK; +} + +static int acpi_motherboard_add (struct acpi_device *device) +{ + if (!device) + return -EINVAL; + acpi_walk_resources(device->handle, METHOD_NAME__CRS, + acpi_reserve_io_ranges, NULL); + + return 0; +} + +static struct acpi_driver acpi_motherboard_driver1 = { + .name = "motherboard", + .class = "", + .ids = ACPI_MB_HID1, + .ops = { + .add = acpi_motherboard_add, + }, +}; + +static struct acpi_driver acpi_motherboard_driver2 = { + .name = "motherboard", + .class = "", + .ids = ACPI_MB_HID2, + .ops = { + .add = acpi_motherboard_add, + }, +}; + +static void __init +acpi_reserve_resources (void) +{ + if (acpi_gbl_FADT->xpm1a_evt_blk.address && acpi_gbl_FADT->pm1_evt_len) + request_region(acpi_gbl_FADT->xpm1a_evt_blk.address, + acpi_gbl_FADT->pm1_evt_len, "PM1a_EVT_BLK"); + + if (acpi_gbl_FADT->xpm1b_evt_blk.address && acpi_gbl_FADT->pm1_evt_len) + request_region(acpi_gbl_FADT->xpm1b_evt_blk.address, + acpi_gbl_FADT->pm1_evt_len, "PM1b_EVT_BLK"); + + if (acpi_gbl_FADT->xpm1a_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len) + request_region(acpi_gbl_FADT->xpm1a_cnt_blk.address, + acpi_gbl_FADT->pm1_cnt_len, "PM1a_CNT_BLK"); + + if (acpi_gbl_FADT->xpm1b_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len) + request_region(acpi_gbl_FADT->xpm1b_cnt_blk.address, + acpi_gbl_FADT->pm1_cnt_len, "PM1b_CNT_BLK"); + + if (acpi_gbl_FADT->xpm_tmr_blk.address && acpi_gbl_FADT->pm_tm_len == 4) + request_region(acpi_gbl_FADT->xpm_tmr_blk.address, + 4, "PM_TMR"); + + if (acpi_gbl_FADT->xpm2_cnt_blk.address && acpi_gbl_FADT->pm2_cnt_len) + request_region(acpi_gbl_FADT->xpm2_cnt_blk.address, + acpi_gbl_FADT->pm2_cnt_len, "PM2_CNT_BLK"); + + /* Length of GPE blocks must be a non-negative multiple of 2 */ + + if (acpi_gbl_FADT->xgpe0_blk.address && acpi_gbl_FADT->gpe0_blk_len && + !(acpi_gbl_FADT->gpe0_blk_len & 0x1)) + request_region(acpi_gbl_FADT->xgpe0_blk.address, + acpi_gbl_FADT->gpe0_blk_len, "GPE0_BLK"); + + if (acpi_gbl_FADT->xgpe1_blk.address && acpi_gbl_FADT->gpe1_blk_len && + !(acpi_gbl_FADT->gpe1_blk_len & 0x1)) + request_region(acpi_gbl_FADT->xgpe1_blk.address, + acpi_gbl_FADT->gpe1_blk_len, "GPE1_BLK"); +} + +static int __init acpi_motherboard_init(void) +{ + acpi_bus_register_driver(&acpi_motherboard_driver1); + acpi_bus_register_driver(&acpi_motherboard_driver2); + /* + * Guarantee motherboard IO reservation first + * This module must run after scan.c + */ + if (!acpi_disabled) + acpi_reserve_resources (); + return 0; +} + +subsys_initcall(acpi_motherboard_init); diff -Nru a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c --- a/drivers/acpi/namespace/nsaccess.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/namespace/nsaccess.c 2004-08-21 23:40:16 -07:00 @@ -193,7 +193,7 @@ case ACPI_TYPE_MUTEX: obj_desc->mutex.node = new_node; - obj_desc->mutex.sync_level = (u16) ACPI_STRTOUL + obj_desc->mutex.sync_level = (u8) ACPI_STRTOUL (val, NULL, 10); if (ACPI_STRCMP (init_val->name, "_GL_") == 0) { diff -Nru a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c --- a/drivers/acpi/namespace/nsalloc.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/namespace/nsalloc.c 2004-08-21 23:40:16 -07:00 @@ -267,7 +267,7 @@ else { #ifdef ACPI_ALPHABETIC_NAMESPACE /* - * Walk the list whilst searching for the the correct + * Walk the list whilst searching for the correct * alphabetic placement. */ previous_child_node = NULL; diff -Nru a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c --- a/drivers/acpi/namespace/nseval.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/namespace/nseval.c 2004-08-21 23:40:16 -07:00 @@ -77,13 +77,10 @@ acpi_status acpi_ns_evaluate_relative ( - struct acpi_namespace_node *handle, char *pathname, - union acpi_operand_object **params, - union acpi_operand_object **return_object) + struct acpi_parameter_info *info) { acpi_status status; - struct acpi_namespace_node *prefix_node; struct acpi_namespace_node *node = NULL; union acpi_generic_state *scope_info; char *internal_path = NULL; @@ -95,7 +92,7 @@ /* * Must have a valid object handle */ - if (!handle) { + if (!info || !info->node) { return_ACPI_STATUS (AE_BAD_PARAMETER); } @@ -118,8 +115,8 @@ goto cleanup; } - prefix_node = acpi_ns_map_handle_to_node (handle); - if (!prefix_node) { + info->node = acpi_ns_map_handle_to_node (info->node); + if (!info->node) { (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); status = AE_BAD_PARAMETER; goto cleanup; @@ -127,7 +124,7 @@ /* Lookup the name in the namespace */ - scope_info->scope.node = prefix_node; + scope_info->scope.node = info->node; status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, &node); @@ -147,7 +144,8 @@ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", pathname, node, acpi_ns_get_attached_object (node))); - status = acpi_ns_evaluate_by_handle (node, params, return_object); + info->node = node; + status = acpi_ns_evaluate_by_handle (info); ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n", pathname)); @@ -166,6 +164,7 @@ * FUNCTION: acpi_ns_evaluate_by_name * * PARAMETERS: Pathname - Fully qualified pathname to the object + * Info - Contains: * return_object - Where to put method's return value (if * any). If NULL, no value is returned. * Params - List of parameters to pass to the method, @@ -184,11 +183,9 @@ acpi_status acpi_ns_evaluate_by_name ( char *pathname, - union acpi_operand_object **params, - union acpi_operand_object **return_object) + struct acpi_parameter_info *info) { acpi_status status; - struct acpi_namespace_node *node = NULL; char *internal_path = NULL; @@ -211,7 +208,7 @@ status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, - &node); + &info->node); (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); @@ -226,9 +223,9 @@ * to evaluate it. */ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", - pathname, node, acpi_ns_get_attached_object (node))); + pathname, info->node, acpi_ns_get_attached_object (info->node))); - status = acpi_ns_evaluate_by_handle (node, params, return_object); + status = acpi_ns_evaluate_by_handle (info); ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n", pathname)); @@ -254,6 +251,7 @@ * Params - List of parameters to pass to the method, * terminated by NULL. Params itself may be * NULL if no parameters are being passed. + * param_type - Type of Parameter list * return_object - Where to put method's return value (if * any). If NULL, no value is returned. * @@ -267,13 +265,9 @@ acpi_status acpi_ns_evaluate_by_handle ( - struct acpi_namespace_node *handle, - union acpi_operand_object **params, - union acpi_operand_object **return_object) + struct acpi_parameter_info *info) { - struct acpi_namespace_node *node; acpi_status status; - union acpi_operand_object *local_return_object; ACPI_FUNCTION_TRACE ("ns_evaluate_by_handle"); @@ -287,15 +281,13 @@ /* Parameter Validation */ - if (!handle) { + if (!info) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - if (return_object) { - /* Initialize the return value to an invalid object */ + /* Initialize the return value to an invalid object */ - *return_object = NULL; - } + info->return_object = NULL; /* Get the prefix handle and Node */ @@ -304,8 +296,8 @@ return_ACPI_STATUS (status); } - node = acpi_ns_map_handle_to_node (handle); - if (!node) { + info->node = acpi_ns_map_handle_to_node (info->node); + if (!info->node) { (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (AE_BAD_PARAMETER); } @@ -315,8 +307,8 @@ * so that proper scoping context will be established * before execution. */ - if (acpi_ns_get_type (node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { - node = ACPI_CAST_PTR (struct acpi_namespace_node, node->object); + if (acpi_ns_get_type (info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { + info->node = ACPI_CAST_PTR (struct acpi_namespace_node, info->node->object); } /* @@ -328,19 +320,18 @@ * In both cases, the namespace is unlocked by the * acpi_ns* procedure */ - if (acpi_ns_get_type (node) == ACPI_TYPE_METHOD) { + if (acpi_ns_get_type (info->node) == ACPI_TYPE_METHOD) { /* * Case 1) We have an actual control method to execute */ - status = acpi_ns_execute_control_method (node, params, - &local_return_object); + status = acpi_ns_execute_control_method (info); } else { /* * Case 2) Object is NOT a method, just return its * current value */ - status = acpi_ns_get_object_value (node, &local_return_object); + status = acpi_ns_get_object_value (info); } /* @@ -348,20 +339,6 @@ * be dealt with */ if (status == AE_CTRL_RETURN_VALUE) { - /* - * If the Method returned a value and the caller - * provided a place to store a returned value, Copy - * the returned value to the object descriptor provided - * by the caller. - */ - if (return_object) { - /* - * Valid return object, copy the pointer to - * the returned object - */ - *return_object = local_return_object; - } - /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ status = AE_OK; @@ -396,9 +373,7 @@ acpi_status acpi_ns_execute_control_method ( - struct acpi_namespace_node *method_node, - union acpi_operand_object **params, - union acpi_operand_object **return_obj_desc) + struct acpi_parameter_info *info) { acpi_status status; union acpi_operand_object *obj_desc; @@ -409,7 +384,7 @@ /* Verify that there is a method associated with this object */ - obj_desc = acpi_ns_get_attached_object (method_node); + obj_desc = acpi_ns_get_attached_object (info->node); if (!obj_desc) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n")); @@ -417,7 +392,7 @@ return_ACPI_STATUS (AE_NULL_OBJECT); } - ACPI_DUMP_PATHNAME (method_node, "Execute Method:", + ACPI_DUMP_PATHNAME (info->node, "Execute Method:", ACPI_LV_INFO, _COMPONENT); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n", @@ -444,7 +419,7 @@ return_ACPI_STATUS (status); } - status = acpi_psx_execute (method_node, params, return_obj_desc); + status = acpi_psx_execute (info); acpi_ex_exit_interpreter (); return_ACPI_STATUS (status); @@ -468,11 +443,10 @@ acpi_status acpi_ns_get_object_value ( - struct acpi_namespace_node *node, - union acpi_operand_object **return_obj_desc) + struct acpi_parameter_info *info) { acpi_status status = AE_OK; - struct acpi_namespace_node *resolved_node = node; + struct acpi_namespace_node *resolved_node = info->node; ACPI_FUNCTION_TRACE ("ns_get_object_value"); @@ -518,9 +492,9 @@ if (ACPI_SUCCESS (status)) { status = AE_CTRL_RETURN_VALUE; - *return_obj_desc = ACPI_CAST_PTR (union acpi_operand_object, resolved_node); + info->return_object = ACPI_CAST_PTR (union acpi_operand_object, resolved_node); ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n", - *return_obj_desc, acpi_ut_get_object_type_name (*return_obj_desc))); + info->return_object, acpi_ut_get_object_type_name (info->return_object))); } } diff -Nru a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c --- a/drivers/acpi/namespace/nsinit.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/namespace/nsinit.c 2004-08-21 23:40:16 -07:00 @@ -149,7 +149,7 @@ return_ACPI_STATUS (status); } - /* Walk namespace for all objects of type Device or Processor */ + /* Walk namespace for all objects */ status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, TRUE, acpi_ns_init_one_device, &info, NULL); @@ -337,25 +337,29 @@ void *context, void **return_value) { - acpi_status status; - struct acpi_namespace_node *node; - u32 flags; struct acpi_device_walk_info *info = (struct acpi_device_walk_info *) context; + struct acpi_parameter_info pinfo; + u32 flags; + acpi_status status; ACPI_FUNCTION_TRACE ("ns_init_one_device"); - node = acpi_ns_map_handle_to_node (obj_handle); - if (!node) { + pinfo.parameters = NULL; + pinfo.parameter_type = ACPI_PARAM_ARGS; + + pinfo.node = acpi_ns_map_handle_to_node (obj_handle); + if (!pinfo.node) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* - * We will run _STA/_INI on Devices and Processors only + * We will run _STA/_INI on Devices, Processors and thermal_zones only */ - if ((node->type != ACPI_TYPE_DEVICE) && - (node->type != ACPI_TYPE_PROCESSOR)) { + if ((pinfo.node->type != ACPI_TYPE_DEVICE) && + (pinfo.node->type != ACPI_TYPE_PROCESSOR) && + (pinfo.node->type != ACPI_TYPE_THERMAL)) { return_ACPI_STATUS (AE_OK); } @@ -368,17 +372,17 @@ /* * Run _STA to determine if we can run _INI on the device. */ - ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, node, "_STA")); - status = acpi_ut_execute_STA (node, &flags); + ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_STA")); + status = acpi_ut_execute_STA (pinfo.node, &flags); if (ACPI_FAILURE (status)) { - if (node->type == ACPI_TYPE_DEVICE) { + if (pinfo.node->type == ACPI_TYPE_DEVICE) { /* Ignore error and move on to next device */ return_ACPI_STATUS (AE_OK); } - /* _STA is not required for Processor objects */ + /* _STA is not required for Processor or thermal_zone objects */ } else { info->num_STA++; @@ -393,22 +397,22 @@ /* * The device is present. Run _INI. */ - ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, obj_handle, "_INI")); - status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL); + ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_INI")); + status = acpi_ns_evaluate_relative ("_INI", &pinfo); if (ACPI_FAILURE (status)) { /* No _INI (AE_NOT_FOUND) means device requires no initialization */ if (status != AE_NOT_FOUND) { /* Ignore error and move on to next device */ - #ifdef ACPI_DEBUG_OUTPUT - char *scope_name = acpi_ns_get_external_pathname (obj_handle); +#ifdef ACPI_DEBUG_OUTPUT + char *scope_name = acpi_ns_get_external_pathname (pinfo.node); ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%s._INI failed: %s\n", scope_name, acpi_format_exception (status))); ACPI_MEM_FREE (scope_name); - #endif +#endif } status = AE_OK; @@ -422,7 +426,7 @@ if (acpi_gbl_init_handler) { /* External initialization handler is present, call it */ - status = acpi_gbl_init_handler (obj_handle, ACPI_INIT_DEVICE_INI); + status = acpi_gbl_init_handler (pinfo.node, ACPI_INIT_DEVICE_INI); } diff -Nru a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c --- a/drivers/acpi/namespace/nsparse.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/namespace/nsparse.c 2004-08-21 23:40:16 -07:00 @@ -94,8 +94,9 @@ return_ACPI_STATUS (AE_NO_MEMORY); } - status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL, table_desc->aml_start, - table_desc->aml_length, NULL, NULL, pass_number); + status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL, + table_desc->aml_start, table_desc->aml_length, + NULL, pass_number); if (ACPI_FAILURE (status)) { acpi_ds_delete_walk_state (walk_state); return_ACPI_STATUS (status); diff -Nru a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c --- a/drivers/acpi/namespace/nsxfeval.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/namespace/nsxfeval.c 2004-08-21 23:40:16 -07:00 @@ -174,8 +174,7 @@ { acpi_status status; acpi_status status2; - union acpi_operand_object **internal_params = NULL; - union acpi_operand_object *internal_return_obj = NULL; + struct acpi_parameter_info info; acpi_size buffer_space_needed; u32 i; @@ -183,6 +182,11 @@ ACPI_FUNCTION_TRACE ("acpi_evaluate_object"); + info.node = handle; + info.parameters = NULL; + info.return_object = NULL; + info.parameter_type = ACPI_PARAM_ARGS; + /* * If there are parameters to be passed to the object * (which must be a control method), the external objects @@ -193,9 +197,10 @@ * Allocate a new parameter block for the internal objects * Add 1 to count to allow for null terminated internal list */ - internal_params = ACPI_MEM_CALLOCATE (((acpi_size) external_params->count + 1) * - sizeof (void *)); - if (!internal_params) { + info.parameters = ACPI_MEM_CALLOCATE ( + ((acpi_size) external_params->count + 1) * + sizeof (void *)); + if (!info.parameters) { return_ACPI_STATUS (AE_NO_MEMORY); } @@ -205,15 +210,16 @@ */ for (i = 0; i < external_params->count; i++) { status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i], - &internal_params[i]); + &info.parameters[i]); if (ACPI_FAILURE (status)) { - acpi_ut_delete_internal_object_list (internal_params); + acpi_ut_delete_internal_object_list (info.parameters); return_ACPI_STATUS (status); } } - internal_params[external_params->count] = NULL; + info.parameters[external_params->count] = NULL; } + /* * Three major cases: * 1) Fully qualified pathname @@ -225,8 +231,7 @@ /* * The path is fully qualified, just evaluate by name */ - status = acpi_ns_evaluate_by_name (pathname, internal_params, - &internal_return_obj); + status = acpi_ns_evaluate_by_name (pathname, &info); } else if (!handle) { /* @@ -256,15 +261,13 @@ * The null pathname case means the handle is for * the actual object to be evaluated */ - status = acpi_ns_evaluate_by_handle (handle, internal_params, - &internal_return_obj); + status = acpi_ns_evaluate_by_handle (&info); } else { /* * Both a Handle and a relative Pathname */ - status = acpi_ns_evaluate_relative (handle, pathname, internal_params, - &internal_return_obj); + status = acpi_ns_evaluate_relative (pathname, &info); } } @@ -274,11 +277,11 @@ * copy the return value to an external object. */ if (return_buffer) { - if (!internal_return_obj) { + if (!info.return_object) { return_buffer->length = 0; } else { - if (ACPI_GET_DESCRIPTOR_TYPE (internal_return_obj) == ACPI_DESC_TYPE_NAMED) { + if (ACPI_GET_DESCRIPTOR_TYPE (info.return_object) == ACPI_DESC_TYPE_NAMED) { /* * If we received a NS Node as a return object, this means that * the object we are evaluating has nothing interesting to @@ -288,7 +291,7 @@ * support for various types at a later date if necessary. */ status = AE_TYPE; - internal_return_obj = NULL; /* No need to delete a NS Node */ + info.return_object = NULL; /* No need to delete a NS Node */ return_buffer->length = 0; } @@ -297,7 +300,7 @@ * Find out how large a buffer is needed * to contain the returned object */ - status = acpi_ut_get_object_size (internal_return_obj, + status = acpi_ut_get_object_size (info.return_object, &buffer_space_needed); if (ACPI_SUCCESS (status)) { /* Validate/Allocate/Clear caller buffer */ @@ -309,13 +312,14 @@ */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Needed buffer size %X, %s\n", - (u32) buffer_space_needed, acpi_format_exception (status))); + (u32) buffer_space_needed, + acpi_format_exception (status))); } else { /* * We have enough space for the object, build it */ - status = acpi_ut_copy_iobject_to_eobject (internal_return_obj, + status = acpi_ut_copy_iobject_to_eobject (info.return_object, return_buffer); } } @@ -323,7 +327,7 @@ } } - if (internal_return_obj) { + if (info.return_object) { /* * Delete the internal return object. NOTE: Interpreter * must be locked to avoid race condition. @@ -334,7 +338,7 @@ * Delete the internal return object. (Or at least * decrement the reference count by one) */ - acpi_ut_remove_reference (internal_return_obj); + acpi_ut_remove_reference (info.return_object); acpi_ex_exit_interpreter (); } } @@ -342,10 +346,10 @@ /* * Free the input parameter list (if we created one), */ - if (internal_params) { + if (info.parameters) { /* Free the allocated parameter block */ - acpi_ut_delete_internal_object_list (internal_params); + acpi_ut_delete_internal_object_list (info.parameters); } return_ACPI_STATUS (status); diff -Nru a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c --- a/drivers/acpi/namespace/nsxfname.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/namespace/nsxfname.c 2004-08-21 23:40:16 -07:00 @@ -281,7 +281,7 @@ if (info.type == ACPI_TYPE_DEVICE) { /* * Get extra info for ACPI Devices objects only: - * Run the Device _HID, _UID, _CID, _STA, and _ADR methods. + * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods. * * Note: none of these methods are required, so they may or may * not be present for this device. The Info.Valid bitfield is used @@ -330,7 +330,7 @@ status = acpi_ut_execute_sxds (node, info.highest_dstates); if (ACPI_SUCCESS (status)) { - info.valid |= ACPI_VALID_STA; + info.valid |= ACPI_VALID_SXDS; } status = AE_OK; diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c --- a/drivers/acpi/osl.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/osl.c 2004-08-21 23:40:16 -07:00 @@ -51,7 +51,7 @@ struct acpi_os_dpc { - OSD_EXECUTION_CALLBACK function; + acpi_osd_exec_callback function; void *context; }; @@ -64,13 +64,19 @@ #endif /*ENABLE_DEBUGGER*/ static unsigned int acpi_irq_irq; -static OSD_HANDLER acpi_irq_handler; +static acpi_osd_handler acpi_irq_handler; static void *acpi_irq_context; static struct workqueue_struct *kacpid_wq; acpi_status acpi_os_initialize(void) { + return AE_OK; +} + +acpi_status +acpi_os_initialize1(void) +{ /* * Initialize PCI configuration space access, as we'll need to access * it while walking the namespace (bus 0 and root bridges w/ _BBNs). @@ -246,7 +252,7 @@ } acpi_status -acpi_os_install_interrupt_handler(u32 gsi, OSD_HANDLER handler, void *context) +acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, void *context) { unsigned int irq; @@ -274,7 +280,7 @@ } acpi_status -acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler) +acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) { if (irq) { free_irq(irq, acpi_irq); @@ -470,6 +476,8 @@ return AE_ERROR; } + BUG_ON(!raw_pci_ops); + result = raw_pci_ops->read(pci_id->segment, pci_id->bus, PCI_DEVFN(pci_id->device, pci_id->function), reg, size, value); @@ -496,6 +504,8 @@ return AE_ERROR; } + BUG_ON(!raw_pci_ops); + result = raw_pci_ops->write(pci_id->segment, pci_id->bus, PCI_DEVFN(pci_id->device, pci_id->function), reg, size, value); @@ -624,7 +634,7 @@ acpi_status acpi_os_queue_for_execution( u32 priority, - OSD_EXECUTION_CALLBACK function, + acpi_osd_exec_callback function, void *context) { acpi_status status = AE_OK; @@ -1066,15 +1076,15 @@ * Run-time events on the same GPE this flag is available * to tell Linux to keep the wake-time GPEs enabled at run-time. */ -static int __init -acpi_leave_gpes_disabled_setup(char *str) +int __init +acpi_wake_gpes_always_on_setup(char *str) { - printk(KERN_INFO PREFIX "leave wake GPEs disabled\n"); + printk(KERN_INFO PREFIX "wake GPEs not disabled\n"); - acpi_gbl_leave_wake_gpes_disabled = TRUE; + acpi_gbl_leave_wake_gpes_disabled = FALSE; return 1; } -__setup("acpi_leave_gpes_disabled", acpi_leave_gpes_disabled_setup); +__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup); diff -Nru a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c --- a/drivers/acpi/parser/psopcode.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/parser/psopcode.c 2004-08-21 23:40:16 -07:00 @@ -251,7 +251,7 @@ #define ARGI_CREATE_FIELD_OP ARGI_LIST4 (ARGI_BUFFER, ARGI_INTEGER, ARGI_INTEGER, ARGI_REFERENCE) #define ARGI_CREATE_QWORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE) #define ARGI_CREATE_WORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE) -#define ARGI_DATA_REGION_OP ARGI_LIST3 (ARGI_STRING, ARGI_STRING, ARGI_STRING) +#define ARGI_DATA_REGION_OP ARGI_LIST3 (ARGI_STRING, ARGI_STRING, ARGI_STRING) #define ARGI_DEBUG_OP ARG_NONE #define ARGI_DECREMENT_OP ARGI_LIST1 (ARGI_INTEGER_REF) #define ARGI_DEREF_OF_OP ARGI_LIST1 (ARGI_REF_OR_STRING) @@ -270,10 +270,10 @@ #define ARGI_INDEX_FIELD_OP ARGI_INVALID_OPCODE #define ARGI_INDEX_OP ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_INTEGER, ARGI_TARGETREF) #define ARGI_LAND_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) -#define ARGI_LEQUAL_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) -#define ARGI_LGREATER_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) +#define ARGI_LEQUAL_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA) +#define ARGI_LGREATER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA) #define ARGI_LGREATEREQUAL_OP ARGI_INVALID_OPCODE -#define ARGI_LLESS_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) +#define ARGI_LLESS_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA) #define ARGI_LLESSEQUAL_OP ARGI_INVALID_OPCODE #define ARGI_LNOT_OP ARGI_LIST1 (ARGI_INTEGER) #define ARGI_LNOTEQUAL_OP ARGI_INVALID_OPCODE diff -Nru a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c --- a/drivers/acpi/parser/psxface.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/parser/psxface.c 2004-08-21 23:40:16 -07:00 @@ -57,7 +57,7 @@ * * FUNCTION: acpi_psx_execute * - * PARAMETERS: method_node - A method object containing both the AML + * PARAMETERS: Info->Node - A method object containing both the AML * address and length. * **Params - List of parameters to pass to method, * terminated by NULL. Params itself may be @@ -73,9 +73,7 @@ acpi_status acpi_psx_execute ( - struct acpi_namespace_node *method_node, - union acpi_operand_object **params, - union acpi_operand_object **return_obj_desc) + struct acpi_parameter_info *info) { acpi_status status; union acpi_operand_object *obj_desc; @@ -89,29 +87,30 @@ /* Validate the Node and get the attached object */ - if (!method_node) { + if (!info || !info->node) { return_ACPI_STATUS (AE_NULL_ENTRY); } - obj_desc = acpi_ns_get_attached_object (method_node); + obj_desc = acpi_ns_get_attached_object (info->node); if (!obj_desc) { return_ACPI_STATUS (AE_NULL_OBJECT); } /* Init for new method, wait on concurrency semaphore */ - status = acpi_ds_begin_method_execution (method_node, obj_desc, NULL); + status = acpi_ds_begin_method_execution (info->node, obj_desc, NULL); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - if (params) { + if ((info->parameter_type == ACPI_PARAM_ARGS) && + (info->parameters)) { /* * The caller "owns" the parameters, so give each one an extra * reference */ - for (i = 0; params[i]; i++) { - acpi_ut_add_reference (params[i]); + for (i = 0; info->parameters[i]; i++) { + acpi_ut_add_reference (info->parameters[i]); } } @@ -121,7 +120,7 @@ */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Begin Method Parse **** Entry=%p obj=%p\n", - method_node, obj_desc)); + info->node, obj_desc)); /* Create and init a Root Node */ @@ -147,8 +146,9 @@ goto cleanup2; } - status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, - obj_desc->method.aml_length, NULL, NULL, 1); + status = acpi_ds_init_aml_walk (walk_state, op, info->node, + obj_desc->method.aml_start, + obj_desc->method.aml_length, NULL, 1); if (ACPI_FAILURE (status)) { goto cleanup3; } @@ -159,7 +159,6 @@ acpi_ps_delete_parse_tree (op); if (ACPI_FAILURE (status)) { goto cleanup1; /* Walk state is already deleted */ - } /* @@ -167,7 +166,7 @@ */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Begin Method Execution **** Entry=%p obj=%p\n", - method_node, obj_desc)); + info->node, obj_desc)); /* Create and init a Root Node */ @@ -179,8 +178,8 @@ /* Init new op with the method name and pointer back to the NS node */ - acpi_ps_set_name (op, method_node->name.integer); - op->common.node = method_node; + acpi_ps_set_name (op, info->node->name.integer); + op->common.node = info->node; /* Create and initialize a new walk state */ @@ -190,8 +189,9 @@ goto cleanup2; } - status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, - obj_desc->method.aml_length, params, return_obj_desc, 3); + status = acpi_ds_init_aml_walk (walk_state, op, info->node, + obj_desc->method.aml_start, + obj_desc->method.aml_length, info, 3); if (ACPI_FAILURE (status)) { goto cleanup3; } @@ -210,13 +210,14 @@ acpi_ps_delete_parse_tree (op); cleanup1: - if (params) { + if ((info->parameter_type == ACPI_PARAM_ARGS) && + (info->parameters)) { /* Take away the extra reference that we gave the parameters above */ - for (i = 0; params[i]; i++) { + for (i = 0; info->parameters[i]; i++) { /* Ignore errors, just do them all */ - (void) acpi_ut_update_object_reference (params[i], REF_DECREMENT); + (void) acpi_ut_update_object_reference (info->parameters[i], REF_DECREMENT); } } @@ -228,10 +229,10 @@ * If the method has returned an object, signal this to the caller with * a control exception code */ - if (*return_obj_desc) { + if (info->return_object) { ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n", - *return_obj_desc)); - ACPI_DUMP_STACK_ENTRY (*return_obj_desc); + info->return_object)); + ACPI_DUMP_STACK_ENTRY (info->return_object); status = AE_CTRL_RETURN_VALUE; } diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c --- a/drivers/acpi/pci_link.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/pci_link.c 2004-08-21 23:40:16 -07:00 @@ -29,6 +29,7 @@ * for IRQ management (e.g. start()->_SRS). */ +#include #include #include #include @@ -71,7 +72,7 @@ u8 active; /* Current IRQ */ u8 edge_level; /* All IRQs */ u8 active_high_low; /* All IRQs */ - u8 setonboot; + u8 initialized; u8 resource_type; u8 possible_count; u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; @@ -517,7 +518,7 @@ ACPI_FUNCTION_TRACE("acpi_pci_link_allocate"); - if (link->irq.setonboot) + if (link->irq.initialized) return_VALUE(0); /* @@ -571,7 +572,7 @@ acpi_device_bid(link->device), link->irq.active); } - link->irq.setonboot = 1; + link->irq.initialized = 1; return_VALUE(0); } @@ -695,6 +696,42 @@ static int +acpi_pci_link_resume ( + struct acpi_pci_link *link) +{ + ACPI_FUNCTION_TRACE("acpi_pci_link_resume"); + + if (link->irq.active && link->irq.initialized) + return_VALUE(acpi_pci_link_set(link, link->irq.active)); + else + return_VALUE(0); +} + + +static int +irqrouter_resume( + struct sys_device *dev) +{ + struct list_head *node = NULL; + struct acpi_pci_link *link = NULL; + + ACPI_FUNCTION_TRACE("irqrouter_resume"); + + list_for_each(node, &acpi_link.entries) { + + link = list_entry(node, struct acpi_pci_link, node); + if (!link) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n")); + continue; + } + + acpi_pci_link_resume(link); + } + return_VALUE(0); +} + + +static int acpi_pci_link_remove ( struct acpi_device *device, int type) @@ -786,11 +823,42 @@ __setup("acpi_irq_balance", acpi_irq_balance_set); +static struct sysdev_class irqrouter_sysdev_class = { + set_kset_name("irqrouter"), + .resume = irqrouter_resume, +}; + + +static struct sys_device device_irqrouter = { + .id = 0, + .cls = &irqrouter_sysdev_class, +}; + + +static int __init irqrouter_init_sysfs(void) +{ + int error; + + ACPI_FUNCTION_TRACE("irqrouter_init_sysfs"); + + if (acpi_disabled || acpi_noirq) + return_VALUE(0); + + error = sysdev_class_register(&irqrouter_sysdev_class); + if (!error) + error = sysdev_register(&device_irqrouter); + + return_VALUE(error); +} + +device_initcall(irqrouter_init_sysfs); + + static int __init acpi_pci_link_init (void) { ACPI_FUNCTION_TRACE("acpi_pci_link_init"); - if (acpi_pci_disabled) + if (acpi_noirq) return_VALUE(0); acpi_link.count = 0; diff -Nru a/drivers/acpi/power.c b/drivers/acpi/power.c --- a/drivers/acpi/power.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/power.c 2004-08-21 23:40:16 -07:00 @@ -288,6 +288,86 @@ return_VALUE(0); } +/* + * Prepare a wakeup device, two steps (Ref ACPI 2.0:P229): + * 1. Power on the power resources required for the wakeup device + * 2. Enable _PSW (power state wake) for the device if present + */ +int acpi_enable_wakeup_device_power (struct acpi_device *dev) +{ + union acpi_object arg = {ACPI_TYPE_INTEGER}; + struct acpi_object_list arg_list = {1, &arg}; + acpi_status status = AE_OK; + int i; + int ret = 0; + + ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_power"); + if (!dev || !dev->wakeup.flags.valid) + return -1; + + arg.integer.value = 1; + /* Open power resource */ + for (i = 0; i < dev->wakeup.resources.count; i++) { + ret = acpi_power_on(dev->wakeup.resources.handles[i]); + if (ret) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error transition power state\n")); + dev->wakeup.flags.valid = 0; + return -1; + } + } + + /* Execute PSW */ + status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL); + if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluate _PSW\n")); + dev->wakeup.flags.valid = 0; + ret = -1; + } + + return ret; +} + +/* + * Shutdown a wakeup device, counterpart of above method + * 1. Disable _PSW (power state wake) + * 2. Shutdown down the power resources + */ +int acpi_disable_wakeup_device_power (struct acpi_device *dev) +{ + union acpi_object arg = {ACPI_TYPE_INTEGER}; + struct acpi_object_list arg_list = {1, &arg}; + acpi_status status = AE_OK; + int i; + int ret = 0; + + ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device_power"); + + if (!dev || !dev->wakeup.flags.valid) + return -1; + + arg.integer.value = 0; + /* Execute PSW */ + status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL); + if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluate _PSW\n")); + dev->wakeup.flags.valid = 0; + return -1; + } + + /* Close power resource */ + for (i = 0; i < dev->wakeup.resources.count; i++) { + ret = acpi_power_off_device(dev->wakeup.resources.handles[i]); + if (ret) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error transition power state\n")); + dev->wakeup.flags.valid = 0; + return -1; + } + } + + return ret; +} /* -------------------------------------------------------------------------- Device Power Management diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c --- a/drivers/acpi/processor.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/processor.c 2004-08-21 23:40:16 -07:00 @@ -44,6 +44,9 @@ #include #include #include +#include +#include +#include #include #include @@ -859,7 +862,6 @@ * _PCT and _PSS structures are read out and written into struct * acpi_processor_performance. */ - static int acpi_processor_set_pdc (struct acpi_processor *pr) { acpi_status status = AE_OK; @@ -1047,6 +1049,8 @@ if (!pr || !pr->performance || !pr->handle) return_VALUE(-EINVAL); + acpi_processor_set_pdc(pr); + status = acpi_get_handle(pr->handle, "_PCT", &handle); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -1054,8 +1058,6 @@ return_VALUE(-ENODEV); } - acpi_processor_set_pdc(pr); - result = acpi_processor_get_performance_control(pr); if (result) return_VALUE(result); @@ -2146,6 +2148,37 @@ return_VALUE(0); } +/* Use the acpiid in MADT to map cpus in case of SMP */ +#ifndef CONFIG_SMP +#define convert_acpiid_to_cpu(acpi_id) (0xff) +#else + +#ifdef CONFIG_IA64 +#define arch_acpiid_to_apicid ia64_acpiid_to_sapicid +#define arch_cpu_to_apicid ia64_cpu_to_sapicid +#define ARCH_BAD_APICID (0xffff) +#else +#define arch_acpiid_to_apicid x86_acpiid_to_apicid +#define arch_cpu_to_apicid x86_cpu_to_apicid +#define ARCH_BAD_APICID (0xff) +#endif + +static u8 convert_acpiid_to_cpu(u8 acpi_id) +{ + u16 apic_id; + int i; + + apic_id = arch_acpiid_to_apicid[acpi_id]; + if (apic_id == ARCH_BAD_APICID) + return -1; + + for (i = 0; i < NR_CPUS; i++) { + if (arch_cpu_to_apicid[i] == apic_id) + return i; + } + return -1; +} +#endif /* -------------------------------------------------------------------------- Driver Interface @@ -2158,7 +2191,8 @@ acpi_status status = 0; union acpi_object object = {0}; struct acpi_buffer buffer = {sizeof(union acpi_object), &object}; - static int cpu_index = 0; + u8 cpu_index; + static int cpu0_initialized; ACPI_FUNCTION_TRACE("acpi_processor_get_info"); @@ -2168,13 +2202,6 @@ if (num_online_cpus() > 1) errata.smp = TRUE; - /* - * Extra Processor objects may be enumerated on MP systems with - * less than the max # of CPUs. They should be ignored. - */ - if ((cpu_index + 1) > num_online_cpus()) - return_VALUE(-ENODEV); - acpi_processor_errata(pr); /* @@ -2206,9 +2233,27 @@ * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c */ - pr->id = cpu_index++; pr->acpi_id = object.processor.proc_id; + cpu_index = convert_acpiid_to_cpu(pr->acpi_id); + + if ( !cpu0_initialized && (cpu_index == 0xff)) { + /* Handle UP system running SMP kernel, with no LAPIC in MADT */ + cpu_index = 0; + } else if (cpu_index > num_online_cpus()) { + /* + * Extra Processor objects may be enumerated on MP systems with + * less than the max # of CPUs. They should be ignored. + */ + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error getting cpuindex for acpiid 0x%x\n", + pr->acpi_id)); + return_VALUE(-ENODEV); + } + cpu0_initialized = 1; + + pr->id = cpu_index; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, pr->acpi_id)); @@ -2234,7 +2279,6 @@ * (In particular, allocating the IO range for Cardbus) */ request_region(pr->throttling.address, 6, "ACPI CPU throttle"); - request_region(acpi_fadt.xpm_tmr_blk.address, 4, "ACPI timer"); } acpi_processor_get_power_info(pr); @@ -2373,8 +2417,10 @@ pr = (struct acpi_processor *) acpi_driver_data(device); /* Unregister the idle handler when processor #0 is removed. */ - if (pr->id == 0) + if (pr->id == 0) { pm_idle = pm_idle_save; + synchronize_kernel(); + } status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, acpi_processor_notify); diff -Nru a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c --- a/drivers/acpi/resources/rsutils.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/resources/rsutils.c 2004-08-21 23:40:16 -07:00 @@ -289,6 +289,7 @@ acpi_handle handle, struct acpi_buffer *in_buffer) { + struct acpi_parameter_info info; union acpi_operand_object *params[2]; acpi_status status; struct acpi_buffer buffer; @@ -329,10 +330,14 @@ params[0]->common.flags = AOPOBJ_DATA_VALID; params[1] = NULL; + info.node = handle; + info.parameters = params; + info.parameter_type = ACPI_PARAM_ARGS; + /* * Execute the method, no return value */ - status = acpi_ns_evaluate_relative (handle, "_SRS", params, NULL); + status = acpi_ns_evaluate_relative ("_SRS", &info); /* * Clean up and return the status from acpi_ns_evaluate_relative diff -Nru a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c --- a/drivers/acpi/resources/rsxface.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/resources/rsxface.c 2004-08-21 23:40:16 -07:00 @@ -259,7 +259,8 @@ /* Setup pointers */ resource = (struct acpi_resource *) buffer.pointer; - buffer_end = (struct acpi_resource *) ((u8 *) buffer.pointer + buffer.length); + buffer_end = ACPI_CAST_PTR (struct acpi_resource, + ((u8 *) buffer.pointer + buffer.length)); /* Walk the resource list */ diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c --- a/drivers/acpi/scan.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/scan.c 2004-08-21 23:40:16 -07:00 @@ -23,7 +23,8 @@ #define ACPI_BUS_DEVICE_NAME "System Bus" static LIST_HEAD(acpi_device_list); -static spinlock_t acpi_device_lock = SPIN_LOCK_UNLOCKED; +spinlock_t acpi_device_lock = SPIN_LOCK_UNLOCKED; +LIST_HEAD(acpi_wakeup_device_list); static void acpi_device_release(struct kobject * kobj) { @@ -115,9 +116,6 @@ status = acpi_get_handle(device->handle, "_IRC", &handle); if (ACPI_SUCCESS(status)) device->power.flags.inrush_current = 1; - status = acpi_get_handle(device->handle, "_PRW", &handle); - if (ACPI_SUCCESS(status)) - device->power.flags.wake_capable = 1; /* * Enumerate supported power management states @@ -163,6 +161,125 @@ return 0; } +static int +acpi_match_ids ( + struct acpi_device *device, + char *ids) +{ + int error = 0; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + + if (device->flags.hardware_id) + if (strstr(ids, device->pnp.hardware_id)) + goto Done; + + if (device->flags.compatible_ids) { + struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; + int i; + + /* compare multiple _CID entries against driver ids */ + for (i = 0; i < cid_list->count; i++) + { + if (strstr(ids, cid_list->id[i].value)) + goto Done; + } + } + error = -ENOENT; + + Done: + if (buffer.pointer) + acpi_os_free(buffer.pointer); + return error; +} + +static acpi_status +acpi_bus_extract_wakeup_device_power_package ( + struct acpi_device *device, + union acpi_object *package) +{ + int i = 0; + union acpi_object *element = NULL; + + if (!device || !package || (package->package.count < 2)) + return AE_BAD_PARAMETER; + + element = &(package->package.elements[0]); + if (element->type == ACPI_TYPE_PACKAGE) { + if ((element->package.count < 2) || + (element->package.elements[0].type != ACPI_TYPE_LOCAL_REFERENCE) || + (element->package.elements[1].type != ACPI_TYPE_INTEGER)) + return AE_BAD_DATA; + device->wakeup.gpe_device = element->package.elements[0].reference.handle; + device->wakeup.gpe_number = (u32)element->package.elements[1].integer.value; + }else if (element->type == ACPI_TYPE_INTEGER) { + device->wakeup.gpe_number = element->integer.value; + }else + return AE_BAD_DATA; + + element = &(package->package.elements[1]); + if (element->type != ACPI_TYPE_INTEGER) { + return AE_BAD_DATA; + } + device->wakeup.sleep_state = element->integer.value; + + if ((package->package.count - 2) > ACPI_MAX_HANDLES) { + return AE_NO_MEMORY; + } + device->wakeup.resources.count = package->package.count - 2; + for (i=0; i < device->wakeup.resources.count; i++) { + element = &(package->package.elements[i + 2]); + if (element->type != ACPI_TYPE_ANY ) { + return AE_BAD_DATA; + } + + device->wakeup.resources.handles[i] = element->reference.handle; + } + + return AE_OK; +} + +static int +acpi_bus_get_wakeup_device_flags ( + struct acpi_device *device) +{ + acpi_status status = 0; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *package = NULL; + + ACPI_FUNCTION_TRACE("acpi_bus_get_wakeup_flags"); + + /* _PRW */ + status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRW\n")); + goto end; + } + + package = (union acpi_object *) buffer.pointer; + status = acpi_bus_extract_wakeup_device_power_package(device, package); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _PRW package\n")); + goto end; + } + + acpi_os_free(buffer.pointer); + + device->wakeup.flags.valid = 1; + /* Power button, Lid switch always enable wakeup*/ + if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E")) + device->wakeup.flags.run_wake = 1; + + /* TBD: lock */ + INIT_LIST_HEAD(&device->wakeup_list); + spin_lock(&acpi_device_lock); + list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); + spin_unlock(&acpi_device_lock); + +end: + if (ACPI_FAILURE(status)) + device->flags.wake_capable = 0; + return 0; +} /* -------------------------------------------------------------------------- Performance Management @@ -195,30 +312,7 @@ struct acpi_device *device, struct acpi_driver *driver) { - int error = 0; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - - if (device->flags.hardware_id) - if (strstr(driver->ids, device->pnp.hardware_id)) - goto Done; - - if (device->flags.compatible_ids) { - struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; - int i; - - /* compare multiple _CID entries against driver ids */ - for (i = 0; i < cid_list->count; i++) - { - if (strstr(driver->ids, cid_list->id[i].value)) - goto Done; - } - } - error = -ENOENT; - - Done: - if (buffer.pointer) - acpi_os_free(buffer.pointer); - return error; + return acpi_match_ids(device, driver->ids); } @@ -276,6 +370,7 @@ static int acpi_driver_attach(struct acpi_driver * drv) { struct list_head * node, * next; + int count = 0; ACPI_FUNCTION_TRACE("acpi_driver_attach"); @@ -290,6 +385,7 @@ if (!acpi_bus_match(dev, drv)) { if (!acpi_bus_driver_init(dev, drv)) { atomic_inc(&drv->references); + count++; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", drv->name, dev->pnp.bus_id)); } @@ -297,7 +393,7 @@ spin_lock(&acpi_device_lock); } spin_unlock(&acpi_device_lock); - return_VALUE(0); + return_VALUE(count); } static int acpi_driver_detach(struct acpi_driver * drv) @@ -328,28 +424,30 @@ * acpi_bus_register_driver * ------------------------ * Registers a driver with the ACPI bus. Searches the namespace for all - * devices that match the driver's criteria and binds. + * devices that match the driver's criteria and binds. Returns the + * number of devices that were claimed by the driver, or a negative + * error status for failure. */ int acpi_bus_register_driver ( struct acpi_driver *driver) { - int error = 0; + int count; ACPI_FUNCTION_TRACE("acpi_bus_register_driver"); if (acpi_disabled) return_VALUE(-ENODEV); - if (driver) { - spin_lock(&acpi_device_lock); - list_add_tail(&driver->node, &acpi_bus_drivers); - spin_unlock(&acpi_device_lock); - acpi_driver_attach(driver); - } else - error = -EINVAL; + if (!driver) + return_VALUE(-EINVAL); - return_VALUE(error); + spin_lock(&acpi_device_lock); + list_add_tail(&driver->node, &acpi_bus_drivers); + spin_unlock(&acpi_device_lock); + count = acpi_driver_attach(driver); + + return_VALUE(count); } @@ -469,6 +567,11 @@ if (ACPI_SUCCESS(status)) device->flags.power_manageable = 1; + /* Presence of _PRW indicates wake capable */ + status = acpi_get_handle(device->handle, "_PRW", &temp); + if (ACPI_SUCCESS(status)) + device->flags.wake_capable = 1; + /* TBD: Peformance management */ return_VALUE(0); @@ -736,6 +839,16 @@ */ if (device->flags.power_manageable) { result = acpi_bus_get_power_flags(device); + if (result) + goto end; + } + + /* + * Wakeup device management + *----------------------- + */ + if (device->flags.wake_capable) { + result = acpi_bus_get_wakeup_device_flags(device); if (result) goto end; } diff -Nru a/drivers/acpi/sleep/Makefile b/drivers/acpi/sleep/Makefile --- a/drivers/acpi/sleep/Makefile 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/sleep/Makefile 2004-08-21 23:40:16 -07:00 @@ -1,5 +1,5 @@ obj-y := poweroff.o -obj-$(CONFIG_ACPI_SLEEP) += main.o +obj-$(CONFIG_ACPI_SLEEP) += main.o wakeup.o obj-$(CONFIG_ACPI_SLEEP_PROC_FS) += proc.o EXTRA_CFLAGS += $(ACPI_CFLAGS) diff -Nru a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c --- a/drivers/acpi/sleep/main.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/sleep/main.c 2004-08-21 23:40:16 -07:00 @@ -35,16 +35,16 @@ /** * acpi_pm_prepare - Do preliminary suspend work. - * @state: suspend state we're entering. + * @pm_state: suspend state we're entering. * * Make sure we support the state. If we do, and we need it, set the * firmware waking vector and do arch-specific nastiness to get the * wakeup code to the waking vector. */ -static int acpi_pm_prepare(u32 state) +static int acpi_pm_prepare(u32 pm_state) { - u32 acpi_state = acpi_suspend_states[state]; + u32 acpi_state = acpi_suspend_states[pm_state]; if (!sleep_states[acpi_state]) return -EPERM; @@ -52,13 +52,14 @@ /* do we have a wakeup address for S2 and S3? */ /* Here, we support only S4BIOS, those we set the wakeup address */ /* S4OS is only supported for now via swsusp.. */ - if (state == PM_SUSPEND_MEM || state == PM_SUSPEND_DISK) { + if (pm_state == PM_SUSPEND_MEM || pm_state == PM_SUSPEND_DISK) { if (!acpi_wakeup_address) return -EFAULT; acpi_set_firmware_waking_vector( (acpi_physical_address) acpi_wakeup_address); } ACPI_FLUSH_CPU_CACHE(); + acpi_enable_wakeup_device_prep(acpi_state); acpi_enter_sleep_state_prep(acpi_state); return 0; } @@ -66,23 +67,23 @@ /** * acpi_pm_enter - Actually enter a sleep state. - * @state: State we're entering. + * @pm_state: State we're entering. * * Flush caches and go to sleep. For STR or STD, we have to call * arch-specific assembly, which in turn call acpi_enter_sleep_state(). * It's unfortunate, but it works. Please fix if you're feeling frisky. */ -static int acpi_pm_enter(u32 state) +static int acpi_pm_enter(u32 pm_state) { acpi_status status = AE_OK; unsigned long flags = 0; - u32 acpi_state = acpi_suspend_states[state]; + u32 acpi_state = acpi_suspend_states[pm_state]; ACPI_FLUSH_CPU_CACHE(); /* Do arch specific saving of state. */ - if (state > PM_SUSPEND_STANDBY) { + if (pm_state > PM_SUSPEND_STANDBY) { int error = acpi_save_state_mem(); if (error) return error; @@ -90,7 +91,8 @@ local_irq_save(flags); - switch (state) + acpi_enable_wakeup_device(acpi_state); + switch (pm_state) { case PM_SUSPEND_STANDBY: barrier(); @@ -118,7 +120,7 @@ * And, in the case of the latter, the memory image should have already * been loaded from disk. */ - if (state > PM_SUSPEND_STANDBY) + if (pm_state > PM_SUSPEND_STANDBY) acpi_restore_state_mem(); @@ -128,15 +130,18 @@ /** * acpi_pm_finish - Finish up suspend sequence. - * @state: State we're coming out of. + * @pm_state: State we're coming out of. * * This is called after we wake back up (or if entering the sleep state * failed). */ -static int acpi_pm_finish(u32 state) +static int acpi_pm_finish(u32 pm_state) { - acpi_leave_sleep_state(state); + u32 acpi_state = acpi_suspend_states[pm_state]; + + acpi_leave_sleep_state(acpi_state); + acpi_disable_wakeup_device(acpi_state); /* reset firmware waking vector */ acpi_set_firmware_waking_vector((acpi_physical_address) 0); @@ -199,7 +204,7 @@ return 0; printk(KERN_INFO PREFIX "(supports"); - for (i=0; iwakeup.flags.valid) + continue; + spin_unlock(&acpi_device_lock); + if (dev->wakeup.flags.run_wake) + seq_printf(seq, "%4s %4d %8s\n", + dev->pnp.bus_id, (u32) dev->wakeup.sleep_state, + dev->wakeup.state.enabled ? "*enabled" : "*disabled"); + else + seq_printf(seq, "%4s %4d %8s\n", + dev->pnp.bus_id, (u32) dev->wakeup.sleep_state, + dev->wakeup.state.enabled ? "enabled" : "disabled"); + spin_lock(&acpi_device_lock); + } + spin_unlock(&acpi_device_lock); + return 0; +} + +static ssize_t +acpi_system_write_wakeup_device ( + struct file *file, + const char __user *buffer, + size_t count, + loff_t *ppos) +{ + struct list_head * node, * next; + char strbuf[5]; + char str[5] = ""; + int len = count; + + if (len > 4) len = 4; + + if (copy_from_user(strbuf, buffer, len)) + return -EFAULT; + strbuf[len] = '\0'; + sscanf(strbuf, "%s", str); + + spin_lock(&acpi_device_lock); + list_for_each_safe(node, next, &acpi_wakeup_device_list) { + struct acpi_device * dev = container_of(node, struct acpi_device, wakeup_list); + if (!dev->wakeup.flags.valid) + continue; + + if (!strncmp(dev->pnp.bus_id, str, 4)) { + dev->wakeup.state.enabled = dev->wakeup.state.enabled ? 0:1; + break; + } + } + spin_unlock(&acpi_device_lock); + return count; +} + +static int +acpi_system_wakeup_device_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_system_wakeup_device_seq_show, PDE(inode)->data); +} + +static struct file_operations acpi_system_wakeup_device_fops = { + .open = acpi_system_wakeup_device_open_fs, + .read = seq_read, + .write = acpi_system_write_wakeup_device, + .llseek = seq_lseek, + .release = single_release, +}; static struct file_operations acpi_system_sleep_fops = { .open = acpi_system_sleep_open_fs, @@ -388,6 +467,13 @@ S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir); if (entry) entry->proc_fops = &acpi_system_alarm_fops; + + /* 'wakeup device' [R/W]*/ + entry = create_proc_entry(ACPI_SYSTEM_FILE_WAKEUP_DEVICE, + S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir); + if (entry) + entry->proc_fops = &acpi_system_wakeup_device_fops; + return 0; } diff -Nru a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h --- a/drivers/acpi/sleep/sleep.h 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/sleep/sleep.h 2004-08-21 23:40:16 -07:00 @@ -2,3 +2,6 @@ extern u8 sleep_states[]; extern int acpi_suspend (u32 state); +extern void acpi_enable_wakeup_device_prep(u8 sleep_state); +extern void acpi_enable_wakeup_device(u8 sleep_state); +extern void acpi_disable_wakeup_device(u8 sleep_state); diff -Nru a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/acpi/sleep/wakeup.c 2004-08-21 23:40:16 -07:00 @@ -0,0 +1,181 @@ +/* + * wakeup.c - support wakeup devices + */ + +#include +#include +#include +#include +#include +#include +#include "sleep.h" + +#define _COMPONENT ACPI_SYSTEM_COMPONENT +ACPI_MODULE_NAME ("wakeup_devices") + +/** + * acpi_enable_wakeup_device_prep - prepare wakeup devices + * @sleep_state: ACPI state + * Enable all wakup devices power if the devices' wakeup level + * is higher than requested sleep level + */ +extern struct list_head acpi_wakeup_device_list; +extern spinlock_t acpi_device_lock; + +void +acpi_enable_wakeup_device_prep( + u8 sleep_state) +{ + struct list_head * node, * next; + + ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_prep"); + + spin_lock(&acpi_device_lock); + list_for_each_safe(node, next, &acpi_wakeup_device_list) { + struct acpi_device * dev = container_of(node, + struct acpi_device, wakeup_list); + + if (!dev->wakeup.flags.valid || + !dev->wakeup.state.enabled || + (sleep_state > (u32) dev->wakeup.sleep_state)) + continue; + + spin_unlock(&acpi_device_lock); + acpi_enable_wakeup_device_power(dev); + spin_lock(&acpi_device_lock); + } + spin_unlock(&acpi_device_lock); +} + +/** + * acpi_enable_wakeup_device - enable wakeup devices + * @sleep_state: ACPI state + * Enable all wakup devices's GPE + */ +void +acpi_enable_wakeup_device( + u8 sleep_state) +{ + struct list_head * node, * next; + + /* + * Caution: this routine must be invoked when interrupt is disabled + * Refer ACPI2.0: P212 + */ + ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device"); + spin_lock(&acpi_device_lock); + list_for_each_safe(node, next, &acpi_wakeup_device_list) { + struct acpi_device * dev = container_of(node, + struct acpi_device, wakeup_list); + + /* If users want to disable run-wake GPE, + * we only disable it for wake and leave it for runtime + */ + if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { + spin_unlock(&acpi_device_lock); + acpi_set_gpe_type(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_GPE_TYPE_RUNTIME); + /* Re-enable it, since set_gpe_type will disable it */ + acpi_enable_gpe(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_ISR); + spin_lock(&acpi_device_lock); + continue; + } + + if (!dev->wakeup.flags.valid || + !dev->wakeup.state.enabled || + (sleep_state > (u32) dev->wakeup.sleep_state)) + continue; + + spin_unlock(&acpi_device_lock); + /* run-wake GPE has been enabled */ + if (!dev->wakeup.flags.run_wake) + acpi_enable_gpe(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_ISR); + dev->wakeup.state.active = 1; + spin_lock(&acpi_device_lock); + } + spin_unlock(&acpi_device_lock); +} + +/** + * acpi_disable_wakeup_device - disable devices' wakeup capability + * @sleep_state: ACPI state + * Disable all wakup devices's GPE and wakeup capability + */ +void +acpi_disable_wakeup_device ( + u8 sleep_state) +{ + struct list_head * node, * next; + + ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device"); + + spin_lock(&acpi_device_lock); + list_for_each_safe(node, next, &acpi_wakeup_device_list) { + struct acpi_device * dev = container_of(node, + struct acpi_device, wakeup_list); + + if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { + spin_unlock(&acpi_device_lock); + acpi_set_gpe_type(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN); + /* Re-enable it, since set_gpe_type will disable it */ + acpi_enable_gpe(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_NOT_ISR); + spin_lock(&acpi_device_lock); + continue; + } + + if (!dev->wakeup.flags.valid || + !dev->wakeup.state.active || + (sleep_state > (u32) dev->wakeup.sleep_state)) + continue; + + spin_unlock(&acpi_device_lock); + acpi_disable_wakeup_device_power(dev); + /* Never disable run-wake GPE */ + if (!dev->wakeup.flags.run_wake) { + acpi_disable_gpe(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_NOT_ISR); + acpi_clear_gpe(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_NOT_ISR); + } + dev->wakeup.state.active = 0; + spin_lock(&acpi_device_lock); + } + spin_unlock(&acpi_device_lock); +} + +static int __init acpi_wakeup_device_init(void) +{ + struct list_head * node, * next; + + if (acpi_disabled) + return 0; + printk("ACPI wakeup devices: \n"); + + spin_lock(&acpi_device_lock); + list_for_each_safe(node, next, &acpi_wakeup_device_list) { + struct acpi_device * dev = container_of(node, + struct acpi_device, wakeup_list); + + /* In case user doesn't load button driver */ + if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { + spin_unlock(&acpi_device_lock); + acpi_set_gpe_type(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN); + acpi_enable_gpe(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_NOT_ISR); + dev->wakeup.state.enabled = 1; + spin_lock(&acpi_device_lock); + } + printk("%4s ", dev->pnp.bus_id); + } + spin_unlock(&acpi_device_lock); + printk("\n"); + + return 0; +} + +late_initcall(acpi_wakeup_device_init); diff -Nru a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c --- a/drivers/acpi/tables/tbxfroot.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/tables/tbxfroot.c 2004-08-21 23:40:16 -07:00 @@ -115,17 +115,14 @@ * Instance - the non zero instance of the table, allows * support for multiple tables of the same type * Flags - Physical/Virtual support - * ret_buffer - pointer to a structure containing a buffer to - * receive the table + * table_pointer - Where a buffer containing the table is + * returned * * RETURN: Status * - * DESCRIPTION: This function is called to get an ACPI table. The caller - * supplies an out_buffer large enough to contain the entire ACPI - * table. Upon completion - * the out_buffer->Length field will indicate the number of bytes - * copied into the out_buffer->buf_ptr buffer. This table will be - * a complete table including the header. + * DESCRIPTION: This function is called to get an ACPI table. A buffer is + * allocated for the table and returned in table_pointer. + * This table will be a complete table including the header. * ******************************************************************************/ @@ -136,12 +133,11 @@ u32 flags, struct acpi_table_header **table_pointer) { - struct acpi_pointer rsdp_address; - struct acpi_pointer address; acpi_status status; - struct acpi_table_header header; - struct acpi_table_desc table_info; - struct acpi_table_desc rsdt_info; + struct acpi_pointer address; + struct acpi_table_header *header = NULL; + struct acpi_table_desc *table_info = NULL; + struct acpi_table_desc *rsdt_info; u32 table_count; u32 i; u32 j; @@ -152,45 +148,41 @@ /* * Ensure that at least the table manager is initialized. We don't - * require that the entire ACPI subsystem is up for this interface - */ - - /* - * If we have a buffer, we must have a length too + * require that the entire ACPI subsystem is up for this interface. + * If we have a buffer, we must have a length too */ - if ((instance == 0) || - (!signature) || + if ((instance == 0) || + (!signature) || (!table_pointer)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - rsdt_info.pointer = NULL; + /* Ensure that we have a RSDP */ if (!acpi_gbl_RSDP) { /* Get the RSDP */ - status = acpi_os_get_root_pointer (flags, &rsdp_address); + status = acpi_os_get_root_pointer (flags, &address); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n")); return_ACPI_STATUS (AE_NO_ACPI_TABLES); } /* Map and validate the RSDP */ if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { - status = acpi_os_map_memory (rsdp_address.pointer.physical, sizeof (struct rsdp_descriptor), + status = acpi_os_map_memory (address.pointer.physical, sizeof (struct rsdp_descriptor), (void *) &acpi_gbl_RSDP); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } } else { - acpi_gbl_RSDP = rsdp_address.pointer.logical; + acpi_gbl_RSDP = address.pointer.logical; } - /* - * The signature and checksum must both be correct - */ + /* The signature and checksum must both be correct */ + if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { /* Nope, BAD Signature */ @@ -204,10 +196,9 @@ } } - /* Get the RSDT and validate it */ + /* Get the RSDT address via the RSDP */ acpi_tb_get_rsdt_address (&address); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP located at %p, RSDT physical=%8.8X%8.8X \n", acpi_gbl_RSDP, @@ -217,20 +208,40 @@ address.pointer_type |= flags; - status = acpi_tb_get_table (&address, &rsdt_info); + /* Get and validate the RSDT */ + + rsdt_info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc)); + if (!rsdt_info) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + status = acpi_tb_get_table (&address, rsdt_info); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto cleanup; } - status = acpi_tb_validate_rsdt (rsdt_info.pointer); + status = acpi_tb_validate_rsdt (rsdt_info->pointer); if (ACPI_FAILURE (status)) { goto cleanup; } - /* Get the number of table pointers within the RSDT */ + /* Allocate a scratch table header and table descriptor */ - table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info.pointer); + header = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_header)); + if (!header) { + status = AE_NO_MEMORY; + goto cleanup; + } + table_info = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_desc)); + if (!table_info) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Get the number of table pointers within the RSDT */ + + table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info->pointer); address.pointer_type = acpi_gbl_table_flags | flags; /* @@ -241,35 +252,36 @@ /* Get the next table pointer, handle RSDT vs. XSDT */ if (acpi_gbl_RSDP->revision < 2) { - address.pointer.value = (ACPI_CAST_PTR (RSDT_DESCRIPTOR, rsdt_info.pointer))->table_offset_entry[i]; + address.pointer.value = (ACPI_CAST_PTR ( + RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i]; } else { - address.pointer.value = - (ACPI_CAST_PTR (XSDT_DESCRIPTOR, rsdt_info.pointer))->table_offset_entry[i]; + address.pointer.value = (ACPI_CAST_PTR ( + XSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i]; } /* Get the table header */ - status = acpi_tb_get_table_header (&address, &header); + status = acpi_tb_get_table_header (&address, header); if (ACPI_FAILURE (status)) { goto cleanup; } /* Compare table signatures and table instance */ - if (!ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) { + if (!ACPI_STRNCMP (header->signature, signature, ACPI_NAME_SIZE)) { /* An instance of the table was found */ j++; if (j >= instance) { /* Found the correct instance, get the entire table */ - status = acpi_tb_get_table_body (&address, &header, &table_info); + status = acpi_tb_get_table_body (&address, header, table_info); if (ACPI_FAILURE (status)) { goto cleanup; } - *table_pointer = table_info.pointer; + *table_pointer = table_info->pointer; goto cleanup; } } @@ -281,7 +293,15 @@ cleanup: - acpi_os_unmap_memory (rsdt_info.pointer, (acpi_size) rsdt_info.pointer->length); + acpi_os_unmap_memory (rsdt_info->pointer, (acpi_size) rsdt_info->pointer->length); + ACPI_MEM_FREE (rsdt_info); + + if (header) { + ACPI_MEM_FREE (header); + } + if (table_info) { + ACPI_MEM_FREE (table_info); + } return_ACPI_STATUS (status); } @@ -389,14 +409,17 @@ * Flags - Current memory mode (logical vs. * physical addressing) * - * RETURN: Status + * RETURN: Status, RSDP physical address * * DESCRIPTION: search lower 1_mbyte of memory for the root system descriptor * pointer structure. If it is found, set *RSDP to point to it. * - * NOTE: The RSDp must be either in the first 1_k of the Extended - * BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section - * 5.2.2; assertion #421). + * NOTE1: The RSDp must be either in the first 1_k of the Extended + * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) + * Only a 32-bit physical address is necessary. + * + * NOTE2: This function is always available, regardless of the + * initialization state of the rest of ACPI. * ******************************************************************************/ @@ -407,8 +430,8 @@ { u8 *table_ptr; u8 *mem_rover; - u64 phys_addr; - acpi_status status = AE_OK; + u32 physical_address; + acpi_status status; ACPI_FUNCTION_TRACE ("tb_find_rsdp"); @@ -419,36 +442,57 @@ */ if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { /* - * 1) Search EBDA (low memory) paragraphs + * 1a) Get the location of the EBDA */ - status = acpi_os_map_memory ((u64) ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE, + status = acpi_os_map_memory ((acpi_physical_address) ACPI_EBDA_PTR_LOCATION, + ACPI_EBDA_PTR_LENGTH, (void *) &table_ptr); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n", - ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n", + ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); return_ACPI_STATUS (status); } - mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE); - acpi_os_unmap_memory (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE); + ACPI_MOVE_16_TO_32 (&physical_address, table_ptr); + physical_address <<= 4; /* Convert segment to physical address */ + acpi_os_unmap_memory (table_ptr, ACPI_EBDA_PTR_LENGTH); + + /* EBDA present? */ + + if (physical_address > 0x400) { + /* + * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length) + */ + status = acpi_os_map_memory ((acpi_physical_address) physical_address, + ACPI_EBDA_WINDOW_SIZE, + (void *) &table_ptr); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n", + physical_address, ACPI_EBDA_WINDOW_SIZE)); + return_ACPI_STATUS (status); + } - if (mem_rover) { - /* Found it, return the physical address */ + mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_EBDA_WINDOW_SIZE); + acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE); - phys_addr = ACPI_LO_RSDP_WINDOW_BASE; - phys_addr += ACPI_PTR_DIFF (mem_rover,table_ptr); + if (mem_rover) { + /* Found it, return the physical address */ - table_info->physical_address = phys_addr; - return_ACPI_STATUS (AE_OK); + physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr); + + table_info->physical_address = (acpi_physical_address) physical_address; + return_ACPI_STATUS (AE_OK); + } } /* - * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h + * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ - status = acpi_os_map_memory ((u64) ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE, + status = acpi_os_map_memory ((acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE, + ACPI_HI_RSDP_WINDOW_SIZE, (void *) &table_ptr); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n", ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); return_ACPI_STATUS (status); } @@ -459,10 +503,9 @@ if (mem_rover) { /* Found it, return the physical address */ - phys_addr = ACPI_HI_RSDP_WINDOW_BASE; - phys_addr += ACPI_PTR_DIFF (mem_rover, table_ptr); + physical_address = ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr); - table_info->physical_address = phys_addr; + table_info->physical_address = (acpi_physical_address) physical_address; return_ACPI_STATUS (AE_OK); } } @@ -472,19 +515,29 @@ */ else { /* - * 1) Search EBDA (low memory) paragraphs + * 1a) Get the location of the EBDA */ - mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_LO_RSDP_WINDOW_BASE), - ACPI_LO_RSDP_WINDOW_SIZE); - if (mem_rover) { - /* Found it, return the physical address */ + ACPI_MOVE_16_TO_32 (&physical_address, ACPI_EBDA_PTR_LOCATION); + physical_address <<= 4; /* Convert segment to physical address */ - table_info->physical_address = ACPI_TO_INTEGER (mem_rover); - return_ACPI_STATUS (AE_OK); + /* EBDA present? */ + + if (physical_address > 0x400) { + /* + * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length) + */ + mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (physical_address), + ACPI_EBDA_WINDOW_SIZE); + if (mem_rover) { + /* Found it, return the physical address */ + + table_info->physical_address = ACPI_TO_INTEGER (mem_rover); + return_ACPI_STATUS (AE_OK); + } } /* - * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h + * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE), ACPI_HI_RSDP_WINDOW_SIZE); diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c --- a/drivers/acpi/thermal.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/thermal.c 2004-08-21 23:40:16 -07:00 @@ -60,6 +60,7 @@ #define ACPI_THERMAL_NOTIFY_HOT 0xF1 #define ACPI_THERMAL_MODE_ACTIVE 0x00 #define ACPI_THERMAL_MODE_PASSIVE 0x01 +#define ACPI_THERMAL_MODE_CRT 0xff #define ACPI_THERMAL_PATH_POWEROFF "/sbin/poweroff" #define ACPI_THERMAL_MAX_ACTIVE 10 @@ -289,13 +290,6 @@ status = acpi_get_handle(tz->handle, "_SCP", &handle); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); - status = acpi_get_handle(tz->handle, "_PSV", &handle); - if(!ACPI_FAILURE(status)) { - tz->cooling_mode = 1; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n", - mode?"passive":"active")); - return_VALUE(0); - } return_VALUE(-ENODEV); } @@ -899,8 +893,10 @@ struct seq_file *m = (struct seq_file *)file->private_data; struct acpi_thermal *tz = (struct acpi_thermal *)m->private; - char limit_string[25] = {'\0'}; - int critical, hot, passive, active0, active1; + char limit_string[65] = {'\0'}; + int num, critical, hot, passive; + int active[ACPI_THERMAL_MAX_ACTIVE]; + int i = 0; ACPI_FUNCTION_TRACE("acpi_thermal_write_trip_points"); @@ -916,7 +912,11 @@ limit_string[count] = '\0'; - if (sscanf(limit_string, "%d:%d:%d:%d:%d", &critical, &hot, &passive, &active0, &active1) != 5) { + num = sscanf(limit_string, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", + &critical, &hot, &passive, + &active[0], &active[1], &active[2], &active[3], &active[4], + &active[5], &active[6], &active[7], &active[8], &active[9]); + if(!(num >=5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n")); return_VALUE(-EINVAL); } @@ -924,8 +924,11 @@ tz->trips.critical.temperature = CELSIUS_TO_KELVIN(critical); tz->trips.hot.temperature = CELSIUS_TO_KELVIN(hot); tz->trips.passive.temperature = CELSIUS_TO_KELVIN(passive); - tz->trips.active[0].temperature = CELSIUS_TO_KELVIN(active0); - tz->trips.active[1].temperature = CELSIUS_TO_KELVIN(active1); + for (i = 0; i < num - 3; i++) { + if (!(tz->trips.active[i].flags.valid)) + break; + tz->trips.active[i].temperature = CELSIUS_TO_KELVIN(active[i]); + } return_VALUE(count); } @@ -941,12 +944,14 @@ goto end; if (!tz->flags.cooling_mode) { - seq_puts(seq, "\n"); - goto end; + seq_puts(seq, "\n"); } - seq_printf(seq, "cooling mode: %s\n", - tz->cooling_mode?"passive":"active"); + if ( tz->cooling_mode == ACPI_THERMAL_MODE_CRT ) + seq_printf(seq, "cooling mode: critical\n"); + else + seq_printf(seq, "cooling mode: %s\n", + tz->cooling_mode?"passive":"active"); end: return 0; @@ -988,6 +993,8 @@ if (result) return_VALUE(result); + acpi_thermal_check(tz); + return_VALUE(count); } @@ -1225,15 +1232,33 @@ if (result) return_VALUE(result); - /* Set the cooling mode [_SCP] to active cooling (default) */ - result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE); - if (!result) - tz->flags.cooling_mode = 1; - /* Get trip points [_CRT, _PSV, etc.] (required) */ result = acpi_thermal_get_trip_points(tz); if (result) return_VALUE(result); + + /* Set the cooling mode [_SCP] to active cooling (default) */ + result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE); + if (!result) + tz->flags.cooling_mode = 1; + else { + /* Oh,we have not _SCP method. + Generally show cooling_mode by _ACx, _PSV,spec 12.2*/ + tz->flags.cooling_mode = 0; + if ( tz->trips.active[0].flags.valid && tz->trips.passive.flags.valid ) { + if ( tz->trips.passive.temperature > tz->trips.active[0].temperature ) + tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE; + else + tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE; + } else if ( !tz->trips.active[0].flags.valid && tz->trips.passive.flags.valid ) { + tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE; + } else if ( tz->trips.active[0].flags.valid && !tz->trips.passive.flags.valid ) { + tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE; + } else { + /* _ACx and _PSV are optional, but _CRT is required */ + tz->cooling_mode = ACPI_THERMAL_MODE_CRT; + } + } /* Get default polling frequency [_TZP] (optional) */ if (tzp) diff -Nru a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c --- a/drivers/acpi/utilities/utalloc.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/utilities/utalloc.c 2004-08-21 23:40:16 -07:00 @@ -259,8 +259,8 @@ * * FUNCTION: acpi_ut_initialize_buffer * - * PARAMETERS: required_length - Length needed - * Buffer - Buffer to be validated + * PARAMETERS: Buffer - Buffer to be validated + * required_length - Length needed * * RETURN: Status * @@ -603,7 +603,8 @@ * * FUNCTION: acpi_ut_find_allocation * - * PARAMETERS: Allocation - Address of allocated memory + * PARAMETERS: list_id - Memory list to search + * Allocation - Address of allocated memory * * RETURN: A list element if found; NULL otherwise. * @@ -646,7 +647,8 @@ * * FUNCTION: acpi_ut_track_allocation * - * PARAMETERS: Allocation - Address of allocated memory + * PARAMETERS: list_id - Memory list to search + * Allocation - Address of allocated memory * Size - Size of the allocation * alloc_type - MEM_MALLOC or MEM_CALLOC * Component - Component type of caller @@ -733,7 +735,8 @@ * * FUNCTION: acpi_ut_remove_allocation * - * PARAMETERS: Allocation - Address of allocated memory + * PARAMETERS: list_id - Memory list to search + * Allocation - Address of allocated memory * Component - Component type of caller * Module - Source file name of caller * Line - Line number of caller diff -Nru a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c --- a/drivers/acpi/utilities/uteval.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/utilities/uteval.c 2004-08-21 23:40:16 -07:00 @@ -133,7 +133,7 @@ u32 expected_return_btypes, union acpi_operand_object **return_desc) { - union acpi_operand_object *obj_desc; + struct acpi_parameter_info info; acpi_status status; u32 return_btype; @@ -141,9 +141,13 @@ ACPI_FUNCTION_TRACE ("ut_evaluate_object"); + info.node = prefix_node; + info.parameters = NULL; + info.parameter_type = ACPI_PARAM_ARGS; + /* Evaluate the object/method */ - status = acpi_ns_evaluate_relative (prefix_node, path, NULL, &obj_desc); + status = acpi_ns_evaluate_relative (path, &info); if (ACPI_FAILURE (status)) { if (status == AE_NOT_FOUND) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n", @@ -159,7 +163,7 @@ /* Did we get a return object? */ - if (!obj_desc) { + if (!info.return_object) { if (expected_return_btypes) { ACPI_REPORT_METHOD_ERROR ("No object was returned from", prefix_node, path, AE_NOT_EXIST); @@ -172,7 +176,7 @@ /* Map the return object type to the bitmapped type */ - switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + switch (ACPI_GET_OBJECT_TYPE (info.return_object)) { case ACPI_TYPE_INTEGER: return_btype = ACPI_BTYPE_INTEGER; break; @@ -202,17 +206,17 @@ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Type returned from %s was incorrect: %X\n", - path, ACPI_GET_OBJECT_TYPE (obj_desc))); + path, ACPI_GET_OBJECT_TYPE (info.return_object))); /* On error exit, we must delete the return object */ - acpi_ut_remove_reference (obj_desc); + acpi_ut_remove_reference (info.return_object); return_ACPI_STATUS (AE_TYPE); } /* Object type is OK, return it */ - *return_desc = obj_desc; + *return_desc = info.return_object; return_ACPI_STATUS (AE_OK); } diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c --- a/drivers/acpi/utilities/utglobal.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/utilities/utglobal.c 2004-08-21 23:40:16 -07:00 @@ -171,27 +171,40 @@ const u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128}; -const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { - "\\_S0_", - "\\_S1_", - "\\_S2_", - "\\_S3_", - "\\_S4_", - "\\_S5_"}; - -const char *acpi_gbl_highest_dstate_names[4] = { - "_S1D", - "_S2D", - "_S3D", - "_S4D"}; - -/* Strings supported by the _OSI predefined (internal) method */ - -const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = { - "Linux", - "Windows 2000", - "Windows 2001", - "Windows 2001.1"}; +const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = +{ + "\\_S0_", + "\\_S1_", + "\\_S2_", + "\\_S3_", + "\\_S4_", + "\\_S5_" +}; + +const char *acpi_gbl_highest_dstate_names[4] = +{ + "_S1D", + "_S2D", + "_S3D", + "_S4D" +}; + +/* + * Strings supported by the _OSI predefined (internal) method. + * When adding strings, be sure to update ACPI_NUM_OSI_STRINGS. + */ +const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = +{ + "Linux", + "Windows 2000", + "Windows 2001", + "Windows 2001.1", + "Windows 2001 SP0", + "Windows 2001 SP1", + "Windows 2001 SP2", + "Windows 2001 SP3", + "Windows 2001 SP4" +}; /****************************************************************************** @@ -213,7 +226,7 @@ {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, {"_SB_", ACPI_TYPE_DEVICE, NULL}, {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, - {"_TZ_", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_TZ_", ACPI_TYPE_THERMAL, NULL}, {"_REV", ACPI_TYPE_INTEGER, "2"}, {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, {"_GL_", ACPI_TYPE_MUTEX, "0"}, @@ -561,26 +574,37 @@ struct acpi_namespace_node *node = (struct acpi_namespace_node *) object; + /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */ + if (!object) { - return ("NULL NODE"); + return ("NULL"); } - if (object == ACPI_ROOT_OBJECT) + /* Check for Root node */ + + if ((object == ACPI_ROOT_OBJECT) || + (object == acpi_gbl_root_node)) { - node = acpi_gbl_root_node; + return ("\"\\\" "); } + /* Descriptor must be a namespace node */ + if (node->descriptor != ACPI_DESC_TYPE_NAMED) { - return ("****"); + return ("####"); } + /* Name must be a valid ACPI name */ + if (!acpi_ut_valid_acpi_name (* (u32 *) node->name.ascii)) { - return ("----"); + return ("????"); } + /* Return the name */ + return (node->name.ascii); } @@ -783,10 +807,6 @@ ACPI_FUNCTION_TRACE ("ut_init_globals"); - /* Runtime configuration */ - - acpi_gbl_create_osi_method = TRUE; - acpi_gbl_all_methods_serialized = FALSE; /* Memory allocation and cache lists */ @@ -880,6 +900,7 @@ /* Hardware oriented */ acpi_gbl_events_initialized = FALSE; + acpi_gbl_system_awake_and_running = TRUE; /* Namespace */ diff -Nru a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c --- a/drivers/acpi/utilities/utxface.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/acpi/utilities/utxface.c 2004-08-21 23:40:16 -07:00 @@ -157,9 +157,8 @@ } } - /* - * Enable ACPI mode - */ + /* Enable ACPI mode */ + if (!(flags & ACPI_NO_ACPI_ENABLE)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n")); @@ -173,7 +172,21 @@ } /* - * Initialize ACPI Event handling + * Install the default op_region handlers. These are installed unless + * other handlers have already been installed via the + * install_address_space_handler interface. + */ + if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n")); + + status = acpi_ev_install_region_handlers (); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + + /* + * Initialize ACPI Event handling (Fixed and General Purpose) * * NOTE: We must have the hardware AND events initialized before we can execute * ANY control methods SAFELY. Any control method can require ACPI hardware @@ -182,18 +195,18 @@ if (!(flags & ACPI_NO_EVENT_INIT)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI events\n")); - status = acpi_ev_initialize (); + status = acpi_ev_initialize_events (); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } } - /* Install the SCI handler, Global Lock handler, and GPE handlers */ + /* Install the SCI handler and Global Lock handler */ if (!(flags & ACPI_NO_HANDLER_INIT)) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL/GPE handlers\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL handlers\n")); - status = acpi_ev_handler_initialize (); + status = acpi_ev_install_xrupt_handlers (); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -226,18 +239,16 @@ /* - * Install the default op_region handlers. These are installed unless - * other handlers have already been installed via the - * install_address_space_handler interface. + * Run all _REG methods * - * NOTE: This will cause _REG methods to be run. Any objects accessed + * NOTE: Any objects accessed * by the _REG methods will be automatically initialized, even if they * contain executable AML (see call to acpi_ns_initialize_objects below). */ if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Executing _REG op_region methods\n")); - status = acpi_ev_init_address_spaces (); + status = acpi_ev_initialize_op_regions (); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -249,7 +260,7 @@ * objects: operation_regions, buffer_fields, Buffers, and Packages. */ if (!(flags & ACPI_NO_OBJECT_INIT)) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Objects\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Completing Initialization of ACPI Objects\n")); status = acpi_ns_initialize_objects (); if (ACPI_FAILURE (status)) { diff -Nru a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c --- a/drivers/block/scsi_ioctl.c 2004-08-21 23:40:16 -07:00 +++ b/drivers/block/scsi_ioctl.c 2004-08-21 23:40:16 -07:00 @@ -154,7 +154,6 @@ safe_for_write(WRITE_12), safe_for_write(WRITE_VERIFY_12), safe_for_write(WRITE_16), - safe_for_write(WRITE_BUFFER), safe_for_write(WRITE_LONG), }; unsigned char type = cmd_type[cmd[0]]; diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h --- a/include/acpi/acconfig.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acconfig.h 2004-08-21 23:40:16 -07:00 @@ -64,11 +64,21 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20040326 +#define ACPI_CA_VERSION 0x20040715 + +/* + * OS name, used for the _OS object. The _OS object is essentially obsolete, + * but there is a large base of ASL/AML code in existing machines that check + * for the string below. The use of this string usually guarantees that + * the ASL will execute down the most tested code path. Also, there is some + * code that will not execute the _OSI method unless _OS matches the string + * below. Therefore, change this string at your own risk. + */ +#define ACPI_OS_NAME "Microsoft Windows NT" /* Maximum objects in the various object caches */ -#define ACPI_MAX_STATE_CACHE_DEPTH 64 /* State objects for stacks */ +#define ACPI_MAX_STATE_CACHE_DEPTH 64 /* State objects */ #define ACPI_MAX_PARSE_CACHE_DEPTH 96 /* Parse tree objects */ #define ACPI_MAX_EXTPARSE_CACHE_DEPTH 64 /* Parse tree objects */ #define ACPI_MAX_OBJECT_CACHE_DEPTH 64 /* Interpreter operand objects */ @@ -152,10 +162,11 @@ /* Constants used in searching for the RSDP in low memory */ -#define ACPI_LO_RSDP_WINDOW_BASE 0 /* Physical Address */ -#define ACPI_HI_RSDP_WINDOW_BASE 0xE0000 /* Physical Address */ -#define ACPI_LO_RSDP_WINDOW_SIZE 0x400 -#define ACPI_HI_RSDP_WINDOW_SIZE 0x20000 +#define ACPI_EBDA_PTR_LOCATION 0x0000040E /* Physical Address */ +#define ACPI_EBDA_PTR_LENGTH 2 +#define ACPI_EBDA_WINDOW_SIZE 1024 +#define ACPI_HI_RSDP_WINDOW_BASE 0x000E0000 /* Physical Address */ +#define ACPI_HI_RSDP_WINDOW_SIZE 0x00020000 #define ACPI_RSDP_SCAN_STEP 16 /* Operation regions */ @@ -187,7 +198,7 @@ /* Number of strings associated with the _OSI reserved method */ -#define ACPI_NUM_OSI_STRINGS 4 +#define ACPI_NUM_OSI_STRINGS 9 /****************************************************************************** diff -Nru a/include/acpi/acdebug.h b/include/acpi/acdebug.h --- a/include/acpi/acdebug.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acdebug.h 2004-08-21 23:40:16 -07:00 @@ -106,6 +106,10 @@ * dbcmds - debug commands and output routines */ +acpi_status +acpi_db_disassemble_method ( + char *name); + void acpi_db_display_table_info ( char *table_arg); @@ -163,6 +167,10 @@ void acpi_db_set_scope ( char *name); + +acpi_status +acpi_db_sleep ( + char *object_arg); void acpi_db_find_references ( diff -Nru a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h --- a/include/acpi/acdisasm.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acdisasm.h 2004-08-21 23:40:16 -07:00 @@ -52,6 +52,13 @@ #define BLOCK_BRACE 2 #define BLOCK_COMMA_LIST 4 +struct acpi_external_list +{ + char *path; + struct acpi_external_list *next; +}; + +extern struct acpi_external_list *acpi_gbl_external_list; extern const char *acpi_gbl_io_decode[2]; extern const char *acpi_gbl_word_decode[4]; extern const char *acpi_gbl_consume_decode[2]; @@ -398,5 +405,13 @@ u32 length, u32 level); + +/* + * dmutils + */ + +void +acpi_dm_add_to_external_list ( + char *path); #endif /* __ACDISASM_H__ */ diff -Nru a/include/acpi/acdispat.h b/include/acpi/acdispat.h --- a/include/acpi/acdispat.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acdispat.h 2004-08-21 23:40:16 -07:00 @@ -437,8 +437,7 @@ struct acpi_namespace_node *method_node, u8 *aml_start, u32 aml_length, - union acpi_operand_object **params, - union acpi_operand_object **return_obj_desc, + struct acpi_parameter_info *info, u32 pass_number); acpi_status diff -Nru a/include/acpi/acevents.h b/include/acpi/acevents.h --- a/include/acpi/acevents.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acevents.h 2004-08-21 23:40:16 -07:00 @@ -46,11 +46,11 @@ acpi_status -acpi_ev_initialize ( +acpi_ev_initialize_events ( void); acpi_status -acpi_ev_handler_initialize ( +acpi_ev_install_xrupt_handlers ( void); @@ -111,12 +111,27 @@ acpi_status acpi_ev_walk_gpe_list ( - ACPI_GPE_CALLBACK gpe_walk_callback); + ACPI_GPE_CALLBACK gpe_walk_callback, + u32 flags); u8 acpi_ev_valid_gpe_event ( struct acpi_gpe_event_info *gpe_event_info); +acpi_status +acpi_ev_update_gpe_enable_masks ( + struct acpi_gpe_event_info *gpe_event_info, + u8 type); + +acpi_status +acpi_ev_enable_gpe ( + struct acpi_gpe_event_info *gpe_event_info, + u8 write_to_hardware); + +acpi_status +acpi_ev_disable_gpe ( + struct acpi_gpe_event_info *gpe_event_info); + struct acpi_gpe_event_info * acpi_ev_get_gpe_event_info ( acpi_handle gpe_device, @@ -139,6 +154,11 @@ acpi_ev_delete_gpe_block ( struct acpi_gpe_block_info *gpe_block); +acpi_status +acpi_ev_delete_gpe_handlers ( + struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block); + u32 acpi_ev_gpe_dispatch ( struct acpi_gpe_event_info *gpe_event_info, @@ -148,12 +168,25 @@ acpi_ev_gpe_detect ( struct acpi_gpe_xrupt_info *gpe_xrupt_list); +acpi_status +acpi_ev_set_gpe_type ( + struct acpi_gpe_event_info *gpe_event_info, + u8 type); + +acpi_status +acpi_ev_check_for_wake_only_gpe ( + struct acpi_gpe_event_info *gpe_event_info); + /* * Evregion - Address Space handling */ acpi_status -acpi_ev_init_address_spaces ( +acpi_ev_install_region_handlers ( + void); + +acpi_status +acpi_ev_initialize_op_regions ( void); acpi_status @@ -181,6 +214,19 @@ acpi_ev_detach_region ( union acpi_operand_object *region_obj, u8 acpi_ns_is_locked); + +acpi_status +acpi_ev_install_space_handler ( + struct acpi_namespace_node *node, + acpi_adr_space_type space_id, + acpi_adr_space_handler handler, + acpi_adr_space_setup setup, + void *context); + +acpi_status +acpi_ev_execute_reg_methods ( + struct acpi_namespace_node *node, + acpi_adr_space_type space_id); acpi_status acpi_ev_execute_reg_method ( diff -Nru a/include/acpi/acexcep.h b/include/acpi/acexcep.h --- a/include/acpi/acexcep.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acexcep.h 2004-08-21 23:40:16 -07:00 @@ -95,8 +95,9 @@ #define AE_LOGICAL_ADDRESS (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL) #define AE_ABORT_METHOD (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL) #define AE_SAME_HANDLER (acpi_status) (0x001D | AE_CODE_ENVIRONMENTAL) +#define AE_WAKE_ONLY_GPE (acpi_status) (0x001E | AE_CODE_ENVIRONMENTAL) -#define AE_CODE_ENV_MAX 0x001D +#define AE_CODE_ENV_MAX 0x001E /* * Programmer exceptions @@ -222,7 +223,8 @@ "AE_NO_GLOBAL_LOCK", "AE_LOGICAL_ADDRESS", "AE_ABORT_METHOD", - "AE_SAME_HANDLER" + "AE_SAME_HANDLER", + "AE_WAKE_ONLY_GPE" }; char const *acpi_gbl_exception_names_pgm[] = diff -Nru a/include/acpi/acglobal.h b/include/acpi/acglobal.h --- a/include/acpi/acglobal.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acglobal.h 2004-08-21 23:40:16 -07:00 @@ -46,15 +46,17 @@ /* - * Ensure that the globals are actually defined only once. + * Ensure that the globals are actually defined and initialized only once. * - * The use of these defines allows a single list of globals (here) in order + * The use of these macros allows a single list of globals (here) in order * to simplify maintenance of the code. */ #ifdef DEFINE_ACPI_GLOBALS #define ACPI_EXTERN +#define ACPI_INIT_GLOBAL(a,b) a=b #else #define ACPI_EXTERN extern +#define ACPI_INIT_GLOBAL(a,b) a #endif /* @@ -64,6 +66,7 @@ ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; + /***************************************************************************** * * Debug support @@ -79,15 +82,42 @@ extern u32 acpi_gbl_nesting_level; + /***************************************************************************** * - * Runtime configuration + * Runtime configuration (static defaults that can be overriden at runtime) * ****************************************************************************/ -ACPI_EXTERN u8 acpi_gbl_create_osi_method; -ACPI_EXTERN u8 acpi_gbl_all_methods_serialized; -ACPI_EXTERN u8 acpi_gbl_leave_wake_gpes_disabled; +/* + * Enable "slack" in the AML interpreter? Default is FALSE, and the + * interpreter strictly follows the ACPI specification. Setting to TRUE + * allows the interpreter to forgive certain bad AML constructs. + */ +ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_enable_interpeter_slack, FALSE); + +/* + * Automatically serialize ALL control methods? Default is FALSE, meaning + * to use the Serialized/not_serialized method flags on a per method basis. + * Only change this if the ASL code is poorly written and cannot handle + * reentrancy even though methods are marked "not_serialized". + */ +ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_all_methods_serialized, FALSE); + +/* + * Create the predefined _OSI method in the namespace? Default is TRUE + * because ACPI CA is fully compatible with other ACPI implementations. + * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. + */ +ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_create_osi_method, TRUE); + +/* + * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and + * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only + * be enabled just before going to sleep. + */ +ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_leave_wake_gpes_disabled, TRUE); + /***************************************************************************** * @@ -102,7 +132,6 @@ * * These tables are single-table only; meaning that there can be at most one * of each in the system. Each global points to the actual table. - * */ ACPI_EXTERN u32 acpi_gbl_table_flags; ACPI_EXTERN u32 acpi_gbl_rsdt_table_count; @@ -170,6 +199,7 @@ ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; ACPI_EXTERN u8 acpi_gbl_global_lock_present; ACPI_EXTERN u8 acpi_gbl_events_initialized; +ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; extern u8 acpi_gbl_shutdown; extern u32 acpi_gbl_startup_flags; diff -Nru a/include/acpi/achware.h b/include/acpi/achware.h --- a/include/acpi/achware.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/achware.h 2004-08-21 23:40:16 -07:00 @@ -114,15 +114,7 @@ /* GPE support */ acpi_status -acpi_hw_enable_gpe ( - struct acpi_gpe_event_info *gpe_event_info); - -void -acpi_hw_enable_gpe_for_wakeup ( - struct acpi_gpe_event_info *gpe_event_info); - -acpi_status -acpi_hw_disable_gpe ( +acpi_hw_write_gpe_enable_reg ( struct acpi_gpe_event_info *gpe_event_info); acpi_status @@ -130,10 +122,6 @@ struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block); -void -acpi_hw_disable_gpe_for_wakeup ( - struct acpi_gpe_event_info *gpe_event_info); - acpi_status acpi_hw_clear_gpe ( struct acpi_gpe_event_info *gpe_event_info); @@ -149,12 +137,26 @@ acpi_event_status *event_status); acpi_status -acpi_hw_prepare_gpes_for_sleep ( - void); +acpi_hw_disable_all_gpes ( + u32 flags); + +acpi_status +acpi_hw_enable_all_runtime_gpes ( + u32 flags); acpi_status -acpi_hw_restore_gpes_on_wake ( - void); +acpi_hw_enable_all_wakeup_gpes ( + u32 flags); + +acpi_status +acpi_hw_enable_runtime_gpe_block ( + struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block); + +acpi_status +acpi_hw_enable_wakeup_gpe_block ( + struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block); /* ACPI Timer prototypes */ diff -Nru a/include/acpi/acinterp.h b/include/acpi/acinterp.h --- a/include/acpi/acinterp.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acinterp.h 2004-08-21 23:40:16 -07:00 @@ -118,6 +118,12 @@ */ acpi_status +acpi_ex_common_buffer_setup ( + union acpi_operand_object *obj_desc, + u32 buffer_length, + u32 *datum_count); + +acpi_status acpi_ex_extract_from_field ( union acpi_operand_object *obj_desc, void *buffer, @@ -240,8 +246,8 @@ u8 acpi_ex_do_logical_op ( u16 opcode, - acpi_integer operand0, - acpi_integer operand1); + union acpi_operand_object *obj_desc, + union acpi_operand_object *obj_desc2); acpi_integer acpi_ex_do_math_op ( @@ -563,8 +569,11 @@ acpi_ex_store_object_to_node ( union acpi_operand_object *source_desc, struct acpi_namespace_node *node, - struct acpi_walk_state *walk_state); + struct acpi_walk_state *walk_state, + u8 implicit_conversion); +#define ACPI_IMPLICIT_CONVERSION TRUE +#define ACPI_NO_IMPLICIT_CONVERSION FALSE /* * exstoren diff -Nru a/include/acpi/aclocal.h b/include/acpi/aclocal.h --- a/include/acpi/aclocal.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/aclocal.h 2004-08-21 23:40:16 -07:00 @@ -189,8 +189,6 @@ u8 type; /* Type associated with this name */ u16 owner_id; union acpi_name_union name; /* ACPI Name, always 4 chars per ACPI spec */ - - union acpi_operand_object *object; /* Pointer to attached ACPI object (optional) */ struct acpi_namespace_node *child; /* First child */ struct acpi_namespace_node *peer; /* Next peer*/ @@ -211,10 +209,8 @@ #define ANOBJ_METHOD_LOCAL 0x10 #define ANOBJ_METHOD_NO_RETVAL 0x20 #define ANOBJ_METHOD_SOME_NO_RETVAL 0x40 - #define ANOBJ_IS_BIT_OFFSET 0x80 - /* * ACPI Table Descriptor. One per ACPI table */ @@ -309,16 +305,31 @@ * ****************************************************************************/ -/* Information about a GPE, one per each GPE in an array */ +/* Dispatch info for each GPE -- either a method or handler, cannot be both */ -struct acpi_gpe_event_info +struct acpi_handler_info { - struct acpi_namespace_node *method_node; /* Method node for this GPE level */ - acpi_gpe_handler handler; /* Address of handler, if any */ + acpi_event_handler address; /* Address of handler, if any */ void *context; /* Context to be passed to handler */ + struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ +}; + +union acpi_gpe_dispatch_info +{ + struct acpi_namespace_node *method_node; /* Method node for this GPE level */ + struct acpi_handler_info *handler; +}; + +/* + * Information about a GPE, one per each GPE in an array. + * NOTE: Important to keep this struct as small as possible. + */ +struct acpi_gpe_event_info +{ + union acpi_gpe_dispatch_info dispatch; /* Either Method or Handler */ struct acpi_gpe_register_info *register_info; /* Backpointer to register info */ - u8 flags; /* Level or Edge */ - u8 bit_mask; /* This GPE within the register */ + u8 flags; /* Misc info about this GPE */ + u8 register_bit; /* This GPE bit within the register */ }; /* Information about a GPE register pair, one per each status/enable pair in an array */ @@ -327,9 +338,8 @@ { struct acpi_generic_address status_address; /* Address of status reg */ struct acpi_generic_address enable_address; /* Address of enable reg */ - u8 status; /* Current value of status reg */ - u8 enable; /* Current value of enable reg */ - u8 wake_enable; /* Mask of bits to keep enabled when sleeping */ + u8 enable_for_wake; /* GPEs to keep enabled when sleeping */ + u8 enable_for_run; /* GPEs to keep enabled when running */ u8 base_gpe_number; /* Base GPE number for this register */ }; @@ -339,6 +349,7 @@ */ struct acpi_gpe_block_info { + struct acpi_namespace_node *node; struct acpi_gpe_block_info *previous; struct acpi_gpe_block_info *next; struct acpi_gpe_xrupt_info *xrupt_block; /* Backpointer to interrupt block */ @@ -502,7 +513,7 @@ struct acpi_walk_state *walk_state_list; /* Head of list of walk_states for this thread */ union acpi_operand_object *acquired_mutex_list; /* List of all currently acquired mutexes */ u32 thread_id; /* Running thread ID */ - u16 current_sync_level; /* Mutex Sync (nested acquire) level */ + u8 current_sync_level; /* Mutex Sync (nested acquire) level */ }; diff -Nru a/include/acpi/acmacros.h b/include/acpi/acmacros.h --- a/include/acpi/acmacros.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acmacros.h 2004-08-21 23:40:16 -07:00 @@ -53,6 +53,9 @@ #define ACPI_LOBYTE(l) ((u8)(u16)(l)) #define ACPI_HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF)) +#define ACPI_SET_BIT(target,bit) ((target) |= (bit)) +#define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit)) + #if ACPI_MACHINE_WIDTH == 16 @@ -97,7 +100,7 @@ * printf() format helpers */ -/* Split 64-bit integer into two 32-bit values. use with %8,8_x%8.8X */ +/* Split 64-bit integer into two 32-bit values. Use with %8.8X%8.8X */ #define ACPI_FORMAT_UINT64(i) ACPI_HIDWORD(i),ACPI_LODWORD(i) diff -Nru a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h --- a/include/acpi/acnamesp.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acnamesp.h 2004-08-21 23:40:16 -07:00 @@ -278,33 +278,25 @@ acpi_status acpi_ns_evaluate_by_handle ( - struct acpi_namespace_node *prefix_node, - union acpi_operand_object **params, - union acpi_operand_object **return_object); + struct acpi_parameter_info *info); acpi_status acpi_ns_evaluate_by_name ( char *pathname, - union acpi_operand_object **params, - union acpi_operand_object **return_object); + struct acpi_parameter_info *info); acpi_status acpi_ns_evaluate_relative ( - struct acpi_namespace_node *prefix_node, char *pathname, - union acpi_operand_object **params, - union acpi_operand_object **return_object); + struct acpi_parameter_info *info); acpi_status acpi_ns_execute_control_method ( - struct acpi_namespace_node *method_node, - union acpi_operand_object **params, - union acpi_operand_object **return_obj_desc); + struct acpi_parameter_info *info); acpi_status acpi_ns_get_object_value ( - struct acpi_namespace_node *object_node, - union acpi_operand_object **return_obj_desc); + struct acpi_parameter_info *info); /* diff -Nru a/include/acpi/acobject.h b/include/acpi/acobject.h --- a/include/acpi/acobject.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acobject.h 2004-08-21 23:40:16 -07:00 @@ -204,13 +204,14 @@ struct acpi_object_mutex { ACPI_OBJECT_COMMON_HEADER - u16 sync_level; - u16 acquisition_depth; - struct acpi_thread_state *owner_thread; - void *semaphore; + u8 sync_level; /* 0-15, specified in Mutex() call */ + u16 acquisition_depth; /* Allow multiple Acquires, same thread */ + struct acpi_thread_state *owner_thread; /* Current owner of the mutex */ + void *semaphore; /* Actual OS synchronization object */ union acpi_operand_object *prev; /* Link for list of acquired mutexes */ union acpi_operand_object *next; /* Link for list of acquired mutexes */ - struct acpi_namespace_node *node; /* containing object */ + struct acpi_namespace_node *node; /* Containing namespace node */ + u8 original_sync_level; /* Owner's original sync level (0-15) */ }; @@ -220,7 +221,7 @@ u8 space_id; union acpi_operand_object *handler; /* Handler for region access */ - struct acpi_namespace_node *node; /* containing object */ + struct acpi_namespace_node *node; /* Containing namespace node */ union acpi_operand_object *next; u32 length; acpi_physical_address address; diff -Nru a/include/acpi/acparser.h b/include/acpi/acparser.h --- a/include/acpi/acparser.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acparser.h 2004-08-21 23:40:16 -07:00 @@ -73,9 +73,7 @@ acpi_status acpi_psx_execute ( - struct acpi_namespace_node *method_node, - union acpi_operand_object **params, - union acpi_operand_object **return_obj_desc); + struct acpi_parameter_info *info); /****************************************************************************** diff -Nru a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h --- a/include/acpi/acpi_bus.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acpi_bus.h 2004-08-21 23:40:16 -07:00 @@ -157,7 +157,8 @@ u32 suprise_removal_ok:1; u32 power_manageable:1; u32 performance_manageable:1; - u32 reserved:21; + u32 wake_capable:1; /* Wakeup(_PRW) supported? */ + u32 reserved:20; }; @@ -203,10 +204,8 @@ u32 explicit_get:1; /* _PSC present? */ u32 power_resources:1; /* Power resources */ u32 inrush_current:1; /* Serialize Dx->D0 */ - u32 wake_capable:1; /* Wakeup supported? */ - u32 wake_enabled:1; /* Enabled for wakeup */ u32 power_removed:1; /* Optimize Dx->D0 */ - u32 reserved:26; + u32 reserved:28; }; struct acpi_device_power_state { @@ -250,6 +249,25 @@ struct acpi_device_perf_state *states; }; +/* Wakeup Management */ +struct acpi_device_wakeup_flags { + u8 valid:1; /* Can successfully enable wakeup? */ + u8 run_wake:1; /* Run-Wake GPE devices */ +}; + +struct acpi_device_wakeup_state { + u8 enabled:1; + u8 active:1; +}; + +struct acpi_device_wakeup { + acpi_handle gpe_device; + acpi_integer gpe_number;; + acpi_integer sleep_state; + struct acpi_handle_list resources; + struct acpi_device_wakeup_state state; + struct acpi_device_wakeup_flags flags; +}; /* Device */ @@ -258,11 +276,13 @@ struct acpi_device *parent; struct list_head children; struct list_head node; + struct list_head wakeup_list; struct list_head g_list; struct acpi_device_status status; struct acpi_device_flags flags; struct acpi_device_pnp pnp; struct acpi_device_power power; + struct acpi_device_wakeup wakeup; struct acpi_device_perf performance; struct acpi_device_dir dir; struct acpi_device_ops ops; diff -Nru a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h --- a/include/acpi/acpi_drivers.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acpi_drivers.h 2004-08-21 23:40:16 -07:00 @@ -81,7 +81,8 @@ -------------------------------------------------------------------------- */ #ifdef CONFIG_ACPI_POWER - +int acpi_enable_wakeup_device_power (struct acpi_device *dev); +int acpi_disable_wakeup_device_power (struct acpi_device *dev); int acpi_power_get_inferred_state (struct acpi_device *device); int acpi_power_transition (struct acpi_device *device, int state); #endif diff -Nru a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h --- a/include/acpi/acpiosxf.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acpiosxf.h 2004-08-21 23:40:16 -07:00 @@ -189,13 +189,13 @@ acpi_status acpi_os_install_interrupt_handler ( u32 gsi, - OSD_HANDLER service_routine, + acpi_osd_handler service_routine, void *context); acpi_status acpi_os_remove_interrupt_handler ( - u32 interrupt_number, - OSD_HANDLER service_routine); + u32 gsi, + acpi_osd_handler service_routine); /* @@ -209,7 +209,7 @@ acpi_status acpi_os_queue_for_execution ( u32 priority, - OSD_EXECUTION_CALLBACK function, + acpi_osd_exec_callback function, void *context); void @@ -262,25 +262,28 @@ /* * Platform and hardware-independent PCI configuration space access + * Note: Can't use "Register" as a parameter, changed to "Reg" -- + * certain compilers complain. */ acpi_status acpi_os_read_pci_configuration ( struct acpi_pci_id *pci_id, - u32 register, + u32 reg, void *value, u32 width); acpi_status acpi_os_write_pci_configuration ( struct acpi_pci_id *pci_id, - u32 register, + u32 reg, acpi_integer value, u32 width); /* * Interim function needed for PCI IRQ routing */ + void acpi_os_derive_pci_id( acpi_handle rhandle, diff -Nru a/include/acpi/acpixf.h b/include/acpi/acpixf.h --- a/include/acpi/acpixf.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acpixf.h 2004-08-21 23:40:16 -07:00 @@ -296,7 +296,7 @@ acpi_handle gpe_device, u32 gpe_number, u32 type, - acpi_gpe_handler handler, + acpi_event_handler address, void *context); acpi_status @@ -312,7 +312,7 @@ acpi_remove_gpe_handler ( acpi_handle gpe_device, u32 gpe_number, - acpi_gpe_handler handler); + acpi_event_handler address); acpi_status acpi_enable_event ( @@ -332,6 +332,12 @@ acpi_get_event_status ( u32 event, acpi_event_status *event_status); + +acpi_status +acpi_set_gpe_type ( + acpi_handle gpe_device, + u32 gpe_number, + u8 type); acpi_status acpi_enable_gpe ( diff -Nru a/include/acpi/acstruct.h b/include/acpi/acstruct.h --- a/include/acpi/acstruct.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/acstruct.h 2004-08-21 23:40:16 -07:00 @@ -69,13 +69,14 @@ struct acpi_walk_state { u8 data_type; /* To differentiate various internal objs MUST BE FIRST!*/\ + u8 walk_type; acpi_owner_id owner_id; /* Owner of objects created during the walk */ u8 last_predicate; /* Result of last predicate */ + u8 reserved; /* For alignment */ u8 current_result; /* */ u8 next_op_info; /* Info about next_op */ u8 num_operands; /* Stack pointer for Operands[] array */ u8 return_used; - u8 walk_type; u16 opcode; /* Current AML opcode */ u8 scope_depth; u8 reserved1; @@ -91,7 +92,8 @@ struct acpi_namespace_node arguments[ACPI_METHOD_NUM_ARGS]; /* Control method arguments */ union acpi_operand_object **caller_return_desc; union acpi_generic_state *control_state; /* List of control states (nested IFs) */ - struct acpi_namespace_node *deferred_node; /* Used when executing deferred opcodes */ + struct acpi_namespace_node *deferred_node; /* Used when executing deferred opcodes */ + struct acpi_gpe_event_info *gpe_event_info; /* Info for GPE (_Lxx/_Exx methods only */ struct acpi_namespace_node local_variables[ACPI_METHOD_NUM_LOCALS]; /* Control method locals */ struct acpi_namespace_node *method_call_node; /* Called method Node*/ union acpi_parse_object *method_call_op; /* method_call Op if running a method */ @@ -198,6 +200,23 @@ } mid; }; + + +/* Internal method parameter list */ + +struct acpi_parameter_info +{ + struct acpi_namespace_node *node; + union acpi_operand_object **parameters; + union acpi_operand_object *return_object; + u8 parameter_type; + u8 return_object_type; +}; + +/* Types for parameter_type above */ + +#define ACPI_PARAM_ARGS 0 +#define ACPI_PARAM_GPE 1 #endif diff -Nru a/include/acpi/actbl.h b/include/acpi/actbl.h --- a/include/acpi/actbl.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/actbl.h 2004-08-21 23:40:16 -07:00 @@ -288,19 +288,6 @@ }; -/* - * High performance timer - */ -struct hpet_table -{ - ACPI_TABLE_HEADER_DEF - u32 hardware_id; - u32 base_address [3]; - u8 hpet_number; - u16 clock_tick; - u8 attributes; -}; - #pragma pack() @@ -343,5 +330,21 @@ #include "actbl1.h" /* Acpi 1.0 table definitions */ #include "actbl2.h" /* Acpi 2.0 table definitions */ + +#pragma pack(1) +/* + * High performance timer + */ +struct hpet_table +{ + ACPI_TABLE_HEADER_DEF + u32 hardware_id; + struct acpi_generic_address base_address; + u8 hpet_number; + u16 clock_tick; + u8 attributes; +}; + +#pragma pack() #endif /* __ACTBL_H__ */ diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h --- a/include/acpi/actypes.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/actypes.h 2004-08-21 23:40:16 -07:00 @@ -557,34 +557,56 @@ #define ACPI_GPE_MAX 0xFF #define ACPI_NUM_GPE 256 +#define ACPI_GPE_ENABLE 0 +#define ACPI_GPE_DISABLE 1 + + /* * GPE info flags - Per GPE - * +---------+-+-+-+ - * |Bits 8:3 |2|1|0| - * +---------+-+-+-+ - * | | | | - * | | | +- Edge or Level Triggered - * | | +--- Type: Wake or Runtime - * | +----- Enabled for wake? - * +-------- - */ -#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 1 -#define ACPI_GPE_LEVEL_TRIGGERED (u8) 1 -#define ACPI_GPE_EDGE_TRIGGERED (u8) 0 - -#define ACPI_GPE_TYPE_MASK (u8) 2 -#define ACPI_GPE_TYPE_WAKE (u8) 2 -#define ACPI_GPE_TYPE_RUNTIME (u8) 0 /* Default */ - -#define ACPI_GPE_ENABLE_MASK (u8) 4 -#define ACPI_GPE_ENABLED (u8) 4 -#define ACPI_GPE_DISABLED (u8) 0 /* Default */ + * +-+-+-+---+---+-+ + * |7|6|5|4:3|2:1|0| + * +-+-+-+---+---+-+ + * | | | | | | + * | | | | | +--- Interrupt type: Edge or Level Triggered + * | | | | +--- Type: Wake-only, Runtime-only, or wake/runtime + * | | | +--- Type of dispatch -- to method, handler, or none + * | | +--- Enabled for runtime? + * | +--- Enabled for wake? + * +--- System state when GPE ocurred (running/waking) + */ +#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01 +#define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x01 +#define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00 + +#define ACPI_GPE_TYPE_MASK (u8) 0x06 +#define ACPI_GPE_TYPE_WAKE_RUN (u8) 0x06 +#define ACPI_GPE_TYPE_WAKE (u8) 0x02 +#define ACPI_GPE_TYPE_RUNTIME (u8) 0x04 /* Default */ + +#define ACPI_GPE_DISPATCH_MASK (u8) 0x18 +#define ACPI_GPE_DISPATCH_HANDLER (u8) 0x08 +#define ACPI_GPE_DISPATCH_METHOD (u8) 0x10 +#define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00 /* Default */ + +#define ACPI_GPE_RUN_ENABLE_MASK (u8) 0x20 +#define ACPI_GPE_RUN_ENABLED (u8) 0x20 +#define ACPI_GPE_RUN_DISABLED (u8) 0x00 /* Default */ + +#define ACPI_GPE_WAKE_ENABLE_MASK (u8) 0x40 +#define ACPI_GPE_WAKE_ENABLED (u8) 0x40 +#define ACPI_GPE_WAKE_DISABLED (u8) 0x00 /* Default */ + +#define ACPI_GPE_ENABLE_MASK (u8) 0x60 /* Both run/wake */ + +#define ACPI_GPE_SYSTEM_MASK (u8) 0x80 +#define ACPI_GPE_SYSTEM_RUNNING (u8) 0x80 +#define ACPI_GPE_SYSTEM_WAKING (u8) 0x00 /* * Flags for GPE and Lock interfaces */ -#define ACPI_EVENT_WAKE_ENABLE 0x2 -#define ACPI_EVENT_WAKE_DISABLE 0x2 +#define ACPI_EVENT_WAKE_ENABLE 0x2 /* acpi_gpe_enable */ +#define ACPI_EVENT_WAKE_DISABLE 0x2 /* acpi_gpe_disable */ #define ACPI_NOT_ISR 0x1 #define ACPI_ISR 0x0 @@ -592,9 +614,10 @@ /* Notify types */ -#define ACPI_SYSTEM_NOTIFY 0 -#define ACPI_DEVICE_NOTIFY 1 -#define ACPI_MAX_NOTIFY_HANDLER_TYPE 1 +#define ACPI_SYSTEM_NOTIFY 0x1 +#define ACPI_DEVICE_NOTIFY 0x2 +#define ACPI_ALL_NOTIFY 0x3 +#define ACPI_MAX_NOTIFY_HANDLER_TYPE 0x3 #define ACPI_MAX_SYS_NOTIFY 0x7f @@ -775,11 +798,11 @@ */ typedef u32 -(ACPI_SYSTEM_XFACE *OSD_HANDLER) ( +(ACPI_SYSTEM_XFACE *acpi_osd_handler) ( void *context); typedef void -(ACPI_SYSTEM_XFACE *OSD_EXECUTION_CALLBACK) ( +(ACPI_SYSTEM_XFACE *acpi_osd_exec_callback) ( void *context); /* @@ -790,10 +813,6 @@ void *context); typedef -void (*acpi_gpe_handler) ( - void *context); - -typedef void (*acpi_notify_handler) ( acpi_handle device, u32 value, @@ -880,6 +899,7 @@ #define ACPI_VALID_HID 0x0004 #define ACPI_VALID_UID 0x0008 #define ACPI_VALID_CID 0x0010 +#define ACPI_VALID_SXDS 0x0020 #define ACPI_COMMON_OBJ_INFO \ @@ -899,12 +919,12 @@ { ACPI_COMMON_OBJ_INFO; - u8 highest_dstates[4]; /* _sx_d values 0xFF indicates not valid */ u32 valid; /* Indicates which fields below are valid */ u32 current_status; /* _STA value */ acpi_integer address; /* _ADR value if any */ struct acpi_device_id hardware_id; /* _HID value if any */ struct acpi_device_id unique_id; /* _UID value if any */ + u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */ struct acpi_compatible_id_list compatibility_id; /* List of _CIDs if any */ }; diff -Nru a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h --- a/include/acpi/platform/acenv.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/platform/acenv.h 2004-08-21 23:40:16 -07:00 @@ -152,12 +152,8 @@ #define COMPILER_DEPENDENT_INT64 long long #define COMPILER_DEPENDENT_UINT64 unsigned long long - -/* Name of host operating system (returned by the _OS_ namespace object) */ - -#define ACPI_OS_NAME "Intel ACPI/CA Core Subsystem" - -/* This macro is used to tag functions as "printf-like" because +/* + * This macro is used to tag functions as "printf-like" because * some compilers can catch printf format string problems. MSVC * doesn't, so this is proprocessed away. */ diff -Nru a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h --- a/include/acpi/platform/aclinux.h 2004-08-21 23:40:16 -07:00 +++ b/include/acpi/platform/aclinux.h 2004-08-21 23:40:16 -07:00 @@ -44,8 +44,6 @@ #ifndef __ACLINUX_H__ #define __ACLINUX_H__ -#define ACPI_OS_NAME "Linux" - #define ACPI_USE_SYSTEM_CLIBRARY #define ACPI_USE_DO_WHILE_0 diff -Nru a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h --- a/include/asm-i386/acpi.h 2004-08-21 23:40:16 -07:00 +++ b/include/asm-i386/acpi.h 2004-08-21 23:40:16 -07:00 @@ -102,6 +102,12 @@ :"0"(n_hi), "1"(n_lo)) +/* + * Refer Intel ACPI _PDC support document for bit definitions + */ +#define ACPI_PDC_EST_CAPABILITY_SMP 0xa +#define ACPI_PDC_EST_CAPABILITY_MSR 0x1 + #ifdef CONFIG_ACPI_BOOT extern int acpi_lapic; extern int acpi_ioapic; @@ -177,6 +183,8 @@ extern void acpi_reserve_bootmem(void); #endif /*CONFIG_ACPI_SLEEP*/ + +extern u8 x86_acpiid_to_apicid[]; #endif /*__KERNEL__*/ diff -Nru a/include/asm-i386/smp.h b/include/asm-i386/smp.h --- a/include/asm-i386/smp.h 2004-08-21 23:40:16 -07:00 +++ b/include/asm-i386/smp.h 2004-08-21 23:40:16 -07:00 @@ -43,6 +43,7 @@ extern void zap_low_mappings (void); #define MAX_APICID 256 +extern u8 x86_cpu_to_apicid[]; /* * This function is needed by all SMP systems. It must _always_ be valid diff -Nru a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h --- a/include/asm-ia64/acpi.h 2004-08-21 23:40:16 -07:00 +++ b/include/asm-ia64/acpi.h 2004-08-21 23:40:16 -07:00 @@ -105,6 +105,8 @@ extern int __initdata nid_to_pxm_map[MAX_NUMNODES]; #endif +extern u16 ia64_acpiid_to_sapicid[]; + #endif /*__KERNEL__*/ #endif /*_ASM_ACPI_H*/ diff -Nru a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h --- a/include/asm-x86_64/acpi.h 2004-08-21 23:40:16 -07:00 +++ b/include/asm-x86_64/acpi.h 2004-08-21 23:40:16 -07:00 @@ -159,6 +159,8 @@ extern int acpi_disabled; extern int acpi_pci_disabled; +extern u8 x86_acpiid_to_apicid[]; + #endif /*__KERNEL__*/ #endif /*_ASM_ACPI_H*/ diff -Nru a/init/main.c b/init/main.c --- a/init/main.c 2004-08-21 23:40:16 -07:00 +++ b/init/main.c 2004-08-21 23:40:16 -07:00 @@ -93,6 +93,11 @@ extern void populate_rootfs(void); extern void driver_init(void); extern void prepare_namespace(void); +#ifdef CONFIG_ACPI +extern void acpi_early_init(void); +#else +static inline acpi_early_init() { } +#endif #ifdef CONFIG_TC extern void tc_init(void); @@ -529,6 +534,8 @@ proc_root_init(); #endif check_bugs(); + + acpi_early_init(); /* before LAPIC and SMP init */ /* * We count on the initial thread going ok