PCI changes for the 3.7 merge window:
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) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iQIcBAABAgAGBQJQac4hAAoJEPGMOI97Hn6zjZYP/iaqU9kjmgTsBbSyzB4oApv/ RRxo3I+ad9GF6XlMQfVAtyx1pgCD1gdGAtoDgGSCTqgdYD3CO10AxKU+yleAk1wo dbMxLifJNTrT3G1mZ/NL16yEGhCwvhfwzRtB1VoZmCT4lSApO/7cJkXl2DzHfA/i pmltOOiQCN8kbUcJbVPtUyTVPi2zl/8bsyCyTkS7YG0VXeGRM+ZUvPWZJ7MnWYYB 5qoCdrw5ENCCiDQ9yw5SAfgL23b+0p6OI/x3Lkex0QQOWwSqGSiaHt4b7eitrC5b 2eAJg32f/AzZke1YbKLMfdsL0VJP3GAswhDVHlgmo63rZkOZChm+97dgZ35Mcv5v kEXkWyBb1xJ3t8rZir6Qer9Iv2wOB+MkZ5qtU/Vf+l0wLQLYTrRVsKngrEDREONk dXbokp6iVSPeA1sTSdH9MmHlTUIj82ZLSGcxcjTsN8NWZjxx6g3rNx1uay+5MYOW 4ET9zNu5snrAqN6N4Tb81gvtG8qYfxzdvVfrA9AaGKI6xxB7jkqgFJRp55JiEcFc x4cmWkhvdlhVsG2TQwFxYNfswOqD+7NCs6V4kSVZX6ezpDrH7I5VvcnnhstF7C8l KZul0EV7OW+kDK23pNe24lVP2xtOv6G8eK/3PmeKIXWl1V83nqre/oLufRzTfs+Z SxkILwY/MFpuCFteKE1t =haBu -----END PGP SIGNATURE----- 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() ...
This commit is contained in:
commit
fdb2f9c2eb
|
@ -253,38 +253,6 @@ Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com>
|
|||
|
||||
-----------------------------
|
||||
|
||||
What: fakephp and associated sysfs files in /sys/bus/pci/slots/
|
||||
When: 2011
|
||||
Why: In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to
|
||||
represent a machine's physical PCI slots. The change in semantics
|
||||
had userspace implications, as the hotplug core no longer allowed
|
||||
drivers to create multiple sysfs files per physical slot (required
|
||||
for multi-function devices, e.g.). fakephp was seen as a developer's
|
||||
tool only, and its interface changed. Too late, we learned that
|
||||
there were some users of the fakephp interface.
|
||||
|
||||
In 2.6.30, the original fakephp interface was restored. At the same
|
||||
time, the PCI core gained the ability that fakephp provided, namely
|
||||
function-level hot-remove and hot-add.
|
||||
|
||||
Since the PCI core now provides the same functionality, exposed in:
|
||||
|
||||
/sys/bus/pci/rescan
|
||||
/sys/bus/pci/devices/.../remove
|
||||
/sys/bus/pci/devices/.../rescan
|
||||
|
||||
there is no functional reason to maintain fakephp as well.
|
||||
|
||||
We will keep the existing module so that 'modprobe fakephp' will
|
||||
present the old /sys/bus/pci/slots/... interface for compatibility,
|
||||
but users are urged to migrate their applications to the API above.
|
||||
|
||||
After a reasonable transition period, we will remove the legacy
|
||||
fakephp interface.
|
||||
Who: Alex Chiang <achiang@hp.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: CONFIG_RFKILL_INPUT
|
||||
When: 2.6.33
|
||||
Why: Should be implemented in userspace, policy daemon.
|
||||
|
|
|
@ -256,12 +256,6 @@ pcibios_fixup_bus(struct pci_bus *bus)
|
|||
}
|
||||
}
|
||||
|
||||
void __init
|
||||
pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
int
|
||||
pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
{
|
||||
|
|
|
@ -270,15 +270,6 @@ static void __devinit pci_fixup_it8152(struct pci_dev *dev)
|
|||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8152, pci_fixup_it8152);
|
||||
|
||||
|
||||
|
||||
void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
if (debug_pci)
|
||||
printk("PCI: Assigning IRQ %02d to %s\n", irq, pci_name(dev));
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the bus contains any of these devices, then we must not turn on
|
||||
* parity checking of any kind. Currently this is CyberPro 20x0 only.
|
||||
|
|
|
@ -367,17 +367,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class);
|
|||
/* Tegra PCIE requires relaxed ordering */
|
||||
static void __devinit tegra_pcie_relax_enable(struct pci_dev *dev)
|
||||
{
|
||||
u16 val16;
|
||||
int pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
|
||||
|
||||
if (pos <= 0) {
|
||||
dev_err(&dev->dev, "skipping relaxed ordering fixup\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &val16);
|
||||
val16 |= PCI_EXP_DEVCTL_RELAX_EN;
|
||||
pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, val16);
|
||||
pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
|
||||
|
||||
|
|
|
@ -330,10 +330,8 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
|
|||
pci_read_bridge_bases(bus);
|
||||
|
||||
if (bus->number == 0) {
|
||||
struct list_head *ln;
|
||||
struct pci_dev *dev;
|
||||
for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
|
||||
dev = pci_dev_b(ln);
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
if (dev->devfn == 0) {
|
||||
dev->resource[0].start = 0;
|
||||
dev->resource[0].end = 0;
|
||||
|
|
|
@ -295,7 +295,6 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
|
|||
window->resource.flags = flags;
|
||||
window->resource.start = addr.minimum + offset;
|
||||
window->resource.end = window->resource.start + addr.address_length - 1;
|
||||
window->resource.child = NULL;
|
||||
window->offset = offset;
|
||||
|
||||
if (insert_resource(root, &window->resource)) {
|
||||
|
@ -357,7 +356,7 @@ pci_acpi_scan_root(struct acpi_pci_root *root)
|
|||
&windows);
|
||||
if (windows) {
|
||||
controller->window =
|
||||
kmalloc_node(sizeof(*controller->window) * windows,
|
||||
kzalloc_node(sizeof(*controller->window) * windows,
|
||||
GFP_KERNEL, controller->node);
|
||||
if (!controller->window)
|
||||
goto out2;
|
||||
|
@ -461,14 +460,6 @@ void pcibios_set_master (struct pci_dev *dev)
|
|||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
void __devinit
|
||||
pcibios_update_irq (struct pci_dev *dev, int irq)
|
||||
{
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
|
||||
/* ??? FIXME -- record old value for shutdown. */
|
||||
}
|
||||
|
||||
int
|
||||
pcibios_enable_device (struct pci_dev *dev, int mask)
|
||||
{
|
||||
|
|
|
@ -229,7 +229,6 @@ void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *pcidev_info,
|
|||
{
|
||||
int segment = pci_domain_nr(dev->bus);
|
||||
struct pcibus_bussoft *bs;
|
||||
struct pci_bus *host_pci_bus;
|
||||
struct pci_dev *host_pci_dev;
|
||||
unsigned int bus_no, devfn;
|
||||
|
||||
|
@ -245,8 +244,7 @@ void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *pcidev_info,
|
|||
|
||||
bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff;
|
||||
devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff;
|
||||
host_pci_bus = pci_find_bus(segment, bus_no);
|
||||
host_pci_dev = pci_get_slot(host_pci_bus, devfn);
|
||||
host_pci_dev = pci_get_domain_bus_and_slot(segment, bus_no, devfn);
|
||||
|
||||
pcidev_info->host_pci_dev = host_pci_dev;
|
||||
pcidev_info->pdi_linux_pcidev = dev;
|
||||
|
|
|
@ -87,11 +87,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
|
|
|
@ -117,16 +117,11 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
|
|||
}
|
||||
|
||||
/* Enable the PCIe normal error reporting */
|
||||
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
|
||||
if (pos) {
|
||||
/* Update Device Control */
|
||||
pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
|
||||
config |= PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */
|
||||
config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */
|
||||
config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */
|
||||
config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */
|
||||
pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
|
||||
}
|
||||
config = PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */
|
||||
config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */
|
||||
config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */
|
||||
config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */
|
||||
pcie_capability_set_word(dev, PCI_EXP_DEVCTL, config);
|
||||
|
||||
/* Find the Advanced Error Reporting capability */
|
||||
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
|
||||
|
|
|
@ -313,12 +313,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
|||
}
|
||||
}
|
||||
|
||||
void __init
|
||||
pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
EXPORT_SYMBOL(PCIBIOS_MIN_IO);
|
||||
EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
|
||||
|
|
|
@ -214,6 +214,9 @@ struct machdep_calls {
|
|||
/* Called after scan and before resource survey */
|
||||
void (*pcibios_fixup_phb)(struct pci_controller *hose);
|
||||
|
||||
/* Called during PCI resource reassignment */
|
||||
resource_size_t (*pcibios_window_alignment)(struct pci_bus *, unsigned long type);
|
||||
|
||||
/* Called to shutdown machine specific hardware not already controlled
|
||||
* by other drivers.
|
||||
*/
|
||||
|
|
|
@ -99,6 +99,26 @@ void pcibios_free_controller(struct pci_controller *phb)
|
|||
kfree(phb);
|
||||
}
|
||||
|
||||
/*
|
||||
* The function is used to return the minimal alignment
|
||||
* for memory or I/O windows of the associated P2P bridge.
|
||||
* By default, 4KiB alignment for I/O windows and 1MiB for
|
||||
* memory windows.
|
||||
*/
|
||||
resource_size_t pcibios_window_alignment(struct pci_bus *bus,
|
||||
unsigned long type)
|
||||
{
|
||||
if (ppc_md.pcibios_window_alignment)
|
||||
return ppc_md.pcibios_window_alignment(bus, type);
|
||||
|
||||
/*
|
||||
* PCI core will figure out the default
|
||||
* alignment: 4KiB for I/O and 1MiB for
|
||||
* memory window.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
static resource_size_t pcibios_io_size(const struct pci_controller *hose)
|
||||
{
|
||||
#ifdef CONFIG_PPC64
|
||||
|
|
|
@ -855,7 +855,7 @@ static void __devinit pnv_ioda_setup_PEs(struct pci_bus *bus)
|
|||
if (pe == NULL)
|
||||
continue;
|
||||
/* Leaving the PCIe domain ... single PE# */
|
||||
if (dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
|
||||
if (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE)
|
||||
pnv_ioda_setup_bus_PE(dev, pe);
|
||||
else if (dev->subordinate)
|
||||
pnv_ioda_setup_PEs(dev->subordinate);
|
||||
|
@ -1139,6 +1139,44 @@ static void __devinit pnv_pci_ioda_fixup_phb(struct pci_controller *hose)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the alignment for I/O or memory windows for P2P
|
||||
* bridges. That actually depends on how PEs are segmented.
|
||||
* For now, we return I/O or M32 segment size for PE sensitive
|
||||
* P2P bridges. Otherwise, the default values (4KiB for I/O,
|
||||
* 1MiB for memory) will be returned.
|
||||
*
|
||||
* The current PCI bus might be put into one PE, which was
|
||||
* create against the parent PCI bridge. For that case, we
|
||||
* needn't enlarge the alignment so that we can save some
|
||||
* resources.
|
||||
*/
|
||||
static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
|
||||
unsigned long type)
|
||||
{
|
||||
struct pci_dev *bridge;
|
||||
struct pci_controller *hose = pci_bus_to_host(bus);
|
||||
struct pnv_phb *phb = hose->private_data;
|
||||
int num_pci_bridges = 0;
|
||||
|
||||
bridge = bus->self;
|
||||
while (bridge) {
|
||||
if (pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE) {
|
||||
num_pci_bridges++;
|
||||
if (num_pci_bridges >= 2)
|
||||
return 1;
|
||||
}
|
||||
|
||||
bridge = bridge->bus->self;
|
||||
}
|
||||
|
||||
/* We need support prefetchable memory window later */
|
||||
if (type & IORESOURCE_MEM)
|
||||
return phb->ioda.m32_segsize;
|
||||
|
||||
return phb->ioda.io_segsize;
|
||||
}
|
||||
|
||||
/* Prevent enabling devices for which we couldn't properly
|
||||
* assign a PE
|
||||
*/
|
||||
|
@ -1306,6 +1344,7 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
|
|||
*/
|
||||
ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb;
|
||||
ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook;
|
||||
ppc_md.pcibios_window_alignment = pnv_pci_window_alignment;
|
||||
pci_add_flags(PCI_PROBE_ONLY | PCI_REASSIGN_ALL_RSRC);
|
||||
|
||||
/* Reset IODA tables to a clean state */
|
||||
|
|
|
@ -192,11 +192,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
|||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
void __init pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
static void __init
|
||||
pcibios_bus_report_status_early(struct pci_channel *hose,
|
||||
int top_bus, int current_bus,
|
||||
|
|
|
@ -102,15 +102,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
|||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
#ifdef CONFIG_PCI_DEBUG
|
||||
printk(KERN_DEBUG "LEONPCI: Assigning IRQ %02d to %s\n", irq,
|
||||
pci_name(dev));
|
||||
#endif
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
/* in/out routines taken from pcic.c
|
||||
*
|
||||
* This probably belongs here rather than ioport.c because
|
||||
|
|
|
@ -622,10 +622,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
|
|||
{
|
||||
}
|
||||
|
||||
void pcibios_update_irq(struct pci_dev *pdev, int irq)
|
||||
{
|
||||
}
|
||||
|
||||
resource_size_t pcibios_align_resource(void *data, const struct resource *res,
|
||||
resource_size_t size, resource_size_t align)
|
||||
{
|
||||
|
|
|
@ -246,16 +246,13 @@ static void __devinit fixup_read_and_payload_sizes(void)
|
|||
|
||||
/* Scan for the smallest maximum payload size. */
|
||||
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
|
||||
int pcie_caps_offset;
|
||||
u32 devcap;
|
||||
int max_payload;
|
||||
|
||||
pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP);
|
||||
if (pcie_caps_offset == 0)
|
||||
if (!pci_is_pcie(dev))
|
||||
continue;
|
||||
|
||||
pci_read_config_dword(dev, pcie_caps_offset + PCI_EXP_DEVCAP,
|
||||
&devcap);
|
||||
pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &devcap);
|
||||
max_payload = devcap & PCI_EXP_DEVCAP_PAYLOAD;
|
||||
if (max_payload < smallest_max_payload)
|
||||
smallest_max_payload = max_payload;
|
||||
|
@ -263,21 +260,10 @@ static void __devinit fixup_read_and_payload_sizes(void)
|
|||
|
||||
/* Now, set the max_payload_size for all devices to that value. */
|
||||
new_values = (max_read_size << 12) | (smallest_max_payload << 5);
|
||||
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
|
||||
int pcie_caps_offset;
|
||||
u16 devctl;
|
||||
|
||||
pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP);
|
||||
if (pcie_caps_offset == 0)
|
||||
continue;
|
||||
|
||||
pci_read_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL,
|
||||
&devctl);
|
||||
devctl &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
|
||||
devctl |= new_values;
|
||||
pci_write_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL,
|
||||
devctl);
|
||||
}
|
||||
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
|
||||
pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
|
||||
PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ,
|
||||
new_values);
|
||||
}
|
||||
|
||||
|
||||
|
@ -403,14 +389,6 @@ void pcibios_set_master(struct pci_dev *dev)
|
|||
/* No special bus mastering setup handling. */
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called from the generic Linux layer.
|
||||
*/
|
||||
void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable memory and/or address decoding, as appropriate, for the
|
||||
* device described by the 'dev' struct.
|
||||
|
|
|
@ -1033,14 +1033,6 @@ char __devinit *pcibios_setup(char *str)
|
|||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called from the generic Linux layer.
|
||||
*/
|
||||
void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable memory address decoding, as appropriate, for the
|
||||
* device described by the 'dev' struct. The I/O decoding
|
||||
|
|
|
@ -154,14 +154,6 @@ void __init puv3_pci_adjust_zones(unsigned long *zone_size,
|
|||
zhole_size[0] = 0;
|
||||
}
|
||||
|
||||
void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
if (debug_pci)
|
||||
printk(KERN_DEBUG "PCI: Assigning IRQ %02d to %s\n",
|
||||
irq, pci_name(dev));
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the bus contains any of these devices, then we must not turn on
|
||||
* parity checking of any kind.
|
||||
|
|
|
@ -305,7 +305,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
|
|||
res->flags = flags;
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
res->child = NULL;
|
||||
|
||||
if (!pci_use_crs) {
|
||||
dev_printk(KERN_DEBUG, &info->bridge->dev,
|
||||
|
@ -434,7 +433,7 @@ probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
|
|||
|
||||
size = sizeof(*info->res) * info->res_num;
|
||||
info->res_num = 0;
|
||||
info->res = kmalloc(size, GFP_KERNEL);
|
||||
info->res = kzalloc(size, GFP_KERNEL);
|
||||
if (!info->res)
|
||||
return;
|
||||
|
||||
|
|
|
@ -62,11 +62,6 @@ out:
|
|||
return irq;
|
||||
}
|
||||
|
||||
void __init pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
int __init pci_visws_init(void)
|
||||
{
|
||||
pcibios_enable_irq = &pci_visws_enable_irq;
|
||||
|
|
|
@ -210,14 +210,6 @@ void pcibios_set_master(struct pci_dev *dev)
|
|||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
/* the next one is stolen from the alpha port... */
|
||||
|
||||
void __init
|
||||
pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
int pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
{
|
||||
u16 cmd, old_cmd;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, state);
|
||||
|
||||
if (!pdev->bus->self)
|
||||
return;
|
||||
|
||||
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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#
|
||||
config ARCH_SUPPORTS_MSI
|
||||
bool
|
||||
default n
|
||||
|
||||
config PCI_MSI
|
||||
bool "Message Signaled Interrupts (MSI and MSI-X)"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -254,36 +254,56 @@ 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
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
* 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. Some capabilities can occur several times, e.g., the
|
||||
* vendor-specific capability, and this provides a way to find them all.
|
||||
*/
|
||||
static int pci_pcie_cap2(struct pci_dev *dev)
|
||||
int pci_find_next_ext_capability(struct pci_dev *dev, int start, int cap)
|
||||
{
|
||||
u16 flags;
|
||||
int pos;
|
||||
u32 header;
|
||||
int ttl;
|
||||
int pos = PCI_CFG_SPACE_SIZE;
|
||||
|
||||
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;
|
||||
/* minimum 8 bytes per capability */
|
||||
ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* If we have no capabilities, this is indicated by cap ID,
|
||||
* cap version and next pointer all being 0.
|
||||
*/
|
||||
if (header == 0)
|
||||
return 0;
|
||||
|
||||
while (ttl-- > 0) {
|
||||
if (PCI_EXT_CAP_ID(header) == cap && pos != start)
|
||||
return pos;
|
||||
|
||||
pos = PCI_EXT_CAP_NEXT(header);
|
||||
if (pos < PCI_CFG_SPACE_SIZE)
|
||||
break;
|
||||
|
||||
if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
|
||||
break;
|
||||
}
|
||||
|
||||
return pos;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_find_next_ext_capability);
|
||||
|
||||
/**
|
||||
* pci_find_ext_capability - Find an extended capability
|
||||
|
@ -301,39 +321,7 @@ static int pci_pcie_cap2(struct pci_dev *dev)
|
|||
*/
|
||||
int pci_find_ext_capability(struct pci_dev *dev, int cap)
|
||||
{
|
||||
u32 header;
|
||||
int ttl;
|
||||
int pos = PCI_CFG_SPACE_SIZE;
|
||||
|
||||
/* minimum 8 bytes per capability */
|
||||
ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
|
||||
|
||||
if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
|
||||
return 0;
|
||||
|
||||
if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If we have no capabilities, this is indicated by cap ID,
|
||||
* cap version and next pointer all being 0.
|
||||
*/
|
||||
if (header == 0)
|
||||
return 0;
|
||||
|
||||
while (ttl-- > 0) {
|
||||
if (PCI_EXT_CAP_ID(header) == cap)
|
||||
return pos;
|
||||
|
||||
pos = PCI_EXT_CAP_NEXT(header);
|
||||
if (pos < PCI_CFG_SPACE_SIZE)
|
||||
break;
|
||||
|
||||
if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return pci_find_next_ext_capability(dev, 0, cap);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_find_ext_capability);
|
||||
|
||||
|
@ -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];
|
||||
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_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;
|
||||
|
||||
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)
|
||||
if (!save_state)
|
||||
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)
|
||||
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++]);
|
||||
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;
|
||||
u16 status;
|
||||
|
||||
pos = pci_pcie_cap(dev);
|
||||
if (!pos)
|
||||
return -ENOTTY;
|
||||
|
||||
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;
|
||||
pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl);
|
||||
|
||||
ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
|
||||
if (!ret)
|
||||
ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
|
||||
|
||||
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;
|
||||
return -EINVAL;
|
||||
|
||||
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 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;
|
||||
pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl);
|
||||
|
||||
ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
|
||||
if (!ret)
|
||||
ret = 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -32,53 +32,67 @@ 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)
|
||||
void pci_remove_bus(struct pci_bus *bus)
|
||||
{
|
||||
if (pci_dev_driver(dev))
|
||||
return -EBUSY;
|
||||
pci_destroy_dev(dev);
|
||||
return 0;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
void pci_remove_bus(struct pci_bus *pci_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);
|
||||
static void pci_stop_bus_device(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_bus *bus = dev->subordinate;
|
||||
struct pci_dev *child, *tmp;
|
||||
|
||||
/*
|
||||
* 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_stop_dev(dev);
|
||||
}
|
||||
|
||||
static void pci_remove_bus_device(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_bus *bus = dev->subordinate;
|
||||
struct pci_dev *child, *tmp;
|
||||
|
||||
if (bus) {
|
||||
list_for_each_entry_safe(child, tmp,
|
||||
&bus->devices, bus_list)
|
||||
pci_remove_bus_device(child);
|
||||
|
||||
pci_remove_bus(bus);
|
||||
dev->subordinate = NULL;
|
||||
}
|
||||
|
||||
pci_destroy_dev(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_stop_and_remove_bus_device - remove a PCI device and any children
|
||||
* @dev: the device to remove
|
||||
|
@ -91,93 +105,9 @@ static void __pci_remove_behind_bridge(struct pci_dev *dev);
|
|||
* device lists, remove the /proc entry, and notify userspace
|
||||
* (/sbin/hotplug).
|
||||
*/
|
||||
void __pci_remove_bus_device(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->subordinate) {
|
||||
struct pci_bus *b = dev->subordinate;
|
||||
|
||||
__pci_remove_behind_bridge(dev);
|
||||
pci_remove_bus(b);
|
||||
dev->subordinate = NULL;
|
||||
}
|
||||
|
||||
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_remove_bus_device(dev);
|
||||
}
|
||||
|
||||
static void __pci_remove_behind_bridge(struct pci_dev *dev)
|
||||
{
|
||||
struct list_head *l, *n;
|
||||
|
||||
if (dev->subordinate)
|
||||
list_for_each_safe(l, n, &dev->subordinate->devices)
|
||||
__pci_remove_bus_device(pci_dev_b(l));
|
||||
}
|
||||
|
||||
static void pci_stop_behind_bridge(struct pci_dev *dev)
|
||||
{
|
||||
struct list_head *l, *n;
|
||||
|
||||
if (dev->subordinate)
|
||||
list_for_each_safe(l, n, &dev->subordinate->devices)
|
||||
pci_stop_bus_device(pci_dev_b(l));
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_stop_and_remove_behind_bridge - stop and remove all devices behind
|
||||
* a PCI bridge
|
||||
* @dev: PCI bridge device
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
void pci_stop_bus_device(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->subordinate)
|
||||
pci_stop_bus_devices(dev->subordinate);
|
||||
|
||||
pci_stop_dev(dev);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(pci_stop_and_remove_bus_device);
|
||||
EXPORT_SYMBOL(pci_stop_and_remove_behind_bridge);
|
||||
EXPORT_SYMBOL_GPL(pci_stop_bus_device);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
struct pci_device_id id = {
|
||||
.vendor = vendor,
|
||||
.device = device,
|
||||
.subvendor = ss_vendor,
|
||||
.subdevice = ss_device,
|
||||
};
|
||||
|
||||
/*
|
||||
* 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;
|
||||
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;
|
||||
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,
|
||||
};
|
||||
|
||||
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;
|
||||
return pci_get_dev_by_id(&id, from);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue