2012-08-01 15:55:03

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

From: Jiang Liu <[email protected]>

As suggested by Bjorn Helgaas and Don Dutile in threads
http://www.spinics.net/lists/linux-pci/msg15663.html, we could improve access
to PCIe capabilities register in to way:
1) cache content of PCIe Capabilities Register into struct pce_dev to avoid
repeatedly reading this register because it's read only.
2) provide access functions for PCIe Capabilities registers to hide differences
among PCIe base specifications, so the caller don't need to handle those
differences.

This patch set applies to
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci-next

And you could pull the change set from
https://github.com/jiangliu/linux.git topic/pcie-cap

v2: 1) change return value to 0 when the register is not implemented by
V1 PCIe devices.
2) Change all driver in the source tree to use the new interfaces.

v3: 1) be more aggresive to remoce if (pci_is_pcie(dev)) check according to
Don's suggestion.
2) Don't cache MSI/MSI-x information in PCIe capabilities flag register
according to Kenji's suggestion.
3) add new pci_pcie_capability_change_word/dword() to reduce duplicated
code.

Jiang Liu (29):
PCI: add PCIe capabilities access functions to hide differences among
PCIe specs
PCI/core: use PCIe capabilities access functions to simplify
implementation
PCI/hotplug: use PCIe capabilities access functions to simplify
implementation
PCI/portdrv: use PCIe capabilities access functions to simplify
implementation
PCI/pciehp: use PCIe capabilities access functions to simplify
implementation
PCI/PME: use PCIe capabilities access functions to simplify
implementation
PCI/AER: use PCIe capabilities access functions to simplify
implementation
PCI/ASPM: use PCIe capabilities access functions to simplify
implementation
PCI/ARM: use PCIe capabilities access functions to simplify
implementation
PCI/MIPS: use PCIe capabilities access functions to simplify
implementation
PCI/tile: use PCIe capabilities access functions to simplify
implementation
PCI/r8169: use PCIe capabilities access functions to simplify
implementation
PCI/broadcom: use PCIe capabilities access functions to simplify
implementation
PCI/igb: use PCIe capabilities access functions to simplify
implementation
PCI/vxge: use PCIe capabilities access functions to simplify
implementation
PCI/mlx4: use PCIe capabilities access functions to simplify
implementation
PCI/niu: use PCIe capabilities access functions to simplify
implementation
PCI/myri10ge: use PCIe capabilities access functions to simplify
implementation
PCI/chelsio: use PCIe capabilities access functions to simplify
implementation
PCI/atl1c: use PCIe capabilities access functions to simplify
implementation
PCI/ath9k: use PCIe capabilities access functions to simplify
implementation
PCI/iwl: use PCIe capabilities access functions to simplify
implementation
PCI/mthca: use PCIe capabilities access functions to simplify
implementation
PCI/qib: use PCIe capabilities access functions to simplify
implementation
PCI/qla: use PCIe capabilities access functions to simplify
implementation
PCI/radeon: use PCIe capabilities access functions to simplify
implementation
PCI/tsi721: use PCIe capabilities access functions to simplify
implementation
PCI/et131x: use PCIe capabilities access functions to simplify
implementation
PCI/rtl8192e: use PCIe capabilities access functions to simplify
implementation

Yijing Wang (3):
PCI: add pcie_flags_reg into struct pci_dev to cache PCIe
capabilities register
PCI: introduce pci_pcie_type(dev) to replace pci_dev->pcie_type
PCI: remove unused field pcie_type from struct pci_dev

arch/arm/mach-tegra/pcie.c | 13 +-
arch/mips/pci/pci-octeon.c | 15 +-
arch/powerpc/platforms/powernv/pci-ioda.c | 2 +-
arch/tile/kernel/pci.c | 25 +-
drivers/gpu/drm/radeon/evergreen.c | 10 +-
drivers/infiniband/hw/mthca/mthca_reset.c | 8 +-
drivers/infiniband/hw/qib/qib_pcie.c | 40 +--
drivers/iommu/intel-iommu.c | 6 +-
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 25 +-
drivers/net/ethernet/broadcom/tg3.c | 60 ++--
drivers/net/ethernet/chelsio/cxgb3/t3_hw.c | 19 +-
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 11 +-
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 10 +-
drivers/net/ethernet/intel/e1000e/netdev.c | 27 +-
drivers/net/ethernet/intel/igb/igb_main.c | 12 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +-
drivers/net/ethernet/mellanox/mlx4/reset.c | 8 +-
drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 39 +--
drivers/net/ethernet/neterion/vxge/vxge-config.c | 4 +-
.../net/ethernet/qlogic/netxen/netxen_nic_main.c | 2 +-
drivers/net/ethernet/realtek/r8169.c | 44 +--
drivers/net/ethernet/sun/niu.c | 18 +-
drivers/net/wireless/ath/ath9k/pci.c | 21 +-
drivers/net/wireless/iwlegacy/common.h | 5 +-
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 +-
drivers/net/wireless/rtlwifi/pci.c | 8 +-
drivers/pci/access.c | 195 ++++++++++++
drivers/pci/hotplug/pciehp_acpi.c | 6 +-
drivers/pci/hotplug/pciehp_hpc.c | 12 +-
drivers/pci/hotplug/pcihp_slot.c | 20 +-
drivers/pci/iov.c | 6 +-
drivers/pci/pci.c | 324 ++++----------------
drivers/pci/pcie/aer/aer_inject.c | 2 +-
drivers/pci/pcie/aer/aerdrv.c | 24 +-
drivers/pci/pcie/aer/aerdrv_acpi.c | 2 +-
drivers/pci/pcie/aer/aerdrv_core.c | 47 +--
drivers/pci/pcie/aspm.c | 111 +++----
drivers/pci/pcie/pme.c | 28 +-
drivers/pci/pcie/portdrv_bus.c | 2 +-
drivers/pci/pcie/portdrv_core.c | 19 +-
drivers/pci/pcie/portdrv_pci.c | 18 +-
drivers/pci/probe.c | 29 +-
drivers/pci/quirks.c | 9 +-
drivers/pci/search.c | 2 +-
drivers/rapidio/devices/tsi721.c | 19 +-
drivers/scsi/qla2xxx/qla_init.c | 4 +-
drivers/scsi/qla2xxx/qla_nx.c | 8 +-
drivers/scsi/qla4xxx/ql4_nx.c | 4 +-
drivers/staging/et131x/et131x.c | 19 +-
drivers/staging/rtl8192e/rtl8192e/rtl_pci.c | 8 +-
include/linux/pci.h | 21 +-
include/linux/pci_regs.h | 2 +
53 files changed, 553 insertions(+), 828 deletions(-)

--
1.7.9.5


2012-08-01 15:55:11

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 01/32] PCI: add pcie_flags_reg into struct pci_dev to cache PCIe capabilities register

From: Yijing Wang <[email protected]>

From: Yijing Wang <[email protected]>

Since PCI Express Capabilities Register is read only, cache its value
into struct pci_dev to avoid repeatedly calling pci_read_config_*().

Signed-off-by: Yijing Wang <[email protected]>
Signed-off-by: Jiang Liu <[email protected]>
---
drivers/pci/probe.c | 3 ++-
include/linux/pci.h | 10 ++++++++++
2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6c143b4..ba4d855 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -929,7 +929,8 @@ void set_pcie_port_type(struct pci_dev *pdev)
pdev->is_pcie = 1;
pdev->pcie_cap = pos;
pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
- pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
+ pdev->pcie_flags_reg = reg16;
+ pdev->pcie_type = pci_pcie_type(pdev);
pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, &reg16);
pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD;
}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5faa831..95662b2 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -258,6 +258,7 @@ struct pci_dev {
u8 pcie_mpss:3; /* PCI-E Max Payload Size Supported */
u8 rom_base_reg; /* which config register controls the ROM */
u8 pin; /* which interrupt pin this device uses */
+ u16 pcie_flags_reg; /* cached PCI-E Capabilities Register */

struct pci_driver *driver; /* which driver has allocated this device */
u64 dma_mask; /* Mask of the bits of bus address this
@@ -1650,6 +1651,15 @@ static inline bool pci_is_pcie(struct pci_dev *dev)
return !!pci_pcie_cap(dev);
}

+/**
+ * pci_pcie_type - get the PCIe device/port type
+ * @dev: PCI device
+ */
+static inline int pci_pcie_type(const struct pci_dev *dev)
+{
+ return (dev->pcie_flags_reg & PCI_EXP_FLAGS_TYPE) >> 4;
+}
+
void pci_request_acs(void);
bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
bool pci_acs_path_enabled(struct pci_dev *start,
--
1.7.9.5

2012-08-01 15:55:40

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 02/32] PCI: introduce pci_pcie_type(dev) to replace pci_dev->pcie_type

From: Yijing Wang <[email protected]>

From: Yijing Wang <[email protected]>

Introduce an inline function pci_pcie_type(dev) to extract PCIe
device type from pci_dev->pcie_flags_reg field, and prepare for
removing pci_dev->pcie_type.

Signed-off-by: Yijing Wang <[email protected]>
Signed-off-by: Jiang Liu <[email protected]>
---
arch/powerpc/platforms/powernv/pci-ioda.c | 2 +-
drivers/iommu/intel-iommu.c | 6 +--
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +-
.../net/ethernet/qlogic/netxen/netxen_nic_main.c | 2 +-
drivers/pci/iov.c | 6 +--
drivers/pci/pci.c | 26 ++++++------
drivers/pci/pcie/aer/aer_inject.c | 2 +-
drivers/pci/pcie/aer/aerdrv.c | 7 ++--
drivers/pci/pcie/aer/aerdrv_acpi.c | 2 +-
drivers/pci/pcie/aer/aerdrv_core.c | 2 +-
drivers/pci/pcie/aspm.c | 42 ++++++++++----------
drivers/pci/pcie/pme.c | 6 +--
drivers/pci/pcie/portdrv_bus.c | 2 +-
drivers/pci/pcie/portdrv_core.c | 4 +-
drivers/pci/pcie/portdrv_pci.c | 8 ++--
drivers/pci/probe.c | 9 +++--
drivers/pci/search.c | 2 +-
17 files changed, 67 insertions(+), 63 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 9cda6a1..b46e1da 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -855,7 +855,7 @@ static void __devinit pnv_ioda_setup_PEs(struct pci_bus *bus)
if (pe == NULL)
continue;
/* Leaving the PCIe domain ... single PE# */
- if (dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE)
pnv_ioda_setup_bus_PE(dev, pe);
else if (dev->subordinate)
pnv_ioda_setup_PEs(dev->subordinate);
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 2fb7d15..8612271 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2350,7 +2350,7 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup)
return 0;
if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
return 0;
- } else if (pdev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
+ } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
return 0;

/*
@@ -3545,10 +3545,10 @@ found:
struct pci_dev *bridge = bus->self;

if (!bridge || !pci_is_pcie(bridge) ||
- bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
+ pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
return 0;

- if (bridge->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
+ if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT) {
for (i = 0; i < atsru->devices_cnt; i++)
if (atsru->devices[i] == bridge)
return 1;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index bf20457..565772e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7470,7 +7470,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
goto skip_bad_vf_detection;

bdev = pdev->bus->self;
- while (bdev && (bdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT))
+ while (bdev && (pci_pcie_type(bdev) != PCI_EXP_TYPE_ROOT_PORT))
bdev = bdev->bus->self;

if (!bdev)
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index 342b3a7..01d6141 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -1382,7 +1382,7 @@ static void netxen_mask_aer_correctable(struct netxen_adapter *adapter)
adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP)
return;

- if (root->pcie_type != PCI_EXP_TYPE_ROOT_PORT)
+ if (pci_pcie_type(root) != PCI_EXP_TYPE_ROOT_PORT)
return;

aer_pos = pci_find_ext_capability(root, PCI_EXT_CAP_ID_ERR);
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 74bbaf8..aeccc91 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -433,8 +433,8 @@ static int sriov_init(struct pci_dev *dev, int pos)
struct resource *res;
struct pci_dev *pdev;

- if (dev->pcie_type != PCI_EXP_TYPE_RC_END &&
- dev->pcie_type != PCI_EXP_TYPE_ENDPOINT)
+ if (pci_pcie_type(dev) != PCI_EXP_TYPE_RC_END &&
+ pci_pcie_type(dev) != PCI_EXP_TYPE_ENDPOINT)
return -ENODEV;

pci_read_config_word(dev, pos + PCI_SRIOV_CTRL, &ctrl);
@@ -503,7 +503,7 @@ found:
iov->self = dev;
pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
- if (dev->pcie_type == PCI_EXP_TYPE_RC_END)
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END)
iov->link = PCI_DEVFN(PCI_SLOT(dev->devfn), iov->link);

if (pdev)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index f3ea977..28eb55b 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -885,7 +885,7 @@ static struct pci_cap_saved_state *pci_find_saved_cap(

static int pci_save_pcie_state(struct pci_dev *dev)
{
- int pos, i = 0;
+ int type, pos, i = 0;
struct pci_cap_saved_state *save_state;
u16 *cap;
u16 flags;
@@ -903,13 +903,14 @@ static int pci_save_pcie_state(struct pci_dev *dev)

pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);

- if (pcie_cap_has_devctl(dev->pcie_type, flags))
+ type = pci_pcie_type(dev);
+ if (pcie_cap_has_devctl(type, flags))
pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]);
- if (pcie_cap_has_lnkctl(dev->pcie_type, flags))
+ if (pcie_cap_has_lnkctl(type, flags))
pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
- if (pcie_cap_has_sltctl(dev->pcie_type, flags))
+ if (pcie_cap_has_sltctl(type, flags))
pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
- if (pcie_cap_has_rtctl(dev->pcie_type, flags))
+ if (pcie_cap_has_rtctl(type, flags))
pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);

pos = pci_pcie_cap2(dev);
@@ -924,7 +925,7 @@ static int pci_save_pcie_state(struct pci_dev *dev)

static void pci_restore_pcie_state(struct pci_dev *dev)
{
- int i = 0, pos;
+ int i = 0, pos, type;
struct pci_cap_saved_state *save_state;
u16 *cap;
u16 flags;
@@ -937,13 +938,14 @@ static void pci_restore_pcie_state(struct pci_dev *dev)

pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);

- if (pcie_cap_has_devctl(dev->pcie_type, flags))
+ type = pci_pcie_type(dev);
+ if (pcie_cap_has_devctl(type, flags))
pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]);
- if (pcie_cap_has_lnkctl(dev->pcie_type, flags))
+ if (pcie_cap_has_lnkctl(type, flags))
pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]);
- if (pcie_cap_has_sltctl(dev->pcie_type, flags))
+ if (pcie_cap_has_sltctl(type, flags))
pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
- if (pcie_cap_has_rtctl(dev->pcie_type, flags))
+ if (pcie_cap_has_rtctl(type, flags))
pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);

pos = pci_pcie_cap2(dev);
@@ -2459,8 +2461,8 @@ bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags)
acs_flags &= (PCI_ACS_RR | PCI_ACS_CR |
PCI_ACS_EC | PCI_ACS_DT);

- if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM ||
- pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM ||
+ pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ||
pdev->multifunction) {
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ACS);
if (!pos)
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 5222986..4e24cb8 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -288,7 +288,7 @@ static struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
while (1) {
if (!pci_is_pcie(dev))
break;
- if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
return dev;
if (!dev->bus->self)
break;
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 58ad791..f7c6245 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -81,10 +81,11 @@ bool pci_aer_available(void)
static int set_device_error_reporting(struct pci_dev *dev, void *data)
{
bool enable = *((bool *)data);
+ int type = pci_pcie_type(dev);

- if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) ||
- (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) ||
- (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) {
+ if ((type == PCI_EXP_TYPE_ROOT_PORT) ||
+ (type == PCI_EXP_TYPE_UPSTREAM) ||
+ (type == PCI_EXP_TYPE_DOWNSTREAM)) {
if (enable)
pci_enable_pcie_error_reporting(dev);
else
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index 124f20f..5194a7d 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -60,7 +60,7 @@ static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data)
p = (struct acpi_hest_aer_common *)(hest_hdr + 1);
if (p->flags & ACPI_HEST_GLOBAL) {
if ((pci_is_pcie(info->pci_dev) &&
- info->pci_dev->pcie_type == pcie_type) || bridge)
+ pci_pcie_type(info->pci_dev) == pcie_type) || bridge)
ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
} else
if (hest_match_pci(p, info->pci_dev))
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 0ca0535..f551534 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -465,7 +465,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)

if (driver && driver->reset_link) {
status = driver->reset_link(udev);
- } else if (udev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) {
+ } else if (pci_pcie_type(udev) == PCI_EXP_TYPE_DOWNSTREAM) {
status = default_downstream_reset_link(udev);
} else {
dev_printk(KERN_DEBUG, &dev->dev,
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index b500840..2591603 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -412,7 +412,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
* do ASPM for now.
*/
list_for_each_entry(child, &linkbus->devices, bus_list) {
- if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
+ if (pci_pcie_type(child) == PCI_EXP_TYPE_PCI_BRIDGE) {
link->aspm_disable = ASPM_STATE_ALL;
break;
}
@@ -425,8 +425,8 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
struct aspm_latency *acceptable =
&link->acceptable[PCI_FUNC(child->devfn)];

- if (child->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
- child->pcie_type != PCI_EXP_TYPE_LEG_END)
+ if (pci_pcie_type(child) != PCI_EXP_TYPE_ENDPOINT &&
+ pci_pcie_type(child) != PCI_EXP_TYPE_LEG_END)
continue;

pos = pci_pcie_cap(child);
@@ -552,7 +552,7 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
INIT_LIST_HEAD(&link->children);
INIT_LIST_HEAD(&link->link);
link->pdev = pdev;
- if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) {
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM) {
struct pcie_link_state *parent;
parent = pdev->bus->parent->self->link_state;
if (!parent) {
@@ -585,12 +585,12 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)

if (!pci_is_pcie(pdev) || pdev->link_state)
return;
- if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
- pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
+ if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT &&
+ pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM)
return;

/* VIA has a strange chipset, root port is under a bridge */
- if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT &&
pdev->bus->self)
return;

@@ -647,8 +647,8 @@ static void pcie_update_aspm_capable(struct pcie_link_state *root)
if (link->root != root)
continue;
list_for_each_entry(child, &linkbus->devices, bus_list) {
- if ((child->pcie_type != PCI_EXP_TYPE_ENDPOINT) &&
- (child->pcie_type != PCI_EXP_TYPE_LEG_END))
+ if ((pci_pcie_type(child) != PCI_EXP_TYPE_ENDPOINT) &&
+ (pci_pcie_type(child) != PCI_EXP_TYPE_LEG_END))
continue;
pcie_aspm_check_latency(child);
}
@@ -663,8 +663,8 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)

if (!pci_is_pcie(pdev) || !parent || !parent->link_state)
return;
- if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
- (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
+ if ((pci_pcie_type(parent) != PCI_EXP_TYPE_ROOT_PORT) &&
+ (pci_pcie_type(parent) != PCI_EXP_TYPE_DOWNSTREAM))
return;

down_read(&pci_bus_sem);
@@ -704,8 +704,8 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev)

if (aspm_disabled || !pci_is_pcie(pdev) || !link)
return;
- if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
- (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
+ if ((pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) &&
+ (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM))
return;
/*
* Devices changed PM state, we should recheck if latency
@@ -729,8 +729,8 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
if (aspm_policy != POLICY_POWERSAVE)
return;

- if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
- (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
+ if ((pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) &&
+ (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM))
return;

down_read(&pci_bus_sem);
@@ -757,8 +757,8 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,
if (!pci_is_pcie(pdev))
return;

- if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
- pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ||
+ pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM)
parent = pdev;
if (!parent || !parent->link_state)
return;
@@ -933,8 +933,8 @@ void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)
struct pcie_link_state *link_state = pdev->link_state;

if (!pci_is_pcie(pdev) ||
- (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
- pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
+ (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT &&
+ pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
return;

if (link_state->aspm_support)
@@ -950,8 +950,8 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
struct pcie_link_state *link_state = pdev->link_state;

if (!pci_is_pcie(pdev) ||
- (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
- pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
+ (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT &&
+ pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
return;

if (link_state->aspm_support)
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index 001f1b7..30897bf 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -120,7 +120,7 @@ static bool pcie_pme_from_pci_bridge(struct pci_bus *bus, u8 devfn)
if (!dev)
return false;

- if (pci_is_pcie(dev) && dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
+ if (pci_is_pcie(dev) && pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE) {
down_read(&pci_bus_sem);
if (pcie_pme_walk_bus(bus))
found = true;
@@ -335,13 +335,13 @@ static void pcie_pme_mark_devices(struct pci_dev *port)
struct pci_dev *dev;

/* Check if this is a root port event collector. */
- if (port->pcie_type != PCI_EXP_TYPE_RC_EC || !bus)
+ if (pci_pcie_type(port) != PCI_EXP_TYPE_RC_EC || !bus)
return;

down_read(&pci_bus_sem);
list_for_each_entry(dev, &bus->devices, bus_list)
if (pci_is_pcie(dev)
- && dev->pcie_type == PCI_EXP_TYPE_RC_END)
+ && pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END)
pcie_pme_set_native(dev, NULL);
up_read(&pci_bus_sem);
}
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
index 18bf90f..67be55a 100644
--- a/drivers/pci/pcie/portdrv_bus.c
+++ b/drivers/pci/pcie/portdrv_bus.c
@@ -38,7 +38,7 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
return 0;

