aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/utilities/utmisc.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2005-12-02 18:27:00 -0500
committerLen Brown <len.brown@intel.com>2005-12-10 00:29:11 -0500
commit28f55ebce5bd2fceec8adc7c8860953d3e4532a8 (patch)
tree2c5c10c18e51f9a717514dfccdc287fc517730c6 /drivers/acpi/utilities/utmisc.c
parentc51a4de85de720670f2fbc592a6f8040af72ad87 (diff)
[ACPI] ACPICA 20051202
Modified the parsing of control methods to no longer create namespace objects during the first pass of the parse. Objects are now created only during the execute phase, at the moment the namespace creation operator is encountered in the AML (Name, OperationRegion, CreateByteField, etc.) This should eliminate ALREADY_EXISTS exceptions seen on some machines where reentrant control methods are protected by an AML mutex. The mutex will now correctly block multiple threads from attempting to create the same object more than once. Increased the number of available Owner Ids for namespace object tracking from 32 to 255. This should eliminate the OWNER_ID_LIMIT exceptions seen on some machines with a large number of ACPI tables (either static or dynamic). Enhanced the namespace dump routine to output the owner ID for each namespace object. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
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);