aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-12-19 16:12:08 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-12-20 13:54:43 -0500
commitfb0f2b40faff41f03acaa2ee6e6231fc96ca497c (patch)
tree10f2f69cb43d6440313bb3efdc53ca69334830c0 /drivers/pci
parent7e7a43c32a8970ea2bfc3d1af353dcb1a9237769 (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.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)
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
652static int pci_setup_device(struct pci_dev * dev) 655static 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, &region, res); 52 pcibios_resource_to_bus(dev, &region, 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)