[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |