1/****************************************************************************** 2 * 3 * Module Name: evxface - External interfaces for ACPI events 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2012, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 45#define __EVXFACE_C__ 46 47#include <contrib/dev/acpica/include/acpi.h> 48#include <contrib/dev/acpica/include/accommon.h> 49#include <contrib/dev/acpica/include/acnamesp.h> 50#include <contrib/dev/acpica/include/acevents.h> 51#include <contrib/dev/acpica/include/acinterp.h> 52 53#define _COMPONENT ACPI_EVENTS 54 ACPI_MODULE_NAME ("evxface") 55 56 57/******************************************************************************* 58 * 59 * FUNCTION: AcpiInstallNotifyHandler 60 * 61 * PARAMETERS: Device - The device for which notifies will be handled 62 * HandlerType - The type of handler: 63 * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 64 * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 65 * ACPI_ALL_NOTIFY: Both System and Device 66 * Handler - Address of the handler 67 * Context - Value passed to the handler on each GPE 68 * 69 * RETURN: Status 70 * 71 * DESCRIPTION: Install a handler for notifications on an ACPI Device, 72 * ThermalZone, or Processor object. 73 * 74 * NOTES: The Root namespace object may have only one handler for each 75 * type of notify (System/Device). Device/Thermal/Processor objects 76 * may have one device notify handler, and multiple system notify 77 * handlers. 78 * 79 ******************************************************************************/ 80 81ACPI_STATUS 82AcpiInstallNotifyHandler ( 83 ACPI_HANDLE Device, 84 UINT32 HandlerType, 85 ACPI_NOTIFY_HANDLER Handler, 86 void *Context) 87{ 88 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 89 ACPI_OPERAND_OBJECT *ObjDesc; 90 ACPI_OPERAND_OBJECT *HandlerObj; 91 ACPI_STATUS Status; 92 UINT32 i; 93 94 95 ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler); 96 97 98 /* Parameter validation */ 99 100 if ((!Device) || (!Handler) || (!HandlerType) || 101 (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 102 { 103 return_ACPI_STATUS (AE_BAD_PARAMETER); 104 } 105 106 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 107 if (ACPI_FAILURE (Status)) 108 { 109 return_ACPI_STATUS (Status); 110 } 111 112 /* 113 * Root Object: 114 * Registering a notify handler on the root object indicates that the 115 * caller wishes to receive notifications for all objects. Note that 116 * only one global handler can be registered per notify type. 117 * Ensure that a handler is not already installed. 118 */ 119 if (Device == ACPI_ROOT_OBJECT) 120 { 121 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 122 { 123 if (HandlerType & (i+1)) 124 { 125 if (AcpiGbl_GlobalNotify[i].Handler) 126 { 127 Status = AE_ALREADY_EXISTS; 128 goto UnlockAndExit; 129 } 130 131 AcpiGbl_GlobalNotify[i].Handler = Handler; 132 AcpiGbl_GlobalNotify[i].Context = Context; 133 } 134 } 135 136 goto UnlockAndExit; /* Global notify handler installed, all done */ 137 } 138 139 /* 140 * All Other Objects: 141 * Caller will only receive notifications specific to the target 142 * object. Note that only certain object types are allowed to 143 * receive notifications. 144 */ 145 146 /* Are Notifies allowed on this object? */ 147 148 if (!AcpiEvIsNotifyObject (Node)) 149 { 150 Status = AE_TYPE; 151 goto UnlockAndExit; 152 } 153 154 /* Check for an existing internal object, might not exist */ 155 156 ObjDesc = AcpiNsGetAttachedObject (Node); 157 if (!ObjDesc) 158 { 159 /* Create a new object */ 160 161 ObjDesc = AcpiUtCreateInternalObject (Node->Type); 162 if (!ObjDesc) 163 { 164 Status = AE_NO_MEMORY; 165 goto UnlockAndExit; 166 } 167 168 /* Attach new object to the Node, remove local reference */ 169 170 Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type); 171 AcpiUtRemoveReference (ObjDesc); 172 if (ACPI_FAILURE (Status)) 173 { 174 goto UnlockAndExit; 175 } 176 } 177 178 /* Ensure that the handler is not already installed in the lists */ 179 180 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 181 { 182 if (HandlerType & (i+1)) 183 { 184 HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 185 while (HandlerObj) 186 { 187 if (HandlerObj->Notify.Handler == Handler) 188 { 189 Status = AE_ALREADY_EXISTS; 190 goto UnlockAndExit; 191 } 192 193 HandlerObj = HandlerObj->Notify.Next[i]; 194 } 195 } 196 } 197 198 /* Create and populate a new notify handler object */ 199 200 HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY); 201 if (!HandlerObj) 202 { 203 Status = AE_NO_MEMORY; 204 goto UnlockAndExit; 205 } 206 207 HandlerObj->Notify.Node = Node; 208 HandlerObj->Notify.HandlerType = HandlerType; 209 HandlerObj->Notify.Handler = Handler; 210 HandlerObj->Notify.Context = Context; 211 212 /* Install the handler at the list head(s) */ 213 214 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 215 { 216 if (HandlerType & (i+1)) 217 { 218 HandlerObj->Notify.Next[i] = 219 ObjDesc->CommonNotify.NotifyList[i]; 220 221 ObjDesc->CommonNotify.NotifyList[i] = HandlerObj; 222 } 223 } 224 225 /* Add an extra reference if handler was installed in both lists */ 226 227 if (HandlerType == ACPI_ALL_NOTIFY) 228 { 229 AcpiUtAddReference (HandlerObj); 230 } 231 232 233UnlockAndExit: 234 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 235 return_ACPI_STATUS (Status); 236} 237 238ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler) 239 240 241/******************************************************************************* 242 * 243 * FUNCTION: AcpiRemoveNotifyHandler 244 * 245 * PARAMETERS: Device - The device for which the handler is installed 246 * HandlerType - The type of handler: 247 * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 248 * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 249 * ACPI_ALL_NOTIFY: Both System and Device 250 * Handler - Address of the handler 251 * 252 * RETURN: Status 253 * 254 * DESCRIPTION: Remove a handler for notifies on an ACPI device 255 * 256 ******************************************************************************/ 257 258ACPI_STATUS 259AcpiRemoveNotifyHandler ( 260 ACPI_HANDLE Device, 261 UINT32 HandlerType, 262 ACPI_NOTIFY_HANDLER Handler) 263{ 264 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 265 ACPI_OPERAND_OBJECT *ObjDesc; 266 ACPI_OPERAND_OBJECT *HandlerObj; 267 ACPI_OPERAND_OBJECT *PreviousHandlerObj; 268 ACPI_STATUS Status; 269 UINT32 i; 270 271 272 ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler); 273 274 275 /* Parameter validation */ 276 277 if ((!Device) || (!Handler) || (!HandlerType) || 278 (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 279 { 280 return_ACPI_STATUS (AE_BAD_PARAMETER); 281 } 282
| 1/****************************************************************************** 2 * 3 * Module Name: evxface - External interfaces for ACPI events 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2012, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 45#define __EVXFACE_C__ 46 47#include <contrib/dev/acpica/include/acpi.h> 48#include <contrib/dev/acpica/include/accommon.h> 49#include <contrib/dev/acpica/include/acnamesp.h> 50#include <contrib/dev/acpica/include/acevents.h> 51#include <contrib/dev/acpica/include/acinterp.h> 52 53#define _COMPONENT ACPI_EVENTS 54 ACPI_MODULE_NAME ("evxface") 55 56 57/******************************************************************************* 58 * 59 * FUNCTION: AcpiInstallNotifyHandler 60 * 61 * PARAMETERS: Device - The device for which notifies will be handled 62 * HandlerType - The type of handler: 63 * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 64 * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 65 * ACPI_ALL_NOTIFY: Both System and Device 66 * Handler - Address of the handler 67 * Context - Value passed to the handler on each GPE 68 * 69 * RETURN: Status 70 * 71 * DESCRIPTION: Install a handler for notifications on an ACPI Device, 72 * ThermalZone, or Processor object. 73 * 74 * NOTES: The Root namespace object may have only one handler for each 75 * type of notify (System/Device). Device/Thermal/Processor objects 76 * may have one device notify handler, and multiple system notify 77 * handlers. 78 * 79 ******************************************************************************/ 80 81ACPI_STATUS 82AcpiInstallNotifyHandler ( 83 ACPI_HANDLE Device, 84 UINT32 HandlerType, 85 ACPI_NOTIFY_HANDLER Handler, 86 void *Context) 87{ 88 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 89 ACPI_OPERAND_OBJECT *ObjDesc; 90 ACPI_OPERAND_OBJECT *HandlerObj; 91 ACPI_STATUS Status; 92 UINT32 i; 93 94 95 ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler); 96 97 98 /* Parameter validation */ 99 100 if ((!Device) || (!Handler) || (!HandlerType) || 101 (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 102 { 103 return_ACPI_STATUS (AE_BAD_PARAMETER); 104 } 105 106 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 107 if (ACPI_FAILURE (Status)) 108 { 109 return_ACPI_STATUS (Status); 110 } 111 112 /* 113 * Root Object: 114 * Registering a notify handler on the root object indicates that the 115 * caller wishes to receive notifications for all objects. Note that 116 * only one global handler can be registered per notify type. 117 * Ensure that a handler is not already installed. 118 */ 119 if (Device == ACPI_ROOT_OBJECT) 120 { 121 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 122 { 123 if (HandlerType & (i+1)) 124 { 125 if (AcpiGbl_GlobalNotify[i].Handler) 126 { 127 Status = AE_ALREADY_EXISTS; 128 goto UnlockAndExit; 129 } 130 131 AcpiGbl_GlobalNotify[i].Handler = Handler; 132 AcpiGbl_GlobalNotify[i].Context = Context; 133 } 134 } 135 136 goto UnlockAndExit; /* Global notify handler installed, all done */ 137 } 138 139 /* 140 * All Other Objects: 141 * Caller will only receive notifications specific to the target 142 * object. Note that only certain object types are allowed to 143 * receive notifications. 144 */ 145 146 /* Are Notifies allowed on this object? */ 147 148 if (!AcpiEvIsNotifyObject (Node)) 149 { 150 Status = AE_TYPE; 151 goto UnlockAndExit; 152 } 153 154 /* Check for an existing internal object, might not exist */ 155 156 ObjDesc = AcpiNsGetAttachedObject (Node); 157 if (!ObjDesc) 158 { 159 /* Create a new object */ 160 161 ObjDesc = AcpiUtCreateInternalObject (Node->Type); 162 if (!ObjDesc) 163 { 164 Status = AE_NO_MEMORY; 165 goto UnlockAndExit; 166 } 167 168 /* Attach new object to the Node, remove local reference */ 169 170 Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type); 171 AcpiUtRemoveReference (ObjDesc); 172 if (ACPI_FAILURE (Status)) 173 { 174 goto UnlockAndExit; 175 } 176 } 177 178 /* Ensure that the handler is not already installed in the lists */ 179 180 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 181 { 182 if (HandlerType & (i+1)) 183 { 184 HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 185 while (HandlerObj) 186 { 187 if (HandlerObj->Notify.Handler == Handler) 188 { 189 Status = AE_ALREADY_EXISTS; 190 goto UnlockAndExit; 191 } 192 193 HandlerObj = HandlerObj->Notify.Next[i]; 194 } 195 } 196 } 197 198 /* Create and populate a new notify handler object */ 199 200 HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY); 201 if (!HandlerObj) 202 { 203 Status = AE_NO_MEMORY; 204 goto UnlockAndExit; 205 } 206 207 HandlerObj->Notify.Node = Node; 208 HandlerObj->Notify.HandlerType = HandlerType; 209 HandlerObj->Notify.Handler = Handler; 210 HandlerObj->Notify.Context = Context; 211 212 /* Install the handler at the list head(s) */ 213 214 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 215 { 216 if (HandlerType & (i+1)) 217 { 218 HandlerObj->Notify.Next[i] = 219 ObjDesc->CommonNotify.NotifyList[i]; 220 221 ObjDesc->CommonNotify.NotifyList[i] = HandlerObj; 222 } 223 } 224 225 /* Add an extra reference if handler was installed in both lists */ 226 227 if (HandlerType == ACPI_ALL_NOTIFY) 228 { 229 AcpiUtAddReference (HandlerObj); 230 } 231 232 233UnlockAndExit: 234 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 235 return_ACPI_STATUS (Status); 236} 237 238ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler) 239 240 241/******************************************************************************* 242 * 243 * FUNCTION: AcpiRemoveNotifyHandler 244 * 245 * PARAMETERS: Device - The device for which the handler is installed 246 * HandlerType - The type of handler: 247 * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 248 * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 249 * ACPI_ALL_NOTIFY: Both System and Device 250 * Handler - Address of the handler 251 * 252 * RETURN: Status 253 * 254 * DESCRIPTION: Remove a handler for notifies on an ACPI device 255 * 256 ******************************************************************************/ 257 258ACPI_STATUS 259AcpiRemoveNotifyHandler ( 260 ACPI_HANDLE Device, 261 UINT32 HandlerType, 262 ACPI_NOTIFY_HANDLER Handler) 263{ 264 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 265 ACPI_OPERAND_OBJECT *ObjDesc; 266 ACPI_OPERAND_OBJECT *HandlerObj; 267 ACPI_OPERAND_OBJECT *PreviousHandlerObj; 268 ACPI_STATUS Status; 269 UINT32 i; 270 271 272 ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler); 273 274 275 /* Parameter validation */ 276 277 if ((!Device) || (!Handler) || (!HandlerType) || 278 (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 279 { 280 return_ACPI_STATUS (AE_BAD_PARAMETER); 281 } 282
|
283#ifdef _UNDER_DEVELOPMENT 284 /* Make sure all deferred tasks are completed */
| 283 /* Make sure all deferred notify tasks are completed */
|
285
| 284
|
286 AcpiOsWaitEventsComplete (NULL); 287#endif
| 285 AcpiOsWaitEventsComplete ();
|
288 289 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 290 if (ACPI_FAILURE (Status)) 291 { 292 return_ACPI_STATUS (Status); 293 } 294 295 /* Root Object. Global handlers are removed here */ 296 297 if (Device == ACPI_ROOT_OBJECT) 298 { 299 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 300 { 301 if (HandlerType & (i+1)) 302 { 303 if (!AcpiGbl_GlobalNotify[i].Handler || 304 (AcpiGbl_GlobalNotify[i].Handler != Handler)) 305 { 306 Status = AE_NOT_EXIST; 307 goto UnlockAndExit; 308 } 309 310 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 311 "Removing global notify handler\n")); 312 313 AcpiGbl_GlobalNotify[i].Handler = NULL; 314 AcpiGbl_GlobalNotify[i].Context = NULL; 315 } 316 } 317 318 goto UnlockAndExit; 319 } 320 321 /* All other objects: Are Notifies allowed on this object? */ 322 323 if (!AcpiEvIsNotifyObject (Node)) 324 { 325 Status = AE_TYPE; 326 goto UnlockAndExit; 327 } 328 329 /* Must have an existing internal object */ 330 331 ObjDesc = AcpiNsGetAttachedObject (Node); 332 if (!ObjDesc) 333 { 334 Status = AE_NOT_EXIST; 335 goto UnlockAndExit; 336 } 337 338 /* Internal object exists. Find the handler and remove it */ 339 340 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 341 { 342 if (HandlerType & (i+1)) 343 { 344 HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 345 PreviousHandlerObj = NULL; 346 347 /* Attempt to find the handler in the handler list */ 348 349 while (HandlerObj && 350 (HandlerObj->Notify.Handler != Handler)) 351 { 352 PreviousHandlerObj = HandlerObj; 353 HandlerObj = HandlerObj->Notify.Next[i]; 354 } 355 356 if (!HandlerObj) 357 { 358 Status = AE_NOT_EXIST; 359 goto UnlockAndExit; 360 } 361 362 /* Remove the handler object from the list */ 363 364 if (PreviousHandlerObj) /* Handler is not at the list head */ 365 { 366 PreviousHandlerObj->Notify.Next[i] = 367 HandlerObj->Notify.Next[i]; 368 } 369 else /* Handler is at the list head */ 370 { 371 ObjDesc->CommonNotify.NotifyList[i] = 372 HandlerObj->Notify.Next[i]; 373 } 374 375 AcpiUtRemoveReference (HandlerObj); 376 } 377 } 378 379 380UnlockAndExit: 381 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 382 return_ACPI_STATUS (Status); 383} 384 385ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler) 386 387 388/******************************************************************************* 389 * 390 * FUNCTION: AcpiInstallExceptionHandler 391 * 392 * PARAMETERS: Handler - Pointer to the handler function for the 393 * event 394 * 395 * RETURN: Status 396 * 397 * DESCRIPTION: Saves the pointer to the handler function 398 * 399 ******************************************************************************/ 400 401ACPI_STATUS 402AcpiInstallExceptionHandler ( 403 ACPI_EXCEPTION_HANDLER Handler) 404{ 405 ACPI_STATUS Status; 406 407 408 ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler); 409 410 411 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 412 if (ACPI_FAILURE (Status)) 413 { 414 return_ACPI_STATUS (Status); 415 } 416 417 /* Don't allow two handlers. */ 418 419 if (AcpiGbl_ExceptionHandler) 420 { 421 Status = AE_ALREADY_EXISTS; 422 goto Cleanup; 423 } 424 425 /* Install the handler */ 426 427 AcpiGbl_ExceptionHandler = Handler; 428 429Cleanup: 430 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 431 return_ACPI_STATUS (Status); 432} 433 434ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler) 435 436 437#if (!ACPI_REDUCED_HARDWARE) 438/******************************************************************************* 439 * 440 * FUNCTION: AcpiInstallGlobalEventHandler 441 * 442 * PARAMETERS: Handler - Pointer to the global event handler function 443 * Context - Value passed to the handler on each event 444 * 445 * RETURN: Status 446 * 447 * DESCRIPTION: Saves the pointer to the handler function. The global handler 448 * is invoked upon each incoming GPE and Fixed Event. It is 449 * invoked at interrupt level at the time of the event dispatch. 450 * Can be used to update event counters, etc. 451 * 452 ******************************************************************************/ 453 454ACPI_STATUS 455AcpiInstallGlobalEventHandler ( 456 ACPI_GBL_EVENT_HANDLER Handler, 457 void *Context) 458{ 459 ACPI_STATUS Status; 460 461 462 ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler); 463 464 465 /* Parameter validation */ 466 467 if (!Handler) 468 { 469 return_ACPI_STATUS (AE_BAD_PARAMETER); 470 } 471 472 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 473 if (ACPI_FAILURE (Status)) 474 { 475 return_ACPI_STATUS (Status); 476 } 477 478 /* Don't allow two handlers. */ 479 480 if (AcpiGbl_GlobalEventHandler) 481 { 482 Status = AE_ALREADY_EXISTS; 483 goto Cleanup; 484 } 485 486 AcpiGbl_GlobalEventHandler = Handler; 487 AcpiGbl_GlobalEventHandlerContext = Context; 488 489 490Cleanup: 491 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 492 return_ACPI_STATUS (Status); 493} 494 495ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler) 496 497 498/******************************************************************************* 499 * 500 * FUNCTION: AcpiInstallFixedEventHandler 501 * 502 * PARAMETERS: Event - Event type to enable. 503 * Handler - Pointer to the handler function for the 504 * event 505 * Context - Value passed to the handler on each GPE 506 * 507 * RETURN: Status 508 * 509 * DESCRIPTION: Saves the pointer to the handler function and then enables the 510 * event. 511 * 512 ******************************************************************************/ 513 514ACPI_STATUS 515AcpiInstallFixedEventHandler ( 516 UINT32 Event, 517 ACPI_EVENT_HANDLER Handler, 518 void *Context) 519{ 520 ACPI_STATUS Status; 521 522 523 ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler); 524 525 526 /* Parameter validation */ 527 528 if (Event > ACPI_EVENT_MAX) 529 { 530 return_ACPI_STATUS (AE_BAD_PARAMETER); 531 } 532 533 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 534 if (ACPI_FAILURE (Status)) 535 { 536 return_ACPI_STATUS (Status); 537 } 538 539 /* Don't allow two handlers. */ 540 541 if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler) 542 { 543 Status = AE_ALREADY_EXISTS; 544 goto Cleanup; 545 } 546 547 /* Install the handler before enabling the event */ 548 549 AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 550 AcpiGbl_FixedEventHandlers[Event].Context = Context; 551 552 Status = AcpiEnableEvent (Event, 0); 553 if (ACPI_FAILURE (Status)) 554 { 555 ACPI_WARNING ((AE_INFO, "Could not enable fixed event 0x%X", Event)); 556 557 /* Remove the handler */ 558 559 AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 560 AcpiGbl_FixedEventHandlers[Event].Context = NULL; 561 } 562 else 563 { 564 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 565 "Enabled fixed event %X, Handler=%p\n", Event, Handler)); 566 } 567 568 569Cleanup: 570 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 571 return_ACPI_STATUS (Status); 572} 573 574ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler) 575 576 577/******************************************************************************* 578 * 579 * FUNCTION: AcpiRemoveFixedEventHandler 580 * 581 * PARAMETERS: Event - Event type to disable. 582 * Handler - Address of the handler 583 * 584 * RETURN: Status 585 * 586 * DESCRIPTION: Disables the event and unregisters the event handler. 587 * 588 ******************************************************************************/ 589 590ACPI_STATUS 591AcpiRemoveFixedEventHandler ( 592 UINT32 Event, 593 ACPI_EVENT_HANDLER Handler) 594{ 595 ACPI_STATUS Status = AE_OK; 596 597 598 ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler); 599 600 601 /* Parameter validation */ 602 603 if (Event > ACPI_EVENT_MAX) 604 { 605 return_ACPI_STATUS (AE_BAD_PARAMETER); 606 } 607 608 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 609 if (ACPI_FAILURE (Status)) 610 { 611 return_ACPI_STATUS (Status); 612 } 613 614 /* Disable the event before removing the handler */ 615 616 Status = AcpiDisableEvent (Event, 0); 617 618 /* Always Remove the handler */ 619 620 AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 621 AcpiGbl_FixedEventHandlers[Event].Context = NULL; 622 623 if (ACPI_FAILURE (Status)) 624 { 625 ACPI_WARNING ((AE_INFO, 626 "Could not write to fixed event enable register 0x%X", Event)); 627 } 628 else 629 { 630 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X\n", Event)); 631 } 632 633 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 634 return_ACPI_STATUS (Status); 635} 636 637ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler) 638 639 640/******************************************************************************* 641 * 642 * FUNCTION: AcpiInstallGpeHandler 643 * 644 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 645 * defined GPEs) 646 * GpeNumber - The GPE number within the GPE block 647 * Type - Whether this GPE should be treated as an 648 * edge- or level-triggered interrupt. 649 * Address - Address of the handler 650 * Context - Value passed to the handler on each GPE 651 * 652 * RETURN: Status 653 * 654 * DESCRIPTION: Install a handler for a General Purpose Event. 655 * 656 ******************************************************************************/ 657 658ACPI_STATUS 659AcpiInstallGpeHandler ( 660 ACPI_HANDLE GpeDevice, 661 UINT32 GpeNumber, 662 UINT32 Type, 663 ACPI_GPE_HANDLER Address, 664 void *Context) 665{ 666 ACPI_GPE_EVENT_INFO *GpeEventInfo; 667 ACPI_GPE_HANDLER_INFO *Handler; 668 ACPI_STATUS Status; 669 ACPI_CPU_FLAGS Flags; 670 671 672 ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler); 673 674 675 /* Parameter validation */ 676 677 if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK)) 678 { 679 return_ACPI_STATUS (AE_BAD_PARAMETER); 680 } 681 682 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 683 if (ACPI_FAILURE (Status)) 684 { 685 return_ACPI_STATUS (Status); 686 } 687 688 /* Allocate and init handler object (before lock) */ 689 690 Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO)); 691 if (!Handler) 692 { 693 Status = AE_NO_MEMORY; 694 goto UnlockAndExit; 695 } 696 697 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 698 699 /* Ensure that we have a valid GPE number */ 700 701 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 702 if (!GpeEventInfo) 703 { 704 Status = AE_BAD_PARAMETER; 705 goto FreeAndExit; 706 } 707 708 /* Make sure that there isn't a handler there already */ 709 710 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 711 ACPI_GPE_DISPATCH_HANDLER) 712 { 713 Status = AE_ALREADY_EXISTS; 714 goto FreeAndExit; 715 } 716 717 Handler->Address = Address; 718 Handler->Context = Context; 719 Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; 720 Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags & 721 (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK)); 722 723 /* 724 * If the GPE is associated with a method, it may have been enabled 725 * automatically during initialization, in which case it has to be 726 * disabled now to avoid spurious execution of the handler. 727 */ 728 if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) || 729 (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) && 730 GpeEventInfo->RuntimeCount) 731 { 732 Handler->OriginallyEnabled = TRUE; 733 (void) AcpiEvRemoveGpeReference (GpeEventInfo); 734 735 /* Sanity check of original type against new type */ 736 737 if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK)) 738 { 739 ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)")); 740 } 741 } 742 743 /* Install the handler */ 744 745 GpeEventInfo->Dispatch.Handler = Handler; 746 747 /* Setup up dispatch flags to indicate handler (vs. method/notify) */ 748 749 GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 750 GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER); 751 752 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 753 754 755UnlockAndExit: 756 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 757 return_ACPI_STATUS (Status); 758 759FreeAndExit: 760 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 761 ACPI_FREE (Handler); 762 goto UnlockAndExit; 763} 764 765ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler) 766 767 768/******************************************************************************* 769 * 770 * FUNCTION: AcpiRemoveGpeHandler 771 * 772 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 773 * defined GPEs) 774 * GpeNumber - The event to remove a handler 775 * Address - Address of the handler 776 * 777 * RETURN: Status 778 * 779 * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 780 * 781 ******************************************************************************/ 782 783ACPI_STATUS 784AcpiRemoveGpeHandler ( 785 ACPI_HANDLE GpeDevice, 786 UINT32 GpeNumber, 787 ACPI_GPE_HANDLER Address) 788{ 789 ACPI_GPE_EVENT_INFO *GpeEventInfo; 790 ACPI_GPE_HANDLER_INFO *Handler; 791 ACPI_STATUS Status; 792 ACPI_CPU_FLAGS Flags; 793 794 795 ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler); 796 797 798 /* Parameter validation */ 799 800 if (!Address) 801 { 802 return_ACPI_STATUS (AE_BAD_PARAMETER); 803 } 804
| 286 287 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 288 if (ACPI_FAILURE (Status)) 289 { 290 return_ACPI_STATUS (Status); 291 } 292 293 /* Root Object. Global handlers are removed here */ 294 295 if (Device == ACPI_ROOT_OBJECT) 296 { 297 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 298 { 299 if (HandlerType & (i+1)) 300 { 301 if (!AcpiGbl_GlobalNotify[i].Handler || 302 (AcpiGbl_GlobalNotify[i].Handler != Handler)) 303 { 304 Status = AE_NOT_EXIST; 305 goto UnlockAndExit; 306 } 307 308 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 309 "Removing global notify handler\n")); 310 311 AcpiGbl_GlobalNotify[i].Handler = NULL; 312 AcpiGbl_GlobalNotify[i].Context = NULL; 313 } 314 } 315 316 goto UnlockAndExit; 317 } 318 319 /* All other objects: Are Notifies allowed on this object? */ 320 321 if (!AcpiEvIsNotifyObject (Node)) 322 { 323 Status = AE_TYPE; 324 goto UnlockAndExit; 325 } 326 327 /* Must have an existing internal object */ 328 329 ObjDesc = AcpiNsGetAttachedObject (Node); 330 if (!ObjDesc) 331 { 332 Status = AE_NOT_EXIST; 333 goto UnlockAndExit; 334 } 335 336 /* Internal object exists. Find the handler and remove it */ 337 338 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 339 { 340 if (HandlerType & (i+1)) 341 { 342 HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 343 PreviousHandlerObj = NULL; 344 345 /* Attempt to find the handler in the handler list */ 346 347 while (HandlerObj && 348 (HandlerObj->Notify.Handler != Handler)) 349 { 350 PreviousHandlerObj = HandlerObj; 351 HandlerObj = HandlerObj->Notify.Next[i]; 352 } 353 354 if (!HandlerObj) 355 { 356 Status = AE_NOT_EXIST; 357 goto UnlockAndExit; 358 } 359 360 /* Remove the handler object from the list */ 361 362 if (PreviousHandlerObj) /* Handler is not at the list head */ 363 { 364 PreviousHandlerObj->Notify.Next[i] = 365 HandlerObj->Notify.Next[i]; 366 } 367 else /* Handler is at the list head */ 368 { 369 ObjDesc->CommonNotify.NotifyList[i] = 370 HandlerObj->Notify.Next[i]; 371 } 372 373 AcpiUtRemoveReference (HandlerObj); 374 } 375 } 376 377 378UnlockAndExit: 379 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 380 return_ACPI_STATUS (Status); 381} 382 383ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler) 384 385 386/******************************************************************************* 387 * 388 * FUNCTION: AcpiInstallExceptionHandler 389 * 390 * PARAMETERS: Handler - Pointer to the handler function for the 391 * event 392 * 393 * RETURN: Status 394 * 395 * DESCRIPTION: Saves the pointer to the handler function 396 * 397 ******************************************************************************/ 398 399ACPI_STATUS 400AcpiInstallExceptionHandler ( 401 ACPI_EXCEPTION_HANDLER Handler) 402{ 403 ACPI_STATUS Status; 404 405 406 ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler); 407 408 409 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 410 if (ACPI_FAILURE (Status)) 411 { 412 return_ACPI_STATUS (Status); 413 } 414 415 /* Don't allow two handlers. */ 416 417 if (AcpiGbl_ExceptionHandler) 418 { 419 Status = AE_ALREADY_EXISTS; 420 goto Cleanup; 421 } 422 423 /* Install the handler */ 424 425 AcpiGbl_ExceptionHandler = Handler; 426 427Cleanup: 428 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 429 return_ACPI_STATUS (Status); 430} 431 432ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler) 433 434 435#if (!ACPI_REDUCED_HARDWARE) 436/******************************************************************************* 437 * 438 * FUNCTION: AcpiInstallGlobalEventHandler 439 * 440 * PARAMETERS: Handler - Pointer to the global event handler function 441 * Context - Value passed to the handler on each event 442 * 443 * RETURN: Status 444 * 445 * DESCRIPTION: Saves the pointer to the handler function. The global handler 446 * is invoked upon each incoming GPE and Fixed Event. It is 447 * invoked at interrupt level at the time of the event dispatch. 448 * Can be used to update event counters, etc. 449 * 450 ******************************************************************************/ 451 452ACPI_STATUS 453AcpiInstallGlobalEventHandler ( 454 ACPI_GBL_EVENT_HANDLER Handler, 455 void *Context) 456{ 457 ACPI_STATUS Status; 458 459 460 ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler); 461 462 463 /* Parameter validation */ 464 465 if (!Handler) 466 { 467 return_ACPI_STATUS (AE_BAD_PARAMETER); 468 } 469 470 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 471 if (ACPI_FAILURE (Status)) 472 { 473 return_ACPI_STATUS (Status); 474 } 475 476 /* Don't allow two handlers. */ 477 478 if (AcpiGbl_GlobalEventHandler) 479 { 480 Status = AE_ALREADY_EXISTS; 481 goto Cleanup; 482 } 483 484 AcpiGbl_GlobalEventHandler = Handler; 485 AcpiGbl_GlobalEventHandlerContext = Context; 486 487 488Cleanup: 489 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 490 return_ACPI_STATUS (Status); 491} 492 493ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler) 494 495 496/******************************************************************************* 497 * 498 * FUNCTION: AcpiInstallFixedEventHandler 499 * 500 * PARAMETERS: Event - Event type to enable. 501 * Handler - Pointer to the handler function for the 502 * event 503 * Context - Value passed to the handler on each GPE 504 * 505 * RETURN: Status 506 * 507 * DESCRIPTION: Saves the pointer to the handler function and then enables the 508 * event. 509 * 510 ******************************************************************************/ 511 512ACPI_STATUS 513AcpiInstallFixedEventHandler ( 514 UINT32 Event, 515 ACPI_EVENT_HANDLER Handler, 516 void *Context) 517{ 518 ACPI_STATUS Status; 519 520 521 ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler); 522 523 524 /* Parameter validation */ 525 526 if (Event > ACPI_EVENT_MAX) 527 { 528 return_ACPI_STATUS (AE_BAD_PARAMETER); 529 } 530 531 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 532 if (ACPI_FAILURE (Status)) 533 { 534 return_ACPI_STATUS (Status); 535 } 536 537 /* Don't allow two handlers. */ 538 539 if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler) 540 { 541 Status = AE_ALREADY_EXISTS; 542 goto Cleanup; 543 } 544 545 /* Install the handler before enabling the event */ 546 547 AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 548 AcpiGbl_FixedEventHandlers[Event].Context = Context; 549 550 Status = AcpiEnableEvent (Event, 0); 551 if (ACPI_FAILURE (Status)) 552 { 553 ACPI_WARNING ((AE_INFO, "Could not enable fixed event 0x%X", Event)); 554 555 /* Remove the handler */ 556 557 AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 558 AcpiGbl_FixedEventHandlers[Event].Context = NULL; 559 } 560 else 561 { 562 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 563 "Enabled fixed event %X, Handler=%p\n", Event, Handler)); 564 } 565 566 567Cleanup: 568 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 569 return_ACPI_STATUS (Status); 570} 571 572ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler) 573 574 575/******************************************************************************* 576 * 577 * FUNCTION: AcpiRemoveFixedEventHandler 578 * 579 * PARAMETERS: Event - Event type to disable. 580 * Handler - Address of the handler 581 * 582 * RETURN: Status 583 * 584 * DESCRIPTION: Disables the event and unregisters the event handler. 585 * 586 ******************************************************************************/ 587 588ACPI_STATUS 589AcpiRemoveFixedEventHandler ( 590 UINT32 Event, 591 ACPI_EVENT_HANDLER Handler) 592{ 593 ACPI_STATUS Status = AE_OK; 594 595 596 ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler); 597 598 599 /* Parameter validation */ 600 601 if (Event > ACPI_EVENT_MAX) 602 { 603 return_ACPI_STATUS (AE_BAD_PARAMETER); 604 } 605 606 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 607 if (ACPI_FAILURE (Status)) 608 { 609 return_ACPI_STATUS (Status); 610 } 611 612 /* Disable the event before removing the handler */ 613 614 Status = AcpiDisableEvent (Event, 0); 615 616 /* Always Remove the handler */ 617 618 AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 619 AcpiGbl_FixedEventHandlers[Event].Context = NULL; 620 621 if (ACPI_FAILURE (Status)) 622 { 623 ACPI_WARNING ((AE_INFO, 624 "Could not write to fixed event enable register 0x%X", Event)); 625 } 626 else 627 { 628 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X\n", Event)); 629 } 630 631 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 632 return_ACPI_STATUS (Status); 633} 634 635ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler) 636 637 638/******************************************************************************* 639 * 640 * FUNCTION: AcpiInstallGpeHandler 641 * 642 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 643 * defined GPEs) 644 * GpeNumber - The GPE number within the GPE block 645 * Type - Whether this GPE should be treated as an 646 * edge- or level-triggered interrupt. 647 * Address - Address of the handler 648 * Context - Value passed to the handler on each GPE 649 * 650 * RETURN: Status 651 * 652 * DESCRIPTION: Install a handler for a General Purpose Event. 653 * 654 ******************************************************************************/ 655 656ACPI_STATUS 657AcpiInstallGpeHandler ( 658 ACPI_HANDLE GpeDevice, 659 UINT32 GpeNumber, 660 UINT32 Type, 661 ACPI_GPE_HANDLER Address, 662 void *Context) 663{ 664 ACPI_GPE_EVENT_INFO *GpeEventInfo; 665 ACPI_GPE_HANDLER_INFO *Handler; 666 ACPI_STATUS Status; 667 ACPI_CPU_FLAGS Flags; 668 669 670 ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler); 671 672 673 /* Parameter validation */ 674 675 if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK)) 676 { 677 return_ACPI_STATUS (AE_BAD_PARAMETER); 678 } 679 680 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 681 if (ACPI_FAILURE (Status)) 682 { 683 return_ACPI_STATUS (Status); 684 } 685 686 /* Allocate and init handler object (before lock) */ 687 688 Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO)); 689 if (!Handler) 690 { 691 Status = AE_NO_MEMORY; 692 goto UnlockAndExit; 693 } 694 695 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 696 697 /* Ensure that we have a valid GPE number */ 698 699 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 700 if (!GpeEventInfo) 701 { 702 Status = AE_BAD_PARAMETER; 703 goto FreeAndExit; 704 } 705 706 /* Make sure that there isn't a handler there already */ 707 708 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 709 ACPI_GPE_DISPATCH_HANDLER) 710 { 711 Status = AE_ALREADY_EXISTS; 712 goto FreeAndExit; 713 } 714 715 Handler->Address = Address; 716 Handler->Context = Context; 717 Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; 718 Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags & 719 (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK)); 720 721 /* 722 * If the GPE is associated with a method, it may have been enabled 723 * automatically during initialization, in which case it has to be 724 * disabled now to avoid spurious execution of the handler. 725 */ 726 if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) || 727 (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) && 728 GpeEventInfo->RuntimeCount) 729 { 730 Handler->OriginallyEnabled = TRUE; 731 (void) AcpiEvRemoveGpeReference (GpeEventInfo); 732 733 /* Sanity check of original type against new type */ 734 735 if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK)) 736 { 737 ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)")); 738 } 739 } 740 741 /* Install the handler */ 742 743 GpeEventInfo->Dispatch.Handler = Handler; 744 745 /* Setup up dispatch flags to indicate handler (vs. method/notify) */ 746 747 GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 748 GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER); 749 750 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 751 752 753UnlockAndExit: 754 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 755 return_ACPI_STATUS (Status); 756 757FreeAndExit: 758 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 759 ACPI_FREE (Handler); 760 goto UnlockAndExit; 761} 762 763ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler) 764 765 766/******************************************************************************* 767 * 768 * FUNCTION: AcpiRemoveGpeHandler 769 * 770 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 771 * defined GPEs) 772 * GpeNumber - The event to remove a handler 773 * Address - Address of the handler 774 * 775 * RETURN: Status 776 * 777 * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 778 * 779 ******************************************************************************/ 780 781ACPI_STATUS 782AcpiRemoveGpeHandler ( 783 ACPI_HANDLE GpeDevice, 784 UINT32 GpeNumber, 785 ACPI_GPE_HANDLER Address) 786{ 787 ACPI_GPE_EVENT_INFO *GpeEventInfo; 788 ACPI_GPE_HANDLER_INFO *Handler; 789 ACPI_STATUS Status; 790 ACPI_CPU_FLAGS Flags; 791 792 793 ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler); 794 795 796 /* Parameter validation */ 797 798 if (!Address) 799 { 800 return_ACPI_STATUS (AE_BAD_PARAMETER); 801 } 802
|
| 803 /* Make sure all deferred GPE tasks are completed */ 804 805 AcpiOsWaitEventsComplete (); 806
|
805 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 806 if (ACPI_FAILURE (Status)) 807 { 808 return_ACPI_STATUS (Status); 809 } 810 811 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 812 813 /* Ensure that we have a valid GPE number */ 814 815 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 816 if (!GpeEventInfo) 817 { 818 Status = AE_BAD_PARAMETER; 819 goto UnlockAndExit; 820 } 821 822 /* Make sure that a handler is indeed installed */ 823 824 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != 825 ACPI_GPE_DISPATCH_HANDLER) 826 { 827 Status = AE_NOT_EXIST; 828 goto UnlockAndExit; 829 } 830 831 /* Make sure that the installed handler is the same */ 832 833 if (GpeEventInfo->Dispatch.Handler->Address != Address) 834 { 835 Status = AE_BAD_PARAMETER; 836 goto UnlockAndExit; 837 } 838 839 /* Remove the handler */ 840 841 Handler = GpeEventInfo->Dispatch.Handler; 842 843 /* Restore Method node (if any), set dispatch flags */ 844 845 GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode; 846 GpeEventInfo->Flags &= 847 ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 848 GpeEventInfo->Flags |= Handler->OriginalFlags; 849 850 /* 851 * If the GPE was previously associated with a method and it was 852 * enabled, it should be enabled at this point to restore the 853 * post-initialization configuration. 854 */ 855 if ((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) && 856 Handler->OriginallyEnabled) 857 { 858 (void) AcpiEvAddGpeReference (GpeEventInfo); 859 } 860 861 /* Now we can free the handler object */ 862 863 ACPI_FREE (Handler); 864 865 866UnlockAndExit: 867 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 868 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 869 return_ACPI_STATUS (Status); 870} 871 872ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler) 873 874 875/******************************************************************************* 876 * 877 * FUNCTION: AcpiAcquireGlobalLock 878 * 879 * PARAMETERS: Timeout - How long the caller is willing to wait 880 * Handle - Where the handle to the lock is returned 881 * (if acquired) 882 * 883 * RETURN: Status 884 * 885 * DESCRIPTION: Acquire the ACPI Global Lock 886 * 887 * Note: Allows callers with the same thread ID to acquire the global lock 888 * multiple times. In other words, externally, the behavior of the global lock 889 * is identical to an AML mutex. On the first acquire, a new handle is 890 * returned. On any subsequent calls to acquire by the same thread, the same 891 * handle is returned. 892 * 893 ******************************************************************************/ 894 895ACPI_STATUS 896AcpiAcquireGlobalLock ( 897 UINT16 Timeout, 898 UINT32 *Handle) 899{ 900 ACPI_STATUS Status; 901 902 903 if (!Handle) 904 { 905 return (AE_BAD_PARAMETER); 906 } 907 908 /* Must lock interpreter to prevent race conditions */ 909 910 AcpiExEnterInterpreter (); 911 912 Status = AcpiExAcquireMutexObject (Timeout, 913 AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ()); 914 915 if (ACPI_SUCCESS (Status)) 916 { 917 /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */ 918 919 *Handle = AcpiGbl_GlobalLockHandle; 920 } 921 922 AcpiExExitInterpreter (); 923 return (Status); 924} 925 926ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock) 927 928 929/******************************************************************************* 930 * 931 * FUNCTION: AcpiReleaseGlobalLock 932 * 933 * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 934 * 935 * RETURN: Status 936 * 937 * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid. 938 * 939 ******************************************************************************/ 940 941ACPI_STATUS 942AcpiReleaseGlobalLock ( 943 UINT32 Handle) 944{ 945 ACPI_STATUS Status; 946 947 948 if (!Handle || (Handle != AcpiGbl_GlobalLockHandle)) 949 { 950 return (AE_NOT_ACQUIRED); 951 } 952 953 Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex); 954 return (Status); 955} 956 957ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock) 958 959#endif /* !ACPI_REDUCED_HARDWARE */
| 807 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 808 if (ACPI_FAILURE (Status)) 809 { 810 return_ACPI_STATUS (Status); 811 } 812 813 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 814 815 /* Ensure that we have a valid GPE number */ 816 817 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 818 if (!GpeEventInfo) 819 { 820 Status = AE_BAD_PARAMETER; 821 goto UnlockAndExit; 822 } 823 824 /* Make sure that a handler is indeed installed */ 825 826 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != 827 ACPI_GPE_DISPATCH_HANDLER) 828 { 829 Status = AE_NOT_EXIST; 830 goto UnlockAndExit; 831 } 832 833 /* Make sure that the installed handler is the same */ 834 835 if (GpeEventInfo->Dispatch.Handler->Address != Address) 836 { 837 Status = AE_BAD_PARAMETER; 838 goto UnlockAndExit; 839 } 840 841 /* Remove the handler */ 842 843 Handler = GpeEventInfo->Dispatch.Handler; 844 845 /* Restore Method node (if any), set dispatch flags */ 846 847 GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode; 848 GpeEventInfo->Flags &= 849 ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 850 GpeEventInfo->Flags |= Handler->OriginalFlags; 851 852 /* 853 * If the GPE was previously associated with a method and it was 854 * enabled, it should be enabled at this point to restore the 855 * post-initialization configuration. 856 */ 857 if ((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) && 858 Handler->OriginallyEnabled) 859 { 860 (void) AcpiEvAddGpeReference (GpeEventInfo); 861 } 862 863 /* Now we can free the handler object */ 864 865 ACPI_FREE (Handler); 866 867 868UnlockAndExit: 869 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 870 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 871 return_ACPI_STATUS (Status); 872} 873 874ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler) 875 876 877/******************************************************************************* 878 * 879 * FUNCTION: AcpiAcquireGlobalLock 880 * 881 * PARAMETERS: Timeout - How long the caller is willing to wait 882 * Handle - Where the handle to the lock is returned 883 * (if acquired) 884 * 885 * RETURN: Status 886 * 887 * DESCRIPTION: Acquire the ACPI Global Lock 888 * 889 * Note: Allows callers with the same thread ID to acquire the global lock 890 * multiple times. In other words, externally, the behavior of the global lock 891 * is identical to an AML mutex. On the first acquire, a new handle is 892 * returned. On any subsequent calls to acquire by the same thread, the same 893 * handle is returned. 894 * 895 ******************************************************************************/ 896 897ACPI_STATUS 898AcpiAcquireGlobalLock ( 899 UINT16 Timeout, 900 UINT32 *Handle) 901{ 902 ACPI_STATUS Status; 903 904 905 if (!Handle) 906 { 907 return (AE_BAD_PARAMETER); 908 } 909 910 /* Must lock interpreter to prevent race conditions */ 911 912 AcpiExEnterInterpreter (); 913 914 Status = AcpiExAcquireMutexObject (Timeout, 915 AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ()); 916 917 if (ACPI_SUCCESS (Status)) 918 { 919 /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */ 920 921 *Handle = AcpiGbl_GlobalLockHandle; 922 } 923 924 AcpiExExitInterpreter (); 925 return (Status); 926} 927 928ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock) 929 930 931/******************************************************************************* 932 * 933 * FUNCTION: AcpiReleaseGlobalLock 934 * 935 * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 936 * 937 * RETURN: Status 938 * 939 * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid. 940 * 941 ******************************************************************************/ 942 943ACPI_STATUS 944AcpiReleaseGlobalLock ( 945 UINT32 Handle) 946{ 947 ACPI_STATUS Status; 948 949 950 if (!Handle || (Handle != AcpiGbl_GlobalLockHandle)) 951 { 952 return (AE_NOT_ACQUIRED); 953 } 954 955 Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex); 956 return (Status); 957} 958 959ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock) 960 961#endif /* !ACPI_REDUCED_HARDWARE */
|