@@ -210,20 +210,39 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
210
210
}
211
211
}
212
212
213
- int __init
214
- acpi_parse_entries (char * id , unsigned long table_size ,
215
- acpi_tbl_entry_handler handler ,
213
+ /**
214
+ * acpi_parse_entries_array - for each proc_num find a suitable subtable
215
+ *
216
+ * @id: table id (for debugging purposes)
217
+ * @table_size: single entry size
218
+ * @table_header: where does the table start?
219
+ * @proc: array of acpi_subtable_proc struct containing entry id
220
+ * and associated handler with it
221
+ * @proc_num: how big proc is?
222
+ * @max_entries: how many entries can we process?
223
+ *
224
+ * For each proc_num find a subtable with proc->id and run proc->handler
225
+ * on it. Assumption is that there's only single handler for particular
226
+ * entry id.
227
+ *
228
+ * On success returns sum of all matching entries for all proc handlers.
229
+ * Otherwise, -ENODEV or -EINVAL is returned.
230
+ */
231
+ static int __init
232
+ acpi_parse_entries_array (char * id , unsigned long table_size ,
216
233
struct acpi_table_header * table_header ,
217
- int entry_id , unsigned int max_entries )
234
+ struct acpi_subtable_proc * proc , int proc_num ,
235
+ unsigned int max_entries )
218
236
{
219
237
struct acpi_subtable_header * entry ;
220
- int count = 0 ;
221
238
unsigned long table_end ;
239
+ int count = 0 ;
240
+ int i ;
222
241
223
242
if (acpi_disabled )
224
243
return - ENODEV ;
225
244
226
- if (!id || ! handler )
245
+ if (!id )
227
246
return - EINVAL ;
228
247
229
248
if (!table_size )
@@ -243,20 +262,27 @@ acpi_parse_entries(char *id, unsigned long table_size,
243
262
244
263
while (((unsigned long )entry ) + sizeof (struct acpi_subtable_header ) <
245
264
table_end ) {
246
- if (entry -> type == entry_id
247
- && (!max_entries || count < max_entries )) {
248
- if (handler (entry , table_end ))
265
+ if (max_entries && count >= max_entries )
266
+ break ;
267
+
268
+ for (i = 0 ; i < proc_num ; i ++ ) {
269
+ if (entry -> type != proc [i ].id )
270
+ continue ;
271
+ if (!proc -> handler || proc [i ].handler (entry , table_end ))
249
272
return - EINVAL ;
250
273
251
- count ++ ;
274
+ proc -> count ++ ;
275
+ break ;
252
276
}
277
+ if (i != proc_num )
278
+ count ++ ;
253
279
254
280
/*
255
281
* If entry->length is 0, break from this loop to avoid
256
282
* infinite loop.
257
283
*/
258
284
if (entry -> length == 0 ) {
259
- pr_err ("[%4.4s:0x%02x] Invalid zero length\n" , id , entry_id );
285
+ pr_err ("[%4.4s:0x%02x] Invalid zero length\n" , id , proc -> id );
260
286
return - EINVAL ;
261
287
}
262
288
@@ -266,17 +292,32 @@ acpi_parse_entries(char *id, unsigned long table_size,
266
292
267
293
if (max_entries && count > max_entries ) {
268
294
pr_warn ("[%4.4s:0x%02x] ignored %i entries of %i found\n" ,
269
- id , entry_id , count - max_entries , count );
295
+ id , proc -> id , count - max_entries , count );
270
296
}
271
297
272
298
return count ;
273
299
}
274
300
275
301
int __init
276
- acpi_table_parse_entries (char * id ,
302
+ acpi_parse_entries (char * id ,
303
+ unsigned long table_size ,
304
+ acpi_tbl_entry_handler handler ,
305
+ struct acpi_table_header * table_header ,
306
+ int entry_id , unsigned int max_entries )
307
+ {
308
+ struct acpi_subtable_proc proc = {
309
+ .id = entry_id ,
310
+ .handler = handler ,
311
+ };
312
+
313
+ return acpi_parse_entries_array (id , table_size , table_header ,
314
+ & proc , 1 , max_entries );
315
+ }
316
+
317
+ int __init
318
+ acpi_table_parse_entries_array (char * id ,
277
319
unsigned long table_size ,
278
- int entry_id ,
279
- acpi_tbl_entry_handler handler ,
320
+ struct acpi_subtable_proc * proc , int proc_num ,
280
321
unsigned int max_entries )
281
322
{
282
323
struct acpi_table_header * table_header = NULL ;
@@ -287,7 +328,7 @@ acpi_table_parse_entries(char *id,
287
328
if (acpi_disabled )
288
329
return - ENODEV ;
289
330
290
- if (!id || ! handler )
331
+ if (!id )
291
332
return - EINVAL ;
292
333
293
334
if (!strncmp (id , ACPI_SIG_MADT , 4 ))
@@ -299,13 +340,29 @@ acpi_table_parse_entries(char *id,
299
340
return - ENODEV ;
300
341
}
301
342
302
- count = acpi_parse_entries (id , table_size , handler , table_header ,
303
- entry_id , max_entries );
343
+ count = acpi_parse_entries_array (id , table_size , table_header ,
344
+ proc , proc_num , max_entries );
304
345
305
346
early_acpi_os_unmap_memory ((char * )table_header , tbl_size );
306
347
return count ;
307
348
}
308
349
350
+ int __init
351
+ acpi_table_parse_entries (char * id ,
352
+ unsigned long table_size ,
353
+ int entry_id ,
354
+ acpi_tbl_entry_handler handler ,
355
+ unsigned int max_entries )
356
+ {
357
+ struct acpi_subtable_proc proc = {
358
+ .id = entry_id ,
359
+ .handler = handler ,
360
+ };
361
+
362
+ return acpi_table_parse_entries_array (id , table_size , & proc , 1 ,
363
+ max_entries );
364
+ }
365
+
309
366
int __init
310
367
acpi_table_parse_madt (enum acpi_madt_type id ,
311
368
acpi_tbl_entry_handler handler , unsigned int max_entries )
0 commit comments