evxfregn.c revision 117521
1/****************************************************************************** 2 * 3 * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and 4 * Address Spaces. 5 * $Revision: 56 $ 6 * 7 *****************************************************************************/ 8 9/****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial prton of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118#define __EVXFREGN_C__ 119 120#include "acpi.h" 121#include "acnamesp.h" 122#include "acevents.h" 123#include "acinterp.h" 124 125#define _COMPONENT ACPI_EVENTS 126 ACPI_MODULE_NAME ("evxfregn") 127 128 129/******************************************************************************* 130 * 131 * FUNCTION: AcpiInstallAddressSpaceHandler 132 * 133 * PARAMETERS: Device - Handle for the device 134 * SpaceId - The address space ID 135 * Handler - Address of the handler 136 * Setup - Address of the setup function 137 * Context - Value passed to the handler on each access 138 * 139 * RETURN: Status 140 * 141 * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId. 142 * 143 ******************************************************************************/ 144 145ACPI_STATUS 146AcpiInstallAddressSpaceHandler ( 147 ACPI_HANDLE Device, 148 ACPI_ADR_SPACE_TYPE SpaceId, 149 ACPI_ADR_SPACE_HANDLER Handler, 150 ACPI_ADR_SPACE_SETUP Setup, 151 void *Context) 152{ 153 ACPI_OPERAND_OBJECT *ObjDesc; 154 ACPI_OPERAND_OBJECT *HandlerObj; 155 ACPI_NAMESPACE_NODE *Node; 156 ACPI_STATUS Status; 157 ACPI_OBJECT_TYPE Type; 158 UINT16 Flags = 0; 159 160 161 ACPI_FUNCTION_TRACE ("AcpiInstallAddressSpaceHandler"); 162 163 164 /* Parameter validation */ 165 166 if (!Device) 167 { 168 return_ACPI_STATUS (AE_BAD_PARAMETER); 169 } 170 171 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 172 if (ACPI_FAILURE (Status)) 173 { 174 return_ACPI_STATUS (Status); 175 } 176 177 /* Convert and validate the device handle */ 178 179 Node = AcpiNsMapHandleToNode (Device); 180 if (!Node) 181 { 182 Status = AE_BAD_PARAMETER; 183 goto UnlockAndExit; 184 } 185 186 /* 187 * This registration is valid for only the types below 188 * and the root. This is where the default handlers 189 * get placed. 190 */ 191 if ((Node->Type != ACPI_TYPE_DEVICE) && 192 (Node->Type != ACPI_TYPE_PROCESSOR) && 193 (Node->Type != ACPI_TYPE_THERMAL) && 194 (Node != AcpiGbl_RootNode)) 195 { 196 Status = AE_BAD_PARAMETER; 197 goto UnlockAndExit; 198 } 199 200 if (Handler == ACPI_DEFAULT_HANDLER) 201 { 202 Flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED; 203 204 switch (SpaceId) 205 { 206 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 207 Handler = AcpiExSystemMemorySpaceHandler; 208 Setup = AcpiEvSystemMemoryRegionSetup; 209 break; 210 211 case ACPI_ADR_SPACE_SYSTEM_IO: 212 Handler = AcpiExSystemIoSpaceHandler; 213 Setup = AcpiEvIoSpaceRegionSetup; 214 break; 215 216 case ACPI_ADR_SPACE_PCI_CONFIG: 217 Handler = AcpiExPciConfigSpaceHandler; 218 Setup = AcpiEvPciConfigRegionSetup; 219 break; 220 221 case ACPI_ADR_SPACE_CMOS: 222 Handler = AcpiExCmosSpaceHandler; 223 Setup = AcpiEvCmosRegionSetup; 224 break; 225 226 case ACPI_ADR_SPACE_PCI_BAR_TARGET: 227 Handler = AcpiExPciBarSpaceHandler; 228 Setup = AcpiEvPciBarRegionSetup; 229 break; 230 231 case ACPI_ADR_SPACE_DATA_TABLE: 232 Handler = AcpiExDataTableSpaceHandler; 233 Setup = NULL; 234 break; 235 236 default: 237 Status = AE_BAD_PARAMETER; 238 goto UnlockAndExit; 239 } 240 } 241 242 /* If the caller hasn't specified a setup routine, use the default */ 243 244 if (!Setup) 245 { 246 Setup = AcpiEvDefaultRegionSetup; 247 } 248 249 /* Check for an existing internal object */ 250 251 ObjDesc = AcpiNsGetAttachedObject (Node); 252 if (ObjDesc) 253 { 254 /* 255 * The attached device object already exists. 256 * Make sure the handler is not already installed. 257 */ 258 HandlerObj = ObjDesc->Device.AddressSpace; 259 260 /* Walk the handler list for this device */ 261 262 while (HandlerObj) 263 { 264 /* Same SpaceId indicates a handler already installed */ 265 266 if(HandlerObj->AddressSpace.SpaceId == SpaceId) 267 { 268 if (HandlerObj->AddressSpace.Handler == Handler) 269 { 270 /* 271 * It is (relatively) OK to attempt to install the SAME 272 * handler twice. This can easily happen with PCI_Config space. 273 */ 274 Status = AE_SAME_HANDLER; 275 goto UnlockAndExit; 276 } 277 else 278 { 279 /* A handler is already installed */ 280 281 Status = AE_ALREADY_EXISTS; 282 } 283 goto UnlockAndExit; 284 } 285 286 /* Walk the linked list of handlers */ 287 288 HandlerObj = HandlerObj->AddressSpace.Next; 289 } 290 } 291 else 292 { 293 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 294 "Creating object on Device %p while installing handler\n", Node)); 295 296 /* ObjDesc does not exist, create one */ 297 298 if (Node->Type == ACPI_TYPE_ANY) 299 { 300 Type = ACPI_TYPE_DEVICE; 301 } 302 else 303 { 304 Type = Node->Type; 305 } 306 307 ObjDesc = AcpiUtCreateInternalObject (Type); 308 if (!ObjDesc) 309 { 310 Status = AE_NO_MEMORY; 311 goto UnlockAndExit; 312 } 313 314 /* Init new descriptor */ 315 316 ObjDesc->Common.Type = (UINT8) Type; 317 318 /* Attach the new object to the Node */ 319 320 Status = AcpiNsAttachObject (Node, ObjDesc, Type); 321 322 /* Remove local reference to the object */ 323 324 AcpiUtRemoveReference (ObjDesc); 325 326 if (ACPI_FAILURE (Status)) 327 { 328 goto UnlockAndExit; 329 } 330 } 331 332 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 333 "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n", 334 AcpiUtGetRegionName (SpaceId), SpaceId, Node->Name.Ascii, Node, ObjDesc)); 335 336 /* 337 * Install the handler 338 * 339 * At this point there is no existing handler. 340 * Just allocate the object for the handler and link it 341 * into the list. 342 */ 343 HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER); 344 if (!HandlerObj) 345 { 346 Status = AE_NO_MEMORY; 347 goto UnlockAndExit; 348 } 349 350 /* Init handler obj */ 351 352 HandlerObj->AddressSpace.SpaceId = (UINT8) SpaceId; 353 HandlerObj->AddressSpace.Hflags = Flags; 354 HandlerObj->AddressSpace.RegionList = NULL; 355 HandlerObj->AddressSpace.Node = Node; 356 HandlerObj->AddressSpace.Handler = Handler; 357 HandlerObj->AddressSpace.Context = Context; 358 HandlerObj->AddressSpace.Setup = Setup; 359 360 /* Install at head of Device.AddressSpace list */ 361 362 HandlerObj->AddressSpace.Next = ObjDesc->Device.AddressSpace; 363 364 /* 365 * The Device object is the first reference on the HandlerObj. 366 * Each region that uses the handler adds a reference. 367 */ 368 ObjDesc->Device.AddressSpace = HandlerObj; 369 370 /* 371 * Walk the namespace finding all of the regions this 372 * handler will manage. 373 * 374 * Start at the device and search the branch toward 375 * the leaf nodes until either the leaf is encountered or 376 * a device is detected that has an address handler of the 377 * same type. 378 * 379 * In either case, back up and search down the remainder 380 * of the branch 381 */ 382 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Device, ACPI_UINT32_MAX, 383 ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler, 384 HandlerObj, NULL); 385 386UnlockAndExit: 387 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 388 return_ACPI_STATUS (Status); 389} 390 391 392/******************************************************************************* 393 * 394 * FUNCTION: AcpiRemoveAddressSpaceHandler 395 * 396 * PARAMETERS: Device - Handle for the device 397 * SpaceId - The address space ID 398 * Handler - Address of the handler 399 * 400 * RETURN: Status 401 * 402 * DESCRIPTION: Remove a previously installed handler. 403 * 404 ******************************************************************************/ 405 406ACPI_STATUS 407AcpiRemoveAddressSpaceHandler ( 408 ACPI_HANDLE Device, 409 ACPI_ADR_SPACE_TYPE SpaceId, 410 ACPI_ADR_SPACE_HANDLER Handler) 411{ 412 ACPI_OPERAND_OBJECT *ObjDesc; 413 ACPI_OPERAND_OBJECT *HandlerObj; 414 ACPI_OPERAND_OBJECT *RegionObj; 415 ACPI_OPERAND_OBJECT **LastObjPtr; 416 ACPI_NAMESPACE_NODE *Node; 417 ACPI_STATUS Status; 418 419 420 ACPI_FUNCTION_TRACE ("AcpiRemoveAddressSpaceHandler"); 421 422 423 /* Parameter validation */ 424 425 if (!Device) 426 { 427 return_ACPI_STATUS (AE_BAD_PARAMETER); 428 } 429 430 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 431 if (ACPI_FAILURE (Status)) 432 { 433 return_ACPI_STATUS (Status); 434 } 435 436 /* Convert and validate the device handle */ 437 438 Node = AcpiNsMapHandleToNode (Device); 439 if (!Node) 440 { 441 Status = AE_BAD_PARAMETER; 442 goto UnlockAndExit; 443 } 444 445 /* Make sure the internal object exists */ 446 447 ObjDesc = AcpiNsGetAttachedObject (Node); 448 if (!ObjDesc) 449 { 450 Status = AE_NOT_EXIST; 451 goto UnlockAndExit; 452 } 453 454 /* Find the address handler the user requested */ 455 456 HandlerObj = ObjDesc->Device.AddressSpace; 457 LastObjPtr = &ObjDesc->Device.AddressSpace; 458 while (HandlerObj) 459 { 460 /* We have a handler, see if user requested this one */ 461 462 if (HandlerObj->AddressSpace.SpaceId == SpaceId) 463 { 464 /* Matched SpaceId, first dereference this in the Regions */ 465 466 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 467 "Removing address handler %p(%p) for region %s on Device %p(%p)\n", 468 HandlerObj, Handler, AcpiUtGetRegionName (SpaceId), 469 Node, ObjDesc)); 470 471 RegionObj = HandlerObj->AddressSpace.RegionList; 472 473 /* Walk the handler's region list */ 474 475 while (RegionObj) 476 { 477 /* 478 * First disassociate the handler from the region. 479 * 480 * NOTE: this doesn't mean that the region goes away 481 * The region is just inaccessible as indicated to 482 * the _REG method 483 */ 484 AcpiEvDetachRegion (RegionObj, TRUE); 485 486 /* 487 * Walk the list: Just grab the head because the 488 * DetachRegion removed the previous head. 489 */ 490 RegionObj = HandlerObj->AddressSpace.RegionList; 491 492 } 493 494 /* Remove this Handler object from the list */ 495 496 *LastObjPtr = HandlerObj->AddressSpace.Next; 497 498 /* Now we can delete the handler object */ 499 500 AcpiUtRemoveReference (HandlerObj); 501 goto UnlockAndExit; 502 } 503 504 /* Walk the linked list of handlers */ 505 506 LastObjPtr = &HandlerObj->AddressSpace.Next; 507 HandlerObj = HandlerObj->AddressSpace.Next; 508 } 509 510 /* The handler does not exist */ 511 512 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 513 "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n", 514 Handler, AcpiUtGetRegionName (SpaceId), SpaceId, Node, ObjDesc)); 515 516 Status = AE_NOT_EXIST; 517 518UnlockAndExit: 519 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 520 return_ACPI_STATUS (Status); 521} 522 523 524