CTC++ Coverage Report - Execution Profile    #272/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/acpi/utilities/utcopy.c
Instrumentation mode: function-decision-multicondition
TER: 38 % ( 49/130)

Start/ End/    
True False - Line Source

  1 /******************************************************************************
  2  *
  3  * Module Name: utcopy - Internal to external object translation utilities
  4  *
  5  *****************************************************************************/
  6 
  7 /*
  8  * Copyright (C) 2000 - 2006, R. Byron Moore
  9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 #include <acpi/acpi.h>
  45 #include <acpi/amlcode.h>
  46 
  47 #define _COMPONENT          ACPI_UTILITIES
  48 ACPI_MODULE_NAME("utcopy")
  49 
  50 /* Local prototypes */
  51 static acpi_status
  52 acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
  53             union acpi_object *external_object,
  54             u8 * data_space, acpi_size * buffer_space_used);
  55 
  56 static acpi_status
  57 acpi_ut_copy_ielement_to_ielement(u8 object_type,
  58               union acpi_operand_object *source_object,
  59               union acpi_generic_state *state,
  60               void *context);
  61 
  62 static acpi_status
  63 acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
  64               u8 * buffer, acpi_size * space_used);
  65 
  66 static acpi_status
  67 acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,
  68             union acpi_operand_object **return_obj);
  69 
  70 static acpi_status
  71 acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
  72             union acpi_operand_object *dest_desc);
  73 
  74 static acpi_status
  75 acpi_ut_copy_ielement_to_eelement(u8 object_type,
  76               union acpi_operand_object *source_object,
  77               union acpi_generic_state *state,
  78               void *context);
  79 
  80 static acpi_status
  81 acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
  82               union acpi_operand_object *dest_obj,
  83               struct acpi_walk_state *walk_state);
  84 
  85 /*******************************************************************************
  86  *
  87  * FUNCTION:    acpi_ut_copy_isimple_to_esimple
  88  *
  89  * PARAMETERS:  internal_object     - Source object to be copied
  90  *              external_object     - Where to return the copied object
  91  *              data_space          - Where object data is returned (such as
  92  *                                    buffer and string data)
  93  *              buffer_space_used   - Length of data_space that was used
  94  *
  95  * RETURN:      Status
  96  *
  97  * DESCRIPTION: This function is called to copy a simple internal object to
  98  *              an external object.
  99  *
  100  *              The data_space buffer is assumed to have sufficient space for
  101  *              the object.
  102  *
  103  ******************************************************************************/
  104 
  105 static acpi_status
 
1070   106 acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
  107             union acpi_object *external_object,
  108             u8 * data_space, acpi_size * buffer_space_used)
  109 {
  110    acpi_status status = AE_OK;
  111 
  112    ACPI_FUNCTION_TRACE("ut_copy_isimple_to_esimple");
  113 
  114    *buffer_space_used = 0;
  115 
  116    /*
  117     * Check for NULL object case (could be an uninitialized
  118     * package element)
  119     */
1070 - 120    if (!internal_object) {
 - 121       return_ACPI_STATUS(AE_OK);
  122    }
  123 
  124    /* Always clear the external object */
  125 
  126    ACPI_MEMSET(external_object, 0, sizeof(union acpi_object));
  127 
  128    /*
  129     * In general, the external object will be the same type as
  130     * the internal object
  131     */
  132    external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
  133 
  134    /* However, only a limited number of external types are supported */
  135 
    136    switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
 - 137    case ACPI_TYPE_STRING:
  138 
  139       external_object->string.pointer = (char *)data_space;
  140       external_object->string.length = internal_object->string.length;
  141       *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
  142                           internal_object->
  143                           string.
  144                           length + 1);
  145 
  146       ACPI_MEMCPY((void *)data_space,
  147              (void *)internal_object->string.pointer,
  148              (acpi_size) internal_object->string.length + 1);
 - 149       break;
  150 
36    151    case ACPI_TYPE_BUFFER:
  152 
  153       external_object->buffer.pointer = data_space;
  154       external_object->buffer.length = internal_object->buffer.length;
  155       *buffer_space_used =
  156           ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string.
  157                    length);
  158 
  159       ACPI_MEMCPY((void *)data_space,
  160              (void *)internal_object->buffer.pointer,
  161              internal_object->buffer.length);
