diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 767051a4ca8c30987b66f4478a37e303be1f53aa..5e0276d43425a1ef2fb4278b0874b309030e669c 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -1086,7 +1086,7 @@ void __init mp_parse_prt (void)
 
 	/*
 	 * Parsing through the PCI Interrupt Routing Table (PRT) and program
-	 * routing for all static (IOAPIC-direct) entries.
+	 * routing for all entries.
 	 */
 	list_for_each(node, &acpi_prt.entries) {
 		entry = list_entry(node, struct acpi_prt_entry, node);
@@ -1100,6 +1100,10 @@ void __init mp_parse_prt (void)
 		else
 			irq = entry->link.index;
 
+		/* Don't set up the ACPI SCI because it's already set up */
+		if (acpi_fadt.sci_int == irq)
+			continue;
+	
 		ioapic = mp_find_ioapic(irq);
 		if (ioapic < 0)
 			continue;
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
index 4bf51506bb47249c6d82d35e6f12c9a9b23ef501..afc359ec5d2f94b1c2ee1fb07265b88e9d4e5949 100644
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -222,8 +222,8 @@ acpi_ds_initialize_objects (
 	}
 
 	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
-		"\nTable [%4.4s] - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
-		table_desc->pointer->signature, info.object_count,
+		"\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
+		table_desc->pointer->signature, table_desc->table_id, info.object_count,
 		info.device_count, info.method_count, info.op_region_count));
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 8ecdf4cc0a13c26c66cc3a6bcf3d448a646502ca..309e43b0346f2dcd5aac923807d34e9fa07510bc 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -290,6 +290,8 @@ acpi_ds_call_control_method (
 		return_ACPI_STATUS (AE_NULL_OBJECT);
 	}
 
+	obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
+
 	/* Init for new method, wait on concurrency semaphore */
 
 	status = acpi_ds_begin_method_execution (method_node, obj_desc,
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index 89f3b8e52558abbc25fe11d5c3bce55d7a60879d..df5f586c73776e59674292d4fcf7eec6d9f3b76a 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -204,7 +204,8 @@ acpi_ds_build_internal_buffer_obj (
 
 	if (obj_desc->buffer.length == 0) {
 		obj_desc->buffer.pointer = NULL;
-		ACPI_REPORT_WARNING (("Buffer created with zero length in AML\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"Buffer defined with zero length in AML, creating\n"));
 	}
 	else {
 		obj_desc->buffer.pointer = ACPI_MEM_CALLOCATE (
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index b004b33489e747d104ee44ac24e01154da1b1c72..5d8e64587f4f073de76304823d8830c89f76f477 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -82,7 +82,7 @@ acpi_ds_execute_arguments (
 	union acpi_parse_object         *arg;
 
 
-	ACPI_FUNCTION_TRACE ("acpi_ds_execute_arguments");
+	ACPI_FUNCTION_TRACE ("ds_execute_arguments");
 
 
 	/*
@@ -99,7 +99,7 @@ acpi_ds_execute_arguments (
 
 	/* Create and initialize a new parser state */
 
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL);
+	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
 	if (!walk_state) {
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
@@ -139,7 +139,7 @@ acpi_ds_execute_arguments (
 
 	/* Create and initialize a new parser state */
 
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL);
+	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
 	if (!walk_state) {
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index 0637567b454218df8e47b235a430ce27eeee3624..0504e1ac597f22417957ada224d650c36b4f82bd 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -50,6 +50,7 @@
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acdebug.h>
+#include <acpi/acdisasm.h>
 
 
 #define _COMPONENT          ACPI_DISPATCHER
@@ -657,6 +658,16 @@ acpi_ds_exec_end_op (
 	/* Always clear the object stack */
 
 	walk_state->num_operands = 0;
+
+#ifdef ACPI_DISASSEMBLER
+
+	/* On error, display method locals/args */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_dm_dump_method_info (status, walk_state, op);
+	}
+#endif
+
 	return_ACPI_STATUS (status);
 }
 
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index cd9dd6d1c89a50b1cfab2c583ed2c3a6715672b9..6281f491c6ca854d64b3bc2de4c726c760cb7c8a 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -113,7 +113,7 @@ acpi_ec_wait (
 	switch (event) {
 	case ACPI_EC_EVENT_OBF:
 		do {
-			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr, 0);
+			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
 			if (acpi_ec_status & ACPI_EC_FLAG_OBF)
 				return 0;
 			udelay(ACPI_EC_UDELAY);
@@ -121,7 +121,7 @@ acpi_ec_wait (
 		break;
 	case ACPI_EC_EVENT_IBE:
 		do {
-			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr, 0);
+			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
 			if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
 				return 0;
 			udelay(ACPI_EC_UDELAY);
@@ -161,18 +161,18 @@ acpi_ec_read (
 	
 	spin_lock_irqsave(&ec->lock, flags);
 
-	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr, 0);
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
 
-	acpi_hw_low_level_write(8, address, &ec->data_addr, 0);
+	acpi_hw_low_level_write(8, address, &ec->data_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (result)
 		goto end;
 
 
-	acpi_hw_low_level_read(8, data, &ec->data_addr, 0);
+	acpi_hw_low_level_read(8, data, &ec->data_addr);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
 		*data, address));
@@ -211,17 +211,17 @@ acpi_ec_write (
 
 	spin_lock_irqsave(&ec->lock, flags);
 
-	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr, 0);
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
 
-	acpi_hw_low_level_write(8, address, &ec->data_addr, 0);
+	acpi_hw_low_level_write(8, address, &ec->data_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
 
-	acpi_hw_low_level_write(8, data, &ec->data_addr, 0);
+	acpi_hw_low_level_write(8, data, &ec->data_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
@@ -310,12 +310,12 @@ acpi_ec_query (
 	 */
 	spin_lock_irqsave(&ec->lock, flags);
 
-	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr, 0);
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (result)
 		goto end;
 	
-	acpi_hw_low_level_read(8, data, &ec->data_addr, 0);
+	acpi_hw_low_level_read(8, data, &ec->data_addr);
 	if (!*data)
 		result = -ENODATA;
 
@@ -355,7 +355,7 @@ acpi_ec_gpe_query (
 		goto end;	
 
 	spin_lock_irqsave(&ec->lock, flags);
-	acpi_hw_low_level_read(8, &value, &ec->command_addr, 0);
+	acpi_hw_low_level_read(8, &value, &ec->command_addr);
 	spin_unlock_irqrestore(&ec->lock, flags);
 
 	/* TBD: Implement asynch events!
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index 2fc32e12c86fae24be6f84997d1ce7a73877eb75..4cb089d54c67f3b278891570425ef3010b292ea7 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -170,7 +170,7 @@ acpi_ev_gpe_detect (
 			/* Read the Status Register */
 
 			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
-					 &gpe_register_info->status_address, 0);
+					 &gpe_register_info->status_address);
 			gpe_register_info->status = (u8) in_value;
 			if (ACPI_FAILURE (status)) {
 				goto unlock_and_exit;
@@ -179,7 +179,7 @@ acpi_ev_gpe_detect (
 			/* Read the Enable Register */
 
 			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
-					 &gpe_register_info->enable_address, 0);
+					 &gpe_register_info->enable_address);
 			gpe_register_info->enable = (u8) in_value;
 			if (ACPI_FAILURE (status)) {
 				goto unlock_and_exit;
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
index 6592b2301caea8ba852a422e9b0bda3e6c3c69c6..c24a11d9aaec50664570e773900593f3a0de3124 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -634,13 +634,13 @@ acpi_ev_create_gpe_info_blocks (
 		 * by writing a '0'.
 		 */
 		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00,
-				 &this_register->enable_address, 0);
+				 &this_register->enable_address);
 		if (ACPI_FAILURE (status)) {
 			goto error_exit;
 		}
 
 		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF,
-				 &this_register->status_address, 0);
+				 &this_register->status_address);
 		if (ACPI_FAILURE (status)) {
 			goto error_exit;
 		}
@@ -732,18 +732,16 @@ acpi_ev_create_gpe_block (
 
 	/* Dump info about this GPE block */
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block: [%4.4s] %X registers at %8.8X%8.8X on interrupt %d\n",
+	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n",
+		gpe_block->block_base_number,
+		(u32) (gpe_block->block_base_number +
+				((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
 		gpe_device->name.ascii,
 		gpe_block->register_count,
 		ACPI_HIDWORD (gpe_block->block_address.address),
 		ACPI_LODWORD (gpe_block->block_address.address),
 		interrupt_level));
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block defined as GPE 0x%.2X to GPE 0x%.2X\n",
-		gpe_block->block_base_number,
-		(u32) (gpe_block->block_base_number +
-				((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1))));
-
 	/* Find all GPE methods (_Lxx, _Exx) for this block */
 
 	status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device,
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index c76f24fb372ee7b20b83271013b9ee52789d3968..8a60bab5b9ddf023bce30fcce200049101ca884f 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -156,10 +156,10 @@ acpi_ev_queue_notify_request (
 		case ACPI_TYPE_POWER:
 
 			if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
-				handler_obj = obj_desc->common_notify.sys_handler;
+				handler_obj = obj_desc->common_notify.system_notify;
 			}
 			else {
-				handler_obj = obj_desc->common_notify.drv_handler;
+				handler_obj = obj_desc->common_notify.device_notify;
 			}
 			break;
 
@@ -171,8 +171,8 @@ acpi_ev_queue_notify_request (
 
 	/* If there is any handler to run, schedule the dispatcher */
 
-	if ((acpi_gbl_sys_notify.handler && (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
-		(acpi_gbl_drv_notify.handler && (notify_value > ACPI_MAX_SYS_NOTIFY)) ||
+	if ((acpi_gbl_system_notify.handler && (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
+		(acpi_gbl_device_notify.handler && (notify_value > ACPI_MAX_SYS_NOTIFY)) ||
 		handler_obj) {
 		notify_info = acpi_ut_create_generic_state ();
 		if (!notify_info) {
@@ -235,17 +235,17 @@ acpi_ev_notify_dispatch (
 	if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) {
 		/* Global system notification handler */
 
-		if (acpi_gbl_sys_notify.handler) {
-			global_handler = acpi_gbl_sys_notify.handler;
-			global_context = acpi_gbl_sys_notify.context;
+		if (acpi_gbl_system_notify.handler) {
+			global_handler = acpi_gbl_system_notify.handler;
+			global_context = acpi_gbl_system_notify.context;
 		}
 	}
 	else {
 		/* Global driver notification handler */
 
-		if (acpi_gbl_drv_notify.handler) {
-			global_handler = acpi_gbl_drv_notify.handler;
-			global_context = acpi_gbl_drv_notify.context;
+		if (acpi_gbl_device_notify.handler) {
+			global_handler = acpi_gbl_device_notify.handler;
+			global_context = acpi_gbl_device_notify.context;
 		}
 	}
 
@@ -259,8 +259,8 @@ acpi_ev_notify_dispatch (
 
 	handler_obj = notify_info->notify.handler_obj;
 	if (handler_obj) {
-		handler_obj->notify_handler.handler (notify_info->notify.node, notify_info->notify.value,
-				  handler_obj->notify_handler.context);
+		handler_obj->notify.handler (notify_info->notify.node, notify_info->notify.value,
+				  handler_obj->notify.context);
 	}
 
 	/* All done with the info object */
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index de32b8f856040f14fb8a9750f30d4b04f3d92ee3..6b60baf5ab41ee69a3a1a5abe19069174afba984 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -50,24 +50,32 @@
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evregion")
 
+#define ACPI_NUM_DEFAULT_SPACES     4
+
+u8                              acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
+			 ACPI_ADR_SPACE_SYSTEM_MEMORY,
+			 ACPI_ADR_SPACE_SYSTEM_IO,
+			 ACPI_ADR_SPACE_PCI_CONFIG,
+			 ACPI_ADR_SPACE_DATA_TABLE};
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_init_address_spaces
  *
- * PARAMETERS:
+ * PARAMETERS:  None
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Installs the core subsystem address space handlers.
+ * DESCRIPTION: Installs the core subsystem default address space handlers.
  *
  ******************************************************************************/
 
 acpi_status
 acpi_ev_init_address_spaces (
-	void)
-{
+	void) {
 	acpi_status                     status;
+	acpi_native_uint                i;
 
 
 	ACPI_FUNCTION_TRACE ("ev_init_address_spaces");
@@ -75,9 +83,11 @@ acpi_ev_init_address_spaces (
 
 	/*
 	 * All address spaces (PCI Config, EC, SMBus) are scope dependent
-	 * and registration must occur for a specific device.  In the case
-	 * system memory and IO address spaces there is currently no device
-	 * associated with the address space.  For these we use the root.
+	 * and registration must occur for a specific device.
+	 *
+	 * In the case of the system memory and IO address spaces there is currently
+	 * no device associated with the address space.  For these we use the root.
+	 *
 	 * We install the default PCI config space handler at the root so
 	 * that this space is immediately available even though the we have
 	 * not enumerated all the PCI Root Buses yet.  This is to conform
@@ -86,39 +96,27 @@ acpi_ev_init_address_spaces (
 	 * near ready to find the PCI root buses at this point.
 	 *
 	 * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
-	 * has already been installed (via acpi_install_address_space_handler)
+	 * has already been installed (via acpi_install_address_space_handler).
+	 * Similar for AE_SAME_HANDLER.
 	 */
 
-	status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
-			   ACPI_ADR_SPACE_SYSTEM_MEMORY,
-			   ACPI_DEFAULT_HANDLER, NULL, NULL);
-	if ((ACPI_FAILURE (status)) &&
-		(status != AE_ALREADY_EXISTS)) {
-		return_ACPI_STATUS (status);
-	}
+	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
+		status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
+				  acpi_gbl_default_address_spaces[i],
+				  ACPI_DEFAULT_HANDLER, NULL, NULL);
+		switch (status) {
+		case AE_OK:
+		case AE_SAME_HANDLER:
+		case AE_ALREADY_EXISTS:
 
-	status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
-			   ACPI_ADR_SPACE_SYSTEM_IO,
-			   ACPI_DEFAULT_HANDLER, NULL, NULL);
-	if ((ACPI_FAILURE (status)) &&
-		(status != AE_ALREADY_EXISTS)) {
-		return_ACPI_STATUS (status);
-	}
+			/* These exceptions are all OK */
 
-	status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
-			   ACPI_ADR_SPACE_PCI_CONFIG,
-			   ACPI_DEFAULT_HANDLER, NULL, NULL);
-	if ((ACPI_FAILURE (status)) &&
-		(status != AE_ALREADY_EXISTS)) {
-		return_ACPI_STATUS (status);
-	}
+			break;
+
+		default:
 
-	status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
-			   ACPI_ADR_SPACE_DATA_TABLE,
-			   ACPI_DEFAULT_HANDLER, NULL, NULL);
-	if ((ACPI_FAILURE (status)) &&
-		(status != AE_ALREADY_EXISTS)) {
-		return_ACPI_STATUS (status);
+			return_ACPI_STATUS (status);
+		}
 	}
 
 	return_ACPI_STATUS (AE_OK);
@@ -161,10 +159,10 @@ acpi_ev_execute_reg_method (
 	}
 
 	/*
-	 *  _REG method has two arguments
-	 *  Arg0:   Integer: Operation region space ID
+	 * _REG method has two arguments
+	 * Arg0:   Integer: Operation region space ID
 	 *          Same value as region_obj->Region.space_id
-	 *  Arg1:   Integer: connection status
+	 * Arg1:   Integer: connection status
 	 *          1 for connecting the handler,
 	 *          0 for disconnecting the handler
 	 *          Passed as a parameter
@@ -180,16 +178,14 @@ acpi_ev_execute_reg_method (
 		goto cleanup;
 	}
 
-	/*
-	 *  Set up the parameter objects
-	 */
+	/* Set up the parameter objects */
+
 	params[0]->integer.value = region_obj->region.space_id;
 	params[1]->integer.value = function;
 	params[2] = NULL;
 
-	/*
-	 *  Execute the method, no return value
-	 */
+	/* Execute the method, no return value */
+
 	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, region_obj2->extra.method_REG, NULL));
 	status = acpi_ns_evaluate_by_handle (region_obj2->extra.method_REG, params, NULL);
 
@@ -245,10 +241,9 @@ acpi_ev_address_space_dispatch (
 		return_ACPI_STATUS (AE_NOT_EXIST);
 	}
 
-	/*
-	 * Ensure that there is a handler associated with this region
-	 */
-	handler_desc = region_obj->region.addr_handler;
+	/* Ensure that there is a handler associated with this region */
+
+	handler_desc = region_obj->region.address_space;
 	if (!handler_desc) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n",
 			region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
@@ -264,24 +259,23 @@ acpi_ev_address_space_dispatch (
 		/*
 		 * This region has not been initialized yet, do it
 		 */
-		region_setup = handler_desc->addr_handler.setup;
+		region_setup = handler_desc->address_space.setup;
 		if (!region_setup) {
-			/*
-			 *  Bad news, no init routine and not init'd
-			 */
+			/* No initialization routine, exit with error */
+
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No init routine for region(%p) [%s]\n",
 				region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
-			return_ACPI_STATUS (AE_UNKNOWN_STATUS);
+			return_ACPI_STATUS (AE_NOT_EXIST);
 		}
 
 		/*
 		 * We must exit the interpreter because the region setup will potentially
-		 * execute control methods
+		 * execute control methods (e.g., _REG method for this region)
 		 */
 		acpi_ex_exit_interpreter ();
 
 		status = region_setup (region_obj, ACPI_REGION_ACTIVATE,
-				  handler_desc->addr_handler.context, &region_context);
+				  handler_desc->address_space.context, &region_context);
 
 		/* Re-enter the interpreter */
 
@@ -290,9 +284,8 @@ acpi_ev_address_space_dispatch (
 			return_ACPI_STATUS (status2);
 		}
 
-		/*
-		 *  Init routine may fail
-		 */
+		/* Check for failure of the Region Setup */
+
 		if (ACPI_FAILURE (status)) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region Init: %s [%s]\n",
 				acpi_format_exception (status),
@@ -300,40 +293,50 @@ acpi_ev_address_space_dispatch (
 			return_ACPI_STATUS (status);
 		}
 
-		region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
-
 		/*
-		 *  Save the returned context for use in all accesses to
-		 *  this particular region.
+		 * Region initialization may have been completed by region_setup
 		 */
-		region_obj2->extra.region_context = region_context;
+		if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
+			region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
+
+			if (region_obj2->extra.region_context) {
+				/* The handler for this region was already installed */
+
+				ACPI_MEM_FREE (region_context);
+			}
+			else {
+				/*
+				 * Save the returned context for use in all accesses to
+				 * this particular region
+				 */
+				region_obj2->extra.region_context = region_context;
+			}
+		}
 	}
 
-	/*
-	 *  We have everything we need, begin the process
-	 */
-	handler = handler_desc->addr_handler.handler;
+	/* We have everything we need, we can invoke the address space handler */
+
+	handler = handler_desc->address_space.handler;
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 		"Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
-		&region_obj->region.addr_handler->addr_handler, handler,
+		&region_obj->region.address_space->address_space, handler,
 		ACPI_HIDWORD (address), ACPI_LODWORD (address),
 		acpi_ut_get_region_name (region_obj->region.space_id)));
 
-	if (!(handler_desc->addr_handler.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+	if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
 		/*
-		 *  For handlers other than the default (supplied) handlers, we must
-		 *  exit the interpreter because the handler *might* block -- we don't
-		 *  know what it will do, so we can't hold the lock on the intepreter.
+		 * For handlers other than the default (supplied) handlers, we must
+		 * exit the interpreter because the handler *might* block -- we don't
+		 * know what it will do, so we can't hold the lock on the intepreter.
 		 */
 		acpi_ex_exit_interpreter();
 	}
 
-	/*
-	 *  Invoke the handler.
-	 */
+	/* Call the handler */
+
 	status = handler (function, address, bit_width, value,
-			 handler_desc->addr_handler.context,
+			 handler_desc->address_space.context,
 			 region_obj2->extra.region_context);
 
 	if (ACPI_FAILURE (status)) {
@@ -342,7 +345,7 @@ acpi_ev_address_space_dispatch (
 			acpi_format_exception (status)));
 	}
 
-	if (!(handler_desc->addr_handler.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+	if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
 		/*
 		 * We just returned from a non-default handler, we must re-enter the
 		 * interpreter
@@ -393,35 +396,30 @@ acpi_ev_detach_region(
 	}
 	region_context = region_obj2->extra.region_context;
 
-	/*
-	 *  Get the address handler from the region object
-	 */
-	handler_obj = region_obj->region.addr_handler;
+	/* Get the address handler from the region object */
+
+	handler_obj = region_obj->region.address_space;
 	if (!handler_obj) {
-		/*
-		 *  This region has no handler, all done
-		 */
+		/* This region has no handler, all done */
+
 		return_VOID;
 	}
 
+	/* Find this region in the handler's list */
 
-	/*
-	 *  Find this region in the handler's list
-	 */
-	obj_desc = handler_obj->addr_handler.region_list;
-	last_obj_ptr = &handler_obj->addr_handler.region_list;
+	obj_desc = handler_obj->address_space.region_list;
+	last_obj_ptr = &handler_obj->address_space.region_list;
 
 	while (obj_desc) {
-		/*
-		 *  See if this is the one
-		 */
+		/* Is this the correct Region? */
+
 		if (obj_desc == region_obj) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 				"Removing Region %p from address handler %p\n",
 				region_obj, handler_obj));
-			/*
-			 *  This is it, remove it from the handler's list
-			 */
+
+			/* This is it, remove it from the handler's list */
+
 			*last_obj_ptr = obj_desc->region.next;
 			obj_desc->region.next = NULL;           /* Must clear field */
 
@@ -432,9 +430,8 @@ acpi_ev_detach_region(
 				}
 			}
 
-			/*
-			 *  Now stop region accesses by executing the _REG method
-			 */
+			/* Now stop region accesses by executing the _REG method */
+
 			status = acpi_ev_execute_reg_method (region_obj, 0);
 			if (ACPI_FAILURE (status)) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region _REG, [%s]\n",
@@ -449,16 +446,14 @@ acpi_ev_detach_region(
 				}
 			}
 
-			/*
-			 *  Call the setup handler with the deactivate notification
-			 */
-			region_setup = handler_obj->addr_handler.setup;
+			/* Call the setup handler with the deactivate notification */
+
+			region_setup = handler_obj->address_space.setup;
 			status = region_setup (region_obj, ACPI_REGION_DEACTIVATE,
-					  handler_obj->addr_handler.context, &region_context);
+					  handler_obj->address_space.context, &region_context);
+
+			/* Init routine may fail, Just ignore errors */
 
-			/*
-			 *  Init routine may fail, Just ignore errors
-			 */
 			if (ACPI_FAILURE (status)) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region init, [%s]\n",
 					acpi_format_exception (status),
@@ -468,31 +463,29 @@ acpi_ev_detach_region(
 			region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);
 
 			/*
-			 *  Remove handler reference in the region
+			 * Remove handler reference in the region
 			 *
-			 *  NOTE: this doesn't mean that the region goes away
-			 *  The region is just inaccessible as indicated to
-			 *  the _REG method
+			 * NOTE: this doesn't mean that the region goes away
+			 * The region is just inaccessible as indicated to
+			 * the _REG method
 			 *
-			 *  If the region is on the handler's list
-			 *  this better be the region's handler
+			 * If the region is on the handler's list
+			 * this better be the region's handler
 			 */
-			region_obj->region.addr_handler = NULL;
+			region_obj->region.address_space = NULL;
+			acpi_ut_remove_reference (handler_obj);
 
 			return_VOID;
+		}
 
-		} /* found the right handler */
+		/* Walk the linked list of handlers */
 
-		/*
-		 *  Move through the linked list of handlers
-		 */
 		last_obj_ptr = &obj_desc->region.next;
 		obj_desc = obj_desc->region.next;
 	}
 
-	/*
-	 *  If we get here, the region was not in the handler's region list
-	 */
+	/* If we get here, the region was not in the handler's region list */
+
 	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 		"Cannot remove region %p from address handler %p\n",
 		region_obj, handler_obj));
@@ -534,16 +527,19 @@ acpi_ev_attach_region (
 		region_obj, handler_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
 
 
-	/*
-	 * Link this region to the front of the handler's list
-	 */
-	region_obj->region.next = handler_obj->addr_handler.region_list;
-	handler_obj->addr_handler.region_list = region_obj;
+	/* Link this region to the front of the handler's list */
 
-	/*
-	 * Set the region's handler
-	 */
-	region_obj->region.addr_handler = handler_obj;
+	region_obj->region.next = handler_obj->address_space.region_list;
+	handler_obj->address_space.region_list = region_obj;
+
+	/* Install the region's handler */
+
+	if (region_obj->region.address_space) {
+		return_ACPI_STATUS (AE_ALREADY_EXISTS);
+	}
+
+	region_obj->region.address_space = handler_obj;
+	acpi_ut_add_reference (handler_obj);
 
 	/*
 	 * Tell all users that this region is usable by running the _REG
@@ -571,14 +567,14 @@ acpi_ev_attach_region (
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_addr_handler_helper
+ * FUNCTION:    acpi_ev_install_handler
  *
  * PARAMETERS:  Handle              - Node to be dumped
  *              Level               - Nesting level of the handle
  *              Context             - Passed into acpi_ns_walk_namespace
  *
  * DESCRIPTION: This routine installs an address handler into objects that are
- *              of type Region.
+ *              of type Region or Device.
  *
  *              If the Object is a Device, and the device has a handler of
  *              the same type then the search is terminated in that branch.
@@ -589,20 +585,20 @@ acpi_ev_attach_region (
  ******************************************************************************/
 
 acpi_status
-acpi_ev_addr_handler_helper (
+acpi_ev_install_handler (
 	acpi_handle                     obj_handle,
 	u32                             level,
 	void                            *context,
 	void                            **return_value)
 {
 	union acpi_operand_object       *handler_obj;
-	union acpi_operand_object       *tmp_obj;
+	union acpi_operand_object       *next_handler_obj;
 	union acpi_operand_object       *obj_desc;
 	struct acpi_namespace_node      *node;
 	acpi_status                     status;
 
 
-	ACPI_FUNCTION_NAME ("ev_addr_handler_helper");
+	ACPI_FUNCTION_NAME ("ev_install_handler");
 
 
 	handler_obj = (union acpi_operand_object   *) context;
@@ -621,8 +617,8 @@ acpi_ev_addr_handler_helper (
 	}
 
 	/*
-	 *  We only care about regions.and objects
-	 *  that can have address handlers
+	 * We only care about regions.and objects
+	 * that are allowed to have address space handlers
 	 */
 	if ((node->type != ACPI_TYPE_DEVICE) &&
 		(node->type != ACPI_TYPE_REGION) &&
@@ -634,81 +630,70 @@ acpi_ev_addr_handler_helper (
 
 	obj_desc = acpi_ns_get_attached_object (node);
 	if (!obj_desc) {
-		/*
-		 *  The object DNE, we don't care about it
-		 */
+		/* No object, just exit */
+
 		return (AE_OK);
 	}
 
-	/*
-	 *  Devices are handled different than regions
-	 */
+	/* Devices are handled different than regions */
+
 	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) {
-		/*
-		 *  See if this guy has any handlers
-		 */
-		tmp_obj = obj_desc->device.addr_handler;
-		while (tmp_obj) {
-			/*
-			 *  Now let's see if it's for the same address space.
-			 */
-			if (tmp_obj->addr_handler.space_id == handler_obj->addr_handler.space_id) {
-				/*
-				 *  It's for the same address space
-				 */
+		/* Check if this Device already has a handler for this address space */
+
+		next_handler_obj = obj_desc->device.address_space;
+		while (next_handler_obj) {
+			/* Found a handler, is it for the same address space? */
+
+			if (next_handler_obj->address_space.space_id == handler_obj->address_space.space_id) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 					"Found handler for region [%s] in device %p(%p) handler %p\n",
-					acpi_ut_get_region_name (handler_obj->addr_handler.space_id),
-					obj_desc, tmp_obj, handler_obj));
+					acpi_ut_get_region_name (handler_obj->address_space.space_id),
+					obj_desc, next_handler_obj, handler_obj));
 
 				/*
-				 *  Since the object we found it on was a device, then it
-				 *  means that someone has already installed a handler for
-				 *  the branch of the namespace from this device on.  Just
-				 *  bail out telling the walk routine to not traverse this
-				 *  branch.  This preserves the scoping rule for handlers.
+				 * Since the object we found it on was a device, then it
+				 * means that someone has already installed a handler for
+				 * the branch of the namespace from this device on.  Just
+				 * bail out telling the walk routine to not traverse this
+				 * branch.  This preserves the scoping rule for handlers.
 				 */
 				return (AE_CTRL_DEPTH);
 			}
 
-			/*
-			 *  Move through the linked list of handlers
-			 */
-			tmp_obj = tmp_obj->addr_handler.next;
+			/* Walk the linked list of handlers attached to this device */
+
+			next_handler_obj = next_handler_obj->address_space.next;
 		}
 
 		/*
-		 *  As long as the device didn't have a handler for this
-		 *  space we don't care about it.  We just ignore it and
-		 *  proceed.
+		 * As long as the device didn't have a handler for this
+		 * space we don't care about it.  We just ignore it and
+		 * proceed.
 		 */
 		return (AE_OK);
 	}
 
-	/*
-	 *  Only here if it was a region
-	 */
-	if (obj_desc->region.space_id != handler_obj->addr_handler.space_id) {
+	/* Object is a Region */
+
+	if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
 		/*
-		 *  This region is for a different address space
-		 *  ignore it
+		 * This region is for a different address space
+		 * -- just ignore it
 		 */
 		return (AE_OK);
 	}
 
 	/*
-	 *  Now we have a region and it is for the handler's address
-	 *  space type.
+	 * Now we have a region and it is for the handler's address
+	 * space type.
 	 *
-	 *  First disconnect region for any previous handler (if any)
+	 * First disconnect region for any previous handler (if any)
 	 */
 	acpi_ev_detach_region (obj_desc, FALSE);
 
-	/*
-	 *  Then connect the region to the new handler
-	 */
-	status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE);
+	/* Connect the region to the new handler */
 
+	status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE);
 	return (status);
 }
 
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 30391790f5390743dfd2091f3fa66608f313cfd2..dcc633fd65c98fbfe2382788b128103a2d61eb17 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -165,10 +165,11 @@ acpi_ev_pci_config_region_setup (
 	void                            **region_context)
 {
 	acpi_status                     status = AE_OK;
-	acpi_integer                    temp;
+	acpi_integer                    pci_value;
 	struct acpi_pci_id              *pci_id = *region_context;
 	union acpi_operand_object       *handler_obj;
-	struct acpi_namespace_node      *node;
+	struct acpi_namespace_node      *parent_node;
+	struct acpi_namespace_node      *pci_root_node;
 	union acpi_operand_object       *region_obj = (union acpi_operand_object   *) handle;
 	struct acpi_device_id           object_hID;
 
@@ -176,7 +177,7 @@ acpi_ev_pci_config_region_setup (
 	ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup");
 
 
-	handler_obj = region_obj->region.addr_handler;
+	handler_obj = region_obj->region.address_space;
 	if (!handler_obj) {
 		/*
 		 * No installed handler. This shouldn't happen because the dispatch
@@ -187,45 +188,15 @@ acpi_ev_pci_config_region_setup (
 		return_ACPI_STATUS (AE_NOT_EXIST);
 	}
 
+	*region_context = NULL;
 	if (function == ACPI_REGION_DEACTIVATE) {
 		if (pci_id) {
 			ACPI_MEM_FREE (pci_id);
-			*region_context = NULL;
 		}
-
 		return_ACPI_STATUS (status);
 	}
 
-	/* Create a new context */
-
-	pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id));
-	if (!pci_id) {
-		return_ACPI_STATUS (AE_NO_MEMORY);
-	}
-
-	/*
-	 * For PCI Config space access, we have to pass the segment, bus,
-	 * device and function numbers.  This routine must acquire those.
-	 */
-
-	/*
-	 * First get device and function numbers from the _ADR object
-	 * in the parent's scope.
-	 */
-	node = acpi_ns_get_parent_node (region_obj->region.node);
-
-	/* Evaluate the _ADR object */
-
-	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node, &temp);
-
-	/*
-	 * The default is zero, and since the allocation above zeroed
-	 * the data, just do nothing on failure.
-	 */
-	if (ACPI_SUCCESS (status)) {
-		pci_id->device  = ACPI_HIWORD (ACPI_LODWORD (temp));
-		pci_id->function = ACPI_LOWORD (ACPI_LODWORD (temp));
-	}
+	parent_node = acpi_ns_get_parent_node (region_obj->region.node);
 
 	/*
 	 * Get the _SEG and _BBN values from the device upon which the handler
@@ -236,61 +207,106 @@ acpi_ev_pci_config_region_setup (
 	 */
 
 	/*
-	 * If the addr_handler.Node is still pointing to the root, we need
+	 * If the address_space.Node is still pointing to the root, we need
 	 * to scan upward for a PCI Root bridge and re-associate the op_region
 	 * handlers with that device.
 	 */
-	if (handler_obj->addr_handler.node == acpi_gbl_root_node) {
-		/*
-		 * Node is currently the parent object
-		 */
-		while (node != acpi_gbl_root_node) {
-			status = acpi_ut_execute_HID (node, &object_hID);
+	if (handler_obj->address_space.node == acpi_gbl_root_node) {
+		/* Start search from the parent object */
+
+		pci_root_node = parent_node;
+		while (pci_root_node != acpi_gbl_root_node) {
+			status = acpi_ut_execute_HID (pci_root_node, &object_hID);
 			if (ACPI_SUCCESS (status)) {
 				/* Got a valid _HID, check if this is a PCI root */
 
-				if (!(ACPI_STRNCMP (object_hID.buffer, PCI_ROOT_HID_STRING,
+				if (!(ACPI_STRNCMP (object_hID.value, PCI_ROOT_HID_STRING,
 						   sizeof (PCI_ROOT_HID_STRING)))) {
 					/* Install a handler for this PCI root bridge */
 
-					status = acpi_install_address_space_handler ((acpi_handle) node,
+					status = acpi_install_address_space_handler ((acpi_handle) pci_root_node,
 							   ACPI_ADR_SPACE_PCI_CONFIG,
 							   ACPI_DEFAULT_HANDLER, NULL, NULL);
 					if (ACPI_FAILURE (status)) {
-						ACPI_REPORT_ERROR (("Could not install pci_config handler for %4.4s, %s\n",
-							node->name.ascii, acpi_format_exception (status)));
+						if (status == AE_SAME_HANDLER) {
+							/*
+							 * It is OK if the handler is already installed on the root
+							 * bridge.  Still need to return a context object for the
+							 * new PCI_Config operation region, however.
+							 */
+							status = AE_OK;
+						}
+						else {
+							ACPI_REPORT_ERROR ((
+								"Could not install pci_config handler for Root Bridge %4.4s, %s\n",
+								pci_root_node->name.ascii, acpi_format_exception (status)));
+						}
 					}
 					break;
 				}
 			}
 
-			node = acpi_ns_get_parent_node (node);
+			pci_root_node = acpi_ns_get_parent_node (pci_root_node);
 		}
+
+		/* PCI root bridge not found, use namespace root node */
 	}
 	else {
-		node = handler_obj->addr_handler.node;
+		pci_root_node = handler_obj->address_space.node;
 	}
 
 	/*
-	 * The PCI segment number comes from the _SEG method
+	 * If this region is now initialized, we are done.
+	 * (install_address_space_handler could have initialized it)
 	 */
-	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, node, &temp);
-	if (ACPI_SUCCESS (status)) {
-		pci_id->segment = ACPI_LOWORD (temp);
+	if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Region is still not initialized. Create a new context */
+
+	pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id));
+	if (!pci_id) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
 	/*
-	 * The PCI bus number comes from the _BBN method
+	 * For PCI_Config space access, we need the segment, bus,
+	 * device and function numbers.  Acquire them here.
 	 */
-	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, node, &temp);
-	if (ACPI_SUCCESS (status)) {
-		pci_id->bus = ACPI_LOWORD (temp);
-	}
 
 	/*
-	 * Complete this device's pci_id
+	 * Get the PCI device and function numbers from the _ADR object
+	 * contained in the parent's scope.
 	 */
-	acpi_os_derive_pci_id (node, region_obj->region.node, &pci_id);
+	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, parent_node, &pci_value);
+
+	/*
+	 * The default is zero, and since the allocation above zeroed
+	 * the data, just do nothing on failure.
+	 */
+	if (ACPI_SUCCESS (status)) {
+		pci_id->device  = ACPI_HIWORD (ACPI_LODWORD (pci_value));
+		pci_id->function = ACPI_LOWORD (ACPI_LODWORD (pci_value));
+	}
+
+	/* The PCI segment number comes from the _SEG method */
+
+	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, pci_root_node, &pci_value);
+	if (ACPI_SUCCESS (status)) {
+		pci_id->segment = ACPI_LOWORD (pci_value);
+	}
+
+	/* The PCI bus number comes from the _BBN method */
+
+	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, pci_root_node, &pci_value);
+	if (ACPI_SUCCESS (status)) {
+		pci_id->bus = ACPI_LOWORD (pci_value);
+	}
+
+	/* Complete this device's pci_id */
+
+	acpi_os_derive_pci_id (pci_root_node, region_obj->region.node, &pci_id);
 
 	*region_context = pci_id;
 	return_ACPI_STATUS (AE_OK);
@@ -451,14 +467,15 @@ acpi_ev_initialize_region (
 	node = acpi_ns_get_parent_node (region_obj->region.node);
 	space_id = region_obj->region.space_id;
 
-	region_obj->region.addr_handler = NULL;
+	/* Setup defaults */
+
+	region_obj->region.address_space = NULL;
 	region_obj2->extra.method_REG = NULL;
 	region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
 	region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
 
-	/*
-	 * Find any "_REG" method associated with this region definition
-	 */
+	/* Find any "_REG" method associated with this region definition */
+
 	status = acpi_ns_search_node (*reg_name_ptr, node,
 			  ACPI_TYPE_METHOD, &method_node);
 	if (ACPI_SUCCESS (status)) {
@@ -475,29 +492,27 @@ acpi_ev_initialize_region (
 	 * ie: acpi_gbl_root_node->parent_entry being set to NULL
 	 */
 	while (node) {
-		/*
-		 * Check to see if a handler exists
-		 */
+		/* Check to see if a handler exists */
+
 		handler_obj = NULL;
 		obj_desc = acpi_ns_get_attached_object (node);
 		if (obj_desc) {
-			/*
-			 * Can only be a handler if the object exists
-			 */
+			/* Can only be a handler if the object exists */
+
 			switch (node->type) {
 			case ACPI_TYPE_DEVICE:
 
-				handler_obj = obj_desc->device.addr_handler;
+				handler_obj = obj_desc->device.address_space;
 				break;
 
 			case ACPI_TYPE_PROCESSOR:
 
-				handler_obj = obj_desc->processor.addr_handler;
+				handler_obj = obj_desc->processor.address_space;
 				break;
 
 			case ACPI_TYPE_THERMAL:
 
-				handler_obj = obj_desc->thermal_zone.addr_handler;
+				handler_obj = obj_desc->thermal_zone.address_space;
 				break;
 
 			default:
@@ -508,7 +523,7 @@ acpi_ev_initialize_region (
 			while (handler_obj) {
 				/* Is this handler of the correct type? */
 
-				if (handler_obj->addr_handler.space_id == space_id) {
+				if (handler_obj->address_space.space_id == space_id) {
 					/* Found correct handler */
 
 					ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
@@ -523,7 +538,7 @@ acpi_ev_initialize_region (
 
 				/* Try next handler in the list */
 
-				handler_obj = handler_obj->addr_handler.next;
+				handler_obj = handler_obj->address_space.next;
 			}
 		}
 
@@ -534,9 +549,8 @@ acpi_ev_initialize_region (
 		node = acpi_ns_get_parent_node (node);
 	}
 
-	/*
-	 * If we get here, there is no handler for this region
-	 */
+	/* If we get here, there is no handler for this region */
+
 	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 		"No handler for region_type %s(%X) (region_obj %p)\n",
 		acpi_ut_get_region_name (space_id), space_id, region_obj));
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 18b04571acf2da2aa4ccdc8ead88bce146828d88..e9a289a52d36e5309d0dffae5a30f305467411aa 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -244,22 +244,22 @@ acpi_install_notify_handler (
 		/* Make sure the handler is not already installed */
 
 		if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
-			  acpi_gbl_sys_notify.handler) ||
+				acpi_gbl_system_notify.handler)        ||
 			((handler_type == ACPI_DEVICE_NOTIFY) &&
-			  acpi_gbl_drv_notify.handler)) {
+				acpi_gbl_device_notify.handler)) {
 			status = AE_ALREADY_EXISTS;
 			goto unlock_and_exit;
 		}
 
 		if (handler_type == ACPI_SYSTEM_NOTIFY) {
-			acpi_gbl_sys_notify.node = node;
-			acpi_gbl_sys_notify.handler = handler;
-			acpi_gbl_sys_notify.context = context;
+			acpi_gbl_system_notify.node  = node;
+			acpi_gbl_system_notify.handler = handler;
+			acpi_gbl_system_notify.context = context;
 		}
 		else /* ACPI_DEVICE_NOTIFY */ {
-			acpi_gbl_drv_notify.node = node;
-			acpi_gbl_drv_notify.handler = handler;
-			acpi_gbl_drv_notify.context = context;
+			acpi_gbl_device_notify.node  = node;
+			acpi_gbl_device_notify.handler = handler;
+			acpi_gbl_device_notify.context = context;
 		}
 
 		/* Global notify handler installed */
@@ -282,13 +282,12 @@ acpi_install_notify_handler (
 
 		obj_desc = acpi_ns_get_attached_object (node);
 		if (obj_desc) {
-
 			/* Object exists - make sure there's no handler */
 
 			if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
-				  obj_desc->common_notify.sys_handler) ||
+					obj_desc->common_notify.system_notify) ||
 				((handler_type == ACPI_DEVICE_NOTIFY) &&
-				  obj_desc->common_notify.drv_handler)) {
+					obj_desc->common_notify.device_notify)) {
 				status = AE_ALREADY_EXISTS;
 				goto unlock_and_exit;
 			}
@@ -305,6 +304,11 @@ acpi_install_notify_handler (
 			/* Attach new object to the Node */
 
 			status = acpi_ns_attach_object (device, obj_desc, node->type);
+
+			/* Remove local reference to the object */
+
+			acpi_ut_remove_reference (obj_desc);
+
 			if (ACPI_FAILURE (status)) {
 				goto unlock_and_exit;
 			}
@@ -318,15 +322,15 @@ acpi_install_notify_handler (
 			goto unlock_and_exit;
 		}
 
-		notify_obj->notify_handler.node = node;
-		notify_obj->notify_handler.handler = handler;
-		notify_obj->notify_handler.context = context;
+		notify_obj->notify.node   = node;
+		notify_obj->notify.handler = handler;
+		notify_obj->notify.context = context;
 
 		if (handler_type == ACPI_SYSTEM_NOTIFY) {
-			obj_desc->common_notify.sys_handler = notify_obj;
+			obj_desc->common_notify.system_notify = notify_obj;
 		}
 		else /* ACPI_DEVICE_NOTIFY */ {
-			obj_desc->common_notify.drv_handler = notify_obj;
+			obj_desc->common_notify.device_notify = notify_obj;
 		}
 	}
 
@@ -395,22 +399,22 @@ acpi_remove_notify_handler (
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
 
 		if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
-			  !acpi_gbl_sys_notify.handler) ||
+			  !acpi_gbl_system_notify.handler) ||
 			((handler_type == ACPI_DEVICE_NOTIFY) &&
-			  !acpi_gbl_drv_notify.handler)) {
+			  !acpi_gbl_device_notify.handler)) {
 			status = AE_NOT_EXIST;
 			goto unlock_and_exit;
 		}
 
 		if (handler_type == ACPI_SYSTEM_NOTIFY) {
-			acpi_gbl_sys_notify.node  = NULL;
-			acpi_gbl_sys_notify.handler = NULL;
-			acpi_gbl_sys_notify.context = NULL;
+			acpi_gbl_system_notify.node  = NULL;
+			acpi_gbl_system_notify.handler = NULL;
+			acpi_gbl_system_notify.context = NULL;
 		}
 		else {
-			acpi_gbl_drv_notify.node  = NULL;
-			acpi_gbl_drv_notify.handler = NULL;
-			acpi_gbl_drv_notify.context = NULL;
+			acpi_gbl_device_notify.node  = NULL;
+			acpi_gbl_device_notify.handler = NULL;
+			acpi_gbl_device_notify.context = NULL;
 		}
 	}
 
