Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb0f2b40 authored by Ralf Baechle's avatar Ralf Baechle Committed by Greg Kroah-Hartman
Browse files

PCI legacy resource fix



Since commit 368c73d4 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: default avatarRalf Baechle <ralf@linux-mips.org>
Acked-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7e7a43c3
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -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;
+17 −2
Original line number Diff line number Diff line
@@ -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)
+3 −0
Original line number Diff line number Diff line
@@ -91,6 +91,9 @@ struct resource_list {
#define IORESOURCE_ROM_COPY		(1<<2)	/* ROM is alloc'd copy, resource field overlaid */
#define IORESOURCE_ROM_BIOS_COPY	(1<<3)	/* ROM is BIOS copy, resource field overlaid */

/* PCI control bits.  Shares IORESOURCE_BITS with above PCI ROM.  */
#define IORESOURCE_PCI_FIXED		(1<<4)	/* Do not move resource */

/* PC/ISA/whatever - the normal PC address spaces: IO and memory */
extern struct resource ioport_resource;
extern struct resource iomem_resource;