utcopy.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: utcopy - Internal to external object translation utilities
  5. *
  6. * Copyright (C) 2000 - 2022, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #include <acpi/acpi.h>
  10. #include "accommon.h"
  11. #include "acnamesp.h"
  12. #define _COMPONENT ACPI_UTILITIES
  13. ACPI_MODULE_NAME("utcopy")
  14. /* Local prototypes */
  15. static acpi_status
  16. acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
  17. union acpi_object *external_object,
  18. u8 *data_space, acpi_size *buffer_space_used);
  19. static acpi_status
  20. acpi_ut_copy_ielement_to_ielement(u8 object_type,
  21. union acpi_operand_object *source_object,
  22. union acpi_generic_state *state,
  23. void *context);
  24. static acpi_status
  25. acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
  26. u8 *buffer, acpi_size *space_used);
  27. static acpi_status
  28. acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,
  29. union acpi_operand_object **return_obj);
  30. static acpi_status
  31. acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
  32. union acpi_operand_object **internal_object);
  33. static acpi_status
  34. acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
  35. union acpi_operand_object *dest_desc);
  36. static acpi_status
  37. acpi_ut_copy_ielement_to_eelement(u8 object_type,
  38. union acpi_operand_object *source_object,
  39. union acpi_generic_state *state,
  40. void *context);
  41. static acpi_status
  42. acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
  43. union acpi_operand_object *dest_obj,
  44. struct acpi_walk_state *walk_state);
  45. /*******************************************************************************
  46. *
  47. * FUNCTION: acpi_ut_copy_isimple_to_esimple
  48. *
  49. * PARAMETERS: internal_object - Source object to be copied
  50. * external_object - Where to return the copied object
  51. * data_space - Where object data is returned (such as
  52. * buffer and string data)
  53. * buffer_space_used - Length of data_space that was used
  54. *
  55. * RETURN: Status
  56. *
  57. * DESCRIPTION: This function is called to copy a simple internal object to
  58. * an external object.
  59. *
  60. * The data_space buffer is assumed to have sufficient space for
  61. * the object.
  62. *
  63. ******************************************************************************/
  64. static acpi_status
  65. acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
  66. union acpi_object *external_object,
  67. u8 *data_space, acpi_size *buffer_space_used)
  68. {
  69. acpi_status status = AE_OK;
  70. ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple);
  71. *buffer_space_used = 0;
  72. /*
  73. * Check for NULL object case (could be an uninitialized
  74. * package element)
  75. */
  76. if (!internal_object) {
  77. return_ACPI_STATUS(AE_OK);
  78. }
  79. /* Always clear the external object */
  80. memset(external_object, 0, sizeof(union acpi_object));
  81. /*
  82. * In general, the external object will be the same type as
  83. * the internal object
  84. */
  85. external_object->type = internal_object->common.type;
  86. /* However, only a limited number of external types are supported */
  87. switch (internal_object->common.type) {
  88. case ACPI_TYPE_STRING:
  89. external_object->string.pointer = (char *)data_space;
  90. external_object->string.length = internal_object->string.length;
  91. *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
  92. internal_object->
  93. string.
  94. length + 1);
  95. memcpy((void *)data_space,
  96. (void *)internal_object->string.pointer,
  97. (acpi_size)internal_object->string.length + 1);
  98. break;
  99. case ACPI_TYPE_BUFFER:
  100. external_object->buffer.pointer = data_space;
  101. external_object->buffer.length = internal_object->buffer.length;
  102. *buffer_space_used =
  103. ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string.
  104. length);
  105. memcpy((void *)data_space,
  106. (void *)internal_object->buffer.pointer,
  107. internal_object->buffer.length);
  108. break;
  109. case ACPI_TYPE_INTEGER:
  110. external_object->integer.value = internal_object->integer.value;
  111. break;
  112. case ACPI_TYPE_LOCAL_REFERENCE:
  113. /* This is an object reference. */
  114. switch (internal_object->reference.class) {
  115. case ACPI_REFCLASS_NAME:
  116. /*
  117. * For namepath, return the object handle ("reference")
  118. * We are referring to the namespace node
  119. */
  120. external_object->reference.handle =
  121. internal_object->reference.node;
  122. external_object->reference.actual_type =
  123. acpi_ns_get_type(internal_object->reference.node);
  124. break;
  125. default:
  126. /* All other reference types are unsupported */
  127. return_ACPI_STATUS(AE_TYPE);
  128. }
  129. break;
  130. case ACPI_TYPE_PROCESSOR:
  131. external_object->processor.proc_id =
  132. internal_object->processor.proc_id;
  133. external_object->processor.pblk_address =
  134. internal_object->processor.address;
  135. external_object->processor.pblk_length =
  136. internal_object->processor.length;
  137. break;
  138. case ACPI_TYPE_POWER:
  139. external_object->power_resource.system_level =
  140. internal_object->power_resource.system_level;
  141. external_object->power_resource.resource_order =
  142. internal_object->power_resource.resource_order;
  143. break;
  144. default:
  145. /*
  146. * There is no corresponding external object type
  147. */
  148. ACPI_ERROR((AE_INFO,
  149. "Unsupported object type, cannot convert to external object: %s",
  150. acpi_ut_get_type_name(internal_object->common.
  151. type)));
  152. return_ACPI_STATUS(AE_SUPPORT);
  153. }
  154. return_ACPI_STATUS(status);
  155. }
  156. /*******************************************************************************
  157. *
  158. * FUNCTION: acpi_ut_copy_ielement_to_eelement
  159. *
  160. * PARAMETERS: acpi_pkg_callback
  161. *
  162. * RETURN: Status
  163. *
  164. * DESCRIPTION: Copy one package element to another package element
  165. *
  166. ******************************************************************************/
  167. static acpi_status
  168. acpi_ut_copy_ielement_to_eelement(u8 object_type,
  169. union acpi_operand_object *source_object,
  170. union acpi_generic_state *state,
  171. void *context)
  172. {
  173. acpi_status status = AE_OK;
  174. struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
  175. acpi_size object_space;
  176. u32 this_index;
  177. union acpi_object *target_object;
  178. ACPI_FUNCTION_ENTRY();
  179. this_index = state->pkg.index;
  180. target_object = (union acpi_object *)&((union acpi_object *)
  181. (state->pkg.dest_object))->
  182. package.elements[this_index];
  183. switch (object_type) {
  184. case ACPI_COPY_TYPE_SIMPLE:
  185. /*
  186. * This is a simple or null object
  187. */
  188. status = acpi_ut_copy_isimple_to_esimple(source_object,
  189. target_object,
  190. info->free_space,
  191. &object_space);
  192. if (ACPI_FAILURE(status)) {
  193. return (status);
  194. }
  195. break;
  196. case ACPI_COPY_TYPE_PACKAGE:
  197. /*
  198. * Build the package object
  199. */
  200. target_object->type = ACPI_TYPE_PACKAGE;
  201. target_object->package.count = source_object->package.count;
  202. target_object->package.elements =
  203. ACPI_CAST_PTR(union acpi_object, info->free_space);
  204. /*
  205. * Pass the new package object back to the package walk routine
  206. */
  207. state->pkg.this_target_obj = target_object;
  208. /*
  209. * Save space for the array of objects (Package elements)
  210. * update the buffer length counter
  211. */
  212. object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
  213. target_object->
  214. package.count *
  215. sizeof(union
  216. acpi_object));
  217. break;
  218. default:
  219. return (AE_BAD_PARAMETER);
  220. }
  221. info->free_space += object_space;
  222. info->length += object_space;
  223. return (status);
  224. }
  225. /*******************************************************************************
  226. *
  227. * FUNCTION: acpi_ut_copy_ipackage_to_epackage
  228. *
  229. * PARAMETERS: internal_object - Pointer to the object we are returning
  230. * buffer - Where the object is returned
  231. * space_used - Where the object length is returned
  232. *
  233. * RETURN: Status
  234. *
  235. * DESCRIPTION: This function is called to place a package object in a user
  236. * buffer. A package object by definition contains other objects.
  237. *
  238. * The buffer is assumed to have sufficient space for the object.
  239. * The caller must have verified the buffer length needed using
  240. * the acpi_ut_get_object_size function before calling this function.
  241. *
  242. ******************************************************************************/
  243. static acpi_status
  244. acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
  245. u8 *buffer, acpi_size *space_used)
  246. {
  247. union acpi_object *external_object;
  248. acpi_status status;
  249. struct acpi_pkg_info info;
  250. ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_epackage);
  251. /*
  252. * First package at head of the buffer
  253. */
  254. external_object = ACPI_CAST_PTR(union acpi_object, buffer);
  255. /*
  256. * Free space begins right after the first package
  257. */
  258. info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  259. info.free_space = buffer +
  260. ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  261. info.object_space = 0;
  262. info.num_packages = 1;
  263. external_object->type = internal_object->common.type;
  264. external_object->package.count = internal_object->package.count;
  265. external_object->package.elements =
  266. ACPI_CAST_PTR(union acpi_object, info.free_space);
  267. /*
  268. * Leave room for an array of ACPI_OBJECTS in the buffer
  269. * and move the free space past it
  270. */
  271. info.length += (acpi_size)external_object->package.count *
  272. ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  273. info.free_space += external_object->package.count *
  274. ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  275. status = acpi_ut_walk_package_tree(internal_object, external_object,
  276. acpi_ut_copy_ielement_to_eelement,
  277. &info);
  278. *space_used = info.length;
  279. return_ACPI_STATUS(status);
  280. }
  281. /*******************************************************************************
  282. *
  283. * FUNCTION: acpi_ut_copy_iobject_to_eobject
  284. *
  285. * PARAMETERS: internal_object - The internal object to be converted
  286. * ret_buffer - Where the object is returned
  287. *
  288. * RETURN: Status
  289. *
  290. * DESCRIPTION: This function is called to build an API object to be returned
  291. * to the caller.
  292. *
  293. ******************************************************************************/
  294. acpi_status
  295. acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
  296. struct acpi_buffer *ret_buffer)
  297. {
  298. acpi_status status;
  299. ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
  300. if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
  301. /*
  302. * Package object: Copy all subobjects (including
  303. * nested packages)
  304. */
  305. status = acpi_ut_copy_ipackage_to_epackage(internal_object,
  306. ret_buffer->pointer,
  307. &ret_buffer->length);
  308. } else {
  309. /*
  310. * Build a simple object (no nested objects)
  311. */
  312. status = acpi_ut_copy_isimple_to_esimple(internal_object,
  313. ACPI_CAST_PTR(union
  314. acpi_object,
  315. ret_buffer->
  316. pointer),
  317. ACPI_ADD_PTR(u8,
  318. ret_buffer->
  319. pointer,
  320. ACPI_ROUND_UP_TO_NATIVE_WORD
  321. (sizeof
  322. (union
  323. acpi_object))),
  324. &ret_buffer->length);
  325. /*
  326. * build simple does not include the object size in the length
  327. * so we add it in here
  328. */
  329. ret_buffer->length += sizeof(union acpi_object);
  330. }
  331. return_ACPI_STATUS(status);
  332. }
  333. /*******************************************************************************
  334. *
  335. * FUNCTION: acpi_ut_copy_esimple_to_isimple
  336. *
  337. * PARAMETERS: external_object - The external object to be converted
  338. * ret_internal_object - Where the internal object is returned
  339. *
  340. * RETURN: Status
  341. *
  342. * DESCRIPTION: This function copies an external object to an internal one.
  343. * NOTE: Pointers can be copied, we don't need to copy data.
  344. * (The pointers have to be valid in our address space no matter
  345. * what we do with them!)
  346. *
  347. ******************************************************************************/
  348. static acpi_status
  349. acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
  350. union acpi_operand_object **ret_internal_object)
  351. {
  352. union acpi_operand_object *internal_object;
  353. ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple);
  354. /*
  355. * Simple types supported are: String, Buffer, Integer
  356. */
  357. switch (external_object->type) {
  358. case ACPI_TYPE_STRING:
  359. case ACPI_TYPE_BUFFER:
  360. case ACPI_TYPE_INTEGER:
  361. case ACPI_TYPE_LOCAL_REFERENCE:
  362. internal_object = acpi_ut_create_internal_object((u8)
  363. external_object->
  364. type);
  365. if (!internal_object) {
  366. return_ACPI_STATUS(AE_NO_MEMORY);
  367. }
  368. break;
  369. case ACPI_TYPE_ANY: /* This is the case for a NULL object */
  370. *ret_internal_object = NULL;
  371. return_ACPI_STATUS(AE_OK);
  372. default:
  373. /* All other types are not supported */
  374. ACPI_ERROR((AE_INFO,
  375. "Unsupported object type, cannot convert to internal object: %s",
  376. acpi_ut_get_type_name(external_object->type)));
  377. return_ACPI_STATUS(AE_SUPPORT);
  378. }
  379. /* Must COPY string and buffer contents */
  380. switch (external_object->type) {
  381. case ACPI_TYPE_STRING:
  382. internal_object->string.pointer =
  383. ACPI_ALLOCATE_ZEROED((acpi_size)
  384. external_object->string.length + 1);
  385. if (!internal_object->string.pointer) {
  386. goto error_exit;
  387. }
  388. memcpy(internal_object->string.pointer,
  389. external_object->string.pointer,
  390. external_object->string.length);
  391. internal_object->string.length = external_object->string.length;
  392. break;
  393. case ACPI_TYPE_BUFFER:
  394. internal_object->buffer.pointer =
  395. ACPI_ALLOCATE_ZEROED(external_object->buffer.length);
  396. if (!internal_object->buffer.pointer) {
  397. goto error_exit;
  398. }
  399. memcpy(internal_object->buffer.pointer,
  400. external_object->buffer.pointer,
  401. external_object->buffer.length);
  402. internal_object->buffer.length = external_object->buffer.length;
  403. /* Mark buffer data valid */
  404. internal_object->buffer.flags |= AOPOBJ_DATA_VALID;
  405. break;
  406. case ACPI_TYPE_INTEGER:
  407. internal_object->integer.value = external_object->integer.value;
  408. break;
  409. case ACPI_TYPE_LOCAL_REFERENCE:
  410. /* An incoming reference is defined to be a namespace node */
  411. internal_object->reference.class = ACPI_REFCLASS_REFOF;
  412. internal_object->reference.object =
  413. external_object->reference.handle;
  414. break;
  415. default:
  416. /* Other types can't get here */
  417. break;
  418. }
  419. *ret_internal_object = internal_object;
  420. return_ACPI_STATUS(AE_OK);
  421. error_exit:
  422. acpi_ut_remove_reference(internal_object);
  423. return_ACPI_STATUS(AE_NO_MEMORY);
  424. }
  425. /*******************************************************************************
  426. *
  427. * FUNCTION: acpi_ut_copy_epackage_to_ipackage
  428. *
  429. * PARAMETERS: external_object - The external object to be converted
  430. * internal_object - Where the internal object is returned
  431. *
  432. * RETURN: Status
  433. *
  434. * DESCRIPTION: Copy an external package object to an internal package.
  435. * Handles nested packages.
  436. *
  437. ******************************************************************************/
  438. static acpi_status
  439. acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
  440. union acpi_operand_object **internal_object)
  441. {
  442. acpi_status status = AE_OK;
  443. union acpi_operand_object *package_object;
  444. union acpi_operand_object **package_elements;
  445. u32 i;
  446. ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
  447. /* Create the package object */
  448. package_object =
  449. acpi_ut_create_package_object(external_object->package.count);
  450. if (!package_object) {
  451. return_ACPI_STATUS(AE_NO_MEMORY);
  452. }
  453. package_elements = package_object->package.elements;
  454. /*
  455. * Recursive implementation. Probably ok, since nested external
  456. * packages as parameters should be very rare.
  457. */
  458. for (i = 0; i < external_object->package.count; i++) {
  459. status =
  460. acpi_ut_copy_eobject_to_iobject(&external_object->package.
  461. elements[i],
  462. &package_elements[i]);
  463. if (ACPI_FAILURE(status)) {
  464. /* Truncate package and delete it */
  465. package_object->package.count = i;
  466. package_elements[i] = NULL;
  467. acpi_ut_remove_reference(package_object);
  468. return_ACPI_STATUS(status);
  469. }
  470. }
  471. /* Mark package data valid */
  472. package_object->package.flags |= AOPOBJ_DATA_VALID;
  473. *internal_object = package_object;
  474. return_ACPI_STATUS(status);
  475. }
  476. /*******************************************************************************
  477. *
  478. * FUNCTION: acpi_ut_copy_eobject_to_iobject
  479. *
  480. * PARAMETERS: external_object - The external object to be converted
  481. * internal_object - Where the internal object is returned
  482. *
  483. * RETURN: Status
  484. *
  485. * DESCRIPTION: Converts an external object to an internal object.
  486. *
  487. ******************************************************************************/
  488. acpi_status
  489. acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object,
  490. union acpi_operand_object **internal_object)
  491. {
  492. acpi_status status;
  493. ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject);
  494. if (external_object->type == ACPI_TYPE_PACKAGE) {
  495. status =
  496. acpi_ut_copy_epackage_to_ipackage(external_object,
  497. internal_object);
  498. } else {
  499. /*
  500. * Build a simple object (no nested objects)
  501. */
  502. status = acpi_ut_copy_esimple_to_isimple(external_object,
  503. internal_object);
  504. }
  505. return_ACPI_STATUS(status);
  506. }
  507. /*******************************************************************************
  508. *
  509. * FUNCTION: acpi_ut_copy_simple_object
  510. *
  511. * PARAMETERS: source_desc - The internal object to be copied
  512. * dest_desc - New target object
  513. *
  514. * RETURN: Status
  515. *
  516. * DESCRIPTION: Simple copy of one internal object to another. Reference count
  517. * of the destination object is preserved.
  518. *
  519. ******************************************************************************/
  520. static acpi_status
  521. acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
  522. union acpi_operand_object *dest_desc)
  523. {
  524. u16 reference_count;
  525. union acpi_operand_object *next_object;
  526. acpi_status status;
  527. acpi_size copy_size;
  528. /* Save fields from destination that we don't want to overwrite */
  529. reference_count = dest_desc->common.reference_count;
  530. next_object = dest_desc->common.next_object;
  531. /*
  532. * Copy the entire source object over the destination object.
  533. * Note: Source can be either an operand object or namespace node.
  534. */
  535. copy_size = sizeof(union acpi_operand_object);
  536. if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_NAMED) {
  537. copy_size = sizeof(struct acpi_namespace_node);
  538. }
  539. memcpy(ACPI_CAST_PTR(char, dest_desc),
  540. ACPI_CAST_PTR(char, source_desc), copy_size);
  541. /* Restore the saved fields */
  542. dest_desc->common.reference_count = reference_count;
  543. dest_desc->common.next_object = next_object;
  544. /* New object is not static, regardless of source */
  545. dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
  546. /* Handle the objects with extra data */
  547. switch (dest_desc->common.type) {
  548. case ACPI_TYPE_BUFFER:
  549. /*
  550. * Allocate and copy the actual buffer if and only if:
  551. * 1) There is a valid buffer pointer
  552. * 2) The buffer has a length > 0
  553. */
  554. if ((source_desc->buffer.pointer) &&
  555. (source_desc->buffer.length)) {
  556. dest_desc->buffer.pointer =
  557. ACPI_ALLOCATE(source_desc->buffer.length);
  558. if (!dest_desc->buffer.pointer) {
  559. return (AE_NO_MEMORY);
  560. }
  561. /* Copy the actual buffer data */
  562. memcpy(dest_desc->buffer.pointer,
  563. source_desc->buffer.pointer,
  564. source_desc->buffer.length);
  565. }
  566. break;
  567. case ACPI_TYPE_STRING:
  568. /*
  569. * Allocate and copy the actual string if and only if:
  570. * 1) There is a valid string pointer
  571. * (Pointer to a NULL string is allowed)
  572. */
  573. if (source_desc->string.pointer) {
  574. dest_desc->string.pointer =
  575. ACPI_ALLOCATE((acpi_size)source_desc->string.
  576. length + 1);
  577. if (!dest_desc->string.pointer) {
  578. return (AE_NO_MEMORY);
  579. }
  580. /* Copy the actual string data */
  581. memcpy(dest_desc->string.pointer,
  582. source_desc->string.pointer,
  583. (acpi_size)source_desc->string.length + 1);
  584. }
  585. break;
  586. case ACPI_TYPE_LOCAL_REFERENCE:
  587. /*
  588. * We copied the reference object, so we now must add a reference
  589. * to the object pointed to by the reference
  590. *
  591. * DDBHandle reference (from Load/load_table) is a special reference,
  592. * it does not have a Reference.Object, so does not need to
  593. * increase the reference count
  594. */
  595. if (source_desc->reference.class == ACPI_REFCLASS_TABLE) {
  596. break;
  597. }
  598. acpi_ut_add_reference(source_desc->reference.object);
  599. break;
  600. case ACPI_TYPE_REGION:
  601. /*
  602. * We copied the Region Handler, so we now must add a reference
  603. */
  604. if (dest_desc->region.handler) {
  605. acpi_ut_add_reference(dest_desc->region.handler);
  606. }
  607. break;
  608. /*
  609. * For Mutex and Event objects, we cannot simply copy the underlying
  610. * OS object. We must create a new one.
  611. */
  612. case ACPI_TYPE_MUTEX:
  613. status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex);
  614. if (ACPI_FAILURE(status)) {
  615. return (status);
  616. }
  617. break;
  618. case ACPI_TYPE_EVENT:
  619. status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
  620. &dest_desc->event.
  621. os_semaphore);
  622. if (ACPI_FAILURE(status)) {
  623. return (status);
  624. }
  625. break;
  626. default:
  627. /* Nothing to do for other simple objects */
  628. break;
  629. }
  630. return (AE_OK);
  631. }
  632. /*******************************************************************************
  633. *
  634. * FUNCTION: acpi_ut_copy_ielement_to_ielement
  635. *
  636. * PARAMETERS: acpi_pkg_callback
  637. *
  638. * RETURN: Status
  639. *
  640. * DESCRIPTION: Copy one package element to another package element
  641. *
  642. ******************************************************************************/
  643. static acpi_status
  644. acpi_ut_copy_ielement_to_ielement(u8 object_type,
  645. union acpi_operand_object *source_object,
  646. union acpi_generic_state *state,
  647. void *context)
  648. {
  649. acpi_status status = AE_OK;
  650. u32 this_index;
  651. union acpi_operand_object **this_target_ptr;
  652. union acpi_operand_object *target_object;
  653. ACPI_FUNCTION_ENTRY();
  654. this_index = state->pkg.index;
  655. this_target_ptr = (union acpi_operand_object **)
  656. &state->pkg.dest_object->package.elements[this_index];
  657. switch (object_type) {
  658. case ACPI_COPY_TYPE_SIMPLE:
  659. /* A null source object indicates a (legal) null package element */
  660. if (source_object) {
  661. /*
  662. * This is a simple object, just copy it
  663. */
  664. target_object =
  665. acpi_ut_create_internal_object(source_object->
  666. common.type);
  667. if (!target_object) {
  668. return (AE_NO_MEMORY);
  669. }
  670. status =
  671. acpi_ut_copy_simple_object(source_object,
  672. target_object);
  673. if (ACPI_FAILURE(status)) {
  674. goto error_exit;
  675. }
  676. *this_target_ptr = target_object;
  677. } else {
  678. /* Pass through a null element */
  679. *this_target_ptr = NULL;
  680. }
  681. break;
  682. case ACPI_COPY_TYPE_PACKAGE:
  683. /*
  684. * This object is a package - go down another nesting level
  685. * Create and build the package object
  686. */
  687. target_object =
  688. acpi_ut_create_package_object(source_object->package.count);
  689. if (!target_object) {
  690. return (AE_NO_MEMORY);
  691. }
  692. target_object->common.flags = source_object->common.flags;
  693. /* Pass the new package object back to the package walk routine */
  694. state->pkg.this_target_obj = target_object;
  695. /* Store the object pointer in the parent package object */
  696. *this_target_ptr = target_object;
  697. break;
  698. default:
  699. return (AE_BAD_PARAMETER);
  700. }
  701. return (status);
  702. error_exit:
  703. acpi_ut_remove_reference(target_object);
  704. return (status);
  705. }
  706. /*******************************************************************************
  707. *
  708. * FUNCTION: acpi_ut_copy_ipackage_to_ipackage
  709. *
  710. * PARAMETERS: source_obj - Pointer to the source package object
  711. * dest_obj - Where the internal object is returned
  712. * walk_state - Current Walk state descriptor
  713. *
  714. * RETURN: Status
  715. *
  716. * DESCRIPTION: This function is called to copy an internal package object
  717. * into another internal package object.
  718. *
  719. ******************************************************************************/
  720. static acpi_status
  721. acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
  722. union acpi_operand_object *dest_obj,
  723. struct acpi_walk_state *walk_state)
  724. {
  725. acpi_status status = AE_OK;
  726. ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
  727. dest_obj->common.type = source_obj->common.type;
  728. dest_obj->common.flags = source_obj->common.flags;
  729. dest_obj->package.count = source_obj->package.count;
  730. /*
  731. * Create the object array and walk the source package tree
  732. */
  733. dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
  734. source_obj->package.
  735. count +
  736. 1) * sizeof(void *));
  737. if (!dest_obj->package.elements) {
  738. ACPI_ERROR((AE_INFO, "Package allocation failure"));
  739. return_ACPI_STATUS(AE_NO_MEMORY);
  740. }
  741. /*
  742. * Copy the package element-by-element by walking the package "tree".
  743. * This handles nested packages of arbitrary depth.
  744. */
  745. status = acpi_ut_walk_package_tree(source_obj, dest_obj,
  746. acpi_ut_copy_ielement_to_ielement,
  747. walk_state);
  748. return_ACPI_STATUS(status);
  749. }
  750. /*******************************************************************************
  751. *
  752. * FUNCTION: acpi_ut_copy_iobject_to_iobject
  753. *
  754. * PARAMETERS: source_desc - The internal object to be copied
  755. * dest_desc - Where the copied object is returned
  756. * walk_state - Current walk state
  757. *
  758. * RETURN: Status
  759. *
  760. * DESCRIPTION: Copy an internal object to a new internal object
  761. *
  762. ******************************************************************************/
  763. acpi_status
  764. acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
  765. union acpi_operand_object **dest_desc,
  766. struct acpi_walk_state *walk_state)
  767. {
  768. acpi_status status = AE_OK;
  769. ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject);
  770. /* Create the top level object */
  771. *dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
  772. if (!*dest_desc) {
  773. return_ACPI_STATUS(AE_NO_MEMORY);
  774. }
  775. /* Copy the object and possible subobjects */
  776. if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
  777. status =
  778. acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
  779. walk_state);
  780. } else {
  781. status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
  782. }
  783. /* Delete the allocated object if copy failed */
  784. if (ACPI_FAILURE(status)) {
  785. acpi_ut_remove_reference(*dest_desc);
  786. }
  787. return_ACPI_STATUS(status);
  788. }