Hi,

2015-04-27 18:19 GMT+09:00 Tobias Nygren <[email protected]>:

> How can I test this in context of kern/49663 (iwm(4) device that only
> works when MSI is enabled)? If someone can make an updated patch for
> iwm I can test it on hardware that has the problem.

Please try the attached patch.

Regards,
-- 
NONAKA Kimihiro
Index: if_iwm.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.30
diff -u -r1.30 if_iwm.c
--- if_iwm.c    15 Apr 2015 05:40:48 -0000      1.30
+++ if_iwm.c    27 Apr 2015 10:36:50 -0000
@@ -6628,7 +6628,9 @@
 {
        struct iwm_softc *sc = device_private(self);
        struct pci_attach_args *pa = aux;
+#ifndef __HAVE_PCI_MSI_MSIX
        pci_intr_handle_t ih;
+#endif
        pcireg_t reg, memtype;
        const char *intrstr;
        int error;
@@ -6676,14 +6678,56 @@
        }
 
        /* Install interrupt handler. */
+       sc->sc_intr_type = IWM_INTR_INTX;
+#ifdef __HAVE_PCI_MSI_MSIX
+       error = ENODEV;
+       if (pci_msix_count(pa) > 0) {
+               error = pci_msix_alloc_exact(pa, &sc->sc_pihp, 1);
+               if (error == 0)
+                       sc->sc_intr_type = IWM_INTR_MSIX;
+       }
+       if (error != 0 && pci_msi_count(pa) > 0) {
+               error = pci_msi_alloc_exact(pa, &sc->sc_pihp, 1);
+               if (error == 0)
+                       sc->sc_intr_type = IWM_INTR_MSI;
+       }
+       if (error != 0) {
+               if (pci_intx_alloc(pa, &sc->sc_pihp)) {
+                       aprint_error_dev(self, "can't map interrupt\n");
+                       return;
+               }
+       }
+#else  /* !__HAVE_PCI_MSI_MSIX */
        if (pci_intr_map(pa, &ih)) {
                aprint_error_dev(self, "can't map interrupt\n");
                return;
        }
+#endif /* __HAVE_PCI_MSI_MSIX */
 
        char intrbuf[PCI_INTRSTR_LEN];
+#ifdef __HAVE_PCI_MSI_MSIX
+       intrstr = pci_intr_string(sc->sc_pct, sc->sc_pihp[0], intrbuf,
+           sizeof(intrbuf));
+       switch (sc->sc_intr_type) {
+       case IWM_INTR_MSIX:
+               sc->sc_ih = pci_msix_establish(sc->sc_pct, sc->sc_pihp[0],
+                   IPL_NET, iwm_intr, sc);
+               break;
+
+       case IWM_INTR_MSI:
+               sc->sc_ih = pci_msi_establish(sc->sc_pct, sc->sc_pihp[0],
+                   IPL_NET, iwm_intr, sc);
+               break;
+
+       case IWM_INTR_INTX:
+               sc->sc_ih = pci_intr_establish(sc->sc_pct, sc->sc_pihp[0],
+                   IPL_NET, iwm_intr, sc);
+               break;
+       }
+#else  /* !__HAVE_PCI_MSI_MSIX */
        intrstr = pci_intr_string(sc->sc_pct, ih, intrbuf, sizeof(intrbuf));
        sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET, iwm_intr, sc);
+#endif /* __HAVE_PCI_MSI_MSIX */
        if (sc->sc_ih == NULL) {
                aprint_error_dev(self, "can't establish interrupt");
                if (intrstr != NULL)

Reply via email to