if ((driver->port_type != PCIE_ANY_PORT) &&
- (driver->port_type != pciedev->port->pcie_type))
+ (driver->port_type != pci_pcie_type(pciedev->port)))
return 0;

return 1;
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 75915b3..bf320a9 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -298,7 +298,7 @@ static int get_port_device_capability(struct pci_dev *dev)
services |= PCIE_PORT_SERVICE_VC;
/* Root ports are capable of generating PME too */
if ((cap_mask & PCIE_PORT_SERVICE_PME)
- && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
+ && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
services |= PCIE_PORT_SERVICE_PME;
/*
* Disable PME interrupt on this port in case it's been enabled
@@ -336,7 +336,7 @@ static int pcie_device_init(struct pci_dev *pdev, int service, int irq)
device->release = release_pcie_device; /* callback to free pcie dev */
dev_set_name(device, "%s:pcie%02x",
pci_name(pdev),
- get_descriptor_id(pdev->pcie_type, service));
+ get_descriptor_id(pci_pcie_type(pdev), service));
device->parent = &pdev->dev;
device_enable_async_suspend(device);

diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 3a7eefc..24d1463 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -95,7 +95,7 @@ static int pcie_port_resume_noirq(struct device *dev)
* which breaks ACPI-based runtime wakeup on PCI Express, so clear those
* bits now just in case (shouldn't hurt).
*/
- if(pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT)
pcie_clear_root_pme_status(pdev);
return 0;
}
@@ -186,9 +186,9 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev,
int status;

if (!pci_is_pcie(dev) ||
- ((dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
- (dev->pcie_type != PCI_EXP_TYPE_UPSTREAM) &&
- (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)))
+ ((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) &&
+ (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM) &&
+ (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM)))
return -ENODEV;

if (!dev->irq && dev->pin) {
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ba4d855..1d52a43 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1384,9 +1384,9 @@ static int only_one_child(struct pci_bus *bus)

if (!parent || !pci_is_pcie(parent))
return 0;
- if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+ if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT)
return 1;
- if (parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM &&
+ if (pci_pcie_type(parent) == PCI_EXP_TYPE_DOWNSTREAM &&
!pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
return 1;
return 0;
@@ -1463,7 +1463,7 @@ static int pcie_find_smpss(struct pci_dev *dev, void *data)
*/
if (dev->is_hotplug_bridge && (!list_is_singular(&dev->bus->devices) ||
(dev->bus->self &&
- dev->bus->self->pcie_type != PCI_EXP_TYPE_ROOT_PORT)))
+ pci_pcie_type(dev->bus->self) != PCI_EXP_TYPE_ROOT_PORT)))
*smpss = 0;

if (*smpss > dev->pcie_mpss)
@@ -1479,7 +1479,8 @@ static void pcie_write_mps(struct pci_dev *dev, int mps)
if (pcie_bus_config == PCIE_BUS_PERFORMANCE) {
mps = 128 << dev->pcie_mpss;

- if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && dev->bus->self)
+ if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT &&
+ dev->bus->self)
/* For "Performance", the assumption is made that
* downstream communication will never be larger than
* the MRRS. So, the MPS only needs to be configured
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 993d4a0..621b162 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -41,7 +41,7 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
continue;
}
/* PCI device should connect to a PCIe bridge */
- if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) {
+ if (pci_pcie_type(pdev) != PCI_EXP_TYPE_PCI_BRIDGE) {
/* Busted hardware? */
WARN_ON_ONCE(1);
return NULL;
--
1.7.9.5

2012-08-01 15:55:49

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 03/32] PCI: remove unused field pcie_type from struct pci_dev

From: Yijing Wang <[email protected]>

From: Yijing Wang <[email protected]>

With introduction of pci_pcie_type(), pci_dev->pcie_type field becomes
redundant, so remove it.

Signed-off-by: Yijing Wang <[email protected]>
Signed-off-by: Jiang Liu <[email protected]>
---
drivers/pci/probe.c | 1 -
include/linux/pci.h | 1 -
2 files changed, 2 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 1d52a43..8bcc985 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -930,7 +930,6 @@ void set_pcie_port_type(struct pci_dev *pdev)
pdev->pcie_cap = pos;
pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
pdev->pcie_flags_reg = reg16;
- pdev->pcie_type = pci_pcie_type(pdev);
pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, &reg16);
pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD;
}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 95662b2..9807da5 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -254,7 +254,6 @@ struct pci_dev {
u8 revision; /* PCI revision, low byte of class word */
u8 hdr_type; /* PCI header type (`multi' flag masked out) */
u8 pcie_cap; /* PCI-E capability offset */
- u8 pcie_type:4; /* PCI-E device/port type */
u8 pcie_mpss:3; /* PCI-E Max Payload Size Supported */
u8 rom_base_reg; /* which config register controls the ROM */
u8 pin; /* which interrupt pin this device uses */
--
1.7.9.5

2012-08-01 15:55:57

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 04/32] PCI: add PCIe capabilities access functions to hide differences among PCIe specs

From: Jiang Liu <[email protected]>

Introduce several configuration access functions for PCIe capabilities
registers to hide differences among PCIe Base Spec versions.

Function pci_pcie_capability_read_word/dword() stores the PCIe Capabilities
register value by the passed parameter val. If related PCIe Capabilities
register is not implemented on the PCIe device, the passed parameter val
will be set 0.

Function pci_pcie_capability_write_word/dowrd() writes the value to PCIe
Capability register.

Function pci_pcie_capability_change_word sets and/or clears bits
of a PCIe Capability register.

Function pci_pcie_capability_reg_implemeneted() checks whether a Capabilities
register is implemented by the PCIe device.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/pci/access.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/pci.h | 10 +++
include/linux/pci_regs.h | 2 +
3 files changed, 207 insertions(+)

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index ba91a7e..1f8c9e8 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -469,3 +469,198 @@ void pci_cfg_access_unlock(struct pci_dev *dev)
raw_spin_unlock_irqrestore(&pci_lock, flags);
}
EXPORT_SYMBOL_GPL(pci_cfg_access_unlock);
+
+static inline int pci_pcie_cap_version(const struct pci_dev *dev)
+{
+ return dev->pcie_flags_reg & PCI_EXP_FLAGS_VERS;
+}
+
+static inline bool pci_pcie_cap_has_devctl(const struct pci_dev *dev)
+{
+ return true;
+}
+
+static inline bool pci_pcie_cap_has_lnkctl(const struct pci_dev *dev)
+{
+ int type = pci_pcie_type(dev);
+
+ return pci_pcie_cap_version(dev) > 1 ||
+ type == PCI_EXP_TYPE_ROOT_PORT ||
+ type == PCI_EXP_TYPE_ENDPOINT ||
+ type == PCI_EXP_TYPE_LEG_END;
+}
+
+static inline bool pci_pcie_cap_has_sltctl(const struct pci_dev *dev)
+{
+ int type = pci_pcie_type(dev);
+
+ return pci_pcie_cap_version(dev) > 1 ||
+ type == PCI_EXP_TYPE_ROOT_PORT ||
+ (type == PCI_EXP_TYPE_DOWNSTREAM &&
+ dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT);
+}
+
+static inline bool pci_pcie_cap_has_rtctl(const struct pci_dev *dev)
+{
+ int type = pci_pcie_type(dev);
+
+ return pci_pcie_cap_version(dev) > 1 ||
+ type == PCI_EXP_TYPE_ROOT_PORT ||
+ type == PCI_EXP_TYPE_RC_EC;
+}
+
+bool pci_pcie_capability_reg_implemented(struct pci_dev *dev, int pos)
+{
+ if (!pci_is_pcie(dev))
+ return false;
+
+ switch (pos) {
+ case PCI_EXP_FLAGS_TYPE:
+ return true;
+ case PCI_EXP_DEVCAP:
+ case PCI_EXP_DEVCTL:
+ case PCI_EXP_DEVSTA:
+ return pci_pcie_cap_has_devctl(dev);
+ case PCI_EXP_LNKCAP:
+ case PCI_EXP_LNKCTL:
+ case PCI_EXP_LNKSTA:
+ return pci_pcie_cap_has_lnkctl(dev);
+ case PCI_EXP_SLTCAP:
+ case PCI_EXP_SLTCTL:
+ case PCI_EXP_SLTSTA:
+ return pci_pcie_cap_has_sltctl(dev);
+ case PCI_EXP_RTCTL:
+ case PCI_EXP_RTCAP:
+ case PCI_EXP_RTSTA:
+ return pci_pcie_cap_has_rtctl(dev);
+ case PCI_EXP_DEVCAP2:
+ case PCI_EXP_DEVCTL2:
+ case PCI_EXP_LNKCAP2:
+ case PCI_EXP_LNKCTL2:
+ case PCI_EXP_LNKSTA2:
+ return pci_pcie_cap_version(dev) > 1;
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL(pci_pcie_capability_reg_implemented);
+
+/*
+ * Quotation from PCIe Base Spec 3.0:
+ * For Functions that do not implement the Slot Capabilities,
+ * Slot Status, and Slot Control registers, these spaces must
+ * be hardwired to 0b, with the exception of the Presence Detect
+ * State bit in the Slot Status register of Downstream Ports,
+ * which must be hardwired to 1b.
+ */
+int pci_pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)
+{
+ int ret = 0;
+
+ *val = 0;
+ if (pos & 1)
+ return -EINVAL;
+
+ if (pci_pcie_capability_reg_implemented(dev, pos)) {
+ ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val);
+ /*
+ * Reset *val to 0 if pci_read_config_word() fails, it may
+ * have been written as 0xFFFF if hardware error happens
+ * during pci_read_config_word().
+ */
+ if (ret)
+ *val = 0;
+ } else if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA &&
+ pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) {
+ *val = PCI_EXP_SLTSTA_PDS;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(pci_pcie_capability_read_word);
+
+int pci_pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val)
+{
+ int ret = 0;
+
+ *val = 0;
+ if (pos & 3)
+ return -EINVAL;
+
+ if (pci_pcie_capability_reg_implemented(dev, pos)) {
+ ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val);
+ /*
+ * Reset *val to 0 if pci_read_config_dword() fails, it may
+ * have been written as 0xFFFFFFFF if hardware error happens
+ * during pci_read_config_dword().
+ */
+ if (ret)
+ *val = 0;
+ } else if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL &&
+ pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) {
+ *val = PCI_EXP_SLTSTA_PDS;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(pci_pcie_capability_read_dword);
+
+int pci_pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val)
+{
+ if (pos & 1)
+ return -EINVAL;
+ else if (!pci_pcie_capability_reg_implemented(dev, pos))
+ return 0;
+
+ return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val);
+}
+EXPORT_SYMBOL(pci_pcie_capability_write_word);
+
+int pci_pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val)
+{
+ if (pos & 3)
+ return -EINVAL;
+ else if (!pci_pcie_capability_reg_implemented(dev, pos))
+ return 0;
+
+ return pci_write_config_dword(dev, pci_pcie_cap(dev) + pos, val);
+}
+EXPORT_SYMBOL(pci_pcie_capability_write_dword);
+
+int pci_pcie_capability_change_word(struct pci_dev *dev, int pos,
+ u16 set_bits, u16 clear_bits)
+{
+ int ret;
+ u16 val, old;
+
+ ret = pci_pcie_capability_read_word(dev, pos, &val);
+ if (!ret) {
+ old = val;
+ val &= ~clear_bits;
+ val |= set_bits;
+ if (val != old)
+ ret = pci_pcie_capability_write_word(dev, pos, val);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(pci_pcie_capability_change_word);
+
+int pci_pcie_capability_change_dword(struct pci_dev *dev, int pos,
+ u32 set_bits, u32 clear_bits)
+{
+ int ret;
+ u32 val, old;
+
+ ret = pci_pcie_capability_read_dword(dev, pos, &val);
+ if (!ret) {
+ old = val;
+ val &= ~clear_bits;
+ val |= set_bits;
+ if (val != old)
+ ret = pci_pcie_capability_write_dword(dev, pos, val);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(pci_pcie_capability_change_dword);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9807da5..4fa3c99 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -816,6 +816,16 @@ static inline int pci_write_config_dword(const struct pci_dev *dev, int where,
return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
}

+int pci_pcie_capability_read_word(struct pci_dev *dev, int where, u16 *val);
+int pci_pcie_capability_read_dword(struct pci_dev *dev, int where, u32 *val);
+int pci_pcie_capability_write_word(struct pci_dev *dev, int where, u16 val);
+int pci_pcie_capability_write_dword(struct pci_dev *dev, int where, u32 val);
+int pci_pcie_capability_change_word(struct pci_dev *dev, int pos,
+ u16 set_bits, u16 clear_bits);
+int pci_pcie_capability_change_dword(struct pci_dev *dev, int pos,
+ u32 set_bits, u32 clear_bits);
+bool pci_pcie_capability_reg_implemented(struct pci_dev *dev, int where);
+
/* user-space driven config access */
int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val);
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 53274bf..5300fdf 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -543,7 +543,9 @@
#define PCI_EXP_OBFF_MSGB_EN 0x4000 /* OBFF enable with Message type B */
#define PCI_EXP_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */
#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 44 /* v2 endpoints end here */
+#define PCI_EXP_LNKCAP2 44 /* Link Capabilities 2 */
#define PCI_EXP_LNKCTL2 48 /* Link Control 2 */
+#define PCI_EXP_LNKSTA2 50 /* Link Status 2 */
#define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */

/* Extended Capabilities (PCI-X 2.0 and Express) */
--
1.7.9.5

2012-08-01 15:56:08

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 05/32] PCI/core: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify PCI core implementation.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/pci/pci.c | 322 +++++++++++---------------------------------------
drivers/pci/probe.c | 18 +--
drivers/pci/quirks.c | 9 +-
3 files changed, 74 insertions(+), 275 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 28eb55b..d5a98cd 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -254,38 +254,6 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
}

/**
- * 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
* @cap: capability code
@@ -854,21 +822,6 @@ EXPORT_SYMBOL(pci_choose_state);

#define PCI_EXP_SAVE_REGS 7

-#define pcie_cap_has_devctl(type, flags) 1
-#define pcie_cap_has_lnkctl(type, flags) \
- ((flags & PCI_EXP_FLAGS_VERS) > 1 || \
- (type == PCI_EXP_TYPE_ROOT_PORT || \
- type == PCI_EXP_TYPE_ENDPOINT || \
- type == PCI_EXP_TYPE_LEG_END))
-#define pcie_cap_has_sltctl(type, flags) \
- ((flags & PCI_EXP_FLAGS_VERS) > 1 || \
- ((type == PCI_EXP_TYPE_ROOT_PORT) || \
- (type == PCI_EXP_TYPE_DOWNSTREAM && \
- (flags & PCI_EXP_FLAGS_SLOT))))
-#define pcie_cap_has_rtctl(type, flags) \
- ((flags & PCI_EXP_FLAGS_VERS) > 1 || \
- (type == PCI_EXP_TYPE_ROOT_PORT || \
- type == PCI_EXP_TYPE_RC_EC))

static struct pci_cap_saved_state *pci_find_saved_cap(
struct pci_dev *pci_dev, char cap)
@@ -885,76 +838,46 @@ static struct pci_cap_saved_state *pci_find_saved_cap(

static int pci_save_pcie_state(struct pci_dev *dev)
{
- int type, pos, i = 0;
+ int i = 0;
struct pci_cap_saved_state *save_state;
u16 *cap;
- u16 flags;
-
- pos = pci_pcie_cap(dev);
- if (!pos)
- return 0;

save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
if (!save_state) {
dev_err(&dev->dev, "buffer not found in %s\n", __func__);
return -ENOMEM;
}
- cap = (u16 *)&save_state->cap.data[0];
-
- pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);

- type = pci_pcie_type(dev);
- if (pcie_cap_has_devctl(type, flags))
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]);
- if (pcie_cap_has_lnkctl(type, flags))
- pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
- if (pcie_cap_has_sltctl(type, flags))
- pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
- if (pcie_cap_has_rtctl(type, flags))
- pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
-
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return 0;
+ cap = (u16 *)&save_state->cap.data[0];
+ pci_pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &cap[i++]);
+ pci_pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &cap[i++]);
+ pci_pcie_capability_read_word(dev, PCI_EXP_SLTCTL, &cap[i++]);
+ pci_pcie_capability_read_word(dev, PCI_EXP_RTCTL, &cap[i++]);
+ pci_pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &cap[i++]);
+ pci_pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &cap[i++]);
+ pci_pcie_capability_read_word(dev, PCI_EXP_SLTCTL2, &cap[i++]);

- 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;
}

static void pci_restore_pcie_state(struct pci_dev *dev)
{
- int i = 0, pos, type;
+ int i = 0;
struct pci_cap_saved_state *save_state;
u16 *cap;
- u16 flags;

save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (!save_state || pos <= 0)
- return;
- cap = (u16 *)&save_state->cap.data[0];
-
- pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
-
- type = pci_pcie_type(dev);
- if (pcie_cap_has_devctl(type, flags))
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]);
- if (pcie_cap_has_lnkctl(type, flags))
- pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]);
- if (pcie_cap_has_sltctl(type, flags))
- pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
- if (pcie_cap_has_rtctl(type, flags))
- pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
-
- pos = pci_pcie_cap2(dev);
- if (!pos)
+ if (!save_state)
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++]);
+ cap = (u16 *)&save_state->cap.data[0];
+ pci_pcie_capability_write_word(dev, PCI_EXP_DEVCTL, cap[i++]);
+ pci_pcie_capability_write_word(dev, PCI_EXP_LNKCTL, cap[i++]);
+ pci_pcie_capability_write_word(dev, PCI_EXP_SLTCTL, cap[i++]);
+ pci_pcie_capability_write_word(dev, PCI_EXP_RTCTL, cap[i++]);
+ pci_pcie_capability_write_word(dev, PCI_EXP_DEVCTL2, cap[i++]);
+ pci_pcie_capability_write_word(dev, PCI_EXP_LNKCTL2, cap[i++]);
+ pci_pcie_capability_write_word(dev, PCI_EXP_SLTCTL2, cap[i++]);
}


@@ -2068,35 +1991,25 @@ void pci_free_cap_save_buffers(struct pci_dev *dev)
*/
void pci_enable_ari(struct pci_dev *dev)
{
- int pos;
u32 cap;
- u16 ctrl;
struct pci_dev *bridge;

- if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
+ if (pcie_ari_disabled || dev->devfn)
return;

- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
- if (!pos)
+ if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI))
return;

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

- /* ARI is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(bridge);
- if (!pos)
- return;
-
- pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
+ pci_pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap);
if (!(cap & PCI_EXP_DEVCAP2_ARI))
return;

- pci_read_config_word(bridge, pos + PCI_EXP_DEVCTL2, &ctrl);
- ctrl |= PCI_EXP_DEVCTL2_ARI;
- pci_write_config_word(bridge, pos + PCI_EXP_DEVCTL2, ctrl);
-
+ pci_pcie_capability_change_word(bridge, PCI_EXP_DEVCTL2,
+ PCI_EXP_DEVCTL2_ARI, 0);
bridge->ari_enabled = 1;
}

@@ -2111,20 +2024,14 @@ void pci_enable_ari(struct pci_dev *dev)
*/
void pci_enable_ido(struct pci_dev *dev, unsigned long type)
{
- int pos;
- u16 ctrl;
+ u16 ctrl = 0;

- /* ID-based Ordering is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return;
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
if (type & PCI_EXP_IDO_REQUEST)
ctrl |= PCI_EXP_IDO_REQ_EN;
if (type & PCI_EXP_IDO_COMPLETION)
ctrl |= PCI_EXP_IDO_CMP_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+ if (ctrl)
+ pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL2, ctrl, 0);
}
EXPORT_SYMBOL(pci_enable_ido);

@@ -2135,20 +2042,14 @@ EXPORT_SYMBOL(pci_enable_ido);
*/
void pci_disable_ido(struct pci_dev *dev, unsigned long type)
{
- int pos;
- u16 ctrl;
-
- /* ID-based Ordering is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return;
+ u16 ctrl = 0;

- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
if (type & PCI_EXP_IDO_REQUEST)
- ctrl &= ~PCI_EXP_IDO_REQ_EN;
+ ctrl |= PCI_EXP_IDO_REQ_EN;
if (type & PCI_EXP_IDO_COMPLETION)
- ctrl &= ~PCI_EXP_IDO_CMP_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+ ctrl |= PCI_EXP_IDO_CMP_EN;
+ if (ctrl)
+ pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL2, 0, ctrl);
}
EXPORT_SYMBOL(pci_disable_ido);

@@ -2173,17 +2074,11 @@ EXPORT_SYMBOL(pci_disable_ido);
*/
int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
{
- int pos;
u32 cap;
u16 ctrl;
int ret;

- /* OBFF is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return -ENOTSUPP;
-
- pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
+ pci_pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);
if (!(cap & PCI_EXP_OBFF_MASK))
return -ENOTSUPP; /* no OBFF support at all */

@@ -2194,7 +2089,7 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
return ret;
}

- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
+ pci_pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &ctrl);
if (cap & PCI_EXP_OBFF_WAKE)
ctrl |= PCI_EXP_OBFF_WAKE_EN;
else {
@@ -2212,7 +2107,7 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
return -ENOTSUPP;
}
}
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+ pci_pcie_capability_write_word(dev, PCI_EXP_DEVCTL2, ctrl);

