evxface.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:16k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: evxface - External interfaces for ACPI events
  4.  *              $Revision: 116 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include "acpi.h"
  25. #include "achware.h"
  26. #include "acnamesp.h"
  27. #include "acevents.h"
  28. #include "amlcode.h"
  29. #include "acinterp.h"
  30. #define _COMPONENT          ACPI_EVENTS
  31.  MODULE_NAME         ("evxface")
  32. /*******************************************************************************
  33.  *
  34.  * FUNCTION:    Acpi_install_fixed_event_handler
  35.  *
  36.  * PARAMETERS:  Event           - Event type to enable.
  37.  *              Handler         - Pointer to the handler function for the
  38.  *                                event
  39.  *              Context         - Value passed to the handler on each GPE
  40.  *
  41.  * RETURN:      Status
  42.  *
  43.  * DESCRIPTION: Saves the pointer to the handler function and then enables the
  44.  *              event.
  45.  *
  46.  ******************************************************************************/
  47. acpi_status
  48. acpi_install_fixed_event_handler (
  49. u32                     event,
  50. acpi_event_handler      handler,
  51. void                    *context)
  52. {
  53. acpi_status             status;
  54. FUNCTION_TRACE ("Acpi_install_fixed_event_handler");
  55. /* Parameter validation */
  56. if (event > ACPI_EVENT_MAX) {
  57. return_ACPI_STATUS (AE_BAD_PARAMETER);
  58. }
  59. acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
  60. /* Don't allow two handlers. */
  61. if (NULL != acpi_gbl_fixed_event_handlers[event].handler) {
  62. status = AE_EXIST;
  63. goto cleanup;
  64. }
  65. /* Install the handler before enabling the event */
  66. acpi_gbl_fixed_event_handlers[event].handler = handler;
  67. acpi_gbl_fixed_event_handlers[event].context = context;
  68. status = acpi_enable_event (event, ACPI_EVENT_FIXED, 0);
  69. if (!ACPI_SUCCESS (status)) {
  70. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.n"));
  71. /* Remove the handler */
  72. acpi_gbl_fixed_event_handlers[event].handler = NULL;
  73. acpi_gbl_fixed_event_handlers[event].context = NULL;
  74. }
  75. else {
  76. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  77. "Enabled fixed event %X, Handler=%pn", event, handler));
  78. }
  79. cleanup:
  80. acpi_ut_release_mutex (ACPI_MTX_EVENTS);
  81. return_ACPI_STATUS (status);
  82. }
  83. /*******************************************************************************
  84.  *
  85.  * FUNCTION:    Acpi_remove_fixed_event_handler
  86.  *
  87.  * PARAMETERS:  Event           - Event type to disable.
  88.  *              Handler         - Address of the handler
  89.  *
  90.  * RETURN:      Status
  91.  *
  92.  * DESCRIPTION: Disables the event and unregisters the event handler.
  93.  *
  94.  ******************************************************************************/
  95. acpi_status
  96. acpi_remove_fixed_event_handler (
  97. u32                     event,
  98. acpi_event_handler      handler)
  99. {
  100. acpi_status             status = AE_OK;
  101. FUNCTION_TRACE ("Acpi_remove_fixed_event_handler");
  102. /* Parameter validation */
  103. if (event > ACPI_EVENT_MAX) {
  104. return_ACPI_STATUS (AE_BAD_PARAMETER);
  105. }
  106. acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
  107. /* Disable the event before removing the handler */
  108. status = acpi_disable_event(event, ACPI_EVENT_FIXED, 0);
  109. /* Always Remove the handler */
  110. acpi_gbl_fixed_event_handlers[event].handler = NULL;
  111. acpi_gbl_fixed_event_handlers[event].context = NULL;
  112. if (!ACPI_SUCCESS (status)) {
  113. ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
  114. "Could not write to fixed event enable register.n"));
  115. }
  116. else {
  117. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.n", event));
  118. }
  119. acpi_ut_release_mutex (ACPI_MTX_EVENTS);
  120. return_ACPI_STATUS (status);
  121. }
  122. /*******************************************************************************
  123.  *
  124.  * FUNCTION:    Acpi_install_notify_handler
  125.  *
  126.  * PARAMETERS:  Device          - The device for which notifies will be handled
  127.  *              Handler_type    - The type of handler:
  128.  *                                  ACPI_SYSTEM_NOTIFY: System_handler (00-7f)
  129.  *                                  ACPI_DEVICE_NOTIFY: Driver_handler (80-ff)
  130.  *              Handler         - Address of the handler
  131.  *              Context         - Value passed to the handler on each GPE
  132.  *
  133.  * RETURN:      Status
  134.  *
  135.  * DESCRIPTION: Install a handler for notifies on an ACPI device
  136.  *
  137.  ******************************************************************************/
  138. acpi_status
  139. acpi_install_notify_handler (
  140. acpi_handle             device,
  141. u32                     handler_type,
  142. acpi_notify_handler     handler,
  143. void                    *context)
  144. {
  145. acpi_operand_object     *obj_desc;
  146. acpi_operand_object     *notify_obj;
  147. acpi_namespace_node     *device_node;
  148. acpi_status             status = AE_OK;
  149. FUNCTION_TRACE ("Acpi_install_notify_handler");
  150. /* Parameter validation */
  151. if ((!handler) ||
  152. (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
  153. return_ACPI_STATUS (AE_BAD_PARAMETER);
  154. }
  155. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  156. /* Convert and validate the device handle */
  157. device_node = acpi_ns_map_handle_to_node (device);
  158. if (!device_node) {
  159. status = AE_BAD_PARAMETER;
  160. goto unlock_and_exit;
  161. }
  162. /*
  163.  * Root Object:
  164.  * Registering a notify handler on the root object indicates that the
  165.  * caller wishes to receive notifications for all objects.  Note that
  166.  * only one <external> global handler can be regsitered (per notify type).
  167.  */
  168. if (device == ACPI_ROOT_OBJECT) {
  169. /* Make sure the handler is not already installed */
  170. if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
  171.   acpi_gbl_sys_notify.handler) ||
  172. ((handler_type == ACPI_DEVICE_NOTIFY) &&
  173.   acpi_gbl_drv_notify.handler)) {
  174. status = AE_EXIST;
  175. goto unlock_and_exit;
  176. }
  177. if (handler_type == ACPI_SYSTEM_NOTIFY) {
  178. acpi_gbl_sys_notify.node = device_node;
  179. acpi_gbl_sys_notify.handler = handler;
  180. acpi_gbl_sys_notify.context = context;
  181. }
  182. else /* ACPI_DEVICE_NOTIFY */ {
  183. acpi_gbl_drv_notify.node = device_node;
  184. acpi_gbl_drv_notify.handler = handler;
  185. acpi_gbl_drv_notify.context = context;
  186. }
  187. /* Global notify handler installed */
  188. }
  189. /*
  190.  * All Other Objects:
  191.  * Caller will only receive notifications specific to the target object.
  192.  * Note that only certain object types can receive notifications.
  193.  */
  194. else {
  195. /*
  196.  * These are the ONLY objects that can receive ACPI notifications
  197.  */
  198. if ((device_node->type != ACPI_TYPE_DEVICE)    &&
  199. (device_node->type != ACPI_TYPE_PROCESSOR) &&
  200. (device_node->type != ACPI_TYPE_POWER)     &&
  201. (device_node->type != ACPI_TYPE_THERMAL)) {
  202. status = AE_BAD_PARAMETER;
  203. goto unlock_and_exit;
  204. }
  205. /* Check for an existing internal object */
  206. obj_desc = acpi_ns_get_attached_object (device_node);
  207. if (obj_desc) {
  208. /* Object exists - make sure there's no handler */
  209. if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
  210.   obj_desc->device.sys_handler) ||
  211. ((handler_type == ACPI_DEVICE_NOTIFY) &&
  212.   obj_desc->device.drv_handler)) {
  213. status = AE_EXIST;
  214. goto unlock_and_exit;
  215. }
  216. }
  217. else {
  218. /* Create a new object */
  219. obj_desc = acpi_ut_create_internal_object (device_node->type);
  220. if (!obj_desc) {
  221. status = AE_NO_MEMORY;
  222. goto unlock_and_exit;
  223. }
  224. /* Attach new object to the Node */
  225. status = acpi_ns_attach_object (device, obj_desc, (u8) device_node->type);
  226. if (ACPI_FAILURE (status)) {
  227. goto unlock_and_exit;
  228. }
  229. }
  230. /* Install the handler */
  231. notify_obj = acpi_ut_create_internal_object (INTERNAL_TYPE_NOTIFY);
  232. if (!notify_obj) {
  233. status = AE_NO_MEMORY;
  234. goto unlock_and_exit;
  235. }
  236. notify_obj->notify_handler.node = device_node;
  237. notify_obj->notify_handler.handler = handler;
  238. notify_obj->notify_handler.context = context;
  239. if (handler_type == ACPI_SYSTEM_NOTIFY) {
  240. obj_desc->device.sys_handler = notify_obj;
  241. }
  242. else /* ACPI_DEVICE_NOTIFY */ {
  243. obj_desc->device.drv_handler = notify_obj;
  244. }
  245. }
  246. unlock_and_exit:
  247. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  248. return_ACPI_STATUS (status);
  249. }
  250. /*******************************************************************************
  251.  *
  252.  * FUNCTION:    Acpi_remove_notify_handler
  253.  *
  254.  * PARAMETERS:  Device          - The device for which notifies will be handled
  255.  *              Handler_type    - The type of handler:
  256.  *                                  ACPI_SYSTEM_NOTIFY: System_handler (00-7f)
  257.  *                                  ACPI_DEVICE_NOTIFY: Driver_handler (80-ff)
  258.  *              Handler         - Address of the handler
  259.  * RETURN:      Status
  260.  *
  261.  * DESCRIPTION: Remove a handler for notifies on an ACPI device
  262.  *
  263.  ******************************************************************************/
  264. acpi_status
  265. acpi_remove_notify_handler (
  266. acpi_handle             device,
  267. u32                     handler_type,
  268. acpi_notify_handler     handler)
  269. {
  270. acpi_operand_object     *notify_obj;
  271. acpi_operand_object     *obj_desc;
  272. acpi_namespace_node     *device_node;
  273. acpi_status             status = AE_OK;
  274. FUNCTION_TRACE ("Acpi_remove_notify_handler");
  275. /* Parameter validation */
  276. if ((!handler) ||
  277. (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
  278. return_ACPI_STATUS (AE_BAD_PARAMETER);
  279. }
  280. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  281. /* Convert and validate the device handle */
  282. device_node = acpi_ns_map_handle_to_node (device);
  283. if (!device_node) {
  284. status = AE_BAD_PARAMETER;
  285. goto unlock_and_exit;
  286. }
  287. /*
  288.  * Root Object
  289.  */
  290. if (device == ACPI_ROOT_OBJECT) {
  291. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.n"));
  292. if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
  293.   !acpi_gbl_sys_notify.handler) ||
  294. ((handler_type == ACPI_DEVICE_NOTIFY) &&
  295.   !acpi_gbl_drv_notify.handler)) {
  296. status = AE_NOT_EXIST;
  297. goto unlock_and_exit;
  298. }
  299. if (handler_type == ACPI_SYSTEM_NOTIFY) {
  300. acpi_gbl_sys_notify.node  = NULL;
  301. acpi_gbl_sys_notify.handler = NULL;
  302. acpi_gbl_sys_notify.context = NULL;
  303. }
  304. else {
  305. acpi_gbl_drv_notify.node  = NULL;
  306. acpi_gbl_drv_notify.handler = NULL;
  307. acpi_gbl_drv_notify.context = NULL;
  308. }
  309. }
  310. /*
  311.  * All Other Objects
  312.  */
  313. else {
  314. /*
  315.  * These are the ONLY objects that can receive ACPI notifications
  316.  */
  317. if ((device_node->type != ACPI_TYPE_DEVICE)    &&
  318. (device_node->type != ACPI_TYPE_PROCESSOR) &&
  319. (device_node->type != ACPI_TYPE_POWER)     &&
  320. (device_node->type != ACPI_TYPE_THERMAL)) {
  321. status = AE_BAD_PARAMETER;
  322. goto unlock_and_exit;
  323. }
  324. /* Check for an existing internal object */
  325. obj_desc = acpi_ns_get_attached_object (device_node);
  326. if (!obj_desc) {
  327. status = AE_NOT_EXIST;
  328. goto unlock_and_exit;
  329. }
  330. /* Object exists - make sure there's an existing handler */
  331. if (handler_type == ACPI_SYSTEM_NOTIFY) {
  332. notify_obj = obj_desc->device.sys_handler;
  333. }
  334. else {
  335. notify_obj = obj_desc->device.drv_handler;
  336. }
  337. if ((!notify_obj) ||
  338. (notify_obj->notify_handler.handler != handler)) {
  339. status = AE_BAD_PARAMETER;
  340. goto unlock_and_exit;
  341. }
  342. /* Remove the handler */
  343. if (handler_type == ACPI_SYSTEM_NOTIFY) {
  344. obj_desc->device.sys_handler = NULL;
  345. }
  346. else {
  347. obj_desc->device.drv_handler = NULL;
  348. }
  349. acpi_ut_remove_reference (notify_obj);
  350. }
  351. unlock_and_exit:
  352. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  353. return_ACPI_STATUS (status);
  354. }
  355. /*******************************************************************************
  356.  *
  357.  * FUNCTION:    Acpi_install_gpe_handler
  358.  *
  359.  * PARAMETERS:  Gpe_number      - The GPE number.  The numbering scheme is
  360.  *                                bank 0 first, then bank 1.
  361.  *              Type            - Whether this GPE should be treated as an
  362.  *                                edge- or level-triggered interrupt.
  363.  *              Handler         - Address of the handler
  364.  *              Context         - Value passed to the handler on each GPE
  365.  *
  366.  * RETURN:      Status
  367.  *
  368.  * DESCRIPTION: Install a handler for a General Purpose Event.
  369.  *
  370.  ******************************************************************************/
  371. acpi_status
  372. acpi_install_gpe_handler (
  373. u32                     gpe_number,
  374. u32                     type,
  375. acpi_gpe_handler        handler,
  376. void                    *context)
  377. {
  378. acpi_status             status = AE_OK;
  379. FUNCTION_TRACE ("Acpi_install_gpe_handler");
  380. /* Parameter validation */
  381. if (!handler || (gpe_number > ACPI_GPE_MAX)) {
  382. return_ACPI_STATUS (AE_BAD_PARAMETER);
  383. }
  384. /* Ensure that we have a valid GPE number */
  385. if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) {
  386. return_ACPI_STATUS (AE_BAD_PARAMETER);
  387. }
  388. acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
  389. /* Make sure that there isn't a handler there already */
  390. if (acpi_gbl_gpe_info[gpe_number].handler) {
  391. status = AE_EXIST;
  392. goto cleanup;
  393. }
  394. /* Install the handler */
  395. acpi_gbl_gpe_info[gpe_number].handler = handler;
  396. acpi_gbl_gpe_info[gpe_number].context = context;
  397. acpi_gbl_gpe_info[gpe_number].type = (u8) type;
  398. /* Clear the GPE (of stale events), the enable it */
  399. acpi_hw_clear_gpe (gpe_number);
  400. acpi_hw_enable_gpe (gpe_number);
  401. cleanup:
  402. acpi_ut_release_mutex (ACPI_MTX_EVENTS);
  403. return_ACPI_STATUS (status);
  404. }
  405. /*******************************************************************************
  406.  *
  407.  * FUNCTION:    Acpi_remove_gpe_handler
  408.  *
  409.  * PARAMETERS:  Gpe_number      - The event to remove a handler
  410.  *              Handler         - Address of the handler
  411.  *
  412.  * RETURN:      Status
  413.  *
  414.  * DESCRIPTION: Remove a handler for a General Purpose Acpi_event.
  415.  *
  416.  ******************************************************************************/
  417. acpi_status
  418. acpi_remove_gpe_handler (
  419. u32                     gpe_number,
  420. acpi_gpe_handler        handler)
  421. {
  422. acpi_status             status = AE_OK;
  423. FUNCTION_TRACE ("Acpi_remove_gpe_handler");
  424. /* Parameter validation */
  425. if (!handler || (gpe_number > ACPI_GPE_MAX)) {
  426. return_ACPI_STATUS (AE_BAD_PARAMETER);
  427. }
  428. /* Ensure that we have a valid GPE number */
  429. if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) {
  430. return_ACPI_STATUS (AE_BAD_PARAMETER);
  431. }
  432. /* Disable the GPE before removing the handler */
  433. acpi_hw_disable_gpe (gpe_number);
  434. acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
  435. /* Make sure that the installed handler is the same */
  436. if (acpi_gbl_gpe_info[gpe_number].handler != handler) {
  437. acpi_hw_enable_gpe (gpe_number);
  438. status = AE_BAD_PARAMETER;
  439. goto cleanup;
  440. }
  441. /* Remove the handler */
  442. acpi_gbl_gpe_info[gpe_number].handler = NULL;
  443. acpi_gbl_gpe_info[gpe_number].context = NULL;
  444. cleanup:
  445. acpi_ut_release_mutex (ACPI_MTX_EVENTS);
  446. return_ACPI_STATUS (status);
  447. }
  448. /*******************************************************************************
  449.  *
  450.  * FUNCTION:    Acpi_acquire_global_lock
  451.  *
  452.  * PARAMETERS:  Timeout         - How long the caller is willing to wait
  453.  *              Out_handle      - A handle to the lock if acquired
  454.  *
  455.  * RETURN:      Status
  456.  *
  457.  * DESCRIPTION: Acquire the ACPI Global Lock
  458.  *
  459.  ******************************************************************************/
  460. acpi_status
  461. acpi_acquire_global_lock (
  462. void)
  463. {
  464. acpi_status             status;
  465. status = acpi_ex_enter_interpreter ();
  466. if (ACPI_FAILURE (status)) {
  467. return (status);
  468. }
  469. /*
  470.  * TBD: [Restructure] add timeout param to internal interface, and
  471.  * perhaps INTERPRETER_LOCKED
  472.  */
  473. status = acpi_ev_acquire_global_lock ();
  474. acpi_ex_exit_interpreter ();
  475. return (status);
  476. }
  477. /*******************************************************************************
  478.  *
  479.  * FUNCTION:    Acpi_release_global_lock
  480.  *
  481.  * PARAMETERS:  Handle      - Returned from Acpi_acquire_global_lock
  482.  *
  483.  * RETURN:      Status
  484.  *
  485.  * DESCRIPTION: Release the ACPI Global Lock
  486.  *
  487.  ******************************************************************************/
  488. acpi_status
  489. acpi_release_global_lock (
  490. void)
  491. {
  492. acpi_ev_release_global_lock ();
  493. return (AE_OK);
  494. }