bmnotify.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:8k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  *
  3.  * Module Name: bmnotify.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 ("bmnotify")
  28. /****************************************************************************
  29.  *                            Internal Functions
  30.  ****************************************************************************/
  31. /****************************************************************************
  32.  *
  33.  * FUNCTION:    bm_generate_notify
  34.  *
  35.  * PARAMETERS:
  36.  *
  37.  * RETURN:
  38.  *
  39.  * DESCRIPTION:
  40.  *
  41.  ****************************************************************************/
  42. acpi_status
  43. bm_generate_notify (
  44. BM_NODE *node,
  45. u32 notify_type)
  46. {
  47. acpi_status status = AE_OK;
  48. BM_DEVICE *device = NULL;
  49. FUNCTION_TRACE("bm_generate_notify");
  50. if (!node) {
  51. return_ACPI_STATUS(AE_BAD_PARAMETER);
  52. }
  53. device = &(node->device);
  54. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Sending notify [%02x] to device [%02x].n", notify_type, node->device.handle));
  55. if (!BM_IS_DRIVER_CONTROL(device)) {
  56. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "No driver installed for device [%02x].n", device->handle));
  57. return_ACPI_STATUS(AE_NOT_EXIST);
  58. }
  59. status = node->driver.notify(notify_type, node->device.handle,
  60. &(node->driver.context));
  61. return_ACPI_STATUS(status);
  62. }
  63. /****************************************************************************
  64.  *
  65.  * FUNCTION:    bm_device_check
  66.  *
  67.  * PARAMETERS:
  68.  *
  69.  * RETURN:
  70.  *
  71.  * DESCRIPTION:
  72.  *
  73.  ****************************************************************************/
  74. acpi_status
  75. bm_device_check (
  76. BM_NODE *node,
  77. u32 *status_change)
  78. {
  79. acpi_status             status = AE_OK;
  80. BM_DEVICE *device = NULL;
  81. BM_DEVICE_STATUS old_status = BM_STATUS_UNKNOWN;
  82. FUNCTION_TRACE("bm_device_check");
  83. if (!node) {
  84. return_ACPI_STATUS(AE_BAD_PARAMETER);
  85. }
  86. device = &(node->device);
  87. if (status_change) {
  88. *status_change = FALSE;
  89. }
  90. old_status = device->status;
  91. /*
  92.  * Parent Present?
  93.  * ---------------
  94.  * Only check this device if its parent is present (which implies
  95.  * this device MAY be present).
  96.  */
  97. if (!BM_NODE_PRESENT(node->parent)) {
  98. return_ACPI_STATUS(AE_OK);
  99. }
  100. /*
  101.  * Get Status:
  102.  * -----------
  103.  * And see if the status has changed.
  104.  */
  105. status = bm_get_status(device);
  106. if (ACPI_FAILURE(status)) {
  107. return_ACPI_STATUS(status);
  108. }
  109. if (old_status == node->device.status) {
  110. return_ACPI_STATUS(AE_OK);
  111. }
  112. if (status_change) {
  113. *status_change = TRUE;
  114. }
  115. /*
  116.  * Device Insertion?
  117.  * -----------------
  118.  */
  119. if ((device->status & BM_STATUS_PRESENT) &&
  120. !(old_status & BM_STATUS_PRESENT)) {
  121. /* TBD: Make sure driver is loaded, and if not, load. */
  122. status = bm_generate_notify(node, BM_NOTIFY_DEVICE_ADDED);
  123. }
  124. /*
  125.  * Device Removal?
  126.  * ---------------
  127.  */
  128. else if (!(device->status & BM_STATUS_PRESENT) &&
  129. (old_status & BM_STATUS_PRESENT)) {
  130. /* TBD: Unload driver if last device instance. */
  131. status = bm_generate_notify(node, BM_NOTIFY_DEVICE_REMOVED);
  132. }
  133. return_ACPI_STATUS(AE_OK);
  134. }
  135. /****************************************************************************
  136.  *
  137.  * FUNCTION:    bm_bus_check
  138.  *
  139.  * PARAMETERS:
  140.  *
  141.  * RETURN:
  142.  *
  143.  * DESCRIPTION:
  144.  *
  145.  ****************************************************************************/
  146. acpi_status
  147. bm_bus_check (
  148. BM_NODE *parent_node)
  149. {
  150. acpi_status             status = AE_OK;
  151. u32 status_change = FALSE;
  152. FUNCTION_TRACE("bm_bus_check");
  153. if (!parent_node) {
  154. return_ACPI_STATUS(AE_BAD_PARAMETER);
  155. }
  156. /*
  157.  * Status Change?
  158.  * --------------
  159.  */
  160. status = bm_device_check(parent_node, &status_change);
  161. if (ACPI_FAILURE(status) || !status_change) {
  162. return_ACPI_STATUS(status);
  163. }
  164. /*
  165.  * Enumerate Scope:
  166.  * ----------------
  167.  * TBD: Enumerate child devices within this device's scope and
  168.  *       run bm_device_check()'s on them...
  169.  */
  170. return_ACPI_STATUS(AE_OK);
  171. }
  172. /****************************************************************************
  173.  *                            External Functions
  174.  ****************************************************************************/
  175. /****************************************************************************
  176.  *
  177.  * FUNCTION:    bm_notify
  178.  *
  179.  * PARAMETERS:
  180.  *
  181.  * RETURN:
  182.  *
  183.  * DESCRIPTION:
  184.  *
  185.  ****************************************************************************/
  186. void
  187. bm_notify (
  188. acpi_handle             acpi_handle,
  189. u32                     notify_value,
  190. void                    *context)
  191. {
  192. acpi_status             status = AE_OK;
  193. BM_NODE *node = NULL;
  194. FUNCTION_TRACE("bm_notify");
  195. /*
  196.  * Resolve the ACPI handle.
  197.  */
  198. status = bm_get_node(0, acpi_handle, &node);
  199. if (ACPI_FAILURE(status)) {
  200. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Recieved notify [%02x] for unknown device [%p].n", notify_value, acpi_handle));
  201. return_VOID;
  202. }
  203. /*
  204.  * Device-Specific or Standard?
  205.  * ----------------------------
  206.  * Device-specific notifies are forwarded to the control module's
  207.  * notify() function for processing.  Standard notifies are handled
  208.  * internally.
  209.  */
  210. if (notify_value > 0x7F) {
  211. status = bm_generate_notify(node, notify_value);
  212. }
  213. else {
  214. switch (notify_value) {
  215. case BM_NOTIFY_BUS_CHECK:
  216. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received BUS CHECK notification for device [%02x].n", node->device.handle));
  217. status = bm_bus_check(node);
  218. break;
  219. case BM_NOTIFY_DEVICE_CHECK:
  220. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received DEVICE CHECK notification for device [%02x].n", node->device.handle));
  221. status = bm_device_check(node, NULL);
  222. break;
  223. case BM_NOTIFY_DEVICE_WAKE:
  224. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received DEVICE WAKE notification for device [%02x].n", node->device.handle));
  225. /* TBD */
  226. break;
  227. case BM_NOTIFY_EJECT_REQUEST:
  228. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received EJECT REQUEST notification for device [%02x].n", node->device.handle));
  229. /* TBD */
  230. break;
  231. case BM_NOTIFY_DEVICE_CHECK_LIGHT:
  232. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received DEVICE CHECK LIGHT notification for device [%02x].n", node->device.handle));
  233. /* TBD: Exactly what does the 'light' mean? */
  234. status = bm_device_check(node, NULL);
  235. break;
  236. case BM_NOTIFY_FREQUENCY_MISMATCH:
  237. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received FREQUENCY MISMATCH notification for device [%02x].n", node->device.handle));
  238. /* TBD */
  239. break;
  240. case BM_NOTIFY_BUS_MODE_MISMATCH:
  241. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received BUS MODE MISMATCH notification for device [%02x].n", node->device.handle));
  242. /* TBD */
  243. break;
  244. case BM_NOTIFY_POWER_FAULT:
  245. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received POWER FAULT notification.n"));
  246. /* TBD */
  247. break;
  248. default:
  249. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Received unknown/unsupported notification.n"));
  250. break;
  251. }
  252. }
  253. return_VOID;
  254. }