diff options
author | Bob Moore <robert.moore@intel.com> | 2008-07-03 22:48:43 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-10-22 23:14:35 -0400 |
commit | e56f561736e340a4e923b0db65f65dabf5d94823 (patch) | |
tree | a8677ad9130168fb2cdeadfd5cb4b07398db8815 /drivers/acpi | |
parent | 237a927682a63f02adb542dbdaafe8a81566451d (diff) |
ACPICA: Allow same ACPI table to be loaded/unloaded more than once
Without this change, a table cannot be loaded again once it has
been loaded/unloaded one time. The current mechanism does not
unregister a table upon an unload. During a load, if the same
table is found, this no longer returns an exception.
http://www.acpica.org/bugzilla/show_bug.cgi?id=722
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/tables/tbinstal.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index b22185f55a16..905dc38ab23b 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -145,6 +145,8 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
145 | } | 145 | } |
146 | } | 146 | } |
147 | 147 | ||
148 | /* Check for a table match on the entire table length */ | ||
149 | |||
148 | length = ACPI_MIN(table_desc->length, | 150 | length = ACPI_MIN(table_desc->length, |
149 | acpi_gbl_root_table_list.tables[i].length); | 151 | acpi_gbl_root_table_list.tables[i].length); |
150 | if (ACPI_MEMCMP(table_desc->pointer, | 152 | if (ACPI_MEMCMP(table_desc->pointer, |
@@ -153,17 +155,49 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
153 | continue; | 155 | continue; |
154 | } | 156 | } |
155 | 157 | ||
156 | /* Table is already registered */ | 158 | /* |
157 | 159 | * Note: the current mechanism does not unregister a table if it is | |
160 | * dynamically unloaded. The related namespace entries are deleted, | ||
161 | * but the table remains in the root table list. | ||
162 | * | ||
163 | * The assumption here is that the number of different tables that | ||
164 | * will be loaded is actually small, and there is minimal overhead | ||
165 | * in just keeping the table in case it is needed again. | ||
166 | * | ||
167 | * If this assumption changes in the future (perhaps on large | ||
168 | * machines with many table load/unload operations), tables will | ||
169 | * need to be unregistered when they are unloaded, and slots in the | ||
170 | * root table list should be reused when empty. | ||
171 | */ | ||
172 | |||
173 | /* | ||
174 | * Table is already registered. | ||
175 | * We can delete the table that was passed as a parameter. | ||
176 | */ | ||
158 | acpi_tb_delete_table(table_desc); | 177 | acpi_tb_delete_table(table_desc); |
159 | *table_index = i; | 178 | *table_index = i; |
160 | status = AE_ALREADY_EXISTS; | 179 | |
161 | goto release; | 180 | if (acpi_gbl_root_table_list.tables[i]. |
181 | flags & ACPI_TABLE_IS_LOADED) { | ||
182 | |||
183 | /* Table is still loaded, this is an error */ | ||
184 | |||
185 | status = AE_ALREADY_EXISTS; | ||
186 | goto release; | ||
187 | } else { | ||
188 | /* Table was unloaded, allow it to be reloaded */ | ||
189 | |||
190 | table_desc->pointer = | ||
191 | acpi_gbl_root_table_list.tables[i].pointer; | ||
192 | table_desc->address = | ||
193 | acpi_gbl_root_table_list.tables[i].address; | ||
194 | status = AE_OK; | ||
195 | goto print_header; | ||
196 | } | ||
162 | } | 197 | } |
163 | 198 | ||
164 | /* | 199 | /* Add the table to the global root table list */ |
165 | * Add the table to the global table list | 200 | |
166 | */ | ||
167 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, | 201 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, |
168 | table_desc->length, table_desc->flags, | 202 | table_desc->length, table_desc->flags, |
169 | table_index); | 203 | table_index); |
@@ -171,6 +205,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
171 | goto release; | 205 | goto release; |
172 | } | 206 | } |
173 | 207 | ||
208 | print_header: | ||
174 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); | 209 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); |
175 | 210 | ||
176 | release: | 211 | release: |