MSI: Fix for MSI to work when MSI-X fails
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 7 Apr 2014 19:24:59 +0000 (12:24 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 7 Apr 2014 19:24:59 +0000 (12:24 -0700)
Need to turn off the MSI-X enable bit.  You can only have either MSI or
MSI-X turned on at a time.

kern/arch/x86/msi.c

index 2188374..89ed9be 100644 (file)
@@ -284,6 +284,8 @@ static int __pci_msix_init(struct pci_device *p)
        p->msix_tbl_paddr = msix_get_capbar_paddr(p, c + 4);
        p->msix_pba_paddr = msix_get_capbar_paddr(p, c + 8);
        if (!p->msix_tbl_paddr || !p->msix_pba_paddr) {
+               /* disable msix, so we can possibly use msi */
+               pcidev_write16(p, c + 2, f & ~Msixenable);
                printk("MSI-X: Missing a tbl (%p) or PBA (%p) paddr!\n",
                       p->msix_tbl_paddr, p->msix_pba_paddr);
                return -1;
@@ -292,12 +294,14 @@ static int __pci_msix_init(struct pci_device *p)
        p->msix_tbl_vaddr = vmap_pmem_nocache(p->msix_tbl_paddr, p->msix_nr_vec *
                                              sizeof(struct msix_entry));
        if (!p->msix_tbl_vaddr) {
+               pcidev_write16(p, c + 2, f & ~Msixenable);
                printk("MSI-X: unable to vmap the Table!\n");
                return -1;
        }
        p->msix_pba_vaddr = vmap_pmem_nocache(p->msix_pba_paddr,
                                              ROUNDUP(p->msix_nr_vec, 8) / 8);
        if (!p->msix_pba_vaddr) {
+               pcidev_write16(p, c + 2, f & ~Msixenable);
                printk("MSI-X: unable to vmap the PBA!\n");
                vunmap_vmem(p->msix_tbl_paddr,
                        p->msix_nr_vec * sizeof(struct msix_entry));