nsxfeval.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. /*******************************************************************************
  2. *
  3. * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
  4. * ACPI Object evaluation interfaces
  5. *
  6. ******************************************************************************/
  7. /*
  8. * Copyright (C) 2000 - 2005, R. Byron Moore
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions, and the following disclaimer,
  16. * without modification.
  17. * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18. * substantially similar to the "NO WARRANTY" disclaimer below
  19. * ("Disclaimer") and any redistribution must be conditioned upon
  20. * including a substantially similar Disclaimer requirement for further
  21. * binary redistribution.
  22. * 3. Neither the names of the above-listed copyright holders nor the names
  23. * of any contributors may be used to endorse or promote products derived
  24. * from this software without specific prior written permission.
  25. *
  26. * Alternatively, this software may be distributed under the terms of the
  27. * GNU General Public License ("GPL") version 2 as published by the Free
  28. * Software Foundation.
  29. *
  30. * NO WARRANTY
  31. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35. * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41. * POSSIBILITY OF SUCH DAMAGES.
  42. */
  43. #include <linux/module.h>
  44. #include <acpi/acpi.h>
  45. #include <acpi/acnamesp.h>
  46. #include <acpi/acinterp.h>
  47. #define _COMPONENT ACPI_NAMESPACE
  48. ACPI_MODULE_NAME ("nsxfeval")
  49. /*******************************************************************************
  50. *
  51. * FUNCTION: acpi_evaluate_object_typed
  52. *
  53. * PARAMETERS: Handle - Object handle (optional)
  54. * *Pathname - Object pathname (optional)
  55. * **external_params - List of parameters to pass to method,
  56. * terminated by NULL. May be NULL
  57. * if no parameters are being passed.
  58. * *return_buffer - Where to put method's return value (if
  59. * any). If NULL, no value is returned.
  60. * return_type - Expected type of return object
  61. *
  62. * RETURN: Status
  63. *
  64. * DESCRIPTION: Find and evaluate the given object, passing the given
  65. * parameters if necessary. One of "Handle" or "Pathname" must
  66. * be valid (non-null)
  67. *
  68. ******************************************************************************/
  69. #ifdef ACPI_FUTURE_USAGE
  70. acpi_status
  71. acpi_evaluate_object_typed (
  72. acpi_handle handle,
  73. acpi_string pathname,
  74. struct acpi_object_list *external_params,
  75. struct acpi_buffer *return_buffer,
  76. acpi_object_type return_type)
  77. {
  78. acpi_status status;
  79. u8 must_free = FALSE;
  80. ACPI_FUNCTION_TRACE ("acpi_evaluate_object_typed");
  81. /* Return buffer must be valid */
  82. if (!return_buffer) {
  83. return_ACPI_STATUS (AE_BAD_PARAMETER);
  84. }
  85. if (return_buffer->length == ACPI_ALLOCATE_BUFFER) {
  86. must_free = TRUE;
  87. }
  88. /* Evaluate the object */
  89. status = acpi_evaluate_object (handle, pathname, external_params, return_buffer);
  90. if (ACPI_FAILURE (status)) {
  91. return_ACPI_STATUS (status);
  92. }
  93. /* Type ANY means "don't care" */
  94. if (return_type == ACPI_TYPE_ANY) {
  95. return_ACPI_STATUS (AE_OK);
  96. }
  97. if (return_buffer->length == 0) {
  98. /* Error because caller specifically asked for a return value */
  99. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  100. "No return value\n"));
  101. return_ACPI_STATUS (AE_NULL_OBJECT);
  102. }
  103. /* Examine the object type returned from evaluate_object */
  104. if (((union acpi_object *) return_buffer->pointer)->type == return_type) {
  105. return_ACPI_STATUS (AE_OK);
  106. }
  107. /* Return object type does not match requested type */
  108. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  109. "Incorrect return type [%s] requested [%s]\n",
  110. acpi_ut_get_type_name (((union acpi_object *) return_buffer->pointer)->type),
  111. acpi_ut_get_type_name (return_type)));
  112. if (must_free) {
  113. /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
  114. acpi_os_free (return_buffer->pointer);
  115. return_buffer->pointer = NULL;
  116. }
  117. return_buffer->length = 0;
  118. return_ACPI_STATUS (AE_TYPE);
  119. }
  120. #endif /* ACPI_FUTURE_USAGE */
  121. /*******************************************************************************
  122. *
  123. * FUNCTION: acpi_evaluate_object
  124. *
  125. * PARAMETERS: Handle - Object handle (optional)
  126. * Pathname - Object pathname (optional)
  127. * external_params - List of parameters to pass to method,
  128. * terminated by NULL. May be NULL
  129. * if no parameters are being passed.
  130. * return_buffer - Where to put method's return value (if
  131. * any). If NULL, no value is returned.
  132. *
  133. * RETURN: Status
  134. *
  135. * DESCRIPTION: Find and evaluate the given object, passing the given
  136. * parameters if necessary. One of "Handle" or "Pathname" must
  137. * be valid (non-null)
  138. *
  139. ******************************************************************************/
  140. acpi_status
  141. acpi_evaluate_object (
  142. acpi_handle handle,
  143. acpi_string pathname,
  144. struct acpi_object_list *external_params,
  145. struct acpi_buffer *return_buffer)
  146. {
  147. acpi_status status;
  148. acpi_status status2;
  149. struct acpi_parameter_info info;
  150. acpi_size buffer_space_needed;
  151. u32 i;
  152. ACPI_FUNCTION_TRACE ("acpi_evaluate_object");
  153. info.node = handle;
  154. info.parameters = NULL;
  155. info.return_object = NULL;
  156. info.parameter_type = ACPI_PARAM_ARGS;
  157. /*
  158. * If there are parameters to be passed to the object
  159. * (which must be a control method), the external objects
  160. * must be converted to internal objects
  161. */
  162. if (external_params && external_params->count) {
  163. /*
  164. * Allocate a new parameter block for the internal objects
  165. * Add 1 to count to allow for null terminated internal list
  166. */
  167. info.parameters = ACPI_MEM_CALLOCATE (
  168. ((acpi_size) external_params->count + 1) *
  169. sizeof (void *));
  170. if (!info.parameters) {
  171. return_ACPI_STATUS (AE_NO_MEMORY);
  172. }
  173. /*
  174. * Convert each external object in the list to an
  175. * internal object
  176. */
  177. for (i = 0; i < external_params->count; i++) {
  178. status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i],
  179. &info.parameters[i]);
  180. if (ACPI_FAILURE (status)) {
  181. acpi_ut_delete_internal_object_list (info.parameters);
  182. return_ACPI_STATUS (status);
  183. }
  184. }
  185. info.parameters[external_params->count] = NULL;
  186. }
  187. /*
  188. * Three major cases:
  189. * 1) Fully qualified pathname
  190. * 2) No handle, not fully qualified pathname (error)
  191. * 3) Valid handle
  192. */
  193. if ((pathname) &&
  194. (acpi_ns_valid_root_prefix (pathname[0]))) {
  195. /*
  196. * The path is fully qualified, just evaluate by name
  197. */
  198. status = acpi_ns_evaluate_by_name (pathname, &info);
  199. }
  200. else if (!handle) {
  201. /*
  202. * A handle is optional iff a fully qualified pathname
  203. * is specified. Since we've already handled fully
  204. * qualified names above, this is an error
  205. */
  206. if (!pathname) {
  207. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  208. "Both Handle and Pathname are NULL\n"));
  209. }
  210. else {
  211. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  212. "Handle is NULL and Pathname is relative\n"));
  213. }
  214. status = AE_BAD_PARAMETER;
  215. }
  216. else {
  217. /*
  218. * We get here if we have a handle -- and if we have a
  219. * pathname it is relative. The handle will be validated
  220. * in the lower procedures
  221. */
  222. if (!pathname) {
  223. /*
  224. * The null pathname case means the handle is for
  225. * the actual object to be evaluated
  226. */
  227. status = acpi_ns_evaluate_by_handle (&info);
  228. }
  229. else {
  230. /*
  231. * Both a Handle and a relative Pathname
  232. */
  233. status = acpi_ns_evaluate_relative (pathname, &info);
  234. }
  235. }
  236. /*
  237. * If we are expecting a return value, and all went well above,
  238. * copy the return value to an external object.
  239. */
  240. if (return_buffer) {
  241. if (!info.return_object) {
  242. return_buffer->length = 0;
  243. }
  244. else {
  245. if (ACPI_GET_DESCRIPTOR_TYPE (info.return_object) == ACPI_DESC_TYPE_NAMED) {
  246. /*
  247. * If we received a NS Node as a return object, this means that
  248. * the object we are evaluating has nothing interesting to
  249. * return (such as a mutex, etc.) We return an error because
  250. * these types are essentially unsupported by this interface.
  251. * We don't check up front because this makes it easier to add
  252. * support for various types at a later date if necessary.
  253. */
  254. status = AE_TYPE;
  255. info.return_object = NULL; /* No need to delete a NS Node */
  256. return_buffer->length = 0;
  257. }
  258. if (ACPI_SUCCESS (status)) {
  259. /*
  260. * Find out how large a buffer is needed
  261. * to contain the returned object
  262. */
  263. status = acpi_ut_get_object_size (info.return_object,
  264. &buffer_space_needed);
  265. if (ACPI_SUCCESS (status)) {
  266. /* Validate/Allocate/Clear caller buffer */
  267. status = acpi_ut_initialize_buffer (return_buffer, buffer_space_needed);
  268. if (ACPI_FAILURE (status)) {
  269. /*
  270. * Caller's buffer is too small or a new one can't be allocated
  271. */
  272. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  273. "Needed buffer size %X, %s\n",
  274. (u32) buffer_space_needed,
  275. acpi_format_exception (status)));
  276. }
  277. else {
  278. /*
  279. * We have enough space for the object, build it
  280. */
  281. status = acpi_ut_copy_iobject_to_eobject (info.return_object,
  282. return_buffer);
  283. }
  284. }
  285. }
  286. }
  287. }
  288. if (info.return_object) {
  289. /*
  290. * Delete the internal return object. NOTE: Interpreter
  291. * must be locked to avoid race condition.
  292. */
  293. status2 = acpi_ex_enter_interpreter ();
  294. if (ACPI_SUCCESS (status2)) {
  295. /*
  296. * Delete the internal return object. (Or at least
  297. * decrement the reference count by one)
  298. */
  299. acpi_ut_remove_reference (info.return_object);
  300. acpi_ex_exit_interpreter ();
  301. }
  302. }
  303. /*
  304. * Free the input parameter list (if we created one),
  305. */
  306. if (info.parameters) {
  307. /* Free the allocated parameter block */
  308. acpi_ut_delete_internal_object_list (info.parameters);
  309. }
  310. return_ACPI_STATUS (status);
  311. }
  312. EXPORT_SYMBOL(acpi_evaluate_object);
  313. /*******************************************************************************
  314. *
  315. * FUNCTION: acpi_walk_namespace
  316. *
  317. * PARAMETERS: Type - acpi_object_type to search for
  318. * start_object - Handle in namespace where search begins
  319. * max_depth - Depth to which search is to reach
  320. * user_function - Called when an object of "Type" is found
  321. * Context - Passed to user function
  322. * return_value - Location where return value of
  323. * user_function is put if terminated early
  324. *
  325. * RETURNS Return value from the user_function if terminated early.
  326. * Otherwise, returns NULL.
  327. *
  328. * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  329. * starting (and ending) at the object specified by start_handle.
  330. * The user_function is called whenever an object that matches
  331. * the type parameter is found. If the user function returns
  332. * a non-zero value, the search is terminated immediately and this
  333. * value is returned to the caller.
  334. *
  335. * The point of this procedure is to provide a generic namespace
  336. * walk routine that can be called from multiple places to
  337. * provide multiple services; the User Function can be tailored
  338. * to each task, whether it is a print function, a compare
  339. * function, etc.
  340. *
  341. ******************************************************************************/
  342. acpi_status
  343. acpi_walk_namespace (
  344. acpi_object_type type,
  345. acpi_handle start_object,
  346. u32 max_depth,
  347. acpi_walk_callback user_function,
  348. void *context,
  349. void **return_value)
  350. {
  351. acpi_status status;
  352. ACPI_FUNCTION_TRACE ("acpi_walk_namespace");
  353. /* Parameter validation */
  354. if ((type > ACPI_TYPE_EXTERNAL_MAX) ||
  355. (!max_depth) ||
  356. (!user_function)) {
  357. return_ACPI_STATUS (AE_BAD_PARAMETER);
  358. }
  359. /*
  360. * Lock the namespace around the walk.
  361. * The namespace will be unlocked/locked around each call
  362. * to the user function - since this function
  363. * must be allowed to make Acpi calls itself.
  364. */
  365. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  366. if (ACPI_FAILURE (status)) {
  367. return_ACPI_STATUS (status);
  368. }
  369. status = acpi_ns_walk_namespace (type, start_object, max_depth, ACPI_NS_WALK_UNLOCK,
  370. user_function, context, return_value);
  371. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  372. return_ACPI_STATUS (status);
  373. }
  374. EXPORT_SYMBOL(acpi_walk_namespace);
  375. /*******************************************************************************
  376. *
  377. * FUNCTION: acpi_ns_get_device_callback
  378. *
  379. * PARAMETERS: Callback from acpi_get_device
  380. *
  381. * RETURN: Status
  382. *
  383. * DESCRIPTION: Takes callbacks from walk_namespace and filters out all non-
  384. * present devices, or if they specified a HID, it filters based
  385. * on that.
  386. *
  387. ******************************************************************************/
  388. static acpi_status
  389. acpi_ns_get_device_callback (
  390. acpi_handle obj_handle,
  391. u32 nesting_level,
  392. void *context,
  393. void **return_value)
  394. {
  395. struct acpi_get_devices_info *info = context;
  396. acpi_status status;
  397. struct acpi_namespace_node *node;
  398. u32 flags;
  399. struct acpi_device_id hid;
  400. struct acpi_compatible_id_list *cid;
  401. acpi_native_uint i;
  402. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  403. if (ACPI_FAILURE (status)) {
  404. return (status);
  405. }
  406. node = acpi_ns_map_handle_to_node (obj_handle);
  407. status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  408. if (ACPI_FAILURE (status)) {
  409. return (status);
  410. }
  411. if (!node) {
  412. return (AE_BAD_PARAMETER);
  413. }
  414. /* Run _STA to determine if device is present */
  415. status = acpi_ut_execute_STA (node, &flags);
  416. if (ACPI_FAILURE (status)) {
  417. return (AE_CTRL_DEPTH);
  418. }
  419. if (!(flags & 0x01)) {
  420. /* Don't return at the device or children of the device if not there */
  421. return (AE_CTRL_DEPTH);
  422. }
  423. /* Filter based on device HID & CID */
  424. if (info->hid != NULL) {
  425. status = acpi_ut_execute_HID (node, &hid);
  426. if (status == AE_NOT_FOUND) {
  427. return (AE_OK);
  428. }
  429. else if (ACPI_FAILURE (status)) {
  430. return (AE_CTRL_DEPTH);
  431. }
  432. if (ACPI_STRNCMP (hid.value, info->hid, sizeof (hid.value)) != 0) {
  433. /* Get the list of Compatible IDs */
  434. status = acpi_ut_execute_CID (node, &cid);
  435. if (status == AE_NOT_FOUND) {
  436. return (AE_OK);
  437. }
  438. else if (ACPI_FAILURE (status)) {
  439. return (AE_CTRL_DEPTH);
  440. }
  441. /* Walk the CID list */
  442. for (i = 0; i < cid->count; i++) {
  443. if (ACPI_STRNCMP (cid->id[i].value, info->hid,
  444. sizeof (struct acpi_compatible_id)) != 0) {
  445. ACPI_MEM_FREE (cid);
  446. return (AE_OK);
  447. }
  448. }
  449. ACPI_MEM_FREE (cid);
  450. }
  451. }
  452. status = info->user_function (obj_handle, nesting_level, info->context, return_value);
  453. return (status);
  454. }
  455. /*******************************************************************************
  456. *
  457. * FUNCTION: acpi_get_devices
  458. *
  459. * PARAMETERS: HID - HID to search for. Can be NULL.
  460. * user_function - Called when a matching object is found
  461. * Context - Passed to user function
  462. * return_value - Location where return value of
  463. * user_function is put if terminated early
  464. *
  465. * RETURNS Return value from the user_function if terminated early.
  466. * Otherwise, returns NULL.
  467. *
  468. * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  469. * starting (and ending) at the object specified by start_handle.
  470. * The user_function is called whenever an object of type
  471. * Device is found. If the user function returns
  472. * a non-zero value, the search is terminated immediately and this
  473. * value is returned to the caller.
  474. *
  475. * This is a wrapper for walk_namespace, but the callback performs
  476. * additional filtering. Please see acpi_get_device_callback.
  477. *
  478. ******************************************************************************/
  479. acpi_status
  480. acpi_get_devices (
  481. char *HID,
  482. acpi_walk_callback user_function,
  483. void *context,
  484. void **return_value)
  485. {
  486. acpi_status status;
  487. struct acpi_get_devices_info info;
  488. ACPI_FUNCTION_TRACE ("acpi_get_devices");
  489. /* Parameter validation */
  490. if (!user_function) {
  491. return_ACPI_STATUS (AE_BAD_PARAMETER);
  492. }
  493. /*
  494. * We're going to call their callback from OUR callback, so we need
  495. * to know what it is, and their context parameter.
  496. */
  497. info.context = context;
  498. info.user_function = user_function;
  499. info.hid = HID;
  500. /*
  501. * Lock the namespace around the walk.
  502. * The namespace will be unlocked/locked around each call
  503. * to the user function - since this function
  504. * must be allowed to make Acpi calls itself.
  505. */
  506. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  507. if (ACPI_FAILURE (status)) {
  508. return_ACPI_STATUS (status);
  509. }
  510. status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE,
  511. ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
  512. ACPI_NS_WALK_UNLOCK,
  513. acpi_ns_get_device_callback, &info,
  514. return_value);
  515. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  516. return_ACPI_STATUS (status);
  517. }
  518. EXPORT_SYMBOL(acpi_get_devices);
  519. /*******************************************************************************
  520. *
  521. * FUNCTION: acpi_attach_data
  522. *
  523. * PARAMETERS: obj_handle - Namespace node
  524. * Handler - Handler for this attachment
  525. * Data - Pointer to data to be attached
  526. *
  527. * RETURN: Status
  528. *
  529. * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
  530. *
  531. ******************************************************************************/
  532. acpi_status
  533. acpi_attach_data (
  534. acpi_handle obj_handle,
  535. acpi_object_handler handler,
  536. void *data)
  537. {
  538. struct acpi_namespace_node *node;
  539. acpi_status status;
  540. /* Parameter validation */
  541. if (!obj_handle ||
  542. !handler ||
  543. !data) {
  544. return (AE_BAD_PARAMETER);
  545. }
  546. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  547. if (ACPI_FAILURE (status)) {
  548. return (status);
  549. }
  550. /* Convert and validate the handle */
  551. node = acpi_ns_map_handle_to_node (obj_handle);
  552. if (!node) {
  553. status = AE_BAD_PARAMETER;
  554. goto unlock_and_exit;
  555. }
  556. status = acpi_ns_attach_data (node, handler, data);
  557. unlock_and_exit:
  558. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  559. return (status);
  560. }
  561. /*******************************************************************************
  562. *
  563. * FUNCTION: acpi_detach_data
  564. *
  565. * PARAMETERS: obj_handle - Namespace node handle
  566. * Handler - Handler used in call to acpi_attach_data
  567. *
  568. * RETURN: Status
  569. *
  570. * DESCRIPTION: Remove data that was previously attached to a node.
  571. *
  572. ******************************************************************************/
  573. acpi_status
  574. acpi_detach_data (
  575. acpi_handle obj_handle,
  576. acpi_object_handler handler)
  577. {
  578. struct acpi_namespace_node *node;
  579. acpi_status status;
  580. /* Parameter validation */
  581. if (!obj_handle ||
  582. !handler) {
  583. return (AE_BAD_PARAMETER);
  584. }
  585. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  586. if (ACPI_FAILURE (status)) {
  587. return (status);
  588. }
  589. /* Convert and validate the handle */
  590. node = acpi_ns_map_handle_to_node (obj_handle);
  591. if (!node) {
  592. status = AE_BAD_PARAMETER;
  593. goto unlock_and_exit;
  594. }
  595. status = acpi_ns_detach_data (node, handler);
  596. unlock_and_exit:
  597. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  598. return (status);
  599. }
  600. /*******************************************************************************
  601. *
  602. * FUNCTION: acpi_get_data
  603. *
  604. * PARAMETERS: obj_handle - Namespace node
  605. * Handler - Handler used in call to attach_data
  606. * Data - Where the data is returned
  607. *
  608. * RETURN: Status
  609. *
  610. * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
  611. *
  612. ******************************************************************************/
  613. acpi_status
  614. acpi_get_data (
  615. acpi_handle obj_handle,
  616. acpi_object_handler handler,
  617. void **data)
  618. {
  619. struct acpi_namespace_node *node;
  620. acpi_status status;
  621. /* Parameter validation */
  622. if (!obj_handle ||
  623. !handler ||
  624. !data) {
  625. return (AE_BAD_PARAMETER);
  626. }
  627. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  628. if (ACPI_FAILURE (status)) {
  629. return (status);
  630. }
  631. /* Convert and validate the handle */
  632. node = acpi_ns_map_handle_to_node (obj_handle);
  633. if (!node) {
  634. status = AE_BAD_PARAMETER;
  635. goto unlock_and_exit;
  636. }
  637. status = acpi_ns_get_attached_data (node, handler, data);
  638. unlock_and_exit:
  639. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  640. return (status);
  641. }