return 0;
}
@@ -2226,17 +2121,8 @@ EXPORT_SYMBOL(pci_enable_obff);
*/
void pci_disable_obff(struct pci_dev *dev)
{
- int pos;
- u16 ctrl;
-
- /* OBFF is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return;
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
- ctrl &= ~PCI_EXP_OBFF_WAKE_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+ pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL2,
+ 0, PCI_EXP_OBFF_WAKE_EN);
}
EXPORT_SYMBOL(pci_disable_obff);

@@ -2249,15 +2135,9 @@ EXPORT_SYMBOL(pci_disable_obff);
*/
static bool pci_ltr_supported(struct pci_dev *dev)
{
- int pos;
u32 cap;

- /* LTR is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return false;
-
- pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
+ pci_pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);

return cap & PCI_EXP_DEVCAP2_LTR;
}
@@ -2274,22 +2154,15 @@ static bool pci_ltr_supported(struct pci_dev *dev)
*/
int pci_enable_ltr(struct pci_dev *dev)
{
- int pos;
- u16 ctrl;
int ret;

- if (!pci_ltr_supported(dev))
- return -ENOTSUPP;
-
- /* LTR is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return -ENOTSUPP;
-
/* Only primary function can enable/disable LTR */
if (PCI_FUNC(dev->devfn) != 0)
return -EINVAL;

+ if (!pci_ltr_supported(dev))
+ return -ENOTSUPP;
+
/* Enable upstream ports first */
if (dev->bus->self) {
ret = pci_enable_ltr(dev->bus->self);
@@ -2297,11 +2170,8 @@ int pci_enable_ltr(struct pci_dev *dev)
return ret;
}

- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
- ctrl |= PCI_EXP_LTR_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
-
- return 0;
+ return pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL2,
+ PCI_EXP_LTR_EN, 0);
}
EXPORT_SYMBOL(pci_enable_ltr);

@@ -2311,24 +2181,15 @@ EXPORT_SYMBOL(pci_enable_ltr);
*/
void pci_disable_ltr(struct pci_dev *dev)
{
- int pos;
- u16 ctrl;
-
- if (!pci_ltr_supported(dev))
- return;
-
- /* LTR is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return;
-
/* Only primary function can enable/disable LTR */
if (PCI_FUNC(dev->devfn) != 0)
return;

- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
- ctrl &= ~PCI_EXP_LTR_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+ if (!pci_ltr_supported(dev))
+ return;
+
+ pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL2,
+ 0, PCI_EXP_LTR_EN);
}
EXPORT_SYMBOL(pci_disable_ltr);

@@ -2411,9 +2272,6 @@ void pci_enable_acs(struct pci_dev *dev)
if (!pci_acs_enable)
return;

- if (!pci_is_pcie(dev))
- return;
-
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
if (!pos)
return;
@@ -3178,15 +3036,10 @@ EXPORT_SYMBOL(pci_set_dma_seg_boundary);
static int pcie_flr(struct pci_dev *dev, int probe)
{
int i;
- int pos;
u32 cap;
- u16 status, control;
-
- pos = pci_pcie_cap(dev);
- if (!pos)
- return -ENOTTY;
+ u16 status;

- pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap);
+ pci_pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
if (!(cap & PCI_EXP_DEVCAP_FLR))
return -ENOTTY;

@@ -3198,7 +3051,7 @@ static int pcie_flr(struct pci_dev *dev, int probe)
if (i)
msleep((1 << (i - 1)) * 100);

- pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status);
+ pci_pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
if (!(status & PCI_EXP_DEVSTA_TRPND))
goto clear;
}
@@ -3207,9 +3060,8 @@ static int pcie_flr(struct pci_dev *dev, int probe)
"proceeding with reset anyway\n");

clear:
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &control);
- control |= PCI_EXP_DEVCTL_BCR_FLR;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, control);
+ pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_BCR_FLR, 0);

msleep(100);

@@ -3577,18 +3429,11 @@ EXPORT_SYMBOL(pcix_set_mmrbc);
*/
int pcie_get_readrq(struct pci_dev *dev)
{
- int ret, cap;
u16 ctl;

- cap = pci_pcie_cap(dev);
- if (!cap)
- return -EINVAL;
-
- ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
- if (!ret)
- ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+ pci_pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl);

- return ret;
+ return 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
}
EXPORT_SYMBOL(pcie_get_readrq);

@@ -3602,19 +3447,11 @@ EXPORT_SYMBOL(pcie_get_readrq);
*/
int pcie_set_readrq(struct pci_dev *dev, int rq)
{
- int cap, err = -EINVAL;
- u16 ctl, v;
+ u16 v;

if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
- goto out;
-
- cap = pci_pcie_cap(dev);
- if (!cap)
- goto out;
+ return -EINVAL;

- err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
- if (err)
- goto out;
/*
* If using the "performance" PCIe config, we clamp the
* read rq size to the max packet size to prevent the
@@ -3632,14 +3469,8 @@ int pcie_set_readrq(struct pci_dev *dev, int rq)

v = (ffs(rq) - 8) << 12;

- if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) {
- ctl &= ~PCI_EXP_DEVCTL_READRQ;
- ctl |= v;
- err = pci_write_config_word(dev, cap + PCI_EXP_DEVCTL, ctl);
- }
-
-out:
- return err;
+ return pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL,
+ v, PCI_EXP_DEVCTL_READRQ);
}
EXPORT_SYMBOL(pcie_set_readrq);

@@ -3652,18 +3483,11 @@ EXPORT_SYMBOL(pcie_set_readrq);
*/
int pcie_get_mps(struct pci_dev *dev)
{
- int ret, cap;
u16 ctl;

- cap = pci_pcie_cap(dev);
- if (!cap)
- return -EINVAL;
-
- ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
- if (!ret)
- ret = 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+ pci_pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl);

- return ret;
+ return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
}

/**
@@ -3676,32 +3500,18 @@ int pcie_get_mps(struct pci_dev *dev)
*/
int pcie_set_mps(struct pci_dev *dev, int mps)
{
- int cap, err = -EINVAL;
- u16 ctl, v;
+ u16 v;

if (mps < 128 || mps > 4096 || !is_power_of_2(mps))
- goto out;
+ return -EINVAL;

v = ffs(mps) - 8;
if (v > dev->pcie_mpss)
- goto out;
+ return -EINVAL;
v <<= 5;

- cap = pci_pcie_cap(dev);
- if (!cap)
- goto out;
-
- err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
- if (err)
- goto out;
-
- if ((ctl & PCI_EXP_DEVCTL_PAYLOAD) != v) {
- ctl &= ~PCI_EXP_DEVCTL_PAYLOAD;
- ctl |= v;
- err = pci_write_config_word(dev, cap + PCI_EXP_DEVCTL, ctl);
- }
-out:
- return err;
+ return pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL,
+ v, PCI_EXP_DEVCTL_PAYLOAD);
}

/**
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 8bcc985..6a2eac8 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -603,10 +603,11 @@ static void pci_set_bus_speed(struct pci_bus *bus)
u32 linkcap;
u16 linksta;

- pci_read_config_dword(bridge, pos + PCI_EXP_LNKCAP, &linkcap);
+ pci_pcie_capability_read_dword(bridge, PCI_EXP_LNKCAP,
+ &linkcap);
bus->max_bus_speed = pcie_link_speed[linkcap & 0xf];

- pci_read_config_word(bridge, pos + PCI_EXP_LNKSTA, &linksta);
+ pci_pcie_capability_read_word(bridge, PCI_EXP_LNKSTA, &linksta);
pcie_update_link_speed(bus, linksta);
}
}
@@ -936,17 +937,9 @@ void set_pcie_port_type(struct pci_dev *pdev)

void set_pcie_hotplug_bridge(struct pci_dev *pdev)
{
- int pos;
- u16 reg16;
u32 reg32;

- pos = pci_pcie_cap(pdev);
- if (!pos)
- return;
- pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
- if (!(reg16 & PCI_EXP_FLAGS_SLOT))
- return;
- pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &reg32);
+ pci_pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &reg32);
if (reg32 & PCI_EXP_SLTCAP_HPC)
pdev->is_hotplug_bridge = 1;
}
@@ -1160,8 +1153,7 @@ int pci_cfg_space_size(struct pci_dev *dev)
if (class == PCI_CLASS_BRIDGE_HOST)
return pci_cfg_space_size_ext(dev);

- pos = pci_pcie_cap(dev);
- if (!pos) {
+ if (!pci_is_pcie(dev)) {
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (!pos)
goto fail;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 003f356..fde4ff3 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3081,17 +3081,14 @@ static int reset_intel_generic_dev(struct pci_dev *dev, int probe)

static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
{
- int pos;
-
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (!pos)
+ if (!pci_pcie_capability_reg_implemented(dev, PCI_EXP_DEVCTL))
return -ENOTTY;

if (probe)
return 0;

- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_BCR_FLR);
+ pci_pcie_capability_write_word(dev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_BCR_FLR);
msleep(100);

return 0;
--
1.7.9.5

2012-08-01 15:56:16

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 06/32] PCI/hotplug: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify cpihp_slot.c.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/pci/hotplug/pcihp_slot.c | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c
index 8c05a18..649dcc8 100644
--- a/drivers/pci/hotplug/pcihp_slot.c
+++ b/drivers/pci/hotplug/pcihp_slot.c
@@ -96,17 +96,11 @@ static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
{
int pos;
- u16 reg16;
u32 reg32;

if (!hpp)
return;

- /* Find PCI Express capability */
- pos = pci_pcie_cap(dev);
- if (!pos)
- return;
-
if (hpp->revision > 1) {
dev_warn(&dev->dev, "PCIe settings rev %d not supported\n",
hpp->revision);
@@ -114,17 +108,13 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
}

/* Initialize Device Control Register */
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
- reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
+ pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL,
+ hpp->pci_exp_devctl_or, ~hpp->pci_exp_devctl_and);

/* Initialize Link Control Register */
- if (dev->subordinate) {
- pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &reg16);
- reg16 = (reg16 & hpp->pci_exp_lnkctl_and)
- | hpp->pci_exp_lnkctl_or;
- pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16);
- }
+ if (dev->subordinate)
+ pci_pcie_capability_change_word(dev, PCI_EXP_LNKCTL,
+ hpp->pci_exp_lnkctl_or, ~hpp->pci_exp_lnkctl_and);

/* Find Advanced Error Reporting Enhanced Capability */
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
--
1.7.9.5

2012-08-01 15:56:24

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 07/32] PCI/portdrv: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify PCIe portdrv implementation.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/pci/pcie/portdrv_core.c | 15 +++++----------
drivers/pci/pcie/portdrv_pci.c | 10 ++--------
2 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index bf320a9..274d524 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -246,8 +246,7 @@ static void cleanup_service_irqs(struct pci_dev *dev)
*/
static int get_port_device_capability(struct pci_dev *dev)
{
- int services = 0, pos;
- u16 reg16;
+ int services = 0;
u32 reg32;
int cap_mask = 0;
int err;
@@ -265,11 +264,9 @@ static int get_port_device_capability(struct pci_dev *dev)
return 0;
}

- pos = pci_pcie_cap(dev);
- pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
/* Hot-Plug Capable */
- if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) {
- pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, &reg32);
+ if ((cap_mask & PCIE_PORT_SERVICE_HP)) {
+ pci_pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, &reg32);
if (reg32 & PCI_EXP_SLTCAP_HPC) {
services |= PCIE_PORT_SERVICE_HP;
/*
@@ -277,10 +274,8 @@ static int get_port_device_capability(struct pci_dev *dev)
* enabled by the BIOS and the hot-plug service driver
* is not loaded.
*/
- pos += PCI_EXP_SLTCTL;
- pci_read_config_word(dev, pos, &reg16);
- reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
- pci_write_config_word(dev, pos, reg16);
+ pci_pcie_capability_change_word(dev, PCI_EXP_SLTCTL,
+ 0, PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
}
}
/* AER capable */
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 24d1463..93f726c 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -64,14 +64,8 @@ __setup("pcie_ports=", pcie_port_setup);
*/
void pcie_clear_root_pme_status(struct pci_dev *dev)
{
- int rtsta_pos;
- u32 rtsta;
-
- rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA;
-
- pci_read_config_dword(dev, rtsta_pos, &rtsta);
- rtsta |= PCI_EXP_RTSTA_PME;
- pci_write_config_dword(dev, rtsta_pos, rtsta);
+ pci_pcie_capability_change_dword(dev, PCI_EXP_RTSTA,
+ PCI_EXP_RTSTA_PME, 0);
}

static int pcie_portdrv_restore_config(struct pci_dev *dev)
--
1.7.9.5

2012-08-01 15:56:34

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 08/32] PCI/pciehp: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify pciehp implementation.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/pci/hotplug/pciehp_acpi.c | 6 +-----
drivers/pci/hotplug/pciehp_hpc.c | 12 ++++--------
2 files changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 376d70d..751b41c 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -81,16 +81,12 @@ static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots);
/* Dummy driver for dumplicate name detection */
static int __init dummy_probe(struct pcie_device *dev)
{
- int pos;
u32 slot_cap;
acpi_handle handle;
struct dummy_slot *slot, *tmp;
struct pci_dev *pdev = dev->port;

- pos = pci_pcie_cap(pdev);
- if (!pos)
- return -ENODEV;
- pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap);
+ pci_pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap);
slot = kzalloc(sizeof(*slot), GFP_KERNEL);
if (!slot)
return -ENOMEM;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 302451e..cf0daf1 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -44,25 +44,25 @@
static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value)
{
struct pci_dev *dev = ctrl->pcie->port;
- return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value);
+ return pci_pcie_capability_read_word(dev, reg, value);
}

static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value)
{
struct pci_dev *dev = ctrl->pcie->port;
- return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value);
+ return pci_pcie_capability_read_dword(dev, reg, value);
}

static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value)
{
struct pci_dev *dev = ctrl->pcie->port;
- return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value);
+ return pci_pcie_capability_write_word(dev, reg, value);
}

static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
{
struct pci_dev *dev = ctrl->pcie->port;
- return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value);
+ return pci_pcie_capability_write_dword(dev, reg, value);
}

/* Power Control Command */
@@ -855,10 +855,6 @@ struct controller *pcie_init(struct pcie_device *dev)
goto abort;
}
ctrl->pcie = dev;
- if (!pci_pcie_cap(pdev)) {
- ctrl_err(ctrl, "Cannot find PCI Express capability\n");
- goto abort_ctrl;
- }
if (pciehp_readl(ctrl, PCI_EXP_SLTCAP, &slot_cap)) {
ctrl_err(ctrl, "Cannot read SLOTCAP register\n");
goto abort_ctrl;
--
1.7.9.5

2012-08-01 15:56:41

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 09/32] PCI/PME: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify PCIe PME implementation.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/pci/pcie/pme.c | 22 ++++++----------------
1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index 30897bf..74a3d4d 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -57,17 +57,13 @@ struct pcie_pme_service_data {
*/
void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
{
- int rtctl_pos;
- u16 rtctl;
+ u16 set = 0, clr = 0;

- rtctl_pos = pci_pcie_cap(dev) + PCI_EXP_RTCTL;
-
- pci_read_config_word(dev, rtctl_pos, &rtctl);
if (enable)
- rtctl |= PCI_EXP_RTCTL_PMEIE;
+ set = PCI_EXP_RTCTL_PMEIE;
else
- rtctl &= ~PCI_EXP_RTCTL_PMEIE;
- pci_write_config_word(dev, rtctl_pos, rtctl);
+ clr = PCI_EXP_RTCTL_PMEIE;
+ pci_pcie_capability_change_word(dev, PCI_EXP_RTCTL, set, clr);
}

/**
@@ -226,18 +222,15 @@ static void pcie_pme_work_fn(struct work_struct *work)
struct pcie_pme_service_data *data =
container_of(work, struct pcie_pme_service_data, work);
struct pci_dev *port = data->srv->port;
- int rtsta_pos;
u32 rtsta;

- rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA;
-
spin_lock_irq(&data->lock);

for (;;) {
if (data->noirq)
break;

- pci_read_config_dword(port, rtsta_pos, &rtsta);
+ pci_pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta);
if (rtsta & PCI_EXP_RTSTA_PME) {
/*
* Clear PME status of the port. If there are other
@@ -276,17 +269,14 @@ static irqreturn_t pcie_pme_irq(int irq, void *context)
{
struct pci_dev *port;
struct pcie_pme_service_data *data;
- int rtsta_pos;
u32 rtsta;
unsigned long flags;

port = ((struct pcie_device *)context)->port;
data = get_service_data((struct pcie_device *)context);

- rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA;
-
spin_lock_irqsave(&data->lock, flags);
- pci_read_config_dword(port, rtsta_pos, &rtsta);
+ pci_pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta);

if (!(rtsta & PCI_EXP_RTSTA_PME)) {
spin_unlock_irqrestore(&data->lock, flags);
--
1.7.9.5

2012-08-01 15:56:49

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 10/32] PCI/AER: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify PCIe AER implementation.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/pci/pcie/aer/aerdrv.c | 17 ++++++--------
drivers/pci/pcie/aer/aerdrv_core.c | 45 ++++++++----------------------------
2 files changed, 16 insertions(+), 46 deletions(-)

diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index f7c6245..b85750d 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -122,19 +122,17 @@ static void set_downstream_devices_error_reporting(struct pci_dev *dev,
static void aer_enable_rootport(struct aer_rpc *rpc)
{
struct pci_dev *pdev = rpc->rpd->port;
- int pos, aer_pos;
+ int aer_pos;
u16 reg16;
u32 reg32;

- pos = pci_pcie_cap(pdev);
/* Clear PCIe Capability's Device Status */
- pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, &reg16);
- pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16);
+ pci_pcie_capability_read_word(pdev, PCI_EXP_DEVSTA, &reg16);
+ pci_pcie_capability_write_word(pdev, PCI_EXP_DEVSTA, reg16);

/* Disable system error generation in response to error messages */
- pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, &reg16);
- reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK);
- pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16);
+ pci_pcie_capability_change_word(pdev, PCI_EXP_RTCTL,
+ 0, SYSTEM_ERROR_INTR_ON_MESG_MASK);

aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
/* Clear error status */
@@ -396,9 +394,8 @@ static void aer_error_resume(struct pci_dev *dev)
u16 reg16;

/* Clean up Root device status */
- pos = pci_pcie_cap(dev);
- pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &reg16);
- pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16);
+ pci_pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &reg16);
+ pci_pcie_capability_write_word(dev, PCI_EXP_DEVSTA, reg16);

/* Clean AER Root Error Status */
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index f551534..2af79f7 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -34,51 +34,26 @@ module_param(nosourceid, bool, 0);

int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{
- u16 reg16 = 0;
- int pos;
-
if (pcie_aer_get_firmware_first(dev))
return -EIO;

- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
- if (!pos)
- return -EIO;
-
- pos = pci_pcie_cap(dev);
- if (!pos)
+ if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
return -EIO;

- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
- reg16 |= (PCI_EXP_DEVCTL_CERE |
- PCI_EXP_DEVCTL_NFERE |
- PCI_EXP_DEVCTL_FERE |
- PCI_EXP_DEVCTL_URRE);
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
-
- return 0;
+ return pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE |
+ PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE, 0);
}
EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);

int pci_disable_pcie_error_reporting(struct pci_dev *dev)
{
- u16 reg16 = 0;
- int pos;
-
if (pcie_aer_get_firmware_first(dev))
return -EIO;

- pos = pci_pcie_cap(dev);
- if (!pos)
- return -EIO;
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
- reg16 &= ~(PCI_EXP_DEVCTL_CERE |
- PCI_EXP_DEVCTL_NFERE |
- PCI_EXP_DEVCTL_FERE |
- PCI_EXP_DEVCTL_URRE);
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
-
- return 0;
+ return pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL, 0,
+ PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE |
+ PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE);
}
EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);

@@ -151,18 +126,16 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
*/
if (atomic_read(&dev->enable_cnt) == 0)
return false;
- pos = pci_pcie_cap(dev);
- if (!pos)
- return false;

/* Check if AER is enabled */
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
+ pci_pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &reg16);
if (!(reg16 & (
PCI_EXP_DEVCTL_CERE |
PCI_EXP_DEVCTL_NFERE |
PCI_EXP_DEVCTL_FERE |
PCI_EXP_DEVCTL_URRE)))
return false;
+
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return false;
--
1.7.9.5

2012-08-01 15:56:59

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 11/32] PCI/ASPM: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify PCIe ASPM implementation.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/pci/pcie/aspm.c | 69 ++++++++++++++++-------------------------------
1 file changed, 23 insertions(+), 46 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 2591603..a66860f 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -125,21 +125,17 @@ static int policy_to_clkpm_state(struct pcie_link_state *link)

