Commit 5b912c10 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Greg Kroah-Hartman

msi: Kill the msi_desc array.

We need to be able to get from an irq number to a struct msi_desc.
The msi_desc array in msi.c had several short comings the big one was
that it could not be used outside of msi.c.  Using irq_data in struct
irq_desc almost worked except on some architectures irq_data needs to
be used for something else.

So this patch adds a msi_desc pointer to irq_desc, adds the appropriate
wrappers and changes all of the msi code to use them.

The dynamic_irq_init/cleanup code was tweaked to ensure the new
field is left in a well defined state.
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Acked-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 1c659d61
...@@ -74,7 +74,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) ...@@ -74,7 +74,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
entry = get_irq_data(irq); entry = get_irq_msi(irq);
if (!entry->msi_attrib.is_64) if (!entry->msi_attrib.is_64)
return -EINVAL; return -EINVAL;
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include "pci.h" #include "pci.h"
#include "msi.h" #include "msi.h"
static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
static struct kmem_cache* msi_cachep; static struct kmem_cache* msi_cachep;
static int pci_msi_enable = 1; static int pci_msi_enable = 1;
...@@ -43,7 +42,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag) ...@@ -43,7 +42,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
{ {
struct msi_desc *entry; struct msi_desc *entry;
entry = msi_desc[irq]; entry = get_irq_msi(irq);
BUG_ON(!entry || !entry->dev); BUG_ON(!entry || !entry->dev);
switch (entry->msi_attrib.type) { switch (entry->msi_attrib.type) {
case PCI_CAP_ID_MSI: case PCI_CAP_ID_MSI:
...@@ -73,7 +72,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag) ...@@ -73,7 +72,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
void read_msi_msg(unsigned int irq, struct msi_msg *msg) void read_msi_msg(unsigned int irq, struct msi_msg *msg)
{ {
struct msi_desc *entry = get_irq_data(irq); struct msi_desc *entry = get_irq_msi(irq);
switch(entry->msi_attrib.type) { switch(entry->msi_attrib.type) {
case PCI_CAP_ID_MSI: case PCI_CAP_ID_MSI:
{ {
...@@ -112,7 +111,7 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg) ...@@ -112,7 +111,7 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)
void write_msi_msg(unsigned int irq, struct msi_msg *msg) void write_msi_msg(unsigned int irq, struct msi_msg *msg)
{ {
struct msi_desc *entry = get_irq_data(irq); struct msi_desc *entry = get_irq_msi(irq);
switch (entry->msi_attrib.type) { switch (entry->msi_attrib.type) {
case PCI_CAP_ID_MSI: case PCI_CAP_ID_MSI:
{ {
...@@ -208,7 +207,7 @@ static int create_msi_irq(void) ...@@ -208,7 +207,7 @@ static int create_msi_irq(void)
return -EBUSY; return -EBUSY;
} }
set_irq_data(irq, entry); set_irq_msi(irq, entry);
return irq; return irq;
} }
...@@ -217,9 +216,9 @@ static void destroy_msi_irq(unsigned int irq) ...@@ -217,9 +216,9 @@ static void destroy_msi_irq(unsigned int irq)
{ {
struct msi_desc *entry; struct msi_desc *entry;
entry = get_irq_data(irq); entry = get_irq_msi(irq);
set_irq_chip(irq, NULL); set_irq_chip(irq, NULL);
set_irq_data(irq, NULL); set_irq_msi(irq, NULL);
destroy_irq(irq); destroy_irq(irq);
kmem_cache_free(msi_cachep, entry); kmem_cache_free(msi_cachep, entry);
} }
...@@ -360,10 +359,10 @@ static int __pci_save_msix_state(struct pci_dev *dev) ...@@ -360,10 +359,10 @@ static int __pci_save_msix_state(struct pci_dev *dev)
while (head != tail) { while (head != tail) {
struct msi_desc *entry; struct msi_desc *entry;
entry = msi_desc[irq]; entry = get_irq_msi(irq);
read_msi_msg(irq, &entry->msg_save); read_msi_msg(irq, &entry->msg_save);
tail = msi_desc[irq]->link.tail; tail = entry->link.tail;
irq = tail; irq = tail;
} }
...@@ -410,10 +409,10 @@ static void __pci_restore_msix_state(struct pci_dev *dev) ...@@ -410,10 +409,10 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
/* route the table */ /* route the table */
irq = head = dev->first_msi_irq; irq = head = dev->first_msi_irq;
while (head != tail) { while (head != tail) {
entry = msi_desc[irq]; entry = get_irq_msi(irq);
write_msi_msg(irq, &entry->msg_save); write_msi_msg(irq, &entry->msg_save);
tail = msi_desc[irq]->link.tail; tail = entry->link.tail;
irq = tail; irq = tail;
} }
...@@ -451,7 +450,7 @@ static int msi_capability_init(struct pci_dev *dev) ...@@ -451,7 +450,7 @@ static int msi_capability_init(struct pci_dev *dev)
if (irq < 0) if (irq < 0)
return irq; return irq;
entry = get_irq_data(irq); entry = get_irq_msi(irq);
entry->link.head = irq; entry->link.head = irq;
entry->link.tail = irq; entry->link.tail = irq;
entry->msi_attrib.type = PCI_CAP_ID_MSI; entry->msi_attrib.type = PCI_CAP_ID_MSI;
...@@ -486,7 +485,7 @@ static int msi_capability_init(struct pci_dev *dev) ...@@ -486,7 +485,7 @@ static int msi_capability_init(struct pci_dev *dev)
} }
dev->first_msi_irq = irq; dev->first_msi_irq = irq;
msi_desc[irq] = entry; set_irq_msi(irq, entry);
/* Set MSI enabled bits */ /* Set MSI enabled bits */
enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
...@@ -535,7 +534,7 @@ static int msix_capability_init(struct pci_dev *dev, ...@@ -535,7 +534,7 @@ static int msix_capability_init(struct pci_dev *dev,
if (irq < 0) if (irq < 0)
break; break;
entry = get_irq_data(irq); entry = get_irq_msi(irq);
j = entries[i].entry; j = entries[i].entry;
entries[i].vector = irq; entries[i].vector = irq;
entry->msi_attrib.type = PCI_CAP_ID_MSIX; entry->msi_attrib.type = PCI_CAP_ID_MSIX;
...@@ -565,7 +564,7 @@ static int msix_capability_init(struct pci_dev *dev, ...@@ -565,7 +564,7 @@ static int msix_capability_init(struct pci_dev *dev,
break; break;
} }
msi_desc[irq] = entry; set_irq_msi(irq, entry);
} }
if (i != nvec) { if (i != nvec) {
int avail = i - 1; int avail = i - 1;
...@@ -682,7 +681,7 @@ void pci_disable_msi(struct pci_dev* dev) ...@@ -682,7 +681,7 @@ void pci_disable_msi(struct pci_dev* dev)
disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
entry = msi_desc[dev->first_msi_irq]; entry = get_irq_msi(dev->first_msi_irq);
if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
return; return;
} }
...@@ -709,7 +708,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq) ...@@ -709,7 +708,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
arch_teardown_msi_irq(irq); arch_teardown_msi_irq(irq);
entry = msi_desc[irq]; entry = get_irq_msi(irq);
if (!entry || entry->dev != dev) { if (!entry || entry->dev != dev) {
return -EINVAL; return -EINVAL;
} }
...@@ -717,10 +716,9 @@ static int msi_free_irq(struct pci_dev* dev, int irq) ...@@ -717,10 +716,9 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
entry_nr = entry->msi_attrib.entry_nr; entry_nr = entry->msi_attrib.entry_nr;
head = entry->link.head; head = entry->link.head;
base = entry->mask_base; base = entry->mask_base;
msi_desc[entry->link.head]->link.tail = entry->link.tail; get_irq_msi(entry->link.head)->link.tail = entry->link.tail;
msi_desc[entry->link.tail]->link.head = entry->link.head; get_irq_msi(entry->link.tail)->link.head = entry->link.head;
entry->dev = NULL; entry->dev = NULL;
msi_desc[irq] = NULL;
destroy_msi_irq(irq); destroy_msi_irq(irq);
...@@ -821,7 +819,7 @@ void pci_disable_msix(struct pci_dev* dev) ...@@ -821,7 +819,7 @@ void pci_disable_msix(struct pci_dev* dev)
irq = head = dev->first_msi_irq; irq = head = dev->first_msi_irq;
while (head != tail) { while (head != tail) {
tail = msi_desc[irq]->link.tail; tail = get_irq_msi(irq)->link.tail;
if (irq_has_action(irq)) if (irq_has_action(irq))
warning = 1; warning = 1;
else if (irq != head) /* Release MSI-X irq */ else if (irq != head) /* Release MSI-X irq */
...@@ -867,8 +865,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) ...@@ -867,8 +865,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
irq = head = dev->first_msi_irq; irq = head = dev->first_msi_irq;
while (head != tail) { while (head != tail) {
tail = msi_desc[irq]->link.tail; tail = get_irq_msi(irq)->link.tail;
base = msi_desc[irq]->mask_base; base = get_irq_msi(irq)->mask_base;
if (irq_has_action(irq)) if (irq_has_action(irq))
warning = 1; warning = 1;
else if (irq != head) /* Release MSI-X irq */ else if (irq != head) /* Release MSI-X irq */
......
...@@ -68,6 +68,7 @@ typedef void fastcall (*irq_flow_handler_t)(unsigned int irq, ...@@ -68,6 +68,7 @@ typedef void fastcall (*irq_flow_handler_t)(unsigned int irq,
#define IRQ_MOVE_PENDING 0x40000000 /* need to re-target IRQ destination */ #define IRQ_MOVE_PENDING 0x40000000 /* need to re-target IRQ destination */
struct proc_dir_entry; struct proc_dir_entry;
struct msi_desc;
/** /**
* struct irq_chip - hardware interrupt chip descriptor * struct irq_chip - hardware interrupt chip descriptor
...@@ -148,6 +149,7 @@ struct irq_chip { ...@@ -148,6 +149,7 @@ struct irq_chip {
struct irq_desc { struct irq_desc {
irq_flow_handler_t handle_irq; irq_flow_handler_t handle_irq;
struct irq_chip *chip; struct irq_chip *chip;
struct msi_desc *msi_desc;
void *handler_data; void *handler_data;
void *chip_data; void *chip_data;
struct irqaction *action; /* IRQ action list */ struct irqaction *action; /* IRQ action list */
...@@ -373,10 +375,12 @@ extern int set_irq_chip(unsigned int irq, struct irq_chip *chip); ...@@ -373,10 +375,12 @@ extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
extern int set_irq_data(unsigned int irq, void *data); extern int set_irq_data(unsigned int irq, void *data);
extern int set_irq_chip_data(unsigned int irq, void *data); extern int set_irq_chip_data(unsigned int irq, void *data);
extern int set_irq_type(unsigned int irq, unsigned int type); extern int set_irq_type(unsigned int irq, unsigned int type);
extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
#define get_irq_chip(irq) (irq_desc[irq].chip) #define get_irq_chip(irq) (irq_desc[irq].chip)
#define get_irq_chip_data(irq) (irq_desc[irq].chip_data) #define get_irq_chip_data(irq) (irq_desc[irq].chip_data)
#define get_irq_data(irq) (irq_desc[irq].handler_data) #define get_irq_data(irq) (irq_desc[irq].handler_data)
#define get_irq_msi(irq) (irq_desc[irq].msi_desc)
#endif /* CONFIG_GENERIC_HARDIRQS */ #endif /* CONFIG_GENERIC_HARDIRQS */
......
...@@ -39,6 +39,7 @@ void dynamic_irq_init(unsigned int irq) ...@@ -39,6 +39,7 @@ void dynamic_irq_init(unsigned int irq)
desc->chip = &no_irq_chip; desc->chip = &no_irq_chip;
desc->handle_irq = handle_bad_irq; desc->handle_irq = handle_bad_irq;
desc->depth = 1; desc->depth = 1;
desc->msi_desc = NULL;
desc->handler_data = NULL; desc->handler_data = NULL;
desc->chip_data = NULL; desc->chip_data = NULL;
desc->action = NULL; desc->action = NULL;
...@@ -74,6 +75,9 @@ void dynamic_irq_cleanup(unsigned int irq) ...@@ -74,6 +75,9 @@ void dynamic_irq_cleanup(unsigned int irq)
WARN_ON(1); WARN_ON(1);
return; return;
} }
desc->msi_desc = NULL;
desc->handler_data = NULL;
desc->chip_data = NULL;
desc->handle_irq = handle_bad_irq; desc->handle_irq = handle_bad_irq;
desc->chip = &no_irq_chip; desc->chip = &no_irq_chip;
spin_unlock_irqrestore(&desc->lock, flags); spin_unlock_irqrestore(&desc->lock, flags);
...@@ -161,6 +165,30 @@ int set_irq_data(unsigned int irq, void *data) ...@@ -161,6 +165,30 @@ int set_irq_data(unsigned int irq, void *data)
} }
EXPORT_SYMBOL(set_irq_data); EXPORT_SYMBOL(set_irq_data);
/**
* set_irq_data - set irq type data for an irq
* @irq: Interrupt number
* @data: Pointer to interrupt specific data
*
* Set the hardware irq controller data for an irq
*/
int set_irq_msi(unsigned int irq, struct msi_desc *entry)
{
struct irq_desc *desc;
unsigned long flags;
if (irq >= NR_IRQS) {
printk(KERN_ERR
"Trying to install msi data for IRQ%d\n", irq);
return -EINVAL;
}
desc = irq_desc + irq;
spin_lock_irqsave(&desc->lock, flags);
desc->msi_desc = entry;
spin_unlock_irqrestore(&desc->lock, flags);
return 0;
}
/** /**
* set_irq_chip_data - set irq chip data for an irq * set_irq_chip_data - set irq chip data for an irq
* @irq: Interrupt number * @irq: Interrupt number
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment