Commit 47fcb6da authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'topic/stowe-cap-cleanup' into next

* topic/stowe-cap-cleanup:
  PCI: remove redundant capabilities checking in pci_{save, restore}_pcie_state
  PCI: add pci_pcie_cap2() check for PCIe feature capabilities >= v2
  PCI: remove redundant checking in PCI Express capability routines
  PCI: make pci_ltr_supported() static
parents cc2fa3fa 9cb604ed
Loading
Loading
Loading
Loading
+67 −48
Original line number Diff line number Diff line
@@ -253,6 +253,38 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
	return pos;
}

/**
 * pci_pcie_cap2 - query for devices' PCI_CAP_ID_EXP v2 capability structure
 * @dev: PCI device to check
 *
 * Like pci_pcie_cap() but also checks that the PCIe capability version is
 * >= 2.  Note that v1 capability structures could be sparse in that not
 * all register fields were required.  v2 requires the entire structure to
 * be present size wise, while still allowing for non-implemented registers
 * to exist but they must be hardwired to 0.
 *
 * Due to the differences in the versions of capability structures, one
 * must be careful not to try and access non-existant registers that may
 * exist in early versions - v1 - of Express devices.
 *
 * Returns the offset of the PCIe capability structure as long as the
 * capability version is >= 2; otherwise 0 is returned.
 */
static int pci_pcie_cap2(struct pci_dev *dev)
{
	u16 flags;
	int pos;

	pos = pci_pcie_cap(dev);
	if (pos) {
		pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
		if ((flags & PCI_EXP_FLAGS_VERS) < 2)
			pos = 0;
	}

	return pos;
}

/**
 * pci_find_ext_capability - Find an extended capability
 * @dev: PCI device to query
@@ -755,12 +787,6 @@ EXPORT_SYMBOL(pci_choose_state);
		((flags & PCI_EXP_FLAGS_VERS) > 1 ||	\
		 (type == PCI_EXP_TYPE_ROOT_PORT ||	\
		  type == PCI_EXP_TYPE_RC_EC))
#define pcie_cap_has_devctl2(type, flags)		\
		((flags & PCI_EXP_FLAGS_VERS) > 1)
#define pcie_cap_has_lnkctl2(type, flags)		\
		((flags & PCI_EXP_FLAGS_VERS) > 1)
#define pcie_cap_has_sltctl2(type, flags)		\
		((flags & PCI_EXP_FLAGS_VERS) > 1)

static struct pci_cap_saved_state *pci_find_saved_cap(
	struct pci_dev *pci_dev, char cap)
@@ -803,13 +829,14 @@ static int pci_save_pcie_state(struct pci_dev *dev)
		pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
	if (pcie_cap_has_rtctl(dev->pcie_type, flags))
		pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
	if (pcie_cap_has_devctl2(dev->pcie_type, flags))

	pos = pci_pcie_cap2(dev);
	if (!pos)
		return 0;

	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
	if (pcie_cap_has_lnkctl2(dev->pcie_type, flags))
	pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
	if (pcie_cap_has_sltctl2(dev->pcie_type, flags))
	pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);

	return 0;
}

@@ -836,11 +863,13 @@ static void pci_restore_pcie_state(struct pci_dev *dev)
		pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
	if (pcie_cap_has_rtctl(dev->pcie_type, flags))
		pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
	if (pcie_cap_has_devctl2(dev->pcie_type, flags))

	pos = pci_pcie_cap2(dev);
	if (!pos)
		return;

	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
	if (pcie_cap_has_lnkctl2(dev->pcie_type, flags))
	pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
	if (pcie_cap_has_sltctl2(dev->pcie_type, flags))
	pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]);
}

@@ -1916,7 +1945,7 @@ void pci_enable_ari(struct pci_dev *dev)
{
	int pos;
	u32 cap;
	u16 flags, ctrl;
	u16 ctrl;
	struct pci_dev *bridge;

	if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
@@ -1927,18 +1956,14 @@ void pci_enable_ari(struct pci_dev *dev)
		return;

	bridge = dev->bus->self;
	if (!bridge || !pci_is_pcie(bridge))
	if (!bridge)
		return;

	pos = pci_pcie_cap(bridge);
	/* ARI is a PCIe cap v2 feature */
	pos = pci_pcie_cap2(bridge);
	if (!pos)
		return;

	/* ARI is a PCIe v2 feature */
	pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags);
	if ((flags & PCI_EXP_FLAGS_VERS) < 2)
		return;

	pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
	if (!(cap & PCI_EXP_DEVCAP2_ARI))
		return;
@@ -1951,7 +1976,7 @@ void pci_enable_ari(struct pci_dev *dev)
}