static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable)
{
- int pos;
u16 reg16;
struct pci_dev *child;
struct pci_bus *linkbus = link->pdev->subordinate;

list_for_each_entry(child, &linkbus->devices, bus_list) {
- pos = pci_pcie_cap(child);
- if (!pos)
- return;
- pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
+ pci_pcie_capability_read_word(child, PCI_EXP_LNKCTL, &reg16);
if (enable)
reg16 |= PCI_EXP_LNKCTL_CLKREQ_EN;
else
reg16 &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
- pci_write_config_word(child, pos + PCI_EXP_LNKCTL, reg16);
+ pci_pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16);
}
link->clkpm_enabled = !!enable;
}
@@ -157,7 +153,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable)

static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
{
- int pos, capable = 1, enabled = 1;
+ int capable = 1, enabled = 1;
u32 reg32;
u16 reg16;
struct pci_dev *child;
@@ -165,16 +161,13 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)

/* All functions should have the same cap and state, take the worst */
list_for_each_entry(child, &linkbus->devices, bus_list) {
- pos = pci_pcie_cap(child);
- if (!pos)
- return;
- pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, &reg32);
+ pci_pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &reg32);
if (!(reg32 & PCI_EXP_LNKCAP_CLKPM)) {
capable = 0;
enabled = 0;
break;
}
- pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
+ pci_pcie_capability_read_word(child, PCI_EXP_LNKCTL, &reg16);
if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN))
enabled = 0;
}
@@ -190,7 +183,7 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
*/
static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
{
- int ppos, cpos, same_clock = 1;
+ int same_clock = 1;
u16 reg16, parent_reg, child_reg[8];
unsigned long start_jiffies;
struct pci_dev *child, *parent = link->pdev;
@@ -203,46 +196,43 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
BUG_ON(!pci_is_pcie(child));

/* Check downstream component if bit Slot Clock Configuration is 1 */
- cpos = pci_pcie_cap(child);
- pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, &reg16);
+ pci_pcie_capability_read_word(child, PCI_EXP_LNKSTA, &reg16);
if (!(reg16 & PCI_EXP_LNKSTA_SLC))
same_clock = 0;

/* Check upstream component if bit Slot Clock Configuration is 1 */
- ppos = pci_pcie_cap(parent);
- pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
+ pci_pcie_capability_read_word(parent, PCI_EXP_LNKSTA, &reg16);
if (!(reg16 & PCI_EXP_LNKSTA_SLC))
same_clock = 0;

/* Configure downstream component, all functions */
list_for_each_entry(child, &linkbus->devices, bus_list) {
- cpos = pci_pcie_cap(child);
- pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, &reg16);
+ pci_pcie_capability_read_word(child, PCI_EXP_LNKCTL, &reg16);
child_reg[PCI_FUNC(child->devfn)] = reg16;
if (same_clock)
reg16 |= PCI_EXP_LNKCTL_CCC;
else
reg16 &= ~PCI_EXP_LNKCTL_CCC;
- pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, reg16);
+ pci_pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16);
}

/* Configure upstream component */
- pci_read_config_word(parent, ppos + PCI_EXP_LNKCTL, &reg16);
+ pci_pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &reg16);
parent_reg = reg16;
if (same_clock)
reg16 |= PCI_EXP_LNKCTL_CCC;
else
reg16 &= ~PCI_EXP_LNKCTL_CCC;
- pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
+ pci_pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);

/* Retrain link */
reg16 |= PCI_EXP_LNKCTL_RL;
- pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
+ pci_pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);

/* Wait for link training end. Break out after waiting for timeout */
start_jiffies = jiffies;
for (;;) {
- pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
+ pci_pcie_capability_read_word(parent, PCI_EXP_LNKSTA, &reg16);
if (!(reg16 & PCI_EXP_LNKSTA_LT))
break;
if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT))
@@ -256,11 +246,10 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
dev_printk(KERN_ERR, &parent->dev,
"ASPM: Could not configure common clock\n");
list_for_each_entry(child, &linkbus->devices, bus_list) {
- cpos = pci_pcie_cap(child);
- pci_write_config_word(child, cpos + PCI_EXP_LNKCTL,
- child_reg[PCI_FUNC(child->devfn)]);
+ pci_pcie_capability_write_word(child, PCI_EXP_LNKCTL,
+ child_reg[PCI_FUNC(child->devfn)]);
}
- pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, parent_reg);
+ pci_pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg);
}

/* Convert L0s latency encoding to ns */
@@ -305,16 +294,14 @@ struct aspm_register_info {
static void pcie_get_aspm_reg(struct pci_dev *pdev,
struct aspm_register_info *info)
{
- int pos;
u16 reg16;
u32 reg32;

- pos = pci_pcie_cap(pdev);
- pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &reg32);
+ pci_pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &reg32);
info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
info->latency_encoding_l1 = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15;
- pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
+ pci_pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &reg16);
info->enabled = reg16 & PCI_EXP_LNKCTL_ASPMC;
}

@@ -420,7 +407,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)

/* Get and check endpoint acceptable latencies */
list_for_each_entry(child, &linkbus->devices, bus_list) {
- int pos;
u32 reg32, encoding;
struct aspm_latency *acceptable =
&link->acceptable[PCI_FUNC(child->devfn)];
@@ -429,8 +415,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
pci_pcie_type(child) != PCI_EXP_TYPE_LEG_END)
continue;

- pos = pci_pcie_cap(child);
- pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
+ pci_pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
/* Calculate endpoint L0s acceptable latency */
encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
acceptable->l0s = calc_l0s_acceptable(encoding);
@@ -444,13 +429,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)

static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val)
{
- u16 reg16;
- int pos = pci_pcie_cap(pdev);
-
- pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
- reg16 &= ~0x3;
- reg16 |= val;
- pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
+ pci_pcie_capability_change_word(pdev, PCI_EXP_LNKCTL, val, 0x3);
}

static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
@@ -505,7 +484,6 @@ static void free_link_state(struct pcie_link_state *link)
static int pcie_aspm_sanity_check(struct pci_dev *pdev)
{
struct pci_dev *child;
- int pos;
u32 reg32;

/*
@@ -513,8 +491,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
* very strange. Disable ASPM for the whole slot
*/
list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
- pos = pci_pcie_cap(child);
- if (!pos)
+ if (!pci_is_pcie(child))
return -EINVAL;

/*
@@ -530,7 +507,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
* Disable ASPM for pre-1.1 PCIe device, we follow MS to use
* RBER bit to determine if a function is 1.1 version device
*/
- pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
+ pci_pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
dev_printk(KERN_INFO, &child->dev, "disabling ASPM"
" on pre-1.1 PCIe device. You can enable it"
--
1.7.9.5

2012-08-01 15:57:14

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 12/32] PCI/ARM: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify PCIe ARM implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/arm/mach-tegra/pcie.c | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 0e09137..5f99d33 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -367,17 +367,8 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class);
/* Tegra PCIE requires relaxed ordering */
static void __devinit tegra_pcie_relax_enable(struct pci_dev *dev)
{
- u16 val16;
- int pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-
- if (pos <= 0) {
- dev_err(&dev->dev, "skipping relaxed ordering fixup\n");
- return;
- }
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &val16);
- val16 |= PCI_EXP_DEVCTL_RELAX_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, val16);
+ pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_RELAX_EN, 0);
}
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);

--
1.7.9.5

2012-08-01 15:57:20

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 13/32] PCI/MIPS: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify PCIe MIPS implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/mips/pci/pci-octeon.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c
index 52a1ba7..aaed2ad 100644
--- a/arch/mips/pci/pci-octeon.c
+++ b/arch/mips/pci/pci-octeon.c
@@ -117,16 +117,11 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
}

/* Enable the PCIe normal error reporting */
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (pos) {
- /* Update Device Control */
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
- config |= PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */
- config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */
- config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */
- config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
- }
+ config = PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */
+ config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */
+ config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */
+ config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */
+ pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL, config, 0);

/* Find the Advanced Error Reporting capability */
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
--
1.7.9.5

2012-08-01 15:57:32

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 14/32] PCI/tile: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify PCIe tile implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/tile/kernel/pci.c | 25 +++++--------------------
1 file changed, 5 insertions(+), 20 deletions(-)

diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c
index 0fdd99d..4640690 100644
--- a/arch/tile/kernel/pci.c
+++ b/arch/tile/kernel/pci.c
@@ -246,16 +246,13 @@ static void __devinit fixup_read_and_payload_sizes(void)

/* Scan for the smallest maximum payload size. */
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- int pcie_caps_offset;
u32 devcap;
int max_payload;

- pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (pcie_caps_offset == 0)
+ if (!pci_is_pcie(dev))
continue;

- pci_read_config_dword(dev, pcie_caps_offset + PCI_EXP_DEVCAP,
- &devcap);
+ pci_pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &devcap);
max_payload = devcap & PCI_EXP_DEVCAP_PAYLOAD;
if (max_payload < smallest_max_payload)
smallest_max_payload = max_payload;
@@ -263,21 +260,9 @@ static void __devinit fixup_read_and_payload_sizes(void)

/* Now, set the max_payload_size for all devices to that value. */
new_values = (max_read_size << 12) | (smallest_max_payload << 5);
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- int pcie_caps_offset;
- u16 devctl;
-
- pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (pcie_caps_offset == 0)
- continue;
-
- pci_read_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL,
- &devctl);
- devctl &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
- devctl |= new_values;
- pci_write_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL,
- devctl);
- }
+ while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+ pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL, new_values,
+ PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
}


--
1.7.9.5

2012-08-01 15:57:40

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 15/32] PCI/r8169: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify r8169 driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/net/ethernet/realtek/r8169.c | 44 +++++++---------------------------
1 file changed, 9 insertions(+), 35 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 9757ce3..d575fbf 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -807,15 +807,8 @@ static void rtl_unlock_work(struct rtl8169_private *tp)

static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
{
- int cap = pci_pcie_cap(pdev);
-
- if (cap) {
- u16 ctl;
-
- pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
- ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
- pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
- }
+ pci_pcie_capability_change_word(pdev, PCI_EXP_DEVCTL,
+ force, PCI_EXP_DEVCTL_READRQ);
}

static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
@@ -4504,28 +4497,14 @@ static void rtl_ephy_init(void __iomem *ioaddr, const struct ephy_info *e, int l

static void rtl_disable_clock_request(struct pci_dev *pdev)
{
- int cap = pci_pcie_cap(pdev);
-
- if (cap) {
- u16 ctl;
-
- pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl);
- ctl &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
- pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl);
- }
+ pci_pcie_capability_change_word(pdev, PCI_EXP_LNKCTL,
+ 0, PCI_EXP_LNKCTL_CLKREQ_EN);
}

static void rtl_enable_clock_request(struct pci_dev *pdev)
{
- int cap = pci_pcie_cap(pdev);
-
- if (cap) {
- u16 ctl;
-
- pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl);
- ctl |= PCI_EXP_LNKCTL_CLKREQ_EN;
- pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl);
- }
+ pci_pcie_capability_change_word(pdev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_CLKREQ_EN, 0);
}

#define R8168_CPCMD_QUIRK_MASK (\
@@ -5132,14 +5111,9 @@ static void rtl_hw_start_8101(struct net_device *dev)
tp->event_slow &= ~RxFIFOOver;

if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
- tp->mac_version == RTL_GIGA_MAC_VER_16) {
- int cap = pci_pcie_cap(pdev);
-
- if (cap) {
- pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_NOSNOOP_EN);
- }
- }
+ tp->mac_version == RTL_GIGA_MAC_VER_16)
+ pci_pcie_capability_write_word(pdev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_NOSNOOP_EN);

RTL_W8(Cfg9346, Cfg9346_Unlock);

--
1.7.9.5

2012-08-01 15:57:51

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 16/32] PCI/broadcom: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify broadcom ethernet drivers'
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 25 ++-------
drivers/net/ethernet/broadcom/tg3.c | 60 ++++++++--------------
2 files changed, 25 insertions(+), 60 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index f755a66..c631f62 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -1142,14 +1142,9 @@ static int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func,

static u8 bnx2x_is_pcie_pending(struct pci_dev *dev)
{
- int pos;
u16 status;

- pos = pci_pcie_cap(dev);
- if (!pos)
- return false;
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status);
+ pci_pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
return status & PCI_EXP_DEVSTA_TRPND;
}

@@ -6114,8 +6109,7 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
u16 devctl;
int r_order, w_order;

- pci_read_config_word(bp->pdev,
- pci_pcie_cap(bp->pdev) + PCI_EXP_DEVCTL, &devctl);
+ pci_pcie_capability_read_word(bp->pdev, PCI_EXP_DEVCTL, &devctl);
DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
if (bp->mrrs == -1)
@@ -9330,15 +9324,10 @@ static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp)

static bool __devinit bnx2x_can_flr(struct bnx2x *bp)
{
- int pos;
u32 cap;
struct pci_dev *dev = bp->pdev;

- pos = pci_pcie_cap(dev);
- if (!pos)
- return false;
-
- pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap);
+ pci_pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
if (!(cap & PCI_EXP_DEVCAP_FLR))
return false;

@@ -9347,7 +9336,7 @@ static bool __devinit bnx2x_can_flr(struct bnx2x *bp)

static int __devinit bnx2x_do_flr(struct bnx2x *bp)
{
- int i, pos;
+ int i;
u16 status;
struct pci_dev *dev = bp->pdev;

@@ -9355,16 +9344,12 @@ static int __devinit bnx2x_do_flr(struct bnx2x *bp)
if (bnx2x_can_flr(bp))
return -ENOTTY;

- pos = pci_pcie_cap(dev);
- if (!pos)
- return -ENOTTY;
-
/* Wait for Transaction Pending bit clean */
for (i = 0; i < 4; i++) {
if (i)
msleep((1 << (i - 1)) * 100);

- pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status);
+ pci_pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
if (!(status & PCI_EXP_DEVSTA_TRPND))
goto clear;
}
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 09fa3c6..d29fe27 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -3541,17 +3541,9 @@ static int tg3_power_down_prepare(struct tg3 *tp)
tg3_enable_register_access(tp);

/* Restore the CLKREQ setting. */
- if (tg3_flag(tp, CLKREQ_BUG)) {
- u16 lnkctl;
-
- pci_read_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
- &lnkctl);
- lnkctl |= PCI_EXP_LNKCTL_CLKREQ_EN;
- pci_write_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
- lnkctl);
- }
+ if (tg3_flag(tp, CLKREQ_BUG))
+ pci_pcie_capability_change_word(tp->pdev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_CLKREQ_EN, 0);

misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
tw32(TG3PCI_MISC_HOST_CTRL,
@@ -4322,20 +4314,15 @@ relink:

/* Prevent send BD corruption. */
if (tg3_flag(tp, CLKREQ_BUG)) {
- u16 oldlnkctl, newlnkctl;
+ u16 set = 0, clr = 0;

- pci_read_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
- &oldlnkctl);
if (tp->link_config.active_speed == SPEED_100 ||
tp->link_config.active_speed == SPEED_10)
- newlnkctl = oldlnkctl & ~PCI_EXP_LNKCTL_CLKREQ_EN;
+ clr = PCI_EXP_LNKCTL_CLKREQ_EN;
else
- newlnkctl = oldlnkctl | PCI_EXP_LNKCTL_CLKREQ_EN;
- if (newlnkctl != oldlnkctl)
- pci_write_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) +
- PCI_EXP_LNKCTL, newlnkctl);
+ set = PCI_EXP_LNKCTL_CLKREQ_EN;
+ pci_pcie_capability_change_word(tp->pdev, PCI_EXP_LNKCTL,
+ set, clr);
}

if (current_link_up != netif_carrier_ok(tp->dev)) {
@@ -7942,7 +7929,7 @@ static int tg3_chip_reset(struct tg3 *tp)

udelay(120);

- if (tg3_flag(tp, PCI_EXPRESS) && pci_pcie_cap(tp->pdev)) {
+ if (tg3_flag(tp, PCI_EXPRESS) && pci_is_pcie(tp->pdev)) {
u16 val16;

if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) {
@@ -7959,28 +7946,22 @@ static int tg3_chip_reset(struct tg3 *tp)
}

/* Clear the "no snoop" and "relaxed ordering" bits. */
- pci_read_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_DEVCTL,
- &val16);
- val16 &= ~(PCI_EXP_DEVCTL_RELAX_EN |
- PCI_EXP_DEVCTL_NOSNOOP_EN);
+ val16 = PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN;
/*
* Older PCIe devices only support the 128 byte
* MPS setting. Enforce the restriction.
*/
if (!tg3_flag(tp, CPMU_PRESENT))
- val16 &= ~PCI_EXP_DEVCTL_PAYLOAD;
- pci_write_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_DEVCTL,
- val16);
+ val16 |= PCI_EXP_DEVCTL_PAYLOAD;
+ pci_pcie_capability_change_word(tp->pdev, PCI_EXP_DEVCTL,
+ 0, val16);

/* Clear error status */
- pci_write_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_DEVSTA,
- PCI_EXP_DEVSTA_CED |
- PCI_EXP_DEVSTA_NFED |
- PCI_EXP_DEVSTA_FED |
- PCI_EXP_DEVSTA_URD);
+ pci_pcie_capability_write_word(tp->pdev, PCI_EXP_DEVSTA,
+ PCI_EXP_DEVSTA_CED |
+ PCI_EXP_DEVSTA_NFED |
+ PCI_EXP_DEVSTA_FED |
+ PCI_EXP_DEVSTA_URD);
}

tg3_restore_pci_state(tp);
@@ -14303,9 +14284,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)

tg3_flag_set(tp, PCI_EXPRESS);

- pci_read_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
- &lnkctl);
+ pci_pcie_capability_read_word(tp->pdev,
+ PCI_EXP_LNKCTL, &lnkctl);
if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
ASIC_REV_5906) {
--
1.7.9.5

2012-08-01 15:58:05

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 17/32] PCI/igb: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify Intel ethernet drivers'
implementation.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/net/ethernet/intel/e1000e/netdev.c | 27 ++++++++-------------------
drivers/net/ethernet/intel/igb/igb_main.c | 12 ++----------
2 files changed, 10 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index a4b0435..30b647f 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -5582,16 +5582,15 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
*/
if (adapter->flags & FLAG_IS_QUAD_PORT) {
struct pci_dev *us_dev = pdev->bus->self;
- int pos = pci_pcie_cap(us_dev);
u16 devctl;

- pci_read_config_word(us_dev, pos + PCI_EXP_DEVCTL, &devctl);
- pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL,
- (devctl & ~PCI_EXP_DEVCTL_CERE));
+ pci_pcie_capability_read_word(us_dev, PCI_EXP_DEVCTL, &devctl);
+ pci_pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL,
+ (devctl & ~PCI_EXP_DEVCTL_CERE));

e1000_power_off(pdev, sleep, wake);

- pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl);
+ pci_pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl);
} else {
e1000_power_off(pdev, sleep, wake);
}
@@ -5605,25 +5604,15 @@ static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
#else
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
{
- int pos;
- u16 reg16;
-
/*
* Both device and parent should have the same ASPM setting.
* Disable ASPM in downstream component first and then upstream.
*/
- pos = pci_pcie_cap(pdev);
- pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
- reg16 &= ~state;
- pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
-
- if (!pdev->bus->self)
- return;
+ pci_pcie_capability_change_word(pdev, PCI_EXP_LNKCTL, 0, state);

- pos = pci_pcie_cap(pdev->bus->self);
- pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, &reg16);
- reg16 &= ~state;
- pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
+ if (pdev->bus->self)
+ pci_pcie_capability_change_word(pdev->bus->self, PCI_EXP_LNKCTL,
+ 0, state);
}
#endif
static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index dd3bfe8..3d46830 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -6446,28 +6446,20 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
{
struct igb_adapter *adapter = hw->back;
- u16 cap_offset;

- cap_offset = adapter->pdev->pcie_cap;
- if (!cap_offset)
+ if (pci_pcie_capability_read_word(adapter->pdev, reg, value))
return -E1000_ERR_CONFIG;

- pci_read_config_word(adapter->pdev, cap_offset + reg, value);
-
return 0;
}

s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
{
struct igb_adapter *adapter = hw->back;
- u16 cap_offset;

- cap_offset = adapter->pdev->pcie_cap;
- if (!cap_offset)
+ if (pci_pcie_capability_write_word(adapter->pdev, reg, *value))
return -E1000_ERR_CONFIG;

- pci_write_config_word(adapter->pdev, cap_offset + reg, *value);
-
return 0;
}

--
1.7.9.5

2012-08-01 15:58:16

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 18/32] PCI/vxge: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify vxge driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/net/ethernet/neterion/vxge/vxge-config.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/neterion/vxge/vxge-config.c b/drivers/net/ethernet/neterion/vxge/vxge-config.c
index 98e2c10..f83f0a4 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-config.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-config.c
@@ -757,7 +757,7 @@ __vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev)
u16 lnk;

/* Get the negotiated link width and speed from PCI config space */
- pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk);
+ pci_pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnk);

if ((lnk & PCI_EXP_LNKSTA_CLS) != 1)
return VXGE_HW_ERR_INVALID_PCI_INFO;
@@ -1982,7 +1982,7 @@ u16 vxge_hw_device_link_width_get(struct __vxge_hw_device *hldev)
struct pci_dev *dev = hldev->pdev;
u16 lnk;

- pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk);
+ pci_pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnk);
return (lnk & VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4;
}

--
1.7.9.5

