ACPI / PM: Fix device power state value after transitions to D3cold
[linux-3.10.git] / drivers / acpi / tables.c
index fec1ae3..2572d97 100644 (file)
@@ -62,6 +62,18 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
                }
                break;
 
+       case ACPI_MADT_TYPE_LOCAL_X2APIC:
+               {
+                       struct acpi_madt_local_x2apic *p =
+                           (struct acpi_madt_local_x2apic *)header;
+                       printk(KERN_INFO PREFIX
+                              "X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n",
+                              p->local_apic_id, p->uid,
+                              (p->lapic_flags & ACPI_MADT_ENABLED) ?
+                              "enabled" : "disabled");
+               }
+               break;
+
        case ACPI_MADT_TYPE_IO_APIC:
                {
                        struct acpi_madt_io_apic *p =
@@ -116,6 +128,24 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
                }
                break;
 
+       case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
+               {
+                       u16 polarity, trigger;
+                       struct acpi_madt_local_x2apic_nmi *p =
+                           (struct acpi_madt_local_x2apic_nmi *)header;
+
+                       polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK;
+                       trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2;
+
+                       printk(KERN_INFO PREFIX
+                              "X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n",
+                              p->uid,
+                              mps_inti_flags_polarity[polarity],
+                              mps_inti_flags_trigger[trigger],
+                              p->lint);
+               }
+               break;
+
        case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
                {
                        struct acpi_madt_local_apic_override *p =
@@ -183,6 +213,9 @@ acpi_table_parse_entries(char *id,
        unsigned long table_end;
        acpi_size tbl_size;
 
+       if (acpi_disabled)
+               return -ENODEV;
+
        if (!handler)
                return -EINVAL;
 
@@ -207,10 +240,17 @@ acpi_table_parse_entries(char *id,
               table_end) {
                if (entry->type == entry_id
                    && (!max_entries || count++ < max_entries))
-                       if (handler(entry, table_end)) {
-                               early_acpi_os_unmap_memory((char *)table_header, tbl_size);
-                               return -EINVAL;
-                       }
+                       if (handler(entry, table_end))
+                               goto err;
+
+               /*
+                * If entry->length is 0, break from this loop to avoid
+                * infinite loop.
+                */
+               if (entry->length == 0) {
+                       pr_err(PREFIX "[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
+                       goto err;
+               }
 
                entry = (struct acpi_subtable_header *)
                    ((unsigned long)entry + entry->length);
@@ -222,6 +262,9 @@ acpi_table_parse_entries(char *id,
 
        early_acpi_os_unmap_memory((char *)table_header, tbl_size);
        return count;
+err:
+       early_acpi_os_unmap_memory((char *)table_header, tbl_size);
+       return -EINVAL;
 }
 
 int __init
@@ -247,6 +290,9 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler)
        struct acpi_table_header *table = NULL;
        acpi_size tbl_size;
 
+       if (acpi_disabled)
+               return -ENODEV;
+
        if (!handler)
                return -EINVAL;