@@ -436,14 +440,14 @@ acpi_remove_notify_handler (
 		/* Object exists - make sure there's an existing handler */
 
 		if (handler_type == ACPI_SYSTEM_NOTIFY) {
-			notify_obj = obj_desc->common_notify.sys_handler;
+			notify_obj = obj_desc->common_notify.system_notify;
 		}
 		else {
-			notify_obj = obj_desc->common_notify.drv_handler;
+			notify_obj = obj_desc->common_notify.device_notify;
 		}
 
 		if ((!notify_obj) ||
-			(notify_obj->notify_handler.handler != handler)) {
+			(notify_obj->notify.handler != handler)) {
 			status = AE_BAD_PARAMETER;
 			goto unlock_and_exit;
 		}
@@ -451,10 +455,10 @@ acpi_remove_notify_handler (
 		/* Remove the handler */
 
 		if (handler_type == ACPI_SYSTEM_NOTIFY) {
-			obj_desc->common_notify.sys_handler = NULL;
+			obj_desc->common_notify.system_notify = NULL;
 		}
 		else {
-			obj_desc->common_notify.drv_handler = NULL;
+			obj_desc->common_notify.device_notify = NULL;
 		}
 
 		acpi_ut_remove_reference (notify_obj);
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
index 89122dfc72a14397f5284b683c3c92cacd7f371e..6eda92f06f7b9105989656006969439c003abf7c 100644
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -654,7 +654,11 @@ acpi_install_gpe_block (
 		}
 
 		status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_DEVICE);
+
+		/* Remove local reference to the object */
+
 		acpi_ut_remove_reference (obj_desc);
+
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
index 79d0c5a3fe334d6ca8eb77717fecf30e2b8c278a..44fa3c9ef872197ca6612ab8995bfb786fc9ba46 100644
--- a/drivers/acpi/events/evxfregn.c
+++ b/drivers/acpi/events/evxfregn.c
@@ -154,7 +154,7 @@ acpi_install_address_space_handler (
 			break;
 
 		default:
-			status = AE_NOT_EXIST;
+			status = AE_BAD_PARAMETER;
 			goto unlock_and_exit;
 		}
 	}
@@ -170,26 +170,36 @@ acpi_install_address_space_handler (
 	obj_desc = acpi_ns_get_attached_object (node);
 	if (obj_desc) {
 		/*
-		 * The object exists.
+		 * The attached device object already exists.
 		 * Make sure the handler is not already installed.
 		 */
+		handler_obj = obj_desc->device.address_space;
 
-		/* check the address handler the user requested */
+		/* Walk the handler list for this device */
 
-		handler_obj = obj_desc->device.addr_handler;
 		while (handler_obj) {
-			/*
-			 * Found an Address handler, see if user requested this
-			 * address space.
-			 */
-			if(handler_obj->addr_handler.space_id == space_id) {
-				status = AE_ALREADY_EXISTS;
+			/* Same space_id indicates a handler already installed */
+
+			if(handler_obj->address_space.space_id == space_id) {
+				if (handler_obj->address_space.handler == handler) {
+					/*
+					 * It is (relatively) OK to attempt to install the SAME
+					 * handler twice. This can easily happen with PCI_Config space.
+					 */
+					status = AE_SAME_HANDLER;
+					goto unlock_and_exit;
+				}
+				else {
+					/* A handler is already installed */
+
+					status = AE_ALREADY_EXISTS;
+				}
 				goto unlock_and_exit;
 			}
 
 			/* Walk the linked list of handlers */
 
-			handler_obj = handler_obj->addr_handler.next;
+			handler_obj = handler_obj->address_space.next;
 		}
 	}
 	else {
@@ -218,8 +228,12 @@ acpi_install_address_space_handler (
 		/* Attach the new object to the Node */
 
 		status = acpi_ns_attach_object (node, obj_desc, type);
+
+		/* Remove local reference to the object */
+
+		acpi_ut_remove_reference (obj_desc);
+
 		if (ACPI_FAILURE (status)) {
-			acpi_ut_remove_reference (obj_desc);
 			goto unlock_and_exit;
 		}
 	}
@@ -241,14 +255,25 @@ acpi_install_address_space_handler (
 		goto unlock_and_exit;
 	}
 
-	handler_obj->addr_handler.space_id  = (u8) space_id;
-	handler_obj->addr_handler.hflags    = flags;
-	handler_obj->addr_handler.next      = obj_desc->device.addr_handler;
-	handler_obj->addr_handler.region_list = NULL;
-	handler_obj->addr_handler.node      = node;
-	handler_obj->addr_handler.handler   = handler;
-	handler_obj->addr_handler.context   = context;
-	handler_obj->addr_handler.setup     = setup;
+	/* Init handler obj */
+
+	handler_obj->address_space.space_id  = (u8) space_id;
+	handler_obj->address_space.hflags    = flags;
+	handler_obj->address_space.region_list = NULL;
+	handler_obj->address_space.node      = node;
+	handler_obj->address_space.handler   = handler;
+	handler_obj->address_space.context   = context;
+	handler_obj->address_space.setup     = setup;
+
+	/* Install at head of Device.address_space list */
+
+	handler_obj->address_space.next      = obj_desc->device.address_space;
+
+	/*
+	 * The Device object is the first reference on the handler_obj.
+	 * Each region that uses the handler adds a reference.
+	 */
+	obj_desc->device.address_space = handler_obj;
 
 	/*
 	 * Walk the namespace finding all of the regions this
@@ -262,18 +287,9 @@ acpi_install_address_space_handler (
 	 * In either case, back up and search down the remainder
 	 * of the branch
 	 */
-	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device,
-			 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
-			 acpi_ev_addr_handler_helper,
-			 handler_obj, NULL);
-
-	/* Place this handler 1st on the list */
-
-	handler_obj->common.reference_count =
-			 (u16) (handler_obj->common.reference_count +
-			 obj_desc->common.reference_count - 1);
-	obj_desc->device.addr_handler = handler_obj;
-
+	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX,
+			  ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
+			  handler_obj, NULL);
 
 unlock_and_exit:
 	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
@@ -341,12 +357,12 @@ acpi_remove_address_space_handler (
 
 	/* Find the address handler the user requested */
 
-	handler_obj = obj_desc->device.addr_handler;
-	last_obj_ptr = &obj_desc->device.addr_handler;
+	handler_obj = obj_desc->device.address_space;
+	last_obj_ptr = &obj_desc->device.address_space;
 	while (handler_obj) {
 		/* We have a handler, see if user requested this one */
 
-		if (handler_obj->addr_handler.space_id == space_id) {
+		if (handler_obj->address_space.space_id == space_id) {
 			/* Matched space_id, first dereference this in the Regions */
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
@@ -354,7 +370,7 @@ acpi_remove_address_space_handler (
 				handler_obj, handler, acpi_ut_get_region_name (space_id),
 				node, obj_desc));
 
-			region_obj = handler_obj->addr_handler.region_list;
+			region_obj = handler_obj->address_space.region_list;
 
 			/* Walk the handler's region list */
 
@@ -372,13 +388,13 @@ acpi_remove_address_space_handler (
 				 * Walk the list: Just grab the head because the
 				 * detach_region removed the previous head.
 				 */
-				region_obj = handler_obj->addr_handler.region_list;
+				region_obj = handler_obj->address_space.region_list;
 
 			}
 
 			/* Remove this Handler object from the list */
 
-			*last_obj_ptr = handler_obj->addr_handler.next;
+			*last_obj_ptr = handler_obj->address_space.next;
 
 			/* Now we can delete the handler object */
 
@@ -388,8 +404,8 @@ acpi_remove_address_space_handler (
 
 		/* Walk the linked list of handlers */
 
-		last_obj_ptr = &handler_obj->addr_handler.next;
-		handler_obj = handler_obj->addr_handler.next;
+		last_obj_ptr = &handler_obj->address_space.next;
+		handler_obj = handler_obj->address_space.next;
 	}
 
 	/* The handler does not exist */
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index d7764149b8947571bf8d05062d00e2af5591c6c6..d6ae105579c8ee1fffc468d7bfb3365c4c771009 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -360,11 +360,11 @@ acpi_ex_load_op (
 	/* The table must be either an SSDT or a PSDT */
 
 	if ((!ACPI_STRNCMP (table_ptr->signature,
-			  acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].signature,
-			  acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].sig_length)) &&
+			  acpi_gbl_table_data[ACPI_TABLE_PSDT].signature,
+			  acpi_gbl_table_data[ACPI_TABLE_PSDT].sig_length)) &&
 		(!ACPI_STRNCMP (table_ptr->signature,
-				 acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].signature,
-				 acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].sig_length))) {
+				 acpi_gbl_table_data[ACPI_TABLE_SSDT].signature,
+				 acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Table has invalid signature [%4.4s], must be SSDT or PSDT\n",
 			table_ptr->signature));
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 5d63a6383ebf81feb62c64e4f1579fc4a061c96e..6617a4374004ff17531308a21360f259c3c5fe24 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -635,9 +635,9 @@ acpi_ex_dump_object_descriptor (
 
 	case ACPI_TYPE_DEVICE:
 
-		acpi_ex_out_pointer ("addr_handler", obj_desc->device.addr_handler);
-		acpi_ex_out_pointer ("sys_handler",  obj_desc->device.sys_handler);
-		acpi_ex_out_pointer ("drv_handler",  obj_desc->device.drv_handler);
+		acpi_ex_out_pointer ("address_space", obj_desc->device.address_space);
+		acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify);
+		acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify);
 		break;
 
 
