ia64/xen-unstable

changeset 15670:c0fbee66aff6

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@jp.fujitsu.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Jul 30 11:27:48 2007 +0100 (2007-07-30)
parents d9c3836e0684
children 9cd309378326
files xen/arch/x86/acpi/boot.c xen/drivers/acpi/tables.c xen/include/xen/acpi.h
line diff
     1.1 --- a/xen/arch/x86/acpi/boot.c	Mon Jul 30 10:59:27 2007 +0100
     1.2 +++ b/xen/arch/x86/acpi/boot.c	Mon Jul 30 11:27:48 2007 +0100
     1.3 @@ -371,12 +371,19 @@ extern u32 pmtmr_ioport;
     1.4  
     1.5  #ifdef CONFIG_ACPI_SLEEP
     1.6  /* Get pm1x_cnt and pm1x_evt information for ACPI sleep */
     1.7 -static int __init
     1.8 +static void __init
     1.9  acpi_fadt_parse_sleep_info(struct fadt_descriptor_rev2 *fadt)
    1.10  {
    1.11 +	struct acpi_table_rsdp *rsdp;
    1.12 +	unsigned long rsdp_phys;
    1.13  	struct facs_descriptor_rev2 *facs = NULL;
    1.14  	uint64_t facs_pa;
    1.15  
    1.16 +	rsdp_phys = acpi_find_rsdp();
    1.17 +	if (!rsdp_phys || acpi_disabled)
    1.18 +		goto bad;
    1.19 +	rsdp = __va(rsdp_phys);
    1.20 +
    1.21  	if (fadt->revision >= FADT2_REVISION_ID) {
    1.22  		/* Sanity check on FADT Rev. 2 */
    1.23  		if ((fadt->xpm1a_cnt_blk.address_space_id !=
    1.24 @@ -432,8 +439,7 @@ acpi_fadt_parse_sleep_info(struct fadt_d
    1.25  			"FACS is shorter than ACPI spec allow: 0x%x",
    1.26  			facs->length);
    1.27  
    1.28 -	if ((acpi_rsdp_rev < 2) ||
    1.29 -	    (facs->length < 32)) {
    1.30 +	if ((rsdp->revision < 2) || (facs->length < 32)) {
    1.31  		acpi_sinfo.wakeup_vector = facs_pa + 
    1.32  			offsetof(struct facs_descriptor_rev2,
    1.33  				 firmware_waking_vector);
    1.34 @@ -451,10 +457,9 @@ acpi_fadt_parse_sleep_info(struct fadt_d
    1.35  		acpi_sinfo.pm1a_cnt, acpi_sinfo.pm1b_cnt,
    1.36  		acpi_sinfo.pm1a_evt, acpi_sinfo.pm1b_cnt,
    1.37  		acpi_sinfo.wakeup_vector, acpi_sinfo.vector_width);
    1.38 -	return 0;
    1.39 +	return;
    1.40  bad:
    1.41  	memset(&acpi_sinfo, 0, sizeof(acpi_sinfo));
    1.42 -	return 0;
    1.43  }
    1.44  #endif
    1.45  
     2.1 --- a/xen/drivers/acpi/tables.c	Mon Jul 30 10:59:27 2007 +0100
     2.2 +++ b/xen/drivers/acpi/tables.c	Mon Jul 30 11:27:48 2007 +0100
     2.3 @@ -73,7 +73,6 @@ struct acpi_table_sdt {
     2.4  
     2.5  static unsigned long sdt_pa;	/* Physical Address */
     2.6  static unsigned long sdt_count;	/* Table count */
     2.7 -unsigned char acpi_rsdp_rev;
     2.8  
     2.9  static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata;
    2.10  
    2.11 @@ -610,8 +609,6 @@ int __init acpi_table_init(void)
    2.12  	       "RSDP (v%3.3d %6.6s                                ) @ 0x%p\n",
    2.13  	       rsdp->revision, rsdp->oem_id, (void *)rsdp_phys);
    2.14  
    2.15 -	acpi_rsdp_rev = rsdp->revision;
    2.16 -
    2.17  	if (rsdp->revision < 2)
    2.18  		result =
    2.19  		    acpi_table_compute_checksum(rsdp,
    2.20 @@ -634,3 +631,143 @@ int __init acpi_table_init(void)
    2.21  
    2.22  	return 0;
    2.23  }
    2.24 +
    2.25 +int __init
    2.26 +acpi_table_disable(enum acpi_table_id table_id)
    2.27 +{
    2.28 +	struct acpi_table_header *header = NULL;
    2.29 +	struct acpi_table_rsdp *rsdp;
    2.30 +	unsigned long rsdp_phys;
    2.31 +	char *table_name;
    2.32 +	int id;
    2.33 +
    2.34 +	rsdp_phys = acpi_find_rsdp();
    2.35 +	if (!rsdp_phys)
    2.36 +		return -ENODEV;
    2.37 +
    2.38 +	rsdp = (struct acpi_table_rsdp *)__acpi_map_table(rsdp_phys,
    2.39 +		sizeof(struct acpi_table_rsdp));
    2.40 +	if (!rsdp)
    2.41 +		return -ENODEV;
    2.42 +
    2.43 +	for (id = 0; id < sdt_count; id++)
    2.44 +		if (sdt_entry[id].id == table_id)
    2.45 +			break;
    2.46 +
    2.47 +	if (id == sdt_count)
    2.48 +		return -ENOENT;
    2.49 +
    2.50 +	table_name = acpi_table_signatures[table_id];
    2.51 +
    2.52 +	/* First check XSDT (but only on ACPI 2.0-compatible systems) */
    2.53 +
    2.54 +	if ((rsdp->revision >= 2) &&
    2.55 +	    (((struct acpi20_table_rsdp *)rsdp)->xsdt_address)) {
    2.56 +
    2.57 +		struct acpi_table_xsdt *mapped_xsdt = NULL;
    2.58 +
    2.59 +		sdt_pa = ((struct acpi20_table_rsdp *)rsdp)->xsdt_address;
    2.60 +
    2.61 +		/* map in just the header */
    2.62 +		header = (struct acpi_table_header *)
    2.63 +		    __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
    2.64 +
    2.65 +		if (!header) {
    2.66 +			printk(KERN_WARNING PREFIX
    2.67 +			       "Unable to map XSDT header\n");
    2.68 +			return -ENODEV;
    2.69 +		}
    2.70 +
    2.71 +		/* remap in the entire table before processing */
    2.72 +		mapped_xsdt = (struct acpi_table_xsdt *)
    2.73 +		    __acpi_map_table(sdt_pa, header->length);
    2.74 +		if (!mapped_xsdt) {
    2.75 +			printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
    2.76 +			return -ENODEV;
    2.77 +		}
    2.78 +		header = &mapped_xsdt->header;
    2.79 +
    2.80 +		if (strncmp(header->signature, "XSDT", 4)) {
    2.81 +			printk(KERN_WARNING PREFIX
    2.82 +			       "XSDT signature incorrect\n");
    2.83 +			return -ENODEV;
    2.84 +		}
    2.85 +
    2.86 +		if (acpi_table_compute_checksum(header, header->length)) {
    2.87 +			printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n");
    2.88 +			return -ENODEV;
    2.89 +		}
    2.90 +
    2.91 +		if (id < sdt_count) {
    2.92 +			header = (struct acpi_table_header *)
    2.93 +			   __acpi_map_table(mapped_xsdt->entry[id], sizeof(struct acpi_table_header));
    2.94 +		} else {
    2.95 +			printk(KERN_WARNING PREFIX
    2.96 +			       "Unable to disable entry %d\n",
    2.97 +			       id);
    2.98 +			return -ENODEV;
    2.99 +		}
   2.100 +	}
   2.101 +
   2.102 +	/* Then check RSDT */
   2.103 +
   2.104 +	else if (rsdp->rsdt_address) {
   2.105 +
   2.106 +		struct acpi_table_rsdt *mapped_rsdt = NULL;
   2.107 +
   2.108 +		sdt_pa = rsdp->rsdt_address;
   2.109 +
   2.110 +		/* map in just the header */
   2.111 +		header = (struct acpi_table_header *)
   2.112 +		    __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
   2.113 +		if (!header) {
   2.114 +			printk(KERN_WARNING PREFIX
   2.115 +			       "Unable to map RSDT header\n");
   2.116 +			return -ENODEV;
   2.117 +		}
   2.118 +
   2.119 +		/* remap in the entire table before processing */
   2.120 +		mapped_rsdt = (struct acpi_table_rsdt *)
   2.121 +		    __acpi_map_table(sdt_pa, header->length);
   2.122 +		if (!mapped_rsdt) {
   2.123 +			printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
   2.124 +			return -ENODEV;
   2.125 +		}
   2.126 +		header = &mapped_rsdt->header;
   2.127 +
   2.128 +		if (strncmp(header->signature, "RSDT", 4)) {
   2.129 +			printk(KERN_WARNING PREFIX
   2.130 +			       "RSDT signature incorrect\n");
   2.131 +			return -ENODEV;
   2.132 +		}
   2.133 +
   2.134 +		if (acpi_table_compute_checksum(header, header->length)) {
   2.135 +			printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n");
   2.136 +			return -ENODEV;
   2.137 +		}
   2.138 +		if (id < sdt_count) {
   2.139 +			header = (struct acpi_table_header *)
   2.140 +			   __acpi_map_table(mapped_rsdt->entry[id], sizeof(struct acpi_table_header));
   2.141 +		} else {
   2.142 +			printk(KERN_WARNING PREFIX
   2.143 +			       "Unable to disable entry %d\n",
   2.144 +			       id);
   2.145 +			return -ENODEV;
   2.146 +		}
   2.147 +	}
   2.148 +
   2.149 +	else {
   2.150 +		printk(KERN_WARNING PREFIX
   2.151 +		       "No System Description Table (RSDT/XSDT) specified in RSDP\n");
   2.152 +		return -ENODEV;
   2.153 +	}
   2.154 +
   2.155 +	memcpy(header->signature, "OEMx", 4);
   2.156 +	memcpy(header->oem_id, "xxxxxx", 6);
   2.157 +	memcpy(header->oem_id+1, table_name, 4);
   2.158 +	memcpy(header->oem_table_id, "Xen     ", 8);
   2.159 +	header->checksum = 0;
   2.160 +	header->checksum = generate_acpi_checksum(header, header->length);
   2.161 +
   2.162 +	return 0;
   2.163 +}
     3.1 --- a/xen/include/xen/acpi.h	Mon Jul 30 10:59:27 2007 +0100
     3.2 +++ b/xen/include/xen/acpi.h	Mon Jul 30 11:27:48 2007 +0100
     3.3 @@ -383,6 +383,7 @@ int acpi_boot_table_init (void);
     3.4  int acpi_numa_init (void);
     3.5  
     3.6  int acpi_table_init (void);
     3.7 +int acpi_table_disable(enum acpi_table_id table_id);
     3.8  int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler);
     3.9  int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header);
    3.10  int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
    3.11 @@ -535,6 +536,5 @@ static inline int acpi_get_pxm(acpi_hand
    3.12  #endif
    3.13  
    3.14  extern int pnpacpi_disabled;
    3.15 -extern unsigned char acpi_rsdp_rev;
    3.16  
    3.17  #endif /*_LINUX_ACPI_H*/