patch-2.4.0-test3 linux/drivers/acpi/events/evrgnini.c
Next file: linux/drivers/acpi/events/evsci.c
Previous file: linux/drivers/acpi/events/evregion.c
Back to the patch index
Back to the overall index
- Lines: 426
- Date:
Wed Jul 5 11:23:12 2000
- Orig file:
v2.4.0-test2/linux/drivers/acpi/events/evrgnini.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.4.0-test2/linux/drivers/acpi/events/evrgnini.c linux/drivers/acpi/events/evrgnini.c
@@ -0,0 +1,425 @@
+/******************************************************************************
+ *
+ * Module Name: evrgnini- ACPI Address_space / Op_region init
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "acpi.h"
+#include "events.h"
+#include "namesp.h"
+#include "interp.h"
+#include "amlcode.h"
+
+#define _COMPONENT EVENT_HANDLING
+ MODULE_NAME ("evrgnini");
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: Acpi_ev_system_memory_region_setup
+ *
+ * PARAMETERS: Region_obj - region we are interested in
+ * Function - start or stop
+ * Handler_context - Address space handler context
+ * Returned context - context to be used with each call to the
+ * handler for this region
+ * RETURN: Status
+ *
+ * DESCRIPTION: Do any prep work for region handling, a nop for now
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ev_system_memory_region_setup (
+ ACPI_HANDLE handle,
+ u32 function,
+ void *handler_context,
+ void **return_context)
+{
+ MEM_HANDLER_CONTEXT *mem_context;
+ ACPI_OBJECT_INTERNAL *region_obj = (ACPI_OBJECT_INTERNAL *) handle;
+
+
+ if (function == ACPI_REGION_DEACTIVATE) {
+ region_obj->region.region_flags &= ~(REGION_INITIALIZED);
+
+ *return_context = NULL;
+ if (handler_context) {
+ mem_context = handler_context;
+ *return_context = mem_context->handler_context;
+
+ acpi_cm_free (mem_context);
+ }
+ return (AE_OK);
+ }
+
+
+ /* Activate. Create a new context */
+
+ mem_context = acpi_cm_callocate (sizeof (MEM_HANDLER_CONTEXT));
+ if (!mem_context) {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Init. (Mapping fields are all set to zeros above) */
+
+ mem_context->handler_context = handler_context;
+ region_obj->region.region_flags |= REGION_INITIALIZED;
+
+ *return_context = mem_context;
+ return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: Acpi_ev_io_space_region_setup
+ *
+ * PARAMETERS: Region_obj - region we are interested in
+ * Function - start or stop
+ * Handler_context - Address space handler context
+ * Returned context - context to be used with each call to the
+ * handler for this region
+ * RETURN: Status
+ *
+ * DESCRIPTION: Do any prep work for region handling
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ev_io_space_region_setup (
+ ACPI_HANDLE handle,
+ u32 function,
+ void *handler_context,
+ void **return_context)
+{
+ ACPI_OBJECT_INTERNAL *region_obj = (ACPI_OBJECT_INTERNAL *) handle;
+
+
+ if (function == ACPI_REGION_DEACTIVATE) {
+ region_obj->region.region_flags &= ~(REGION_INITIALIZED);
+ *return_context = handler_context;
+ return (AE_OK);
+ }
+
+ /* Activate the region */
+
+ region_obj->region.region_flags |= REGION_INITIALIZED;
+ *return_context = handler_context;
+
+ return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: Acpi_ev_pci_config_region_setup
+ *
+ * PARAMETERS: Region_obj - region we are interested in
+ * Function - start or stop
+ * Handler_context - Address space handler context
+ * Returned context - context to be used with each call to the
+ * handler for this region
+ * RETURN: Status
+ *
+ * DESCRIPTION: Do any prep work for region handling
+ *
+ * MUTEX: Assumes namespace is locked
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ev_pci_config_region_setup (
+ ACPI_HANDLE handle,
+ u32 function,
+ void *handler_context,
+ void **return_context)
+{
+ ACPI_STATUS status = AE_OK;
+ u32 temp;
+ PCI_HANDLER_CONTEXT *pci_context;
+ ACPI_OBJECT_INTERNAL *handler_obj;
+ ACPI_NAMED_OBJECT *search_scope;
+ ACPI_OBJECT_INTERNAL *region_obj = (ACPI_OBJECT_INTERNAL *) handle;
+
+
+ handler_obj = region_obj->region.addr_handler;
+
+ if (!handler_obj) {
+ /*
+ * No installed handler. This shouldn't happen because the dispatch
+ * routine checks before we get here, but we check again just in case.
+ */
+ return(AE_EXIST);
+ }
+
+ if (function == ACPI_REGION_DEACTIVATE) {
+ region_obj->region.region_flags &= ~(REGION_INITIALIZED);
+
+ *return_context = NULL;
+ if (handler_context) {
+ pci_context = handler_context;
+ *return_context = pci_context->handler_context;
+
+ acpi_cm_free (pci_context);
+ }
+
+ return (status);
+ }
+
+
+ /* Create a new context */
+
+ pci_context = acpi_cm_allocate (sizeof(PCI_HANDLER_CONTEXT));
+ if (!pci_context) {
+ return (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.
+ */
+ ACPI_ASSERT(region_obj->region.nte);
+
+ search_scope = acpi_ns_get_parent_entry (region_obj->region.nte);
+
+
+ acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+
+ /* Acpi_evaluate the _ADR object */
+
+ status = acpi_cm_evaluate_numeric_object (METHOD_NAME__ADR, search_scope, &temp);
+ /*
+ * The default is zero, since the allocation above zeroed the data, just
+ * do nothing on failures.
+ */
+ if (ACPI_SUCCESS (status)) {
+ /*
+ * Got it..
+ */
+ pci_context->dev_func = temp;
+ }
+
+ /*
+ * Get the _SEG and _BBN values from the device upon which the handler
+ * is installed.
+ *
+ * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
+ * This is the device the handler has been registered to handle.
+ */
+
+ search_scope = handler_obj->addr_handler.nte;
+
+ status = acpi_cm_evaluate_numeric_object (METHOD_NAME__SEG, search_scope, &temp);
+ if (ACPI_SUCCESS (status)) {
+ /*
+ * Got it..
+ */
+ pci_context->seg = temp;
+ }
+
+ status = acpi_cm_evaluate_numeric_object (METHOD_NAME__BBN, search_scope, &temp);
+ if (ACPI_SUCCESS (status)) {
+ /*
+ * Got it..
+ */
+ pci_context->bus = temp;
+ }
+
+ acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+
+ *return_context = pci_context;
+
+ region_obj->region.region_flags |= REGION_INITIALIZED;
+ return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: Acpi_ev_default_region_setup
+ *
+ * PARAMETERS: Region_obj - region we are interested in
+ * Function - start or stop
+ * Handler_context - Address space handler context
+ * Returned context - context to be used with each call to the
+ * handler for this region
+ * RETURN: Status
+ *
+ * DESCRIPTION: Do any prep work for region handling
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ev_default_region_setup (
+ ACPI_HANDLE handle,
+ u32 function,
+ void *handler_context,
+ void **return_context)
+{
+ ACPI_OBJECT_INTERNAL *region_obj = (ACPI_OBJECT_INTERNAL *) handle;
+
+
+ if (function == ACPI_REGION_DEACTIVATE) {
+ region_obj->region.region_flags &= ~(REGION_INITIALIZED);
+ *return_context = NULL;
+ }
+ else {
+ region_obj->region.region_flags |= REGION_INITIALIZED;
+ *return_context = handler_context;
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: Acpi_ev_initialize_region
+ *
+ * PARAMETERS: Region_obj - Region we are initializing
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
+ * for execution at a later time
+ *
+ * Get the appropriate address space handler for a newly
+ * created region.
+ *
+ * This also performs address space specific intialization. For
+ * example, PCI regions must have an _ADR object that contains
+ * a PCI address in the scope of the defintion. This address is
+ * required to perform an access to PCI config space.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ev_initialize_region (
+ ACPI_OBJECT_INTERNAL *region_obj,
+ u8 acpi_ns_locked)
+{
+ ACPI_OBJECT_INTERNAL *handler_obj;
+ ACPI_OBJECT_INTERNAL *obj_desc;
+ u32 space_id;
+ ACPI_NAMED_OBJECT *entry; /* Namespace Object */
+ ACPI_STATUS status;
+ ACPI_NAMED_OBJECT *reg_entry;
+ ACPI_NAME *reg_name_ptr = (ACPI_NAME *) METHOD_NAME__REG;
+
+
+ if (!region_obj) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ ACPI_ASSERT(region_obj->region.nte);
+
+ entry = acpi_ns_get_parent_entry (region_obj->region.nte);
+ space_id = region_obj->region.space_id;
+
+ region_obj->region.addr_handler = NULL;
+ region_obj->region.REGmethod = NULL;
+ region_obj->region.region_flags = INITIAL_REGION_FLAGS;
+
+ /*
+ * Find any "_REG" associated with this region definition
+ */
+ status = acpi_ns_search_one_scope (*reg_name_ptr, entry->child_table,
+ ACPI_TYPE_METHOD, ®_entry, NULL);
+ if (status == AE_OK) {
+ /*
+ * The _REG method is optional and there can be only one per region
+ * definition. This will be executed when the handler is attached
+ * or removed
+ */
+ region_obj->region.REGmethod = reg_entry;
+ }
+
+ /*
+ * The following loop depends upon the root nte having no parent
+ * ie: Acpi_gbl_Root_object->Parent_entry being set to NULL
+ */
+ while (entry) {
+ /*
+ * Check to see if a handler exists
+ */
+ handler_obj = NULL;
+ obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) entry);
+ if (obj_desc) {
+ /*
+ * can only be a handler if the object exists
+ */
+ switch (entry->type)
+ {
+ case ACPI_TYPE_DEVICE:
+
+ handler_obj = obj_desc->device.addr_handler;
+ break;
+
+ case ACPI_TYPE_PROCESSOR:
+
+ handler_obj = obj_desc->processor.addr_handler;
+ break;
+
+ case ACPI_TYPE_THERMAL:
+
+ handler_obj = obj_desc->thermal_zone.addr_handler;
+ break;
+ }
+
+ while (handler_obj) {
+ /*
+ * This guy has at least one address handler
+ * see if it has the type we want
+ */
+ if (handler_obj->addr_handler.space_id == space_id) {
+ /*
+ * Found it! Now update the region and the handler
+ */
+ acpi_ev_associate_region_and_handler(handler_obj, region_obj);
+ return (AE_OK);
+ }
+
+ handler_obj = handler_obj->addr_handler.link;
+
+ } /* while handlerobj */
+ }
+
+ /*
+ * This one does not have the handler we need
+ * Pop up one level
+ */
+ entry = acpi_ns_get_parent_entry (entry);
+
+ } /* while Entry != ROOT */
+
+ /*
+ * If we get here, there is no handler for this region
+ */
+ return (AE_NOT_EXIST);
+}
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)