2012-08-01 15:58:22

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 19/32] PCI/mlx4: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify mlx4 driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/net/ethernet/mellanox/mlx4/reset.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/reset.c b/drivers/net/ethernet/mellanox/mlx4/reset.c
index 11e7c1c..6895214 100644
--- a/drivers/net/ethernet/mellanox/mlx4/reset.c
+++ b/drivers/net/ethernet/mellanox/mlx4/reset.c
@@ -141,16 +141,16 @@ int mlx4_reset(struct mlx4_dev *dev)
/* Now restore the PCI headers */
if (pcie_cap) {
devctl = hca_header[(pcie_cap + PCI_EXP_DEVCTL) / 4];
- if (pci_write_config_word(dev->pdev, pcie_cap + PCI_EXP_DEVCTL,
- devctl)) {
+ if (pci_pcie_capability_write_word(dev->pdev, PCI_EXP_DEVCTL,
+ devctl)) {
err = -ENODEV;
mlx4_err(dev, "Couldn't restore HCA PCI Express "
"Device Control register, aborting.\n");
goto out;
}
linkctl = hca_header[(pcie_cap + PCI_EXP_LNKCTL) / 4];
- if (pci_write_config_word(dev->pdev, pcie_cap + PCI_EXP_LNKCTL,
- linkctl)) {
+ if (pci_pcie_capability_write_word(dev->pdev, PCI_EXP_LNKCTL,
+ linkctl)) {
err = -ENODEV;
mlx4_err(dev, "Couldn't restore HCA PCI Express "
"Link control register, aborting.\n");
--
1.7.9.5

2012-08-01 15:58:32

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 20/32] PCI/niu: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify niu driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/net/ethernet/sun/niu.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 703c8cc..e8e2932 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -9768,9 +9768,8 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev,
union niu_parent_id parent_id;
struct net_device *dev;
struct niu *np;
- int err, pos;
+ int err;
u64 dma_mask;
- u16 val16;

niu_driver_version();

@@ -9793,8 +9792,7 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev,
goto err_out_disable_pdev;
}

- pos = pci_pcie_cap(pdev);
- if (pos <= 0) {
+ if (!pci_is_pcie(pdev)) {
dev_err(&pdev->dev, "Cannot find PCI Express capability, aborting\n");
goto err_out_free_res;
}
@@ -9819,14 +9817,10 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev,
goto err_out_free_dev;
}

- pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &val16);
- val16 &= ~PCI_EXP_DEVCTL_NOSNOOP_EN;
- val16 |= (PCI_EXP_DEVCTL_CERE |
- PCI_EXP_DEVCTL_NFERE |
- PCI_EXP_DEVCTL_FERE |
- PCI_EXP_DEVCTL_URRE |
- PCI_EXP_DEVCTL_RELAX_EN);
- pci_write_config_word(pdev, pos + PCI_EXP_DEVCTL, val16);
+ pci_pcie_capability_change_word(pdev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE |
+ PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE |
+ PCI_EXP_DEVCTL_RELAX_EN, PCI_EXP_DEVCTL_NOSNOOP_EN);

dma_mask = DMA_BIT_MASK(44);
err = pci_set_dma_mask(pdev, dma_mask);
--
1.7.9.5

2012-08-01 15:58:43

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 21/32] PCI/myri10ge: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify myri10ge driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 39 ++++------------------
1 file changed, 7 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 90153fc..fe6c44d 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -1078,24 +1078,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
#ifdef CONFIG_MYRI10GE_DCA
static int myri10ge_toggle_relaxed(struct pci_dev *pdev, int on)
{
- int ret, cap, err;
- u16 ctl;
-
- cap = pci_pcie_cap(pdev);
- if (!cap)
- return 0;
-
- err = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
- if (err)
- return 0;
-
- ret = (ctl & PCI_EXP_DEVCTL_RELAX_EN) >> 4;
- if (ret != on) {
- ctl &= ~PCI_EXP_DEVCTL_RELAX_EN;
- ctl |= (on << 4);
- pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
- }
- return ret;
+ return pci_pcie_capability_change_word(pdev, PCI_EXP_DEVCTL,
+ on << 4, PCI_EXP_DEVCTL_RELAX_EN);
}

static void
@@ -3192,18 +3176,13 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
struct device *dev = &mgp->pdev->dev;
int cap;
unsigned err_cap;
- u16 val;
- u8 ext_type;
int ret;

if (!myri10ge_ecrc_enable || !bridge)
return;

/* check that the bridge is a root port */
- cap = pci_pcie_cap(bridge);
- pci_read_config_word(bridge, cap + PCI_CAP_FLAGS, &val);
- ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4;
- if (ext_type != PCI_EXP_TYPE_ROOT_PORT) {
+ if (pci_pcie_type(bridge) != PCI_EXP_TYPE_ROOT_PORT) {
if (myri10ge_ecrc_enable > 1) {
struct pci_dev *prev_bridge, *old_bridge = bridge;

@@ -3218,11 +3197,8 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
" to force ECRC\n");
return;
}
- cap = pci_pcie_cap(bridge);
- pci_read_config_word(bridge,
- cap + PCI_CAP_FLAGS, &val);
- ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4;
- } while (ext_type != PCI_EXP_TYPE_ROOT_PORT);
+ } while (pci_pcie_type(bridge) !=
+ PCI_EXP_TYPE_ROOT_PORT);

dev_info(dev,
"Forcing ECRC on non-root port %s"
@@ -3335,11 +3311,10 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
int overridden = 0;

if (myri10ge_force_firmware == 0) {
- int link_width, exp_cap;
+ int link_width;
u16 lnk;

- exp_cap = pci_pcie_cap(mgp->pdev);
- pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
+ pci_pcie_capability_read_word(mgp->pdev, PCI_EXP_LNKSTA, &lnk);
link_width = (lnk >> 4) & 0x3f;

/* Check to see if Link is less than 8 or if the
--
1.7.9.5

2012-08-01 15:58:52

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 22/32] PCI/chelsio: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify chelsio ethernet drivers'
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/net/ethernet/chelsio/cxgb3/t3_hw.c | 19 +++++++------------
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 11 ++---------
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 10 +++-------
3 files changed, 12 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
index 44ac2f4..8fadbb3 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
@@ -3289,22 +3289,18 @@ static void config_pcie(struct adapter *adap)
unsigned int log2_width, pldsize;
unsigned int fst_trn_rx, fst_trn_tx, acklat, rpllmt;

- pci_read_config_word(adap->pdev,
- adap->pdev->pcie_cap + PCI_EXP_DEVCTL,
- &val);
+ pci_pcie_capability_read_word(adap->pdev, PCI_EXP_DEVCTL, &val);
pldsize = (val & PCI_EXP_DEVCTL_PAYLOAD) >> 5;

pci_read_config_word(adap->pdev, 0x2, &devid);
if (devid == 0x37) {
- pci_write_config_word(adap->pdev,
- adap->pdev->pcie_cap + PCI_EXP_DEVCTL,
+ pci_pcie_capability_write_word(adap->pdev, PCI_EXP_DEVCTL,
val & ~PCI_EXP_DEVCTL_READRQ &
~PCI_EXP_DEVCTL_PAYLOAD);
pldsize = 0;
}

- pci_read_config_word(adap->pdev, adap->pdev->pcie_cap + PCI_EXP_LNKCTL,
- &val);
+ pci_pcie_capability_read_word(adap->pdev, PCI_EXP_LNKCTL, &val);

fst_trn_tx = G_NUMFSTTRNSEQ(t3_read_reg(adap, A_PCIE_PEX_CTRL0));
fst_trn_rx = adap->params.rev == 0 ? fst_trn_tx :
@@ -3425,15 +3421,14 @@ out_err:
static void get_pci_mode(struct adapter *adapter, struct pci_params *p)
{
static unsigned short speed_map[] = { 33, 66, 100, 133 };
- u32 pci_mode, pcie_cap;
+ u32 pci_mode;

- pcie_cap = pci_pcie_cap(adapter->pdev);
- if (pcie_cap) {
+ if (pci_is_pcie(adapter->pdev)) {
u16 val;

p->variant = PCI_VARIANT_PCIE;
- pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA,
- &val);
+ pci_pcie_capability_read_word(adapter->pdev, PCI_EXP_LNKSTA,
+ &val);
p->width = (val >> 4) & 0x3f;
return;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index e1f96fb..a414bac 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3694,15 +3694,8 @@ static void __devinit print_port_info(const struct net_device *dev)

static void __devinit enable_pcie_relaxed_ordering(struct pci_dev *dev)
{
- u16 v;
- int pos;
-
- pos = pci_pcie_cap(dev);
- if (pos > 0) {
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &v);
- v |= PCI_EXP_DEVCTL_RELAX_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, v);
- }
+ pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_RELAX_EN, 0);
}

/*
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 32e1dd5..f0e673e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -2741,14 +2741,10 @@ static void __devinit get_pci_mode(struct adapter *adapter,
struct pci_params *p)
{
u16 val;
- u32 pcie_cap = pci_pcie_cap(adapter->pdev);

- if (pcie_cap) {
- pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA,
- &val);
- p->speed = val & PCI_EXP_LNKSTA_CLS;
- p->width = (val & PCI_EXP_LNKSTA_NLW) >> 4;
- }
+ pci_pcie_capability_read_word(adapter->pdev, PCI_EXP_LNKSTA, &val);
+ p->speed = val & PCI_EXP_LNKSTA_CLS;
+ p->width = (val & PCI_EXP_LNKSTA_NLW) >> 4;
}

/**
--
1.7.9.5

2012-08-01 15:59:15

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 24/32] PCI/ath9k: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify ath9k driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/net/wireless/ath/ath9k/pci.c | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index a856b51..1aff99c 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -112,12 +112,7 @@ static void ath_pci_aspm_init(struct ath_common *common)
struct ath_hw *ah = sc->sc_ah;
struct pci_dev *pdev = to_pci_dev(sc->dev);
struct pci_dev *parent;
- int pos;
- u8 aspm;
-
- pos = pci_pcie_cap(pdev);
- if (!pos)
- return;
+ u16 aspm;

parent = pdev->bus->self;
if (!parent)
@@ -125,24 +120,20 @@ static void ath_pci_aspm_init(struct ath_common *common)

if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
/* Bluetooth coexistance requires disabling ASPM. */
- pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm);
- aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
- pci_write_config_byte(pdev, pos + PCI_EXP_LNKCTL, aspm);
+ pci_pcie_capability_change_word(pdev, PCI_EXP_LNKCTL,
+ 0, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);

/*
* Both upstream and downstream PCIe components should
* have the same ASPM settings.
*/
- pos = pci_pcie_cap(parent);
- pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm);
- aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
- pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm);
+ pci_pcie_capability_change_word(parent, PCI_EXP_LNKCTL,
+ 0, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);

return;
}

- pos = pci_pcie_cap(parent);
- pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm);
+ pci_pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &aspm);
if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) {
ah->aspm_enabled = true;
/* Initialize PCIe PM and SERDES registers. */
--
1.7.9.5

2012-08-01 15:59:30

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 25/32] PCI/iwl: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify Intel Wireless drivers'
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/net/wireless/iwlegacy/common.h | 5 ++---
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 +---
drivers/net/wireless/rtlwifi/pci.c | 8 +++-----
3 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index 5f50177..d119fa3 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1832,10 +1832,9 @@ int il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd);
static inline u16
il_pcie_link_ctl(struct il_priv *il)
{
- int pos;
u16 pci_lnk_ctl;
- pos = pci_pcie_cap(il->pci_dev);
- pci_read_config_word(il->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+ pci_pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL,
+ &pci_lnk_ctl);
return pci_lnk_ctl;
}

diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index ec6fb39..48b9561 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -643,15 +643,13 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans)

static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans)
{
- int pos;
u16 pci_lnk_ctl;
struct iwl_trans_pcie *trans_pcie =
IWL_TRANS_GET_PCIE_TRANS(trans);

struct pci_dev *pci_dev = trans_pcie->pci_dev;

- pos = pci_pcie_cap(pci_dev);
- pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+ pci_pcie_capability_read_word(pci_dev, PCI_EXP_LNKCTL, &pci_lnk_ctl);
return pci_lnk_ctl;
}

diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 2062ea1..1018b5b 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -372,13 +372,11 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev,
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);

u8 tmp;
- int pos;
- u8 linkctrl_reg;
+ u16 linkctrl_reg;

/*Link Control Register */
- pos = pci_pcie_cap(pdev);
- pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg);
- pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg;
+ pci_pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &linkctrl_reg);
+ pcipriv->ndis_adapter.linkctrl_reg = (u8)linkctrl_reg;

RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n",
pcipriv->ndis_adapter.linkctrl_reg);
--
1.7.9.5

2012-08-01 15:59:35

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 26/32] PCI/mthca: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify mthca driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/infiniband/hw/mthca/mthca_reset.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c
index 4fa3534..7b1a3bc 100644
--- a/drivers/infiniband/hw/mthca/mthca_reset.c
+++ b/drivers/infiniband/hw/mthca/mthca_reset.c
@@ -241,16 +241,16 @@ good:

if (hca_pcie_cap) {
devctl = hca_header[(hca_pcie_cap + PCI_EXP_DEVCTL) / 4];
- if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_DEVCTL,
- devctl)) {
+ if (pci_pcie_capability_write_word(mdev->pdev, PCI_EXP_DEVCTL,
+ devctl)) {
err = -ENODEV;
mthca_err(mdev, "Couldn't restore HCA PCI Express "
"Device Control register, aborting.\n");
goto out;
}
linkctl = hca_header[(hca_pcie_cap + PCI_EXP_LNKCTL) / 4];
- if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_LNKCTL,
- linkctl)) {
+ if (pci_pcie_capability_write_word(mdev->pdev, PCI_EXP_LNKCTL,
+ linkctl)) {
err = -ENODEV;
mthca_err(mdev, "Couldn't restore HCA PCI Express "
"Link control register, aborting.\n");
--
1.7.9.5

2012-08-01 15:59:43

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 27/32] PCI/qib: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify qib driver's implementation.

Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Yijing Wang <[email protected]>
---
drivers/infiniband/hw/qib/qib_pcie.c | 40 +++++++++++++++-------------------
1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c
index 790646e..9a5cb02 100644
--- a/drivers/infiniband/hw/qib/qib_pcie.c
+++ b/drivers/infiniband/hw/qib/qib_pcie.c
@@ -271,10 +271,9 @@ int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent,
struct qib_msix_entry *entry)
{
u16 linkstat, speed;
- int pos = 0, pose, ret = 1;
+ int pos = 0, ret = 1;

- pose = pci_pcie_cap(dd->pcidev);
- if (!pose) {
+ if (!pci_is_pcie(dd->pcidev)) {
qib_dev_err(dd, "Can't find PCI Express capability!\n");
/* set up something... */
dd->lbus_width = 1;
@@ -296,7 +295,7 @@ int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent,
if (!pos)
qib_enable_intx(dd->pcidev);

- pci_read_config_word(dd->pcidev, pose + PCI_EXP_LNKSTA, &linkstat);
+ pci_pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKSTA, &linkstat);
/*
* speed is bits 0-3, linkwidth is bits 4-8
* no defines for them in headers
@@ -514,7 +513,6 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd)
{
int r;
struct pci_dev *parent;
- int ppos;
u16 devid;
u32 mask, bits, val;

@@ -527,8 +525,7 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd)
qib_devinfo(dd->pcidev, "Parent not root\n");
return 1;
}
- ppos = pci_pcie_cap(parent);
- if (!ppos)
+ if (!pci_is_pcie(parent))
return 1;
if (parent->vendor != 0x8086)
return 1;
@@ -585,7 +582,6 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd)
{
int ret = 1; /* Assume the worst */
struct pci_dev *parent;
- int ppos, epos;
u16 pcaps, pctl, ecaps, ectl;
int rc_sup, ep_sup;
int rc_cur, ep_cur;
@@ -596,19 +592,15 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd)
qib_devinfo(dd->pcidev, "Parent not root\n");
goto bail;
}
- ppos = pci_pcie_cap(parent);
- if (ppos) {
- pci_read_config_word(parent, ppos + PCI_EXP_DEVCAP, &pcaps);
- pci_read_config_word(parent, ppos + PCI_EXP_DEVCTL, &pctl);
- } else
+
+ if (!pci_is_pcie(parent) || !pci_is_pcie(dd->pcidev))
goto bail;
+ pci_pcie_capability_read_word(parent, PCI_EXP_DEVCAP, &pcaps);
+ pci_pcie_capability_read_word(parent, PCI_EXP_DEVCTL, &pctl);
/* Find out supported and configured values for endpoint (us) */
- epos = pci_pcie_cap(dd->pcidev);
- if (epos) {
- pci_read_config_word(dd->pcidev, epos + PCI_EXP_DEVCAP, &ecaps);
- pci_read_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, &ectl);
- } else
- goto bail;
+ pci_pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCAP, &ecaps);
+ pci_pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCTL, &ectl);
+
ret = 0;
/* Find max payload supported by root, endpoint */
rc_sup = fld2val(pcaps, PCI_EXP_DEVCAP_PAYLOAD);
@@ -627,14 +619,15 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd)
rc_cur = rc_sup;
pctl = (pctl & ~PCI_EXP_DEVCTL_PAYLOAD) |
val2fld(rc_cur, PCI_EXP_DEVCTL_PAYLOAD);
- pci_write_config_word(parent, ppos + PCI_EXP_DEVCTL, pctl);
+ pci_pcie_capability_write_word(parent, PCI_EXP_DEVCTL, pctl);
}
/* If less than (allowed, supported), bump endpoint payload */
if (rc_sup > ep_cur) {
ep_cur = rc_sup;
ectl = (ectl & ~PCI_EXP_DEVCTL_PAYLOAD) |
val2fld(ep_cur, PCI_EXP_DEVCTL_PAYLOAD);
- pci_write_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, ectl);
+ pci_pcie_capability_write_word(dd->pcidev,
+ PCI_EXP_DEVCTL, ectl);
}

/*
@@ -652,13 +645,14 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd)
rc_cur = rc_sup;
pctl = (pctl & ~PCI_EXP_DEVCTL_READRQ) |
val2fld(rc_cur, PCI_EXP_DEVCTL_READRQ);
- pci_write_config_word(parent, ppos + PCI_EXP_DEVCTL, pctl);
+ pci_pcie_capability_write_word(parent, PCI_EXP_DEVCTL, pctl);
}
if (rc_sup > ep_cur) {
ep_cur = rc_sup;
ectl = (ectl & ~PCI_EXP_DEVCTL_READRQ) |
val2fld(ep_cur, PCI_EXP_DEVCTL_READRQ);
- pci_write_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, ectl);
+ pci_pcie_capability_write_word(dd->pcidev,
+ PCI_EXP_DEVCTL, ectl);
}
bail:
return ret;
--
1.7.9.5

2012-08-01 16:00:06

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 28/32] PCI/qla: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify QLA SCSI drivers'
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/scsi/qla2xxx/qla_init.c | 4 ++--
drivers/scsi/qla2xxx/qla_nx.c | 8 ++------
drivers/scsi/qla4xxx/ql4_nx.c | 4 +---
3 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index ca50847..a44653b 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -685,7 +685,7 @@ qla24xx_pci_config(scsi_qla_host_t *vha)
pcix_set_mmrbc(ha->pdev, 2048);

/* PCIe -- adjust Maximum Read Request Size (2048). */
- if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP))
+ if (pci_is_pcie(ha->pdev))
pcie_set_readrq(ha->pdev, 2048);

pci_disable_rom(ha->pdev);
@@ -721,7 +721,7 @@ qla25xx_pci_config(scsi_qla_host_t *vha)
pci_write_config_word(ha->pdev, PCI_COMMAND, w);

/* PCIe -- adjust Maximum Read Request Size (2048). */
- if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP))
+ if (pci_is_pcie(ha->pdev))
pcie_set_readrq(ha->pdev, 2048);

pci_disable_rom(ha->pdev);
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index caf627b..be516e9 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -1615,13 +1615,11 @@ qla82xx_get_fw_offs(struct qla_hw_data *ha)
char *
qla82xx_pci_info_str(struct scsi_qla_host *vha, char *str)
{
- int pcie_reg;
struct qla_hw_data *ha = vha->hw;
char lwstr[6];
uint16_t lnk;

- pcie_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP);
- pci_read_config_word(ha->pdev, pcie_reg + PCI_EXP_LNKSTA, &lnk);
+ pci_pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk);
ha->link_width = (lnk >> 4) & 0x3f;

strcpy(str, "PCIe (");
@@ -2497,7 +2495,6 @@ fw_load_failed:
int
qla82xx_start_firmware(scsi_qla_host_t *vha)
{
- int pcie_cap;
uint16_t lnk;
struct qla_hw_data *ha = vha->hw;

@@ -2528,8 +2525,7 @@ qla82xx_start_firmware(scsi_qla_host_t *vha)
}

/* Negotiated Link width */
- pcie_cap = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP);
- pci_read_config_word(ha->pdev, pcie_cap + PCI_EXP_LNKSTA, &lnk);
+ pci_pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk);
ha->link_width = (lnk >> 4) & 0x3f;

/* Synchronize with Receive peg */
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 228b670..7e30158 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -1566,7 +1566,6 @@ qla4_8xxx_set_qsnt_ready(struct scsi_qla_host *ha)
static int
qla4_8xxx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start)
{
- int pcie_cap;
uint16_t lnk;

/* scrub dma mask expansion register */
@@ -1590,8 +1589,7 @@ qla4_8xxx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start)
}

/* Negotiated Link width */
- pcie_cap = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP);
- pci_read_config_word(ha->pdev, pcie_cap + PCI_EXP_LNKSTA, &lnk);
+ pci_pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk);
ha->link_width = (lnk >> 4) & 0x3f;

/* Synchronize with Receive peg */
--
1.7.9.5

2012-08-01 16:00:19

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 30/32] PCI/tsi721: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify tsi721 driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/rapidio/devices/tsi721.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 722246c..5970c43 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -2212,9 +2212,8 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct tsi721_device *priv;
- int i, cap;
+ int i;
int err;
- u32 regval;

priv = kzalloc(sizeof(struct tsi721_device), GFP_KERNEL);
if (priv == NULL) {
@@ -2320,20 +2319,16 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
dev_info(&pdev->dev, "Unable to set consistent DMA mask\n");
}

- cap = pci_pcie_cap(pdev);
- BUG_ON(cap == 0);
+ BUG_ON(!pci_is_pcie(pdev));

/* Clear "no snoop" and "relaxed ordering" bits, use default MRRS. */
- pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, &regval);
- regval &= ~(PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN |
- PCI_EXP_DEVCTL_NOSNOOP_EN);
- regval |= 0x2 << MAX_READ_REQUEST_SZ_SHIFT;
- pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL, regval);
+ pci_pcie_capability_change_dword(pdev, PCI_EXP_DEVCTL,
+ 0x2 << MAX_READ_REQUEST_SZ_SHIFT,
+ PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN |
+ PCI_EXP_DEVCTL_NOSNOOP_EN);

/* Adjust PCIe completion timeout. */
- pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL2, &regval);
- regval &= ~(0x0f);
- pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL2, regval | 0x2);
+ pci_pcie_capability_change_dword(pdev, PCI_EXP_DEVCTL2, 0x2, 0xf);

/*
* FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block
--
1.7.9.5

2012-08-01 16:00:27

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 31/32] PCI/et131x: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify et131x driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/staging/et131x/et131x.c | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index 5b11c5e..7c2e781 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -4001,16 +4001,14 @@ static void et131x_hwaddr_init(struct et131x_adapter *adapter)
static int et131x_pci_init(struct et131x_adapter *adapter,
struct pci_dev *pdev)
{
- int cap = pci_pcie_cap(pdev);
u16 max_payload;
- u16 ctl;
int i, rc;

rc = et131x_init_eeprom(adapter);
if (rc < 0)
goto out;

- if (!cap) {
+ if (!pci_is_pcie(pdev)) {
dev_err(&pdev->dev, "Missing PCIe capabilities\n");
goto err_out;
}
@@ -4018,7 +4016,7 @@ static int et131x_pci_init(struct et131x_adapter *adapter,
/* Let's set up the PORT LOGIC Register. First we need to know what
* the max_payload_size is
*/
- if (pci_read_config_word(pdev, cap + PCI_EXP_DEVCAP, &max_payload)) {
+ if (pci_pcie_capability_read_word(pdev, PCI_EXP_DEVCAP, &max_payload)) {
dev_err(&pdev->dev,
"Could not read PCI config space for Max Payload Size\n");
goto err_out;
@@ -4055,17 +4053,10 @@ static int et131x_pci_init(struct et131x_adapter *adapter,
}

/* Change the max read size to 2k */
- if (pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl)) {
+ if (pci_pcie_capability_change_word(pdev, PCI_EXP_DEVCTL,
+ 0x4 << 12, PCI_EXP_DEVCTL_READRQ)) {
dev_err(&pdev->dev,
- "Could not read PCI config space for Max read size\n");
- goto err_out;
- }
-
- ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | (0x04 << 12);
-
- if (pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl)) {
- dev_err(&pdev->dev,
- "Could not write PCI config space for Max read size\n");
+ "Couldn't change PCI config space for Max read size\n");
goto err_out;
}

--
1.7.9.5

2012-08-01 16:00:42

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 32/32] PCI/rtl8192e: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify rtl8192e driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/staging/rtl8192e/rtl8192e/rtl_pci.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c
index ddadcc3..820cc68 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c
@@ -31,12 +31,10 @@ static void rtl8192_parse_pci_configuration(struct pci_dev *pdev,
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);

u8 tmp;
- int pos;
- u8 LinkCtrlReg;
+ u16 LinkCtrlReg;

- pos = pci_find_capability(priv->pdev, PCI_CAP_ID_EXP);
- pci_read_config_byte(priv->pdev, pos + PCI_EXP_LNKCTL, &LinkCtrlReg);
- priv->NdisAdapter.LinkCtrlReg = LinkCtrlReg;
+ pci_pcie_capability_read_word(priv->pdev, PCI_EXP_LNKCTL, &LinkCtrlReg);
+ priv->NdisAdapter.LinkCtrlReg = (u8)LinkCtrlReg;

RT_TRACE(COMP_INIT, "Link Control Register =%x\n",
priv->NdisAdapter.LinkCtrlReg);
--
1.7.9.5

2012-08-01 16:01:28

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 29/32] PCI/radeon: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify radeon driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/gpu/drm/radeon/evergreen.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 01550d0..8804c80 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -77,13 +77,9 @@ void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
{
u16 ctl, v;
- int cap, err;
+ int err;

- cap = pci_pcie_cap(rdev->pdev);
- if (!cap)
- return;
-
- err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl);
+ err = pci_pcie_capability_read_word(rdev->pdev, PCI_EXP_DEVCTL, &ctl);
if (err)
return;

@@ -95,7 +91,7 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
if ((v == 0) || (v == 6) || (v == 7)) {
ctl &= ~PCI_EXP_DEVCTL_READRQ;
ctl |= (2 << 12);
- pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl);
+ pci_pcie_capability_write_word(rdev->pdev, PCI_EXP_DEVCTL, ctl);
}
}

--
1.7.9.5

2012-08-01 16:02:20

by Jiang Liu

[permalink] [raw]
Subject: [PATCH v3 23/32] PCI/atl1c: use PCIe capabilities access functions to simplify implementation

From: Jiang Liu <[email protected]>

Use PCIe capabilities access functions to simplify atl1c driver's
implementation.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 9cc1570..1b7e1ff 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -149,7 +149,7 @@ static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag)
data &= ~(PCI_ERR_UNC_DLP | PCI_ERR_UNC_FCP);
pci_write_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, data);
/* clear error status */
- pci_write_config_word(pdev, pci_pcie_cap(pdev) + PCI_EXP_DEVSTA,
+ pci_pcie_capability_write_word(pdev, PCI_EXP_DEVSTA,
PCI_EXP_DEVSTA_NFED |
PCI_EXP_DEVSTA_FED |
PCI_EXP_DEVSTA_CED |
--
1.7.9.5

2012-08-01 16:04:44

by Deucher, Alexander

[permalink] [raw]
Subject: RE: [PATCH v3 29/32] PCI/radeon: use PCIe capabilities access functions to simplify implementation

> -----Original Message-----
> From: Jiang Liu [mailto:[email protected]]
> Sent: Wednesday, August 01, 2012 11:55 AM
> To: Bjorn Helgaas; Don Dutile; David Airlie; Dave Airlie; Deucher, Alexander;
> Jerome Glisse
> Cc: Jiang Liu; Yinghai Lu; Taku Izumi; Rafael J . Wysocki; Kenji Kaneshige; Yijing
> Wang; [email protected]; [email protected]; Jiang Liu
> Subject: [PATCH v3 29/32] PCI/radeon: use PCIe capabilities access functions
> to simplify implementation
>
> From: Jiang Liu <[email protected]>
>
> Use PCIe capabilities access functions to simplify radeon driver's
> implementation.
>
> Signed-off-by: Jiang Liu <[email protected]>

Reviewed-by: Alex Deucher <[email protected]>

> ---
> drivers/gpu/drm/radeon/evergreen.c | 10 +++-------
> 1 file changed, 3 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/evergreen.c
> b/drivers/gpu/drm/radeon/evergreen.c
> index 01550d0..8804c80 100644
> --- a/drivers/gpu/drm/radeon/evergreen.c
> +++ b/drivers/gpu/drm/radeon/evergreen.c
> @@ -77,13 +77,9 @@ void evergreen_tiling_fields(unsigned tiling_flags,
> unsigned *bankw,
> void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
> {
> u16 ctl, v;
> - int cap, err;
> + int err;
>
> - cap = pci_pcie_cap(rdev->pdev);
> - if (!cap)
> - return;
> -
> - err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL,
> &ctl);
> + err = pci_pcie_capability_read_word(rdev->pdev, PCI_EXP_DEVCTL,
> &ctl);
> if (err)
> return;
>
> @@ -95,7 +91,7 @@ void evergreen_fix_pci_max_read_req_size(struct
> radeon_device *rdev)
> if ((v == 0) || (v == 6) || (v == 7)) {
> ctl &= ~PCI_EXP_DEVCTL_READRQ;
> ctl |= (2 << 12);
> - pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL,
> ctl);
> + pci_pcie_capability_write_word(rdev->pdev,
> PCI_EXP_DEVCTL, ctl);
> }
> }
>
> --
> 1.7.9.5
>

2012-08-01 17:20:21

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH v3 12/32] PCI/ARM: use PCIe capabilities access functions to simplify implementation

On 08/01/2012 09:54 AM, Jiang Liu wrote:
> From: Jiang Liu <[email protected]>
>
> Use PCIe capabilities access functions to simplify PCIe ARM implementation.
>
> Signed-off-by: Jiang Liu <[email protected]>

This is probably fine from my perspective assuming the underlying PCI
API implementation is OKd by relevant people.

Thierry, can you comment on whether this will conflict with your Tegra
PCIe driver series? If it doesn't, this patch can go through any
relevant PCI tree. If it does, we may have to take this through the
Tegra tree after merging the dependencies, or defer it to later.

2012-08-01 17:30:14

by Marciniszyn, Mike

[permalink] [raw]
Subject: RE: [PATCH v3 27/32] PCI/qib: use PCIe capabilities access functions to simplify implementation

> Subject: [PATCH v3 27/32] PCI/qib: use PCIe capabilities access functions to
> simplify implementation

Acked-by: Mike Marciniszyn <[email protected]>

2012-08-01 21:07:27

by Chris Metcalf

[permalink] [raw]
Subject: Re: [PATCH v3 14/32] PCI/tile: use PCIe capabilities access functions to simplify implementation

On 8/1/2012 11:54 AM, Jiang Liu wrote:
> From: Jiang Liu <[email protected]>
>
> Use PCIe capabilities access functions to simplify PCIe tile implementation.
>
> Signed-off-by: Jiang Liu <[email protected]>
> ---
> arch/tile/kernel/pci.c | 25 +++++--------------------
> 1 file changed, 5 insertions(+), 20 deletions(-)

Acked-by: Chris Metcalf <[email protected]>

--
Chris Metcalf, Tilera Corp.
http://www.tilera.com

2012-08-02 01:30:35

by Kenji Kaneshige

[permalink] [raw]
Subject: RE: [PATCH v3 06/32] PCI/hotplug: use PCIe capabilities access functions to simplify implementation

Reviewed-by: Kenji Kaneshige <[email protected]>

Regards,
Kenji Kaneshige


> -----Original Message-----
> From: Jiang Liu [mailto:[email protected]]
> Sent: Thursday, August 02, 2012 12:54 AM
> To: Bjorn Helgaas; Don Dutile
> Cc: Jiang Liu; Yinghai Lu; Izumi, Taku/$B@t(B $BBs(B; Rafael J . Wysocki; Kaneshige,
> Kenji/$B6b=E(B $B7{<#(B; Yijing Wang; [email protected];
> [email protected]; Jiang Liu
> Subject: [PATCH v3 06/32] PCI/hotplug: use PCIe capabilities access
> functions to simplify implementation
>
> From: Jiang Liu <[email protected]>
>
> Use PCIe capabilities access functions to simplify cpihp_slot.c.
>
> Signed-off-by: Jiang Liu <[email protected]>
> ---
> drivers/pci/hotplug/pcihp_slot.c | 20 +++++---------------
> 1 file changed, 5 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/pci/hotplug/pcihp_slot.c
> b/drivers/pci/hotplug/pcihp_slot.c
> index 8c05a18..649dcc8 100644
> --- a/drivers/pci/hotplug/pcihp_slot.c
> +++ b/drivers/pci/hotplug/pcihp_slot.c
> @@ -96,17 +96,11 @@ static void program_hpp_type1(struct pci_dev *dev,
> struct hpp_type1 *hpp)
> static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
> {
> int pos;
> - u16 reg16;
> u32 reg32;
>
> if (!hpp)
> return;
>
> - /* Find PCI Express capability */
> - pos = pci_pcie_cap(dev);
> - if (!pos)
> - return;
> -
> if (hpp->revision > 1) {
> dev_warn(&dev->dev, "PCIe settings rev %d not
> supported\n",
> hpp->revision);
> @@ -114,17 +108,13 @@ static void program_hpp_type2(struct pci_dev *dev,
> struct hpp_type2 *hpp)
> }
>
> /* Initialize Device Control Register */
> - pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
> - reg16 = (reg16 & hpp->pci_exp_devctl_and) |
> hpp->pci_exp_devctl_or;
> - pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
> + pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL,
> + hpp->pci_exp_devctl_or,
> ~hpp->pci_exp_devctl_and);
>
> /* Initialize Link Control Register */
> - if (dev->subordinate) {
> - pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &reg16);
> - reg16 = (reg16 & hpp->pci_exp_lnkctl_and)
> - | hpp->pci_exp_lnkctl_or;
> - pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16);
> - }
> + if (dev->subordinate)
> + pci_pcie_capability_change_word(dev, PCI_EXP_LNKCTL,
> + hpp->pci_exp_lnkctl_or,
> ~hpp->pci_exp_lnkctl_and);
>
> /* Find Advanced Error Reporting Enhanced Capability */
> pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
> --
> 1.7.9.5

2012-08-02 01:33:41

by Kenji Kaneshige

[permalink] [raw]
Subject: RE: [PATCH v3 07/32] PCI/portdrv: use PCIe capabilities access functions to simplify implementation

Reviewed-by: Kenji Kaneshige <[email protected]>

Regards,
Kenji Kaneshige


> -----Original Message-----
> From: Jiang Liu [mailto:[email protected]]
> Sent: Thursday, August 02, 2012 12:54 AM
> To: Bjorn Helgaas; Don Dutile
> Cc: Jiang Liu; Yinghai Lu; Izumi, Taku/$B@t(B $BBs(B; Rafael J . Wysocki; Kaneshige,
> Kenji/$B6b=E(B $B7{<#(B; Yijing Wang; [email protected];
> [email protected]; Jiang Liu
> Subject: [PATCH v3 07/32] PCI/portdrv: use PCIe capabilities access
> functions to simplify implementation
>
> From: Jiang Liu <[email protected]>
>
> Use PCIe capabilities access functions to simplify PCIe portdrv
> implementation.
>
> Signed-off-by: Jiang Liu <[email protected]>
> Signed-off-by: Yijing Wang <[email protected]>
> ---
> drivers/pci/pcie/portdrv_core.c | 15 +++++----------
> drivers/pci/pcie/portdrv_pci.c | 10 ++--------
> 2 files changed, 7 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/pci/pcie/portdrv_core.c
> b/drivers/pci/pcie/portdrv_core.c
> index bf320a9..274d524 100644
> --- a/drivers/pci/pcie/portdrv_core.c
> +++ b/drivers/pci/pcie/portdrv_core.c
> @@ -246,8 +246,7 @@ static void cleanup_service_irqs(struct pci_dev *dev)
> */
> static int get_port_device_capability(struct pci_dev *dev)
> {
> - int services = 0, pos;
> - u16 reg16;
> + int services = 0;
> u32 reg32;
> int cap_mask = 0;
> int err;
> @@ -265,11 +264,9 @@ static int get_port_device_capability(struct pci_dev
> *dev)
> return 0;
> }
>
> - pos = pci_pcie_cap(dev);
> - pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
> /* Hot-Plug Capable */
> - if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 &
> PCI_EXP_FLAGS_SLOT)) {
> - pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP,
> &reg32);
> + if ((cap_mask & PCIE_PORT_SERVICE_HP)) {
> + pci_pcie_capability_read_dword(dev, PCI_EXP_SLTCAP,
> &reg32);
> if (reg32 & PCI_EXP_SLTCAP_HPC) {
> services |= PCIE_PORT_SERVICE_HP;
> /*
> @@ -277,10 +274,8 @@ static int get_port_device_capability(struct pci_dev
> *dev)
> * enabled by the BIOS and the hot-plug service
> driver
> * is not loaded.
> */
> - pos += PCI_EXP_SLTCTL;
> - pci_read_config_word(dev, pos, &reg16);
> - reg16 &= ~(PCI_EXP_SLTCTL_CCIE |
> PCI_EXP_SLTCTL_HPIE);
> - pci_write_config_word(dev, pos, reg16);
> + pci_pcie_capability_change_word(dev,
> PCI_EXP_SLTCTL,
> + 0, PCI_EXP_SLTCTL_CCIE |
> PCI_EXP_SLTCTL_HPIE);
> }
> }
> /* AER capable */
> diff --git a/drivers/pci/pcie/portdrv_pci.c
> b/drivers/pci/pcie/portdrv_pci.c
> index 24d1463..93f726c 100644
> --- a/drivers/pci/pcie/portdrv_pci.c
> +++ b/drivers/pci/pcie/portdrv_pci.c
> @@ -64,14 +64,8 @@ __setup("pcie_ports=", pcie_port_setup);
> */
> void pcie_clear_root_pme_status(struct pci_dev *dev)
> {
> - int rtsta_pos;
> - u32 rtsta;
> -
> - rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA;
> -
> - pci_read_config_dword(dev, rtsta_pos, &rtsta);
> - rtsta |= PCI_EXP_RTSTA_PME;
> - pci_write_config_dword(dev, rtsta_pos, rtsta);
> + pci_pcie_capability_change_dword(dev, PCI_EXP_RTSTA,
> + PCI_EXP_RTSTA_PME, 0);
> }
>
> static int pcie_portdrv_restore_config(struct pci_dev *dev)
> --
> 1.7.9.5

2012-08-02 01:37:15

by Kenji Kaneshige

[permalink] [raw]
Subject: RE: [PATCH v3 08/32] PCI/pciehp: use PCIe capabilities access functions to simplify implementation

Reviewed-by: Kenji Kaneshige <[email protected]>

Regards,
Kenji Kaneshige


> -----Original Message-----
> From: Jiang Liu [mailto:[email protected]]
> Sent: Thursday, August 02, 2012 12:54 AM
> To: Bjorn Helgaas; Don Dutile
> Cc: Jiang Liu; Yinghai Lu; Izumi, Taku/$B@t(B $BBs(B; Rafael J . Wysocki; Kaneshige,
> Kenji/$B6b=E(B $B7{<#(B; Yijing Wang; [email protected];
> [email protected]; Jiang Liu
> Subject: [PATCH v3 08/32] PCI/pciehp: use PCIe capabilities access
> functions to simplify implementation
>
> From: Jiang Liu <[email protected]>
>
> Use PCIe capabilities access functions to simplify pciehp implementation.
>
> Signed-off-by: Jiang Liu <[email protected]>
> Signed-off-by: Yijing Wang <[email protected]>
> ---
> drivers/pci/hotplug/pciehp_acpi.c | 6 +-----
> drivers/pci/hotplug/pciehp_hpc.c | 12 ++++--------
> 2 files changed, 5 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/pci/hotplug/pciehp_acpi.c
> b/drivers/pci/hotplug/pciehp_acpi.c
> index 376d70d..751b41c 100644
> --- a/drivers/pci/hotplug/pciehp_acpi.c
> +++ b/drivers/pci/hotplug/pciehp_acpi.c
> @@ -81,16 +81,12 @@ static struct list_head __initdata dummy_slots =
> LIST_HEAD_INIT(dummy_slots);
> /* Dummy driver for dumplicate name detection */
> static int __init dummy_probe(struct pcie_device *dev)
> {
> - int pos;
> u32 slot_cap;
> acpi_handle handle;
> struct dummy_slot *slot, *tmp;
> struct pci_dev *pdev = dev->port;
>
> - pos = pci_pcie_cap(pdev);
> - if (!pos)
> - return -ENODEV;
> - pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap);
> + pci_pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP,
> &slot_cap);
> slot = kzalloc(sizeof(*slot), GFP_KERNEL);
> if (!slot)
> return -ENOMEM;
> diff --git a/drivers/pci/hotplug/pciehp_hpc.c
> b/drivers/pci/hotplug/pciehp_hpc.c
> index 302451e..cf0daf1 100644
> --- a/drivers/pci/hotplug/pciehp_hpc.c
> +++ b/drivers/pci/hotplug/pciehp_hpc.c
> @@ -44,25 +44,25 @@
> static inline int pciehp_readw(struct controller *ctrl, int reg, u16
> *value)
> {
> struct pci_dev *dev = ctrl->pcie->port;
> - return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value);
> + return pci_pcie_capability_read_word(dev, reg, value);
> }
>
> static inline int pciehp_readl(struct controller *ctrl, int reg, u32
> *value)
> {
> struct pci_dev *dev = ctrl->pcie->port;
> - return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg,
> value);
> + return pci_pcie_capability_read_dword(dev, reg, value);
> }
>
> static inline int pciehp_writew(struct controller *ctrl, int reg, u16
> value)
> {
> struct pci_dev *dev = ctrl->pcie->port;
> - return pci_write_config_word(dev, pci_pcie_cap(dev) + reg,
> value);
> + return pci_pcie_capability_write_word(dev, reg, value);
> }
>
> static inline int pciehp_writel(struct controller *ctrl, int reg, u32
> value)
> {
> struct pci_dev *dev = ctrl->pcie->port;
> - return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg,
> value);
> + return pci_pcie_capability_write_dword(dev, reg, value);
> }
>
> /* Power Control Command */
> @@ -855,10 +855,6 @@ struct controller *pcie_init(struct pcie_device *dev)
> goto abort;
> }
> ctrl->pcie = dev;
> - if (!pci_pcie_cap(pdev)) {
> - ctrl_err(ctrl, "Cannot find PCI Express capability\n");
> - goto abort_ctrl;
> - }
> if (pciehp_readl(ctrl, PCI_EXP_SLTCAP, &slot_cap)) {
> ctrl_err(ctrl, "Cannot read SLOTCAP register\n");
> goto abort_ctrl;
> --
> 1.7.9.5

2012-08-02 05:58:56

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v3 12/32] PCI/ARM: use PCIe capabilities access functions to simplify implementation

On Wed, Aug 01, 2012 at 11:20:13AM -0600, Stephen Warren wrote:
> On 08/01/2012 09:54 AM, Jiang Liu wrote:
> > From: Jiang Liu <[email protected]>
> >
> > Use PCIe capabilities access functions to simplify PCIe ARM implementation.
> >
> > Signed-off-by: Jiang Liu <[email protected]>
>
> This is probably fine from my perspective assuming the underlying PCI
> API implementation is OKd by relevant people.
>
> Thierry, can you comment on whether this will conflict with your Tegra
> PCIe driver series? If it doesn't, this patch can go through any
> relevant PCI tree. If it does, we may have to take this through the
> Tegra tree after merging the dependencies, or defer it to later.

I haven't touched those lines. tegra_pcie_relax_enable() only uses
generic PCI functions so I don't expect any conflicts. git blame
confirms that those lines haven't been changed in about 2 years.

Thierry


Attachments:
(No filename) (898.00 B)
(No filename) (836.00 B)
Download all attachments

2012-08-02 21:47:17

by Roland Dreier

[permalink] [raw]
Subject: Re: [PATCH v3 26/32] PCI/mthca: use PCIe capabilities access functions to simplify implementation

> Use PCIe capabilities access functions to simplify mthca driver's
> implementation.

Acked-by: Roland Dreier <[email protected]>

2012-08-02 22:12:17

by Jeff Kirsher

[permalink] [raw]
Subject: Re: [PATCH v3 17/32] PCI/igb: use PCIe capabilities access functions to simplify implementation

On Wed, 2012-08-01 at 23:54 +0800, Jiang Liu wrote:
> From: Jiang Liu <[email protected]>
>
> Use PCIe capabilities access functions to simplify Intel ethernet
> drivers'
> implementation.
>
> Signed-off-by: Jiang Liu <[email protected]>
> Signed-off-by: Yijing Wang <[email protected]>
> ---
> drivers/net/ethernet/intel/e1000e/netdev.c | 27
> ++++++++-------------------
> drivers/net/ethernet/intel/igb/igb_main.c | 12 ++----------
> 2 files changed, 10 insertions(+), 29 deletions(-)

Acked-by: Jeff Kirsher <[email protected]>


Attachments:
signature.asc (836.00 B)
This is a digitally signed message part

2012-08-03 18:05:27

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH v3 12/32] PCI/ARM: use PCIe capabilities access functions to simplify implementation

On 08/01/2012 09:54 AM, Jiang Liu wrote:
> From: Jiang Liu <[email protected]>
>
> Use PCIe capabilities access functions to simplify PCIe ARM implementation.
>
> Signed-off-by: Jiang Liu <[email protected]>

Acked-by: Stephen Warren <[email protected]>

2012-08-09 14:34:59

by Bounine, Alexandre

[permalink] [raw]
Subject: RE: [PATCH v3 30/32] PCI/tsi721: use PCIe capabilities access functions to simplify implementation

> Sent: Wednesday, August 01, 2012 11:55 AM
> Subject: [PATCH v3 30/32] PCI/tsi721: use PCIe capabilities access
> functions to simplify implementation
>
> From: Jiang Liu <[email protected]>
>
> Use PCIe capabilities access functions to simplify tsi721 driver's
> implementation.
>
> Signed-off-by: Jiang Liu <[email protected]>
> ---
> drivers/rapidio/devices/tsi721.c | 19 +++++++------------
> 1 file changed, 7 insertions(+), 12 deletions(-)
>

Acked-by: Alexandre Bounine <[email protected]>

2012-08-13 21:40:17

by David Daney

[permalink] [raw]
Subject: Re: [PATCH v3 13/32] PCI/MIPS: use PCIe capabilities access functions to simplify implementation

On 08/01/2012 08:54 AM, Jiang Liu wrote:
> From: Jiang Liu<[email protected]>
>
> Use PCIe capabilities access functions to simplify PCIe MIPS implementation.
>
> Signed-off-by: Jiang Liu<[email protected]>

Acked-by: David Daney <[email protected]>

> ---
> arch/mips/pci/pci-octeon.c | 15 +++++----------
> 1 file changed, 5 insertions(+), 10 deletions(-)
>
> diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c
> index 52a1ba7..aaed2ad 100644
> --- a/arch/mips/pci/pci-octeon.c
> +++ b/arch/mips/pci/pci-octeon.c
> @@ -117,16 +117,11 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
> }
>
> /* Enable the PCIe normal error reporting */
> - pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
> - if (pos) {
> - /* Update Device Control */
> - pci_read_config_word(dev, pos + PCI_EXP_DEVCTL,&config);
> - config |= PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */
> - config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */
> - config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */
> - config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */
> - pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
> - }
> + config = PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */
> + config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */
> + config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */
> + config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */
> + pci_pcie_capability_change_word(dev, PCI_EXP_DEVCTL, config, 0);
>
> /* Find the Advanced Error Reporting capability */
> pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);

