On Fri, 2009-05-08 at 07:13 -0600, Matthew Wilcox 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 of the mask > register to after MSI-X is enabled. > > Reported-by: David S. Miller <davem@xxxxxxxxxxxxx> > Tested-by: David S. Miller <davem@xxxxxxxxxxxxx> > Reviewed-by: David S. Miller <davem@xxxxxxxxxxxxx> > Signed-off-by: Matthew Wilcox <willy@xxxxxxxxxxxxxxx> > > diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c > index 6f2e629..3627732 100644 > --- a/drivers/pci/msi.c > +++ b/drivers/pci/msi.c > @@ -455,8 +455,6 @@ 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); 158 static void msix_mask_irq(struct msi_desc *desc, u32 flag) 159 { 160 u32 mask_bits = desc->masked; ... 165 writel(mask_bits, desc->mask_base + offset); So I guess this device is just silently ignoring that write? And aren't we violating the spec by writing 0x1 into the device there (assuming desc->masked is 0x0 from the kzalloc), ie. we're supposed to read and write back the reserved bits unchanged. (§ 6.8.2.9?) > @@ -493,6 +491,12 @@ static int msix_capability_init(struct pci_dev *dev, > msix_set_enable(dev, 1); > dev->msix_enabled = 1; Are we safe if we take an interrupt 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); > + } > + > return 0; > } > cheers
Attachment:
signature.asc
Description: This is a digitally signed message part