^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: evhandler - Support for Address Space handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2000 - 2020, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "acevents.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "acnamesp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "acinterp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define _COMPONENT ACPI_EVENTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) ACPI_MODULE_NAME("evhandler")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* Local prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) acpi_ev_install_handler(acpi_handle obj_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) u32 level, void *context, void **return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* These are the address spaces that will get default handlers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) ACPI_ADR_SPACE_SYSTEM_MEMORY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) ACPI_ADR_SPACE_SYSTEM_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ACPI_ADR_SPACE_PCI_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) ACPI_ADR_SPACE_DATA_TABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * FUNCTION: acpi_ev_install_region_handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * PARAMETERS: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * DESCRIPTION: Installs the core subsystem default address space handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) acpi_status acpi_ev_install_region_handlers(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ACPI_FUNCTION_TRACE(ev_install_region_handlers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * All address spaces (PCI Config, EC, SMBus) are scope dependent and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * registration must occur for a specific device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * In the case of the system memory and IO address spaces there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * currently no device associated with the address space. For these we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * use the root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * We install the default PCI config space handler at the root so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * this space is immediately available even though the we have not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * enumerated all the PCI Root Buses yet. This is to conform to the ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * specification which states that the PCI config space must be always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * available -- even though we are nowhere near ready to find the PCI root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * buses at this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * has already been installed (via acpi_install_address_space_handler).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Similar for AE_SAME_HANDLER.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) status = acpi_ev_install_space_handler(acpi_gbl_root_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) acpi_gbl_default_address_spaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) [i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ACPI_DEFAULT_HANDLER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) case AE_OK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) case AE_SAME_HANDLER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) case AE_ALREADY_EXISTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* These exceptions are all OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) goto unlock_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unlock_and_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * FUNCTION: acpi_ev_has_default_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * PARAMETERS: node - Namespace node for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * space_id - The address space ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * RETURN: TRUE if default handler is installed, FALSE otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * DESCRIPTION: Check if the default handler is installed for the requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * space ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) acpi_ev_has_default_handler(struct acpi_namespace_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) acpi_adr_space_type space_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) union acpi_operand_object *obj_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) union acpi_operand_object *handler_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Must have an existing internal object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) obj_desc = acpi_ns_get_attached_object(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (obj_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) handler_obj = obj_desc->common_notify.handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Walk the linked list of handlers for this object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) while (handler_obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (handler_obj->address_space.space_id == space_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (handler_obj->address_space.handler_flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return (TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) handler_obj = handler_obj->address_space.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return (FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * FUNCTION: acpi_ev_install_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * PARAMETERS: walk_namespace callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * DESCRIPTION: This routine installs an address handler into objects that are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * of type Region or Device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * If the Object is a Device, and the device has a handler of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * the same type then the search is terminated in that branch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * This is because the existing handler is closer in proximity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * to any more regions than the one we are trying to install.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) acpi_ev_install_handler(acpi_handle obj_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) u32 level, void *context, void **return_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) union acpi_operand_object *handler_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) union acpi_operand_object *next_handler_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) union acpi_operand_object *obj_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct acpi_namespace_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ACPI_FUNCTION_NAME(ev_install_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) handler_obj = (union acpi_operand_object *)context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* Parameter validation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (!handler_obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* Convert and validate the device handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) node = acpi_ns_validate_handle(obj_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return (AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * We only care about regions and objects that are allowed to have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * address space handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if ((node->type != ACPI_TYPE_DEVICE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) (node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* Check for an existing internal object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) obj_desc = acpi_ns_get_attached_object(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (!obj_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* No object, just exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* Devices are handled different than regions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Check if this Device already has a handler for this address space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) next_handler_obj =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) acpi_ev_find_region_handler(handler_obj->address_space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) space_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) obj_desc->common_notify.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (next_handler_obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* Found a handler, is it for the same address space? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) "Found handler for region [%s] in device %p(%p) handler %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) acpi_ut_get_region_name(handler_obj->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) address_space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) space_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) obj_desc, next_handler_obj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) handler_obj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Since the object we found it on was a device, then it means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * that someone has already installed a handler for the branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * of the namespace from this device on. Just bail out telling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * the walk routine to not traverse this branch. This preserves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * the scoping rule for handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return (AE_CTRL_DEPTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * As long as the device didn't have a handler for this space we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * don't care about it. We just ignore it and proceed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* Object is a Region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* This region is for a different address space, just ignore it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * Now we have a region and it is for the handler's address space type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * First disconnect region for any previous handler (if any)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) acpi_ev_detach_region(obj_desc, FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* Connect the region to the new handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * FUNCTION: acpi_ev_find_region_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * PARAMETERS: space_id - The address space ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * handler_obj - Head of the handler object list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * RETURN: Matching handler object. NULL if space ID not matched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * DESCRIPTION: Search a handler object list for a match on the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * space ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) union acpi_operand_object *acpi_ev_find_region_handler(acpi_adr_space_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) space_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) union acpi_operand_object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) *handler_obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* Walk the handler list for this device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) while (handler_obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* Same space_id indicates a handler is installed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (handler_obj->address_space.space_id == space_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return (handler_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* Next handler object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) handler_obj = handler_obj->address_space.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * FUNCTION: acpi_ev_install_space_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * PARAMETERS: node - Namespace node for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * space_id - The address space ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * handler - Address of the handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * setup - Address of the setup function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * context - Value passed to the handler on each access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * DESCRIPTION: Install a handler for all op_regions of a given space_id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * Assumes namespace is locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) acpi_ev_install_space_handler(struct acpi_namespace_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) acpi_adr_space_type space_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) acpi_adr_space_handler handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) acpi_adr_space_setup setup, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) union acpi_operand_object *obj_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) union acpi_operand_object *handler_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) acpi_object_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) u8 flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ACPI_FUNCTION_TRACE(ev_install_space_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * This registration is valid for only the types below and the root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * The root node is where the default handlers get installed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if ((node->type != ACPI_TYPE_DEVICE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) (node->type != ACPI_TYPE_PROCESSOR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) (node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) status = AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) goto unlock_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (handler == ACPI_DEFAULT_HANDLER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) switch (space_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case ACPI_ADR_SPACE_SYSTEM_MEMORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) handler = acpi_ex_system_memory_space_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) setup = acpi_ev_system_memory_region_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case ACPI_ADR_SPACE_SYSTEM_IO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) handler = acpi_ex_system_io_space_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) setup = acpi_ev_io_space_region_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) #ifdef ACPI_PCI_CONFIGURED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) case ACPI_ADR_SPACE_PCI_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) handler = acpi_ex_pci_config_space_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) setup = acpi_ev_pci_config_region_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) case ACPI_ADR_SPACE_CMOS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) handler = acpi_ex_cmos_space_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) setup = acpi_ev_cmos_region_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) #ifdef ACPI_PCI_CONFIGURED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) case ACPI_ADR_SPACE_PCI_BAR_TARGET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) handler = acpi_ex_pci_bar_space_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) setup = acpi_ev_pci_bar_region_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) case ACPI_ADR_SPACE_DATA_TABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) handler = acpi_ex_data_table_space_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) setup = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) status = AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) goto unlock_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* If the caller hasn't specified a setup routine, use the default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (!setup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) setup = acpi_ev_default_region_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* Check for an existing internal object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) obj_desc = acpi_ns_get_attached_object(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (obj_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * The attached device object already exists. Now make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * the handler is not already installed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) handler_obj = acpi_ev_find_region_handler(space_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) obj_desc->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) common_notify.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (handler_obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (handler_obj->address_space.handler == handler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * It is (relatively) OK to attempt to install the SAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * handler twice. This can easily happen with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * PCI_Config space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) status = AE_SAME_HANDLER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) goto unlock_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* A handler is already installed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) status = AE_ALREADY_EXISTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) goto unlock_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) "Creating object on Device %p while installing handler\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* obj_desc does not exist, create one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (node->type == ACPI_TYPE_ANY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) type = ACPI_TYPE_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) type = node->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) obj_desc = acpi_ut_create_internal_object(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (!obj_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) goto unlock_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* Init new descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) obj_desc->common.type = (u8)type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* Attach the new object to the Node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) status = acpi_ns_attach_object(node, obj_desc, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /* Remove local reference to the object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) acpi_ut_remove_reference(obj_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) goto unlock_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) "Installing address handler for region %s(%X) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) "on Device %4.4s %p(%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) acpi_ut_get_region_name(space_id), space_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) acpi_ut_get_node_name(node), node, obj_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * Install the handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * At this point there is no existing handler. Just allocate the object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * for the handler and link it into the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) handler_obj =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (!handler_obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) goto unlock_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* Init handler obj */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) acpi_os_create_mutex(&handler_obj->address_space.context_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) acpi_ut_remove_reference(handler_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto unlock_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) handler_obj->address_space.space_id = (u8)space_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) handler_obj->address_space.handler_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) handler_obj->address_space.region_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) handler_obj->address_space.node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) handler_obj->address_space.handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) handler_obj->address_space.context = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) handler_obj->address_space.setup = setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* Install at head of Device.address_space list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) handler_obj->address_space.next = obj_desc->common_notify.handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * The Device object is the first reference on the handler_obj.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * Each region that uses the handler adds a reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) obj_desc->common_notify.handler = handler_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * Walk the namespace finding all of the regions this handler will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * manage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * Start at the device and search the branch toward the leaf nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * until either the leaf is encountered or a device is detected that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * has an address handler of the same type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * In either case, back up and search down the remainder of the branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) acpi_ev_install_handler, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) handler_obj, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) unlock_and_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }