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

Commit 341f3a2b authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branches 'pci/enumeration', 'pci/hotplug', 'pci/resource' and 'pci/virtualization' into next

* pci/enumeration:
  PCI: Generate uppercase hex for modalias var in uevent

* pci/hotplug:
  PCI: pciehp: Handle surprise add even if surprise removal isn't supported

* pci/resource:
  PCI: Fix infinite loop with ROM image of size 0

* pci/virtualization:
  PCI: Add Wellsburg (X99) to Intel PCH root port ACS quirk
  PCI: Add DMA alias quirk for Adaptec 3405
  PCI: Add ACS quirk for Emulex NICs
  PCI: Mark AMD/ATI VGA devices that don't reset on D3hot->D0 transition
  PCI: Add flag for devices that don't reset on D3hot->D0 transition
  PCI: Mark Atheros AR93xx to avoid bus reset
  PCI: Add flag for devices where we can't use bus reset
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -532,8 +532,6 @@ static void interrupt_event_handler(struct work_struct *work)
		pciehp_green_led_off(p_slot);
		break;
	case INT_PRESENCE_ON:
		if (!HP_SUPR_RM(ctrl))
			break;
		ctrl_dbg(ctrl, "Surprise Insertion\n");
		handle_surprise_event(p_slot);
		break;
+1 −1
Original line number Diff line number Diff line
@@ -1383,7 +1383,7 @@ static int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
	if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev)))
		return -ENOMEM;

	if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
	if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X",
			   pdev->vendor, pdev->device,
			   pdev->subsystem_vendor, pdev->subsystem_device,
			   (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
+37 −5
Original line number Diff line number Diff line
@@ -3199,7 +3199,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
{
	u16 csr;

	if (!dev->pm_cap)
	if (!dev->pm_cap || dev->dev_flags & PCI_DEV_FLAGS_NO_PM_RESET)
		return -ENOTTY;

	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr);
@@ -3273,7 +3273,8 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
{
	struct pci_dev *pdev;

	if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self)
	if (pci_is_root_bus(dev->bus) || dev->subordinate ||
	    !dev->bus->self || dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET)
		return -ENOTTY;

	list_for_each_entry(pdev, &dev->bus->devices, bus_list)
@@ -3307,7 +3308,8 @@ static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe)
{
	struct pci_dev *pdev;

	if (dev->subordinate || !dev->slot)
	if (dev->subordinate || !dev->slot ||
	    dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET)
		return -ENOTTY;

	list_for_each_entry(pdev, &dev->bus->devices, bus_list)
@@ -3559,6 +3561,20 @@ int pci_try_reset_function(struct pci_dev *dev)
}
EXPORT_SYMBOL_GPL(pci_try_reset_function);

/* Do any devices on or below this bus prevent a bus reset? */
static bool pci_bus_resetable(struct pci_bus *bus)
{
	struct pci_dev *dev;

	list_for_each_entry(dev, &bus->devices, bus_list) {
		if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
		    (dev->subordinate && !pci_bus_resetable(dev->subordinate)))
			return false;
	}

	return true;
}

/* Lock devices from the top of the tree down */
static void pci_bus_lock(struct pci_bus *bus)
{
@@ -3609,6 +3625,22 @@ static int pci_bus_trylock(struct pci_bus *bus)
	return 0;
}

/* Do any devices on or below this slot prevent a bus reset? */
static bool pci_slot_resetable(struct pci_slot *slot)
{
	struct pci_dev *dev;

	list_for_each_entry(dev, &slot->bus->devices, bus_list) {
		if (!dev->slot || dev->slot != slot)
			continue;
		if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
		    (dev->subordinate && !pci_bus_resetable(dev->subordinate)))
			return false;
	}

	return true;
}