2012-08-14 04:26:19

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

On Wed, Aug 1, 2012 at 8:54 AM, Jiang Liu <[email protected]> wrote:
> From: Jiang Liu <[email protected]>
>
> As suggested by Bjorn Helgaas and Don Dutile in threads
> http://www.spinics.net/lists/linux-pci/msg15663.html, we could improve access
> to PCIe capabilities register in to way:
> 1) cache content of PCIe Capabilities Register into struct pce_dev to avoid
> repeatedly reading this register because it's read only.
> 2) provide access functions for PCIe Capabilities registers to hide differences
> among PCIe base specifications, so the caller don't need to handle those
> differences.
>
> This patch set applies to
> git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci-next

Would you mind rebasing this to v3.6-rc1? I think you posted this
when my branch was still 3.5-based, and there are some upstream
changes that cause minor conflicts here.

You currently have:

int pci_pcie_capability_change_word(struct pci_dev *dev, int pos,
u16 set_bits, u16 clear_bits)

I think this is a bit awkward because the function name doesn't
suggest *how* the word will be changed, and the clearing happens
before the setting (opposite the parameter order). Something like:

int pci_pcie_capability_mask_and_set_word(..., u16 mask, u16 set) or
int pci_pcie_capability_clear_and_set_word(..., u16 clear, u16 set)

would be more obvious. If you use "mask_and_set", I think the
function should do "(val & mask) | set" with the complement being at
the call site. If you use "clear_and_set", I think it's OK to do
"(val & ~mask) | set" as in your current patch.

I know I suggested the "pci_pcie_capability_*" names, but they're
getting a bit unwieldy, especially if we do "mask_and_set" or similar.
There are already several "pcie_*" functions, so maybe we should
drop the leading "pci_" from these and just have:

pcie_capability_read_word
pcie_capability_write_word
pcie_capability_mask_and_set_word

Bjorn

2012-08-14 15:47:08

by Jiang Liu

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

Hi Bjorn,
No problem, will handle issues mentioned below.
Regards!
Gerry
On 08/14/2012 12:25 PM, Bjorn Helgaas wrote:
> On Wed, Aug 1, 2012 at 8:54 AM, Jiang Liu <[email protected]> wrote:
>> From: Jiang Liu <[email protected]>
>>
>> As suggested by Bjorn Helgaas and Don Dutile in threads
>> http://www.spinics.net/lists/linux-pci/msg15663.html, we could improve access
>> to PCIe capabilities register in to way:
>> 1) cache content of PCIe Capabilities Register into struct pce_dev to avoid
>> repeatedly reading this register because it's read only.
>> 2) provide access functions for PCIe Capabilities registers to hide differences
>> among PCIe base specifications, so the caller don't need to handle those
>> differences.
>>
>> This patch set applies to
>> git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci-next
>
> Would you mind rebasing this to v3.6-rc1? I think you posted this
> when my branch was still 3.5-based, and there are some upstream
> changes that cause minor conflicts here.
>
> You currently have:
>
> int pci_pcie_capability_change_word(struct pci_dev *dev, int pos,
> u16 set_bits, u16 clear_bits)
>
> I think this is a bit awkward because the function name doesn't
> suggest *how* the word will be changed, and the clearing happens
> before the setting (opposite the parameter order). Something like:
>
> int pci_pcie_capability_mask_and_set_word(..., u16 mask, u16 set) or
> int pci_pcie_capability_clear_and_set_word(..., u16 clear, u16 set)
>
> would be more obvious. If you use "mask_and_set", I think the
> function should do "(val & mask) | set" with the complement being at
> the call site. If you use "clear_and_set", I think it's OK to do
> "(val & ~mask) | set" as in your current patch.
>
> I know I suggested the "pci_pcie_capability_*" names, but they're
> getting a bit unwieldy, especially if we do "mask_and_set" or similar.
> There are already several "pcie_*" functions, so maybe we should
> drop the leading "pci_" from these and just have:
>
> pcie_capability_read_word
> pcie_capability_write_word
> pcie_capability_mask_and_set_word
>
> Bjorn
>

2012-08-20 15:27:04

by Jiang Liu

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

On 08/14/2012 12:25 PM, Bjorn Helgaas wrote:
> On Wed, Aug 1, 2012 at 8:54 AM, Jiang Liu <[email protected]> wrote:
>> From: Jiang Liu <[email protected]>
>>
>> As suggested by Bjorn Helgaas and Don Dutile in threads
>> http://www.spinics.net/lists/linux-pci/msg15663.html, we could improve access
>> to PCIe capabilities register in to way:
>> 1) cache content of PCIe Capabilities Register into struct pce_dev to avoid
>> repeatedly reading this register because it's read only.
>> 2) provide access functions for PCIe Capabilities registers to hide differences
>> among PCIe base specifications, so the caller don't need to handle those
>> differences.
>>
>> This patch set applies to
>> git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci-next
>
> Would you mind rebasing this to v3.6-rc1? I think you posted this
> when my branch was still 3.5-based, and there are some upstream
> changes that cause minor conflicts here.
>
> You currently have:
>
> int pci_pcie_capability_change_word(struct pci_dev *dev, int pos,
> u16 set_bits, u16 clear_bits)
>
> I think this is a bit awkward because the function name doesn't
> suggest *how* the word will be changed, and the clearing happens
> before the setting (opposite the parameter order). Something like:
>
> int pci_pcie_capability_mask_and_set_word(..., u16 mask, u16 set) or
> int pci_pcie_capability_clear_and_set_word(..., u16 clear, u16 set)
>
> would be more obvious. If you use "mask_and_set", I think the
> function should do "(val & mask) | set" with the complement being at
> the call site. If you use "clear_and_set", I think it's OK to do
> "(val & ~mask) | set" as in your current patch.
>
> I know I suggested the "pci_pcie_capability_*" names, but they're
> getting a bit unwieldy, especially if we do "mask_and_set" or similar.
> There are already several "pcie_*" functions, so maybe we should
> drop the leading "pci_" from these and just have:
>
> pcie_capability_read_word
> pcie_capability_write_word
> pcie_capability_mask_and_set_word
>
> Bjorn
>
Hi Bjorn,
I have made following changes according to your suggestions,
1) get rid of the "pci_" prefix for access functions.
2) rename pci_pcie_capability_change_{word|dword}() to
pcie_capability_clear_and_set_{word|dword}.
3) add pcie_capability_{set|clear}_{word|dword}().
4) Add "Acked-by" and "Reviewed-by"
5) rebase to your latest pci-next tree

So could you please help to pull from "https://github.com/jiangliu/linux.git topic/pcie-cap"
or should I send all the patches to mail list again?

Regards!
Gerry

2012-08-20 15:35:45

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

On Mon, Aug 20, 2012 at 9:26 AM, Jiang Liu <[email protected]> wrote:
> On 08/14/2012 12:25 PM, Bjorn Helgaas wrote:
>> On Wed, Aug 1, 2012 at 8:54 AM, Jiang Liu <[email protected]> wrote:
>>> From: Jiang Liu <[email protected]>
>>>
>>> As suggested by Bjorn Helgaas and Don Dutile in threads
>>> http://www.spinics.net/lists/linux-pci/msg15663.html, we could improve access
>>> to PCIe capabilities register in to way:
>>> 1) cache content of PCIe Capabilities Register into struct pce_dev to avoid
>>> repeatedly reading this register because it's read only.
>>> 2) provide access functions for PCIe Capabilities registers to hide differences
>>> among PCIe base specifications, so the caller don't need to handle those
>>> differences.
>>>
>>> This patch set applies to
>>> git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci-next
>>
>> Would you mind rebasing this to v3.6-rc1? I think you posted this
>> when my branch was still 3.5-based, and there are some upstream
>> changes that cause minor conflicts here.
>>
>> You currently have:
>>
>> int pci_pcie_capability_change_word(struct pci_dev *dev, int pos,
>> u16 set_bits, u16 clear_bits)
>>
>> I think this is a bit awkward because the function name doesn't
>> suggest *how* the word will be changed, and the clearing happens
>> before the setting (opposite the parameter order). Something like:
>>
>> int pci_pcie_capability_mask_and_set_word(..., u16 mask, u16 set) or
>> int pci_pcie_capability_clear_and_set_word(..., u16 clear, u16 set)
>>
>> would be more obvious. If you use "mask_and_set", I think the
>> function should do "(val & mask) | set" with the complement being at
>> the call site. If you use "clear_and_set", I think it's OK to do
>> "(val & ~mask) | set" as in your current patch.
>>
>> I know I suggested the "pci_pcie_capability_*" names, but they're
>> getting a bit unwieldy, especially if we do "mask_and_set" or similar.
>> There are already several "pcie_*" functions, so maybe we should
>> drop the leading "pci_" from these and just have:
>>
>> pcie_capability_read_word
>> pcie_capability_write_word
>> pcie_capability_mask_and_set_word
>>
>> Bjorn
>>
> Hi Bjorn,
> I have made following changes according to your suggestions,
> 1) get rid of the "pci_" prefix for access functions.
> 2) rename pci_pcie_capability_change_{word|dword}() to
> pcie_capability_clear_and_set_{word|dword}.
> 3) add pcie_capability_{set|clear}_{word|dword}().

Are 2) and 3) really the same? If they're really different, we'll end up with:

pcie_capability_clear_and_set_word()
pcie_capability_clear_and_set_dword()
pcie_capability_set_word()
pcie_capability_set_dword()
pcie_capability_clear_word()
pcie_capability_clear_dword()

It seems a little excessive to have all six interfaces, since the
first two are sufficient to provide all the functionality.

> 4) Add "Acked-by" and "Reviewed-by"
> 5) rebase to your latest pci-next tree
>
> So could you please help to pull from "https://github.com/jiangliu/linux.git topic/pcie-cap"
> or should I send all the patches to mail list again?

Just let me know what you think about the above, and I'll try pulling
from your tree. We're done to nits, and it hardly seems worthwhile to
flood LKML with 32 more almost-identical patches.

Bjorn

2012-08-20 15:47:51

by Jiang Liu

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

On 08/20/2012 11:35 PM, Bjorn Helgaas wrote:
> On Mon, Aug 20, 2012 at 9:26 AM, Jiang Liu <[email protected]> wrote:
>> On 08/14/2012 12:25 PM, Bjorn Helgaas wrote:
>>> On Wed, Aug 1, 2012 at 8:54 AM, Jiang Liu <[email protected]> wrote:
>>>> From: Jiang Liu <[email protected]>
>>>>
>>>> As suggested by Bjorn Helgaas and Don Dutile in threads
>>>> http://www.spinics.net/lists/linux-pci/msg15663.html, we could improve access
>>>> to PCIe capabilities register in to way:
>>>> 1) cache content of PCIe Capabilities Register into struct pce_dev to avoid
>>>> repeatedly reading this register because it's read only.
>>>> 2) provide access functions for PCIe Capabilities registers to hide differences
>>>> among PCIe base specifications, so the caller don't need to handle those
>>>> differences.
>>>>
>>>> This patch set applies to
>>>> git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci-next
>>>
>>> Would you mind rebasing this to v3.6-rc1? I think you posted this
>>> when my branch was still 3.5-based, and there are some upstream
>>> changes that cause minor conflicts here.
>>>
>>> You currently have:
>>>
>>> int pci_pcie_capability_change_word(struct pci_dev *dev, int pos,
>>> u16 set_bits, u16 clear_bits)
>>>
>>> I think this is a bit awkward because the function name doesn't
>>> suggest *how* the word will be changed, and the clearing happens
>>> before the setting (opposite the parameter order). Something like:
>>>
>>> int pci_pcie_capability_mask_and_set_word(..., u16 mask, u16 set) or
>>> int pci_pcie_capability_clear_and_set_word(..., u16 clear, u16 set)
>>>
>>> would be more obvious. If you use "mask_and_set", I think the
>>> function should do "(val & mask) | set" with the complement being at
>>> the call site. If you use "clear_and_set", I think it's OK to do
>>> "(val & ~mask) | set" as in your current patch.
>>>
>>> I know I suggested the "pci_pcie_capability_*" names, but they're
>>> getting a bit unwieldy, especially if we do "mask_and_set" or similar.
>>> There are already several "pcie_*" functions, so maybe we should
>>> drop the leading "pci_" from these and just have:
>>>
>>> pcie_capability_read_word
>>> pcie_capability_write_word
>>> pcie_capability_mask_and_set_word
>>>
>>> Bjorn
>>>
>> Hi Bjorn,
>> I have made following changes according to your suggestions,
>> 1) get rid of the "pci_" prefix for access functions.
>> 2) rename pci_pcie_capability_change_{word|dword}() to
>> pcie_capability_clear_and_set_{word|dword}.
>> 3) add pcie_capability_{set|clear}_{word|dword}().
>
> Are 2) and 3) really the same? If they're really different, we'll end up with:
>
> pcie_capability_clear_and_set_word()
> pcie_capability_clear_and_set_dword()
> pcie_capability_set_word()
> pcie_capability_set_dword()
> pcie_capability_clear_word()
> pcie_capability_clear_dword()
>
> It seems a little excessive to have all six interfaces, since the
> first two are sufficient to provide all the functionality.
>
Hi Bjorn,
pcie_capability_{set|clear}_{word|dword}() are implemented as inline functions
which just call pcie_capability_clear_and_set_{word|dword}(). If it seems a little redundant,
I could help to remove them.
Regards!
Gerry

2012-08-20 16:10:37

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

On Mon, Aug 20, 2012 at 9:47 AM, Jiang Liu <[email protected]> wrote:
> On 08/20/2012 11:35 PM, Bjorn Helgaas wrote:
>> On Mon, Aug 20, 2012 at 9:26 AM, Jiang Liu <[email protected]> wrote:
>>> On 08/14/2012 12:25 PM, Bjorn Helgaas wrote:
>>>> On Wed, Aug 1, 2012 at 8:54 AM, Jiang Liu <[email protected]> wrote:
>>>>> From: Jiang Liu <[email protected]>
>>>>>
>>>>> As suggested by Bjorn Helgaas and Don Dutile in threads
>>>>> http://www.spinics.net/lists/linux-pci/msg15663.html, we could improve access
>>>>> to PCIe capabilities register in to way:
>>>>> 1) cache content of PCIe Capabilities Register into struct pce_dev to avoid
>>>>> repeatedly reading this register because it's read only.
>>>>> 2) provide access functions for PCIe Capabilities registers to hide differences
>>>>> among PCIe base specifications, so the caller don't need to handle those
>>>>> differences.
>>>>>
>>>>> This patch set applies to
>>>>> git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci-next
>>>>
>>>> Would you mind rebasing this to v3.6-rc1? I think you posted this
>>>> when my branch was still 3.5-based, and there are some upstream
>>>> changes that cause minor conflicts here.
>>>>
>>>> You currently have:
>>>>
>>>> int pci_pcie_capability_change_word(struct pci_dev *dev, int pos,
>>>> u16 set_bits, u16 clear_bits)
>>>>
>>>> I think this is a bit awkward because the function name doesn't
>>>> suggest *how* the word will be changed, and the clearing happens
>>>> before the setting (opposite the parameter order). Something like:
>>>>
>>>> int pci_pcie_capability_mask_and_set_word(..., u16 mask, u16 set) or
>>>> int pci_pcie_capability_clear_and_set_word(..., u16 clear, u16 set)
>>>>
>>>> would be more obvious. If you use "mask_and_set", I think the
>>>> function should do "(val & mask) | set" with the complement being at
>>>> the call site. If you use "clear_and_set", I think it's OK to do
>>>> "(val & ~mask) | set" as in your current patch.
>>>>
>>>> I know I suggested the "pci_pcie_capability_*" names, but they're
>>>> getting a bit unwieldy, especially if we do "mask_and_set" or similar.
>>>> There are already several "pcie_*" functions, so maybe we should
>>>> drop the leading "pci_" from these and just have:
>>>>
>>>> pcie_capability_read_word
>>>> pcie_capability_write_word
>>>> pcie_capability_mask_and_set_word
>>>>
>>>> Bjorn
>>>>
>>> Hi Bjorn,
>>> I have made following changes according to your suggestions,
>>> 1) get rid of the "pci_" prefix for access functions.
>>> 2) rename pci_pcie_capability_change_{word|dword}() to
>>> pcie_capability_clear_and_set_{word|dword}.
>>> 3) add pcie_capability_{set|clear}_{word|dword}().
>>
>> Are 2) and 3) really the same? If they're really different, we'll end up with:
>>
>> pcie_capability_clear_and_set_word()
>> pcie_capability_clear_and_set_dword()
>> pcie_capability_set_word()
>> pcie_capability_set_dword()
>> pcie_capability_clear_word()
>> pcie_capability_clear_dword()
>>
>> It seems a little excessive to have all six interfaces, since the
>> first two are sufficient to provide all the functionality.
>>
> Hi Bjorn,
> pcie_capability_{set|clear}_{word|dword}() are implemented as inline functions
> which just call pcie_capability_clear_and_set_{word|dword}(). If it seems a little redundant,
> I could help to remove them.

I looked through your v3 patches and found

12 clear_word callers
9 set_word callers
11 clear_and_set_word callers
0 clear_dword callers
0 set_dword callers
2 clear_and_set_dword callers that should be clear_and_set_word
callers (in tsi721.c)
1 clear_and_set_dword caller (PCI_EXP_RTSTA, Root Status)

I had expected that almost all would be clear_and_set users, but that
wasn't the case. Bottom line, it does seem like there are enough
callers of clear, set, and clear_and_set to keep all of them.

There's only one legitimate user of the dword interfaces, but I'm OK
with keeping all of them for symmetry with the word interfaces.

So I'll try pulling your branch (I'll do something about the tsi721.c
stuff myself).

Thanks!

Bjorn

2012-08-20 22:14:18

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

On Mon, Aug 20, 2012 at 10:10 AM, Bjorn Helgaas <[email protected]> wrote:

> So I'll try pulling your branch (I'll do something about the tsi721.c
> stuff myself).

I pulled this into
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git
pci/jiang-pcie-cap with the following changes:

- Dropped some "pci_" prefixes on internal functions in access.c
- Minor restructure of pcie_capability_read_*()
- Removed export of pcie_capability_reg_implemented()
- Reworked reset_intel_82599_sfp_virtfn() to check for FLR bit in
DEVCAP rather than using pcie_capability_reg_implemented()
- Split driver patches into one driver per patch
- Fixed myri10ge_toggle_relaxed() -- previous code returned useful
value, but your patch made it always return zero
- Use 16-bit, not 32-bit, accesses for DEVCTL, DEVCTL2 (tsi721)

I am still concerned about reset_intel_82599_sfp_virtfn(). It looks
wrong and possibly unnecessary. It looks wrong because it sets
PCI_EXP_DEVCTL_BCR_FLR and blindly clears all other bits in
PCI_EXP_DEVCTL. Most of the bits are probably cleared by the FLR
anyway, but Aux Power PM Enable is RWS ("sticky"), so it is *not*
modified by FLR. Therefore, using reset_intel_82599_sfp_virtfn() has
the probably unintended side effect of clearing Aux Power PM Enable.

It looks possibly unnecessary because the generic pcie_flr() does
essentially the same thing, so it's not clear why we need a special
case for 82599.

Yu or Dexuan, can you comment on these 82599 questions?

The proposed new code is here:
http://git.kernel.org/?p=linux/kernel/git/helgaas/pci.git;a=blob;f=drivers/pci/quirks.c;h=9abbf56e93fe5c98364a7dfe2b0b724047dfa4a9;hb=ef529bf0cb5606ff5bd1422d2d2700a821d8218b#l3082

Bjorn

2012-08-21 04:41:16

by Cui, Dexuan

[permalink] [raw]
Subject: RE: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

Bjorn Helgaas wrote on 2012-08-21:
> On Mon, Aug 20, 2012 at 10:10 AM, Bjorn Helgaas <[email protected]>
> wrote:
>
>> So I'll try pulling your branch (I'll do something about the tsi721.c
>> stuff myself).
>
> I pulled this into
> git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git
> pci/jiang-pcie-cap with the following changes:
>
> - Dropped some "pci_" prefixes on internal functions in access.c -
> Minor restructure of pcie_capability_read_*() - Removed export of
> pcie_capability_reg_implemented() - Reworked
> reset_intel_82599_sfp_virtfn() to check for FLR bit in DEVCAP rather
> than using pcie_capability_reg_implemented() - Split driver patches
> into one driver per patch - Fixed myri10ge_toggle_relaxed() --
> previous code returned useful value, but your patch made it always
> return zero - Use 16-bit, not 32-bit, accesses for DEVCTL, DEVCTL2
> (tsi721)
> I am still concerned about reset_intel_82599_sfp_virtfn(). It looks
> wrong and possibly unnecessary. It looks wrong because it sets
> PCI_EXP_DEVCTL_BCR_FLR and blindly clears all other bits in
> PCI_EXP_DEVCTL. Most of the bits are probably cleared by the FLR
> anyway, but Aux Power PM Enable is RWS ("sticky"), so it is *not*
> modified by FLR. Therefore, using reset_intel_82599_sfp_virtfn() has
> the probably unintended side effect of clearing Aux Power PM Enable.
>
> It looks possibly unnecessary because the generic pcie_flr() does
> essentially the same thing, so it's not clear why we need a special
> case for 82599.
>
> Yu or Dexuan, can you comment on these 82599 questions?
(Removed Yu Zhao from the To list since he has left Intel and the same
email is now used by another unrelated person...)

Hi Bjorn
I think reset_intel_82599_sfp_virtfn() is correct AND necessary.
(pcie_flr() doesn't work here)

Please note the 82599 VF is a special PCIe device that doesn't report
PCIe FLR capability though actually it does support that.
That is why we put it in quirks.c. :-)

The PCI_EXP_DEVCTL_AUX_PME bit of the 82599 VF is read-only and
always zero.

Please see
http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf
9.5 Virtual Functions Configuration Space
Table 9.7 VF PCIe Configuration Space
9.5.2.2.1 VF Device Control Register (0xA8; RW)

Surely I should say sorry for not putting these necessary information
in the git commit description.
Now I don't know why I forgot to do that at that time(almost 3 years ago...).

It would be great if you could help to add a comment in the code. :-)

>
> The proposed new code is here:
> http://git.kernel.org/?p=linux/kernel/git/helgaas/pci.git;a=blob;f=driver
> s/pci/
> quirks.c;h=9abbf56e93fe5c98364a7dfe2b0b724047dfa4a9;hb=ef529bf0cb560
> 6ff5bd1422d2d2700a821d8218b#l3082
>
> Bjorn

Thanks,
-- Dexuan

2012-08-21 15:59:31

by Jiang Liu

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

Hi Bjorn,
Thanks for your help to finalize the patchset.
There's another suspicious issue in r8169.c, which directly writes PCI_EXP_DEVCTL_NOSNOOP_EN
to PCI_EXP_DEVCTL. I feel it should preserve other bits when setting the NOSNOOP flag.
Regards!
Gerry

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index b47d5b3..4104968 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5405,14 +5384,9 @@ static void rtl_hw_start_8101(struct net_device *dev)
tp->event_slow &= ~RxFIFOOver;

if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
- tp->mac_version == RTL_GIGA_MAC_VER_16) {
- int cap = pci_pcie_cap(pdev);
-
- if (cap) {
- pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_NOSNOOP_EN);
- }
- }
+ tp->mac_version == RTL_GIGA_MAC_VER_16)
+ pcie_capability_write_word(pdev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_NOSNOOP_EN);

RTL_W8(Cfg9346, Cfg9346_Unlock);

2012-08-22 16:29:25

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

On Mon, Aug 20, 2012 at 9:40 PM, Cui, Dexuan <[email protected]> wrote:
> Bjorn Helgaas wrote on 2012-08-21:

>> I am still concerned about reset_intel_82599_sfp_virtfn(). It looks
>> wrong and possibly unnecessary. It looks wrong because it sets
>> PCI_EXP_DEVCTL_BCR_FLR and blindly clears all other bits in
>> PCI_EXP_DEVCTL. Most of the bits are probably cleared by the FLR
>> anyway, but Aux Power PM Enable is RWS ("sticky"), so it is *not*
>> modified by FLR. Therefore, using reset_intel_82599_sfp_virtfn() has
>> the probably unintended side effect of clearing Aux Power PM Enable.
>>
>> It looks possibly unnecessary because the generic pcie_flr() does
>> essentially the same thing, so it's not clear why we need a special
>> case for 82599.

> I think reset_intel_82599_sfp_virtfn() is correct AND necessary.
> (pcie_flr() doesn't work here)
>
> Please note the 82599 VF is a special PCIe device that doesn't report
> PCIe FLR capability though actually it does support that.
> That is why we put it in quirks.c. :-)
>
> The PCI_EXP_DEVCTL_AUX_PME bit of the 82599 VF is read-only and
> always zero.
>
> Please see
> http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf
> 9.5 Virtual Functions Configuration Space
> Table 9.7 VF PCIe Configuration Space
> 9.5.2.2.1 VF Device Control Register (0xA8; RW)

Thanks, Dexuan!

The 82599 does report FLR in the DEVCAP for the PF (sec 9.3.10.4), but
not in the DEVCAP for the VF (sec 9.5), which indeed means we can't
use pcie_flr() on the VFs. I wonder whether this error appears in any
other devices.

The VF DEVCTL register (sec 9.5.2.2.1) is RO and zero except for
"Initiate FLR" unlike the PF DEVCTL (sec 9.3.10.5). The
read/modify/write done by pcie_flr() would work on the VF but is not
necessary.

The VF DEVSTA register (sec 9.5.2.2.2) does have an active
"Transaction Pending" bit. That suggests to me that we should wait
for it to be clear, as pcie_flr() does.

What would you think of a patch like the following? My idea is to
make it the same as pcie_flr() except for the absolutely necessary
differences. With this patch, the only difference is that we don't
look at the 82599 DEVCAP FLR bit.

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index aa77538..7a451ff 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3081,10 +3081,36 @@ static int reset_intel_generic_dev(struct
pci_dev *dev, int probe)

static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
{
+ int i;
+ u16 status;
+
+ /*
+ * http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf
+ *
+ * The 82599 supports FLR on VFs, but FLR support is reported only
+ * in the PF DEVCAP (sec 9.3.10.4), not in the VF DEVCAP (sec 9.5).
+ * Therefore, we can't use pcie_flr(), which checks the VF DEVCAP.
+ */
+
if (probe)
return 0;

- pcie_capability_write_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
+ /* Wait for Transaction Pending bit clean */
+ for (i = 0; i < 4; i++) {
+ if (i)
+ msleep((1 << (i - 1)) * 100);
+
+ pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
+ if (!(status & PCI_EXP_DEVSTA_TRPND))
+ goto clear;
+ }
+
+ dev_err(&dev->dev, "transaction is not cleared; "
+ "proceeding with reset anyway\n");
+
+clear:
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
+
msleep(100);

return 0;

2012-08-22 17:09:21

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

On Tue, Aug 21, 2012 at 8:59 AM, Jiang Liu <[email protected]> wrote:
> Hi Bjorn,
> Thanks for your help to finalize the patchset.
> There's another suspicious issue in r8169.c, which directly writes PCI_EXP_DEVCTL_NOSNOOP_EN
> to PCI_EXP_DEVCTL. I feel it should preserve other bits when setting the NOSNOOP flag.

I think you're right. I propose the following patch on top of your
original one:

commit 300ef7967e87467656b0fe24270edba66bce45e4
Author: Bjorn Helgaas <[email protected]>
Date: Wed Aug 22 10:29:42 2012 -0600

r8169: Preserve other Device Control bits when setting NOSNOOP_EN

Previously, when we turned on the "Enable No Snoop Bit," we cleared all
the other Device Control bits, including error reporting enables,
Max_Payload_Size, Max_Read_Request_Size, etc. This patch preserves
all the other bits.

Signed-off-by: Bjorn Helgaas <[email protected]>

diff --git a/drivers/net/ethernet/realtek/r8169.c
b/drivers/net/ethernet/realtek/r8169.c
index 4104968..a7cc560 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5385,8 +5385,8 @@ static void rtl_hw_start_8101(struct net_device *dev)

if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
tp->mac_version == RTL_GIGA_MAC_VER_16)
- pcie_capability_write_word(pdev, PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_NOSNOOP_EN);
+ pcie_capability_set_word(pdev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_NOSNOOP_EN);

RTL_W8(Cfg9346, Cfg9346_Unlock);

2012-08-23 01:00:47

by Cui, Dexuan

[permalink] [raw]
Subject: RE: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

Bjorn Helgaas wrote on 2012-08-23:
> On Mon, Aug 20, 2012 at 9:40 PM, Cui, Dexuan <[email protected]>
> wrote:
>> Bjorn Helgaas wrote on 2012-08-21:
>
>>> I am still concerned about reset_intel_82599_sfp_virtfn(). It looks
>>> wrong and possibly unnecessary. It looks wrong because it sets
>>> PCI_EXP_DEVCTL_BCR_FLR and blindly clears all other bits in
>>> PCI_EXP_DEVCTL. Most of the bits are probably cleared by the FLR
>>> anyway, but Aux Power PM Enable is RWS ("sticky"), so it is *not*
>>> modified by FLR. Therefore, using reset_intel_82599_sfp_virtfn() has
>>> the probably unintended side effect of clearing Aux Power PM Enable.
>>>
>>> It looks possibly unnecessary because the generic pcie_flr() does
>>> essentially the same thing, so it's not clear why we need a special
>>> case for 82599.
>
>> I think reset_intel_82599_sfp_virtfn() is correct AND necessary.
>> (pcie_flr() doesn't work here)
>>
>> Please note the 82599 VF is a special PCIe device that doesn't report
>> PCIe FLR capability though actually it does support that.
>> That is why we put it in quirks.c. :-)
>>
>> The PCI_EXP_DEVCTL_AUX_PME bit of the 82599 VF is read-only and
>> always zero.
>>
>> Please see
>>
> http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-
> datasheet.pdf
>> 9.5 Virtual Functions Configuration Space
>> Table 9.7 VF PCIe Configuration Space
>> 9.5.2.2.1 VF Device Control Register (0xA8; RW)
>
> Thanks, Dexuan!
>
> The 82599 does report FLR in the DEVCAP for the PF (sec 9.3.10.4), but
> not in the DEVCAP for the VF (sec 9.5), which indeed means we can't
> use pcie_flr() on the VFs. I wonder whether this error appears in any
> other devices.
>
> The VF DEVCTL register (sec 9.5.2.2.1) is RO and zero except for
> "Initiate FLR" unlike the PF DEVCTL (sec 9.3.10.5). The
> read/modify/write done by pcie_flr() would work on the VF but is not
> necessary.
>
> The VF DEVSTA register (sec 9.5.2.2.2) does have an active
> "Transaction Pending" bit. That suggests to me that we should wait
> for it to be clear, as pcie_flr() does.
I agree.

>
> What would you think of a patch like the following? My idea is to
> make it the same as pcie_flr() except for the absolutely necessary
> differences. With this patch, the only difference is that we don't
> look at the 82599 DEVCAP FLR bit.
Hi Bjorn,
Thanks for the patch!
It seems good to me (BTW, I don't have such a device at
hand to test)

Thanks,
-- Dexuan

2012-08-23 01:52:21

by Donald Dutile

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

On 08/22/2012 12:28 PM, Bjorn Helgaas wrote:
> On Mon, Aug 20, 2012 at 9:40 PM, Cui, Dexuan<[email protected]> wrote:
>> Bjorn Helgaas wrote on 2012-08-21:
>
>>> I am still concerned about reset_intel_82599_sfp_virtfn(). It looks
>>> wrong and possibly unnecessary. It looks wrong because it sets
>>> PCI_EXP_DEVCTL_BCR_FLR and blindly clears all other bits in
>>> PCI_EXP_DEVCTL. Most of the bits are probably cleared by the FLR
>>> anyway, but Aux Power PM Enable is RWS ("sticky"), so it is *not*
>>> modified by FLR. Therefore, using reset_intel_82599_sfp_virtfn() has
>>> the probably unintended side effect of clearing Aux Power PM Enable.
>>>
>>> It looks possibly unnecessary because the generic pcie_flr() does
>>> essentially the same thing, so it's not clear why we need a special
>>> case for 82599.
>
>> I think reset_intel_82599_sfp_virtfn() is correct AND necessary.
>> (pcie_flr() doesn't work here)
>>
>> Please note the 82599 VF is a special PCIe device that doesn't report
>> PCIe FLR capability though actually it does support that.
>> That is why we put it in quirks.c. :-)
>>
>> The PCI_EXP_DEVCTL_AUX_PME bit of the 82599 VF is read-only and
>> always zero.
>>
>> Please see
>> http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf
>> 9.5 Virtual Functions Configuration Space
>> Table 9.7 VF PCIe Configuration Space
>> 9.5.2.2.1 VF Device Control Register (0xA8; RW)
>
> Thanks, Dexuan!
>
> The 82599 does report FLR in the DEVCAP for the PF (sec 9.3.10.4), but
> not in the DEVCAP for the VF (sec 9.5), which indeed means we can't
> use pcie_flr() on the VFs. I wonder whether this error appears in any
> other devices.
>
It should not exist in any other VF device. The SRIOV spec states
that all VFs must support FLR. The 82599 quirk is just that...

> The VF DEVCTL register (sec 9.5.2.2.1) is RO and zero except for
> "Initiate FLR" unlike the PF DEVCTL (sec 9.3.10.5). The
> read/modify/write done by pcie_flr() would work on the VF but is not
> necessary.
>
> The VF DEVSTA register (sec 9.5.2.2.2) does have an active
> "Transaction Pending" bit. That suggests to me that we should wait
> for it to be clear, as pcie_flr() does.
>
> What would you think of a patch like the following? My idea is to
> make it the same as pcie_flr() except for the absolutely necessary
> differences. With this patch, the only difference is that we don't
> look at the 82599 DEVCAP FLR bit.
>
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index aa77538..7a451ff 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -3081,10 +3081,36 @@ static int reset_intel_generic_dev(struct
> pci_dev *dev, int probe)
>
> static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
> {
> + int i;
> + u16 status;
> +
> + /*
> + * http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf
> + *
> + * The 82599 supports FLR on VFs, but FLR support is reported only
> + * in the PF DEVCAP (sec 9.3.10.4), not in the VF DEVCAP (sec 9.5).
> + * Therefore, we can't use pcie_flr(), which checks the VF DEVCAP.
> + */
> +
> if (probe)
> return 0;
>
> - pcie_capability_write_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
> + /* Wait for Transaction Pending bit clean */
> + for (i = 0; i< 4; i++) {
> + if (i)
> + msleep((1<< (i - 1)) * 100);
> +
> + pcie_capability_read_word(dev, PCI_EXP_DEVSTA,&status);
> + if (!(status& PCI_EXP_DEVSTA_TRPND))
> + goto clear;
> + }
> +
> + dev_err(&dev->dev, "transaction is not cleared; "
> + "proceeding with reset anyway\n");
> +
> +clear:
> + pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
> +
> msleep(100);
>
> return 0;

2012-08-24 18:53:01

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH v3 00/32] provide interfaces to access PCIe capabilities registers

On Mon, Aug 20, 2012 at 9:26 AM, Jiang Liu <[email protected]> wrote:
> Hi Bjorn,
> I have made following changes according to your suggestions,
> 1) get rid of the "pci_" prefix for access functions.
> 2) rename pci_pcie_capability_change_{word|dword}() to
> pcie_capability_clear_and_set_{word|dword}.
> 3) add pcie_capability_{set|clear}_{word|dword}().
> 4) Add "Acked-by" and "Reviewed-by"
> 5) rebase to your latest pci-next tree
>
> So could you please help to pull from "https://github.com/jiangliu/linux.git topic/pcie-cap"
> or should I send all the patches to mail list again?

I applied these (with the fixups mentioned in this thread) to my
"next" branch. Unfortunately, I just missed the 0824 -next tree, and
Stephen is taking a hiatus for KS/LPC next week, so it might be a
while before they show up in his tree.

Thanks a lot for doing this work! I feel much more confident that we
can avoid driver issues with the v1/v2 differences, and you removed an
appreciable amount of code at the same time:

52 files changed, 591 insertions(+), 823 deletions(-)