[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86: split MSI IRQ chip



# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxx>
# Date 1316302012 -3600
# Node ID a422e2a4451e16dc791b293f41966b842fa4781d
# Parent  2dab09bcec8136a5962e71beed1f5dc06275a6b1
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@xxxxxxxx>
---


diff -r 2dab09bcec81 -r a422e2a4451e xen/arch/x86/hpet.c
--- a/xen/arch/x86/hpet.c       Sun Sep 18 00:25:57 2011 +0100
+++ b/xen/arch/x86/hpet.c       Sun Sep 18 00:26:52 2011 +0100
@@ -312,7 +312,7 @@
 {
     struct msi_msg msg;
 
-    msi_compose_msg(desc->irq, &msg);
+    msi_compose_msg(desc, &msg);
     hpet_msi_write(desc->action->dev_id, &msg);
 }
 
diff -r 2dab09bcec81 -r a422e2a4451e xen/arch/x86/hvm/vmsi.c
--- a/xen/arch/x86/hvm/vmsi.c   Sun Sep 18 00:25:57 2011 +0100
+++ b/xen/arch/x86/hvm/vmsi.c   Sun Sep 18 00:26:52 2011 +0100
@@ -382,7 +382,7 @@
         return r;
     }
 
-    if ( irq_desc->handler != &pci_msi_type )
+    if ( !irq_desc->msi_desc )
         goto out;
 
     msi_desc = irq_desc->msi_desc;
@@ -426,7 +426,7 @@
     if ( !irq_desc )
         return;
 
-    if ( irq_desc->handler != &pci_msi_type )
+    if ( !irq_desc->msi_desc )
         goto out;
 
     msi_desc = irq_desc->msi_desc;
diff -r 2dab09bcec81 -r a422e2a4451e xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Sun Sep 18 00:25:57 2011 +0100
+++ b/xen/arch/x86/io_apic.c    Sun Sep 18 00:26:52 2011 +0100
@@ -1882,44 +1882,6 @@
     .set_affinity      = set_ioapic_affinity_irq,
 };
 
-static unsigned int startup_msi_irq(struct irq_desc *desc)
-{
-    unmask_msi_irq(desc);
-    return 0;
-}
-
-static void ack_msi_irq(struct irq_desc *desc)
-{
-    irq_complete_move(desc);
-    move_native_irq(desc);
-
-    if ( msi_maskable_irq(desc->msi_desc) )
-        ack_APIC_irq(); /* ACKTYPE_NONE */
-}
-
-static void end_msi_irq(struct irq_desc *desc, u8 vector)
-{
-    if ( !msi_maskable_irq(desc->msi_desc) )
-        ack_APIC_irq(); /* ACKTYPE_EOI */
-}
-
-#define shutdown_msi_irq mask_msi_irq
-
-/*
- * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI or MSI-X Capability Structure.
- */
-hw_irq_controller pci_msi_type = {
-    .typename   = "PCI-MSI",
-    .startup    = startup_msi_irq,
-    .shutdown   = shutdown_msi_irq,
-    .enable        = unmask_msi_irq,
-    .disable    = mask_msi_irq,
-    .ack        = ack_msi_irq,
-    .end        = end_msi_irq,
-    .set_affinity   = set_msi_affinity,
-};
-
 static inline void init_IO_APIC_traps(void)
 {
     int irq;
diff -r 2dab09bcec81 -r a422e2a4451e xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Sun Sep 18 00:25:57 2011 +0100
+++ b/xen/arch/x86/irq.c        Sun Sep 18 00:26:52 2011 +0100
@@ -1304,7 +1304,7 @@
      * MSIs are treated as edge-triggered interrupts, except
      * when there is no proper way to mask them.
      */
-    if ( desc->handler == &pci_msi_type )
+    if ( desc->msi_desc )
         return msi_maskable_irq(desc->msi_desc) ? ACKTYPE_NONE : ACKTYPE_EOI;
 
     /*
@@ -1723,7 +1723,7 @@
         if ( desc->handler != &no_irq_type )
             dprintk(XENLOG_G_ERR, "dom%d: irq %d in use\n",
                     d->domain_id, irq);
-        desc->handler = &pci_msi_type;
+        setup_msi_handler(desc, msi_desc);
 
         if ( opt_irq_vector_map == OPT_IRQ_VECTOR_MAP_PERDEV
              && !desc->chip_data->used_vectors )
@@ -1739,7 +1739,7 @@
         }
 
         set_domain_irq_pirq(d, irq, info);
-        setup_msi_irq(msi_desc, irq);
+        setup_msi_irq(desc);
         spin_unlock_irqrestore(&desc->lock, flags);
     }
     else
@@ -1807,6 +1807,12 @@
             radix_tree_int_to_ptr(-pirq));
     }
 
+    if ( msi_desc )
+    {
+        desc->handler = &no_irq_type;
+        desc->msi_desc = NULL;
+    }
+
     spin_unlock_irqrestore(&desc->lock, flags);
     if (msi_desc)
         msi_free_irq(msi_desc);
@@ -1819,9 +1825,6 @@
         dprintk(XENLOG_G_ERR, "dom%d: could not deny access to irq %d\n",
                 d->domain_id, pirq);
 
-    if ( desc->handler == &pci_msi_type )
-        desc->handler = &no_irq_type;
-
  done:
     return ret;
 }
diff -r 2dab09bcec81 -r a422e2a4451e xen/arch/x86/msi.c
--- a/xen/arch/x86/msi.c        Sun Sep 18 00:25:57 2011 +0100
+++ b/xen/arch/x86/msi.c        Sun Sep 18 00:26:52 2011 +0100
@@ -120,11 +120,11 @@
 /*
  * 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 @@
         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 @@
     }
 }
 
-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 @@
     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 @@
     return entry;
 }
 
-int setup_msi_irq(struct msi_desc *msidesc, int irq)
+void setup_msi_handler(struct irq_desc *desc, struct msi_desc *msidesc)
+{
+    desc->msi_desc = msidesc;
+    desc->handler = msi_maskable_irq(msidesc) ? &pci_msi_maskable
+                                              : &pci_msi_nonmaskable;
+}
+
+void setup_msi_irq(struct irq_desc *desc)
 {
     struct msi_msg msg;
 
-    msi_compose_msg(irq, &msg);
-    set_irq_msi(msidesc);
-    write_msi_msg(irq_desc[irq].msi_desc, &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 @@
     {
         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 @@
 
         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 @@
                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);
     }
 }
 
diff -r 2dab09bcec81 -r a422e2a4451e xen/include/asm-x86/msi.h
--- a/xen/include/asm-x86/msi.h Sun Sep 18 00:25:57 2011 +0100
+++ b/xen/include/asm-x86/msi.h Sun Sep 18 00:26:52 2011 +0100
@@ -74,15 +74,14 @@
        u32     dest32;         /* used when Interrupt Remapping with EIM is 
enabled */
 };
 
