bk://linux-acpi.bkbits.net/to-akpm len.brown@intel.com|ChangeSet|20050304052525|28709 len.brown # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2005/03/03 23:21:29-05:00 len.brown@intel.com # [ACPI] fix [ACPI_MTX_Hardware] AE_TIME warning # which resulted from enabling the wake-on-RTC feature # # http://bugme.osdl.org/show_bug.cgi?id=3967 # # Signed-off-by: David Shaohua Li # Signed-off-by: Len Brown # # drivers/acpi/events/evxface.c # 2004/12/30 02:39:01-05:00 len.brown@intel.com +3 -1 # fix [ACPI_MTX_Hardware] AE_TIME warnings resulting from wake-on-RTC fix # # ChangeSet # 2005/03/03 19:55:50-05:00 len.brown@intel.com # [ACPI] ACPICA 20050303 from Bob Moore for AE_AML_BUFFER_LIMIT issue. # # It turns out that tightening up the interpreter to truncate buffers # per the ACPI spec was a bad idea -- BIOS' in the field depended # on old behaviour. Instead, we'll endeavor to update the ACPI spec # to reflect industry practice in this area. # # http://bugme.osdl.org/show_bug.cgi?id=4263 # # Signed-off-by: Len Brown # # include/acpi/acconfig.h # 2005/03/03 19:55:39-05:00 len.brown@intel.com +1 -1 # ACPICA 20050303 # # drivers/acpi/executer/exstorob.c # 2005/03/03 19:55:38-05:00 len.brown@intel.com +2 -0 # ACPICA 20050303 # # ChangeSet # 2005/03/02 20:54:36-05: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 # 2005/03/02 20:54:31-05:00 len.brown@intel.com +0 -0 # Auto merged # # arch/ia64/kernel/acpi.c # 2005/03/02 20:54:31-05:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2005/03/02 14:13:39-05:00 len.brown@intel.com # [ACPI] fix sysfs "eject" file # # This fixes a if-statement in setup_sys_fs_device_files(). It seems to # assume that 'struct acpi_device_flags.ejectable' indicates whether a device # has _EJ0 or not. But this is not a right assumption. It indicates whether # a device has _EJ0|_EJD (See acpi_bus_get_flags() function). # # setup_sys_fs_device_files() creates 'eject' file for devices that have _EJ0 # control method under a corresponding directory in # /sys/firmware/acpi/namespace/ACPI/. 'eject' file is used to trigger # hot-removal function from userland. # # # # Signed-off-by: Keiichiro Tokunaga # Signed-off-by: Andrew Morton # Signed-off-by: Len Brown # # drivers/acpi/scan.c # 2005/02/23 04:48:12-05:00 len.brown@intel.com +9 -1 # Import patch acpi-fix-a-if-statement-in-setup_sys_fs_device_files.patch # # ChangeSet # 2005/03/02 14:06:18-05:00 len.brown@intel.com # [ACPI] fix ACPI container driver's notify handler. # # Previously, the handler tried to make a container device be offline if an # ACPI_NOTIFY_BUS/DEVICE_CHECK notification is performed on the device was # present and has its acpi_device. But, the condition is weird. Whenever # the notification is performed, there should be only the following two # conditions: # # 1. the device is present, but does not have its acpi_device. # 2. the device is not present, but has its acpi_device. # # #1 is a hot-addition case, which was handled properly also in previous # handler. #2 is a surprising hot-removal case, which was not handled in # previous handler. # # Signed-off-by: Keiichiro Tokunaga # Signed-off-by: Andrew Morton # Signed-off-by: Len Brown # # drivers/acpi/container.c # 2005/02/23 04:48:06-05:00 len.brown@intel.com +8 -3 # Import patch acpi-fix-containers-notify-handler-to-handle-proper-cases-properly.patch # # ChangeSet # 2005/03/02 14:02:55-05:00 len.brown@intel.com # [ACPI] fix kobject_hotplug() use by ACPI processor and container drivers # # A while ago, the drivers used their own function # 'processor_run_sbin_hotplug() and container_run_sbin_hotplug()' to notify # the agent script using /sbin/hotplug mechanism. But, they were changed to # use kobject_hotplug() instead and this has caused a side effect. # # The container driver was supposed to invoke a container.agent (user mode # agent script) using /sbin/hotplug mechanism, but after the changes, it is # not able to call the agent any more and kobject_hotplug() in the # container.c became to invoke a namespace.agent instead if exists. So, I # would like to use the namespace.agent to handle container hotplug event (or # something else) and let the agent to call proper agent (e.g. # container.agent). But, there is an issue we need to solve. When the # namespace.agent is called, a path name of associated kobject is passed as a # DEVPATH (e.g./sys/firmware/ acpi/namespace/ACPI/_SB/DEV0). However, the # agent would not know what device is associated with the DEVPATH nor which # agents to call since the DEVPATH name depends on platform. The attached # patch is to add .hotplug_ops member to acpi_namespace_kset structure and # let it to set a driver name attached to the target kobject into the envp[] # variable as a DRV_NAME element. With this, the namespace.agent can call # proper agents (e.g. container.agent) by refering the DRV_NAME. # # Signed-off-by: Keiichiro Tokunaga # Signed-off-by: Andrew Morton # Signed-off-by: Len Brown # # drivers/acpi/scan.c # 2005/02/23 04:48:05-05:00 len.brown@intel.com +25 -0 # Import patch fix-an-issue-in-acpi-processor-and-container-drivers-related-with-kobject_hotplug.patch # # ChangeSet # 2005/03/02 13:57:35-05:00 len.brown@intel.com # [ACPI] flush TLB in init_low_mappings() # # From: Li Shaohua # Signed-off-by: Andrew Morton # Signed-off-by: Len Brown # # arch/i386/kernel/acpi/sleep.c # 2005/02/23 04:48:04-05:00 len.brown@intel.com +2 -1 # Import patch acpi-flush-tlb-when-pagetable-changed.patch # # ChangeSet # 2005/03/02 13:54:47-05:00 len.brown@intel.com # [ACPI] enhance fan output in error path # # Currently, fan.c ignores errors from acpi_bus_get_power. On compaq evo # notebook that leads to very confusing empty output. # # From: Pavel Machek # Signed-off-by: Andrew Morton # Signed-off-by: Len Brown # # drivers/acpi/fan.c # 2005/02/23 04:48:03-05:00 len.brown@intel.com +8 -11 # Import patch acpi-report-errors-in-fanc.patch # # ChangeSet # 2005/03/02 13:36:53-05:00 len.brown@intel.com # [ACPI] CONFIG_ACPI_NUMA build fix # # Signed-off-by: Andrew Morton # Signed-off-by: Len Brown # # arch/ia64/kernel/acpi.c # 2005/02/23 04:47:50-05:00 len.brown@intel.com +1 -1 # Import patch ia64-acpi-build-fix.patch # # ChangeSet # 2005/03/01 15:26:20-05:00 len.brown@intel.com # [ACPI] ACPICA 20050228 from Bob Moore # # Fixed a problem where the result of an Index() operator # (an object reference) must increment the reference count # on the target object for the life of the object reference. # # Implemented AML Interpreter and Debugger support for # the new ACPI 3.0 Extended Address (IO, Memory, Space), # QwordSpace, DwordSpace, and WordSpace resource descriptors. # # Implemented support in the _OSI method for the ACPI 3.0 # "Extended Address Space Descriptor" string, indicating # interpreter support for the descriptors above. # # Implemented header support for the new ACPI 3.0 FADT # flag bits. # # Implemented header support for the new ACPI 3.0 PCI Express # bits for the PM1 status/enable registers. # # Updated header support for the MADT processor local Apic # struct and MADT platform interrupt source struct for new # ACPI 3.0 fields. # # Implemented header support for the SRAT and SLIT ACPI # tables. # # Signed-off-by: Len Brown # # include/acpi/platform/acenv.h # 2005/03/01 15:20:35-05:00 len.brown@intel.com +2 -0 # ACPICA 20050228 # # include/acpi/actypes.h # 2005/03/01 15:14:22-05:00 len.brown@intel.com +18 -15 # ACPICA 20050228 # # include/acpi/actbl2.h # 2005/03/01 15:14:22-05:00 len.brown@intel.com +68 -11 # ACPICA 20050228 # # include/acpi/actbl.h # 2005/03/01 15:14:22-05:00 len.brown@intel.com +3 -1 # ACPICA 20050228 # # include/acpi/aclocal.h # 2005/03/01 15:14:23-05:00 len.brown@intel.com +4 -0 # ACPICA 20050228 # # include/acpi/acdisasm.h # 2005/03/01 15:14:23-05:00 len.brown@intel.com +5 -0 # ACPICA 20050228 # # include/acpi/acconfig.h # 2005/03/01 15:14:23-05:00 len.brown@intel.com +2 -2 # ACPICA 20050228 # # drivers/acpi/utilities/utmisc.c # 2005/03/01 15:14:26-05:00 len.brown@intel.com +12 -8 # ACPICA 20050228 # # drivers/acpi/utilities/utglobal.c # 2005/03/01 15:14:26-05:00 len.brown@intel.com +9 -1 # ACPICA 20050228 # # drivers/acpi/utilities/utdelete.c # 2005/03/01 15:14:26-05:00 len.brown@intel.com +17 -1 # ACPICA 20050228 # # drivers/acpi/resources/rslist.c # 2005/03/01 15:14:25-05:00 len.brown@intel.com +1 -0 # ACPICA 20050228 # # drivers/acpi/resources/rsdump.c # 2005/03/01 15:14:25-05:00 len.brown@intel.com +13 -10 # ACPICA 20050228 # # drivers/acpi/resources/rscalc.c # 2005/03/01 15:14:25-05:00 len.brown@intel.com +14 -0 # ACPICA 20050228 # # drivers/acpi/resources/rsaddr.c # 2005/03/01 15:14:25-05:00 len.brown@intel.com +82 -64 # ACPICA 20050228 # # drivers/acpi/parser/psopcode.c # 2005/03/01 15:14:25-05:00 len.brown@intel.com +1 -1 # ACPICA 20050228 # # drivers/acpi/executer/exoparg2.c # 2005/03/01 15:14:25-05:00 len.brown@intel.com +6 -0 # ACPICA 20050228 # # ChangeSet # 2005/02/17 01:50:15-05:00 len.brown@intel.com # [ACPI] Add ACPI-based memory hot plug driver. # # The ACPI based memory hot plug driver patch supports physical hotplug # operations on memory. This driver fields notifications for memory add # and remove operations from firmware and notifies the VM of the affected # memory ranges. Accordingly, this driver also maintains and updates the # states of all the memory ranges. This driver is useful on hardware which # helps firmware generating ACPI events for every physical hotplug # operation of memory boards on the system during runtime. # # Signed-off-by: Dave Hansen # Signed-off-by: Naveen B S # Signed-off-by: Matt Tolentino # Signed-off-by: Len Brown # # drivers/acpi/acpi_memhotplug.c # 2005/01/17 08:37:54-05:00 len.brown@intel.com +542 -0 # Import patch acpi_memhp_driver.patch # # drivers/acpi/acpi_memhotplug.c # 2005/01/17 08:37:54-05:00 len.brown@intel.com +0 -0 # BitKeeper file /home/lenb/src/26-latest-hotplug/drivers/acpi/acpi_memhotplug.c # # drivers/acpi/Makefile # 2005/01/17 08:37:54-05:00 len.brown@intel.com +1 -0 # Import patch acpi_memhp_driver.patch # # drivers/acpi/Kconfig # 2005/01/17 09:09:09-05:00 len.brown@intel.com +21 -0 # Import patch acpi_memhp_driver.patch # diff -Nru a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c --- a/arch/i386/kernel/acpi/sleep.c 2005-03-03 21:42:34 -08:00 +++ b/arch/i386/kernel/acpi/sleep.c 2005-03-03 21:42:34 -08:00 @@ -8,7 +8,7 @@ #include #include #include - +#include /* address in low memory of the wakeup routine. */ unsigned long acpi_wakeup_address = 0; @@ -27,6 +27,7 @@ set_pgd(pgd, *(pgd+USER_PTRS_PER_PGD)); pgd_ofs++, pgd++; } + flush_tlb_all(); } /** diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c --- a/arch/ia64/kernel/acpi.c 2005-03-03 21:42:34 -08:00 +++ b/arch/ia64/kernel/acpi.c 2005-03-03 21:42:34 -08:00 @@ -771,7 +771,7 @@ #endif /* CONFIG_ACPI_HOTPLUG_CPU */ -#ifdef CONFIG_NUMA +#ifdef CONFIG_ACPI_NUMA acpi_status __init acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) { diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig --- a/drivers/acpi/Kconfig 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/Kconfig 2005-03-03 21:42:34 -08:00 @@ -343,4 +343,25 @@ This is the ACPI generic container driver which supports ACPI0004, PNP0A05 and PNP0A06 devices +config ACPI_HOTPLUG_MEMORY + tristate "Memory Hotplug" + depends on ACPI + depends on MEMORY_HOTPLUG + default n + help + This driver adds supports for ACPI Memory Hotplug. This driver + provides support for fielding notifications on ACPI memory + devices (PNP0C80) which represent memory ranges that may be + onlined or offlined during runtime. + + Enabling this driver assumes that your platform hardware + and firmware have support for hot-plugging physical memory. If + your system does not support physically adding or ripping out + memory DIMMs at some platfrom defined granularity (individually + or as a bank) at runtime, then you need not enable this driver. + + If one selects "m," this driver can be loaded using the following + command: + $>modprobe acpi_memhotplug + endmenu diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile --- a/drivers/acpi/Makefile 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/Makefile 2005-03-03 21:42:34 -08:00 @@ -55,3 +55,4 @@ obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o obj-$(CONFIG_ACPI_BUS) += scan.o motherboard.o +obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o diff -Nru a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/acpi/acpi_memhotplug.c 2005-03-03 21:42:34 -08:00 @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2004 Intel Corporation + * + * All rights reserved. + * + * 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, GOOD TITLE or + * NON INFRINGEMENT. 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * ACPI based HotPlug driver that supports Memory Hotplug + * This driver fields notifications from firmare for memory add + * and remove operations and alerts the VM of the affected memory + * ranges. + */ + +#include +#include +#include +#include +#include +#include + + +#define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000UL +#define ACPI_MEMORY_DEVICE_CLASS "memory" +#define ACPI_MEMORY_DEVICE_HID "PNP0C80" +#define ACPI_MEMORY_DEVICE_DRIVER_NAME "Hotplug Mem Driver" +#define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device" + +#define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT + +ACPI_MODULE_NAME ("acpi_memory") +MODULE_AUTHOR("Naveen B S "); +MODULE_DESCRIPTION(ACPI_MEMORY_DEVICE_DRIVER_NAME); +MODULE_LICENSE("GPL"); + +/* ACPI _STA method values */ +#define ACPI_MEMORY_STA_PRESENT (0x00000001UL) +#define ACPI_MEMORY_STA_ENABLED (0x00000002UL) +#define ACPI_MEMORY_STA_FUNCTIONAL (0x00000008UL) + +/* Memory Device States */ +#define MEMORY_INVALID_STATE 0 +#define MEMORY_POWER_ON_STATE 1 +#define MEMORY_POWER_OFF_STATE 2 + +static int acpi_memory_device_add (struct acpi_device *device); +static int acpi_memory_device_remove (struct acpi_device *device, int type); + +static struct acpi_driver acpi_memory_device_driver = { + .name = ACPI_MEMORY_DEVICE_DRIVER_NAME, + .class = ACPI_MEMORY_DEVICE_CLASS, + .ids = ACPI_MEMORY_DEVICE_HID, + .ops = { + .add = acpi_memory_device_add, + .remove = acpi_memory_device_remove, + }, +}; + +struct acpi_memory_device { + acpi_handle handle; + unsigned int state; /* State of the memory device */ + unsigned short cache_attribute; /* memory cache attribute */ + unsigned short read_write_attribute;/* memory read/write attribute */ + u64 start_addr; /* Memory Range start physical addr */ + u64 end_addr; /* Memory Range end physical addr */ +}; + + +static int +acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) +{ + acpi_status status; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + struct acpi_resource *resource = NULL; + struct acpi_resource_address64 address64; + + ACPI_FUNCTION_TRACE("acpi_memory_get_device_resources"); + + /* Get the range from the _CRS */ + status = acpi_get_current_resources(mem_device->handle, &buffer); + if (ACPI_FAILURE(status)) + return_VALUE(-EINVAL); + + resource = (struct acpi_resource *) buffer.pointer; + status = acpi_resource_to_address64(resource, &address64); + if (ACPI_SUCCESS(status)) { + if (address64.resource_type == ACPI_MEMORY_RANGE) { + /* Populate the structure */ + mem_device->cache_attribute = + address64.attribute.memory.cache_attribute; + mem_device->read_write_attribute = + address64.attribute.memory.read_write_attribute; + mem_device->start_addr = address64.min_address_range; + mem_device->end_addr = address64.max_address_range; + } + } + + acpi_os_free(buffer.pointer); + return_VALUE(0); +} + +static int +acpi_memory_get_device(acpi_handle handle, + struct acpi_memory_device **mem_device) +{ + acpi_status status; + acpi_handle phandle; + struct acpi_device *device = NULL; + struct acpi_device *pdevice = NULL; + + ACPI_FUNCTION_TRACE("acpi_memory_get_device"); + + if (!acpi_bus_get_device(handle, &device) && device) + goto end; + + status = acpi_get_parent(handle, &phandle); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error in acpi_get_parent\n")); + return_VALUE(-EINVAL); + } + + /* Get the parent device */ + status = acpi_bus_get_device(phandle, &pdevice); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error in acpi_bus_get_device\n")); + return_VALUE(-EINVAL); + } + + /* + * Now add the notified device. This creates the acpi_device + * and invokes .add function + */ + status = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error in acpi_bus_add\n")); + return_VALUE(-EINVAL); + } + +end: + *mem_device = acpi_driver_data(device); + if (!(*mem_device)) { + printk(KERN_ERR "\n driver data not found" ); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + +static int +acpi_memory_check_device(struct acpi_memory_device *mem_device) +{ + unsigned long current_status; + + ACPI_FUNCTION_TRACE("acpi_memory_check_device"); + + /* Get device present/absent information from the _STA */ + if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->handle, "_STA", + NULL, ¤t_status))) + return_VALUE(-ENODEV); + /* + * Check for device status. Device should be + * present/enabled/functioning. + */ + if (!((current_status & ACPI_MEMORY_STA_PRESENT) + && (current_status & ACPI_MEMORY_STA_ENABLED) + && (current_status & ACPI_MEMORY_STA_FUNCTIONAL))) + return_VALUE(-ENODEV); + + return_VALUE(0); +} + +static int +acpi_memory_enable_device(struct acpi_memory_device *mem_device) +{ + int result; + + ACPI_FUNCTION_TRACE("acpi_memory_enable_device"); + + /* Get the range from the _CRS */ + result = acpi_memory_get_device_resources(mem_device); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "\nget_device_resources failed\n")); + mem_device->state = MEMORY_INVALID_STATE; + return result; + } + + /* + * Tell the VM there is more memory here... + * Note: Assume that this function returns zero on success + */ + result = add_memory(mem_device->start_addr, + (mem_device->end_addr - mem_device->start_addr) + 1, + mem_device->read_write_attribute); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "\nadd_memory failed\n")); + mem_device->state = MEMORY_INVALID_STATE; + return result; + } + + return result; +} + +static int +acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) +{ + acpi_status status; + struct acpi_object_list arg_list; + union acpi_object arg; + unsigned long current_status; + + ACPI_FUNCTION_TRACE("acpi_memory_powerdown_device"); + + /* Issue the _EJ0 command */ + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = 1; + status = acpi_evaluate_object(mem_device->handle, + "_EJ0", &arg_list, NULL); + /* Return on _EJ0 failure */ + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"_EJ0 failed.\n")); + return_VALUE(-ENODEV); + } + + /* Evalute _STA to check if the device is disabled */ + status = acpi_evaluate_integer(mem_device->handle, "_STA", + NULL, ¤t_status); + if (ACPI_FAILURE(status)) + return_VALUE(-ENODEV); + + /* Check for device status. Device should be disabled */ + if (current_status & ACPI_MEMORY_STA_ENABLED) + return_VALUE(-EINVAL); + + return_VALUE(0); +} + +static int +acpi_memory_disable_device(struct acpi_memory_device *mem_device) +{ + int result; + u64 start = mem_device->start_addr; + u64 len = mem_device->end_addr - start + 1; + unsigned long attr = mem_device->read_write_attribute; + + ACPI_FUNCTION_TRACE("acpi_memory_disable_device"); + + /* + * Ask the VM to offline this memory range. + * Note: Assume that this function returns zero on success + */ + result = remove_memory(start, len, attr); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Hot-Remove failed.\n")); + return_VALUE(result); + } + + /* Power-off and eject the device */ + result = acpi_memory_powerdown_device(mem_device); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Device Power Down failed.\n")); + /* Set the status of the device to invalid */ + mem_device->state = MEMORY_INVALID_STATE; + return result; + } + + mem_device->state = MEMORY_POWER_OFF_STATE; + return result; +} + +static void +acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) +{ + struct acpi_memory_device *mem_device; + struct acpi_device *device; + + ACPI_FUNCTION_TRACE("acpi_memory_device_notify"); + + switch (event) { + case ACPI_NOTIFY_BUS_CHECK: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "\nReceived BUS CHECK notification for device\n")); + /* Fall Through */ + case ACPI_NOTIFY_DEVICE_CHECK: + if (event == ACPI_NOTIFY_DEVICE_CHECK) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "\nReceived DEVICE CHECK notification for device\n")); + if (acpi_memory_get_device(handle, &mem_device)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error in finding driver data\n")); + return_VOID; + } + + if (!acpi_memory_check_device(mem_device)) { + if (acpi_memory_enable_device(mem_device)) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error in acpi_memory_enable_device\n")); + } + break; + case ACPI_NOTIFY_EJECT_REQUEST: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "\nReceived EJECT REQUEST notification for device\n")); + + if (acpi_bus_get_device(handle, &device)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Device doesn't exist\n")); + break; + } + mem_device = acpi_driver_data(device); + if (!mem_device) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Driver Data is NULL\n")); + break; + } + + /* + * Currently disabling memory device from kernel mode + * TBD: Can also be disabled from user mode scripts + * TBD: Can also be disabled by Callback registration + * with generic sysfs driver + */ + if (acpi_memory_disable_device(mem_device)) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error in acpi_memory_disable_device\n")); + /* + * TBD: Invoke acpi_bus_remove to cleanup data structures + */ + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Unsupported event [0x%x]\n", event)); + break; + } + + return_VOID; +} + +static int +acpi_memory_device_add(struct acpi_device *device) +{ + int result; + struct acpi_memory_device *mem_device = NULL; + + ACPI_FUNCTION_TRACE("acpi_memory_device_add"); + + if (!device) + return_VALUE(-EINVAL); + + mem_device = kmalloc(sizeof(struct acpi_memory_device), GFP_KERNEL); + if (!mem_device) + return_VALUE(-ENOMEM); + memset(mem_device, 0, sizeof(struct acpi_memory_device)); + + mem_device->handle = device->handle; + sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); + acpi_driver_data(device) = mem_device; + + /* Get the range from the _CRS */ + result = acpi_memory_get_device_resources(mem_device); + if (result) { + kfree(mem_device); + return_VALUE(result); + } + + /* Set the device state */ + mem_device->state = MEMORY_POWER_ON_STATE; + + printk(KERN_INFO "%s \n", acpi_device_name(device)); + + return_VALUE(result); +} + +static int +acpi_memory_device_remove (struct acpi_device *device, int type) +{ + struct acpi_memory_device *mem_device = NULL; + + ACPI_FUNCTION_TRACE("acpi_memory_device_remove"); + + if (!device || !acpi_driver_data(device)) + return_VALUE(-EINVAL); + + mem_device = (struct acpi_memory_device *) acpi_driver_data(device); + kfree(mem_device); + + return_VALUE(0); +} + +/* + * Helper function to check for memory device + */ +static acpi_status +is_memory_device(acpi_handle handle) +{ + char *hardware_id; + acpi_status status; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + struct acpi_device_info *info; + + ACPI_FUNCTION_TRACE("is_memory_device"); + + status = acpi_get_object_info(handle, &buffer); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(AE_ERROR); + + info = buffer.pointer; + if (!(info->valid & ACPI_VALID_HID)) { + acpi_os_free(buffer.pointer); + return_ACPI_STATUS(AE_ERROR); + } + + hardware_id = info->hardware_id.value; + if ((hardware_id == NULL) || + (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) + status = AE_ERROR; + + acpi_os_free(buffer.pointer); + return_ACPI_STATUS(status); +} + +static acpi_status +acpi_memory_register_notify_handler (acpi_handle handle, + u32 level, void *ctxt, void **retv) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE("acpi_memory_register_notify_handler"); + + status = is_memory_device(handle); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(AE_OK); /* continue */ + + status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + acpi_memory_device_notify, NULL); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error installing notify handler\n")); + return_ACPI_STATUS(AE_OK); /* continue */ + } + + return_ACPI_STATUS(status); +} + +static acpi_status +acpi_memory_deregister_notify_handler (acpi_handle handle, + u32 level, void *ctxt, void **retv) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE("acpi_memory_deregister_notify_handler"); + + status = is_memory_device(handle); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(AE_OK); /* continue */ + + status = acpi_remove_notify_handler(handle, + ACPI_SYSTEM_NOTIFY, acpi_memory_device_notify); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error removing notify handler\n")); + return_ACPI_STATUS(AE_OK); /* continue */ + } + + return_ACPI_STATUS(status); +} + +static int __init +acpi_memory_device_init (void) +{ + int result; + acpi_status status; + + ACPI_FUNCTION_TRACE("acpi_memory_device_init"); + + result = acpi_bus_register_driver(&acpi_memory_device_driver); + + if (result < 0) + return_VALUE(-ENODEV); + + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, + acpi_memory_register_notify_handler, + NULL, NULL); + + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed\n")); + acpi_bus_unregister_driver(&acpi_memory_device_driver); + return_VALUE(-ENODEV); + } + + return_VALUE(0); +} + +static void __exit +acpi_memory_device_exit (void) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE("acpi_memory_device_exit"); + + /* + * Adding this to un-install notification handlers for all the device + * handles. + */ + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, + acpi_memory_deregister_notify_handler, + NULL, NULL); + + if (ACPI_FAILURE (status)) + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed\n")); + + acpi_bus_unregister_driver(&acpi_memory_device_driver); + + return_VOID; +} + +module_init(acpi_memory_device_init); +module_exit(acpi_memory_device_exit); + + diff -Nru a/drivers/acpi/container.c b/drivers/acpi/container.c --- a/drivers/acpi/container.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/container.c 2005-03-03 21:42:34 -08:00 @@ -177,13 +177,18 @@ printk("Container driver received %s event\n", (type == ACPI_NOTIFY_BUS_CHECK)? "ACPI_NOTIFY_BUS_CHECK":"ACPI_NOTIFY_DEVICE_CHECK"); + status = acpi_bus_get_device(handle, &device); if (present) { - status = acpi_bus_get_device(handle, &device); if (ACPI_FAILURE(status) || !device) { result = container_device_add(&device, handle); if (!result) - kobject_hotplug(&device->kobj, KOBJ_ONLINE); - } else { + kobject_hotplug(&device->kobj, + KOBJ_ONLINE); + else + printk("Failed to add container\n"); + } + } else { + if (ACPI_SUCCESS(status)) { /* device exist and this is a remove request */ kobject_hotplug(&device->kobj, KOBJ_OFFLINE); } diff -Nru a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c --- a/drivers/acpi/events/evxface.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/events/evxface.c 2005-03-03 21:42:34 -08:00 @@ -149,7 +149,9 @@ acpi_gbl_fixed_event_handlers[event].handler = handler; acpi_gbl_fixed_event_handlers[event].context = context; - status = acpi_enable_event (event, 0); + status = acpi_clear_event (event); + if (ACPI_SUCCESS(status)) + status = acpi_enable_event (event, 0); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n")); diff -Nru a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c --- a/drivers/acpi/executer/exoparg2.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/executer/exoparg2.c 2005-03-03 21:42:34 -08:00 @@ -442,6 +442,12 @@ return_desc->reference.object = operand[0]; } + /* + * Add a reference to the target package/buffer/string for the life + * of the index. + */ + acpi_ut_add_reference (operand[0]); + /* Complete the Index reference object */ return_desc->reference.opcode = AML_INDEX_OP; diff -Nru a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c --- a/drivers/acpi/executer/exstorob.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/executer/exstorob.c 2005-03-03 21:42:34 -08:00 @@ -105,6 +105,7 @@ ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length); ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length); +#if ACPI_STRICT_CONFORMANCE /* * If the original source was a string, we must truncate the buffer, * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer @@ -115,6 +116,7 @@ target_desc->buffer.length = length; } +#endif } else { /* Truncate the source, copy only what will fit */ diff -Nru a/drivers/acpi/fan.c b/drivers/acpi/fan.c --- a/drivers/acpi/fan.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/fan.c 2005-03-03 21:42:34 -08:00 @@ -78,21 +78,18 @@ static int acpi_fan_read_state (struct seq_file *seq, void *offset) { - struct acpi_fan *fan = (struct acpi_fan *) seq->private; + struct acpi_fan *fan = seq->private; int state = 0; ACPI_FUNCTION_TRACE("acpi_fan_read_state"); - if (!fan) - goto end; - - if (acpi_bus_get_power(fan->handle, &state)) - goto end; - - seq_printf(seq, "status: %s\n", - !state?"on":"off"); - -end: + if (fan) { + if (acpi_bus_get_power(fan->handle, &state)) + seq_printf(seq, "status: ERROR\n"); + else + seq_printf(seq, "status: %s\n", + !state?"on":"off"); + } return_VALUE(0); } diff -Nru a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c --- a/drivers/acpi/parser/psopcode.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/parser/psopcode.c 2005-03-03 21:42:34 -08:00 @@ -522,7 +522,7 @@ /* 2E */ ACPI_OP ("DerefOf", ARGP_DEREF_OF_OP, ARGI_DEREF_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R), /* 2F */ ACPI_OP ("Notify", ARGP_NOTIFY_OP, ARGI_NOTIFY_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_0R, AML_FLAGS_EXEC_2A_0T_0R), /* 30 */ ACPI_OP ("SizeOf", ARGP_SIZE_OF_OP, ARGI_SIZE_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE), -/* 31 */ ACPI_OP ("Index", ARGP_INDEX_OP, ARGI_INDEX_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT), +/* 31 */ ACPI_OP ("Index", ARGP_INDEX_OP, ARGI_INDEX_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R), /* 32 */ ACPI_OP ("Match", ARGP_MATCH_OP, ARGI_MATCH_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R | AML_CONSTANT), /* 33 */ ACPI_OP ("CreateDWordField", ARGP_CREATE_DWORD_FIELD_OP,ARGI_CREATE_DWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), /* 34 */ ACPI_OP ("CreateWordField", ARGP_CREATE_WORD_FIELD_OP, ARGI_CREATE_WORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), diff -Nru a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c --- a/drivers/acpi/resources/rsaddr.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/resources/rsaddr.c 2005-03-03 21:42:34 -08:00 @@ -110,13 +110,13 @@ buffer += 2; temp8 = *buffer; - /* Values 0-2 are valid */ + /* Values 0-2 and 0xC0-0xFF are valid */ - if (temp8 > 2) { + if ((temp8 > 2) && (temp8 < 0xC0)) { return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); } - output_struct->data.address16.resource_type = temp8 & 0x03; + output_struct->data.address16.resource_type = temp8; /* * Get the General Flags (Byte4) @@ -496,12 +496,13 @@ buffer += 2; temp8 = *buffer; - /* Values 0-2 are valid */ - if(temp8 > 2) { + /* Values 0-2 and 0xC0-0xFF are valid */ + + if ((temp8 > 2) && (temp8 < 0xC0)) { return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); } - output_struct->data.address32.resource_type = temp8 & 0x03; + output_struct->data.address32.resource_type = temp8; /* * Get the General Flags (Byte4) @@ -850,6 +851,7 @@ struct acpi_resource *output_struct = (void *) *output_buffer; u16 temp16; u8 temp8; + u8 resource_type; u8 *temp_ptr; acpi_size struct_size; u32 index; @@ -860,6 +862,7 @@ buffer = byte_stream_buffer; struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64); + resource_type = *buffer; /* * Point past the Descriptor to get the number of bytes consumed @@ -882,13 +885,13 @@ buffer += 2; temp8 = *buffer; - /* Values 0-2 are valid */ + /* Values 0-2 and 0xC0-0xFF are valid */ - if(temp8 > 2) { + if ((temp8 > 2) && (temp8 < 0xC0)) { return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); } - output_struct->data.address64.resource_type = temp8 & 0x03; + output_struct->data.address64.resource_type = temp8; /* * Get the General Flags (Byte4) @@ -942,98 +945,113 @@ } } + if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { + /* Move past revision_id and Reserved byte */ + + buffer += 2; + } + /* - * Get Granularity (Bytes 6-13) + * Get Granularity (Bytes 6-13) or (Bytes 8-15) */ buffer += 1; ACPI_MOVE_64_TO_64 (&output_struct->data.address64.granularity, buffer); /* - * Get min_address_range (Bytes 14-21) + * Get min_address_range (Bytes 14-21) or (Bytes 16-23) */ buffer += 8; ACPI_MOVE_64_TO_64 (&output_struct->data.address64.min_address_range, buffer); /* - * Get max_address_range (Bytes 22-29) + * Get max_address_range (Bytes 22-29) or (Bytes 24-31) */ buffer += 8; ACPI_MOVE_64_TO_64 (&output_struct->data.address64.max_address_range, buffer); /* - * Get address_translation_offset (Bytes 30-37) + * Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */ buffer += 8; ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset, buffer); /* - * Get address_length (Bytes 38-45) + * Get address_length (Bytes 38-45) or (Bytes 40-47) */ buffer += 8; ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_length, buffer); - /* - * Resource Source Index (if present) - */ - buffer += 8; + output_struct->data.address64.resource_source.index = 0x00; + output_struct->data.address64.resource_source.string_length = 0; + output_struct->data.address64.resource_source.string_ptr = NULL; - /* - * This will leave us pointing to the Resource Source Index - * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: - * Each Interrupt takes 32-bits + the 5 bytes of the - * stream that are default. - * - * Note: Some resource descriptors will have an additional null, so - * we add 1 to the length. - */ - if (*bytes_consumed > (46 + 1)) { - /* Dereference the Index */ + if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { + /* Get type_specific_attribute (Bytes 48-55) */ - temp8 = *buffer; - output_struct->data.address64.resource_source.index = - (u32) temp8; + buffer += 8; + ACPI_MOVE_64_TO_64 (&output_struct->data.address64.type_specific_attributes, buffer); + } + else { + output_struct->data.address64.type_specific_attributes = 0; - /* Point to the String */ + /* + * Resource Source Index (if present) + */ + buffer += 8; - buffer += 1; + /* + * This will leave us pointing to the Resource Source Index + * If it is present, then save it off and calculate the + * pointer to where the null terminated string goes: + * Each Interrupt takes 32-bits + the 5 bytes of the + * stream that are default. + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the length. + */ + if (*bytes_consumed > (46 + 1)) { + /* Dereference the Index */ - /* Point the String pointer to the end of this structure */ + temp8 = *buffer; + output_struct->data.address64.resource_source.index = + (u32) temp8; - output_struct->data.address64.resource_source.string_ptr = - (char *)((u8 *)output_struct + struct_size); + /* Point to the String */ - temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr; + buffer += 1; - /* Copy the string into the buffer */ + /* Point the String pointer to the end of this structure */ - index = 0; - while (0x00 != *buffer) { - *temp_ptr = *buffer; + output_struct->data.address64.resource_source.string_ptr = + (char *)((u8 *)output_struct + struct_size); - temp_ptr += 1; - buffer += 1; - index += 1; - } + temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr; - /* - * Add the terminating null - */ - *temp_ptr = 0x00; - output_struct->data.address64.resource_source.string_length = index + 1; + /* Copy the string into the buffer */ - /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the string and expand the - * struct_size to the next 32-bit boundary. - */ - temp8 = (u8) (index + 1); - struct_size += ACPI_ROUND_UP_to_32_bITS (temp8); - } - else { - output_struct->data.address64.resource_source.index = 0x00; - output_struct->data.address64.resource_source.string_length = 0; - output_struct->data.address64.resource_source.string_ptr = NULL; + index = 0; + while (0x00 != *buffer) { + *temp_ptr = *buffer; + + temp_ptr += 1; + buffer += 1; + index += 1; + } + + /* + * Add the terminating null + */ + *temp_ptr = 0x00; + output_struct->data.address64.resource_source.string_length = index + 1; + + /* + * In order for the struct_size to fall on a 32-bit boundary, + * calculate the length of the string and expand the + * struct_size to the next 32-bit boundary. + */ + temp8 = (u8) (index + 1); + struct_size += ACPI_ROUND_UP_to_32_bITS (temp8); + } } /* diff -Nru a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c --- a/drivers/acpi/resources/rscalc.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/resources/rscalc.c 2005-03-03 21:42:34 -08:00 @@ -376,6 +376,20 @@ break; + case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: + /* + * 64-Bit Address Resource + */ + buffer = byte_stream_buffer; + + ++buffer; + ACPI_MOVE_16_TO_16 (&temp16, buffer); + + bytes_consumed = temp16 + 3; + structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64); + break; + + case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: /* * 64-Bit Address Resource diff -Nru a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c --- a/drivers/acpi/resources/rsdump.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/resources/rsdump.c 2005-03-03 21:42:34 -08:00 @@ -571,7 +571,7 @@ break; } - acpi_os_printf (" Type Specific: %s Translation\n", + acpi_os_printf (" Type Specific: %s Translation\n", ACPI_SPARSE_TRANSLATION == address16_data->attribute.io.translation_attribute ? "Sparse" : "Dense"); @@ -584,8 +584,8 @@ default: - acpi_os_printf ("Invalid resource type. Exiting.\n"); - return; + acpi_os_printf ("0x%2.2X\n", address16_data->resource_type); + break; } acpi_os_printf (" Resource %s\n", @@ -718,7 +718,7 @@ break; } - acpi_os_printf (" Type Specific: %s Translation\n", + acpi_os_printf (" Type Specific: %s Translation\n", ACPI_SPARSE_TRANSLATION == address32_data->attribute.io.translation_attribute ? "Sparse" : "Dense"); @@ -731,8 +731,8 @@ default: - acpi_os_printf (" Invalid Resource Type..exiting.\n"); - return; + acpi_os_printf (" Resource Type: 0x%2.2X\n", address32_data->resource_type); + break; } acpi_os_printf (" Resource %s\n", @@ -865,7 +865,7 @@ break; } - acpi_os_printf (" Type Specific: %s Translation\n", + acpi_os_printf (" Type Specific: %s Translation\n", ACPI_SPARSE_TRANSLATION == address64_data->attribute.io.translation_attribute ? "Sparse" : "Dense"); @@ -878,8 +878,8 @@ default: - acpi_os_printf (" Invalid Resource Type..exiting.\n"); - return; + acpi_os_printf (" Resource Type: 0x%2.2X\n", address64_data->resource_type); + break; } acpi_os_printf (" Resource %s\n", @@ -913,7 +913,10 @@ acpi_os_printf (" Address Length: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (address64_data->address_length)); - if(0xFF != address64_data->resource_source.index) { + acpi_os_printf (" Type Specific Attributes: %8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (address64_data->type_specific_attributes)); + + if (0xFF != address64_data->resource_source.index) { acpi_os_printf (" Resource Source Index: %X\n", address64_data->resource_source.index); acpi_os_printf (" Resource Source: %s\n", diff -Nru a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c --- a/drivers/acpi/resources/rslist.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/resources/rslist.c 2005-03-03 21:42:34 -08:00 @@ -178,6 +178,7 @@ case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: + case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: /* * 64-Bit Address Resource */ diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c --- a/drivers/acpi/scan.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/scan.c 2005-03-03 21:42:34 -08:00 @@ -81,12 +81,37 @@ .release = acpi_device_release, }; +static int namespace_hotplug(struct kset *kset, struct kobject *kobj, + char **envp, int num_envp, char *buffer, + int buffer_size) +{ + struct acpi_device *dev = to_acpi_device(kobj); + int i = 0; + int len = 0; + + if (!dev->driver) + return 0; + + if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len, + "PHYSDEVDRIVER=%s", dev->driver->name)) + return -ENOMEM; + + envp[i] = NULL; + + return 0; +} + +static struct kset_hotplug_ops namespace_hotplug_ops = { + .hotplug = &namespace_hotplug, +}; + static struct kset acpi_namespace_kset = { .kobj = { .name = "namespace", }, .subsys = &acpi_subsys, .ktype = &ktype_acpi_ns, + .hotplug_ops = &namespace_hotplug_ops, }; @@ -358,7 +383,15 @@ struct acpi_device *dev, acpi_device_sysfs_files *func) { - if (dev->flags.ejectable == 1) + acpi_status status; + acpi_handle temp = NULL; + + /* + * If device has _EJ0, 'eject' file is created that is used to trigger + * hot-removal function from userland. + */ + status = acpi_get_handle(dev->handle, "_EJ0", &temp); + if (ACPI_SUCCESS(status)) (*(func))(&dev->kobj,&acpi_device_attr_eject.attr); } diff -Nru a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c --- a/drivers/acpi/utilities/utdelete.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/utilities/utdelete.c 2005-03-03 21:42:34 -08:00 @@ -46,6 +46,7 @@ #include #include #include +#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME ("utdelete") @@ -562,8 +563,23 @@ break; - case ACPI_TYPE_REGION: case ACPI_TYPE_LOCAL_REFERENCE: + + /* + * The target of an Index (a package, string, or buffer) must track + * changes to the ref count of the index. + */ + if (object->reference.opcode == AML_INDEX_OP) { + status = acpi_ut_create_update_state_and_push ( + object->reference.object, action, &state_list); + if (ACPI_FAILURE (status)) { + goto error_exit; + } + } + break; + + + case ACPI_TYPE_REGION: default: /* No subobjects */ diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c --- a/drivers/acpi/utilities/utglobal.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/utilities/utglobal.c 2005-03-03 21:42:34 -08:00 @@ -194,6 +194,8 @@ */ const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = { + /* Operating System Vendor Strings */ + "Linux", "Windows 2000", "Windows 2001", @@ -202,7 +204,11 @@ "Windows 2001 SP1", "Windows 2001 SP2", "Windows 2001 SP3", - "Windows 2001 SP4" + "Windows 2001 SP4", + + /* Feature Group Strings */ + + "Extended Address Space Descriptor" }; @@ -355,6 +361,7 @@ /* ACPI_BITREG_SLEEP_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_STATUS}, /* ACPI_BITREG_RT_CLOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_STATUS}, /* ACPI_BITREG_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_WAKE_STATUS, ACPI_BITMASK_WAKE_STATUS}, + /* ACPI_BITREG_PCIEXP_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_PCIEXP_WAKE_STATUS, ACPI_BITMASK_PCIEXP_WAKE_STATUS}, /* ACPI_BITREG_TIMER_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_TIMER_ENABLE, ACPI_BITMASK_TIMER_ENABLE}, /* ACPI_BITREG_GLOBAL_LOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_ENABLE}, @@ -362,6 +369,7 @@ /* ACPI_BITREG_SLEEP_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_ENABLE}, /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_ENABLE}, /* ACPI_BITREG_WAKE_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, 0, 0}, + /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE, ACPI_BITMASK_PCIEXP_WAKE_DISABLE}, /* ACPI_BITREG_SCI_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SCI_ENABLE, ACPI_BITMASK_SCI_ENABLE}, /* ACPI_BITREG_BUS_MASTER_RLD */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_BUS_MASTER_RLD, ACPI_BITMASK_BUS_MASTER_RLD}, diff -Nru a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c --- a/drivers/acpi/utilities/utmisc.c 2005-03-03 21:42:34 -08:00 +++ b/drivers/acpi/utilities/utmisc.c 2005-03-03 21:42:34 -08:00 @@ -380,6 +380,10 @@ ACPI_FUNCTION_TRACE ("ut_stroul64"); + if ((!string) || !(*string)) { + goto error_exit; + } + switch (base) { case ACPI_ANY_BASE: case 10: @@ -394,7 +398,7 @@ /* Skip over any white space in the buffer */ while (ACPI_IS_SPACE (*string) || *string == '\t') { - ++string; + string++; } /* @@ -403,9 +407,9 @@ */ if (base == 0) { if ((*string == '0') && - (ACPI_TOLOWER (*(++string)) == 'x')) { + (ACPI_TOLOWER (*(string + 1)) == 'x')) { base = 16; - ++string; + string += 2; } else { base = 10; @@ -416,10 +420,10 @@ * For hexadecimal base, skip over the leading * 0 or 0x, if they are present. */ - if (base == 16 && - *string == '0' && - ACPI_TOLOWER (*(++string)) == 'x') { - string++; + if ((base == 16) && + (*string == '0') && + (ACPI_TOLOWER (*(string + 1)) == 'x')) { + string += 2; } /* Any string left? */ @@ -464,7 +468,7 @@ return_value *= base; return_value += this_digit; - ++string; + string++; } *ret_integer = return_value; diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h --- a/include/acpi/acconfig.h 2005-03-03 21:42:34 -08:00 +++ b/include/acpi/acconfig.h 2005-03-03 21:42:34 -08:00 @@ -64,7 +64,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20050211 +#define ACPI_CA_VERSION 0x20050303 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, @@ -198,7 +198,7 @@ /* Number of strings associated with the _OSI reserved method */ -#define ACPI_NUM_OSI_STRINGS 9 +#define ACPI_NUM_OSI_STRINGS 10 /****************************************************************************** diff -Nru a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h --- a/include/acpi/acdisasm.h 2005-03-03 21:42:34 -08:00 +++ b/include/acpi/acdisasm.h 2005-03-03 21:42:34 -08:00 @@ -75,6 +75,11 @@ extern const char *acpi_gbl_TYPdecode[4]; extern const char *acpi_gbl_BMdecode[2]; extern const char *acpi_gbl_SIZdecode[4]; +extern const char *acpi_gbl_TTPdecode[2]; +extern const char *acpi_gbl_MTPdecode[4]; +extern const char *acpi_gbl_TRSdecode[2]; + + extern const char *acpi_gbl_lock_rule[ACPI_NUM_LOCK_RULES]; extern const char *acpi_gbl_access_types[ACPI_NUM_ACCESS_TYPES]; extern const char *acpi_gbl_update_rules[ACPI_NUM_UPDATE_RULES]; diff -Nru a/include/acpi/aclocal.h b/include/acpi/aclocal.h --- a/include/acpi/aclocal.h 2005-03-03 21:42:34 -08:00 +++ b/include/acpi/aclocal.h 2005-03-03 21:42:34 -08:00 @@ -774,6 +774,7 @@ #define ACPI_BITMASK_POWER_BUTTON_STATUS 0x0100 #define ACPI_BITMASK_SLEEP_BUTTON_STATUS 0x0200 #define ACPI_BITMASK_RT_CLOCK_STATUS 0x0400 +#define ACPI_BITMASK_PCIEXP_WAKE_STATUS 0x4000 /* ACPI 3.0 */ #define ACPI_BITMASK_WAKE_STATUS 0x8000 #define ACPI_BITMASK_ALL_FIXED_STATUS (ACPI_BITMASK_TIMER_STATUS | \ @@ -789,6 +790,7 @@ #define ACPI_BITMASK_POWER_BUTTON_ENABLE 0x0100 #define ACPI_BITMASK_SLEEP_BUTTON_ENABLE 0x0200 #define ACPI_BITMASK_RT_CLOCK_ENABLE 0x0400 +#define ACPI_BITMASK_PCIEXP_WAKE_DISABLE 0x4000 /* ACPI 3.0 */ #define ACPI_BITMASK_SCI_ENABLE 0x0001 #define ACPI_BITMASK_BUS_MASTER_RLD 0x0002 @@ -807,6 +809,7 @@ #define ACPI_BITPOSITION_POWER_BUTTON_STATUS 0x08 #define ACPI_BITPOSITION_SLEEP_BUTTON_STATUS 0x09 #define ACPI_BITPOSITION_RT_CLOCK_STATUS 0x0A +#define ACPI_BITPOSITION_PCIEXP_WAKE_STATUS 0x0E /* ACPI 3.0 */ #define ACPI_BITPOSITION_WAKE_STATUS 0x0F #define ACPI_BITPOSITION_TIMER_ENABLE 0x00 @@ -814,6 +817,7 @@ #define ACPI_BITPOSITION_POWER_BUTTON_ENABLE 0x08 #define ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE 0x09 #define ACPI_BITPOSITION_RT_CLOCK_ENABLE 0x0A +#define ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE 0x0E /* ACPI 3.0 */ #define ACPI_BITPOSITION_SCI_ENABLE 0x00 #define ACPI_BITPOSITION_BUS_MASTER_RLD 0x01 diff -Nru a/include/acpi/actbl.h b/include/acpi/actbl.h --- a/include/acpi/actbl.h 2005-03-03 21:42:34 -08:00 +++ b/include/acpi/actbl.h 2005-03-03 21:42:34 -08:00 @@ -261,6 +261,8 @@ u8 local_sapic_eid; /* SAPIC EID */ u8 reserved [3]; /* Reserved - must be zero */ LOCAL_APIC_FLAGS + u32 processor_uID; /* Numeric UID - ACPI 3.0 */ + char processor_uIDstring[1]; /* String UID - ACPI 3.0 */ }; struct madt_interrupt_source @@ -272,7 +274,7 @@ u8 processor_eid; /* Processor EID */ u8 io_sapic_vector; /* Vector value for PMI interrupts */ u32 interrupt; /* Global system interrupt */ - u32 reserved; /* Reserved - must be zero */ + u32 flags; /* Interrupt Source Flags */ }; diff -Nru a/include/acpi/actbl2.h b/include/acpi/actbl2.h --- a/include/acpi/actbl2.h 2005-03-03 21:42:34 -08:00 +++ b/include/acpi/actbl2.h 2005-03-03 21:42:34 -08:00 @@ -108,7 +108,7 @@ /* - * ACPI 2.0 Generic Address Structure (GAS) + * ACPI 2.0+ Generic Address Structure (GAS) */ struct acpi_generic_address { @@ -159,7 +159,7 @@ u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/ /* - * ACPI 2.0 Fixed ACPI Description Table (FADT) + * ACPI 2.0+ Fixed ACPI Description Table (FADT) */ struct fadt_descriptor_rev2 { @@ -174,17 +174,25 @@ u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ - u32 tmr_val_ext : 1; /* Indicates tmr_val is 32 bits 0=24-bits*/ + u32 tmr_val_ext : 1; /* Indicates tmr_val is 32 bits 0=24-bits */ u32 dock_cap : 1; /* Supports Docking */ - u32 reset_reg_sup : 1; /* Indicates system supports system reset via the FADT RESET_REG*/ - u32 sealed_case : 1; /* Indicates system has no internal expansion capabilities and case is sealed. */ - u32 headless : 1; /* Indicates system does not have local video capabilities or local input devices.*/ + u32 reset_reg_sup : 1; /* Indicates system supports system reset via the FADT RESET_REG */ + u32 sealed_case : 1; /* Indicates system has no internal expansion capabilities and case is sealed */ + u32 headless : 1; /* Indicates system does not have local video capabilities or local input devices */ u32 cpu_sw_sleep : 1; /* Indicates to OSPM that a processor native instruction */ - /* Must be executed after writing the SLP_TYPx register. */ - u32 reserved6 : 18; /* Reserved - must be zero */ + /* must be executed after writing the SLP_TYPx register */ + /* ACPI 3.0 flag bits */ + + u32 pci_exp_wak : 1; /* System supports PCIEXP_WAKE (STS/EN) bits */ + u32 use_platform_clock : 1; /* OSPM should use platform-provided timer */ + u32 S4rtc_sts_valid : 1; /* Contents of RTC_STS valid after S4 wake */ + u32 remote_power_on_capable : 1; /* System is compatible with remote power on */ + u32 force_apic_cluster_model : 1; /* All local APICs must use cluster model */ + u32 force_apic_physical_destination_mode : 1; /* all local x_aPICs must use physical dest mode */ + u32 reserved6 : 12;/* Reserved - must be zero */ struct acpi_generic_address reset_register; /* Reset register address in GAS format */ - u8 reset_value; /* Value to write to the reset_register port to reset the system. */ + u8 reset_value; /* Value to write to the reset_register port to reset the system */ u8 reserved7[3]; /* These three bytes must be zero */ u64 xfirmware_ctrl; /* 64-bit physical address of FACS */ u64 Xdsdt; /* 64-bit physical address of DSDT */ @@ -199,7 +207,7 @@ }; -/* "Downrevved" ACPI 2.0 FADT descriptor */ +/* "Down-revved" ACPI 2.0 FADT descriptor */ struct fadt_descriptor_rev2_minus { @@ -213,7 +221,7 @@ }; -/* Embedded Controller */ +/* ECDT - Embedded Controller Boot Resources Table */ struct ec_boot_resources { @@ -223,6 +231,55 @@ u32 uid; /* Unique ID - must be same as the EC _UID method */ u8 gpe_bit; /* The GPE for the EC */ u8 ec_id[1]; /* Full namepath of the EC in the ACPI namespace */ +}; + + +/* SRAT - System Resource Affinity Table */ + +struct static_resource_alloc +{ + u8 type; + u8 length; + u8 proximity_domain_lo; + u8 apic_id; + u32 enabled :1; + u32 reserved3 :31; + u8 local_sapic_eid; + u8 proximity_domain_hi[3]; + u32 reserved4; +}; + +struct memory_affinity +{ + u8 type; + u8 length; + u32 proximity_domain; + u16 reserved3; + u64 base_address; + u64 address_length; + u32 reserved4; + u32 enabled :1; + u32 hot_pluggable :1; + u32 non_volatile :1; + u32 reserved5 :29; + u64 reserved6; +}; + +struct system_resource_affinity +{ + ACPI_TABLE_HEADER_DEF + u32 reserved1; /* Must be value '1' */ + u64 reserved2; +}; + + +/* SLIT - System Locality Distance Information Table */ + +struct system_locality_info +{ + ACPI_TABLE_HEADER_DEF + u64 locality_count; + u8 entry[1][1]; }; diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h --- a/include/acpi/actypes.h 2005-03-03 21:42:34 -08:00 +++ b/include/acpi/actypes.h 2005-03-03 21:42:34 -08:00 @@ -653,24 +653,26 @@ #define ACPI_BITREG_SLEEP_BUTTON_STATUS 0x04 #define ACPI_BITREG_RT_CLOCK_STATUS 0x05 #define ACPI_BITREG_WAKE_STATUS 0x06 +#define ACPI_BITREG_PCIEXP_WAKE_STATUS 0x07 -#define ACPI_BITREG_TIMER_ENABLE 0x07 -#define ACPI_BITREG_GLOBAL_LOCK_ENABLE 0x08 -#define ACPI_BITREG_POWER_BUTTON_ENABLE 0x09 -#define ACPI_BITREG_SLEEP_BUTTON_ENABLE 0x0A -#define ACPI_BITREG_RT_CLOCK_ENABLE 0x0B -#define ACPI_BITREG_WAKE_ENABLE 0x0C - -#define ACPI_BITREG_SCI_ENABLE 0x0D -#define ACPI_BITREG_BUS_MASTER_RLD 0x0E -#define ACPI_BITREG_GLOBAL_LOCK_RELEASE 0x0F -#define ACPI_BITREG_SLEEP_TYPE_A 0x10 -#define ACPI_BITREG_SLEEP_TYPE_B 0x11 -#define ACPI_BITREG_SLEEP_ENABLE 0x12 +#define ACPI_BITREG_TIMER_ENABLE 0x08 +#define ACPI_BITREG_GLOBAL_LOCK_ENABLE 0x09 +#define ACPI_BITREG_POWER_BUTTON_ENABLE 0x0A +#define ACPI_BITREG_SLEEP_BUTTON_ENABLE 0x0B +#define ACPI_BITREG_RT_CLOCK_ENABLE 0x0C +#define ACPI_BITREG_WAKE_ENABLE 0x0D +#define ACPI_BITREG_PCIEXP_WAKE_DISABLE 0x0E + +#define ACPI_BITREG_SCI_ENABLE 0x0F +#define ACPI_BITREG_BUS_MASTER_RLD 0x10 +#define ACPI_BITREG_GLOBAL_LOCK_RELEASE 0x11 +#define ACPI_BITREG_SLEEP_TYPE_A 0x12 +#define ACPI_BITREG_SLEEP_TYPE_B 0x13 +#define ACPI_BITREG_SLEEP_ENABLE 0x14 -#define ACPI_BITREG_ARB_DISABLE 0x13 +#define ACPI_BITREG_ARB_DISABLE 0x15 -#define ACPI_BITREG_MAX 0x13 +#define ACPI_BITREG_MAX 0x15 #define ACPI_NUM_BITREG ACPI_BITREG_MAX + 1 @@ -1206,6 +1208,7 @@ u64 max_address_range; u64 address_translation_offset; u64 address_length; + u64 type_specific_attributes; struct acpi_resource_source resource_source; }; diff -Nru a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h --- a/include/acpi/platform/acenv.h 2005-03-03 21:42:34 -08:00 +++ b/include/acpi/platform/acenv.h 2005-03-03 21:42:34 -08:00 @@ -226,6 +226,7 @@ */ #define ACPI_STRSTR(s1,s2) strstr((s1), (s2)) +#define ACPI_STRCHR(s1,c) strchr((s1), (c)) #ifdef ACPI_FUTURE_USAGE #define ACPI_STRUPR(s) (void) acpi_ut_strupr ((s)) @@ -294,6 +295,7 @@ #define ACPI_STRSTR(s1,s2) acpi_ut_strstr ((s1), (s2)) +#define ACPI_STRCHR(s1,c) acpi_ut_strchr ((s1), (c)) #ifdef ACPI_FUTURE_USAGE #define ACPI_STRUPR(s) (void) acpi_ut_strupr ((s))