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

Commit fd6e7321 authored by Yoichi Yuasa's avatar Yoichi Yuasa Committed by Greg Kroah-Hartman
Browse files

PCI: fix IDE legacy mode resources



I got the following error on MIPS Cobalt.

PCI: Unable to reserve I/O region #1:8@f00001f0 for device 0000:00:09.1
pata_via 0000:00:09.1: failed to request/iomap BARs for port 0 (errno=-16)
PCI: Unable to reserve I/O region #3:8@f0000170 for device 0000:00:09.1
pata_via 0000:00:09.1: failed to request/iomap BARs for port 1 (errno=-16)
pata_via 0000:00:09.1: no available native port

The legacy mode IDE resources set the following order.

pci_setup_device()
    Legacy mode ATA controllers have fixed addresses.
    IDE resources: 0x1F0-0x1F7, 0x3F6, 0x170-0x177, 0x376
    |
    V
pcibios_fixup_bus()
    MIPS Cobalt PCI bus regions have the -0x10000000 offset from PCI resources.
    pcibios_fixup_bus() fix PCI bus regions.
    0x1F0 - 0x10000000 = 0xF00001F0
    |
    V
ata_pci_init_one()
    PCI: Unable to reserve I/O region #1:8@f00001f0 for device 0000:00:09.1

In some architectures, PCI bus regions have the offset from PCI resources. 
For this reason, pci_setup_device() should set PCI bus regions to
dev->resource[].

[akpm@linux-foundation.org: use struct initialiser]
Signed-off-by: default avatarYoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Greg KH <greg@kroah.com>
Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent cbf5d9e6
Loading
Loading
Loading
Loading
+36 −12
Original line number Diff line number Diff line
@@ -744,22 +744,46 @@ static int pci_setup_device(struct pci_dev * dev)
		 */
		if (class == PCI_CLASS_STORAGE_IDE) {
			u8 progif;
			struct pci_bus_region region;

			pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
			if ((progif & 1) == 0) {
				dev->resource[0].start = 0x1F0;
				dev->resource[0].end = 0x1F7;
				dev->resource[0].flags = LEGACY_IO_RESOURCE;
				dev->resource[1].start = 0x3F6;
				dev->resource[1].end = 0x3F6;
				dev->resource[1].flags = LEGACY_IO_RESOURCE;
				struct resource resource = {
					.start = 0x1F0,
					.end = 0x1F7,
					.flags = LEGACY_IO_RESOURCE,
				};

				pcibios_resource_to_bus(dev, &region, &resource);
				dev->resource[0].start = region.start;
				dev->resource[0].end = region.end;
				dev->resource[0].flags = resource.flags;
				resource.start = 0x3F6;
				resource.end = 0x3F6;
				resource.flags = LEGACY_IO_RESOURCE;
				pcibios_resource_to_bus(dev, &region, &resource);
				dev->resource[1].start = region.start;
				dev->resource[1].end = region.end;
				dev->resource[1].flags = resource.flags;
			}
			if ((progif & 4) == 0) {
				dev->resource[2].start = 0x170;
				dev->resource[2].end = 0x177;
				dev->resource[2].flags = LEGACY_IO_RESOURCE;
				dev->resource[3].start = 0x376;
				dev->resource[3].end = 0x376;
				dev->resource[3].flags = LEGACY_IO_RESOURCE;
				struct resource resource = {
					.start = 0x170,
					.end = 0x177,
					.flags = LEGACY_IO_RESOURCE,
				};

				pcibios_resource_to_bus(dev, &region, &resource);
				dev->resource[2].start = region.start;
				dev->resource[2].end = region.end;
				dev->resource[2].flags = resource.flags;
				resource.start = 0x376;
				resource.end = 0x376;
				resource.flags = LEGACY_IO_RESOURCE;
				pcibios_resource_to_bus(dev, &region, &resource);
				dev->resource[3].start = region.start;
				dev->resource[3].end = region.end;
				dev->resource[3].flags = resource.flags;
			}
		}
		break;