/* Lock devices from the top of the tree down */
static void pci_slot_lock(struct pci_slot *slot)
{
@@ -3730,7 +3762,7 @@ static int pci_slot_reset(struct pci_slot *slot, int probe)
{
	int rc;

	if (!slot)
	if (!slot || !pci_slot_resetable(slot))
		return -ENOTTY;

	if (!probe)
@@ -3822,7 +3854,7 @@ EXPORT_SYMBOL_GPL(pci_try_reset_slot);

static int pci_bus_reset(struct pci_bus *bus, int probe)
{
	if (!bus->self)
	if (!bus->self || !pci_bus_resetable(bus))
		return -ENOTTY;

	if (probe)
+78 −0
Original line number Diff line number Diff line
@@ -3028,6 +3028,41 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_REALTEK, 0x8169,
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID,
			 quirk_broken_intx_masking);

static void quirk_no_bus_reset(struct pci_dev *dev)
{
	dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET;
}

/*
 * Atheros AR93xx chips do not behave after a bus reset.  The device will
 * throw a Link Down error on AER-capable systems and regardless of AER,
 * config space of the device is never accessible again and typically
 * causes the system to hang or reset when access is attempted.
 * http://www.spinics.net/lists/linux-pci/msg34797.html
 */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset);

static void quirk_no_pm_reset(struct pci_dev *dev)
{
	/*
	 * We can't do a bus reset on root bus devices, but an ineffective
	 * PM reset may be better than nothing.
	 */
	if (!pci_is_root_bus(dev->bus))
		dev->dev_flags |= PCI_DEV_FLAGS_NO_PM_RESET;
}

/*
 * Some AMD/ATI GPUS (HD8570 - Oland) report that a D3hot->D0 transition
 * causes a reset (i.e., they advertise NoSoftRst-).  This transition seems
 * to have no effect on the device: it retains the framebuffer contents and
 * monitor sync.  Advertising this support makes other layers, like VFIO,
 * assume pci_reset_function() is viable for this device.  Mark it as
 * unavailable to skip it when testing reset methods.
 */
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_ATI, PCI_ANY_ID,
			       PCI_CLASS_DISPLAY_VGA, 8, quirk_no_pm_reset);

#ifdef CONFIG_ACPI
/*
 * Apple: Shutdown Cactus Ridge Thunderbolt controller.
@@ -3527,6 +3562,44 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON,
			 PCI_DEVICE_ID_JMICRON_JMB388_ESD,
			 quirk_dma_func1_alias);

/*
 * Some devices DMA with the wrong devfn, not just the wrong function.
 * quirk_fixed_dma_alias() uses this table to create fixed aliases, where
 * the alias is "fixed" and independent of the device devfn.
 *
 * For example, the Adaptec 3405 is a PCIe card with an Intel 80333 I/O
 * processor.  To software, this appears as a PCIe-to-PCI/X bridge with a
 * single device on the secondary bus.  In reality, the single exposed
 * device at 0e.0 is the Address Translation Unit (ATU) of the controller
 * that provides a bridge to the internal bus of the I/O processor.  The
 * controller supports private devices, which can be hidden from PCI config
 * space.  In the case of the Adaptec 3405, a private device at 01.0
 * appears to be the DMA engine, which therefore needs to become a DMA
 * alias for the device.
 */
static const struct pci_device_id fixed_dma_alias_tbl[] = {
	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285,
			 PCI_VENDOR_ID_ADAPTEC2, 0x02bb), /* Adaptec 3405 */
	  .driver_data = PCI_DEVFN(1, 0) },
	{ 0 }
};

static void quirk_fixed_dma_alias(struct pci_dev *dev)
{
	const struct pci_device_id *id;

	id = pci_match_id(fixed_dma_alias_tbl, dev);
	if (id) {
		dev->dma_alias_devfn = id->driver_data;
		dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN;
		dev_info(&dev->dev, "Enabling fixed DMA alias to %02x.%d\n",
			 PCI_SLOT(dev->dma_alias_devfn),
			 PCI_FUNC(dev->dma_alias_devfn));
	}
}

DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADAPTEC2, 0x0285, quirk_fixed_dma_alias);

/*
 * A few PCIe-to-PCI bridges fail to expose a PCIe capability, resulting in
 * using the wrong DMA alias for the device.  Some of these devices can be
@@ -3630,6 +3703,9 @@ static const u16 pci_quirk_intel_pch_acs_ids[] = {
	0x9c98, 0x9c99, 0x9c9a, 0x9c9b,
	/* Patsburg (X79) PCH */
	0x1d10, 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e,
	/* Wellsburg (X99) PCH */
	0x8d10, 0x8d11, 0x8d12, 0x8d13, 0x8d14, 0x8d15, 0x8d16, 0x8d17,
	0x8d18, 0x8d19, 0x8d1a, 0x8d1b, 0x8d1c, 0x8d1d, 0x8d1e,
};

static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev)
@@ -3713,6 +3789,8 @@ static const struct pci_dev_acs_enabled {
	{ PCI_VENDOR_ID_INTEL, 0x1551, pci_quirk_mf_endpoint_acs },
	{ PCI_VENDOR_ID_INTEL, 0x1558, pci_quirk_mf_endpoint_acs },
	{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },
	{ 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */
	{ 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */
	{ 0 }
};

+4 −3
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
{
	void __iomem *image;
	int last_image;
	unsigned length;

	image = rom;
	do {
@@ -93,9 +94,9 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
		if (readb(pds + 3) != 'R')
			break;
		last_image = readb(pds + 21) & 0x80;
		/* this length is reliable */
		image += readw(pds + 16) * 512;
	} while (!last_image);
		length = readw(pds + 16);
		image += length * 512;
	} while (length && !last_image);

	/* never return a size larger than the PCI resource window */
	/* there are known ROMs that get the size wrong */
Loading