^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: utownerid - Support for Table/Method Owner IDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "acnamesp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define _COMPONENT ACPI_UTILITIES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) ACPI_MODULE_NAME("utownerid")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * FUNCTION: acpi_ut_allocate_owner_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * PARAMETERS: owner_id - Where the new owner ID is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * track objects created by the table or method, to be deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * when the method exits or the table is unloaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) acpi_status acpi_ut_allocate_owner_id(acpi_owner_id *owner_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) u32 j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) u32 k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Guard against multiple allocations of ID to the same location */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (*owner_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) ACPI_ERROR((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) "Owner ID [0x%3.3X] already exists", *owner_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return_ACPI_STATUS(AE_ALREADY_EXISTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Mutex for the global ID mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * Find a free owner ID, cycle through all possible IDs on repeated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * may have to be scanned twice.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) for (i = 0, j = acpi_gbl_last_owner_id_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (j >= ACPI_NUM_OWNERID_MASKS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) j = 0; /* Wraparound to start of mask array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* There are no free IDs in this mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * Note: the u32 cast ensures that 1 is stored as a unsigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * integer. Omitting the cast may result in 1 being stored as an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * int. Some compilers or runtime error detection may flag this as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (!(acpi_gbl_owner_id_mask[j] & ((u32)1 << k))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Found a free ID. The actual ID is the bit index plus one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * making zero an invalid Owner ID. Save this as the last ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * allocated and update the global ID mask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) acpi_gbl_owner_id_mask[j] |= ((u32)1 << k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) acpi_gbl_last_owner_id_index = (u8)j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) acpi_gbl_next_owner_id_offset = (u8)(k + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * Construct encoded ID from the index and bit position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * Note: Last [j].k (bit 4095) is never used and is marked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * permanently allocated (prevents +1 overflow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) *owner_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) (acpi_owner_id)((k + 1) + ACPI_MUL_32(j));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) "Allocated OwnerId: 0x%3.3X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) (unsigned int)*owner_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) acpi_gbl_next_owner_id_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * All owner_ids have been allocated. This typically should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * not happen since the IDs are reused after deallocation. The IDs are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * allocated upon table load (one per table) and method execution, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * they are released when a table is unloaded or a method completes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * execution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * If this error happens, there may be very deep nesting of invoked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * control methods, or there may be a bug where the IDs are not released.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) status = AE_OWNER_ID_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ACPI_ERROR((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) "Could not allocate new OwnerId (4095 max), AE_OWNER_ID_LIMIT"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * FUNCTION: acpi_ut_release_owner_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * PARAMETERS: owner_id_ptr - Pointer to a previously allocated owner_ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * RETURN: None. No error is returned because we are either exiting a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * control method or unloading a table. Either way, we would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * ignore any error anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) void acpi_ut_release_owner_id(acpi_owner_id *owner_id_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) acpi_owner_id owner_id = *owner_id_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u32 bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Always clear the input owner_id (zero is an invalid ID) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *owner_id_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Zero is not a valid owner_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (owner_id == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ACPI_ERROR((AE_INFO, "Invalid OwnerId: 0x%3.3X", owner_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return_VOID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Mutex for the global ID mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return_VOID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* Normalize the ID to zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) owner_id--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* Decode ID to index/offset pair */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) index = ACPI_DIV_32(owner_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) bit = (u32)1 << ACPI_MOD_32(owner_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* Free the owner ID only if it is valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (acpi_gbl_owner_id_mask[index] & bit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) acpi_gbl_owner_id_mask[index] ^= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ACPI_ERROR((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) "Attempted release of non-allocated OwnerId: 0x%3.3X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) owner_id + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return_VOID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }