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 *