summaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorRalf Baechle2006-12-19 22:12:08 +0100
committerGreg Kroah-Hartman2006-12-20 19:54:43 +0100
commitfb0f2b40faff41f03acaa2ee6e6231fc96ca497c (patch)
tree10f2f69cb43d6440313bb3efdc53ca69334830c0 /drivers/pci
parentPCI: don't export device IDs to userspace (diff)
downloadkernel-qcow2-linux-fb0f2b40faff41f03acaa2ee6e6231fc96ca497c.tar.gz
kernel-qcow2-linux-fb0f2b40faff41f03acaa2ee6e6231fc96ca497c.tar.xz
kernel-qcow2-linux-fb0f2b40faff41f03acaa2ee6e6231fc96ca497c.zip
PCI legacy resource fix
Since commit 368c73d4f689dae0807d0a2aa74c61fd2b9b075f the kernel will try to update the non-writeable BAR registers 0..3 of PIIX4 IDE adapters if pci_assign_unassigned_resources() is used to do full resource assignment of the bus. This fails because in the PIIX4 these BAR registers have implicitly assumed values and read back as zero; it used to work because the kernel used to just write zero to that register the read back value did match what was written. The fix is a new resource flag IORESOURCE_PCI_FIXED used to mark a resource as non-movable. This will also be useful to keep other import system resources from being moved around - for example system consoles on PCI busses. [akpm@osdl.org: cleanup] Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Acked-by: Alan Cox <alan@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/probe.c11
-rw-r--r--drivers/pci/setup-res.c19
2 files changed, 24 insertions, 6 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6a3c1e728900..1ae9c3f50ffa 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -649,6 +649,9 @@ static void pci_read_irq(struct pci_dev *dev)
* Returns 0 on success and -1 if unknown type of device (not normal, bridge
* or CardBus).
*/
+
+#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
+
static int pci_setup_device(struct pci_dev * dev)
{
u32 class;
@@ -692,18 +695,18 @@ static int pci_setup_device(struct pci_dev * dev)
if ((progif & 1) == 0) {
dev->resource[0].start = 0x1F0;
dev->resource[0].end = 0x1F7;
- dev->resource[0].flags = IORESOURCE_IO;
+ dev->resource[0].flags = LEGACY_IO_RESOURCE;
dev->resource[1].start = 0x3F6;
dev->resource[1].end = 0x3F6;
- dev->resource[1].flags = IORESOURCE_IO;
+ dev->resource[1].flags = LEGACY_IO_RESOURCE;
}
if ((progif & 4) == 0) {
dev->resource[2].start = 0x170;
dev->resource[2].end = 0x177;
- dev->resource[2].flags = IORESOURCE_IO;
+ dev->resource[2].flags = LEGACY_IO_RESOURCE;
dev->resource[3].start = 0x376;
dev->resource[3].end = 0x376;
- dev->resource[3].flags = IORESOURCE_IO;
+ dev->resource[3].flags = LEGACY_IO_RESOURCE;
}
}
break;
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index ab78e4bbdd83..cb4ced3560e9 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -33,11 +33,22 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
u32 new, check, mask;
int reg;
- /* Ignore resources for unimplemented BARs and unused resource slots
- for 64 bit BARs. */
+ /*
+ * Ignore resources for unimplemented BARs and unused resource slots
+ * for 64 bit BARs.
+ */
if (!res->flags)
return;
+ /*
+ * Ignore non-moveable resources. This might be legacy resources for
+ * which no functional BAR register exists or another important
+ * system resource we should better not move around in system address
+ * space.
+ */
+ if (res->flags & IORESOURCE_PCI_FIXED)
+ return;
+
pcibios_resource_to_bus(dev, &region, res);
pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for "
@@ -212,6 +223,10 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
resource_size_t r_align;
r = &dev->resource[i];
+
+ if (r->flags & IORESOURCE_PCI_FIXED)
+ continue;
+
r_align = r->end - r->start;
if (!(r->flags) || r->parent)