[ACPI] ACPICA 20060113
[sfrench/cifs-2.6.git] / drivers / acpi / utilities / utmisc.c
index 0c5abc536c7ad1deb1f7db7e55c410ccf289a591..a77ffcd5570f5e7549b31bb358ac08020f2b8512 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,6 +63,8 @@ ACPI_MODULE_NAME("utmisc")
 acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
 {
        acpi_native_uint i;
+       acpi_native_uint j;
+       acpi_native_uint k;
        acpi_status status;
 
        ACPI_FUNCTION_TRACE("ut_allocate_owner_id");
@@ -82,31 +84,66 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
                return_ACPI_STATUS(status);
        }
 
-       /* Find a free owner ID */
+       /*
+        * Find a free owner ID, cycle through all possible IDs on repeated
+        * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
+        * to be scanned twice.
+        */
+       for (i = 0, j = acpi_gbl_last_owner_id_index;
+            i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
+               if (j >= ACPI_NUM_OWNERID_MASKS) {
+                       j = 0;  /* Wraparound to start of mask array */
+               }
+
+               for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
+                       if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
+                               /* There are no free IDs in this mask */
+
+                               break;
+                       }
+
+                       if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
+                               /*
+                                * Found a free ID. The actual ID is the bit index plus one,
+                                * making zero an invalid Owner ID. Save this as the last ID
+                                * allocated and update the global ID mask.
+                                */
+                               acpi_gbl_owner_id_mask[j] |= (1 << k);
+
+                               acpi_gbl_last_owner_id_index = (u8) j;
+                               acpi_gbl_next_owner_id_offset = (u8) (k + 1);
 
-       for (i = 0; i < 32; i++) {
-               if (!(acpi_gbl_owner_id_mask & (1 << i))) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
-                                         "Current owner_id mask: %8.8X New ID: %2.2X\n",
-                                         acpi_gbl_owner_id_mask,
-                                         (unsigned int)(i + 1)));
+                               /*
+                                * Construct encoded ID from the index and bit position
+                                *
+                                * Note: Last [j].k (bit 255) is never used and is marked
+                                * permanently allocated (prevents +1 overflow)
+                                */
+                               *owner_id =
+                                   (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));
 
-                       acpi_gbl_owner_id_mask |= (1 << i);
-                       *owner_id = (acpi_owner_id) (i + 1);
-                       goto exit;
+                               ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
+                                                 "Allocated owner_id: %2.2X\n",
+                                                 (unsigned int)*owner_id));
+                               goto exit;
+                       }
                }
+
+               acpi_gbl_next_owner_id_offset = 0;
        }
 
        /*
-        * If we are here, all owner_ids have been allocated. This probably should
+        * All owner_ids have been allocated. This typically should
         * not happen since the IDs are reused after deallocation. The IDs are
         * allocated upon table load (one per table) and method execution, and
         * they are released when a table is unloaded or a method completes
         * execution.
+        *
+        * If this error happens, there may be very deep nesting of invoked control
+        * methods, or there may be a bug where the IDs are not released.
         */
-       *owner_id = 0;
        status = AE_OWNER_ID_LIMIT;