+struct irq_desc;
 struct msi_desc;
 /* Helper functions */
-extern void mask_msi_irq(struct irq_desc *);
-extern void unmask_msi_irq(struct irq_desc *);
-extern void set_msi_affinity(struct irq_desc *, const cpumask_t *);
 extern int pci_enable_msi(struct msi_info *msi, struct msi_desc **desc);
 extern void pci_disable_msi(struct msi_desc *desc);
 extern void pci_cleanup_msi(struct pci_dev *pdev);
-extern int setup_msi_irq(struct msi_desc *desc, int irq);
+extern void setup_msi_handler(struct irq_desc *, struct msi_desc *);
+extern void setup_msi_irq(struct irq_desc *);
 extern void teardown_msi_irq(int irq);
 extern int msi_free_vector(struct msi_desc *entry);
 extern int pci_restore_msi_state(struct pci_dev *pdev);
@@ -90,14 +89,14 @@
 extern unsigned int pci_msix_get_table_len(struct pci_dev *pdev);
 
 struct msi_desc {
-       struct {
+       struct msi_attrib {
                __u8    type    : 5;    /* {0: unused, 5h:MSI, 11h:MSI-X} */
                __u8    maskbit : 1;    /* mask-pending bit supported ?   */
                __u8    masked  : 1;
                __u8    is_64   : 1;    /* Address size: 0=32bit 1=64bit  */
                __u8    pos;            /* Location of the msi capability */
                __u16   entry_nr;       /* specific enabled entry         */
-       }msi_attrib;
+       } msi_attrib;
 
        struct list_head list;
 
@@ -123,8 +122,6 @@
  */
 #define NR_HP_RESERVED_VECTORS         20
 
-extern const struct hw_interrupt_type pci_msi_type;
-
 #define PCI_MSIX_ENTRY_SIZE                    16
 #define  PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET      0
 #define  PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET      4
@@ -222,5 +219,6 @@
        __u32   hi_address;
 } __attribute__ ((packed));
 
-void msi_compose_msg(int irq, struct msi_msg *);
+void msi_compose_msg(struct irq_desc *, struct msi_msg *);
+
 #endif /* __ASM_MSI_H */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.