diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2006-12-19 16:12:08 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-12-20 13:54:43 -0500 |
commit | fb0f2b40faff41f03acaa2ee6e6231fc96ca497c (patch) | |
tree | 10f2f69cb43d6440313bb3efdc53ca69334830c0 /drivers/pci | |
parent | 7e7a43c32a8970ea2bfc3d1af353dcb1a9237769 (diff) |
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.c | 11 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 19 |
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) | |||
649 | * Returns 0 on success and -1 if unknown type of device (not normal, bridge | 649 | * Returns 0 on success and -1 if unknown type of device (not normal, bridge |
650 | * or CardBus). | 650 | * or CardBus). |
651 | */ | 651 | */ |
652 | |||
653 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) | ||
654 | |||
652 | static int pci_setup_device(struct pci_dev * dev) | 655 | static int pci_setup_device(struct pci_dev * dev) |
653 | { | 656 | { |
654 | u32 class; | 657 | u32 class; |
@@ -692,18 +695,18 @@ static int pci_setup_device(struct pci_dev * dev) | |||
692 | if ((progif & 1) == 0) { | 695 | if ((progif & 1) == 0) { |
693 | dev->resource[0].start = 0x1F0; | 696 | dev->resource[0].start = 0x1F0; |
694 | dev->resource[0].end = 0x1F7; | 697 | dev->resource[0].end = 0x1F7; |
695 | dev->resource[0].flags = IORESOURCE_IO; | 698 | dev->resource[0].flags = LEGACY_IO_RESOURCE; |
696 | dev->resource[1].start = 0x3F6; | 699 | dev->resource[1].start = 0x3F6; |
697 | dev->resource[1].end = 0x3F6; | 700 | dev->resource[1].end = 0x3F6; |
698 | dev->resource[1].flags = IORESOURCE_IO; | 701 | dev->resource[1].flags = LEGACY_IO_RESOURCE; |
699 | } | 702 | } |
700 | if ((progif & 4) == 0) { | 703 | if ((progif & 4) == 0) { |
701 | dev->resource[2].start = 0x170; | 704 | dev->resource[2].start = 0x170; |
702 | dev->resource[2].end = 0x177; | 705 | dev->resource[2].end = 0x177; |
703 | dev->resource[2].flags = IORESOURCE_IO; | 706 | dev->resource[2].flags = LEGACY_IO_RESOURCE; |
704 | dev->resource[3].start = 0x376; | 707 | dev->resource[3].start = 0x376; |
705 | dev->resource[3].end = 0x376; | 708 | dev->resource[3].end = 0x376; |
706 | dev->resource[3].flags = IORESOURCE_IO; | 709 | dev->resource[3].flags = LEGACY_IO_RESOURCE; |
707 | } | 710 | } |
708 | } | 711 | } |
709 | break; | 712 | 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) | |||
33 | u32 new, check, mask; | 33 | u32 new, check, mask; |
34 | int reg; | 34 | int reg; |
35 | 35 | ||
36 | /* Ignore resources for unimplemented BARs and unused resource slots | 36 | /* |
37 | for 64 bit BARs. */ | 37 | * Ignore resources for unimplemented BARs and unused resource slots |
38 | * for 64 bit BARs. | ||
39 | */ | ||
38 | if (!res->flags) | 40 | if (!res->flags) |
39 | return; | 41 | return; |
40 | 42 | ||
43 | /* | ||
44 | * Ignore non-moveable resources. This might be legacy resources for | ||
45 | * which no functional BAR register exists or another important | ||
46 | * system resource we should better not move around in system address | ||
47 | * space. | ||
48 | */ | ||
49 | if (res->flags & IORESOURCE_PCI_FIXED) | ||
50 | return; | ||
51 | |||
41 | pcibios_resource_to_bus(dev, ®ion, res); | 52 | pcibios_resource_to_bus(dev, ®ion, res); |
42 | 53 | ||
43 | pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for " | 54 | 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) | |||
212 | resource_size_t r_align; | 223 | resource_size_t r_align; |
213 | 224 | ||
214 | r = &dev->resource[i]; | 225 | r = &dev->resource[i]; |
226 | |||
227 | if (r->flags & IORESOURCE_PCI_FIXED) | ||
228 | continue; | ||
229 | |||
215 | r_align = r->end - r->start; | 230 | r_align = r->end - r->start; |
216 | 231 | ||
217 | if (!(r->flags) || r->parent) | 232 | if (!(r->flags) || r->parent) |