@@ -673,7 +673,7 @@ acpi_ex_dump_object_descriptor (
 		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 ("addr_handler", obj_desc->region.addr_handler);
+		acpi_ex_out_pointer ("address_space", obj_desc->region.address_space);
 		acpi_ex_out_pointer ("Next",         obj_desc->region.next);
 		break;
 
@@ -682,8 +682,8 @@ acpi_ex_dump_object_descriptor (
 
 		acpi_ex_out_integer ("system_level", obj_desc->power_resource.system_level);
 		acpi_ex_out_integer ("resource_order", obj_desc->power_resource.resource_order);
-		acpi_ex_out_pointer ("sys_handler",  obj_desc->power_resource.sys_handler);
-		acpi_ex_out_pointer ("drv_handler",  obj_desc->power_resource.drv_handler);
+		acpi_ex_out_pointer ("system_notify", obj_desc->power_resource.system_notify);
+		acpi_ex_out_pointer ("device_notify", obj_desc->power_resource.device_notify);
 		break;
 
 
@@ -692,17 +692,17 @@ acpi_ex_dump_object_descriptor (
 		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_pointer ("sys_handler",  obj_desc->processor.sys_handler);
-		acpi_ex_out_pointer ("drv_handler",  obj_desc->processor.drv_handler);
-		acpi_ex_out_pointer ("addr_handler", obj_desc->processor.addr_handler);
+		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 ("address_space", obj_desc->processor.address_space);
 		break;
 
 
 	case ACPI_TYPE_THERMAL:
 
-		acpi_ex_out_pointer ("sys_handler",  obj_desc->thermal_zone.sys_handler);
-		acpi_ex_out_pointer ("drv_handler",  obj_desc->thermal_zone.drv_handler);
-		acpi_ex_out_pointer ("addr_handler", obj_desc->thermal_zone.addr_handler);
+		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 ("address_space", obj_desc->thermal_zone.address_space);
 		break;
 
 
@@ -762,18 +762,18 @@ acpi_ex_dump_object_descriptor (
 
 	case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
 
-		acpi_ex_out_integer ("space_id",     obj_desc->addr_handler.space_id);
-		acpi_ex_out_pointer ("Next",         obj_desc->addr_handler.next);
-		acpi_ex_out_pointer ("region_list",  obj_desc->addr_handler.region_list);
-		acpi_ex_out_pointer ("Node",         obj_desc->addr_handler.node);
-		acpi_ex_out_pointer ("Context",      obj_desc->addr_handler.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_handler.node);
-		acpi_ex_out_pointer ("Context",      obj_desc->notify_handler.context);
+		acpi_ex_out_pointer ("Node",         obj_desc->notify.node);
+		acpi_ex_out_pointer ("Context",      obj_desc->notify.context);
 		break;
 
 
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
index d7fa0b5d9881e39564fd810c697f32955323b561..1ba86f79b853e73a8abd92a003f49fb57616f753 100644
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -77,7 +77,7 @@ acpi_hw_enable_gpe (
 	 * to enable the GPE, and write out the new register.
 	 */
 	status = acpi_hw_low_level_read (8, &in_byte,
-			  &gpe_event_info->register_info->enable_address, 0);
+			  &gpe_event_info->register_info->enable_address);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -85,7 +85,7 @@ acpi_hw_enable_gpe (
 	/* Write with the new GPE bit enabled */
 
 	status = acpi_hw_low_level_write (8, (in_byte | gpe_event_info->bit_mask),
-			  &gpe_event_info->register_info->enable_address, 0);
+			  &gpe_event_info->register_info->enable_address);
 
 	return (status);
 }
@@ -164,7 +164,7 @@ acpi_hw_disable_gpe (
 	 * and write out the new register value to disable the GPE.
 	 */
 	status = acpi_hw_low_level_read (8, &in_byte,
-			  &gpe_register_info->enable_address, 0);
+			  &gpe_register_info->enable_address);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -172,7 +172,7 @@ acpi_hw_disable_gpe (
 	/* Write the byte with this GPE bit cleared */
 
 	status = acpi_hw_low_level_write (8, (in_byte & ~(gpe_event_info->bit_mask)),
-			  &gpe_register_info->enable_address, 0);
+			  &gpe_register_info->enable_address);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -246,7 +246,7 @@ acpi_hw_clear_gpe (
 	 * clear this GPE.
 	 */
 	status = acpi_hw_low_level_write (8, gpe_event_info->bit_mask,
-			  &gpe_event_info->register_info->status_address, 0);
+			  &gpe_event_info->register_info->status_address);
 
 	return (status);
 }
@@ -293,7 +293,7 @@ acpi_hw_get_gpe_status (
 
 	/* GPE Enabled? */
 
-	status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->enable_address, 0);
+	status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->enable_address);
 	if (ACPI_FAILURE (status)) {
 		goto unlock_and_exit;
 	}
@@ -310,7 +310,7 @@ acpi_hw_get_gpe_status (
 
 	/* GPE active (set)? */
 
-	status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address, 0);
+	status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address);
 	if (ACPI_FAILURE (status)) {
 		goto unlock_and_exit;
 	}
@@ -360,7 +360,7 @@ acpi_hw_disable_gpe_block (
 
 	for (i = 0; i < gpe_block->register_count; i++) {
 		status = acpi_hw_low_level_write (8, 0x00,
-				 &gpe_block->register_info[i].enable_address, (u32) i);
+				 &gpe_block->register_info[i].enable_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -401,7 +401,7 @@ acpi_hw_clear_gpe_block (
 
 	for (i = 0; i < gpe_block->register_count; i++) {
 		status = acpi_hw_low_level_write (8, 0xFF,
-				 &gpe_block->register_info[i].status_address, (u32) i);
+				 &gpe_block->register_info[i].status_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -447,7 +447,7 @@ acpi_hw_disable_non_wakeup_gpe_block (
 		 * will be using it to restore all the GPEs later.
 		 */
 		status = acpi_hw_low_level_read (8, &in_value,
-				 &gpe_register_info->enable_address, 0);
+				 &gpe_register_info->enable_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -458,7 +458,7 @@ acpi_hw_disable_non_wakeup_gpe_block (
 		 * Disable all GPEs except wakeup GPEs.
 		 */
 		status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable,
-				&gpe_register_info->enable_address, 0);
+				&gpe_register_info->enable_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -539,7 +539,7 @@ acpi_hw_enable_non_wakeup_gpe_block (
 		 * Blast them back in.
 		 */
 		status = acpi_hw_low_level_write (8, gpe_register_info->enable,
-				 &gpe_register_info->enable_address, 0);
+				 &gpe_register_info->enable_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index 638c7323f1190f2c88cee061fc1da4226fd8d867..25e05b1384431a2480540707c866514cc57efb01 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -93,7 +93,7 @@ acpi_hw_clear_acpi_status (void)
 
 	if (acpi_gbl_FADT->xpm1b_evt_blk.address) {
 		status = acpi_hw_low_level_write (16, ACPI_BITMASK_ALL_FIXED_STATUS,
-				 &acpi_gbl_FADT->xpm1b_evt_blk, 0);
+				 &acpi_gbl_FADT->xpm1b_evt_blk);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
@@ -470,7 +470,6 @@ acpi_hw_register_read (
 {
 	u32                             value1 = 0;
 	u32                             value2 = 0;
-	u32                             bank_offset;
 	acpi_status                     status;
 
 
@@ -487,50 +486,53 @@ acpi_hw_register_read (
 	switch (register_id) {
 	case ACPI_REGISTER_PM1_STATUS:           /* 16-bit access */
 
-		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk, 0);
+		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk, 0);
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk);
 		value1 |= value2;
 		break;
 
 
-	case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access*/
+	case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access */
 
-		bank_offset = ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len);
-		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk, bank_offset);
+		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_xpm1a_enable);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk, bank_offset);
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_xpm1b_enable);
 		value1 |= value2;
 		break;
 
 
 	case ACPI_REGISTER_PM1_CONTROL:          /* 16-bit access */
 
-		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_cnt_blk, 0);
+		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_cnt_blk);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_cnt_blk, 0);
+		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_cnt_blk);
 		value1 |= value2;
 		break;
 
 
 	case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
 
-		status = acpi_hw_low_level_read (8, &value1, &acpi_gbl_FADT->xpm2_cnt_blk, 0);
+		status = acpi_hw_low_level_read (8, &value1, &acpi_gbl_FADT->xpm2_cnt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
 
-		status = acpi_hw_low_level_read (32, &value1, &acpi_gbl_FADT->xpm_tmr_blk, 0);
+		status = acpi_hw_low_level_read (32, &value1, &acpi_gbl_FADT->xpm_tmr_blk);
 		break;
 
 	case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
@@ -577,7 +579,6 @@ acpi_hw_register_write (
 	u32                             register_id,
 	u32                             value)
 {
-	u32                             bank_offset;
 	acpi_status                     status;
 
 
@@ -594,59 +595,62 @@ acpi_hw_register_write (
 	switch (register_id) {
 	case ACPI_REGISTER_PM1_STATUS:           /* 16-bit access */
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk, 0);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk, 0);
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access*/
 
-		bank_offset = ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len);
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk, bank_offset);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1a_enable);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk, bank_offset);
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1b_enable);
 		break;
 
 
 	case ACPI_REGISTER_PM1_CONTROL:          /* 16-bit access */
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk, 0);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk, 0);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM1A_CONTROL:         /* 16-bit access */
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk, 0);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM1B_CONTROL:         /* 16-bit access */
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk, 0);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
 
-		status = acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->xpm2_cnt_blk, 0);
+		status = acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->xpm2_cnt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
 
-		status = acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->xpm_tmr_blk, 0);
+		status = acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->xpm_tmr_blk);
 		break;
 
 
@@ -676,11 +680,11 @@ acpi_hw_register_write (
  *
  * FUNCTION:    acpi_hw_low_level_read
  *
- * PARAMETERS:  Register            - GAS register structure
- *              Offset              - Offset from the base address in the GAS
- *              Width               - 8, 16, or 32
+ * PARAMETERS:  Width               - 8, 16, or 32
+ *              Value               - Where the value is returned
+ *              Register            - GAS register structure
  *
- * RETURN:      Value read
+ * RETURN:      Status
  *
  * DESCRIPTION: Read from either memory, IO, or PCI config space.
  *
@@ -690,11 +694,8 @@ acpi_status
 acpi_hw_low_level_read (
 	u32                             width,
 	u32                             *value,
-	struct acpi_generic_address     *reg,
-	u32                             offset)
+	struct acpi_generic_address     *reg)
 {
-	acpi_physical_address           mem_address;
-	acpi_io_address                 io_address;
 	struct acpi_pci_id              pci_id;
 	u16                             pci_register;
 	acpi_status                     status;
@@ -721,19 +722,16 @@ acpi_hw_low_level_read (
 	switch (reg->address_space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 
-		mem_address = (reg->address
-				  + (acpi_physical_address) offset);
-
-		status = acpi_os_read_memory (mem_address, value, width);
+		status = acpi_os_read_memory (
+				 (acpi_physical_address) reg->address,
+				 value, width);
 		break;
 
 
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
-		io_address = (acpi_io_address) (reg->address
-				   + (acpi_physical_address) offset);
-
-		status = acpi_os_read_port (io_address, value, width);
+		status = acpi_os_read_port ((acpi_io_address) reg->address,
+				 value, width);
 		break;
 
 
@@ -743,15 +741,16 @@ acpi_hw_low_level_read (
 		pci_id.bus     = 0;
 		pci_id.device  = ACPI_PCI_DEVICE (reg->address);
 		pci_id.function = ACPI_PCI_FUNCTION (reg->address);
-		pci_register   = (u16) (ACPI_PCI_REGISTER (reg->address)
-				  + offset);
+		pci_register   = (u16) ACPI_PCI_REGISTER (reg->address);
 
-		status = acpi_os_read_pci_configuration (&pci_id, pci_register, value, width);
+		status = acpi_os_read_pci_configuration (&pci_id, pci_register,
+				 value, width);
 		break;
 
 
 	default:
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", reg->address_space_id));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unsupported address space: %X\n", reg->address_space_id));
 		status = AE_BAD_PARAMETER;
 		break;
 	}
@@ -767,12 +766,10 @@ acpi_hw_low_level_read (
  * PARAMETERS:  Width               - 8, 16, or 32
  *              Value               - To be written
  *              Register            - GAS register structure
- *              Offset              - Offset from the base address in the GAS
- *
  *
- * RETURN:      Value read
+ * RETURN:      Status
  *
- * DESCRIPTION: Read from either memory, IO, or PCI config space.
+ * DESCRIPTION: Write to either memory, IO, or PCI config space.
  *
  ******************************************************************************/
 
@@ -780,11 +777,8 @@ acpi_status
 acpi_hw_low_level_write (
 	u32                             width,
 	u32                             value,
-	struct acpi_generic_address     *reg,
-	u32                             offset)
+	struct acpi_generic_address     *reg)
 {
-	acpi_physical_address           mem_address;
-	acpi_io_address                 io_address;
 	struct acpi_pci_id              pci_id;
 	u16                             pci_register;
 	acpi_status                     status;
@@ -809,19 +803,16 @@ acpi_hw_low_level_write (
 	switch (reg->address_space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 
-		mem_address = (reg->address
-				  + (acpi_physical_address) offset);
-
-		status = acpi_os_write_memory (mem_address, value, width);
+		status = acpi_os_write_memory (
+				 (acpi_physical_address) reg->address,
+				 value, width);
 		break;
 
 
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
-		io_address = (acpi_io_address) (reg->address
-				   + (acpi_physical_address) offset);
-
-		status = acpi_os_write_port (io_address, value, width);
+		status = acpi_os_write_port ((acpi_io_address) reg->address,
+				 value, width);
 		break;
 
 
@@ -831,15 +822,16 @@ acpi_hw_low_level_write (
 		pci_id.bus     = 0;
 		pci_id.device  = ACPI_PCI_DEVICE (reg->address);
 		pci_id.function = ACPI_PCI_FUNCTION (reg->address);
-		pci_register   = (u16) (ACPI_PCI_REGISTER (reg->address)
-				  + offset);
+		pci_register   = (u16) ACPI_PCI_REGISTER (reg->address);
 
-		status = acpi_os_write_pci_configuration (&pci_id, pci_register, (acpi_integer) value, width);
+		status = acpi_os_write_pci_configuration (&pci_id, pci_register,
+				 (acpi_integer) value, width);
 		break;
 
 
 	default:
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", reg->address_space_id));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unsupported address space: %X\n", reg->address_space_id));
 		status = AE_BAD_PARAMETER;
 		break;
 	}
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
index b8053a1d8193d112198a361d5bc6b2431e396bab..897dd6db98d9e27a30a68cb52c3e5dd81429bb5e 100644
--- a/drivers/acpi/hardware/hwtimer.c
+++ b/drivers/acpi/hardware/hwtimer.c
@@ -108,7 +108,7 @@ acpi_get_timer (
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	status = acpi_hw_low_level_read (32, ticks, &acpi_gbl_FADT->xpm_tmr_blk, 0);
+	status = acpi_hw_low_level_read (32, ticks, &acpi_gbl_FADT->xpm_tmr_blk);
 
 	return_ACPI_STATUS (status);
 }
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index c412245e848a02648c52a26dd08e8672e9fd540d..37ab3e0cbb8a3d835c3b949365065ff20fd86b2a 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -116,19 +116,33 @@ acpi_ns_delete_node (
 	prev_node = NULL;
 	next_node = parent_node->child;
 
+	/* Find the node that is the previous peer in the parent's child list */
+
 	while (next_node != node) {
 		prev_node = next_node;
 		next_node = prev_node->peer;
 	}
 
 	if (prev_node) {
+		/* Node is not first child, unlink it */
+
 		prev_node->peer = next_node->peer;
 		if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
 			prev_node->flags |= ANOBJ_END_OF_PEER_LIST;
 		}
 	}
 	else {
-		parent_node->child = next_node->peer;
+		/* Node is first child (has no previous peer) */
+
+		if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
+			/* No peers at all */
+
+			parent_node->child = NULL;
+		}
+		else {   /* Link peer list to parent */
+
+			parent_node->child = next_node->peer;
+		}
 	}
 
 
@@ -222,7 +236,7 @@ acpi_ns_install_node (
 	struct acpi_namespace_node      *node,          /* New Child*/
 	acpi_object_type                type)
 {
-	u16                             owner_id = TABLE_ID_DSDT;
+	u16                             owner_id = 0;
 	struct acpi_namespace_node      *child_node;
 #ifdef ACPI_ALPHABETIC_NAMESPACE
 
@@ -355,6 +369,7 @@ acpi_ns_delete_children (
 {
 	struct acpi_namespace_node      *child_node;
 	struct acpi_namespace_node      *next_node;
+	struct acpi_namespace_node      *node;
 	u8                              flags;
 
 
@@ -399,6 +414,25 @@ acpi_ns_delete_children (
 		 * Detach an object if there is one, then free the child node
 		 */
 		acpi_ns_detach_object (child_node);
+
+		/*
+		 * Decrement the reference count(s) of all parents up to
+		 * the root! (counts were incremented when the node was created)
+		 */
+		node = child_node;
+		while ((node = acpi_ns_get_parent_node (node)) != NULL) {
+			node->reference_count--;
+		}
+
+		/* There should be only one reference remaining on this node */
+
+		if (child_node->reference_count != 1) {
+			ACPI_REPORT_WARNING (("Existing references (%d) on node being deleted (%p)\n",
+				child_node->reference_count, child_node));
+		}
+
+		/* Now we can delete the node */
+
 		ACPI_MEM_FREE (child_node);
 
 		/* And move on to the next child in the list */
@@ -512,7 +546,7 @@ acpi_ns_delete_namespace_subtree (
  *
  ******************************************************************************/
 
-static void
+void
 acpi_ns_remove_reference (
 	struct acpi_namespace_node      *node)
 {
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c
index af4bdd41e5ccd5f74180e114c37319823c55fa39..6abbd09197dd3e5e25b8dc49307351e552918193 100644
--- a/drivers/acpi/namespace/nsdumpdv.c
+++ b/drivers/acpi/namespace/nsdumpdv.c
@@ -72,7 +72,8 @@ acpi_ns_dump_one_device (
 	void                            *context,
 	void                            **return_value)
 {
-	struct acpi_device_info         info;
+	struct acpi_buffer              buffer;
+	struct acpi_device_info         *info;
 	acpi_status                     status;
 	u32                             i;
 
@@ -82,16 +83,19 @@ acpi_ns_dump_one_device (
 
 	status = acpi_ns_dump_one_object (obj_handle, level, context, return_value);
 
-	status = acpi_get_object_info (obj_handle, &info);
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	status = acpi_get_object_info (obj_handle, &buffer);
 	if (ACPI_SUCCESS (status)) {
+		info = buffer.pointer;
 		for (i = 0; i < level; i++) {
 			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,
-				  ACPI_HIDWORD (info.address), ACPI_LODWORD (info.address),
-				  info.current_status));
+				  info->hardware_id.value,
+				  ACPI_HIDWORD (info->address), ACPI_LODWORD (info->address),
+				  info->current_status));
+		ACPI_MEM_FREE (info);
 	}
 
 	return (status);
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
index 8cb42fefda19b7c8131de580e5a8151e8d8f8799..1eac324e601c70b65755e607bf9d96302a4808e5 100644
--- a/drivers/acpi/namespace/nsload.c
+++ b/drivers/acpi/namespace/nsload.c
@@ -79,7 +79,7 @@ acpi_ns_load_table (
 
 	/* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */
 
-	if (!(acpi_gbl_acpi_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) {
+	if (!(acpi_gbl_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) {
 		/* Just ignore this table */
 
 		return_ACPI_STATUS (AE_OK);
@@ -182,7 +182,7 @@ acpi_ns_load_table_by_type (
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading DSDT\n"));
 
-		table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_DSDT];
+		table_desc = acpi_gbl_table_lists[ACPI_TABLE_DSDT].next;
 
 		/* If table already loaded into namespace, just return */
 
@@ -190,8 +190,6 @@ acpi_ns_load_table_by_type (
 			goto unlock_and_exit;
 		}
 
-		table_desc->table_id = TABLE_ID_DSDT;
-
 		/* Now load the single DSDT */
 
 		status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
@@ -205,13 +203,13 @@ acpi_ns_load_table_by_type (
 	case ACPI_TABLE_SSDT:
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d SSDTs\n",
-			acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count));
+			acpi_gbl_table_lists[ACPI_TABLE_SSDT].count));
 
 		/*
 		 * Traverse list of SSDT tables
 		 */
-		table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_SSDT];
-		for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count; i++) {
+		table_desc = acpi_gbl_table_lists[ACPI_TABLE_SSDT].next;
+		for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_SSDT].count; i++) {
 			/*
 			 * Only attempt to load table if it is not
 			 * already loaded!
@@ -233,14 +231,14 @@ acpi_ns_load_table_by_type (
 	case ACPI_TABLE_PSDT:
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d PSDTs\n",
-			acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count));
+			acpi_gbl_table_lists[ACPI_TABLE_PSDT].count));
 
 		/*
 		 * Traverse list of PSDT tables
 		 */
-		table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_PSDT];
+		table_desc = acpi_gbl_table_lists[ACPI_TABLE_PSDT].next;
 
-		for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count; i++) {
+		for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_PSDT].count; i++) {
 			/* Only attempt to load table if it is not already loaded! */
 
 			if (!table_desc->loaded_into_namespace) {
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
index 3d75e08a2d0926fb9ef414b6301aff784727b518..0ba6651976c1f9ed624abc3bed595bc6df1751a1 100644
--- a/drivers/acpi/namespace/nsparse.c
+++ b/drivers/acpi/namespace/nsparse.c
@@ -85,10 +85,9 @@ acpi_ns_one_complete_parse (
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
-
 	/* Create and initialize a new walk state */
 
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT,
+	walk_state = acpi_ds_create_walk_state (table_desc->table_id,
 			   NULL, NULL, NULL);
 	if (!walk_state) {
 		acpi_ps_free_op (parse_root);
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index 10fe6e8f5aedde2bcbfcc9acf38ce03df18a1fba..ba116b7900ec7aec1b9d590ee1cea8d7ad6c8e46 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -117,8 +117,9 @@ acpi_ns_search_node (
 			 * Found matching entry.
 			 */
 			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
-				"Name %4.4s Type [%s] found at %p\n",
-				(char *) &target_name, acpi_ut_get_type_name (next_node->type), next_node));
+				"Name %4.4s Type [%s] found in scope [%4.4s] %p\n",
+				(char *) &target_name, acpi_ut_get_type_name (next_node->type),
+				next_node->name.ascii, next_node));
 
 			*return_node = next_node;
 			return_ACPI_STATUS (AE_OK);
@@ -141,8 +142,10 @@ acpi_ns_search_node (
 
 	/* Searched entire namespace level, not found */
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Name %4.4s Type [%s] not found at %p\n",
-		(char *) &target_name, acpi_ut_get_type_name (type), next_node));
+	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+		"Name %4.4s Type [%s] not found in search in scope [%4.4s] %p first child %p\n",
+		(char *) &target_name, acpi_ut_get_type_name (type),
+		node->name.ascii, node, node->child));
 
 	return_ACPI_STATUS (AE_NOT_FOUND);
 }
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index 321dcbc0484f38ce270212da647f7a1871480024..12d6087c48cd8e614b433aba4944a3fff4c5cc99 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -181,7 +181,11 @@ acpi_ns_print_node_pathname (
 
 	status = acpi_ns_handle_to_pathname (node, &buffer);
 	if (ACPI_SUCCESS (status)) {
-		acpi_os_printf ("%s [%s] (Node %p)", msg, (char *) buffer.pointer, node);
+		if (msg) {
+			acpi_os_printf ("%s ", msg);
+		}
+
+		acpi_os_printf ("[%s] (Node %p)", (char *) buffer.pointer, node);
 		ACPI_MEM_FREE (buffer.pointer);
 	}
 }