-       ACPI_REPORT_ERROR(("Could not allocate new owner_id (32 max), AE_OWNER_ID_LIMIT\n"));
+       ACPI_REPORT_ERROR(("Could not allocate new owner_id (255 max), AE_OWNER_ID_LIMIT\n"));
 
       exit:
        (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
@@ -123,7 +160,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
  *              control method or unloading a table. Either way, we would
  *              ignore any error anyway.
  *
- * DESCRIPTION: Release a table or method owner ID.  Valid IDs are 1 - 32
+ * DESCRIPTION: Release a table or method owner ID.  Valid IDs are 1 - 255
  *
  ******************************************************************************/
 
@@ -131,6 +168,8 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
 {
        acpi_owner_id owner_id = *owner_id_ptr;
        acpi_status status;
+       acpi_native_uint index;
+       u32 bit;
 
        ACPI_FUNCTION_TRACE_U32("ut_release_owner_id", owner_id);
 
@@ -140,7 +179,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
 
        /* Zero is not a valid owner_iD */
 
-       if ((owner_id == 0) || (owner_id > 32)) {
+       if (owner_id == 0) {
                ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id));
                return_VOID;
        }
@@ -156,10 +195,18 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
 
        owner_id--;
 
+       /* Decode ID to index/offset pair */
+
+       index = ACPI_DIV_32(owner_id);
+       bit = 1 << ACPI_MOD_32(owner_id);
+
        /* Free the owner ID only if it is valid */
 
-       if (acpi_gbl_owner_id_mask & (1 << owner_id)) {
-               acpi_gbl_owner_id_mask ^= (1 << owner_id);
+       if (acpi_gbl_owner_id_mask[index] & bit) {
+               acpi_gbl_owner_id_mask[index] ^= bit;
+       } else {
+               ACPI_REPORT_ERROR(("Release of non-allocated owner_id: %2.2X\n",
+                                  owner_id + 1));
        }
 
        (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
@@ -788,61 +835,12 @@ u8 acpi_ut_generate_checksum(u8 * buffer, u32 length)
        return ((u8) (0 - sum));
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_get_resource_end_tag
- *
- * PARAMETERS:  obj_desc        - The resource template buffer object
- *
- * RETURN:      Pointer to the end tag
- *
- * DESCRIPTION: Find the END_TAG resource descriptor in a resource template
- *
- ******************************************************************************/
-
-u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc)
-{
-       u8 buffer_byte;
-       u8 *buffer;
-       u8 *end_buffer;
-
-       buffer = obj_desc->buffer.pointer;
-       end_buffer = buffer + obj_desc->buffer.length;
-
-       while (buffer < end_buffer) {
-               buffer_byte = *buffer;
-               if (buffer_byte & ACPI_RDESC_TYPE_MASK) {
-                       /* Large Descriptor - Length is next 2 bytes */
-
-                       buffer += ((*(buffer + 1) | (*(buffer + 2) << 8)) + 3);
-               } else {
-                       /* Small Descriptor.  End Tag will be found here */
-
-                       if ((buffer_byte & ACPI_RDESC_SMALL_MASK) ==
-                           ACPI_RDESC_TYPE_END_TAG) {
-                               /* Found the end tag descriptor, all done. */
-
-                               return (buffer);
-                       }
-
-                       /* Length is in the header */
-
-                       buffer += ((buffer_byte & 0x07) + 1);
-               }
-       }
-
-       /* End tag not found */
-
-       return (NULL);
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_report_error
  *
  * PARAMETERS:  module_name         - Caller's module name (for error output)
  *              line_number         - Caller's line number (for error output)
- *              component_id        - Caller's component ID (for error output)
  *
  * RETURN:      None
  *
@@ -850,10 +848,10 @@ u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc)
  *
  ******************************************************************************/
 
-void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id)
+void acpi_ut_report_error(char *module_name, u32 line_number)
 {
 
-       acpi_os_printf("%8s-%04d: *** Error: ", module_name, line_number);
+       acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
 }
 
 /*******************************************************************************
@@ -862,7 +860,6 @@ void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id)
  *
  * PARAMETERS:  module_name         - Caller's module name (for error output)
  *              line_number         - Caller's line number (for error output)
- *              component_id        - Caller's component ID (for error output)
  *
  * RETURN:      None
  *
@@ -870,11 +867,10 @@ void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id)
  *
  ******************************************************************************/
 
-void
-acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id)
+void acpi_ut_report_warning(char *module_name, u32 line_number)
 {
 
-       acpi_os_printf("%8s-%04d: *** Warning: ", module_name, line_number);
+       acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number);
 }
 
 /*******************************************************************************
@@ -883,7 +879,6 @@ acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id)
  *
  * PARAMETERS:  module_name         - Caller's module name (for error output)
  *              line_number         - Caller's line number (for error output)
- *              component_id        - Caller's component ID (for error output)
  *
  * RETURN:      None
  *
@@ -891,8 +886,8 @@ acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id)
  *
  ******************************************************************************/
 
-void acpi_ut_report_info(char *module_name, u32 line_number, u32 component_id)
+void acpi_ut_report_info(char *module_name, u32 line_number)
 {
 
-       acpi_os_printf("%8s-%04d: *** Info: ", module_name, line_number);
+       acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number);
 }