aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/utilities/utmisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/utilities/utmisc.c')
-rw-r--r--drivers/acpi/utilities/utmisc.c79
1 files changed, 54 insertions, 25 deletions
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 89efba7bf449..64dd64b1aa18 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -64,6 +64,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
64{ 64{
65 acpi_native_uint i; 65 acpi_native_uint i;
66 acpi_native_uint j; 66 acpi_native_uint j;
67 acpi_native_uint k;
67 acpi_status status; 68 acpi_status status;
68 69
69 ACPI_FUNCTION_TRACE("ut_allocate_owner_id"); 70 ACPI_FUNCTION_TRACE("ut_allocate_owner_id");
@@ -85,32 +86,50 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
85 86
86 /* 87 /*
87 * Find a free owner ID, cycle through all possible IDs on repeated 88 * Find a free owner ID, cycle through all possible IDs on repeated
88 * allocations. Note: Index for next possible ID is equal to the value 89 * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
89 * of the last allocated ID. 90 * to be scanned twice.
90 */ 91 */
91 for (i = 0, j = acpi_gbl_last_owner_id; i < 32; i++, j++) { 92 for (i = 0, j = acpi_gbl_last_owner_id_index;
92 if (j >= 32) { 93 i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
93 j = 0; /* Wraparound to ID start */ 94 if (j >= ACPI_NUM_OWNERID_MASKS) {
95 j = 0; /* Wraparound to start of mask array */
94 } 96 }
95 97
96 if (!(acpi_gbl_owner_id_mask & (1 << j))) { 98 for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
97 /* 99 if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
98 * Found a free ID. The actual ID is the bit index plus one, 100 /* There are no free IDs in this mask */
99 * making zero an invalid Owner ID. Save this as the last ID
100 * allocated and update the global ID mask.
101 */
102 acpi_gbl_last_owner_id = (acpi_owner_id) (j + 1);
103 *owner_id = acpi_gbl_last_owner_id;
104 101
105 ACPI_DEBUG_PRINT((ACPI_DB_VALUES, 102 break;
106 "Current owner_id mask: %8.8X New ID: %2.2X\n", 103 }
107 acpi_gbl_owner_id_mask,
108 (unsigned int)
109 acpi_gbl_last_owner_id));
110 104
111 acpi_gbl_owner_id_mask |= (1 << j); 105 if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
112 goto exit; 106 /*
107 * Found a free ID. The actual ID is the bit index plus one,
108 * making zero an invalid Owner ID. Save this as the last ID
109 * allocated and update the global ID mask.
110 */
111 acpi_gbl_owner_id_mask[j] |= (1 << k);
112
113 acpi_gbl_last_owner_id_index = (u8) j;
114 acpi_gbl_next_owner_id_offset = (u8) (k + 1);
115
116 /*
117 * Construct encoded ID from the index and bit position
118 *
119 * Note: Last [j].k (bit 255) is never used and is marked
120 * permanently allocated (prevents +1 overflow)
121 */
122 *owner_id =
123 (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));
124
125 ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
126 "Allocated owner_id: %2.2X\n",
127 (unsigned int)*owner_id));
128 goto exit;
129 }
113 } 130 }
131
132 acpi_gbl_next_owner_id_offset = 0;
114 } 133 }
115 134
116 /* 135 /*
@@ -124,7 +143,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
124 * methods, or there may be a bug where the IDs are not released. 143 * methods, or there may be a bug where the IDs are not released.
125 */ 144 */
126 status = AE_OWNER_ID_LIMIT; 145 status = AE_OWNER_ID_LIMIT;
127 ACPI_REPORT_ERROR(("Could not allocate new owner_id (32 max), AE_OWNER_ID_LIMIT\n")); 146 ACPI_REPORT_ERROR(("Could not allocate new owner_id (255 max), AE_OWNER_ID_LIMIT\n"));
128 147
129 exit: 148 exit:
130 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); 149 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
@@ -141,7 +160,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
141 * control method or unloading a table. Either way, we would 160 * control method or unloading a table. Either way, we would
142 * ignore any error anyway. 161 * ignore any error anyway.
143 * 162 *
144 * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 32 163 * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
145 * 164 *
146 ******************************************************************************/ 165 ******************************************************************************/
147 166
@@ -149,6 +168,8 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
149{ 168{
150 acpi_owner_id owner_id = *owner_id_ptr; 169 acpi_owner_id owner_id = *owner_id_ptr;
151 acpi_status status; 170 acpi_status status;
171 acpi_native_uint index;
172 u32 bit;
152 173
153 ACPI_FUNCTION_TRACE_U32("ut_release_owner_id", owner_id); 174 ACPI_FUNCTION_TRACE_U32("ut_release_owner_id", owner_id);
154 175
@@ -158,7 +179,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
158 179
159 /* Zero is not a valid owner_iD */ 180 /* Zero is not a valid owner_iD */
160 181
161 if ((owner_id == 0) || (owner_id > 32)) { 182 if ((owner_id == 0) || (owner_id > 255)) {
162 ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id)); 183 ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id));
163 return_VOID; 184 return_VOID;
164 } 185 }
@@ -174,10 +195,18 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
174 195
175 owner_id--; 196 owner_id--;
176 197
198 /* Decode ID to index/offset pair */
199
200 index = ACPI_DIV_32(owner_id);
201 bit = 1 << ACPI_MOD_32(owner_id);
202
177 /* Free the owner ID only if it is valid */ 203 /* Free the owner ID only if it is valid */
178 204
179 if (acpi_gbl_owner_id_mask & (1 << owner_id)) { 205 if (acpi_gbl_owner_id_mask[index] & bit) {
180 acpi_gbl_owner_id_mask ^= (1 << owner_id); 206 acpi_gbl_owner_id_mask[index] ^= bit;
207 } else {
208 ACPI_REPORT_ERROR(("Release of non-allocated owner_id: %2.2X\n",
209 owner_id + 1));
181 } 210 }
182 211
183 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); 212 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);