On Wed, 2009-05-13 at 14:06 +0900, Hidetoshi Seto wrote: > The NIU device refuses to allow accesses to MSI-X registers before MSI-X > is enabled. This patch fixes the problem by moving the read & write the > mask register (for preserved bits) to after MSI-X is enabled. > > Reported-by: David S. Miller > Signed-off-by: Hidetoshi Seto > --- > drivers/pci/msi.c | 21 ++++++++++++++++++--- > 1 files changed, 18 insertions(+), 3 deletions(-) > > diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c > index 6f2e629..44085e0 100644 > --- a/drivers/pci/msi.c > +++ b/drivers/pci/msi.c > @@ -455,9 +455,7 @@ static int msix_capability_init(struct pci_dev *dev, > entry->msi_attrib.default_irq = dev->irq; > entry->msi_attrib.pos = pos; > entry->mask_base = base; > - entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE + > - PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); > - msix_mask_irq(entry, 1); > + entry->masked = 1; > > list_add_tail(&entry->list, &dev->msi_list); > } > @@ -493,6 +491,23 @@ static int msix_capability_init(struct pci_dev *dev, > msix_set_enable(dev, 1); > dev->msix_enabled = 1; > > + /* > + * The states of Reserved bits[31:01] of Vector Control for MSI-X > + * Table Entries must be 0. However, for potential future use, > + * software must preserve the value of these reserved bits. > + * Refer PCI spec 3.0, 6.8.2.9. > + * > + * Note that there are some device that refuses access to MSI-X > + * Table Entries before MSI-X is enabled. Therefore we do it here. > + */ > + list_for_each_entry(entry, &dev->msi_list, list) { > + int vector = entry->msi_attrib.entry_nr; > + entry->masked = readl(base + vector * PCI_MSIX_ENTRY_SIZE + > + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); > + /* Make sure it is masked */ > + msix_mask_irq(entry, 1); > + } > + > return 0; > } That looks better to me, hopefully it fixes DaveM's device too :) Acked-by: Michael Ellerman cheers