diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2006-10-04 05:16:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 10:55:29 -0400 |
commit | 1f80025e624bb14fefadfef7e80fbfb9740d4714 (patch) | |
tree | 1d6f18ebd2855e882213922036d8df8cd7e88db4 /drivers/pci/msi.c | |
parent | 8b955b0dddb35e398b07e217a81f8bd49400796f (diff) |
[PATCH] msi: simplify msi sanity checks by adding with generic irq code
Currently msi.c is doing sanity checks that make certain before an irq is
destroyed it has no more users.
By adding irq_has_action I can perform the test is a generic way, instead of
relying on a msi specific data structure.
By performing the core check in dynamic_irq_cleanup I ensure every user of
dynamic irqs has a test present and we don't free resources that are in use.
In msi.c this allows me to kill the attrib.state member of msi_desc and all of
the assciated code to maintain it.
To keep from freeing data structures when irq cleanup code is called to soon
changing dyanamic_irq_cleanup is insufficient because there are msi specific
data structures that are also not safe to free.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Andi Kleen <ak@suse.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/pci/msi.c')
-rw-r--r-- | drivers/pci/msi.c | 43 |
1 files changed, 8 insertions, 35 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index da2c6c2b6b11..e3ba3963988c 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -188,18 +188,6 @@ static void unmask_MSI_irq(unsigned int irq) | |||
188 | 188 | ||
189 | static unsigned int startup_msi_irq_wo_maskbit(unsigned int irq) | 189 | static unsigned int startup_msi_irq_wo_maskbit(unsigned int irq) |
190 | { | 190 | { |
191 | struct msi_desc *entry; | ||
192 | unsigned long flags; | ||
193 | |||
194 | spin_lock_irqsave(&msi_lock, flags); | ||
195 | entry = msi_desc[irq]; | ||
196 | if (!entry || !entry->dev) { | ||
197 | spin_unlock_irqrestore(&msi_lock, flags); | ||
198 | return 0; | ||
199 | } | ||
200 | entry->msi_attrib.state = 1; /* Mark it active */ | ||
201 | spin_unlock_irqrestore(&msi_lock, flags); | ||
202 | |||
203 | return 0; /* never anything pending */ | 191 | return 0; /* never anything pending */ |
204 | } | 192 | } |
205 | 193 | ||
@@ -212,14 +200,6 @@ static unsigned int startup_msi_irq_w_maskbit(unsigned int irq) | |||
212 | 200 | ||
213 | static void shutdown_msi_irq(unsigned int irq) | 201 | static void shutdown_msi_irq(unsigned int irq) |
214 | { | 202 | { |
215 | struct msi_desc *entry; | ||
216 | unsigned long flags; | ||
217 | |||
218 | spin_lock_irqsave(&msi_lock, flags); | ||
219 | entry = msi_desc[irq]; | ||
220 | if (entry && entry->dev) | ||
221 | entry->msi_attrib.state = 0; /* Mark it not active */ | ||
222 | spin_unlock_irqrestore(&msi_lock, flags); | ||
223 | } | 203 | } |
224 | 204 | ||
225 | static void end_msi_irq_wo_maskbit(unsigned int irq) | 205 | static void end_msi_irq_wo_maskbit(unsigned int irq) |
@@ -671,7 +651,6 @@ static int msi_capability_init(struct pci_dev *dev) | |||
671 | entry->link.head = irq; | 651 | entry->link.head = irq; |
672 | entry->link.tail = irq; | 652 | entry->link.tail = irq; |
673 | entry->msi_attrib.type = PCI_CAP_ID_MSI; | 653 | entry->msi_attrib.type = PCI_CAP_ID_MSI; |
674 | entry->msi_attrib.state = 0; /* Mark it not active */ | ||
675 | entry->msi_attrib.is_64 = is_64bit_address(control); | 654 | entry->msi_attrib.is_64 = is_64bit_address(control); |
676 | entry->msi_attrib.entry_nr = 0; | 655 | entry->msi_attrib.entry_nr = 0; |
677 | entry->msi_attrib.maskbit = is_mask_bit_support(control); | 656 | entry->msi_attrib.maskbit = is_mask_bit_support(control); |
@@ -744,7 +723,6 @@ static int msix_capability_init(struct pci_dev *dev, | |||
744 | j = entries[i].entry; | 723 | j = entries[i].entry; |
745 | entries[i].vector = irq; | 724 | entries[i].vector = irq; |
746 | entry->msi_attrib.type = PCI_CAP_ID_MSIX; | 725 | entry->msi_attrib.type = PCI_CAP_ID_MSIX; |
747 | entry->msi_attrib.state = 0; /* Mark it not active */ | ||
748 | entry->msi_attrib.is_64 = 1; | 726 | entry->msi_attrib.is_64 = 1; |
749 | entry->msi_attrib.entry_nr = j; | 727 | entry->msi_attrib.entry_nr = j; |
750 | entry->msi_attrib.maskbit = 1; | 728 | entry->msi_attrib.maskbit = 1; |
@@ -897,12 +875,12 @@ void pci_disable_msi(struct pci_dev* dev) | |||
897 | spin_unlock_irqrestore(&msi_lock, flags); | 875 | spin_unlock_irqrestore(&msi_lock, flags); |
898 | return; | 876 | return; |
899 | } | 877 | } |
900 | if (entry->msi_attrib.state) { | 878 | if (irq_has_action(dev->irq)) { |
901 | spin_unlock_irqrestore(&msi_lock, flags); | 879 | spin_unlock_irqrestore(&msi_lock, flags); |
902 | printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " | 880 | printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " |
903 | "free_irq() on MSI irq %d\n", | 881 | "free_irq() on MSI irq %d\n", |
904 | pci_name(dev), dev->irq); | 882 | pci_name(dev), dev->irq); |
905 | BUG_ON(entry->msi_attrib.state > 0); | 883 | BUG_ON(irq_has_action(dev->irq)); |
906 | } else { | 884 | } else { |
907 | default_irq = entry->msi_attrib.default_irq; | 885 | default_irq = entry->msi_attrib.default_irq; |
908 | spin_unlock_irqrestore(&msi_lock, flags); | 886 | spin_unlock_irqrestore(&msi_lock, flags); |
@@ -1035,17 +1013,16 @@ void pci_disable_msix(struct pci_dev* dev) | |||
1035 | 1013 | ||
1036 | temp = dev->irq; | 1014 | temp = dev->irq; |
1037 | if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { | 1015 | if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { |
1038 | int state, irq, head, tail = 0, warning = 0; | 1016 | int irq, head, tail = 0, warning = 0; |
1039 | unsigned long flags; | 1017 | unsigned long flags; |
1040 | 1018 | ||
1041 | irq = head = dev->irq; | 1019 | irq = head = dev->irq; |
1042 | dev->irq = temp; /* Restore pin IRQ */ | 1020 | dev->irq = temp; /* Restore pin IRQ */ |
1043 | while (head != tail) { | 1021 | while (head != tail) { |
1044 | spin_lock_irqsave(&msi_lock, flags); | 1022 | spin_lock_irqsave(&msi_lock, flags); |
1045 | state = msi_desc[irq]->msi_attrib.state; | ||
1046 | tail = msi_desc[irq]->link.tail; | 1023 | tail = msi_desc[irq]->link.tail; |
1047 | spin_unlock_irqrestore(&msi_lock, flags); | 1024 | spin_unlock_irqrestore(&msi_lock, flags); |
1048 | if (state) | 1025 | if (irq_has_action(irq)) |
1049 | warning = 1; | 1026 | warning = 1; |
1050 | else if (irq != head) /* Release MSI-X irq */ | 1027 | else if (irq != head) /* Release MSI-X irq */ |
1051 | msi_free_irq(dev, irq); | 1028 | msi_free_irq(dev, irq); |
@@ -1072,7 +1049,7 @@ void pci_disable_msix(struct pci_dev* dev) | |||
1072 | **/ | 1049 | **/ |
1073 | void msi_remove_pci_irq_vectors(struct pci_dev* dev) | 1050 | void msi_remove_pci_irq_vectors(struct pci_dev* dev) |
1074 | { | 1051 | { |
1075 | int state, pos, temp; | 1052 | int pos, temp; |
1076 | unsigned long flags; | 1053 | unsigned long flags; |
1077 | 1054 | ||
1078 | if (!pci_msi_enable || !dev) | 1055 | if (!pci_msi_enable || !dev) |
@@ -1081,14 +1058,11 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) | |||
1081 | temp = dev->irq; /* Save IOAPIC IRQ */ | 1058 | temp = dev->irq; /* Save IOAPIC IRQ */ |
1082 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 1059 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); |
1083 | if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { | 1060 | if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { |
1084 | spin_lock_irqsave(&msi_lock, flags); | 1061 | if (irq_has_action(dev->irq)) { |
1085 | state = msi_desc[dev->irq]->msi_attrib.state; | ||
1086 | spin_unlock_irqrestore(&msi_lock, flags); | ||
1087 | if (state) { | ||
1088 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " | 1062 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " |
1089 | "called without free_irq() on MSI irq %d\n", | 1063 | "called without free_irq() on MSI irq %d\n", |
1090 | pci_name(dev), dev->irq); | 1064 | pci_name(dev), dev->irq); |
1091 | BUG_ON(state > 0); | 1065 | BUG_ON(irq_has_action(dev->irq)); |
1092 | } else /* Release MSI irq assigned to this device */ | 1066 | } else /* Release MSI irq assigned to this device */ |
1093 | msi_free_irq(dev, dev->irq); | 1067 | msi_free_irq(dev, dev->irq); |
1094 | dev->irq = temp; /* Restore IOAPIC IRQ */ | 1068 | dev->irq = temp; /* Restore IOAPIC IRQ */ |
@@ -1101,11 +1075,10 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) | |||
1101 | irq = head = dev->irq; | 1075 | irq = head = dev->irq; |
1102 | while (head != tail) { | 1076 | while (head != tail) { |
1103 | spin_lock_irqsave(&msi_lock, flags); | 1077 | spin_lock_irqsave(&msi_lock, flags); |
1104 | state = msi_desc[irq]->msi_attrib.state; | ||
1105 | tail = msi_desc[irq]->link.tail; | 1078 | tail = msi_desc[irq]->link.tail; |
1106 | base = msi_desc[irq]->mask_base; | 1079 | base = msi_desc[irq]->mask_base; |
1107 | spin_unlock_irqrestore(&msi_lock, flags); | 1080 | spin_unlock_irqrestore(&msi_lock, flags); |
1108 | if (state) | 1081 | if (irq_has_action(irq)) |
1109 | warning = 1; | 1082 | warning = 1; |
1110 | else if (irq != head) /* Release MSI-X irq */ | 1083 | else if (irq != head) /* Release MSI-X irq */ |
1111 | msi_free_irq(dev, irq); | 1084 | msi_free_irq(dev, irq); |