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

Commit b194dbf5 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/kevin-bus-to-resource' into next

* pci/kevin-bus-to-resource:
  PCI: Unset resource if initial BAR value is invalid
  PCI: Consolidate calls to pcibios_bus_to_resource() in __pci_read_base()
  PCI: Add 0x prefix to BAR register position in __pci_read_base()
parents 755bda3f cf4d1cf5
Loading
Loading
Loading
Loading
+25 −6
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
{
	u32 l, sz, mask;
	u16 orig_cmd;
	struct pci_bus_region region;
	struct pci_bus_region region, inverted_region;
	bool bar_too_big = false, bar_disabled = false;

	mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
@@ -250,12 +250,10 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
			pci_write_config_dword(dev, pos + 4, 0);
			region.start = 0;
			region.end = sz64;
			pcibios_bus_to_resource(dev, res, &region);
			bar_disabled = true;
		} else {
			region.start = l64;
			region.end = l64 + sz64;
			pcibios_bus_to_resource(dev, res, &region);
		}
	} else {
		sz = pci_size(l, sz, mask);
@@ -265,7 +263,28 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,

		region.start = l;
		region.end = l + sz;
	}

	pcibios_bus_to_resource(dev, res, &region);
	pcibios_resource_to_bus(dev, &inverted_region, res);

	/*
	 * If "A" is a BAR value (a bus address), "bus_to_resource(A)" is
	 * the corresponding resource address (the physical address used by
	 * the CPU.  Converting that resource address back to a bus address
	 * should yield the original BAR value:
	 *
	 *     resource_to_bus(bus_to_resource(A)) == A
	 *
	 * If it doesn't, CPU accesses to "bus_to_resource(A)" will not
	 * be claimed by the device.
	 */
	if (inverted_region.start != region.start) {
		dev_info(&dev->dev, "reg 0x%x: initial BAR value %pa invalid; forcing reassignment\n",
			 pos, &region.start);
		res->flags |= IORESOURCE_UNSET;
		res->end -= res->start;
		res->start = 0;
	}

	goto out;
@@ -278,9 +297,9 @@ out:
		pci_write_config_word(dev, PCI_COMMAND, orig_cmd);

	if (bar_too_big)
		dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", pos);
		dev_err(&dev->dev, "reg 0x%x: can't handle 64-bit BAR\n", pos);
	if (res->flags && !bar_disabled)
		dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res);
		dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res);

	return (res->flags & IORESOURCE_MEM_64) ? 1 : 0;
}