Lines 68-73
EXPORT_SYMBOL(acpi_in_debugger);
Link Here
|
68 |
extern char line_buf[80]; |
68 |
extern char line_buf[80]; |
69 |
#endif /*ENABLE_DEBUGGER */ |
69 |
#endif /*ENABLE_DEBUGGER */ |
70 |
|
70 |
|
|
|
71 |
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD |
72 |
int acpi_must_unregister_table = FALSE; |
73 |
#endif |
74 |
|
71 |
static unsigned int acpi_irq_irq; |
75 |
static unsigned int acpi_irq_irq; |
72 |
static acpi_osd_handler acpi_irq_handler; |
76 |
static acpi_osd_handler acpi_irq_handler; |
73 |
static void *acpi_irq_context; |
77 |
static void *acpi_irq_context; |
Lines 275-280
acpi_os_predefined_override(const struct
Link Here
|
275 |
return AE_OK; |
279 |
return AE_OK; |
276 |
} |
280 |
} |
277 |
|
281 |
|
|
|
282 |
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD |
283 |
#define MAX_DS_SDTS 10 |
284 |
static struct acpi_table_header *ds_sdt_buffers[MAX_DS_SDTS]; |
285 |
static unsigned int tables_loaded = 0; |
286 |
|
287 |
void acpi_load_override_tables(void){ |
288 |
struct file *firmware_file; |
289 |
mm_segment_t oldfs; |
290 |
unsigned long len, len2; |
291 |
struct kstat stat; |
292 |
unsigned int x, y; |
293 |
char *ramfs_ds_sdt_names[MAX_DS_SDTS] = { |
294 |
"/DSDT.aml", |
295 |
"/SSDT.aml", |
296 |
"/SSDT1.aml", |
297 |
"/SSDT2.aml", |
298 |
"/SSDT3.aml", |
299 |
"/SSDT4.aml", |
300 |
"/SSDT5.aml", |
301 |
"/SSDT6.aml", |
302 |
"/SSDT7.aml", |
303 |
"/SSDT8.aml", |
304 |
}; |
305 |
/* |
306 |
* Never do this at home, only the user-space is allowed to open a file. |
307 |
* The clean way would be to use the firmware loader. But this code must be run |
308 |
* before there is any userspace available. So we need a static/init firmware |
309 |
* infrastructure, which doesn't exist yet... |
310 |
*/ |
311 |
for (x = 0; x < MAX_DS_SDTS; x++){ |
312 |
if (vfs_stat(ramfs_ds_sdt_names[x], &stat) < 0) { |
313 |
continue; |
314 |
} |
315 |
len = stat.size; |
316 |
/* check especially against empty files */ |
317 |
if (len <= 4) { |
318 |
printk("error file %s is too small, only %lu bytes.\n", |
319 |
ramfs_ds_sdt_names[x], len); |
320 |
continue; |
321 |
} |
322 |
|
323 |
ds_sdt_buffers[x] = kmalloc(len, GFP_KERNEL); |
324 |
if (!ds_sdt_buffers[x]) { |
325 |
printk("error when allocating %lu bytes of memory.\n", |
326 |
len); |
327 |
/* better free all tables again */ |
328 |
for (y = 0; y < x; y++){ |
329 |
if (ds_sdt_buffers[y]) |
330 |
kfree(ds_sdt_buffers[x]); |
331 |
} |
332 |
acpi_must_unregister_table = FALSE; |
333 |
return; |
334 |
} |
335 |
|
336 |
firmware_file = filp_open(ramfs_ds_sdt_names[x], O_RDONLY, 0); |
337 |
if (IS_ERR(firmware_file)) { |
338 |
printk("error, could not open file %s.\n", |
339 |
ramfs_ds_sdt_names[x]); |
340 |
kfree(ds_sdt_buffers[x]); |
341 |
continue; |
342 |
} |
343 |
|
344 |
oldfs = get_fs(); |
345 |
set_fs(KERNEL_DS); |
346 |
len2 = vfs_read(firmware_file, |
347 |
(char __user *)ds_sdt_buffers[x], |
348 |
len, |
349 |
&firmware_file->f_pos); |
350 |
set_fs(oldfs); |
351 |
filp_close(firmware_file, NULL); |
352 |
if (len2 < len) { |
353 |
printk("error trying to read %lu bytes from %s.\n", |
354 |
len, ramfs_ds_sdt_names[x]); |
355 |
kfree(ds_sdt_buffers[x]); |
356 |
continue; |
357 |
} |
358 |
printk(PREFIX "successfully read %lu bytes from file %s\n", |
359 |
len, ramfs_ds_sdt_names[x]); |
360 |
} |
361 |
} |
362 |
|
363 |
struct acpi_table_header * acpi_find_dsdt_initrd(struct acpi_table_header * t) |
364 |
{ |
365 |
struct acpi_table_header *ret = NULL; |
366 |
unsigned int x; |
367 |
for (x = 0; x < MAX_DS_SDTS; x++){ |
368 |
if (ds_sdt_buffers[x]){ |
369 |
if (!memcmp(ds_sdt_buffers[x]->signature, |
370 |
t->signature, 4) && |
371 |
!memcmp(ds_sdt_buffers[x]->oem_table_id, |
372 |
t->oem_table_id, 8)){ |
373 |
ret = ds_sdt_buffers[x]; |
374 |
printk(PREFIX "Override [%4.4s-%8.8s]" |
375 |
" from initramfs -" |
376 |
" tainting kernel\n", |
377 |
t->signature, |
378 |
t->oem_table_id); |
379 |
add_taint(TAINT_NO_SUPPORT); |
380 |
acpi_must_unregister_table = TRUE; |
381 |
break; |
382 |
} |
383 |
} |
384 |
} |
385 |
return ret; |
386 |
} |
387 |
#endif |
388 |
|
278 |
acpi_status |
389 |
acpi_status |
279 |
acpi_os_table_override(struct acpi_table_header * existing_table, |
390 |
acpi_os_table_override(struct acpi_table_header * existing_table, |
280 |
struct acpi_table_header ** new_table) |
391 |
struct acpi_table_header ** new_table) |
Lines 282-294
acpi_os_table_override(struct acpi_table
Link Here
|
282 |
if (!existing_table || !new_table) |
393 |
if (!existing_table || !new_table) |
283 |
return AE_BAD_PARAMETER; |
394 |
return AE_BAD_PARAMETER; |
284 |
|
395 |
|
|
|
396 |
*new_table = NULL; |
397 |
|
285 |
#ifdef CONFIG_ACPI_CUSTOM_DSDT |
398 |
#ifdef CONFIG_ACPI_CUSTOM_DSDT |
286 |
if (strncmp(existing_table->signature, "DSDT", 4) == 0) |
399 |
if (strncmp(existing_table->signature, "DSDT", 4) == 0) |
287 |
*new_table = (struct acpi_table_header *)AmlCode; |
400 |
*new_table = (struct acpi_table_header *)AmlCode; |
288 |
else |
401 |
#endif |
289 |
*new_table = NULL; |
402 |
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD |
290 |
#else |
403 |
if (!tables_loaded){ |
291 |
*new_table = NULL; |
404 |
acpi_load_override_tables(); |
|
|
405 |
tables_loaded = 1; |
406 |
} |
407 |
if (!strncmp(existing_table->signature, "DSDT", 4) || |
408 |
!strncmp(existing_table->signature, "SSDT", 4)){ |
409 |
*new_table = acpi_find_dsdt_initrd(existing_table); |
410 |
} |
292 |
#endif |
411 |
#endif |
293 |
return AE_OK; |
412 |
return AE_OK; |
294 |
} |
413 |
} |