[PATCH] PCI: clean up the MSI code a bit.
Mostly just cleans up the irq handling logic to be smaller and a bit more descriptive as to what it really does. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
@@ -28,10 +28,10 @@ static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
|
|||||||
static kmem_cache_t* msi_cachep;
|
static kmem_cache_t* msi_cachep;
|
||||||
|
|
||||||
static int pci_msi_enable = 1;
|
static int pci_msi_enable = 1;
|
||||||
static int last_alloc_vector = 0;
|
static int last_alloc_vector;
|
||||||
static int nr_released_vectors = 0;
|
static int nr_released_vectors;
|
||||||
static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
|
static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
|
||||||
static int nr_msix_devices = 0;
|
static int nr_msix_devices;
|
||||||
|
|
||||||
#ifndef CONFIG_X86_IO_APIC
|
#ifndef CONFIG_X86_IO_APIC
|
||||||
int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
|
int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
|
||||||
@@ -170,44 +170,30 @@ static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector)
|
|||||||
return 0; /* never anything pending */
|
return 0; /* never anything pending */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release_msi(unsigned int vector);
|
|
||||||
static void shutdown_msi_irq(unsigned int vector)
|
|
||||||
{
|
|
||||||
release_msi(vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define shutdown_msi_irq_wo_maskbit shutdown_msi_irq
|
|
||||||
static void enable_msi_irq_wo_maskbit(unsigned int vector) {}
|
|
||||||
static void disable_msi_irq_wo_maskbit(unsigned int vector) {}
|
|
||||||
static void ack_msi_irq_wo_maskbit(unsigned int vector) {}
|
|
||||||
static void end_msi_irq_wo_maskbit(unsigned int vector)
|
|
||||||
{
|
|
||||||
move_msi(vector);
|
|
||||||
ack_APIC_irq();
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
|
static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
|
||||||
|
{
|
||||||
|
startup_msi_irq_wo_maskbit(vector);
|
||||||
|
unmask_MSI_irq(vector);
|
||||||
|
return 0; /* never anything pending */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shutdown_msi_irq(unsigned int vector)
|
||||||
{
|
{
|
||||||
struct msi_desc *entry;
|
struct msi_desc *entry;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&msi_lock, flags);
|
spin_lock_irqsave(&msi_lock, flags);
|
||||||
entry = msi_desc[vector];
|
entry = msi_desc[vector];
|
||||||
if (!entry || !entry->dev) {
|
if (entry && entry->dev)
|
||||||
|
entry->msi_attrib.state = 0; /* Mark it not active */
|
||||||
spin_unlock_irqrestore(&msi_lock, flags);
|
spin_unlock_irqrestore(&msi_lock, flags);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
entry->msi_attrib.state = 1; /* Mark it active */
|
|
||||||
spin_unlock_irqrestore(&msi_lock, flags);
|
|
||||||
|
|
||||||
unmask_MSI_irq(vector);
|
|
||||||
return 0; /* never anything pending */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define shutdown_msi_irq_w_maskbit shutdown_msi_irq
|
static void end_msi_irq_wo_maskbit(unsigned int vector)
|
||||||
#define enable_msi_irq_w_maskbit unmask_MSI_irq
|
{
|
||||||
#define disable_msi_irq_w_maskbit mask_MSI_irq
|
move_msi(vector);
|
||||||
#define ack_msi_irq_w_maskbit mask_MSI_irq
|
ack_APIC_irq();
|
||||||
|
}
|
||||||
|
|
||||||
static void end_msi_irq_w_maskbit(unsigned int vector)
|
static void end_msi_irq_w_maskbit(unsigned int vector)
|
||||||
{
|
{
|
||||||
@@ -216,6 +202,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector)
|
|||||||
ack_APIC_irq();
|
ack_APIC_irq();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void do_nothing(unsigned int vector)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
|
* Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
|
||||||
* which implement the MSI-X Capability Structure.
|
* which implement the MSI-X Capability Structure.
|
||||||
@@ -223,10 +213,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector)
|
|||||||
static struct hw_interrupt_type msix_irq_type = {
|
static struct hw_interrupt_type msix_irq_type = {
|
||||||
.typename = "PCI-MSI-X",
|
.typename = "PCI-MSI-X",
|
||||||
.startup = startup_msi_irq_w_maskbit,
|
.startup = startup_msi_irq_w_maskbit,
|
||||||
.shutdown = shutdown_msi_irq_w_maskbit,
|
.shutdown = shutdown_msi_irq,
|
||||||
.enable = enable_msi_irq_w_maskbit,
|
.enable = unmask_MSI_irq,
|
||||||
.disable = disable_msi_irq_w_maskbit,
|
.disable = mask_MSI_irq,
|
||||||
.ack = ack_msi_irq_w_maskbit,
|
.ack = mask_MSI_irq,
|
||||||
.end = end_msi_irq_w_maskbit,
|
.end = end_msi_irq_w_maskbit,
|
||||||
.set_affinity = set_msi_irq_affinity
|
.set_affinity = set_msi_irq_affinity
|
||||||
};
|
};
|
||||||
@@ -239,10 +229,10 @@ static struct hw_interrupt_type msix_irq_type = {
|
|||||||
static struct hw_interrupt_type msi_irq_w_maskbit_type = {
|
static struct hw_interrupt_type msi_irq_w_maskbit_type = {
|
||||||
.typename = "PCI-MSI",
|
.typename = "PCI-MSI",
|
||||||
.startup = startup_msi_irq_w_maskbit,
|
.startup = startup_msi_irq_w_maskbit,
|
||||||
.shutdown = shutdown_msi_irq_w_maskbit,
|
.shutdown = shutdown_msi_irq,
|
||||||
.enable = enable_msi_irq_w_maskbit,
|
.enable = unmask_MSI_irq,
|
||||||
.disable = disable_msi_irq_w_maskbit,
|
.disable = mask_MSI_irq,
|
||||||
.ack = ack_msi_irq_w_maskbit,
|
.ack = mask_MSI_irq,
|
||||||
.end = end_msi_irq_w_maskbit,
|
.end = end_msi_irq_w_maskbit,
|
||||||
.set_affinity = set_msi_irq_affinity
|
.set_affinity = set_msi_irq_affinity
|
||||||
};
|
};
|
||||||
@@ -255,10 +245,10 @@ static struct hw_interrupt_type msi_irq_w_maskbit_type = {
|
|||||||
static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
|
static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
|
||||||
.typename = "PCI-MSI",
|
.typename = "PCI-MSI",
|
||||||
.startup = startup_msi_irq_wo_maskbit,
|
.startup = startup_msi_irq_wo_maskbit,
|
||||||
.shutdown = shutdown_msi_irq_wo_maskbit,
|
.shutdown = shutdown_msi_irq,
|
||||||
.enable = enable_msi_irq_wo_maskbit,
|
.enable = do_nothing,
|
||||||
.disable = disable_msi_irq_wo_maskbit,
|
.disable = do_nothing,
|
||||||
.ack = ack_msi_irq_wo_maskbit,
|
.ack = do_nothing,
|
||||||
.end = end_msi_irq_wo_maskbit,
|
.end = end_msi_irq_wo_maskbit,
|
||||||
.set_affinity = set_msi_irq_affinity
|
.set_affinity = set_msi_irq_affinity
|
||||||
};
|
};
|
||||||
@@ -407,7 +397,7 @@ static struct msi_desc* alloc_msi_entry(void)
|
|||||||
{
|
{
|
||||||
struct msi_desc *entry;
|
struct msi_desc *entry;
|
||||||
|
|
||||||
entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
|
entry = kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -796,18 +786,6 @@ void pci_disable_msi(struct pci_dev* dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release_msi(unsigned int vector)
|
|
||||||
{
|
|
||||||
struct msi_desc *entry;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&msi_lock, flags);
|
|
||||||
entry = msi_desc[vector];
|
|
||||||
if (entry && entry->dev)
|
|
||||||
entry->msi_attrib.state = 0; /* Mark it not active */
|
|
||||||
spin_unlock_irqrestore(&msi_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
|
static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
|
||||||
{
|
{
|
||||||
struct msi_desc *entry;
|
struct msi_desc *entry;
|
||||||
@@ -924,7 +902,7 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
|
|||||||
/**
|
/**
|
||||||
* pci_enable_msix - configure device's MSI-X capability structure
|
* pci_enable_msix - configure device's MSI-X capability structure
|
||||||
* @dev: pointer to the pci_dev data structure of MSI-X device function
|
* @dev: pointer to the pci_dev data structure of MSI-X device function
|
||||||
* @data: pointer to an array of MSI-X entries
|
* @entries: pointer to an array of MSI-X entries
|
||||||
* @nvec: number of MSI-X vectors requested for allocation by device driver
|
* @nvec: number of MSI-X vectors requested for allocation by device driver
|
||||||
*
|
*
|
||||||
* Setup the MSI-X capability structure of device function with the number
|
* Setup the MSI-X capability structure of device function with the number
|
||||||
|
@@ -41,11 +41,11 @@ static inline void move_msi(int vector) {}
|
|||||||
#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
|
#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
|
||||||
#define PCI_MSIX_FLAGS_BITMASK (1 << 0)
|
#define PCI_MSIX_FLAGS_BITMASK (1 << 0)
|
||||||
|
|
||||||
|
#define PCI_MSIX_ENTRY_SIZE 16
|
||||||
#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0
|
#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0
|
||||||
#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4
|
#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4
|
||||||
#define PCI_MSIX_ENTRY_DATA_OFFSET 8
|
#define PCI_MSIX_ENTRY_DATA_OFFSET 8
|
||||||
#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12
|
#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12
|
||||||
#define PCI_MSIX_ENTRY_SIZE 16
|
|
||||||
|
|
||||||
#define msi_control_reg(base) (base + PCI_MSI_FLAGS)
|
#define msi_control_reg(base) (base + PCI_MSI_FLAGS)
|
||||||
#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO)
|
#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO)
|
||||||
@@ -64,7 +64,6 @@ static inline void move_msi(int vector) {}
|
|||||||
#define msi_enable(control, num) multi_msi_enable(control, num); \
|
#define msi_enable(control, num) multi_msi_enable(control, num); \
|
||||||
control |= PCI_MSI_FLAGS_ENABLE
|
control |= PCI_MSI_FLAGS_ENABLE
|
||||||
|
|
||||||
#define msix_control_reg msi_control_reg
|
|
||||||
#define msix_table_offset_reg(base) (base + 0x04)
|
#define msix_table_offset_reg(base) (base + 0x04)
|
||||||
#define msix_pba_offset_reg(base) (base + 0x08)
|
#define msix_pba_offset_reg(base) (base + 0x08)
|
||||||
#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE
|
#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE
|
||||||
|
Reference in New Issue
Block a user