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
This commit is contained in:
commit
47fcb6da65
3 changed files with 73 additions and 49 deletions
|
@ -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))
|
||||
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++]);
|
||||
|
||||
pos = pci_pcie_cap2(dev);
|
||||
if (!pos)
|
||||
return 0;
|
||||
|
||||
pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
|
||||
pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
|
||||
pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -836,12 +863,14 @@ 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))
|
||||
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++]);
|
||||
|
||||
pos = pci_pcie_cap2(dev);
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
|
||||
pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
|
||||
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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue