diff options
Diffstat (limited to 'drivers/acpi/tables/tbinstal.c')
-rw-r--r-- | drivers/acpi/tables/tbinstal.c | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index b22185f55a16..18747ce8dd2f 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -110,7 +110,6 @@ acpi_status | |||
110 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | 110 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) |
111 | { | 111 | { |
112 | u32 i; | 112 | u32 i; |
113 | u32 length; | ||
114 | acpi_status status = AE_OK; | 113 | acpi_status status = AE_OK; |
115 | 114 | ||
116 | ACPI_FUNCTION_TRACE(tb_add_table); | 115 | ACPI_FUNCTION_TRACE(tb_add_table); |
@@ -145,25 +144,64 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
145 | } | 144 | } |
146 | } | 145 | } |
147 | 146 | ||
148 | length = ACPI_MIN(table_desc->length, | 147 | /* |
149 | acpi_gbl_root_table_list.tables[i].length); | 148 | * Check for a table match on the entire table length, |
149 | * not just the header. | ||
150 | */ | ||
151 | if (table_desc->length != | ||
152 | acpi_gbl_root_table_list.tables[i].length) { | ||
153 | continue; | ||
154 | } | ||
155 | |||
150 | if (ACPI_MEMCMP(table_desc->pointer, | 156 | if (ACPI_MEMCMP(table_desc->pointer, |
151 | acpi_gbl_root_table_list.tables[i].pointer, | 157 | acpi_gbl_root_table_list.tables[i].pointer, |
152 | length)) { | 158 | acpi_gbl_root_table_list.tables[i].length)) { |
153 | continue; | 159 | continue; |
154 | } | 160 | } |
155 | 161 | ||
156 | /* Table is already registered */ | 162 | /* |
157 | 163 | * Note: the current mechanism does not unregister a table if it is | |
164 | * dynamically unloaded. The related namespace entries are deleted, | ||
165 | * but the table remains in the root table list. | ||
166 | * | ||
167 | * The assumption here is that the number of different tables that | ||
168 | * will be loaded is actually small, and there is minimal overhead | ||
169 | * in just keeping the table in case it is needed again. | ||
170 | * | ||
171 | * If this assumption changes in the future (perhaps on large | ||
172 | * machines with many table load/unload operations), tables will | ||
173 | * need to be unregistered when they are unloaded, and slots in the | ||
174 | * root table list should be reused when empty. | ||
175 | */ | ||
176 | |||
177 | /* | ||
178 | * Table is already registered. | ||
179 | * We can delete the table that was passed as a parameter. | ||
180 | */ | ||
158 | acpi_tb_delete_table(table_desc); | 181 | acpi_tb_delete_table(table_desc); |
159 | *table_index = i; | 182 | *table_index = i; |
160 | status = AE_ALREADY_EXISTS; | 183 | |
161 | goto release; | 184 | if (acpi_gbl_root_table_list.tables[i]. |
185 | flags & ACPI_TABLE_IS_LOADED) { | ||
186 | |||
187 | /* Table is still loaded, this is an error */ | ||
188 | |||
189 | status = AE_ALREADY_EXISTS; | ||
190 | goto release; | ||
191 | } else { | ||
192 | /* Table was unloaded, allow it to be reloaded */ | ||
193 | |||
194 | table_desc->pointer = | ||
195 | acpi_gbl_root_table_list.tables[i].pointer; | ||
196 | table_desc->address = | ||
197 | acpi_gbl_root_table_list.tables[i].address; | ||
198 | status = AE_OK; | ||
199 | goto print_header; | ||
200 | } | ||
162 | } | 201 | } |
163 | 202 | ||
164 | /* | 203 | /* Add the table to the global root table list */ |
165 | * Add the table to the global table list | 204 | |
166 | */ | ||
167 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, | 205 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, |
168 | table_desc->length, table_desc->flags, | 206 | table_desc->length, table_desc->flags, |
169 | table_index); | 207 | table_index); |
@@ -171,6 +209,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
171 | goto release; | 209 | goto release; |
172 | } | 210 | } |
173 | 211 | ||
212 | print_header: | ||
174 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); | 213 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); |
175 | 214 | ||
176 | release: | 215 | release: |