diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-03-11 10:49:34 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-11 10:49:34 +0100 |
commit | d95c3578120e5bc4784069439f00ccb1b5f87717 (patch) | |
tree | c819de31de3983f3d69f223ede07667ff23bf7da /drivers/pci/msi.c | |
parent | ba1d755a36f66101aa88ac9ebb54694def6ec38d (diff) | |
parent | 78b020d035074fc3aa4d017353bb2c32e2aff56f (diff) |
Merge branch 'x86/core' into cpus4096
Diffstat (limited to 'drivers/pci/msi.c')
-rw-r--r-- | drivers/pci/msi.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index b4a90badd0a..baba2eb5367 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -103,6 +103,14 @@ static void msix_set_enable(struct pci_dev *dev, int enable) } } +static inline __attribute_const__ u32 msi_mask(unsigned x) +{ + /* Don't shift by >= width of type */ + if (x >= 5) + return 0xffffffff; + return (1 << (1 << x)) - 1; +} + static void msix_flush_writes(struct irq_desc *desc) { struct msi_desc *entry; @@ -398,21 +406,18 @@ static int msi_capability_init(struct pci_dev *dev) entry->msi_attrib.masked = 1; entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ entry->msi_attrib.pos = pos; - if (entry->msi_attrib.maskbit) { - entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, - entry->msi_attrib.is_64); - } entry->dev = dev; if (entry->msi_attrib.maskbit) { - unsigned int maskbits, temp; + unsigned int base, maskbits, temp; + + base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64); + entry->mask_base = (void __iomem *)(long)base; + /* All MSIs are unmasked by default, Mask them all */ - pci_read_config_dword(dev, - msi_mask_bits_reg(pos, entry->msi_attrib.is_64), - &maskbits); - temp = (1 << multi_msi_capable(control)); - temp = ((temp - 1) & ~temp); + pci_read_config_dword(dev, base, &maskbits); + temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1); maskbits |= temp; - pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits); + pci_write_config_dword(dev, base, maskbits); entry->msi_attrib.maskbits_mask = temp; } list_add_tail(&entry->list, &dev->msi_list); |