diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-01 12:05:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-01 12:05:36 -0700 |
commit | fdb2f9c2ebd4f07d7b11a3bc86d8c669eb841697 (patch) | |
tree | d85824518fc13a8c84b7399019fc11ad77aaa120 /drivers | |
parent | 81f56e5375e84689b891e0e6c5a02ec12a1f18d9 (diff) | |
parent | 78c8f84302ce007aedcfa11912fd4aacf22727ab (diff) |
Merge tag 'for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas:
"Host bridge hotplug
- Protect acpi_pci_drivers and acpi_pci_roots (Taku Izumi)
- Clear host bridge resource info to avoid issue when releasing
(Yinghai Lu)
- Notify acpi_pci_drivers when hot-plugging host bridges (Jiang Liu)
- Use standard list ops for acpi_pci_drivers (Jiang Liu)
Device hotplug
- Use pci_get_domain_bus_and_slot() to close hotplug races (Jiang
Liu)
- Remove fakephp driver (Bjorn Helgaas)
- Fix VGA ref count in hotplug remove path (Yinghai Lu)
- Allow acpiphp to handle PCIe ports without native hotplug (Jiang
Liu)
- Implement resume regardless of pciehp_force param (Oliver Neukum)
- Make pci_fixup_irqs() work after init (Thierry Reding)
Miscellaneous
- Add pci_pcie_type(dev) and remove pci_dev.pcie_type (Yijing Wang)
- Factor out PCI Express Capability accessors (Jiang Liu)
- Add pcibios_window_alignment() so powerpc EEH can use generic
resource assignment (Gavin Shan)
- Make pci_error_handlers const (Stephen Hemminger)
- Cleanup drivers/pci/remove.c (Bjorn Helgaas)
- Improve Vendor-Specific Extended Capability support (Bjorn
Helgaas)
- Use standard list ops for bus->devices (Bjorn Helgaas)
- Avoid kmalloc in pci_get_subsys() and pci_get_class() (Feng Tang)
- Reassign invalid bus number ranges (Intel DP43BF workaround)
(Yinghai Lu)"
* tag 'for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (102 commits)
PCI: acpiphp: Handle PCIe ports without native hotplug capability
PCI/ACPI: Use acpi_driver_data() rather than searching acpi_pci_roots
PCI/ACPI: Protect acpi_pci_roots list with mutex
PCI/ACPI: Use acpi_pci_root info rather than looking it up again
PCI/ACPI: Pass acpi_pci_root to acpi_pci_drivers' add/remove interface
PCI/ACPI: Protect acpi_pci_drivers list with mutex
PCI/ACPI: Notify acpi_pci_drivers when hot-plugging PCI root bridges
PCI/ACPI: Use normal list for struct acpi_pci_driver
PCI/ACPI: Use DEVICE_ACPI_HANDLE rather than searching acpi_pci_roots
PCI: Fix default vga ref_count
ia64/PCI: Clear host bridge aperture struct resource
x86/PCI: Clear host bridge aperture struct resource
PCI: Stop all children first, before removing all children
Revert "PCI: Use hotplug-safe pci_get_domain_bus_and_slot()"
PCI: Provide a default pcibios_update_irq()
PCI: Discard __init annotations for pci_fixup_irqs() and related functions
PCI: Use correct type when freeing bus resource list
PCI: Check P2P bridge for invalid secondary/subordinate range
PCI: Convert "new_id"/"remove_id" into generic pci_bus driver attributes
xen-pcifront: Use hotplug-safe pci_get_domain_bus_and_slot()
...
Diffstat (limited to 'drivers')
96 files changed, 929 insertions, 1560 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 72a2c98bc42..bce469c0b48 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -27,7 +27,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/types.h> -#include <linux/spinlock.h> +#include <linux/mutex.h> #include <linux/pm.h> #include <linux/pm_runtime.h> #include <linux/pci.h> @@ -71,9 +71,11 @@ static struct acpi_driver acpi_pci_root_driver = { }, }; +/* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */ +static DEFINE_MUTEX(acpi_pci_root_lock); static LIST_HEAD(acpi_pci_roots); +static LIST_HEAD(acpi_pci_drivers); -static struct acpi_pci_driver *sub_driver; static DEFINE_MUTEX(osc_lock); int acpi_pci_register_driver(struct acpi_pci_driver *driver) @@ -81,55 +83,46 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver) int n = 0; struct acpi_pci_root *root; - struct acpi_pci_driver **pptr = &sub_driver; - while (*pptr) - pptr = &(*pptr)->next; - *pptr = driver; - - if (!driver->add) - return 0; - - list_for_each_entry(root, &acpi_pci_roots, node) { - driver->add(root->device->handle); - n++; - } + mutex_lock(&acpi_pci_root_lock); + list_add_tail(&driver->node, &acpi_pci_drivers); + if (driver->add) + list_for_each_entry(root, &acpi_pci_roots, node) { + driver->add(root); + n++; + } + mutex_unlock(&acpi_pci_root_lock); return n; } - EXPORT_SYMBOL(acpi_pci_register_driver); void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) { struct acpi_pci_root *root; - struct acpi_pci_driver **pptr = &sub_driver; - while (*pptr) { - if (*pptr == driver) - break; - pptr = &(*pptr)->next; - } - BUG_ON(!*pptr); - *pptr = (*pptr)->next; - - if (!driver->remove) - return; - - list_for_each_entry(root, &acpi_pci_roots, node) - driver->remove(root->device->handle); + mutex_lock(&acpi_pci_root_lock); + list_del(&driver->node); + if (driver->remove) + list_for_each_entry(root, &acpi_pci_roots, node) + driver->remove(root); + mutex_unlock(&acpi_pci_root_lock); } - EXPORT_SYMBOL(acpi_pci_unregister_driver); acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) { struct acpi_pci_root *root; + acpi_handle handle = NULL; + mutex_lock(&acpi_pci_root_lock); list_for_each_entry(root, &acpi_pci_roots, node) if ((root->segment == (u16) seg) && - (root->secondary.start == (u16) bus)) - return root->device->handle; - return NULL; + (root->secondary.start == (u16) bus)) { + handle = root->device->handle; + break; + } + mutex_unlock(&acpi_pci_root_lock); + return handle; } EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); @@ -277,12 +270,15 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) { struct acpi_pci_root *root; + struct acpi_device *device; - list_for_each_entry(root, &acpi_pci_roots, node) { - if (root->device->handle == handle) - return root; - } - return NULL; + if (acpi_bus_get_device(handle, &device) || + acpi_match_device_ids(device, root_device_ids)) + return NULL; + + root = acpi_driver_data(device); + + return root; } EXPORT_SYMBOL_GPL(acpi_pci_find_root); @@ -518,8 +514,9 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) * TBD: Need PCI interface for enumeration/configuration of roots. */ - /* TBD: Locking */ + mutex_lock(&acpi_pci_root_lock); list_add_tail(&root->node, &acpi_pci_roots); + mutex_unlock(&acpi_pci_root_lock); printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n", acpi_device_name(device), acpi_device_bid(device), @@ -538,7 +535,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) "Bus %04x:%02x not present in PCI namespace\n", root->segment, (unsigned int)root->secondary.start); result = -ENODEV; - goto end; + goto out_del_root; } /* @@ -548,7 +545,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) */ result = acpi_pci_bind_root(device); if (result) - goto end; + goto out_del_root; /* * PCI Routing Table @@ -633,9 +630,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) return 0; +out_del_root: + mutex_lock(&acpi_pci_root_lock); + list_del(&root->node); + mutex_unlock(&acpi_pci_root_lock); end: - if (!list_empty(&root->node)) - list_del(&root->node); kfree(root); return result; } @@ -643,18 +642,34 @@ end: static int acpi_pci_root_start(struct acpi_device *device) { struct acpi_pci_root *root = acpi_driver_data(device); + struct acpi_pci_driver *driver; + + mutex_lock(&acpi_pci_root_lock); + list_for_each_entry(driver, &acpi_pci_drivers, node) + if (driver->add) + driver->add(root); + mutex_unlock(&acpi_pci_root_lock); pci_bus_add_devices(root->bus); + return 0; } static int acpi_pci_root_remove(struct acpi_device *device, int type) { struct acpi_pci_root *root = acpi_driver_data(device); + struct acpi_pci_driver *driver; + + mutex_lock(&acpi_pci_root_lock); + list_for_each_entry(driver, &acpi_pci_drivers, node) + if (driver->remove) + driver->remove(root); device_set_run_wake(root->bus->bridge, false); pci_acpi_remove_bus_pm_notifier(device); + list_del(&root->node); + mutex_unlock(&acpi_pci_root_lock); kfree(root); return 0; } diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index e50e31a518a..d22585f21ae 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c @@ -67,8 +67,8 @@ struct acpi_pci_slot { struct list_head list; /* node in the list of slots */ }; -static int acpi_pci_slot_add(acpi_handle handle); -static void acpi_pci_slot_remove(acpi_handle handle); +static int acpi_pci_slot_add(struct acpi_pci_root *root); +static void acpi_pci_slot_remove(struct acpi_pci_root *root); static LIST_HEAD(slot_list); static DEFINE_MUTEX(slot_list_lock); @@ -233,45 +233,20 @@ out: /* * walk_root_bridge - generic root bridge walker - * @handle: points to an acpi_pci_root + * @root: poiner of an acpi_pci_root * @user_function: user callback for slot objects * * Call user_function for all objects underneath this root bridge. * Walk p2p bridges underneath us and call user_function on those too. */ static int -walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function) +walk_root_bridge(struct acpi_pci_root *root, acpi_walk_callback user_function) { - int seg, bus; - unsigned long long tmp; acpi_status status; - acpi_handle dummy_handle; - struct pci_bus *pci_bus; + acpi_handle handle = root->device->handle; + struct pci_bus *pci_bus = root->bus; struct callback_args context; - /* If the bridge doesn't have _STA, we assume it is always there */ - status = acpi_get_handle(handle, "_STA", &dummy_handle); - if (ACPI_SUCCESS(status)) { - status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp); - if (ACPI_FAILURE(status)) { - info("%s: _STA evaluation failure\n", __func__); - return 0; - } - if ((tmp & ACPI_STA_DEVICE_FUNCTIONING) == 0) - /* don't register this object */ - return 0; - } - - status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp); - seg = ACPI_SUCCESS(status) ? tmp : 0; - - status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp); - bus = ACPI_SUCCESS(status) ? tmp : 0; - - pci_bus = pci_find_bus(seg, bus); - if (!pci_bus) - return 0; - context.pci_bus = pci_bus; context.user_function = user_function; context.root_handle = handle; @@ -295,11 +270,11 @@ walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function) * @handle: points to an acpi_pci_root */ static int -acpi_pci_slot_add(acpi_handle handle) +acpi_pci_slot_add(struct acpi_pci_root *root) { acpi_status status; - status = walk_root_bridge(handle, register_slot); + status = walk_root_bridge(root, register_slot); if (ACPI_FAILURE(status)) err("%s: register_slot failure - %d\n", __func__, status); @@ -311,10 +286,11 @@ acpi_pci_slot_add(acpi_handle handle) * @handle: points to an acpi_pci_root */ static void -acpi_pci_slot_remove(acpi_handle handle) +acpi_pci_slot_remove(struct acpi_pci_root *root) { struct acpi_pci_slot *slot, *tmp; struct pci_bus *pbus; + acpi_handle handle = root->device->handle; mutex_lock(&slot_list_lock); list_for_each_entry_safe(slot, tmp, &slot_list, list) { diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c index ad16c68c864..931769e133e 100644 --- a/drivers/block/nvme.c +++ b/drivers/block/nvme.c @@ -1726,7 +1726,7 @@ static void __devexit nvme_remove(struct pci_dev *pdev) #define nvme_suspend NULL #define nvme_resume NULL -static struct pci_error_handlers nvme_err_handler = { +static const struct pci_error_handlers nvme_err_handler = { .error_detected = nvme_error_detected, .mmio_enabled = nvme_dump_registers, .link_reset = nvme_link_reset, diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index 19200037773..3a5af2f9b01 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c @@ -289,12 +289,11 @@ static int __devinit agp_sgi_init(void) j = 0; list_for_each_entry(info, &tioca_list, ca_list) { - struct list_head *tmp; if (list_empty(info->ca_devices)) continue; - list_for_each(tmp, info->ca_devices) { + list_for_each_entry(pdev, info->ca_devices, bus_list) { u8 cap_ptr; - pdev = pci_dev_b(tmp); + if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8)) continue; cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e93b80a6d4e..ed3340adeb6 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 = 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); + pcie_capability_write_word(rdev->pdev, PCI_EXP_DEVCTL, ctl); } } diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index 3df8fc0ec01..e893f6e1937 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -141,7 +141,11 @@ EXPORT_SYMBOL_GPL(vga_default_device); void vga_set_default_device(struct pci_dev *pdev) { - vga_default = pdev; + if (vga_default == pdev) + return; + + pci_dev_put(vga_default); + vga_default = pci_dev_get(pdev); } #endif @@ -577,7 +581,7 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev) #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE if (vga_default == NULL && ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) - vga_default = pci_dev_get(pdev); + vga_set_default_device(pdev); #endif vga_arbiter_check_bridge_sharing(vgadev); @@ -613,10 +617,8 @@ static bool vga_arbiter_del_pci_device(struct pci_dev *pdev) } #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE - if (vga_default == pdev) { - pci_dev_put(vga_default); - vga_default = NULL; - } + if (vga_default == pdev) + vga_set_default_device(NULL); #endif if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) @@ -1066,7 +1068,6 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, } } else if (strncmp(curr_pos, "target ", 7) == 0) { - struct pci_bus *pbus; unsigned int domain, bus, devfn; struct vga_device *vgadev; @@ -1085,19 +1086,11 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, pr_debug("vgaarb: %s ==> %x:%x:%x.%x\n", curr_pos, domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); - pbus = pci_find_bus(domain, bus); - pr_debug("vgaarb: pbus %p\n", pbus); - if (pbus == NULL) { - pr_err("vgaarb: invalid PCI domain and/or bus address %x:%x\n", - domain, bus); - ret_val = -ENODEV; - goto done; - } - pdev = pci_get_slot(pbus, devfn); + pdev = pci_get_domain_bus_and_slot(domain, bus, devfn); pr_debug("vgaarb: pdev %p\n", pdev); if (!pdev) { - pr_err("vgaarb: invalid PCI address %x:%x\n", - bus, devfn); + pr_err("vgaarb: invalid PCI address %x:%x:%x\n", + domain, bus, devfn); ret_val = -ENODEV; goto done; } diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c index 4fa3534ec23..74c6a942604 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 (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 (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"); diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h index 7b1b8669002..4d11575c201 100644 --- a/drivers/infiniband/hw/qib/qib.h +++ b/drivers/infiniband/hw/qib/qib.h @@ -87,7 +87,7 @@ struct qlogic_ib_stats { }; extern struct qlogic_ib_stats qib_stats; -extern struct pci_error_handlers qib_pci_err_handler; +extern const struct pci_error_handlers qib_pci_err_handler; extern struct pci_driver qib_driver; #define QIB_CHIP_SWVERSION QIB_CHIP_VERS_MAJ diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c index 062c301ebf5..c574ec7c85e 100644 --- a/drivers/infiniband/hw/qib/qib_pcie.c +++ b/drivers/infiniband/hw/qib/qib_pcie.c @@ -273,10 +273,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; @@ -298,7 +297,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); + 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 @@ -516,7 +515,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; @@ -529,8 +527,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; @@ -587,7 +584,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; @@ -598,19 +594,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; + pcie_capability_read_word(parent, PCI_EXP_DEVCAP, &pcaps); + 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; + pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCAP, &ecaps); + 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); @@ -629,14 +621,14 @@ 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); + 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); + pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL, ectl); } /* @@ -654,13 +646,13 @@ 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); + 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); + pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL, ectl); } bail: return ret; @@ -753,7 +745,7 @@ qib_pci_resume(struct pci_dev *pdev) qib_init(dd, 1); /* same as re-init after reset */ } -struct pci_error_handlers qib_pci_err_handler = { +const struct pci_error_handlers qib_pci_err_handler = { .error_detected = qib_pci_error_detected, .mmio_enabled = qib_pci_mmio_enabled, .link_reset = qib_pci_link_reset, diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 2297ec193eb..db820d7dd0b 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -2351,7 +2351,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; /* @@ -3546,10 +3546,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/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c index 72ee8de0226..0a497be97af 100644 --- a/drivers/media/dvb/ngene/ngene-cards.c +++ b/drivers/media/dvb/ngene/ngene-cards.c @@ -524,7 +524,7 @@ static void ngene_resume(struct pci_dev *dev) printk(KERN_INFO DEVICE_NAME ": resume\n"); } -static struct pci_error_handlers ngene_errors = { +static const struct pci_error_handlers ngene_errors = { .error_detected = ngene_error_detected, .link_reset = ngene_link_reset, .slot_reset = ngene_slot_reset, diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 1bf5bbfe778..55a2e379505 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, + pcie_capability_write_word(pdev, PCI_EXP_DEVSTA, PCI_EXP_DEVSTA_NFED | PCI_EXP_DEVSTA_FED | PCI_EXP_DEVSTA_CED | @@ -2685,7 +2685,7 @@ static void atl1c_io_resume(struct pci_dev *pdev) netif_device_attach(netdev); } -static struct pci_error_handlers atl1c_err_handler = { +static const struct pci_error_handlers atl1c_err_handler = { .error_detected = atl1c_io_error_detected, .slot_reset = atl1c_io_slot_reset, .resume = atl1c_io_resume, diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index a98acc8a956..e213da29e73 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -2489,7 +2489,7 @@ static void atl1e_io_resume(struct pci_dev *pdev) netif_device_attach(netdev); } -static struct pci_error_handlers atl1e_err_handler = { +static const struct pci_error_handlers atl1e_err_handler = { .error_detected = atl1e_io_error_detected, .slot_reset = atl1e_io_slot_reset, .resume = atl1e_io_resume, diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index e48312f2305..d4310700c7a 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -8742,7 +8742,7 @@ static void bnx2_io_resume(struct pci_dev *pdev) rtnl_unlock(); } -static struct pci_error_handlers bnx2_err_handler = { +static const struct pci_error_handlers bnx2_err_handler = { .error_detected = bnx2_io_error_detected, .slot_reset = bnx2_io_slot_reset, .resume = bnx2_io_resume, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 0875ecfe337..e11485ca037 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -1162,14 +1162,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); + pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status); return status & PCI_EXP_DEVSTA_TRPND; } @@ -6135,8 +6130,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); + 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) @@ -9380,7 +9374,7 @@ static int __devinit bnx2x_prev_mark_path(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; @@ -9397,16 +9391,12 @@ static int __devinit bnx2x_do_flr(struct bnx2x *bp) return -EINVAL; } - 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); + pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status); if (!(status & PCI_EXP_DEVSTA_TRPND)) goto clear; } @@ -12167,7 +12157,7 @@ static void bnx2x_io_resume(struct pci_dev *pdev) rtnl_unlock(); } -static struct pci_error_handlers bnx2x_err_handler = { +static const struct pci_error_handlers bnx2x_err_handler = { .error_detected = bnx2x_io_error_detected, .slot_reset = bnx2x_io_slot_reset, .resume = bnx2x_io_resume, diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index bf906c51d82..388d3221393 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -3653,17 +3653,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)) + pcie_capability_set_word(tp->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CLKREQ_EN); misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL); tw32(TG3PCI_MISC_HOST_CTRL, @@ -4434,20 +4426,13 @@ relink: /* Prevent send BD corruption. */ if (tg3_flag(tp, CLKREQ_BUG)) { - u16 oldlnkctl, newlnkctl; - - 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; + pcie_capability_clear_word(tp->pdev, PCI_EXP_LNKCTL, + 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); + pcie_capability_set_word(tp->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CLKREQ_EN); } if (current_link_up != netif_carrier_ok(tp->dev)) { @@ -8054,7 +8039,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) { @@ -8071,24 +8056,17 @@ 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; + pcie_capability_clear_word(tp->pdev, PCI_EXP_DEVCTL, val16); /* Clear error status */ - pci_write_config_word(tp->pdev, - pci_pcie_cap(tp->pdev) + PCI_EXP_DEVSTA, + pcie_capability_write_word(tp->pdev, PCI_EXP_DEVSTA, PCI_EXP_DEVSTA_CED | PCI_EXP_DEVSTA_NFED | PCI_EXP_DEVSTA_FED | @@ -14565,9 +14543,7 @@ 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); + 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) { @@ -16397,7 +16373,7 @@ done: rtnl_unlock(); } -static struct pci_error_handlers tg3_err_handler = { +static const struct pci_error_handlers tg3_err_handler = { .error_detected = tg3_io_error_detected, .slot_reset = tg3_io_slot_reset, .resume = tg3_io_resume diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 6505070abcf..875bbb999aa 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -3036,7 +3036,7 @@ static void t3_io_resume(struct pci_dev *pdev) t3_resume_ports(adapter); } -static struct pci_error_handlers t3_err_handler = { +static const struct pci_error_handlers t3_err_handler = { .error_detected = t3_io_error_detected, .slot_reset = t3_io_slot_reset, .resume = t3_io_resume, diff --git a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c index bff8a3cdd3d..aef45d3113b 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); + 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, - val & ~PCI_EXP_DEVCTL_READRQ & - ~PCI_EXP_DEVCTL_PAYLOAD); + 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); + 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,13 @@ 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); + 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 5ed49af23d6..933985420ac 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3453,7 +3453,7 @@ static void eeh_resume(struct pci_dev *pdev) rtnl_unlock(); } -static struct pci_error_handlers cxgb4_eeh = { +static const struct pci_error_handlers cxgb4_eeh = { .error_detected = eeh_err_detected, .slot_reset = eeh_slot_reset, .resume = eeh_resume, @@ -3694,15 +3694,7 @@ 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); - } + pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN); } /* diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index fa947dfa4c3..af160132317 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -2741,11 +2741,9 @@ 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); + if (pci_is_pcie(adapter->pdev)) { + 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; } diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 78b8aa8069f..95d10472f23 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -4106,7 +4106,7 @@ err: dev_err(&adapter->pdev->dev, "EEH resume failed\n"); } -static struct pci_error_handlers be_eeh_handlers = { +static const struct pci_error_handlers be_eeh_handlers = { .error_detected = be_eeh_err_detected, .slot_reset = be_eeh_reset, .resume = be_eeh_resume, diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 535f94fac4a..29ce9bd27f9 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -3157,7 +3157,7 @@ static void e100_io_resume(struct pci_dev *pdev) } } -static struct pci_error_handlers e100_err_handler = { +static const struct pci_error_handlers e100_err_handler = { .error_detected = e100_io_error_detected, .slot_reset = e100_io_slot_reset, .resume = e100_io_resume, diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index bde337ee1a3..f3f9aeb7d1e 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -192,7 +192,7 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev); static void e1000_io_resume(struct pci_dev *pdev); -static struct pci_error_handlers e1000_err_handler = { +static const struct pci_error_handlers e1000_err_handler = { .error_detected = e1000_io_error_detected, .slot_reset = e1000_io_slot_reset, .resume = e1000_io_resume, diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index d01a099475a..3f0223ac4c7 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -5584,16 +5584,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)); + pcie_capability_read_word(us_dev, PCI_EXP_DEVCTL, &devctl); + 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); + pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl); } else { e1000_power_off(pdev, sleep, wake); } @@ -5607,25 +5606,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, ®16); - reg16 &= ~state; - pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); - - if (!pdev->bus->self) - return; + pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, state); - pos = pci_pcie_cap(pdev->bus->self); - pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, ®16); - reg16 &= ~state; - pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16); + if (pdev->bus->self) + pcie_capability_clear_word(pdev->bus->self, PCI_EXP_LNKCTL, + state); } #endif static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state) @@ -6486,7 +6475,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev) } /* PCI Error Recovery (ERS) */ -static struct pci_error_handlers e1000_err_handler = { +static const struct pci_error_handlers e1000_err_handler = { .error_detected = e1000_io_error_detected, .slot_reset = e1000_io_slot_reset, .resume = e1000_io_resume, diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 48cc4fb1a30..f88c822e57a 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -217,7 +217,7 @@ static pci_ers_result_t igb_io_error_detected(struct pci_dev *, static pci_ers_result_t igb_io_slot_reset(struct pci_dev *); static void igb_io_resume(struct pci_dev *); -static struct pci_error_handlers igb_err_handler = { +static const struct pci_error_handlers igb_err_handler = { .error_detected = igb_io_error_detected, .slot_reset = igb_io_slot_reset, .resume = igb_io_resume, @@ -6538,28 +6538,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 (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 (pcie_capability_write_word(adapter->pdev, reg, *value)) return -E1000_ERR_CONFIG; - pci_write_config_word(adapter->pdev, cap_offset + reg, *value); - return 0; } diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index 0696abfe994..0ac11f527a8 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -2833,7 +2833,7 @@ static void __devexit igbvf_remove(struct pci_dev *pdev) } /* PCI Error Recovery (ERS) */ -static struct pci_error_handlers igbvf_err_handler = { +static const struct pci_error_handlers igbvf_err_handler = { .error_detected = igbvf_io_error_detected, .slot_reset = igbvf_io_slot_reset, .resume = igbvf_io_resume, diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index d05fc95befc..d99a2d51b94 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -115,7 +115,7 @@ static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev, static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev); static void ixgb_io_resume (struct pci_dev *pdev); -static struct pci_error_handlers ixgb_err_handler = { +static const struct pci_error_handlers ixgb_err_handler = { .error_detected = ixgb_io_error_detected, .slot_reset = ixgb_io_slot_reset, .resume = ixgb_io_resume, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 4326f74f713..ee61819d608 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7527,7 +7527,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) @@ -7677,7 +7677,7 @@ static void ixgbe_io_resume(struct pci_dev *pdev) netif_device_attach(netdev); } -static struct pci_error_handlers ixgbe_err_handler = { +static const struct pci_error_handlers ixgbe_err_handler = { .error_detected = ixgbe_io_error_detected, .slot_reset = ixgbe_io_slot_reset, .resume = ixgbe_io_resume, diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 60ef6458741..6647383c4dd 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -3256,7 +3256,7 @@ static void ixgbevf_io_resume(struct pci_dev *pdev) } /* PCI Error Recovery (ERS) */ -static struct pci_error_handlers ixgbevf_err_handler = { +static const struct pci_error_handlers ixgbevf_err_handler = { .error_detected = ixgbevf_io_error_detected, .slot_reset = ixgbevf_io_slot_reset, .resume = ixgbevf_io_resume, diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 2f816c6aed7..dd6ea942625 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -2300,7 +2300,7 @@ static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev) return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; } -static struct pci_error_handlers mlx4_err_handler = { +static const struct pci_error_handlers mlx4_err_handler = { .error_detected = mlx4_pci_err_detected, .slot_reset = mlx4_pci_slot_reset, }; diff --git a/drivers/net/ethernet/mellanox/mlx4/reset.c b/drivers/net/ethernet/mellanox/mlx4/reset.c index 11e7c1cb99b..dd1b5093d8b 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 (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 (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"); diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index fa85cf1353f..83516e3369c 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -1078,22 +1078,16 @@ 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; + int ret; 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; + pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &ctl); 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); + pcie_capability_write_word(pdev, PCI_EXP_DEVCTL, ctl); } return ret; } @@ -3192,18 +3186,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 +3207,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 +3321,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); + 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 diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index d958c229937..de50547c187 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -484,7 +484,7 @@ static DEFINE_PCI_DEVICE_TABLE(s2io_tbl) = { MODULE_DEVICE_TABLE(pci, s2io_tbl); -static struct pci_error_handlers s2io_err_handler = { +static const struct pci_error_handlers s2io_err_handler = { .error_detected = s2io_io_error_detected, .slot_reset = s2io_io_slot_reset, .resume = s2io_io_resume, diff --git a/drivers/net/ethernet/neterion/vxge/vxge-config.c b/drivers/net/ethernet/neterion/vxge/vxge-config.c index 32d06824fe3..c2e420a84d2 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); + 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); + pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnk); return (lnk & VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4; } diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index de219044351..cfa71a30dc8 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -4799,7 +4799,7 @@ static void __devexit vxge_remove(struct pci_dev *pdev) __LINE__); } -static struct pci_error_handlers vxge_err_handler = { +static const struct pci_error_handlers vxge_err_handler = { .error_detected = vxge_io_error_detected, .slot_reset = vxge_io_slot_reset, .resume = vxge_io_resume, diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index feb85d56c75..b2a94d02a52 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -2795,7 +2795,7 @@ static const struct dev_pm_ops pch_gbe_pm_ops = { }; #endif -static struct pci_error_handlers pch_gbe_err_handler = { +static const struct pci_error_handlers pch_gbe_err_handler = { .error_detected = pch_gbe_io_error_detected, .slot_reset = pch_gbe_io_slot_reset, .resume = pch_gbe_io_resume diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index a77c558d8f4..df450616ab3 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -1386,7 +1386,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); @@ -3340,7 +3340,7 @@ netxen_free_vlan_ip_list(struct netxen_adapter *adapter) { } #endif -static struct pci_error_handlers netxen_err_handler = { +static const struct pci_error_handlers netxen_err_handler = { .error_detected = netxen_io_error_detected, .slot_reset = netxen_io_slot_reset, .resume = netxen_io_resume, diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 212c1219327..473ce134ca6 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -4522,7 +4522,7 @@ static void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long event) { } #endif -static struct pci_error_handlers qlcnic_err_handler = { +static const struct pci_error_handlers qlcnic_err_handler = { .error_detected = qlcnic_io_error_detected, .slot_reset = qlcnic_io_slot_reset, .resume = qlcnic_io_resume, diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index b53a3b60b64..b262d615681 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -4847,7 +4847,7 @@ static void qlge_io_resume(struct pci_dev *pdev) netif_device_attach(ndev); } -static struct pci_error_handlers qlge_err_handler = { +static const struct pci_error_handlers qlge_err_handler = { .error_detected = qlge_io_error_detected, .slot_reset = qlge_io_slot_reset, .resume = qlge_io_resume, diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index b47d5b35024..a7cc56007b3 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -833,15 +833,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); - } + pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_READRQ, force); } struct rtl_cond { @@ -4739,28 +4732,14 @@ static void rtl_ephy_init(struct rtl8169_private *tp, const struct ephy_info *e, 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); - } + pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, + 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); - } + pcie_capability_set_word(pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CLKREQ_EN); } #define R8168_CPCMD_QUIRK_MASK (\ @@ -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_set_word(pdev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_NOSNOOP_EN); RTL_W8(Cfg9346, Cfg9346_Unlock); diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index c2a0fe39326..3208dca6675 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -9762,9 +9762,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(); @@ -9787,8 +9786,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; } @@ -9813,14 +9811,11 @@ 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); + pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_NOSNOOP_EN, + PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE | + PCI_EXP_DEVCTL_RELAX_EN); dma_mask = DMA_BIT_MASK(44); err = pci_set_dma_mask(pdev, dma_mask); diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index a978984d78a..ef11dc63946 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -113,41 +113,32 @@ 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; + u16 aspm; if (!ah->is_pciexpress) return; - pos = pci_pcie_cap(pdev); - if (!pos) - return; - parent = pdev->bus->self; if (!parent) return; 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); + pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, + 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); + pcie_capability_clear_word(parent, PCI_EXP_LNKCTL, + PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); ath_info(common, "Disabling ASPM since BTCOEX is enabled\n"); return; } - pos = pci_pcie_cap(parent); - pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); + 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. */ diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 5f5017767b9..72468266906 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1832,10 +1832,8 @@ 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); + pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &pci_lnk_ctl); return pci_lnk_ctl; } diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index dbeebef562d..063ecaff5b5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -675,13 +675,10 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - int pos; u16 pci_lnk_ctl; - 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); + pcie_capability_read_word(trans_pcie->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 80f75d3ba84..5983631a1b1 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; + 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); diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index ffddc4f6426..fb6a1fe21b9 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -477,14 +477,12 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr) if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB, F_EXTEND(0xf0000000UL) | _8MB, F_EXTEND(0xffffffffUL) &~ _8MB, _8MB) < 0) { - struct list_head *ln, *tmp_ln; + struct pci_dev *dev, *tmp; printk(KERN_ERR "Dino: cannot attach bus %s\n", dev_name(bus->bridge)); /* kill the bus, we can't do anything with it */ - list_for_each_safe(ln, tmp_ln, &bus->devices) { - struct pci_dev *dev = pci_dev_b(ln); - + list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { list_del(&dev->bus_list); } @@ -549,7 +547,6 @@ dino_card_fixup(struct pci_dev *dev) static void __init dino_fixup_bus(struct pci_bus *bus) { - struct list_head *ln; struct pci_dev *dev; struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); @@ -596,8 +593,7 @@ dino_fixup_bus(struct pci_bus *bus) } - list_for_each(ln, &bus->devices) { - dev = pci_dev_b(ln); + list_for_each_entry(dev, &bus->devices, bus_list) { if (is_card_dino(&dino_dev->hba.dev->id)) dino_card_fixup(dev); diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 4f9cf2456f4..fdd63a6a62d 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -629,7 +629,7 @@ truncate_pat_collision(struct resource *root, struct resource *new) static void lba_fixup_bus(struct pci_bus *bus) { - struct list_head *ln; + struct pci_dev *dev; #ifdef FBB_SUPPORT u16 status; #endif @@ -710,9 +710,8 @@ lba_fixup_bus(struct pci_bus *bus) } - list_for_each(ln, &bus->devices) { + list_for_each_entry(dev, &bus->devices, bus_list) { int i; - struct pci_dev *dev = pci_dev_b(ln); DBG("lba_fixup_bus() %s\n", pci_name(dev)); @@ -770,7 +769,7 @@ lba_fixup_bus(struct pci_bus *bus) } /* Lastly enable FBB/PERR/SERR on all devices too */ - list_for_each(ln, &bus->devices) { + list_for_each_entry(dev, &bus->devices, bus_list) { (void) pci_read_config_word(dev, PCI_COMMAND, &status); status |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR | fbb_enable; (void) pci_write_config_word(dev, PCI_COMMAND, status); diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 848bfb84c04..6d51aa68ec7 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -3,7 +3,6 @@ # config ARCH_SUPPORTS_MSI bool - default n config PCI_MSI bool "Message Signaled Interrupts (MSI and MSI-X)" diff --git a/drivers/pci/access.c b/drivers/pci/access.c index ba91a7e1751..3af0478c057 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -469,3 +469,205 @@ 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 pcie_cap_version(const struct pci_dev *dev) +{ + return dev->pcie_flags_reg & PCI_EXP_FLAGS_VERS; +} + +static inline bool pcie_cap_has_devctl(const struct pci_dev *dev) +{ + return true; +} + +static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev) +{ + int type = pci_pcie_type(dev); + + return 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 pcie_cap_has_sltctl(const struct pci_dev *dev) +{ + int type = pci_pcie_type(dev); + + return 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 pcie_cap_has_rtctl(const struct pci_dev *dev) +{ + int type = pci_pcie_type(dev); + + return pcie_cap_version(dev) > 1 || + type == PCI_EXP_TYPE_ROOT_PORT || + type == PCI_EXP_TYPE_RC_EC; +} + +static bool 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 pcie_cap_has_devctl(dev); + case PCI_EXP_LNKCAP: + case PCI_EXP_LNKCTL: + case PCI_EXP_LNKSTA: + return pcie_cap_has_lnkctl(dev); + case PCI_EXP_SLTCAP: + case PCI_EXP_SLTCTL: + case PCI_EXP_SLTSTA: + return pcie_cap_has_sltctl(dev); + case PCI_EXP_RTCTL: + case PCI_EXP_RTCAP: + case PCI_EXP_RTSTA: + return 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 pcie_cap_version(dev) > 1; + default: + return false; + } +} + +/* + * Note that these accessor functions are only for the "PCI Express + * Capability" (see PCIe spec r3.0, sec 7.8). They do not apply to the + * other "PCI Express Extended Capabilities" (AER, VC, ACS, MFVC, etc.) + */ +int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) +{ + int ret; + + *val = 0; + if (pos & 1) + return -EINVAL; + + if (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; + return ret; + } + + /* + * 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. (PCIe Base Spec 3.0, sec 7.8) + */ + if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && + pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { + *val = PCI_EXP_SLTSTA_PDS; + } + + return 0; +} +EXPORT_SYMBOL(pcie_capability_read_word); + +int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) +{ + int ret; + + *val = 0; + if (pos & 3) + return -EINVAL; + + if (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; + return ret; + } + + if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL && + pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { + *val = PCI_EXP_SLTSTA_PDS; + } + + return 0; +} +EXPORT_SYMBOL(pcie_capability_read_dword); + +int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) +{ + if (pos & 1) + return -EINVAL; + + if (!pcie_capability_reg_implemented(dev, pos)) + return 0; + + return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val); +} +EXPORT_SYMBOL(pcie_capability_write_word); + +int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val) +{ + if (pos & 3) + return -EINVAL; + + if (!pcie_capability_reg_implemented(dev, pos)) + return 0; + + return pci_write_config_dword(dev, pci_pcie_cap(dev) + pos, val); +} +EXPORT_SYMBOL(pcie_capability_write_dword); + +int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, + u16 clear, u16 set) +{ + int ret; + u16 val; + + ret = pcie_capability_read_word(dev, pos, &val); + if (!ret) { + val &= ~clear; + val |= set; + ret = pcie_capability_write_word(dev, pos, val); + } + + return ret; +} +EXPORT_SYMBOL(pcie_capability_clear_and_set_word); + +int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos, + u32 clear, u32 set) +{ + int ret; + u32 val; + + ret = pcie_capability_read_dword(dev, pos, &val); + if (!ret) { + val &= ~clear; + val |= set; + ret = pcie_capability_write_dword(dev, pos, val); + } + + return ret; +} +EXPORT_SYMBOL(pcie_capability_clear_and_set_dword); diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 4b0970b46e0..6241fd05bd4 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -87,11 +87,15 @@ EXPORT_SYMBOL_GPL(pci_bus_resource_n); void pci_bus_remove_resources(struct pci_bus *bus) { int i; + struct pci_bus_resource *bus_res, *tmp; for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) bus->resource[i] = NULL; - pci_free_resource_list(&bus->resources); + list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) { + list_del(&bus_res->list); + kfree(bus_res); + } } /** diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 66f29bc00be..b0e46dede1a 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig @@ -17,28 +17,6 @@ menuconfig HOTPLUG_PCI if HOTPLUG_PCI -config HOTPLUG_PCI_FAKE - tristate "Fake PCI Hotplug driver" - help - Say Y here if you want to use the fake PCI hotplug driver. It can - be used to simulate PCI hotplug events if even if your system is - not PCI hotplug capable. - - This driver will "emulate" removing PCI devices from the system. - If the "power" file is written to with "0" then the specified PCI - device will be completely removed from the kernel. - - WARNING, this does NOT turn off the power to the PCI device. - This is a "logical" removal, not a physical or electrical - removal. - - Use this module at your own risk. You have been warned! - - To compile this driver as a module, choose M here: the - module will be called fakephp. - - When in doubt, say N. - config HOTPLUG_PCI_COMPAQ tristate "Compaq PCI Hotplug driver" depends on X86 && PCI_BIOS @@ -143,7 +121,7 @@ config HOTPLUG_PCI_SHPC config HOTPLUG_PCI_RPA tristate "RPA PCI Hotplug driver" - depends on PPC_PSERIES && EEH && !HOTPLUG_PCI_FAKE + depends on PPC_PSERIES && EEH help Say Y here if you have a RPA system that supports PCI Hotplug. diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 6cd9f3c9887..c459cd4e39c 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile @@ -23,9 +23,6 @@ obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o -# Link this last so it doesn't claim devices that have a real hotplug driver -obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o - pci_hotplug-objs := pci_hotplug_core.o pcihp_slot.o ifdef CONFIG_HOTPLUG_PCI_CPCI diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index ad6fd669549..3d6d4fd1e3c 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -115,6 +115,35 @@ static const struct acpi_dock_ops acpiphp_dock_ops = { .handler = handle_hotplug_event_func, }; +/* Check whether the PCI device is managed by native PCIe hotplug driver */ +static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) +{ + u32 reg32; + acpi_handle tmp; + struct acpi_pci_root *root; + + /* Check whether the PCIe port supports native PCIe hotplug */ + if (pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, ®32)) + return false; + if (!(reg32 & PCI_EXP_SLTCAP_HPC)) + return false; + + /* + * Check whether native PCIe hotplug has been enabled for + * this PCIe hierarchy. + */ + tmp = acpi_find_root_bridge_handle(pdev); + if (!tmp) + return false; + root = acpi_pci_find_root(tmp); + if (!root) + return false; + if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) + return false; + + return true; +} + /* callback routine to register each ACPI PCI slot object */ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) @@ -142,16 +171,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) function = adr & 0xffff; pdev = pbus->self; - if (pdev && pci_is_pcie(pdev)) { - tmp = acpi_find_root_bridge_handle(pdev); - if (tmp) { - struct acpi_pci_root *root = acpi_pci_find_root(tmp); - - if (root && (root->osc_control_set & - OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) - return AE_OK; - } - } + if (pdev && device_is_managed_by_native_pciehp(pdev)) + return AE_OK; newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); if (!newfunc) @@ -382,10 +403,10 @@ static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge) /* allocate and initialize host bridge data structure */ -static void add_host_bridge(acpi_handle *handle) +static void add_host_bridge(struct acpi_pci_root *root) { struct acpiphp_bridge *bridge; - struct acpi_pci_root *root = acpi_pci_find_root(handle); + acpi_handle handle = root->device->handle; bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); if (bridge == NULL) @@ -468,11 +489,12 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) /* find hot-pluggable slots, and then find P2P bridge */ -static int add_bridge(acpi_handle handle) +static int add_bridge(struct acpi_pci_root *root) { acpi_status status; unsigned long long tmp; acpi_handle dummy_handle; + acpi_handle handle = root->device->handle; /* if the bridge doesn't have _STA, we assume it is always there */ status = acpi_get_handle(handle, "_STA", &dummy_handle); @@ -490,7 +512,7 @@ static int add_bridge(acpi_handle handle) /* check if this bridge has ejectable slots */ if (detect_ejectable_slots(handle) > 0) { dbg("found PCI host-bus bridge with hot-pluggable slots\n"); - add_host_bridge(handle); + add_host_bridge(root); } /* search P2P bridges under this host bridge */ @@ -588,9 +610,10 @@ cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } -static void remove_bridge(acpi_handle handle) +static void remove_bridge(struct acpi_pci_root *root) { struct acpiphp_bridge *bridge; + acpi_handle handle = root->device->handle; /* cleanup p2p bridges under this host bridge in a depth-first manner */ @@ -869,17 +892,6 @@ static int __ref enable_device(struct acpiphp_slot *slot) return retval; } -static void disable_bridges(struct pci_bus *bus) -{ - struct pci_dev *dev; - list_for_each_entry(dev, &bus->devices, bus_list) { - if (dev->subordinate) { - disable_bridges(dev->subordinate); - pci_disable_device(dev); - } - } -} - /* return first device in slot, acquiring a reference on it */ static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) { @@ -931,12 +943,7 @@ static int disable_device(struct acpiphp_slot *slot) * here. */ while ((pdev = dev_in_slot(slot))) { - pci_stop_bus_device(pdev); - if (pdev->subordinate) { - disable_bridges(pdev->subordinate); - pci_disable_device(pdev); - } - __pci_remove_bus_device(pdev); + pci_stop_and_remove_bus_device(pdev); pci_dev_put(pdev); } @@ -1477,34 +1484,6 @@ int __init acpiphp_get_num_slots(void) } -#if 0 -/** - * acpiphp_for_each_slot - call function for each slot - * @fn: callback function - * @data: context to be passed to callback function - */ -static int acpiphp_for_each_slot(acpiphp_callback fn, void *data) -{ - struct list_head *node; - struct acpiphp_bridge *bridge; - struct acpiphp_slot *slot; - int retval = 0; - - list_for_each (node, &bridge_list) { - bridge = (struct acpiphp_bridge *)node; - for (slot = bridge->slots; slot; slot = slot->next) { - retval = fn(slot, data); - if (!retval) - goto err_exit; - } - } - - err_exit: - return retval; -} -#endif - - /** * acpiphp_enable_slot - power on slot * @slot: ACPI PHP slot diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c index 81af764c629..a6a71c41cdf 100644 --- a/drivers/pci/hotplug/cpcihp_generic.c +++ b/drivers/pci/hotplug/cpcihp_generic.c @@ -154,12 +154,8 @@ static int __init cpcihp_generic_init(void) if(!r) return -EBUSY; - bus = pci_find_bus(0, bridge_busnr); - if (!bus) { - err("Invalid bus number %d", bridge_busnr); - return -EINVAL; - } - dev = pci_get_slot(bus, PCI_DEVFN(bridge_slot, 0)); + dev = pci_get_domain_bus_and_slot(0, bridge_busnr, + PCI_DEVFN(bridge_slot, 0)); if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { err("Invalid bridge device %s", bridge); pci_dev_put(dev); diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index e43908d9b5d..36112fe212d 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -2890,27 +2890,8 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func func->mem_head = mem_node; } else return -ENOMEM; - } else if ((temp_register & 0x0BL) == 0x04) { - /* Map memory */ - base = temp_register & 0xFFFFFFF0; - base = ~base + 1; - - dbg("CND: length = 0x%x\n", base); - mem_node = get_resource(&(resources->mem_head), base); - - /* allocate the resource to the board */ - if (mem_node) { - base = mem_node->base; - - mem_node->next = func->mem_head; - func->mem_head = mem_node; - } else - return -ENOMEM; - } else if ((temp_register & 0x0BL) == 0x06) { - /* Those bits are reserved, we can't handle this */ - return 1; } else { - /* Requesting space below 1M */ + /* Reserved bits or requesting space below 1M */ return NOT_ENOUGH_RESOURCES; } diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c deleted file mode 100644 index a019c9a712b..00000000000 --- a/drivers/pci/hotplug/fakephp.c +++ /dev/null @@ -1,164 +0,0 @@ -/* Works like the fakephp driver used to, except a little better. - * - * - It's possible to remove devices with subordinate busses. - * - New PCI devices that appear via any method, not just a fakephp triggered - * rescan, will be noticed. - * - Devices that are removed via any method, not just a fakephp triggered - * removal, will also be noticed. - * - * Uses nothing from the pci-hotplug subsystem. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/list.h> -#include <linux/kobject.h> -#include <linux/sysfs.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/device.h> -#include <linux/slab.h> -#include "../pci.h" - -struct legacy_slot { - struct kobject kobj; - struct pci_dev *dev; - struct list_head list; -}; - -static LIST_HEAD(legacy_list); - -static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj); - strcpy(buf, "1\n"); - return 2; -} - -static void remove_callback(void *data) -{ - pci_stop_and_remove_bus_device((struct pci_dev *)data); -} - -static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t len) -{ - struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj); - unsigned long val; - - if (strict_strtoul(buf, 0, &val) < 0) - return -EINVAL; - - if (val) - pci_rescan_bus(slot->dev->bus); - else - sysfs_schedule_callback(&slot->dev->dev.kobj, remove_callback, - slot->dev, THIS_MODULE); - return len; -} - -static struct attribute *legacy_attrs[] = { - &(struct attribute){ .name = "power", .mode = 0644 }, - NULL, -}; - -static void legacy_release(struct kobject *kobj) -{ - struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj); - - pci_dev_put(slot->dev); - kfree(slot); -} - -static struct kobj_type legacy_ktype = { - .sysfs_ops = &(const struct sysfs_ops){ - .store = legacy_store, .show = legacy_show - }, - .release = &legacy_release, - .default_attrs = legacy_attrs, -}; - -static int legacy_add_slot(struct pci_dev *pdev) -{ - struct legacy_slot *slot = kzalloc(sizeof(*slot), GFP_KERNEL); - - if (!slot) - return -ENOMEM; - - if (kobject_init_and_add(&slot->kobj, &legacy_ktype, - &pci_slots_kset->kobj, "%s", - dev_name(&pdev->dev))) { - dev_warn(&pdev->dev, "Failed to created legacy fake slot\n"); - return -EINVAL; - } - slot->dev = pci_dev_get(pdev); - - list_add(&slot->list, &legacy_list); - - return 0; -} - -static int legacy_notify(struct notifier_block *nb, - unsigned long action, void *data) -{ - struct pci_dev *pdev = to_pci_dev(data); - - if (action == BUS_NOTIFY_ADD_DEVICE) { - legacy_add_slot(pdev); - } else if (action == BUS_NOTIFY_DEL_DEVICE) { - struct legacy_slot *slot; - - list_for_each_entry(slot, &legacy_list, list) - if (slot->dev == pdev) - goto found; - - dev_warn(&pdev->dev, "Missing legacy fake slot?"); - return -ENODEV; -found: - kobject_del(&slot->kobj); - list_del(&slot->list); - kobject_put(&slot->kobj); - } - - return 0; -} - -static struct notifier_block legacy_notifier = { - .notifier_call = legacy_notify -}; - -static int __init init_legacy(void) -{ - struct pci_dev *pdev = NULL; - - /* Add existing devices */ - for_each_pci_dev(pdev) - legacy_add_slot(pdev); - - /* Be alerted of any new ones */ - bus_register_notifier(&pci_bus_type, &legacy_notifier); - return 0; -} -module_init(init_legacy); - -static void __exit remove_legacy(void) -{ - struct legacy_slot *slot, *tmp; - - bus_unregister_notifier(&pci_bus_type, &legacy_notifier); - - list_for_each_entry_safe(slot, tmp, &legacy_list, list) { - list_del(&slot->list); - kobject_del(&slot->kobj); - kobject_put(&slot->kobj); - } -} -module_exit(remove_legacy); - - -MODULE_AUTHOR("Trent Piepho <xyzzy@speakeasy.org>"); -MODULE_DESCRIPTION("Legacy version of the fakephp interface"); -MODULE_LICENSE("GPL"); diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 376d70d1717..24d709b7388 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); + 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_core.c b/drivers/pci/hotplug/pciehp_core.c index 365c6b96c64..916bf4f53ab 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -300,24 +300,24 @@ static int pciehp_suspend (struct pcie_device *dev) static int pciehp_resume (struct pcie_device *dev) { + struct controller *ctrl; + struct slot *slot; + u8 status; + dev_info(&dev->device, "%s ENTRY\n", __func__); - if (pciehp_force) { - struct controller *ctrl = get_service_data(dev); - struct slot *slot; - u8 status; + ctrl = get_service_data(dev); - /* reinitialize the chipset's event detection logic */ - pcie_enable_notification(ctrl); + /* reinitialize the chipset's event detection logic */ + pcie_enable_notification(ctrl); - slot = ctrl->slot; + slot = ctrl->slot; - /* Check if slot is occupied */ - pciehp_get_adapter_status(slot, &status); - if (status) - pciehp_enable_slot(slot); - else - pciehp_disable_slot(slot); - } + /* Check if slot is occupied */ + pciehp_get_adapter_status(slot, &status); + if (status) + pciehp_enable_slot(slot); + else + pciehp_disable_slot(slot); return 0; } #endif /* PM */ diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 302451e8289..13b2eaf7ba4 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 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 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 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 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; diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c index 8c05a18c977..fec2d5b7544 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, ®16); - reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or; - pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16); + pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, + ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or); /* Initialize Link Control Register */ - if (dev->subordinate) { - pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, ®16); - 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) + pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL, + ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or); /* Find Advanced Error Reporting Enhanced Capability */ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 74bbaf82638..aeccc911abb 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-driver.c b/drivers/pci/pci-driver.c index d6fd6b6d9d4..9e1d2959e22 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -139,7 +139,6 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) return retval; return count; } -static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); /** * store_remove_id - remove a PCI device ID from this driver @@ -185,38 +184,16 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count) return retval; return count; } -static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); -static int -pci_create_newid_files(struct pci_driver *drv) -{ - int error = 0; +static struct driver_attribute pci_drv_attrs[] = { + __ATTR(new_id, S_IWUSR, NULL, store_new_id), + __ATTR(remove_id, S_IWUSR, NULL, store_remove_id), + __ATTR_NULL, +}; - if (drv->probe != NULL) { - error = driver_create_file(&drv->driver, &driver_attr_new_id); - if (error == 0) { - error = driver_create_file(&drv->driver, - &driver_attr_remove_id); - if (error) - driver_remove_file(&drv->driver, - &driver_attr_new_id); - } - } - return error; -} - -static void pci_remove_newid_files(struct pci_driver *drv) -{ - driver_remove_file(&drv->driver, &driver_attr_remove_id); - driver_remove_file(&drv->driver, &driver_attr_new_id); -} -#else /* !CONFIG_HOTPLUG */ -static inline int pci_create_newid_files(struct pci_driver *drv) -{ - return 0; -} -static inline void pci_remove_newid_files(struct pci_driver *drv) {} -#endif +#else +#define pci_drv_attrs NULL +#endif /* CONFIG_HOTPLUG */ /** * pci_match_id - See if a pci device matches a given pci_id table @@ -1162,8 +1139,6 @@ const struct dev_pm_ops pci_dev_pm_ops = { int __pci_register_driver(struct pci_driver *drv, struct module *owner, const char *mod_name) { - int error; - /* initialize common driver fields */ drv->driver.name = drv->name; drv->driver.bus = &pci_bus_type; @@ -1174,19 +1149,7 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner, INIT_LIST_HEAD(&drv->dynids.list); /* register with core */ - error = driver_register(&drv->driver); - if (error) - goto out; - - error = pci_create_newid_files(drv); - if (error) - goto out_newid; -out: - return error; - -out_newid: - driver_unregister(&drv->driver); - goto out; + return driver_register(&drv->driver); } /** @@ -1202,7 +1165,6 @@ out_newid: void pci_unregister_driver(struct pci_driver *drv) { - pci_remove_newid_files(drv); driver_unregister(&drv->driver); pci_free_dynids(drv); } @@ -1302,6 +1264,7 @@ struct bus_type pci_bus_type = { .shutdown = pci_device_shutdown, .dev_attrs = pci_dev_attrs, .bus_attrs = pci_bus_attrs, + .drv_attrs = pci_drv_attrs, .pm = PCI_PM_OPS_PTR, }; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ab4bf5a4c2f..54858838f09 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -254,52 +254,17 @@ 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 + * pci_find_next_ext_capability - Find an extended capability * @dev: PCI device to query + * @start: address at which to start looking (0 to start at beginning of list) * @cap: capability code * - * Returns the address of the requested extended capability structure + * Returns the address of the next matching extended capability structure * within the device's PCI configuration space or 0 if the device does - * not support it. Possible values for @cap: - * - * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting - * %PCI_EXT_CAP_ID_VC Virtual Channel - * %PCI_EXT_CAP_ID_DSN Device Serial Number - * %PCI_EXT_CAP_ID_PWR Power Budgeting + * not support it. Some capabilities can occur several times, e.g., the + * vendor-specific capability, and this provides a way to find them all. */ -int pci_find_ext_capability(struct pci_dev *dev, int cap) +int pci_find_next_ext_capability(struct pci_dev *dev, int start, int cap) { u32 header; int ttl; @@ -311,6 +276,9 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) if (dev->cfg_size <= PCI_CFG_SPACE_SIZE) return 0; + if (start) + pos = start; + if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) return 0; @@ -322,7 +290,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) return 0; while (ttl-- > 0) { - if (PCI_EXT_CAP_ID(header) == cap) + if (PCI_EXT_CAP_ID(header) == cap && pos != start) return pos; pos = PCI_EXT_CAP_NEXT(header); @@ -335,6 +303,26 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) return 0; } +EXPORT_SYMBOL_GPL(pci_find_next_ext_capability); + +/** + * pci_find_ext_capability - Find an extended capability + * @dev: PCI device to query + * @cap: capability code + * + * Returns the address of the requested extended capability structure + * within the device's PCI configuration space or 0 if the device does + * not support it. Possible values for @cap: + * + * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting + * %PCI_EXT_CAP_ID_VC Virtual Channel + * %PCI_EXT_CAP_ID_DSN Device Serial Number + * %PCI_EXT_CAP_ID_PWR Power Budgeting + */ +int pci_find_ext_capability(struct pci_dev *dev, int cap) +{ + return pci_find_next_ext_capability(dev, 0, cap); +} EXPORT_SYMBOL_GPL(pci_find_ext_capability); static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) @@ -854,21 +842,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,13 +858,11 @@ 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 i = 0; struct pci_cap_saved_state *save_state; u16 *cap; - u16 flags; - pos = pci_pcie_cap(dev); - if (!pos) + if (!pci_is_pcie(dev)) return 0; save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); @@ -899,60 +870,37 @@ static int pci_save_pcie_state(struct pci_dev *dev) 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); - if (pcie_cap_has_devctl(dev->pcie_type, flags)) - pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]); - if (pcie_cap_has_lnkctl(dev->pcie_type, flags)) - pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]); - if (pcie_cap_has_sltctl(dev->pcie_type, flags)) - pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); - if (pcie_cap_has_rtctl(dev->pcie_type, flags)) - pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); - - pos = pci_pcie_cap2(dev); - if (!pos) - return 0; + cap = (u16 *)&save_state->cap.data[0]; + pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &cap[i++]); + pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &cap[i++]); + pcie_capability_read_word(dev, PCI_EXP_SLTCTL, &cap[i++]); + pcie_capability_read_word(dev, PCI_EXP_RTCTL, &cap[i++]); + pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &cap[i++]); + pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &cap[i++]); + 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; + 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); - - if (pcie_cap_has_devctl(dev->pcie_type, flags)) - pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]); - if (pcie_cap_has_lnkctl(dev->pcie_type, flags)) - pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); - if (pcie_cap_has_sltctl(dev->pcie_type, flags)) - pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); - if (pcie_cap_has_rtctl(dev->pcie_type, flags)) - pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); - - 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]; + pcie_capability_write_word(dev, PCI_EXP_DEVCTL, cap[i++]); + pcie_capability_write_word(dev, PCI_EXP_LNKCTL, cap[i++]); + pcie_capability_write_word(dev, PCI_EXP_SLTCTL, cap[i++]); + pcie_capability_write_word(dev, PCI_EXP_RTCTL, cap[i++]); + pcie_capability_write_word(dev, PCI_EXP_DEVCTL2, cap[i++]); + pcie_capability_write_word(dev, PCI_EXP_LNKCTL2, cap[i++]); + pcie_capability_write_word(dev, PCI_EXP_SLTCTL2, cap[i++]); } @@ -1543,7 +1491,7 @@ void pci_pme_wakeup_bus(struct pci_bus *bus) /** * pci_wakeup - Wake up a PCI device - * @dev: Device to handle. + * @pci_dev: Device to handle. * @ign: ignored parameter */ static int pci_wakeup(struct pci_dev *pci_dev, void *ign) @@ -2067,35 +2015,24 @@ 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) 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); + 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); - + pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI); bridge->ari_enabled = 1; } @@ -2110,20 +2047,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) + pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, ctrl); } EXPORT_SYMBOL(pci_enable_ido); @@ -2134,20 +2065,14 @@ EXPORT_SYMBOL(pci_enable_ido); */ void pci_disable_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; + 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) + pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, ctrl); } EXPORT_SYMBOL(pci_disable_ido); @@ -2172,17 +2097,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); + pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap); if (!(cap & PCI_EXP_OBFF_MASK)) return -ENOTSUPP; /* no OBFF support at all */ @@ -2193,7 +2112,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); + pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &ctrl); if (cap & PCI_EXP_OBFF_WAKE) ctrl |= PCI_EXP_OBFF_WAKE_EN; else { @@ -2211,7 +2130,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); + pcie_capability_write_word(dev, PCI_EXP_DEVCTL2, ctrl); return 0; } @@ -2225,17 +2144,7 @@ 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); + pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_OBFF_WAKE_EN); } EXPORT_SYMBOL(pci_disable_obff); @@ -2248,15 +2157,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); + pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap); return cap & PCI_EXP_DEVCAP2_LTR; } @@ -2273,22 +2176,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); @@ -2296,11 +2192,7 @@ 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 pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_LTR_EN); } EXPORT_SYMBOL(pci_enable_ltr); @@ -2310,24 +2202,14 @@ 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; + + pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_LTR_EN); } EXPORT_SYMBOL(pci_disable_ltr); @@ -2410,9 +2292,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; @@ -2460,8 +2339,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) @@ -3177,15 +3056,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); + pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); if (!(cap & PCI_EXP_DEVCAP_FLR)) return -ENOTTY; @@ -3197,7 +3071,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); + pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status); if (!(status & PCI_EXP_DEVSTA_TRPND)) goto clear; } @@ -3206,9 +3080,7 @@ 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); + pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); msleep(100); @@ -3576,18 +3448,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); + pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl); - return ret; + return 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12); } EXPORT_SYMBOL(pcie_get_readrq); @@ -3601,19 +3466,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 @@ -3631,14 +3488,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 pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_READRQ, v); } EXPORT_SYMBOL(pcie_set_readrq); @@ -3651,18 +3502,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); + pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl); - return ret; + return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); } /** @@ -3675,32 +3519,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 pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_PAYLOAD, v); } /** diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 52229863e9f..4e24cb8a94a 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 58ad7917553..030cf12d546 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -48,7 +48,7 @@ static pci_ers_result_t aer_error_detected(struct pci_dev *dev, static void aer_error_resume(struct pci_dev *dev); static pci_ers_result_t aer_root_reset(struct pci_dev *dev); -static struct pci_error_handlers aer_error_handlers = { +static const struct pci_error_handlers aer_error_handlers = { .error_detected = aer_error_detected, .resume = aer_error_resume, }; @@ -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 @@ -121,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, ®16); - pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); + pcie_capability_read_word(pdev, PCI_EXP_DEVSTA, ®16); + 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, ®16); - reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK); - pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16); + pcie_capability_clear_word(pdev, PCI_EXP_RTCTL, + SYSTEM_ERROR_INTR_ON_MESG_MASK); aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); /* Clear error status */ @@ -395,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, ®16); - pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); + pcie_capability_read_word(dev, PCI_EXP_DEVSTA, ®16); + 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_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index 124f20ff11b..5194a7d4173 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 0ca05353814..06bad96af41 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -32,53 +32,28 @@ static bool nosourceid; module_param(forceload, bool, 0); module_param(nosourceid, bool, 0); +#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \ + PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE) + 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) + if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) return -EIO; - pos = pci_pcie_cap(dev); - if (!pos) - return -EIO; - - pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); - 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 pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS); } 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, ®16); - 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 pcie_capability_clear_word(dev, PCI_EXP_DEVCTL, + PCI_EXP_AER_FLAGS); } EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); @@ -151,18 +126,12 @@ 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, ®16); - if (!(reg16 & ( - PCI_EXP_DEVCTL_CERE | - PCI_EXP_DEVCTL_NFERE | - PCI_EXP_DEVCTL_FERE | - PCI_EXP_DEVCTL_URRE))) + pcie_capability_read_word(dev, PCI_EXP_DEVCTL, ®16); + if (!(reg16 & PCI_EXP_AER_FLAGS)) return false; + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos) return false; @@ -240,7 +209,7 @@ static bool find_source_device(struct pci_dev *parent, static int report_error_detected(struct pci_dev *dev, void *data) { pci_ers_result_t vote; - struct pci_error_handlers *err_handler; + const struct pci_error_handlers *err_handler; struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; @@ -274,7 +243,7 @@ static int report_error_detected(struct pci_dev *dev, void *data) static int report_mmio_enabled(struct pci_dev *dev, void *data) { pci_ers_result_t vote; - struct pci_error_handlers *err_handler; + const struct pci_error_handlers *err_handler; struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; @@ -292,7 +261,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data) static int report_slot_reset(struct pci_dev *dev, void *data) { pci_ers_result_t vote; - struct pci_error_handlers *err_handler; + const struct pci_error_handlers *err_handler; struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; @@ -309,7 +278,7 @@ static int report_slot_reset(struct pci_dev *dev, void *data) static int report_resume(struct pci_dev *dev, void *data) { - struct pci_error_handlers *err_handler; + const struct pci_error_handlers *err_handler; dev->error_state = pci_channel_io_normal; @@ -465,7 +434,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, @@ -540,14 +509,12 @@ static void do_recovery(struct pci_dev *dev, int severity) "resume", report_resume); - dev_printk(KERN_DEBUG, &dev->dev, - "AER driver successfully recovered\n"); + dev_info(&dev->dev, "AER: Device recovery successful\n"); return; failed: /* TODO: Should kernel panic here? */ - dev_printk(KERN_DEBUG, &dev->dev, - "AER driver didn't recover\n"); + dev_info(&dev->dev, "AER: Device recovery failed\n"); } /** diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index b500840a143..213753b283a 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -125,21 +125,16 @@ 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, ®16); if (enable) - reg16 |= PCI_EXP_LNKCTL_CLKREQ_EN; + pcie_capability_set_word(child, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CLKREQ_EN); else - reg16 &= ~PCI_EXP_LNKCTL_CLKREQ_EN; - pci_write_config_word(child, pos + PCI_EXP_LNKCTL, reg16); + pcie_capability_clear_word(child, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CLKREQ_EN); } link->clkpm_enabled = !!enable; } @@ -157,7 +152,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 +160,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, ®32); + pcie_capability_read_dword(child, PCI_EXP_LNKCAP, ®32); if (!(reg32 & PCI_EXP_LNKCAP_CLKPM)) { capable = 0; enabled = 0; break; } - pci_read_config_word(child, pos + PCI_EXP_LNKCTL, ®16); + pcie_capability_read_word(child, PCI_EXP_LNKCTL, ®16); if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN)) enabled = 0; } @@ -190,7 +182,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 +195,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, ®16); + pcie_capability_read_word(child, PCI_EXP_LNKSTA, ®16); 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, ®16); + pcie_capability_read_word(parent, PCI_EXP_LNKSTA, ®16); 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, ®16); + pcie_capability_read_word(child, PCI_EXP_LNKCTL, ®16); 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); + pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16); } /* Configure upstream component */ - pci_read_config_word(parent, ppos + PCI_EXP_LNKCTL, ®16); + pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); 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); + 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); + 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, ®16); + pcie_capability_read_word(parent, PCI_EXP_LNKSTA, ®16); if (!(reg16 & PCI_EXP_LNKSTA_LT)) break; if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) @@ -255,12 +244,10 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) /* Training failed. Restore common clock configurations */ 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_write_config_word(parent, ppos + PCI_EXP_LNKCTL, parent_reg); + list_for_each_entry(child, &linkbus->devices, bus_list) + pcie_capability_write_word(child, PCI_EXP_LNKCTL, + child_reg[PCI_FUNC(child->devfn)]); + pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg); } /* Convert L0s latency encoding to ns */ @@ -305,16 +292,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, ®32); + pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, ®32); 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, ®16); + pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, ®16); info->enabled = reg16 & PCI_EXP_LNKCTL_ASPMC; } @@ -412,7 +397,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; } @@ -420,17 +405,15 @@ 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)]; - 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); - pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, ®32); + pcie_capability_read_dword(child, PCI_EXP_DEVCAP, ®32); /* Calculate endpoint L0s acceptable latency */ encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; acceptable->l0s = calc_l0s_acceptable(encoding); @@ -444,13 +427,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, ®16); - reg16 &= ~0x3; - reg16 |= val; - pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); + pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL, 0x3, val); } static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state) @@ -505,7 +482,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 +489,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 +505,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, ®32); + pcie_capability_read_dword(child, PCI_EXP_DEVCAP, ®32); 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" @@ -552,7 +527,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 +560,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 +622,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 +638,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 +679,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 +704,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 +732,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 +908,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 +925,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 001f1b78f39..9ca0dc9ffd8 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c @@ -57,17 +57,12 @@ struct pcie_pme_service_data { */ void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) { - int rtctl_pos; - u16 rtctl; - - rtctl_pos = pci_pcie_cap(dev) + PCI_EXP_RTCTL; - - pci_read_config_word(dev, rtctl_pos, &rtctl); if (enable) - rtctl |= PCI_EXP_RTCTL_PMEIE; + pcie_capability_set_word(dev, PCI_EXP_RTCTL, + PCI_EXP_RTCTL_PMEIE); else - rtctl &= ~PCI_EXP_RTCTL_PMEIE; - pci_write_config_word(dev, rtctl_pos, rtctl); + pcie_capability_clear_word(dev, PCI_EXP_RTCTL, + PCI_EXP_RTCTL_PMEIE); } /** @@ -120,7 +115,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; @@ -226,18 +221,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); + 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 +268,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); + pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta); if (!(rtsta & PCI_EXP_RTSTA_PME)) { spin_unlock_irqrestore(&data->lock, flags); @@ -335,13 +324,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 18bf90f748f..67be55a7f26 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 75915b30ad1..d03a7a39b2d 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -200,10 +200,13 @@ static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask) { int i, irq = -1; - /* We have to use INTx if MSI cannot be used for PCIe PME or pciehp. */ + /* + * If MSI cannot be used for PCIe PME or hotplug, we have to use + * INTx or other interrupts, e.g. system shared interrupt. + */ if (((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) || ((mask & PCIE_PORT_SERVICE_HP) && pciehp_no_msi())) { - if (dev->pin) + if (dev->irq) irq = dev->irq; goto no_msi; } @@ -212,8 +215,12 @@ static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask) if (!pcie_port_enable_msix(dev, irqs, mask)) return 0; - /* We're not going to use MSI-X, so try MSI and fall back to INTx */ - if (!pci_enable_msi(dev) || dev->pin) + /* + * We're not going to use MSI-X, so try MSI and fall back to INTx. + * If neither MSI/MSI-X nor INTx available, try other interrupt. On + * some platforms, root port doesn't support MSI/MSI-X/INTx in RC mode. + */ + if (!pci_enable_msi(dev) || dev->irq) irq = dev->irq; no_msi: @@ -246,8 +253,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 +271,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, ®16); /* Hot-Plug Capable */ - if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) { - pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, ®32); + if (cap_mask & PCIE_PORT_SERVICE_HP) { + pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); if (reg32 & PCI_EXP_SLTCAP_HPC) { services |= PCIE_PORT_SERVICE_HP; /* @@ -277,10 +281,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, ®16); - reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE); - pci_write_config_word(dev, pos, reg16); + pcie_capability_clear_word(dev, PCI_EXP_SLTCTL, + PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE); } } /* AER capable */ @@ -298,7 +300,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 +338,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 e76b44777db..0761d90ca27 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -64,14 +64,7 @@ __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); + pcie_capability_set_dword(dev, PCI_EXP_RTSTA, PCI_EXP_RTSTA_PME); } static int pcie_portdrv_restore_config(struct pci_dev *dev) @@ -95,7 +88,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; } @@ -195,9 +188,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) { @@ -385,11 +378,11 @@ static const struct pci_device_id port_pci_ids[] = { { }; MODULE_DEVICE_TABLE(pci, port_pci_ids); -static struct pci_error_handlers pcie_portdrv_err_handler = { - .error_detected = pcie_portdrv_error_detected, - .mmio_enabled = pcie_portdrv_mmio_enabled, - .slot_reset = pcie_portdrv_slot_reset, - .resume = pcie_portdrv_err_resume, +static const struct pci_error_handlers pcie_portdrv_err_handler = { + .error_detected = pcie_portdrv_error_detected, + .mmio_enabled = pcie_portdrv_mmio_enabled, + .slot_reset = pcie_portdrv_slot_reset, + .resume = pcie_portdrv_err_resume, }; static struct pci_driver pcie_portdriver = { diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 9f8a6b79a8e..ec909afa90b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -606,10 +606,10 @@ static void pci_set_bus_speed(struct pci_bus *bus) u32 linkcap; u16 linksta; - pci_read_config_dword(bridge, pos + PCI_EXP_LNKCAP, &linkcap); + 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); + pcie_capability_read_word(bridge, PCI_EXP_LNKSTA, &linksta); pcie_update_link_speed(bus, linksta); } } @@ -729,8 +729,10 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, /* Check if setup is sensible at all */ if (!pass && - (primary != bus->number || secondary <= bus->number)) { - dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); + (primary != bus->number || secondary <= bus->number || + secondary > subordinate)) { + dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n", + secondary, subordinate); broken = 1; } @@ -932,24 +934,16 @@ 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, ®16); - pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; + pdev->pcie_flags_reg = reg16; pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, ®16); pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD; } 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, ®16); - if (!(reg16 & PCI_EXP_FLAGS_SLOT)) - return; - pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, ®32); + pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, ®32); if (reg32 & PCI_EXP_SLTCAP_HPC) pdev->is_hotplug_bridge = 1; } @@ -1163,8 +1157,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; @@ -1386,9 +1379,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; @@ -1465,7 +1458,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) @@ -1481,7 +1474,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 @@ -1756,11 +1750,6 @@ int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) "busn_res: can not insert %pR under %s%pR (conflicts with %s %pR)\n", res, pci_is_root_bus(b) ? "domain " : "", parent_res, conflict->name, conflict); - else - dev_printk(KERN_DEBUG, &b->dev, - "busn_res: %pR is inserted under %s%pR\n", - res, pci_is_root_bus(b) ? "domain " : "", - parent_res); return conflict == NULL; } diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 27911b55c2a..eb907a8faf2 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -434,25 +434,6 @@ int pci_proc_detach_device(struct pci_dev *dev) return 0; } -#if 0 -int pci_proc_attach_bus(struct pci_bus* bus) -{ - struct proc_dir_entry *de = bus->procdir; - - if (!proc_initialized) - return -EACCES; - - if (!de) { - char name[16]; - sprintf(name, "%02x", bus->number); - de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir); - if (!de) - return -ENOMEM; - } - return 0; -} -#endif /* 0 */ - int pci_proc_detach_bus(struct pci_bus* bus) { struct proc_dir_entry *de = bus->procdir; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 51553179e96..7a451ff56ec 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3081,17 +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 pos; + int i; + u16 status; - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (!pos) - return -ENOTTY; + /* + * 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; - pci_write_config_word(dev, pos + 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; diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 04a4861b474..513972f3ed1 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -32,152 +32,82 @@ static void pci_stop_dev(struct pci_dev *dev) static void pci_destroy_dev(struct pci_dev *dev) { - /* Remove the device from the device lists, and prevent any further - * list accesses from this device */ down_write(&pci_bus_sem); list_del(&dev->bus_list); - dev->bus_list.next = dev->bus_list.prev = NULL; up_write(&pci_bus_sem); pci_free_resources(dev); pci_dev_put(dev); } -/** - * pci_remove_device_safe - remove an unused hotplug device - * @dev: the device to remove - * - * Delete the device structure from the device lists and - * notify userspace (/sbin/hotplug), but only if the device - * in question is not being used by a driver. - * Returns 0 on success. - */ -#if 0 -int pci_remove_device_safe(struct pci_dev *dev) -{ - if (pci_dev_driver(dev)) - return -EBUSY; - pci_destroy_dev(dev); - return 0; -} -#endif /* 0 */ - -void pci_remove_bus(struct pci_bus *pci_bus) +void pci_remove_bus(struct pci_bus *bus) { - pci_proc_detach_bus(pci_bus); + pci_proc_detach_bus(bus); down_write(&pci_bus_sem); - list_del(&pci_bus->node); - pci_bus_release_busn_res(pci_bus); + list_del(&bus->node); + pci_bus_release_busn_res(bus); up_write(&pci_bus_sem); - if (!pci_bus->is_added) + if (!bus->is_added) return; - pci_remove_legacy_files(pci_bus); - device_unregister(&pci_bus->dev); + pci_remove_legacy_files(bus); + device_unregister(&bus->dev); } EXPORT_SYMBOL(pci_remove_bus); -static void __pci_remove_behind_bridge(struct pci_dev *dev); -/** - * pci_stop_and_remove_bus_device - remove a PCI device and any children - * @dev: the device to remove - * - * Remove a PCI device from the device lists, informing the drivers - * that the device has been removed. We also remove any subordinate - * buses and children in a depth-first manner. - * - * For each device we remove, delete the device structure from the - * device lists, remove the /proc entry, and notify userspace - * (/sbin/hotplug). - */ -void __pci_remove_bus_device(struct pci_dev *dev) +static void pci_stop_bus_device(struct pci_dev *dev) { - if (dev->subordinate) { - struct pci_bus *b = dev->subordinate; + struct pci_bus *bus = dev->subordinate; + struct pci_dev *child, *tmp; - __pci_remove_behind_bridge(dev); - pci_remove_bus(b); - dev->subordinate = NULL; + /* + * Stopping an SR-IOV PF device removes all the associated VFs, + * which will update the bus->devices list and confuse the + * iterator. Therefore, iterate in reverse so we remove the VFs + * first, then the PF. + */ + if (bus) { + list_for_each_entry_safe_reverse(child, tmp, + &bus->devices, bus_list) + pci_stop_bus_device(child); } - pci_destroy_dev(dev); -} -EXPORT_SYMBOL(__pci_remove_bus_device); - -void pci_stop_and_remove_bus_device(struct pci_dev *dev) -{ - pci_stop_bus_device(dev); - __pci_remove_bus_device(dev); + pci_stop_dev(dev); } -static void __pci_remove_behind_bridge(struct pci_dev *dev) +static void pci_remove_bus_device(struct pci_dev *dev) { - struct list_head *l, *n; + struct pci_bus *bus = dev->subordinate; + struct pci_dev *child, *tmp; - if (dev->subordinate) - list_for_each_safe(l, n, &dev->subordinate->devices) - __pci_remove_bus_device(pci_dev_b(l)); -} + if (bus) { + list_for_each_entry_safe(child, tmp, + &bus->devices, bus_list) + pci_remove_bus_device(child); -static void pci_stop_behind_bridge(struct pci_dev *dev) -{ - struct list_head *l, *n; + pci_remove_bus(bus); + dev->subordinate = NULL; + } - if (dev->subordinate) - list_for_each_safe(l, n, &dev->subordinate->devices) - pci_stop_bus_device(pci_dev_b(l)); + pci_destroy_dev(dev); } /** - * pci_stop_and_remove_behind_bridge - stop and remove all devices behind - * a PCI bridge - * @dev: PCI bridge device + * pci_stop_and_remove_bus_device - remove a PCI device and any children + * @dev: the device to remove * - * Remove all devices on the bus, except for the parent bridge. - * This also removes any child buses, and any devices they may - * contain in a depth-first manner. - */ -void pci_stop_and_remove_behind_bridge(struct pci_dev *dev) -{ - pci_stop_behind_bridge(dev); - __pci_remove_behind_bridge(dev); -} - -static void pci_stop_bus_devices(struct pci_bus *bus) -{ - struct list_head *l, *n; - - /* - * VFs could be removed by pci_stop_and_remove_bus_device() in the - * pci_stop_bus_devices() code path for PF. - * aka, bus->devices get updated in the process. - * but VFs are inserted after PFs when SRIOV is enabled for PF, - * We can iterate the list backwards to get prev valid PF instead - * of removed VF. - */ - list_for_each_prev_safe(l, n, &bus->devices) { - struct pci_dev *dev = pci_dev_b(l); - pci_stop_bus_device(dev); - } -} - -/** - * pci_stop_bus_device - stop a PCI device and any children - * @dev: the device to stop + * Remove a PCI device from the device lists, informing the drivers + * that the device has been removed. We also remove any subordinate + * buses and children in a depth-first manner. * - * Stop a PCI device (detach the driver, remove from the global list - * and so on). This also stop any subordinate buses and children in a - * depth-first manner. + * For each device we remove, delete the device structure from the + * device lists, remove the /proc entry, and notify userspace + * (/sbin/hotplug). */ -void pci_stop_bus_device(struct pci_dev *dev) +void pci_stop_and_remove_bus_device(struct pci_dev *dev) { - if (dev->subordinate) - pci_stop_bus_devices(dev->subordinate); - - pci_stop_dev(dev); + pci_stop_bus_device(dev); + pci_remove_bus_device(dev); } - EXPORT_SYMBOL(pci_stop_and_remove_bus_device); -EXPORT_SYMBOL(pci_stop_and_remove_behind_bridge); -EXPORT_SYMBOL_GPL(pci_stop_bus_device); diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 48ebdb237f3..0b3037ab8b9 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -167,44 +167,6 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) return rom; } -#if 0 -/** - * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy - * @pdev: pointer to pci device struct - * @size: pointer to receive size of pci window over ROM - * - * Return: kernel virtual pointer to image of ROM - * - * Map a PCI ROM into kernel space. If ROM is boot video ROM, - * the shadow BIOS copy will be returned instead of the - * actual ROM. - */ -void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size) -{ - struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; - void __iomem *rom; - - rom = pci_map_rom(pdev, size); - if (!rom) - return NULL; - - if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW | - IORESOURCE_ROM_BIOS_COPY)) - return rom; - - res->start = (unsigned long)kmalloc(*size, GFP_KERNEL); - if (!res->start) - return rom; - - res->end = res->start + *size; - memcpy_fromio((void*)(unsigned long)res->start, rom, *size); - pci_unmap_rom(pdev, rom); - res->flags |= IORESOURCE_ROM_COPY; - - return (void __iomem *)(unsigned long)res->start; -} -#endif /* 0 */ - /** * pci_unmap_rom - unmap the ROM from kernel space * @pdev: pointer to pci device struct @@ -226,27 +188,6 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) pci_disable_rom(pdev); } -#if 0 -/** - * pci_remove_rom - disable the ROM and remove its sysfs attribute - * @pdev: pointer to pci device struct - * - * Remove the rom file in sysfs and disable ROM decoding. - */ -void pci_remove_rom(struct pci_dev *pdev) -{ - struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; - - if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) - sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); - if (!(res->flags & (IORESOURCE_ROM_ENABLE | - IORESOURCE_ROM_SHADOW | - IORESOURCE_ROM_BIOS_COPY | - IORESOURCE_ROM_COPY))) - pci_disable_rom(pdev); -} -#endif /* 0 */ - /** * pci_cleanup_rom - free the ROM copy created by pci_map_rom_copy * @pdev: pointer to pci device struct diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 993d4a0a246..bf969ba58e5 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; @@ -130,16 +130,14 @@ pci_find_next_bus(const struct pci_bus *from) * decrement the reference count by calling pci_dev_put(). * If no device is found, %NULL is returned. */ -struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) +struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn) { - struct list_head *tmp; struct pci_dev *dev; WARN_ON(in_interrupt()); down_read(&pci_bus_sem); - list_for_each(tmp, &bus->devices) { - dev = pci_dev_b(tmp); + list_for_each_entry(dev, &bus->devices, bus_list) { if (dev->devfn == devfn) goto out; } @@ -245,30 +243,14 @@ struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from) { - struct pci_dev *pdev; - struct pci_device_id *id; - - /* - * pci_find_subsys() can be called on the ide_setup() path, - * super-early in boot. But the down_read() will enable local - * interrupts, which can cause some machines to crash. So here we - * detect and flag that situation and bail out early. - */ - if (unlikely(no_pci_devices())) - return NULL; - - id = kzalloc(sizeof(*id), GFP_KERNEL); - if (!id) - return NULL; - id->vendor = vendor; - id->device = device; - id->subvendor = ss_vendor; - id->subdevice = ss_device; - - pdev = pci_get_dev_by_id(id, from); - kfree(id); - - return pdev; + struct pci_device_id id = { + .vendor = vendor, + .device = device, + .subvendor = ss_vendor, + .subdevice = ss_device, + }; + + return pci_get_dev_by_id(&id, from); } /** @@ -307,19 +289,16 @@ pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) */ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) { - struct pci_dev *dev; - struct pci_device_id *id; - - id = kzalloc(sizeof(*id), GFP_KERNEL); - if (!id) - return NULL; - id->vendor = id->device = id->subvendor = id->subdevice = PCI_ANY_ID; - id->class_mask = PCI_ANY_ID; - id->class = class; - - dev = pci_get_dev_by_id(id, from); - kfree(id); - return dev; + struct pci_device_id id = { + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .class_mask = PCI_ANY_ID, + .class = class, + }; + + return pci_get_dev_by_id(&id, from); } /** diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index fb506137aae..1e808ca338f 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -697,6 +697,38 @@ static resource_size_t calculate_memsize(resource_size_t size, return size; } +resource_size_t __weak pcibios_window_alignment(struct pci_bus *bus, + unsigned long type) +{ + return 1; +} + +#define PCI_P2P_DEFAULT_MEM_ALIGN 0x100000 /* 1MiB */ +#define PCI_P2P_DEFAULT_IO_ALIGN 0x1000 /* 4KiB */ +#define PCI_P2P_DEFAULT_IO_ALIGN_1K 0x400 /* 1KiB */ + +static resource_size_t window_alignment(struct pci_bus *bus, + unsigned long type) +{ + resource_size_t align = 1, arch_align; + + if (type & IORESOURCE_MEM) + align = PCI_P2P_DEFAULT_MEM_ALIGN; + else if (type & IORESOURCE_IO) { + /* + * Per spec, I/O windows are 4K-aligned, but some + * bridges have an extension to support 1K alignment. + */ + if (bus->self->io_window_1k) + align = PCI_P2P_DEFAULT_IO_ALIGN_1K; + else + align = PCI_P2P_DEFAULT_IO_ALIGN; + } + + arch_align = pcibios_window_alignment(bus, type); + return max(align, arch_align); +} + /** * pbus_size_io() - size the io window of a given bus * @@ -717,17 +749,12 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); unsigned long size = 0, size0 = 0, size1 = 0; resource_size_t children_add_size = 0; - resource_size_t min_align = 4096, align; + resource_size_t min_align, io_align, align; if (!b_res) return; - /* - * Per spec, I/O windows are 4K-aligned, but some bridges have an - * extension to support 1K alignment. - */ - if (bus->self->io_window_1k) - min_align = 1024; + io_align = min_align = window_alignment(bus, IORESOURCE_IO); list_for_each_entry(dev, &bus->devices, bus_list) { int i; @@ -754,8 +781,8 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, } } - if (min_align > 4096) - min_align = 4096; + if (min_align > io_align) + min_align = io_align; size0 = calculate_iosize(size, min_size, size1, resource_size(b_res), min_align); @@ -785,6 +812,28 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, } } +static inline resource_size_t calculate_mem_align(resource_size_t *aligns, + int max_order) +{ + resource_size_t align = 0; + resource_size_t min_align = 0; + int order; + + for (order = 0; order <= max_order; order++) { + resource_size_t align1 = 1; + + align1 <<= (order + 20); + + if (!align) + min_align = align1; + else if (ALIGN(align + min_align, min_align) < align1) + min_align = align1 >> 1; + align += aligns[order]; + } + + return min_align; +} + /** * pbus_size_mem() - size the memory window of a given bus * @@ -864,19 +913,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, children_add_size += get_res_add_size(realloc_head, r); } } - align = 0; - min_align = 0; - for (order = 0; order <= max_order; order++) { - resource_size_t align1 = 1; - align1 <<= (order + 20); - - if (!align) - min_align = align1; - else if (ALIGN(align + min_align, min_align) < align1) - min_align = align1 >> 1; - align += aligns[order]; - } + min_align = calculate_mem_align(aligns, max_order); + min_align = max(min_align, window_alignment(bus, b_res->flags & mask)); size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); if (children_add_size > add_size) add_size = children_add_size; diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c index eb219a1d16f..9bd6864ec5d 100644 --- a/drivers/pci/setup-irq.c +++ b/drivers/pci/setup-irq.c @@ -17,8 +17,13 @@ #include <linux/ioport.h> #include <linux/cache.h> +void __weak pcibios_update_irq(struct pci_dev *dev, int irq) +{ + dev_dbg(&dev->dev, "assigning IRQ %02d\n", irq); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} -static void __init +static void pdev_fixup_irq(struct pci_dev *dev, u8 (*swizzle)(struct pci_dev *, u8 *), int (*map_irq)(const struct pci_dev *, u8, u8)) @@ -54,7 +59,7 @@ pdev_fixup_irq(struct pci_dev *dev, pcibios_update_irq(dev, irq); } -void __init +void pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *), int (*map_irq)(const struct pci_dev *, u8, u8)) { diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index d6cc62cb4cf..def8d0b5620 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -982,7 +982,6 @@ static int pcifront_detach_devices(struct pcifront_device *pdev) int err = 0; int i, num_devs; unsigned int domain, bus, slot, func; - struct pci_bus *pci_bus; struct pci_dev *pci_dev; char str[64]; @@ -1032,13 +1031,8 @@ static int pcifront_detach_devices(struct pcifront_device *pdev) goto out; } - pci_bus = pci_find_bus(domain, bus); - if (!pci_bus) { - dev_dbg(&pdev->xdev->dev, "Cannot get bus %04x:%02x\n", - domain, bus); - continue; - } - pci_dev = pci_get_slot(pci_bus, PCI_DEVFN(slot, func)); + pci_dev = pci_get_domain_bus_and_slot(domain, bus, + PCI_DEVFN(slot, func)); if (!pci_dev) { dev_dbg(&pdev->xdev->dev, "Cannot get PCI device %04x:%02x:%02x.%d\n", diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index 24caeaf5052..9d3ac998fc1 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -105,8 +105,17 @@ int __ref cb_alloc(struct pcmcia_socket *s) */ void cb_free(struct pcmcia_socket *s) { - struct pci_dev *bridge = s->cb_dev; + struct pci_dev *bridge, *dev, *tmp; + struct pci_bus *bus; - if (bridge) - pci_stop_and_remove_behind_bridge(bridge); + bridge = s->cb_dev; + if (!bridge) + return; + + bus = bridge->subordinate; + if (!bus) + return; + + list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) + pci_stop_and_remove_bus_device(dev); } diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 5d44252b734..d5e1625bbac 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c @@ -2219,9 +2219,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct tsi721_device *priv; - int cap; int err; - u32 regval; priv = kzalloc(sizeof(struct tsi721_device), GFP_KERNEL); if (priv == NULL) { @@ -2330,20 +2328,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, ®val); - 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); + pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN | + PCI_EXP_DEVCTL_NOSNOOP_EN, + 0x2 << MAX_READ_REQUEST_SZ_SHIFT); /* Adjust PCIe completion timeout. */ - pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL2, ®val); - regval &= ~(0x0f); - pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL2, regval | 0x2); + pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL2, 0xf, 0x2); /* * FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 1059c99690e..0a2c5a8ebb8 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -9228,7 +9228,7 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { }; MODULE_DEVICE_TABLE(pci, ipr_pci_table); -static struct pci_error_handlers ipr_err_handler = { +static const struct pci_error_handlers ipr_err_handler = { .error_detected = ipr_pci_error_detected, .slot_reset = ipr_pci_slot_reset, }; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 29937b606c8..628a703abdd 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -10425,7 +10425,7 @@ static struct pci_device_id lpfc_id_table[] = { MODULE_DEVICE_TABLE(pci, lpfc_id_table); -static struct pci_error_handlers lpfc_err_handler = { +static const struct pci_error_handlers lpfc_err_handler = { .error_detected = lpfc_io_error_detected, .slot_reset = lpfc_io_slot_reset, .resume = lpfc_io_resume, diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index b1ebd6f8dab..1ccae45c527 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -8306,7 +8306,7 @@ _scsih_pci_mmio_enabled(struct pci_dev *pdev) return PCI_ERS_RESULT_NEED_RESET; } -static struct pci_error_handlers _scsih_err_handler = { +static const struct pci_error_handlers _scsih_err_handler = { .error_detected = _scsih_pci_error_detected, .mmio_enabled = _scsih_pci_mmio_enabled, .slot_reset = _scsih_pci_slot_reset, diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 9ce3a8f8754..7cfdf2bd8ed 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_pcie_cap(ha->pdev); - pci_read_config_word(ha->pdev, pcie_reg + PCI_EXP_LNKSTA, &lnk); + 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_pcie_cap(ha->pdev); - pci_read_config_word(ha->pdev, pcie_cap + PCI_EXP_LNKSTA, &lnk); + 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/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index fb8cd3847d4..d3052622e77 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4471,7 +4471,7 @@ qla2xxx_pci_resume(struct pci_dev *pdev) ha->flags.eeh_busy = 0; } -static struct pci_error_handlers qla2xxx_err_handler = { +static const struct pci_error_handlers qla2xxx_err_handler = { .error_detected = qla2xxx_pci_error_detected, .mmio_enabled = qla2xxx_pci_mmio_enabled, .slot_reset = qla2xxx_pci_slot_reset, diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index 939d7261c37..807bf76f1b6 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_pcie_cap(ha->pdev); - pci_read_config_word(ha->pdev, pcie_cap + PCI_EXP_LNKSTA, &lnk); + 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_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 487e3c8411c..79243b76d17 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -6148,7 +6148,7 @@ qla4xxx_pci_resume(struct pci_dev *pdev) clear_bit(AF_EEH_BUSY, &ha->flags); } -static struct pci_error_handlers qla4xxx_err_handler = { +static const struct pci_error_handlers qla4xxx_err_handler = { .error_detected = qla4xxx_pci_error_detected, .mmio_enabled = qla4xxx_pci_mmio_enabled, .slot_reset = qla4xxx_pci_slot_reset, diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 36d1ed7817e..e2b8e68b57e 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -2117,7 +2117,7 @@ static struct pci_device_id sym2_id_table[] __devinitdata = { MODULE_DEVICE_TABLE(pci, sym2_id_table); -static struct pci_error_handlers sym2_err_handler = { +static const struct pci_error_handlers sym2_err_handler = { .error_detected = sym2_io_error_detected, .mmio_enabled = sym2_io_slot_dump, .slot_reset = sym2_io_slot_reset, diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 029725c89e5..49553f88c7b 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -3995,16 +3995,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; } @@ -4012,7 +4010,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 (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; @@ -4049,17 +4047,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 (pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_READRQ, 0x4 << 12)) { 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; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c index ddadcc3e4e7..5abbee37cdc 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; + 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); diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 28e7c7cce89..452278efef2 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -4236,7 +4236,7 @@ static void serial8250_io_resume(struct pci_dev *dev) pciserial_resume_ports(priv); } -static struct pci_error_handlers serial8250_err_handler = { +static const struct pci_error_handlers serial8250_err_handler = { .error_detected = serial8250_io_error_detected, .slot_reset = serial8250_io_slot_reset, .resume = serial8250_io_resume, diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 7545fe1b992..5ab3c3b595e 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -54,7 +54,7 @@ static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev, static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev); static void jsm_io_resume(struct pci_dev *pdev); -static struct pci_error_handlers jsm_err_handler = { +static const struct pci_error_handlers jsm_err_handler = { .error_detected = jsm_io_error_detected, .slot_reset = jsm_io_slot_reset, .resume = jsm_io_resume, diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 03342728bf2..92ff01dbeb1 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -871,7 +871,7 @@ end: } /*add xen_pcibk AER handling*/ -static struct pci_error_handlers xen_pcibk_error_handler = { +static const struct pci_error_handlers xen_pcibk_error_handler = { .error_detected = xen_pcibk_error_detected, .mmio_enabled = xen_pcibk_mmio_enabled, .slot_reset = xen_pcibk_slot_reset, |