@@ -799,38 +803,31 @@ void
 acpi_ns_terminate (void)
 {
 	union acpi_operand_object       *obj_desc;
-	struct acpi_namespace_node      *this_node;
 
 
 	ACPI_FUNCTION_TRACE ("ns_terminate");
 
 
-	this_node = acpi_gbl_root_node;
-
 	/*
-	 * 1) Free the entire namespace -- all objects, tables, and stacks
+	 * 1) Free the entire namespace -- all nodes and objects
 	 *
-	 * Delete all objects linked to the root
-	 * (additional table descriptors)
+	 * Delete all object descriptors attached to namepsace nodes
 	 */
-	acpi_ns_delete_namespace_subtree (this_node);
+	acpi_ns_delete_namespace_subtree (acpi_gbl_root_node);
 
-	/* Detach any object(s) attached to the root */
+	/* Detach any objects attached to the root */
 
-	obj_desc = acpi_ns_get_attached_object (this_node);
+	obj_desc = acpi_ns_get_attached_object (acpi_gbl_root_node);
 	if (obj_desc) {
-		acpi_ns_detach_object (this_node);
-		acpi_ut_remove_reference (obj_desc);
+		acpi_ns_detach_object (acpi_gbl_root_node);
 	}
 
-	acpi_ns_delete_children (this_node);
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
 
-
 	/*
 	 * 2) Now we can delete the ACPI tables
 	 */
-	acpi_tb_delete_acpi_tables ();
+	acpi_tb_delete_all_tables ();
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
 
 	return_VOID;
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index 584c76aed5239d2480ea11eb58799adde3a1826a..6706d7b42c4524c59099ebd129711c680fb8cb6a 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -437,16 +437,15 @@ acpi_ns_get_device_callback (
 	void                            *context,
 	void                            **return_value)
 {
+	struct acpi_get_devices_info    *info = context;
 	acpi_status                     status;
 	struct acpi_namespace_node      *node;
 	u32                             flags;
 	struct acpi_device_id           hid;
-	struct acpi_device_id           cid;
-	struct acpi_get_devices_info    *info;
+	struct acpi_compatible_id_list *cid;
+	acpi_native_uint                i;
 
 
-	info = context;
-
 	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE (status)) {
 		return (status);
@@ -462,9 +461,8 @@ acpi_ns_get_device_callback (
 		return (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Run _STA to determine if device is present
-	 */
+	/* Run _STA to determine if device is present */
+
 	status = acpi_ut_execute_STA (node, &flags);
 	if (ACPI_FAILURE (status)) {
 		return (AE_CTRL_DEPTH);
@@ -472,12 +470,12 @@ acpi_ns_get_device_callback (
 
 	if (!(flags & 0x01)) {
 		/* Don't return at the device or children of the device if not there */
+
 		return (AE_CTRL_DEPTH);
 	}
 
-	/*
-	 * Filter based on device HID & CID
-	 */
+	/* Filter based on device HID & CID */
+
 	if (info->hid != NULL) {
 		status = acpi_ut_execute_HID (node, &hid);
 		if (status == AE_NOT_FOUND) {
@@ -487,7 +485,9 @@ acpi_ns_get_device_callback (
 			return (AE_CTRL_DEPTH);
 		}
 
-		if (ACPI_STRNCMP (hid.buffer, info->hid, sizeof (hid.buffer)) != 0) {
+		if (ACPI_STRNCMP (hid.value, info->hid, sizeof (hid.value)) != 0) {
+			/* Get the list of Compatible IDs */
+
 			status = acpi_ut_execute_CID (node, &cid);
 			if (status == AE_NOT_FOUND) {
 				return (AE_OK);
@@ -496,11 +496,16 @@ acpi_ns_get_device_callback (
 				return (AE_CTRL_DEPTH);
 			}
 
-			/* TBD: Handle CID packages */
+			/* Walk the CID list */
 
-			if (ACPI_STRNCMP (cid.buffer, info->hid, sizeof (cid.buffer)) != 0) {
-				return (AE_OK);
+			for (i = 0; i < cid->count; i++) {
+				if (ACPI_STRNCMP (cid->id[i].value, info->hid,
+						 sizeof (struct acpi_compatible_id)) != 0) {
+					ACPI_MEM_FREE (cid);
+					return (AE_OK);
+				}
 			}
+			ACPI_MEM_FREE (cid);
 		}
 	}
 
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index 5c146c96bb3cba142a1bc99e4a15a2bf1e0b24eb..362efe49fde816c344bc46f6d40617ca5e3ce556 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -51,7 +51,7 @@
 	 ACPI_MODULE_NAME    ("nsxfname")
 
 
-/****************************************************************************
+/******************************************************************************
  *
  * FUNCTION:    acpi_get_handle
  *
@@ -119,7 +119,8 @@ acpi_get_handle (
 	/*
 	 *  Find the Node and convert to a handle
 	 */
-	status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH, &node);
+	status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH,
+			  &node);
 
 	*ret_handle = NULL;
 	if (ACPI_SUCCESS (status)) {
@@ -130,7 +131,7 @@ acpi_get_handle (
 }
 
 
-/****************************************************************************
+/******************************************************************************
  *
  * FUNCTION:    acpi_get_name
  *
@@ -211,7 +212,7 @@ acpi_get_name (
 }
 
 
-/****************************************************************************
+/******************************************************************************
  *
  * FUNCTION:    acpi_get_object_info
  *
@@ -229,22 +230,27 @@ acpi_get_name (
 acpi_status
 acpi_get_object_info (
 	acpi_handle                     handle,
-	struct acpi_device_info         *info)
+	struct acpi_buffer              *buffer)
 {
-	struct acpi_device_id           hid;
-	struct acpi_device_id           uid;
 	acpi_status                     status;
-	u32                             device_status = 0;
-	acpi_integer                    address = 0;
 	struct acpi_namespace_node      *node;
+	struct acpi_device_info         info;
+	struct acpi_device_info         *return_info;
+	struct acpi_compatible_id_list *cid_list = NULL;
+	acpi_size                       size;
 
 
 	/* Parameter validation */
 
-	if (!handle || !info) {
+	if (!handle || !buffer) {
 		return (AE_BAD_PARAMETER);
 	}
 
+	status = acpi_ut_validate_buffer (buffer);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE (status)) {
 		return (status);
@@ -256,69 +262,94 @@ acpi_get_object_info (
 		return (AE_BAD_PARAMETER);
 	}
 
-	info->type = node->type;
-	info->name = node->name.integer;
+	/* Init return structure */
+
+	size = sizeof (struct acpi_device_info);
+	ACPI_MEMSET (&info, 0, size);
+
+	info.type  = node->type;
+	info.name  = node->name.integer;
+	info.valid = 0;
 
 	status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
 
-	/*
-	 * If not a device, we are all done.
-	 */
-	if (info->type != ACPI_TYPE_DEVICE) {
-		return (AE_OK);
-	}
+	/* If not a device, we are all done */
 
+	if (info.type == ACPI_TYPE_DEVICE) {
+		/*
+		 * Get extra info for ACPI Devices objects only:
+		 * Run the Device _HID, _UID, _CID, _STA, and _ADR methods.
+		 *
+		 * Note: none of these methods are required, so they may or may
+		 * not be present for this device.  The Info.Valid bitfield is used
+		 * to indicate which methods were found and ran successfully.
+		 */
 
-	/*
-	 * Get extra info for ACPI devices only.  Run the
-	 * _HID, _UID, _STA, and _ADR methods.  Note: none
-	 * of these methods are required, so they may or may
-	 * not be present.  The Info->Valid bits are used
-	 * to indicate which methods ran successfully.
-	 */
-	info->valid = 0;
+		/* Execute the Device._HID method */
 
-	/* Execute the _HID method and save the result */
+		status = acpi_ut_execute_HID (node, &info.hardware_id);
+		if (ACPI_SUCCESS (status)) {
+			info.valid |= ACPI_VALID_HID;
+		}
 
-	status = acpi_ut_execute_HID (node, &hid);
-	if (ACPI_SUCCESS (status)) {
-		ACPI_STRNCPY (info->hardware_id, hid.buffer, sizeof(info->hardware_id));
-		info->valid |= ACPI_VALID_HID;
-	}
+		/* Execute the Device._UID method */
 
-	/* Execute the _UID method and save the result */
+		status = acpi_ut_execute_UID (node, &info.unique_id);
+		if (ACPI_SUCCESS (status)) {
+			info.valid |= ACPI_VALID_UID;
+		}
 
-	status = acpi_ut_execute_UID (node, &uid);
-	if (ACPI_SUCCESS (status)) {
-		ACPI_STRCPY (info->unique_id, uid.buffer);
-		info->valid |= ACPI_VALID_UID;
+		/* Execute the Device._CID method */
+
+		status = acpi_ut_execute_CID (node, &cid_list);
+		if (ACPI_SUCCESS (status)) {
+			size += ((acpi_size) cid_list->count - 1) *
+					 sizeof (struct acpi_compatible_id);
+			info.valid |= ACPI_VALID_CID;
+		}
+
+		/* Execute the Device._STA method */
+
+		status = acpi_ut_execute_STA (node, &info.current_status);
+		if (ACPI_SUCCESS (status)) {
+			info.valid |= ACPI_VALID_STA;
+		}
+
+		/* Execute the Device._ADR method */
+
+		status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node,
+				  &info.address);
+		if (ACPI_SUCCESS (status)) {
+			info.valid |= ACPI_VALID_ADR;
+		}
+
+		status = AE_OK;
 	}
 
-	/*
-	 * Execute the _STA method and save the result
-	 * _STA is not always present
-	 */
-	status = acpi_ut_execute_STA (node, &device_status);
-	if (ACPI_SUCCESS (status)) {
-		info->current_status = device_status;
-		info->valid |= ACPI_VALID_STA;
+	/* Validate/Allocate/Clear caller buffer */
+
+	status = acpi_ut_initialize_buffer (buffer, size);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
 	}
 
-	/*
-	 * Execute the _ADR method and save result if successful
-	 * _ADR is not always present
-	 */
-	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR,
-			  node, &address);
+	/* Populate the return buffer */
 
-	if (ACPI_SUCCESS (status)) {
-		info->address = address;
-		info->valid |= ACPI_VALID_ADR;
+	return_info = buffer->pointer;
+	ACPI_MEMCPY (return_info, &info, sizeof (struct acpi_device_info));
+
+	if (cid_list) {
+		ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size);
 	}
 
-	return (AE_OK);
+
+cleanup:
+	if (cid_list) {
+		ACPI_MEM_FREE (cid_list);
+	}
+	return (status);
 }
 
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index c78ea7e34bb6f2bab70f5bd507418535ad684540..997b6cb20cf079b41f3a89332906950dd3f5f6b5 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -237,7 +237,7 @@ acpi_os_table_override (struct acpi_table_header *existing_table,
 static irqreturn_t
 acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
-	return (*acpi_irq_handler)(acpi_irq_context);
+	return (*acpi_irq_handler)(acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE;
 }
 
 acpi_status
@@ -1006,7 +1006,7 @@ acpi_os_name_setup(char *str)
 		return 0;
 
 	for (; count-- && str && *str; str++) {
-		if (isalnum(*str) || *str == ' ')
+		if (isalnum(*str) || *str == ' ' || *str == ':')
 			*p++ = *str;
 		else if (*str == '\'' || *str == '"')
 			continue;
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index 2f79d963eddbf1d5a934525ad7323e10fa82ce8e..d0e8cc6acd8e8f42374aa93b050327080889da9d 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -350,6 +350,11 @@ acpi_ps_get_next_namepath (
 
 				(status != AE_NOT_FOUND)) {
 				ACPI_REPORT_NSERROR (path, status);
+
+				acpi_os_printf ("search_node %p start_node %p return_node %p\n",
+					scope_info.scope.node, parser_state->start_node, node);
+
+
 			}
 			else {
 				/*
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
index f2a92dc2e3cf7262977aa61104a32e0fa60b9b32..43f8547a991d88d021c744f8bb1f05b60a9e7f48 100644
--- a/drivers/acpi/parser/pswalk.c
+++ b/drivers/acpi/parser/pswalk.c
@@ -270,7 +270,7 @@ acpi_ps_delete_parse_tree (
 		return_VOID;
 	}
 
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, thread);
+	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, thread);
 	if (!walk_state) {
 		return_VOID;
 	}
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index bc2ce6b17c05386bf3d5886f06996a930a308fa9..1e0602883641917ea0e038daff8f3ee8ca8e7d36 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -178,7 +178,7 @@ acpi_psx_execute (
 
 	/* Create and initialize a new walk state */
 
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL);
+	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
 	if (!walk_state) {
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
index 63fd9ac1df7ab6c19d627117a4fe4d8c46d66120..cb2d60ea35c6336c7bbc2c356f00d8d2074343e4 100644
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -379,25 +379,31 @@ acpi_resource_to_address64 (
 {
 	struct acpi_resource_address16      *address16;
 	struct acpi_resource_address32      *address32;
-	struct acpi_resource_address64      *address64;
 
 
 	switch (resource->id) {
 	case ACPI_RSTYPE_ADDRESS16:
+
 		address16 = (struct acpi_resource_address16 *) &resource->data;
 		ACPI_COPY_ADDRESS(out, address16);
 		break;
 
+
 	case ACPI_RSTYPE_ADDRESS32:
+
 		address32 = (struct acpi_resource_address32 *) &resource->data;
 		ACPI_COPY_ADDRESS(out, address32);
 		break;
 
+
 	case ACPI_RSTYPE_ADDRESS64:
-		address64 = (struct acpi_resource_address64 *) &resource->data;
-		ACPI_COPY_ADDRESS(out, address64);
+
+		/* Simple copy for 64 bit source */
+
+		ACPI_MEMCPY (out, &resource->data, sizeof (struct acpi_resource_address64));
 		break;
 
+
 	default:
 		return (AE_BAD_PARAMETER);
 	}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index fa930325c8282e0a914828e3040379ebccf39ed0..ec8313fa549a4ac3295ca20280b3b220897161b0 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -28,6 +28,8 @@ static spinlock_t acpi_device_lock = SPIN_LOCK_UNLOCKED;
 static void acpi_device_release(struct kobject * kobj)
 {
 	struct acpi_device * dev = container_of(kobj,struct acpi_device,kobj);
+	if (dev->pnp.cid_list)
+		kfree(dev->pnp.cid_list);
 	kfree(dev);
 }
 
@@ -69,7 +71,7 @@ static void acpi_device_register(struct acpi_device * device, struct acpi_device
 		device->kobj.parent = &parent->kobj;
 	device->kobj.ktype = &ktype_acpi_ns;
 	device->kobj.kset = &acpi_namespace_kset;
-	kobject_register(&device->kobj);
+	kobject_add(&device->kobj);
 }
 
 static int
@@ -201,32 +203,15 @@ acpi_bus_match (
 			goto Done;
 
 	if (device->flags.compatible_ids) {
-		acpi_status		status = AE_OK;
-		union acpi_object	*object = NULL;
-		char			cid[256] = {};
+		struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
+		int i;
 
-		status = acpi_evaluate_object(device->handle, "_CID", NULL, 
-			&buffer);
-		if (ACPI_FAILURE(status) || !buffer.pointer)
-			return -ENOENT;
-
-		object = (union acpi_object *) buffer.pointer;
-
-		switch (object->type) {
-		case ACPI_TYPE_INTEGER:
-			acpi_ex_eisa_id_to_string((u32) object->integer.value, 
-				cid);
-			break;
-		case ACPI_TYPE_STRING:
-			strncpy(cid, object->string.pointer, sizeof(cid) - 1);
-			break;
-		case ACPI_TYPE_PACKAGE:
-			/* TBD: Support CID packages */
-			break;
+		/* compare multiple _CID entries against driver ids */
+		for (i = 0; i < cid_list->count; i++)
+		{
+			if (strstr(driver->ids, cid_list->id[i].value))
+				goto Done;
 		}
-
-		if (strlen(cid) && strstr(driver->ids,cid))
-			goto Done;
 	}
 	error = -ENOENT;
 
@@ -523,27 +508,30 @@ static void acpi_device_get_busid(struct acpi_device * device, acpi_handle handl
 static void acpi_device_set_id(struct acpi_device * device, struct acpi_device * parent,
 			       acpi_handle handle, int type)
 {
-	struct acpi_device_info	info;
+	struct acpi_device_info	*info;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
 	char			*hid = NULL;
 	char			*uid = NULL;
+	struct acpi_compatible_id_list *cid_list = NULL;
 	acpi_status		status;
 
 	switch (type) {
 	case ACPI_BUS_TYPE_DEVICE:
-		status = acpi_get_object_info(handle, &info);
+		status = acpi_get_object_info(handle, &buffer);
 		if (ACPI_FAILURE(status)) {
 			printk("%s: Error reading device info\n",__FUNCTION__);
 			return;
 		}
-		/* Clean up info strings (not NULL terminated) */
-		info.hardware_id[sizeof(info.hardware_id)-1] = '\0';
-		info.unique_id[sizeof(info.unique_id)-1] = '\0';
-		if (info.valid & ACPI_VALID_HID)
-			hid = info.hardware_id;
-		if (info.valid & ACPI_VALID_UID)
-			uid = info.unique_id;
-		if (info.valid & ACPI_VALID_ADR) {
-			device->pnp.bus_address = info.address;
+
+		info = buffer.pointer;
+		if (info->valid & ACPI_VALID_HID)
+			hid = info->hardware_id.value;
+		if (info->valid & ACPI_VALID_UID)
+			uid = info->unique_id.value;
+		if (info->valid & ACPI_VALID_CID)
+			cid_list = &info->compatibility_id;
+		if (info->valid & ACPI_VALID_ADR) {
+			device->pnp.bus_address = info->address;
 			device->flags.bus_address = 1;
 		}
 		break;
@@ -586,6 +574,15 @@ static void acpi_device_set_id(struct acpi_device * device, struct acpi_device *
 		sprintf(device->pnp.unique_id, "%s", uid);
 		device->flags.unique_id = 1;
 	}
+	if (cid_list) {
+		device->pnp.cid_list = kmalloc(cid_list->size, GFP_KERNEL);
+		if (device->pnp.cid_list)
+			memcpy(device->pnp.cid_list, cid_list, cid_list->size);
+		else
+			printk(KERN_ERR "Memory allocation error\n");
+	}
+
+	acpi_os_free(buffer.pointer);
 }
 
 int acpi_device_set_context(struct acpi_device * device, int type)
@@ -781,8 +778,12 @@ acpi_bus_add (
 end:
 	if (!result)
 		*child = device;
-	else
+	else {
+		if (device->pnp.cid_list)
+			kfree(device->pnp.cid_list);
 		kfree(device);
+	}
+
 	return_VALUE(result);
 }
 
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
index ae9f5977f0d01cda675632cb64d3d7f66de280d3..4b412360e417a03c3f861d65c9cc4e9d59f80225 100644
--- a/drivers/acpi/tables/tbconvrt.c
+++ b/drivers/acpi/tables/tbconvrt.c
@@ -164,6 +164,36 @@ acpi_tb_convert_to_xsdt (
 }
 
 
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_init_generic_address
+ *
+ * PARAMETERS:  new_gas_struct      - GAS struct to be initialized
+ *              register_bit_width  - Width of this register
+ *              Address             - Address of the register
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Initialize a GAS structure.
+ *
+ ******************************************************************************/
+
+static void
+acpi_tb_init_generic_address (
+	struct acpi_generic_address     *new_gas_struct,
+	u8                              register_bit_width,
+	acpi_physical_address           address)
+{
+
+	ACPI_STORE_ADDRESS (new_gas_struct->address, address);
+
+	new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
+	new_gas_struct->register_bit_width = register_bit_width;
+	new_gas_struct->register_bit_offset = 0;
+	new_gas_struct->reserved        = 0;
+}
+
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_convert_fadt1
@@ -233,14 +263,34 @@ acpi_tb_convert_fadt1 (
 	/*
 	 * Convert the V1.0 block addresses to V2.0 GAS structures
 	 */
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len, local_fadt->V1_pm1a_evt_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len, local_fadt->V1_pm1b_evt_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len, local_fadt->V1_pm1a_cnt_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len, local_fadt->V1_pm1b_cnt_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len, local_fadt->V1_pm2_cnt_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len, local_fadt->V1_pm_tmr_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk,  0,                     local_fadt->V1_gpe0_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk,  0,                     local_fadt->V1_gpe1_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1a_evt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1b_evt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1a_cnt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1b_cnt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm2_cnt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len,
+			  (acpi_physical_address)   local_fadt->V1_pm_tmr_blk);
+	acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, 0,
+			  (acpi_physical_address)   local_fadt->V1_gpe0_blk);
+	acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, 0,
+			  (acpi_physical_address)   local_fadt->V1_gpe1_blk);
+
+	/* Create separate GAS structs for the PM1 Enable registers */
+
+	acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
+		 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+		 (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
+			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+
+	acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
+		 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+		 (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
 }
 
 
@@ -282,44 +332,58 @@ acpi_tb_convert_fadt2 (
 	}
 
 	if (!(local_fadt->xpm1a_evt_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_evt_blk,
-			local_fadt->pm1_evt_len, local_fadt->V1_pm1a_evt_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk,
+			local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
 	}
 
 	if (!(local_fadt->xpm1b_evt_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_evt_blk,
-			local_fadt->pm1_evt_len, local_fadt->V1_pm1b_evt_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk,
+			local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
 	}
 
 	if (!(local_fadt->xpm1a_cnt_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_cnt_blk,
-			local_fadt->pm1_cnt_len, local_fadt->V1_pm1a_cnt_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk,
+			local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
 	}
 
 	if (!(local_fadt->xpm1b_cnt_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_cnt_blk,
-			local_fadt->pm1_cnt_len, local_fadt->V1_pm1b_cnt_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk,
+			local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
 	}
 
 	if (!(local_fadt->xpm2_cnt_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm2_cnt_blk,
-			local_fadt->pm2_cnt_len, local_fadt->V1_pm2_cnt_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk,
+			local_fadt->pm2_cnt_len, (acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
 	}
 
 	if (!(local_fadt->xpm_tmr_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm_tmr_blk,
-			local_fadt->pm_tm_len, local_fadt->V1_pm_tmr_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk,
+			local_fadt->pm_tm_len, (acpi_physical_address) local_fadt->V1_pm_tmr_blk);
 	}
 
 	if (!(local_fadt->xgpe0_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk,
-			0, local_fadt->V1_gpe0_blk);
+		acpi_tb_init_generic_address (&local_fadt->xgpe0_blk,
+			0, (acpi_physical_address) local_fadt->V1_gpe0_blk);
 	}
 
 	if (!(local_fadt->xgpe1_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk,
-			0, local_fadt->V1_gpe1_blk);
+		acpi_tb_init_generic_address (&local_fadt->xgpe1_blk,
+			0, (acpi_physical_address) local_fadt->V1_gpe1_blk);
 	}
+
+	/* Create separate GAS structs for the PM1 Enable registers */
+
+	acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
+		(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+		(acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
+			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+	acpi_gbl_xpm1a_enable.address_space_id = local_fadt->xpm1a_evt_blk.address_space_id;
+
+	acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
+		(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+		(acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+	acpi_gbl_xpm1b_enable.address_space_id = local_fadt->xpm1b_evt_blk.address_space_id;
 }
 
 
@@ -396,7 +460,7 @@ acpi_tb_convert_table_fadt (void)
 
 	/* Free the original table */
 
-	table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_FADT];
+	table_desc = acpi_gbl_table_lists[ACPI_TABLE_FADT].next;
 	acpi_tb_delete_single_table (table_desc);
 
 	/* Install the new table */
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
index 91ed931eb2f1dae02aa341ad55229af452153184..65e696cf145eeea32fee479cf36b92aa45ce31dd 100644
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -456,18 +456,18 @@ acpi_tb_get_table_ptr (
 	 * instance is always in the list head.
 	 */
 	if (instance == 1) {
-		/*
-		 * Just pluck the pointer out of the global table!
-		 * Will be null if no table is present
-		 */
-		*table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer;
+		/* Get the first */
+
+		if (acpi_gbl_table_lists[table_type].next) {
+			*table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer;
+		}
 		return_ACPI_STATUS (AE_OK);
 	}
 
 	/*
 	 * Check for instance out of range
 	 */
-	if (instance > acpi_gbl_acpi_tables[table_type].count) {
+	if (instance > acpi_gbl_table_lists[table_type].count) {
 		return_ACPI_STATUS (AE_NOT_EXIST);
 	}
 
@@ -478,7 +478,7 @@ acpi_tb_get_table_ptr (
 	 * need to walk from the 2nd table until we reach the Instance
 	 * that the user is looking for and return its table pointer.
 	 */
-	table_desc = acpi_gbl_acpi_tables[table_type].next;
+	table_desc = acpi_gbl_table_lists[table_type].next;
 	for (i = 2; i < instance; i++) {
 		table_desc = table_desc->next;
 	}
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c
index 8c3f44ad4f6816b86beccfc2f45528eab785d1a6..48381c0dcbfec77d96f4e16070fee74cfbe5ff25 100644
--- a/drivers/acpi/tables/tbgetall.c
+++ b/drivers/acpi/tables/tbgetall.c
@@ -307,7 +307,7 @@ acpi_tb_get_required_tables (
 
 	/* Always delete the RSDP mapping, we are done with it */
 
-	acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP);
+	acpi_tb_delete_tables_by_type (ACPI_TABLE_RSDP);
 	return_ACPI_STATUS (status);
 }
 
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 2e5921992d9983753a35827379d37281d62ae701..a96c5de2bfeb10bd53b5403412e5bfd6cf4772aa 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -79,13 +79,13 @@ acpi_tb_match_signature (
 	/*
 	 * Search for a signature match among the known table types
 	 */
-	for (i = 0; i < NUM_ACPI_TABLES; i++) {
-		if (!(acpi_gbl_acpi_table_data[i].flags & search_type)) {
+	for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
+		if (!(acpi_gbl_table_data[i].flags & search_type)) {
 			continue;
 		}
 
-		if (!ACPI_STRNCMP (signature, acpi_gbl_acpi_table_data[i].signature,
-				   acpi_gbl_acpi_table_data[i].sig_length)) {
+		if (!ACPI_STRNCMP (signature, acpi_gbl_table_data[i].signature,
+				   acpi_gbl_table_data[i].sig_length)) {
 			/* Found a signature match, return index if requested */
 
 			if (table_info) {
@@ -94,7 +94,7 @@ acpi_tb_match_signature (
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 				"Table [%4.4s] is an ACPI table consumed by the core subsystem\n",
-				(char *) acpi_gbl_acpi_table_data[i].signature));
+				(char *) acpi_gbl_table_data[i].signature));
 
 			return_ACPI_STATUS (AE_OK);
 		}
@@ -149,7 +149,7 @@ acpi_tb_install_table (
 	}
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n",
-		acpi_gbl_acpi_table_data[table_info->type].name, table_info->pointer));
+		acpi_gbl_table_data[table_info->type].name, table_info->pointer));
 
 	(void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
 	return_ACPI_STATUS (status);
@@ -239,70 +239,58 @@ acpi_tb_init_table_descriptor (
 	acpi_table_type                 table_type,
 	struct acpi_table_desc          *table_info)
 {
-	struct acpi_table_desc          *list_head;
+	struct acpi_table_list          *list_head;
 	struct acpi_table_desc          *table_desc;
 
 
 	ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type);
 
+
+	/* Allocate a descriptor for this table */
+
+	table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
+	if (!table_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
 	/*
 	 * Install the table into the global data structure
 	 */
-	list_head   = &acpi_gbl_acpi_tables[table_type];
-	table_desc  = list_head;
+	list_head = &acpi_gbl_table_lists[table_type];
 
 	/*
 	 * Two major types of tables:  1) Only one instance is allowed.  This
 	 * includes most ACPI tables such as the DSDT.  2) Multiple instances of
 	 * the table are allowed.  This includes SSDT and PSDTs.
 	 */
-	if (ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags)) {
+	if (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags)) {
 		/*
 		 * Only one table allowed, and a table has alread been installed
 		 *  at this location, so return an error.
 		 */
-		if (list_head->pointer) {
+		if (list_head->next) {
 			return_ACPI_STATUS (AE_ALREADY_EXISTS);
 		}
-
-		table_desc->count = 1;
-		table_desc->prev = NULL;
-		table_desc->next = NULL;
 	}
-	else {
-		/*
-		 * Multiple tables allowed for this table type, we must link
-		 * the new table in to the list of tables of this type.
-		 */
-		if (list_head->pointer) {
-			table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
-			if (!table_desc) {
-				return_ACPI_STATUS (AE_NO_MEMORY);
-			}
-
-			list_head->count++;
-
-			/* Update the original previous */
-
-			list_head->prev->next = table_desc;
-
-			/* Update new entry */
 
-			table_desc->prev = list_head->prev;
-			table_desc->next = list_head;
-
-			/* Update list head */
+	/*
+	 * Link the new table in to the list of tables of this type.
+	 * Just insert at the start of the list, order unimportant.
+	 *
+	 * table_desc->Prev is already NULL from calloc()
+	 */
+	table_desc->next = list_head->next;
+	list_head->next = table_desc;
 
-			list_head->prev = table_desc;
-		}
-		else {
-			table_desc->count = 1;
-		}
+	if (table_desc->next) {
+		table_desc->next->prev = table_desc;
 	}
 
-	/* Common initialization of the table descriptor */
+	list_head->count++;
 
-	table_desc->type                = table_info->type;
+	/* Finish initialization of the table descriptor */
+
+	table_desc->type                = (u8) table_type;
 	table_desc->pointer             = table_info->pointer;
 	table_desc->length              = table_info->length;
 	table_desc->allocation          = table_info->allocation;
@@ -316,8 +304,8 @@ acpi_tb_init_table_descriptor (
 	 * Set the appropriate global pointer (if there is one) to point to the
 	 * newly installed table
 	 */
-	if (acpi_gbl_acpi_table_data[table_type].global_ptr) {
-		*(acpi_gbl_acpi_table_data[table_type].global_ptr) = table_info->pointer;
+	if (acpi_gbl_table_data[table_type].global_ptr) {
+		*(acpi_gbl_table_data[table_type].global_ptr) = table_info->pointer;
 	}
 
 	/* Return Data */
@@ -331,7 +319,7 @@ acpi_tb_init_table_descriptor (
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_delete_acpi_tables
+ * FUNCTION:    acpi_tb_delete_all_tables
  *
  * PARAMETERS:  None.
  *
@@ -342,7 +330,7 @@ acpi_tb_init_table_descriptor (
  ******************************************************************************/
 
 void
-acpi_tb_delete_acpi_tables (void)
+acpi_tb_delete_all_tables (void)
 {
 	acpi_table_type                     type;
 
@@ -351,15 +339,15 @@ acpi_tb_delete_acpi_tables (void)
 	 * Free memory allocated for ACPI tables
 	 * Memory can either be mapped or allocated
 	 */
-	for (type = 0; type < NUM_ACPI_TABLES; type++) {
-		acpi_tb_delete_acpi_table (type);
+	for (type = 0; type < NUM_ACPI_TABLE_TYPES; type++) {
+		acpi_tb_delete_tables_by_type (type);
 	}
 }
 
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_delete_acpi_table
+ * FUNCTION:    acpi_tb_delete_tables_by_type
  *
  * PARAMETERS:  Type                - The table type to be deleted
  *
@@ -371,11 +359,15 @@ acpi_tb_delete_acpi_tables (void)
  ******************************************************************************/
 
 void
-acpi_tb_delete_acpi_table (
+acpi_tb_delete_tables_by_type (
 	acpi_table_type                     type)
 {
+	struct acpi_table_desc          *table_desc;
+	u32                             count;
+	u32                             i;
 
-	ACPI_FUNCTION_TRACE_U32 ("tb_delete_acpi_table", type);
+
+	ACPI_FUNCTION_TRACE_U32 ("tb_delete_tables_by_type", type);
 
 
 	if (type > ACPI_TABLE_MAX) {
@@ -416,43 +408,10 @@ acpi_tb_delete_acpi_table (
 	}
 
 	/* Free the table */
-
-	acpi_tb_free_acpi_tables_of_type (&acpi_gbl_acpi_tables[type]);
-
-	(void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
-	return_VOID;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_free_acpi_tables_of_type
- *
- * PARAMETERS:  table_info          - A table info struct
- *
- * RETURN:      None.
- *
- * DESCRIPTION: Free the memory associated with an internal ACPI table
- *              Table mutex should be locked.
- *
- ******************************************************************************/
-
-void
-acpi_tb_free_acpi_tables_of_type (
-	struct acpi_table_desc          *list_head)
-{
-	struct acpi_table_desc          *table_desc;
-	u32                             count;
-	u32                             i;
-
-
-	ACPI_FUNCTION_TRACE_PTR ("tb_free_acpi_tables_of_type", list_head);
-
-
 	/* Get the head of the list */
 
-	table_desc  = list_head;
-	count       = list_head->count;
+	table_desc = acpi_gbl_table_lists[type].next;
+	count     = acpi_gbl_table_lists[type].count;
 
 	/*
 	 * Walk the entire list, deleting both the allocated tables
@@ -462,6 +421,7 @@ acpi_tb_free_acpi_tables_of_type (
 		table_desc = acpi_tb_uninstall_table (table_desc);
 	}
 
+	(void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
 	return_VOID;
 }
 
@@ -484,30 +444,31 @@ acpi_tb_delete_single_table (
 	struct acpi_table_desc          *table_desc)
 {
 
-	if (!table_desc) {
+	/* Must have a valid table descriptor and pointer */
+
+	if ((!table_desc) ||
+		 (!table_desc->pointer)) {
 		return;
 	}
 
-	if (table_desc->pointer) {
-		/* Valid table, determine type of memory allocation */
+	/* Valid table, determine type of memory allocation */
 
-		switch (table_desc->allocation) {
-		case ACPI_MEM_NOT_ALLOCATED:
-			break;
+	switch (table_desc->allocation) {
+	case ACPI_MEM_NOT_ALLOCATED:
+		break;
 
-		case ACPI_MEM_ALLOCATED:
+	case ACPI_MEM_ALLOCATED:
 
-			ACPI_MEM_FREE (table_desc->pointer);
-			break;
+		ACPI_MEM_FREE (table_desc->pointer);
+		break;
 
-		case ACPI_MEM_MAPPED:
+	case ACPI_MEM_MAPPED:
 
-			acpi_os_unmap_memory (table_desc->pointer, table_desc->length);
-			break;
+		acpi_os_unmap_memory (table_desc->pointer, table_desc->length);
+		break;
 
-		default:
-			break;
-		}
+	default:
+		break;
 	}
 }
 
@@ -533,18 +494,23 @@ acpi_tb_uninstall_table (
 	struct acpi_table_desc          *next_desc;
 
 
-	ACPI_FUNCTION_TRACE_PTR ("acpi_tb_uninstall_table", table_desc);
+	ACPI_FUNCTION_TRACE_PTR ("tb_uninstall_table", table_desc);
 
 
 	if (!table_desc) {
 		return_PTR (NULL);
 	}
 
-	/* Unlink the descriptor */
+	/* Unlink the descriptor from the doubly linked list */
 
 	if (table_desc->prev) {
 		table_desc->prev->next = table_desc->next;
 	}
+	else {
+		/* Is first on list, update list head */
+
+		acpi_gbl_table_lists[table_desc->type].next = table_desc->next;
+	}
 
 	if (table_desc->next) {
 		table_desc->next->prev = table_desc->prev;
@@ -554,23 +520,12 @@ acpi_tb_uninstall_table (
 
 	acpi_tb_delete_single_table (table_desc);
 
-	/* Free the table descriptor (Don't delete the list head, tho) */
-
-	if ((table_desc->prev) == (table_desc->next)) {
-		next_desc = NULL;
+	/* Free the table descriptor */
 
-		/* Clear the list head */
+	next_desc = table_desc->next;
+	ACPI_MEM_FREE (table_desc);
 
-		table_desc->pointer  = NULL;
-		table_desc->length   = 0;
-		table_desc->count    = 0;
-	}
-	else {
-		/* Free the table descriptor */
-
-		next_desc = table_desc->next;
-		ACPI_MEM_FREE (table_desc);
-	}
+	/* Return pointer to the next descriptor */
 
 	return_PTR (next_desc);
 }
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 94a9f001490548ecca76e4e96c18cb4e26d750f6..7e087319532a78aba032edf197157839f67f1ea5 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -66,26 +66,25 @@
 acpi_status
 acpi_tb_handle_to_object (
 	u16                             table_id,
-	struct acpi_table_desc          **table_desc)
+	struct acpi_table_desc          **return_table_desc)
 {
 	u32                             i;
-	struct acpi_table_desc          *list_head;
+	struct acpi_table_desc          *table_desc;
 
 
 	ACPI_FUNCTION_NAME ("tb_handle_to_object");
 
 
 	for (i = 0; i < ACPI_TABLE_MAX; i++) {
-		list_head = &acpi_gbl_acpi_tables[i];
-		do {
-			if (list_head->table_id == table_id) {
-				*table_desc = list_head;
+		table_desc = acpi_gbl_table_lists[i].next;
+		while (table_desc) {
+			if (table_desc->table_id == table_id) {
+				*return_table_desc = table_desc;
 				return (AE_OK);
 			}
 
-			list_head = list_head->next;
-
-		} while (list_head != &acpi_gbl_acpi_tables[i]);
+			table_desc = table_desc->next;
+		}
 	}
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id));
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 43597f10f2f493991327c3bcd0ac99f4015ab353..76953d7fa0b44696fe65c396e2333f8aeef63463 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -235,7 +235,7 @@ acpi_status
 acpi_unload_table (
 	acpi_table_type                 table_type)
 {
-	struct acpi_table_desc          *list_head;
+	struct acpi_table_desc          *table_desc;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_unload_table");
@@ -250,22 +250,22 @@ acpi_unload_table (
 
 	/* Find all tables of the requested type */
 
-	list_head = &acpi_gbl_acpi_tables[table_type];
-	do {
+	table_desc = acpi_gbl_table_lists[table_type].next;
+	while (table_desc); {
 		/*
 		 * Delete all namespace entries owned by this table.  Note that these
 		 * entries can appear anywhere in the namespace by virtue of the AML
 		 * "Scope" operator.  Thus, we need to track ownership by an ID, not
 		 * simply a position within the hierarchy
 		 */
-		acpi_ns_delete_namespace_by_owner (list_head->table_id);
+		acpi_ns_delete_namespace_by_owner (table_desc->table_id);
 
-		/* Delete (or unmap) the actual table */
-
-		acpi_tb_delete_acpi_table (table_type);
+		table_desc = table_desc->next;
+	}
 
-	} while (list_head != &acpi_gbl_acpi_tables[table_type]);
+	/* Delete (or unmap) all tables of this type */
 
+	acpi_tb_delete_tables_by_type (table_type);
 	return_ACPI_STATUS (AE_OK);
 }
 
@@ -313,7 +313,7 @@ acpi_get_table_header (
 	/* Check the table type and instance */
 
 	if ((table_type > ACPI_TABLE_MAX)   ||
-		(ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
+		(ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
 		 instance > 1)) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
@@ -394,7 +394,7 @@ acpi_get_table (
 	/* Check the table type and instance */
 
 	if ((table_type > ACPI_TABLE_MAX)   ||
-		(ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
+		(ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
 		 instance > 1)) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index ed2d6778721451a7d2308b614396af76323c587a..0cb16126e317b74309ca85a7ac0a1cda7f2a0dc5 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -33,7 +33,7 @@
  *
  */
 
-#define TOSHIBA_ACPI_VERSION	"0.14"
+#define TOSHIBA_ACPI_VERSION	"0.15"
 #define PROC_INTERFACE_VERSION	1
 
 #include <linux/kernel.h>
@@ -172,9 +172,7 @@ hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
 	for (i = 0; i < HCI_WORDS; ++i) {
 		in_objs[i].type = ACPI_TYPE_INTEGER;
 		in_objs[i].integer.value = in[i];
-		/*printk("%04x ", in[i]);*/
 	}
-	/*printk("\n");*/
 
 	results.length = sizeof(out_objs);
 	results.pointer = out_objs;
@@ -184,9 +182,7 @@ hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
 	if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) {
 		for (i = 0; i < out_objs->package.count; ++i) {
 			out[i] = out_objs->package.elements[i].integer.value;
-			/*printk("%04x ", out[i]);*/
 		}
-		/*printk("\n");*/
 	}
 
 	return status;
@@ -226,7 +222,7 @@ static int			key_event_valid;
 
 typedef struct _ProcItem
 {
-	char* name;
+	const char* name;
 	char* (*read_func)(char*);
 	unsigned long (*write_func)(const char*, unsigned long);
 } ProcItem;
@@ -284,10 +280,8 @@ static unsigned long
 write_lcd(const char* buffer, unsigned long count)
 {
 	int value;
-	/*int byte_count;*/
 	u32 hci_result;
 
-	/* ISSUE: %i doesn't work with hex values as advertised */
 	if (snscanf(buffer, count, " brightness : %i", &value) == 1 &&
 			value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
 		value = value << HCI_LCD_BRIGHTNESS_SHIFT;
@@ -414,6 +408,11 @@ read_keys(char* p)
 			last_key_event = value;
 		} else if (hci_result == HCI_EMPTY) {
 			/* better luck next time */
+		} else if (hci_result == HCI_NOT_SUPPORTED) {
+			/* This is a workaround for an unresolved issue on
+			 * some machines where system events sporadically
+			 * become disabled. */
+			hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
 		} else {
 			p += sprintf(p, "ERROR\n");
 			goto end;
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 441920d56f6a44bacf9325a25d57cfa2472cdfb0..c21679c5aa579dbdfd7fa5be6314320845d4f7dd 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -651,13 +651,21 @@ acpi_ut_copy_simple_object (
 		 */
 		if ((source_desc->buffer.pointer) &&
 			(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
-			dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length);
-			if (!dest_desc->buffer.pointer) {
-				return (AE_NO_MEMORY);
-			}
+			dest_desc->buffer.pointer = NULL;
+
+			/* Create an actual buffer only if length > 0 */
 
-			ACPI_MEMCPY (dest_desc->buffer.pointer, source_desc->buffer.pointer,
-					  source_desc->buffer.length);
+			if (source_desc->buffer.length) {
+				dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length);
+				if (!dest_desc->buffer.pointer) {
+					return (AE_NO_MEMORY);
+				}
+
+				/* Copy the actual buffer data */
+
+				ACPI_MEMCPY (dest_desc->buffer.pointer, source_desc->buffer.pointer,
+						  source_desc->buffer.length);
+			}
 		}
 		break;
 
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 2e2b8f44d47ee960de3c758a0fda8c636975a33b..ea0fcb867caaac6b118aee0f762a5b8f7025442f 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -71,6 +71,7 @@ acpi_ut_delete_internal_obj (
 	void                            *obj_pointer = NULL;
 	union acpi_operand_object       *handler_desc;
 	union acpi_operand_object       *second_desc;
+	union acpi_operand_object       *next_desc;
 
 
 	ACPI_FUNCTION_TRACE_PTR ("ut_delete_internal_obj", object);
@@ -136,6 +137,15 @@ acpi_ut_delete_internal_obj (
 		if (object->device.gpe_block) {
 			(void) acpi_ev_delete_gpe_block (object->device.gpe_block);
 		}
+
+		/* Walk the handler list for this device */
+
+		handler_desc = object->device.address_space;
+		while (handler_desc) {
+			next_desc = handler_desc->address_space.next;
+			acpi_ut_remove_reference (handler_desc);
+			handler_desc = next_desc;
+		}
 		break;
 
 
@@ -183,10 +193,13 @@ acpi_ut_delete_internal_obj (
 			 * default handlers -- and therefore, we created the context object
 			 * locally, it was not created by an external caller.
 			 */
-			handler_desc = object->region.addr_handler;
-			if ((handler_desc) &&
-				(handler_desc->addr_handler.hflags == ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
-				obj_pointer = second_desc->extra.region_context;
+			handler_desc = object->region.address_space;
+			if (handler_desc) {
+				if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
+					obj_pointer = second_desc->extra.region_context;
+				}
+
+				acpi_ut_remove_reference (handler_desc);
 			}
 
 			/* Now we can free the Extra object */
@@ -211,7 +224,6 @@ acpi_ut_delete_internal_obj (
 		break;
 	}
 
-
 	/* Free any allocated memory (pointer within the object) found above */
 
 	if (obj_pointer) {
@@ -299,7 +311,7 @@ acpi_ut_update_ref_count (
 	new_count = count;
 
 	/*
-	 * Reference count action (increment, decrement, or force delete)
+	 * Perform the reference count action (increment, decrement, or force delete)
 	 */
 	switch (action) {
 
@@ -402,8 +414,6 @@ acpi_ut_update_object_reference (
 {
 	acpi_status                     status;
 	u32                             i;
-	union acpi_operand_object       *next;
-	union acpi_operand_object       *new;
 	union acpi_generic_state         *state_list = NULL;
 	union acpi_generic_state         *state;
 
@@ -417,9 +427,8 @@ acpi_ut_update_object_reference (
 		return_ACPI_STATUS (AE_OK);
 	}
 
-	/*
-	 * Make sure that this isn't a namespace handle
-	 */
+	/* Make sure that this isn't a namespace handle */
+
 	if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", object));
 		return_ACPI_STATUS (AE_OK);
@@ -439,28 +448,8 @@ acpi_ut_update_object_reference (
 		switch (ACPI_GET_OBJECT_TYPE (object)) {
 		case ACPI_TYPE_DEVICE:
 
-			status = acpi_ut_create_update_state_and_push (object->device.addr_handler,
-					   action, &state_list);
-			if (ACPI_FAILURE (status)) {
-				goto error_exit;
-			}
-
-			acpi_ut_update_ref_count (object->device.sys_handler, action);
-			acpi_ut_update_ref_count (object->device.drv_handler, action);
-			break;
-
-
-		case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
-
-			/* Must walk list of address handlers */
-
-			next = object->addr_handler.next;
-			while (next) {
-				new = next->addr_handler.next;
-				acpi_ut_update_ref_count (next, action);
-
-				next = new;
-			}
+			acpi_ut_update_ref_count (object->device.system_notify, action);
+			acpi_ut_update_ref_count (object->device.device_notify, action);
 			break;
 
 
@@ -590,16 +579,14 @@ acpi_ut_add_reference (
 	ACPI_FUNCTION_TRACE_PTR ("ut_add_reference", object);
 
 
-	/*
-	 * Ensure that we have a valid object
-	 */
+	/* Ensure that we have a valid object */
+
 	if (!acpi_ut_valid_internal_object (object)) {
 		return_VOID;
 	}
 
-	/*
-	 * We have a valid ACPI internal object, now increment the reference count
-	 */
+	/* Increment the reference count */
+
 	(void) acpi_ut_update_object_reference (object, REF_INCREMENT);
 	return_VOID;
 }
@@ -624,6 +611,7 @@ acpi_ut_remove_reference (
 
 	ACPI_FUNCTION_TRACE_PTR ("ut_remove_reference", object);
 
+
 	/*
 	 * Allow a NULL pointer to be passed in, just ignore it.  This saves
 	 * each caller from having to check.  Also, ignore NS nodes.
@@ -634,9 +622,8 @@ acpi_ut_remove_reference (
 		return_VOID;
 	}
 
-	/*
-	 * Ensure that we have a valid object
-	 */
+	/* Ensure that we have a valid object */
+
 	if (!acpi_ut_valid_internal_object (object)) {
 		return_VOID;
 	}
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index 141f21af0cd76aa85e48f5f36b95214fc6a26bb7..4b4cd90fe5610dcaa8727b15bbcc7beb973fc767 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -208,6 +208,46 @@ acpi_ut_evaluate_numeric_object (
 }
 
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_id_string
+ *
+ * PARAMETERS:  Destination         - Where to copy the string
+ *              Source              - Source string
+ *              max_length          - Length of the destination buffer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
+ *              Performs removal of a leading asterisk if present -- workaround
+ *              for a known issue on a bunch of machines.
+ *
+ ******************************************************************************/
+
+static void
+acpi_ut_copy_id_string (
+	char                            *destination,
+	char                            *source,
+	acpi_size                       max_length)
+{
+
+
+	/*
+	 * Workaround for ID strings that have a leading asterisk. This construct
+	 * is not allowed by the ACPI specification  (ID strings must be
+	 * alphanumeric), but enough existing machines have this embedded in their
+	 * ID strings that the following code is useful.
+	 */
+	if (*source == '*') {
+		source++;
+	}
+
+	/* Do the actual copy */
+
+	ACPI_STRNCPY (destination, source, max_length);
+}
+
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_execute_HID
@@ -245,12 +285,13 @@ acpi_ut_execute_HID (
 	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 		/* Convert the Numeric HID to string */
 
-		acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->buffer);
+		acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->value);
 	}
 	else {
 		/* Copy the String HID from the returned object */
 
-		ACPI_STRNCPY (hid->buffer, obj_desc->string.pointer, sizeof(hid->buffer));
+		acpi_ut_copy_id_string (hid->value, obj_desc->string.pointer,
+				sizeof (hid->value));
 	}
 
 	/* On exit, we must delete the return object */
@@ -260,6 +301,57 @@ acpi_ut_execute_HID (
 }
 
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_translate_one_cid
+ *
+ * PARAMETERS:  obj_desc            - _CID object, must be integer or string
+ *              one_cid             - Where the CID string is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Return a numeric or string _CID value as a string.
+ *              (Compatible ID)
+ *
+ *              NOTE:  Assumes a maximum _CID string length of
+ *                     ACPI_MAX_CID_LENGTH.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_translate_one_cid (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_compatible_id       *one_cid)
+{
+
+
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_INTEGER:
+
+		/* Convert the Numeric CID to string */
+
+		acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, one_cid->value);
+		return (AE_OK);
+
+	case ACPI_TYPE_STRING:
+
+		if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
+			return (AE_AML_STRING_LIMIT);
+		}
+
+		/* Copy the String CID from the returned object */
+
+		acpi_ut_copy_id_string (one_cid->value, obj_desc->string.pointer,
+				ACPI_MAX_CID_LENGTH);
+		return (AE_OK);
+
+	default:
+
+		return (AE_TYPE);
+	}
+}
+
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_execute_CID
@@ -279,55 +371,86 @@ acpi_ut_execute_HID (
 acpi_status
 acpi_ut_execute_CID (
 	struct acpi_namespace_node      *device_node,
-	struct acpi_device_id           *cid)
+	struct acpi_compatible_id_list **return_cid_list)
 {
 	union acpi_operand_object       *obj_desc;
 	acpi_status                     status;
+	u32                             count;
+	u32                             size;
+	struct acpi_compatible_id_list *cid_list;
+	acpi_native_uint                i;
 
 
 	ACPI_FUNCTION_TRACE ("ut_execute_CID");
 
 
+	/* Evaluate the _CID method for this device */
+
 	status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID,
-			 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE, &obj_desc);
+			 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
+			 &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	/*
-	 *  A _CID can return either a single compatible ID or a package of compatible
-	 *  IDs.  Each compatible ID can be a Number (32 bit compressed EISA ID) or
-	 *  string (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
-	 */
-	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
-	case ACPI_TYPE_INTEGER:
+	/* Get the number of _CIDs returned */
 
-		/* Convert the Numeric CID to string */
+	count = 1;
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
+		count = obj_desc->package.count;
+	}
 
-		acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, cid->buffer);
-		break;
+	/* Allocate a worst-case buffer for the _CIDs */
 
-	case ACPI_TYPE_STRING:
+	size = (((count - 1) * sizeof (struct acpi_compatible_id)) +
+			   sizeof (struct acpi_compatible_id_list));
 
-		/* Copy the String CID from the returned object */
+	cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size);
+	if (!cid_list) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
 
-		ACPI_STRNCPY (cid->buffer, obj_desc->string.pointer, sizeof (cid->buffer));
-		break;
+	/* Init CID list */
 
-	case ACPI_TYPE_PACKAGE:
+	cid_list->count = count;
+	cid_list->size = size;
 
-		/* TBD: Parse package elements; need different return struct, etc. */
+	/*
+	 *  A _CID can return either a single compatible ID or a package of compatible
+	 *  IDs.  Each compatible ID can be one of the following:
+	 *  -- Number (32 bit compressed EISA ID) or
+	 *  -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
+	 */
 
-		status = AE_SUPPORT;
-		break;
+	/* The _CID object can be either a single CID or a package (list) of CIDs */
 
-	default:
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
+		/* Translate each package element */
 
-		status = AE_TYPE;
-		break;
+		for (i = 0; i < count; i++) {
+			status = acpi_ut_translate_one_cid (obj_desc->package.elements[i],
+					  &cid_list->id[i]);
+			if (ACPI_FAILURE (status)) {
+				break;
+			}
+		}
 	}
+	else {
+		/* Only one CID, translate to a string */
 
-	/* On exit, we must delete the return object */
+		status = acpi_ut_translate_one_cid (obj_desc, cid_list->id);
+	}
+
+	/* Cleanup on error */
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_MEM_FREE (cid_list);
+	}
+	else {
+		*return_cid_list = cid_list;
+	}
+
+	/* On exit, we must delete the _CID return object */
 
 	acpi_ut_remove_reference (obj_desc);
 	return_ACPI_STATUS (status);
@@ -371,12 +494,13 @@ acpi_ut_execute_UID (
 	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 		/* Convert the Numeric UID to string */
 
-		acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->buffer);
+		acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value);
 	}
 	else {
 		/* Copy the String UID from the returned object */
 
-		ACPI_STRNCPY (uid->buffer, obj_desc->string.pointer, sizeof (uid->buffer));
+		acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer,
+				sizeof (uid->value));
 	}
 
 	/* On exit, we must delete the return object */
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index b2d14d924cd94c29d3bf572be93e4700eb82a0ce..51c01acfdb0a573d2cc37e3e450265809b381b12 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -299,10 +299,10 @@ acpi_ut_hex_to_ascii_char (
  ******************************************************************************/
 
 
-struct acpi_table_desc              acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
+struct acpi_table_list              acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
 
 
-struct acpi_table_support           acpi_gbl_acpi_table_data[NUM_ACPI_TABLES] =
+struct acpi_table_support           acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] =
 {
 	/***********    Name,   Signature, Global typed pointer     Signature size,      Type                  How many allowed?,    Contains valid AML? */
 
@@ -535,12 +535,10 @@ acpi_ut_get_object_type_name (
 
 
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
-
 /*
  * Strings and procedures used for debug only
  */
 
-
 /*****************************************************************************
  *
  * FUNCTION:    acpi_ut_get_mutex_name
@@ -558,7 +556,7 @@ acpi_ut_get_mutex_name (
 	u32                             mutex_id)
 {
 
-	if (mutex_id > MAX_MTX)
+	if (mutex_id > MAX_MUTEX)
 	{
 		return ("Invalid Mutex ID");
 	}
@@ -566,7 +564,6 @@ acpi_ut_get_mutex_name (
 	return (acpi_gbl_mutex_names[mutex_id]);
 }
 
-
 #endif
 
 
@@ -630,9 +627,12 @@ acpi_ut_allocate_owner_id (
 		owner_id = acpi_gbl_next_table_owner_id;
 		acpi_gbl_next_table_owner_id++;
 
+		/* Check for wraparound */
+
 		if (acpi_gbl_next_table_owner_id == ACPI_FIRST_METHOD_ID)
 		{
 			acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID;
+			ACPI_REPORT_WARNING (("Table owner ID wraparound\n"));
 		}
 		break;
 
@@ -644,6 +644,8 @@ acpi_ut_allocate_owner_id (
 
 		if (acpi_gbl_next_method_owner_id == ACPI_FIRST_TABLE_ID)
 		{
+			/* Check for wraparound */
+
 			acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID;
 		}
 		break;
@@ -710,23 +712,19 @@ acpi_ut_init_globals (
 
 	/* ACPI table structure */
 
-	for (i = 0; i < NUM_ACPI_TABLES; i++)
+	for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
 	{
-		acpi_gbl_acpi_tables[i].prev        = &acpi_gbl_acpi_tables[i];
-		acpi_gbl_acpi_tables[i].next        = &acpi_gbl_acpi_tables[i];
-		acpi_gbl_acpi_tables[i].pointer     = NULL;
-		acpi_gbl_acpi_tables[i].length      = 0;
-		acpi_gbl_acpi_tables[i].allocation  = ACPI_MEM_NOT_ALLOCATED;
-		acpi_gbl_acpi_tables[i].count       = 0;
+		acpi_gbl_table_lists[i].next        = NULL;
+		acpi_gbl_table_lists[i].count       = 0;
 	}
 
 	/* Mutex locked flags */
 
-	for (i = 0; i < NUM_MTX; i++)
+	for (i = 0; i < NUM_MUTEX; i++)
 	{
-		acpi_gbl_acpi_mutex_info[i].mutex   = NULL;
-		acpi_gbl_acpi_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
-		acpi_gbl_acpi_mutex_info[i].use_count = 0;
+		acpi_gbl_mutex_info[i].mutex        = NULL;
+		acpi_gbl_mutex_info[i].owner_id     = ACPI_MUTEX_NOT_ACQUIRED;
+		acpi_gbl_mutex_info[i].use_count    = 0;
 	}
 
 	/* GPE support */
@@ -737,8 +735,8 @@ acpi_ut_init_globals (
 
 	/* Global notify handlers */
 
-	acpi_gbl_sys_notify.handler         = NULL;
-	acpi_gbl_drv_notify.handler         = NULL;
+	acpi_gbl_system_notify.handler      = NULL;
+	acpi_gbl_device_notify.handler      = NULL;
 	acpi_gbl_init_handler               = NULL;
 
 	/* Global "typed" ACPI table pointers */
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 6894c58aa201ce1eb7ed3206caf0cf229c2f8c0f..b16c01e8355993f815f9d07ab926989a58ba59f5 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -549,7 +549,7 @@ acpi_ut_mutex_initialize (
 	/*
 	 * Create each of the predefined mutex objects
 	 */
-	for (i = 0; i < NUM_MTX; i++) {
+	for (i = 0; i < NUM_MUTEX; i++) {
 		status = acpi_ut_create_mutex (i);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
@@ -588,7 +588,7 @@ acpi_ut_mutex_terminate (
 	/*
 	 * Delete each predefined mutex object
 	 */
-	for (i = 0; i < NUM_MTX; i++) {
+	for (i = 0; i < NUM_MUTEX; i++) {
 		(void) acpi_ut_delete_mutex (i);
 	}
 
@@ -619,15 +619,15 @@ acpi_ut_create_mutex (
 	ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id);
 
 
-	if (mutex_id > MAX_MTX) {
+	if (mutex_id > MAX_MUTEX) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	if (!acpi_gbl_acpi_mutex_info[mutex_id].mutex) {
+	if (!acpi_gbl_mutex_info[mutex_id].mutex) {
 		status = acpi_os_create_semaphore (1, 1,
-				  &acpi_gbl_acpi_mutex_info[mutex_id].mutex);
-		acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
-		acpi_gbl_acpi_mutex_info[mutex_id].use_count = 0;
+				  &acpi_gbl_mutex_info[mutex_id].mutex);
+		acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+		acpi_gbl_mutex_info[mutex_id].use_count = 0;
 	}
 
 	return_ACPI_STATUS (status);
@@ -656,14 +656,14 @@ acpi_ut_delete_mutex (
 	ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id);
 
 
-	if (mutex_id > MAX_MTX) {
+	if (mutex_id > MAX_MUTEX) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	status = acpi_os_delete_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex);
+	status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex);
 
-	acpi_gbl_acpi_mutex_info[mutex_id].mutex = NULL;
-	acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+	acpi_gbl_mutex_info[mutex_id].mutex = NULL;
+	acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
 
 	return_ACPI_STATUS (status);
 }
@@ -693,7 +693,7 @@ acpi_ut_acquire_mutex (
 	ACPI_FUNCTION_NAME ("ut_acquire_mutex");
 
 
-	if (mutex_id > MAX_MTX) {
+	if (mutex_id > MAX_MUTEX) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -705,8 +705,8 @@ acpi_ut_acquire_mutex (
 	 * the mutex ordering rule.  This indicates a coding error somewhere in
 	 * the ACPI subsystem code.
 	 */
-	for (i = mutex_id; i < MAX_MTX; i++) {
-		if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) {
+	for (i = mutex_id; i < MAX_MUTEX; i++) {
+		if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
 			if (i == mutex_id) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 						"Mutex [%s] already acquired by this thread [%X]\n",
@@ -728,14 +728,14 @@ acpi_ut_acquire_mutex (
 			 "Thread %X attempting to acquire Mutex [%s]\n",
 			 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
 
-	status = acpi_os_wait_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex,
+	status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex,
 			   1, ACPI_WAIT_FOREVER);
 	if (ACPI_SUCCESS (status)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
 				 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
 
-		acpi_gbl_acpi_mutex_info[mutex_id].use_count++;
-		acpi_gbl_acpi_mutex_info[mutex_id].owner_id = this_thread_id;
+		acpi_gbl_mutex_info[mutex_id].use_count++;
+		acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id;
 	}
 	else {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n",
@@ -776,14 +776,14 @@ acpi_ut_release_mutex (
 		"Thread %X releasing Mutex [%s]\n", this_thread_id,
 		acpi_ut_get_mutex_name (mutex_id)));
 
-	if (mutex_id > MAX_MTX) {
+	if (mutex_id > MAX_MUTEX) {
 		return (AE_BAD_PARAMETER);
 	}
 
 	/*
 	 * Mutex must be acquired in order to release it!
 	 */
-	if (acpi_gbl_acpi_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
+	if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 				"Mutex [%s] is not acquired, cannot release\n",
 				acpi_ut_get_mutex_name (mutex_id)));
@@ -797,8 +797,8 @@ acpi_ut_release_mutex (
 	 * ordering rule.  This indicates a coding error somewhere in
 	 * the ACPI subsystem code.
 	 */
-	for (i = mutex_id; i < MAX_MTX; i++) {
-		if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) {
+	for (i = mutex_id; i < MAX_MUTEX; i++) {
+		if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
 			if (i == mutex_id) {
 				continue;
 			}
@@ -813,9 +813,9 @@ acpi_ut_release_mutex (
 
 	/* Mark unlocked FIRST */
 
-	acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+	acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
 
-	status = acpi_os_signal_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, 1);
+	status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1);
 
 	if (ACPI_FAILURE (status)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n",
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index aa7dd52cf37a1dcd5d9838f84525479dbbb4ce9e..2d63be55f066f2e57b0abe5745113d97356a0537 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -149,7 +149,7 @@ acpi_ut_create_buffer_object (
 	acpi_size                       buffer_size)
 {
 	union acpi_operand_object       *buffer_desc;
-	u8                              *buffer;
+	u8                              *buffer = NULL;
 
 
 	ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size);
@@ -163,14 +163,18 @@ acpi_ut_create_buffer_object (
 		return_PTR (NULL);
 	}
 
-	/* Allocate the actual buffer */
+	/* Create an actual buffer only if size > 0 */
 
-	buffer = ACPI_MEM_CALLOCATE (buffer_size);
-	if (!buffer) {
-		ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n",
-			(u32) buffer_size));
-		acpi_ut_remove_reference (buffer_desc);
-		return_PTR (NULL);
+	if (buffer_size > 0) {
+		/* Allocate the actual buffer */
+
+		buffer = ACPI_MEM_CALLOCATE (buffer_size);
+		if (!buffer) {
+			ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n",
+				(u32) buffer_size));
+			acpi_ut_remove_reference (buffer_desc);
+			return_PTR (NULL);
+		}
 	}
 
 	/* Complete buffer object initialization */
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
index b1eeb9e49fbc8ef380f4101611684d8b0f519011..cf03534522feea66f1e8ce3d84cdcd1be370a9bd 100644
--- a/drivers/acpi/utilities/utxface.c
+++ b/drivers/acpi/utilities/utxface.c
@@ -144,23 +144,9 @@ acpi_enable_subsystem (
 	ACPI_FUNCTION_TRACE ("acpi_enable_subsystem");
 
 
-	/*
-	 * Install the default op_region handlers. These are installed unless
-	 * other handlers have already been installed via the
-	 * install_address_space_handler interface
-	 */
-	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
-
-		status = acpi_ev_init_address_spaces ();
-		if (ACPI_FAILURE (status)) {
-			return_ACPI_STATUS (status);
-		}
-	}
-
 	/*
 	 * We must initialize the hardware before we can enable ACPI.
-	 * FADT values are validated here.
+	 * The values from the FADT are validated here.
 	 */
 	if (!(flags & ACPI_NO_HARDWARE_INIT)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI hardware\n"));
@@ -172,7 +158,7 @@ acpi_enable_subsystem (
 	}
 
 	/*
-	 * Enable ACPI on this platform
+	 * Enable ACPI mode
 	 */
 	if (!(flags & ACPI_NO_ACPI_ENABLE)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n"));
@@ -187,8 +173,9 @@ acpi_enable_subsystem (
 	}
 
 	/*
-	 * Note:
-	 * We must have the hardware AND events initialized before we can execute
+	 * Initialize ACPI Event handling
+	 *
+	 * NOTE: We must have the hardware AND events initialized before we can execute
 	 * ANY control methods SAFELY.  Any control method can require ACPI hardware
 	 * support, so the hardware MUST be initialized before execution!
 	 */
@@ -201,7 +188,7 @@ acpi_enable_subsystem (
 		}
 	}
 
-	/* Install SCI handler, Global Lock handler, GPE handlers */
+	/* Install the SCI handler, Global Lock handler, and GPE handlers */
 
 	if (!(flags & ACPI_NO_HANDLER_INIT)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL/GPE handlers\n"));
@@ -237,14 +224,20 @@ acpi_initialize_objects (
 
 	ACPI_FUNCTION_TRACE ("acpi_initialize_objects");
 
+
 	/*
-	 * Initialize all device objects in the namespace
-	 * This runs the _STA and _INI methods.
+	 * Install the default op_region handlers. These are installed unless
+	 * other handlers have already been installed via the
+	 * install_address_space_handler interface.
+	 *
+	 * NOTE: This will cause _REG methods to be run.  Any objects accessed
+	 * by the _REG methods will be automatically initialized, even if they
+	 * contain executable AML (see call to acpi_ns_initialize_objects below).
 	 */
-	if (!(flags & ACPI_NO_DEVICE_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n"));
+	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
 
-		status = acpi_ns_initialize_devices ();
+		status = acpi_ev_init_address_spaces ();
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -252,8 +245,8 @@ acpi_initialize_objects (
 
 	/*
 	 * Initialize the objects that remain uninitialized.  This
-	 * runs the executable AML that is part of the declaration of op_regions
-	 * and Fields.
+	 * runs the executable AML that may be part of the declaration of these
+	 * objects: operation_regions, buffer_fields, Buffers, and Packages.
 	 */
 	if (!(flags & ACPI_NO_OBJECT_INIT)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Objects\n"));
@@ -264,6 +257,19 @@ acpi_initialize_objects (
 		}
 	}
 
+	/*
+	 * Initialize all device objects in the namespace
+	 * This runs the _STA and _INI methods.
+	 */
+	if (!(flags & ACPI_NO_DEVICE_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n"));
+
+		status = acpi_ns_initialize_devices ();
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
 	/*
 	 * Empty the caches (delete the cached objects) on the assumption that
 	 * the table load filled them up more than they will be at runtime --
@@ -431,9 +437,9 @@ acpi_get_system_info (
 
 	/* Current status of the ACPI tables, per table type */
 
-	info_ptr->num_table_types = NUM_ACPI_TABLES;
-	for (i = 0; i < NUM_ACPI_TABLES; i++) {
-		info_ptr->table_info[i].count = acpi_gbl_acpi_tables[i].count;
+	info_ptr->num_table_types = NUM_ACPI_TABLE_TYPES;
+	for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
+		info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count;
 	}
 
 	return_ACPI_STATUS (AE_OK);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 8ad09844971f130314576ade92533e78b381804c..00985933a64250fd87c944b395baedb5f9dc3066 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -247,7 +247,7 @@ static ide_startstop_t write_intr (ide_drive_t *drive)
  *
  * Returns 0 on success.
  *
- * Note that we may be called from two contexts - the do_rw_disk context
+ * Note that we may be called from two contexts - __ide_do_rw_disk() context
  * and IRQ context. The IRQ can happen any time after we've output the
  * full "mcount" number of sectors, so we must make sure we update the
  * state _before_ we output the final part of the data!
@@ -351,11 +351,11 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive)
 }
 
 /*
- * do_rw_disk() issues READ and WRITE commands to a disk,
+ * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
  * using LBA if supported, or CHS otherwise, to address sectors.
  * It also takes care of issuing special DRIVE_CMDs.
  */
-static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
+ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 lba48		= (drive->addressing == 1) ? 1 : 0;
@@ -367,11 +367,6 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto
 	if (driver_blocked)
 		panic("Request while ide driver is blocked?");
 
-#if defined(CONFIG_BLK_DEV_PDC4030) || defined(CONFIG_BLK_DEV_PDC4030_MODULE)
-	if (IS_PDC4030_DRIVE)
-		return promise_rw_disk(drive, rq, block);
-#endif /* CONFIG_BLK_DEV_PDC4030 */
-
 	if (drive->using_tcq && idedisk_start_tag(drive, rq)) {
 		if (!ata_pending_commands(drive))
 			BUG();
@@ -550,10 +545,11 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto
 		}
 		return ide_started;
 	}
-	blk_dump_rq_flags(rq, "do_rw_disk - bad command");
+	blk_dump_rq_flags(rq, "__ide_do_rw_disk - bad command");
 	ide_end_request(drive, 0, 0);
 	return ide_stopped;
 }
+EXPORT_SYMBOL_GPL(__ide_do_rw_disk);
 
 #else /* CONFIG_IDE_TASKFILE_IO */
 
@@ -562,15 +558,15 @@ static ide_startstop_t lba_28_rw_disk(ide_drive_t *, struct request *, unsigned
 static ide_startstop_t lba_48_rw_disk(ide_drive_t *, struct request *, unsigned long long);
 
 /*
- * do_rw_disk() issues READ and WRITE commands to a disk,
+ * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
  * using LBA if supported, or CHS otherwise, to address sectors.
  * It also takes care of issuing special DRIVE_CMDs.
  */
-static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
+ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
 {
 	BUG_ON(drive->blocked);
 	if (!blk_fs_request(rq)) {
-		blk_dump_rq_flags(rq, "do_rw_disk - bad command");
+		blk_dump_rq_flags(rq, "__ide_do_rw_disk - bad command");
 		ide_end_request(drive, 0, 0);
 		return ide_stopped;
 	}
@@ -581,11 +577,6 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto
 	 * need to add split taskfile operations based on 28bit threshold.
 	 */
 
-#if defined(CONFIG_BLK_DEV_PDC4030) || defined(CONFIG_BLK_DEV_PDC4030_MODULE)
-        if (IS_PDC4030_DRIVE)
-                return promise_rw_disk(drive, rq, block);
-#endif /* CONFIG_BLK_DEV_PDC4030 */
-
 	if (drive->using_tcq && idedisk_start_tag(drive, rq)) {
 		if (!ata_pending_commands(drive))
 			BUG();
@@ -601,6 +592,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto
 	/* 28-bit CHS : DIE DIE DIE piece of legacy crap!!! */
 	return chs_rw_disk(drive, rq, (unsigned long) block);
 }
+EXPORT_SYMBOL_GPL(__ide_do_rw_disk);
 
 static task_ioreg_t get_command (ide_drive_t *drive, int cmd)
 {
@@ -760,6 +752,16 @@ static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, u
 
 #endif /* CONFIG_IDE_TASKFILE_IO */
 
+static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+
+	if (hwif->rw_disk)
+		return hwif->rw_disk(drive, rq, block);
+	else
+		return __ide_do_rw_disk(drive, rq, block);
+}
+
 static int do_idedisk_flushcache(ide_drive_t *drive);
 
 static u8 idedisk_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
@@ -1541,11 +1543,6 @@ static void idedisk_setup (ide_drive_t *drive)
 	struct hd_driveid *id = drive->id;
 	unsigned long capacity;
 
-#if 0
-	if (IS_PDC4030_DRIVE)
-		DRIVER(drive)->do_request = promise_rw_disk;
-#endif
-	
 	idedisk_add_settings(drive);
 
 	if (drive->id_read == 0)
@@ -1674,7 +1671,7 @@ static ide_driver_t idedisk_driver = {
 	.supports_dsc_overlap	= 0,
 	.cleanup		= idedisk_cleanup,
 	.flushcache		= do_idedisk_flushcache,
-	.do_request		= do_rw_disk,
+	.do_request		= ide_do_rw_disk,
 	.sense			= idedisk_dump_status,
 	.error			= idedisk_error,
 	.abort			= idedisk_abort,
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 5967fe4337787d972816a6a0c97018f320c3c953..142a84ae4507da513d26ae5821739215a374a826 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -913,6 +913,8 @@ int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp)
 		}
 		for (index = 0; index < MAX_HWIFS; ++index) {
 			hwif = &ide_hwifs[index];
+			if (hwif->hold)
+				continue;
 			if ((!hwif->present && !hwif->mate && !initializing) ||
 			    (!hwif->hw.io_ports[IDE_DATA_OFFSET] && initializing))
 				goto found;
@@ -924,6 +926,8 @@ int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp)
 found:
 	if (hwif->present)
 		ide_unregister(index);
+	else if (!hwif->hold)
+		init_hwif_data(index);
 	if (hwif->present)
 		return -1;
 	memcpy(&hwif->hw, hw, sizeof(*hw));
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c
index 5d3e85a59e33e863d3b2d1c8336147d6093117d6..acbe02fc156a6c7e3d6f43b07eedee633ab15c7a 100644
--- a/drivers/ide/legacy/ali14xx.c
+++ b/drivers/ide/legacy/ali14xx.c
@@ -54,13 +54,7 @@
 
 #include <asm/io.h>
 
-#ifdef CONFIG_BLK_DEV_ALI14XX_MODULE
-# define _IDE_C
-# include "ide_modes.h"
-# undef _IDE_C
-#else
-# include "ide_modes.h"
-#endif /* CONFIG_BLK_DEV_ALI14XX_MODULE */
+#include "ide_modes.h"
 
 /* port addresses for auto-detection */
 #define ALI_NUM_PORTS 4
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c
index fad634599dd081d006f47c68511fc72a3fdf45b3..c89e28e8894076b47fbb6845bb03825c7e000fd2 100644
--- a/drivers/ide/legacy/dtc2278.c
+++ b/drivers/ide/legacy/dtc2278.c
@@ -21,13 +21,7 @@
 
 #include <asm/io.h>
 
-#ifdef CONFIG_BLK_DEV_DTC2278_MODULE
-# define _IDE_C
-# include "ide_modes.h"
-# undef _IDE_C
-#else
-# include "ide_modes.h"
-#endif /* CONFIG_BLK_DEV_DTC2278_MODULE */
+#include "ide_modes.h"
 
 /*
  * Changing this #undef to #define may solve start up problems in some systems.
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index 104a99d1af0f9a30ae6cd7f4fcf207c3f35d0684..dc5cfc7a8c4e347778e4f637556ff8eda81ba8bd 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -53,13 +53,7 @@
 
 #include <asm/io.h>
 
-#ifdef CONFIG_BLK_DEV_HT6560B_MODULE
-# define _IDE_C
-# include "ide_modes.h"
-# undef _IDE_C
-#else
-# include "ide_modes.h"
-#endif /* CONFIG_BLK_DEV_HT6560B_MODULE */
+#include "ide_modes.h"
 
 /* #define DEBUG */  /* remove comments for DEBUG messages */
 
diff --git a/drivers/ide/legacy/pdc4030.c b/drivers/ide/legacy/pdc4030.c
index c1c407319b4d463cbf9332b9972ad1515aaf2321..8a1967a7c52550050869e801230c4e58a9173733 100644
--- a/drivers/ide/legacy/pdc4030.c
+++ b/drivers/ide/legacy/pdc4030.c
@@ -94,6 +94,8 @@
 
 #include "pdc4030.h"
 
+static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block);
+
 /*
  * promise_selectproc() is invoked by ide.c
  * in preparation for access to the specified drive.
@@ -231,6 +233,10 @@ int __init setup_pdc4030(ide_hwif_t *hwif)
 	/* DC4030 hosted drives need their own identify... */
 	hwif->identify = hwif2->identify = &pdc4030_identify;
 
+	/* Override the normal ide disk read/write. */
+	hwif->rw_disk = promise_rw_disk;
+	hwif2->rw_disk = promise_rw_disk;
+
 	/* Shift the remaining interfaces up by one */
 	for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) {
 		ide_hwif_t *h = &ide_hwifs[i];
@@ -803,7 +809,7 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task)
 	}
 }
 
-ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
 {
 	/* The four drives on the two logical (one physical) interfaces
 	   are distinguished by writing the drive number (0-3) to the
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c
index d1c1db4cb28379af920accb9cee5a6d1fd232c67..3ff868a5896d2ee8a2e1c31527641a9f233912f2 100644
--- a/drivers/ide/legacy/qd65xx.c
+++ b/drivers/ide/legacy/qd65xx.c
@@ -42,14 +42,7 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
-#ifdef CONFIG_BLK_DEV_QD65XX_MODULE
-# define _IDE_C
-# include "ide_modes.h"
-# undef _IDE_C
-#else
-# include "ide_modes.h"
-#endif /* CONFIG_BLK_DEV_QD65XX_MODULE */
-
+#include "ide_modes.h"
 #include "qd65xx.h"
 
 /*
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c
index 8bf4dc26799cafb7d55549ca566ce0dbddb75764..1ff2a8cc844214f0bb4e47126059df1ea031512f 100644
--- a/drivers/ide/legacy/umc8672.c
+++ b/drivers/ide/legacy/umc8672.c
@@ -54,13 +54,7 @@
 
 #include <asm/io.h>
 
-#ifdef CONFIG_BLK_DEV_UMC8672_MODULE
-# define _IDE_C
-# include "ide_modes.h"
-# undef _IDE_C
-#else
-# include "ide_modes.h"
-#endif /* CONFIG_BLK_DEV_UMC8672_MODULE */
+#include "ide_modes.h"
 
 /*
  * Default speeds.  These can be changed with "auto-tune" and/or hdparm.
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 96c0d428069894c9f4724c25397cd5a052aab13a..2970429d745f4a1d793efafe147d9988c13d4dbc 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -313,7 +313,8 @@ static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char
 
 		case AMD_UDMA_100:
 			pci_read_config_byte(dev, AMD_CABLE_DETECT, &t);
-			amd_80w = ((u & 0x3) ? 1 : 0) | ((u & 0xc) ? 2 : 0);
+			pci_read_config_dword(dev, AMD_UDMA_TIMING, &u);
+			amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0);
 			for (i = 24; i >= 0; i -= 8)
 				if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) {
 					printk(KERN_WARNING "AMD_IDE: Bios didn't set cable bits correctly. Enabling workaround.\n");
@@ -383,11 +384,6 @@ static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char
 	return 0;
 }
 
-static unsigned int __init ata66_amd74xx(ide_hwif_t *hwif)
-{
-	return ((amd_enabled & amd_80w) >> hwif->channel) & 1;
-}
-
 static void __init init_hwif_amd74xx(ide_hwif_t *hwif)
 {
 	int i;
diff --git a/drivers/ide/pci/amd74xx.h b/drivers/ide/pci/amd74xx.h
index e5984607cb56d1390c4ec12dd7449f51a07e5761..af8e0ed51330ce719a15e753d5005d3bd1d84c58 100644
--- a/drivers/ide/pci/amd74xx.h
+++ b/drivers/ide/pci/amd74xx.h
@@ -40,7 +40,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0
 	},{	/* 1 */
@@ -53,7 +53,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0
 	},{	/* 2 */
@@ -66,7 +66,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0
 	},{	/* 3 */
@@ -79,7 +79,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0
 	},{	/* 4 */
@@ -92,7 +92,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
 		.init_dma	= init_dma_amd74xx,
 		.autodma	= AUTODMA,
 		.channels	= 2,
-		.enablebits	= {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0
 	},
@@ -106,7 +106,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x50,0x01,0x01}, {0x50,0x02,0x02}},
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0,
 	},
@@ -120,7 +120,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x50,0x01,0x01}, {0x50,0x02,0x02}},
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0,
 	},
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index e9952c84c23680e1755e0457b249c34b1be7edf3..e3302e156c1632fb5fd8481a827b9abe7980d509 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -142,6 +142,9 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
 		p += sprintf(p, "\nController: %d\n", i);
 		p += sprintf(p, "\n                                Intel ");
 		switch(dev->device) {
+			case PCI_DEVICE_ID_INTEL_82801EB_1:
+				p += sprintf(p, "PIIX4 SATA 150 ");
+				break;
 			case PCI_DEVICE_ID_INTEL_82801BA_8:
 			case PCI_DEVICE_ID_INTEL_82801BA_9:
 			case PCI_DEVICE_ID_INTEL_82801CA_10:
@@ -275,6 +278,9 @@ static u8 piix_ratemask (ide_drive_t *drive)
 	u8 mode;
 
 	switch(dev->device) {
+		case PCI_DEVICE_ID_INTEL_82801EB_1:
+			mode = 3;
+			break;
 		/* UDMA 100 capable */
 		case PCI_DEVICE_ID_INTEL_82801BA_8:
 		case PCI_DEVICE_ID_INTEL_82801BA_9:
@@ -325,6 +331,7 @@ static u8 piix_ratemask (ide_drive_t *drive)
  
 static u8 piix_dma_2_pio (u8 xfer_rate) {
 	switch(xfer_rate) {
+		case XFER_UDMA_6:
 		case XFER_UDMA_5:
 		case XFER_UDMA_4:
 		case XFER_UDMA_3:
@@ -603,6 +610,7 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive)
 static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
 {
         switch(dev->device) {
+		case PCI_DEVICE_ID_INTEL_82801EB_1:
 		case PCI_DEVICE_ID_INTEL_82801AA_1:
 		case PCI_DEVICE_ID_INTEL_82801AB_1:
 		case PCI_DEVICE_ID_INTEL_82801BA_8:
@@ -803,6 +811,7 @@ static struct pci_device_id piix_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15},
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16},
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17},
+ 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18},
 	{ 0, },
 };
 
diff --git a/drivers/ide/pci/piix.h b/drivers/ide/pci/piix.h
index 4502d2347112904eb2c3fe868f040b9781fe34df..87c8047da40bcdb70b8b45f096351ae17570ab11 100644
--- a/drivers/ide/pci/piix.h
+++ b/drivers/ide/pci/piix.h
@@ -291,10 +291,10 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = {
 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
 		.bootable	= ON_BOARD,
 		.extra		= 0,
-	},{	/* 17 */
+	},{	/* 18 */
 		.vendor		= PCI_VENDOR_ID_INTEL,
-		.device		= PCI_DEVICE_ID_INTEL_82801DB_10,
-		.name		= "ICH4",
+		.device		= PCI_DEVICE_ID_INTEL_82801EB_1,
+		.name		= "ICH5-SATA",
 		.init_setup	= init_setup_piix,
 		.init_chipset	= init_chipset_piix,
 		.init_iops	= NULL,
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index ae383cd05862ba2834fbd902a5ca12709299824d..6ae4c62089641c4df6054888045c320b7e2e168f 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/serverworks.c		Version 0.7	10 Sept 2002
+ * linux/drivers/ide/pci/serverworks.c		Version 0.8	 25 Ebr 2003
  *
  * Copyright (C) 1998-2000 Michel Aubry
  * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
@@ -203,11 +203,22 @@ static int svwks_get_info (char *buffer, char **addr, off_t offset, int count)
 }
 #endif  /* defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS) */
 
+static int check_in_drive_lists (ide_drive_t *drive, const char **list)
+{
+	while (*list)
+		if (!strcmp(*list++, drive->id->model))
+			return 1;
+	return 0;
+}
+
 static u8 svwks_ratemask (ide_drive_t *drive)
 {
 	struct pci_dev *dev     = HWIF(drive)->pci_dev;
 	u8 mode;
 
+	if (!svwks_revision)
+		pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
+
 	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
 		u32 reg = 0;
 		if (isa_dev)
@@ -225,9 +236,13 @@ static u8 svwks_ratemask (ide_drive_t *drive)
 	} else if (svwks_revision >= SVWKS_CSB5_REVISION_NEW) {
 		u8 btr = 0;
 		pci_read_config_byte(dev, 0x5A, &btr);
-		mode = btr;
+		mode = btr & 0x3;
 		if (!eighty_ninty_three(drive))
 			mode = min(mode, (u8)1);
+		/* If someone decides to do UDMA133 on CSB5 the same
+		   issue will bite so be inclusive */
+		if (mode > 2 && check_in_drive_lists(drive, svwks_bad_ata100))
+			mode = 2;
 	}
 	if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
 	     (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) &&
@@ -419,13 +434,10 @@ static void config_chipset_for_pio (ide_drive_t *drive)
 
 static void svwks_tune_drive (ide_drive_t *drive, u8 pio)
 {
-	/* Tune to desired value or to "best". We must not adjust
-	   "best" when we adjust from pio numbers to rate values! */
-	   
-	if(pio != 255)
-		(void) svwks_tune_chipset(drive, (XFER_PIO_0 + pio));
-	else
+	if(pio == 255)
 		(void) svwks_tune_chipset(drive, 255);
+	else
+		(void) svwks_tune_chipset(drive, (XFER_PIO_0 + pio));
 }
 
 static int config_chipset_for_dma (ide_drive_t *drive)
@@ -446,7 +458,7 @@ static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
 
 	drive->init_speed = 0;
 
-	if (id && (id->capability & 1) && drive->autodma) {
+	if ((id->capability & 1) && drive->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (hwif->ide_dma_bad_drive(drive))
 			goto fast_ata_pio;
@@ -483,28 +495,10 @@ static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
 	return hwif->ide_dma_on(drive);
 }
 
+/* This can go soon */
+
 static int svwks_ide_dma_end (ide_drive_t *drive)
 {
-	/*
-	 *	We never place the OSB4 into a UDMA mode with a disk
-	 *	medium, that means the UDMA "all my data is 4 byte shifted"
-	 *	problem cannot occur.
-	 */
-#if 0
-	ide_hwif_t *hwif	= HWIF(drive);
-	u8 dma_stat		= hwif->INB(hwif->dma_status);
-
-	if ((dma_stat & 1) && drive->media == ide_disk)
-	{
-		printk(KERN_CRIT "Serverworks OSB4 in impossible state.\n");
-		printk(KERN_CRIT "Disable UDMA or if you are using Seagate then try switching disk types\n");
-		printk(KERN_CRIT "on this controller. Please report this event to osb4-bug@ide.cabal.tm\n");
-		/* Panic might sys_sync -> death by corrupt disk */
-		printk(KERN_CRIT "OSB4: continuing might cause disk corruption.\n");
-		while(1)
-			cpu_relax();
-	}
-#endif	
 	return __ide_dma_end(drive);
 }
 
@@ -630,8 +624,6 @@ static unsigned int __init init_chipset_svwks (struct pci_dev *dev, const char *
 
 static unsigned int __init ata66_svwks_svwks (ide_hwif_t *hwif)
 {
-//	struct pci_dev *dev = hwif->pci_dev;
-//	return 0;
 	return 1;
 }
 
diff --git a/drivers/ide/pci/serverworks.h b/drivers/ide/pci/serverworks.h
index 73e9b6b4f0f44777438fd458b66bc3ec736bf3a0..aec835380e293d16113d88aeda1e69ccf3aadd2e 100644
--- a/drivers/ide/pci/serverworks.h
+++ b/drivers/ide/pci/serverworks.h
@@ -11,6 +11,16 @@
 #define SVWKS_CSB5_REVISION_NEW	0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
 #define SVWKS_CSB6_REVISION	0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
 
+/* Seagate Barracuda ATA IV Family drives in UDMA mode 5
+ * can overrun their FIFOs when used with the CSB5 */
+const char *svwks_bad_ata100[] = {
+	"ST320011A",
+	"ST340016A",
+	"ST360021A",
+	"ST380021A",
+	NULL
+};
+
 #define DISPLAY_SVWKS_TIMINGS	1
 
 #if defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS)
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 6f41eade2bfb632f637b687ab530af08b210d641..5b7d079bf96ac21de63256c8d24d943bf76a321e 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -161,9 +161,10 @@ static const struct {
 	{ "SiS748",	PCI_DEVICE_ID_SI_748,	ATA_133,	0 },
 	{ "SiS746",	PCI_DEVICE_ID_SI_746,	ATA_133,	0 },
 	{ "SiS745",	PCI_DEVICE_ID_SI_745,	ATA_133,	0 },
-	{ "SiS740",	PCI_DEVICE_ID_SI_740,	ATA_100,	0 },
+	{ "SiS740",	PCI_DEVICE_ID_SI_740,	ATA_133,	0 },
 	{ "SiS735",	PCI_DEVICE_ID_SI_735,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS730",	PCI_DEVICE_ID_SI_730,	ATA_100a,	SIS5513_LATENCY },
+	{ "SiS655",	PCI_DEVICE_ID_SI_655,	ATA_133,	0 },
 	{ "SiS652",	PCI_DEVICE_ID_SI_652,	ATA_133,	0 },
 	{ "SiS651",	PCI_DEVICE_ID_SI_651,	ATA_133,	0 },
 	{ "SiS650",	PCI_DEVICE_ID_SI_650,	ATA_133,	0 },
@@ -257,8 +258,8 @@ static struct pci_dev *host_dev = NULL;
 static char* chipset_capability[] = {
 	"ATA", "ATA 16",
 	"ATA 33", "ATA 66",
-	"ATA 100", "ATA 100",
-	"ATA 133", "ATA 133"
+	"ATA 100 (1st gen)", "ATA 100 (2nd gen)",
+	"ATA 133 (1st gen)", "ATA 133 (2nd gen)"
 };
 
 #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
@@ -331,8 +332,8 @@ static char* get_drives_info (char *buffer, u8 pos)
 			// Configuration space remapped to 0x70
 			drive_pci = 0x70;
 		}
-		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+8*pos, &regdw0);
-		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+8*pos+4, &regdw1);
+		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos, &regdw0);
+		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos+8, &regdw1);
 		p += sprintf(p, "Drive %d:\n", pos);
 	}
 
@@ -357,8 +358,7 @@ static char* get_drives_info (char *buffer, u8 pos)
 			case ATA_100a:	p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break;
 			case ATA_100:
 			case ATA_133a:	p += sprintf(p, cycle_time[reg01 & 0x0F]); break;
-			case ATA_133:
-			default:	p += sprintf(p, "133+ ?"); break;
+			default:	p += sprintf(p, "?"); break;
 		}
 		p += sprintf(p, " \t UDMA Cycle Time    ");
 		switch(chipset_family) {
@@ -367,42 +367,39 @@ static char* get_drives_info (char *buffer, u8 pos)
 			case ATA_100a:	p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break;
 			case ATA_100:
 			case ATA_133a:  p += sprintf(p, cycle_time[reg11 & 0x0F]); break;
-			case ATA_133:
-			default:	p += sprintf(p, "133+ ?"); break;
+			default:	p += sprintf(p, "?"); break;
 		}
 		p += sprintf(p, "\n");
 	}
 
+	if (chipset_family < ATA_133) { /* else case TODO */
 /* Data Active */
-	p += sprintf(p, "                Data Active Time   ");
-	switch(chipset_family) {
-		case ATA_00:
-		case ATA_16: /* confirmed */
-		case ATA_33:
-		case ATA_66:
-		case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break;
-		case ATA_100:
-		case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break;
-		case ATA_133:
-		default: p += sprintf(p, "133+ ?"); break;
-	}
-	p += sprintf(p, " \t Data Active Time   ");
-	switch(chipset_family) {
-		case ATA_00:
-		case ATA_16:
-		case ATA_33:
-		case ATA_66:
-		case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break;
-		case ATA_100:
-		case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break;
-		case ATA_133:
-		default: p += sprintf(p, "133+ ?"); break;
-	}
-	p += sprintf(p, "\n");
+		p += sprintf(p, "                Data Active Time   ");
+		switch(chipset_family) {
+			case ATA_00:
+			case ATA_16: /* confirmed */
+			case ATA_33:
+			case ATA_66:
+			case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break;
+			case ATA_100:
+			case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break;
+			default: p += sprintf(p, "?"); break;
+		}
+		p += sprintf(p, " \t Data Active Time   ");
+		switch(chipset_family) {
+			case ATA_00:
+			case ATA_16:
+			case ATA_33:
+			case ATA_66:
+			case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break;
+			case ATA_100:
+			case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break;
+			default: p += sprintf(p, "?"); break;
+		}
+		p += sprintf(p, "\n");
 
 /* Data Recovery */
 	/* warning: may need (reg&0x07) for pre ATA66 chips */
-	if (chipset_family < ATA_133) {
 		p += sprintf(p, "                Data Recovery Time %s \t Data Recovery Time %s\n",
 			     recovery_time[reg00 & 0x0f], recovery_time[reg10 & 0x0f]);
 	}
@@ -430,7 +427,6 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
 
 	p += sprintf(p, "\nSiS 5513 ");
 	switch(chipset_family) {
-		case ATA_00: p += sprintf(p, "Unknown???"); break;
 		case ATA_16: p += sprintf(p, "DMA 16"); break;
 		case ATA_33: p += sprintf(p, "Ultra 33"); break;
 		case ATA_66: p += sprintf(p, "Ultra 66"); break;
@@ -867,6 +863,19 @@ static int sis5513_config_xfer_rate (ide_drive_t *drive)
 	return sis5513_config_drive_xfer_rate(drive);
 }
 
+/* Helper function used at init time
+ * returns a PCI device revision ID
+ * (used to detect different IDE controller versions)
+ */
+static u8 __init devfn_rev(int device, int function)
+{
+	u8 revision;
+	/* Find device */
+	struct pci_dev* dev = pci_find_slot(0,PCI_DEVFN(device,function));
+	pci_read_config_byte(dev, PCI_REVISION_ID, &revision);
+	return revision;
+}
+
 /* Chip detection and general config */
 static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name)
 {
@@ -887,26 +896,24 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char
 		/* check 100/133 chipset family */
 		if (chipset_family == ATA_133) {
 			u32 reg54h;
-			u16 reg02h;
+			u16 devid;
 			pci_read_config_dword(dev, 0x54, &reg54h);
+			/* SiS962 and above report 0x5518 dev id if high bit is cleared */
 			pci_write_config_dword(dev, 0x54, (reg54h & 0x7fffffff));
-			pci_read_config_word(dev, 0x02, &reg02h);
+			pci_read_config_word(dev, 0x02, &devid);
+			/* restore register 0x54 */
 			pci_write_config_dword(dev, 0x54, reg54h);
+
 			/* devid 5518 here means SiS962 or later
-			   which supports ATA133 */
-			if (reg02h != 0x5518) {
+			   which supports ATA133.
+			   These are refered by chipset_family = ATA133
+			*/
+			if (devid != 0x5518) {
 				u8 reg49h;
-				unsigned long sbrev;
 				/* SiS961 family */
-
-		/*
-		 * FIXME !!! GAK!!!!!!!!!! PCI DIRECT POKING 
-		 */
-				outl(0x80001008, 0x0cf8);
-				sbrev = inl(0x0cfc);
-
 				pci_read_config_byte(dev, 0x49, &reg49h);
-				if (((sbrev & 0xff) == 0x10) && (reg49h & 0x80))
+				/* check isa bridge device rev id */
+				if (((devfn_rev(2,0) & 0xff) == 0x10) && (reg49h & 0x80))
 					chipset_family = ATA_133a;
 				else
 					chipset_family = ATA_100;
@@ -924,6 +931,14 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char
 			u8 latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */
 			pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
 		}
+
+		/* Special case for SiS630 : 630S/ET is ATA_100a */
+		if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) {
+			/* check host device rev id */
+			if (devfn_rev(0,0) >= 0x30) {
+				chipset_family = ATA_100a;
+			}
+		}
 	}
 
 	/* Make general config ops here
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 93014269ee5bf22c78a5d63725751ddc4232a2b4..7261140d50445b2ffea18d30adea25de58b562e4 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -1,12 +1,12 @@
 /*
  *
- * Version 3.36
+ * Version 3.37
  *
  * VIA IDE driver for Linux. Supported southbridges:
  *
  *   vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
  *   vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a,
- *   vt8235
+ *   vt8235, vt8237
  *
  * Copyright (c) 2000-2002 Vojtech Pavlik
  *
@@ -74,9 +74,7 @@ static struct via_isa_bridge {
 	u8 rev_max;
 	u16 flags;
 } via_isa_bridges[] = {
-#ifdef FUTURE_BRIDGES
-	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 },
-#endif
+	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8233c",	PCI_DEVICE_ID_VIA_8233C_0,  0x00, 0x2f, VIA_UDMA_100 },
@@ -148,7 +146,7 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count)
 	via_print("----------VIA BusMastering IDE Configuration"
 		"----------------");
 
-	via_print("Driver Version:                     3.36");
+	via_print("Driver Version:                     3.37");
 	via_print("South Bridge:                       VIA %s",
 		via_config->name);
 
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index e25c4dbe595a29b7254bd6636040cce5daa3562e..ce1b710e0884c2cf8db5ebc272f6189ef63f320c 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -635,7 +635,22 @@ static void __init quirk_via_bridge(struct pci_dev *pdev)
 	if(pdev->devfn == 0)
 		interrupt_line_quirk = 1;
 }
-	
+
+/*
+ *	Serverworks CSB5 IDE does not fully support native mode
+ */
+static void __init quirk_svwks_csb5ide(struct pci_dev *pdev)
+{
+	u8 prog;
+	pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
+	if (prog & 5) {
+		prog &= ~5;
+		pdev->class &= ~5;
+		pci_write_config_byte(pdev, PCI_CLASS_PROG, prog);
+		/* need to re-assign BARs for compat mode */
+		quirk_ide_bases(pdev);
+	}
+}
 
 /* This was originally an Alpha specific thing, but it really fits here.
  * The i82375 PCI/EISA bridge appears as non-classified. Fix that.
@@ -812,7 +827,9 @@ static struct pci_fixup pci_fixups[] __devinitdata = {
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_TOSHIBA,	0x605,	quirk_transparent_bridge },
 
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_CYRIX,	PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master },
-	
+
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide },
+
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82375,	quirk_eisa_bridge },
 
 	/*
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index f7532f979c7fc6e45b30a4c3c4f88b8f032bcb31..3fda218d6de3af8c731cb681e7f940e0ab7b71ef 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -64,7 +64,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20030418
+#define ACPI_CA_VERSION                 0x20030522
 
 /* Maximum objects in the various object caches */
 
@@ -133,6 +133,11 @@
 
 #define ACPI_MAX_STRING_CONVERSION      200
 
+/* Length of _HID, _UID, and _CID values */
+
+#define ACPI_DEVICE_ID_LENGTH           0x09
+#define ACPI_MAX_CID_LENGTH             48
+
 /*
  * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG
  */
diff --git a/include/acpi/acdebug.h b/include/acpi/acdebug.h
index 65c18eba57a6f7d774d1b1b940cd4d242eda8e51..60cf6eac7a07db70751da169c83497f54f821a70 100644
--- a/include/acpi/acdebug.h
+++ b/include/acpi/acdebug.h
@@ -229,10 +229,6 @@ acpi_db_decode_and_display_object (
 	char                            *target,
 	char                            *output_type);
 
-void
-acpi_db_decode_node (
-	struct acpi_namespace_node      *node);
-
 void
 acpi_db_display_result_object (
 	union acpi_operand_object       *obj_desc,
@@ -242,11 +238,6 @@ acpi_status
 acpi_db_display_all_methods (
 	char                            *display_count_arg);
 
-void
-acpi_db_display_internal_object (
-	union acpi_operand_object       *obj_desc,
-	struct acpi_walk_state          *walk_state);
-
 void
 acpi_db_display_arguments (
 	void);
@@ -263,6 +254,10 @@ void
 acpi_db_display_calling_tree (
 	void);
 
+void
+acpi_db_display_object_type (
+	char                            *object_arg);
+
 void
 acpi_db_display_argument_object (
 	union acpi_operand_object       *obj_desc,
@@ -276,10 +271,6 @@ void *
 acpi_db_get_pointer (
 	void                            *target);
 
-void
-acpi_db_decode_internal_object (
-	union acpi_operand_object       *obj_desc);
-
 
 /*
  * dbexec - debugger control method execution
diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h
new file mode 100644
index 0000000000000000000000000000000000000000..e2938c593e2c1f3d95ec570c92aac872946cb98b
--- /dev/null
+++ b/include/acpi/acdisasm.h
@@ -0,0 +1,406 @@
+/******************************************************************************
+ *
+ * Name: acdisasm.h - AML disassembler
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2003, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef __ACDISASM_H__
+#define __ACDISASM_H__
+
+#include "amlresrc.h"
+
+
+#define BLOCK_NONE              0
+#define BLOCK_PAREN             1
+#define BLOCK_BRACE             2
+#define BLOCK_COMMA_LIST        4
+
+extern const char                       *acpi_gbl_io_decode[2];
+extern const char                       *acpi_gbl_word_decode[4];
+extern const char                       *acpi_gbl_consume_decode[2];
+extern const char                       *acpi_gbl_min_decode[2];
+extern const char                       *acpi_gbl_max_decode[2];
+extern const char                       *acpi_gbl_DECdecode[2];
+extern const char                       *acpi_gbl_RNGdecode[4];
+extern const char                       *acpi_gbl_MEMdecode[4];
+extern const char                       *acpi_gbl_RWdecode[2];
+extern const char                       *acpi_gbl_irq_decode[2];
+extern const char                       *acpi_gbl_HEdecode[2];
+extern const char                       *acpi_gbl_LLdecode[2];
+extern const char                       *acpi_gbl_SHRdecode[2];
+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_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];
+extern const char                       *acpi_gbl_match_ops[ACPI_NUM_MATCH_OPS];
+
+
+struct acpi_op_walk_info
+{
+	u32                             level;
+	u32                             bit_offset;
+};
+
+typedef
+acpi_status (*asl_walk_callback) (
+	union acpi_parse_object             *op,
+	u32                                 level,
+	void                                *context);
+
+
+/*
+ * dmwalk
+ */
+
+void
+acpi_dm_walk_parse_tree (
+	union acpi_parse_object         *op,
+	asl_walk_callback               descending_callback,
+	asl_walk_callback               ascending_callback,
+	void                            *context);
+
+acpi_status
+acpi_dm_descending_op (
+	union acpi_parse_object         *op,
+	u32                             level,
+	void                            *context);
+
+acpi_status
+acpi_dm_ascending_op (
+	union acpi_parse_object         *op,
+	u32                             level,
+	void                            *context);
+
+
+/*
+ * dmopcode
+ */
+
+void
+acpi_dm_validate_name (
+	char                            *name,
+	union acpi_parse_object         *op);
+
+u32
+acpi_dm_dump_name (
+	char                            *name);
+
+void
+acpi_dm_unicode (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_disassemble (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *origin,
+	u32                             num_opcodes);
+
+void
+acpi_dm_namestring (
+	char                            *name);
+
+void
+acpi_dm_display_path (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_disassemble_one_op (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_op_walk_info        *info,
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_decode_internal_object (
+	union acpi_operand_object       *obj_desc);
+
+void
+acpi_dm_decode_node (
+	struct acpi_namespace_node      *node);
+
+u32
+acpi_dm_block_type (
+	union acpi_parse_object         *op);
+
+u32
+acpi_dm_list_type (
+	union acpi_parse_object         *op);
+
+acpi_status
+acpi_ps_display_object_pathname (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_method_flags (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_field_flags (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_address_space (
+	u8                              space_id);
+
+void
+acpi_dm_region_flags (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_match_op (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_match_keyword (
+	union acpi_parse_object         *op);
+
+u8
+acpi_dm_comma_if_list_member (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_comma_if_field_member (
+	union acpi_parse_object         *op);
+
+
+/*
+ * dmobject
+ */
+
+void
+acpi_dm_decode_node (
+	struct acpi_namespace_node      *node);
+
+void
+acpi_dm_display_internal_object (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_dm_display_arguments (
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_dm_display_locals (
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_dm_dump_method_info (
+	acpi_status                     status,
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+
+/*
+ * dmbuffer
+ */
+
+void
+acpi_is_eisa_id (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_eisa_id (
+	u32                             encoded_id);
+
+u8
+acpi_dm_is_unicode_buffer (
+	union acpi_parse_object         *op);
+
+u8
+acpi_dm_is_string_buffer (
+	union acpi_parse_object         *op);
+
+
+/*
+ * dmresrc
+ */
+
+void
+acpi_dm_disasm_byte_list (
+	u32                             level,
+	u8                              *byte_data,
+	u32                             byte_count);
+
+void
+acpi_dm_byte_list (
+	struct acpi_op_walk_info        *info,
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_resource_descriptor (
+	struct acpi_op_walk_info        *info,
+	u8                              *byte_data,
+	u32                             byte_count);
+
+u8
+acpi_dm_is_resource_descriptor (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_indent (
+	u32                             level);
+
+void
+acpi_dm_bit_list (
+	u16                             mask);
+
+void
+acpi_dm_decode_attribute (
+	u8                              attribute);
+
+/*
+ * dmresrcl
+ */
+
+void
+acpi_dm_io_flags (
+		u8                          flags);
+
+void
+acpi_dm_memory_flags (
+	u8                              flags,
+	u8                              specific_flags);
+
+void
+acpi_dm_word_descriptor (
+	struct asl_word_address_desc    *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_dword_descriptor (
+	struct asl_dword_address_desc   *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_qword_descriptor (
+	struct asl_qword_address_desc   *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_memory24_descriptor (
+	struct asl_memory_24_desc       *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_memory32_descriptor (
+	struct asl_memory_32_desc       *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_fixed_mem32_descriptor (
+	struct asl_fixed_memory_32_desc *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_generic_register_descriptor (
+	struct asl_general_register_desc *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_interrupt_descriptor (
+	struct asl_extended_xrupt_desc *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_vendor_large_descriptor (
+	struct asl_large_vendor_desc    *resource,
+	u32                             length,
+	u32                             level);
+
+
+/*
+ * dmresrcs
+ */
+
+void
+acpi_dm_irq_descriptor (
+	struct asl_irq_format_desc      *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_dma_descriptor (
+	struct asl_dma_format_desc      *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_io_descriptor (
+	struct asl_io_port_desc         *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_fixed_io_descriptor (
+	struct asl_fixed_io_port_desc   *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_start_dependent_descriptor (
+	struct asl_start_dependent_desc *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_end_dependent_descriptor (
+	struct asl_start_dependent_desc *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_vendor_small_descriptor (
+	struct asl_small_vendor_desc    *resource,
+	u32                             length,
+	u32                             level);
+
+
+#endif  /* __ACDISASM_H__ */
diff --git a/include/acpi/acevents.h b/include/acpi/acevents.h
index f23360115e8385de6f796a012391684b8df983b6..38664422c5552ce42b900117eebec90710f07ded 100644
--- a/include/acpi/acevents.h
+++ b/include/acpi/acevents.h
@@ -165,7 +165,7 @@ acpi_ev_address_space_dispatch (
 	void                            *value);
 
 acpi_status
-acpi_ev_addr_handler_helper (
+acpi_ev_install_handler (
 	acpi_handle                     obj_handle,
 	u32                             level,
 	void                            *context,
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index cc0bb192980c63633de32742dd9c8168c90cfb88..d225bdd2b9b9136ed66b38d00825807f84438320 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -94,8 +94,9 @@
 #define AE_NO_GLOBAL_LOCK               (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
 #define AE_LOGICAL_ADDRESS              (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
 #define AE_ABORT_METHOD                 (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL)
+#define AE_SAME_HANDLER                 (acpi_status) (0x001D | AE_CODE_ENVIRONMENTAL)
 
-#define AE_CODE_ENV_MAX                 0x001C
+#define AE_CODE_ENV_MAX                 0x001D
 
 /*
  * Programmer exceptions
@@ -219,7 +220,8 @@ char const   *acpi_gbl_exception_names_env[] =
 	"AE_NO_HARDWARE_RESPONSE",
 	"AE_NO_GLOBAL_LOCK",
 	"AE_LOGICAL_ADDRESS",
-	"AE_ABORT_METHOD"
+	"AE_ABORT_METHOD",
+	"AE_SAME_HANDLER"
 };
 
 char const   *acpi_gbl_exception_names_pgm[] =
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
index 55f7eb9b71408135b25f951e4eaba64aacfc9273..254d11a7ac5e95502411e041988474136e1cd156 100644
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -105,6 +105,8 @@ ACPI_EXTERN struct acpi_common_facs             acpi_gbl_common_fACS;
  */
 ACPI_EXTERN u8                                  acpi_gbl_integer_bit_width;
 ACPI_EXTERN u8                                  acpi_gbl_integer_byte_width;
+ACPI_EXTERN struct acpi_generic_address         acpi_gbl_xpm1a_enable;
+ACPI_EXTERN struct acpi_generic_address         acpi_gbl_xpm1b_enable;
 
 /*
  * Since there may be multiple SSDTs and PSDTS, a single pointer is not
@@ -115,15 +117,15 @@ ACPI_EXTERN u8                                  acpi_gbl_integer_byte_width;
 /*
  * ACPI Table info arrays
  */
-extern      struct acpi_table_desc              acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
-extern      struct acpi_table_support           acpi_gbl_acpi_table_data[NUM_ACPI_TABLES];
+extern      struct acpi_table_list              acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
+extern      struct acpi_table_support           acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES];
 
 /*
  * Predefined mutex objects.  This array contains the
  * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs.
  * (The table maps local handles to the real OS handles)
  */
-ACPI_EXTERN struct acpi_mutex_info              acpi_gbl_acpi_mutex_info [NUM_MTX];
+ACPI_EXTERN struct acpi_mutex_info              acpi_gbl_mutex_info[NUM_MUTEX];
 
 
 /*****************************************************************************
@@ -134,8 +136,8 @@ ACPI_EXTERN struct acpi_mutex_info              acpi_gbl_acpi_mutex_info [NUM_MT
 
 
 ACPI_EXTERN struct acpi_memory_list             acpi_gbl_memory_lists[ACPI_NUM_MEM_LISTS];
-ACPI_EXTERN struct acpi_object_notify_handler   acpi_gbl_drv_notify;
-ACPI_EXTERN struct acpi_object_notify_handler   acpi_gbl_sys_notify;
+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_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;
@@ -200,7 +202,7 @@ ACPI_EXTERN u32                                 acpi_gbl_deepest_nesting;
  ****************************************************************************/
 
 
-ACPI_EXTERN struct acpi_thread_state            *acpi_gbl_current_walk_list;
+ACPI_EXTERN struct acpi_thread_state           *acpi_gbl_current_walk_list;
 
 /* Control method single step flag */
 
@@ -213,7 +215,7 @@ ACPI_EXTERN u8                                  acpi_gbl_cm_single_step;
  *
  ****************************************************************************/
 
-ACPI_EXTERN union acpi_parse_object             *acpi_gbl_parsed_namespace_root;
+ACPI_EXTERN union acpi_parse_object            *acpi_gbl_parsed_namespace_root;
 
 /*****************************************************************************
  *
@@ -234,8 +236,8 @@ ACPI_EXTERN u8                                  acpi_gbl_sleep_type_b;
 
 extern      struct acpi_fixed_event_info        acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS];
 ACPI_EXTERN struct acpi_fixed_event_handler     acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
-ACPI_EXTERN struct acpi_gpe_xrupt_info          *acpi_gbl_gpe_xrupt_list_head;
-ACPI_EXTERN struct acpi_gpe_block_info          *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
+ACPI_EXTERN struct acpi_gpe_xrupt_info         *acpi_gbl_gpe_xrupt_list_head;
+ACPI_EXTERN struct acpi_gpe_block_info         *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
 ACPI_EXTERN acpi_handle                         acpi_gbl_gpe_lock;
 
 
diff --git a/include/acpi/achware.h b/include/acpi/achware.h
index 1d34e757d11fbd0f0189372d3fbc2b3b30698a82..4be6958950e6616cc1b2c80073c368796cf9d64f 100644
--- a/include/acpi/achware.h
+++ b/include/acpi/achware.h
@@ -98,15 +98,13 @@ acpi_status
 acpi_hw_low_level_read (
 	u32                             width,
 	u32                             *value,
-	struct acpi_generic_address     *reg,
-	u32                             offset);
+	struct acpi_generic_address     *reg);
 
 acpi_status
 acpi_hw_low_level_write (
 	u32                             width,
 	u32                             value,
-	struct acpi_generic_address     *reg,
-	u32                             offset);
+	struct acpi_generic_address     *reg);
 
 acpi_status
 acpi_hw_clear_acpi_status (
diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h
index fffbddc8f532a873f9c185491cac34acb23202a7..d0387af6169d1b96eb759a62eb18d1ece051aa45 100644
--- a/include/acpi/aclocal.h
+++ b/include/acpi/aclocal.h
@@ -87,8 +87,8 @@ typedef u32                                     acpi_mutex_handle;
 #define ACPI_MTX_DEBUG_CMD_COMPLETE     11
 #define ACPI_MTX_DEBUG_CMD_READY        12
 
-#define MAX_MTX                         12
-#define NUM_MTX                         MAX_MTX+1
+#define MAX_MUTEX                       12
+#define NUM_MUTEX                       MAX_MUTEX+1
 
 
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
@@ -140,12 +140,8 @@ struct acpi_mutex_info
 typedef u16                                     acpi_owner_id;
 #define ACPI_OWNER_TYPE_TABLE           0x0
 #define ACPI_OWNER_TYPE_METHOD          0x1
-#define ACPI_FIRST_METHOD_ID            0x0000
-#define ACPI_FIRST_TABLE_ID             0x8000
-
-/* TBD: [Restructure] get rid of the need for this! */
-
-#define TABLE_ID_DSDT                   (acpi_owner_id) 0x8000
+#define ACPI_FIRST_METHOD_ID            0x0001
+#define ACPI_FIRST_TABLE_ID             0xF000
 
 
 /* Field access granularities */
@@ -232,13 +228,18 @@ struct acpi_table_desc
 	u64                             physical_address;
 	u32                             aml_length;
 	acpi_size                       length;
-	u32                             count;
 	acpi_owner_id                   table_id;
 	u8                              type;
 	u8                              allocation;
 	u8                              loaded_into_namespace;
 };
 
+struct acpi_table_list
+{
+	struct acpi_table_desc          *next;
+	u32                             count;
+};
+
 
 struct acpi_find_context
 {
@@ -855,16 +856,6 @@ struct acpi_bit_register_info
 #define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE     0x8A
 
 
-/* String version of device HIDs and UIDs */
-
-#define ACPI_DEVICE_ID_LENGTH                   0x09
-
-struct acpi_device_id
-{
-	char                    buffer[ACPI_DEVICE_ID_LENGTH];
-};
-
-
 /*****************************************************************************
  *
  * Miscellaneous
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index 7b0f65b8439410a21c8a2b88abea3cc13f1c2936..7160c41972d1d6457fc632ca09d5d3a448bfc7b8 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -440,26 +440,6 @@
 #define INCREMENT_ARG_LIST(list)        (list >>= ((u32) ARG_TYPE_WIDTH))
 
 
-/*
- * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions)
- *
- * 1) Address space
- * 2) Length in bytes -- convert to length in bits
- * 3) Bit offset is zero
- * 4) Reserved field is zero
- * 5) Expand address to 64 bits
- */
-#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d)   do {a.address_space_id = (u8) d;\
-												a.register_bit_width = (u8) ACPI_MUL_8 (b);\
-												a.register_bit_offset = 0;\
-												a.reserved = 0;\
-												ACPI_STORE_ADDRESS (a.address,(acpi_physical_address) c);} while (0)
-
-/* ACPI V1.0 entries -- address space is always I/O */
-
-#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c)  ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ACPI_ADR_SPACE_SYSTEM_IO)
-
-
 /*
  * Reporting macros that are never compiled out
  */
diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h
index e809068247ff8841a1c02f6861b58ad682f7e257..f6e52a7837914a050b8018a29618d0b22e8b66c4 100644
--- a/include/acpi/acnamesp.h
+++ b/include/acpi/acnamesp.h
@@ -201,6 +201,11 @@ acpi_ns_compare_names (
 	char                            *name1,
 	char                            *name2);
 
+void
+acpi_ns_remove_reference (
+	struct acpi_namespace_node      *node);
+
+
 /*
  * Namespace modification - nsmodify
  */
diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h
index e121f26094d3c52698f5dfe2e781dd91ff9ab8d5..be30364c52184feebf4e2d9e83f8e4abe17870af 100644
--- a/include/acpi/acobject.h
+++ b/include/acpi/acobject.h
@@ -112,9 +112,9 @@
  * Common fields for objects that support ASL notifications
  */
 #define ACPI_COMMON_NOTIFY_INFO \
-	union acpi_operand_object               *sys_handler;        /* Handler for system notifies */\
-	union acpi_operand_object               *drv_handler;        /* Handler for driver notifies */\
-	union acpi_operand_object               *addr_handler;       /* Handler for Address space */
+	union acpi_operand_object               *system_notify;     /* Handler for system notifies */\
+	union acpi_operand_object               *device_notify;     /* Handler for driver notifies */\
+	union acpi_operand_object               *address_space;     /* Handler for Address space */
 
 
 /******************************************************************************
@@ -214,7 +214,7 @@ struct acpi_object_region
 	ACPI_OBJECT_COMMON_HEADER
 
 	u8                                      space_id;
-	union acpi_operand_object               *addr_handler;      /* Handler for system notifies */
+	union acpi_operand_object               *address_space;     /* Handler for region access */
 	struct acpi_namespace_node              *node;              /* containing object */
 	union acpi_operand_object               *next;
 	u32                                     length;
@@ -446,8 +446,8 @@ union acpi_operand_object
 	struct acpi_object_buffer_field         buffer_field;
 	struct acpi_object_bank_field           bank_field;
 	struct acpi_object_index_field          index_field;
-	struct acpi_object_notify_handler       notify_handler;
-	struct acpi_object_addr_handler         addr_handler;
+	struct acpi_object_notify_handler       notify;
+	struct acpi_object_addr_handler         address_space;
 	struct acpi_object_reference            reference;
 	struct acpi_object_extra                extra;
 	struct acpi_object_data                 data;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 8acb65f9eccdc43b5949143c947a4af9ffd0e180..7e0f5941433aab4ad7a3ac4143ad26b10dab4293 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -186,6 +186,7 @@ struct acpi_device_pnp {
 	acpi_bus_id		bus_id;		               /* Object name */
 	acpi_bus_address	bus_address;	                      /* _ADR */
 	acpi_hardware_id	hardware_id;	                      /* _HID */
+	struct acpi_compatible_id_list *cid_list;		     /* _CIDs */
 	acpi_unique_id		unique_id;	                      /* _UID */
 	acpi_device_name	device_name;	         /* Driver-determined */
 	acpi_device_class	device_class;	         /*        "          */
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 928b5f49030afda6f405e1a344f5492a8d220c44..bb6df66442bc15bf04e68a1fa59c912be217df34 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -290,12 +290,12 @@ acpi_os_derive_pci_id(
 u8
 acpi_os_readable (
 	void                            *pointer,
-	u32                             length);
+	acpi_size                       length);
 
 u8
 acpi_os_writable (
 	void                            *pointer,
-	u32                             length);
+	acpi_size                       length);
 
 u32
 acpi_os_get_timer (
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index aa97e22aeb0da9ae22febcc8236023fd1c96f8b3..cd4979869007fbfd6ed21a77119b902f95027603 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -228,8 +228,8 @@ acpi_evaluate_object_typed (
 
 acpi_status
 acpi_get_object_info (
-	acpi_handle                     device,
-	struct acpi_device_info         *info);
+	acpi_handle                     handle,
+	struct acpi_buffer              *return_buffer);
 
 acpi_status
 acpi_get_next_object (
diff --git a/include/acpi/actables.h b/include/acpi/actables.h
index 32fe58c16dd7e2694557892c01f5e430306ceda8..305c2a9adf4fc90a937193501113687985f897c1 100644
--- a/include/acpi/actables.h
+++ b/include/acpi/actables.h
@@ -157,7 +157,7 @@ acpi_tb_match_signature (
 acpi_status
 acpi_tb_recognize_table (
 	struct acpi_table_desc          *table_info,
-	u8                             search_type);
+	u8                              search_type);
 
 acpi_status
 acpi_tb_init_table_descriptor (
@@ -170,11 +170,11 @@ acpi_tb_init_table_descriptor (
  */
 
 void
-acpi_tb_delete_acpi_tables (
+acpi_tb_delete_all_tables (
 	void);
 
 void
-acpi_tb_delete_acpi_table (
+acpi_tb_delete_tables_by_type (
 	acpi_table_type                 type);
 
 void
@@ -185,10 +185,6 @@ struct acpi_table_desc *
 acpi_tb_uninstall_table (
 	struct acpi_table_desc          *table_desc);
 
-void
-acpi_tb_free_acpi_tables_of_type (
-	struct acpi_table_desc          *table_info);
-
 
 /*
  * tbrsd - RSDP, RSDT utilities
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 7ffa0b226c3187dc4e049c3e76e343e43a473ed4..875bee2947a882b88ef9735111f6f37e253d2e7c 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -407,7 +407,7 @@ typedef u32                                     acpi_table_type;
 #define ACPI_TABLE_SSDT                 (acpi_table_type) 5
 #define ACPI_TABLE_XSDT                 (acpi_table_type) 6
 #define ACPI_TABLE_MAX                  6
-#define NUM_ACPI_TABLES                 (ACPI_TABLE_MAX+1)
+#define NUM_ACPI_TABLE_TYPES            (ACPI_TABLE_MAX+1)
 
 
 /*
@@ -747,7 +747,7 @@ struct acpi_system_info
 	u32                                 debug_level;
 	u32                                 debug_layer;
 	u32                                 num_table_types;
-	struct acpi_table_info              table_info [NUM_ACPI_TABLES];
+	struct acpi_table_info              table_info [NUM_ACPI_TABLE_TYPES];
 };
 
 
@@ -832,12 +832,35 @@ acpi_status (*acpi_walk_callback) (
 #define ACPI_INTERRUPT_HANDLED          0x01
 
 
-/* Structure and flags for acpi_get_device_info */
+/* Common string version of device HIDs and UIDs */
 
-#define ACPI_VALID_HID                  0x1
-#define ACPI_VALID_UID                  0x2
-#define ACPI_VALID_ADR                  0x4
-#define ACPI_VALID_STA                  0x8
+struct acpi_device_id
+{
+	char                            value[ACPI_DEVICE_ID_LENGTH];
+};
+
+/* Common string version of device CIDs */
+
+struct acpi_compatible_id
+{
+	char                            value[ACPI_MAX_CID_LENGTH];
+};
+
+struct acpi_compatible_id_list
+{
+	u32                             count;
+	u32                             size;
+	struct acpi_compatible_id       id[1];
+};
+
+
+/* Structure and flags for acpi_get_object_info */
+
+#define ACPI_VALID_STA                  0x0001
+#define ACPI_VALID_ADR                  0x0002
+#define ACPI_VALID_HID                  0x0004
+#define ACPI_VALID_UID                  0x0008
+#define ACPI_VALID_CID                  0x0010
 
 
 #define ACPI_COMMON_OBJ_INFO \
@@ -851,15 +874,18 @@ struct acpi_obj_info_header
 };
 
 
+/* Structure returned from Get Object Info */
+
 struct acpi_device_info
 {
 	ACPI_COMMON_OBJ_INFO;
 
-	u32                                 valid;              /*  Are the next bits legit? */
-	char                                hardware_id[9];     /*  _HID value if any */
-	char                                unique_id[9];       /*  _UID value if any */
-	acpi_integer                        address;            /*  _ADR value if any */
-	u32                                 current_status;     /*  _STA value */
+	u32                                 valid;              /* Indicates which fields are valid */
+	u32                                 current_status;     /* _STA value */
+	acpi_integer                        address;            /* _ADR value if any */
+	struct acpi_device_id               hardware_id;        /* _HID value if any */
+	struct acpi_device_id               unique_id;          /* _UID value if any */
+	struct acpi_compatible_id_list      compatibility_id;   /* List of _CIDs if any */
 };
 
 
diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h
index 576ad04ca41f494cb1fa7c37c3b3a4f15bdb00a3..6c79df2c46ac8dc08864bcad9b8b8936da609c18 100644
--- a/include/acpi/acutils.h
+++ b/include/acpi/acutils.h
@@ -488,7 +488,7 @@ acpi_ut_execute_HID (
 acpi_status
 acpi_ut_execute_CID (
 	struct acpi_namespace_node      *device_node,
-	struct acpi_device_id           *cid);
+	struct acpi_compatible_id_list **return_cid_list);
 
 acpi_status
 acpi_ut_execute_STA (
diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h
new file mode 100644
index 0000000000000000000000000000000000000000..cdaa4689f36ed2d05681d914279111d93c0f32c5
--- /dev/null
+++ b/include/acpi/amlresrc.h
@@ -0,0 +1,329 @@
+
+/******************************************************************************
+ *
+ * Module Name: amlresrc.h - AML resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2003, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#ifndef __AMLRESRC_H
+#define __AMLRESRC_H
+
+
+#define ASL_RESNAME_ADDRESS                     "_ADR"
+#define ASL_RESNAME_ALIGNMENT                   "_ALN"
+#define ASL_RESNAME_ADDRESSSPACE                "_ASI"
+#define ASL_RESNAME_BASEADDRESS                 "_BAS"
+#define ASL_RESNAME_BUSMASTER                   "_BM_"  /* Master(1), Slave(0) */
+#define ASL_RESNAME_DECODE                      "_DEC"
+#define ASL_RESNAME_DMA                         "_DMA"
+#define ASL_RESNAME_DMATYPE                     "_TYP"  /* Compatible(0), A(1), B(2), F(3) */
+#define ASL_RESNAME_GRANULARITY                 "_GRA"
+#define ASL_RESNAME_INTERRUPT                   "_INT"
+#define ASL_RESNAME_INTERRUPTLEVEL              "_LL_"  /* active_lo(1), active_hi(0) */
+#define ASL_RESNAME_INTERRUPTSHARE              "_SHR"  /* Shareable(1), no_share(0) */
+#define ASL_RESNAME_INTERRUPTTYPE               "_HE_"  /* Edge(1), Level(0) */
+#define ASL_RESNAME_LENGTH                      "_LEN"
+#define ASL_RESNAME_MEMATTRIBUTES               "_MTP"  /* Memory(0), Reserved(1), ACPI(2), NVS(3) */
+#define ASL_RESNAME_MEMTYPE                     "_MEM"  /* non_cache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */
+#define ASL_RESNAME_MAXADDR                     "_MAX"
+#define ASL_RESNAME_MINADDR                     "_MIN"
+#define ASL_RESNAME_MAXTYPE                     "_MAF"
+#define ASL_RESNAME_MINTYPE                     "_MIF"
+#define ASL_RESNAME_REGISTERBITOFFSET           "_RBO"
+#define ASL_RESNAME_REGISTERBITWIDTH            "_RBW"
+#define ASL_RESNAME_RANGETYPE                   "_RNG"
+#define ASL_RESNAME_READWRITETYPE               "_RW_"  /* read_only(0), Writeable (1) */
+#define ASL_RESNAME_TRANSLATION                 "_TRA"
+#define ASL_RESNAME_TRANSTYPE                   "_TRS"  /* Sparse(1), Dense(0) */
+#define ASL_RESNAME_TYPE                        "_TTP"  /* Translation(1), Static (0) */
+#define ASL_RESNAME_XFERTYPE                    "_SIz"  /* 8(0), 8_and16(1), 16(2) */
+
+
+/* Default sizes for "small" resource descriptors */
+
+#define ASL_RDESC_IRQ_SIZE                      0x02
+#define ASL_RDESC_DMA_SIZE                      0x02
+#define ASL_RDESC_ST_DEPEND_SIZE                0x00
+#define ASL_RDESC_END_DEPEND_SIZE               0x00
+#define ASL_RDESC_IO_SIZE                       0x07
+#define ASL_RDESC_FIXED_IO_SIZE                 0x03
+#define ASL_RDESC_END_TAG_SIZE                  0x01
+
+
+struct asl_resource_node
+{
+	u32                                 buffer_length;
+	void                                *buffer;
+	struct asl_resource_node            *next;
+};
+
+
+/*
+ * Resource descriptors defined in the ACPI specification.
+ *
+ * Alignment must be BYTE because these descriptors
+ * are used to overlay the AML byte stream.
+ */
+#pragma pack(1)
+
+struct asl_irq_format_desc
+{
+	u8                                  descriptor_type;
+	u16                                 irq_mask;
+	u8                                  flags;
+};
+
+
+struct asl_irq_noflags_desc
+{
+	u8                                  descriptor_type;
+	u16                                 irq_mask;
+};
+
+
+struct asl_dma_format_desc
+{
+	u8                                  descriptor_type;
+	u8                                  dma_channel_mask;
+	u8                                  flags;
+};
+
+
+struct asl_start_dependent_desc
+{
+	u8                                  descriptor_type;
+	u8                                  flags;
+};
+
+
+struct asl_start_dependent_noprio_desc
+{
+	u8                                  descriptor_type;
+};
+
+
+struct asl_end_dependent_desc
+{
+	u8                                  descriptor_type;
+};
+
+
+struct asl_io_port_desc
+{
+	u8                                  descriptor_type;
+	u8                                  information;
+	u16                                 address_min;
+	u16                                 address_max;
+	u8                                  alignment;
+	u8                                  length;
+};
+
+
+struct asl_fixed_io_port_desc
+{
+	u8                                  descriptor_type;
+	u16                                 base_address;
+	u8                                  length;
+};
+
+
+struct asl_small_vendor_desc
+{
+	u8                                  descriptor_type;
+	u8                                  vendor_defined[7];
+};
+
+
+struct asl_end_tag_desc
+{
+	u8                                  descriptor_type;
+	u8                                  checksum;
+};
+
+
+/* LARGE descriptors */
+
+struct asl_memory_24_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  information;
+	u16                                 address_min;
+	u16                                 address_max;
+	u16                                 alignment;
+	u16                                 range_length;
+};
+
+
+struct asl_large_vendor_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  vendor_defined[1];
+};
+
+
+struct asl_memory_32_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  information;
+	u32                                 address_min;
+	u32                                 address_max;
+	u32                                 alignment;
+	u32                                 range_length;
+};
+
+
+struct asl_fixed_memory_32_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  information;
+	u32                                 base_address;
+	u32                                 range_length;
+};
+
+
+struct asl_qword_address_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  resource_type;
+	u8                                  flags;
+	u8                                  specific_flags;
+	u64                                 granularity;
+	u64                                 address_min;
+	u64                                 address_max;
+	u64                                 translation_offset;
+	u64                                 address_length;
+	u8                                  optional_fields[2];
+};
+
+
+struct asl_dword_address_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  resource_type;
+	u8                                  flags;
+	u8                                  specific_flags;
+	u32                                 granularity;
+	u32                                 address_min;
+	u32                                 address_max;
+	u32                                 translation_offset;
+	u32                                 address_length;
+	u8                                  optional_fields[2];
+};
+
+
+struct asl_word_address_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  resource_type;
+	u8                                  flags;
+	u8                                  specific_flags;
+	u16                                 granularity;
+	u16                                 address_min;
+	u16                                 address_max;
+	u16                                 translation_offset;
+	u16                                 address_length;
+	u8                                  optional_fields[2];
+};
+
+
+struct asl_extended_xrupt_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  flags;
+	u8                                  table_length;
+	u32                                 interrupt_number[1];
+	/* res_source_index, res_source optional fields follow */
+};
+
+
+struct asl_general_register_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  address_space_id;
+	u8                                  bit_width;
+	u8                                  bit_offset;
+	u8                                  reserved;
+	u64                                 address;
+};
+
+/* restore default alignment */
+
+#pragma pack()
+
+/* Union of all resource descriptors, sow we can allocate the worst case */
+
+union asl_resource_desc
+{
+	struct asl_irq_format_desc          irq;
+	struct asl_dma_format_desc          dma;
+	struct asl_start_dependent_desc     std;
+	struct asl_end_dependent_desc       end;
+	struct asl_io_port_desc             iop;
+	struct asl_fixed_io_port_desc       fio;
+	struct asl_small_vendor_desc        smv;
+	struct asl_end_tag_desc             et;
+
+	struct asl_memory_24_desc           M24;
+	struct asl_large_vendor_desc        lgv;
+	struct asl_memory_32_desc           M32;
+	struct asl_fixed_memory_32_desc     F32;
+	struct asl_qword_address_desc       qas;
+	struct asl_dword_address_desc       das;
+	struct asl_word_address_desc        was;
+	struct asl_extended_xrupt_desc      exx;
+	struct asl_general_register_desc    grg;
+	u32                                 u32_item;
+	u16                                 u16_item;
+	u8                                  U8item;
+};
+
+
+#endif
+
diff --git a/include/linux/ide.h b/include/linux/ide.h
index f773ff4268a93fd7c64b0cd7f02e9f3809c18955..a6166056977c9aba7b5098de18fe31a93e3fece2 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -886,6 +886,8 @@ typedef struct hwif_s {
 	
 	struct pnp_dev  *pnp_dev;	/* for PnP devices */
 
+	ide_startstop_t (*rw_disk)(ide_drive_t *, struct request *, sector_t);
+
 #if 0
 	ide_hwif_ops_t	*hwifops;
 #else
@@ -1001,6 +1003,7 @@ typedef struct hwif_s {
 
 	unsigned	noprobe    : 1;	/* don't probe for this interface */
 	unsigned	present    : 1;	/* this interface exists */
+	unsigned	hold       : 1; /* this interface is always present */
 	unsigned	serialized : 1;	/* serialized all channel operation */
 	unsigned	sharing_irq: 1;	/* 1 = sharing irq with another hwif */
 	unsigned	reset      : 1;	/* reset after probe */
@@ -1534,6 +1537,8 @@ extern u8 eighty_ninty_three (ide_drive_t *);
 extern int set_transfer(ide_drive_t *, ide_task_t *);
 extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *);
 
+ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block);
+
 /*
  * ide_system_bus_speed() returns what we think is the system VESA/PCI
  * bus speed (in MHz).  This is used for calculating interface PIO timings.
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 4c8f4240d33d9f4e470b4c357d584847f4b6f5cb..4f5fdde6dc4b55b8af73b25567bc1c8d60632f06 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -557,6 +557,7 @@
 #define PCI_DEVICE_ID_SI_650		0x0650
 #define PCI_DEVICE_ID_SI_651		0x0651
 #define PCI_DEVICE_ID_SI_652		0x0652
+#define PCI_DEVICE_ID_SI_655		0x0655
 #define PCI_DEVICE_ID_SI_730		0x0730
 #define PCI_DEVICE_ID_SI_630_VGA	0x6300
 #define PCI_DEVICE_ID_SI_730_VGA	0x7300
@@ -1127,6 +1128,7 @@
 #define PCI_DEVICE_ID_VIA_8753_0	0x3128
 #define PCI_DEVICE_ID_VIA_8233A		0x3147
 #define PCI_DEVICE_ID_VIA_8752		0x3148
+#define PCI_DEVICE_ID_VIA_8237_SATA	0x3149
 #define PCI_DEVICE_ID_VIA_KN266		0x3156
 #define PCI_DEVICE_ID_VIA_8754		0x3168
 #define PCI_DEVICE_ID_VIA_8235		0x3177
@@ -1135,6 +1137,7 @@
 #define PCI_DEVICE_ID_VIA_8377_0	0x3189
 #define PCI_DEVICE_ID_VIA_KM400		0x3205
 #define PCI_DEVICE_ID_VIA_P4M400	0x3209
+#define PCI_DEVICE_ID_VIA_8237		0x3227
 #define PCI_DEVICE_ID_VIA_86C100A	0x6100
 #define PCI_DEVICE_ID_VIA_8231		0x8231
 #define PCI_DEVICE_ID_VIA_8231_4	0x8235
@@ -1893,6 +1896,7 @@
 #define PCI_DEVICE_ID_INTEL_82801DB_12  0x24cc
 #define PCI_DEVICE_ID_INTEL_82801DB_13	0x24cd
 #define PCI_DEVICE_ID_INTEL_82801EB_0	0x24d0
+#define PCI_DEVICE_ID_INTEL_82801EB_1	0x24d1
 #define PCI_DEVICE_ID_INTEL_82801EB_2	0x24d2
 #define PCI_DEVICE_ID_INTEL_82801EB_3	0x24d3
 #define PCI_DEVICE_ID_INTEL_82801EB_4	0x24d4