aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/msi.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-10-04 05:16:34 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:27 -0400
commit38bc0361303535c86f6b67b151a541728d7bdae6 (patch)
tree6a3939b1f7aea3b00fc4ecd72646fd8442c95766 /drivers/pci/msi.c
parent0366f8f7137deb072991e4c50769c6da31f8940c (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.c22
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
168static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) 168static 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)
928int pci_enable_msi(struct pci_dev* dev) 923int 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 */