/**
 * pci_enable_ido - enable ID-based ordering on a device
 * pci_enable_ido - enable ID-based Ordering on a device
 * @dev: the PCI device
 * @type: which types of IDO to enable
 *
@@ -1964,7 +1989,8 @@ void pci_enable_ido(struct pci_dev *dev, unsigned long type)
	int pos;
	u16 ctrl;

	pos = pci_pcie_cap(dev);
	/* ID-based Ordering is a PCIe cap v2 feature */
	pos = pci_pcie_cap2(dev);
	if (!pos)
		return;

@@ -1987,10 +2013,8 @@ void pci_disable_ido(struct pci_dev *dev, unsigned long type)
	int pos;
	u16 ctrl;

	if (!pci_is_pcie(dev))
		return;

	pos = pci_pcie_cap(dev);
	/* ID-based Ordering is a PCIe cap v2 feature */
	pos = pci_pcie_cap2(dev);
	if (!pos)
		return;

@@ -2029,10 +2053,8 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
	u16 ctrl;
	int ret;

	if (!pci_is_pcie(dev))
		return -ENOTSUPP;

	pos = pci_pcie_cap(dev);
	/* OBFF is a PCIe cap v2 feature */
	pos = pci_pcie_cap2(dev);
	if (!pos)
		return -ENOTSUPP;

@@ -2082,10 +2104,8 @@ void pci_disable_obff(struct pci_dev *dev)
	int pos;
	u16 ctrl;

	if (!pci_is_pcie(dev))
		return;

	pos = pci_pcie_cap(dev);
	/* OBFF is a PCIe cap v2 feature */
	pos = pci_pcie_cap2(dev);
	if (!pos)
		return;

@@ -2102,15 +2122,13 @@ EXPORT_SYMBOL(pci_disable_obff);
 * RETURNS:
 * True if @dev supports latency tolerance reporting, false otherwise.
 */
bool pci_ltr_supported(struct pci_dev *dev)
static bool pci_ltr_supported(struct pci_dev *dev)
{
	int pos;
	u32 cap;

	if (!pci_is_pcie(dev))
		return false;

	pos = pci_pcie_cap(dev);
	/* LTR is a PCIe cap v2 feature */
	pos = pci_pcie_cap2(dev);
	if (!pos)
		return false;

@@ -2118,7 +2136,6 @@ bool pci_ltr_supported(struct pci_dev *dev)

	return cap & PCI_EXP_DEVCAP2_LTR;
}
EXPORT_SYMBOL(pci_ltr_supported);

/**
 * pci_enable_ltr - enable latency tolerance reporting
@@ -2139,7 +2156,8 @@ int pci_enable_ltr(struct pci_dev *dev)
	if (!pci_ltr_supported(dev))
		return -ENOTSUPP;

	pos = pci_pcie_cap(dev);
	/* LTR is a PCIe cap v2 feature */
	pos = pci_pcie_cap2(dev);
	if (!pos)
		return -ENOTSUPP;

@@ -2174,7 +2192,8 @@ void pci_disable_ltr(struct pci_dev *dev)
	if (!pci_ltr_supported(dev))
		return;

	pos = pci_pcie_cap(dev);
	/* LTR is a PCIe cap v2 feature */
	pos = pci_pcie_cap2(dev);
	if (!pos)
		return;

+0 −1
Original line number Diff line number Diff line
@@ -911,7 +911,6 @@ enum pci_obff_signal_type {
int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type);
void pci_disable_obff(struct pci_dev *dev);

bool pci_ltr_supported(struct pci_dev *dev);
int pci_enable_ltr(struct pci_dev *dev);
void pci_disable_ltr(struct pci_dev *dev);
int pci_set_ltr(struct pci_dev *dev, int snoop_lat_ns, int nosnoop_lat_ns);
+6 −0
Original line number Diff line number Diff line
@@ -521,6 +521,12 @@
#define PCI_EXP_RTSTA		32	/* Root Status */
#define PCI_EXP_RTSTA_PME	0x10000 /* PME status */
#define PCI_EXP_RTSTA_PENDING	0x20000 /* PME pending */
/*
 * Note that the following PCI Express 'Capability Structure' registers
 * were introduced with 'Capability Version' 0x2 (v2).  These registers
 * do not exist on devices with Capability Version 1.  Use pci_pcie_cap2()
 * to use these fields safely.
 */
#define PCI_EXP_DEVCAP2		36	/* Device Capabilities 2 */
#define  PCI_EXP_DEVCAP2_ARI	0x20	/* Alternative Routing-ID */
#define  PCI_EXP_DEVCAP2_LTR	0x800	/* Latency tolerance reporting */