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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: nsinit - namespace initialization
  4.  *              $Revision: 33 $
  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 "acnamesp.h"
  26. #include "acdispat.h"
  27. #include "acinterp.h"
  28. #define _COMPONENT          ACPI_NAMESPACE
  29.  MODULE_NAME         ("nsinit")
  30. /*******************************************************************************
  31.  *
  32.  * FUNCTION:    Acpi_ns_initialize_objects
  33.  *
  34.  * PARAMETERS:  None
  35.  *
  36.  * RETURN:      Status
  37.  *
  38.  * DESCRIPTION: Walk the entire namespace and perform any necessary
  39.  *              initialization on the objects found therein
  40.  *
  41.  ******************************************************************************/
  42. acpi_status
  43. acpi_ns_initialize_objects (
  44. void)
  45. {
  46. acpi_status             status;
  47. acpi_init_walk_info     info;
  48. FUNCTION_TRACE ("Ns_initialize_objects");
  49. ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  50. "**** Starting initialization of namespace objects ****n"));
  51. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Completing Region and Field initialization:"));
  52. info.field_count = 0;
  53. info.field_init = 0;
  54. info.op_region_count = 0;
  55. info.op_region_init = 0;
  56. info.object_count = 0;
  57. /* Walk entire namespace from the supplied root */
  58. status = acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  59.   ACPI_UINT32_MAX, acpi_ns_init_one_object,
  60.   &info, NULL);
  61. if (ACPI_FAILURE (status)) {
  62. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Walk_namespace failed! %xn", status));
  63. }
  64. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK,
  65. "n%d/%d Regions, %d/%d Fields initialized (%d nodes total)n",
  66. info.op_region_init, info.op_region_count, info.field_init,
  67. info.field_count, info.object_count));
  68. ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  69. "%d Control Methods foundn", info.method_count));
  70. ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  71. "%d Op Regions foundn", info.op_region_count));
  72. return_ACPI_STATUS (AE_OK);
  73. }
  74. /*******************************************************************************
  75.  *
  76.  * FUNCTION:    Acpi_ns_initialize_devices
  77.  *
  78.  * PARAMETERS:  None
  79.  *
  80.  * RETURN:      acpi_status
  81.  *
  82.  * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.
  83.  *              This means running _INI on all present devices.
  84.  *
  85.  *              Note: We install PCI config space handler on region access,
  86.  *              not here.
  87.  *
  88.  ******************************************************************************/
  89. acpi_status
  90. acpi_ns_initialize_devices (
  91. void)
  92. {
  93. acpi_status             status;
  94. acpi_device_walk_info   info;
  95. FUNCTION_TRACE ("Ns_initialize_devices");
  96. info.device_count = 0;
  97. info.num_STA = 0;
  98. info.num_INI = 0;
  99. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Executing device _INI methods:"));
  100. status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
  101.   ACPI_UINT32_MAX, FALSE, acpi_ns_init_one_device, &info, NULL);
  102. if (ACPI_FAILURE (status)) {
  103. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Walk_namespace failed! %xn", status));
  104. }
  105. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK,
  106. "n%d Devices found: %d _STA, %d _INIn",
  107. info.device_count, info.num_STA, info.num_INI));
  108. return_ACPI_STATUS (status);
  109. }
  110. /*******************************************************************************
  111.  *
  112.  * FUNCTION:    Acpi_ns_init_one_object
  113.  *
  114.  * PARAMETERS:  Obj_handle      - Node
  115.  *              Level           - Current nesting level
  116.  *              Context         - Points to a init info struct
  117.  *              Return_value    - Not used
  118.  *
  119.  * RETURN:      Status
  120.  *
  121.  * DESCRIPTION: Callback from Acpi_walk_namespace. Invoked for every object
  122.  *              within the  namespace.
  123.  *
  124.  *              Currently, the only objects that require initialization are:
  125.  *              1) Methods
  126.  *              2) Op Regions
  127.  *
  128.  ******************************************************************************/
  129. acpi_status
  130. acpi_ns_init_one_object (
  131. acpi_handle             obj_handle,
  132. u32                     level,
  133. void                    *context,
  134. void                    **return_value)
  135. {
  136. acpi_object_type8       type;
  137. acpi_status             status;
  138. acpi_init_walk_info     *info = (acpi_init_walk_info *) context;
  139. acpi_namespace_node     *node = (acpi_namespace_node *) obj_handle;
  140. acpi_operand_object     *obj_desc;
  141. PROC_NAME ("Ns_init_one_object");
  142. info->object_count++;
  143. /* And even then, we are only interested in a few object types */
  144. type = acpi_ns_get_type (obj_handle);
  145. obj_desc = node->object;
  146. if (!obj_desc) {
  147. return (AE_OK);
  148. }
  149. if ((type != ACPI_TYPE_REGION) &&
  150. (type != ACPI_TYPE_BUFFER_FIELD)) {
  151. return (AE_OK);
  152. }
  153. /*
  154.  * Must lock the interpreter before executing AML code
  155.  */
  156. status = acpi_ex_enter_interpreter ();
  157. if (ACPI_FAILURE (status)) {
  158. return (status);
  159. }
  160. switch (type) {
  161. case ACPI_TYPE_REGION:
  162. info->op_region_count++;
  163. if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
  164. break;
  165. }
  166. info->op_region_init++;
  167. status = acpi_ds_get_region_arguments (obj_desc);
  168. if (ACPI_FAILURE (status)) {
  169. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "n"));
  170. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  171. "%s while getting region arguments [%4.4s]n",
  172. acpi_format_exception (status), (char*)&node->name));
  173. }
  174. if (!(acpi_dbg_level & ACPI_LV_INIT)) {
  175. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "."));
  176. }
  177. break;
  178. case ACPI_TYPE_BUFFER_FIELD:
  179. info->field_count++;
  180. if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
  181. break;
  182. }
  183. info->field_init++;
  184. status = acpi_ds_get_buffer_field_arguments (obj_desc);
  185. if (ACPI_FAILURE (status)) {
  186. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "n"));
  187. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  188. "%s while getting buffer field arguments [%4.4s]n",
  189. acpi_format_exception (status), (char*)&node->name));
  190. }
  191. if (!(acpi_dbg_level & ACPI_LV_INIT)) {
  192. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "."));
  193. }
  194. break;
  195. default:
  196. break;
  197. }
  198. /*
  199.  * We ignore errors from above, and always return OK, since
  200.  * we don't want to abort the walk on a single error.
  201.  */
  202. acpi_ex_exit_interpreter ();
  203. return (AE_OK);
  204. }
  205. /*******************************************************************************
  206.  *
  207.  * FUNCTION:    Acpi_ns_init_one_device
  208.  *
  209.  * PARAMETERS:  acpi_walk_callback
  210.  *
  211.  * RETURN:      acpi_status
  212.  *
  213.  * DESCRIPTION: This is called once per device soon after ACPI is enabled
  214.  *              to initialize each device. It determines if the device is
  215.  *              present, and if so, calls _INI.
  216.  *
  217.  ******************************************************************************/
  218. acpi_status
  219. acpi_ns_init_one_device (
  220. acpi_handle             obj_handle,
  221. u32                     nesting_level,
  222. void                    *context,
  223. void                    **return_value)
  224. {
  225. acpi_status             status;
  226. acpi_namespace_node    *node;
  227. u32                     flags;
  228. acpi_device_walk_info  *info = (acpi_device_walk_info *) context;
  229. FUNCTION_TRACE ("Ns_init_one_device");
  230. if (!(acpi_dbg_level & ACPI_LV_INIT)) {
  231. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "."));
  232. }
  233. info->device_count++;
  234. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  235. node = acpi_ns_map_handle_to_node (obj_handle);
  236. if (!node) {
  237. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  238. return (AE_BAD_PARAMETER);
  239. }
  240. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  241. /*
  242.  * Run _STA to determine if we can run _INI on the device.
  243.  */
  244. DEBUG_EXEC (acpi_ut_display_init_pathname (node, "_STA [Method]"));
  245. status = acpi_ut_execute_STA (node, &flags);
  246. if (ACPI_FAILURE (status)) {
  247. /* Ignore error and move on to next device */
  248. return_ACPI_STATUS (AE_OK);
  249. }
  250. info->num_STA++;
  251. if (!(flags & 0x01)) {
  252. /* don't look at children of a not present device */
  253. return_ACPI_STATUS(AE_CTRL_DEPTH);
  254. }
  255. /*
  256.  * The device is present. Run _INI.
  257.  */
  258. DEBUG_EXEC (acpi_ut_display_init_pathname (obj_handle, "_INI [Method]"));
  259. status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL);
  260. if (AE_NOT_FOUND == status) {
  261. /* No _INI means device requires no initialization */
  262. status = AE_OK;
  263. }
  264. else if (ACPI_FAILURE (status)) {
  265. /* Ignore error and move on to next device */
  266. #ifdef ACPI_DEBUG
  267. NATIVE_CHAR *scope_name = acpi_ns_get_table_pathname (obj_handle);
  268. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%s._INI failed: %sn",
  269. scope_name, acpi_format_exception (status)));
  270. ACPI_MEM_FREE (scope_name);
  271. #endif
  272. }
  273. else {
  274. /* Count of successful INIs */
  275. info->num_INI++;
  276. }
  277. return_ACPI_STATUS (AE_OK);
  278. }