Merge branch 'pci/host-vmd' into next
* pci/host-vmd: x86/PCI: VMD: Move VMD driver to drivers/pci/host x86/PCI: VMD: Synchronize with RCU freeing MSI IRQ descs x86/PCI: VMD: Eliminate index member from IRQ list x86/PCI: VMD: Eliminate vmd_vector member from list type x86/PCI: VMD: Convert to use pci_alloc_irq_vectors() API x86/PCI: VMD: Allocate IRQ lists with correct MSI-X count PCI: Use positive flags in pci_alloc_irq_vectors() PCI: Update "pci=resource_alignment" documentation Conflicts: drivers/pci/host/Kconfig drivers/pci/host/Makefile
This commit is contained in:
commit
bdf530984d
|
@ -94,14 +94,11 @@ has a requirements for a minimum number of vectors the driver can pass a
|
||||||
min_vecs argument set to this limit, and the PCI core will return -ENOSPC
|
min_vecs argument set to this limit, and the PCI core will return -ENOSPC
|
||||||
if it can't meet the minimum number of vectors.
|
if it can't meet the minimum number of vectors.
|
||||||
|
|
||||||
The flags argument should normally be set to 0, but can be used to pass the
|
The flags argument is used to specify which type of interrupt can be used
|
||||||
PCI_IRQ_NOMSI and PCI_IRQ_NOMSIX flag in case a device claims to support
|
by the device and the driver (PCI_IRQ_LEGACY, PCI_IRQ_MSI, PCI_IRQ_MSIX).
|
||||||
MSI or MSI-X, but the support is broken, or to pass PCI_IRQ_NOLEGACY in
|
A convenient short-hand (PCI_IRQ_ALL_TYPES) is also available to ask for
|
||||||
case the device does not support legacy interrupt lines.
|
any possible kind of interrupt. If the PCI_IRQ_AFFINITY flag is set,
|
||||||
|
pci_alloc_irq_vectors() will spread the interrupts around the available CPUs.
|
||||||
By default this function will spread the interrupts around the available
|
|
||||||
CPUs, but this feature can be disabled by passing the PCI_IRQ_NOAFFINITY
|
|
||||||
flag.
|
|
||||||
|
|
||||||
To get the Linux IRQ numbers passed to request_irq() and free_irq() and the
|
To get the Linux IRQ numbers passed to request_irq() and free_irq() and the
|
||||||
vectors, use the following function:
|
vectors, use the following function:
|
||||||
|
@ -131,7 +128,7 @@ larger than the number supported by the device it will automatically be
|
||||||
capped to the supported limit, so there is no need to query the number of
|
capped to the supported limit, so there is no need to query the number of
|
||||||
vectors supported beforehand:
|
vectors supported beforehand:
|
||||||
|
|
||||||
nvec = pci_alloc_irq_vectors(pdev, 1, nvec, 0);
|
nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_ALL_TYPES)
|
||||||
if (nvec < 0)
|
if (nvec < 0)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
|
@ -140,7 +137,7 @@ interrupts it can request a particular number of interrupts by passing that
|
||||||
number to pci_alloc_irq_vectors() function as both 'min_vecs' and
|
number to pci_alloc_irq_vectors() function as both 'min_vecs' and
|
||||||
'max_vecs' parameters:
|
'max_vecs' parameters:
|
||||||
|
|
||||||
ret = pci_alloc_irq_vectors(pdev, nvec, nvec, 0);
|
ret = pci_alloc_irq_vectors(pdev, nvec, nvec, PCI_IRQ_ALL_TYPES);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
|
@ -148,15 +145,14 @@ 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
|
the single MSI mode for a device. It could be done by passing two 1s as
|
||||||
'min_vecs' and 'max_vecs':
|
'min_vecs' and 'max_vecs':
|
||||||
|
|
||||||
ret = pci_alloc_irq_vectors(pdev, 1, 1, 0);
|
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
Some devices might not support using legacy line interrupts, in which case
|
Some devices might not support using legacy line interrupts, in which case
|
||||||
the PCI_IRQ_NOLEGACY flag can be used to fail the request if the platform
|
the driver can specify that only MSI or MSI-X is acceptable:
|
||||||
can't provide MSI or MSI-X interrupts:
|
|
||||||
|
|
||||||
nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_NOLEGACY);
|
nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_MSI | PCI_IRQ_MSIX);
|
||||||
if (nvec < 0)
|
if (nvec < 0)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
|
|
|
@ -3032,6 +3032,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||||
PAGE_SIZE is used as alignment.
|
PAGE_SIZE is used as alignment.
|
||||||
PCI-PCI bridge can be specified, if resource
|
PCI-PCI bridge can be specified, if resource
|
||||||
windows need to be expanded.
|
windows need to be expanded.
|
||||||
|
To specify the alignment for several
|
||||||
|
instances of a device, the PCI vendor,
|
||||||
|
device, subvendor, and subdevice may be
|
||||||
|
specified, e.g., 4096@pci:8086:9c22:103c:198f
|
||||||
ecrc= Enable/disable PCIe ECRC (transaction layer
|
ecrc= Enable/disable PCIe ECRC (transaction layer
|
||||||
end-to-end CRC checking).
|
end-to-end CRC checking).
|
||||||
bios: Use BIOS/firmware settings. This is the
|
bios: Use BIOS/firmware settings. This is the
|
||||||
|
|
|
@ -2744,19 +2744,6 @@ config PMC_ATOM
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on PCI
|
depends on PCI
|
||||||
|
|
||||||
config VMD
|
|
||||||
depends on PCI_MSI
|
|
||||||
tristate "Volume Management Device Driver"
|
|
||||||
default N
|
|
||||||
---help---
|
|
||||||
Adds support for the Intel Volume Management Device (VMD). VMD is a
|
|
||||||
secondary PCI host bridge that allows PCI Express root ports,
|
|
||||||
and devices attached to them, to be removed from the default
|
|
||||||
PCI domain and placed within the VMD domain. This provides
|
|
||||||
more bus resources than are otherwise possible with a
|
|
||||||
single domain. If you know your system provides one of these and
|
|
||||||
has devices attached to it, say Y; if you are not sure, say N.
|
|
||||||
|
|
||||||
source "net/Kconfig"
|
source "net/Kconfig"
|
||||||
|
|
||||||
source "drivers/Kconfig"
|
source "drivers/Kconfig"
|
||||||
|
|
|
@ -23,8 +23,6 @@ obj-y += bus_numa.o
|
||||||
obj-$(CONFIG_AMD_NB) += amd_bus.o
|
obj-$(CONFIG_AMD_NB) += amd_bus.o
|
||||||
obj-$(CONFIG_PCI_CNB20LE_QUIRK) += broadcom_bus.o
|
obj-$(CONFIG_PCI_CNB20LE_QUIRK) += broadcom_bus.o
|
||||||
|
|
||||||
obj-$(CONFIG_VMD) += vmd.o
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_PCI_DEBUG),y)
|
ifeq ($(CONFIG_PCI_DEBUG),y)
|
||||||
EXTRA_CFLAGS += -DDEBUG
|
EXTRA_CFLAGS += -DDEBUG
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -285,4 +285,20 @@ config PCIE_ROCKCHIP
|
||||||
There is 1 internal PCIe port available to support GEN2 with
|
There is 1 internal PCIe port available to support GEN2 with
|
||||||
4 slots.
|
4 slots.
|
||||||
|
|
||||||
|
config VMD
|
||||||
|
depends on PCI_MSI && X86_64
|
||||||
|
tristate "Intel Volume Management Device Driver"
|
||||||
|
default N
|
||||||
|
---help---
|
||||||
|
Adds support for the Intel Volume Management Device (VMD). VMD is a
|
||||||
|
secondary PCI host bridge that allows PCI Express root ports,
|
||||||
|
and devices attached to them, to be removed from the default
|
||||||
|
PCI domain and placed within the VMD domain. This provides
|
||||||
|
more bus resources than are otherwise possible with a
|
||||||
|
single domain. If you know your system provides one of these and
|
||||||
|
has devices attached to it, say Y; if you are not sure, say N.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called vmd.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -32,3 +32,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
|
||||||
obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
|
obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
|
||||||
obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
|
obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
|
||||||
obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
|
obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
|
||||||
|
obj-$(CONFIG_VMD) += vmd.o
|
||||||
|
|
|
@ -56,16 +56,11 @@ struct vmd_irq {
|
||||||
/**
|
/**
|
||||||
* struct vmd_irq_list - list of driver requested IRQs mapping to a VMD vector
|
* struct vmd_irq_list - list of driver requested IRQs mapping to a VMD vector
|
||||||
* @irq_list: the list of irq's the VMD one demuxes to.
|
* @irq_list: the list of irq's the VMD one demuxes to.
|
||||||
* @vmd_vector: the h/w IRQ assigned to the VMD.
|
|
||||||
* @index: index into the VMD MSI-X table; used for message routing.
|
|
||||||
* @count: number of child IRQs assigned to this vector; used to track
|
* @count: number of child IRQs assigned to this vector; used to track
|
||||||
* sharing.
|
* sharing.
|
||||||
*/
|
*/
|
||||||
struct vmd_irq_list {
|
struct vmd_irq_list {
|
||||||
struct list_head irq_list;
|
struct list_head irq_list;
|
||||||
struct vmd_dev *vmd;
|
|
||||||
unsigned int vmd_vector;
|
|
||||||
unsigned int index;
|
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,7 +71,6 @@ struct vmd_dev {
|
||||||
char __iomem *cfgbar;
|
char __iomem *cfgbar;
|
||||||
|
|
||||||
int msix_count;
|
int msix_count;
|
||||||
struct msix_entry *msix_entries;
|
|
||||||
struct vmd_irq_list *irqs;
|
struct vmd_irq_list *irqs;
|
||||||
|
|
||||||
struct pci_sysdata sysdata;
|
struct pci_sysdata sysdata;
|
||||||
|
@ -95,6 +89,12 @@ static inline struct vmd_dev *vmd_from_bus(struct pci_bus *bus)
|
||||||
return container_of(bus->sysdata, struct vmd_dev, sysdata);
|
return container_of(bus->sysdata, struct vmd_dev, sysdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned int index_from_irqs(struct vmd_dev *vmd,
|
||||||
|
struct vmd_irq_list *irqs)
|
||||||
|
{
|
||||||
|
return irqs - vmd->irqs;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Drivers managing a device in a VMD domain allocate their own IRQs as before,
|
* Drivers managing a device in a VMD domain allocate their own IRQs as before,
|
||||||
* but the MSI entry for the hardware it's driving will be programmed with a
|
* but the MSI entry for the hardware it's driving will be programmed with a
|
||||||
|
@ -107,9 +107,11 @@ static void vmd_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
|
||||||
{
|
{
|
||||||
struct vmd_irq *vmdirq = data->chip_data;
|
struct vmd_irq *vmdirq = data->chip_data;
|
||||||
struct vmd_irq_list *irq = vmdirq->irq;
|
struct vmd_irq_list *irq = vmdirq->irq;
|
||||||
|
struct vmd_dev *vmd = irq_data_get_irq_handler_data(data);
|
||||||
|
|
||||||
msg->address_hi = MSI_ADDR_BASE_HI;
|
msg->address_hi = MSI_ADDR_BASE_HI;
|
||||||
msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_DEST_ID(irq->index);
|
msg->address_lo = MSI_ADDR_BASE_LO |
|
||||||
|
MSI_ADDR_DEST_ID(index_from_irqs(vmd, irq));
|
||||||
msg->data = 0;
|
msg->data = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +196,7 @@ static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info,
|
||||||
struct msi_desc *desc = arg->desc;
|
struct msi_desc *desc = arg->desc;
|
||||||
struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(desc)->bus);
|
struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(desc)->bus);
|
||||||
struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL);
|
struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL);
|
||||||
|
unsigned int index, vector;
|
||||||
|
|
||||||
if (!vmdirq)
|
if (!vmdirq)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -201,9 +204,11 @@ static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info,
|
||||||
INIT_LIST_HEAD(&vmdirq->node);
|
INIT_LIST_HEAD(&vmdirq->node);
|
||||||
vmdirq->irq = vmd_next_irq(vmd, desc);
|
vmdirq->irq = vmd_next_irq(vmd, desc);
|
||||||
vmdirq->virq = virq;
|
vmdirq->virq = virq;
|
||||||
|
index = index_from_irqs(vmd, vmdirq->irq);
|
||||||
|
vector = pci_irq_vector(vmd->dev, index);
|
||||||
|
|
||||||
irq_domain_set_info(domain, virq, vmdirq->irq->vmd_vector, info->chip,
|
irq_domain_set_info(domain, virq, vector, info->chip, vmdirq,
|
||||||
vmdirq, handle_untracked_irq, vmd, NULL);
|
handle_untracked_irq, vmd, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +218,8 @@ static void vmd_msi_free(struct irq_domain *domain,
|
||||||
struct vmd_irq *vmdirq = irq_get_chip_data(virq);
|
struct vmd_irq *vmdirq = irq_get_chip_data(virq);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
synchronize_rcu();
|
||||||
|
|
||||||
/* XXX: Potential optimization to rebalance */
|
/* XXX: Potential optimization to rebalance */
|
||||||
raw_spin_lock_irqsave(&list_lock, flags);
|
raw_spin_lock_irqsave(&list_lock, flags);
|
||||||
vmdirq->irq->count--;
|
vmdirq->irq->count--;
|
||||||
|
@ -672,30 +679,19 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
if (vmd->msix_count < 0)
|
if (vmd->msix_count < 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
vmd->msix_count = pci_alloc_irq_vectors(dev, 1, vmd->msix_count,
|
||||||
|
PCI_IRQ_MSIX | PCI_IRQ_AFFINITY);
|
||||||
|
if (vmd->msix_count < 0)
|
||||||
|
return vmd->msix_count;
|
||||||
|
|
||||||
vmd->irqs = devm_kcalloc(&dev->dev, vmd->msix_count, sizeof(*vmd->irqs),
|
vmd->irqs = devm_kcalloc(&dev->dev, vmd->msix_count, sizeof(*vmd->irqs),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!vmd->irqs)
|
if (!vmd->irqs)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
vmd->msix_entries = devm_kcalloc(&dev->dev, vmd->msix_count,
|
|
||||||
sizeof(*vmd->msix_entries),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!vmd->msix_entries)
|
|
||||||
return -ENOMEM;
|
|
||||||
for (i = 0; i < vmd->msix_count; i++)
|
|
||||||
vmd->msix_entries[i].entry = i;
|
|
||||||
|
|
||||||
vmd->msix_count = pci_enable_msix_range(vmd->dev, vmd->msix_entries, 1,
|
|
||||||
vmd->msix_count);
|
|
||||||
if (vmd->msix_count < 0)
|
|
||||||
return vmd->msix_count;
|
|
||||||
|
|
||||||
for (i = 0; i < vmd->msix_count; i++) {
|
for (i = 0; i < vmd->msix_count; i++) {
|
||||||
INIT_LIST_HEAD(&vmd->irqs[i].irq_list);
|
INIT_LIST_HEAD(&vmd->irqs[i].irq_list);
|
||||||
vmd->irqs[i].vmd_vector = vmd->msix_entries[i].vector;
|
err = devm_request_irq(&dev->dev, pci_irq_vector(dev, i),
|
||||||
vmd->irqs[i].index = i;
|
|
||||||
|
|
||||||
err = devm_request_irq(&dev->dev, vmd->irqs[i].vmd_vector,
|
|
||||||
vmd_irq, 0, "vmd", &vmd->irqs[i]);
|
vmd_irq, 0, "vmd", &vmd->irqs[i]);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
|
@ -1069,7 +1069,7 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
|
||||||
nvec = maxvec;
|
nvec = maxvec;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!(flags & PCI_IRQ_NOAFFINITY)) {
|
if (flags & PCI_IRQ_AFFINITY) {
|
||||||
dev->irq_affinity = irq_create_affinity_mask(&nvec);
|
dev->irq_affinity = irq_create_affinity_mask(&nvec);
|
||||||
if (nvec < minvec)
|
if (nvec < minvec)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
@ -1105,7 +1105,7 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
|
||||||
**/
|
**/
|
||||||
int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
|
int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
|
||||||
{
|
{
|
||||||
return __pci_enable_msi_range(dev, minvec, maxvec, PCI_IRQ_NOAFFINITY);
|
return __pci_enable_msi_range(dev, minvec, maxvec, 0);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pci_enable_msi_range);
|
EXPORT_SYMBOL(pci_enable_msi_range);
|
||||||
|
|
||||||
|
@ -1120,7 +1120,7 @@ static int __pci_enable_msix_range(struct pci_dev *dev,
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!(flags & PCI_IRQ_NOAFFINITY)) {
|
if (flags & PCI_IRQ_AFFINITY) {
|
||||||
dev->irq_affinity = irq_create_affinity_mask(&nvec);
|
dev->irq_affinity = irq_create_affinity_mask(&nvec);
|
||||||
if (nvec < minvec)
|
if (nvec < minvec)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
@ -1160,8 +1160,7 @@ static int __pci_enable_msix_range(struct pci_dev *dev,
|
||||||
int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
|
int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
|
||||||
int minvec, int maxvec)
|
int minvec, int maxvec)
|
||||||
{
|
{
|
||||||
return __pci_enable_msix_range(dev, entries, minvec, maxvec,
|
return __pci_enable_msix_range(dev, entries, minvec, maxvec, 0);
|
||||||
PCI_IRQ_NOAFFINITY);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pci_enable_msix_range);
|
EXPORT_SYMBOL(pci_enable_msix_range);
|
||||||
|
|
||||||
|
@ -1187,21 +1186,21 @@ int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
|
||||||
{
|
{
|
||||||
int vecs = -ENOSPC;
|
int vecs = -ENOSPC;
|
||||||
|
|
||||||
if (!(flags & PCI_IRQ_NOMSIX)) {
|
if (flags & PCI_IRQ_MSIX) {
|
||||||
vecs = __pci_enable_msix_range(dev, NULL, min_vecs, max_vecs,
|
vecs = __pci_enable_msix_range(dev, NULL, min_vecs, max_vecs,
|
||||||
flags);
|
flags);
|
||||||
if (vecs > 0)
|
if (vecs > 0)
|
||||||
return vecs;
|
return vecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(flags & PCI_IRQ_NOMSI)) {
|
if (flags & PCI_IRQ_MSI) {
|
||||||
vecs = __pci_enable_msi_range(dev, min_vecs, max_vecs, flags);
|
vecs = __pci_enable_msi_range(dev, min_vecs, max_vecs, flags);
|
||||||
if (vecs > 0)
|
if (vecs > 0)
|
||||||
return vecs;
|
return vecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use legacy irq if allowed */
|
/* use legacy irq if allowed */
|
||||||
if (!(flags & PCI_IRQ_NOLEGACY) && min_vecs == 1)
|
if ((flags & PCI_IRQ_LEGACY) && min_vecs == 1)
|
||||||
return 1;
|
return 1;
|
||||||
return vecs;
|
return vecs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1264,10 +1264,12 @@ resource_size_t pcibios_iov_resource_alignment(struct pci_dev *dev, int resno);
|
||||||
int pci_set_vga_state(struct pci_dev *pdev, bool decode,
|
int pci_set_vga_state(struct pci_dev *pdev, bool decode,
|
||||||
unsigned int command_bits, u32 flags);
|
unsigned int command_bits, u32 flags);
|
||||||
|
|
||||||
#define PCI_IRQ_NOLEGACY (1 << 0) /* don't use legacy interrupts */
|
#define PCI_IRQ_LEGACY (1 << 0) /* allow legacy interrupts */
|
||||||
#define PCI_IRQ_NOMSI (1 << 1) /* don't use MSI interrupts */
|
#define PCI_IRQ_MSI (1 << 1) /* allow MSI interrupts */
|
||||||
#define PCI_IRQ_NOMSIX (1 << 2) /* don't use MSI-X interrupts */
|
#define PCI_IRQ_MSIX (1 << 2) /* allow MSI-X interrupts */
|
||||||
#define PCI_IRQ_NOAFFINITY (1 << 3) /* don't auto-assign affinity */
|
#define PCI_IRQ_AFFINITY (1 << 3) /* auto-assign affinity */
|
||||||
|
#define PCI_IRQ_ALL_TYPES \
|
||||||
|
(PCI_IRQ_LEGACY | PCI_IRQ_MSI | PCI_IRQ_MSIX)
|
||||||
|
|
||||||
/* kmem_cache style wrapper around pci_alloc_consistent() */
|
/* kmem_cache style wrapper around pci_alloc_consistent() */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue