# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1190390339 -3600
# Node ID 2f94fc96f99c2de54442fba488e11c7d2d40d73a
# Parent 707b4d2087b28f9d3d33ae4367b0e342a666e118
Add acpi_table_disable() into xen/drivers/acpi/tables.c
This function can disable a ACPI table by updating the table header.
Signed-off-by: Akio Takebe <takebe_akio@xxxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
xen-unstable changeset: 15654:c0fbee66aff63978addc5f8b263947553f606d08
xen-unstable date: Mon Jul 30 11:27:48 2007 +0100
---
xen/drivers/acpi/tables.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++
xen/include/xen/acpi.h | 1
2 files changed, 141 insertions(+)
diff -r 707b4d2087b2 -r 2f94fc96f99c xen/drivers/acpi/tables.c
--- a/xen/drivers/acpi/tables.c Fri Sep 21 16:58:25 2007 +0100
+++ b/xen/drivers/acpi/tables.c Fri Sep 21 16:58:59 2007 +0100
@@ -620,3 +620,143 @@ int __init acpi_table_init(void)
return 0;
}
+
+int __init
+acpi_table_disable(enum acpi_table_id table_id)
+{
+ struct acpi_table_header *header = NULL;
+ struct acpi_table_rsdp *rsdp;
+ unsigned long rsdp_phys;
+ char *table_name;
+ int id;
+
+ rsdp_phys = acpi_find_rsdp();
+ if (!rsdp_phys)
+ return -ENODEV;
+
+ rsdp = (struct acpi_table_rsdp *)__acpi_map_table(rsdp_phys,
+ sizeof(struct acpi_table_rsdp));
+ if (!rsdp)
+ return -ENODEV;
+
+ for (id = 0; id < sdt_count; id++)
+ if (sdt_entry[id].id == table_id)
+ break;
+
+ if (id == sdt_count)
+ return -ENOENT;
+
+ table_name = acpi_table_signatures[table_id];
+
+ /* First check XSDT (but only on ACPI 2.0-compatible systems) */
+
+ if ((rsdp->revision >= 2) &&
+ (((struct acpi20_table_rsdp *)rsdp)->xsdt_address)) {
+
+ struct acpi_table_xsdt *mapped_xsdt = NULL;
+
+ sdt_pa = ((struct acpi20_table_rsdp *)rsdp)->xsdt_address;
+
+ /* map in just the header */
+ header = (struct acpi_table_header *)
+ __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
+
+ if (!header) {
+ printk(KERN_WARNING PREFIX
+ "Unable to map XSDT header\n");
+ return -ENODEV;
+ }
+
+ /* remap in the entire table before processing */
+ mapped_xsdt = (struct acpi_table_xsdt *)
+ __acpi_map_table(sdt_pa, header->length);
+ if (!mapped_xsdt) {
+ printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
+ return -ENODEV;
+ }
+ header = &mapped_xsdt->header;
+
+ if (strncmp(header->signature, "XSDT", 4)) {
+ printk(KERN_WARNING PREFIX
+ "XSDT signature incorrect\n");
+ return -ENODEV;
+ }
+
+ if (acpi_table_compute_checksum(header, header->length)) {
+ printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n");
+ return -ENODEV;
+ }
+
+ if (id < sdt_count) {
+ header = (struct acpi_table_header *)
+ __acpi_map_table(mapped_xsdt->entry[id],
sizeof(struct acpi_table_header));
+ } else {
+ printk(KERN_WARNING PREFIX
+ "Unable to disable entry %d\n",
+ id);
+ return -ENODEV;
+ }
+ }
+
+ /* Then check RSDT */
+
+ else if (rsdp->rsdt_address) {
+
+ struct acpi_table_rsdt *mapped_rsdt = NULL;
+
+ sdt_pa = rsdp->rsdt_address;
+
+ /* map in just the header */
+ header = (struct acpi_table_header *)
+ __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
+ if (!header) {
+ printk(KERN_WARNING PREFIX
+ "Unable to map RSDT header\n");
+ return -ENODEV;
+ }
+
+ /* remap in the entire table before processing */
+ mapped_rsdt = (struct acpi_table_rsdt *)
+ __acpi_map_table(sdt_pa, header->length);
+ if (!mapped_rsdt) {
+ printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
+ return -ENODEV;
+ }
+ header = &mapped_rsdt->header;
+
+ if (strncmp(header->signature, "RSDT", 4)) {
+ printk(KERN_WARNING PREFIX
+ "RSDT signature incorrect\n");
+ return -ENODEV;
+ }
+
+ if (acpi_table_compute_checksum(header, header->length)) {
+ printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n");
+ return -ENODEV;
+ }
+ if (id < sdt_count) {
+ header = (struct acpi_table_header *)
+ __acpi_map_table(mapped_rsdt->entry[id],
sizeof(struct acpi_table_header));
+ } else {
+ printk(KERN_WARNING PREFIX
+ "Unable to disable entry %d\n",
+ id);
+ return -ENODEV;
+ }
+ }
+
+ else {
+ printk(KERN_WARNING PREFIX
+ "No System Description Table (RSDT/XSDT) specified in
RSDP\n");
+ return -ENODEV;
+ }
+
+ memcpy(header->signature, "OEMx", 4);
+ memcpy(header->oem_id, "xxxxxx", 6);
+ memcpy(header->oem_id+1, table_name, 4);
+ memcpy(header->oem_table_id, "Xen ", 8);
+ header->checksum = 0;
+ header->checksum = generate_acpi_checksum(header, header->length);
+
+ return 0;
+}
diff -r 707b4d2087b2 -r 2f94fc96f99c xen/include/xen/acpi.h
--- a/xen/include/xen/acpi.h Fri Sep 21 16:58:25 2007 +0100
+++ b/xen/include/xen/acpi.h Fri Sep 21 16:58:59 2007 +0100
@@ -383,6 +383,7 @@ int acpi_numa_init (void);
int acpi_numa_init (void);
int acpi_table_init (void);
+int acpi_table_disable(enum acpi_table_id table_id);
int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler);
int acpi_get_table_header_early (enum acpi_table_id id, struct
acpi_table_header **header);
int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler
handler, unsigned int max_entries);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|