aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/msi.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2011-09-18 00:26:52 +0100
committerJan Beulich <jbeulich@suse.com>2011-09-18 00:26:52 +0100
commit1b0061ac2b57297e7d7211ce6f4e1b197b8e0ec2 (patch)
tree4bb3b14eb7af3223ce36a09fbf9de90776aa3919 /xen/arch/x86/msi.c
parentac4afd4aaac5f8e6e706f97bbfb0bd925577ed15 (diff)
downloadxen-1b0061ac2b57297e7d7211ce6f4e1b197b8e0ec2.tar.gz
xen-1b0061ac2b57297e7d7211ce6f4e1b197b8e0ec2.tar.bz2
xen-1b0061ac2b57297e7d7211ce6f4e1b197b8e0ec2.zip
x86: split MSI IRQ chip
With the .end() accessor having become optional and noting that several of the accessors' behavior really depends on the result of msi_maskable_irq(), the splits the MSI IRQ chip type into two - one for the maskable ones, and the other for the (MSI only) non-maskable ones. At once the implementation of those methods gets moved from io_apic.c to msi.c. Signed-off-by: Jan Beulich <jbeulich@suse.com>
Diffstat (limited to 'xen/arch/x86/msi.c')
-rw-r--r--xen/arch/x86/msi.c110
1 files changed, 77 insertions, 33 deletions
diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index 5ff4e3d098..c6f938503e 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -120,11 +120,11 @@ static void msix_put_fixmap(struct pci_dev *dev, int idx)
/*
* MSI message composition
*/
-void msi_compose_msg(int irq, struct msi_msg *msg)
+void msi_compose_msg(struct irq_desc *desc, struct msi_msg *msg)
{
unsigned dest;
cpumask_t domain;
- struct irq_cfg *cfg = irq_cfg(irq);
+ struct irq_cfg *cfg = desc->chip_data;
int vector = cfg->vector;
domain = cfg->cpu_mask;
@@ -205,19 +205,6 @@ static void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
iommu_read_msi_from_ire(entry, msg);
}
-static int set_irq_msi(struct msi_desc *entry)
-{
- if ( entry->irq >= nr_irqs )
- {
- dprintk(XENLOG_ERR, "Trying to install msi data for irq %d\n",
- entry->irq);
- return -EINVAL;
- }
-
- irq_desc[entry->irq].msi_desc = entry;
- return 0;
-}
-
static void write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
entry->msg = *msg;
@@ -266,7 +253,7 @@ static void write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
}
}
-void set_msi_affinity(struct irq_desc *desc, const cpumask_t *mask)
+static void set_msi_affinity(struct irq_desc *desc, const cpumask_t *mask)
{
struct msi_msg msg;
unsigned int dest;
@@ -387,16 +374,65 @@ static int msi_get_mask_bit(const struct msi_desc *entry)
return -1;
}
-void mask_msi_irq(struct irq_desc *desc)
+static void mask_msi_irq(struct irq_desc *desc)
{
msi_set_mask_bit(desc, 1);
}
-void unmask_msi_irq(struct irq_desc *desc)
+static void unmask_msi_irq(struct irq_desc *desc)
{
msi_set_mask_bit(desc, 0);
}
+static unsigned int startup_msi_irq(struct irq_desc *desc)
+{
+ unmask_msi_irq(desc);
+ return 0;
+}
+
+static void ack_nonmaskable_msi_irq(struct irq_desc *desc)
+{
+ irq_complete_move(desc);
+ move_native_irq(desc);
+}
+
+static void ack_maskable_msi_irq(struct irq_desc *desc)
+{
+ ack_nonmaskable_msi_irq(desc);
+ ack_APIC_irq(); /* ACKTYPE_NONE */
+}
+
+static void end_nonmaskable_msi_irq(struct irq_desc *desc, u8 vector)
+{
+ ack_APIC_irq(); /* ACKTYPE_EOI */
+}
+
+/*
+ * IRQ chip for MSI PCI/PCI-X/PCI-Express devices,
+ * which implement the MSI or MSI-X capability structure.
+ */
+static hw_irq_controller pci_msi_maskable = {
+ .typename = "PCI-MSI/-X",
+ .startup = startup_msi_irq,
+ .shutdown = mask_msi_irq,
+ .enable = unmask_msi_irq,
+ .disable = mask_msi_irq,
+ .ack = ack_maskable_msi_irq,
+ .set_affinity = set_msi_affinity
+};
+
+/* As above, but without having masking capability. */
+static hw_irq_controller pci_msi_nonmaskable = {
+ .typename = "PCI-MSI",
+ .startup = irq_startup_none,
+ .shutdown = irq_shutdown_none,
+ .enable = irq_enable_none,
+ .disable = irq_disable_none,
+ .ack = ack_nonmaskable_msi_irq,
+ .end = end_nonmaskable_msi_irq,
+ .set_affinity = set_msi_affinity
+};
+
static struct msi_desc* alloc_msi_entry(void)
{
struct msi_desc *entry;
@@ -412,15 +448,19 @@ static struct msi_desc* alloc_msi_entry(void)
return entry;
}
-int setup_msi_irq(struct msi_desc *msidesc, int irq)
+void setup_msi_handler(struct irq_desc *desc, struct msi_desc *msidesc)
{
- struct msi_msg msg;
+ desc->msi_desc = msidesc;
+ desc->handler = msi_maskable_irq(msidesc) ? &pci_msi_maskable
+ : &pci_msi_nonmaskable;
+}
- msi_compose_msg(irq, &msg);
- set_irq_msi(msidesc);
- write_msi_msg(irq_desc[irq].msi_desc, &msg);
+void setup_msi_irq(struct irq_desc *desc)
+{
+ struct msi_msg msg;
- return 0;
+ msi_compose_msg(desc, &msg);
+ write_msi_msg(desc->msi_desc, &msg);
}
int msi_free_irq(struct msi_desc *entry)
@@ -1022,19 +1062,20 @@ static void dump_msi(unsigned char key)
{
struct irq_desc *desc = irq_to_desc(irq);
const struct msi_desc *entry;
- u32 addr, data;
+ u32 addr, data, dest32;
+ int mask;
+ struct msi_attrib attr;
unsigned long flags;
char type;
spin_lock_irqsave(&desc->lock, flags);
entry = desc->msi_desc;
- type = desc->handler == &pci_msi_type && entry;
-
- spin_unlock_irqrestore(&desc->lock, flags);
-
- if ( !type )
+ if ( !entry )
+ {
+ spin_unlock_irqrestore(&desc->lock, flags);
continue;
+ }
switch ( entry->msi_attrib.type )
{
@@ -1045,6 +1086,11 @@ static void dump_msi(unsigned char key)
data = entry->msg.data;
addr = entry->msg.address_lo;
+ dest32 = entry->msg.dest32;
+ attr = entry->msi_attrib;
+ mask = msi_get_mask_bit(entry);
+
+ spin_unlock_irqrestore(&desc->lock, flags);
printk(" MSI%c %4u vec=%02x%7s%6s%3sassert%5s%7s"
" dest=%08x mask=%d/%d/%d\n",
@@ -1055,9 +1101,7 @@ static void dump_msi(unsigned char key)
data & MSI_DATA_LEVEL_ASSERT ? "" : "de",
addr & MSI_ADDR_DESTMODE_LOGIC ? "log" : "phys",
addr & MSI_ADDR_REDIRECTION_LOWPRI ? "lowest" : "cpu",
- entry->msg.dest32,
- entry->msi_attrib.maskbit, entry->msi_attrib.masked,
- msi_get_mask_bit(entry));
+ dest32, attr.maskbit, attr.masked, mask);
}
}