diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2006-10-04 05:16:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 10:55:27 -0400 |
commit | 38bc0361303535c86f6b67b151a541728d7bdae6 (patch) | |
tree | 6a3939b1f7aea3b00fc4ecd72646fd8442c95766 /drivers/pci/msi.c | |
parent | 0366f8f7137deb072991e4c50769c6da31f8940c (diff) |
[PATCH] genirq: msi: refactor the msi_ops
The current msi_ops are short sighted in a number of ways, this patch attempts
to fix the glaring deficiences.
- Report in msi_ops if a 64bit address is needed in the msi message, so we
can fail 32bit only msi structures.
- Send and receive a full struct msi_msg in both setup and target. This is
a little cleaner and allows for architectures that need to modify the data
to retarget the msi interrupt to a different cpu.
- In target pass in the full cpu mask instead of just the first cpu in case
we can make use of the full cpu mask.
- Operate in terms of irqs and not vectors, currently there is still a 1-1
relationship but on architectures other than ia64 I expect this will change.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rajesh Shah <rajesh.shah@intel.com>
Cc: Andi Kleen <ak@muc.de>
Cc: "Protasevich, Natalie" <Natalie.Protasevich@UNISYS.com>
Cc: "Luck, Tony" <tony.luck@intel.com>
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 | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index cca6cb3ccdac..6d9de026e141 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -165,19 +165,17 @@ static void write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | #ifdef CONFIG_SMP | 167 | #ifdef CONFIG_SMP |
168 | static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) | 168 | static void set_msi_affinity(unsigned int irq, cpumask_t cpu_mask) |
169 | { | 169 | { |
170 | struct msi_desc *entry; | 170 | struct msi_desc *entry; |
171 | struct msi_msg msg; | 171 | struct msi_msg msg; |
172 | unsigned int irq = vector; | ||
173 | unsigned int dest_cpu = first_cpu(cpu_mask); | ||
174 | 172 | ||
175 | entry = (struct msi_desc *)msi_desc[vector]; | 173 | entry = msi_desc[irq]; |
176 | if (!entry || !entry->dev) | 174 | if (!entry || !entry->dev) |
177 | return; | 175 | return; |
178 | 176 | ||
179 | read_msi_msg(entry, &msg); | 177 | read_msi_msg(entry, &msg); |
180 | msi_ops->target(vector, dest_cpu, &msg.address_hi, &msg.address_lo); | 178 | msi_ops->target(irq, cpu_mask, &msg); |
181 | write_msi_msg(entry, &msg); | 179 | write_msi_msg(entry, &msg); |
182 | set_native_irq_info(irq, cpu_mask); | 180 | set_native_irq_info(irq, cpu_mask); |
183 | } | 181 | } |
@@ -701,14 +699,14 @@ static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry) | |||
701 | { | 699 | { |
702 | int status; | 700 | int status; |
703 | struct msi_msg msg; | 701 | struct msi_msg msg; |
704 | int pos, vector = dev->irq; | 702 | int pos; |
705 | u16 control; | 703 | u16 control; |
706 | 704 | ||
707 | pos = entry->msi_attrib.pos; | 705 | pos = entry->msi_attrib.pos; |
708 | pci_read_config_word(dev, msi_control_reg(pos), &control); | 706 | pci_read_config_word(dev, msi_control_reg(pos), &control); |
709 | 707 | ||
710 | /* Configure MSI capability structure */ | 708 | /* Configure MSI capability structure */ |
711 | status = msi_ops->setup(dev, vector, &msg.address_hi, &msg.address_lo, &msg.data); | 709 | status = msi_ops->setup(dev, dev->irq, &msg); |
712 | if (status < 0) | 710 | if (status < 0) |
713 | return status; | 711 | return status; |
714 | 712 | ||
@@ -863,10 +861,7 @@ static int msix_capability_init(struct pci_dev *dev, | |||
863 | /* Replace with MSI-X handler */ | 861 | /* Replace with MSI-X handler */ |
864 | irq_handler_init(PCI_CAP_ID_MSIX, vector, 1); | 862 | irq_handler_init(PCI_CAP_ID_MSIX, vector, 1); |
865 | /* Configure MSI-X capability structure */ | 863 | /* Configure MSI-X capability structure */ |
866 | status = msi_ops->setup(dev, vector, | 864 | status = msi_ops->setup(dev, vector, &msg); |
867 | &msg.address_hi, | ||
868 | &msg.address_lo, | ||
869 | &msg.data); | ||
870 | if (status < 0) | 865 | if (status < 0) |
871 | break; | 866 | break; |
872 | 867 | ||
@@ -928,6 +923,7 @@ int pci_msi_supported(struct pci_dev * dev) | |||
928 | int pci_enable_msi(struct pci_dev* dev) | 923 | int pci_enable_msi(struct pci_dev* dev) |
929 | { | 924 | { |
930 | int pos, temp, status; | 925 | int pos, temp, status; |
926 | u16 control; | ||
931 | 927 | ||
932 | if (pci_msi_supported(dev) < 0) | 928 | if (pci_msi_supported(dev) < 0) |
933 | return -EINVAL; | 929 | return -EINVAL; |
@@ -942,6 +938,10 @@ int pci_enable_msi(struct pci_dev* dev) | |||
942 | if (!pos) | 938 | if (!pos) |
943 | return -EINVAL; | 939 | return -EINVAL; |
944 | 940 | ||
941 | pci_read_config_word(dev, msi_control_reg(pos), &control); | ||
942 | if (!is_64bit_address(control) && msi_ops->needs_64bit_address) | ||
943 | return -EINVAL; | ||
944 | |||
945 | WARN_ON(!msi_lookup_vector(dev, PCI_CAP_ID_MSI)); | 945 | WARN_ON(!msi_lookup_vector(dev, PCI_CAP_ID_MSI)); |
946 | 946 | ||
947 | /* Check whether driver already requested for MSI-X vectors */ | 947 | /* Check whether driver already requested for MSI-X vectors */ |