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

[Xen-changelog] [xen master] x86/MSI: cleanup to prepare for multi-vector MSI



commit fe017c59c4c3ce189119954841a38ef0f1e415d0
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Apr 10 17:30:19 2013 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Apr 10 17:30:19 2013 +0200

    x86/MSI: cleanup to prepare for multi-vector MSI
    
    The major aspect being the removal of the overload of the MSI entry's
    mask_base field for MSI purposes - a proper union is being installed
    instead, tracking both the config space position needed and the number
    of vectors used (which is going to be 1 until the actual multi-vector
    MSI patches arrive).
    
    It also corrects misleading information from debug key 'M': When
    msi_get_mask_bit() returns a negative value, there's no mask bit, and
    hence output shouldn't give the impression there is.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/arch/x86/msi.c        |   41 ++++++++++++++++++++++-------------------
 xen/include/asm-x86/msi.h |    4 ++++
 2 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index 37ed8f8..6cc8f7a 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -348,18 +348,16 @@ static void msi_set_mask_bit(struct irq_desc *desc, int 
flag)
     switch (entry->msi_attrib.type) {
     case PCI_CAP_ID_MSI:
         if (entry->msi_attrib.maskbit) {
-            int pos;
             u32 mask_bits;
             u16 seg = entry->dev->seg;
             u8 bus = entry->dev->bus;
             u8 slot = PCI_SLOT(entry->dev->devfn);
             u8 func = PCI_FUNC(entry->dev->devfn);
 
-            pos = (long)entry->mask_base;
-            mask_bits = pci_conf_read32(seg, bus, slot, func, pos);
+            mask_bits = pci_conf_read32(seg, bus, slot, func, entry->msi.mpos);
             mask_bits &= ~(1);
             mask_bits |= flag;
-            pci_conf_write32(seg, bus, slot, func, pos, mask_bits);
+            pci_conf_write32(seg, bus, slot, func, entry->msi.mpos, mask_bits);
         }
         break;
     case PCI_CAP_ID_MSIX:
@@ -385,7 +383,7 @@ static int msi_get_mask_bit(const struct msi_desc *entry)
         return pci_conf_read32(entry->dev->seg, entry->dev->bus,
                                PCI_SLOT(entry->dev->devfn),
                                PCI_FUNC(entry->dev->devfn),
-                               (unsigned long)entry->mask_base) & 1;
+                               entry->msi.mpos) & 1;
     case PCI_CAP_ID_MSIX:
         return readl(entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET) & 1;
     }
@@ -530,6 +528,7 @@ static int msi_capability_init(struct pci_dev *dev,
 {
     struct msi_desc *entry;
     int pos;
+    unsigned int maxvec, mpos;
     u16 control, seg = dev->seg;
     u8 bus = dev->bus;
     u8 slot = PCI_SLOT(dev->devfn);
@@ -538,6 +537,9 @@ static int msi_capability_init(struct pci_dev *dev,
     ASSERT(spin_is_locked(&pcidevs_lock));
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
     control = pci_conf_read16(seg, bus, slot, func, msi_control_reg(pos));
+    maxvec = multi_msi_capable(control);
+    control &= ~PCI_MSI_FLAGS_QSIZE;
+
     /* MSI Entry Initialization */
     msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */
 
@@ -551,23 +553,20 @@ static int msi_capability_init(struct pci_dev *dev,
     entry->msi_attrib.maskbit = is_mask_bit_support(control);
     entry->msi_attrib.masked = 1;
     entry->msi_attrib.pos = pos;
+    mpos = msi_mask_bits_reg(pos, is_64bit_address(control));
+    entry->msi.nvec = 1;
     entry->irq = irq;
     if ( is_mask_bit_support(control) )
-        entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
-                                                                   
is_64bit_address(control));
+        entry->msi.mpos = mpos;
     entry->dev = dev;
     if ( entry->msi_attrib.maskbit )
     {
-        unsigned int maskbits, temp;
+        u32 maskbits;
+
         /* All MSIs are unmasked by default, Mask them all */
-        maskbits = pci_conf_read32(seg, bus, slot, func,
-                                   msi_mask_bits_reg(pos, 
is_64bit_address(control)));
-        temp = (1 << multi_msi_capable(control));
-        temp = ((temp - 1) & ~temp);
-        maskbits |= temp;
-        pci_conf_write32(seg, bus, slot, func,
-                         msi_mask_bits_reg(pos, is_64bit_address(control)),
-                         maskbits);
+        maskbits = pci_conf_read32(seg, bus, slot, func, mpos);
+        maskbits |= ~(u32)0 >> (32 - maxvec);
+        pci_conf_write32(seg, bus, slot, func, mpos, maskbits);
     }
     list_add_tail(&entry->list, &dev->msi_list);
 
@@ -1204,7 +1203,7 @@ static void dump_msi(unsigned char key)
         struct irq_desc *desc = irq_to_desc(irq);
         const struct msi_desc *entry;
         u32 addr, data, dest32;
-        char mask;
+        signed char mask;
         struct msi_attrib attr;
         unsigned long flags;
         const char *type = "???";
@@ -1239,12 +1238,16 @@ static void dump_msi(unsigned char key)
         dest32 = entry->msg.dest32;
         attr = entry->msi_attrib;
         if ( entry->msi_attrib.type )
-            mask = msi_get_mask_bit(entry) ? '1' : '0';
+            mask = msi_get_mask_bit(entry);
         else
-            mask = '?';
+            mask = -1;
 
         spin_unlock_irqrestore(&desc->lock, flags);
 
+        if ( mask >= 0 )
+            mask += '0';
+        else
+            mask = '?';
         printk(" %-6s%4u vec=%02x%7s%6s%3sassert%5s%7s"
                " dest=%08x mask=%d/%d/%c\n",
                type, irq,
diff --git a/xen/include/asm-x86/msi.h b/xen/include/asm-x86/msi.h
index 6fe67dc..d288cfc 100644
--- a/xen/include/asm-x86/msi.h
+++ b/xen/include/asm-x86/msi.h
@@ -100,6 +100,10 @@ struct msi_desc {
 
        union {
                void __iomem *mask_base;/* va for the entry in mask table */
+               struct {
+                       unsigned int nvec;/* number of vectors            */
+                       unsigned int mpos;/* location of mask register    */
+               } msi;
                unsigned int hpet_id;   /* HPET (dev is NULL)             */
        };
        struct pci_dev *dev;
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
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®.