Hi,

2017-03-01 3:21 GMT+09:00 Yorick Hardy <yorickha...@gmail.com>:

> It is not obvious to me why the MSI changes were problematic.
> Do you have any ideas what went wrong?

It seem necessary to implement pci_enable_msi() and pci_disable_msi().
I tried again to write a new patch.
Could you try it?

Regards,
-- 
Kimihiro Nonaka
diff --git a/sys/external/bsd/drm2/dist/drm/nouveau/core/include/subdev/mc.h 
b/sys/external/bsd/drm2/dist/drm/nouveau/core/include/subdev/mc.h
index d914ed8827a..c1e8bd61af0 100644
--- a/sys/external/bsd/drm2/dist/drm/nouveau/core/include/subdev/mc.h
+++ b/sys/external/bsd/drm2/dist/drm/nouveau/core/include/subdev/mc.h
@@ -15,6 +15,7 @@ struct nouveau_mc {
        unsigned int irq;
 #ifdef __NetBSD__
        void *irq_cookie;
+       pci_intr_handle_t *intr_handles;
 #endif
 };
 
diff --git 
a/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mc/nouveau_subdev_mc_base.c
 
b/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mc/nouveau_subdev_mc_base.c
index 860690054a7..9371b127c55 100644
--- 
a/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mc/nouveau_subdev_mc_base.c
+++ 
b/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mc/nouveau_subdev_mc_base.c
@@ -114,7 +114,9 @@ _nouveau_mc_dtor(struct nouveau_object *object)
        struct nouveau_mc *pmc = (void *)object;
 #if defined(__NetBSD__)
        if (nv_device_is_pci(device)) {
-               pci_intr_disestablish(device->pdev->pd_pa.pa_pc, 
pmc->irq_cookie);
+               const struct pci_attach_args *pa = &device->pdev->pd_pa;
+               pci_intr_disestablish(pa->pa_pc, pmc->irq_cookie);
+               pci_intr_release(pa->pa_pc, pmc->intr_handles, 1);
 #if defined(__arm__)
        } else {
                intr_disestablish(pmc->irq_cookie);
@@ -175,16 +177,33 @@ nouveau_mc_create_(struct nouveau_object *parent, struct 
nouveau_object *engine,
 
 #if defined(__NetBSD__)
        if (nv_device_is_pci(device)) {
-               const pci_chipset_tag_t pc = device->pdev->pd_pa.pa_pc;
-               pci_intr_handle_t ih;
-
-               if (pci_intr_map(&device->pdev->pd_pa, &ih))
+               const struct pci_attach_args *pa = &device->pdev->pd_pa;
+               const pci_chipset_tag_t pc = pa->pa_pc;
+               char intrbuf[PCI_INTRSTR_LEN];
+               const char *intrstr;
+               int counts[PCI_INTR_TYPE_MSI + 1];
+
+               counts[PCI_INTR_TYPE_INTX] = pmc->use_msi ? 0 : 1;
+               counts[PCI_INTR_TYPE_MSI] = pmc->use_msi ? 1 : 0;
+               if (pci_intr_alloc(pa, &pmc->intr_handles, counts,
+                   PCI_INTR_TYPE_MSI))
                        return -EIO;
 
-               pmc->irq_cookie = pci_intr_establish(pc, ih, IPL_VM,
-                   &nouveau_mc_intr, pmc);
-               if (pmc->irq_cookie == NULL)
+               intrstr = pci_intr_string(pc, pmc->intr_handles[0], intrbuf,
+                   sizeof(intrbuf));
+               pmc->irq_cookie = pci_intr_establish_xname(pc,
+                   pmc->intr_handles[0], IPL_VM, nouveau_mc_intr, pmc,
+                   "nouveau");
+               if (pmc->irq_cookie == NULL) {
+                       aprint_error_dev(device->pdev->pd_dev,
+                           "couldn't establish interrupt at %s (nouveau)\n",
+                           intrstr);
+                       pci_intr_release(pa->pa_pc, pmc->intr_handles, 1);
                        return -EIO;
+               }
+
+               aprint_normal_dev(device->pdev->pd_dev,
+                   "interrupting at %s (nouveau)\n", intrstr);
 #if defined (__arm__)
        } else {
                pmc->irq_cookie = intr_establish(TEGRA_INTR_GPU,
diff --git a/sys/external/bsd/drm2/dist/include/drm/drmP.h 
b/sys/external/bsd/drm2/dist/include/drm/drmP.h
index d4b8ecb5fd7..b25b525ddcf 100644
--- a/sys/external/bsd/drm2/dist/include/drm/drmP.h
+++ b/sys/external/bsd/drm2/dist/include/drm/drmP.h
@@ -1268,6 +1268,7 @@ struct drm_device {
        bool irq_enabled;               /**< True if irq handler is enabled */
 #ifdef __NetBSD__
        struct drm_bus_irq_cookie *irq_cookie;
+       pci_intr_handle_t *intr_handles;
 #endif
        __volatile__ long context_flag; /**< Context swapping flag */
        int last_context;               /**< Last current context */
diff --git a/sys/external/bsd/drm2/include/linux/pci.h 
b/sys/external/bsd/drm2/include/linux/pci.h
index d7d153deb3d..c7b4aaf170e 100644
--- a/sys/external/bsd/drm2/include/linux/pci.h
+++ b/sys/external/bsd/drm2/include/linux/pci.h
@@ -289,19 +289,24 @@ pci_write_config_byte(struct pci_dev *pdev, int reg, 
uint8_t value)
        return 0;
 }
 
-/*
- * XXX pci msi
- */
 static inline int
 pci_enable_msi(struct pci_dev *pdev)
 {
-       return -ENOSYS;
+       const struct pci_attach_args *const pa = &pdev->pd_pa;
+       pci_intr_handle_t *ihps;
+
+       if (pci_msi_alloc_exact(pa, &ihps, 1))
+               return -EINVAL;
+
+       pci_intr_release(pa->pa_pc, ihps, 1);
+       pdev->msi_enabled = 1;
+       return 0;
 }
 
 static inline void
 pci_disable_msi(struct pci_dev *pdev __unused)
 {
-       KASSERT(pdev->msi_enabled);
+       pdev->msi_enabled = 0;
 }
 
 static inline void
diff --git a/sys/external/bsd/drm2/pci/drm_pci.c 
b/sys/external/bsd/drm2/pci/drm_pci.c
index ddfa79f445f..16a06bd3d96 100644
--- a/sys/external/bsd/drm2/pci/drm_pci.c
+++ b/sys/external/bsd/drm2/pci/drm_pci.c
@@ -232,25 +232,27 @@ drm_pci_irq_install(struct drm_device *dev, irqreturn_t 
(*handler)(void *),
     struct drm_bus_irq_cookie **cookiep)
 {
        const struct pci_attach_args *const pa = drm_pci_attach_args(dev);
-       pci_intr_handle_t ih;
        const char *intrstr;
        void *ih_cookie;
        char intrbuf[PCI_INTRSTR_LEN];
+       int counts[PCI_INTR_TYPE_MSI + 1];
 
-       if (pci_intr_map(pa, &ih))
+       counts[PCI_INTR_TYPE_INTX] = dev->pdev->msi_enabled ? 0 : 1;
+       counts[PCI_INTR_TYPE_MSI] = dev->pdev->msi_enabled ? 1 : 0;
+       if (pci_intr_alloc(pa, &dev->intr_handles, counts, PCI_INTR_TYPE_MSI))
                return -ENOENT;
 
-       intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf));
-       ih_cookie = pci_intr_establish(pa->pa_pc, ih, IPL_DRM, handler, arg);
+       intrstr = pci_intr_string(pa->pa_pc, dev->intr_handles[0], intrbuf,
+           sizeof(intrbuf));
+       ih_cookie = pci_intr_establish_xname(pa->pa_pc, dev->intr_handles[0],
+           IPL_DRM, handler, arg, name);
        if (ih_cookie == NULL) {
                aprint_error_dev(dev->dev,
-                   "couldn't establish interrupt at %s (%s)\n",
-                   intrstr, name);
+                   "couldn't establish interrupt at %s (%s)\n", intrstr, name);
                return -ENOENT;
        }
 
-       aprint_normal_dev(dev->dev, "interrupting at %s (%s)\n",
-           intrstr, name);
+       aprint_normal_dev(dev->dev, "interrupting at %s (%s)\n", intrstr, name);
        *cookiep = (struct drm_bus_irq_cookie *)ih_cookie;
        return 0;
 }
@@ -262,6 +264,7 @@ drm_pci_irq_uninstall(struct drm_device *dev,
        const struct pci_attach_args *pa = drm_pci_attach_args(dev);
 
        pci_intr_disestablish(pa->pa_pc, (void *)cookie);
+       pci_intr_release(pa->pa_pc, dev->intr_handles, 1);
 }
 
 static const char *

Reply via email to