http://linux-acpi.bkbits.net/linux-acpi-test-mm len.brown@intel.com|ChangeSet|20041026063454|63344 len.brown # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/10/26 13:34:06-07:00 akpm@bix.(none) # Merge http://linux-acpi.bkbits.net/linux-acpi-test-mm # into bix.(none):/usr/src/bk-acpi # # drivers/acpi/thermal.c # 2004/10/26 13:34:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/acpi/Kconfig # 2004/10/26 13:34:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/Makefile # 2004/10/26 13:34:02-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/Makefile # 2004/10/26 13:34:02-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/acpi/boot.c # 2004/10/26 13:34:02-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/Makefile # 2004/10/26 13:34:02-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/26 02:34:54-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-test # into intel.com:/home/lenb/bk/26-latest-mm # # include/acpi/acpi_bus.h # 2004/10/26 02:34:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/Makefile # 2004/10/26 02:34:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/Kconfig # 2004/10/26 02:34:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/Makefile # 2004/10/26 02:34:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/Makefile # 2004/10/26 02:34:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/acpi/boot.c # 2004/10/26 02:34:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/Makefile # 2004/10/26 02:34:49-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/26 02:25:28-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/26-stable-dev # into intel.com:/home/lenb/src/26-latest-dev # # arch/i386/pci/irq.c # 2004/10/26 02:25:25-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/acpi/boot.c # 2004/10/26 02:25:25-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/26 00:20:08-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-ref # into intel.com:/home/lenb/src/26-latest-dev # # drivers/acpi/thermal.c # 2004/10/26 00:19:56-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/25 23:30:02-04:00 len.brown@intel.com # [ACPI] Move the "only do this once" stuff from acpi_register_gsi() into # eisa_set_level(). # # Signed-off-by: Bjorn Helgaas # Signed-off-by: Andrew Morton # Signed-off-by: Len Brown # # arch/i386/pci/irq.c # 2004/09/30 12:39:46-04:00 len.brown@intel.com +8 -1 # Import patch eisa_set_level_irq.txt # # arch/i386/kernel/acpi/boot.c # 2004/09/30 12:39:46-04:00 len.brown@intel.com +1 -7 # Import patch eisa_set_level_irq.txt # # ChangeSet # 2004/10/25 22:44:31-04:00 len.brown@intel.com # [ACPI] ACPI_VIDEO is EXPERIMENTAL # # drivers/acpi/Kconfig # 2004/10/25 22:44:21-04:00 len.brown@intel.com +1 -0 # ACPI_VIDEO is EXPERIMENTAL # # ChangeSet # 2004/10/25 19:06:17-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi # # drivers/acpi/thermal.c # 2004/10/25 19:06:13-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/Makefile # 2004/10/25 19:06:13-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/Makefile # 2004/10/25 19:06:13-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/Makefile # 2004/10/25 19:06:13-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/25 18:25:59-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/26-stable-dev # into intel.com:/home/lenb/src/26-latest-dev # # drivers/acpi/scan.c # 2004/10/25 18:25:52-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/25 18:21:05-04:00 len.brown@intel.com # [ACPI] Extensions for Display Adapters (Bruno Ducrot) # http://bugme.osdl.org/show_bug.cgi?id=1944 # # Signed-off-by: Luming Yu # Signed-off-by: Len Brown # # drivers/acpi/video.c # 2004/10/25 11:41:27-04:00 len.brown@intel.com +1962 -0 # Import patch video_extension2.patch # # include/acpi/acpi_bus.h # 2004/10/25 11:38:43-04:00 len.brown@intel.com +2 -0 # Import patch video_extension2.patch # # drivers/acpi/video.c # 2004/10/25 11:41:27-04:00 len.brown@intel.com +0 -0 # BitKeeper file /home/lenb/src/26-stable-dev/drivers/acpi/video.c # # drivers/acpi/scan.c # 2004/10/25 11:38:43-04:00 len.brown@intel.com +6 -1 # Import patch video_extension2.patch # # drivers/acpi/Makefile # 2004/10/25 11:38:43-04:00 len.brown@intel.com +1 -0 # Import patch video_extension2.patch # # drivers/acpi/Kconfig # 2004/10/25 11:38:43-04:00 len.brown@intel.com +14 -0 # Import patch video_extension2.patch # # Documentation/power/video_extension.txt # 2004/10/25 11:38:43-04:00 len.brown@intel.com +34 -0 # Import patch video_extension2.patch # # Documentation/power/video_extension.txt # 2004/10/25 11:38:43-04:00 len.brown@intel.com +0 -0 # BitKeeper file /home/lenb/src/26-stable-dev/Documentation/power/video_extension.txt # # ChangeSet # 2004/10/25 17:54:56-04:00 len.brown@intel.com # [ACPI] ACPI_CUSTOM_DSDT for IA64 too # # Signed-off-by: Anil S Keshavamurthy # Signed-off-by: Len Brown # # drivers/acpi/ibm_acpi.c # 2004/10/23 03:43:34-04:00 len.brown@intel.com +20 -17 # Import patch ibm-acpi-0.7.patch # # Documentation/ibm-acpi.txt # 2004/10/23 03:43:48-04:00 len.brown@intel.com +4 -4 # Import patch ibm-acpi-0.7.patch # # ChangeSet # 2004/10/23 02:53:12-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-test # into intel.com:/home/lenb/bk/26-latest-mm # # sound/drivers/mpu401/mpu401.c # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # include/asm-x86_64/mpspec.h # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # include/asm-x86_64/acpi.h # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # include/asm-i386/mpspec.h # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/char/ipmi/ipmi_si_intf.c # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/processor.c # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/Makefile # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/Kconfig # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/Makefile # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/mpparse.c # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/io_apic.c # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/Kconfig # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/ia64/kernel/acpi.c # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/mpparse.c # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/acpi/boot.c # 2004/10/23 02:47:28-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/10/23 02:47:27-04:00 len.brown@intel.com +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/23 02:47:27-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/23 02:16:04-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/26-latest-dominik # into intel.com:/home/lenb/src/26-latest-dev # # drivers/acpi/processor.c # 2004/10/23 02:16:00-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c # 2004/10/23 02:16:00-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/cpu/cpufreq/powernow-k8.c # 2004/10/23 02:16:00-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/23 02:13:06-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/26-stable-dev # into intel.com:/home/lenb/src/26-latest-dev # # include/acpi/acpiosxf.h # 2004/10/23 02:13:02-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/thermal.c # 2004/10/23 02:13:02-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/osl.c # 2004/10/23 02:13:02-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/mach-es7000/es7000plat.c # 2004/10/23 02:13:02-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/mpparse.c # 2004/10/23 02:13:02-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/23 01:21:11-04:00 len.brown@intel.com # Cset exclude: jason.davis@unisys.com[torvalds]|ChangeSet|20040914144015|50315 # # arch/i386/mach-es7000/es7000.h # 2004/10/23 01:20:53-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/i386/mach-es7000/es7000plat.c # 2004/10/23 01:20:52-04:00 len.brown@intel.com +0 -0 # Exclude # # ChangeSet # 2004/10/22 23:44:20-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/26-stable-acpica # into intel.com:/home/lenb/src/26-stable-dev # # drivers/acpi/osl.c # 2004/10/22 23:44:17-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/22 23:12:41-04:00 len.brown@intel.com # [ACPI] fix build warning # # drivers/acpi/executer/exstore.c # 2004/10/22 23:12:35-04:00 len.brown@intel.com +1 -1 # build warning # # ChangeSet # 2004/10/22 22:56:02-04:00 len.brown@intel.com # [ACPI] ACPICA 20041015 from Bob Moore # # Signed-off-by: Len Brown # # Note: ACPI CA is currently undergoing an in-depth and # complete formal evaluation to test/verify the following # areas. Other suggestions are welcome. This will result in # an increase in the frequency of releases and the number # of bug fixes in the next few months. # # - Functional tests for all ASL/AML operators # - All implicit/explicit type conversions # - Bit fields and operation regions # - 64-bit math support and 32-bit-only "truncated" math support # - Exceptional conditions, both compiler and interpreter # - Dynamic object deletion and memory leaks # - ACPI 3.0 support when implemented # - External interfaces to the ACPI subsystem # # Fixed two alignment issues on 64-bit platforms - # within debug statements in acpi_ev_gpe_detect and # acpi_ev_create_gpe_block. Removed references to the # Address field within the non-aligned ACPI generic address # structure. # # Fixed a problem in the Increment and Decrement operators # where incorrect operand resolution could result in the # inadvertent modification of the original integer when the # integer is passed into another method as an argument and # the arg is then incremented/decremented. # # Fixed a problem in the FromBCD operator where the upper # 32-bits of a 64-bit BCD number were truncated during # conversion. # # Fixed a problem in the ToDecimal operator where the length # of the resulting string could be set incorrectly too long # if the input operand was a Buffer object. # # Fixed a problem in the Logical operators (LLess, # etc.) where a NULL byte (0) within a buffer would # prematurely terminate a compare between buffer objects. # # Added a check for string overflow (>200 characters as per # the ACPI specification) during the Concatenate operator # with two string operands. # # include/acpi/platform/acenv.h # 2004/10/22 22:22:10-04:00 len.brown@intel.com +2 -0 # ACPICA 20041015 # # include/acpi/acutils.h # 2004/10/22 22:22:09-04:00 len.brown@intel.com +6 -0 # ACPICA 20041015 # # include/acpi/acconfig.h # 2004/10/22 22:22:10-04:00 len.brown@intel.com +1 -1 # ACPICA 20041015 # # drivers/acpi/utilities/utobject.c # 2004/10/22 22:22:15-04:00 len.brown@intel.com +15 -17 # ACPICA 20041015 # # drivers/acpi/parser/psopcode.c # 2004/10/22 22:22:14-04:00 len.brown@intel.com +1 -1 # ACPICA 20041015 # # drivers/acpi/hardware/hwregs.c # 2004/10/22 22:22:14-04:00 len.brown@intel.com +2 -2 # ACPICA 20041015 # # drivers/acpi/executer/exstore.c # 2004/10/22 22:22:15-04:00 len.brown@intel.com +11 -2 # ACPICA 20041015 # # drivers/acpi/executer/exresop.c # 2004/10/22 22:22:15-04:00 len.brown@intel.com +4 -3 # ACPICA 20041015 # # drivers/acpi/executer/exoparg2.c # 2004/10/22 22:22:15-04:00 len.brown@intel.com +2 -2 # ACPICA 20041015 # # drivers/acpi/executer/exoparg1.c # 2004/10/22 22:22:15-04:00 len.brown@intel.com +59 -29 # ACPICA 20041015 # # drivers/acpi/executer/exmisc.c # 2004/10/22 22:22:15-04:00 len.brown@intel.com +12 -5 # ACPICA 20041015 # # drivers/acpi/executer/exconvrt.c # 2004/10/22 22:22:15-04:00 len.brown@intel.com +7 -3 # ACPICA 20041015 # # drivers/acpi/events/evgpeblk.c # 2004/10/22 22:22:14-04:00 len.brown@intel.com +1 -3 # ACPICA 20041015 # # drivers/acpi/events/evgpe.c # 2004/10/22 22:22:14-04:00 len.brown@intel.com +2 -7 # ACPICA 20041015 # # drivers/acpi/dispatcher/dsutils.c # 2004/10/22 22:22:15-04:00 len.brown@intel.com +1 -1 # ACPICA 20041015 # # drivers/acpi/dispatcher/dsmthdat.c # 2004/10/22 22:22:15-04:00 len.brown@intel.com +2 -2 # ACPICA 20041015 # # ChangeSet # 2004/10/22 22:55:32-04:00 len.brown@intel.com # [ACPI] fix build warning in tables/tbget.c # # drivers/acpi/tables/tbget.c # 2004/10/22 22:55:25-04:00 len.brown@intel.com +1 -1 # fix build warning # # ChangeSet # 2004/10/22 22:10:26-04:00 len.brown@intel.com # [ACPI] ACPICA 20041006 from Bob Moore # # Signed-off-by: Len Brown # # Implemented support for the ACPI 3.0 Timer operator. This # ASL function implements a 64-bit timer with 100 nanosecond # granularity. # # Defined a new OSL interface, acpi_os_get_timer. This # interface is used to implement the ACPI 3.0 Timer # operator. This allows the host OS to implement the timer # with the best clock available. Also, it keeps the core # subsystem out of the clock handling business, since the # host OS (usually) performs this function. # # Fixed an alignment issue on 64-bit platforms. The # hw_low_level_read/write() functions use a 64-bit address # which is part of the packed ACPI Generic Address # Structure. Since the structure is non-aligned, the # alignment macros are now used to extract the address to # a local variable before use. # # Fixed a problem where the ToInteger operator assumed all # input strings were hexadecimal. The operator now handles # both decimal strings and hex strings (prefixed with "0x"). # # Fixed a problem where the string length in the string # object created as a result of the internal ConvertToString # procedure could be incorrect. This potentially affected # all implicit conversions and also the ToDecimalString and # ToHexString operators. # # Fixed two problems in the ToString operator. If the # length parameter was zero, an incorrect string object was # created and the value of the input length parameter was # inadvertently changed from zero to Ones. # # Fixed a problem where the optional ResourceSource string # in the ExtendedIRQ resource macro was ignored. # # Simplified the interfaces to the internal division # functions, reducing code size and complexity. # # include/acpi/acutils.h # 2004/10/22 22:09:21-04:00 len.brown@intel.com +7 -3 # ACPICA 20041015 # # include/acpi/actypes.h # 2004/10/22 22:09:21-04:00 len.brown@intel.com +5 -1 # ACPICA 20041015 # # include/acpi/acinterp.h # 2004/10/22 22:09:21-04:00 len.brown@intel.com +4 -6 # ACPICA 20041015 # # include/acpi/acconfig.h # 2004/10/22 22:09:22-04:00 len.brown@intel.com +1 -1 # ACPICA 20041015 # # drivers/acpi/utilities/utmisc.c # 2004/10/22 22:09:29-04:00 len.brown@intel.com +41 -61 # ACPICA 20041015 # # drivers/acpi/utilities/utmath.c # 2004/10/22 22:09:29-04:00 len.brown@intel.com +22 -21 # ACPICA 20041015 # # drivers/acpi/utilities/utdelete.c # 2004/10/22 22:09:29-04:00 len.brown@intel.com +7 -2 # ACPICA 20041015 # # drivers/acpi/resources/rscalc.c # 2004/10/22 22:09:28-04:00 len.brown@intel.com +47 -65 # ACPICA 20041015 # # drivers/acpi/parser/psutils.c # 2004/10/22 22:09:28-04:00 len.brown@intel.com +10 -15 # ACPICA 20041015 # # drivers/acpi/hardware/hwtimer.c # 2004/10/22 22:09:28-04:00 len.brown@intel.com +8 -11 # ACPICA 20041015 # # drivers/acpi/hardware/hwregs.c # 2004/10/22 22:09:28-04:00 len.brown@intel.com +24 -10 # ACPICA 20041015 # # drivers/acpi/executer/exutils.c # 2004/10/22 22:09:28-04:00 len.brown@intel.com +8 -10 # ACPICA 20041015 # # drivers/acpi/executer/exresop.c # 2004/10/22 22:09:28-04:00 len.brown@intel.com +4 -7 # ACPICA 20041015 # # drivers/acpi/executer/exregion.c # 2004/10/22 22:09:28-04:00 len.brown@intel.com +1 -1 # ACPICA 20041015 # # drivers/acpi/executer/exoparg2.c # 2004/10/22 22:09:28-04:00 len.brown@intel.com +29 -22 # ACPICA 20041015 # # drivers/acpi/executer/exoparg1.c # 2004/10/22 22:09:28-04:00 len.brown@intel.com +8 -9 # ACPICA 20041015 # # drivers/acpi/executer/exmisc.c # 2004/10/22 22:09:29-04:00 len.brown@intel.com +6 -8 # ACPICA 20041015 # # drivers/acpi/executer/exconvrt.c # 2004/10/22 22:09:29-04:00 len.brown@intel.com +18 -53 # ACPICA 20041015 # # drivers/acpi/dispatcher/dswexec.c # 2004/10/22 22:09:28-04:00 len.brown@intel.com +3 -1 # ACPICA 20041015 # # ChangeSet # 2004/10/22 22:00:01-04:00 len.brown@intel.com # [ACPI] place-holder for ACPI 3.0 acpi_os_get_timer() # # drivers/acpi/osl.c # 2004/10/22 21:59:54-04:00 len.brown@intel.com +23 -0 # acpi_os_get_timer place-holder # # ChangeSet # 2004/10/22 18:07:16-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi # # arch/x86_64/Kconfig # 2004/10/22 18:07:11-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/10/22 18:07:11-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/22 16:17:02-04:00 len.brown@intel.com # [ACPI] ACPICA 20040924 from Bob Moore # # Signed-off-by: Len Brown # # Added a new OSL interface, acpi_os_get_timer. This # interface implements a 64-bit monotonic timer in 100 # nanosecond units. # # Implemented support for the ACPI 3.0 Timer operator. # This 64-bit timer utilizes the timer provided by the # acpi_os_get_timer interface. # # include/acpi/amlcode.h # 2004/10/22 16:16:07-04:00 len.brown@intel.com +14 -11 # ACPICA 20040924 # # include/acpi/acpiosxf.h # 2004/10/22 16:16:08-04:00 len.brown@intel.com +1 -1 # ACPICA 20040924 # # include/acpi/aclocal.h # 2004/10/22 16:16:08-04:00 len.brown@intel.com +1 -1 # ACPICA 20040924 # # include/acpi/acinterp.h # 2004/10/22 16:16:07-04:00 len.brown@intel.com +4 -0 # ACPICA 20040924 # # include/acpi/acconfig.h # 2004/10/22 16:16:08-04:00 len.brown@intel.com +1 -1 # ACPICA 20040924 # # drivers/acpi/parser/psopcode.c # 2004/10/22 16:16:10-04:00 len.brown@intel.com +12 -5 # ACPICA 20040924 # # drivers/acpi/executer/exoparg1.c # 2004/10/22 16:16:11-04:00 len.brown@intel.com +63 -0 # ACPICA 20040924 # # drivers/acpi/dispatcher/dswexec.c # 2004/10/22 16:16:11-04:00 len.brown@intel.com +13 -12 # ACPICA 20040924 # # ChangeSet # 2004/10/22 16:12:02-04:00 len.brown@intel.com # [ACPI] acpi_os_sleep() now takes a single 64-bit value in [ms] # # Signed-off-by: Len Brown # # drivers/acpi/osl.c # 2004/10/22 16:11:56-04:00 len.brown@intel.com +2 -2 # acpi_os_sleep() now takes a single 64-bit value in [ms] # # ChangeSet # 2004/10/22 15:39:52-04:00 len.brown@intel.com # [ACPI] ACPICA 20040922 from Bob Moore # # Signed-off-by: Len Brown # # Fixed a problem with the implementation of the LNot() # operator where "Ones" was not returned for the TRUE # case. Changed the code to return Ones instead of (!Arg) # which was usually 1. This change affects iASL constant # folding for this operator also. # # Fixed a problem in acpi_ut_initialize_buffer where an # existing buffer was not initialized properly -- Now zero # the entire buffer in this case where the buffer already # exists. # # Changed the interface to acpi_os_sleep from (UINT32 # Seconds, UINT32 Milliseconds) to simply (ACPI_INTEGER # Milliseconds). This simplifies all related code # considerably. This requires changes/updates to all OS # interface layers (OSLs.) # # Implemented a new external interface, # acpi_install_exception_handler, to allow a system exception # handler to be installed. This handler is invoked upon # any run-time exception that occurs during control method # execution. # # Added support for the DSDT in acpi_tb_find_table. This # allows the DataTableRegion() operator to access the local # copy of the DSDT. # # include/acpi/actypes.h # 2004/10/22 15:38:55-04:00 len.brown@intel.com +4 -0 # ACPICA 20040922 # # include/acpi/acpixf.h # 2004/10/22 15:38:55-04:00 len.brown@intel.com +9 -0 # ACPICA 20040922 # # include/acpi/acpiosxf.h # 2004/10/22 15:38:55-04:00 len.brown@intel.com +5 -2 # ACPICA 20040922 # # include/acpi/acinterp.h # 2004/10/22 15:38:55-04:00 len.brown@intel.com +1 -1 # ACPICA 20040922 # # include/acpi/acglobal.h # 2004/10/22 15:38:55-04:00 len.brown@intel.com +1 -0 # ACPICA 20040922 # # include/acpi/acconfig.h # 2004/10/22 15:38:55-04:00 len.brown@intel.com +1 -1 # ACPICA 20040922 # # drivers/acpi/utilities/utglobal.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +1 -0 # ACPICA 20040922 # # drivers/acpi/utilities/utalloc.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +8 -7 # ACPICA 20040922 # # drivers/acpi/tables/tbxfroot.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +22 -5 # ACPICA 20040922 # # drivers/acpi/tables/tbget.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +3 -0 # ACPICA 20040922 # # drivers/acpi/namespace/nsutils.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +27 -26 # ACPICA 20040922 # # drivers/acpi/namespace/nssearch.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +26 -23 # ACPICA 20040922 # # drivers/acpi/namespace/nsnames.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +2 -1 # ACPICA 20040922 # # drivers/acpi/namespace/nsload.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +6 -5 # ACPICA 20040922 # # drivers/acpi/namespace/nsinit.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +14 -13 # ACPICA 20040922 # # drivers/acpi/namespace/nseval.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +37 -55 # ACPICA 20040922 # # drivers/acpi/namespace/nsdumpdv.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +6 -5 # ACPICA 20040922 # # drivers/acpi/namespace/nsdump.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +32 -29 # ACPICA 20040922 # # drivers/acpi/namespace/nsaccess.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +9 -5 # ACPICA 20040922 # # drivers/acpi/executer/exsystem.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +2 -3 # ACPICA 20040922 # # drivers/acpi/executer/exstore.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +15 -9 # ACPICA 20040922 # # drivers/acpi/executer/exoparg1.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +8 -2 # ACPICA 20040922 # # drivers/acpi/executer/exdump.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +89 -84 # ACPICA 20040922 # # drivers/acpi/events/evxface.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +45 -0 # ACPICA 20040922 # # drivers/acpi/dispatcher/dswexec.c # 2004/10/22 15:38:58-04:00 len.brown@intel.com +11 -0 # ACPICA 20040922 # # ChangeSet # 2004/10/22 15:33:45-04:00 len.brown@intel.com # [ACPI] ACPICA 20040827 update from Bob Moore # # Signed-off-by: Len Brown # # Implemented support for implicit object conversion in # the non-numeric logical operators (LEqual, LGreater, # LGreaterEqual, LLess, LLessEqual, and LNotEqual.) Any # combination of Integers/Strings/Buffers may now be used; # the second operand is implicitly converted on the fly to # match the type of the first operand. For example: # # LEqual (Source1, Source2) # # Source1 and Source2 must each evaluate to an integer, a # string, or a buffer. The data type of Source1 dictates the # required type of Source2. Source2 is implicitly converted # if necessary to match the type of Source1. # # Updated and corrected the behavior of the string # conversion support. The rules concerning conversion of # buffers to strings (according to the ACPI specification) # are as follows: # # ToDecimalString - explicit byte-wise conversion of buffer # to string of decimal values (0-255) separated by commas. # # ToHexString - explicit byte-wise conversion of buffer to # string of hex values (0-FF) separated by commas. # # ToString - explicit byte-wise conversion of buffer to # string. Byte-by-byte copy with no transform except NULL # terminated. Any other implicit buffer-to-string conversion # # byte-wise conversion of buffer to string of hex values # (0-FF) separated by spaces. # # Fixed a problem in acpi_ns_get_pathname_length where the # returned length was one byte too short in the case of a # node in the root scope. This could cause a fault during # debug output. # # include/acpi/amlresrc.h # 2004/10/22 15:30:48-04:00 len.brown@intel.com +2 -2 # ACPICA 20040827 # # include/acpi/amlcode.h # 2004/10/22 15:30:48-04:00 len.brown@intel.com +13 -12 # ACPICA 20040827 # # include/acpi/acutils.h # 2004/10/22 15:30:48-04:00 len.brown@intel.com +4 -0 # ACPICA 20040827 # # include/acpi/actypes.h # 2004/10/22 15:30:48-04:00 len.brown@intel.com +7 -2 # ACPICA 20040827 # # include/acpi/acobject.h # 2004/10/22 15:30:48-04:00 len.brown@intel.com +4 -1 # ACPICA 20040827 # # include/acpi/acinterp.h # 2004/10/22 15:30:48-04:00 len.brown@intel.com +23 -9 # ACPICA 20040827 # # include/acpi/acconfig.h # 2004/10/22 15:30:48-04:00 len.brown@intel.com +1 -1 # ACPICA 20040827 # # drivers/acpi/utilities/utobject.c # 2004/10/22 15:30:51-04:00 len.brown@intel.com +59 -3 # ACPICA 20040827 # # drivers/acpi/utilities/utalloc.c # 2004/10/22 15:30:51-04:00 len.brown@intel.com +3 -2 # ACPICA 20040827 # # drivers/acpi/parser/psopcode.c # 2004/10/22 15:30:51-04:00 len.brown@intel.com +2 -2 # ACPICA 20040827 # # drivers/acpi/namespace/nsnames.c # 2004/10/22 15:30:51-04:00 len.brown@intel.com +5 -1 # ACPICA 20040827 # # drivers/acpi/executer/exresop.c # 2004/10/22 15:30:51-04:00 len.brown@intel.com +8 -4 # ACPICA 20040827 # # drivers/acpi/executer/exoparg2.c # 2004/10/22 15:30:51-04:00 len.brown@intel.com +23 -72 # ACPICA 20040827 # # drivers/acpi/executer/exoparg1.c # 2004/10/22 15:30:51-04:00 len.brown@intel.com +14 -8 # ACPICA 20040827 # # drivers/acpi/executer/exmisc.c # 2004/10/22 15:30:51-04:00 len.brown@intel.com +291 -173 # ACPICA 20040827 # # drivers/acpi/executer/exfldio.c # 2004/10/22 15:30:51-04:00 len.brown@intel.com +1 -1 # ACPICA 20040827 # # drivers/acpi/executer/exconvrt.c # 2004/10/22 15:30:51-04:00 len.brown@intel.com +164 -156 # ACPICA 20040827 # # drivers/acpi/dispatcher/dswexec.c # 2004/10/22 15:30:51-04:00 len.brown@intel.com +2 -1 # ACPICA 20040827 # # ChangeSet # 2004/10/21 21:57:50-04:00 len.brown@intel.com # [ACPI] disable printk on AML breakpoint # https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=135856 # # Signed-off-by: Len Brown # # drivers/acpi/osl.c # 2004/10/21 21:57:43-04:00 len.brown@intel.com +9 -5 # disable printk on AML breakpoint # # drivers/acpi/osl.c # 2004/10/21 21:50:03-04:00 len.brown@intel.com +1 -1 # tweak _OS printk # # ChangeSet # 2004/10/21 14:04:06-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-ref # into intel.com:/home/lenb/src/26-latest-dev # # drivers/acpi/processor.c # 2004/10/21 14:04:02-04:00 len.brown@intel.com +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/21 14:04:01-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/20 23:54:44-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi # # sound/drivers/mpu401/mpu401.c # 2004/10/20 23:54:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # include/asm-x86_64/acpi.h # 2004/10/20 23:54:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/char/ipmi/ipmi_si_intf.c # 2004/10/20 23:54:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/10/20 23:54:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/io_apic.c # 2004/10/20 23:54:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/Kconfig # 2004/10/20 23:54:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/10/20 23:54:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/20 23:54:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/20 17:13:13-04:00 len.brown@intel.com # [ACPI] clarify #define ACPI_THERMAL_MODE_CRITICAL (Pavel Machek) # # drivers/acpi/thermal.c # 2004/10/20 17:11:04-04:00 len.brown@intel.com +3 -3 # ACPI_THERMAL_MODE_CRT is now ACPI_THERMAL_MODE_CRITICAL # # ChangeSet # 2004/10/20 01:42:31-04:00 len.brown@intel.com # [ACPI] simplify ES7000 IRQ re-naming scheme # so that it works for all PCI interrupts. # # Signed-off-by: Natalie Protasevich # Signed-off-by: Len Brown # # arch/i386/mach-es7000/es7000plat.c # 2004/10/20 01:42:24-04:00 len.brown@intel.com +20 -18 # es7000_rename_gsi() update to rename all interrupts below 16 # to use IRQs above the highest actual GSI in the system. # This is needed because the ES7000 has mapped its legacy # interrupts above 16 and uses the lines < 16 for PCI devices. # # arch/i386/kernel/mpparse.c # 2004/10/20 01:42:24-04:00 len.brown@intel.com +6 -0 # ES7000 has no legacy identity mapped IRQs # # ChangeSet # 2004/10/19 20:24:45-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi # # drivers/char/ipmi/ipmi_si_intf.c # 2004/10/19 20:24:39-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/acpi/processor.c # 2004/10/19 20:24:39-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/Makefile # 2004/10/19 20:24:39-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c # 2004/10/19 20:24:39-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/cpu/cpufreq/powernow-k8.c # 2004/10/19 20:24:39-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/19 20:18:57-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-ref # into intel.com:/home/lenb/src/26-latest-dev # # Documentation/kernel-parameters.txt # 2004/10/19 20:18:53-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/19 16:50:42-07:00 akpm@bix.(none) # Merge http://linux-acpi.bkbits.net/linux-acpi-test-mm # into bix.(none):/usr/src/bk-acpi # # include/asm-i386/io_apic.h # 2004/10/19 16:50:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/10/19 16:50:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/Makefile # 2004/10/19 16:50:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/Kconfig # 2004/10/19 16:50:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/io_apic.c # 2004/10/19 16:50:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/10/19 16:50:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/19 16:50:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/19 16:48:59-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi # # include/asm-x86_64/mpspec.h # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # include/asm-i386/mpspec.h # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # include/asm-i386/io_apic.h # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/char/ipmi/ipmi_si_intf.c # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/mpparse.c # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/Makefile # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/Kconfig # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/kernel/acpi.c # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/mpparse.c # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/io_apic.c # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/acpi/boot.c # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/19 16:48:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/19 19:29:50-04:00 len.brown@intel.com # [ACPI] create IBM ThinkPad ACPI driver -- ibm-acpi-0.6.patch # # by Borislav Deianov # Signed-off-by: Len Brown # # drivers/acpi/ibm_acpi.c # 2004/10/19 01:21:21-04:00 len.brown@intel.com +1240 -0 # ibm-acpi-0.6.patch # # drivers/acpi/ibm_acpi.c # 2004/10/19 01:21:21-04:00 len.brown@intel.com +0 -0 # BitKeeper file /home/lenb/src/26-stable-dev/drivers/acpi/ibm_acpi.c # # drivers/acpi/Makefile # 2004/10/18 20:20:44-04:00 len.brown@intel.com +1 -0 # ibm-acpi-0.6.patch # # drivers/acpi/Kconfig # 2004/10/19 19:29:15-04:00 len.brown@intel.com +14 -0 # ibm-acpi-0.6.patch # # Documentation/ibm-acpi.txt # 2004/10/19 01:46:55-04:00 len.brown@intel.com +474 -0 # ibm-acpi-0.6.patch # # Documentation/ibm-acpi.txt # 2004/10/19 01:46:55-04:00 len.brown@intel.com +0 -0 # BitKeeper file /home/lenb/src/26-stable-dev/Documentation/ibm-acpi.txt # # ChangeSet # 2004/10/19 13:36:18-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-test # into intel.com:/home/lenb/bk/26-latest-mm # # drivers/acpi/processor.c # 2004/10/19 13:36:14-04:00 len.brown@intel.com +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/19 13:36:14-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/19 12:51:26-04:00 len.brown@intel.com # Merge # # Documentation/kernel-parameters.txt # 2004/10/19 12:51:21-04:00 len.brown@intel.com +0 -0 # SCCS merged # # drivers/acpi/sleep/main.c # 2004/10/19 12:49:04-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/processor.c # 2004/10/19 12:49:04-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/19 12:22:10-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-test # into intel.com:/home/lenb/bk/26-latest-mm # # include/asm-i386/io_apic.h # 2004/10/19 12:22:03-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/10/19 12:22:03-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/Makefile # 2004/10/19 12:22:03-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/Kconfig # 2004/10/19 12:22:03-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/io_apic.c # 2004/10/19 12:22:02-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/10/19 12:22:02-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/18 16:28:17-04:00 len.brown@intel.com # [ACPI] add module parameters: processor.c2=[0,1] processor.c3=[0,1] # to disable/enable C2 or C3 # blacklist entries for R40e and Medion 41700 # http://bugme.osdl.org/show_bug.cgi?id=3549 # # from Andi Kleen # # drivers/acpi/processor.c # 2004/10/18 16:28:11-04:00 len.brown@intel.com +39 -0 # module parameters: processor.c2=[0,1] processor.c3=[0,1] # to disable/enable C2 or C3 # blacklist entry for R40e and Medion to disable c2/c3 using above # # Documentation/kernel-parameters.txt # 2004/10/18 16:28:11-04:00 len.brown@intel.com +5 -0 # module parameters: processor.c2=[0,1] processor.c3=[0,1] # to disable/enable C2 or C3 # # ChangeSet # 2004/10/18 14:47:59-04:00 len.brown@intel.com # [ACPI] firmware wakeup address is physical, not virtual (David Shaohua Li) # http://bugzilla.kernel.org/show_bug.cgi?id=3390 # # drivers/acpi/sleep/main.c # 2004/10/18 14:47:51-04:00 len.brown@intel.com +4 -1 # firmware wakeup address is physical, not virtual # # ChangeSet # 2004/10/15 21:58:18-07:00 akpm@bix.(none) # Merge http://linux-acpi.bkbits.net/linux-acpi-test-mm # into bix.(none):/usr/src/bk-acpi # # arch/i386/kernel/io_apic.c # 2004/10/15 21:58:15-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/14 14:05:31-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-test # into intel.com:/home/lenb/bk/26-latest-mm # # arch/i386/kernel/io_apic.c # 2004/10/14 14:05:27-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/10 22:09:40-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi # # arch/i386/kernel/io_apic.c # 2004/10/10 22:09:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/10 04:34:32-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/26-latest-dominik # into intel.com:/home/lenb/bk/26-latest-mm # # drivers/acpi/acpi_ksyms.c # 2004/10/10 04:34:29-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/10 04:25:57-04:00 len.brown@intel.com # EXPORT_SYMBOL(acpi_os_write_port); # EXPORT_SYMBOL(acpi_fadt_is_v1); # # drivers/acpi/acpi_ksyms.c # 2004/10/10 04:24:53-04:00 len.brown@intel.com +3 -0 # EXPORT_SYMBOL(acpi_os_write_port); # EXPORT_SYMBOL(acpi_fadt_is_v1); # # ChangeSet # 2004/10/09 14:14:38-07:00 akpm@bix.(none) # Merge http://linux-acpi.bkbits.net/linux-acpi-test-mm # into bix.(none):/usr/src/bk-acpi # # include/asm-x86_64/mpspec.h # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/acpi/Kconfig # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/Makefile # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/io_apic.c # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/Kconfig # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/kernel/setup.c # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/kernel/acpi.c # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/setup.c # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/dmi_scan.c # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/09 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/09 14:13:26-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi # # drivers/acpi/osl.c # 2004/10/09 14:13:21-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/acpi/Kconfig # 2004/10/09 14:13:21-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/10/09 14:13:21-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/io_apic.c # 2004/10/09 14:13:21-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/dmi_scan.c # 2004/10/09 14:13:21-07:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/09 14:13:21-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/08 18:51:45-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/26-latest-dev # into intel.com:/home/lenb/bk/26-latest-mm # # drivers/acpi/Kconfig # 2004/10/08 18:51:41-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/10/08 18:51:41-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/08 18:44:00-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/26-latest-dominik # into intel.com:/home/lenb/bk/26-latest-mm # # arch/x86_64/kernel/io_apic.c # 2004/10/08 18:43:56-04:00 len.brown@intel.com +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/08 18:43:56-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/08 18:01:04-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-ref # into intel.com:/home/lenb/bk/26-latest-mm # # drivers/Makefile # 2004/10/08 18:01:00-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/10/08 18:01:00-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/io_apic.c # 2004/10/08 18:01:00-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/Kconfig # 2004/10/08 18:01:00-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/ia64/kernel/setup.c # 2004/10/08 18:01:00-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/ia64/kernel/acpi.c # 2004/10/08 18:01:00-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/setup.c # 2004/10/08 18:01:00-04:00 len.brown@intel.com +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/08 18:01:00-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/10/08 16:55:44-04:00 len.brown@intel.com # [ACPI] Notify SMM of cpufreq # http://marc.theaimsgroup.com/?l=acpi4linux&m=109428989121089&w=2 # # Signed-off-by: Dominik Brodowski # # include/acpi/processor.h # 2004/09/04 05:07:43-04:00 len.brown@intel.com +4 -0 # Notify SMM of cpufreq # # include/acpi/actbl.h # 2004/09/04 05:07:43-04:00 len.brown@intel.com +2 -0 # Notify SMM of cpufreq # # drivers/acpi/tables/tbconvrt.c # 2004/09/04 05:07:43-04:00 len.brown@intel.com +8 -2 # Notify SMM of cpufreq # # drivers/acpi/processor.c # 2004/09/04 05:07:43-04:00 len.brown@intel.com +79 -8 # Notify SMM of cpufreq # # arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c # 2004/09/04 05:07:43-04:00 len.brown@intel.com +3 -0 # Notify SMM of cpufreq # # arch/i386/kernel/cpu/cpufreq/powernow-k8.c # 2004/09/04 05:07:43-04:00 len.brown@intel.com +4 -0 # Notify SMM of cpufreq # # arch/i386/kernel/cpu/cpufreq/powernow-k7.c # 2004/09/04 05:07:43-04:00 len.brown@intel.com +3 -0 # Notify SMM of cpufreq # # arch/i386/kernel/cpu/cpufreq/acpi.c # 2004/09/04 05:07:43-04:00 len.brown@intel.com +3 -1 # Notify SMM of cpufreq # # ChangeSet # 2004/10/08 11:48:09-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi # # arch/ia64/kernel/setup.c # 2004/10/08 11:48:05-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/kernel/acpi.c # 2004/10/08 11:48:05-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/06 20:25:56-07:00 akpm@bix.(none) # Merge http://linux-acpi.bkbits.net/linux-acpi-test-mm # into bix.(none):/usr/src/bk-acpi # # include/asm-x86_64/mpspec.h # 2004/10/06 20:25:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/acpi/osl.c # 2004/10/06 20:25:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/Makefile # 2004/10/06 20:25:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/10/06 20:25:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/kernel/io_apic.c # 2004/10/06 20:25:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/x86_64/Kconfig # 2004/10/06 20:25:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/kernel/acpi.c # 2004/10/06 20:25:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/setup.c # 2004/10/06 20:25:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/dmi_scan.c # 2004/10/06 20:25:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/10/06 20:25:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/06 20:25:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/17 00:29:39-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-test # into intel.com:/home/lenb/bk/linux-acpi-test-mm # # drivers/Makefile # 2004/09/17 00:29:35-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/Kconfig # 2004/09/17 00:29:35-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/dmi_scan.c # 2004/09/17 00:29:35-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/09/17 00:29:35-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/09/10 16:26:55-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-test # into intel.com:/home/lenb/bk/linux-acpi-test-mm # # include/asm-x86_64/mpspec.h # 2004/09/10 16:26:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/Makefile # 2004/09/10 16:26:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/09/10 16:26:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/ia64/kernel/acpi.c # 2004/09/10 16:26:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/09/02 03:39:43-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-test # into intel.com:/home/lenb/bk/linux-acpi-test-mm # # include/linux/acpi.h # 2004/09/02 03:39:35-04:00 len.brown@intel.com +0 -0 # Auto merged # # include/acpi/acpi_drivers.h # 2004/09/02 03:39:35-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/Kconfig # 2004/09/02 03:39:35-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/io_apic.c # 2004/09/02 03:39:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/io_apic.c # 2004/09/02 03:39:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/dmi_scan.c # 2004/09/02 03:39:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/acpi/boot.c # 2004/09/02 03:39:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/09/02 03:25:49-04:00 len.brown@intel.com # merge # # arch/x86_64/Kconfig # 2004/09/02 03:25:42-04:00 len.brown@intel.com +1 -0 # merge # # sound/drivers/mpu401/mpu401.c # 2004/09/02 03:20:35-04:00 len.brown@intel.com +3 -3 # Auto merged # # include/asm-x86_64/mpspec.h # 2004/09/02 03:20:35-04:00 len.brown@intel.com +0 -0 # Auto merged # # include/asm-x86_64/acpi.h # 2004/09/02 03:20:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # include/asm-i386/fixmap.h # 2004/09/02 03:20:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # include/asm-i386/acpi.h # 2004/09/02 03:20:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/char/ipmi/ipmi_si_intf.c # 2004/09/02 03:20:34-04:00 len.brown@intel.com +1 -2 # Auto merged # # drivers/Makefile # 2004/09/02 03:20:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/09/02 03:20:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/Makefile # 2004/09/02 03:20:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/setup.c # 2004/09/02 03:20:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/io_apic.c # 2004/09/02 03:20:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/acpi/boot.c # 2004/09/02 03:20:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/Makefile # 2004/09/02 03:20:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/09/02 03:20:34-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/09/02 03:00:54-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-test # into intel.com:/home/lenb/bk/linux-acpi-test-mm # # sound/drivers/mpu401/mpu401.c # 2004/09/02 03:00:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/setup.c # 2004/09/02 03:00:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/io_apic.c # 2004/09/02 03:00:50-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/Makefile # 2004/09/02 03:00:49-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/09/01 20:28:43-04:00 len.brown@intel.com # Cset exclude: len.brown@intel.com|ChangeSet|20040817220851|52337 # # arch/i386/kernel/dmi_scan.c # 2004/09/01 20:28:41-04:00 len.brown@intel.com +0 -0 # Exclude # # ChangeSet # 2004/09/01 20:26:54-04:00 len.brown@intel.com # Cset exclude: len.brown@intel.com|ChangeSet|20040826050001|40089 # # sound/drivers/mpu401/mpu401.c # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # include/linux/acpi.h # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # include/asm-i386/mpspec.h # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # include/asm-i386/io_apic.h # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # include/asm-i386/fixmap.h # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # drivers/acpi/acpi_ksyms.c # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # drivers/acpi/Makefile # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # drivers/acpi/Kconfig # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # drivers/Makefile # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/x86_64/Kconfig # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/ia64/kernel/setup.c # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/ia64/kernel/acpi.c # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/i386/kernel/setup.c # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/i386/kernel/mpparse.c # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/i386/kernel/io_apic.c # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/i386/kernel/dmi_scan.c # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/i386/kernel/acpi/Makefile # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/i386/kernel/Makefile # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/i386/Kconfig # 2004/09/01 20:26:43-04:00 len.brown@intel.com +0 -0 # Exclude # # include/asm-x86_64/mpspec.h # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # include/asm-x86_64/io_apic.h # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # include/asm-x86_64/acpi.h # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # include/asm-i386/acpi.h # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # include/acpi/acpi_drivers.h # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # include/acpi/acpi_bus.h # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # drivers/char/ipmi/ipmi_si_intf.c # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/x86_64/kernel/setup.c # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/x86_64/kernel/mpparse.c # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/x86_64/kernel/io_apic.c # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/x86_64/kernel/acpi/Makefile # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/x86_64/kernel/Makefile # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # arch/i386/kernel/acpi/boot.c # 2004/09/01 20:26:42-04:00 len.brown@intel.com +0 -0 # Exclude # # ChangeSet # 2004/08/27 01:25:27-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/26-latest-test # into intel.com:/home/lenb/bk/linux-acpi-test-mm # # include/asm-i386/acpi.h # 2004/08/27 01:25:23-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/acpi/boot.c # 2004/08/27 01:25:23-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/Makefile # 2004/08/27 01:25:23-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/08/26 01:04:55-04:00 len.brown@intel.com # merge # # arch/x86_64/Kconfig # 2004/08/26 01:04:50-04:00 len.brown@intel.com +0 -1 # merge # # include/asm-x86_64/mpspec.h # 2004/08/26 01:01:12-04:00 len.brown@intel.com +0 -0 # Auto merged # # include/asm-x86_64/acpi.h # 2004/08/26 01:01:12-04:00 len.brown@intel.com +0 -0 # Auto merged # # include/asm-i386/fixmap.h # 2004/08/26 01:01:12-04:00 len.brown@intel.com +0 -0 # Auto merged # # include/asm-i386/acpi.h # 2004/08/26 01:01:12-04:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/char/ipmi/ipmi_si_intf.c # 2004/08/26 01:01:12-04:00 len.brown@intel.com +0 -3 # Auto merged # # drivers/Makefile # 2004/08/26 01:01:12-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/setup.c # 2004/08/26 01:01:12-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/Makefile # 2004/08/26 01:01:12-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/io_apic.c # 2004/08/26 01:01:12-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/Makefile # 2004/08/26 01:01:12-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/08/26 01:01:12-04:00 len.brown@intel.com +0 -0 # Auto merged # diff -Nru a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/ibm-acpi.txt 2004-10-26 18:29:14 -07:00 @@ -0,0 +1,474 @@ + IBM ThinkPad ACPI Extras Driver + + Version 0.7 + 23 October 2004 + + Borislav Deianov + http://ibm-acpi.sf.net/ + + +This is a Linux ACPI driver for the IBM ThinkPad laptops. It aims to +support various features of these laptops which are accessible through +the ACPI framework but not otherwise supported by the generic Linux +ACPI drivers. + + +Status +------ + +The features currently supported are the following (see below for +detailed description): + + - Fn key combinations + - Bluetooth enable and disable + - video output switching, expansion control + - ThinkLight on and off + - limited docking and undocking + - UltraBay eject + - Experimental: CMOS control + - Experimental: LED control + - Experimental: ACPI sounds + +A compatibility table by model and feature is maintained on the web +site, http://ibm-acpi.sf.net/. I appreciate any success or failure +reports, especially if they add to or correct the compatibility table. +Please include the following information in your report: + + - ThinkPad model name + - a copy of your DSDT, from /proc/acpi/dsdt + - which driver features work and which don't + - the observed behavior of non-working features + +Any other comments or patches are also more than welcome. + + +Installation +------------ + +If you are compiling this driver as included in the Linux kernel +sources, simply enable the CONFIG_ACPI_IBM option (Power Management / +ACPI / IBM ThinkPad Laptop Extras). The rest of this section describes +how to install this driver when downloaded from the web site. + +First, you need to get a kernel with ACPI support up and running. +Please refer to http://acpi.sourceforge.net/ for help with this +step. How successful you will be depends a lot on you ThinkPad model, +the kernel you are using and any additional patches applied. The +kernel provided with your distribution may not be good enough. I +needed to compile a 2.6.7 kernel with the 20040715 ACPI patch to get +ACPI working reliably on my ThinkPad X40. Old ThinkPad models may not +be supported at all. + +Assuming you have the basic ACPI support working (e.g. you can see the +/proc/acpi directory), follow the following steps to install this +driver: + + - unpack the archive: + + tar xzvf ibm-acpi-x.y.tar.gz; cd ibm-acpi-x.y + + - compile the driver: + + make + + - install the module in your kernel modules directory: + + make install + + - load the module: + + modprobe ibm_acpi + +After loading the module, check the "dmesg" output for any error messages. + + +Features +-------- + +The driver creates the /proc/acpi/ibm directory. There is a file under +that directory for each feature described below. Note that while the +driver is still in the alpha stage, the exact proc file format and +commands supported by the various features is guaranteed to change +frequently. + +Driver Version -- /proc/acpi/ibm/driver +-------------------------------------- + +The driver name and version. No commands can be written to this file. + +Hot Keys -- /proc/acpi/ibm/hotkey +--------------------------------- + +Without this driver, only the Fn-F4 key (sleep button) generates an +ACPI event. With the driver loaded, the hotkey feature enabled and the +mask set (see below), the various hot keys generate ACPI events in the +following format: + + ibm/hotkey HKEY 00000080 0000xxxx + +The last four digits vary depending on the key combination pressed. +All labeled Fn-Fx key combinations generate distinct events. In +addition, the lid microswitch and some docking station buttons may +also generate such events. + +The following commands can be written to this file: + + echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature + echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature + echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys + echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys + ... any other 4-hex-digit mask ... + echo reset > /proc/acpi/ibm/hotkey -- restore the original mask + +The bit mask allows some control over which hot keys generate ACPI +events. Not all bits in the mask can be modified. Not all bits that +can be modified do anything. Not all hot keys can be individually +controlled by the mask. Most recent ThinkPad models honor the +following bits (assuming the hot keys feature has been enabled): + + key bit behavior when set behavior when unset + + Fn-F3 always generates ACPI event + Fn-F4 always generates ACPI event + Fn-F5 0010 generate ACPI event enable/disable Bluetooth + Fn-F7 0040 generate ACPI event switch LCD and external display + Fn-F8 0080 generate ACPI event expand screen or none + Fn-F9 0100 generate ACPI event none + Fn-F12 always generates ACPI event + +Some models do not support all of the above. For example, the T30 does +not support Fn-F5 and Fn-F9. Other models do not support the mask at +all. On those models, hot keys cannot be controlled individually. + +Note that enabling ACPI events for some keys prevents their default +behavior. For example, if events for Fn-F5 are enabled, that key will +no longer enable/disable Bluetooth by itself. This can still be done +from an acpid handler for the ibm/hotkey event. + +Note also that not all Fn key combinations are supported through +ACPI. For example, on the X40, the brightness, volume and "Access IBM" +buttons do not generate ACPI events even with this driver. They *can* +be used through the "ThinkPad Buttons" utility, see +http://www.nongnu.org/tpb/ + +Bluetooth -- /proc/acpi/ibm/bluetooth +------------------------------------- + +This feature shows the presence and current state of a Bluetooth +device. If Bluetooth is installed, the following commands can be used: + + echo enable > /proc/acpi/ibm/bluetooth + echo disable > /proc/acpi/ibm/bluetooth + +Video output control -- /proc/acpi/ibm/video +-------------------------------------------- + +This feature allows control over the devices used for video output - +LCD, CRT or DVI (if available). The following commands are available: + + echo lcd_enable > /proc/acpi/ibm/video + echo lcd_disable > /proc/acpi/ibm/video + echo crt_enable > /proc/acpi/ibm/video + echo crt_disable > /proc/acpi/ibm/video + echo dvi_enable > /proc/acpi/ibm/video + echo dvi_disable > /proc/acpi/ibm/video + echo auto_enable > /proc/acpi/ibm/video + echo auto_disable > /proc/acpi/ibm/video + echo expand_toggle > /proc/acpi/ibm/video + echo video_switch > /proc/acpi/ibm/video + +Each video output device can be enabled or disabled individually. +Reading /proc/acpi/ibm/video shows the status of each device. + +Automatic video switching can be enabled or disabled. When automatic +video switching is enabled, certain events (e.g. opening the lid, +docking or undocking) cause the video output device to change +automatically. While this can be useful, it also causes flickering +and, on the X40, video corruption. By disabling automatic switching, +the flickering or video corruption can be avoided. + +The video_switch command cycles through the available video outputs +(it sumulates the behavior of Fn-F7). + +Video expansion can be toggled through this feature. This controls +whether the display is expanded to fill the entire LCD screen when a +mode with less than full resolution is used. Note that the current +video expansion status cannot be determined through this feature. + +Note that on many models (particularly those using Radeon graphics +chips) the X driver configures the video card in a way which prevents +Fn-F7 from working. This also disables the video output switching +features of this driver, as it uses the same ACPI methods as +Fn-F7. Video switching on the console should still work. + +ThinkLight control -- /proc/acpi/ibm/light +------------------------------------------ + +The current status of the ThinkLight can be found in this file. A few +models which do not make the status available will show it as +"unknown". The available commands are: + + echo on > /proc/acpi/ibm/light + echo off > /proc/acpi/ibm/light + +Docking / Undocking -- /proc/acpi/ibm/dock +------------------------------------------ + +Docking and undocking (e.g. with the X4 UltraBase) requires some +actions to be taken by the operating system to safely make or break +the electrical connections with the dock. + +The docking feature of this driver generates the following ACPI events: + + ibm/dock GDCK 00000003 00000001 -- eject request + ibm/dock GDCK 00000003 00000002 -- undocked + ibm/dock GDCK 00000000 00000003 -- docked + +NOTE: These events will only be generated if the laptop was docked +when originally booted. This is due to the current lack of support for +hot plugging of devices in the Linux ACPI framework. If the laptop was +booted while not in the dock, the following message is shown in the +logs: "ibm_acpi: dock device not present". No dock-related events are +generated but the dock and undock commands described below still +work. They can be executed manually or triggered by Fn key +combinations (see the example acpid configuration files included in +the driver tarball package available on the web site). + +When the eject request button on the dock is pressed, the first event +above is generated. The handler for this event should issue the +following command: + + echo undock > /proc/acpi/ibm/dock + +After the LED on the dock goes off, it is safe to eject the laptop. +Note: if you pressed this key by mistake, go ahead and eject the +laptop, then dock it back in. Otherwise, the dock may not function as +expected. + +When the laptop is docked, the third event above is generated. The +handler for this event should issue the following command to fully +enable the dock: + + echo dock > /proc/acpi/ibm/dock + +The contents of the /proc/acpi/ibm/dock file shows the current status +of the dock, as provided by the ACPI framework. + +The docking support in this driver does not take care of enabling or +disabling any other devices you may have attached to the dock. For +example, a CD drive plugged into the UltraBase needs to be disabled or +enabled separately. See the provided example acpid configuration files +for how this can be accomplished. + +There is no support yet for PCI devices that may be attached to a +docking station, e.g. in the ThinkPad Dock II. The driver currently +does not recognize, enable or disable such devices. This means that +the only docking stations currently supported are the X-series +UltraBase docks and "dumb" port replicators like the Mini Dock (the +latter don't need any ACPI support, actually). + +UltraBay Eject -- /proc/acpi/ibm/bay +------------------------------------ + +Inserting or ejecting an UltraBay device requires some actions to be +taken by the operating system to safely make or break the electrical +connections with the device. + +This feature generates the following ACPI events: + + ibm/bay MSTR 00000003 00000000 -- eject request + ibm/bay MSTR 00000001 00000000 -- eject lever inserted + +NOTE: These events will only be generated if the UltraBay was present +when the laptop was originally booted (on the X series, the UltraBay +is in the dock, so it may not be present if the laptop was undocked). +This is due to the current lack of support for hot plugging of devices +in the Linux ACPI framework. If the laptop was booted without the +UltraBay, the following message is shown in the logs: "ibm_acpi: bay +device not present". No bay-related events are generated but the eject +command described below still works. It can be executed manually or +triggered by a hot key combination. + +Sliding the eject lever generates the first event shown above. The +handler for this event should take whatever actions are necessary to +shut down the device in the UltraBay (e.g. call idectl), then issue +the following command: + + echo eject > /proc/acpi/ibm/bay + +After the LED on the UltraBay goes off, it is safe to pull out the +device. + +When the eject lever is inserted, the second event above is +generated. The handler for this event should take whatever actions are +necessary to enable the UltraBay device (e.g. call idectl). + +The contents of the /proc/acpi/ibm/bay file shows the current status +of the UltraBay, as provided by the ACPI framework. + +Experimental Features +--------------------- + +The following features are marked experimental because using them +involves guessing the correct values of some parameters. Guessing +incorrectly may have undesirable effects like crashing your +ThinkPad. USE THESE WITH CAUTION! To activate them, you'll need to +supply the experimental=1 parameter when loading the module. + +Experimental: CMOS control - /proc/acpi/ibm/cmos +------------------------------------------------ + +This feature is used internally by the ACPI firmware to control the +ThinkLight on most newer ThinkPad models. It appears that it can also +control LCD brightness, sounds volume and more, but only on some +models. + +The commands are non-negative integer numbers: + + echo 0 >/proc/acpi/ibm/cmos + echo 1 >/proc/acpi/ibm/cmos + echo 2 >/proc/acpi/ibm/cmos + ... + +The range of numbers which are used internally by various models is 0 +to 21, but it's possible that numbers outside this range have +interesting behavior. Here is the behavior on the X40 (tpb is the +ThinkPad Buttons utility): + + 0 - no effect but tpb reports "Volume down" + 1 - no effect but tpb reports "Volume up" + 2 - no effect but tpb reports "Mute on" + 3 - simulate pressing the "Access IBM" button + 4 - LCD brightness up + 5 - LCD brightness down + 11 - toggle screen expansion + 12 - ThinkLight on + 13 - ThinkLight off + 14 - no effect but tpb reports ThinkLight status change + +If you try this feature, please send me a report similar to the +above. On models which allow control of LCD brightness or sound +volume, I'd like to provide this functionality in an user-friendly +way, but first I need a way to identify the models which this is +possible. + +Experimental: LED control - /proc/acpi/ibm/LED +---------------------------------------------- + +Some of the LED indicators can be controlled through this feature. The +available commands are: + + echo on >/proc/acpi/ibm/led + echo off >/proc/acpi/ibm/led + echo blink >/proc/acpi/ibm/led + +The parameter is a non-negative integer. The range of LED +numbers used internally by various models is 0 to 7 but it's possible +that numbers outside this range are also valid. Here is the mapping on +the X40: + + 0 - power + 1 - battery (orange) + 2 - battery (green) + 3 - UltraBase + 4 - UltraBay + 7 - standby + +All of the above can be turned on and off and can be made to blink. + +If you try this feature, please send me a report similar to the +above. I'd like to provide this functionality in an user-friendly way, +but first I need to identify the which numbers correspond to which +LEDs on various models. + +Experimental: ACPI sounds - /proc/acpi/ibm/beep +----------------------------------------------- + +The BEEP method is used internally by the ACPI firmware to provide +audible alerts in various situtation. This feature allows the same +sounds to be triggered manually. + +The commands are non-negative integer numbers: + + echo 0 >/proc/acpi/ibm/beep + echo 1 >/proc/acpi/ibm/beep + echo 2 >/proc/acpi/ibm/beep + ... + +The range of numbers which are used internally by various models is 0 +to 17, but it's possible that numbers outside this range are also +valid. Here is the behavior on the X40: + + 2 - two beeps, pause, third beep + 3 - single beep + 4 - "unable" + 5 - single beep + 6 - "AC/DC" + 7 - high-pitched beep + 9 - three short beeps + 10 - very long beep + 12 - low-pitched beep + +(I've only been able to identify a couple of them). + +If you try this feature, please send me a report similar to the +above. I'd like to provide this functionality in an user-friendly way, +but first I need to identify the which numbers correspond to which +sounds on various models. + + +Multiple Command, Module Parameters +----------------------------------- + +Multiple commands can be written to the proc files in one shot by +separating them with commas, for example: + + echo enable,0xffff > /proc/acpi/ibm/hotkey + echo lcd_disable,crt_enable > /proc/acpi/ibm/video + +Commands can also be specified when loading the ibm_acpi module, for +example: + + modprobe ibm_acpi hotkey=enable,0xffff video=auto_disable + + +Example Configuration +--------------------- + +The ACPI support in the kernel is intended to be used in conjunction +with a user-space daemon, acpid. The configuration files for this +daemon control what actions are taken in response to various ACPI +events. An example set of configuration files are included in the +config/ directory of the tarball package available on the web +site. Note that these are provided for illustration purposes only and +may need to be adapted to your particular setup. + +The following utility scripts are used by the example action +scripts (included with ibm-acpi for completeness): + + /usr/local/sbin/idectl -- from the hdparm source distribution, + see http://www.ibiblio.org/pub/Linux/system/hardware + /usr/local/sbin/laptop_mode -- from the Linux kernel source + distribution, see Documentation/laptop-mode.txt + /sbin/service -- comes with Redhat/Fedora distributions + +Toan T Nguyen has written a SuSE powersave +script for the X20, included in config/usr/sbin/ibm_hotkeys_X20 + +Henrik Brix Andersen has written a Gentoo ACPI event +handler script for the X31. You can get the latest version from +http://dev.gentoo.org/~brix/files/x31.sh + +David Schweikert has written an alternative blank.sh +script which works on Debian systems, included in +configs/etc/acpi/actions/blank-debian.sh + + +TODO +---- + +I'd like to implement the following features but haven't yet found the +time and/or I don't yet know how to implement them: + +- UltraBay floppy drive support + diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt 2004-10-26 18:29:14 -07:00 +++ b/Documentation/kernel-parameters.txt 2004-10-26 18:29:14 -07:00 @@ -960,6 +960,11 @@ (param: profile step/bucket size as a power of 2 for statistical time based profiling) + processor.c2= [HW, ACPI] + processor.c3= [HW, ACPI] + 0 - disable C2 or C3 idle power saving state. + 1 - enable C2 or C3 (default unless DMI blacklist entry) + prompt_ramdisk= [RAM] List of RAM disks to prompt for floppy disk before loading. See Documentation/ramdisk.txt. diff -Nru a/Documentation/power/video_extension.txt b/Documentation/power/video_extension.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/power/video_extension.txt 2004-10-26 18:29:14 -07:00 @@ -0,0 +1,34 @@ +This driver implement the ACPI Extensions For Display Adapters +for integrated graphics devices on motherboard, as specified in +ACPI 2.0 Specification, Appendix B, allowing to perform some basic +control like defining the video POST device, retrieving EDID information +or to setup a video output, etc. Note that this is an ref. implementation only. +It may or may not work for your integrated video device. + +Interfaces exposed to userland through /proc/acpi/video: + +VGA/info : display the supported video bus device capability like ,Video ROM, CRT/LCD/TV. +VGA/ROM : Used to get a copy of the display devices' ROM data (up to 4k). +VGA/POST_info : Used to determine what options are implemented. +VGA/POST : Used to get/set POST device. +VGA/DOS : Used to get/set ownership of output switching: + Please refer ACPI spec B.4.1 _DOS +VGA/CRT : CRT output +VGA/LCD : LCD output +VGA/TV : TV output +VGA/*/brightness : Used to get/set brightness of output device + +Notify event through /proc/acpi/event: + +#define ACPI_VIDEO_NOTIFY_SWITCH 0x80 +#define ACPI_VIDEO_NOTIFY_PROBE 0x81 +#define ACPI_VIDEO_NOTIFY_CYCLE 0x82 +#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 +#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 + +#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82 +#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83 +#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84 +#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85 +#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86 + diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c --- a/arch/i386/kernel/acpi/boot.c 2004-10-26 18:29:14 -07:00 +++ b/arch/i386/kernel/acpi/boot.c 2004-10-26 18:29:14 -07:00 @@ -457,16 +457,10 @@ * Make sure all (legacy) PCI IRQs are set as level-triggered. */ if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { - static u16 irq_mask; extern void eisa_set_level_irq(unsigned int irq); - if (edge_level == ACPI_LEVEL_SENSITIVE) { - if ((gsi < 16) && !((1 << gsi) & irq_mask)) { - Dprintk(KERN_DEBUG PREFIX "Setting GSI %u as level-triggered\n", gsi); - irq_mask |= (1 << gsi); + if (edge_level == ACPI_LEVEL_SENSITIVE) eisa_set_level_irq(gsi); - } - } } #endif 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-10-26 18:29:14 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/acpi.c 2004-10-26 18:29:14 -07:00 @@ -428,7 +428,9 @@ if (result) { goto err_freqfree; } - + + /* notify BIOS that we exist */ + acpi_processor_notify_smm(THIS_MODULE); printk(KERN_INFO "cpufreq: CPU%u - ACPI performance management activated.\n", cpu); diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c 2004-10-26 18:29:14 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c 2004-10-26 18:29:14 -07:00 @@ -400,6 +400,9 @@ powernow_table[i].frequency = CPUFREQ_TABLE_END; powernow_table[i].index = 0; + /* notify BIOS that we exist */ + acpi_processor_notify_smm(THIS_MODULE); + return 0; err2: diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2004-10-26 18:29:14 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2004-10-26 18:29:14 -07:00 @@ -777,6 +777,10 @@ data->numps = data->acpi_data.state_count; print_basics(data); powernow_k8_acpi_pst_values(data, 0); + + /* notify BIOS that we exist */ + acpi_processor_notify_smm(THIS_MODULE); + return 0; err_out_mem: diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2004-10-26 18:29:14 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2004-10-26 18:29:14 -07:00 @@ -428,6 +428,9 @@ centrino_model->op_points[i].frequency = CPUFREQ_ENTRY_INVALID; } + /* notify BIOS that we exist */ + acpi_processor_notify_smm(THIS_MODULE); + return 0; err_kfree_all: diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c --- a/arch/i386/kernel/mpparse.c 2004-10-26 18:29:14 -07:00 +++ b/arch/i386/kernel/mpparse.c 2004-10-26 18:29:14 -07:00 @@ -996,6 +996,12 @@ mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; Dprintk("Bus #%d is ISA\n", MP_ISA_BUS); + /* + * ES7000 has no legacy identity mappings + */ + if (es7000_plat) + return; + /* * Locate the IOAPIC that manages the ISA IRQs (0-15). */ diff -Nru a/arch/i386/mach-es7000/es7000.h b/arch/i386/mach-es7000/es7000.h --- a/arch/i386/mach-es7000/es7000.h 2004-10-26 18:29:14 -07:00 +++ b/arch/i386/mach-es7000/es7000.h 2004-10-26 18:29:14 -07:00 @@ -104,13 +104,6 @@ #define MIP_SW_APIC 0x1020b #define MIP_FUNC(VALUE) (VALUE & 0xff) -#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT)) -#define IOAPIC_GSI_BOUND(ioapic) ((ioapic+1) * (nr_ioapic_registers[ioapic]-1)) -#define MAX_GSI_MAPSIZE 32 -#endif - -extern unsigned long io_apic_irqs; - extern int parse_unisys_oem (char *oemptr, int oem_entries); extern int find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length); extern int es7000_start_cpu(int cpu, unsigned long eip); diff -Nru a/arch/i386/mach-es7000/es7000plat.c b/arch/i386/mach-es7000/es7000plat.c --- a/arch/i386/mach-es7000/es7000plat.c 2004-10-26 18:29:14 -07:00 +++ b/arch/i386/mach-es7000/es7000plat.c 2004-10-26 18:29:14 -07:00 @@ -52,72 +52,27 @@ unsigned long mip_addr, host_addr; #if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT)) -static unsigned long cycle_irqs = 0; -static unsigned long free_irqs = 0; -static int gsi_map[MAX_GSI_MAPSIZE] = { [0 ... MAX_GSI_MAPSIZE-1] = -1 }; /* * GSI override for ES7000 platforms. */ -static int __init -es7000_gsi_override(int ioapic, int gsi) -{ - static int newgsi = 0; - - if (gsi_map[gsi] != -1) - gsi = gsi_map[gsi]; - else if (cycle_irqs ^ free_irqs) { - newgsi = find_next_bit(&cycle_irqs, IOAPIC_GSI_BOUND(0), newgsi); - __set_bit(newgsi, &free_irqs); - gsi_map[gsi] = newgsi; - gsi = newgsi; - newgsi++; - Dprintk("es7000_gsi_override: free_irqs = 0x%lx\n", free_irqs); - } - - return gsi; -} +static unsigned int base; -static int __init +static int es7000_rename_gsi(int ioapic, int gsi) { - static int initialized = 0; - int i; - - /* - * These should NEVER be true at this point but we'd rather be - * safe than sorry. - */ - if (acpi_disabled || acpi_pci_disabled || acpi_noirq) - return gsi; - - if (ioapic) - return gsi; - - if (!initialized) { - unsigned long tmp_irqs = 0; - - for (i = 0; i < nr_ioapic_registers[0]; i++) - __set_bit(mp_irqs[i].mpc_srcbusirq, &tmp_irqs); - - cycle_irqs = (~tmp_irqs & io_apic_irqs & ((1 << IOAPIC_GSI_BOUND(0)) - 1)); - - initialized = 1; - Dprintk("es7000_rename_gsi: cycle_irqs = 0x%lx\n", cycle_irqs); - } - - for (i = 0; i < nr_ioapic_registers[0]; i++) { - if (mp_irqs[i].mpc_srcbusirq == gsi) { - if (mp_irqs[i].mpc_dstirq == gsi) - return gsi; - else - return es7000_gsi_override(0, gsi); - } + if (!base) { + int i; + for (i = 0; i < nr_ioapics; i++) + base += nr_ioapic_registers[i]; } + if (!ioapic && (gsi < 16)) + gsi += base; return gsi; } + #endif // (CONFIG_X86_IO_APIC) && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT) /* @@ -240,7 +195,7 @@ } } } - Dprintk("ES7000: did not find Unisys ACPI OEM table!\n"); + printk("ES7000: did not find Unisys ACPI OEM table!\n"); return -1; } diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c --- a/arch/i386/pci/irq.c 2004-10-26 18:29:14 -07:00 +++ b/arch/i386/pci/irq.c 2004-10-26 18:29:14 -07:00 @@ -127,8 +127,15 @@ { unsigned char mask = 1 << (irq & 7); unsigned int port = 0x4d0 + (irq >> 3); - unsigned char val = inb(port); + unsigned char val; + static u16 eisa_irq_mask; + if (irq >= 16 || (1 << irq) & eisa_irq_mask) + return; + + eisa_irq_mask |= (1 << irq); + printk("PCI: setting IRQ %u as level-triggered\n", irq); + val = inb(port); if (!(val & mask)) { DBG(" -> edge"); outb(val | mask, port); diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig --- a/arch/x86_64/Kconfig 2004-10-26 18:29:14 -07:00 +++ b/arch/x86_64/Kconfig 2004-10-26 18:29:14 -07:00 @@ -170,7 +170,7 @@ bool depends on SMP && !MK8 default y - + config MATH_EMULATION bool diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig --- a/drivers/acpi/Kconfig 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/Kconfig 2004-10-26 18:29:14 -07:00 @@ -110,6 +110,21 @@ down the system. Until then, you can cat it, and see output when a button is pressed. +config ACPI_VIDEO + tristate "Video" + depends on ACPI_INTERPRETER + depends on EXPERIMENTAL + depends on !IA64_SGI_SN + default m + help + This driver implement the ACPI Extensions For Display Adapters + for integrated graphics devices on motherboard, as specified in + ACPI 2.0 Specification, Appendix B, allowing to perform some basic + control like defining the video POST device, retrieving EDID information + or to setup a video output, etc. + Note that this is an ref. implementation only. It may or may not work + for your integrated video device. + config ACPI_FAN tristate "Fan" depends on ACPI_INTERPRETER @@ -176,6 +191,20 @@ something works not quite as expected, please use the mailing list available on the above page (acpi4asus-user@lists.sourceforge.net) +config ACPI_IBM + tristate "IBM ThinkPad Laptop Extras" + depends on X86 + depends on ACPI_INTERPRETER + default m + ---help--- + This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds + support for Fn-Fx key combinations, Bluetooth control, video + output switching, ThinkLight control, UltraBay eject and more. + For more information about this driver see Documentation/ibm-acpi.txt + and http://ibm-acpi.sf.net/ . + + If you have an IBM ThinkPad laptop, say Y or M here. + config ACPI_TOSHIBA tristate "Toshiba Laptop Extras" depends on X86 @@ -206,7 +235,7 @@ config ACPI_CUSTOM_DSDT bool "Include Custom DSDT" - depends on X86 && ACPI_INTERPRETER && !STANDALONE + depends on ACPI_INTERPRETER && !STANDALONE default n help Thist option is to load a custom ACPI DSDT diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile --- a/drivers/acpi/Makefile 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/Makefile 2004-10-26 18:29:14 -07:00 @@ -38,6 +38,7 @@ obj-$(CONFIG_ACPI_BUTTON) += button.o obj-$(CONFIG_ACPI_EC) += ec.o obj-$(CONFIG_ACPI_FAN) += fan.o +obj-$(CONFIG_ACPI_VIDEO) += video.o obj-$(CONFIG_ACPI_PCI) += pci_root.o pci_link.o pci_irq.o pci_bind.o obj-$(CONFIG_ACPI_POWER) += power.o obj-$(CONFIG_ACPI_PROCESSOR) += processor.o @@ -46,5 +47,6 @@ obj-$(CONFIG_ACPI_DEBUG) += debug.o obj-$(CONFIG_ACPI_NUMA) += numa.o obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o +obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.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-10-26 18:29:14 -07:00 +++ b/drivers/acpi/acpi_ksyms.c 2004-10-26 18:29:14 -07:00 @@ -102,6 +102,8 @@ EXPORT_SYMBOL(acpi_os_printf); EXPORT_SYMBOL(acpi_os_sleep); EXPORT_SYMBOL(acpi_os_stall); +EXPORT_SYMBOL(acpi_os_read_port); +EXPORT_SYMBOL(acpi_os_write_port); EXPORT_SYMBOL(acpi_os_signal); EXPORT_SYMBOL(acpi_os_queue_for_execution); EXPORT_SYMBOL(acpi_os_signal_semaphore); @@ -125,6 +127,7 @@ #ifdef CONFIG_ACPI_BUS EXPORT_SYMBOL(acpi_fadt); +EXPORT_SYMBOL(acpi_fadt_is_v1); EXPORT_SYMBOL(acpi_walk_namespace); EXPORT_SYMBOL(acpi_root_dir); EXPORT_SYMBOL(acpi_bus_get_device); diff -Nru a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c --- a/drivers/acpi/dispatcher/dsmthdat.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/dispatcher/dsmthdat.c 2004-10-26 18:29:14 -07:00 @@ -312,7 +312,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "obj %p op %X, ref count = %d [%s]\n", object, + "new_obj %p Opcode %X, Refs=%d [%s]\n", object, opcode, object->common.reference_count, acpi_ut_get_type_name (object->common.type))); @@ -572,7 +572,7 @@ ACPI_FUNCTION_TRACE ("ds_store_object_to_local"); - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n", opcode, index, obj_desc)); /* Parameter validation */ diff -Nru a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c --- a/drivers/acpi/dispatcher/dsutils.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/dispatcher/dsutils.c 2004-10-26 18:29:14 -07:00 @@ -333,7 +333,7 @@ u32 i; - ACPI_FUNCTION_TRACE_PTR ("acpi_ds_clear_operands", walk_state); + ACPI_FUNCTION_TRACE_PTR ("ds_clear_operands", walk_state); /* diff -Nru a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c --- a/drivers/acpi/dispatcher/dswexec.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/dispatcher/dswexec.c 2004-10-26 18:29:14 -07:00 @@ -60,17 +60,18 @@ * Dispatch table for opcode classes */ static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch [] = { - acpi_ex_opcode_1A_0T_0R, - acpi_ex_opcode_1A_0T_1R, - acpi_ex_opcode_1A_1T_0R, - acpi_ex_opcode_1A_1T_1R, - acpi_ex_opcode_2A_0T_0R, - acpi_ex_opcode_2A_0T_1R, - acpi_ex_opcode_2A_1T_1R, - acpi_ex_opcode_2A_2T_1R, - acpi_ex_opcode_3A_0T_0R, - acpi_ex_opcode_3A_1T_1R, - acpi_ex_opcode_6A_0T_1R}; + acpi_ex_opcode_0A_0T_1R, + acpi_ex_opcode_1A_0T_0R, + acpi_ex_opcode_1A_0T_1R, + acpi_ex_opcode_1A_1T_0R, + acpi_ex_opcode_1A_1T_1R, + acpi_ex_opcode_2A_0T_0R, + acpi_ex_opcode_2A_0T_1R, + acpi_ex_opcode_2A_1T_1R, + acpi_ex_opcode_2A_2T_1R, + acpi_ex_opcode_3A_0T_0R, + acpi_ex_opcode_3A_1T_1R, + acpi_ex_opcode_6A_0T_1R}; /***************************************************************************** * @@ -413,7 +414,7 @@ * routine. There is one routine per opcode "type" based upon the * number of opcode arguments and return type. */ - status = acpi_gbl_op_type_dispatch [op_type] (walk_state); + status = acpi_gbl_op_type_dispatch[op_type] (walk_state); } else { /* @@ -639,7 +640,8 @@ * conditional predicate */ - if ((walk_state->control_state) && + if ((ACPI_SUCCESS (status)) && + (walk_state->control_state) && (walk_state->control_state->common.state == ACPI_CONTROL_PREDICATE_EXECUTING) && (walk_state->control_state->control.predicate_op == op)) { @@ -649,6 +651,19 @@ cleanup: + + /* Invoke exception handler on error */ + + if (ACPI_FAILURE (status) && + acpi_gbl_exception_handler && + !(status & AE_CODE_CONTROL)) { + acpi_ex_exit_interpreter (); + status = acpi_gbl_exception_handler (status, + walk_state->method_node->name.integer, walk_state->opcode, + walk_state->aml_offset, NULL); + acpi_ex_enter_interpreter (); + } + if (walk_state->result_obj) { /* Break to debugger to display result */ diff -Nru a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c --- a/drivers/acpi/events/evgpe.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/events/evgpe.c 2004-10-26 18:29:14 -07:00 @@ -434,13 +434,8 @@ } 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), - status_reg, - ACPI_FORMAT_UINT64 ( - gpe_register_info->enable_address.address), - enable_reg)); + "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n", + gpe_register_info->base_gpe_number, status_reg, enable_reg)); /* First check if there is anything active at all in this register */ diff -Nru a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c --- a/drivers/acpi/events/evgpeblk.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/events/evgpeblk.c 2004-10-26 18:29:14 -07:00 @@ -970,15 +970,13 @@ /* 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", + "GPE %02X to %02X [%4.4s] %u regs 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 */ diff -Nru a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c --- a/drivers/acpi/events/evxface.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/events/evxface.c 2004-10-26 18:29:14 -07:00 @@ -53,6 +53,51 @@ /******************************************************************************* * + * FUNCTION: acpi_install_exception_handler + * + * PARAMETERS: Handler - Pointer to the handler function for the + * event + * + * RETURN: Status + * + * DESCRIPTION: Saves the pointer to the handler function + * + ******************************************************************************/ + +acpi_status +acpi_install_exception_handler ( + acpi_exception_handler handler) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("acpi_install_exception_handler"); + + + status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Don't allow two handlers. */ + + if (acpi_gbl_exception_handler) { + status = AE_ALREADY_EXISTS; + goto cleanup; + } + + /* Install the handler */ + + acpi_gbl_exception_handler = handler; + +cleanup: + (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * * FUNCTION: acpi_install_fixed_event_handler * * PARAMETERS: Event - Event type to enable. diff -Nru a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c --- a/drivers/acpi/executer/exconvrt.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/executer/exconvrt.c 2004-10-26 18:29:14 -07:00 @@ -58,7 +58,7 @@ * PARAMETERS: obj_desc - Object to be converted. Must be an * Integer, Buffer, or String * result_desc - Where the new Integer object is returned - * walk_state - Current method state + * Flags - Used for string conversion * * RETURN: Status * @@ -70,13 +70,13 @@ acpi_ex_convert_to_integer ( union acpi_operand_object *obj_desc, union acpi_operand_object **result_desc, - struct acpi_walk_state *walk_state) + u32 flags) { - u32 i; - union acpi_operand_object *ret_desc; - u32 count; + union acpi_operand_object *return_desc; u8 *pointer; acpi_integer result; + u32 i; + u32 count; acpi_status status; @@ -85,15 +85,17 @@ switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { case ACPI_TYPE_INTEGER: + + /* No conversion necessary */ + *result_desc = obj_desc; return_ACPI_STATUS (AE_OK); + case ACPI_TYPE_BUFFER: case ACPI_TYPE_STRING: - pointer = (u8 *) obj_desc->string.pointer; - count = obj_desc->string.length; - break; - case ACPI_TYPE_BUFFER: + /* Note: Takes advantage of common buffer/string fields */ + pointer = obj_desc->buffer.pointer; count = obj_desc->buffer.length; break; @@ -126,10 +128,12 @@ case ACPI_TYPE_STRING: /* - * Convert string to an integer - * String must be hexadecimal as per the ACPI specification + * Convert string to an integer - for most cases, the string must be + * hexadecimal as per the ACPI specification. The only exception (as + * of ACPI 3.0) is that the to_integer() operator allows both decimal + * and hexadecimal strings (hex prefixed with "0x"). */ - status = acpi_ut_strtoul64 ((char *) pointer, 16, &result); + status = acpi_ut_strtoul64 ((char *) pointer, flags, &result); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -139,8 +143,8 @@ case ACPI_TYPE_BUFFER: /* - * Buffer conversion - we simply grab enough raw data from the - * buffer to fill an integer + * Convert buffer to an integer - we simply grab enough raw data + * from the buffer to fill an integer */ for (i = 0; i < count; i++) { /* @@ -161,27 +165,15 @@ /* * Create a new integer */ - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc) { + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Save the Result */ - ret_desc->integer.value = result; - - /* - * If we are about to overwrite the original object on the operand stack, - * we must remove a reference on the original object because we are - * essentially removing it from the stack. - */ - if (*result_desc == obj_desc) { - if (walk_state->opcode != AML_STORE_OP) { - acpi_ut_remove_reference (obj_desc); - } - } - - *result_desc = ret_desc; + return_desc->integer.value = result; + *result_desc = return_desc; return_ACPI_STATUS (AE_OK); } @@ -193,7 +185,6 @@ * PARAMETERS: obj_desc - Object to be converted. Must be an * Integer, Buffer, or String * result_desc - Where the new buffer object is returned - * walk_state - Current method state * * RETURN: Status * @@ -204,11 +195,9 @@ acpi_status acpi_ex_convert_to_buffer ( union acpi_operand_object *obj_desc, - union acpi_operand_object **result_desc, - struct acpi_walk_state *walk_state) + union acpi_operand_object **result_desc) { - union acpi_operand_object *ret_desc; - u32 i; + union acpi_operand_object *return_desc; u8 *new_buf; @@ -230,17 +219,17 @@ * Create a new Buffer object. * Need enough space for one integer */ - ret_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width); - if (!ret_desc) { + return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width); + if (!return_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } - /* Copy the integer to the buffer */ + /* Copy the integer to the buffer, LSB first */ - new_buf = ret_desc->buffer.pointer; - for (i = 0; i < acpi_gbl_integer_byte_width; i++) { - new_buf[i] = (u8) (obj_desc->integer.value >> (i * 8)); - } + new_buf = return_desc->buffer.pointer; + ACPI_MEMCPY (new_buf, + &obj_desc->integer.value, + acpi_gbl_integer_byte_width); break; @@ -250,14 +239,14 @@ * Create a new Buffer object * Size will be the string length */ - ret_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length); - if (!ret_desc) { + return_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length); + if (!return_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Copy the string to the buffer */ - new_buf = ret_desc->buffer.pointer; + new_buf = return_desc->buffer.pointer; ACPI_STRNCPY ((char *) new_buf, (char *) obj_desc->string.pointer, obj_desc->string.length); break; @@ -269,32 +258,20 @@ /* Mark buffer initialized */ - ret_desc->common.flags |= AOPOBJ_DATA_VALID; - - /* - * If we are about to overwrite the original object on the operand stack, - * we must remove a reference on the original object because we are - * essentially removing it from the stack. - */ - if (*result_desc == obj_desc) { - if (walk_state->opcode != AML_STORE_OP) { - acpi_ut_remove_reference (obj_desc); - } - } - - *result_desc = ret_desc; + return_desc->common.flags |= AOPOBJ_DATA_VALID; + *result_desc = return_desc; return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_ex_convert_ascii + * FUNCTION: acpi_ex_convert_to_ascii * * PARAMETERS: Integer - Value to be converted - * Base - 10 or 16 + * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX * String - Where the string is returned - * data_width - Size of data item to be converted + * data_width - Size of data item to be converted, in bytes * * RETURN: Actual string length * @@ -305,79 +282,81 @@ u32 acpi_ex_convert_to_ascii ( acpi_integer integer, - u32 base, + u16 base, u8 *string, u8 data_width) { - u32 i; - u32 j; - u32 k = 0; - char hex_digit; acpi_integer digit; + acpi_native_uint i; + acpi_native_uint j; + acpi_native_uint k = 0; + acpi_native_uint hex_length; + acpi_native_uint decimal_length; u32 remainder; - u32 length; - u8 leading_zero; + u8 supress_zeros; ACPI_FUNCTION_ENTRY (); - if (data_width < sizeof (acpi_integer)) { - leading_zero = FALSE; - length = data_width; - } - else { - leading_zero = TRUE; - length = sizeof (acpi_integer); - } - switch (base) { case 10: + /* Setup max length for the decimal number */ + + switch (data_width) { + case 1: + decimal_length = ACPI_MAX8_DECIMAL_DIGITS; + break; + + case 4: + decimal_length = ACPI_MAX32_DECIMAL_DIGITS; + break; + + case 8: + default: + decimal_length = ACPI_MAX64_DECIMAL_DIGITS; + break; + } + + supress_zeros = TRUE; /* No leading zeros */ remainder = 0; - for (i = ACPI_MAX_DECIMAL_DIGITS; i > 0; i--) { + + for (i = decimal_length; i > 0; i--) { /* Divide by nth factor of 10 */ digit = integer; for (j = 0; j < i; j++) { - (void) acpi_ut_short_divide (&digit, 10, &digit, &remainder); + (void) acpi_ut_short_divide (digit, 10, &digit, &remainder); } - /* Create the decimal digit */ + /* Handle leading zeros */ if (remainder != 0) { - leading_zero = FALSE; + supress_zeros = FALSE; } - if (!leading_zero) { + if (!supress_zeros) { string[k] = (u8) (ACPI_ASCII_ZERO + remainder); k++; } } break; - case 16: - /* Copy the integer to the buffer */ + hex_length = ACPI_MUL_2 (data_width); /* 2 ascii hex chars per data byte */ - for (i = 0, j = ((length * 2) -1); i < (length * 2); i++, j--) { + for (i = 0, j = (hex_length-1); i < hex_length; i++, j--) { + /* Get one hex digit, most significant digits first */ - hex_digit = acpi_ut_hex_to_ascii_char (integer, (j * 4)); - if (hex_digit != ACPI_ASCII_ZERO) { - leading_zero = FALSE; - } - - if (!leading_zero) { - string[k] = (u8) hex_digit; - k++; - } + string[k] = (u8) acpi_ut_hex_to_ascii_char (integer, ACPI_MUL_4 (j)); + k++; } break; - default: - break; + return (0); } /* @@ -392,7 +371,7 @@ } string [k] = 0; - return (k); + return ((u32) k); } @@ -401,11 +380,9 @@ * FUNCTION: acpi_ex_convert_to_string * * PARAMETERS: obj_desc - Object to be converted. Must be an - * Integer, Buffer, or String + * Integer, Buffer, or String * result_desc - Where the string object is returned - * Base - 10 or 16 - * max_length - Max length of the returned string - * walk_state - Current method state + * Type - String flags (base and conversion type) * * RETURN: Status * @@ -417,15 +394,14 @@ acpi_ex_convert_to_string ( union acpi_operand_object *obj_desc, union acpi_operand_object **result_desc, - u32 base, - u32 max_length, - struct acpi_walk_state *walk_state) + u32 type) { - union acpi_operand_object *ret_desc; + union acpi_operand_object *return_desc; u8 *new_buf; - u8 *pointer; - u32 string_length; + u32 string_length = 0; + u16 base = 16; u32 i; + u8 separator = ','; ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_string", obj_desc); @@ -434,130 +410,129 @@ switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { case ACPI_TYPE_STRING: - if (max_length >= obj_desc->string.length) { - *result_desc = obj_desc; - return_ACPI_STATUS (AE_OK); - } - else { - /* Must copy the string first and then truncate it */ + /* No conversion necessary */ - return_ACPI_STATUS (AE_NOT_IMPLEMENTED); - } + *result_desc = obj_desc; + return_ACPI_STATUS (AE_OK); case ACPI_TYPE_INTEGER: - string_length = acpi_gbl_integer_byte_width * 2; - if (base == 10) { + switch (type) { + case ACPI_EXPLICIT_CONVERT_DECIMAL: + + /* Make room for maximum decimal number */ + string_length = ACPI_MAX_DECIMAL_DIGITS; + base = 10; + break; + + default: + + /* Two hex string characters for each integer byte */ + + string_length = ACPI_MUL_2 (acpi_gbl_integer_byte_width); + break; } /* * Create a new String + * Need enough space for one ASCII integer (plus null terminator) */ - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); - if (!ret_desc) { + return_desc = acpi_ut_create_string_object ((acpi_size) string_length); + if (!return_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } - /* Need enough space for one ASCII integer plus null terminator */ + new_buf = return_desc->buffer.pointer; - new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1); - if (!new_buf) { - ACPI_REPORT_ERROR - (("ex_convert_to_string: Buffer allocation failure\n")); - acpi_ut_remove_reference (ret_desc); - return_ACPI_STATUS (AE_NO_MEMORY); - } + /* Convert integer to string */ - /* Convert */ - - i = acpi_ex_convert_to_ascii (obj_desc->integer.value, base, new_buf, sizeof (acpi_integer)); + string_length = acpi_ex_convert_to_ascii (obj_desc->integer.value, base, + new_buf, acpi_gbl_integer_byte_width); /* Null terminate at the correct place */ - if (max_length < i) { - new_buf[max_length] = 0; - ret_desc->string.length = max_length; - } - else { - new_buf [i] = 0; - ret_desc->string.length = i; - } - - ret_desc->buffer.pointer = new_buf; + return_desc->string.length = string_length; + new_buf [string_length] = 0; break; case ACPI_TYPE_BUFFER: - /* Find the string length */ + switch (type) { + case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string operator */ + /* + * From ACPI: "If Data is a buffer, it is converted to a string of + * decimal values separated by commas." + */ + base = 10; + string_length = obj_desc->buffer.length; /* 4 chars for each decimal */ - pointer = obj_desc->buffer.pointer; - for (string_length = 0; string_length < obj_desc->buffer.length; string_length++) { - /* Exit on null terminator */ + /*lint -fallthrough */ - if (!pointer[string_length]) { - break; + case ACPI_IMPLICIT_CONVERT_HEX: + /* + * From the ACPI spec: + *"The entire contents of the buffer are converted to a string of + * two-character hexadecimal numbers, each separated by a space." + */ + if (type == ACPI_IMPLICIT_CONVERT_HEX) { + separator = ' '; } - } - if (max_length > ACPI_MAX_STRING_CONVERSION) { - if (string_length > ACPI_MAX_STRING_CONVERSION) { + /*lint -fallthrough */ + + case ACPI_EXPLICIT_CONVERT_HEX: /* Used by to_hex_string operator */ + /* + * From ACPI: "If Data is a buffer, it is converted to a string of + * hexadecimal values separated by commas." + */ + string_length += (obj_desc->buffer.length * 3); + if (string_length > ACPI_MAX_STRING_CONVERSION) /* ACPI limit */ { return_ACPI_STATUS (AE_AML_STRING_LIMIT); } - } - /* - * Create a new string object - */ - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); - if (!ret_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); - } + /* Create a new string object and string buffer */ - /* String length is the lesser of the Max or the actual length */ + return_desc = acpi_ut_create_string_object ((acpi_size) string_length -1); + if (!return_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } - if (max_length < string_length) { - string_length = max_length; - } + new_buf = return_desc->buffer.pointer; - new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1); - if (!new_buf) { - ACPI_REPORT_ERROR - (("ex_convert_to_string: Buffer allocation failure\n")); - acpi_ut_remove_reference (ret_desc); - return_ACPI_STATUS (AE_NO_MEMORY); - } + /* + * Convert buffer bytes to hex or decimal values + * (separated by commas) + */ + for (i = 0; i < obj_desc->buffer.length; i++) { + new_buf += acpi_ex_convert_to_ascii ( + (acpi_integer) obj_desc->buffer.pointer[i], base, + new_buf, 1); + *new_buf++ = separator; /* each separated by a comma or space */ + } - /* Copy the appropriate number of buffer characters */ + /* Null terminate the string (overwrites final comma from above) */ - ACPI_MEMCPY (new_buf, pointer, string_length); + new_buf--; + *new_buf = 0; - /* Null terminate */ + /* Recalculate length */ - new_buf [string_length] = 0; - ret_desc->buffer.pointer = new_buf; - ret_desc->string.length = string_length; - break; + return_desc->string.length = ACPI_STRLEN (return_desc->string.pointer); + break; + default: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + break; default: return_ACPI_STATUS (AE_TYPE); } - /* - * If we are about to overwrite the original object on the operand stack, - * we must remove a reference on the original object because we are - * essentially removing it from the stack. - */ - if (*result_desc == obj_desc) { - if (walk_state->opcode != AML_STORE_OP) { - acpi_ut_remove_reference (obj_desc); - } - } - - *result_desc = ret_desc; + *result_desc = return_desc; return_ACPI_STATUS (AE_OK); } @@ -635,7 +610,8 @@ * These types require an Integer operand. We can convert * a Buffer or a String to an Integer if necessary. */ - status = acpi_ex_convert_to_integer (source_desc, result_desc, walk_state); + status = acpi_ex_convert_to_integer (source_desc, result_desc, + 16); break; @@ -645,7 +621,8 @@ * The operand must be a String. We can convert an * Integer or Buffer if necessary */ - status = acpi_ex_convert_to_string (source_desc, result_desc, 16, ACPI_UINT32_MAX, walk_state); + status = acpi_ex_convert_to_string (source_desc, result_desc, + ACPI_IMPLICIT_CONVERT_HEX); break; @@ -655,7 +632,7 @@ * The operand must be a Buffer. We can convert an * Integer or String if necessary */ - status = acpi_ex_convert_to_buffer (source_desc, result_desc, walk_state); + status = acpi_ex_convert_to_buffer (source_desc, result_desc); break; diff -Nru a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c --- a/drivers/acpi/executer/exdump.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/executer/exdump.c 2004-10-26 18:29:14 -07:00 @@ -55,7 +55,6 @@ /* * The following routines are used for debug output only */ - #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /***************************************************************************** @@ -103,8 +102,8 @@ if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "%p is not a node or operand object: [%s]\n", - obj_desc, acpi_ut_get_descriptor_name (obj_desc))); + "%p is not a node or operand object: [%s]\n", + obj_desc, acpi_ut_get_descriptor_name (obj_desc))); ACPI_DUMP_BUFFER (obj_desc, sizeof (union acpi_operand_object)); return; } @@ -125,8 +124,8 @@ case AML_NAME_OP: - ACPI_DUMP_PATHNAME (obj_desc->reference.object, "Reference: Name: ", - ACPI_LV_INFO, _COMPONENT); + ACPI_DUMP_PATHNAME (obj_desc->reference.object, + "Reference: Name: ", ACPI_LV_INFO, _COMPONENT); ACPI_DUMP_ENTRY (obj_desc->reference.object, ACPI_LV_INFO); break; @@ -134,27 +133,27 @@ case AML_INDEX_OP: acpi_os_printf ("Reference: Index %p\n", - obj_desc->reference.object); + obj_desc->reference.object); break; case AML_REF_OF_OP: acpi_os_printf ("Reference: (ref_of) %p\n", - obj_desc->reference.object); + obj_desc->reference.object); break; case AML_ARG_OP: acpi_os_printf ("Reference: Arg%d", - obj_desc->reference.offset); + obj_desc->reference.offset); if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { /* Value is an Integer */ acpi_os_printf (" value is [%8.8X%8.8x]", - ACPI_FORMAT_UINT64 (obj_desc->integer.value)); + ACPI_FORMAT_UINT64 (obj_desc->integer.value)); } acpi_os_printf ("\n"); @@ -164,14 +163,14 @@ case AML_LOCAL_OP: acpi_os_printf ("Reference: Local%d", - obj_desc->reference.offset); + obj_desc->reference.offset); if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { /* Value is an Integer */ acpi_os_printf (" value is [%8.8X%8.8x]", - ACPI_FORMAT_UINT64 (obj_desc->integer.value)); + ACPI_FORMAT_UINT64 (obj_desc->integer.value)); } acpi_os_printf ("\n"); @@ -181,7 +180,7 @@ case AML_INT_NAMEPATH_OP: acpi_os_printf ("Reference.Node->Name %X\n", - obj_desc->reference.node->name.integer); + obj_desc->reference.node->name.integer); break; @@ -201,8 +200,7 @@ case ACPI_TYPE_BUFFER: acpi_os_printf ("Buffer len %X @ %p \n", - obj_desc->buffer.length, - obj_desc->buffer.pointer); + obj_desc->buffer.length, obj_desc->buffer.pointer); length = obj_desc->buffer.length; @@ -227,14 +225,14 @@ case ACPI_TYPE_INTEGER: acpi_os_printf ("Integer %8.8X%8.8X\n", - ACPI_FORMAT_UINT64 (obj_desc->integer.value)); + ACPI_FORMAT_UINT64 (obj_desc->integer.value)); break; case ACPI_TYPE_PACKAGE: acpi_os_printf ("Package count %X @ %p\n", - obj_desc->package.count, obj_desc->package.elements); + obj_desc->package.count, obj_desc->package.elements); /* * If elements exist, package vector pointer is valid, @@ -277,7 +275,7 @@ case ACPI_TYPE_STRING: acpi_os_printf ("String length %X @ %p ", - obj_desc->string.length, obj_desc->string.pointer); + obj_desc->string.length, obj_desc->string.pointer); acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX); acpi_os_printf ("\n"); break; @@ -387,10 +385,13 @@ * * FUNCTION: acpi_ex_dump_operands * - * PARAMETERS: interpreter_mode - Load or Exec - * *Ident - Identification + * PARAMETERS: Operands - Operand list + * interpreter_mode - Load or Exec + * Ident - Identification * num_levels - # of stack entries to dump above line - * *Note - Output notation + * Note - Output notation + * module_name - Caller's module name + * line_number - Caller's invocation line number * * DESCRIPTION: Dump the object stack * @@ -489,8 +490,7 @@ #if ACPI_MACHINE_WIDTH == 16 acpi_os_printf ("%20s : %p\n", title, value); #else - acpi_os_printf ("%20s : %8.8X%8.8X\n", title, - ACPI_FORMAT_UINT64 (value)); + acpi_os_printf ("%20s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64 (value)); #endif } @@ -563,22 +563,25 @@ if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) { acpi_ex_dump_node ((struct acpi_namespace_node *) obj_desc, flags); - acpi_os_printf ("\nAttached Object (%p):\n", ((struct acpi_namespace_node *) obj_desc)->object); - acpi_ex_dump_object_descriptor (((struct acpi_namespace_node *) obj_desc)->object, flags); - return; + acpi_os_printf ("\nAttached Object (%p):\n", + ((struct acpi_namespace_node *) obj_desc)->object); + acpi_ex_dump_object_descriptor ( + ((struct acpi_namespace_node *) obj_desc)->object, flags); + return_VOID; } if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) { - acpi_os_printf ("ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n", - obj_desc, acpi_ut_get_descriptor_name (obj_desc)); + acpi_os_printf ( + "ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n", + obj_desc, acpi_ut_get_descriptor_name (obj_desc)); return_VOID; } /* Common Fields */ - acpi_ex_out_string ("Type", acpi_ut_get_object_type_name (obj_desc)); + acpi_ex_out_string ("Type", acpi_ut_get_object_type_name (obj_desc)); acpi_ex_out_integer ("Reference Count", obj_desc->common.reference_count); - acpi_ex_out_integer ("Flags", obj_desc->common.flags); + acpi_ex_out_integer ("Flags", obj_desc->common.flags); /* Object-specific Fields */ @@ -592,7 +595,7 @@ case ACPI_TYPE_STRING: - acpi_ex_out_integer ("Length", obj_desc->string.length); + acpi_ex_out_integer ("Length", obj_desc->string.length); acpi_os_printf ("%20s : %p ", "Pointer", obj_desc->string.pointer); acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX); @@ -602,17 +605,17 @@ case ACPI_TYPE_BUFFER: - acpi_ex_out_integer ("Length", obj_desc->buffer.length); - acpi_ex_out_pointer ("Pointer", obj_desc->buffer.pointer); + acpi_ex_out_integer ("Length", obj_desc->buffer.length); + acpi_ex_out_pointer ("Pointer", obj_desc->buffer.pointer); ACPI_DUMP_BUFFER (obj_desc->buffer.pointer, obj_desc->buffer.length); break; case ACPI_TYPE_PACKAGE: - acpi_ex_out_integer ("Flags", obj_desc->package.flags); - acpi_ex_out_integer ("Count", obj_desc->package.count); - acpi_ex_out_pointer ("Elements", obj_desc->package.elements); + acpi_ex_out_integer ("Flags", obj_desc->package.flags); + acpi_ex_out_integer ("Count", obj_desc->package.count); + acpi_ex_out_pointer ("Elements", obj_desc->package.elements); /* Dump the package contents */ @@ -621,7 +624,8 @@ for (i = 0; i < obj_desc->package.count; i++) { acpi_os_printf ("[%.3d] %p", i, obj_desc->package.elements[i]); if (obj_desc->package.elements[i]) { - acpi_os_printf (" %s", acpi_ut_get_object_type_name (obj_desc->package.elements[i])); + acpi_os_printf (" %s", + acpi_ut_get_object_type_name (obj_desc->package.elements[i])); } acpi_os_printf ("\n"); } @@ -639,38 +643,38 @@ case ACPI_TYPE_EVENT: - acpi_ex_out_pointer ("Semaphore", obj_desc->event.semaphore); + acpi_ex_out_pointer ("Semaphore", obj_desc->event.semaphore); break; case ACPI_TYPE_METHOD: - acpi_ex_out_integer ("param_count", obj_desc->method.param_count); - acpi_ex_out_integer ("Concurrency", obj_desc->method.concurrency); - acpi_ex_out_pointer ("Semaphore", obj_desc->method.semaphore); - acpi_ex_out_integer ("owning_id", obj_desc->method.owning_id); - acpi_ex_out_integer ("aml_length", obj_desc->method.aml_length); - acpi_ex_out_pointer ("aml_start", obj_desc->method.aml_start); + acpi_ex_out_integer ("param_count", obj_desc->method.param_count); + acpi_ex_out_integer ("Concurrency", obj_desc->method.concurrency); + acpi_ex_out_pointer ("Semaphore", obj_desc->method.semaphore); + acpi_ex_out_integer ("owning_id", obj_desc->method.owning_id); + acpi_ex_out_integer ("aml_length", obj_desc->method.aml_length); + acpi_ex_out_pointer ("aml_start", obj_desc->method.aml_start); break; case ACPI_TYPE_MUTEX: - acpi_ex_out_integer ("sync_level", obj_desc->mutex.sync_level); + acpi_ex_out_integer ("sync_level", obj_desc->mutex.sync_level); acpi_ex_out_pointer ("owner_thread", obj_desc->mutex.owner_thread); - acpi_ex_out_integer ("acquisition_depth",obj_desc->mutex.acquisition_depth); - acpi_ex_out_pointer ("Semaphore", obj_desc->mutex.semaphore); + acpi_ex_out_integer ("acquire_depth", obj_desc->mutex.acquisition_depth); + acpi_ex_out_pointer ("Semaphore", obj_desc->mutex.semaphore); break; case ACPI_TYPE_REGION: - acpi_ex_out_integer ("space_id", obj_desc->region.space_id); - acpi_ex_out_integer ("Flags", obj_desc->region.flags); - acpi_ex_out_address ("Address", obj_desc->region.address); - acpi_ex_out_integer ("Length", obj_desc->region.length); - acpi_ex_out_pointer ("Handler", obj_desc->region.handler); - acpi_ex_out_pointer ("Next", obj_desc->region.next); + acpi_ex_out_integer ("space_id", obj_desc->region.space_id); + acpi_ex_out_integer ("Flags", obj_desc->region.flags); + acpi_ex_out_address ("Address", obj_desc->region.address); + acpi_ex_out_integer ("Length", obj_desc->region.length); + acpi_ex_out_pointer ("Handler", obj_desc->region.handler); + acpi_ex_out_pointer ("Next", obj_desc->region.next); break; @@ -686,11 +690,11 @@ case ACPI_TYPE_PROCESSOR: acpi_ex_out_integer ("Processor ID", obj_desc->processor.proc_id); - acpi_ex_out_integer ("Length", obj_desc->processor.length); - acpi_ex_out_address ("Address", (acpi_physical_address) obj_desc->processor.address); + acpi_ex_out_integer ("Length", obj_desc->processor.length); + acpi_ex_out_address ("Address", (acpi_physical_address) obj_desc->processor.address); acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify); - acpi_ex_out_pointer ("Handler", obj_desc->processor.handler); + acpi_ex_out_pointer ("Handler", obj_desc->processor.handler); break; @@ -698,7 +702,7 @@ acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify); - acpi_ex_out_pointer ("Handler", obj_desc->thermal_zone.handler); + acpi_ex_out_pointer ("Handler", obj_desc->thermal_zone.handler); break; @@ -707,35 +711,35 @@ case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: - acpi_ex_out_integer ("field_flags", obj_desc->common_field.field_flags); - acpi_ex_out_integer ("access_byte_width", obj_desc->common_field.access_byte_width); - acpi_ex_out_integer ("bit_length", obj_desc->common_field.bit_length); + acpi_ex_out_integer ("field_flags", obj_desc->common_field.field_flags); + acpi_ex_out_integer ("access_byte_width",obj_desc->common_field.access_byte_width); + acpi_ex_out_integer ("bit_length", obj_desc->common_field.bit_length); acpi_ex_out_integer ("fld_bit_offset", obj_desc->common_field.start_field_bit_offset); acpi_ex_out_integer ("base_byte_offset", obj_desc->common_field.base_byte_offset); acpi_ex_out_integer ("datum_valid_bits", obj_desc->common_field.datum_valid_bits); - acpi_ex_out_integer ("end_fld_valid_bits", obj_desc->common_field.end_field_valid_bits); - acpi_ex_out_integer ("end_buf_valid_bits", obj_desc->common_field.end_buffer_valid_bits); - acpi_ex_out_pointer ("parent_node", obj_desc->common_field.node); + acpi_ex_out_integer ("end_fld_valid_bits",obj_desc->common_field.end_field_valid_bits); + acpi_ex_out_integer ("end_buf_valid_bits",obj_desc->common_field.end_buffer_valid_bits); + acpi_ex_out_pointer ("parent_node", obj_desc->common_field.node); switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { case ACPI_TYPE_BUFFER_FIELD: - acpi_ex_out_pointer ("buffer_obj", obj_desc->buffer_field.buffer_obj); + acpi_ex_out_pointer ("buffer_obj", obj_desc->buffer_field.buffer_obj); break; case ACPI_TYPE_LOCAL_REGION_FIELD: - acpi_ex_out_pointer ("region_obj", obj_desc->field.region_obj); + acpi_ex_out_pointer ("region_obj", obj_desc->field.region_obj); break; case ACPI_TYPE_LOCAL_BANK_FIELD: - acpi_ex_out_integer ("Value", obj_desc->bank_field.value); - acpi_ex_out_pointer ("region_obj", obj_desc->bank_field.region_obj); - acpi_ex_out_pointer ("bank_obj", obj_desc->bank_field.bank_obj); + acpi_ex_out_integer ("Value", obj_desc->bank_field.value); + acpi_ex_out_pointer ("region_obj", obj_desc->bank_field.region_obj); + acpi_ex_out_pointer ("bank_obj", obj_desc->bank_field.bank_obj); break; case ACPI_TYPE_LOCAL_INDEX_FIELD: - acpi_ex_out_integer ("Value", obj_desc->index_field.value); - acpi_ex_out_pointer ("Index", obj_desc->index_field.index_obj); - acpi_ex_out_pointer ("Data", obj_desc->index_field.data_obj); + acpi_ex_out_integer ("Value", obj_desc->index_field.value); + acpi_ex_out_pointer ("Index", obj_desc->index_field.index_obj); + acpi_ex_out_pointer ("Data", obj_desc->index_field.data_obj); break; default: @@ -747,29 +751,29 @@ case ACPI_TYPE_LOCAL_REFERENCE: - acpi_ex_out_integer ("target_type", obj_desc->reference.target_type); - acpi_ex_out_string ("Opcode", (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name); - acpi_ex_out_integer ("Offset", obj_desc->reference.offset); - acpi_ex_out_pointer ("obj_desc", obj_desc->reference.object); - acpi_ex_out_pointer ("Node", obj_desc->reference.node); - acpi_ex_out_pointer ("Where", obj_desc->reference.where); + acpi_ex_out_integer ("target_type", obj_desc->reference.target_type); + acpi_ex_out_string ("Opcode", (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name); + acpi_ex_out_integer ("Offset", obj_desc->reference.offset); + acpi_ex_out_pointer ("obj_desc", obj_desc->reference.object); + acpi_ex_out_pointer ("Node", obj_desc->reference.node); + acpi_ex_out_pointer ("Where", obj_desc->reference.where); break; case ACPI_TYPE_LOCAL_ADDRESS_HANDLER: - acpi_ex_out_integer ("space_id", obj_desc->address_space.space_id); - acpi_ex_out_pointer ("Next", obj_desc->address_space.next); - acpi_ex_out_pointer ("region_list", obj_desc->address_space.region_list); - acpi_ex_out_pointer ("Node", obj_desc->address_space.node); - acpi_ex_out_pointer ("Context", obj_desc->address_space.context); + acpi_ex_out_integer ("space_id", obj_desc->address_space.space_id); + acpi_ex_out_pointer ("Next", obj_desc->address_space.next); + acpi_ex_out_pointer ("region_list", obj_desc->address_space.region_list); + acpi_ex_out_pointer ("Node", obj_desc->address_space.node); + acpi_ex_out_pointer ("Context", obj_desc->address_space.context); break; case ACPI_TYPE_LOCAL_NOTIFY: - acpi_ex_out_pointer ("Node", obj_desc->notify.node); - acpi_ex_out_pointer ("Context", obj_desc->notify.context); + acpi_ex_out_pointer ("Node", obj_desc->notify.node); + acpi_ex_out_pointer ("Context", obj_desc->notify.context); break; @@ -779,7 +783,8 @@ case ACPI_TYPE_LOCAL_DATA: default: - acpi_os_printf ("ex_dump_object_descriptor: Display not implemented for object type %s\n", + acpi_os_printf ( + "ex_dump_object_descriptor: Display not implemented for object type %s\n", acpi_ut_get_object_type_name (obj_desc)); break; } diff -Nru a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c --- a/drivers/acpi/executer/exfldio.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/executer/exfldio.c 2004-10-26 18:29:14 -07:00 @@ -139,7 +139,7 @@ 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 + + (acpi_native_uint) obj_desc->common_field.access_byte_width + field_datum_byte_offset)) { return_ACPI_STATUS (AE_OK); } diff -Nru a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c --- a/drivers/acpi/executer/exmisc.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/executer/exmisc.c 2004-10-26 18:29:14 -07:00 @@ -149,8 +149,9 @@ * * FUNCTION: acpi_ex_concat_template * - * PARAMETERS: *obj_desc - Object to be converted. Must be an - * Integer, Buffer, or String + * PARAMETERS: Operand0 - First source object + * Operand1 - Second source object + * actual_return_desc - Where to place the return object * walk_state - Current walk state * * RETURN: Status @@ -161,8 +162,8 @@ acpi_status acpi_ex_concat_template ( - union acpi_operand_object *obj_desc1, - union acpi_operand_object *obj_desc2, + union acpi_operand_object *operand0, + union acpi_operand_object *operand1, union acpi_operand_object **actual_return_desc, struct acpi_walk_state *walk_state) { @@ -179,16 +180,16 @@ /* Find the end_tags in each resource template */ - end_tag1 = acpi_ut_get_resource_end_tag (obj_desc1); - end_tag2 = acpi_ut_get_resource_end_tag (obj_desc2); + end_tag1 = acpi_ut_get_resource_end_tag (operand0); + end_tag2 = acpi_ut_get_resource_end_tag (operand1); if (!end_tag1 || !end_tag2) { return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* Compute the length of each part */ - length1 = ACPI_PTR_DIFF (end_tag1, obj_desc1->buffer.pointer); - length2 = ACPI_PTR_DIFF (end_tag2, obj_desc2->buffer.pointer) + + length1 = ACPI_PTR_DIFF (end_tag1, operand0->buffer.pointer); + length2 = ACPI_PTR_DIFF (end_tag2, operand1->buffer.pointer) + 2; /* Size of END_TAG */ /* Create a new buffer object for the result */ @@ -201,8 +202,8 @@ /* Copy the templates to the new descriptor */ new_buf = return_desc->buffer.pointer; - ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer, length1); - ACPI_MEMCPY (new_buf + length1, obj_desc2->buffer.pointer, length2); + ACPI_MEMCPY (new_buf, operand0->buffer.pointer, length1); + ACPI_MEMCPY (new_buf + length1, operand1->buffer.pointer, length2); /* Compute the new checksum */ @@ -221,8 +222,8 @@ * * FUNCTION: acpi_ex_do_concatenate * - * PARAMETERS: obj_desc1 - First source object - * obj_desc2 - Second source object + * PARAMETERS: Operand0 - First source object + * Operand1 - Second source object * actual_return_desc - Where to place the return object * walk_state - Current walk state * @@ -234,20 +235,57 @@ acpi_status acpi_ex_do_concatenate ( - union acpi_operand_object *obj_desc1, - union acpi_operand_object *obj_desc2, + union acpi_operand_object *operand0, + union acpi_operand_object *operand1, union acpi_operand_object **actual_return_desc, struct acpi_walk_state *walk_state) { - acpi_status status; - u32 i; - acpi_integer this_integer; + union acpi_operand_object *local_operand1 = operand1; union acpi_operand_object *return_desc; char *new_buf; + acpi_status status; + acpi_size new_length; - ACPI_FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE ("ex_do_concatenate"); + + + /* + * Convert the second operand if necessary. The first operand + * determines the type of the second operand, (See the Data Types + * section of the ACPI specification.) Both object types are + * guaranteed to be either Integer/String/Buffer by the operand + * resolution mechanism. + */ + switch (ACPI_GET_OBJECT_TYPE (operand0)) { + case ACPI_TYPE_INTEGER: + status = acpi_ex_convert_to_integer (operand1, &local_operand1, 16); + break; + + case ACPI_TYPE_STRING: + status = acpi_ex_convert_to_string (operand1, &local_operand1, + ACPI_IMPLICIT_CONVERT_HEX); + break; + + case ACPI_TYPE_BUFFER: + status = acpi_ex_convert_to_buffer (operand1, &local_operand1); + break; + + default: + ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n", + ACPI_GET_OBJECT_TYPE (operand0))); + status = AE_AML_INTERNAL; + } + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + /* + * Both operands are now known to be the same object type + * (Both are Integer, String, or Buffer), and we can now perform the + * concatenation. + */ /* * There are three cases to handle: @@ -256,113 +294,102 @@ * 2) Two Strings concatenated to produce a new String * 3) Two Buffers concatenated to produce a new Buffer */ - switch (ACPI_GET_OBJECT_TYPE (obj_desc1)) { + switch (ACPI_GET_OBJECT_TYPE (operand0)) { case ACPI_TYPE_INTEGER: /* Result of two Integers is a Buffer */ /* Need enough buffer space for two integers */ - return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width * 2); + return_desc = acpi_ut_create_buffer_object ( + ACPI_MUL_2 (acpi_gbl_integer_byte_width)); if (!return_desc) { - return (AE_NO_MEMORY); + status = AE_NO_MEMORY; + goto cleanup; } new_buf = (char *) return_desc->buffer.pointer; - /* Convert the first integer */ - - this_integer = obj_desc1->integer.value; - for (i = 0; i < acpi_gbl_integer_byte_width; i++) { - new_buf[i] = (char) this_integer; - this_integer >>= 8; - } + /* Copy the first integer, LSB first */ - /* Convert the second integer */ + ACPI_MEMCPY (new_buf, + &operand0->integer.value, + acpi_gbl_integer_byte_width); - this_integer = obj_desc2->integer.value; - for (; i < (ACPI_MUL_2 (acpi_gbl_integer_byte_width)); i++) { - new_buf[i] = (char) this_integer; - this_integer >>= 8; - } + /* Copy the second integer (LSB first) after the first */ + ACPI_MEMCPY (new_buf + acpi_gbl_integer_byte_width, + &local_operand1->integer.value, + acpi_gbl_integer_byte_width); break; - case ACPI_TYPE_STRING: /* Result of two Strings is a String */ - return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); - if (!return_desc) { - return (AE_NO_MEMORY); + new_length = (acpi_size) operand0->string.length + + (acpi_size) local_operand1->string.length; + if (new_length > ACPI_MAX_STRING_CONVERSION) { + status = AE_AML_STRING_LIMIT; + goto cleanup; } - /* Operand0 is string */ - - new_buf = ACPI_MEM_CALLOCATE ((acpi_size) obj_desc1->string.length + - (acpi_size) obj_desc2->string.length + 1); - if (!new_buf) { - ACPI_REPORT_ERROR - (("ex_do_concatenate: String allocation failure\n")); + return_desc = acpi_ut_create_string_object (new_length); + if (!return_desc) { status = AE_NO_MEMORY; goto cleanup; } + new_buf = return_desc->string.pointer; + /* Concatenate the strings */ - ACPI_STRCPY (new_buf, obj_desc1->string.pointer); - ACPI_STRCPY (new_buf + obj_desc1->string.length, - obj_desc2->string.pointer); - - /* Complete the String object initialization */ - - return_desc->string.pointer = new_buf; - return_desc->string.length = obj_desc1->string.length + - obj_desc2->string.length; + ACPI_STRCPY (new_buf, + operand0->string.pointer); + ACPI_STRCPY (new_buf + operand0->string.length, + local_operand1->string.pointer); break; - case ACPI_TYPE_BUFFER: /* Result of two Buffers is a Buffer */ return_desc = acpi_ut_create_buffer_object ( - (acpi_size) obj_desc1->buffer.length + - (acpi_size) obj_desc2->buffer.length); + (acpi_size) operand0->buffer.length + + (acpi_size) local_operand1->buffer.length); if (!return_desc) { - return (AE_NO_MEMORY); + status = AE_NO_MEMORY; + goto cleanup; } new_buf = (char *) return_desc->buffer.pointer; /* Concatenate the buffers */ - ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer, - obj_desc1->buffer.length); - ACPI_MEMCPY (new_buf + obj_desc1->buffer.length, obj_desc2->buffer.pointer, - obj_desc2->buffer.length); - + ACPI_MEMCPY (new_buf, + operand0->buffer.pointer, + operand0->buffer.length); + ACPI_MEMCPY (new_buf + operand0->buffer.length, + local_operand1->buffer.pointer, + local_operand1->buffer.length); break; - default: /* Invalid object type, should not happen here */ - ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n", - ACPI_GET_OBJECT_TYPE (obj_desc1))); - status = AE_AML_INTERNAL; - return_desc = NULL; + ACPI_REPORT_ERROR (("Concatenate - Invalid object type: %X\n", + ACPI_GET_OBJECT_TYPE (operand0))); + status =AE_AML_INTERNAL; + goto cleanup; } *actual_return_desc = return_desc; - return (AE_OK); - cleanup: - - acpi_ut_remove_reference (return_desc); - return (status); + if (local_operand1 != operand1) { + acpi_ut_remove_reference (local_operand1); + } + return_ACPI_STATUS (AE_OK); } @@ -371,8 +398,8 @@ * FUNCTION: acpi_ex_do_math_op * * PARAMETERS: Opcode - AML opcode - * Operand0 - Integer operand #0 - * Operand1 - Integer operand #1 + * Integer0 - Integer operand #0 + * Integer1 - Integer operand #1 * * RETURN: Integer result of the operation * @@ -385,62 +412,62 @@ acpi_integer acpi_ex_do_math_op ( u16 opcode, - acpi_integer operand0, - acpi_integer operand1) + acpi_integer integer0, + acpi_integer integer1) { ACPI_FUNCTION_ENTRY (); switch (opcode) { - case AML_ADD_OP: /* Add (Operand0, Operand1, Result) */ + case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */ - return (operand0 + operand1); + return (integer0 + integer1); - case AML_BIT_AND_OP: /* And (Operand0, Operand1, Result) */ + case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */ - return (operand0 & operand1); + return (integer0 & integer1); - case AML_BIT_NAND_OP: /* NAnd (Operand0, Operand1, Result) */ + case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */ - return (~(operand0 & operand1)); + return (~(integer0 & integer1)); - case AML_BIT_OR_OP: /* Or (Operand0, Operand1, Result) */ + case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */ - return (operand0 | operand1); + return (integer0 | integer1); - case AML_BIT_NOR_OP: /* NOr (Operand0, Operand1, Result) */ + case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */ - return (~(operand0 | operand1)); + return (~(integer0 | integer1)); - case AML_BIT_XOR_OP: /* XOr (Operand0, Operand1, Result) */ + case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */ - return (operand0 ^ operand1); + return (integer0 ^ integer1); - case AML_MULTIPLY_OP: /* Multiply (Operand0, Operand1, Result) */ + case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */ - return (operand0 * operand1); + return (integer0 * integer1); case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */ - return (operand0 << operand1); + return (integer0 << integer1); case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */ - return (operand0 >> operand1); + return (integer0 >> integer1); - case AML_SUBTRACT_OP: /* Subtract (Operand0, Operand1, Result) */ + case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */ - return (operand0 - operand1); + return (integer0 - integer1); default: @@ -451,20 +478,84 @@ /******************************************************************************* * + * FUNCTION: acpi_ex_do_logical_numeric_op + * + * PARAMETERS: Opcode - AML opcode + * Integer0 - Integer operand #0 + * Integer1 - Integer operand #1 + * logical_result - TRUE/FALSE result of the operation + * + * RETURN: Status + * + * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric + * operators (LAnd and LOr), both operands must be integers. + * + * Note: cleanest machine code seems to be produced by the code + * below, rather than using statements of the form: + * Result = (Integer0 && Integer1); + * + ******************************************************************************/ + +acpi_status +acpi_ex_do_logical_numeric_op ( + u16 opcode, + acpi_integer integer0, + acpi_integer integer1, + u8 *logical_result) +{ + acpi_status status = AE_OK; + u8 local_result = FALSE; + + + ACPI_FUNCTION_TRACE ("ex_do_logical_numeric_op"); + + + switch (opcode) { + case AML_LAND_OP: /* LAnd (Integer0, Integer1) */ + + if (integer0 && integer1) { + local_result = TRUE; + } + break; + + case AML_LOR_OP: /* LOr (Integer0, Integer1) */ + + if (integer0 || integer1) { + local_result = TRUE; + } + break; + + default: + status = AE_AML_INTERNAL; + break; + } + + /* Return the logical result and status */ + + *logical_result = local_result; + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * * FUNCTION: acpi_ex_do_logical_op * * PARAMETERS: Opcode - AML opcode - * obj_desc0 - operand #0 - * obj_desc1 - operand #1 + * Operand0 - operand #0 + * Operand1 - operand #1 + * logical_result - TRUE/FALSE result of the operation * - * RETURN: TRUE/FALSE result of the operation + * RETURN: Status * * 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. Both operands must already be validated as - * 1) Both the same type, and - * 2) Either Integer, Buffer, or String type. + * logical value. For the Numeric operators (LAnd and LOr), both + * operands must be integers. For the other logical operators, + * operands can be any combination of Integer/String/Buffer. The + * first operand determines the type to which the second operand + * will be converted. * * Note: cleanest machine code seems to be produced by the code * below, rather than using statements of the form: @@ -472,143 +563,175 @@ * ******************************************************************************/ -u8 +acpi_status acpi_ex_do_logical_op ( u16 opcode, - union acpi_operand_object *obj_desc0, - union acpi_operand_object *obj_desc1) + union acpi_operand_object *operand0, + union acpi_operand_object *operand1, + u8 *logical_result) { - acpi_integer operand0; - acpi_integer operand1; - u8 *ptr0; - u8 *ptr1; + union acpi_operand_object *local_operand1 = operand1; + acpi_integer integer0; + acpi_integer integer1; u32 length0; u32 length1; - u32 i; + acpi_status status = AE_OK; + u8 local_result = FALSE; + int compare; - ACPI_FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE ("ex_do_logical_op"); - if (ACPI_GET_OBJECT_TYPE (obj_desc0) == ACPI_TYPE_INTEGER) { - /* Both operands are of type integer */ + /* + * Convert the second operand if necessary. The first operand + * determines the type of the second operand, (See the Data Types + * section of the ACPI 3.0+ specification.) Both object types are + * guaranteed to be either Integer/String/Buffer by the operand + * resolution mechanism. + */ + switch (ACPI_GET_OBJECT_TYPE (operand0)) { + case ACPI_TYPE_INTEGER: + status = acpi_ex_convert_to_integer (operand1, &local_operand1, 16); + break; - operand0 = obj_desc0->integer.value; - operand1 = obj_desc1->integer.value; + case ACPI_TYPE_STRING: + status = acpi_ex_convert_to_string (operand1, &local_operand1, + ACPI_IMPLICIT_CONVERT_HEX); + break; - switch (opcode) { - case AML_LAND_OP: /* LAnd (Operand0, Operand1) */ + case ACPI_TYPE_BUFFER: + status = acpi_ex_convert_to_buffer (operand1, &local_operand1); + break; - if (operand0 && operand1) { - return (TRUE); - } - break; + default: + status = AE_AML_INTERNAL; + break; + } + + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + /* + * Two cases: 1) Both Integers, 2) Both Strings or Buffers + */ + if (ACPI_GET_OBJECT_TYPE (operand0) == ACPI_TYPE_INTEGER) { + /* + * 1) Both operands are of type integer + * Note: local_operand1 may have changed above + */ + integer0 = operand0->integer.value; + integer1 = local_operand1->integer.value; + switch (opcode) { case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ - if (operand0 == operand1) { - return (TRUE); + if (integer0 == integer1) { + local_result = TRUE; } break; case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ - if (operand0 > operand1) { - return (TRUE); + if (integer0 > integer1) { + local_result = TRUE; } break; case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ - if (operand0 < operand1) { - return (TRUE); - } - break; - - case AML_LOR_OP: /* LOr (Operand0, Operand1) */ - - if (operand0 || operand1) { - return (TRUE); + if (integer0 < integer1) { + local_result = TRUE; } break; default: + status = AE_AML_INTERNAL; break; } } else { /* - * Case for Buffer/String objects. - * NOTE: takes advantage of common Buffer/String object fields + * 2) Both operands are Strings or both are Buffers + * Note: Code below takes advantage of common Buffer/String + * object fields. local_operand1 may have changed above. Use + * memcmp to handle nulls in buffers. */ - length0 = obj_desc0->buffer.length; - ptr0 = obj_desc0->buffer.pointer; + length0 = operand0->buffer.length; + length1 = local_operand1->buffer.length; + + /* Lexicographic compare: compare the data bytes */ - length1 = obj_desc1->buffer.length; - ptr1 = obj_desc1->buffer.pointer; + compare = ACPI_MEMCMP ((const char * ) operand0->buffer.pointer, + (const char * ) local_operand1->buffer.pointer, + (length0 > length1) ? length1 : length0); switch (opcode) { case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ /* Length and all bytes must be equal */ - if (length0 != length1) { - return (FALSE); - } + if ((length0 == length1) && + (compare == 0)) { + /* Length and all bytes match ==> TRUE */ - for (i = 0; i < length0; i++) { - if (ptr0[i] != ptr1[i]) { - return (FALSE); - } + local_result = TRUE; } - return (TRUE); + 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); - } + if (compare > 0) { + local_result = TRUE; + goto cleanup; /* TRUE */ + } + if (compare < 0) { + goto cleanup; /* FALSE */ } - /* Bytes match, now check lengths */ + /* Bytes match (to shortest length), compare lengths */ if (length0 > length1) { - return (TRUE); + local_result = TRUE; } - - /* Length0 <= Length1 */ - - return (FALSE); + break; 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); - } + if (compare > 0) { + goto cleanup; /* FALSE */ + } + if (compare < 0) { + local_result = TRUE; + goto cleanup; /* TRUE */ } - /* Bytes match, now check lengths */ + /* Bytes match (to shortest length), compare lengths */ if (length0 < length1) { - return (TRUE); + local_result = TRUE; } - - /* Length0 >= Length1 */ - - return (FALSE); + break; default: + status = AE_AML_INTERNAL; break; } } - return (FALSE); +cleanup: + + /* New object was created if implicit conversion performed - delete */ + + if (local_operand1 != operand1) { + acpi_ut_remove_reference (local_operand1); + } + + /* Return the logical result and status */ + + *logical_result = local_result; + return_ACPI_STATUS (status); } diff -Nru a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c --- a/drivers/acpi/executer/exoparg1.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/executer/exoparg1.c 2004-10-26 18:29:14 -07:00 @@ -67,7 +67,7 @@ * Where: * * xA - ARGUMENTS: The number of arguments (input operands) that are - * required for this opcode type (1 through 6 args). + * required for this opcode type (0 through 6 args). * yT - TARGETS: The number of targets (output operands) that are required * for this opcode type (0, 1, or 2 targets). * zR - RETURN VALUE: Indicates whether this opcode type returns a value @@ -79,6 +79,69 @@ /******************************************************************************* * + * FUNCTION: acpi_ex_opcode_0A_0T_1R + * + * PARAMETERS: walk_state - Current state (contains AML opcode) + * + * RETURN: Status + * + * DESCRIPTION: Execute operator with no operands, one return value + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_0A_0T_1R ( + struct acpi_walk_state *walk_state) +{ + acpi_status status = AE_OK; + union acpi_operand_object *return_desc = NULL; + + + ACPI_FUNCTION_TRACE_STR ("ex_opcode_0A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + /* Examine the AML opcode */ + + switch (walk_state->opcode) { + case AML_TIMER_OP: /* Timer () */ + + /* Create a return object of type Integer */ + + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + return_desc->integer.value = acpi_os_get_timer (); + break; + + default: /* Unknown opcode */ + + ACPI_REPORT_ERROR (("acpi_ex_opcode_0A_0T_1R: Unknown opcode %X\n", + walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + break; + } + +cleanup: + + if (!walk_state->result_obj) { + walk_state->result_obj = return_desc; + } + + /* Delete return object on error */ + + if (ACPI_FAILURE (status)) { + acpi_ut_remove_reference (return_desc); + } + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * * FUNCTION: acpi_ex_opcode_1A_0T_0R * * PARAMETERS: walk_state - Current state (contains AML opcode) @@ -124,7 +187,7 @@ case AML_SLEEP_OP: /* Sleep (msec_time) */ - status = acpi_ex_system_do_suspend ((u32) operand[0]->integer.value); + status = acpi_ex_system_do_suspend (operand[0]->integer.value); break; @@ -222,7 +285,7 @@ union acpi_operand_object *return_desc2 = NULL; u32 temp32; u32 i; - u32 power_of_ten; + acpi_integer power_of_ten; acpi_integer digit; @@ -262,7 +325,8 @@ * Acpi specification describes Integer type as a little * endian unsigned value, so this boundary condition is valid. */ - for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { + for (temp32 = 0; return_desc->integer.value && + temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { return_desc->integer.value >>= 1; } @@ -278,13 +342,15 @@ * The Acpi specification describes Integer type as a little * endian unsigned value, so this boundary condition is valid. */ - for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { + for (temp32 = 0; return_desc->integer.value && + temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { return_desc->integer.value <<= 1; } /* Since the bit position is one-based, subtract from 33 (65) */ - return_desc->integer.value = temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32; + return_desc->integer.value = temp32 == 0 ? 0 : + (ACPI_INTEGER_BIT_SIZE + 1) - temp32; break; @@ -319,7 +385,8 @@ /* Sum the digit into the result with the current power of 10 */ - return_desc->integer.value += (((acpi_integer) temp32) * power_of_ten); + return_desc->integer.value += (((acpi_integer) temp32) * + power_of_ten); /* Shift to next BCD digit */ @@ -340,18 +407,20 @@ /* Each BCD digit is one nybble wide */ for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) { - (void) acpi_ut_short_divide (&digit, 10, &digit, &temp32); + (void) acpi_ut_short_divide (digit, 10, &digit, &temp32); /* Insert the BCD digit that resides in the remainder from above */ - return_desc->integer.value |= (((acpi_integer) temp32) << (i * 4)); + return_desc->integer.value |= (((acpi_integer) temp32) << + ACPI_MUL_4 (i)); } /* Overflow if there is any data left in Digit */ if (digit > 0) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Integer too large to convert to BCD: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64 (operand[0]->integer.value))); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Integer too large to convert to BCD: %8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (operand[0]->integer.value))); status = AE_AML_NUMERIC_OVERFLOW; goto cleanup; } @@ -429,42 +498,47 @@ */ case AML_COPY_OP: /* Copy (Source, Target) */ - status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc, walk_state); + status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc, + walk_state); break; case AML_TO_DECSTRING_OP: /* to_decimal_string (Data, Result) */ - status = acpi_ex_convert_to_string (operand[0], &return_desc, 10, ACPI_UINT32_MAX, walk_state); + status = acpi_ex_convert_to_string (operand[0], &return_desc, + ACPI_EXPLICIT_CONVERT_DECIMAL); break; case AML_TO_HEXSTRING_OP: /* to_hex_string (Data, Result) */ - status = acpi_ex_convert_to_string (operand[0], &return_desc, 16, ACPI_UINT32_MAX, walk_state); + status = acpi_ex_convert_to_string (operand[0], &return_desc, + ACPI_EXPLICIT_CONVERT_HEX); break; case AML_TO_BUFFER_OP: /* to_buffer (Data, Result) */ - status = acpi_ex_convert_to_buffer (operand[0], &return_desc, walk_state); + status = acpi_ex_convert_to_buffer (operand[0], &return_desc); break; case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */ - status = acpi_ex_convert_to_integer (operand[0], &return_desc, walk_state); + status = acpi_ex_convert_to_integer (operand[0], &return_desc, + ACPI_ANY_BASE); break; - case AML_SHIFT_LEFT_BIT_OP: /* shift_left_bit (Source, bit_num) */ - case AML_SHIFT_RIGHT_BIT_OP: /* shift_right_bit (Source, bit_num) */ + case AML_SHIFT_LEFT_BIT_OP: /* shift_left_bit (Source, bit_num) */ + case AML_SHIFT_RIGHT_BIT_OP: /* shift_right_bit (Source, bit_num) */ /* * These are two obsolete opcodes */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implemented\n", - acpi_ps_get_opcode_name (walk_state->opcode))); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "%s is obsolete and not implemented\n", + acpi_ps_get_opcode_name (walk_state->opcode))); status = AE_SUPPORT; goto cleanup; @@ -537,7 +611,13 @@ goto cleanup; } - return_desc->integer.value = !operand[0]->integer.value; + /* + * Set result to ONES (TRUE) if Value == 0. Note: + * return_desc->Integer.Value is initially == 0 (FALSE) from above. + */ + if (!operand[0]->integer.value) { + return_desc->integer.value = ACPI_INTEGER_MAX; + } break; @@ -545,41 +625,61 @@ case AML_INCREMENT_OP: /* Increment (Operand) */ /* - * Since we are expecting a Reference operand, it - * can be either a NS Node or an internal object. + * Create a new integer. Can't just get the base integer and + * increment it because it may be an Arg or Field. */ - return_desc = operand[0]; - if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) == ACPI_DESC_TYPE_OPERAND) { + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* + * Since we are expecting a Reference operand, it can be either a + * NS Node or an internal object. + */ + temp_desc = operand[0]; + if (ACPI_GET_DESCRIPTOR_TYPE (temp_desc) == ACPI_DESC_TYPE_OPERAND) { /* Internal reference object - prevent deletion */ - acpi_ut_add_reference (return_desc); + acpi_ut_add_reference (temp_desc); } /* - * Convert the return_desc Reference to a Number - * (This removes a reference on the return_desc object) + * Convert the Reference operand to an Integer (This removes a + * reference on the Operand[0] object) + * + * NOTE: We use LNOT_OP here in order to force resolution of the + * reference operand to an actual integer. */ - status = acpi_ex_resolve_operands (AML_LNOT_OP, &return_desc, walk_state); + status = acpi_ex_resolve_operands (AML_LNOT_OP, &temp_desc, walk_state); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n", - acpi_ps_get_opcode_name (walk_state->opcode), acpi_format_exception(status))); + acpi_ps_get_opcode_name (walk_state->opcode), + acpi_format_exception(status))); goto cleanup; } /* - * return_desc is now guaranteed to be an Integer object - * Do the actual increment or decrement + * temp_desc is now guaranteed to be an Integer object -- + * Perform the actual increment or decrement */ - if (AML_INCREMENT_OP == walk_state->opcode) { - return_desc->integer.value++; + if (walk_state->opcode == AML_INCREMENT_OP) { + return_desc->integer.value = temp_desc->integer.value +1; } else { - return_desc->integer.value--; + return_desc->integer.value = temp_desc->integer.value -1; } - /* Store the result back in the original descriptor */ + /* Finished with this Integer object */ + acpi_ut_remove_reference (temp_desc); + + /* + * Store the result back (indirectly) through the original + * Reference object + */ status = acpi_ex_store (return_desc, operand[0], walk_state); break; @@ -633,7 +733,8 @@ break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "size_of, Not Buf/Str/Pkg - found type %s\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "size_of, Not Buf/Str/Pkg - found type %s\n", acpi_ut_get_type_name (type))); status = AE_AML_OPERAND_TYPE; goto cleanup; @@ -803,7 +904,8 @@ * an uninitialized package element and is thus a * severe error. */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "NULL package element obj %p\n", operand[0])); status = AE_AML_UNINITIALIZED_ELEMENT; goto cleanup; @@ -815,7 +917,8 @@ default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Index target_type %X in obj %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unknown Index target_type %X in obj %p\n", operand[0]->reference.target_type, operand[0])); status = AE_AML_OPERAND_TYPE; goto cleanup; @@ -839,7 +942,8 @@ default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unknown opcode in ref(%p) - %X\n", operand[0], operand[0]->reference.opcode)); status = AE_TYPE; diff -Nru a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c --- a/drivers/acpi/executer/exoparg2.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/executer/exoparg2.c 2004-10-26 18:29:14 -07:00 @@ -199,7 +199,8 @@ acpi_status status; - ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_2T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_2T_1R", + acpi_ps_get_opcode_name (walk_state->opcode)); /* @@ -222,8 +223,10 @@ /* Quotient to return_desc1, remainder to return_desc2 */ - status = acpi_ut_divide (&operand[0]->integer.value, &operand[1]->integer.value, - &return_desc1->integer.value, &return_desc2->integer.value); + status = acpi_ut_divide (operand[0]->integer.value, + operand[1]->integer.value, + &return_desc1->integer.value, + &return_desc2->integer.value); if (ACPI_FAILURE (status)) { goto cleanup; } @@ -292,13 +295,13 @@ { union acpi_operand_object **operand = &walk_state->operands[0]; union acpi_operand_object *return_desc = NULL; - union acpi_operand_object *temp_desc = NULL; u32 index; acpi_status status = AE_OK; acpi_size length; - ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_1T_1R", + acpi_ps_get_opcode_name (walk_state->opcode)); /* @@ -331,52 +334,17 @@ /* return_desc will contain the remainder */ - status = acpi_ut_divide (&operand[0]->integer.value, &operand[1]->integer.value, - NULL, &return_desc->integer.value); + status = acpi_ut_divide (operand[0]->integer.value, + operand[1]->integer.value, + NULL, + &return_desc->integer.value); break; case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */ - /* - * Convert the second operand if necessary. The first operand - * determines the type of the second operand, (See the Data Types - * section of the ACPI specification.) Both object types are - * guaranteed to be either Integer/String/Buffer by the operand - * resolution mechanism above. - */ - switch (ACPI_GET_OBJECT_TYPE (operand[0])) { - case ACPI_TYPE_INTEGER: - status = acpi_ex_convert_to_integer (operand[1], &temp_desc, walk_state); - break; - - case ACPI_TYPE_STRING: - status = acpi_ex_convert_to_string (operand[1], &temp_desc, 16, ACPI_UINT32_MAX, walk_state); - break; - - case ACPI_TYPE_BUFFER: - status = acpi_ex_convert_to_buffer (operand[1], &temp_desc, walk_state); - break; - - default: - ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n", - ACPI_GET_OBJECT_TYPE (operand[0]))); - status = AE_AML_INTERNAL; - } - - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - /* - * Both operands are now known to be the same object type - * (Both are Integer, String, or Buffer), and we can now perform the - * concatenation. - */ - status = acpi_ex_do_concatenate (operand[0], temp_desc, &return_desc, walk_state); - if (temp_desc != operand[1]) { - acpi_ut_remove_reference (temp_desc); - } + status = acpi_ex_do_concatenate (operand[0], operand[1], + &return_desc, walk_state); break; @@ -387,55 +355,45 @@ * been converted.) Copy the raw buffer data to a new object of type String. */ - /* Get the length of the new string */ - + /* + * Get the length of the new string. It is the smallest of: + * 1) Length of the input buffer + * 2) Max length as specified in the to_string operator + * 3) Length of input buffer up to a zero byte (null terminator) + * + * NOTE: A length of zero is ok, and will create a zero-length, null + * terminated string. + */ length = 0; - if (operand[1]->integer.value == 0) { - /* Handle optional length value */ - - operand[1]->integer.value = ACPI_INTEGER_MAX; - } - while ((length < operand[0]->buffer.length) && (length < operand[1]->integer.value) && (operand[0]->buffer.pointer[length])) { length++; + if (length > ACPI_MAX_STRING_CONVERSION) { + status = AE_AML_STRING_LIMIT; + goto cleanup; + } } - if (length > ACPI_MAX_STRING_CONVERSION) { - status = AE_AML_STRING_LIMIT; - goto cleanup; - } - - /* Create the internal return object */ + /* Allocate a new string object */ - return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); + return_desc = acpi_ut_create_string_object (length); if (!return_desc) { status = AE_NO_MEMORY; goto cleanup; } - /* Allocate a new string buffer (Length + 1 for null terminator) */ - - return_desc->string.pointer = ACPI_MEM_CALLOCATE (length + 1); - if (!return_desc->string.pointer) { - status = AE_NO_MEMORY; - goto cleanup; - } + /* Copy the raw buffer data with no transform. NULL terminated already. */ - /* Copy the raw buffer data with no transform */ - - ACPI_MEMCPY (return_desc->string.pointer, operand[0]->buffer.pointer, length); - - /* Set the string length */ - - return_desc->string.length = (u32) length; + ACPI_MEMCPY (return_desc->string.pointer, + operand[0]->buffer.pointer, length); break; case AML_CONCAT_RES_OP: /* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */ - status = acpi_ex_concat_template (operand[0], operand[1], &return_desc, walk_state); + status = acpi_ex_concat_template (operand[0], operand[1], + &return_desc, walk_state); break; @@ -458,7 +416,8 @@ /* Object to be indexed is a Package */ if (index >= operand[0]->package.count) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond package end (%X)\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Index value (%X) beyond package end (%X)\n", index, operand[0]->package.count)); status = AE_AML_PACKAGE_LIMIT; goto cleanup; @@ -472,7 +431,8 @@ /* Object to be indexed is a Buffer */ if (index >= operand[0]->buffer.length) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond end of buffer (%X)\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Index value (%X) beyond end of buffer (%X)\n", index, operand[0]->buffer.length)); status = AE_AML_BUFFER_LIMIT; goto cleanup; @@ -558,7 +518,8 @@ u8 logical_result = FALSE; - ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_1R", + acpi_ps_get_opcode_name (walk_state->opcode)); /* Create the internal return object */ @@ -572,18 +533,15 @@ /* * 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], - operand[1]); + if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) /* logical_op (Operand0, Operand1) */ { + status = acpi_ex_do_logical_numeric_op (walk_state->opcode, + operand[0]->integer.value, operand[1]->integer.value, + &logical_result); + goto store_logical_result; + } + else if (walk_state->op_info->flags & AML_LOGICAL) /* logical_op (Operand0, Operand1) */ { + status = acpi_ex_do_logical_op (walk_state->opcode, operand[0], + operand[1], &logical_result); goto store_logical_result; } diff -Nru a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c --- a/drivers/acpi/executer/exregion.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/executer/exregion.c 2004-10-26 18:29:14 -07:00 @@ -121,7 +121,7 @@ * Hardware does not support non-aligned data transfers, we must verify * the request. */ - (void) acpi_ut_short_divide ((acpi_integer *) &address, length, NULL, &remainder); + (void) acpi_ut_short_divide ((acpi_integer) address, length, NULL, &remainder); if (remainder != 0) { return_ACPI_STATUS (AE_AML_ALIGNMENT); } diff -Nru a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c --- a/drivers/acpi/executer/exresop.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/executer/exresop.c 2004-10-26 18:29:14 -07:00 @@ -160,7 +160,7 @@ return_ACPI_STATUS (AE_AML_INTERNAL); } - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode %X [%s] operand_types=%X \n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode %X [%s] required_operand_types=%8.8X \n", opcode, op_info->name, arg_types)); /* @@ -227,12 +227,13 @@ case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */ ACPI_DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "Reference Opcode: %s\n", op_info->name))); + "Operand is a Reference, ref_opcode [%s]\n", + (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name))); break; default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unknown Reference Opcode %X [%s]\n", + "Operand is a Reference, Unknown Reference Opcode %X [%s]\n", obj_desc->reference.opcode, (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name)); @@ -398,7 +399,7 @@ * But we can implicitly convert from a STRING or BUFFER * Aka - "Implicit Source Operand Conversion" */ - status = acpi_ex_convert_to_integer (obj_desc, stack_ptr, walk_state); + status = acpi_ex_convert_to_integer (obj_desc, stack_ptr, 16); if (ACPI_FAILURE (status)) { if (status == AE_TYPE) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, @@ -420,7 +421,7 @@ * But we can implicitly convert from a STRING or INTEGER * Aka - "Implicit Source Operand Conversion" */ - status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr, walk_state); + status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr); if (ACPI_FAILURE (status)) { if (status == AE_TYPE) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, @@ -442,7 +443,8 @@ * But we can implicitly convert from a BUFFER or INTEGER * Aka - "Implicit Source Operand Conversion" */ - status = acpi_ex_convert_to_string (obj_desc, stack_ptr, 16, ACPI_UINT32_MAX, walk_state); + status = acpi_ex_convert_to_string (obj_desc, stack_ptr, + ACPI_IMPLICIT_CONVERT_HEX); if (ACPI_FAILURE (status)) { if (status == AE_TYPE) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, @@ -494,7 +496,7 @@ /* Highest priority conversion is to type Buffer */ - status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr, walk_state); + status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } diff -Nru a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c --- a/drivers/acpi/executer/exstore.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/executer/exstore.c 2004-10-26 18:29:14 -07:00 @@ -129,7 +129,8 @@ /* Destination is not a Reference object */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Destination is not a Reference or Constant object [%p]\n", dest_desc)); + "Target is not a Reference or Constant object - %s [%p]\n", + acpi_ut_get_object_type_name (dest_desc), dest_desc)); ACPI_DUMP_STACK_ENTRY (source_desc); ACPI_DUMP_STACK_ENTRY (dest_desc); @@ -182,23 +183,37 @@ * Storing to the Debug object causes the value stored to be * displayed and otherwise has no effect -- see ACPI Specification */ - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Write to Debug Object: ****:\n\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "**** Write to Debug Object: Object %p %s ****:\n\n", + source_desc, acpi_ut_get_object_type_name (source_desc))); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ", - acpi_ut_get_object_type_name (source_desc))); + acpi_ut_get_object_type_name (source_desc))); + + if (!acpi_ut_valid_internal_object (source_desc)) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, + "%p, Invalid Internal Object!\n", source_desc)); + break; + } switch (ACPI_GET_OBJECT_TYPE (source_desc)) { case ACPI_TYPE_INTEGER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n", + if (acpi_gbl_integer_byte_width == 4) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n", + (u32) source_desc->integer.value)); + } + else { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n", ACPI_FORMAT_UINT64 (source_desc->integer.value))); + } break; case ACPI_TYPE_BUFFER: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length 0x%.2X", - (u32) source_desc->buffer.length)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]", + (u32) source_desc->buffer.length)); ACPI_DUMP_BUFFER (source_desc->buffer.pointer, (source_desc->buffer.length < 32) ? source_desc->buffer.length : 32); break; @@ -206,22 +221,22 @@ case ACPI_TYPE_STRING: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length 0x%.2X, \"%s\"\n", - source_desc->string.length, source_desc->string.pointer)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n", + source_desc->string.length, source_desc->string.pointer)); break; case ACPI_TYPE_PACKAGE: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Size 0x%.2X Elements Ptr - %p\n", - source_desc->package.count, source_desc->package.elements)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] Elements Ptr - %p\n", + source_desc->package.count, source_desc->package.elements)); break; default: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p\n", - source_desc)); + source_desc)); break; } diff -Nru a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c --- a/drivers/acpi/executer/exsystem.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/executer/exsystem.c 2004-10-26 18:29:14 -07:00 @@ -167,7 +167,7 @@ acpi_status acpi_ex_system_do_suspend ( - u32 how_long) + acpi_integer how_long) { acpi_status status; @@ -179,8 +179,7 @@ acpi_ex_exit_interpreter (); - acpi_os_sleep ((u16) (how_long / (u32) 1000), - (u16) (how_long % (u32) 1000)); + acpi_os_sleep (how_long); /* And now we must get the interpreter again */ diff -Nru a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c --- a/drivers/acpi/executer/exutils.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/executer/exutils.c 2004-10-26 18:29:14 -07:00 @@ -280,25 +280,25 @@ { u32 num_digits; acpi_integer current_value; - acpi_integer quotient; ACPI_FUNCTION_TRACE ("ex_digits_needed"); - /* - * acpi_integer is unsigned, so we don't worry about a '-' - */ - if ((current_value = value) == 0) { + /* acpi_integer is unsigned, so we don't worry about a '-' prefix */ + + if (value == 0) { return_VALUE (1); } + current_value = value; num_digits = 0; + /* Count the digits in the requested base */ + while (current_value) { - (void) acpi_ut_short_divide (¤t_value, base, "ient, NULL); + (void) acpi_ut_short_divide (current_value, base, ¤t_value, NULL); num_digits++; - current_value = quotient; } return_VALUE (num_digits); @@ -361,7 +361,6 @@ u32 count; u32 digits_needed; u32 remainder; - acpi_integer quotient; ACPI_FUNCTION_ENTRY (); @@ -371,9 +370,8 @@ out_string[digits_needed] = 0; for (count = digits_needed; count > 0; count--) { - (void) acpi_ut_short_divide (&value, 10, "ient, &remainder); + (void) acpi_ut_short_divide (value, 10, &value, &remainder); out_string[count-1] = (char) ('0' + remainder);\ - value = quotient; } } diff -Nru a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c --- a/drivers/acpi/hardware/hwregs.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/hardware/hwregs.c 2004-10-26 18:29:14 -07:00 @@ -709,6 +709,7 @@ u32 *value, struct acpi_generic_address *reg) { + u64 address; acpi_status status; @@ -720,8 +721,14 @@ * a non-zero address within. However, don't return an error * because the PM1A/B code must not fail if B isn't present. */ - if ((!reg) || - (!reg->address)) { + if (!reg) { + return (AE_OK); + } + + /* Get a local copy of the address. Handles possible alignment issues */ + + ACPI_MOVE_64_TO_64 (&address, ®->address); + if (!address) { return (AE_OK); } *value = 0; @@ -734,14 +741,14 @@ case ACPI_ADR_SPACE_SYSTEM_MEMORY: status = acpi_os_read_memory ( - (acpi_physical_address) reg->address, + (acpi_physical_address) address, value, width); break; case ACPI_ADR_SPACE_SYSTEM_IO: - status = acpi_os_read_port ((acpi_io_address) reg->address, + status = acpi_os_read_port ((acpi_io_address) address, value, width); break; @@ -754,7 +761,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", *value, width, - ACPI_FORMAT_UINT64 (reg->address), + ACPI_FORMAT_UINT64 (address), acpi_ut_get_region_name (reg->address_space_id))); return (status); @@ -781,6 +788,7 @@ u32 value, struct acpi_generic_address *reg) { + u64 address; acpi_status status; @@ -792,8 +800,14 @@ * a non-zero address within. However, don't return an error * because the PM1A/B code must not fail if B isn't present. */ - if ((!reg) || - (!reg->address)) { + if (!reg) { + return (AE_OK); + } + + /* Get a local copy of the address. Handles possible alignment issues */ + + ACPI_MOVE_64_TO_64 (&address, ®->address); + if (!address) { return (AE_OK); } @@ -805,14 +819,14 @@ case ACPI_ADR_SPACE_SYSTEM_MEMORY: status = acpi_os_write_memory ( - (acpi_physical_address) reg->address, + (acpi_physical_address) address, value, width); break; case ACPI_ADR_SPACE_SYSTEM_IO: - status = acpi_os_write_port ((acpi_io_address) reg->address, + status = acpi_os_write_port ((acpi_io_address) address, value, width); break; @@ -825,7 +839,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", value, width, - ACPI_FORMAT_UINT64 (reg->address), + ACPI_FORMAT_UINT64 (address), acpi_ut_get_region_name (reg->address_space_id))); return (status); diff -Nru a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c --- a/drivers/acpi/hardware/hwtimer.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/hardware/hwtimer.c 2004-10-26 18:29:14 -07:00 @@ -149,10 +149,9 @@ u32 end_ticks, u32 *time_elapsed) { - u32 delta_ticks = 0; - union uint64_overlay normalized_ticks; acpi_status status; - acpi_integer out_quotient; + u32 delta_ticks; + acpi_integer quotient; ACPI_FUNCTION_TRACE ("acpi_get_timer_duration"); @@ -164,7 +163,7 @@ /* * Compute Tick Delta: - * Handle (max one) timer rollovers on 24- versus 32-bit timers. + * Handle (max one) timer rollovers on 24-bit versus 32-bit timers. */ if (start_ticks < end_ticks) { delta_ticks = end_ticks - start_ticks; @@ -181,22 +180,20 @@ delta_ticks = (0xFFFFFFFF - start_ticks) + end_ticks; } } - else { + else /* start_ticks == end_ticks */ { *time_elapsed = 0; return_ACPI_STATUS (AE_OK); } /* - * Compute Duration (Requires a 64-bit divide): + * Compute Duration (Requires a 64-bit multiply and divide): * * time_elapsed = (delta_ticks * 1000000) / PM_TIMER_FREQUENCY; */ - normalized_ticks.full = ((u64) delta_ticks) * 1000000; + status = acpi_ut_short_divide (((u64) delta_ticks) * 1000000, + PM_TIMER_FREQUENCY, "ient, NULL); - status = acpi_ut_short_divide (&normalized_ticks.full, PM_TIMER_FREQUENCY, - &out_quotient, NULL); - - *time_elapsed = (u32) out_quotient; + *time_elapsed = (u32) quotient; return_ACPI_STATUS (status); } diff -Nru a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/acpi/ibm_acpi.c 2004-10-26 18:29:14 -07:00 @@ -0,0 +1,1243 @@ +/* + * ibm_acpi.c - IBM ThinkPad ACPI Extras + * + * + * Copyright (C) 2004 Borislav Deianov + * + * 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 + * + * Changelog: + * + * 2004-08-09 0.1 initial release, support for X series + * 2004-08-14 0.2 support for T series, X20 + * bluetooth enable/disable + * hotkey events disabled by default + * removed fan control, currently useless + * 2004-08-17 0.3 support for R40 + * lcd off, brightness control + * thinklight on/off + * 2004-09-16 0.4 support for module parameters + * hotkey mask can be prefixed by 0x + * video output switching + * video expansion control + * ultrabay eject support + * removed lcd brightness/on/off control, didn't work + * 2004-10-18 0.5 thinklight support on A21e, G40, R32, T20, T21, X20 + * proc file format changed + * video_switch command + * experimental cmos control + * experimental led control + * experimental acpi sounds + * 2004-10-19 0.6 use acpi_bus_register_driver() to claim HKEY device + * 2004-10-23 0.7 fix module loading on A21e, A22p, T20, T21, X20 + * fix LED control on A21e + */ + +#define IBM_VERSION "0.7" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define IBM_NAME "ibm" +#define IBM_DESC "IBM ThinkPad ACPI Extras" +#define IBM_FILE "ibm_acpi" +#define IBM_URL "http://ibm-acpi.sf.net/" + +#define IBM_DIR IBM_NAME + +#define IBM_LOG IBM_FILE ": " +#define IBM_ERR KERN_ERR IBM_LOG +#define IBM_NOTICE KERN_NOTICE IBM_LOG +#define IBM_INFO KERN_INFO IBM_LOG +#define IBM_DEBUG KERN_DEBUG IBM_LOG + +#define IBM_MAX_ACPI_ARGS 3 + +#define __unused __attribute__ ((unused)) + +static int experimental; +module_param(experimental, int, 0); + +static acpi_handle root_handle = NULL; + +#define IBM_HANDLE(object, parent, paths...) \ + static acpi_handle object##_handle; \ + static acpi_handle *object##_parent = &parent##_handle; \ + static char *object##_paths[] = { paths } + +IBM_HANDLE(ec, root, + "\\_SB.PCI0.ISA.EC", /* A21e, A22p, T20, T21, X20 */ + "\\_SB.PCI0.LPC.EC", /* all others */ +); + +IBM_HANDLE(vid, root, + "\\_SB.PCI0.VID", /* A21e, G40, X30, X40 */ + "\\_SB.PCI0.AGP.VID", /* all others */ +); + +IBM_HANDLE(cmos, root, + "\\UCMS", /* R50, R50p, R51, T4x, X31, X40 */ + "\\CMOS", /* A3x, G40, R32, T23, T30, X22, X24, X30 */ + "\\CMS", /* R40, R40e */ +); /* A21e, A22p, T20, T21, X20 */ + +IBM_HANDLE(dock, root, + "\\_SB.GDCK", /* X30, X31, X40 */ + "\\_SB.PCI0.DOCK", /* A22p, T20, T21, X20 */ + "\\_SB.PCI0.PCI1.DOCK", /* all others */ +); /* A21e, G40, R32, R40, R40e */ + +IBM_HANDLE(bay, root, + "\\_SB.PCI0.IDE0.SCND.MSTR"); /* all except A21e */ +IBM_HANDLE(bayej, root, + "\\_SB.PCI0.IDE0.SCND.MSTR._EJ0"); /* all except A2x, A3x */ + +IBM_HANDLE(lght, root, "\\LGHT"); /* A21e, A22p, T20, T21, X20 */ +IBM_HANDLE(hkey, ec, "HKEY"); /* all */ +IBM_HANDLE(led, ec, "LED"); /* all except A21e, A22p, T20, T21, X20 */ +IBM_HANDLE(sysl, ec, "SYSL"); /* A21e, A22p, T20, T21, X20 */ +IBM_HANDLE(bled, ec, "BLED"); /* A22p, T20, T21, X20 */ +IBM_HANDLE(beep, ec, "BEEP"); /* all models */ + +struct ibm_struct { + char *name; + + char *hid; + struct acpi_driver *driver; + + int (*init) (struct ibm_struct *); + int (*read) (struct ibm_struct *, char *); + int (*write) (struct ibm_struct *, char *); + void (*exit) (struct ibm_struct *); + + void (*notify) (struct ibm_struct *, u32); + acpi_handle *handle; + int type; + struct acpi_device *device; + + int driver_registered; + int proc_created; + int init_called; + int notify_installed; + + int supported; + union { + struct { + int status; + int mask; + } hotkey; + struct { + int autoswitch; + } video; + } state; + + int experimental; +}; + +struct proc_dir_entry *proc_dir = NULL; + +#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") +#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") +#define strlencmp(a,b) (strncmp((a), (b), strlen(b))) + +static int acpi_evalf(acpi_handle handle, + void *res, char *method, char *fmt, ...) +{ + char *fmt0 = fmt; + struct acpi_object_list params; + union acpi_object in_objs[IBM_MAX_ACPI_ARGS]; + struct acpi_buffer result; + union acpi_object out_obj; + acpi_status status; + va_list ap; + char res_type; + int success; + int quiet; + + if (!*fmt) { + printk(IBM_ERR "acpi_evalf() called with empty format\n"); + return 0; + } + + if (*fmt == 'q') { + quiet = 1; + fmt++; + } else + quiet = 0; + + res_type = *(fmt++); + + params.count = 0; + params.pointer = &in_objs[0]; + + va_start(ap, fmt); + while (*fmt) { + char c = *(fmt++); + switch (c) { + case 'd': /* int */ + in_objs[params.count].integer.value = va_arg(ap, int); + in_objs[params.count++].type = ACPI_TYPE_INTEGER; + break; + /* add more types as needed */ + default: + printk(IBM_ERR "acpi_evalf() called " + "with invalid format character '%c'\n", c); + return 0; + } + } + va_end(ap); + + result.length = sizeof(out_obj); + result.pointer = &out_obj; + + status = acpi_evaluate_object(handle, method, ¶ms, &result); + + switch (res_type) { + case 'd': /* int */ + if (res) + *(int *)res = out_obj.integer.value; + success = status == AE_OK && out_obj.type == ACPI_TYPE_INTEGER; + break; + case 'v': /* void */ + success = status == AE_OK; + break; + /* add more types as needed */ + default: + printk(IBM_ERR "acpi_evalf() called " + "with invalid format character '%c'\n", res_type); + return 0; + } + + if (!success && !quiet) + printk(IBM_ERR "acpi_evalf(%s, %s, ...) failed: %d\n", + method, fmt0, status); + + return success; +} + +static void __unused acpi_print_int(acpi_handle handle, char *method) +{ + int i; + + if (acpi_evalf(handle, &i, method, "d")) + printk(IBM_INFO "%s = 0x%x\n", method, i); + else + printk(IBM_ERR "error calling %s\n", method); +} + +static char *next_cmd(char **cmds) +{ + char *start = *cmds; + char *end; + + while ((end = strchr(start, ',')) && end == start) + start = end + 1; + + if (!end) + return NULL; + + *end = 0; + *cmds = end + 1; + return start; +} + +static int driver_init(struct ibm_struct *ibm) +{ + printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); + printk(IBM_INFO "%s\n", IBM_URL); + + return 0; +} + +static int driver_read(struct ibm_struct *ibm, char *p) +{ + int len = 0; + + len += sprintf(p + len, "driver:\t\t%s\n", IBM_DESC); + len += sprintf(p + len, "version:\t%s\n", IBM_VERSION); + + return len; +} + +static int hotkey_get(struct ibm_struct *ibm, int *status, int *mask) +{ + if (!acpi_evalf(hkey_handle, status, "DHKC", "d")) + return -EIO; + if (ibm->supported) { + if (!acpi_evalf(hkey_handle, mask, "DHKN", "qd")) + return -EIO; + } else { + *mask = ibm->state.hotkey.mask; + } + return 0; +} + +static int hotkey_set(struct ibm_struct *ibm, int status, int mask) +{ + int i; + + if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status)) + return -EIO; + + if (!ibm->supported) + return 0; + + for (i=0; i<32; i++) { + int bit = ((1 << i) & mask) != 0; + if (!acpi_evalf(hkey_handle, NULL, "MHKM", "vdd", i+1, bit)) + return -EIO; + } + + return 0; +} + +static int hotkey_init(struct ibm_struct *ibm) +{ + int ret; + + ibm->supported = 1; + ret = hotkey_get(ibm, + &ibm->state.hotkey.status, + &ibm->state.hotkey.mask); + if (ret < 0) { + /* mask not supported on A21e, A22p, T20, T21, X20, X22, X24 */ + ibm->supported = 0; + ret = hotkey_get(ibm, + &ibm->state.hotkey.status, + &ibm->state.hotkey.mask); + } + + return ret; +} + +static int hotkey_read(struct ibm_struct *ibm, char *p) +{ + int status, mask; + int len = 0; + + if (hotkey_get(ibm, &status, &mask) < 0) + return -EIO; + + len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); + if (ibm->supported) { + len += sprintf(p + len, "mask:\t\t0x%04x\n", mask); + len += sprintf(p + len, + "commands:\tenable, disable, reset, \n"); + } else { + len += sprintf(p + len, "mask:\t\tnot supported\n"); + len += sprintf(p + len, "commands:\tenable, disable, reset\n"); + } + + return len; +} + +static int hotkey_write(struct ibm_struct *ibm, char *buf) +{ + int status, mask; + char *cmd; + int do_cmd = 0; + + if (hotkey_get(ibm, &status, &mask) < 0) + return -ENODEV; + + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "enable") == 0) { + status = 1; + } else if (strlencmp(cmd, "disable") == 0) { + status = 0; + } else if (strlencmp(cmd, "reset") == 0) { + status = ibm->state.hotkey.status; + mask = ibm->state.hotkey.mask; + } else if (sscanf(cmd, "0x%x", &mask) == 1) { + /* mask set */ + } else if (sscanf(cmd, "%x", &mask) == 1) { + /* mask set */ + } else + return -EINVAL; + do_cmd = 1; + } + + if (do_cmd && hotkey_set(ibm, status, mask) < 0) + return -EIO; + + return 0; +} + +static void hotkey_exit(struct ibm_struct *ibm) +{ + hotkey_set(ibm, ibm->state.hotkey.status, ibm->state.hotkey.mask); +} + +static void hotkey_notify(struct ibm_struct *ibm, u32 event) +{ + int hkey; + + if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) + acpi_bus_generate_event(ibm->device, event, hkey); + else { + printk(IBM_ERR "unknown hotkey event %d\n", event); + acpi_bus_generate_event(ibm->device, event, 0); + } +} + +static int bluetooth_init(struct ibm_struct *ibm) +{ + /* bluetooth not supported on A21e, G40, T20, T21, X20 */ + ibm->supported = acpi_evalf(hkey_handle, NULL, "GBDC", "qv"); + + return 0; +} + +static int bluetooth_status(struct ibm_struct *ibm) +{ + int status; + + if (!ibm->supported || !acpi_evalf(hkey_handle, &status, "GBDC", "d")) + status = 0; + + return status; +} + +static int bluetooth_read(struct ibm_struct *ibm, char *p) +{ + int len = 0; + int status = bluetooth_status(ibm); + + if (!ibm->supported) + len += sprintf(p + len, "status:\t\tnot supported\n"); + else if (!(status & 1)) + len += sprintf(p + len, "status:\t\tnot installed\n"); + else { + len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 1)); + len += sprintf(p + len, "commands:\tenable, disable\n"); + } + + return len; +} + +static int bluetooth_write(struct ibm_struct *ibm, char *buf) +{ + int status = bluetooth_status(ibm); + char *cmd; + int do_cmd = 0; + + if (!ibm->supported) + return -EINVAL; + + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "enable") == 0) { + status |= 2; + } else if (strlencmp(cmd, "disable") == 0) { + status &= ~2; + } else + return -EINVAL; + do_cmd = 1; + } + + if (do_cmd && !acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) + return -EIO; + + return 0; +} + +static int video_init(struct ibm_struct *ibm) +{ + if (!acpi_evalf(vid_handle, + &ibm->state.video.autoswitch, "^VDEE", "d")) + return -ENODEV; + + return 0; +} + +static int video_status(struct ibm_struct *ibm) +{ + int status = 0; + int i; + + acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1); + if (acpi_evalf(NULL, &i, "\\VCDC", "d")) + status |= 0x02 * i; + + acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0); + if (acpi_evalf(NULL, &i, "\\VCDL", "d")) + status |= 0x01 * i; + if (acpi_evalf(NULL, &i, "\\VCDD", "d")) + status |= 0x08 * i; + + if (acpi_evalf(vid_handle, &i, "^VDEE", "d")) + status |= 0x10 * (i & 1); + + return status; +} + +static int video_read(struct ibm_struct *ibm, char *p) +{ + int status = video_status(ibm); + int len = 0; + + len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0)); + len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1)); + len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3)); + len += sprintf(p + len, "auto:\t\t%s\n", enabled(status, 4)); + len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable, " + "crt_enable, crt_disable\n"); + len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable, " + "auto_enable, auto_disable\n"); + len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n"); + + return len; +} + +static int video_write(struct ibm_struct *ibm, char *buf) +{ + char *cmd; + int enable, disable, status; + + enable = disable = 0; + + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "lcd_enable") == 0) { + enable |= 0x01; + } else if (strlencmp(cmd, "lcd_disable") == 0) { + disable |= 0x01; + } else if (strlencmp(cmd, "crt_enable") == 0) { + enable |= 0x02; + } else if (strlencmp(cmd, "crt_disable") == 0) { + disable |= 0x02; + } else if (strlencmp(cmd, "dvi_enable") == 0) { + enable |= 0x08; + } else if (strlencmp(cmd, "dvi_disable") == 0) { + disable |= 0x08; + } else if (strlencmp(cmd, "auto_enable") == 0) { + if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1)) + return -EIO; + } else if (strlencmp(cmd, "auto_disable") == 0) { + if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 0)) + return -EIO; + } else if (strlencmp(cmd, "video_switch") == 0) { + int autoswitch; + if (!acpi_evalf(vid_handle, &autoswitch, "^VDEE", "d")) + return -EIO; + if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1)) + return -EIO; + if (!acpi_evalf(vid_handle, NULL, "VSWT", "v")) + return -EIO; + if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", + autoswitch)) + return -EIO; + } else if (strlencmp(cmd, "expand_toggle") == 0) { + if (!acpi_evalf(NULL, NULL, "\\VEXP", "v")) + return -EIO; + } else + return -EINVAL; + } + + if (enable || disable) { + status = (video_status(ibm) & 0x0f & ~disable) | enable; + if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80)) + return -EIO; + if (!acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1)) + return -EIO; + } + + return 0; +} + +static void video_exit(struct ibm_struct *ibm) +{ + acpi_evalf(vid_handle, NULL, "_DOS", "vd", + ibm->state.video.autoswitch); +} + +static int light_init(struct ibm_struct *ibm) +{ + /* kblt not supported on G40, R32, X20 */ + ibm->supported = acpi_evalf(ec_handle, NULL, "KBLT", "qv"); + + return 0; +} + +static int light_read(struct ibm_struct *ibm, char *p) +{ + int len = 0; + int status = 0; + + if (ibm->supported) { + if (!acpi_evalf(ec_handle, &status, "KBLT", "d")) + return -EIO; + len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0)); + } else + len += sprintf(p + len, "status:\t\tunknown\n"); + + len += sprintf(p + len, "commands:\ton, off\n"); + + return len; +} + +static int light_write(struct ibm_struct *ibm, char *buf) +{ + int cmos_cmd, lght_cmd; + char *cmd; + int success; + + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "on") == 0) { + cmos_cmd = 0x0c; + lght_cmd = 1; + } else if (strlencmp(cmd, "off") == 0) { + cmos_cmd = 0x0d; + lght_cmd = 0; + } else + return -EINVAL; + + success = cmos_handle ? + acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) : + acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd); + if (!success) + return -EIO; + } + + return 0; +} + +static int _sta(acpi_handle handle) +{ + int status; + + if (!handle || !acpi_evalf(handle, &status, "_STA", "d")) + status = 0; + + return status; +} + +#define dock_docked() (_sta(dock_handle) & 1) + +static int dock_read(struct ibm_struct *ibm, char *p) +{ + int len = 0; + int docked = dock_docked(); + + if (!dock_handle) + len += sprintf(p + len, "status:\t\tnot supported\n"); + else if (!docked) + len += sprintf(p + len, "status:\t\tundocked\n"); + else { + len += sprintf(p + len, "status:\t\tdocked\n"); + len += sprintf(p + len, "commands:\tdock, undock\n"); + } + + return len; +} + +static int dock_write(struct ibm_struct *ibm, char *buf) +{ + char *cmd; + + if (!dock_docked()) + return -EINVAL; + + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "undock") == 0) { + if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0)) + return -EIO; + if (!acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1)) + return -EIO; + } else if (strlencmp(cmd, "dock") == 0) { + if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 1)) + return -EIO; + } else + return -EINVAL; + } + + return 0; +} + +static void dock_notify(struct ibm_struct *ibm, u32 event) +{ + int docked = dock_docked(); + + if (event == 3 && docked) + acpi_bus_generate_event(ibm->device, event, 1); /* button */ + else if (event == 3 && !docked) + acpi_bus_generate_event(ibm->device, event, 2); /* undock */ + else if (event == 0 && docked) + acpi_bus_generate_event(ibm->device, event, 3); /* dock */ + else { + printk(IBM_ERR "unknown dock event %d, status %d\n", + event, _sta(dock_handle)); + acpi_bus_generate_event(ibm->device, event, 0); /* unknown */ + } +} + +#define bay_occupied() (_sta(bay_handle) & 1) + +static int bay_init(struct ibm_struct *ibm) +{ + /* bay not supported on A21e, A22p, A31, A31p, G40, R32, R40e */ + ibm->supported = bay_handle && bayej_handle && + acpi_evalf(bay_handle, NULL, "_STA", "qv"); + + return 0; +} + +static int bay_read(struct ibm_struct *ibm, char *p) +{ + int len = 0; + int occupied = bay_occupied(); + + if (!ibm->supported) + len += sprintf(p + len, "status:\t\tnot supported\n"); + else if (!occupied) + len += sprintf(p + len, "status:\t\tunoccupied\n"); + else { + len += sprintf(p + len, "status:\t\toccupied\n"); + len += sprintf(p + len, "commands:\teject\n"); + } + + return len; +} + +static int bay_write(struct ibm_struct *ibm, char *buf) +{ + char *cmd; + + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "eject") == 0) { + if (!ibm->supported || + !acpi_evalf(bay_handle, NULL, "_EJ0", "vd", 1)) + return -EIO; + } else + return -EINVAL; + } + + return 0; +} + +static void bay_notify(struct ibm_struct *ibm, u32 event) +{ + acpi_bus_generate_event(ibm->device, event, 0); +} + +static int cmos_read(struct ibm_struct *ibm, char *p) +{ + int len = 0; + + /* cmos not supported on A21e, A22p, T20, T21, X20 */ + if (!cmos_handle) + len += sprintf(p + len, "status:\t\tnot supported\n"); + else { + len += sprintf(p + len, "status:\t\tsupported\n"); + len += sprintf(p + len, "commands:\t\n"); + } + + return len; +} + +static int cmos_write(struct ibm_struct *ibm, char *buf) +{ + char *cmd; + int cmos_cmd; + + if (!cmos_handle) + return -EINVAL; + + while ((cmd = next_cmd(&buf))) { + if (sscanf(cmd, "%u", &cmos_cmd) == 1) { + /* cmos_cmd set */ + } else + return -EINVAL; + + if (!acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd)) + return -EIO; + } + + return 0; +} + +static int led_read(struct ibm_struct *ibm, char *p) +{ + int len = 0; + + len += sprintf(p + len, "commands:\t" + " on, off, blink\n"); + + return len; +} + +static int led_write(struct ibm_struct *ibm, char *buf) +{ + char *cmd; + unsigned int led; + int led_cmd, sysl_cmd, bled_a, bled_b; + + while ((cmd = next_cmd(&buf))) { + if (sscanf(cmd, "%u", &led) != 1) + return -EINVAL; + + if (strstr(cmd, "blink")) { + led_cmd = 0xc0; + sysl_cmd = 2; + bled_a = 2; + bled_b = 1; + } else if (strstr(cmd, "on")) { + led_cmd = 0x80; + sysl_cmd = 1; + bled_a = 2; + bled_b = 0; + } else if (strstr(cmd, "off")) { + led_cmd = sysl_cmd = bled_a = bled_b = 0; + } else + return -EINVAL; + + if (led_handle) { + if (!acpi_evalf(led_handle, NULL, NULL, "vdd", + led, led_cmd)) + return -EIO; + } else if (led < 2) { + if (acpi_evalf(sysl_handle, NULL, NULL, "vdd", + led, sysl_cmd)) + return -EIO; + } else if (led == 2 && bled_handle) { + if (acpi_evalf(bled_handle, NULL, NULL, "vdd", + bled_a, bled_b)) + return -EIO; + } else + return -EINVAL; + } + + return 0; +} + +static int beep_read(struct ibm_struct *ibm, char *p) +{ + int len = 0; + + len += sprintf(p + len, "commands:\t\n"); + + return len; +} + +static int beep_write(struct ibm_struct *ibm, char *buf) +{ + char *cmd; + int beep_cmd; + + while ((cmd = next_cmd(&buf))) { + if (sscanf(cmd, "%u", &beep_cmd) == 1) { + /* beep_cmd set */ + } else + return -EINVAL; + + if (!acpi_evalf(beep_handle, NULL, NULL, "vd", beep_cmd)) + return -EIO; + } + + return 0; +} + +struct ibm_struct ibms[] = { + { + .name = "driver", + .init = driver_init, + .read = driver_read, + }, + { + .name = "hotkey", + .hid = "IBM0068", + .init = hotkey_init, + .read = hotkey_read, + .write = hotkey_write, + .exit = hotkey_exit, + .notify = hotkey_notify, + .handle = &hkey_handle, + .type = ACPI_DEVICE_NOTIFY, + }, + { + .name = "bluetooth", + .init = bluetooth_init, + .read = bluetooth_read, + .write = bluetooth_write, + }, + { + .name = "video", + .init = video_init, + .read = video_read, + .write = video_write, + .exit = video_exit, + }, + { + .name = "light", + .init = light_init, + .read = light_read, + .write = light_write, + }, + { + .name = "dock", + .read = dock_read, + .write = dock_write, + .notify = dock_notify, + .handle = &dock_handle, + .type = ACPI_SYSTEM_NOTIFY, + }, + { + .name = "bay", + .init = bay_init, + .read = bay_read, + .write = bay_write, + .notify = bay_notify, + .handle = &bay_handle, + .type = ACPI_SYSTEM_NOTIFY, + }, + { + .name = "cmos", + .read = cmos_read, + .write = cmos_write, + .experimental = 1, + }, + { + .name = "led", + .read = led_read, + .write = led_write, + .experimental = 1, + }, + { + .name = "beep", + .read = beep_read, + .write = beep_write, + .experimental = 1, + }, +}; +#define NUM_IBMS (sizeof(ibms)/sizeof(ibms[0])) + +static int dispatch_read(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + struct ibm_struct *ibm = (struct ibm_struct *)data; + int len; + + if (!ibm || !ibm->read) + return -EINVAL; + + len = ibm->read(ibm, page); + if (len < 0) + return len; + + if (len <= off + count) + *eof = 1; + *start = page + off; + len -= off; + if (len > count) + len = count; + if (len < 0) + len = 0; + + return len; +} + +static int dispatch_write(struct file *file, const char __user *userbuf, + unsigned long count, void *data) +{ + struct ibm_struct *ibm = (struct ibm_struct *)data; + char *kernbuf; + int ret; + + if (!ibm || !ibm->write) + return -EINVAL; + + kernbuf = kmalloc(count + 2, GFP_KERNEL); + if (!kernbuf) + return -ENOMEM; + + if (copy_from_user(kernbuf, userbuf, count)) { + kfree(kernbuf); + return -EFAULT; + } + + kernbuf[count] = 0; + strcat(kernbuf, ","); + ret = ibm->write(ibm, kernbuf); + if (ret == 0) + ret = count; + + kfree(kernbuf); + + return ret; +} + +static void dispatch_notify(acpi_handle handle, u32 event, void *data) +{ + struct ibm_struct *ibm = (struct ibm_struct *)data; + + if (!ibm || !ibm->notify) + return; + + ibm->notify(ibm, event); +} + +static int setup_notify(struct ibm_struct *ibm) +{ + acpi_status status; + int ret; + + if (!*ibm->handle) + return 0; + + ret = acpi_bus_get_device(*ibm->handle, &ibm->device); + if (ret < 0) { + printk(IBM_ERR "%s device not present\n", ibm->name); + return 0; + } + + acpi_driver_data(ibm->device) = ibm; + sprintf(acpi_device_class(ibm->device), "%s/%s", IBM_NAME, ibm->name); + + status = acpi_install_notify_handler(*ibm->handle, ibm->type, + dispatch_notify, ibm); + if (ACPI_FAILURE(status)) { + printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n", + ibm->name, status); + return -ENODEV; + } + + ibm->notify_installed = 1; + + return 0; +} + +static int device_add(struct acpi_device *device) +{ + return 0; +} + +static int register_driver(struct ibm_struct *ibm) +{ + int ret; + + ibm->driver = kmalloc(sizeof(struct acpi_driver), GFP_KERNEL); + if (!ibm->driver) { + printk(IBM_ERR "kmalloc(ibm->driver) failed\n"); + return -1; + } + + memset(ibm->driver, 0, sizeof(struct acpi_driver)); + sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name); + ibm->driver->ids = ibm->hid; + ibm->driver->ops.add = &device_add; + + ret = acpi_bus_register_driver(ibm->driver); + if (ret < 0) { + printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n", + ibm->hid, ret); + kfree(ibm->driver); + } + + return ret; +} + +static int ibm_init(struct ibm_struct *ibm) +{ + int ret; + struct proc_dir_entry *entry; + + if (ibm->experimental && !experimental) + return 0; + + if (ibm->hid) { + ret = register_driver(ibm); + if (ret < 0) + return ret; + ibm->driver_registered = 1; + } + + if (ibm->init) { + ret = ibm->init(ibm); + if (ret != 0) + return ret; + ibm->init_called = 1; + } + + entry = create_proc_entry(ibm->name, S_IFREG | S_IRUGO | S_IWUSR, + proc_dir); + if (!entry) { + printk(IBM_ERR "unable to create proc entry %s\n", ibm->name); + return -ENODEV; + } + entry->owner = THIS_MODULE; + ibm->proc_created = 1; + + entry->data = ibm; + if (ibm->read) + entry->read_proc = &dispatch_read; + if (ibm->write) + entry->write_proc = &dispatch_write; + + if (ibm->notify) { + ret = setup_notify(ibm); + if (ret < 0) + return ret; + } + + return 0; +} + +static void ibm_exit(struct ibm_struct *ibm) +{ + if (ibm->notify_installed) + acpi_remove_notify_handler(*ibm->handle, ibm->type, + dispatch_notify); + + if (ibm->proc_created) + remove_proc_entry(ibm->name, proc_dir); + + if (ibm->init_called && ibm->exit) + ibm->exit(ibm); + + if (ibm->driver_registered) { + acpi_bus_unregister_driver(ibm->driver); + kfree(ibm->driver); + } +} + +static int ibm_handle_init(char *name, + acpi_handle *handle, acpi_handle parent, + char **paths, int num_paths, int required) +{ + int i; + acpi_status status; + + for (i=0; i=0; i--) + ibm_exit(&ibms[i]); + + remove_proc_entry(IBM_DIR, acpi_root_dir); +} + +static int __init acpi_ibm_init(void) +{ + int ret, i; + + if (acpi_disabled) + return -ENODEV; + + proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir); + if (!proc_dir) { + printk(IBM_ERR "unable to create proc dir %s", IBM_DIR); + return -ENODEV; + } + proc_dir->owner = THIS_MODULE; + + IBM_HANDLE_INIT_REQ(ec); + IBM_HANDLE_INIT_REQ(hkey); + IBM_HANDLE_INIT_REQ(vid); + IBM_HANDLE_INIT(cmos); + IBM_HANDLE_INIT(lght); + IBM_HANDLE_INIT(dock); + IBM_HANDLE_INIT(bay); + IBM_HANDLE_INIT(bayej); + IBM_HANDLE_INIT(led); + IBM_HANDLE_INIT(sysl); + IBM_HANDLE_INIT(bled); + IBM_HANDLE_INIT_REQ(beep); + + if (!cmos_handle && !lght_handle) { + printk(IBM_ERR "neither cmos nor lght object found\n"); + return -ENODEV; + } + + if (!led_handle && !sysl_handle) { + printk(IBM_ERR "neither led nor sysl object found\n"); + return -ENODEV; + } + + for (i=0; iowner_id = obj_desc->method.param_count; #else /* Mark this as a very SPECIAL method */ @@ -236,7 +238,8 @@ /* Store pointer to value descriptor in the Node */ - status = acpi_ns_attach_object (new_node, obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc)); + status = acpi_ns_attach_object (new_node, obj_desc, + ACPI_GET_OBJECT_TYPE (obj_desc)); /* Remove local reference to the object */ @@ -462,7 +465,8 @@ type = this_node->type; ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, - "Prefix-only Pathname (Zero name segments), Flags=%X\n", flags)); + "Prefix-only Pathname (Zero name segments), Flags=%X\n", + flags)); break; case AML_DUAL_NAME_PREFIX: @@ -554,7 +558,7 @@ /* Try to find the single (4 character) ACPI name */ status = acpi_ns_search_and_enter (simple_name, walk_state, current_node, - interpreter_mode, this_search_type, local_flags, &this_node); + interpreter_mode, this_search_type, local_flags, &this_node); if (ACPI_FAILURE (status)) { if (status == AE_NOT_FOUND) { /* Name not found in ACPI namespace */ diff -Nru a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c --- a/drivers/acpi/namespace/nsdump.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/namespace/nsdump.c 2004-10-26 18:29:14 -07:00 @@ -198,7 +198,8 @@ } if (!acpi_ut_valid_acpi_name (this_node->name.integer)) { - ACPI_REPORT_WARNING (("Invalid ACPI Name %08X\n", this_node->name.integer)); + ACPI_REPORT_WARNING (("Invalid ACPI Name %08X\n", + this_node->name.integer)); } /* @@ -226,9 +227,8 @@ case ACPI_TYPE_PROCESSOR: acpi_os_printf ("ID %X Len %.4X Addr %p\n", - obj_desc->processor.proc_id, - obj_desc->processor.length, - (char *) obj_desc->processor.address); + obj_desc->processor.proc_id, obj_desc->processor.length, + (char *) obj_desc->processor.address); break; @@ -241,16 +241,15 @@ case ACPI_TYPE_METHOD: acpi_os_printf ("Args %X Len %.4X Aml %p\n", - (u32) obj_desc->method.param_count, - obj_desc->method.aml_length, - obj_desc->method.aml_start); + (u32) obj_desc->method.param_count, + obj_desc->method.aml_length, obj_desc->method.aml_start); break; case ACPI_TYPE_INTEGER: acpi_os_printf ("= %8.8X%8.8X\n", - ACPI_FORMAT_UINT64 (obj_desc->integer.value)); + ACPI_FORMAT_UINT64 (obj_desc->integer.value)); break; @@ -258,7 +257,7 @@ if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { acpi_os_printf ("Elements %.2X\n", - obj_desc->package.count); + obj_desc->package.count); } else { acpi_os_printf ("[Length not yet evaluated]\n"); @@ -298,11 +297,12 @@ case ACPI_TYPE_REGION: - acpi_os_printf ("[%s]", acpi_ut_get_region_name (obj_desc->region.space_id)); + acpi_os_printf ("[%s]", + acpi_ut_get_region_name (obj_desc->region.space_id)); if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { acpi_os_printf (" Addr %8.8X%8.8X Len %.4X\n", - ACPI_FORMAT_UINT64 (obj_desc->region.address), - obj_desc->region.length); + ACPI_FORMAT_UINT64 (obj_desc->region.address), + obj_desc->region.length); } else { acpi_os_printf (" [Address/Length not yet evaluated]\n"); @@ -313,7 +313,7 @@ case ACPI_TYPE_LOCAL_REFERENCE: acpi_os_printf ("[%s]\n", - acpi_ps_get_opcode_name (obj_desc->reference.opcode)); + acpi_ps_get_opcode_name (obj_desc->reference.opcode)); break; @@ -322,7 +322,7 @@ if (obj_desc->buffer_field.buffer_obj && obj_desc->buffer_field.buffer_obj->buffer.node) { acpi_os_printf ("Buf [%4.4s]", - acpi_ut_get_node_name (obj_desc->buffer_field.buffer_obj->buffer.node)); + acpi_ut_get_node_name (obj_desc->buffer_field.buffer_obj->buffer.node)); } break; @@ -330,30 +330,31 @@ case ACPI_TYPE_LOCAL_REGION_FIELD: acpi_os_printf ("Rgn [%4.4s]", - acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node)); + acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node)); break; case ACPI_TYPE_LOCAL_BANK_FIELD: acpi_os_printf ("Rgn [%4.4s] Bnk [%4.4s]", - acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node), - acpi_ut_get_node_name (obj_desc->bank_field.bank_obj->common_field.node)); + acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node), + acpi_ut_get_node_name (obj_desc->bank_field.bank_obj->common_field.node)); break; case ACPI_TYPE_LOCAL_INDEX_FIELD: acpi_os_printf ("Idx [%4.4s] Dat [%4.4s]", - acpi_ut_get_node_name (obj_desc->index_field.index_obj->common_field.node), - acpi_ut_get_node_name (obj_desc->index_field.data_obj->common_field.node)); + acpi_ut_get_node_name (obj_desc->index_field.index_obj->common_field.node), + acpi_ut_get_node_name (obj_desc->index_field.data_obj->common_field.node)); break; case ACPI_TYPE_LOCAL_ALIAS: case ACPI_TYPE_LOCAL_METHOD_ALIAS: - acpi_os_printf ("Target %4.4s (%p)\n", acpi_ut_get_node_name (obj_desc), obj_desc); + acpi_os_printf ("Target %4.4s (%p)\n", + acpi_ut_get_node_name (obj_desc), obj_desc); break; default: @@ -371,10 +372,10 @@ case ACPI_TYPE_LOCAL_INDEX_FIELD: acpi_os_printf (" Off %.3X Len %.2X Acc %.2hd\n", - (obj_desc->common_field.base_byte_offset * 8) - + obj_desc->common_field.start_field_bit_offset, - obj_desc->common_field.bit_length, - obj_desc->common_field.access_byte_width); + (obj_desc->common_field.base_byte_offset * 8) + + obj_desc->common_field.start_field_bit_offset, + obj_desc->common_field.bit_length, + obj_desc->common_field.access_byte_width); break; default: @@ -471,12 +472,13 @@ obj_type = ACPI_GET_OBJECT_TYPE (obj_desc); if (obj_type > ACPI_TYPE_LOCAL_MAX) { - acpi_os_printf ("(Ptr to ACPI Object type %X [UNKNOWN])\n", obj_type); + acpi_os_printf ("(Ptr to ACPI Object type %X [UNKNOWN])\n", + obj_type); bytes_to_dump = 32; } else { acpi_os_printf ("(Ptr to ACPI Object type %s, %X)\n", - acpi_ut_get_type_name (obj_type), obj_type); + acpi_ut_get_type_name (obj_type), obj_type); bytes_to_dump = sizeof (union acpi_operand_object); } break; @@ -484,8 +486,9 @@ default: - acpi_os_printf ("(String or Buffer ptr - not an object descriptor) [%s]\n", - acpi_ut_get_descriptor_name (obj_desc)); + acpi_os_printf ( + "(String or Buffer ptr - not an object descriptor) [%s]\n", + acpi_ut_get_descriptor_name (obj_desc)); bytes_to_dump = 16; break; } @@ -552,7 +555,7 @@ * FUNCTION: acpi_ns_dump_objects * * PARAMETERS: Type - Object type to be dumped - * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX + * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX * for an effectively unlimited depth. * owner_id - Dump only objects owned by this ID. Use * ACPI_UINT32_MAX to match all owners. diff -Nru a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c --- a/drivers/acpi/namespace/nsdumpdv.c 2004-10-26 18:29:13 -07:00 +++ b/drivers/acpi/namespace/nsdumpdv.c 2004-10-26 18:29:13 -07:00 @@ -91,10 +91,10 @@ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); } - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", - info->hardware_id.value, - ACPI_FORMAT_UINT64 (info->address), - info->current_status)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, + " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", + info->hardware_id.value, ACPI_FORMAT_UINT64 (info->address), + info->current_status)); ACPI_MEM_FREE (info); } @@ -133,7 +133,8 @@ return; } - ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Display of all devices in the namespace:\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, + "Display of all devices in the namespace:\n")); status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, sys_bus_handle, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, diff -Nru a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c --- a/drivers/acpi/namespace/nseval.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/namespace/nseval.c 2004-10-26 18:29:14 -07:00 @@ -57,14 +57,9 @@ * * FUNCTION: acpi_ns_evaluate_relative * - * PARAMETERS: Handle - The relative containing object - * Pathname - Name of method to execute, If NULL, the + * PARAMETERS: Pathname - Name of method to execute, If NULL, the * handle is the object to execute - * Params - List of parameters to pass to the method, - * terminated by NULL. Params itself may be - * NULL if no parameters are being passed. - * return_object - Where to put method's return value (if - * any). If NULL, no value is returned. + * Info - Method info block * * RETURN: Status * @@ -138,8 +133,7 @@ } /* - * Now that we have a handle to the object, we can attempt - * to evaluate it. + * Now that we have a handle to the object, we can attempt to evaluate it. */ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", pathname, node, acpi_ns_get_attached_object (node))); @@ -165,9 +159,9 @@ * * PARAMETERS: Pathname - Fully qualified pathname to the object * Info - Contains: - * return_object - Where to put method's return value (if + * 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, + * Params - List of parameters to pass to the method, * terminated by NULL. Params itself may be * NULL if no parameters are being passed. * @@ -213,14 +207,14 @@ (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object at [%s] was not found, status=%.4X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "Object at [%s] was not found, status=%.4X\n", pathname, status)); goto cleanup; } /* - * Now that we have a handle to the object, we can attempt - * to evaluate it. + * Now that we have a handle to the object, we can attempt to evaluate it. */ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", pathname, info->node, acpi_ns_get_attached_object (info->node))); @@ -303,9 +297,8 @@ } /* - * For a method alias, we must grab the actual method node - * so that proper scoping context will be established - * before execution. + * For a method alias, we must grab the actual method node so that proper + * scoping context will be established before execution. */ if (acpi_ns_get_type (info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { info->node = ACPI_CAST_PTR (struct acpi_namespace_node, info->node->object); @@ -314,11 +307,9 @@ /* * Two major cases here: * 1) The object is an actual control method -- execute it. - * 2) The object is not a method -- just return it's current - * value + * 2) The object is not a method -- just return it's current value * - * In both cases, the namespace is unlocked by the - * acpi_ns* procedure + * In both cases, the namespace is unlocked by the acpi_ns* procedure */ if (acpi_ns_get_type (info->node) == ACPI_TYPE_METHOD) { /* @@ -328,15 +319,13 @@ } else { /* - * Case 2) Object is NOT a method, just return its - * current value + * Case 2) Object is NOT a method, just return its current value */ status = acpi_ns_get_object_value (info); } /* - * Check if there is a return value on the stack that must - * be dealt with + * Check if there is a return value on the stack that must be dealt with */ if (status == AE_CTRL_RETURN_VALUE) { /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ @@ -345,8 +334,8 @@ } /* - * Namespace was unlocked by the handling acpi_ns* function, - * so we just return + * Namespace was unlocked by the handling acpi_ns* function, so we + * just return */ return_ACPI_STATUS (status); } @@ -356,12 +345,7 @@ * * FUNCTION: acpi_ns_execute_control_method * - * PARAMETERS: method_node - The method to execute - * Params - List of parameters to pass to the method, - * terminated by NULL. Params itself may be - * NULL if no parameters are being passed. - * return_obj_desc - List of result objects to be returned - * from the method. + * PARAMETERS: Info - Method info block (w/params) * * RETURN: Status * @@ -430,8 +414,7 @@ * * FUNCTION: acpi_ns_get_object_value * - * PARAMETERS: Node - The object - * return_obj_desc - Where the objects value is returned + * PARAMETERS: Info - Method info block (w/params) * * RETURN: Status * @@ -453,28 +436,25 @@ /* - * Objects require additional resolution steps (e.g., the - * Node may be a field that must be read, etc.) -- we can't just grab - * the object out of the node. + * Objects require additional resolution steps (e.g., the Node may be a + * field that must be read, etc.) -- we can't just grab the object out of + * the node. */ /* - * Use resolve_node_to_value() to get the associated value. This call - * always deletes obj_desc (allocated above). + * Use resolve_node_to_value() to get the associated value. This call always + * deletes obj_desc (allocated above). * - * NOTE: we can get away with passing in NULL for a walk state - * because obj_desc is guaranteed to not be a reference to either - * a method local or a method argument (because this interface can only be - * called from the acpi_evaluate external interface, never called from - * a running control method.) + * NOTE: we can get away with passing in NULL for a walk state because + * obj_desc is guaranteed to not be a reference to either a method local or + * a method argument (because this interface can only be called from the + * acpi_evaluate external interface, never called from a running method.) * - * Even though we do not directly invoke the interpreter - * for this, we must enter it because we could access an opregion. - * The opregion access code assumes that the interpreter - * is locked. + * Even though we do not directly invoke the interpreter for this, we must + * enter it because we could access an opregion. The opregion access code + * assumes that the interpreter is locked. * - * We must release the namespace lock before entering the - * intepreter. + * We must release the namespace lock before entering the intepreter. */ status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { @@ -485,16 +465,18 @@ if (ACPI_SUCCESS (status)) { status = acpi_ex_resolve_node_to_value (&resolved_node, NULL); /* - * If acpi_ex_resolve_node_to_value() succeeded, the return value was - * placed in resolved_node. + * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed + * in resolved_node. */ acpi_ex_exit_interpreter (); if (ACPI_SUCCESS (status)) { status = AE_CTRL_RETURN_VALUE; - info->return_object = 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", - info->return_object, acpi_ut_get_object_type_name (info->return_object))); + 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-10-26 18:29:14 -07:00 +++ b/drivers/acpi/namespace/nsinit.c 2004-10-26 18:29:14 -07:00 @@ -77,7 +77,8 @@ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "**** Starting initialization of namespace objects ****\n")); - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Completing Region/Field/Buffer/Package initialization:")); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, + "Completing Region/Field/Buffer/Package initialization:")); /* Set all init info to zero */ @@ -142,7 +143,8 @@ info.num_STA = 0; info.num_INI = 0; - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Executing all Device _STA and_INI methods:")); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, + "Executing all Device _STA and_INI methods:")); status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { @@ -257,8 +259,8 @@ } /* - * Each of these types can contain executable AML code within - * the declaration. + * Each of these types can contain executable AML code within the + * declaration. */ switch (type) { case ACPI_TYPE_REGION: @@ -267,21 +269,18 @@ status = acpi_ds_get_region_arguments (obj_desc); break; - case ACPI_TYPE_BUFFER_FIELD: info->field_init++; status = acpi_ds_get_buffer_field_arguments (obj_desc); break; - case ACPI_TYPE_BUFFER: info->buffer_init++; status = acpi_ds_get_buffer_arguments (obj_desc); break; - case ACPI_TYPE_PACKAGE: info->package_init++; @@ -301,15 +300,17 @@ acpi_format_exception (status))); } - /* Print a dot for each object unless we are going to print the entire pathname */ - + /* + * Print a dot for each object unless we are going to print the entire + * pathname + */ if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); } /* - * We ignore errors from above, and always return OK, since - * we don't want to abort the walk on any single error. + * We ignore errors from above, and always return OK, since we don't want + * to abort the walk on any single error. */ acpi_ex_exit_interpreter (); return (AE_OK); @@ -363,7 +364,8 @@ return_ACPI_STATUS (AE_OK); } - if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) { + if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && + (!(acpi_dbg_level & ACPI_LV_INFO))) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); } @@ -428,7 +430,6 @@ status = acpi_gbl_init_handler (pinfo.node, ACPI_INIT_DEVICE_INI); } - return_ACPI_STATUS (status); } diff -Nru a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c --- a/drivers/acpi/namespace/nsload.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/namespace/nsload.c 2004-10-26 18:29:14 -07:00 @@ -92,12 +92,14 @@ return_ACPI_STATUS (AE_BAD_PARAMETER); } - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AML block at %p\n", table_desc->aml_start)); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AML block at %p\n", + table_desc->aml_start)); /* Ignore table if there is no AML contained within */ if (!table_desc->aml_length) { - ACPI_REPORT_WARNING (("Zero-length AML block in table [%4.4s]\n", table_desc->pointer->signature)); + ACPI_REPORT_WARNING (("Zero-length AML block in table [%4.4s]\n", + table_desc->pointer->signature)); return_ACPI_STATUS (AE_OK); } @@ -110,7 +112,8 @@ * to another control method, we can't continue parsing * because we don't know how many arguments to parse next! */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Loading table into namespace ****\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "**** Loading table into namespace ****\n")); status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { @@ -196,7 +199,6 @@ if (ACPI_SUCCESS (status)) { table_desc->loaded_into_namespace = TRUE; } - break; @@ -252,7 +254,6 @@ table_desc = table_desc->next; } - break; diff -Nru a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c --- a/drivers/acpi/namespace/nsnames.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/namespace/nsnames.c 2004-10-26 18:29:14 -07:00 @@ -202,7 +202,11 @@ next_node = acpi_ns_get_parent_node (next_node); } - return (size + 1); + if (!size) { + size = 1; /* Root node case */ + } + + return (size + 1); /* +1 for null string terminator */ } @@ -253,7 +257,8 @@ acpi_ns_build_external_path (node, required_size, buffer->pointer); - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X] \n", (char *) buffer->pointer, (u32) required_size)); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X] \n", + (char *) buffer->pointer, (u32) required_size)); return_ACPI_STATUS (AE_OK); } diff -Nru a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c --- a/drivers/acpi/namespace/nssearch.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/namespace/nssearch.c 2004-10-26 18:29:14 -07:00 @@ -96,8 +96,10 @@ scope_name = acpi_ns_get_external_pathname (node); if (scope_name) { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching %s (%p) For [%4.4s] (%s)\n", - scope_name, node, (char *) &target_name, acpi_ut_get_type_name (type))); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "Searching %s (%p) For [%4.4s] (%s)\n", + scope_name, node, (char *) &target_name, + acpi_ut_get_type_name (type))); ACPI_MEM_FREE (scope_name); } @@ -164,7 +166,7 @@ * PARAMETERS: *target_name - Ascii ACPI name to search for * *Node - Starting node where search will begin * Type - Object type to match - * **return_node - Where the matched Named Obj is returned + * **return_node - Where the matched Node is returned * * RETURN: Status * @@ -199,13 +201,13 @@ parent_node = acpi_ns_get_parent_node (node); /* - * If there is no parent (i.e., we are at the root) or - * type is "local", we won't be searching the parent tree. + * If there is no parent (i.e., we are at the root) or type is "local", + * we won't be searching the parent tree. */ if (!parent_node) { ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] has no parent\n", (char *) &target_name)); - return_ACPI_STATUS (AE_NOT_FOUND); + return_ACPI_STATUS (AE_NOT_FOUND); } if (acpi_ns_local (type)) { @@ -217,11 +219,12 @@ /* Search the parent tree */ - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching parent for %4.4s\n", (char *) &target_name)); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "Searching parent [%4.4s] for [%4.4s]\n", + acpi_ut_get_node_name (parent_node), (char *) &target_name)); /* - * Search parents until found the target or we have backed up to - * the root + * Search parents until target is found or we have backed up to the root */ while (parent_node) { /* @@ -230,7 +233,7 @@ * the actual name we are searching for. Typechecking comes later. */ status = acpi_ns_search_node (target_name, parent_node, - ACPI_TYPE_ANY, return_node); + ACPI_TYPE_ANY, return_node); if (ACPI_SUCCESS (status)) { return_ACPI_STATUS (status); } @@ -293,7 +296,8 @@ /* Parameter validation */ if (!node || !target_name || !return_node) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null param: Node %p Name %X return_node %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Null param: Node %p Name %X return_node %p\n", node, target_name, return_node)); ACPI_REPORT_ERROR (("ns_search_and_enter: Null parameter\n")); @@ -330,22 +334,20 @@ } /* - * The name was not found. If we are NOT performing the - * first pass (name entry) of loading the namespace, search - * the parent tree (all the way to the root if necessary.) - * We don't want to perform the parent search when the - * namespace is actually being loaded. We want to perform - * the search when namespace references are being resolved - * (load pass 2) and during the execution phase. + * The name was not found. If we are NOT performing the first pass + * (name entry) of loading the namespace, search the parent tree (all the + * way to the root if necessary.) We don't want to perform the parent + * search when the namespace is actually being loaded. We want to perform + * the search when namespace references are being resolved (load pass 2) + * and during the execution phase. */ if ((interpreter_mode != ACPI_IMODE_LOAD_PASS1) && (flags & ACPI_NS_SEARCH_PARENT)) { /* - * Not found at this level - search parent tree according - * to ACPI specification + * Not found at this level - search parent tree according to the + * ACPI specification */ - status = acpi_ns_search_parent_tree (target_name, node, - type, return_node); + status = acpi_ns_search_parent_tree (target_name, node, type, return_node); if (ACPI_SUCCESS (status)) { return_ACPI_STATUS (status); } @@ -355,7 +357,8 @@ * In execute mode, just search, never add names. Exit now. */ if (interpreter_mode == ACPI_IMODE_EXECUTE) { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s Not found in %p [Not adding]\n", + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "%4.4s Not found in %p [Not adding]\n", (char *) &target_name, node)); return_ACPI_STATUS (AE_NOT_FOUND); diff -Nru a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c --- a/drivers/acpi/namespace/nsutils.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/namespace/nsutils.c 2004-10-26 18:29:14 -07:00 @@ -85,12 +85,14 @@ if (lookup_status == AE_BAD_CHARACTER) { /* There is a non-ascii character in the name */ - acpi_os_printf ("[0x%4.4X] (NON-ASCII)\n", *(ACPI_CAST_PTR (u32, internal_name))); + acpi_os_printf ("[0x%4.4X] (NON-ASCII)\n", + *(ACPI_CAST_PTR (u32, internal_name))); } else { /* Convert path to external format */ - status = acpi_ns_externalize_name (ACPI_UINT32_MAX, internal_name, NULL, &name); + status = acpi_ns_externalize_name (ACPI_UINT32_MAX, + internal_name, NULL, &name); /* Print target name */ @@ -141,7 +143,8 @@ if (path) { - status = acpi_ns_get_node_by_path (path, prefix_node, ACPI_NS_NO_UPSEARCH, &node); + status = acpi_ns_get_node_by_path (path, prefix_node, + ACPI_NS_NO_UPSEARCH, &node); if (ACPI_FAILURE (status)) { acpi_os_printf ("report_method_error: Could not get node\n"); return; @@ -180,7 +183,7 @@ return; } - /* Convert handle to a full pathname and print it (with supplied message) */ + /* Convert handle to full pathname and print it (with supplied message) */ buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; @@ -324,13 +327,11 @@ info->fully_qualified = FALSE; /* - * For the internal name, the required length is 4 bytes - * per segment, plus 1 each for root_prefix, multi_name_prefix_op, - * segment count, trailing null (which is not really needed, - * but no there's harm in putting it there) + * For the internal name, the required length is 4 bytes per segment, plus + * 1 each for root_prefix, multi_name_prefix_op, segment count, trailing null + * (which is not really needed, but no there's harm in putting it there) * - * strlen() + 1 covers the first name_seg, which has no - * path separator + * strlen() + 1 covers the first name_seg, which has no path separator */ if (acpi_ns_valid_root_prefix (next_external_char[0])) { info->fully_qualified = TRUE; @@ -347,10 +348,9 @@ } /* - * Determine the number of ACPI name "segments" by counting - * the number of path separators within the string. Start - * with one segment since the segment count is (# separators) - * + 1, and zero separators is ok. + * Determine the number of ACPI name "segments" by counting the number of + * path separators within the string. Start with one segment since the + * segment count is [(# separators) + 1], and zero separators is ok. */ if (*next_external_char) { info->num_segments = 1; @@ -625,7 +625,8 @@ /* 4-byte names */ names_index = prefix_length + 2; - num_segments = (acpi_native_uint) (u8) internal_name[(acpi_native_uint) (prefix_length + 1)]; + num_segments = (acpi_native_uint) (u8) + internal_name[(acpi_native_uint) (prefix_length + 1)]; break; case AML_DUAL_NAME_PREFIX: @@ -672,7 +673,7 @@ } /* - * Build converted_name... + * Build converted_name */ *converted_name = ACPI_MEM_CALLOCATE (required_length); if (!(*converted_name)) { @@ -756,7 +757,7 @@ * * PARAMETERS: Node - Node to be converted to a Handle * - * RETURN: An USER acpi_handle + * RETURN: A user handle * * DESCRIPTION: Convert a real Node to a namespace handle * @@ -976,7 +977,8 @@ parent_node = acpi_ns_get_parent_node (child_node); if (parent_node) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Parent of %p [%4.4s] is %p [%4.4s]\n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "Parent of %p [%4.4s] is %p [%4.4s]\n", child_node, acpi_ut_get_node_name (child_node), parent_node, acpi_ut_get_node_name (parent_node))); @@ -985,7 +987,8 @@ } } - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "unable to find parent of %p (%4.4s)\n", + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "Unable to find parent of %p (%4.4s)\n", child_node, acpi_ut_get_node_name (child_node))); } @@ -1018,11 +1021,9 @@ } /* - * Walk to the end of this peer list. - * The last entry is marked with a flag and the peer - * pointer is really a pointer back to the parent. - * This saves putting a parent back pointer in each and - * every named object! + * Walk to the end of this peer list. The last entry is marked with a flag + * and the peer pointer is really a pointer back to the parent. This saves + * putting a parent back pointer in each and every named object! */ while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) { node = node->peer; @@ -1039,8 +1040,8 @@ * * PARAMETERS: Node - Current table entry * - * RETURN: Next valid Node in the linked node list. NULL if no more valid - * nodess + * RETURN: Next valid Node in the linked node list. NULL if no more valid + * nodes. * * DESCRIPTION: Find the next valid node within a name table. * Useful for implementing NULL-end-of-list loops. diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c --- a/drivers/acpi/osl.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/osl.c 2004-10-26 18:29:14 -07:00 @@ -229,7 +229,7 @@ *new_val = NULL; if (!memcmp (init_val->name, "_OS_", 4) && strlen(acpi_os_name)) { - printk(KERN_INFO PREFIX "Overriding _OS definition %s\n", + printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'\n", acpi_os_name); *new_val = acpi_os_name; } @@ -306,10 +306,10 @@ */ void -acpi_os_sleep(u32 sec, u32 ms) +acpi_os_sleep(acpi_integer ms) { current->state = TASK_INTERRUPTIBLE; - schedule_timeout(HZ * sec + (ms * HZ) / 1000); + schedule_timeout(((signed long) ms * HZ) / 1000); } void @@ -326,6 +326,29 @@ } } +/* + * Support ACPI 3.0 AML Timer operand + * Returns 64-bit free-running, monotonically increasing timer + * with 100ns granularity + */ +u64 +acpi_os_get_timer (void) +{ + static u64 t; + +#ifdef CONFIG_HPET + /* TBD: use HPET if available */ +#endif + +#ifdef CONFIG_X86_PM_TIMER + /* TBD: default to PM timer if HPET was not available */ +#endif + if (!t) + printk(KERN_ERR PREFIX "acpi_os_get_timer() TBD\n"); + + return(++t); +} + acpi_status acpi_os_read_port( acpi_io_address port, @@ -1007,11 +1030,15 @@ printk(KERN_ERR PREFIX "Fatal opcode executed\n"); break; case ACPI_SIGNAL_BREAKPOINT: - { - char *bp_info = (char*) info; - - printk(KERN_ERR "ACPI breakpoint: %s\n", bp_info); - } + /* + * AML Breakpoint + * ACPI spec. says to treat it as a NOP unless + * you are debugging. So if/when we integrate + * AML debugger into the kernel debugger its + * hook will go here. But until then it is + * not useful to print anything on breakpoints. + */ + break; default: break; } diff -Nru a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c --- a/drivers/acpi/parser/psopcode.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/parser/psopcode.c 2004-10-26 18:29:14 -07:00 @@ -194,6 +194,7 @@ #define ARGP_STRING_OP ARGP_LIST1 (ARGP_CHARLIST) #define ARGP_SUBTRACT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) #define ARGP_THERMAL_ZONE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_OBJLIST) +#define ARGP_TIMER_OP ARG_NONE #define ARGP_TO_BCD_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET) #define ARGP_TO_BUFFER_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET) #define ARGP_TO_DEC_STR_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET) @@ -325,6 +326,7 @@ #define ARGI_STRING_OP ARGI_INVALID_OPCODE #define ARGI_SUBTRACT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) #define ARGI_THERMAL_ZONE_OP ARGI_INVALID_OPCODE +#define ARGI_TIMER_OP ARG_NONE #define ARGI_TO_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_FIXED_TARGET) #define ARGI_TO_BUFFER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET) #define ARGI_TO_DEC_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET) @@ -527,8 +529,8 @@ /* 35 */ ACPI_OP ("CreateByteField", ARGP_CREATE_BYTE_FIELD_OP, ARGI_CREATE_BYTE_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), /* 36 */ ACPI_OP ("CreateBitField", ARGP_CREATE_BIT_FIELD_OP, ARGI_CREATE_BIT_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), /* 37 */ ACPI_OP ("ObjectType", ARGP_TYPE_OP, ARGI_TYPE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), -/* 38 */ ACPI_OP ("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT), -/* 39 */ ACPI_OP ("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT), +/* 38 */ ACPI_OP ("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT), +/* 39 */ ACPI_OP ("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT), /* 3A */ ACPI_OP ("LNot", ARGP_LNOT_OP, ARGI_LNOT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT), /* 3B */ ACPI_OP ("LEqual", ARGP_LEQUAL_OP, ARGI_LEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT), /* 3C */ ACPI_OP ("LGreater", ARGP_LGREATER_OP, ARGI_LGREATER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT), @@ -588,7 +590,6 @@ /* 6C */ ACPI_OP ("-ASCII_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY, AML_CLASS_ASCII, AML_TYPE_BOGUS, AML_HAS_ARGS), /* 6D */ ACPI_OP ("-PREFIX_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY, AML_CLASS_PREFIX, AML_TYPE_BOGUS, AML_HAS_ARGS), - /* ACPI 2.0 opcodes */ /* 6E */ ACPI_OP ("QwordConst", ARGP_QWORD_OP, ARGI_QWORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT), @@ -606,7 +607,11 @@ /* 7A */ ACPI_OP ("Continue", ARGP_CONTINUE_OP, ARGI_CONTINUE_OP, ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0), /* 7B */ ACPI_OP ("LoadTable", ARGP_LOAD_TABLE_OP, ARGI_LOAD_TABLE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R), /* 7C */ ACPI_OP ("DataTableRegion", ARGP_DATA_REGION_OP, ARGI_DATA_REGION_OP, ACPI_TYPE_REGION, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED), -/* 7D */ ACPI_OP ("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE) +/* 7D */ ACPI_OP ("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE), + +/* ACPI 3.0 opcodes */ + +/* 7E */ ACPI_OP ("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R, AML_FLAGS_EXEC_0A_0T_1R) /*! [End] no source code translation !*/ }; @@ -615,7 +620,6 @@ * This table is directly indexed by the opcodes, and returns an * index into the table above */ - static const u8 acpi_gbl_short_op_index[256] = { /* 0 1 2 3 4 5 6 7 */ @@ -654,7 +658,10 @@ /* 0xF8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45, }; - +/* + * This table is indexed by the second opcode of the extended opcode + * pair. It returns an index into the opcode table (acpi_gbl_aml_op_info) + */ static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] = { /* 0 1 2 3 4 5 6 7 */ @@ -665,7 +672,7 @@ /* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B, /* 0x20 */ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, /* 0x28 */ 0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK, -/* 0x30 */ 0x55, 0x56, 0x57, _UNK, _UNK, _UNK, _UNK, _UNK, +/* 0x30 */ 0x55, 0x56, 0x57, 0x7e, _UNK, _UNK, _UNK, _UNK, /* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x40 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x48 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, @@ -724,7 +731,7 @@ default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown extended opcode [%X]\n", opcode)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown AML opcode [%4.4X]\n", opcode)); break; } diff -Nru a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c --- a/drivers/acpi/parser/psutils.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/parser/psutils.c 2004-10-26 18:29:14 -07:00 @@ -129,10 +129,9 @@ acpi_ps_alloc_op ( u16 opcode) { - union acpi_parse_object *op = NULL; - u32 size; - u8 flags; + union acpi_parse_object *op; const struct acpi_opcode_info *op_info; + u8 flags = ACPI_PARSEOP_GENERIC; ACPI_FUNCTION_ENTRY (); @@ -140,32 +139,28 @@ op_info = acpi_ps_get_opcode_info (opcode); - /* Allocate the minimum required size object */ + /* Determine type of parse_op required */ if (op_info->flags & AML_DEFER) { - size = sizeof (struct acpi_parse_obj_named); flags = ACPI_PARSEOP_DEFERRED; } else if (op_info->flags & AML_NAMED) { - size = sizeof (struct acpi_parse_obj_named); flags = ACPI_PARSEOP_NAMED; } else if (opcode == AML_INT_BYTELIST_OP) { - size = sizeof (struct acpi_parse_obj_named); flags = ACPI_PARSEOP_BYTELIST; } - else { - size = sizeof (struct acpi_parse_obj_common); - flags = ACPI_PARSEOP_GENERIC; - } - if (size == sizeof (struct acpi_parse_obj_common)) { - /* - * The generic op is by far the most common (16 to 1) - */ + /* Allocate the minimum required size object */ + + if (flags == ACPI_PARSEOP_GENERIC) { + /* The generic op (default) is by far the most common (16 to 1) */ + op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE); } else { + /* Extended parseop */ + op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE_EXT); } diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c --- a/drivers/acpi/processor.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/processor.c 2004-10-26 18:29:14 -07:00 @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include #include @@ -99,6 +101,8 @@ }, }; +static int c2 = -1; +static int c3 = -1; struct acpi_processor_errata { u8 smp; @@ -140,6 +144,8 @@ static struct acpi_processor *processors[NR_CPUS]; static struct acpi_processor_errata errata; +module_param_named(c2, c2, bool, 0); +module_param_named(c3, c3, bool, 0); static void (*pm_idle_save)(void); @@ -656,6 +662,11 @@ else if (errata.smp) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "C2 not supported in SMP mode\n")); + + + else if (!c2) + printk(KERN_INFO "C2 disabled\n"); + /* * Otherwise we've met all of our C2 requirements. * Normalize the C2 latency to expidite policy. @@ -711,6 +722,9 @@ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "C3 not supported on PIIX4 with Type-F DMA\n")); } + else if (!c3) + printk(KERN_INFO "C3 disabled\n"); + /* * Otherwise we've met all of our C3 requirements. * Normalize the C2 latency to expidite policy. Enable @@ -767,7 +781,10 @@ * policy is adjusted accordingly. */ -static int acpi_processor_ppc_is_init = 0; +#define PPC_REGISTERED 1 +#define PPC_IN_USE 2 + +static int acpi_processor_ppc_status = 0; static int acpi_processor_ppc_notifier(struct notifier_block *nb, unsigned long event, @@ -825,6 +842,10 @@ * (e.g. 0 = states 0..n; 1 = states 1..n; etc. */ status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc); + + if (status != AE_NOT_FOUND) + acpi_processor_ppc_status |= PPC_IN_USE; + if(ACPI_FAILURE(status) && status != AE_NOT_FOUND) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PPC\n")); return_VALUE(-ENODEV); @@ -849,17 +870,17 @@ static void acpi_processor_ppc_init(void) { if (!cpufreq_register_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER)) - acpi_processor_ppc_is_init = 1; + acpi_processor_ppc_status |= PPC_REGISTERED; else printk(KERN_DEBUG "Warning: Processor Platform Limit not supported.\n"); } static void acpi_processor_ppc_exit(void) { - if (acpi_processor_ppc_is_init) + if (acpi_processor_ppc_status & PPC_REGISTERED) cpufreq_unregister_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER); - acpi_processor_ppc_is_init = 0; + acpi_processor_ppc_status &= ~PPC_REGISTERED; } /* @@ -1079,6 +1100,73 @@ } +int acpi_processor_notify_smm(struct module *calling_module) { + acpi_status status; + static int is_done = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_notify_smm"); + + if (!(acpi_processor_ppc_status & PPC_REGISTERED)) + return_VALUE(-EBUSY); + + if (!try_module_get(calling_module)) + return_VALUE(-EINVAL); + + /* is_done is set to negative if an error occured, + * and to postitive if _no_ error occured, but SMM + * was already notified. This avoids double notification + * which might lead to unexpected results... + */ + if (is_done > 0) { + module_put(calling_module); + return_VALUE(0); + } + else if (is_done < 0) { + module_put(calling_module); + return_VALUE(is_done); + } + + is_done = -EIO; + + /* Can't write pstate_cnt to smi_cmd if either value is zero */ + if ((!acpi_fadt.smi_cmd) || + (!acpi_fadt.pstate_cnt)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "No SMI port or pstate_cnt\n")); + module_put(calling_module); + return_VALUE(0); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Writing pstate_cnt [0x%x] to smi_cmd [0x%x]\n", acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd)); + + /* FADT v1 doesn't support pstate_cnt, many BIOS vendors use + * it anyway, so we need to support it... */ + if (acpi_fadt_is_v1) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Using v1.0 FADT reserved value for pstate_cnt\n")); + } + + status = acpi_os_write_port (acpi_fadt.smi_cmd, + (u32) acpi_fadt.pstate_cnt, 8); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Failed to write pstate_cnt [0x%x] to " + "smi_cmd [0x%x]\n", acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd)); + module_put(calling_module); + return_VALUE(status); + } + + /* Success. If there's no _PPC, we need to fear nothing, so + * we can allow the cpufreq driver to be rmmod'ed. */ + is_done = 1; + + if (!(acpi_processor_ppc_status & PPC_IN_USE)) + module_put(calling_module); + + return_VALUE(0); +} +EXPORT_SYMBOL(acpi_processor_notify_smm); + + #ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF /* /proc/acpi/processor/../performance interface (DEPRECATED) */ @@ -1235,7 +1323,7 @@ ACPI_FUNCTION_TRACE("acpi_processor_register_performance"); - if (!acpi_processor_ppc_is_init) + if (!(acpi_processor_ppc_status & PPC_REGISTERED)) return_VALUE(-EINVAL); down(&performance_sem); @@ -1276,9 +1364,6 @@ ACPI_FUNCTION_TRACE("acpi_processor_unregister_performance"); - if (!acpi_processor_ppc_is_init) - return_VOID; - down(&performance_sem); pr = processors[cpu]; @@ -2448,6 +2533,29 @@ return_VALUE(0); } +/* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. + For now disable this. Probably a bug somewhere else. */ +static int no_c2c3(struct dmi_system_id *id) +{ + printk(KERN_INFO + "%s detected - C2,C3 disabled. Overwrite with \"processor.c2=1 processor.c3=1\n\"", + id->ident); + if (c2 == -1) + c2 = 0; + if (c3 == -1) + c3 = 0; + return 0; +} + +static struct dmi_system_id __initdata processor_dmi_table[] = { + { no_c2c3, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }}, + { no_c2c3, "Medion 41700", { + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), + DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }}, + {}, +}; static int __init acpi_processor_init (void) @@ -2473,6 +2581,8 @@ acpi_thermal_cpufreq_init(); acpi_processor_ppc_init(); + + dmi_check_system(processor_dmi_table); return_VALUE(0); } diff -Nru a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c --- a/drivers/acpi/resources/rscalc.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/resources/rscalc.c 2004-10-26 18:29:14 -07:00 @@ -74,7 +74,6 @@ { acpi_size byte_stream_size_needed = 0; acpi_size segment_size; - struct acpi_resource_ext_irq *ex_irq = NULL; u8 done = FALSE; @@ -91,8 +90,8 @@ case ACPI_RSTYPE_IRQ: /* * IRQ Resource - * For an IRQ Resource, Byte 3, although optional, will - * always be created - it holds IRQ information. + * For an IRQ Resource, Byte 3, although optional, will always be + * created - it holds IRQ information. */ segment_size = 4; break; @@ -108,8 +107,8 @@ case ACPI_RSTYPE_START_DPF: /* * Start Dependent Functions Resource - * For a start_dependent_functions Resource, Byte 1, - * although optional, will always be created. + * For a start_dependent_functions Resource, Byte 1, although + * optional, will always be created. */ segment_size = 2; break; @@ -141,10 +140,9 @@ case ACPI_RSTYPE_VENDOR: /* * Vendor Defined Resource - * For a Vendor Specific resource, if the Length is - * between 1 and 7 it will be created as a Small - * Resource data type, otherwise it is a Large - * Resource data type. + * For a Vendor Specific resource, if the Length is between 1 and 7 + * it will be created as a Small Resource data type, otherwise it + * is a Large Resource data type. */ if (linked_list->data.vendor_specific.length > 7) { segment_size = 3; @@ -191,10 +189,9 @@ case ACPI_RSTYPE_ADDRESS16: /* * 16-Bit Address Resource - * The base size of this byte stream is 16. If a - * Resource Source string is not NULL, add 1 for - * the Index + the length of the null terminated - * string Resource Source + 1 for the null. + * The base size of this byte stream is 16. If a Resource Source + * string is not NULL, add 1 for the Index + the length of the null + * terminated string Resource Source + 1 for the null. */ segment_size = 16; @@ -223,10 +220,9 @@ case ACPI_RSTYPE_ADDRESS64: /* * 64-Bit Address Resource - * The base size of this byte stream is 46. If a Resource - * Source string is not NULL, add 1 for the Index + the - * length of the null terminated string Resource Source + - * 1 for the null. + * The base size of this byte stream is 46. If a resource_source + * string is not NULL, add 1 for the Index + the length of the null + * terminated string Resource Source + 1 for the null. */ segment_size = 46; @@ -239,9 +235,8 @@ case ACPI_RSTYPE_EXT_IRQ: /* * Extended IRQ Resource - * The base size of this byte stream is 9. This is for an - * Interrupt table length of 1. For each additional - * interrupt, add 4. + * The base size of this byte stream is 9. This is for an Interrupt + * table length of 1. For each additional interrupt, add 4. * If a Resource Source string is not NULL, add 1 for the * Index + the length of the null terminated string * Resource Source + 1 for the null. @@ -249,7 +244,7 @@ segment_size = 9 + (((acpi_size) linked_list->data.extended_irq.number_of_interrupts - 1) * 4); - if (ex_irq && ex_irq->resource_source.string_ptr) { + if (linked_list->data.extended_irq.resource_source.string_ptr) { segment_size += linked_list->data.extended_irq.resource_source.string_length; segment_size++; } @@ -257,8 +252,7 @@ default: /* - * If we get here, everything is out of sync, - * so exit with an error + * If we get here, everything is out of sync, exit with error */ return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); @@ -366,7 +360,6 @@ /* * 32-Bit Memory Range Resource */ - bytes_consumed = 20; structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem32); @@ -395,14 +388,12 @@ bytes_consumed = temp16 + 3; /* - * Resource Source Index and Resource Source are - * optional elements. Check the length of the - * Bytestream. If it is greater than 43, that - * means that an Index exists and is followed by - * a null termininated string. Therefore, set - * the temp variable to the length minus the minimum - * byte stream length plus the byte for the Index to - * determine the size of the NULL terminiated string. + * Resource Source Index and Resource Source are optional elements. + * Check the length of the Bytestream. If it is greater than 43, + * that means that an Index exists and is followed by a null + * terminated string. Therefore, set the temp variable to the + * length minus the minimum byte stream length plus the byte for + * the Index to determine the size of the NULL terminated string. */ if (43 < temp16) { temp8 = (u8) (temp16 - 44); @@ -433,14 +424,12 @@ bytes_consumed = temp16 + 3; /* - * Resource Source Index and Resource Source are - * optional elements. Check the length of the - * Bytestream. If it is greater than 23, that - * means that an Index exists and is followed by - * a null termininated string. Therefore, set - * the temp variable to the length minus the minimum - * byte stream length plus the byte for the Index to - * determine the size of the NULL terminiated string. + * Resource Source Index and Resource Source are optional elements. + * Check the length of the Bytestream. If it is greater than 23, + * that means that an Index exists and is followed by a null + * terminated string. Therefore, set the temp variable to the + * length minus the minimum byte stream length plus the byte for + * the Index to determine the size of the NULL terminated string. */ if (23 < temp16) { temp8 = (u8) (temp16 - 24); @@ -471,14 +460,12 @@ bytes_consumed = temp16 + 3; /* - * Resource Source Index and Resource Source are - * optional elements. Check the length of the - * Bytestream. If it is greater than 13, that - * means that an Index exists and is followed by - * a null termininated string. Therefore, set - * the temp variable to the length minus the minimum - * byte stream length plus the byte for the Index to - * determine the size of the NULL terminiated string. + * Resource Source Index and Resource Source are optional elements. + * Check the length of the Bytestream. If it is greater than 13, + * that means that an Index exists and is followed by a null + * terminated string. Therefore, set the temp variable to the + * length minus the minimum byte stream length plus the byte for + * the Index to determine the size of the NULL terminated string. */ if (13 < temp16) { temp8 = (u8) (temp16 - 14); @@ -509,9 +496,8 @@ bytes_consumed = temp16 + 3; /* - * Point past the length field and the - * Interrupt vector flags to save off the - * Interrupt table length to the Temp8 variable. + * Point past the length field and the Interrupt vector flags to + * save off the Interrupt table length to the Temp8 variable. */ buffer += 3; temp8 = *buffer; @@ -523,14 +509,12 @@ additional_bytes = (u8) ((temp8 - 1) * 4); /* - * Resource Source Index and Resource Source are - * optional elements. Check the length of the - * Bytestream. If it is greater than 9, that - * means that an Index exists and is followed by - * a null termininated string. Therefore, set - * the temp variable to the length minus the minimum - * byte stream length plus the byte for the Index to - * determine the size of the NULL terminiated string. + * Resource Source Index and Resource Source are optional elements. + * Check the length of the Bytestream. If it is greater than 9, + * that means that an Index exists and is followed by a null + * terminated string. Therefore, set the temp variable to the + * length minus the minimum byte stream length plus the byte for + * the Index to determine the size of the NULL terminated string. */ if (9 + additional_bytes < temp16) { temp8 = (u8) (temp16 - (9 + additional_bytes)); @@ -565,9 +549,8 @@ bytes_consumed = 3; } - /* - * Point past the descriptor - */ + /* Point past the descriptor */ + ++buffer; /* @@ -595,9 +578,8 @@ buffer = byte_stream_buffer; bytes_consumed = 3; - /* - * Point past the descriptor - */ + /* Point past the descriptor */ + ++buffer; /* diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c --- a/drivers/acpi/scan.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/scan.c 2004-10-26 18:29:14 -07:00 @@ -314,7 +314,12 @@ struct acpi_device *device, struct acpi_driver *driver) { - return acpi_match_ids(device, driver->ids); + int error = 0; + + error = driver->ops.match ? driver->ops.match(device, driver) : + acpi_match_ids(device, driver->ids) ; + + return error; } diff -Nru a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c --- a/drivers/acpi/sleep/main.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/sleep/main.c 2004-10-26 18:29:14 -07:00 @@ -1,6 +1,7 @@ /* * sleep.c - ACPI sleep support. * + * Copyright (c) 2004 David Shaohua Li * Copyright (c) 2000-2003 Patrick Mochel * Copyright (c) 2003 Open Source Development Lab * @@ -13,6 +14,7 @@ #include #include #include +#include #include #include #include "sleep.h" @@ -56,7 +58,8 @@ if (!acpi_wakeup_address) return -EFAULT; acpi_set_firmware_waking_vector( - (acpi_physical_address) acpi_wakeup_address); + (acpi_physical_address) virt_to_phys( + (void *)acpi_wakeup_address)); } ACPI_FLUSH_CPU_CACHE(); acpi_enable_wakeup_device_prep(acpi_state); diff -Nru a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c --- a/drivers/acpi/tables/tbconvrt.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/tables/tbconvrt.c 2004-10-26 18:29:14 -07:00 @@ -50,6 +50,8 @@ ACPI_MODULE_NAME ("tbconvrt") +u8 acpi_fadt_is_v1; + /******************************************************************************* * * FUNCTION: acpi_tb_get_table_count @@ -212,6 +214,7 @@ /* ACPI 1.0 FACS */ /* The BIOS stored FADT should agree with Revision 1.0 */ + acpi_fadt_is_v1 = 1; /* * Copy the table header and the common part of the tables. @@ -240,9 +243,12 @@ /* * Processor Performance State Control. This is the value OSPM writes to * the SMI_CMD register to assume processor performance state control - * responsibility. There isn't any equivalence in 1.0, leave it zeroed. + * responsibility. There isn't any equivalence in 1.0, but as many 1.x + * ACPI tables contain _PCT and _PSS we also keep this value, unless + * acpi_strict is set. */ - local_fadt->pstate_cnt = 0; + if (acpi_strict) + local_fadt->pstate_cnt = 0; /* * Support for the _CST object and C States change notification. diff -Nru a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c --- a/drivers/acpi/tables/tbget.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/tables/tbget.c 2004-10-26 18:29:14 -07:00 @@ -167,6 +167,9 @@ return_ACPI_STATUS (AE_BAD_PARAMETER); } + ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n", + return_header->signature)); + return_ACPI_STATUS (AE_OK); } diff -Nru a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c --- a/drivers/acpi/tables/tbxfroot.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/tables/tbxfroot.c 2004-10-26 18:29:14 -07:00 @@ -87,12 +87,28 @@ return_ACPI_STATUS (AE_AML_STRING_LIMIT); } - /* Find the table */ + if (!ACPI_STRNCMP (signature, DSDT_SIG, ACPI_NAME_SIZE)) { + /* + * The DSDT pointer is contained in the FADT, not the RSDT. + * This code should suffice, because the only code that would perform + * a "find" on the DSDT is the data_table_region() AML opcode -- in + * which case, the DSDT is guaranteed to be already loaded. + * If this becomes insufficient, the FADT will have to be found first. + */ + if (!acpi_gbl_DSDT) { + return_ACPI_STATUS (AE_NO_ACPI_TABLES); + } - status = acpi_get_firmware_table (signature, 1, - ACPI_LOGICAL_ADDRESSING, &table); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + table = acpi_gbl_DSDT; + } + else { + /* Find the table */ + + status = acpi_get_firmware_table (signature, 1, + ACPI_LOGICAL_ADDRESSING, &table); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } /* Check oem_id and oem_table_id */ @@ -102,6 +118,7 @@ return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND); } + ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n", table->signature)); *table_ptr = table; return_ACPI_STATUS (AE_OK); } diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c --- a/drivers/acpi/thermal.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/thermal.c 2004-10-26 18:29:14 -07:00 @@ -60,7 +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_MODE_CRITICAL 0xff #define ACPI_THERMAL_PATH_POWEROFF "/sbin/poweroff" #define ACPI_THERMAL_MAX_ACTIVE 10 @@ -953,7 +953,7 @@ seq_puts(seq, "\n"); } - if ( tz->cooling_mode == ACPI_THERMAL_MODE_CRT ) + if ( tz->cooling_mode == ACPI_THERMAL_MODE_CRITICAL ) seq_printf(seq, "cooling mode: critical\n"); else seq_printf(seq, "cooling mode: %s\n", @@ -1262,7 +1262,7 @@ tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE; } else { /* _ACx and _PSV are optional, but _CRT is required */ - tz->cooling_mode = ACPI_THERMAL_MODE_CRT; + tz->cooling_mode = ACPI_THERMAL_MODE_CRITICAL; } } diff -Nru a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c --- a/drivers/acpi/utilities/utalloc.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/utilities/utalloc.c 2004-10-26 18:29:14 -07:00 @@ -265,7 +265,7 @@ * RETURN: Status * * DESCRIPTION: Validate that the buffer is of the required length or - * allocate a new buffer. + * allocate a new buffer. Returned buffer is always zeroed. * ******************************************************************************/ @@ -305,24 +305,25 @@ /* Allocate a new buffer with local interface to allow tracking */ - buffer->pointer = ACPI_MEM_ALLOCATE (required_length); + buffer->pointer = ACPI_MEM_CALLOCATE (required_length); if (!buffer->pointer) { return (AE_NO_MEMORY); } - - /* Clear the buffer */ - - ACPI_MEMSET (buffer->pointer, 0, required_length); break; default: - /* Validate the size of the buffer */ + /* Existing buffer: Validate the size of the buffer */ if (buffer->length < required_length) { status = AE_BUFFER_OVERFLOW; + break; } + + /* Clear the buffer */ + + ACPI_MEMSET (buffer->pointer, 0, required_length); break; } @@ -472,7 +473,7 @@ acpi_status status; - allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_block), component, + allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header), component, module, line); if (!allocation) { return (NULL); @@ -518,7 +519,7 @@ acpi_status status; - allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_block), component, + allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header), component, module, line); if (!allocation) { /* Report allocation error */ @@ -712,6 +713,7 @@ allocation->line = line; ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME); + allocation->module[ACPI_MAX_MODULE_NAME-1] = 0; /* Insert at list head */ diff -Nru a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c --- a/drivers/acpi/utilities/utdelete.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/utilities/utdelete.c 2004-10-26 18:29:14 -07:00 @@ -621,6 +621,10 @@ return_VOID; } + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, + "Obj %p Current Refs=%X [To Be Incremented]\n", + object, object->common.reference_count)); + /* Increment the reference count */ (void) acpi_ut_update_object_reference (object, REF_INCREMENT); @@ -664,8 +668,9 @@ return_VOID; } - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X\n", - object, object->common.reference_count)); + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, + "Obj %p Current Refs=%X [To Be Decremented]\n", + object, object->common.reference_count)); /* * Decrement the reference count, and only actually delete the object diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c --- a/drivers/acpi/utilities/utglobal.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/utilities/utglobal.c 2004-10-26 18:29:14 -07:00 @@ -861,6 +861,7 @@ acpi_gbl_system_notify.handler = NULL; acpi_gbl_device_notify.handler = NULL; + acpi_gbl_exception_handler = NULL; acpi_gbl_init_handler = NULL; /* Global "typed" ACPI table pointers */ diff -Nru a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c --- a/drivers/acpi/utilities/utmath.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/utilities/utmath.c 2004-10-26 18:29:14 -07:00 @@ -59,7 +59,7 @@ * * FUNCTION: acpi_ut_short_divide * - * PARAMETERS: in_dividend - Pointer to the dividend + * PARAMETERS: Dividend - 64-bit dividend * Divisor - 32-bit divisor * out_quotient - Pointer to where the quotient is returned * out_remainder - Pointer to where the remainder is returned @@ -74,19 +74,18 @@ acpi_status acpi_ut_short_divide ( - acpi_integer *in_dividend, + acpi_integer dividend, u32 divisor, acpi_integer *out_quotient, u32 *out_remainder) { - union uint64_overlay dividend; + union uint64_overlay dividend_ovl; union uint64_overlay quotient; u32 remainder32; ACPI_FUNCTION_TRACE ("ut_short_divide"); - dividend.full = *in_dividend; /* Always check for a zero divisor */ @@ -95,13 +94,15 @@ return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); } + dividend_ovl.full = dividend; + /* * The quotient is 64 bits, the remainder is always 32 bits, * and is generated by the second divide. */ - ACPI_DIV_64_BY_32 (0, dividend.part.hi, divisor, + ACPI_DIV_64_BY_32 (0, dividend_ovl.part.hi, divisor, quotient.part.hi, remainder32); - ACPI_DIV_64_BY_32 (remainder32, dividend.part.lo, divisor, + ACPI_DIV_64_BY_32 (remainder32, dividend_ovl.part.lo, divisor, quotient.part.lo, remainder32); /* Return only what was requested */ @@ -121,8 +122,8 @@ * * FUNCTION: acpi_ut_divide * - * PARAMETERS: in_dividend - Pointer to the dividend - * in_divisor - Pointer to the divisor + * PARAMETERS: in_dividend - Dividend + * in_divisor - Divisor * out_quotient - Pointer to where the quotient is returned * out_remainder - Pointer to where the remainder is returned * @@ -134,8 +135,8 @@ acpi_status acpi_ut_divide ( - acpi_integer *in_dividend, - acpi_integer *in_divisor, + acpi_integer in_dividend, + acpi_integer in_divisor, acpi_integer *out_quotient, acpi_integer *out_remainder) { @@ -155,13 +156,13 @@ /* Always check for a zero divisor */ - if (*in_divisor == 0) { + if (in_divisor == 0) { ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n")); return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); } - divisor.full = *in_divisor; - dividend.full = *in_dividend; + divisor.full = in_divisor; + dividend.full = in_dividend; if (divisor.part.hi == 0) { /* * 1) Simplest case is where the divisor is 32 bits, we can @@ -269,7 +270,7 @@ acpi_status acpi_ut_short_divide ( - acpi_integer *in_dividend, + acpi_integer in_dividend, u32 divisor, acpi_integer *out_quotient, u32 *out_remainder) @@ -288,10 +289,10 @@ /* Return only what was requested */ if (out_quotient) { - *out_quotient = *in_dividend / divisor; + *out_quotient = in_dividend / divisor; } if (out_remainder) { - *out_remainder = (u32) *in_dividend % divisor; + *out_remainder = (u32) in_dividend % divisor; } return_ACPI_STATUS (AE_OK); @@ -299,8 +300,8 @@ acpi_status acpi_ut_divide ( - acpi_integer *in_dividend, - acpi_integer *in_divisor, + acpi_integer in_dividend, + acpi_integer in_divisor, acpi_integer *out_quotient, acpi_integer *out_remainder) { @@ -309,7 +310,7 @@ /* Always check for a zero divisor */ - if (*in_divisor == 0) { + if (in_divisor == 0) { ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n")); return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); } @@ -318,10 +319,10 @@ /* Return only what was requested */ if (out_quotient) { - *out_quotient = *in_dividend / *in_divisor; + *out_quotient = in_dividend / in_divisor; } if (out_remainder) { - *out_remainder = *in_dividend % *in_divisor; + *out_remainder = in_dividend % in_divisor; } return_ACPI_STATUS (AE_OK); diff -Nru a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c --- a/drivers/acpi/utilities/utmisc.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/utilities/utmisc.c 2004-10-26 18:29:14 -07:00 @@ -356,16 +356,15 @@ * FUNCTION: acpi_ut_strtoul64 * * PARAMETERS: String - Null terminated string - * Terminater - Where a pointer to the terminating byte is returned - * Base - Radix of the string + * Base - Radix of the string: 10, 16, or ACPI_ANY_BASE + * ret_integer - Where the converted integer is returned * - * RETURN: Converted value + * RETURN: Status and Converted value * * DESCRIPTION: Convert a string into an unsigned value. + * NOTE: Does not support Octal strings, not needed. * ******************************************************************************/ -#define NEGATIVE 1 -#define POSITIVE 0 acpi_status acpi_ut_strtoul64 ( @@ -373,50 +372,40 @@ u32 base, acpi_integer *ret_integer) { - u32 index; + u32 this_digit; acpi_integer return_value = 0; - acpi_status status = AE_OK; - acpi_integer dividend; acpi_integer quotient; - *ret_integer = 0; + ACPI_FUNCTION_TRACE ("ut_stroul64"); + switch (base) { - case 0: - case 8: + case ACPI_ANY_BASE: case 10: case 16: break; default: - /* - * The specified Base parameter is not in the domain of - * this function: - */ - return (AE_BAD_PARAMETER); + /* Invalid Base */ + return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* - * skip over any white space in the buffer: - */ + /* Skip over any white space in the buffer */ + while (ACPI_IS_SPACE (*string) || *string == '\t') { ++string; } /* * If the input parameter Base is zero, then we need to - * determine if it is octal, decimal, or hexadecimal: + * determine if it is decimal or hexadecimal: */ if (base == 0) { - if (*string == '0') { - if (ACPI_TOLOWER (*(++string)) == 'x') { - base = 16; - ++string; - } - else { - base = 8; - } + if ((*string == '0') && + (ACPI_TOLOWER (*(++string)) == 'x')) { + base = 16; + ++string; } else { base = 10; @@ -424,76 +413,67 @@ } /* - * For octal and hexadecimal bases, skip over the leading + * For hexadecimal base, skip over the leading * 0 or 0x, if they are present. */ - if (base == 8 && *string == '0') { - string++; - } - if (base == 16 && *string == '0' && ACPI_TOLOWER (*(++string)) == 'x') { string++; } - /* Main loop: convert the string to an unsigned long */ + /* Main loop: convert the string to a 64-bit integer */ while (*string) { if (ACPI_IS_DIGIT (*string)) { - index = ((u8) *string) - '0'; + /* Convert ASCII 0-9 to Decimal value */ + + this_digit = ((u8) *string) - '0'; } else { - index = (u8) ACPI_TOUPPER (*string); - if (ACPI_IS_UPPER ((char) index)) { - index = index - 'A' + 10; + this_digit = (u8) ACPI_TOUPPER (*string); + if (ACPI_IS_UPPER ((char) this_digit)) { + /* Convert ASCII Hex char to value */ + + this_digit = this_digit - 'A' + 10; } else { goto error_exit; } } - if (index >= base) { + /* Check to see if digit is out of range */ + + if (this_digit >= base) { goto error_exit; } - /* Check to see if value is out of range: */ + /* Divide the digit into the correct position */ - dividend = ACPI_INTEGER_MAX - (acpi_integer) index; - (void) acpi_ut_short_divide (÷nd, base, "ient, NULL); + (void) acpi_ut_short_divide ((ACPI_INTEGER_MAX - (acpi_integer) this_digit), + base, "ient, NULL); if (return_value > quotient) { goto error_exit; } return_value *= base; - return_value += index; + return_value += this_digit; ++string; } *ret_integer = return_value; - return (status); + return_ACPI_STATUS (AE_OK); error_exit: - switch (base) { - case 8: - status = AE_BAD_OCTAL_CONSTANT; - break; - - case 10: - status = AE_BAD_DECIMAL_CONSTANT; - break; - - case 16: - status = AE_BAD_HEX_CONSTANT; - break; + /* Base was set/validated above */ - default: - /* Base validated above */ - break; + if (base == 10) { + return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); + } + else { + return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); } - - return (status); } diff -Nru a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c --- a/drivers/acpi/utilities/utobject.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/acpi/utilities/utobject.c 2004-10-26 18:29:14 -07:00 @@ -155,9 +155,8 @@ ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size); - /* - * Create a new Buffer object - */ + /* Create a new Buffer object */ + buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); if (!buffer_desc) { return_PTR (NULL); @@ -186,6 +185,61 @@ /* Return the new buffer descriptor */ return_PTR (buffer_desc); +} + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_create_string_object + * + * PARAMETERS: string_size - Size of string to be created. Does not + * include NULL terminator, this is added + * automatically. + * + * RETURN: Pointer to a new String object + * + * DESCRIPTION: Create a fully initialized string object + * + ******************************************************************************/ + +union acpi_operand_object * +acpi_ut_create_string_object ( + acpi_size string_size) +{ + union acpi_operand_object *string_desc; + char *string; + + + ACPI_FUNCTION_TRACE_U32 ("ut_create_string_object", string_size); + + + /* Create a new String object */ + + string_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); + if (!string_desc) { + return_PTR (NULL); + } + + /* + * Allocate the actual string buffer -- (Size + 1) for NULL terminator. + * NOTE: Zero-length strings are NULL terminated + */ + string = ACPI_MEM_CALLOCATE (string_size + 1); + if (!string) { + ACPI_REPORT_ERROR (("create_string: could not allocate size %X\n", + (u32) string_size)); + acpi_ut_remove_reference (string_desc); + return_PTR (NULL); + } + + /* Complete string object initialization */ + + string_desc->string.pointer = string; + string_desc->string.length = (u32) string_size; + + /* Return the new string descriptor */ + + return_PTR (string_desc); } diff -Nru a/drivers/acpi/video.c b/drivers/acpi/video.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/acpi/video.c 2004-10-26 18:29:14 -07:00 @@ -0,0 +1,1962 @@ +/* + * video.c - ACPI Video Driver ($Revision:$) + * + * Copyright (C) 2004 Luming Yu + * Copyright (C) 2004 Bruno Ducrot + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#define ACPI_VIDEO_COMPONENT 0x08000000 +#define ACPI_VIDEO_CLASS "video" +#define ACPI_VIDEO_DRIVER_NAME "ACPI Video Driver" +#define ACPI_VIDEO_BUS_NAME "Video Bus" +#define ACPI_VIDEO_DEVICE_NAME "Video Device" +#define ACPI_VIDEO_NOTIFY_SWITCH 0x80 +#define ACPI_VIDEO_NOTIFY_PROBE 0x81 +#define ACPI_VIDEO_NOTIFY_CYCLE 0x82 +#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 +#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 + +#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82 +#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83 +#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84 +#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85 +#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86 + + +#define ACPI_VIDEO_HEAD_INVALID (~0ul - 1) +#define ACPI_VIDEO_HEAD_END (~0ul) + + +#define _COMPONENT ACPI_VIDEO_COMPONENT +ACPI_MODULE_NAME ("acpi_video") + +MODULE_AUTHOR("Bruno Ducrot"); +MODULE_DESCRIPTION(ACPI_VIDEO_DRIVER_NAME); +MODULE_LICENSE("GPL"); + +static int acpi_video_bus_add (struct acpi_device *device); +static int acpi_video_bus_remove (struct acpi_device *device, int type); +static int acpi_video_bus_match (struct acpi_device *device, struct acpi_driver *driver); + +static struct acpi_driver acpi_video_bus = { + .name = ACPI_VIDEO_DRIVER_NAME, + .class = ACPI_VIDEO_CLASS, + .ops = { + .add = acpi_video_bus_add, + .remove = acpi_video_bus_remove, + .match = acpi_video_bus_match, + }, +}; + +struct acpi_video_bus_flags { + u8 multihead:1; /* can switch video heads */ + u8 rom:1; /* can retrieve a video rom */ + u8 post:1; /* can configure the head to */ + u8 reserved:5; +}; + +struct acpi_video_bus_cap { + u8 _DOS:1; /*Enable/Disable output switching*/ + u8 _DOD:1; /*Enumerate all devices attached to display adapter*/ + u8 _ROM:1; /*Get ROM Data*/ + u8 _GPD:1; /*Get POST Device*/ + u8 _SPD:1; /*Set POST Device*/ + u8 _VPO:1; /*Video POST Options*/ + u8 reserved:2; +}; + +struct acpi_video_device_attrib{ + u32 display_index:4; /* A zero-based instance of the Display*/ + u32 display_port_attachment:4; /*This field differenates displays type*/ + u32 display_type:4; /*Describe the specific type in use*/ + u32 vendor_specific:4; /*Chipset Vendor Specifi*/ + u32 bios_can_detect:1; /*BIOS can detect the device*/ + u32 depend_on_vga:1; /*Non-VGA output device whose power is related to + the VGA device.*/ + u32 pipe_id:3; /*For VGA multiple-head devices.*/ + u32 reserved:10; /*Must be 0*/ + u32 device_id_scheme:1; /*Device ID Scheme*/ +}; + +struct acpi_video_enumerated_device { + union { + u32 int_val; + struct acpi_video_device_attrib attrib; + } value; + struct acpi_video_device *bind_info; +}; + +struct acpi_video_bus { + acpi_handle handle; + u8 dos_setting; + struct acpi_video_enumerated_device *attached_array; + u8 attached_count; + struct acpi_video_bus_cap cap; + struct acpi_video_bus_flags flags; + struct semaphore sem; + struct list_head video_device_list; + struct proc_dir_entry *dir; +}; + +struct acpi_video_device_flags { + u8 crt:1; + u8 lcd:1; + u8 tvout:1; + u8 bios:1; + u8 unknown:1; + u8 reserved:3; +}; + +struct acpi_video_device_cap { + u8 _ADR:1; /*Return the unique ID */ + u8 _BCL:1; /*Query list of brightness control levels supported*/ + u8 _BCM:1; /*Set the brightness level*/ + u8 _DDC:1; /*Return the EDID for this device*/ + u8 _DCS:1; /*Return status of output device*/ + u8 _DGS:1; /*Query graphics state*/ + u8 _DSS:1; /*Device state set*/ + u8 _reserved:1; +}; + +struct acpi_video_device_brightness { + int curr; + int count; + int *levels; +}; + +struct acpi_video_device { + acpi_handle handle; + unsigned long device_id; + struct acpi_video_device_flags flags; + struct acpi_video_device_cap cap; + struct list_head entry; + struct acpi_video_bus *video; + struct acpi_device *dev; + struct acpi_video_device_brightness *brightness; +}; + + +/* bus */ +static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); +static struct file_operations acpi_video_bus_info_fops = { + .open = acpi_video_bus_info_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file); +static struct file_operations acpi_video_bus_ROM_fops = { + .open = acpi_video_bus_ROM_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file); +static struct file_operations acpi_video_bus_POST_info_fops = { + .open = acpi_video_bus_POST_info_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file); +static struct file_operations acpi_video_bus_POST_fops = { + .open = acpi_video_bus_POST_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + +static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file); +static struct file_operations acpi_video_bus_DOS_fops = { + .open = acpi_video_bus_DOS_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* device */ +static int acpi_video_device_info_open_fs(struct inode *inode, struct file *file); +static struct file_operations acpi_video_device_info_fops = { + .open = acpi_video_device_info_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_device_state_open_fs(struct inode *inode, struct file *file); +static struct file_operations acpi_video_device_state_fops = { + .open = acpi_video_device_state_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file); +static struct file_operations acpi_video_device_brightness_fops = { + .open = acpi_video_device_brightness_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file); +static struct file_operations acpi_video_device_EDID_fops = { + .open = acpi_video_device_EDID_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void acpi_video_device_notify ( acpi_handle handle, u32 event, void *data); +static void acpi_video_device_rebind( struct acpi_video_bus *video); +static void acpi_video_device_bind( struct acpi_video_bus *video, struct acpi_video_device *device); +static int acpi_video_device_enumerate(struct acpi_video_bus *video); +static int acpi_video_switch_output( struct acpi_video_bus *video, int event); +static int acpi_video_get_next_level( struct acpi_video_device *device, u32 level_current,u32 event); +static void acpi_video_switch_brightness ( struct acpi_video_device *device, int event); + + +/* -------------------------------------------------------------------------- + Video Management + -------------------------------------------------------------------------- */ + +/* device */ + +static int +acpi_video_device_query ( + struct acpi_video_device *device, + unsigned long *state) +{ + int status; + ACPI_FUNCTION_TRACE("acpi_video_device_query"); + status = acpi_evaluate_integer(device->handle, "_DGS", NULL, state); + + return_VALUE(status); +} + +static int +acpi_video_device_get_state ( + struct acpi_video_device *device, + unsigned long *state) +{ + int status; + + ACPI_FUNCTION_TRACE("acpi_video_device_get_state"); + + status = acpi_evaluate_integer(device->handle, "_DCS", NULL, state); + + return_VALUE(status); +} + +static int +acpi_video_device_set_state ( + struct acpi_video_device *device, + int state) +{ + int status; + union acpi_object arg0 = {ACPI_TYPE_INTEGER}; + struct acpi_object_list args = {1, &arg0}; + + ACPI_FUNCTION_TRACE("acpi_video_device_set_state"); + + arg0.integer.value = state; + status = acpi_evaluate_integer(device->handle, "_DSS", &args, NULL); + + return_VALUE(status); +} + +static int +acpi_video_device_lcd_query_levels ( + struct acpi_video_device *device, + union acpi_object **levels) +{ + int status; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *obj; + + + ACPI_FUNCTION_TRACE("acpi_video_device_lcd_query_levels"); + + *levels = NULL; + + status = acpi_evaluate_object(device->handle, "_BCL", NULL, &buffer); + if (!ACPI_SUCCESS(status)) + return_VALUE(status); + obj = (union acpi_object *) buffer.pointer; + if (!obj && (obj->type != ACPI_TYPE_PACKAGE)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _BCL data\n")); + status = -EFAULT; + goto err; + } + + *levels = obj; + + return_VALUE(0); + +err: + if (buffer.pointer) + kfree(buffer.pointer); + + return_VALUE(status); +} + +static int +acpi_video_device_lcd_set_level ( + struct acpi_video_device *device, + int level) +{ + int status; + union acpi_object arg0 = {ACPI_TYPE_INTEGER}; + struct acpi_object_list args = {1, &arg0}; + + ACPI_FUNCTION_TRACE("acpi_video_device_lcd_set_level"); + + arg0.integer.value = level; + status = acpi_evaluate_object(device->handle, "_BCM", &args, NULL); + + printk(KERN_DEBUG "set_level status: %x\n", status); + return_VALUE(status); +} + +static int +acpi_video_device_lcd_get_level_current ( + struct acpi_video_device *device, + unsigned long *level) +{ + int status; + ACPI_FUNCTION_TRACE("acpi_video_device_lcd_get_level_current"); + + status = acpi_evaluate_integer(device->handle, "_BQC", NULL, level); + + return_VALUE(status); +} + +static int +acpi_video_device_EDID ( + struct acpi_video_device *device, + union acpi_object **edid, + ssize_t length) +{ + int status; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *obj; + union acpi_object arg0 = {ACPI_TYPE_INTEGER}; + struct acpi_object_list args = {1, &arg0}; + + ACPI_FUNCTION_TRACE("acpi_video_device_get_EDID"); + + *edid = NULL; + + if (!device) + return_VALUE(-ENODEV); + if (length == 128) + arg0.integer.value = 1; + else if (length == 256) + arg0.integer.value = 2; + else + return_VALUE(-EINVAL); + + status = acpi_evaluate_object(device->handle, "_DDC", &args, &buffer); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + obj = (union acpi_object *) buffer.pointer; + + if (obj && obj->type == ACPI_TYPE_BUFFER) + *edid = obj; + else { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _DDC data\n")); + status = -EFAULT; + kfree(obj); + } + + return_VALUE(status); +} + + +/* bus */ + +static int +acpi_video_bus_set_POST ( + struct acpi_video_bus *video, + unsigned long option) +{ + int status; + unsigned long tmp; + union acpi_object arg0 = {ACPI_TYPE_INTEGER}; + struct acpi_object_list args = {1, &arg0}; + + ACPI_FUNCTION_TRACE("acpi_video_bus_set_POST"); + + arg0.integer.value = option; + + status = acpi_evaluate_integer(video->handle, "_SPD", &args, &tmp); + if (ACPI_SUCCESS(status)) + status = tmp ? (-EINVAL):(AE_OK); + + return_VALUE(status); +} + +static int +acpi_video_bus_get_POST ( + struct acpi_video_bus *video, + unsigned long *id) +{ + int status; + + ACPI_FUNCTION_TRACE("acpi_video_bus_get_POST"); + + status = acpi_evaluate_integer(video->handle, "_GPD", NULL, id); + + return_VALUE(status); +} + +static int +acpi_video_bus_POST_options ( + struct acpi_video_bus *video, + unsigned long *options) +{ + int status; + ACPI_FUNCTION_TRACE("acpi_video_bus_POST_options"); + + status = acpi_evaluate_integer(video->handle, "_VPO", NULL, options); + *options &= 3; + + return_VALUE(status); +} + +/* + * Arg: + * video : video bus device pointer + * bios_flag : + * 0. The system BIOS should NOT automatically switch(toggle) + * the active display output. + * 1. The system BIOS should automatically switch (toggle) the + * active display output. No swich event. + * 2. The _DGS value should be locked. + * 3. The system BIOS should not automatically switch (toggle) the + * active display output, but instead generate the display switch + * event notify code. + * lcd_flag : + * 0. The system BIOS should automatically control the brightness level + * of the LCD, when the power changes from AC to DC + * 1. The system BIOS should NOT automatically control the brightness + * level of the LCD, when the power changes from AC to DC. + * Return Value: + * -1 wrong arg. + */ + +static int +acpi_video_bus_DOS( + struct acpi_video_bus *video, + int bios_flag, + int lcd_flag) +{ + acpi_integer status = 0; + union acpi_object arg0 = {ACPI_TYPE_INTEGER}; + struct acpi_object_list args = {1, &arg0}; + + ACPI_FUNCTION_TRACE("acpi_video_bus_DOS"); + + if (bios_flag < 0 || bios_flag >3 || lcd_flag < 0 || lcd_flag > 1){ + status = -1; + goto Failed; + } + arg0.integer.value = (lcd_flag << 2) | bios_flag; + video->dos_setting = arg0.integer.value; + acpi_evaluate_object(video->handle, "_DOS", &args, NULL); + +Failed: + return_VALUE(status); +} + +/* + * Arg: + * device : video output device (LCD, CRT, ..) + * + * Return Value: + * None + * + * Find out all required AML method defined under the output + * device. + */ + +static void +acpi_video_device_find_cap (struct acpi_video_device *device) +{ + acpi_integer status; + acpi_handle h_dummy1; + int i; + union acpi_object *obj = NULL; + struct acpi_video_device_brightness *br = NULL; + + ACPI_FUNCTION_TRACE("acpi_video_device_find_cap"); + + memset( &device->cap, 0, 4); + + if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_ADR", &h_dummy1))) { + device->cap._ADR = 1; + } + if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_BCL", &h_dummy1))) { + device->cap._BCL= 1; + } + if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_BCM", &h_dummy1))) { + device->cap._BCM= 1; + } + if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DDC", &h_dummy1))) { + device->cap._DDC= 1; + } + if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DCS", &h_dummy1))) { + device->cap._DCS = 1; + } + if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DGS", &h_dummy1))) { + device->cap._DGS = 1; + } + if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DSS", &h_dummy1))) { + device->cap._DSS = 1; + } + + status = acpi_video_device_lcd_query_levels(device, &obj); + + if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count >= 2) { + int count = 0; + union acpi_object *o; + + br = kmalloc(sizeof &br, GFP_KERNEL); + if (!br) { + printk(KERN_ERR "can't allocate memory\n"); + } else { + memset(br, 0, sizeof &br); + br->levels = kmalloc(obj->package.count * sizeof &br->levels, GFP_KERNEL); + if (!br->levels) + goto out; + + for (i = 0; i < obj->package.count; i++) { + o = (union acpi_object *) &obj->package.elements[i]; + if (o->type != ACPI_TYPE_INTEGER) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n")); + continue; + } + br->levels[count] = (u32) o->integer.value; + count++; + } +out: + if (count < 2) { + if (br->levels) + kfree(br->levels); + kfree(br); + } else { + br->count = count; + device->brightness = br; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count)); + } + } + } + + if (obj) + kfree(obj); + + return_VOID; +} + +/* + * Arg: + * device : video output device (VGA) + * + * Return Value: + * None + * + * Find out all required AML method defined under the video bus device. + */ + +static void +acpi_video_bus_find_cap (struct acpi_video_bus *video) +{ + acpi_handle h_dummy1; + + memset(&video->cap ,0, 4); + if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_DOS", &h_dummy1))) { + video->cap._DOS = 1; + } + if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_DOD", &h_dummy1))) { + video->cap._DOD = 1; + } + if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_ROM", &h_dummy1))) { + video->cap._ROM = 1; + } + if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_GPD", &h_dummy1))) { + video->cap._GPD = 1; + } + if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_SPD", &h_dummy1))) { + video->cap._SPD = 1; + } + if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_VPO", &h_dummy1))) { + video->cap._VPO = 1; + } +} + +/* + * Check whether the video bus device has required AML method to + * support the desired features + */ + +static int +acpi_video_bus_check ( + struct acpi_video_bus *video) +{ + acpi_status status = -ENOENT; + + + ACPI_FUNCTION_TRACE("acpi_video_bus_check"); + + if (!video) + return_VALUE(-EINVAL); + + /* Since there is no HID, CID and so on for VGA driver, we have + * to check well known required nodes. + */ + + /* Does this device able to support video switching ? */ + if(video->cap._DOS){ + video->flags.multihead = 1; + status = 0; + } + + /* Does this device able to retrieve a retrieve a video ROM ? */ + if(video->cap._ROM){ + video->flags.rom = 1; + status = 0; + } + + /* Does this device able to configure which video device to POST ? */ + if(video->cap._GPD && video->cap._SPD && video->cap._VPO){ + video->flags.post = 1; + status = 0; + } + + return_VALUE(status); +} + +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +struct proc_dir_entry *acpi_video_dir; + +/* video devices */ + +static ssize_t +acpi_video_device_info_seq_show ( + struct seq_file *seq, + void *offset) +{ + struct acpi_video_device *dev = (struct acpi_video_device *) seq->private; + + ACPI_FUNCTION_TRACE("acpi_video_device_info_seq_show"); + + if (!dev) + goto end; + + seq_printf(seq, "device_id: 0x%04x\n", (u32) dev->device_id); + seq_printf(seq, "type: "); + if (dev->flags.crt) + seq_printf(seq, "CRT\n"); + else if (dev->flags.lcd) + seq_printf(seq, "LCD\n"); + else if (dev->flags.tvout) + seq_printf(seq, "TVOUT\n"); + else + seq_printf(seq, "UNKNOWN\n"); + + seq_printf(seq,"known by bios: %s\n", + dev->flags.bios ? "yes":"no"); + +end: + return_VALUE(0); +} + +static int +acpi_video_device_info_open_fs ( + struct inode *inode, + struct file *file) +{ + return single_open(file, acpi_video_device_info_seq_show, + PDE(inode)->data); +} + +static ssize_t +acpi_video_device_state_seq_show ( + struct seq_file *seq, + void *offset) +{ + int status; + struct acpi_video_device *dev = (struct acpi_video_device *) seq->private; + unsigned long state; + + ACPI_FUNCTION_TRACE("acpi_video_device_state_seq_show"); + + if (!dev) + goto end; + + status = acpi_video_device_get_state(dev, &state); + seq_printf(seq, "state: "); + if (ACPI_SUCCESS(status)) + seq_printf(seq, "0x%02lx\n", state); + else + seq_printf(seq, "\n"); + + status = acpi_video_device_query(dev, &state); + seq_printf(seq, "query: "); + if (ACPI_SUCCESS(status)) + seq_printf(seq, "0x%02lx\n", state); + else + seq_printf(seq, "\n"); + +end: + return_VALUE(0); +} + +static int +acpi_video_device_state_open_fs ( + struct inode *inode, + struct file *file) +{ + return single_open(file, acpi_video_device_state_seq_show, + PDE(inode)->data); +} + +static ssize_t +acpi_video_device_write_state ( + struct file *file, + const char __user *buffer, + size_t count, + loff_t *data) +{ + int status; + struct seq_file *m = (struct seq_file *) file->private_data; + struct acpi_video_device *dev = (struct acpi_video_device *) m->private; + char str[12] = {0}; + u32 state = 0; + + ACPI_FUNCTION_TRACE("acpi_video_device_write_state"); + + if (!dev || count + 1 > sizeof str) + return_VALUE(-EINVAL); + + if (copy_from_user(str, buffer, count)) + return_VALUE(-EFAULT); + + str[count] = 0; + state = simple_strtoul(str, NULL, 0); + state &= ((1ul<<31) | (1ul<<30) | (1ul<<0)); + + status = acpi_video_device_set_state(dev, state); + + if (status) + return_VALUE(-EFAULT); + + return_VALUE(count); +} + +static ssize_t +acpi_video_device_brightness_seq_show ( + struct seq_file *seq, + void *offset) +{ + struct acpi_video_device *dev = (struct acpi_video_device *) seq->private; + int i; + + ACPI_FUNCTION_TRACE("acpi_video_device_brightness_seq_show"); + + if (!dev || !dev->brightness) { + seq_printf(seq, "\n"); + return_VALUE(0); + } + + seq_printf(seq, "levels: "); + for (i = 0; i < dev->brightness->count; i++) + seq_printf(seq, " %d", dev->brightness->levels[i]); + seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); + + return_VALUE(0); +} + +static int +acpi_video_device_brightness_open_fs ( + struct inode *inode, + struct file *file) +{ + return single_open(file, acpi_video_device_brightness_seq_show, + PDE(inode)->data); +} + +static ssize_t +acpi_video_device_write_brightness ( + struct file *file, + const char __user *buffer, + size_t count, + loff_t *data) +{ + struct seq_file *m = (struct seq_file *) file->private_data; + struct acpi_video_device *dev = (struct acpi_video_device *) m->private; + char str[4] = {0}; + unsigned int level = 0; + int i; + + ACPI_FUNCTION_TRACE("acpi_video_device_write_brightness"); + + if (!dev || count + 1 > sizeof str) + return_VALUE(-EINVAL); + + if (copy_from_user(str, buffer, count)) + return_VALUE(-EFAULT); + + str[count] = 0; + level = simple_strtoul(str, NULL, 0); + + if (level > 100) + return_VALUE(-EFAULT); + + /* validate though the list of available levels */ + for (i = 0; i < dev->brightness->count; i++) + if (level == dev->brightness->levels[i]) { + if (ACPI_SUCCESS(acpi_video_device_lcd_set_level(dev, level))) + dev->brightness->curr = level; + break; + } + + return_VALUE(count); +} + +static ssize_t +acpi_video_device_EDID_seq_show ( + struct seq_file *seq, + void *offset) +{ + struct acpi_video_device *dev = (struct acpi_video_device *) seq->private; + int status; + int i; + union acpi_object *edid = NULL; + + ACPI_FUNCTION_TRACE("acpi_video_device_EDID_seq_show"); + + if (!dev) + goto out; + + status = acpi_video_device_EDID (dev, &edid, 128); + if (ACPI_FAILURE(status)) { + status = acpi_video_device_EDID (dev, &edid, 256); + } + + if (ACPI_FAILURE(status)) { + goto out; + } + + if (edid && edid->type == ACPI_TYPE_BUFFER) { + for (i = 0; i < edid->buffer.length; i++) + seq_putc(seq, edid->buffer.pointer[i]); + } + +out: + if (!edid) + seq_printf(seq, "\n"); + else + kfree(edid); + + return_VALUE(0); +} + +static int +acpi_video_device_EDID_open_fs ( + struct inode *inode, + struct file *file) +{ + return single_open(file, acpi_video_device_EDID_seq_show, + PDE(inode)->data); +} + + +static int +acpi_video_device_add_fs ( + struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + struct acpi_video_device *vid_dev; + + ACPI_FUNCTION_TRACE("acpi_video_device_add_fs"); + + if (!device) + return_VALUE(-ENODEV); + + vid_dev = (struct acpi_video_device *) acpi_driver_data(device); + if (!vid_dev) + return_VALUE(-ENODEV); + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + vid_dev->video->dir); + if (!acpi_device_dir(device)) + return_VALUE(-ENODEV); + } + + /* 'info' [R] */ + entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create 'info' fs entry\n")); + else { + entry->proc_fops = &acpi_video_device_info_fops; + entry->data = acpi_driver_data(device); + } + + /* 'state' [R/W] */ + entry = create_proc_entry("state", S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create 'state' fs entry\n")); + else { + entry->proc_fops = &acpi_video_device_state_fops; + entry->proc_fops->write = acpi_video_device_write_state; + entry->data = acpi_driver_data(device); + } + + /* 'brightness' [R/W] */ + entry = create_proc_entry("brightness", S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create 'brightness' fs entry\n")); + else { + entry->proc_fops = &acpi_video_device_brightness_fops; + entry->proc_fops->write = acpi_video_device_write_brightness; + entry->data = acpi_driver_data(device); + } + + /* 'EDID' [R] */ + entry = create_proc_entry("EDID", S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create 'brightness' fs entry\n")); + else { + entry->proc_fops = &acpi_video_device_EDID_fops; + entry->data = acpi_driver_data(device); + } + + return_VALUE(0); +} + +static int +acpi_video_device_remove_fs ( + struct acpi_device *device) +{ + struct acpi_video_device *vid_dev; + ACPI_FUNCTION_TRACE("acpi_video_device_remove_fs"); + + vid_dev = (struct acpi_video_device *) acpi_driver_data(device); + if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) + return_VALUE(-ENODEV); + + if (acpi_device_dir(device)) { + remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); + acpi_device_dir(device) = NULL; + } + + return_VALUE(0); +} + + +/* video bus */ +static ssize_t +acpi_video_bus_info_seq_show ( + struct seq_file *seq, + void *offset) +{ + struct acpi_video_bus *video = (struct acpi_video_bus *) seq->private; + + ACPI_FUNCTION_TRACE("acpi_video_bus_info_seq_show"); + + if (!video) + goto end; + + seq_printf(seq, "Switching heads: %s\n", + video->flags.multihead ? "yes":"no"); + seq_printf(seq, "Video ROM: %s\n", + video->flags.rom ? "yes":"no"); + seq_printf(seq, "Device to be POSTed on boot: %s\n", + video->flags.post ? "yes":"no"); + +end: + return_VALUE(0); +} + +static int +acpi_video_bus_info_open_fs ( + struct inode *inode, + struct file *file) +{ + return single_open(file, acpi_video_bus_info_seq_show, PDE(inode)->data); +} + +static ssize_t +acpi_video_bus_ROM_seq_show ( + struct seq_file *seq, + void *offset) +{ + struct acpi_video_bus *video = (struct acpi_video_bus *) seq->private; + + ACPI_FUNCTION_TRACE("acpi_video_bus_ROM_seq_show"); + + if (!video) + goto end; + + printk(KERN_INFO PREFIX "Please implement %s\n", __FUNCTION__); + seq_printf(seq, "\n"); + +end: + return_VALUE(0); +} + +static int +acpi_video_bus_ROM_open_fs ( + struct inode *inode, + struct file *file) +{ + return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data); +} + +static ssize_t +acpi_video_bus_POST_info_seq_show ( + struct seq_file *seq, + void *offset) +{ + struct acpi_video_bus *video = (struct acpi_video_bus *) seq->private; + unsigned long options; + int status; + + ACPI_FUNCTION_TRACE("acpi_video_bus_POST_info_seq_show"); + + if (!video) + goto end; + + status = acpi_video_bus_POST_options(video, &options); + if (ACPI_SUCCESS(status)) { + if (!(options & 1)) { + printk(KERN_WARNING PREFIX "The motherboard VGA device is not listed as a possible POST device.\n"); + printk(KERN_WARNING PREFIX "This indicate a BIOS bug. Please contact the manufacturer.\n"); + } + printk("%lx\n", options); + seq_printf(seq, "can POST: "); + if (options & 2) + seq_printf(seq, " "); + if (options & 4) + seq_printf(seq, " "); + seq_putc(seq, '\n'); + } else + seq_printf(seq, "\n"); +end: + return_VALUE(0); +} + +static int +acpi_video_bus_POST_info_open_fs ( + struct inode *inode, + struct file *file) +{ + return single_open(file, acpi_video_bus_POST_info_seq_show, PDE(inode)->data); +} + +static ssize_t +acpi_video_bus_POST_seq_show ( + struct seq_file *seq, + void *offset) +{ + struct acpi_video_bus *video = (struct acpi_video_bus *) seq->private; + int status; + unsigned long id; + char device_decode[][30] = { + "motherboard VGA device", + "PCI VGA device", + "AGP VGA device", + "UNKNOWN", + }; + + ACPI_FUNCTION_TRACE("acpi_video_bus_POST_seq_show"); + + if (!video) + goto end; + + status = acpi_video_bus_get_POST (video, &id); + if (!ACPI_SUCCESS(status)) { + seq_printf(seq, "\n"); + goto end; + } + seq_printf(seq, "device posted is <%s>\n", device_decode[id & 3]); + +end: + return_VALUE(0); +} + +static ssize_t +acpi_video_bus_DOS_seq_show ( + struct seq_file *seq, + void *offset) +{ + struct acpi_video_bus *video = (struct acpi_video_bus *) seq->private; + + ACPI_FUNCTION_TRACE("acpi_video_bus_DOS_seq_show"); + + seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting ); + + return_VALUE(0); +} + +static int +acpi_video_bus_POST_open_fs ( + struct inode *inode, + struct file *file) +{ + return single_open(file, acpi_video_bus_POST_seq_show, PDE(inode)->data); +} + +static int +acpi_video_bus_DOS_open_fs ( + struct inode *inode, + struct file *file) +{ + return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data); +} + +static ssize_t +acpi_video_bus_write_POST ( + struct file *file, + const char __user *buffer, + size_t count, + loff_t *data) +{ + int status; + struct seq_file *m = (struct seq_file *) file->private_data; + struct acpi_video_bus *video = (struct acpi_video_bus *) m->private; + char str[12] = {0}; + unsigned long opt, options; + + ACPI_FUNCTION_TRACE("acpi_video_bus_write_POST"); + + + if (!video || count + 1 > sizeof str) + return_VALUE(-EINVAL); + + status = acpi_video_bus_POST_options(video, &options); + if (!ACPI_SUCCESS(status)) + return_VALUE(-EINVAL); + + if (copy_from_user(str, buffer, count)) + return_VALUE(-EFAULT); + + str[count] = 0; + opt = strtoul(str, NULL, 0); + if (opt > 3) + return_VALUE(-EFAULT); + + /* just in case an OEM 'forget' the motherboard... */ + options |= 1; + + if (options & (1ul << opt)) { + status = acpi_video_bus_set_POST (video, opt); + if (!ACPI_SUCCESS(status)) + return_VALUE(-EFAULT); + + } + + + return_VALUE(count); +} + +static ssize_t +acpi_video_bus_write_DOS ( + struct file *file, + const char __user *buffer, + size_t count, + loff_t *data) +{ + int status; + struct seq_file *m = (struct seq_file *) file->private_data; + struct acpi_video_bus *video = (struct acpi_video_bus *) m->private; + char str[12] = {0}; + unsigned long opt; + + ACPI_FUNCTION_TRACE("acpi_video_bus_write_DOS"); + + + if (!video || count + 1 > sizeof str) + return_VALUE(-EINVAL); + + if (copy_from_user(str, buffer, count)) + return_VALUE(-EFAULT); + + str[count] = 0; + opt = strtoul(str, NULL, 0); + if (opt > 7) + return_VALUE(-EFAULT); + + status = acpi_video_bus_DOS (video, opt & 0x3, (opt & 0x4)>>2); + + if (!ACPI_SUCCESS(status)) + return_VALUE(-EFAULT); + + return_VALUE(count); +} + +static int +acpi_video_bus_add_fs ( + struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + struct acpi_video_bus *video; + + ACPI_FUNCTION_TRACE("acpi_video_bus_add_fs"); + + video = (struct acpi_video_bus *) acpi_driver_data(device); + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + acpi_video_dir); + if (!acpi_device_dir(device)) + return_VALUE(-ENODEV); + } + + video->dir = acpi_device_dir(device); + + /* 'info' [R] */ + entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'info' fs entry\n")); + else { + entry->proc_fops = &acpi_video_bus_info_fops; + entry->data = acpi_driver_data(device); + } + + /* 'ROM' [R] */ + entry = create_proc_entry("ROM", S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'ROM' fs entry\n")); + else { + entry->proc_fops = &acpi_video_bus_ROM_fops; + entry->data = acpi_driver_data(device); + } + + /* 'POST_info' [R] */ + entry = create_proc_entry("POST_info", S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'POST_info' fs entry\n")); + else { + entry->proc_fops = &acpi_video_bus_POST_info_fops; + entry->data = acpi_driver_data(device); + } + + /* 'POST' [R/W] */ + entry = create_proc_entry("POST", S_IFREG|S_IRUGO|S_IRUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'POST' fs entry\n")); + else { + entry->proc_fops = &acpi_video_bus_POST_fops; + entry->proc_fops->write = acpi_video_bus_write_POST; + entry->data = acpi_driver_data(device); + } + + /* 'DOS' [R/W] */ + entry = create_proc_entry("DOS", S_IFREG|S_IRUGO|S_IRUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'DOS' fs entry\n")); + else { + entry->proc_fops = &acpi_video_bus_DOS_fops; + entry->proc_fops->write = acpi_video_bus_write_DOS; + entry->data = acpi_driver_data(device); + } + + return_VALUE(0); +} + +static int +acpi_video_bus_remove_fs ( + struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_video_bus_remove_fs"); + + if (acpi_device_dir(device)) { + remove_proc_entry(acpi_device_bid(device), acpi_video_dir); + acpi_device_dir(device) = NULL; + } + + return_VALUE(0); +} + +/* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ + +/* device interface */ + +static int +acpi_video_bus_get_one_device ( + struct acpi_device *device, + struct acpi_video_bus *video) +{ + unsigned long device_id; + int status, result; + struct acpi_video_device *data; + + ACPI_FUNCTION_TRACE("acpi_video_bus_get_one_device"); + + if (!device || !video) + return_VALUE(-EINVAL); + + status = acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); + if (ACPI_SUCCESS(status)) { + + data = kmalloc(sizeof(struct acpi_video_device), GFP_KERNEL); + if (!data) + return_VALUE(-ENOMEM); + + memset(data, 0, sizeof(struct acpi_video_device)); + + data->handle = device->handle; + strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); + strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); + acpi_driver_data(device) = data; + + data->device_id = device_id; + data->video = video; + data->dev = device; + + switch (device_id & 0xffff) { + case 0x0100: + data->flags.crt = 1; + break; + case 0x0400: + data->flags.lcd = 1; + break; + case 0x0200: + data->flags.tvout = 1; + break; + default: + data->flags.unknown = 1; + break; + } + + acpi_video_device_bind(video, data); + acpi_video_device_find_cap(data); + + status = acpi_install_notify_handler(data->handle, + ACPI_DEVICE_NOTIFY, acpi_video_device_notify, data); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error installing notify handler\n")); + result = -ENODEV; + goto end; + } + + down(&video->sem); + list_add_tail(&data->entry, &video->video_device_list); + up(&video->sem); + + acpi_video_device_add_fs(device); + + return_VALUE(0); + } + +end: + return_VALUE(-ENOENT); +} + +/* + * Arg: + * video : video bus device + * + * Return: + * none + * + * Enumerate the video device list of the video bus, + * bind the ids with the corresponding video devices + * under the video bus. + */ + +static void +acpi_video_device_rebind( struct acpi_video_bus *video) +{ + struct list_head * node, * next; + list_for_each_safe(node, next, &video->video_device_list) { + struct acpi_video_device * dev = container_of(node, struct acpi_video_device, entry); + acpi_video_device_bind( video, dev); + } +} + +/* + * Arg: + * video : video bus device + * device : video output device under the video + * bus + * + * Return: + * none + * + * Bind the ids with the corresponding video devices + * under the video bus. + */ + +static void +acpi_video_device_bind( struct acpi_video_bus *video, + struct acpi_video_device *device) +{ + int i; + ACPI_FUNCTION_TRACE("acpi_video_device_bind"); + +#define IDS_VAL(i) video->attached_array[i].value.int_val +#define IDS_BIND(i) video->attached_array[i].bind_info + + for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID && + i < video->attached_count; i++) { + if (device->device_id == (IDS_VAL(i)& 0xffff)) { + IDS_BIND(i) = device; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i)); + } + } +#undef IDS_VAL +#undef IDS_BIND +} + +/* + * Arg: + * video : video bus device + * + * Return: + * < 0 : error + * + * Call _DOD to enumerate all devices attached to display adapter + * + */ + +static int acpi_video_device_enumerate(struct acpi_video_bus *video) +{ + int status; + int count; + int i; + struct acpi_video_enumerated_device *active_device_list; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *dod = NULL; + union acpi_object *obj; + + ACPI_FUNCTION_TRACE("acpi_video_device_enumerate"); + + status = acpi_evaluate_object(video->handle, "_DOD", NULL, &buffer); + if (!ACPI_SUCCESS(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _DOD\n")); + return_VALUE(status); + } + + dod = (union acpi_object *) buffer.pointer; + if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _DOD data\n")); + status = -EFAULT; + goto out; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n", + dod->package.count)); + + active_device_list= kmalloc( + dod->package.count*sizeof(struct acpi_video_enumerated_device), + GFP_KERNEL); + + if (!active_device_list) { + status = -ENOMEM; + goto out; + } + + count = 0; + for (i = 0; i < dod->package.count; i++) { + obj = (union acpi_object *) &dod->package.elements[i]; + + if (obj->type != ACPI_TYPE_INTEGER) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _DOD data\n")); + active_device_list[i].value.int_val = ACPI_VIDEO_HEAD_INVALID; + } + active_device_list[i].value.int_val = obj->integer.value; + active_device_list[i].bind_info = NULL; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, (int) obj->integer.value)); + count++; + } + active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END; + + if(video->attached_array) + kfree(video->attached_array); + + video->attached_array = active_device_list; + video->attached_count = count; +out: + acpi_os_free(buffer.pointer); + return_VALUE(status); +} + +/* + * Arg: + * video : video bus device + * event : Nontify Event + * + * Return: + * < 0 : error + * + * 1. Find out the current active output device. + * 2. Identify the next output device to switch + * 3. call _DSS to do actual switch. + */ + +static int +acpi_video_switch_output( + struct acpi_video_bus *video, + int event) +{ + struct list_head * node, * next; + struct acpi_video_device *dev=NULL; + struct acpi_video_device *dev_next=NULL; + struct acpi_video_device *dev_prev=NULL; + unsigned long state; + int status = 0; + + ACPI_FUNCTION_TRACE("acpi_video_switch_output"); + + list_for_each_safe(node, next, &video->video_device_list) { + struct acpi_video_device * dev = container_of(node, struct acpi_video_device, entry); + status = acpi_video_device_get_state(dev, &state); + if (state & 0x2){ + dev_next = container_of(node->next, struct acpi_video_device, entry); + dev_prev = container_of(node->prev, struct acpi_video_device, entry); + goto out; + } + } + dev_next = container_of(node->next, struct acpi_video_device, entry); + dev_prev = container_of(node->prev, struct acpi_video_device, entry); +out: + switch (event) { + case ACPI_VIDEO_NOTIFY_CYCLE: + case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: + acpi_video_device_set_state(dev, 0); + acpi_video_device_set_state(dev_next, 0x80000001); + break; + case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: + acpi_video_device_set_state(dev, 0); + acpi_video_device_set_state(dev_prev, 0x80000001); + default: + break; + } + + return_VALUE(status); +} + +static int +acpi_video_get_next_level( + struct acpi_video_device *device, + u32 level_current, + u32 event) +{ + /*Fix me*/ + return level_current; +} + + +static void +acpi_video_switch_brightness ( + struct acpi_video_device *device, + int event) +{ + unsigned long level_current, level_next; + acpi_video_device_lcd_get_level_current(device, &level_current); + level_next = acpi_video_get_next_level(device, level_current, event); + acpi_video_device_lcd_set_level(device, level_next); +} + +static int +acpi_video_bus_get_devices ( + struct acpi_video_bus *video, + struct acpi_device *device) +{ + int status = 0; + struct list_head *node, *next; + + ACPI_FUNCTION_TRACE("acpi_video_get_devices"); + + acpi_video_device_enumerate(video); + + list_for_each_safe(node, next, &device->children) { + struct acpi_device *dev = list_entry(node, struct acpi_device, node); + + if (!dev) + continue; + + status = acpi_video_bus_get_one_device(dev, video); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Cant attach device\n")); + continue; + } + + } + return_VALUE(status); +} + +static int +acpi_video_bus_put_one_device( + struct acpi_video_device *device) +{ + struct acpi_video_bus *video; + + ACPI_FUNCTION_TRACE("acpi_video_bus_put_one_device"); + + if (!device || !device->video) + return (-ENOENT); + + video = device->video; + + down(&video->sem); + list_del(&device->entry); + up(&video->sem); + acpi_video_device_remove_fs(device->dev); + + return_VALUE(0); +} + +static int +acpi_video_bus_put_devices ( + struct acpi_video_bus *video) +{ + int status; + struct list_head *node, *next; + + ACPI_FUNCTION_TRACE("acpi_video_bus_put_devices"); + + list_for_each_safe(node, next, &video->video_device_list) { + struct acpi_video_device *data = list_entry(node, struct acpi_video_device, entry); + if (!data) + continue; + + status = acpi_video_bus_put_one_device(data); + if(ACPI_FAILURE(status)) + printk(KERN_WARNING PREFIX "hhuuhhuu bug in acpi video driver.\n"); + + if (data->brightness) + kfree(data->brightness); + + kfree(data); + } + + return_VALUE(0); +} + +/* acpi_video interface */ + +static int +acpi_video_bus_start_devices( + struct acpi_video_bus *video) +{ + return acpi_video_bus_DOS(video, 1, 0); +} + +static int +acpi_video_bus_stop_devices( + struct acpi_video_bus *video) +{ + return acpi_video_bus_DOS(video, 0, 1); +} + +static void +acpi_video_bus_notify ( + acpi_handle handle, + u32 event, + void *data) +{ + struct acpi_video_bus *video = (struct acpi_video_bus *) data; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_video_bus_notify"); + printk("video bus notify\n"); + + if (!video) + return_VOID; + + if (acpi_bus_get_device(handle, &device)) + return_VOID; + + switch (event) { + case ACPI_VIDEO_NOTIFY_SWITCH: /* User request that a switch occur, + * most likely via hotkey. */ + acpi_bus_generate_event(device, event, 0); + break; + + case ACPI_VIDEO_NOTIFY_PROBE: /* User plug or remove a video + * connector. */ + acpi_video_device_enumerate(video); + acpi_video_device_rebind(video); + acpi_video_switch_output(video, event); + acpi_bus_generate_event(device, event, 0); + break; + + case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed.*/ + case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ + case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ + acpi_video_switch_output(video, event); + acpi_bus_generate_event(device, event, 0); + break; + + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Unsupported event [0x%x]\n", event)); + break; + } + + return_VOID; +} + +static void +acpi_video_device_notify ( + acpi_handle handle, + u32 event, + void *data) +{ + struct acpi_video_device *video_device = (struct acpi_video_device *) data; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_video_device_notify"); + + printk("video device notify\n"); + if (!video_device) + return_VOID; + + if (acpi_bus_get_device(handle, &device)) + return_VOID; + + switch (event) { + case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */ + case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */ + acpi_bus_generate_event(device, event, 0); + break; + case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ + case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ + case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ + case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ + case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ + acpi_video_switch_brightness (video_device, event); + acpi_bus_generate_event(device, event, 0); + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Unsupported event [0x%x]\n", event)); + break; + } + return_VOID; +} + +static int +acpi_video_bus_add ( + struct acpi_device *device) +{ + int result = 0; + acpi_status status = 0; + struct acpi_video_bus *video = NULL; + + ACPI_FUNCTION_TRACE("acpi_video_bus_add"); + + if (!device) + return_VALUE(-EINVAL); + + video = kmalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); + if (!video) + return_VALUE(-ENOMEM); + memset(video, 0, sizeof(struct acpi_video_bus)); + + video->handle = device->handle; + strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); + strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); + acpi_driver_data(device) = video; + + acpi_video_bus_find_cap(video); + result = acpi_video_bus_check(video); + if (result) + goto end; + + result = acpi_video_bus_add_fs(device); + if (result) + goto end; + + init_MUTEX(&video->sem); + INIT_LIST_HEAD(&video->video_device_list); + + acpi_video_bus_get_devices(video, device); + acpi_video_bus_start_devices(video); + + status = acpi_install_notify_handler(video->handle, + ACPI_DEVICE_NOTIFY, acpi_video_bus_notify, video); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error installing notify handler\n")); + result = -ENODEV; + goto end; + } + + printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", + ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), + video->flags.multihead ? "yes":"no", + video->flags.rom ? "yes":"no", + video->flags.post ? "yes":"no"); + +end: + if (result) { + acpi_video_bus_remove_fs(device); + kfree(video); + } + + return_VALUE(result); +} + +static int +acpi_video_bus_remove ( + struct acpi_device *device, + int type) +{ + acpi_status status = 0; + struct acpi_video_bus *video = NULL; + + ACPI_FUNCTION_TRACE("acpi_video_bus_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + video = (struct acpi_video_bus *) acpi_driver_data(device); + + acpi_video_bus_stop_devices(video); + + status = acpi_remove_notify_handler(video->handle, + ACPI_DEVICE_NOTIFY, acpi_video_bus_notify); + if (ACPI_FAILURE(status)) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error removing notify handler\n")); + + acpi_video_bus_put_devices(video); + acpi_video_bus_remove_fs(device); + + if (video->attached_array) + kfree(video->attached_array); + kfree(video); + + return_VALUE(0); +} + + +static int +acpi_video_bus_match ( + struct acpi_device *device, + struct acpi_driver *driver) +{ + acpi_handle h_dummy1; + acpi_handle h_dummy2; + acpi_handle h_dummy3; + + ACPI_FUNCTION_TRACE("acpi_video_bus_match"); + + if (!device || !driver) + return_VALUE(-EINVAL); + + /* Since there is no HID, CID for ACPI Video drivers, we have + * to check well known required nodes for each feature we support. + */ + + /* Does this device able to support video switching ? */ + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) && + ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2))) + return_VALUE(0); + + /* Does this device able to retrieve a video ROM ? */ + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1))) + return_VALUE(0); + + /* Does this device able to configure which video head to be POSTed ? */ + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) && + ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) && + ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3))) + return_VALUE(0); + + + return_VALUE(-ENODEV); +} + + +static int __init +acpi_video_init (void) +{ + int result = 0; + + ACPI_FUNCTION_TRACE("acpi_video_init"); + + /* + acpi_dbg_level = 0xFFFFFFFF; + acpi_dbg_layer = 0x08000000; + */ + + acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); + if (!acpi_video_dir) + return_VALUE(-ENODEV); + + result = acpi_bus_register_driver(&acpi_video_bus); + if (result < 0) { + remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + +static void __exit +acpi_video_exit (void) +{ + ACPI_FUNCTION_TRACE("acpi_video_exit"); + + acpi_bus_unregister_driver(&acpi_video_bus); + + remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); + + return_VOID; +} + +module_init(acpi_video_init); +module_exit(acpi_video_exit); diff -Nru a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c --- a/drivers/char/ipmi/ipmi_si_intf.c 2004-10-26 18:29:14 -07:00 +++ b/drivers/char/ipmi/ipmi_si_intf.c 2004-10-26 18:29:14 -07:00 @@ -1331,7 +1331,7 @@ static int acpi_failure = 0; /* For GPE-type interrupts. */ -u32 ipmi_acpi_gpe(void *context) +void ipmi_acpi_gpe(void *context) { struct smi_info *smi_info = context; unsigned long flags; @@ -1355,8 +1355,6 @@ smi_event_handler(smi_info, 0); out: spin_unlock_irqrestore(&(smi_info->si_lock), flags); - - return ACPI_INTERRUPT_HANDLED; } static int acpi_gpe_irq_setup(struct smi_info *info) diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h --- a/include/acpi/acconfig.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/acconfig.h 2004-10-26 18:29:14 -07:00 @@ -64,7 +64,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20040816 +#define ACPI_CA_VERSION 0x20041015 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, diff -Nru a/include/acpi/acglobal.h b/include/acpi/acglobal.h --- a/include/acpi/acglobal.h 2004-10-26 18:29:13 -07:00 +++ b/include/acpi/acglobal.h 2004-10-26 18:29:13 -07:00 @@ -180,6 +180,7 @@ ACPI_EXTERN struct acpi_memory_list acpi_gbl_memory_lists[ACPI_NUM_MEM_LISTS]; ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_device_notify; ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_system_notify; +ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler; ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; ACPI_EXTERN acpi_handle acpi_gbl_global_lock_semaphore; diff -Nru a/include/acpi/acinterp.h b/include/acpi/acinterp.h --- a/include/acpi/acinterp.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/acinterp.h 2004-10-26 18:29:14 -07:00 @@ -83,21 +83,25 @@ acpi_ex_convert_to_integer ( union acpi_operand_object *obj_desc, union acpi_operand_object **result_desc, - struct acpi_walk_state *walk_state); + u32 flags); acpi_status acpi_ex_convert_to_buffer ( union acpi_operand_object *obj_desc, - union acpi_operand_object **result_desc, - struct acpi_walk_state *walk_state); + union acpi_operand_object **result_desc); acpi_status acpi_ex_convert_to_string ( union acpi_operand_object *obj_desc, union acpi_operand_object **result_desc, - u32 base, - u32 max_length, - struct acpi_walk_state *walk_state); + u32 type); + +/* Types for ->String conversion */ + +#define ACPI_EXPLICIT_BYTE_COPY 0x00000000 +#define ACPI_EXPLICIT_CONVERT_HEX 0x00000001 +#define ACPI_IMPLICIT_CONVERT_HEX 0x00000002 +#define ACPI_EXPLICIT_CONVERT_DECIMAL 0x00000003 acpi_status acpi_ex_convert_to_target_type ( @@ -109,7 +113,7 @@ u32 acpi_ex_convert_to_ascii ( acpi_integer integer, - u32 base, + u16 base, u8 *string, u8 max_length); @@ -243,11 +247,19 @@ union acpi_operand_object **actual_return_desc, struct acpi_walk_state *walk_state); -u8 +acpi_status +acpi_ex_do_logical_numeric_op ( + u16 opcode, + acpi_integer integer0, + acpi_integer integer1, + u8 *logical_result); + +acpi_status acpi_ex_do_logical_op ( u16 opcode, - union acpi_operand_object *obj_desc, - union acpi_operand_object *obj_desc2); + union acpi_operand_object *operand0, + union acpi_operand_object *operand1, + u8 *logical_result); acpi_integer acpi_ex_do_math_op ( @@ -374,7 +386,7 @@ acpi_status acpi_ex_system_do_suspend( - u32 time); + acpi_integer time); acpi_status acpi_ex_system_do_stall ( @@ -411,6 +423,10 @@ /* * exmonadic - ACPI AML (p-code) execution, monadic operators */ + +acpi_status +acpi_ex_opcode_0A_0T_1R ( + struct acpi_walk_state *walk_state); acpi_status acpi_ex_opcode_1A_0T_0R ( diff -Nru a/include/acpi/aclocal.h b/include/acpi/aclocal.h --- a/include/acpi/aclocal.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/aclocal.h 2004-10-26 18:29:14 -07:00 @@ -53,7 +53,7 @@ /* Total number of aml opcodes defined */ -#define AML_NUM_OPCODES 0x7E +#define AML_NUM_OPCODES 0x7F /***************************************************************************** diff -Nru a/include/acpi/acobject.h b/include/acpi/acobject.h --- a/include/acpi/acobject.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/acobject.h 2004-10-26 18:29:14 -07:00 @@ -135,7 +135,10 @@ acpi_integer value; }; - +/* + * Note: The String and Buffer object must be identical through the Pointer + * element. There is code that depends on this. + */ struct acpi_object_string /* Null terminated, ASCII characters only */ { ACPI_OBJECT_COMMON_HEADER diff -Nru a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h --- a/include/acpi/acpi_bus.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/acpi_bus.h 2004-10-26 18:29:14 -07:00 @@ -104,6 +104,7 @@ typedef int (*acpi_op_resume) (struct acpi_device *device, int state); typedef int (*acpi_op_scan) (struct acpi_device *device); typedef int (*acpi_op_bind) (struct acpi_device *device); +typedef int (*acpi_op_match) (struct acpi_device *device, struct acpi_driver *driver); struct acpi_device_ops { acpi_op_add add; @@ -115,6 +116,7 @@ acpi_op_resume resume; acpi_op_scan scan; acpi_op_bind bind; + acpi_op_match match; }; struct acpi_driver { diff -Nru a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h --- a/include/acpi/acpiosxf.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/acpiosxf.h 2004-10-26 18:29:14 -07:00 @@ -217,9 +217,12 @@ void * context); void +acpi_os_wait_events_complete ( + void *context); + +void acpi_os_sleep ( - u32 seconds, - u32 milliseconds); + acpi_integer milliseconds); void acpi_os_stall ( @@ -304,7 +307,7 @@ void *pointer, acpi_size length); -u32 +u64 acpi_os_get_timer ( void); diff -Nru a/include/acpi/acpixf.h b/include/acpi/acpixf.h --- a/include/acpi/acpixf.h 2004-10-26 18:29:13 -07:00 +++ b/include/acpi/acpixf.h 2004-10-26 18:29:13 -07:00 @@ -300,6 +300,15 @@ void *context); acpi_status +acpi_install_exception_handler ( + acpi_exception_handler handler); + + +/* + * Event interfaces + */ + +acpi_status acpi_acquire_global_lock ( u16 timeout, u32 *handle); diff -Nru a/include/acpi/actbl.h b/include/acpi/actbl.h --- a/include/acpi/actbl.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/actbl.h 2004-10-26 18:29:14 -07:00 @@ -330,6 +330,8 @@ #include "actbl1.h" /* Acpi 1.0 table definitions */ #include "actbl2.h" /* Acpi 2.0 table definitions */ +extern u8 acpi_fadt_is_v1; /* is set to 1 if FADT is revision 1, + * needed for certain workarounds */ #pragma pack(1) /* diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h --- a/include/acpi/actypes.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/actypes.h 2004-10-26 18:29:14 -07:00 @@ -303,7 +303,7 @@ typedef u32 acpi_integer; #define ACPI_INTEGER_MAX ACPI_UINT32_MAX #define ACPI_INTEGER_BIT_SIZE 32 -#define ACPI_MAX_DECIMAL_DIGITS 10 +#define ACPI_MAX_DECIMAL_DIGITS 10 /* 2^32 = 4,294,967,296 */ #define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 32-bit divide */ @@ -315,13 +315,18 @@ typedef u64 acpi_integer; #define ACPI_INTEGER_MAX ACPI_UINT64_MAX #define ACPI_INTEGER_BIT_SIZE 64 -#define ACPI_MAX_DECIMAL_DIGITS 19 +#define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */ + #if ACPI_MACHINE_WIDTH == 64 #define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 64-bit divide */ #endif #endif +#define ACPI_MAX64_DECIMAL_DIGITS 20 +#define ACPI_MAX32_DECIMAL_DIGITS 10 +#define ACPI_MAX16_DECIMAL_DIGITS 5 +#define ACPI_MAX8_DECIMAL_DIGITS 3 /* * Constants with special meanings @@ -830,6 +835,14 @@ u32 function); #define ACPI_INIT_DEVICE_INI 1 + +typedef +acpi_status (*acpi_exception_handler) ( + acpi_status aml_status, + acpi_name name, + u16 opcode, + u32 aml_offset, + void *context); /* Address Spaces (For Operation Regions) */ diff -Nru a/include/acpi/acutils.h b/include/acpi/acutils.h --- a/include/acpi/acutils.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/acutils.h 2004-10-26 18:29:14 -07:00 @@ -178,6 +178,12 @@ acpi_size count); int +acpi_ut_memcmp ( + const char *buffer1, + const char *buffer2, + acpi_size count); + +int acpi_ut_strncmp ( const char *string1, const char *string2, @@ -577,6 +583,10 @@ acpi_ut_create_buffer_object ( acpi_size buffer_size); +union acpi_operand_object * +acpi_ut_create_string_object ( + acpi_size string_size); + /* * ut_ref_cnt - Object reference count management @@ -690,14 +700,14 @@ acpi_status acpi_ut_divide ( - acpi_integer *in_dividend, - acpi_integer *in_divisor, + acpi_integer in_dividend, + acpi_integer in_divisor, acpi_integer *out_quotient, acpi_integer *out_remainder); acpi_status acpi_ut_short_divide ( - acpi_integer *in_dividend, + acpi_integer in_dividend, u32 divisor, acpi_integer *out_quotient, u32 *out_remainder); @@ -715,6 +725,10 @@ char *string, u32 base, acpi_integer *ret_integer); + +/* Values for Base above (16=Hex, 10=Decimal) */ + +#define ACPI_ANY_BASE 0 char * acpi_ut_strupr ( diff -Nru a/include/acpi/amlcode.h b/include/acpi/amlcode.h --- a/include/acpi/amlcode.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/amlcode.h 2004-10-26 18:29:14 -07:00 @@ -170,6 +170,7 @@ #define AML_REVISION_OP (u16) 0x5b30 #define AML_DEBUG_OP (u16) 0x5b31 #define AML_FATAL_OP (u16) 0x5b32 +#define AML_TIMER_OP (u16) 0x5b33 /* ACPI 3.0 */ #define AML_REGION_OP (u16) 0x5b80 #define AML_FIELD_OP (u16) 0x5b81 #define AML_DEVICE_OP (u16) 0x5b82 @@ -305,22 +306,24 @@ /* Opcode flags */ -#define AML_HAS_ARGS 0x0800 -#define AML_HAS_TARGET 0x0400 -#define AML_HAS_RETVAL 0x0200 -#define AML_NSOBJECT 0x0100 -#define AML_NSOPCODE 0x0080 -#define AML_NSNODE 0x0040 -#define AML_NAMED 0x0020 -#define AML_DEFER 0x0010 -#define AML_FIELD 0x0008 -#define AML_CREATE 0x0004 -#define AML_MATH 0x0002 #define AML_LOGICAL 0x0001 -#define AML_CONSTANT 0x1000 +#define AML_LOGICAL_NUMERIC 0x0002 +#define AML_MATH 0x0004 +#define AML_CREATE 0x0008 +#define AML_FIELD 0x0010 +#define AML_DEFER 0x0020 +#define AML_NAMED 0x0040 +#define AML_NSNODE 0x0080 +#define AML_NSOPCODE 0x0100 +#define AML_NSOBJECT 0x0200 +#define AML_HAS_RETVAL 0x0400 +#define AML_HAS_TARGET 0x0800 +#define AML_HAS_ARGS 0x1000 +#define AML_CONSTANT 0x2000 /* Convenient flag groupings */ +#define AML_FLAGS_EXEC_0A_0T_1R AML_HAS_RETVAL #define AML_FLAGS_EXEC_1A_0T_0R AML_HAS_ARGS /* Monadic1 */ #define AML_FLAGS_EXEC_1A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Monadic2 */ #define AML_FLAGS_EXEC_1A_1T_0R AML_HAS_ARGS | AML_HAS_TARGET @@ -338,17 +341,18 @@ * The opcode Type is used in a dispatch table, do not change * without updating the table. */ -#define AML_TYPE_EXEC_1A_0T_0R 0x00 /* Monadic1 */ -#define AML_TYPE_EXEC_1A_0T_1R 0x01 /* Monadic2 */ -#define AML_TYPE_EXEC_1A_1T_0R 0x02 -#define AML_TYPE_EXEC_1A_1T_1R 0x03 /* monadic2_r */ -#define AML_TYPE_EXEC_2A_0T_0R 0x04 /* Dyadic1 */ -#define AML_TYPE_EXEC_2A_0T_1R 0x05 /* Dyadic2 */ -#define AML_TYPE_EXEC_2A_1T_1R 0x06 /* dyadic2_r */ -#define AML_TYPE_EXEC_2A_2T_1R 0x07 -#define AML_TYPE_EXEC_3A_0T_0R 0x08 -#define AML_TYPE_EXEC_3A_1T_1R 0x09 -#define AML_TYPE_EXEC_6A_0T_1R 0x0A +#define AML_TYPE_EXEC_0A_0T_1R 0x00 +#define AML_TYPE_EXEC_1A_0T_0R 0x01 /* Monadic1 */ +#define AML_TYPE_EXEC_1A_0T_1R 0x02 /* Monadic2 */ +#define AML_TYPE_EXEC_1A_1T_0R 0x03 +#define AML_TYPE_EXEC_1A_1T_1R 0x04 /* monadic2_r */ +#define AML_TYPE_EXEC_2A_0T_0R 0x05 /* Dyadic1 */ +#define AML_TYPE_EXEC_2A_0T_1R 0x06 /* Dyadic2 */ +#define AML_TYPE_EXEC_2A_1T_1R 0x07 /* dyadic2_r */ +#define AML_TYPE_EXEC_2A_2T_1R 0x08 +#define AML_TYPE_EXEC_3A_0T_0R 0x09 +#define AML_TYPE_EXEC_3A_1T_1R 0x0A +#define AML_TYPE_EXEC_6A_0T_1R 0x0B /* End of types used in dispatch table */ #define AML_TYPE_LITERAL 0x0B diff -Nru a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h --- a/include/acpi/amlresrc.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/amlresrc.h 2004-10-26 18:29:14 -07:00 @@ -99,7 +99,7 @@ /* * Resource descriptors defined in the ACPI specification. * - * Alignment must be BYTE because these descriptors + * Packing/alignment must be BYTE because these descriptors * are used to overlay the AML byte stream. */ #pragma pack(1) @@ -297,7 +297,7 @@ #pragma pack() -/* Union of all resource descriptors, sow we can allocate the worst case */ +/* Union of all resource descriptors, so we can allocate the worst case */ union asl_resource_desc { diff -Nru a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h --- a/include/acpi/platform/acenv.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/platform/acenv.h 2004-10-26 18:29:14 -07:00 @@ -232,6 +232,7 @@ #define ACPI_STRCAT(d,s) (void) strcat((d), (s)) #define ACPI_STRNCAT(d,s,n) strncat((d), (s), (acpi_size)(n)) #define ACPI_STRTOUL(d,s,n) strtoul((d), (s), (acpi_size)(n)) +#define ACPI_MEMCMP(s1,s2,n) memcmp((s1), (s2), (acpi_size)(n)) #define ACPI_MEMCPY(d,s,n) (void) memcpy((d), (s), (acpi_size)(n)) #define ACPI_MEMSET(d,s,n) (void) memset((d), (s), (acpi_size)(n)) @@ -295,6 +296,7 @@ #define ACPI_STRCAT(d,s) (void) acpi_ut_strcat ((d), (s)) #define ACPI_STRNCAT(d,s,n) acpi_ut_strncat ((d), (s), (acpi_size)(n)) #define ACPI_STRTOUL(d,s,n) acpi_ut_strtoul ((d), (s), (acpi_size)(n)) +#define ACPI_MEMCMP(s1,s2,n) acpi_ut_memcmp((s1), (s2), (acpi_size)(n)) #define ACPI_MEMCPY(d,s,n) (void) acpi_ut_memcpy ((d), (s), (acpi_size)(n)) #define ACPI_MEMSET(d,v,n) (void) acpi_ut_memset ((d), (v), (acpi_size)(n)) #define ACPI_TOUPPER acpi_ut_to_upper diff -Nru a/include/acpi/processor.h b/include/acpi/processor.h --- a/include/acpi/processor.h 2004-10-26 18:29:14 -07:00 +++ b/include/acpi/processor.h 2004-10-26 18:29:14 -07:00 @@ -140,4 +140,8 @@ struct acpi_processor_performance * performance, unsigned int cpu); +/* note: this locks both the calling module and the processor module + if a _PPC object exists, rmmod is disallowed then */ +int acpi_processor_notify_smm(struct module *calling_module); + #endif