mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
Merge tag 'pci-v3.14-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas:
"PCI changes for the v3.14 merge window:
Resource management
- Change pci_bus_region addresses to dma_addr_t (Bjorn Helgaas)
- Support 64-bit AGP BARs (Bjorn Helgaas, Yinghai Lu)
- Add pci_bus_address() to get bus address of a BAR (Bjorn Helgaas)
- Use pci_resource_start() for CPU address of AGP BARs (Bjorn Helgaas)
- Enforce bus address limits in resource allocation (Yinghai Lu)
- Allocate 64-bit BARs above 4G when possible (Yinghai Lu)
- Convert pcibios_resource_to_bus() to take pci_bus, not pci_dev (Yinghai Lu)
PCI device hotplug
- Major rescan/remove locking update (Rafael J. Wysocki)
- Make ioapic builtin only (not modular) (Yinghai Lu)
- Fix release/free issues (Yinghai Lu)
- Clean up pciehp (Bjorn Helgaas)
- Announce pciehp slot info during enumeration (Bjorn Helgaas)
MSI
- Add pci_msi_vec_count(), pci_msix_vec_count() (Alexander Gordeev)
- Add pci_enable_msi_range(), pci_enable_msix_range() (Alexander Gordeev)
- Deprecate "tri-state" interfaces: fail/success/fail+info (Alexander Gordeev)
- Export MSI mode using attributes, not kobjects (Greg Kroah-Hartman)
- Drop "irq" param from *_restore_msi_irqs() (DuanZhenzhong)
SR-IOV
- Clear NumVFs when disabling SR-IOV in sriov_init() (ethan.zhao)
Virtualization
- Add support for save/restore of extended capabilities (Alex Williamson)
- Add Virtual Channel to save/restore support (Alex Williamson)
- Never treat a VF as a multifunction device (Alex Williamson)
- Add pci_try_reset_function(), et al (Alex Williamson)
AER
- Ignore non-PCIe error sources (Betty Dall)
- Support ACPI HEST error sources for domains other than 0 (Betty Dall)
- Consolidate HEST error source parsers (Bjorn Helgaas)
- Add a TLP header print helper (Borislav Petkov)
Freescale i.MX6
- Remove unnecessary code (Fabio Estevam)
- Make reset-gpio optional (Marek Vasut)
- Report "link up" only after link training completes (Marek Vasut)
- Start link in Gen1 before negotiating for Gen2 mode (Marek Vasut)
- Fix PCIe startup code (Richard Zhu)
Marvell MVEBU
- Remove duplicate of_clk_get_by_name() call (Andrew Lunn)
- Drop writes to bridge Secondary Status register (Jason Gunthorpe)
- Obey bridge PCI_COMMAND_MEM and PCI_COMMAND_IO bits (Jason Gunthorpe)
- Support a bridge with no IO port window (Jason Gunthorpe)
- Use max_t() instead of max(resource_size_t,) (Jingoo Han)
- Remove redundant of_match_ptr (Sachin Kamat)
- Call pci_ioremap_io() at startup instead of dynamically (Thomas Petazzoni)
NVIDIA Tegra
- Disable Gen2 for Tegra20 and Tegra30 (Eric Brower)
Renesas R-Car
- Add runtime PM support (Valentine Barshak)
- Fix rcar_pci_probe() return value check (Wei Yongjun)
Synopsys DesignWare
- Fix crash in dw_msi_teardown_irq() (Bjørn Erik Nilsen)
- Remove redundant call to pci_write_config_word() (Bjørn Erik Nilsen)
- Fix missing MSI IRQs (Harro Haan)
- Add dw_pcie prefix before cfg_read/write (Pratyush Anand)
- Fix I/O transfers by using CPU (not realio) address (Pratyush Anand)
- Whitespace cleanup (Jingoo Han)
EISA
- Call put_device() if device_register() fails (Levente Kurusa)
- Revert EISA initialization breakage ((Bjorn Helgaas)
Miscellaneous
- Remove unused code, including PCIe 3.0 interfaces (Stephen Hemminger)
- Prevent bus conflicts while checking for bridge apertures (Bjorn Helgaas)
- Stop clearing bridge Secondary Status when setting up I/O aperture (Bjorn Helgaas)
- Use dev_is_pci() to identify PCI devices (Yijing Wang)
- Deprecate DEFINE_PCI_DEVICE_TABLE (Joe Perches)
- Update documentation 00-INDEX (Erik Ekman)"
* tag 'pci-v3.14-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (119 commits)
Revert "EISA: Initialize device before its resources"
Revert "EISA: Log device resources in dmesg"
vfio-pci: Use pci "try" reset interface
PCI: Check parent kobject in pci_destroy_dev()
xen/pcifront: Use global PCI rescan-remove locking
powerpc/eeh: Use global PCI rescan-remove locking
PCI: Fix pci_check_and_unmask_intx() comment typos
PCI: Add pci_try_reset_function(), pci_try_reset_slot(), pci_try_reset_bus()
MPT / PCI: Use pci_stop_and_remove_bus_device_locked()
platform / x86: Use global PCI rescan-remove locking
PCI: hotplug: Use global PCI rescan-remove locking
pcmcia: Use global PCI rescan-remove locking
ACPI / hotplug / PCI: Use global PCI rescan-remove locking
ACPI / PCI: Use global PCI rescan-remove locking in PCI root hotplug
PCI: Add global pci_lock_rescan_remove()
PCI: Cleanup pci.h whitespace
PCI: Reorder so actual code comes before stubs
PCI/AER: Support ACPI HEST AER error sources for PCI domains other than 0
ACPICA: Add helper macros to extract bus/segment numbers from HEST table.
PCI: Make local functions static
...
This commit is contained in:
@@ -70,18 +70,15 @@ Date: September, 2011
|
||||
Contact: Neil Horman <nhorman@tuxdriver.com>
|
||||
Description:
|
||||
The /sys/devices/.../msi_irqs directory contains a variable set
|
||||
of sub-directories, with each sub-directory being named after a
|
||||
corresponding msi irq vector allocated to that device. Each
|
||||
numbered sub-directory N contains attributes of that irq.
|
||||
Note that this directory is not created for device drivers which
|
||||
do not support msi irqs
|
||||
of files, with each file being named after a corresponding msi
|
||||
irq vector allocated to that device.
|
||||
|
||||
What: /sys/bus/pci/devices/.../msi_irqs/<N>/mode
|
||||
What: /sys/bus/pci/devices/.../msi_irqs/<N>
|
||||
Date: September 2011
|
||||
Contact: Neil Horman <nhorman@tuxdriver.com>
|
||||
Description:
|
||||
This attribute indicates the mode that the irq vector named by
|
||||
the parent directory is in (msi vs. msix)
|
||||
the file is in (msi vs. msix)
|
||||
|
||||
What: /sys/bus/pci/devices/.../remove
|
||||
Date: January 2009
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
- this file
|
||||
MSI-HOWTO.txt
|
||||
- the Message Signaled Interrupts (MSI) Driver Guide HOWTO and FAQ.
|
||||
PCI-DMA-mapping.txt
|
||||
- info for PCI drivers using DMA portably across all platforms
|
||||
PCIEBUS-HOWTO.txt
|
||||
- a guide describing the PCI Express Port Bus driver
|
||||
pci-error-recovery.txt
|
||||
- info on PCI error recovery
|
||||
pci-iov-howto.txt
|
||||
- the PCI Express I/O Virtualization HOWTO
|
||||
pci.txt
|
||||
- info on the PCI subsystem for device driver authors
|
||||
pcieaer-howto.txt
|
||||
|
||||
@@ -82,93 +82,111 @@ Most of the hard work is done for the driver in the PCI layer. It simply
|
||||
has to request that the PCI layer set up the MSI capability for this
|
||||
device.
|
||||
|
||||
4.2.1 pci_enable_msi
|
||||
4.2.1 pci_enable_msi_range
|
||||
|
||||
int pci_enable_msi(struct pci_dev *dev)
|
||||
int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
|
||||
|
||||
A successful call allocates ONE interrupt to the device, regardless
|
||||
of how many MSIs the device supports. The device is switched from
|
||||
pin-based interrupt mode to MSI mode. The dev->irq number is changed
|
||||
to a new number which represents the message signaled interrupt;
|
||||
consequently, this function should be called before the driver calls
|
||||
request_irq(), because an MSI is delivered via a vector that is
|
||||
different from the vector of a pin-based interrupt.
|
||||
This function allows a device driver to request any number of MSI
|
||||
interrupts within specified range from 'minvec' to 'maxvec'.
|
||||
|
||||
4.2.2 pci_enable_msi_block
|
||||
|
||||
int pci_enable_msi_block(struct pci_dev *dev, int count)
|
||||
|
||||
This variation on the above call allows a device driver to request multiple
|
||||
MSIs. The MSI specification only allows interrupts to be allocated in
|
||||
powers of two, up to a maximum of 2^5 (32).
|
||||
|
||||
If this function returns 0, it has succeeded in allocating at least as many
|
||||
interrupts as the driver requested (it may have allocated more in order
|
||||
to satisfy the power-of-two requirement). In this case, the function
|
||||
enables MSI on this device and updates dev->irq to be the lowest of
|
||||
the new interrupts assigned to it. The other interrupts assigned to
|
||||
the device are in the range dev->irq to dev->irq + count - 1.
|
||||
|
||||
If this function returns a negative number, it indicates an error and
|
||||
the driver should not attempt to request any more MSI interrupts for
|
||||
this device. If this function returns a positive number, it is
|
||||
less than 'count' and indicates the number of interrupts that could have
|
||||
been allocated. In neither case is the irq value updated or the device
|
||||
switched into MSI mode.
|
||||
|
||||
The device driver must decide what action to take if
|
||||
pci_enable_msi_block() returns a value less than the number requested.
|
||||
For instance, the driver could still make use of fewer interrupts;
|
||||
in this case the driver should call pci_enable_msi_block()
|
||||
again. Note that it is not guaranteed to succeed, even when the
|
||||
'count' has been reduced to the value returned from a previous call to
|
||||
pci_enable_msi_block(). This is because there are multiple constraints
|
||||
on the number of vectors that can be allocated; pci_enable_msi_block()
|
||||
returns as soon as it finds any constraint that doesn't allow the
|
||||
call to succeed.
|
||||
|
||||
4.2.3 pci_enable_msi_block_auto
|
||||
|
||||
int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *count)
|
||||
|
||||
This variation on pci_enable_msi() call allows a device driver to request
|
||||
the maximum possible number of MSIs. The MSI specification only allows
|
||||
interrupts to be allocated in powers of two, up to a maximum of 2^5 (32).
|
||||
|
||||
If this function returns a positive number, it indicates that it has
|
||||
succeeded and the returned value is the number of allocated interrupts. In
|
||||
this case, the function enables MSI on this device and updates dev->irq to
|
||||
be the lowest of the new interrupts assigned to it. The other interrupts
|
||||
assigned to the device are in the range dev->irq to dev->irq + returned
|
||||
value - 1.
|
||||
If this function returns a positive number it indicates the number of
|
||||
MSI interrupts that have been successfully allocated. In this case
|
||||
the device is switched from pin-based interrupt mode to MSI mode and
|
||||
updates dev->irq to be the lowest of the new interrupts assigned to it.
|
||||
The other interrupts assigned to the device are in the range dev->irq
|
||||
to dev->irq + returned value - 1. Device driver can use the returned
|
||||
number of successfully allocated MSI interrupts to further allocate
|
||||
and initialize device resources.
|
||||
|
||||
If this function returns a negative number, it indicates an error and
|
||||
the driver should not attempt to request any more MSI interrupts for
|
||||
this device.
|
||||
|
||||
If the device driver needs to know the number of interrupts the device
|
||||
supports it can pass the pointer count where that number is stored. The
|
||||
device driver must decide what action to take if pci_enable_msi_block_auto()
|
||||
succeeds, but returns a value less than the number of interrupts supported.
|
||||
If the device driver does not need to know the number of interrupts
|
||||
supported, it can set the pointer count to NULL.
|
||||
This function should be called before the driver calls request_irq(),
|
||||
because MSI interrupts are delivered via vectors that are different
|
||||
from the vector of a pin-based interrupt.
|
||||
|
||||
4.2.4 pci_disable_msi
|
||||
It is ideal if drivers can cope with a variable number of MSI interrupts;
|
||||
there are many reasons why the platform may not be able to provide the
|
||||
exact number that a driver asks for.
|
||||
|
||||
There could be devices that can not operate with just any number of MSI
|
||||
interrupts within a range. See chapter 4.3.1.3 to get the idea how to
|
||||
handle such devices for MSI-X - the same logic applies to MSI.
|
||||
|
||||
4.2.1.1 Maximum possible number of MSI interrupts
|
||||
|
||||
The typical usage of MSI interrupts is to allocate as many vectors as
|
||||
possible, likely up to the limit returned by pci_msi_vec_count() function:
|
||||
|
||||
static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec)
|
||||
{
|
||||
return pci_enable_msi_range(pdev, 1, nvec);
|
||||
}
|
||||
|
||||
Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive,
|
||||
the value of 0 would be meaningless and could result in error.
|
||||
|
||||
Some devices have a minimal limit on number of MSI interrupts.
|
||||
In this case the function could look like this:
|
||||
|
||||
static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec)
|
||||
{
|
||||
return pci_enable_msi_range(pdev, FOO_DRIVER_MINIMUM_NVEC, nvec);
|
||||
}
|
||||
|
||||
4.2.1.2 Exact number of MSI interrupts
|
||||
|
||||
If a driver is unable or unwilling to deal with a variable number of MSI
|
||||
interrupts it could request a particular number of interrupts by passing
|
||||
that number to pci_enable_msi_range() function as both 'minvec' and 'maxvec'
|
||||
parameters:
|
||||
|
||||
static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec)
|
||||
{
|
||||
return pci_enable_msi_range(pdev, nvec, nvec);
|
||||
}
|
||||
|
||||
4.2.1.3 Single MSI mode
|
||||
|
||||
The most notorious example of the request type described above is
|
||||
enabling the single MSI mode for a device. It could be done by passing
|
||||
two 1s as 'minvec' and 'maxvec':
|
||||
|
||||
static int foo_driver_enable_single_msi(struct pci_dev *pdev)
|
||||
{
|
||||
return pci_enable_msi_range(pdev, 1, 1);
|
||||
}
|
||||
|
||||
4.2.2 pci_disable_msi
|
||||
|
||||
void pci_disable_msi(struct pci_dev *dev)
|
||||
|
||||
This function should be used to undo the effect of pci_enable_msi() or
|
||||
pci_enable_msi_block() or pci_enable_msi_block_auto(). Calling it restores
|
||||
dev->irq to the pin-based interrupt number and frees the previously
|
||||
allocated message signaled interrupt(s). The interrupt may subsequently be
|
||||
assigned to another device, so drivers should not cache the value of
|
||||
dev->irq.
|
||||
This function should be used to undo the effect of pci_enable_msi_range().
|
||||
Calling it restores dev->irq to the pin-based interrupt number and frees
|
||||
the previously allocated MSIs. The interrupts may subsequently be assigned
|
||||
to another device, so drivers should not cache the value of dev->irq.
|
||||
|
||||
Before calling this function, a device driver must always call free_irq()
|
||||
on any interrupt for which it previously called request_irq().
|
||||
Failure to do so results in a BUG_ON(), leaving the device with
|
||||
MSI enabled and thus leaking its vector.
|
||||
|
||||
4.2.3 pci_msi_vec_count
|
||||
|
||||
int pci_msi_vec_count(struct pci_dev *dev)
|
||||
|
||||
This function could be used to retrieve the number of MSI vectors the
|
||||
device requested (via the Multiple Message Capable register). The MSI
|
||||
specification only allows the returned value to be a power of two,
|
||||
up to a maximum of 2^5 (32).
|
||||
|
||||
If this function returns a negative number, it indicates the device is
|
||||
not capable of sending MSIs.
|
||||
|
||||
If this function returns a positive number, it indicates the maximum
|
||||
number of MSI interrupt vectors that could be allocated.
|
||||
|
||||
4.3 Using MSI-X
|
||||
|
||||
The MSI-X capability is much more flexible than the MSI capability.
|
||||
@@ -188,26 +206,31 @@ in each element of the array to indicate for which entries the kernel
|
||||
should assign interrupts; it is invalid to fill in two entries with the
|
||||
same number.
|
||||
|
||||
4.3.1 pci_enable_msix
|
||||
4.3.1 pci_enable_msix_range
|
||||
|
||||
int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
|
||||
int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
|
||||
int minvec, int maxvec)
|
||||
|
||||
Calling this function asks the PCI subsystem to allocate 'nvec' MSIs.
|
||||
Calling this function asks the PCI subsystem to allocate any number of
|
||||
MSI-X interrupts within specified range from 'minvec' to 'maxvec'.
|
||||
The 'entries' argument is a pointer to an array of msix_entry structs
|
||||
which should be at least 'nvec' entries in size. On success, the
|
||||
device is switched into MSI-X mode and the function returns 0.
|
||||
The 'vector' member in each entry is populated with the interrupt number;
|
||||
which should be at least 'maxvec' entries in size.
|
||||
|
||||
On success, the device is switched into MSI-X mode and the function
|
||||
returns the number of MSI-X interrupts that have been successfully
|
||||
allocated. In this case the 'vector' member in entries numbered from
|
||||
0 to the returned value - 1 is populated with the interrupt number;
|
||||
the driver should then call request_irq() for each 'vector' that it
|
||||
decides to use. The device driver is responsible for keeping track of the
|
||||
interrupts assigned to the MSI-X vectors so it can free them again later.
|
||||
Device driver can use the returned number of successfully allocated MSI-X
|
||||
interrupts to further allocate and initialize device resources.
|
||||
|
||||
If this function returns a negative number, it indicates an error and
|
||||
the driver should not attempt to allocate any more MSI-X interrupts for
|
||||
this device. If it returns a positive number, it indicates the maximum
|
||||
number of interrupt vectors that could have been allocated. See example
|
||||
below.
|
||||
this device.
|
||||
|
||||
This function, in contrast with pci_enable_msi(), does not adjust
|
||||
This function, in contrast with pci_enable_msi_range(), does not adjust
|
||||
dev->irq. The device will not generate interrupts for this interrupt
|
||||
number once MSI-X is enabled.
|
||||
|
||||
@@ -218,28 +241,103 @@ It is ideal if drivers can cope with a variable number of MSI-X interrupts;
|
||||
there are many reasons why the platform may not be able to provide the
|
||||
exact number that a driver asks for.
|
||||
|
||||
A request loop to achieve that might look like:
|
||||
There could be devices that can not operate with just any number of MSI-X
|
||||
interrupts within a range. E.g., an network adapter might need let's say
|
||||
four vectors per each queue it provides. Therefore, a number of MSI-X
|
||||
interrupts allocated should be a multiple of four. In this case interface
|
||||
pci_enable_msix_range() can not be used alone to request MSI-X interrupts
|
||||
(since it can allocate any number within the range, without any notion of
|
||||
the multiple of four) and the device driver should master a custom logic
|
||||
to request the required number of MSI-X interrupts.
|
||||
|
||||
4.3.1.1 Maximum possible number of MSI-X interrupts
|
||||
|
||||
The typical usage of MSI-X interrupts is to allocate as many vectors as
|
||||
possible, likely up to the limit returned by pci_msix_vec_count() function:
|
||||
|
||||
static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec)
|
||||
{
|
||||
while (nvec >= FOO_DRIVER_MINIMUM_NVEC) {
|
||||
rc = pci_enable_msix(adapter->pdev,
|
||||
adapter->msix_entries, nvec);
|
||||
if (rc > 0)
|
||||
nvec = rc;
|
||||
else
|
||||
return rc;
|
||||
return pci_enable_msi_range(adapter->pdev, adapter->msix_entries,
|
||||
1, nvec);
|
||||
}
|
||||
|
||||
Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive,
|
||||
the value of 0 would be meaningless and could result in error.
|
||||
|
||||
Some devices have a minimal limit on number of MSI-X interrupts.
|
||||
In this case the function could look like this:
|
||||
|
||||
static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec)
|
||||
{
|
||||
return pci_enable_msi_range(adapter->pdev, adapter->msix_entries,
|
||||
FOO_DRIVER_MINIMUM_NVEC, nvec);
|
||||
}
|
||||
|
||||
4.3.1.2 Exact number of MSI-X interrupts
|
||||
|
||||
If a driver is unable or unwilling to deal with a variable number of MSI-X
|
||||
interrupts it could request a particular number of interrupts by passing
|
||||
that number to pci_enable_msix_range() function as both 'minvec' and 'maxvec'
|
||||
parameters:
|
||||
|
||||
static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec)
|
||||
{
|
||||
return pci_enable_msi_range(adapter->pdev, adapter->msix_entries,
|
||||
nvec, nvec);
|
||||
}
|
||||
|
||||
4.3.1.3 Specific requirements to the number of MSI-X interrupts
|
||||
|
||||
As noted above, there could be devices that can not operate with just any
|
||||
number of MSI-X interrupts within a range. E.g., let's assume a device that
|
||||
is only capable sending the number of MSI-X interrupts which is a power of
|
||||
two. A routine that enables MSI-X mode for such device might look like this:
|
||||
|
||||
/*
|
||||
* Assume 'minvec' and 'maxvec' are non-zero
|
||||
*/
|
||||
static int foo_driver_enable_msix(struct foo_adapter *adapter,
|
||||
int minvec, int maxvec)
|
||||
{
|
||||
int rc;
|
||||
|
||||
minvec = roundup_pow_of_two(minvec);
|
||||
maxvec = rounddown_pow_of_two(maxvec);
|
||||
|
||||
if (minvec > maxvec)
|
||||
return -ERANGE;
|
||||
|
||||
retry:
|
||||
rc = pci_enable_msix_range(adapter->pdev, adapter->msix_entries,
|
||||
maxvec, maxvec);
|
||||
/*
|
||||
* -ENOSPC is the only error code allowed to be analized
|
||||
*/
|
||||
if (rc == -ENOSPC) {
|
||||
if (maxvec == 1)
|
||||
return -ENOSPC;
|
||||
|
||||
maxvec /= 2;
|
||||
|
||||
if (minvec > maxvec)
|
||||
return -ENOSPC;
|
||||
|
||||
goto retry;
|
||||
}
|
||||
|
||||
return -ENOSPC;
|
||||
return rc;
|
||||
}
|
||||
|
||||
Note how pci_enable_msix_range() return value is analized for a fallback -
|
||||
any error code other than -ENOSPC indicates a fatal error and should not
|
||||
be retried.
|
||||
|
||||
4.3.2 pci_disable_msix
|
||||
|
||||
void pci_disable_msix(struct pci_dev *dev)
|
||||
|
||||
This function should be used to undo the effect of pci_enable_msix(). It frees
|
||||
the previously allocated message signaled interrupts. The interrupts may
|
||||
This function should be used to undo the effect of pci_enable_msix_range().
|
||||
It frees the previously allocated MSI-X interrupts. The interrupts may
|
||||
subsequently be assigned to another device, so drivers should not cache
|
||||
the value of the 'vector' elements over a call to pci_disable_msix().
|
||||
|
||||
@@ -255,18 +353,32 @@ MSI-X Table. This address is mapped by the PCI subsystem, and should not
|
||||
be accessed directly by the device driver. If the driver wishes to
|
||||
mask or unmask an interrupt, it should call disable_irq() / enable_irq().
|
||||
|
||||
4.3.4 pci_msix_vec_count
|
||||
|
||||
int pci_msix_vec_count(struct pci_dev *dev)
|
||||
|
||||
This function could be used to retrieve number of entries in the device
|
||||
MSI-X table.
|
||||
|
||||
If this function returns a negative number, it indicates the device is
|
||||
not capable of sending MSI-Xs.
|
||||
|
||||
If this function returns a positive number, it indicates the maximum
|
||||
number of MSI-X interrupt vectors that could be allocated.
|
||||
|
||||
4.4 Handling devices implementing both MSI and MSI-X capabilities
|
||||
|
||||
If a device implements both MSI and MSI-X capabilities, it can
|
||||
run in either MSI mode or MSI-X mode, but not both simultaneously.
|
||||
This is a requirement of the PCI spec, and it is enforced by the
|
||||
PCI layer. Calling pci_enable_msi() when MSI-X is already enabled or
|
||||
pci_enable_msix() when MSI is already enabled results in an error.
|
||||
If a device driver wishes to switch between MSI and MSI-X at runtime,
|
||||
it must first quiesce the device, then switch it back to pin-interrupt
|
||||
mode, before calling pci_enable_msi() or pci_enable_msix() and resuming
|
||||
operation. This is not expected to be a common operation but may be
|
||||
useful for debugging or testing during development.
|
||||
PCI layer. Calling pci_enable_msi_range() when MSI-X is already
|
||||
enabled or pci_enable_msix_range() when MSI is already enabled
|
||||
results in an error. If a device driver wishes to switch between MSI
|
||||
and MSI-X at runtime, it must first quiesce the device, then switch
|
||||
it back to pin-interrupt mode, before calling pci_enable_msi_range()
|
||||
or pci_enable_msix_range() and resuming operation. This is not expected
|
||||
to be a common operation but may be useful for debugging or testing
|
||||
during development.
|
||||
|
||||
4.5 Considerations when using MSIs
|
||||
|
||||
@@ -381,5 +493,5 @@ or disabled (0). If 0 is found in any of the msi_bus files belonging
|
||||
to bridges between the PCI root and the device, MSIs are disabled.
|
||||
|
||||
It is also worth checking the device driver to see whether it supports MSIs.
|
||||
For example, it may contain calls to pci_enable_msi(), pci_enable_msix() or
|
||||
pci_enable_msi_block().
|
||||
For example, it may contain calls to pci_enable_msi_range() or
|
||||
pci_enable_msix_range().
|
||||
|
||||
@@ -123,8 +123,10 @@ initialization with a pointer to a structure describing the driver
|
||||
|
||||
|
||||
The ID table is an array of struct pci_device_id entries ending with an
|
||||
all-zero entry; use of the macro DEFINE_PCI_DEVICE_TABLE is the preferred
|
||||
method of declaring the table. Each entry consists of:
|
||||
all-zero entry. Definitions with static const are generally preferred.
|
||||
Use of the deprecated macro DEFINE_PCI_DEVICE_TABLE should be avoided.
|
||||
|
||||
Each entry consists of:
|
||||
|
||||
vendor,device Vendor and device ID to match (or PCI_ANY_ID)
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ Required properties:
|
||||
to define the mapping of the PCIe interface to interrupt
|
||||
numbers.
|
||||
- num-lanes: number of lanes to use
|
||||
|
||||
Optional properties:
|
||||
- reset-gpio: gpio pin number of power good signal
|
||||
|
||||
Optional properties for fsl,imx6q-pcie
|
||||
|
||||
@@ -83,7 +83,7 @@ static int pci_mmap_resource(struct kobject *kobj,
|
||||
if (iomem_is_exclusive(res->start))
|
||||
return -EINVAL;
|
||||
|
||||
pcibios_resource_to_bus(pdev, &bar, res);
|
||||
pcibios_resource_to_bus(pdev->bus, &bar, res);
|
||||
vma->vm_pgoff += bar.start >> (PAGE_SHIFT - (sparse ? 5 : 0));
|
||||
mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
|
||||
|
||||
@@ -139,7 +139,7 @@ static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num)
|
||||
long dense_offset;
|
||||
unsigned long sparse_size;
|
||||
|
||||
pcibios_resource_to_bus(pdev, &bar, &pdev->resource[num]);
|
||||
pcibios_resource_to_bus(pdev->bus, &bar, &pdev->resource[num]);
|
||||
|
||||
/* All core logic chips have 4G sparse address space, except
|
||||
CIA which has 16G (see xxx_SPARSE_MEM and xxx_DENSE_MEM
|
||||
|
||||
@@ -325,7 +325,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
|
||||
/* Helper for generic DMA-mapping functions. */
|
||||
static struct pci_dev *alpha_gendev_to_pci(struct device *dev)
|
||||
{
|
||||
if (dev && dev->bus == &pci_bus_type)
|
||||
if (dev && dev_is_pci(dev))
|
||||
return to_pci_dev(dev);
|
||||
|
||||
/* Assume that non-PCI devices asking for DMA are either ISA or EISA,
|
||||
|
||||
@@ -257,7 +257,7 @@ static int it8152_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t s
|
||||
*/
|
||||
static int it8152_pci_platform_notify(struct device *dev)
|
||||
{
|
||||
if (dev->bus == &pci_bus_type) {
|
||||
if (dev_is_pci(dev)) {
|
||||
if (dev->dma_mask)
|
||||
*dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET;
|
||||
dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET;
|
||||
@@ -268,7 +268,7 @@ static int it8152_pci_platform_notify(struct device *dev)
|
||||
|
||||
static int it8152_pci_platform_notify_remove(struct device *dev)
|
||||
{
|
||||
if (dev->bus == &pci_bus_type)
|
||||
if (dev_is_pci(dev))
|
||||
dmabounce_unregister_dev(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -326,7 +326,7 @@ static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t s
|
||||
*/
|
||||
static int ixp4xx_pci_platform_notify(struct device *dev)
|
||||
{
|
||||
if(dev->bus == &pci_bus_type) {
|
||||
if (dev_is_pci(dev)) {
|
||||
*dev->dma_mask = SZ_64M - 1;
|
||||
dev->coherent_dma_mask = SZ_64M - 1;
|
||||
dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce);
|
||||
@@ -336,9 +336,9 @@ static int ixp4xx_pci_platform_notify(struct device *dev)
|
||||
|
||||
static int ixp4xx_pci_platform_notify_remove(struct device *dev)
|
||||
{
|
||||
if(dev->bus == &pci_bus_type) {
|
||||
if (dev_is_pci(dev))
|
||||
dmabounce_unregister_dev(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ static u64 prefetch_spill_page;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
# define GET_IOC(dev) (((dev)->bus == &pci_bus_type) \
|
||||
# define GET_IOC(dev) ((dev_is_pci(dev)) \
|
||||
? ((struct ioc *) PCI_CONTROLLER(to_pci_dev(dev))->iommu) : NULL)
|
||||
#else
|
||||
# define GET_IOC(dev) NULL
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
*/
|
||||
static int sn_dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
|
||||
if (mask < 0x7fffffff)
|
||||
return 0;
|
||||
@@ -50,7 +50,7 @@ static int sn_dma_supported(struct device *dev, u64 mask)
|
||||
*/
|
||||
int sn_dma_set_mask(struct device *dev, u64 dma_mask)
|
||||
{
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
|
||||
if (!sn_dma_supported(dev, dma_mask))
|
||||
return 0;
|
||||
@@ -85,7 +85,7 @@ static void *sn_dma_alloc_coherent(struct device *dev, size_t size,
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
|
||||
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
|
||||
/*
|
||||
* Allocate the memory.
|
||||
@@ -143,7 +143,7 @@ static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
|
||||
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
|
||||
provider->dma_unmap(pdev, dma_handle, 0);
|
||||
free_pages((unsigned long)cpu_addr, get_order(size));
|
||||
@@ -187,7 +187,7 @@ static dma_addr_t sn_dma_map_page(struct device *dev, struct page *page,
|
||||
|
||||
dmabarr = dma_get_attr(DMA_ATTR_WRITE_BARRIER, attrs);
|
||||
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
|
||||
phys_addr = __pa(cpu_addr);
|
||||
if (dmabarr)
|
||||
@@ -223,7 +223,7 @@ static void sn_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
|
||||
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
|
||||
provider->dma_unmap(pdev, dma_addr, dir);
|
||||
}
|
||||
@@ -247,7 +247,7 @@ static void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
|
||||
struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
|
||||
struct scatterlist *sg;
|
||||
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
|
||||
for_each_sg(sgl, sg, nhwentries, i) {
|
||||
provider->dma_unmap(pdev, sg->dma_address, dir);
|
||||
@@ -284,7 +284,7 @@ static int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl,
|
||||
|
||||
dmabarr = dma_get_attr(DMA_ATTR_WRITE_BARRIER, attrs);
|
||||
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
|
||||
/*
|
||||
* Setup a DMA address for each entry in the scatterlist.
|
||||
@@ -323,26 +323,26 @@ static int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl,
|
||||
static void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
|
||||
size_t size, enum dma_data_direction dir)
|
||||
{
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
}
|
||||
|
||||
static void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
|
||||
size_t size,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
}
|
||||
|
||||
static void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
|
||||
int nelems, enum dma_data_direction dir)
|
||||
{
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
}
|
||||
|
||||
static void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
|
||||
int nelems, enum dma_data_direction dir)
|
||||
{
|
||||
BUG_ON(dev->bus != &pci_bus_type);
|
||||
BUG_ON(!dev_is_pci(dev));
|
||||
}
|
||||
|
||||
static int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
|
||||
|
||||
@@ -282,18 +282,6 @@ find_pa_parent_type(const struct parisc_device *padev, int type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static inline int is_pci_dev(struct device *dev)
|
||||
{
|
||||
return dev->bus == &pci_bus_type;
|
||||
}
|
||||
#else
|
||||
static inline int is_pci_dev(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* get_node_path fills in @path with the firmware path to the device.
|
||||
* Note that if @node is a parisc device, we don't fill in the 'mod' field.
|
||||
@@ -306,7 +294,7 @@ static void get_node_path(struct device *dev, struct hardware_path *path)
|
||||
int i = 5;
|
||||
memset(&path->bc, -1, 6);
|
||||
|
||||
if (is_pci_dev(dev)) {
|
||||
if (dev_is_pci(dev)) {
|
||||
unsigned int devfn = to_pci_dev(dev)->devfn;
|
||||
path->mod = PCI_FUNC(devfn);
|
||||
path->bc[i--] = PCI_SLOT(devfn);
|
||||
@@ -314,7 +302,7 @@ static void get_node_path(struct device *dev, struct hardware_path *path)
|
||||
}
|
||||
|
||||
while (dev != &root) {
|
||||
if (is_pci_dev(dev)) {
|
||||
if (dev_is_pci(dev)) {
|
||||
unsigned int devfn = to_pci_dev(dev)->devfn;
|
||||
path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn)<< 5);
|
||||
} else if (dev->bus == &parisc_bus_type) {
|
||||
@@ -695,7 +683,7 @@ static int check_parent(struct device * dev, void * data)
|
||||
if (dev->bus == &parisc_bus_type) {
|
||||
if (match_parisc_device(dev, d->index, d->modpath))
|
||||
d->dev = dev;
|
||||
} else if (is_pci_dev(dev)) {
|
||||
} else if (dev_is_pci(dev)) {
|
||||
if (match_pci_device(dev, d->index, d->modpath))
|
||||
d->dev = dev;
|
||||
} else if (dev->bus == NULL) {
|
||||
@@ -753,7 +741,7 @@ struct device *hwpath_to_device(struct hardware_path *modpath)
|
||||
if (!parent)
|
||||
return NULL;
|
||||
}
|
||||
if (is_pci_dev(parent)) /* pci devices already parse MOD */
|
||||
if (dev_is_pci(parent)) /* pci devices already parse MOD */
|
||||
return parent;
|
||||
else
|
||||
return parse_tree_node(parent, 6, modpath);
|
||||
@@ -772,7 +760,7 @@ void device_to_hwpath(struct device *dev, struct hardware_path *path)
|
||||
padev = to_parisc_device(dev);
|
||||
get_node_path(dev->parent, path);
|
||||
path->mod = padev->hw_path;
|
||||
} else if (is_pci_dev(dev)) {
|
||||
} else if (dev_is_pci(dev)) {
|
||||
get_node_path(dev, path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,7 +369,9 @@ static void *eeh_rmv_device(void *data, void *userdata)
|
||||
edev->mode |= EEH_DEV_DISCONNECTED;
|
||||
(*removed)++;
|
||||
|
||||
pci_lock_rescan_remove();
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
pci_unlock_rescan_remove();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -416,10 +418,13 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
|
||||
* into pcibios_add_pci_devices().
|
||||
*/
|
||||
eeh_pe_state_mark(pe, EEH_PE_KEEP);
|
||||
if (bus)
|
||||
if (bus) {
|
||||
pci_lock_rescan_remove();
|
||||
pcibios_remove_pci_devices(bus);
|
||||
else if (frozen_bus)
|
||||
pci_unlock_rescan_remove();
|
||||
} else if (frozen_bus) {
|
||||
eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed);
|
||||
}
|
||||
|
||||
/* Reset the pci controller. (Asserts RST#; resets config space).
|
||||
* Reconfigure bridges and devices. Don't try to bring the system
|
||||
@@ -429,6 +434,8 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
pci_lock_rescan_remove();
|
||||
|
||||
/* Restore PE */
|
||||
eeh_ops->configure_bridge(pe);
|
||||
eeh_pe_restore_bars(pe);
|
||||
@@ -462,6 +469,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
|
||||
pe->tstamp = tstamp;
|
||||
pe->freeze_count = cnt;
|
||||
|
||||
pci_unlock_rescan_remove();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -618,8 +626,11 @@ perm_error:
|
||||
eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
|
||||
|
||||
/* Shut down the device drivers for good. */
|
||||
if (frozen_bus)
|
||||
if (frozen_bus) {
|
||||
pci_lock_rescan_remove();
|
||||
pcibios_remove_pci_devices(frozen_bus);
|
||||
pci_unlock_rescan_remove();
|
||||
}
|
||||
}
|
||||
|
||||
static void eeh_handle_special_event(void)
|
||||
@@ -692,6 +703,7 @@ static void eeh_handle_special_event(void)
|
||||
if (rc == 2 || rc == 1)
|
||||
eeh_handle_normal_event(pe);
|
||||
else {
|
||||
pci_lock_rescan_remove();
|
||||
list_for_each_entry_safe(hose, tmp,
|
||||
&hose_list, list_node) {
|
||||
phb_pe = eeh_phb_pe_get(hose);
|
||||
@@ -703,6 +715,7 @@ static void eeh_handle_special_event(void)
|
||||
eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
|
||||
pcibios_remove_pci_devices(bus);
|
||||
}
|
||||
pci_unlock_rescan_remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -835,7 +835,7 @@ static void pcibios_fixup_resources(struct pci_dev *dev)
|
||||
* at 0 as unset as well, except if PCI_PROBE_ONLY is also set
|
||||
* since in that case, we don't want to re-assign anything
|
||||
*/
|
||||
pcibios_resource_to_bus(dev, ®, res);
|
||||
pcibios_resource_to_bus(dev->bus, ®, res);
|
||||
if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) ||
|
||||
(reg.start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) {
|
||||
/* Only print message if not re-assigning */
|
||||
@@ -886,7 +886,7 @@ static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
|
||||
|
||||
/* Job is a bit different between memory and IO */
|
||||
if (res->flags & IORESOURCE_MEM) {
|
||||
pcibios_resource_to_bus(dev, ®ion, res);
|
||||
pcibios_resource_to_bus(dev->bus, ®ion, res);
|
||||
|
||||
/* If the BAR is non-0 then it's probably been initialized */
|
||||
if (region.start != 0)
|
||||
|
||||
@@ -111,7 +111,7 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
|
||||
res->name = pci_name(dev);
|
||||
region.start = base;
|
||||
region.end = base + size - 1;
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +280,7 @@ void of_scan_pci_bridge(struct pci_dev *dev)
|
||||
res->flags = flags;
|
||||
region.start = of_read_number(&ranges[1], 2);
|
||||
region.end = region.start + size - 1;
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
||||
}
|
||||
sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
|
||||
bus->number);
|
||||
|
||||
@@ -407,8 +407,8 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
|
||||
struct msi_msg msg;
|
||||
int rc;
|
||||
|
||||
if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI)
|
||||
return -EINVAL;
|
||||
if (type == PCI_CAP_ID_MSI && nvec > 1)
|
||||
return 1;
|
||||
msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX);
|
||||
msi_vecs = min_t(unsigned int, msi_vecs, CONFIG_PCI_NR_MSI);
|
||||
|
||||
|
||||
@@ -392,7 +392,7 @@ static void apb_fake_ranges(struct pci_dev *dev,
|
||||
res->flags = IORESOURCE_IO;
|
||||
region.start = (first << 21);
|
||||
region.end = (last << 21) + ((1 << 21) - 1);
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
||||
|
||||
pci_read_config_byte(dev, APB_MEM_ADDRESS_MAP, &map);
|
||||
apb_calc_first_last(map, &first, &last);
|
||||
@@ -400,7 +400,7 @@ static void apb_fake_ranges(struct pci_dev *dev,
|
||||
res->flags = IORESOURCE_MEM;
|
||||
region.start = (first << 29);
|
||||
region.end = (last << 29) + ((1 << 29) - 1);
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
||||
}
|
||||
|
||||
static void pci_of_scan_bus(struct pci_pbm_info *pbm,
|
||||
@@ -491,7 +491,7 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm,
|
||||
res->flags = flags;
|
||||
region.start = GET_64BIT(ranges, 1);
|
||||
region.end = region.start + size - 1;
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
||||
}
|
||||
after_ranges:
|
||||
sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
|
||||
|
||||
@@ -104,7 +104,7 @@ extern void pci_iommu_alloc(void);
|
||||
struct msi_desc;
|
||||
int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
|
||||
void native_teardown_msi_irq(unsigned int irq);
|
||||
void native_restore_msi_irqs(struct pci_dev *dev, int irq);
|
||||
void native_restore_msi_irqs(struct pci_dev *dev);
|
||||
int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
|
||||
unsigned int irq_base, unsigned int irq_offset);
|
||||
#else
|
||||
@@ -125,7 +125,6 @@ int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
|
||||
|
||||
/* generic pci stuff */
|
||||
#include <asm-generic/pci.h>
|
||||
#define PCIBIOS_MAX_MEM_32 0xffffffff
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
/* Returns the node based on pci bus */
|
||||
|
||||
@@ -181,7 +181,7 @@ struct x86_msi_ops {
|
||||
u8 hpet_id);
|
||||
void (*teardown_msi_irq)(unsigned int irq);
|
||||
void (*teardown_msi_irqs)(struct pci_dev *dev);
|
||||
void (*restore_msi_irqs)(struct pci_dev *dev, int irq);
|
||||
void (*restore_msi_irqs)(struct pci_dev *dev);
|
||||
int (*setup_hpet_msi)(unsigned int irq, unsigned int id);
|
||||
u32 (*msi_mask_irq)(struct msi_desc *desc, u32 mask, u32 flag);
|
||||
u32 (*msix_mask_irq)(struct msi_desc *desc, u32 flag);
|
||||
|
||||
@@ -1034,9 +1034,7 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,
|
||||
|
||||
if (!acpi_ioapic)
|
||||
return 0;
|
||||
if (!dev)
|
||||
return 0;
|
||||
if (dev->bus != &pci_bus_type)
|
||||
if (!dev || !dev_is_pci(dev))
|
||||
return 0;
|
||||
|
||||
pdev = to_pci_dev(dev);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user