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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  *
  3.  * Module Name: bmdriver.c
  4.  *   $Revision: 21 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 Andrew Grover
  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 "bm.h"
  26. #define _COMPONENT ACPI_BUS
  27. MODULE_NAME ("bmdriver")
  28. /****************************************************************************
  29.  *                            External Functions
  30.  ****************************************************************************/
  31. /****************************************************************************
  32.  *
  33.  * FUNCTION:    bm_get_device_power_state
  34.  *
  35.  * PARAMETERS:
  36.  *
  37.  * RETURN:
  38.  *
  39.  * DESCRIPTION:
  40.  *
  41.  ****************************************************************************/
  42. acpi_status
  43. bm_get_device_power_state (
  44. BM_HANDLE               device_handle,
  45. BM_POWER_STATE *state)
  46. {
  47. acpi_status             status = AE_OK;
  48. BM_NODE *node = NULL;
  49. FUNCTION_TRACE("bm_get_device_power_state");
  50. if (!state) {
  51. return_ACPI_STATUS(AE_BAD_PARAMETER);
  52. }
  53. *state = ACPI_STATE_UNKNOWN;
  54. /*
  55.  * Resolve device handle to node.
  56.  */
  57. status = bm_get_node(device_handle, 0, &node);
  58. if (ACPI_FAILURE(status)) {
  59. return_ACPI_STATUS(status);
  60. }
  61. /*
  62.  * Get the current power state.
  63.  */
  64. status = bm_get_power_state(node);
  65. if (ACPI_FAILURE(status)) {
  66. return_ACPI_STATUS(status);
  67. }
  68. *state = node->device.power.state;
  69. return_ACPI_STATUS(status);
  70. }
  71. /****************************************************************************
  72.  *
  73.  * FUNCTION:    bm_set_device_power_state
  74.  *
  75.  * PARAMETERS:
  76.  *
  77.  * RETURN:
  78.  *
  79.  * DESCRIPTION:
  80.  *
  81.  ****************************************************************************/
  82. acpi_status
  83. bm_set_device_power_state (
  84. BM_HANDLE               device_handle,
  85. BM_POWER_STATE state)
  86. {
  87. acpi_status           status = AE_OK;
  88. BM_NODE *node = NULL;
  89. FUNCTION_TRACE("bm_set_device_power_state");
  90. /*
  91.  * Resolve device handle to node.
  92.  */
  93. status = bm_get_node(device_handle, 0, &node);
  94. if (ACPI_FAILURE(status)) {
  95. return_ACPI_STATUS(status);
  96. }
  97. /*
  98.  * Set the current power state.
  99.  */
  100. status = bm_set_power_state(node, state);
  101. if (ACPI_FAILURE(status)) {
  102. return_ACPI_STATUS(status);
  103. }
  104. return_ACPI_STATUS(status);
  105. }
  106. /****************************************************************************
  107.  *
  108.  * FUNCTION:    bm_get_device_status
  109.  *
  110.  * PARAMETERS:
  111.  *    device_handle is really an index number into the array of BM_DEVICE
  112.  *                  structures in info_list.  This data item is passed to
  113.  *                  the registered program's "notify" callback.  It is used
  114.  *                  to retrieve the specific BM_DEVICE structure instance
  115.  *                  associated with the callback.
  116.  *    device_status is a pointer that receives the result of processing
  117.  *                  the device's associated ACPI _STA.
  118.  *
  119.  * RETURN:
  120.  *    The acpi_status value indicates success AE_OK or failure of the function
  121.  *
  122.  * DESCRIPTION: Evaluates the device's ACPI _STA, if it is present.
  123.  *
  124.  ****************************************************************************/
  125. acpi_status
  126. bm_get_device_status (
  127. BM_HANDLE               device_handle,
  128. BM_DEVICE_STATUS        *device_status)
  129. {
  130. acpi_status           status = AE_OK;
  131. BM_NODE *node = NULL;
  132. FUNCTION_TRACE("bm_get_device_status");
  133. if (!device_status) {
  134. return_ACPI_STATUS(AE_BAD_PARAMETER);
  135. }
  136. *device_status = BM_STATUS_UNKNOWN;
  137. /*
  138.  * Resolve device handle to node.
  139.  */
  140. status = bm_get_node(device_handle, 0, &node);
  141. if (ACPI_FAILURE(status)) {
  142. return_ACPI_STATUS(status);
  143. }
  144. /*
  145.  * Parent Present?
  146.  * ---------------
  147.  * If the parent isn't present we can't evalute _STA on the child.
  148.  * Return an unknown status.
  149.  */
  150. if (!BM_NODE_PRESENT(node->parent)) {
  151. return_ACPI_STATUS(AE_OK);
  152. }
  153. /*
  154.  * Dynamic Status?
  155.  * ---------------
  156.  * If _STA isn't present we just return the default status.
  157.  */
  158. if (!(node->device.flags & BM_FLAGS_DYNAMIC_STATUS)) {
  159. *device_status = BM_STATUS_DEFAULT;
  160. return_ACPI_STATUS(AE_OK);
  161. }
  162. /*
  163.  * Evaluate _STA:
  164.  * --------------
  165.  */
  166. status = bm_evaluate_simple_integer(node->device.acpi_handle, "_STA",
  167. &(node->device.status));
  168. if (ACPI_SUCCESS(status)) {
  169. *device_status = node->device.status;
  170. }
  171. return_ACPI_STATUS(status);
  172. }
  173. /****************************************************************************
  174.  *
  175.  * FUNCTION:    bm_get_device_info
  176.  *
  177.  * PARAMETERS:
  178.  *    device_handle An index used to retrieve the associated BM_DEVICE info.
  179.  *    device        A pointer to a BM_DEVICE structure instance pointer.
  180.  *                  This pointed to BM_DEVICE structure will contain the
  181.  *                  this device's information.
  182.  *
  183.  * RETURN:
  184.  *    The acpi_status value indicates success AE_OK or failure of the function
  185.  *
  186.  * DESCRIPTION:
  187.  *    Using the device_handle this function retrieves this device's
  188.  *    BM_DEVICE structure instance and save's it in device.
  189.  *
  190.  ****************************************************************************/
  191. acpi_status
  192. bm_get_device_info (
  193. BM_HANDLE               device_handle,
  194. BM_DEVICE               **device)
  195. {
  196. acpi_status           status = AE_OK;
  197. BM_NODE *node = NULL;
  198. FUNCTION_TRACE("bm_get_device_info");
  199. if (!device) {
  200. return_ACPI_STATUS(AE_BAD_PARAMETER);
  201. }
  202. /*
  203.  * Resolve device handle to internal device.
  204.  */
  205. status = bm_get_node(device_handle, 0, &node);
  206. if (ACPI_FAILURE(status)) {
  207. return_ACPI_STATUS(status);
  208. }
  209. *device = &(node->device);
  210. return_ACPI_STATUS(AE_OK);
  211. }
  212. /****************************************************************************
  213.  *
  214.  * FUNCTION:    bm_get_device_context
  215.  *
  216.  *    device_handle An index used to retrieve the associated BM_DEVICE info.
  217.  *    context       A pointer to a BM_DRIVER_CONTEXT structure instance.
  218.  *
  219.  * RETURN:
  220.  *    The acpi_status value indicates success AE_OK or failure of the function
  221.  *
  222.  * DESCRIPTION:
  223.  *    Using the device_handle this function retrieves this device's
  224.  *    BM_DRIVER_CONTEXT structure instance and save's it in context.
  225.  *
  226.  ****************************************************************************/
  227. acpi_status
  228. bm_get_device_context (
  229. BM_HANDLE               device_handle,
  230. BM_DRIVER_CONTEXT *context)
  231. {
  232. acpi_status           status = AE_OK;
  233. BM_NODE *node = NULL;
  234. FUNCTION_TRACE("bm_get_device_context");
  235. if (!context) {
  236. return_ACPI_STATUS(AE_BAD_PARAMETER);
  237. }
  238. *context = NULL;
  239. /*
  240.  * Resolve device handle to internal device.
  241.  */
  242. status = bm_get_node(device_handle, 0, &node);
  243. if (ACPI_FAILURE(status)) {
  244. return_ACPI_STATUS(status);
  245. }
  246. if (!node->driver.context) {
  247. return_ACPI_STATUS(AE_NULL_ENTRY);
  248. }
  249. *context = node->driver.context;
  250. return_ACPI_STATUS(AE_OK);
  251. }
  252. /****************************************************************************
  253.  *
  254.  * FUNCTION:    bm_register_driver
  255.  *
  256.  * PARAMETERS:
  257.  *
  258.  * RETURN:
  259.  *
  260.  * DESCRIPTION:
  261.  *
  262.  ****************************************************************************/
  263. acpi_status
  264. bm_register_driver (
  265. BM_DEVICE_ID *criteria,
  266. BM_DRIVER *driver)
  267. {
  268. acpi_status           status = AE_NOT_FOUND;
  269. BM_HANDLE_LIST          device_list;
  270. BM_NODE *node = NULL;
  271. BM_DEVICE *device = NULL;
  272. u32                     i = 0;
  273. FUNCTION_TRACE("bm_register_driver");
  274. if (!criteria || !driver || !driver->notify || !driver->request) {
  275. return_ACPI_STATUS(AE_BAD_PARAMETER);
  276. }
  277. MEMSET(&device_list, 0, sizeof(BM_HANDLE_LIST));
  278. /*
  279.  * Find Matches:
  280.  * -------------
  281.  * Search through the entire device hierarchy for matches against
  282.  * the given device criteria.
  283.  */
  284. status = bm_search(BM_HANDLE_ROOT, criteria, &device_list);
  285. if (ACPI_FAILURE(status)) {
  286. return_ACPI_STATUS(status);
  287. }
  288. /*
  289.  * Install driver:
  290.  * ----------------
  291.  * For each match, record the driver information and execute the
  292.  * driver's Notify() funciton (if present) to notify the driver
  293.  * of the device's presence.
  294.  */
  295. for (i = 0; i < device_list.count; i++) {
  296. /* Resolve the device handle. */
  297. status = bm_get_node(device_list.handles[i], 0, &node);
  298. if (ACPI_FAILURE(status)) {
  299. continue;
  300. }
  301. device = &(node->device);
  302. /*
  303.  * Make sure another driver hasn't already registered for
  304.  * this device.
  305.  */
  306. if (BM_IS_DRIVER_CONTROL(device)) {
  307. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Another driver has already registered for device [%02x].n", device->handle));
  308. continue;
  309. }
  310. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registering driver for device [%02x].n", device->handle));
  311. /* Notify driver of new device. */
  312. status = driver->notify(BM_NOTIFY_DEVICE_ADDED,
  313. node->device.handle, &(node->driver.context));
  314. if (ACPI_SUCCESS(status)) {
  315. node->driver.notify = driver->notify;
  316. node->driver.request = driver->request;
  317. node->device.flags |= BM_FLAGS_DRIVER_CONTROL;
  318. }
  319. }
  320. return_ACPI_STATUS(AE_OK);
  321. }
  322. /****************************************************************************
  323.  *
  324.  * FUNCTION:    bm_unregister_driver
  325.  *
  326.  * PARAMETERS:
  327.  *
  328.  * RETURN:
  329.  *
  330.  * DESCRIPTION:
  331.  *
  332.  ****************************************************************************/
  333. acpi_status
  334. bm_unregister_driver (
  335. BM_DEVICE_ID *criteria,
  336. BM_DRIVER *driver)
  337. {
  338. acpi_status           status = AE_NOT_FOUND;
  339. BM_HANDLE_LIST          device_list;
  340. BM_NODE *node = NULL;
  341. BM_DEVICE *device = NULL;
  342. u32                     i = 0;
  343. FUNCTION_TRACE("bm_unregister_driver");
  344. if (!criteria || !driver || !driver->notify || !driver->request) {
  345. return_ACPI_STATUS(AE_BAD_PARAMETER);
  346. }
  347. MEMSET(&device_list, 0, sizeof(BM_HANDLE_LIST));
  348. /*
  349.  * Find Matches:
  350.  * -------------
  351.  * Search through the entire device hierarchy for matches against
  352.  * the given device criteria.
  353.  */
  354. status = bm_search(BM_HANDLE_ROOT, criteria, &device_list);
  355. if (ACPI_FAILURE(status)) {
  356. return_ACPI_STATUS(status);
  357. }
  358. /*
  359.  * Remove driver:
  360.  * ---------------
  361.  * For each match, execute the driver's Notify() function to allow
  362.  * the driver to cleanup each device instance.
  363.  */
  364. for (i = 0; i < device_list.count; i++) {
  365. /* Resolve the device handle. */
  366. status = bm_get_node(device_list.handles[i], 0, &node);
  367. if (ACPI_FAILURE(status)) {
  368. continue;
  369. }
  370. device = &(node->device);
  371. /*
  372.  * Make sure driver has really registered for this device.
  373.  */
  374. if (!BM_IS_DRIVER_CONTROL(device)) {
  375. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Driver hasn't registered for device [%02x].n", device->handle));
  376. continue;
  377. }
  378. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Unregistering driver for device [%02x].n", device->handle));
  379. /* Notify driver of device removal. */
  380. status = node->driver.notify(BM_NOTIFY_DEVICE_REMOVED,
  381. node->device.handle, &(node->driver.context));
  382. if (ACPI_SUCCESS(status)) {
  383. node->driver.notify = NULL;
  384. node->driver.request = NULL;
  385. node->driver.context = NULL;
  386. node->device.flags &= ~BM_FLAGS_DRIVER_CONTROL;
  387. }
  388. }
  389. return_ACPI_STATUS(AE_OK);
  390. }