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

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

Merge branch 'pci/enumeration' into next

* pci/enumeration:
  PCI: Include PCI-to-PCIe bridges as "Downstream Ports"
  PCI: Improve __pci_read_base() robustness
  PCI: Short-circuit pci_device_is_present() for disconnected devices
  PCI/MSI: Skip disabling disconnected devices
  PCI: Don't attempt config access to disconnected devices
  PCI: Add device disconnected state
  PCI: Export PCI device config accessors
parents d060c6fc 9b70ae49
Loading
Loading
Loading
Loading
+58 −1
Original line number Diff line number Diff line
@@ -700,7 +700,8 @@ static bool pcie_downstream_port(const struct pci_dev *dev)
	int type = pci_pcie_type(dev);

	return type == PCI_EXP_TYPE_ROOT_PORT ||
	       type == PCI_EXP_TYPE_DOWNSTREAM;
	       type == PCI_EXP_TYPE_DOWNSTREAM ||
	       type == PCI_EXP_TYPE_PCIE_BRIDGE;
}

bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
@@ -890,3 +891,59 @@ int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos,
	return ret;
}
EXPORT_SYMBOL(pcie_capability_clear_and_set_dword);

int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)
{
	if (pci_dev_is_disconnected(dev)) {
		*val = ~0;
		return -ENODEV;
	}
	return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
}
EXPORT_SYMBOL(pci_read_config_byte);

int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val)
{
	if (pci_dev_is_disconnected(dev)) {
		*val = ~0;
		return -ENODEV;
	}
	return pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
}
EXPORT_SYMBOL(pci_read_config_word);

int pci_read_config_dword(const struct pci_dev *dev, int where,
					u32 *val)
{
	if (pci_dev_is_disconnected(dev)) {
		*val = ~0;
		return -ENODEV;
	}
	return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
}
EXPORT_SYMBOL(pci_read_config_dword);

int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val)
{
	if (pci_dev_is_disconnected(dev))
		return -ENODEV;
	return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val);
}
EXPORT_SYMBOL(pci_write_config_byte);

int pci_write_config_word(const struct pci_dev *dev, int where, u16 val)
{
	if (pci_dev_is_disconnected(dev))
		return -ENODEV;
	return pci_bus_write_config_word(dev->bus, dev->devfn, where, val);
}
EXPORT_SYMBOL(pci_write_config_word);

int pci_write_config_dword(const struct pci_dev *dev, int where,
					 u32 val)
{
	if (pci_dev_is_disconnected(dev))
		return -ENODEV;
	return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
}
EXPORT_SYMBOL(pci_write_config_dword);
+6 −0
Original line number Diff line number Diff line
@@ -109,6 +109,12 @@ int pciehp_unconfigure_device(struct slot *p_slot)
				break;
			}
		}
		if (!presence) {
			pci_dev_set_disconnected(dev, NULL);
			if (pci_has_subordinate(dev))
				pci_walk_bus(dev->subordinate,
					     pci_dev_set_disconnected, NULL);
		}
		pci_stop_and_remove_bus_device(dev);
		/*
		 * Ensure that no new Requests will be generated from
+6 −1
Original line number Diff line number Diff line
@@ -298,7 +298,7 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
	struct pci_dev *dev = msi_desc_to_pci_dev(entry);

	if (dev->current_state != PCI_D0) {
	if (dev->current_state != PCI_D0 || pci_dev_is_disconnected(dev)) {
		/* Don't touch the hardware now */
	} else if (entry->msi_attrib.is_msix) {
		void __iomem *base = pci_msix_desc_addr(entry);
@@ -1001,6 +1001,11 @@ void pci_msix_shutdown(struct pci_dev *dev)
	if (!pci_msi_enable || !dev || !dev->msix_enabled)
		return;

	if (pci_dev_is_disconnected(dev)) {
		dev->msix_enabled = 0;
		return;
	}

	/* Return the device with MSI-X masked as initial states */
	for_each_pci_msi_entry(entry, dev) {
		/* Keep cached states to be restored */
+2 −0
Original line number Diff line number Diff line
@@ -4934,6 +4934,8 @@ bool pci_device_is_present(struct pci_dev *pdev)
{
	u32 v;

	if (pci_dev_is_disconnected(pdev))
		return false;
	return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0);
}
EXPORT_SYMBOL_GPL(pci_device_is_present);
+14 −0
Original line number Diff line number Diff line
@@ -274,6 +274,20 @@ struct pci_sriov {
	resource_size_t barsz[PCI_SRIOV_NUM_BARS];	/* VF BAR size */
};

/* pci_dev priv_flags */
#define PCI_DEV_DISCONNECTED 0

static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused)
{
	set_bit(PCI_DEV_DISCONNECTED, &dev->priv_flags);
	return 0;
}

static inline bool pci_dev_is_disconnected(const struct pci_dev *dev)
{
	return test_bit(PCI_DEV_DISCONNECTED, &dev->priv_flags);
}

#ifdef CONFIG_PCI_ATS
void pci_restore_ats_state(struct pci_dev *dev);
#else
Loading