ia64/PCI: Keep CPU physical (not virtual) addresses in shadow ROM resource
authorBjorn Helgaas <bhelgaas@google.com>
Wed, 2 Mar 2016 22:06:32 +0000 (16:06 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Sat, 12 Mar 2016 12:00:29 +0000 (06:00 -0600)
A struct resource contains CPU physical addresses, not virtual addresses.
But sn_acpi_slot_fixup() and sn_io_slot_fixup() stored the virtual address
of a shadow ROM copy in the resource.  To compensate, pci_map_rom() had a
special case that returned the resource address directly rather than
calling ioremap() on it.

When we're using a shadow copy in RAM or PROM, disable the ROM BAR and
release the address space it was consuming.

Store the CPU physical (not virtual) address in the shadow ROM resource,
and mark the resource as IORESOURCE_ROM_SHADOW so we use the normal
pci_map_rom() path that ioremaps the copy.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
arch/ia64/sn/kernel/io_acpi_init.c
arch/ia64/sn/kernel/io_init.c

index 815c29163e1d4bc18f6cb474a23154eaa83cbaf4..231234c8d1133a8e593b2c5312cdb95141ecc4c6 100644 (file)
@@ -430,7 +430,7 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
        struct pcidev_info *pcidev_info = NULL;
        struct sn_irq_info *sn_irq_info = NULL;
        struct resource *res;
-       size_t image_size, size;
+       size_t size;
 
        if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) {
                panic("%s:  Failure obtaining pcidev_info for %s\n",
@@ -444,13 +444,17 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
                 * of the shadowed copy, and the actual length of the ROM image.
                 */
                size = pci_resource_len(dev, PCI_ROM_RESOURCE);
-               addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
-                              size);
-               image_size = pci_get_rom_size(dev, addr, size);
+
                res = &dev->resource[PCI_ROM_RESOURCE];
-               res->start = (unsigned long) addr;
-               res->end = (unsigned long) addr + image_size - 1;
-               res->flags |= IORESOURCE_ROM_BIOS_COPY;
+
+               pci_disable_rom(dev);
+               if (res->parent)
+                       release_resource(res);
+
+               res->start = pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE];
+               res->end = res->start + size - 1;
+               res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
+                            IORESOURCE_PCI_FIXED;
        }
        sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
 }
index 0227e202b6bb136e5cf47241b5d3477f1a34b7fd..c15a41e2d1f2e85662fbfeaa811c7bb90d71e745 100644 (file)
@@ -185,8 +185,7 @@ sn_io_slot_fixup(struct pci_dev *dev)
                if (size == 0)
                        continue;
 
-               res->start = ioremap(pcidev_info->pdi_pio_mapped_addr[idx],
-                                    size + 1);
+               res->start = pcidev_info->pdi_pio_mapped_addr[idx];
                res->end = addr + size;
 
                /*
@@ -201,18 +200,12 @@ sn_io_slot_fixup(struct pci_dev *dev)
                else
                        insert_resource(&iomem_resource, res);
                /*
-                * If ROM, set the actual ROM image size, and mark as
-                * shadowed in PROM.
+                * If ROM, mark as shadowed in PROM.
                 */
                if (idx == PCI_ROM_RESOURCE) {
-                       size_t image_size;
-                       void __iomem *rom;
-
-                       rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE),
-                                     size + 1);
-                       image_size = pci_get_rom_size(dev, rom, size + 1);
-                       res->end = res->start + image_size - 1;
-                       res->flags |= IORESOURCE_ROM_BIOS_COPY;
+                       pci_disable_rom(dev);
+                       res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
+                                    IORESOURCE_PCI_FIXED;
                }
        }