Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: utownerid - Support for Table/Method Owner IDs
  4.  *
  5.  ******************************************************************************/
  6.  
  7. /*
  8.  * Copyright (C) 2000 - 2015, Intel Corp.
  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 "accommon.h"
  46. #include "acnamesp.h"
  47.  
  48. #define _COMPONENT          ACPI_UTILITIES
  49. ACPI_MODULE_NAME("utownerid")
  50.  
  51. /*******************************************************************************
  52.  *
  53.  * FUNCTION:    acpi_ut_allocate_owner_id
  54.  *
  55.  * PARAMETERS:  owner_id        - Where the new owner ID is returned
  56.  *
  57.  * RETURN:      Status
  58.  *
  59.  * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
  60.  *              track objects created by the table or method, to be deleted
  61.  *              when the method exits or the table is unloaded.
  62.  *
  63.  ******************************************************************************/
  64. acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
  65. {
  66.         u32 i;
  67.         u32 j;
  68.         u32 k;
  69.         acpi_status status;
  70.  
  71.         ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
  72.  
  73.         /* Guard against multiple allocations of ID to the same location */
  74.  
  75.         if (*owner_id) {
  76.                 ACPI_ERROR((AE_INFO, "Owner ID [0x%2.2X] already exists",
  77.                             *owner_id));
  78.                 return_ACPI_STATUS(AE_ALREADY_EXISTS);
  79.         }
  80.  
  81.         /* Mutex for the global ID mask */
  82.  
  83.         status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
  84.         if (ACPI_FAILURE(status)) {
  85.                 return_ACPI_STATUS(status);
  86.         }
  87.  
  88.         /*
  89.          * Find a free owner ID, cycle through all possible IDs on repeated
  90.          * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
  91.          * to be scanned twice.
  92.          */
  93.         for (i = 0, j = acpi_gbl_last_owner_id_index;
  94.              i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
  95.                 if (j >= ACPI_NUM_OWNERID_MASKS) {
  96.                         j = 0;  /* Wraparound to start of mask array */
  97.                 }
  98.  
  99.                 for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
  100.                         if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
  101.  
  102.                                 /* There are no free IDs in this mask */
  103.  
  104.                                 break;
  105.                         }
  106.  
  107.                         if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
  108.                                 /*
  109.                                  * Found a free ID. The actual ID is the bit index plus one,
  110.                                  * making zero an invalid Owner ID. Save this as the last ID
  111.                                  * allocated and update the global ID mask.
  112.                                  */
  113.                                 acpi_gbl_owner_id_mask[j] |= (1 << k);
  114.  
  115.                                 acpi_gbl_last_owner_id_index = (u8)j;
  116.                                 acpi_gbl_next_owner_id_offset = (u8)(k + 1);
  117.  
  118.                                 /*
  119.                                  * Construct encoded ID from the index and bit position
  120.                                  *
  121.                                  * Note: Last [j].k (bit 255) is never used and is marked
  122.                                  * permanently allocated (prevents +1 overflow)
  123.                                  */
  124.                                 *owner_id =
  125.                                     (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));
  126.  
  127.                                 ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
  128.                                                   "Allocated OwnerId: %2.2X\n",
  129.                                                   (unsigned int)*owner_id));
  130.                                 goto exit;
  131.                         }
  132.                 }
  133.  
  134.                 acpi_gbl_next_owner_id_offset = 0;
  135.         }
  136.  
  137.         /*
  138.          * All owner_ids have been allocated. This typically should
  139.          * not happen since the IDs are reused after deallocation. The IDs are
  140.          * allocated upon table load (one per table) and method execution, and
  141.          * they are released when a table is unloaded or a method completes
  142.          * execution.
  143.          *
  144.          * If this error happens, there may be very deep nesting of invoked control
  145.          * methods, or there may be a bug where the IDs are not released.
  146.          */
  147.         status = AE_OWNER_ID_LIMIT;
  148.         ACPI_ERROR((AE_INFO,
  149.                     "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
  150.  
  151. exit:
  152.         (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
  153.         return_ACPI_STATUS(status);
  154. }
  155.  
  156. /*******************************************************************************
  157.  *
  158.  * FUNCTION:    acpi_ut_release_owner_id
  159.  *
  160.  * PARAMETERS:  owner_id_ptr        - Pointer to a previously allocated owner_ID
  161.  *
  162.  * RETURN:      None. No error is returned because we are either exiting a
  163.  *              control method or unloading a table. Either way, we would
  164.  *              ignore any error anyway.
  165.  *
  166.  * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
  167.  *
  168.  ******************************************************************************/
  169.  
  170. void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
  171. {
  172.         acpi_owner_id owner_id = *owner_id_ptr;
  173.         acpi_status status;
  174.         u32 index;
  175.         u32 bit;
  176.  
  177.         ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
  178.  
  179.         /* Always clear the input owner_id (zero is an invalid ID) */
  180.  
  181.         *owner_id_ptr = 0;
  182.  
  183.         /* Zero is not a valid owner_ID */
  184.  
  185.         if (owner_id == 0) {
  186.                 ACPI_ERROR((AE_INFO, "Invalid OwnerId: 0x%2.2X", owner_id));
  187.                 return_VOID;
  188.         }
  189.  
  190.         /* Mutex for the global ID mask */
  191.  
  192.         status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
  193.         if (ACPI_FAILURE(status)) {
  194.                 return_VOID;
  195.         }
  196.  
  197.         /* Normalize the ID to zero */
  198.  
  199.         owner_id--;
  200.  
  201.         /* Decode ID to index/offset pair */
  202.  
  203.         index = ACPI_DIV_32(owner_id);
  204.         bit = 1 << ACPI_MOD_32(owner_id);
  205.  
  206.         /* Free the owner ID only if it is valid */
  207.  
  208.         if (acpi_gbl_owner_id_mask[index] & bit) {
  209.                 acpi_gbl_owner_id_mask[index] ^= bit;
  210.         } else {
  211.                 ACPI_ERROR((AE_INFO,
  212.                             "Release of non-allocated OwnerId: 0x%2.2X",
  213.                             owner_id + 1));
  214.         }
  215.  
  216.         (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
  217.         return_VOID;
  218. }
  219.