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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: utcopy - Internal to external object translation utilities
  4.  *              $Revision: 83 $
  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 "acinterp.h"
  26. #include "acnamesp.h"
  27. #include "amlcode.h"
  28. #define _COMPONENT          ACPI_UTILITIES
  29.  MODULE_NAME         ("utcopy")
  30. /*******************************************************************************
  31.  *
  32.  * FUNCTION:    Acpi_ut_copy_isimple_to_esimple
  33.  *
  34.  * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
  35.  *              *Buffer             - Where the object is returned
  36.  *              *Space_used         - Where the data length is returned
  37.  *
  38.  * RETURN:      Status
  39.  *
  40.  * DESCRIPTION: This function is called to place a simple object in a user
  41.  *              buffer.
  42.  *
  43.  *              The buffer is assumed to have sufficient space for the object.
  44.  *
  45.  ******************************************************************************/
  46. static acpi_status
  47. acpi_ut_copy_isimple_to_esimple (
  48. acpi_operand_object     *internal_object,
  49. acpi_object             *external_object,
  50. u8                      *data_space,
  51. u32                     *buffer_space_used)
  52. {
  53. u32                     length = 0;
  54. acpi_status             status = AE_OK;
  55. FUNCTION_TRACE ("Ut_copy_isimple_to_esimple");
  56. /*
  57.  * Check for NULL object case (could be an uninitialized
  58.  * package element
  59.  */
  60. if (!internal_object) {
  61. *buffer_space_used = 0;
  62. return_ACPI_STATUS (AE_OK);
  63. }
  64. /* Always clear the external object */
  65. MEMSET (external_object, 0, sizeof (acpi_object));
  66. /*
  67.  * In general, the external object will be the same type as
  68.  * the internal object
  69.  */
  70. external_object->type = internal_object->common.type;
  71. /* However, only a limited number of external types are supported */
  72. switch (internal_object->common.type) {
  73. case ACPI_TYPE_STRING:
  74. length = internal_object->string.length + 1;
  75. external_object->string.length = internal_object->string.length;
  76. external_object->string.pointer = (NATIVE_CHAR *) data_space;
  77. MEMCPY ((void *) data_space, (void *) internal_object->string.pointer, length);
  78. break;
  79. case ACPI_TYPE_BUFFER:
  80. length = internal_object->buffer.length;
  81. external_object->buffer.length = internal_object->buffer.length;
  82. external_object->buffer.pointer = data_space;
  83. MEMCPY ((void *) data_space, (void *) internal_object->buffer.pointer, length);
  84. break;
  85. case ACPI_TYPE_INTEGER:
  86. external_object->integer.value= internal_object->integer.value;
  87. break;
  88. case INTERNAL_TYPE_REFERENCE:
  89. /*
  90.  * This is an object reference.  Attempt to dereference it.
  91.  */
  92. switch (internal_object->reference.opcode) {
  93. case AML_ZERO_OP:
  94. external_object->type = ACPI_TYPE_INTEGER;
  95. external_object->integer.value = 0;
  96. break;
  97. case AML_ONE_OP:
  98. external_object->type = ACPI_TYPE_INTEGER;
  99. external_object->integer.value = 1;
  100. break;
  101. case AML_ONES_OP:
  102. external_object->type = ACPI_TYPE_INTEGER;
  103. external_object->integer.value = ACPI_INTEGER_MAX;
  104. break;
  105. case AML_REVISION_OP:
  106. external_object->type = ACPI_TYPE_INTEGER;
  107. external_object->integer.value = ACPI_CA_SUPPORT_LEVEL;
  108. break;
  109. case AML_INT_NAMEPATH_OP:
  110. /*
  111.  * This is a named reference, get the string.  We already know that
  112.  * we have room for it, use max length
  113.  */
  114. length = MAX_STRING_LENGTH;
  115. external_object->type = ACPI_TYPE_STRING;
  116. external_object->string.pointer = (NATIVE_CHAR *) data_space;
  117. status = acpi_ns_handle_to_pathname ((acpi_handle *) internal_object->reference.node,
  118.  &length, (char *) data_space);
  119. /* Converted (external) string length is returned from above */
  120. external_object->string.length = length;
  121. break;
  122. default:
  123. /*
  124.  * Use the object type of "Any" to indicate a reference
  125.  * to object containing a handle to an ACPI named object.
  126.  */
  127. external_object->type = ACPI_TYPE_ANY;
  128. external_object->reference.handle = internal_object->reference.node;
  129. break;
  130. }
  131. break;
  132. case ACPI_TYPE_PROCESSOR:
  133. external_object->processor.proc_id = internal_object->processor.proc_id;
  134. external_object->processor.pblk_address = internal_object->processor.address;
  135. external_object->processor.pblk_length = internal_object->processor.length;
  136. break;
  137. case ACPI_TYPE_POWER:
  138. external_object->power_resource.system_level =
  139.    internal_object->power_resource.system_level;
  140. external_object->power_resource.resource_order =
  141.    internal_object->power_resource.resource_order;
  142. break;
  143. default:
  144. /*
  145.  * There is no corresponding external object type
  146.  */
  147. return_ACPI_STATUS (AE_SUPPORT);
  148. break;
  149. }
  150. *buffer_space_used = (u32) ROUND_UP_TO_NATIVE_WORD (length);
  151. return_ACPI_STATUS (status);
  152. }
  153. /*******************************************************************************
  154.  *
  155.  * FUNCTION:    Acpi_ut_copy_ielement_to_eelement
  156.  *
  157.  * PARAMETERS:  ACPI_PKG_CALLBACK
  158.  *
  159.  * RETURN:      Status
  160.  *
  161.  * DESCRIPTION: Copy one package element to another package element
  162.  *
  163.  ******************************************************************************/
  164. acpi_status
  165. acpi_ut_copy_ielement_to_eelement (
  166. u8                      object_type,
  167. acpi_operand_object     *source_object,
  168. acpi_generic_state      *state,
  169. void                    *context)
  170. {
  171. acpi_status             status = AE_OK;
  172. acpi_pkg_info           *info = (acpi_pkg_info *) context;
  173. u32                     object_space;
  174. u32                     this_index;
  175. acpi_object             *target_object;
  176. FUNCTION_ENTRY ();
  177. this_index   = state->pkg.index;
  178. target_object = (acpi_object *)
  179.   &((acpi_object *)(state->pkg.dest_object))->package.elements[this_index];
  180. switch (object_type) {
  181. case ACPI_COPY_TYPE_SIMPLE:
  182. /*
  183.  * This is a simple or null object -- get the size
  184.  */
  185. status = acpi_ut_copy_isimple_to_esimple (source_object,
  186.   target_object, info->free_space, &object_space);
  187. if (ACPI_FAILURE (status)) {
  188. return (status);
  189. }
  190. break;
  191. case ACPI_COPY_TYPE_PACKAGE:
  192. /*
  193.  * Build the package object
  194.  */
  195. target_object->type             = ACPI_TYPE_PACKAGE;
  196. target_object->package.count    = source_object->package.count;
  197. target_object->package.elements = (acpi_object *) info->free_space;
  198. /*
  199.  * Pass the new package object back to the package walk routine
  200.  */
  201. state->pkg.this_target_obj = target_object;
  202. /*
  203.  * Save space for the array of objects (Package elements)
  204.  * update the buffer length counter
  205.  */
  206. object_space = (u32) ROUND_UP_TO_NATIVE_WORD (
  207.    target_object->package.count * sizeof (acpi_object));
  208. break;
  209. default:
  210. return (AE_BAD_PARAMETER);
  211. }
  212. info->free_space  += object_space;
  213. info->length      += object_space;
  214. return (status);
  215. }
  216. /*******************************************************************************
  217.  *
  218.  * FUNCTION:    Acpi_ut_copy_ipackage_to_epackage
  219.  *
  220.  * PARAMETERS:  *Internal_object    - Pointer to the object we are returning
  221.  *              *Buffer             - Where the object is returned
  222.  *              *Space_used         - Where the object length is returned
  223.  *
  224.  * RETURN:      Status
  225.  *
  226.  * DESCRIPTION: This function is called to place a package object in a user
  227.  *              buffer.  A package object by definition contains other objects.
  228.  *
  229.  *              The buffer is assumed to have sufficient space for the object.
  230.  *              The caller must have verified the buffer length needed using the
  231.  *              Acpi_ut_get_object_size function before calling this function.
  232.  *
  233.  ******************************************************************************/
  234. static acpi_status
  235. acpi_ut_copy_ipackage_to_epackage (
  236. acpi_operand_object     *internal_object,
  237. u8                      *buffer,
  238. u32                     *space_used)
  239. {
  240. acpi_object             *external_object;
  241. acpi_status             status;
  242. acpi_pkg_info           info;
  243. FUNCTION_TRACE ("Ut_copy_ipackage_to_epackage");
  244. /*
  245.  * First package at head of the buffer
  246.  */
  247. external_object = (acpi_object *) buffer;
  248. /*
  249.  * Free space begins right after the first package
  250.  */
  251. info.length      = 0;
  252. info.object_space = 0;
  253. info.num_packages = 1;
  254. info.free_space  = buffer + ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
  255. external_object->type              = internal_object->common.type;
  256. external_object->package.count     = internal_object->package.count;
  257. external_object->package.elements  = (acpi_object *) info.free_space;
  258. /*
  259.  * Build an array of ACPI_OBJECTS in the buffer
  260.  * and move the free space past it
  261.  */
  262. info.free_space += external_object->package.count *
  263.   ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
  264. status = acpi_ut_walk_package_tree (internal_object, external_object,
  265.  acpi_ut_copy_ielement_to_eelement, &info);
  266. *space_used = info.length;
  267. return_ACPI_STATUS (status);
  268. }
  269. /*******************************************************************************
  270.  *
  271.  * FUNCTION:    Acpi_ut_copy_iobject_to_eobject
  272.  *
  273.  * PARAMETERS:  *Internal_object    - The internal object to be converted
  274.  *              *Buffer_ptr         - Where the object is returned
  275.  *
  276.  * RETURN:      Status
  277.  *
  278.  * DESCRIPTION: This function is called to build an API object to be returned to
  279.  *              the caller.
  280.  *
  281.  ******************************************************************************/
  282. acpi_status
  283. acpi_ut_copy_iobject_to_eobject (
  284. acpi_operand_object     *internal_object,
  285. acpi_buffer             *ret_buffer)
  286. {
  287. acpi_status             status;
  288. FUNCTION_TRACE ("Ut_copy_iobject_to_eobject");
  289. if (IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE)) {
  290. /*
  291.  * Package object:  Copy all subobjects (including
  292.  * nested packages)
  293.  */
  294. status = acpi_ut_copy_ipackage_to_epackage (internal_object,
  295.   ret_buffer->pointer, &ret_buffer->length);
  296. }
  297. else {
  298. /*
  299.  * Build a simple object (no nested objects)
  300.  */
  301. status = acpi_ut_copy_isimple_to_esimple (internal_object,
  302.   (acpi_object *) ret_buffer->pointer,
  303.   ((u8 *) ret_buffer->pointer +
  304.   ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object))),
  305.   &ret_buffer->length);
  306. /*
  307.  * build simple does not include the object size in the length
  308.  * so we add it in here
  309.  */
  310. ret_buffer->length += sizeof (acpi_object);
  311. }
  312. return_ACPI_STATUS (status);
  313. }
  314. /*******************************************************************************
  315.  *
  316.  * FUNCTION:    Acpi_ut_copy_esimple_to_isimple
  317.  *
  318.  * PARAMETERS:  *External_object   - The external object to be converted
  319.  *              *Internal_object   - Where the internal object is returned
  320.  *
  321.  * RETURN:      Status
  322.  *
  323.  * DESCRIPTION: This function copies an external object to an internal one.
  324.  *              NOTE: Pointers can be copied, we don't need to copy data.
  325.  *              (The pointers have to be valid in our address space no matter
  326.  *              what we do with them!)
  327.  *
  328.  ******************************************************************************/
  329. acpi_status
  330. acpi_ut_copy_esimple_to_isimple (
  331. acpi_object             *external_object,
  332. acpi_operand_object     **ret_internal_object)
  333. {
  334. acpi_operand_object     *internal_object;
  335. FUNCTION_TRACE ("Ut_copy_esimple_to_isimple");
  336. /*
  337.  * Simple types supported are: String, Buffer, Integer
  338.  */
  339. switch (external_object->type) {
  340. case ACPI_TYPE_STRING:
  341. case ACPI_TYPE_BUFFER:
  342. case ACPI_TYPE_INTEGER:
  343. internal_object = acpi_ut_create_internal_object ((u8) external_object->type);
  344. if (!internal_object) {
  345. return_ACPI_STATUS (AE_NO_MEMORY);
  346. }
  347. break;
  348. default:
  349. /*
  350.  * Whatever other type -- it is not supported
  351.  */
  352. return_ACPI_STATUS (AE_SUPPORT);
  353. break;
  354. }
  355. switch (external_object->type) {
  356. /* Must COPY string and buffer contents */
  357. case ACPI_TYPE_STRING:
  358. internal_object->string.pointer = ACPI_MEM_CALLOCATE (external_object->string.length + 1);
  359. if (!internal_object->string.pointer) {
  360. return_ACPI_STATUS (AE_NO_MEMORY);
  361. }
  362. MEMCPY (internal_object->string.pointer,
  363. external_object->string.pointer,
  364. external_object->string.length);
  365. internal_object->string.length = external_object->string.length;
  366. break;
  367. case ACPI_TYPE_BUFFER:
  368. internal_object->buffer.pointer = ACPI_MEM_CALLOCATE (external_object->buffer.length);
  369. if (!internal_object->buffer.pointer) {
  370. return_ACPI_STATUS (AE_NO_MEMORY);
  371. }
  372. MEMCPY (internal_object->buffer.pointer,
  373. external_object->buffer.pointer,
  374. external_object->buffer.length);
  375. internal_object->buffer.length = external_object->buffer.length;
  376. break;
  377. case ACPI_TYPE_INTEGER:
  378. internal_object->integer.value  = external_object->integer.value;
  379. break;
  380. }
  381. *ret_internal_object = internal_object;
  382. return_ACPI_STATUS (AE_OK);
  383. }
  384. #ifdef ACPI_FUTURE_IMPLEMENTATION
  385. /* Code to convert packages that are parameters to control methods */
  386. /*******************************************************************************
  387.  *
  388.  * FUNCTION:    Acpi_ut_copy_epackage_to_ipackage
  389.  *
  390.  * PARAMETERS:  *Internal_object   - Pointer to the object we are returning
  391.  *              *Buffer         - Where the object is returned
  392.  *              *Space_used     - Where the length of the object is returned
  393.  *
  394.  * RETURN:      Status          - the status of the call
  395.  *
  396.  * DESCRIPTION: This function is called to place a package object in a user
  397.  *              buffer.  A package object by definition contains other objects.
  398.  *
  399.  *              The buffer is assumed to have sufficient space for the object.
  400.  *              The caller must have verified the buffer length needed using the
  401.  *              Acpi_ut_get_object_size function before calling this function.
  402.  *
  403.  ******************************************************************************/
  404. static acpi_status
  405. acpi_ut_copy_epackage_to_ipackage (
  406. acpi_operand_object     *internal_object,
  407. u8                      *buffer,
  408. u32                     *space_used)
  409. {
  410. u8                      *free_space;
  411. acpi_object             *external_object;
  412. u32                     length = 0;
  413. u32                     this_index;
  414. u32                     object_space = 0;
  415. acpi_operand_object     *this_internal_obj;
  416. acpi_object             *this_external_obj;
  417. FUNCTION_TRACE ("Ut_copy_epackage_to_ipackage");
  418. /*
  419.  * First package at head of the buffer
  420.  */
  421. external_object = (acpi_object *)buffer;
  422. /*
  423.  * Free space begins right after the first package
  424.  */
  425. free_space = buffer + sizeof(acpi_object);
  426. external_object->type              = internal_object->common.type;
  427. external_object->package.count     = internal_object->package.count;
  428. external_object->package.elements  = (acpi_object *)free_space;
  429. /*
  430.  * Build an array of ACPI_OBJECTS in the buffer
  431.  * and move the free space past it
  432.  */
  433. free_space += external_object->package.count * sizeof(acpi_object);
  434. /* Call Walk_package */
  435. }
  436. #endif /* Future implementation */
  437. /*******************************************************************************
  438.  *
  439.  * FUNCTION:    Acpi_ut_copy_eobject_to_iobject
  440.  *
  441.  * PARAMETERS:  *Internal_object   - The external object to be converted
  442.  *              *Buffer_ptr     - Where the internal object is returned
  443.  *
  444.  * RETURN:      Status          - the status of the call
  445.  *
  446.  * DESCRIPTION: Converts an external object to an internal object.
  447.  *
  448.  ******************************************************************************/
  449. acpi_status
  450. acpi_ut_copy_eobject_to_iobject (
  451. acpi_object             *external_object,
  452. acpi_operand_object     **internal_object)
  453. {
  454. acpi_status             status;
  455. FUNCTION_TRACE ("Ut_copy_eobject_to_iobject");
  456. if (external_object->type == ACPI_TYPE_PACKAGE) {
  457. /*
  458.  * Package objects contain other objects (which can be objects)
  459.  * buildpackage does it all
  460.  *
  461.  * TBD: Package conversion must be completed and tested
  462.  * NOTE: this code converts packages as input parameters to
  463.  * control methods only.  This is a very, very rare case.
  464.  */
  465. /*
  466. Status = Acpi_ut_copy_epackage_to_ipackage(Internal_object,
  467.  Ret_buffer->Pointer,
  468.  &Ret_buffer->Length);
  469. */
  470. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  471. "Packages as parameters not implemented!n"));
  472. return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
  473. }
  474. else {
  475. /*
  476.  * Build a simple object (no nested objects)
  477.  */
  478. status = acpi_ut_copy_esimple_to_isimple (external_object, internal_object);
  479. }
  480. return_ACPI_STATUS (status);
  481. }
  482. /*******************************************************************************
  483.  *
  484.  * FUNCTION:    Acpi_ut_copy_ielement_to_ielement
  485.  *
  486.  * PARAMETERS:  ACPI_PKG_CALLBACK
  487.  *
  488.  * RETURN:      Status          - the status of the call
  489.  *
  490.  * DESCRIPTION: Copy one package element to another package element
  491.  *
  492.  ******************************************************************************/
  493. acpi_status
  494. acpi_ut_copy_ielement_to_ielement (
  495. u8                      object_type,
  496. acpi_operand_object     *source_object,
  497. acpi_generic_state      *state,
  498. void                    *context)
  499. {
  500. acpi_status             status = AE_OK;
  501. u32                     this_index;
  502. acpi_operand_object     **this_target_ptr;
  503. acpi_operand_object     *target_object;
  504. FUNCTION_ENTRY ();
  505. this_index    = state->pkg.index;
  506. this_target_ptr = (acpi_operand_object **)
  507.    &state->pkg.dest_object->package.elements[this_index];
  508. switch (object_type) {
  509. case 0:
  510. /*
  511.  * This is a simple object, just copy it
  512.  */
  513. target_object = acpi_ut_create_internal_object (source_object->common.type);
  514. if (!target_object) {
  515. return (AE_NO_MEMORY);
  516. }
  517. status = acpi_ex_store_object_to_object (source_object, target_object,
  518.   (acpi_walk_state *) context);
  519. if (ACPI_FAILURE (status)) {
  520. return (status);
  521. }
  522. *this_target_ptr = target_object;
  523. break;
  524. case 1:
  525. /*
  526.  * This object is a package - go down another nesting level
  527.  * Create and build the package object
  528.  */
  529. target_object = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
  530. if (!target_object) {
  531. /* TBD: must delete package created up to this point */
  532. return (AE_NO_MEMORY);
  533. }
  534. target_object->package.count = source_object->package.count;
  535. /*
  536.  * Pass the new package object back to the package walk routine
  537.  */
  538. state->pkg.this_target_obj = target_object;
  539. /*
  540.  * Store the object pointer in the parent package object
  541.  */
  542. *this_target_ptr = target_object;
  543. break;
  544. default:
  545. return (AE_BAD_PARAMETER);
  546. }
  547. return (status);
  548. }
  549. /*******************************************************************************
  550.  *
  551.  * FUNCTION:    Acpi_ut_copy_ipackage_to_ipackage
  552.  *
  553.  * PARAMETERS:  *Source_obj     - Pointer to the source package object
  554.  *              *Dest_obj       - Where the internal object is returned
  555.  *
  556.  * RETURN:      Status          - the status of the call
  557.  *
  558.  * DESCRIPTION: This function is called to copy an internal package object
  559.  *              into another internal package object.
  560.  *
  561.  ******************************************************************************/
  562. acpi_status
  563. acpi_ut_copy_ipackage_to_ipackage (
  564. acpi_operand_object     *source_obj,
  565. acpi_operand_object     *dest_obj,
  566. acpi_walk_state         *walk_state)
  567. {
  568. acpi_status             status = AE_OK;
  569. FUNCTION_TRACE ("Ut_copy_ipackage_to_ipackage");
  570. dest_obj->common.type   = source_obj->common.type;
  571. dest_obj->package.count = source_obj->package.count;
  572. /*
  573.  * Create the object array and walk the source package tree
  574.  */
  575. dest_obj->package.elements = ACPI_MEM_CALLOCATE ((source_obj->package.count + 1) *
  576.  sizeof (void *));
  577. dest_obj->package.next_element = dest_obj->package.elements;
  578. if (!dest_obj->package.elements) {
  579. REPORT_ERROR (
  580. ("Aml_build_copy_internal_package_object: Package allocation failuren"));
  581. return_ACPI_STATUS (AE_NO_MEMORY);
  582. }
  583. status = acpi_ut_walk_package_tree (source_obj, dest_obj,
  584.  acpi_ut_copy_ielement_to_ielement, walk_state);
  585. return_ACPI_STATUS (status);
  586. }