36    162       break;
  163 
1022    164    case ACPI_TYPE_INTEGER:
  165 
  166       external_object->integer.value = internal_object->integer.value;
1022    167       break;
  168 
   169    case ACPI_TYPE_LOCAL_REFERENCE:
  170 
  171       /*
  172        * This is an object reference.  Attempt to dereference it.
  173        */
    174       switch (internal_object->reference.opcode) {
   175       case AML_INT_NAMEPATH_OP:
  176 
  177          /* For namepath, return the object handle ("reference") */
  178 
 - 179       default:
  180          /*
  181           * Use the object type of "Any" to indicate a reference
  182           * to object containing a handle to an ACPI named object.
  183           */
  184          external_object->type = ACPI_TYPE_ANY;
  185          external_object->reference.handle =
  186              internal_object->reference.node;
   187          break;
  188       }
   189       break;
  190 
   191    case ACPI_TYPE_PROCESSOR:
  192 
  193       external_object->processor.proc_id =
  194           internal_object->processor.proc_id;
  195       external_object->processor.pblk_address =
  196           internal_object->processor.address;
  197       external_object->processor.pblk_length =
  198           internal_object->processor.length;
   199       break;
  200 
 - 201    case ACPI_TYPE_POWER:
  202 
  203       external_object->power_resource.system_level =
  204           internal_object->power_resource.system_level;
  205 
  206       external_object->power_resource.resource_order =
  207           internal_object->power_resource.resource_order;
 - 208       break;
  209 
 - 210    default:
  211       /*
  212        * There is no corresponding external object type
  213        */
 - 214       return_ACPI_STATUS(AE_SUPPORT);
  215    }
  216 
1070    217    return_ACPI_STATUS(status);
  218 }
  219 
  220 /*******************************************************************************
  221  *
  222  * FUNCTION:    acpi_ut_copy_ielement_to_eelement
  223  *
  224  * PARAMETERS:  acpi_pkg_callback
  225  *
  226  * RETURN:      Status
  227  *
  228  * DESCRIPTION: Copy one package element to another package element
  229  *
  230  ******************************************************************************/
  231 
  232 static acpi_status
 
312   233 acpi_ut_copy_ielement_to_eelement(u8 object_type,
  234               union acpi_operand_object *source_object,
  235               union acpi_generic_state *state,
  236               void *context)
  237 {
  238    acpi_status status = AE_OK;
  239    struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
  240    acpi_size object_space;
  241    u32 this_index;
  242    union acpi_object *target_object;
  243 
  244    ACPI_FUNCTION_ENTRY();
  245 
  246    this_index = state->pkg.index;
  247    target_object = (union acpi_object *)
  248        &((union acpi_object *)(state->pkg.dest_object))->package.
  249        elements[this_index];
  250 
    251    switch (object_type) {
294    252    case ACPI_COPY_TYPE_SIMPLE:
  253 
  254       /*
  255        * This is a simple or null object
  256        */
  257       status = acpi_ut_copy_isimple_to_esimple(source_object,
  258                       target_object,
  259                       info->free_space,
  260                       &object_space);
294 - 261       if (ACPI_FAILURE(status)) {
 - 262          return (status);
  263       }
294    264       break;
  265 
18    266    case ACPI_COPY_TYPE_PACKAGE:
  267 
  268       /*
  269        * Build the package object
  270        */
  271       target_object->type = ACPI_TYPE_PACKAGE;
  272       target_object->package.count = source_object->package.count;
  273       target_object->package.elements =
  274           ACPI_CAST_PTR(union acpi_object, info->free_space);
  275 
  276       /*
  277        * Pass the new package object back to the package walk routine
  278        */
  279       state->pkg.this_target_obj = target_object;
  280 
  281       /*
  282        * Save space for the array of objects (Package elements)
  283        * update the buffer length counter
  284        */
  285       object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
  286                          target_object->
  287                          package.count *
  288                          sizeof(union
  289                            acpi_object));
18    290       break;
  291 
 - 292    default:
 - 293       return (AE_BAD_PARAMETER);
  294    }
  295 
  296    info->free_space += object_space;
  297    info->length += object_space;
