Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: src/sys/external/bsd/drm2



Hi,

2017-03-01 13:30 GMT+09:00 Kimihiro Nonaka <nonakap%gmail.com@localhost>:

> 2017-03-01 3:21 GMT+09:00 Yorick Hardy <yorickhardy%gmail.com@localhost>:
>
>> 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?

Updated the patch.

Regards,
-- 
Kimihiro Nonaka
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..31282f88f49 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
@@ -30,10 +30,13 @@ __KERNEL_RCSID(0, "$NetBSD: nouveau_subdev_mc_base.c,v 1.5 2015/10/22 23:17:08 j
 #include <subdev/mc.h>
 #include <core/option.h>
 
-#if defined(__NetBSD__) && defined(__arm__)
+#if defined(__NetBSD__)
+#include <drm/drmP.h>
+#if defined(__arm__)
 /* XXX nouveau platform kludge */
 #include <arm/nvidia/tegra_intr.h>
 #endif
+#endif	/* __NetBSD__ */
 
 static inline u32
 nouveau_mc_intr_mask(struct nouveau_mc *pmc)
@@ -114,7 +117,8 @@ _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);
+		struct drm_device *dev = pci_get_drvdata(device->pdev);
+		(*dev->driver->bus->irq_uninstall)(dev, pmc->irq_cookie);
 #if defined(__arm__)
 	} else {
 		intr_disestablish(pmc->irq_cookie);
@@ -175,16 +179,12 @@ 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))
-			return -EIO;
-
-		pmc->irq_cookie = pci_intr_establish(pc, ih, IPL_VM,
-		    &nouveau_mc_intr, pmc);
-		if (pmc->irq_cookie == NULL)
-			return -EIO;
+		struct drm_device *dev = pci_get_drvdata(device->pdev);
+		ret = (*dev->driver->bus->irq_install)(dev, nouveau_mc_intr,
+		    IRQF_SHARED, "nouveau", pmc,
+		    (struct drm_bus_irq_cookie **)&pmc->irq_cookie);
+		if (ret < 0)
+			return ret;
 #if defined (__arm__)
 	} else {
 		pmc->irq_cookie = intr_establish(TEGRA_INTR_GPU,
diff --git a/sys/external/bsd/drm2/include/linux/pci.h b/sys/external/bsd/drm2/include/linux/pci.h
index d7d153deb3d..d9c6eb38a8f 100644
--- a/sys/external/bsd/drm2/include/linux/pci.h
+++ b/sys/external/bsd/drm2/include/linux/pci.h
@@ -155,6 +155,7 @@ struct pci_dev {
 	uint8_t			revision;
 	uint32_t		class;
 	bool			msi_enabled;
+	pci_intr_handle_t	*intr_handles;
 };
 
 static inline device_t
@@ -289,19 +290,28 @@ 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;
+
+	if (pci_msi_alloc_exact(pa, &pdev->intr_handles, 1))
+		return -EINVAL;
+
+	pdev->msi_enabled = 1;
+	return 0;
 }
 
 static inline void
 pci_disable_msi(struct pci_dev *pdev __unused)
 {
-	KASSERT(pdev->msi_enabled);
+	const struct pci_attach_args *const pa = &pdev->pd_pa;
+
+	if (pdev->intr_handles != NULL) {
+		pci_intr_release(pa->pa_pc, pdev->intr_handles, 1);
+		pdev->intr_handles = NULL;
+	}
+	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..caa1bd6694b 100644
--- a/sys/external/bsd/drm2/pci/drm_pci.c
+++ b/sys/external/bsd/drm2/pci/drm_pci.c
@@ -40,6 +40,11 @@ __KERNEL_RCSID(0, "$NetBSD: drm_pci.c,v 1.15 2017/02/27 23:52:05 nonaka Exp $");
 
 #include <drm/drmP.h>
 
+struct drm_bus_irq_cookie {
+	pci_intr_handle_t *intr_handles;
+	void *ih_cookie;
+};
+
 static int	drm_pci_get_irq(struct drm_device *);
 static int	drm_pci_irq_install(struct drm_device *,
 		    irqreturn_t (*)(void *), int, const char *, void *,
@@ -228,40 +233,48 @@ drm_pci_get_irq(struct drm_device *dev)
 
 static int
 drm_pci_irq_install(struct drm_device *dev, irqreturn_t (*handler)(void *),
-    int flags, const char *name, void *arg,
-    struct drm_bus_irq_cookie **cookiep)
+    int flags, const char *name, void *arg, 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];
+	struct drm_bus_irq_cookie *irq_cookie;
+
+	irq_cookie = kmem_alloc(sizeof(*irq_cookie), KM_SLEEP);
+	if (irq_cookie == NULL)
+		return -ENOMEM;
+
+	if (dev->pdev->msi_enabled) {
+		irq_cookie->intr_handles = dev->pdev->intr_handles;
+		dev->pdev->intr_handles = NULL;
+	} else {
+		if (pci_intx_alloc(pa, &irq_cookie->intr_handles))
+			return -ENOENT;
+	}
 
-	if (pci_intr_map(pa, &ih))
-		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);
-	if (ih_cookie == NULL) {
+	intrstr = pci_intr_string(pa->pa_pc, irq_cookie->intr_handles[0],
+	    intrbuf, sizeof(intrbuf));
+	irq_cookie->ih_cookie = pci_intr_establish_xname(pa->pa_pc,
+	    irq_cookie->intr_handles[0], IPL_DRM, handler, arg, name);
+	if (irq_cookie->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);
-	*cookiep = (struct drm_bus_irq_cookie *)ih_cookie;
+	aprint_normal_dev(dev->dev, "interrupting at %s (%s)\n", intrstr, name);
+	*cookiep = irq_cookie;
 	return 0;
 }
 
 static void
-drm_pci_irq_uninstall(struct drm_device *dev,
-    struct drm_bus_irq_cookie *cookie)
+drm_pci_irq_uninstall(struct drm_device *dev, struct drm_bus_irq_cookie *cookie)
 {
 	const struct pci_attach_args *pa = drm_pci_attach_args(dev);
 
-	pci_intr_disestablish(pa->pa_pc, (void *)cookie);
+	pci_intr_disestablish(pa->pa_pc, cookie->ih_cookie);
+	pci_intr_release(pa->pa_pc, cookie->intr_handles, 1);
+	kmem_free(cookie, sizeof(*cookie));
 }
 
 static const char *


Home | Main Index | Thread Index | Old Index