Merge branch 'apei' into release
authorLen Brown <len.brown@intel.com>
Fri, 30 Mar 2012 20:12:23 +0000 (16:12 -0400)
committerLen Brown <len.brown@intel.com>
Fri, 30 Mar 2012 20:14:02 +0000 (16:14 -0400)
Conflicts:
drivers/acpi/apei/apei-base.c

This was a conflict between

15afae604651d4e17652d2ffb56f5e36f991cfef
(CPI, APEI: Fix incorrect APEI register bit width check and usage)

and

653f4b538f66d37db560e0f56af08117136d29b7
(ACPICA: Expand OSL memory read/write interfaces to 64 bits)

The former changed a parameter in the call to acpi_os_read_memory64()
and the later replaced all calls to acpi_os_read_memory64()
with calls to acpi_os_read_memory().

Signed-off-by: Len Brown <len.brown@intel.com>
1  2 
drivers/acpi/apei/apei-base.c

index ca773683d87ea6f9637eda63aa58da5265327c29,1d3656f6919f4b7543acf14338dd0954438fd4e7..5577762daee1d7d22a8dbf49a27cf02ead2e54a4
@@@ -558,33 -558,48 +558,48 @@@ void apei_resources_release(struct apei
  }
  EXPORT_SYMBOL_GPL(apei_resources_release);
  
- static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr)
+ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr,
+                               u32 *access_bit_width)
  {
-       u32 width, space_id;
+       u32 bit_width, bit_offset, access_size_code, space_id;
  
-       width = reg->bit_width;
+       bit_width = reg->bit_width;
+       bit_offset = reg->bit_offset;
+       access_size_code = reg->access_width;
        space_id = reg->space_id;
        /* Handle possible alignment issues */
        memcpy(paddr, &reg->address, sizeof(*paddr));
        if (!*paddr) {
                pr_warning(FW_BUG APEI_PFX
-                          "Invalid physical address in GAR [0x%llx/%u/%u]\n",
-                          *paddr, width, space_id);
+                          "Invalid physical address in GAR [0x%llx/%u/%u/%u/%u]\n",
+                          *paddr, bit_width, bit_offset, access_size_code,
+                          space_id);
                return -EINVAL;
        }
  
-       if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) {
+       if (access_size_code < 1 || access_size_code > 4) {
                pr_warning(FW_BUG APEI_PFX
-                          "Invalid bit width in GAR [0x%llx/%u/%u]\n",
-                          *paddr, width, space_id);
+                          "Invalid access size code in GAR [0x%llx/%u/%u/%u/%u]\n",
+                          *paddr, bit_width, bit_offset, access_size_code,
+                          space_id);
+               return -EINVAL;
+       }
+       *access_bit_width = 1UL << (access_size_code + 2);
+       if ((bit_width + bit_offset) > *access_bit_width) {
+               pr_warning(FW_BUG APEI_PFX
+                          "Invalid bit width + offset in GAR [0x%llx/%u/%u/%u/%u]\n",
+                          *paddr, bit_width, bit_offset, access_size_code,
+                          space_id);
                return -EINVAL;
        }
  
        if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY &&
            space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
                pr_warning(FW_BUG APEI_PFX
-                          "Invalid address space type in GAR [0x%llx/%u/%u]\n",
-                          *paddr, width, space_id);
+                          "Invalid address space type in GAR [0x%llx/%u/%u/%u/%u]\n",
+                          *paddr, bit_width, bit_offset, access_size_code,
+                          space_id);
                return -EINVAL;
        }
  
  int apei_read(u64 *val, struct acpi_generic_address *reg)
  {
        int rc;
+       u32 access_bit_width;
        u64 address;
        acpi_status status;
  
-       rc = apei_check_gar(reg, &address);
+       rc = apei_check_gar(reg, &address, &access_bit_width);
        if (rc)
                return rc;
  
        *val = 0;
        switch(reg->space_id) {
        case ACPI_ADR_SPACE_SYSTEM_MEMORY:
-               status = acpi_os_read_memory((acpi_physical_address)
-                                            address, val, reg->bit_width);
 -              status = acpi_os_read_memory64((acpi_physical_address) address,
++              status = acpi_os_read_memory((acpi_physical_address) address,
+                                              val, access_bit_width);
                if (ACPI_FAILURE(status))
                        return -EIO;
                break;
        case ACPI_ADR_SPACE_SYSTEM_IO:
-               status = acpi_os_read_port(address, (u32 *)val, reg->bit_width);
+               status = acpi_os_read_port(address, (u32 *)val,
+                                          access_bit_width);
                if (ACPI_FAILURE(status))
                        return -EIO;
                break;
@@@ -627,22 -644,23 +644,23 @@@ EXPORT_SYMBOL_GPL(apei_read)
  int apei_write(u64 val, struct acpi_generic_address *reg)
  {
        int rc;
+       u32 access_bit_width;
        u64 address;
        acpi_status status;
  
-       rc = apei_check_gar(reg, &address);
+       rc = apei_check_gar(reg, &address, &access_bit_width);
        if (rc)
                return rc;
  
        switch (reg->space_id) {
        case ACPI_ADR_SPACE_SYSTEM_MEMORY:
-               status = acpi_os_write_memory((acpi_physical_address)
-                                             address, val, reg->bit_width);
 -              status = acpi_os_write_memory64((acpi_physical_address) address,
++              status = acpi_os_write_memory((acpi_physical_address) address,
+                                               val, access_bit_width);
                if (ACPI_FAILURE(status))
                        return -EIO;
                break;
        case ACPI_ADR_SPACE_SYSTEM_IO:
-               status = acpi_os_write_port(address, val, reg->bit_width);
+               status = acpi_os_write_port(address, val, access_bit_width);
                if (ACPI_FAILURE(status))
                        return -EIO;
                break;
@@@ -661,23 -679,24 +679,24 @@@ static int collect_res_callback(struct 
        struct apei_resources *resources = data;
        struct acpi_generic_address *reg = &entry->register_region;
        u8 ins = entry->instruction;
+       u32 access_bit_width;
        u64 paddr;
        int rc;
  
        if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER))
                return 0;
  
-       rc = apei_check_gar(reg, &paddr);
+       rc = apei_check_gar(reg, &paddr, &access_bit_width);
        if (rc)
                return rc;
  
        switch (reg->space_id) {
        case ACPI_ADR_SPACE_SYSTEM_MEMORY:
                return apei_res_add(&resources->iomem, paddr,
-                                   reg->bit_width / 8);
+                                   access_bit_width / 8);
        case ACPI_ADR_SPACE_SYSTEM_IO:
                return apei_res_add(&resources->ioport, paddr,
-                                   reg->bit_width / 8);
+                                   access_bit_width / 8);
        default:
                return -EINVAL;
        }