Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenutcopy.c
Go to the documentation of this file.
00001 /****************************************************************************** 00002 * 00003 * Module Name: utcopy - Internal to external object translation utilities 00004 * 00005 *****************************************************************************/ 00006 00007 /****************************************************************************** 00008 * 00009 * 1. Copyright Notice 00010 * 00011 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp. 00012 * All rights reserved. 00013 * 00014 * 2. License 00015 * 00016 * 2.1. This is your license from Intel Corp. under its intellectual property 00017 * rights. You may have additional license terms from the party that provided 00018 * you this software, covering your right to use that party's intellectual 00019 * property rights. 00020 * 00021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 00022 * copy of the source code appearing in this file ("Covered Code") an 00023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 00024 * base code distributed originally by Intel ("Original Intel Code") to copy, 00025 * make derivatives, distribute, use and display any portion of the Covered 00026 * Code in any form, with the right to sublicense such rights; and 00027 * 00028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 00029 * license (with the right to sublicense), under only those claims of Intel 00030 * patents that are infringed by the Original Intel Code, to make, use, sell, 00031 * offer to sell, and import the Covered Code and derivative works thereof 00032 * solely to the minimum extent necessary to exercise the above copyright 00033 * license, and in no event shall the patent license extend to any additions 00034 * to or modifications of the Original Intel Code. No other license or right 00035 * is granted directly or by implication, estoppel or otherwise; 00036 * 00037 * The above copyright and patent license is granted only if the following 00038 * conditions are met: 00039 * 00040 * 3. Conditions 00041 * 00042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 00043 * Redistribution of source code of any substantial portion of the Covered 00044 * Code or modification with rights to further distribute source must include 00045 * the above Copyright Notice, the above License, this list of Conditions, 00046 * and the following Disclaimer and Export Compliance provision. In addition, 00047 * Licensee must cause all Covered Code to which Licensee contributes to 00048 * contain a file documenting the changes Licensee made to create that Covered 00049 * Code and the date of any change. Licensee must include in that file the 00050 * documentation of any changes made by any predecessor Licensee. Licensee 00051 * must include a prominent statement that the modification is derived, 00052 * directly or indirectly, from Original Intel Code. 00053 * 00054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 00055 * Redistribution of source code of any substantial portion of the Covered 00056 * Code or modification without rights to further distribute source must 00057 * include the following Disclaimer and Export Compliance provision in the 00058 * documentation and/or other materials provided with distribution. In 00059 * addition, Licensee may not authorize further sublicense of source of any 00060 * portion of the Covered Code, and must include terms to the effect that the 00061 * license from Licensee to its licensee is limited to the intellectual 00062 * property embodied in the software Licensee provides to its licensee, and 00063 * not to intellectual property embodied in modifications its licensee may 00064 * make. 00065 * 00066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 00067 * substantial portion of the Covered Code or modification must reproduce the 00068 * above Copyright Notice, and the following Disclaimer and Export Compliance 00069 * provision in the documentation and/or other materials provided with the 00070 * distribution. 00071 * 00072 * 3.4. Intel retains all right, title, and interest in and to the Original 00073 * Intel Code. 00074 * 00075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 00076 * Intel shall be used in advertising or otherwise to promote the sale, use or 00077 * other dealings in products derived from or relating to the Covered Code 00078 * without prior written authorization from Intel. 00079 * 00080 * 4. Disclaimer and Export Compliance 00081 * 00082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 00083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 00084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 00085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 00086 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 00087 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 00088 * PARTICULAR PURPOSE. 00089 * 00090 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 00091 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 00092 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 00093 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 00094 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 00095 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 00096 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 00097 * LIMITED REMEDY. 00098 * 00099 * 4.3. Licensee shall not export, either directly or indirectly, any of this 00100 * software or system incorporating such software without first obtaining any 00101 * required license or other approval from the U. S. Department of Commerce or 00102 * any other agency or department of the United States Government. In the 00103 * event Licensee exports any such software from the United States or 00104 * re-exports any such software from a foreign destination, Licensee shall 00105 * ensure that the distribution and export/re-export of the software is in 00106 * compliance with all laws, regulations, orders, or other restrictions of the 00107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 00108 * any of its subsidiaries will export/re-export any technical data, process, 00109 * software, or service, directly or indirectly, to any country for which the 00110 * United States government or any agency thereof requires an export license, 00111 * other governmental approval, or letter of assurance, without first obtaining 00112 * such license, approval or letter. 00113 * 00114 *****************************************************************************/ 00115 00116 #define __UTCOPY_C__ 00117 00118 #include "acpi.h" 00119 #include "accommon.h" 00120 #include "acnamesp.h" 00121 00122 00123 #define _COMPONENT ACPI_UTILITIES 00124 ACPI_MODULE_NAME ("utcopy") 00125 00126 /* Local prototypes */ 00127 00128 static ACPI_STATUS 00129 AcpiUtCopyIsimpleToEsimple ( 00130 ACPI_OPERAND_OBJECT *InternalObject, 00131 ACPI_OBJECT *ExternalObject, 00132 UINT8 *DataSpace, 00133 ACPI_SIZE *BufferSpaceUsed); 00134 00135 static ACPI_STATUS 00136 AcpiUtCopyIelementToIelement ( 00137 UINT8 ObjectType, 00138 ACPI_OPERAND_OBJECT *SourceObject, 00139 ACPI_GENERIC_STATE *State, 00140 void *Context); 00141 00142 static ACPI_STATUS 00143 AcpiUtCopyIpackageToEpackage ( 00144 ACPI_OPERAND_OBJECT *InternalObject, 00145 UINT8 *Buffer, 00146 ACPI_SIZE *SpaceUsed); 00147 00148 static ACPI_STATUS 00149 AcpiUtCopyEsimpleToIsimple( 00150 ACPI_OBJECT *UserObj, 00151 ACPI_OPERAND_OBJECT **ReturnObj); 00152 00153 static ACPI_STATUS 00154 AcpiUtCopyEpackageToIpackage ( 00155 ACPI_OBJECT *ExternalObject, 00156 ACPI_OPERAND_OBJECT **InternalObject); 00157 00158 static ACPI_STATUS 00159 AcpiUtCopySimpleObject ( 00160 ACPI_OPERAND_OBJECT *SourceDesc, 00161 ACPI_OPERAND_OBJECT *DestDesc); 00162 00163 static ACPI_STATUS 00164 AcpiUtCopyIelementToEelement ( 00165 UINT8 ObjectType, 00166 ACPI_OPERAND_OBJECT *SourceObject, 00167 ACPI_GENERIC_STATE *State, 00168 void *Context); 00169 00170 static ACPI_STATUS 00171 AcpiUtCopyIpackageToIpackage ( 00172 ACPI_OPERAND_OBJECT *SourceObj, 00173 ACPI_OPERAND_OBJECT *DestObj, 00174 ACPI_WALK_STATE *WalkState); 00175 00176 00177 /******************************************************************************* 00178 * 00179 * FUNCTION: AcpiUtCopyIsimpleToEsimple 00180 * 00181 * PARAMETERS: InternalObject - Source object to be copied 00182 * ExternalObject - Where to return the copied object 00183 * DataSpace - Where object data is returned (such as 00184 * buffer and string data) 00185 * BufferSpaceUsed - Length of DataSpace that was used 00186 * 00187 * RETURN: Status 00188 * 00189 * DESCRIPTION: This function is called to copy a simple internal object to 00190 * an external object. 00191 * 00192 * The DataSpace buffer is assumed to have sufficient space for 00193 * the object. 00194 * 00195 ******************************************************************************/ 00196 00197 static ACPI_STATUS 00198 AcpiUtCopyIsimpleToEsimple ( 00199 ACPI_OPERAND_OBJECT *InternalObject, 00200 ACPI_OBJECT *ExternalObject, 00201 UINT8 *DataSpace, 00202 ACPI_SIZE *BufferSpaceUsed) 00203 { 00204 ACPI_STATUS Status = AE_OK; 00205 00206 00207 ACPI_FUNCTION_TRACE (UtCopyIsimpleToEsimple); 00208 00209 00210 *BufferSpaceUsed = 0; 00211 00212 /* 00213 * Check for NULL object case (could be an uninitialized 00214 * package element) 00215 */ 00216 if (!InternalObject) 00217 { 00218 return_ACPI_STATUS (AE_OK); 00219 } 00220 00221 /* Always clear the external object */ 00222 00223 ACPI_MEMSET (ExternalObject, 0, sizeof (ACPI_OBJECT)); 00224 00225 /* 00226 * In general, the external object will be the same type as 00227 * the internal object 00228 */ 00229 ExternalObject->Type = InternalObject->Common.Type; 00230 00231 /* However, only a limited number of external types are supported */ 00232 00233 switch (InternalObject->Common.Type) 00234 { 00235 case ACPI_TYPE_STRING: 00236 00237 ExternalObject->String.Pointer = (char *) DataSpace; 00238 ExternalObject->String.Length = InternalObject->String.Length; 00239 *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD ( 00240 (ACPI_SIZE) InternalObject->String.Length + 1); 00241 00242 ACPI_MEMCPY ((void *) DataSpace, 00243 (void *) InternalObject->String.Pointer, 00244 (ACPI_SIZE) InternalObject->String.Length + 1); 00245 break; 00246 00247 00248 case ACPI_TYPE_BUFFER: 00249 00250 ExternalObject->Buffer.Pointer = DataSpace; 00251 ExternalObject->Buffer.Length = InternalObject->Buffer.Length; 00252 *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD ( 00253 InternalObject->String.Length); 00254 00255 ACPI_MEMCPY ((void *) DataSpace, 00256 (void *) InternalObject->Buffer.Pointer, 00257 InternalObject->Buffer.Length); 00258 break; 00259 00260 00261 case ACPI_TYPE_INTEGER: 00262 00263 ExternalObject->Integer.Value = InternalObject->Integer.Value; 00264 break; 00265 00266 00267 case ACPI_TYPE_LOCAL_REFERENCE: 00268 00269 /* This is an object reference. */ 00270 00271 switch (InternalObject->Reference.Class) 00272 { 00273 case ACPI_REFCLASS_NAME: 00274 00275 /* 00276 * For namepath, return the object handle ("reference") 00277 * We are referring to the namespace node 00278 */ 00279 ExternalObject->Reference.Handle = 00280 InternalObject->Reference.Node; 00281 ExternalObject->Reference.ActualType = 00282 AcpiNsGetType (InternalObject->Reference.Node); 00283 break; 00284 00285 default: 00286 00287 /* All other reference types are unsupported */ 00288 00289 return_ACPI_STATUS (AE_TYPE); 00290 } 00291 break; 00292 00293 00294 case ACPI_TYPE_PROCESSOR: 00295 00296 ExternalObject->Processor.ProcId = 00297 InternalObject->Processor.ProcId; 00298 ExternalObject->Processor.PblkAddress = 00299 InternalObject->Processor.Address; 00300 ExternalObject->Processor.PblkLength = 00301 InternalObject->Processor.Length; 00302 break; 00303 00304 00305 case ACPI_TYPE_POWER: 00306 00307 ExternalObject->PowerResource.SystemLevel = 00308 InternalObject->PowerResource.SystemLevel; 00309 00310 ExternalObject->PowerResource.ResourceOrder = 00311 InternalObject->PowerResource.ResourceOrder; 00312 break; 00313 00314 00315 default: 00316 /* 00317 * There is no corresponding external object type 00318 */ 00319 ACPI_ERROR ((AE_INFO, 00320 "Unsupported object type, cannot convert to external object: %s", 00321 AcpiUtGetTypeName (InternalObject->Common.Type))); 00322 00323 return_ACPI_STATUS (AE_SUPPORT); 00324 } 00325 00326 return_ACPI_STATUS (Status); 00327 } 00328 00329 00330 /******************************************************************************* 00331 * 00332 * FUNCTION: AcpiUtCopyIelementToEelement 00333 * 00334 * PARAMETERS: ACPI_PKG_CALLBACK 00335 * 00336 * RETURN: Status 00337 * 00338 * DESCRIPTION: Copy one package element to another package element 00339 * 00340 ******************************************************************************/ 00341 00342 static ACPI_STATUS 00343 AcpiUtCopyIelementToEelement ( 00344 UINT8 ObjectType, 00345 ACPI_OPERAND_OBJECT *SourceObject, 00346 ACPI_GENERIC_STATE *State, 00347 void *Context) 00348 { 00349 ACPI_STATUS Status = AE_OK; 00350 ACPI_PKG_INFO *Info = (ACPI_PKG_INFO *) Context; 00351 ACPI_SIZE ObjectSpace; 00352 UINT32 ThisIndex; 00353 ACPI_OBJECT *TargetObject; 00354 00355 00356 ACPI_FUNCTION_ENTRY (); 00357 00358 00359 ThisIndex = State->Pkg.Index; 00360 TargetObject = (ACPI_OBJECT *) 00361 &((ACPI_OBJECT *)(State->Pkg.DestObject))->Package.Elements[ThisIndex]; 00362 00363 switch (ObjectType) 00364 { 00365 case ACPI_COPY_TYPE_SIMPLE: 00366 00367 /* 00368 * This is a simple or null object 00369 */ 00370 Status = AcpiUtCopyIsimpleToEsimple (SourceObject, 00371 TargetObject, Info->FreeSpace, &ObjectSpace); 00372 if (ACPI_FAILURE (Status)) 00373 { 00374 return (Status); 00375 } 00376 break; 00377 00378 00379 case ACPI_COPY_TYPE_PACKAGE: 00380 00381 /* 00382 * Build the package object 00383 */ 00384 TargetObject->Type = ACPI_TYPE_PACKAGE; 00385 TargetObject->Package.Count = SourceObject->Package.Count; 00386 TargetObject->Package.Elements = 00387 ACPI_CAST_PTR (ACPI_OBJECT, Info->FreeSpace); 00388 00389 /* 00390 * Pass the new package object back to the package walk routine 00391 */ 00392 State->Pkg.ThisTargetObj = TargetObject; 00393 00394 /* 00395 * Save space for the array of objects (Package elements) 00396 * update the buffer length counter 00397 */ 00398 ObjectSpace = ACPI_ROUND_UP_TO_NATIVE_WORD ( 00399 (ACPI_SIZE) TargetObject->Package.Count * 00400 sizeof (ACPI_OBJECT)); 00401 break; 00402 00403 00404 default: 00405 return (AE_BAD_PARAMETER); 00406 } 00407 00408 Info->FreeSpace += ObjectSpace; 00409 Info->Length += ObjectSpace; 00410 return (Status); 00411 } 00412 00413 00414 /******************************************************************************* 00415 * 00416 * FUNCTION: AcpiUtCopyIpackageToEpackage 00417 * 00418 * PARAMETERS: InternalObject - Pointer to the object we are returning 00419 * Buffer - Where the object is returned 00420 * SpaceUsed - Where the object length is returned 00421 * 00422 * RETURN: Status 00423 * 00424 * DESCRIPTION: This function is called to place a package object in a user 00425 * buffer. A package object by definition contains other objects. 00426 * 00427 * The buffer is assumed to have sufficient space for the object. 00428 * The caller must have verified the buffer length needed using 00429 * the AcpiUtGetObjectSize function before calling this function. 00430 * 00431 ******************************************************************************/ 00432 00433 static ACPI_STATUS 00434 AcpiUtCopyIpackageToEpackage ( 00435 ACPI_OPERAND_OBJECT *InternalObject, 00436 UINT8 *Buffer, 00437 ACPI_SIZE *SpaceUsed) 00438 { 00439 ACPI_OBJECT *ExternalObject; 00440 ACPI_STATUS Status; 00441 ACPI_PKG_INFO Info; 00442 00443 00444 ACPI_FUNCTION_TRACE (UtCopyIpackageToEpackage); 00445 00446 00447 /* 00448 * First package at head of the buffer 00449 */ 00450 ExternalObject = ACPI_CAST_PTR (ACPI_OBJECT, Buffer); 00451 00452 /* 00453 * Free space begins right after the first package 00454 */ 00455 Info.Length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); 00456 Info.FreeSpace = Buffer + ACPI_ROUND_UP_TO_NATIVE_WORD ( 00457 sizeof (ACPI_OBJECT)); 00458 Info.ObjectSpace = 0; 00459 Info.NumPackages = 1; 00460 00461 ExternalObject->Type = InternalObject->Common.Type; 00462 ExternalObject->Package.Count = InternalObject->Package.Count; 00463 ExternalObject->Package.Elements = ACPI_CAST_PTR (ACPI_OBJECT, 00464 Info.FreeSpace); 00465 00466 /* 00467 * Leave room for an array of ACPI_OBJECTS in the buffer 00468 * and move the free space past it 00469 */ 00470 Info.Length += (ACPI_SIZE) ExternalObject->Package.Count * 00471 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); 00472 Info.FreeSpace += ExternalObject->Package.Count * 00473 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); 00474 00475 Status = AcpiUtWalkPackageTree (InternalObject, ExternalObject, 00476 AcpiUtCopyIelementToEelement, &Info); 00477 00478 *SpaceUsed = Info.Length; 00479 return_ACPI_STATUS (Status); 00480 } 00481 00482 00483 /******************************************************************************* 00484 * 00485 * FUNCTION: AcpiUtCopyIobjectToEobject 00486 * 00487 * PARAMETERS: InternalObject - The internal object to be converted 00488 * RetBuffer - Where the object is returned 00489 * 00490 * RETURN: Status 00491 * 00492 * DESCRIPTION: This function is called to build an API object to be returned 00493 * to the caller. 00494 * 00495 ******************************************************************************/ 00496 00497 ACPI_STATUS 00498 AcpiUtCopyIobjectToEobject ( 00499 ACPI_OPERAND_OBJECT *InternalObject, 00500 ACPI_BUFFER *RetBuffer) 00501 { 00502 ACPI_STATUS Status; 00503 00504 00505 ACPI_FUNCTION_TRACE (UtCopyIobjectToEobject); 00506 00507 00508 if (InternalObject->Common.Type == ACPI_TYPE_PACKAGE) 00509 { 00510 /* 00511 * Package object: Copy all subobjects (including 00512 * nested packages) 00513 */ 00514 Status = AcpiUtCopyIpackageToEpackage (InternalObject, 00515 RetBuffer->Pointer, &RetBuffer->Length); 00516 } 00517 else 00518 { 00519 /* 00520 * Build a simple object (no nested objects) 00521 */ 00522 Status = AcpiUtCopyIsimpleToEsimple (InternalObject, 00523 ACPI_CAST_PTR (ACPI_OBJECT, RetBuffer->Pointer), 00524 ACPI_ADD_PTR (UINT8, RetBuffer->Pointer, 00525 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))), 00526 &RetBuffer->Length); 00527 /* 00528 * build simple does not include the object size in the length 00529 * so we add it in here 00530 */ 00531 RetBuffer->Length += sizeof (ACPI_OBJECT); 00532 } 00533 00534 return_ACPI_STATUS (Status); 00535 } 00536 00537 00538 /******************************************************************************* 00539 * 00540 * FUNCTION: AcpiUtCopyEsimpleToIsimple 00541 * 00542 * PARAMETERS: ExternalObject - The external object to be converted 00543 * RetInternalObject - Where the internal object is returned 00544 * 00545 * RETURN: Status 00546 * 00547 * DESCRIPTION: This function copies an external object to an internal one. 00548 * NOTE: Pointers can be copied, we don't need to copy data. 00549 * (The pointers have to be valid in our address space no matter 00550 * what we do with them!) 00551 * 00552 ******************************************************************************/ 00553 00554 static ACPI_STATUS 00555 AcpiUtCopyEsimpleToIsimple ( 00556 ACPI_OBJECT *ExternalObject, 00557 ACPI_OPERAND_OBJECT **RetInternalObject) 00558 { 00559 ACPI_OPERAND_OBJECT *InternalObject; 00560 00561 00562 ACPI_FUNCTION_TRACE (UtCopyEsimpleToIsimple); 00563 00564 00565 /* 00566 * Simple types supported are: String, Buffer, Integer 00567 */ 00568 switch (ExternalObject->Type) 00569 { 00570 case ACPI_TYPE_STRING: 00571 case ACPI_TYPE_BUFFER: 00572 case ACPI_TYPE_INTEGER: 00573 case ACPI_TYPE_LOCAL_REFERENCE: 00574 00575 InternalObject = AcpiUtCreateInternalObject ( 00576 (UINT8) ExternalObject->Type); 00577 if (!InternalObject) 00578 { 00579 return_ACPI_STATUS (AE_NO_MEMORY); 00580 } 00581 break; 00582 00583 case ACPI_TYPE_ANY: /* This is the case for a NULL object */ 00584 00585 *RetInternalObject = NULL; 00586 return_ACPI_STATUS (AE_OK); 00587 00588 default: 00589 /* All other types are not supported */ 00590 00591 ACPI_ERROR ((AE_INFO, 00592 "Unsupported object type, cannot convert to internal object: %s", 00593 AcpiUtGetTypeName (ExternalObject->Type))); 00594 00595 return_ACPI_STATUS (AE_SUPPORT); 00596 } 00597 00598 00599 /* Must COPY string and buffer contents */ 00600 00601 switch (ExternalObject->Type) 00602 { 00603 case ACPI_TYPE_STRING: 00604 00605 InternalObject->String.Pointer = 00606 ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) 00607 ExternalObject->String.Length + 1); 00608 00609 if (!InternalObject->String.Pointer) 00610 { 00611 goto ErrorExit; 00612 } 00613 00614 ACPI_MEMCPY (InternalObject->String.Pointer, 00615 ExternalObject->String.Pointer, 00616 ExternalObject->String.Length); 00617 00618 InternalObject->String.Length = ExternalObject->String.Length; 00619 break; 00620 00621 00622 case ACPI_TYPE_BUFFER: 00623 00624 InternalObject->Buffer.Pointer = 00625 ACPI_ALLOCATE_ZEROED (ExternalObject->Buffer.Length); 00626 if (!InternalObject->Buffer.Pointer) 00627 { 00628 goto ErrorExit; 00629 } 00630 00631 ACPI_MEMCPY (InternalObject->Buffer.Pointer, 00632 ExternalObject->Buffer.Pointer, 00633 ExternalObject->Buffer.Length); 00634 00635 InternalObject->Buffer.Length = ExternalObject->Buffer.Length; 00636 00637 /* Mark buffer data valid */ 00638 00639 InternalObject->Buffer.Flags |= AOPOBJ_DATA_VALID; 00640 break; 00641 00642 00643 case ACPI_TYPE_INTEGER: 00644 00645 InternalObject->Integer.Value = ExternalObject->Integer.Value; 00646 break; 00647 00648 case ACPI_TYPE_LOCAL_REFERENCE: 00649 00650 /* TBD: should validate incoming handle */ 00651 00652 InternalObject->Reference.Class = ACPI_REFCLASS_NAME; 00653 InternalObject->Reference.Node = ExternalObject->Reference.Handle; 00654 break; 00655 00656 default: 00657 /* Other types can't get here */ 00658 break; 00659 } 00660 00661 *RetInternalObject = InternalObject; 00662 return_ACPI_STATUS (AE_OK); 00663 00664 00665 ErrorExit: 00666 AcpiUtRemoveReference (InternalObject); 00667 return_ACPI_STATUS (AE_NO_MEMORY); 00668 } 00669 00670 00671 /******************************************************************************* 00672 * 00673 * FUNCTION: AcpiUtCopyEpackageToIpackage 00674 * 00675 * PARAMETERS: ExternalObject - The external object to be converted 00676 * InternalObject - Where the internal object is returned 00677 * 00678 * RETURN: Status 00679 * 00680 * DESCRIPTION: Copy an external package object to an internal package. 00681 * Handles nested packages. 00682 * 00683 ******************************************************************************/ 00684 00685 static ACPI_STATUS 00686 AcpiUtCopyEpackageToIpackage ( 00687 ACPI_OBJECT *ExternalObject, 00688 ACPI_OPERAND_OBJECT **InternalObject) 00689 { 00690 ACPI_STATUS Status = AE_OK; 00691 ACPI_OPERAND_OBJECT *PackageObject; 00692 ACPI_OPERAND_OBJECT **PackageElements; 00693 UINT32 i; 00694 00695 00696 ACPI_FUNCTION_TRACE (UtCopyEpackageToIpackage); 00697 00698 00699 /* Create the package object */ 00700 00701 PackageObject = AcpiUtCreatePackageObject (ExternalObject->Package.Count); 00702 if (!PackageObject) 00703 { 00704 return_ACPI_STATUS (AE_NO_MEMORY); 00705 } 00706 00707 PackageElements = PackageObject->Package.Elements; 00708 00709 /* 00710 * Recursive implementation. Probably ok, since nested external packages 00711 * as parameters should be very rare. 00712 */ 00713 for (i = 0; i < ExternalObject->Package.Count; i++) 00714 { 00715 Status = AcpiUtCopyEobjectToIobject ( 00716 &ExternalObject->Package.Elements[i], 00717 &PackageElements[i]); 00718 if (ACPI_FAILURE (Status)) 00719 { 00720 /* Truncate package and delete it */ 00721 00722 PackageObject->Package.Count = i; 00723 PackageElements[i] = NULL; 00724 AcpiUtRemoveReference (PackageObject); 00725 return_ACPI_STATUS (Status); 00726 } 00727 } 00728 00729 /* Mark package data valid */ 00730 00731 PackageObject->Package.Flags |= AOPOBJ_DATA_VALID; 00732 00733 *InternalObject = PackageObject; 00734 return_ACPI_STATUS (Status); 00735 } 00736 00737 00738 /******************************************************************************* 00739 * 00740 * FUNCTION: AcpiUtCopyEobjectToIobject 00741 * 00742 * PARAMETERS: ExternalObject - The external object to be converted 00743 * InternalObject - Where the internal object is returned 00744 * 00745 * RETURN: Status 00746 * 00747 * DESCRIPTION: Converts an external object to an internal object. 00748 * 00749 ******************************************************************************/ 00750 00751 ACPI_STATUS 00752 AcpiUtCopyEobjectToIobject ( 00753 ACPI_OBJECT *ExternalObject, 00754 ACPI_OPERAND_OBJECT **InternalObject) 00755 { 00756 ACPI_STATUS Status; 00757 00758 00759 ACPI_FUNCTION_TRACE (UtCopyEobjectToIobject); 00760 00761 00762 if (ExternalObject->Type == ACPI_TYPE_PACKAGE) 00763 { 00764 Status = AcpiUtCopyEpackageToIpackage (ExternalObject, InternalObject); 00765 } 00766 else 00767 { 00768 /* 00769 * Build a simple object (no nested objects) 00770 */ 00771 Status = AcpiUtCopyEsimpleToIsimple (ExternalObject, InternalObject); 00772 } 00773 00774 return_ACPI_STATUS (Status); 00775 } 00776 00777 00778 /******************************************************************************* 00779 * 00780 * FUNCTION: AcpiUtCopySimpleObject 00781 * 00782 * PARAMETERS: SourceDesc - The internal object to be copied 00783 * DestDesc - New target object 00784 * 00785 * RETURN: Status 00786 * 00787 * DESCRIPTION: Simple copy of one internal object to another. Reference count 00788 * of the destination object is preserved. 00789 * 00790 ******************************************************************************/ 00791 00792 static ACPI_STATUS 00793 AcpiUtCopySimpleObject ( 00794 ACPI_OPERAND_OBJECT *SourceDesc, 00795 ACPI_OPERAND_OBJECT *DestDesc) 00796 { 00797 UINT16 ReferenceCount; 00798 ACPI_OPERAND_OBJECT *NextObject; 00799 ACPI_STATUS Status; 00800 ACPI_SIZE CopySize; 00801 00802 00803 /* Save fields from destination that we don't want to overwrite */ 00804 00805 ReferenceCount = DestDesc->Common.ReferenceCount; 00806 NextObject = DestDesc->Common.NextObject; 00807 00808 /* 00809 * Copy the entire source object over the destination object. 00810 * Note: Source can be either an operand object or namespace node. 00811 */ 00812 CopySize = sizeof (ACPI_OPERAND_OBJECT); 00813 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED) 00814 { 00815 CopySize = sizeof (ACPI_NAMESPACE_NODE); 00816 } 00817 00818 ACPI_MEMCPY (ACPI_CAST_PTR (char, DestDesc), 00819 ACPI_CAST_PTR (char, SourceDesc), CopySize); 00820 00821 /* Restore the saved fields */ 00822 00823 DestDesc->Common.ReferenceCount = ReferenceCount; 00824 DestDesc->Common.NextObject = NextObject; 00825 00826 /* New object is not static, regardless of source */ 00827 00828 DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER; 00829 00830 /* Handle the objects with extra data */ 00831 00832 switch (DestDesc->Common.Type) 00833 { 00834 case ACPI_TYPE_BUFFER: 00835 /* 00836 * Allocate and copy the actual buffer if and only if: 00837 * 1) There is a valid buffer pointer 00838 * 2) The buffer has a length > 0 00839 */ 00840 if ((SourceDesc->Buffer.Pointer) && 00841 (SourceDesc->Buffer.Length)) 00842 { 00843 DestDesc->Buffer.Pointer = 00844 ACPI_ALLOCATE (SourceDesc->Buffer.Length); 00845 if (!DestDesc->Buffer.Pointer) 00846 { 00847 return (AE_NO_MEMORY); 00848 } 00849 00850 /* Copy the actual buffer data */ 00851 00852 ACPI_MEMCPY (DestDesc->Buffer.Pointer, 00853 SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length); 00854 } 00855 break; 00856 00857 case ACPI_TYPE_STRING: 00858 /* 00859 * Allocate and copy the actual string if and only if: 00860 * 1) There is a valid string pointer 00861 * (Pointer to a NULL string is allowed) 00862 */ 00863 if (SourceDesc->String.Pointer) 00864 { 00865 DestDesc->String.Pointer = 00866 ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1); 00867 if (!DestDesc->String.Pointer) 00868 { 00869 return (AE_NO_MEMORY); 00870 } 00871 00872 /* Copy the actual string data */ 00873 00874 ACPI_MEMCPY (DestDesc->String.Pointer, SourceDesc->String.Pointer, 00875 (ACPI_SIZE) SourceDesc->String.Length + 1); 00876 } 00877 break; 00878 00879 case ACPI_TYPE_LOCAL_REFERENCE: 00880 /* 00881 * We copied the reference object, so we now must add a reference 00882 * to the object pointed to by the reference 00883 * 00884 * DDBHandle reference (from Load/LoadTable) is a special reference, 00885 * it does not have a Reference.Object, so does not need to 00886 * increase the reference count 00887 */ 00888 if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE) 00889 { 00890 break; 00891 } 00892 00893 AcpiUtAddReference (SourceDesc->Reference.Object); 00894 break; 00895 00896 case ACPI_TYPE_REGION: 00897 /* 00898 * We copied the Region Handler, so we now must add a reference 00899 */ 00900 if (DestDesc->Region.Handler) 00901 { 00902 AcpiUtAddReference (DestDesc->Region.Handler); 00903 } 00904 break; 00905 00906 /* 00907 * For Mutex and Event objects, we cannot simply copy the underlying 00908 * OS object. We must create a new one. 00909 */ 00910 case ACPI_TYPE_MUTEX: 00911 00912 Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex); 00913 if (ACPI_FAILURE (Status)) 00914 { 00915 return (Status); 00916 } 00917 break; 00918 00919 case ACPI_TYPE_EVENT: 00920 00921 Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0, 00922 &DestDesc->Event.OsSemaphore); 00923 if (ACPI_FAILURE (Status)) 00924 { 00925 return (Status); 00926 } 00927 break; 00928 00929 default: 00930 /* Nothing to do for other simple objects */ 00931 break; 00932 } 00933 00934 return (AE_OK); 00935 } 00936 00937 00938 /******************************************************************************* 00939 * 00940 * FUNCTION: AcpiUtCopyIelementToIelement 00941 * 00942 * PARAMETERS: ACPI_PKG_CALLBACK 00943 * 00944 * RETURN: Status 00945 * 00946 * DESCRIPTION: Copy one package element to another package element 00947 * 00948 ******************************************************************************/ 00949 00950 static ACPI_STATUS 00951 AcpiUtCopyIelementToIelement ( 00952 UINT8 ObjectType, 00953 ACPI_OPERAND_OBJECT *SourceObject, 00954 ACPI_GENERIC_STATE *State, 00955 void *Context) 00956 { 00957 ACPI_STATUS Status = AE_OK; 00958 UINT32 ThisIndex; 00959 ACPI_OPERAND_OBJECT **ThisTargetPtr; 00960 ACPI_OPERAND_OBJECT *TargetObject; 00961 00962 00963 ACPI_FUNCTION_ENTRY (); 00964 00965 00966 ThisIndex = State->Pkg.Index; 00967 ThisTargetPtr = (ACPI_OPERAND_OBJECT **) 00968 &State->Pkg.DestObject->Package.Elements[ThisIndex]; 00969 00970 switch (ObjectType) 00971 { 00972 case ACPI_COPY_TYPE_SIMPLE: 00973 00974 /* A null source object indicates a (legal) null package element */ 00975 00976 if (SourceObject) 00977 { 00978 /* 00979 * This is a simple object, just copy it 00980 */ 00981 TargetObject = AcpiUtCreateInternalObject ( 00982 SourceObject->Common.Type); 00983 if (!TargetObject) 00984 { 00985 return (AE_NO_MEMORY); 00986 } 00987 00988 Status = AcpiUtCopySimpleObject (SourceObject, TargetObject); 00989 if (ACPI_FAILURE (Status)) 00990 { 00991 goto ErrorExit; 00992 } 00993 00994 *ThisTargetPtr = TargetObject; 00995 } 00996 else 00997 { 00998 /* Pass through a null element */ 00999 01000 *ThisTargetPtr = NULL; 01001 } 01002 break; 01003 01004 01005 case ACPI_COPY_TYPE_PACKAGE: 01006 01007 /* 01008 * This object is a package - go down another nesting level 01009 * Create and build the package object 01010 */ 01011 TargetObject = AcpiUtCreatePackageObject (SourceObject->Package.Count); 01012 if (!TargetObject) 01013 { 01014 return (AE_NO_MEMORY); 01015 } 01016 01017 TargetObject->Common.Flags = SourceObject->Common.Flags; 01018 01019 /* Pass the new package object back to the package walk routine */ 01020 01021 State->Pkg.ThisTargetObj = TargetObject; 01022 01023 /* Store the object pointer in the parent package object */ 01024 01025 *ThisTargetPtr = TargetObject; 01026 break; 01027 01028 01029 default: 01030 return (AE_BAD_PARAMETER); 01031 } 01032 01033 return (Status); 01034 01035 ErrorExit: 01036 AcpiUtRemoveReference (TargetObject); 01037 return (Status); 01038 } 01039 01040 01041 /******************************************************************************* 01042 * 01043 * FUNCTION: AcpiUtCopyIpackageToIpackage 01044 * 01045 * PARAMETERS: SourceObj - Pointer to the source package object 01046 * DestObj - Where the internal object is returned 01047 * WalkState - Current Walk state descriptor 01048 * 01049 * RETURN: Status 01050 * 01051 * DESCRIPTION: This function is called to copy an internal package object 01052 * into another internal package object. 01053 * 01054 ******************************************************************************/ 01055 01056 static ACPI_STATUS 01057 AcpiUtCopyIpackageToIpackage ( 01058 ACPI_OPERAND_OBJECT *SourceObj, 01059 ACPI_OPERAND_OBJECT *DestObj, 01060 ACPI_WALK_STATE *WalkState) 01061 { 01062 ACPI_STATUS Status = AE_OK; 01063 01064 01065 ACPI_FUNCTION_TRACE (UtCopyIpackageToIpackage); 01066 01067 01068 DestObj->Common.Type = SourceObj->Common.Type; 01069 DestObj->Common.Flags = SourceObj->Common.Flags; 01070 DestObj->Package.Count = SourceObj->Package.Count; 01071 01072 /* 01073 * Create the object array and walk the source package tree 01074 */ 01075 DestObj->Package.Elements = ACPI_ALLOCATE_ZEROED ( 01076 ((ACPI_SIZE) SourceObj->Package.Count + 1) * 01077 sizeof (void *)); 01078 if (!DestObj->Package.Elements) 01079 { 01080 ACPI_ERROR ((AE_INFO, "Package allocation failure")); 01081 return_ACPI_STATUS (AE_NO_MEMORY); 01082 } 01083 01084 /* 01085 * Copy the package element-by-element by walking the package "tree". 01086 * This handles nested packages of arbitrary depth. 01087 */ 01088 Status = AcpiUtWalkPackageTree (SourceObj, DestObj, 01089 AcpiUtCopyIelementToIelement, WalkState); 01090 if (ACPI_FAILURE (Status)) 01091 { 01092 /* On failure, delete the destination package object */ 01093 01094 AcpiUtRemoveReference (DestObj); 01095 } 01096 01097 return_ACPI_STATUS (Status); 01098 } 01099 01100 01101 /******************************************************************************* 01102 * 01103 * FUNCTION: AcpiUtCopyIobjectToIobject 01104 * 01105 * PARAMETERS: SourceDesc - The internal object to be copied 01106 * DestDesc - Where the copied object is returned 01107 * WalkState - Current walk state 01108 * 01109 * RETURN: Status 01110 * 01111 * DESCRIPTION: Copy an internal object to a new internal object 01112 * 01113 ******************************************************************************/ 01114 01115 ACPI_STATUS 01116 AcpiUtCopyIobjectToIobject ( 01117 ACPI_OPERAND_OBJECT *SourceDesc, 01118 ACPI_OPERAND_OBJECT **DestDesc, 01119 ACPI_WALK_STATE *WalkState) 01120 { 01121 ACPI_STATUS Status = AE_OK; 01122 01123 01124 ACPI_FUNCTION_TRACE (UtCopyIobjectToIobject); 01125 01126 01127 /* Create the top level object */ 01128 01129 *DestDesc = AcpiUtCreateInternalObject (SourceDesc->Common.Type); 01130 if (!*DestDesc) 01131 { 01132 return_ACPI_STATUS (AE_NO_MEMORY); 01133 } 01134 01135 /* Copy the object and possible subobjects */ 01136 01137 if (SourceDesc->Common.Type == ACPI_TYPE_PACKAGE) 01138 { 01139 Status = AcpiUtCopyIpackageToIpackage (SourceDesc, *DestDesc, 01140 WalkState); 01141 } 01142 else 01143 { 01144 Status = AcpiUtCopySimpleObject (SourceDesc, *DestDesc); 01145 } 01146 01147 return_ACPI_STATUS (Status); 01148 } 01149 01150 Generated on Sat May 26 2012 04:25:57 for ReactOS by
1.7.6.1
|