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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
  4.  *                         ACPI Object oriented interfaces
  5.  *              $Revision: 95 $
  6.  *
  7.  ******************************************************************************/
  8. /*
  9.  *  Copyright (C) 2000, 2001 R. Byron Moore
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with this program; if not, write to the Free Software
  23.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.  */
  25. #include "acpi.h"
  26. #include "acinterp.h"
  27. #include "acnamesp.h"
  28. #include "acdispat.h"
  29. #define _COMPONENT          ACPI_NAMESPACE
  30.  MODULE_NAME         ("nsxfobj")
  31. /*******************************************************************************
  32.  *
  33.  * FUNCTION:    Acpi_evaluate_object
  34.  *
  35.  * PARAMETERS:  Handle              - Object handle (optional)
  36.  *              *Pathname           - Object pathname (optional)
  37.  *              **External_params   - List of parameters to pass to method,
  38.  *                                    terminated by NULL.  May be NULL
  39.  *                                    if no parameters are being passed.
  40.  *              *Return_buffer      - Where to put method's return value (if
  41.  *                                    any).  If NULL, no value is returned.
  42.  *
  43.  * RETURN:      Status
  44.  *
  45.  * DESCRIPTION: Find and evaluate the given object, passing the given
  46.  *              parameters if necessary.  One of "Handle" or "Pathname" must
  47.  *              be valid (non-null)
  48.  *
  49.  ******************************************************************************/
  50. acpi_status
  51. acpi_evaluate_object (
  52. acpi_handle             handle,
  53. acpi_string             pathname,
  54. acpi_object_list        *external_params,
  55. acpi_buffer             *return_buffer)
  56. {
  57. acpi_status             status;
  58. acpi_operand_object     **internal_params = NULL;
  59. acpi_operand_object     *internal_return_obj = NULL;
  60. u32                     buffer_space_needed;
  61. u32                     user_buffer_length;
  62. u32                     i;
  63. FUNCTION_TRACE ("Acpi_evaluate_object");
  64. /*
  65.  * If there are parameters to be passed to the object
  66.  * (which must be a control method), the external objects
  67.  * must be converted to internal objects
  68.  */
  69. if (external_params && external_params->count) {
  70. /*
  71.  * Allocate a new parameter block for the internal objects
  72.  * Add 1 to count to allow for null terminated internal list
  73.  */
  74. internal_params = ACPI_MEM_CALLOCATE ((external_params->count + 1) * sizeof (void *));
  75. if (!internal_params) {
  76. return_ACPI_STATUS (AE_NO_MEMORY);
  77. }
  78. /*
  79.  * Convert each external object in the list to an
  80.  * internal object
  81.  */
  82. for (i = 0; i < external_params->count; i++) {
  83. status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i],
  84.  &internal_params[i]);
  85. if (ACPI_FAILURE (status)) {
  86. acpi_ut_delete_internal_object_list (internal_params);
  87. return_ACPI_STATUS (status);
  88. }
  89. }
  90. internal_params[external_params->count] = NULL;
  91. }
  92. /*
  93.  * Three major cases:
  94.  * 1) Fully qualified pathname
  95.  * 2) No handle, not fully qualified pathname (error)
  96.  * 3) Valid handle
  97.  */
  98. if ((pathname) &&
  99. (acpi_ns_valid_root_prefix (pathname[0]))) {
  100. /*
  101.  *  The path is fully qualified, just evaluate by name
  102.  */
  103. status = acpi_ns_evaluate_by_name (pathname, internal_params, &internal_return_obj);
  104. }
  105. else if (!handle) {
  106. /*
  107.  * A handle is optional iff a fully qualified pathname
  108.  * is specified.  Since we've already handled fully
  109.  * qualified names above, this is an error
  110.  */
  111. if (!pathname) {
  112. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Both Handle and Pathname are NULLn"));
  113. }
  114. else {
  115. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Handle is NULL and Pathname is relativen"));
  116. }
  117. status = AE_BAD_PARAMETER;
  118. }
  119. else {
  120. /*
  121.  * We get here if we have a handle -- and if we have a
  122.  * pathname it is relative.  The handle will be validated
  123.  * in the lower procedures
  124.  */
  125. if (!pathname) {
  126. /*
  127.  * The null pathname case means the handle is for
  128.  * the actual object to be evaluated
  129.  */
  130. status = acpi_ns_evaluate_by_handle (handle, internal_params, &internal_return_obj);
  131. }
  132. else {
  133.    /*
  134. * Both a Handle and a relative Pathname
  135. */
  136. status = acpi_ns_evaluate_relative (handle, pathname, internal_params,
  137.  &internal_return_obj);
  138. }
  139. }
  140. /*
  141.  * If we are expecting a return value, and all went well above,
  142.  * copy the return value to an external object.
  143.  */
  144. if (return_buffer) {
  145. user_buffer_length = return_buffer->length;
  146. return_buffer->length = 0;
  147. if (internal_return_obj) {
  148. if (VALID_DESCRIPTOR_TYPE (internal_return_obj, ACPI_DESC_TYPE_NAMED)) {
  149. /*
  150.  * If we got an Node as a return object,
  151.  * this means the object we are evaluating
  152.  * has nothing interesting to return (such
  153.  * as a mutex, etc.)  We return an error
  154.  * because these types are essentially
  155.  * unsupported by this interface.  We
  156.  * don't check up front because this makes
  157.  * it easier to add support for various
  158.  * types at a later date if necessary.
  159.  */
  160. status = AE_TYPE;
  161. internal_return_obj = NULL; /* No need to delete an Node */
  162. }
  163. if (ACPI_SUCCESS (status)) {
  164. /*
  165.  * Find out how large a buffer is needed
  166.  * to contain the returned object
  167.  */
  168. status = acpi_ut_get_object_size (internal_return_obj,
  169.    &buffer_space_needed);
  170. if (ACPI_SUCCESS (status)) {
  171. /*
  172.  * Check if there is enough room in the
  173.  * caller's buffer
  174.  */
  175. if (user_buffer_length < buffer_space_needed) {
  176. /*
  177.  * Caller's buffer is too small, can't
  178.  * give him partial results fail the call
  179.  * but return the buffer size needed
  180.  */
  181. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  182. "Needed buffer size %X, received %Xn",
  183. buffer_space_needed, user_buffer_length));
  184. return_buffer->length = buffer_space_needed;
  185. status = AE_BUFFER_OVERFLOW;
  186. }
  187. else {
  188. /*
  189.  *  We have enough space for the object, build it
  190.  */
  191. status = acpi_ut_copy_iobject_to_eobject (internal_return_obj,
  192.   return_buffer);
  193. return_buffer->length = buffer_space_needed;
  194. }
  195. }
  196. }
  197. }
  198. }
  199. /* Delete the return and parameter objects */
  200. if (internal_return_obj) {
  201. /*
  202.  * Delete the internal return object. (Or at least
  203.  * decrement the reference count by one)
  204.  */
  205. acpi_ut_remove_reference (internal_return_obj);
  206. }
  207. /*
  208.  * Free the input parameter list (if we created one),
  209.  */
  210. if (internal_params) {
  211. /* Free the allocated parameter block */
  212. acpi_ut_delete_internal_object_list (internal_params);
  213. }
  214. return_ACPI_STATUS (status);
  215. }
  216. /*******************************************************************************
  217.  *
  218.  * FUNCTION:    Acpi_get_next_object
  219.  *
  220.  * PARAMETERS:  Type            - Type of object to be searched for
  221.  *              Parent          - Parent object whose children we are getting
  222.  *              Last_child      - Previous child that was found.
  223.  *                                The NEXT child will be returned
  224.  *              Ret_handle      - Where handle to the next object is placed
  225.  *
  226.  * RETURN:      Status
  227.  *
  228.  * DESCRIPTION: Return the next peer object within the namespace.  If Handle is
  229.  *              valid, Scope is ignored.  Otherwise, the first object within
  230.  *              Scope is returned.
  231.  *
  232.  ******************************************************************************/
  233. acpi_status
  234. acpi_get_next_object (
  235. acpi_object_type        type,
  236. acpi_handle             parent,
  237. acpi_handle             child,
  238. acpi_handle             *ret_handle)
  239. {
  240. acpi_status             status = AE_OK;
  241. acpi_namespace_node     *node;
  242. acpi_namespace_node     *parent_node = NULL;
  243. acpi_namespace_node     *child_node = NULL;
  244. /* Parameter validation */
  245. if (type > ACPI_TYPE_MAX) {
  246. return (AE_BAD_PARAMETER);
  247. }
  248. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  249. /* If null handle, use the parent */
  250. if (!child) {
  251. /* Start search at the beginning of the specified scope */
  252. parent_node = acpi_ns_map_handle_to_node (parent);
  253. if (!parent_node) {
  254. status = AE_BAD_PARAMETER;
  255. goto unlock_and_exit;
  256. }
  257. }
  258. /* Non-null handle, ignore the parent */
  259. else {
  260. /* Convert and validate the handle */
  261. child_node = acpi_ns_map_handle_to_node (child);
  262. if (!child_node) {
  263. status = AE_BAD_PARAMETER;
  264. goto unlock_and_exit;
  265. }
  266. }
  267. /* Internal function does the real work */
  268. node = acpi_ns_get_next_node ((acpi_object_type8) type,
  269.    parent_node, child_node);
  270. if (!node) {
  271. status = AE_NOT_FOUND;
  272. goto unlock_and_exit;
  273. }
  274. if (ret_handle) {
  275. *ret_handle = acpi_ns_convert_entry_to_handle (node);
  276. }
  277. unlock_and_exit:
  278. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  279. return (status);
  280. }
  281. /*******************************************************************************
  282.  *
  283.  * FUNCTION:    Acpi_get_type
  284.  *
  285.  * PARAMETERS:  Handle          - Handle of object whose type is desired
  286.  *              *Ret_type       - Where the type will be placed
  287.  *
  288.  * RETURN:      Status
  289.  *
  290.  * DESCRIPTION: This routine returns the type associatd with a particular handle
  291.  *
  292.  ******************************************************************************/
  293. acpi_status
  294. acpi_get_type (
  295. acpi_handle             handle,
  296. acpi_object_type        *ret_type)
  297. {
  298. acpi_namespace_node     *node;
  299. /* Parameter Validation */
  300. if (!ret_type) {
  301. return (AE_BAD_PARAMETER);
  302. }
  303. /*
  304.  * Special case for the predefined Root Node
  305.  * (return type ANY)
  306.  */
  307. if (handle == ACPI_ROOT_OBJECT) {
  308. *ret_type = ACPI_TYPE_ANY;
  309. return (AE_OK);
  310. }
  311. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  312. /* Convert and validate the handle */
  313. node = acpi_ns_map_handle_to_node (handle);
  314. if (!node) {
  315. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  316. return (AE_BAD_PARAMETER);
  317. }
  318. *ret_type = node->type;
  319. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  320. return (AE_OK);
  321. }
  322. /*******************************************************************************
  323.  *
  324.  * FUNCTION:    Acpi_get_parent
  325.  *
  326.  * PARAMETERS:  Handle          - Handle of object whose parent is desired
  327.  *              Ret_handle      - Where the parent handle will be placed
  328.  *
  329.  * RETURN:      Status
  330.  *
  331.  * DESCRIPTION: Returns a handle to the parent of the object represented by
  332.  *              Handle.
  333.  *
  334.  ******************************************************************************/
  335. acpi_status
  336. acpi_get_parent (
  337. acpi_handle             handle,
  338. acpi_handle             *ret_handle)
  339. {
  340. acpi_namespace_node     *node;
  341. acpi_status             status = AE_OK;
  342. if (!ret_handle) {
  343. return (AE_BAD_PARAMETER);
  344. }
  345. /* Special case for the predefined Root Node (no parent) */
  346. if (handle == ACPI_ROOT_OBJECT) {
  347. return (AE_NULL_ENTRY);
  348. }
  349. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  350. /* Convert and validate the handle */
  351. node = acpi_ns_map_handle_to_node (handle);
  352. if (!node) {
  353. status = AE_BAD_PARAMETER;
  354. goto unlock_and_exit;
  355. }
  356. /* Get the parent entry */
  357. *ret_handle =
  358. acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_object (node));
  359. /* Return exeption if parent is null */
  360. if (!acpi_ns_get_parent_object (node)) {
  361. status = AE_NULL_ENTRY;
  362. }
  363. unlock_and_exit:
  364. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  365. return (status);
  366. }
  367. /*******************************************************************************
  368.  *
  369.  * FUNCTION:    Acpi_walk_namespace
  370.  *
  371.  * PARAMETERS:  Type                - acpi_object_type to search for
  372.  *              Start_object        - Handle in namespace where search begins
  373.  *              Max_depth           - Depth to which search is to reach
  374.  *              User_function       - Called when an object of "Type" is found
  375.  *              Context             - Passed to user function
  376.  *              Return_value        - Location where return value of
  377.  *                                    User_function is put if terminated early
  378.  *
  379.  * RETURNS      Return value from the User_function if terminated early.
  380.  *              Otherwise, returns NULL.
  381.  *
  382.  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  383.  *              starting (and ending) at the object specified by Start_handle.
  384.  *              The User_function is called whenever an object that matches
  385.  *              the type parameter is found.  If the user function returns
  386.  *              a non-zero value, the search is terminated immediately and this
  387.  *              value is returned to the caller.
  388.  *
  389.  *              The point of this procedure is to provide a generic namespace
  390.  *              walk routine that can be called from multiple places to
  391.  *              provide multiple services;  the User Function can be tailored
  392.  *              to each task, whether it is a print function, a compare
  393.  *              function, etc.
  394.  *
  395.  ******************************************************************************/
  396. acpi_status
  397. acpi_walk_namespace (
  398. acpi_object_type        type,
  399. acpi_handle             start_object,
  400. u32                     max_depth,
  401. acpi_walk_callback      user_function,
  402. void                    *context,
  403. void                    **return_value)
  404. {
  405. acpi_status             status;
  406. FUNCTION_TRACE ("Acpi_walk_namespace");
  407. /* Parameter validation */
  408. if ((type > ACPI_TYPE_MAX)  ||
  409. (!max_depth)            ||
  410. (!user_function)) {
  411. return_ACPI_STATUS (AE_BAD_PARAMETER);
  412. }
  413. /*
  414.  * Lock the namespace around the walk.
  415.  * The namespace will be unlocked/locked around each call
  416.  * to the user function - since this function
  417.  * must be allowed to make Acpi calls itself.
  418.  */
  419. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  420. status = acpi_ns_walk_namespace ((acpi_object_type8) type, start_object,
  421.   max_depth, NS_WALK_UNLOCK, user_function, context,
  422.   return_value);
  423. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  424. return_ACPI_STATUS (status);
  425. }
  426. /*******************************************************************************
  427.  *
  428.  * FUNCTION:    Acpi_ns_get_device_callback
  429.  *
  430.  * PARAMETERS:  Callback from Acpi_get_device
  431.  *
  432.  * RETURN:      Status
  433.  *
  434.  * DESCRIPTION: Takes callbacks from Walk_namespace and filters out all non-
  435.  *              present devices, or if they specified a HID, it filters based
  436.  *              on that.
  437.  *
  438.  ******************************************************************************/
  439. static acpi_status
  440. acpi_ns_get_device_callback (
  441. acpi_handle             obj_handle,
  442. u32                     nesting_level,
  443. void                    *context,
  444. void                    **return_value)
  445. {
  446. acpi_status             status;
  447. acpi_namespace_node     *node;
  448. u32                     flags;
  449. acpi_device_id          device_id;
  450. acpi_get_devices_info   *info;
  451. info = context;
  452. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  453. node = acpi_ns_map_handle_to_node (obj_handle);
  454. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  455. if (!node) {
  456. return (AE_BAD_PARAMETER);
  457. }
  458. /*
  459.  * Run _STA to determine if device is present
  460.  */
  461. status = acpi_ut_execute_STA (node, &flags);
  462. if (ACPI_FAILURE (status)) {
  463. return (AE_CTRL_DEPTH);
  464. }
  465. if (!(flags & 0x01)) {
  466. /* don't return at the device or children of the device if not there */
  467. return (AE_CTRL_DEPTH);
  468. }
  469. /*
  470.  * Filter based on device HID
  471.  */
  472. if (info->hid != NULL) {
  473. status = acpi_ut_execute_HID (node, &device_id);
  474. if (status == AE_NOT_FOUND) {
  475. return (AE_OK);
  476. }
  477. else if (ACPI_FAILURE (status)) {
  478. return (AE_CTRL_DEPTH);
  479. }
  480. if (STRNCMP (device_id.buffer, info->hid, sizeof (device_id.buffer)) != 0) {
  481. return (AE_OK);
  482. }
  483. }
  484. info->user_function (obj_handle, nesting_level, info->context, return_value);
  485. return (AE_OK);
  486. }
  487. /*******************************************************************************
  488.  *
  489.  * FUNCTION:    Acpi_get_devices
  490.  *
  491.  * PARAMETERS:  HID                 - HID to search for. Can be NULL.
  492.  *              User_function       - Called when a matching object is found
  493.  *              Context             - Passed to user function
  494.  *              Return_value        - Location where return value of
  495.  *                                    User_function is put if terminated early
  496.  *
  497.  * RETURNS      Return value from the User_function if terminated early.
  498.  *              Otherwise, returns NULL.
  499.  *
  500.  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  501.  *              starting (and ending) at the object specified by Start_handle.
  502.  *              The User_function is called whenever an object that matches
  503.  *              the type parameter is found.  If the user function returns
  504.  *              a non-zero value, the search is terminated immediately and this
  505.  *              value is returned to the caller.
  506.  *
  507.  *              This is a wrapper for Walk_namespace, but the callback performs
  508.  *              additional filtering. Please see Acpi_get_device_callback.
  509.  *
  510.  ******************************************************************************/
  511. acpi_status
  512. acpi_get_devices (
  513. NATIVE_CHAR             *HID,
  514. acpi_walk_callback      user_function,
  515. void                    *context,
  516. void                    **return_value)
  517. {
  518. acpi_status             status;
  519. acpi_get_devices_info   info;
  520. FUNCTION_TRACE ("Acpi_get_devices");
  521. /* Parameter validation */
  522. if (!user_function) {
  523. return_ACPI_STATUS (AE_BAD_PARAMETER);
  524. }
  525. /*
  526.  * We're going to call their callback from OUR callback, so we need
  527.  * to know what it is, and their context parameter.
  528.  */
  529. info.context      = context;
  530. info.user_function = user_function;
  531. info.hid          = HID;
  532. /*
  533.  * Lock the namespace around the walk.
  534.  * The namespace will be unlocked/locked around each call
  535.  * to the user function - since this function
  536.  * must be allowed to make Acpi calls itself.
  537.  */
  538. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  539. status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE,
  540.    ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
  541.    NS_WALK_UNLOCK,
  542.    acpi_ns_get_device_callback, &info,
  543.    return_value);
  544. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  545. return_ACPI_STATUS (status);
  546. }