312    298    return (status);
  299 }
  300 
  301 /*******************************************************************************
  302  *
  303  * FUNCTION:    acpi_ut_copy_ipackage_to_epackage
  304  *
  305  * PARAMETERS:  internal_object     - Pointer to the object we are returning
  306  *              Buffer              - Where the object is returned
  307  *              space_used          - Where the object length is returned
  308  *
  309  * RETURN:      Status
  310  *
  311  * DESCRIPTION: This function is called to place a package object in a user
  312  *              buffer.  A package object by definition contains other objects.
  313  *
  314  *              The buffer is assumed to have sufficient space for the object.
  315  *              The caller must have verified the buffer length needed using the
  316  *              acpi_ut_get_object_size function before calling this function.
  317  *
  318  ******************************************************************************/
  319 
  320 static acpi_status
 
66   321 acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
  322               u8 * buffer, acpi_size * space_used)
  323 {
  324    union acpi_object *external_object;
  325    acpi_status status;
  326    struct acpi_pkg_info info;
  327 
  328    ACPI_FUNCTION_TRACE("ut_copy_ipackage_to_epackage");
  329 
  330    /*
  331     * First package at head of the buffer
  332     */
  333    external_object = ACPI_CAST_PTR(union acpi_object, buffer);
  334 
  335    /*
  336     * Free space begins right after the first package
  337     */
  338    info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  339    info.free_space =
  340        buffer + ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  341    info.object_space = 0;
  342    info.num_packages = 1;
  343 
  344    external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
  345    external_object->package.count = internal_object->package.count;
  346    external_object->package.elements = ACPI_CAST_PTR(union acpi_object,
  347                        info.free_space);
  348 
  349    /*
  350     * Leave room for an array of ACPI_OBJECTS in the buffer
  351     * and move the free space past it
  352     */
  353    info.length += (acpi_size) external_object->package.count *
  354        ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  355    info.free_space += external_object->package.count *
  356        ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  357 
  358    status = acpi_ut_walk_package_tree(internal_object, external_object,
  359                   acpi_ut_copy_ielement_to_eelement,
  360                   &info);
  361 
  362    *space_used = info.length;
66    363    return_ACPI_STATUS(status);
  364 }
  365 
  366 /*******************************************************************************
  367  *
  368  * FUNCTION:    acpi_ut_copy_iobject_to_eobject
  369  *
  370  * PARAMETERS:  internal_object     - The internal object to be converted
  371  *              buffer_ptr          - Where the object is returned
  372  *
  373  * RETURN:      Status
  374  *
  375  * DESCRIPTION: This function is called to build an API object to be returned to
  376  *              the caller.
  377  *
  378  ******************************************************************************/
  379 
  380 acpi_status
 
842   381 acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
  382             struct acpi_buffer *ret_buffer)
  383 {
  384    acpi_status status;
  385 
  386    ACPI_FUNCTION_TRACE("ut_copy_iobject_to_eobject");
  387 
66 776   388    if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) {
  389       /*
  390        * Package object:  Copy all subobjects (including
  391        * nested packages)
  392        */
  393       status = acpi_ut_copy_ipackage_to_epackage(internal_object,
  394                         ret_buffer->pointer,
  395                         &ret_buffer->length);
    396    } else {
  397       /*
  398        * Build a simple object (no nested objects)
  399        */
  400       status = acpi_ut_copy_isimple_to_esimple(internal_object,
  401                       ACPI_CAST_PTR(union
  402                                acpi_object,
  403                                ret_buffer->
  404                                pointer),
  405                       ACPI_ADD_PTR(u8,
  406                               ret_buffer->
  407                               pointer,
  408                               ACPI_ROUND_UP_TO_NATIVE_WORD
  409                               (sizeof
  410                                (union
  411                            acpi_object))),
  412                       &ret_buffer->length);
  413       /*
  414        * build simple does not include the object size in the length
  415        * so we add it in here
  416        */
  417       ret_buffer->length += sizeof(union acpi_object);
  418    }
  419 
842    420    return_ACPI_STATUS(status);
  421 }
  422 
  423 /*******************************************************************************
  424  *
  425  * FUNCTION:    acpi_ut_copy_esimple_to_isimple
  426  *
  427  * PARAMETERS:  external_object     - The external object to be converted
  428  *              ret_internal_object - Where the internal object is returned
  429  *
  430  * RETURN:      Status
  431  *
  432  * DESCRIPTION: This function copies an external object to an internal one.
  433  *              NOTE: Pointers can be copied, we don't need to copy data.
  434  *              (The pointers have to be valid in our address space no matter
  435  *              what we do with them!)
  436  *
  437  ******************************************************************************/
  438 
  439 static acpi_status
 
