aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-01-28 14:52:03 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 18:50:08 -0500
commit5b912c108c8b1fcecbfe13d6d9a183db97b682d3 (patch)
tree0267f65fd9237a41207e4359e09d09e60f6cd754
parent1c659d61cfbd8dc3926688c1bbf12d80f4cfb5c2 (diff)
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: Eric W. Biederman <ebiederm@xmission.com> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--arch/ia64/sn/kernel/msi_sn.c2
-rw-r--r--drivers/pci/msi.c44
-rw-r--r--include/linux/irq.h4
-rw-r--r--kernel/irq/chip.c28
4 files changed, 54 insertions, 24 deletions
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index b3a435fd70fb..31fbb859b67e 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -74,7 +74,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
74 struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); 74 struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
75 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); 75 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
76 76
77 entry = get_irq_data(irq); 77 entry = get_irq_msi(irq);
78 if (!entry->msi_attrib.is_64) 78 if (!entry->msi_attrib.is_64)
79 return -EINVAL; 79 return -EINVAL;
80 80
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 55fe83dfd77b..52c253c5ad3d 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -24,7 +24,6 @@
24#include "pci.h" 24#include "pci.h"
25#include "msi.h" 25#include "msi.h"
26 26
27static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
28static struct kmem_cache* msi_cachep; 27static struct kmem_cache* msi_cachep;
29 28
30static int pci_msi_enable = 1; 29static int pci_msi_enable = 1;
@@ -43,7 +42,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
43{ 42{
44 struct msi_desc *entry; 43 struct msi_desc *entry;
45 44
46 entry = msi_desc[irq]; 45 entry = get_irq_msi(irq);
47 BUG_ON(!entry || !entry->dev); 46 BUG_ON(!entry || !entry->dev);
48 switch (entry->msi_attrib.type) { 47 switch (entry->msi_attrib.type) {
49 case PCI_CAP_ID_MSI: 48 case PCI_CAP_ID_MSI:
@@ -73,7 +72,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
73 72
74void read_msi_msg(unsigned int irq, struct msi_msg *msg) 73void read_msi_msg(unsigned int irq, struct msi_msg *msg)
75{ 74{
76 struct msi_desc *entry = get_irq_data(irq); 75 struct msi_desc *entry = get_irq_msi(irq);
77 switch(entry->msi_attrib.type) { 76 switch(entry->msi_attrib.type) {
78 case PCI_CAP_ID_MSI: 77 case PCI_CAP_ID_MSI:
79 { 78 {
@@ -112,7 +111,7 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)
112 111
113void write_msi_msg(unsigned int irq, struct msi_msg *msg) 112void write_msi_msg(unsigned int irq, struct msi_msg *msg)
114{ 113{
115 struct msi_desc *entry = get_irq_data(irq); 114 struct msi_desc *entry = get_irq_msi(irq);
116 switch (entry->msi_attrib.type) { 115 switch (entry->msi_attrib.type) {
117 case PCI_CAP_ID_MSI: 116 case PCI_CAP_ID_MSI:
118 { 117 {
@@ -208,7 +207,7 @@ static int create_msi_irq(void)
208 return -EBUSY; 207 return -EBUSY;
209 } 208 }
210 209
211 set_irq_data(irq, entry); 210 set_irq_msi(irq, entry);
212 211
213 return irq; 212 return irq;
214} 213}
@@ -217,9 +216,9 @@ static void destroy_msi_irq(unsigned int irq)
217{ 216{
218 struct msi_desc *entry; 217 struct msi_desc *entry;
219 218
220 entry = get_irq_data(irq); 219 entry = get_irq_msi(irq);
221 set_irq_chip(irq, NULL); 220 set_irq_chip(irq, NULL);
222 set_irq_data(irq, NULL); 221 set_irq_msi(irq, NULL);
223 destroy_irq(irq); 222 destroy_irq(irq);
224 kmem_cache_free(msi_cachep, entry); 223 kmem_cache_free(msi_cachep, entry);
225} 224}
@@ -360,10 +359,10 @@ static int __pci_save_msix_state(struct pci_dev *dev)
360 while (head != tail) { 359 while (head != tail) {
361 struct msi_desc *entry; 360 struct msi_desc *entry;
362 361
363 entry = msi_desc[irq]; 362 entry = get_irq_msi(irq);
364 read_msi_msg(irq, &entry->msg_save); 363 read_msi_msg(irq, &entry->msg_save);
365 364
366 tail = msi_desc[irq]->link.tail; 365 tail = entry->link.tail;
367 irq = tail; 366 irq = tail;
368 } 367 }
369 368
@@ -410,10 +409,10 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
410 /* route the table */ 409 /* route the table */
411 irq = head = dev->first_msi_irq; 410 irq = head = dev->first_msi_irq;
412 while (head != tail) { 411 while (head != tail) {
413 entry = msi_desc[irq]; 412 entry = get_irq_msi(irq);
414 write_msi_msg(irq, &entry->msg_save); 413 write_msi_msg(irq, &entry->msg_save);
415 414
416 tail = msi_desc[irq]->link.tail; 415 tail = entry->link.tail;
417 irq = tail; 416 irq = tail;
418 } 417 }
419 418
@@ -451,7 +450,7 @@ static int msi_capability_init(struct pci_dev *dev)
451 if (irq < 0) 450 if (irq < 0)
452 return irq; 451 return irq;
453 452
454 entry = get_irq_data(irq); 453 entry = get_irq_msi(irq);
455 entry->link.head = irq; 454 entry->link.head = irq;
456 entry->link.tail = irq; 455 entry->link.tail = irq;
457 entry->msi_attrib.type = PCI_CAP_ID_MSI; 456 entry->msi_attrib.type = PCI_CAP_ID_MSI;
@@ -486,7 +485,7 @@ static int msi_capability_init(struct pci_dev *dev)
486 } 485 }
487 486
488 dev->first_msi_irq = irq; 487 dev->first_msi_irq = irq;
489 msi_desc[irq] = entry; 488 set_irq_msi(irq, entry);
490 /* Set MSI enabled bits */ 489 /* Set MSI enabled bits */
491 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); 490 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
492 491
@@ -535,7 +534,7 @@ static int msix_capability_init(struct pci_dev *dev,
535 if (irq < 0) 534 if (irq < 0)
536 break; 535 break;
537 536
538 entry = get_irq_data(irq); 537 entry = get_irq_msi(irq);
539 j = entries[i].entry; 538 j = entries[i].entry;
540 entries[i].vector = irq; 539 entries[i].vector = irq;
541 entry->msi_attrib.type = PCI_CAP_ID_MSIX; 540 entry->msi_attrib.type = PCI_CAP_ID_MSIX;
@@ -565,7 +564,7 @@ static int msix_capability_init(struct pci_dev *dev,
565 break; 564 break;
566 } 565 }
567 566
568 msi_desc[irq] = entry; 567 set_irq_msi(irq, entry);
569 } 568 }
570 if (i != nvec) { 569 if (i != nvec) {
571 int avail = i - 1; 570 int avail = i - 1;
@@ -682,7 +681,7 @@ void pci_disable_msi(struct pci_dev* dev)
682 681
683 disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); 682 disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
684 683
685 entry = msi_desc[dev->first_msi_irq]; 684 entry = get_irq_msi(dev->first_msi_irq);
686 if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { 685 if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
687 return; 686 return;
688 } 687 }
@@ -709,7 +708,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
709 708
710 arch_teardown_msi_irq(irq); 709 arch_teardown_msi_irq(irq);
711 710
712 entry = msi_desc[irq]; 711 entry = get_irq_msi(irq);
713 if (!entry || entry->dev != dev) { 712 if (!entry || entry->dev != dev) {
714 return -EINVAL; 713 return -EINVAL;
715 } 714 }
@@ -717,10 +716,9 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
717 entry_nr = entry->msi_attrib.entry_nr; 716 entry_nr = entry->msi_attrib.entry_nr;
718 head = entry->link.head; 717 head = entry->link.head;
719 base = entry->mask_base; 718 base = entry->mask_base;
720 msi_desc[entry->link.head]->link.tail = entry->link.tail; 719 get_irq_msi(entry->link.head)->link.tail = entry->link.tail;
721 msi_desc[entry->link.tail]->link.head = entry->link.head; 720 get_irq_msi(entry->link.tail)->link.head = entry->link.head;
722 entry->dev = NULL; 721 entry->dev = NULL;
723 msi_desc[irq] = NULL;
724 722
725 destroy_msi_irq(irq); 723 destroy_msi_irq(irq);
726 724
@@ -821,7 +819,7 @@ void pci_disable_msix(struct pci_dev* dev)
821 819
822 irq = head = dev->first_msi_irq; 820 irq = head = dev->first_msi_irq;
823 while (head != tail) { 821 while (head != tail) {
824 tail = msi_desc[irq]->link.tail; 822 tail = get_irq_msi(irq)->link.tail;
825 if (irq_has_action(irq)) 823 if (irq_has_action(irq))
826 warning = 1; 824 warning = 1;
827 else if (irq != head) /* Release MSI-X irq */ 825 else if (irq != head) /* Release MSI-X irq */
@@ -867,8 +865,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
867 865
868 irq = head = dev->first_msi_irq; 866 irq = head = dev->first_msi_irq;
869 while (head != tail) { 867 while (head != tail) {
870 tail = msi_desc[irq]->link.tail; 868 tail = get_irq_msi(irq)->link.tail;
871 base = msi_desc[irq]->mask_base; 869 base = get_irq_msi(irq)->mask_base;
872 if (irq_has_action(irq)) 870 if (irq_has_action(irq))
873 warning = 1; 871 warning = 1;
874 else if (irq != head) /* Release MSI-X irq */ 872 else if (irq != head) /* Release MSI-X irq */
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 52fc4052a0ae..5504b671357f 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -68,6 +68,7 @@ typedef void fastcall (*irq_flow_handler_t)(unsigned int irq,
68#define IRQ_MOVE_PENDING 0x40000000 /* need to re-target IRQ destination */ 68#define IRQ_MOVE_PENDING 0x40000000 /* need to re-target IRQ destination */
69 69
70struct proc_dir_entry; 70struct proc_dir_entry;
71struct msi_desc;
71 72
72/** 73/**
73 * struct irq_chip - hardware interrupt chip descriptor 74 * struct irq_chip - hardware interrupt chip descriptor
@@ -148,6 +149,7 @@ struct irq_chip {
148struct irq_desc { 149struct irq_desc {
149 irq_flow_handler_t handle_irq; 150 irq_flow_handler_t handle_irq;
150 struct irq_chip *chip; 151 struct irq_chip *chip;
152 struct msi_desc *msi_desc;
151 void *handler_data; 153 void *handler_data;
152 void *chip_data; 154 void *chip_data;
153 struct irqaction *action; /* IRQ action list */ 155 struct irqaction *action; /* IRQ action list */
@@ -373,10 +375,12 @@ extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
373extern int set_irq_data(unsigned int irq, void *data); 375extern int set_irq_data(unsigned int irq, void *data);
374extern int set_irq_chip_data(unsigned int irq, void *data); 376extern int set_irq_chip_data(unsigned int irq, void *data);
375extern int set_irq_type(unsigned int irq, unsigned int type); 377extern int set_irq_type(unsigned int irq, unsigned int type);
378extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
376 379
377#define get_irq_chip(irq) (irq_desc[irq].chip) 380#define get_irq_chip(irq) (irq_desc[irq].chip)
378#define get_irq_chip_data(irq) (irq_desc[irq].chip_data) 381#define get_irq_chip_data(irq) (irq_desc[irq].chip_data)
379#define get_irq_data(irq) (irq_desc[irq].handler_data) 382#define get_irq_data(irq) (irq_desc[irq].handler_data)
383#define get_irq_msi(irq) (irq_desc[irq].msi_desc)
380 384
381#endif /* CONFIG_GENERIC_HARDIRQS */ 385#endif /* CONFIG_GENERIC_HARDIRQS */
382 386
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index d27b25855743..475e8a71bcdc 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -39,6 +39,7 @@ void dynamic_irq_init(unsigned int irq)
39 desc->chip = &no_irq_chip; 39 desc->chip = &no_irq_chip;
40 desc->handle_irq = handle_bad_irq; 40 desc->handle_irq = handle_bad_irq;
41 desc->depth = 1; 41 desc->depth = 1;
42 desc->msi_desc = NULL;
42 desc->handler_data = NULL; 43 desc->handler_data = NULL;
43 desc->chip_data = NULL; 44 desc->chip_data = NULL;
44 desc->action = NULL; 45 desc->action = NULL;
@@ -74,6 +75,9 @@ void dynamic_irq_cleanup(unsigned int irq)
74 WARN_ON(1); 75 WARN_ON(1);
75 return; 76 return;
76 } 77 }
78 desc->msi_desc = NULL;
79 desc->handler_data = NULL;
80 desc->chip_data = NULL;
77 desc->handle_irq = handle_bad_irq; 81 desc->handle_irq = handle_bad_irq;
78 desc->chip = &no_irq_chip; 82 desc->chip = &no_irq_chip;
79 spin_unlock_irqrestore(&desc->lock, flags); 83 spin_unlock_irqrestore(&desc->lock, flags);
@@ -162,6 +166,30 @@ int set_irq_data(unsigned int irq, void *data)
162EXPORT_SYMBOL(set_irq_data); 166EXPORT_SYMBOL(set_irq_data);
163 167
164/** 168/**
169 * set_irq_data - set irq type data for an irq
170 * @irq: Interrupt number
171 * @data: Pointer to interrupt specific data
172 *
173 * Set the hardware irq controller data for an irq
174 */
175int set_irq_msi(unsigned int irq, struct msi_desc *entry)
176{
177 struct irq_desc *desc;
178 unsigned long flags;
179
180 if (irq >= NR_IRQS) {
181 printk(KERN_ERR
182 "Trying to install msi data for IRQ%d\n", irq);
183 return -EINVAL;
184 }
185 desc = irq_desc + irq;
186 spin_lock_irqsave(&desc->lock, flags);
187 desc->msi_desc = entry;
188 spin_unlock_irqrestore(&desc->lock, flags);
189 return 0;
190}
191
192/**
165 * set_irq_chip_data - set irq chip data for an irq 193 * set_irq_chip_data - set irq chip data for an irq
166 * @irq: Interrupt number 194 * @irq: Interrupt number
167 * @data: Pointer to chip specific data 195 * @data: Pointer to chip specific data