vserver 1.9.3
[linux-2.6.git] / drivers / acpi / events / evxfregn.c
index b31d4fd..8eeb938 100644 (file)
@@ -46,7 +46,6 @@
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acevents.h>
-#include <acpi/acinterp.h>
 
 #define _COMPONENT          ACPI_EVENTS
         ACPI_MODULE_NAME    ("evxfregn")
@@ -76,12 +75,8 @@ acpi_install_address_space_handler (
        acpi_adr_space_setup            setup,
        void                            *context)
 {
-       union acpi_operand_object       *obj_desc;
-       union acpi_operand_object       *handler_obj;
        struct acpi_namespace_node      *node;
        acpi_status                     status;
-       acpi_object_type                type;
-       u16                             flags = 0;
 
 
        ACPI_FUNCTION_TRACE ("acpi_install_address_space_handler");
@@ -106,202 +101,16 @@ acpi_install_address_space_handler (
                goto unlock_and_exit;
        }
 
-       /*
-        * This registration is valid for only the types below
-        * and the root.  This is where the default handlers
-        * get placed.
-        */
-       if ((node->type != ACPI_TYPE_DEVICE)     &&
-               (node->type != ACPI_TYPE_PROCESSOR)  &&
-               (node->type != ACPI_TYPE_THERMAL)    &&
-               (node != acpi_gbl_root_node)) {
-               status = AE_BAD_PARAMETER;
-               goto unlock_and_exit;
-       }
-
-       if (handler == ACPI_DEFAULT_HANDLER) {
-               flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
-
-               switch (space_id) {
-               case ACPI_ADR_SPACE_SYSTEM_MEMORY:
-                       handler = acpi_ex_system_memory_space_handler;
-                       setup   = acpi_ev_system_memory_region_setup;
-                       break;
-
-               case ACPI_ADR_SPACE_SYSTEM_IO:
-                       handler = acpi_ex_system_io_space_handler;
-                       setup   = acpi_ev_io_space_region_setup;
-                       break;
-
-               case ACPI_ADR_SPACE_PCI_CONFIG:
-                       handler = acpi_ex_pci_config_space_handler;
-                       setup   = acpi_ev_pci_config_region_setup;
-                       break;
-
-               case ACPI_ADR_SPACE_CMOS:
-                       handler = acpi_ex_cmos_space_handler;
-                       setup   = acpi_ev_cmos_region_setup;
-                       break;
-
-               case ACPI_ADR_SPACE_PCI_BAR_TARGET:
-                       handler = acpi_ex_pci_bar_space_handler;
-                       setup   = acpi_ev_pci_bar_region_setup;
-                       break;
-
-               case ACPI_ADR_SPACE_DATA_TABLE:
-                       handler = acpi_ex_data_table_space_handler;
-                       setup   = NULL;
-                       break;
-
-               default:
-                       status = AE_BAD_PARAMETER;
-                       goto unlock_and_exit;
-               }
-       }
-
-       /* If the caller hasn't specified a setup routine, use the default */
-
-       if (!setup) {
-               setup = acpi_ev_default_region_setup;
-       }
-
-       /* Check for an existing internal object */
-
-       obj_desc = acpi_ns_get_attached_object (node);
-       if (obj_desc) {
-               /*
-                * The attached device object already exists.
-                * Make sure the handler is not already installed.
-                */
-               handler_obj = obj_desc->device.handler;
-
-               /* Walk the handler list for this device */
-
-               while (handler_obj) {
-                       /* Same space_id indicates a handler already installed */
-
-                       if(handler_obj->address_space.space_id == space_id) {
-                               if (handler_obj->address_space.handler == handler) {
-                                       /*
-                                        * It is (relatively) OK to attempt to install the SAME
-                                        * handler twice. This can easily happen with PCI_Config space.
-                                        */
-                                       status = AE_SAME_HANDLER;
-                                       goto unlock_and_exit;
-                               }
-                               else {
-                                       /* A handler is already installed */
-
-                                       status = AE_ALREADY_EXISTS;
-                               }
-                               goto unlock_and_exit;
-                       }
-
-                       /* Walk the linked list of handlers */
-
-                       handler_obj = handler_obj->address_space.next;
-               }
-       }
-       else {
-               ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
-                       "Creating object on Device %p while installing handler\n", node));
-
-               /* obj_desc does not exist, create one */
-
-               if (node->type == ACPI_TYPE_ANY) {
-                       type = ACPI_TYPE_DEVICE;
-               }
-               else {
-                       type = node->type;
-               }
-
-               obj_desc = acpi_ut_create_internal_object (type);
-               if (!obj_desc) {
-                       status = AE_NO_MEMORY;
-                       goto unlock_and_exit;
-               }
-
-               /* Init new descriptor */
-
-               obj_desc->common.type = (u8) type;
-
-               /* Attach the new object to the Node */
+       /* Install the handler for all Regions for this Space ID */
 
-               status = acpi_ns_attach_object (node, obj_desc, type);
-
-               /* Remove local reference to the object */
-
-               acpi_ut_remove_reference (obj_desc);
-
-               if (ACPI_FAILURE (status)) {
-                       goto unlock_and_exit;
-               }
-       }
-
-       ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
-               "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
-               acpi_ut_get_region_name (space_id), space_id,
-               acpi_ut_get_node_name (node), node, obj_desc));
-
-       /*
-        * Install the handler
-        *
-        * At this point there is no existing handler.
-        * Just allocate the object for the handler and link it
-        * into the list.
-        */
-       handler_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
-       if (!handler_obj) {
-               status = AE_NO_MEMORY;
+       status = acpi_ev_install_space_handler (node, space_id, handler, setup, context);
+       if (ACPI_FAILURE (status)) {
                goto unlock_and_exit;
        }
 
-       /* Init handler obj */
-
-       handler_obj->address_space.space_id  = (u8) space_id;
-       handler_obj->address_space.hflags    = flags;
-       handler_obj->address_space.region_list = NULL;
-       handler_obj->address_space.node      = node;
-       handler_obj->address_space.handler   = handler;
-       handler_obj->address_space.context   = context;
-       handler_obj->address_space.setup     = setup;
-
-       /* Install at head of Device.address_space list */
-
-       handler_obj->address_space.next      = obj_desc->device.handler;
-
-       /*
-        * The Device object is the first reference on the handler_obj.
-        * Each region that uses the handler adds a reference.
-        */
-       obj_desc->device.handler = handler_obj;
-
-       /*
-        * Walk the namespace finding all of the regions this
-        * handler will manage.
-        *
-        * Start at the device and search the branch toward
-        * the leaf nodes until either the leaf is encountered or
-        * a device is detected that has an address handler of the
-        * same type.
-        *
-        * In either case, back up and search down the remainder
-        * of the branch
-        */
-       status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX,
-                         ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
-                         handler_obj, NULL);
-
-       /*
-        * Now we can run the _REG methods for all Regions for this
-        * space ID.  This is a separate walk in order to handle any
-        * interdependencies between regions and _REG methods.  (i.e. handlers
-        * must be installed for all regions of this Space ID before we
-        * can run any _REG methods.
-        */
-       status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX,
-                         ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
-                         handler_obj, NULL);
+       /* Run all _REG methods for this address space */
+
+       status = acpi_ev_execute_reg_methods (node, space_id);
 
 unlock_and_exit:
        (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);