12   440 acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
  441             union acpi_operand_object **ret_internal_object)
  442 {
  443    union acpi_operand_object *internal_object;
  444 
  445    ACPI_FUNCTION_TRACE("ut_copy_esimple_to_isimple");
  446 
  447    /*
  448     * Simple types supported are: String, Buffer, Integer
  449     */
    450    switch (external_object->type) {
 - 451    case ACPI_TYPE_STRING:
 - 452    case ACPI_TYPE_BUFFER:
12    453    case ACPI_TYPE_INTEGER:
  454 
  455       internal_object = acpi_ut_create_internal_object((u8)
  456                          external_object->
  457                          type);
12 - 458       if (!internal_object) {
 - 459          return_ACPI_STATUS(AE_NO_MEMORY);
  460       }
12    461       break;
  462 
 - 463    default:
  464       /* All other types are not supported */
  465 
 - 466       return_ACPI_STATUS(AE_SUPPORT);
  467    }
  468 
  469    /* Must COPY string and buffer contents */
  470 
    471    switch (external_object->type) {
 - 472    case ACPI_TYPE_STRING:
  473 
  474       internal_object->string.pointer =
  475           ACPI_MEM_CALLOCATE((acpi_size) external_object->string.
  476                    length + 1);
- 477       if (!internal_object->string.pointer) {
 - 478          goto error_exit;
  479       }
  480 
  481       ACPI_MEMCPY(internal_object->string.pointer,
  482              external_object->string.pointer,
  483              external_object->string.length);
  484 
  485       internal_object->string.length = external_object->string.length;
 - 486       break;
  487 
 - 488    case ACPI_TYPE_BUFFER:
  489 
  490       internal_object->buffer.pointer =
  491           ACPI_MEM_CALLOCATE(external_object->buffer.length);
- 492       if (!internal_object->buffer.pointer) {
 - 493          goto error_exit;
  494       }
  495 
  496       ACPI_MEMCPY(internal_object->buffer.pointer,
  497              external_object->buffer.pointer,
  498              external_object->buffer.length);
  499 
  500       internal_object->buffer.length = external_object->buffer.length;
 - 501       break;
  502 
12    503    case ACPI_TYPE_INTEGER:
  504 
  505       internal_object->integer.value = external_object->integer.value;
12    506       break;
  507 
 - 508    default:
  509       /* Other types can't get here */
 - 510       break;
  511    }
  512 
  513    *ret_internal_object = internal_object;
12    514    return_ACPI_STATUS(AE_OK);
  515 
  516       error_exit:
  517    acpi_ut_remove_reference(internal_object);
 - 518    return_ACPI_STATUS(AE_NO_MEMORY);
  519 }
  520 
  521 #ifdef ACPI_FUTURE_IMPLEMENTATION
  522 /* Code to convert packages that are parameters to control methods */
  523 
  524 /*******************************************************************************
  525  *
  526  * FUNCTION:    acpi_ut_copy_epackage_to_ipackage
  527  *
  528  * PARAMETERS:  *internal_object   - Pointer to the object we are returning
  529  *              *Buffer            - Where the object is returned
  530  *              *space_used        - Where the length of the object is returned
  531  *
  532  * RETURN:      Status
  533  *
  534  * DESCRIPTION: This function is called to place a package object in a user
  535  *              buffer.  A package object by definition contains other objects.
  536  *
  537  *              The buffer is assumed to have sufficient space for the object.
  538  *              The caller must have verified the buffer length needed using the
  539  *              acpi_ut_get_object_size function before calling this function.
  540  *
  541  ******************************************************************************/
  542 
  543 static acpi_status
  544 acpi_ut_copy_epackage_to_ipackage(union acpi_operand_object *internal_object,
  545               u8 * buffer, u32 * space_used)
  546 {
  547    u8 *free_space;
  548    union acpi_object *external_object;
  549    u32 length = 0;
  550    u32 this_index;
  551    u32 object_space = 0;
  552