Module Name:    src
Committed By:   riastradh
Date:           Mon Aug 27 15:22:55 UTC 2018

Modified Files:
        src/sys/external/bsd/drm2/dist/drm: drm_gem.c drm_internal.h
            drm_ioctl.c drm_prime.c
        src/sys/external/bsd/drm2/dist/drm/amd/amdgpu: amdgpu_display.c
            amdgpu_drv.c amdgpu_gem.c amdgpu_ttm.c
        src/sys/external/bsd/drm2/dist/drm/i915: i915_drv.c i915_drv.h
            i915_gem.c i915_gem_dmabuf.c
        src/sys/external/bsd/drm2/dist/drm/nouveau: nouveau_bo.c nouveau_drm.c
            nouveau_gem.c
        src/sys/external/bsd/drm2/dist/drm/radeon: radeon_display.c
            radeon_drv.c radeon_gem.c radeon_ttm.c
        src/sys/external/bsd/drm2/dist/include/drm: drmP.h drm_gem.h
        src/sys/external/bsd/drm2/dist/uapi/drm: drm.h
        src/sys/external/bsd/drm2/drm: drm_fops.c files.drmkms
        src/sys/external/bsd/drm2/i915drm: files.i915drmkms
        src/sys/external/bsd/drm2/include/linux: dma-buf.h module.h
        src/sys/external/bsd/drm2/linux: files.drmkms_linux
        src/sys/external/bsd/drm2/nouveau: files.nouveau
        src/sys/external/bsd/drm2/radeon: files.radeon
Added Files:
        src/sys/external/bsd/drm2/linux: linux_dma_buf.c

Log Message:
Draft support for drm prime.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/external/bsd/drm2/dist/drm/drm_gem.c
cvs rdiff -u -r1.2 -r1.3 src/sys/external/bsd/drm2/dist/drm/drm_internal.h \
    src/sys/external/bsd/drm2/dist/drm/drm_prime.c
cvs rdiff -u -r1.8 -r1.9 src/sys/external/bsd/drm2/dist/drm/drm_ioctl.c
cvs rdiff -u -r1.3 -r1.4 \
    src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_display.c \
    src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_gem.c \
    src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_ttm.c
cvs rdiff -u -r1.4 -r1.5 \
    src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_drv.c
cvs rdiff -u -r1.14 -r1.15 src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.c
cvs rdiff -u -r1.26 -r1.27 src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h
cvs rdiff -u -r1.53 -r1.54 src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c
cvs rdiff -u -r1.2 -r1.3 \
    src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_dmabuf.c
cvs rdiff -u -r1.11 -r1.12 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c
cvs rdiff -u -r1.14 -r1.15 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c
cvs rdiff -u -r1.7 -r1.8 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c
cvs rdiff -u -r1.8 -r1.9 \
    src/sys/external/bsd/drm2/dist/drm/radeon/radeon_display.c
cvs rdiff -u -r1.7 -r1.8 \
    src/sys/external/bsd/drm2/dist/drm/radeon/radeon_drv.c
cvs rdiff -u -r1.5 -r1.6 \
    src/sys/external/bsd/drm2/dist/drm/radeon/radeon_gem.c
cvs rdiff -u -r1.14 -r1.15 \
    src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c
cvs rdiff -u -r1.26 -r1.27 src/sys/external/bsd/drm2/dist/include/drm/drmP.h
cvs rdiff -u -r1.4 -r1.5 src/sys/external/bsd/drm2/dist/include/drm/drm_gem.h
cvs rdiff -u -r1.7 -r1.8 src/sys/external/bsd/drm2/dist/uapi/drm/drm.h
cvs rdiff -u -r1.13 -r1.14 src/sys/external/bsd/drm2/drm/drm_fops.c
cvs rdiff -u -r1.27 -r1.28 src/sys/external/bsd/drm2/drm/files.drmkms
cvs rdiff -u -r1.30 -r1.31 src/sys/external/bsd/drm2/i915drm/files.i915drmkms
cvs rdiff -u -r1.2 -r1.3 src/sys/external/bsd/drm2/include/linux/dma-buf.h
cvs rdiff -u -r1.6 -r1.7 src/sys/external/bsd/drm2/include/linux/module.h
cvs rdiff -u -r1.16 -r1.17 src/sys/external/bsd/drm2/linux/files.drmkms_linux
cvs rdiff -u -r0 -r1.1 src/sys/external/bsd/drm2/linux/linux_dma_buf.c
cvs rdiff -u -r1.17 -r1.18 src/sys/external/bsd/drm2/nouveau/files.nouveau
cvs rdiff -u -r1.19 -r1.20 src/sys/external/bsd/drm2/radeon/files.radeon

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/dist/drm/drm_gem.c
diff -u src/sys/external/bsd/drm2/dist/drm/drm_gem.c:1.9 src/sys/external/bsd/drm2/dist/drm/drm_gem.c:1.10
--- src/sys/external/bsd/drm2/dist/drm/drm_gem.c:1.9	Mon Aug 27 14:14:29 2018
+++ src/sys/external/bsd/drm2/dist/drm/drm_gem.c	Mon Aug 27 15:22:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_gem.c,v 1.9 2018/08/27 14:14:29 riastradh Exp $	*/
+/*	$NetBSD: drm_gem.c,v 1.10 2018/08/27 15:22:53 riastradh Exp $	*/
 
 /*
  * Copyright © 2008 Intel Corporation
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_gem.c,v 1.9 2018/08/27 14:14:29 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_gem.c,v 1.10 2018/08/27 15:22:53 riastradh Exp $");
 
 #include <linux/types.h>
 #include <linux/slab.h>
@@ -224,7 +224,6 @@ EXPORT_SYMBOL(drm_gem_private_object_ini
 static void
 drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp)
 {
-#ifndef __NetBSD__		/* XXX drm prime */
 	/*
 	 * Note: obj->dma_buf can't disappear as long as we still hold a
 	 * handle reference in obj->handle_count.
@@ -235,7 +234,6 @@ drm_gem_remove_prime_handles(struct drm_
 						   obj->dma_buf);
 	}
 	mutex_unlock(&filp->prime.lock);
-#endif
 }
 
 /**
@@ -822,10 +820,8 @@ drm_gem_object_release_handle(int id, vo
 	if (dev->driver->gem_close_object)
 		dev->driver->gem_close_object(obj, file_priv);
 
-#ifndef __NetBSD__			/* XXX drm prime */
 	if (drm_core_check_feature(dev, DRIVER_PRIME))
 		drm_gem_remove_prime_handles(obj, file_priv);
-#endif
 	drm_vma_node_revoke(&obj->vma_node, file_priv->filp);
 
 	drm_gem_object_handle_unreference_unlocked(obj);

Index: src/sys/external/bsd/drm2/dist/drm/drm_internal.h
diff -u src/sys/external/bsd/drm2/dist/drm/drm_internal.h:1.2 src/sys/external/bsd/drm2/dist/drm/drm_internal.h:1.3
--- src/sys/external/bsd/drm2/dist/drm/drm_internal.h:1.2	Mon Aug 27 04:58:19 2018
+++ src/sys/external/bsd/drm2/dist/drm/drm_internal.h	Mon Aug 27 15:22:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_internal.h,v 1.2 2018/08/27 04:58:19 riastradh Exp $	*/
+/*	$NetBSD: drm_internal.h,v 1.3 2018/08/27 15:22:53 riastradh Exp $	*/
 
 /*
  * Copyright © 2014 Intel Corporation
@@ -50,12 +50,10 @@ int drm_prime_handle_to_fd_ioctl(struct 
 int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
 				 struct drm_file *file_priv);
 
-#ifndef __NetBSD__		/* XXX drm prime */
 void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv);
 void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv);
 void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv,
 					struct dma_buf *dma_buf);
-#endif
 
 #ifndef __NetBSD__
 /* drm_info.c */
Index: src/sys/external/bsd/drm2/dist/drm/drm_prime.c
diff -u src/sys/external/bsd/drm2/dist/drm/drm_prime.c:1.2 src/sys/external/bsd/drm2/dist/drm/drm_prime.c:1.3
--- src/sys/external/bsd/drm2/dist/drm/drm_prime.c:1.2	Mon Aug 27 04:58:19 2018
+++ src/sys/external/bsd/drm2/dist/drm/drm_prime.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_prime.c,v 1.2 2018/08/27 04:58:19 riastradh Exp $	*/
+/*	$NetBSD: drm_prime.c,v 1.3 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright © 2012 Red Hat
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_prime.c,v 1.2 2018/08/27 04:58:19 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_prime.c,v 1.3 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <linux/export.h>
 #include <linux/dma-buf.h>
@@ -38,6 +38,72 @@ __KERNEL_RCSID(0, "$NetBSD: drm_prime.c,
 
 #include "drm_internal.h"
 
+struct sg_table {
+	bus_dma_segment_t	*sgt_segs;
+	int			sgt_nsegs;
+	bus_size_t		sgt_size;
+};
+
+static int
+sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages,
+    unsigned npages, bus_size_t offset, bus_size_t size, gfp_t gfp)
+{
+	unsigned i;
+
+	KASSERT(offset == 0);
+	KASSERT(size == npages << PAGE_SHIFT);
+
+	sgt->sgt_segs = kcalloc(npages, sizeof(sgt->sgt_segs[0]), gfp);
+	if (sgt->sgt_segs == NULL)
+		return -ENOMEM;
+	sgt->sgt_nsegs = npages;
+	sgt->sgt_size = size;
+
+	for (i = 0; i < npages; i++) {
+		sgt->sgt_segs[i].ds_addr = VM_PAGE_TO_PHYS(&pages[i]->p_vmp);
+		sgt->sgt_segs[i].ds_len = PAGE_SIZE;
+	}
+
+	return 0;
+}
+
+static int
+sg_alloc_table_from_pglist(struct sg_table *sgt, struct pglist *pglist,
+    unsigned npages, bus_size_t offset, bus_size_t size, gfp_t gfp)
+{
+	struct vm_page *pg;
+	unsigned i;
+
+	KASSERT(offset == 0);
+	KASSERT(size == npages << PAGE_SHIFT);
+
+	sgt->sgt_segs = kcalloc(npages, sizeof(sgt->sgt_segs[0]), gfp);
+	if (sgt->sgt_segs == NULL)
+		return -ENOMEM;
+	sgt->sgt_nsegs = npages;
+	sgt->sgt_size = size;
+
+	i = 0;
+	TAILQ_FOREACH(pg, pglist, pageq.queue) {
+		KASSERT(i < npages);
+		sgt->sgt_segs[i].ds_addr = VM_PAGE_TO_PHYS(pg);
+		sgt->sgt_segs[i].ds_len = PAGE_SIZE;
+	}
+	KASSERT(i == npages);
+
+	return 0;
+}
+
+static void
+sg_free_table(struct sg_table *sgt)
+{
+
+	kfree(sgt->sgt_segs);
+	sgt->sgt_segs = NULL;
+	sgt->sgt_nsegs = 0;
+	sgt->sgt_size = 0;
+}
+
 /*
  * DMA-BUF/GEM Object references and lifetime overview:
  *
@@ -157,9 +223,11 @@ static void drm_gem_map_detach(struct dm
 
 	sgt = prime_attach->sgt;
 	if (sgt) {
+#ifndef __NetBSD__		/* We map/unmap elsewhere.  */
 		if (prime_attach->dir != DMA_NONE)
 			dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents,
 					prime_attach->dir);
+#endif
 		sg_free_table(sgt);
 	}
 
@@ -183,7 +251,7 @@ void drm_prime_remove_buf_handle_locked(
 }
 
 static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
-					    enum dma_data_direction dir)
+						enum dma_data_direction dir)
 {
 	struct drm_prime_attachment *prime_attach = attach->priv;
 	struct drm_gem_object *obj = attach->dmabuf->priv;
@@ -204,8 +272,11 @@ static struct sg_table *drm_gem_map_dma_
 		return ERR_PTR(-EBUSY);
 
 	sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
-
 	if (!IS_ERR(sgt)) {
+#ifdef __NetBSD__		/* We map/unmap elsewhere.  */
+		prime_attach->sgt = sgt;
+		prime_attach->dir = dir;
+#else
 		if (!dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir)) {
 			sg_free_table(sgt);
 			kfree(sgt);
@@ -214,6 +285,7 @@ static struct sg_table *drm_gem_map_dma_
 			prime_attach->sgt = sgt;
 			prime_attach->dir = dir;
 		}
+#endif
 	}
 
 	return sgt;
@@ -281,8 +353,15 @@ static void drm_gem_dmabuf_kunmap(struct
 
 }
 
+#ifdef __NetBSD__
+static int
+drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, off_t *offp, size_t size,
+    int prot, int *flagsp, int *advicep, struct uvm_object **uobjp,
+    int *maxprotp)
+#else
 static int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf,
 			       struct vm_area_struct *vma)
+#endif
 {
 	struct drm_gem_object *obj = dma_buf->priv;
 	struct drm_device *dev = obj->dev;
@@ -290,7 +369,12 @@ static int drm_gem_dmabuf_mmap(struct dm
 	if (!dev->driver->gem_prime_mmap)
 		return -ENOSYS;
 
+#ifdef __NetBSD__
+	return dev->driver->gem_prime_mmap(obj, offp, size, prot, flagsp,
+	    advicep, uobjp, maxprotp);
+#else
 	return dev->driver->gem_prime_mmap(obj, vma);
+#endif
 }
 
 static const struct dma_buf_ops drm_gem_prime_dmabuf_ops =  {
@@ -348,8 +432,10 @@ struct dma_buf *drm_gem_prime_export(str
 				     int flags)
 {
 	struct dma_buf_export_info exp_info = {
+#ifndef __NetBSD__
 		.exp_name = KBUILD_MODNAME, /* white lie for debug */
 		.owner = dev->driver->fops->owner,
+#endif
 		.ops = &drm_gem_prime_dmabuf_ops,
 		.size = obj->size,
 		.flags = flags,
@@ -706,6 +792,52 @@ out:
 }
 EXPORT_SYMBOL(drm_prime_pages_to_sg);
 
+#ifdef __NetBSD__
+
+struct sg_table *
+drm_prime_pglist_to_sg(struct pglist *pglist, unsigned npages)
+{
+	struct sg_table *sg;
+	int ret;
+
+	sg = kmalloc(sizeof(*sg), GFP_KERNEL);
+	if (sg == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = sg_alloc_table_from_pglist(sg, pglist, 0, npages << PAGE_SHIFT,
+	    npages, GFP_KERNEL);
+	if (ret)
+		goto out;
+
+	return sg;
+
+out:
+	kfree(sg);
+	return ERR_PTR(ret);
+}
+
+void
+drm_prime_sg_free(struct sg_table *sg)
+{
+
+	sg_free_table(sg);
+	kfree(sg);
+}
+
+int
+drm_prime_bus_dmamap_load_sgt(bus_dma_tag_t dmat, bus_dmamap_t map,
+    struct sg_table *sgt)
+{
+
+	/* XXX errno NetBSD->Linux */
+	return -bus_dmamap_load_raw(dmat, map, sgt->sgt_segs, sgt->sgt_nsegs,
+	    sgt->sgt_size, BUS_DMA_NOWAIT);
+}
+
+#else  /* !__NetBSD__ */
+
 /**
  * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array
  * @sgt: scatter-gather table to convert
@@ -749,6 +881,8 @@ int drm_prime_sg_to_page_addr_arrays(str
 }
 EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays);
 
+#endif	/* __NetBSD__ */
+
 /**
  * drm_prime_gem_destroy - helper to clean up a PRIME-imported GEM object
  * @obj: GEM object which was created from a dma-buf
@@ -774,11 +908,20 @@ EXPORT_SYMBOL(drm_prime_gem_destroy);
 void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv)
 {
 	INIT_LIST_HEAD(&prime_fpriv->head);
+#ifdef __NetBSD__
+	linux_mutex_init(&prime_fpriv->lock);
+#else
 	mutex_init(&prime_fpriv->lock);
+#endif
 }
 
 void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv)
 {
 	/* by now drm_gem_release should've made sure the list is empty */
 	WARN_ON(!list_empty(&prime_fpriv->head));
+#ifdef __NetBSD__
+	linux_mutex_destroy(&prime_fpriv->lock);
+#else
+	mutex_destroy(&prime_fpriv->lock);
+#endif
 }

Index: src/sys/external/bsd/drm2/dist/drm/drm_ioctl.c
diff -u src/sys/external/bsd/drm2/dist/drm/drm_ioctl.c:1.8 src/sys/external/bsd/drm2/dist/drm/drm_ioctl.c:1.9
--- src/sys/external/bsd/drm2/dist/drm/drm_ioctl.c:1.8	Mon Aug 27 14:45:45 2018
+++ src/sys/external/bsd/drm2/dist/drm/drm_ioctl.c	Mon Aug 27 15:22:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_ioctl.c,v 1.8 2018/08/27 14:45:45 riastradh Exp $	*/
+/*	$NetBSD: drm_ioctl.c,v 1.9 2018/08/27 15:22:53 riastradh Exp $	*/
 
 /*
  * Created: Fri Jan  8 09:01:26 1999 by [email protected]
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c,v 1.8 2018/08/27 14:45:45 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c,v 1.9 2018/08/27 15:22:53 riastradh Exp $");
 
 #include <drm/drmP.h>
 #include <drm/drm_core.h>
@@ -665,10 +665,8 @@ static const struct drm_ioctl_desc drm_i
 
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 
-#ifndef __NetBSD__		/* XXX drm prime */
 	DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
-#endif
 
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),

Index: src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_display.c
diff -u src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_display.c:1.3 src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_display.c:1.4
--- src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_display.c:1.3	Mon Aug 27 14:04:50 2018
+++ src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_display.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: amdgpu_display.c,v 1.3 2018/08/27 14:04:50 riastradh Exp $	*/
+/*	$NetBSD: amdgpu_display.c,v 1.4 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright 2007-8 Advanced Micro Devices, Inc.
@@ -26,7 +26,7 @@
  *          Alex Deucher
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amdgpu_display.c,v 1.3 2018/08/27 14:04:50 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amdgpu_display.c,v 1.4 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <drm/drmP.h>
 #include <drm/amdgpu_drm.h>
@@ -565,13 +565,11 @@ amdgpu_user_framebuffer_create(struct dr
 		return ERR_PTR(-ENOENT);
 	}
 
-#ifndef __NetBSD__		/* XXX drm prime */
 	/* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */
 	if (obj->import_attach) {
 		DRM_DEBUG_KMS("Cannot create framebuffer from imported dma_buf\n");
 		return ERR_PTR(-EINVAL);
 	}
-#endif
 
 	amdgpu_fb = kzalloc(sizeof(*amdgpu_fb), GFP_KERNEL);
 	if (amdgpu_fb == NULL) {
Index: src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_gem.c
diff -u src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_gem.c:1.3 src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_gem.c:1.4
--- src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_gem.c:1.3	Mon Aug 27 14:04:50 2018
+++ src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_gem.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: amdgpu_gem.c,v 1.3 2018/08/27 14:04:50 riastradh Exp $	*/
+/*	$NetBSD: amdgpu_gem.c,v 1.4 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright 2008 Advanced Micro Devices, Inc.
@@ -28,7 +28,7 @@
  *          Jerome Glisse
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amdgpu_gem.c,v 1.3 2018/08/27 14:04:50 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amdgpu_gem.c,v 1.4 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <linux/ktime.h>
 #include <drm/drmP.h>
@@ -40,10 +40,8 @@ void amdgpu_gem_object_free(struct drm_g
 	struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj);
 
 	if (robj) {
-#ifndef __NetBSD__		/* XXX drm prime */
 		if (robj->gem_base.import_attach)
 			drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg);
-#endif
 		amdgpu_mn_unregister(robj);
 		amdgpu_bo_unref(&robj);
 	}
Index: src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_ttm.c
diff -u src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_ttm.c:1.3 src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_ttm.c:1.4
--- src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_ttm.c:1.3	Mon Aug 27 14:04:50 2018
+++ src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_ttm.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: amdgpu_ttm.c,v 1.3 2018/08/27 14:04:50 riastradh Exp $	*/
+/*	$NetBSD: amdgpu_ttm.c,v 1.4 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright 2009 Jerome Glisse.
@@ -32,7 +32,7 @@
  *    Dave Airlie
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amdgpu_ttm.c,v 1.3 2018/08/27 14:04:50 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amdgpu_ttm.c,v 1.4 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <ttm/ttm_bo_api.h>
 #include <ttm/ttm_bo_driver.h>
@@ -687,8 +687,8 @@ static int amdgpu_ttm_tt_populate(struct
 	struct amdgpu_ttm_tt *gtt = (void *)ttm;
 #ifndef __NetBSD__
 	unsigned i;
-	int r;
 #endif
+	int r;
 	bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
 
 	if (ttm->state != tt_unpopulated)
@@ -709,14 +709,17 @@ static int amdgpu_ttm_tt_populate(struct
 	}
 
 	if (slave && ttm->sg) {
-#ifdef __NetBSD__		/* XXX drm prime */
-		return -EINVAL;
+#ifdef __NetBSD__
+		r = drm_prime_bus_dmamap_load_sgt(ttm->bdev->dmat,
+		    gtt->ttm.dma_address, ttm->sg);
+		if (r)
+			return r;
 #else
 		drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
 						 gtt->ttm.dma_address, ttm->num_pages);
+#endif
 		ttm->state = tt_unbound;
 		return 0;
-#endif
 	}
 
 #ifdef __NetBSD__

Index: src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_drv.c
diff -u src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_drv.c:1.4 src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_drv.c:1.5
--- src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_drv.c:1.4	Mon Aug 27 14:04:50 2018
+++ src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_drv.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: amdgpu_drv.c,v 1.4 2018/08/27 14:04:50 riastradh Exp $	*/
+/*	$NetBSD: amdgpu_drv.c,v 1.5 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /**
  * \file amdgpu_drv.c
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amdgpu_drv.c,v 1.4 2018/08/27 14:04:50 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amdgpu_drv.c,v 1.5 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <drm/drmP.h>
 #include <drm/amdgpu_drm.h>
@@ -538,7 +538,6 @@ static struct drm_driver kms_driver = {
 	.fops = &amdgpu_driver_kms_fops,
 #endif
 
-#ifndef __NetBSD__		/* XXX drm prime */
 	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 	.gem_prime_export = amdgpu_gem_prime_export,
@@ -550,7 +549,6 @@ static struct drm_driver kms_driver = {
 	.gem_prime_import_sg_table = amdgpu_gem_prime_import_sg_table,
 	.gem_prime_vmap = amdgpu_gem_prime_vmap,
 	.gem_prime_vunmap = amdgpu_gem_prime_vunmap,
-#endif
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,

Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.c
diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.c:1.14 src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.c:1.15
--- src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.c:1.14	Mon Aug 27 14:49:22 2018
+++ src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: i915_drv.c,v 1.14 2018/08/27 14:49:22 riastradh Exp $	*/
+/*	$NetBSD: i915_drv.c,v 1.15 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
  */
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i915_drv.c,v 1.14 2018/08/27 14:49:22 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i915_drv.c,v 1.15 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <linux/device.h>
 #include <linux/acpi.h>
@@ -1775,12 +1775,10 @@ static struct drm_driver driver = {
 	.gem_vm_ops = &i915_gem_vm_ops,
 #endif
 
-#ifndef __NetBSD__		/* XXX drm prime */
 	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 	.gem_prime_export = i915_gem_prime_export,
 	.gem_prime_import = i915_gem_prime_import,
-#endif
 
 	.dumb_create = i915_gem_dumb_create,
 	.dumb_map_offset = i915_gem_mmap_gtt,

Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h
diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h:1.26 src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h:1.27
--- src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h:1.26	Mon Aug 27 15:09:35 2018
+++ src/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: i915_drv.h,v 1.26 2018/08/27 15:09:35 riastradh Exp $	*/
+/*	$NetBSD: i915_drv.h,v 1.27 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
  */
@@ -2188,6 +2188,7 @@ struct drm_i915_gem_object {
 #ifdef __NetBSD__
 	struct pglist pageq;
 	bus_dmamap_t pages;	/* expedient misnomer */
+	struct sg_table *sg;	/* drm prime */
 #else
 	struct sg_table *pages;
 #endif

Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c
diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c:1.53 src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c:1.54
--- src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c:1.53	Mon Aug 27 14:50:04 2018
+++ src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: i915_gem.c,v 1.53 2018/08/27 14:50:04 riastradh Exp $	*/
+/*	$NetBSD: i915_gem.c,v 1.54 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright © 2008-2015 Intel Corporation
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i915_gem.c,v 1.53 2018/08/27 14:50:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i915_gem.c,v 1.54 2018/08/27 15:22:54 riastradh Exp $");
 
 #ifdef __NetBSD__
 #if 0				/* XXX uvmhist option?  */
@@ -5107,10 +5107,8 @@ void i915_gem_free_object(struct drm_gem
 
 	BUG_ON(obj->pages);
 
-#ifndef __NetBSD__		/* XXX drm prime */
 	if (obj->base.import_attach)
 		drm_prime_gem_destroy(&obj->base, NULL);
-#endif
 
 	if (obj->ops->release)
 		obj->ops->release(obj);

Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_dmabuf.c
diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_dmabuf.c:1.2 src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_dmabuf.c:1.3
--- src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_dmabuf.c:1.2	Mon Aug 27 04:58:23 2018
+++ src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_dmabuf.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: i915_gem_dmabuf.c,v 1.2 2018/08/27 04:58:23 riastradh Exp $	*/
+/*	$NetBSD: i915_gem_dmabuf.c,v 1.3 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright 2012 Red Hat Inc
@@ -26,7 +26,7 @@
  *	Dave Airlie <[email protected]>
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i915_gem_dmabuf.c,v 1.2 2018/08/27 04:58:23 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i915_gem_dmabuf.c,v 1.3 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <drm/drmP.h>
 #include "i915_drv.h"
@@ -34,7 +34,9 @@ __KERNEL_RCSID(0, "$NetBSD: i915_gem_dma
 
 static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf)
 {
-	return to_intel_bo(buf->priv);
+	struct drm_gem_object *obj = buf->priv;
+
+	return to_intel_bo(obj);
 }
 
 static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachment,
@@ -42,8 +44,12 @@ static struct sg_table *i915_gem_map_dma
 {
 	struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
 	struct sg_table *st;
+#ifdef __NetBSD__
+	int ret;
+#else
 	struct scatterlist *src, *dst;
 	int ret, i;
+#endif
 
 	ret = i915_mutex_lock_interruptible(obj->base.dev);
 	if (ret)
@@ -55,6 +61,11 @@ static struct sg_table *i915_gem_map_dma
 
 	i915_gem_object_pin_pages(obj);
 
+#ifdef __NetBSD__
+	st = drm_prime_pglist_to_sg(&obj->pageq, obj->base.size >> PAGE_SHIFT);
+	if (IS_ERR(st))
+		goto err_unpin;
+#else
 	/* Copy sg so that we make an independent mapping */
 	st = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
 	if (st == NULL) {
@@ -78,14 +89,17 @@ static struct sg_table *i915_gem_map_dma
 		ret =-ENOMEM;
 		goto err_free_sg;
 	}
+#endif
 
 	mutex_unlock(&obj->base.dev->struct_mutex);
 	return st;
 
+#ifndef __NetBSD__
 err_free_sg:
 	sg_free_table(st);
 err_free:
 	kfree(st);
+#endif
 err_unpin:
 	i915_gem_object_unpin_pages(obj);
 err_unlock:
@@ -102,9 +116,13 @@ static void i915_gem_unmap_dma_buf(struc
 
 	mutex_lock(&obj->base.dev->struct_mutex);
 
+#ifdef __NetBSD__
+	drm_prime_sg_free(sg);
+#else
 	dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir);
 	sg_free_table(sg);
 	kfree(sg);
+#endif
 
 	i915_gem_object_unpin_pages(obj);
 
@@ -115,7 +133,11 @@ static void *i915_gem_dmabuf_vmap(struct
 {
 	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
 	struct drm_device *dev = obj->base.dev;
+#ifdef __NetBSD__
+	struct vm_page *pg;
+#else
 	struct sg_page_iter sg_iter;
+#endif
 	struct page **pages;
 	int ret, i;
 
@@ -141,8 +163,14 @@ static void *i915_gem_dmabuf_vmap(struct
 		goto err_unpin;
 
 	i = 0;
+#ifdef __NetBSD__
+	TAILQ_FOREACH(pg, &obj->pageq, pageq.queue)
+		pages[i++] = container_of(pg, struct page, p_vmp);
+	KASSERT(i == obj->base.size >> PAGE_SHIFT);
+#else
 	for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0)
 		pages[i++] = sg_page_iter_page(&sg_iter);
+#endif
 
 	obj->dma_buf_vmapping = vmap(pages, i, 0, PAGE_KERNEL);
 	drm_free_large(pages);
@@ -169,7 +197,11 @@ static void i915_gem_dmabuf_vunmap(struc
 
 	mutex_lock(&dev->struct_mutex);
 	if (--obj->vmapping_count == 0) {
+#ifdef __NetBSD__
+		vunmap(obj->dma_buf_vmapping, obj->base.size >> PAGE_SHIFT);
+#else
 		vunmap(obj->dma_buf_vmapping);
+#endif
 		obj->dma_buf_vmapping = NULL;
 
 		i915_gem_object_unpin_pages(obj);
@@ -196,7 +228,14 @@ static void i915_gem_dmabuf_kunmap(struc
 
 }
 
+#ifdef __NetBSD__
+static int
+i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, off_t *offp, size_t size,
+    int prot, int *flagsp, int *advicep, struct uvm_object **uobjp,
+    int *maxprotp)
+#else
 static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
+#endif
 {
 	return -EINVAL;
 }
@@ -255,19 +294,52 @@ struct dma_buf *i915_gem_prime_export(st
 static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
 {
 	struct sg_table *sg;
+#ifdef __NetBSD__
+	struct drm_device *dev = obj->base.dev;
+	bus_dmamap_t map;
+	int ret;
+#endif
 
 	sg = dma_buf_map_attachment(obj->base.import_attach, DMA_BIDIRECTIONAL);
 	if (IS_ERR(sg))
 		return PTR_ERR(sg);
 
+#ifdef __NetBSD__
+	ret = -bus_dmamap_create(dev->dmat, obj->base.size,
+	    obj->base.size >> PAGE_SHIFT, obj->base.size, 0, BUS_DMA_NOWAIT,
+	    &map);
+	if (ret) {
+fail0:		dma_buf_unmap_attachment(obj->base.import_attach, sg,
+		    DMA_BIDIRECTIONAL);
+		return ret;
+	}
+	ret = drm_prime_bus_dmamap_load_sgt(dev->dmat, map, sg);
+	if (ret) {
+fail1: __unused
+		bus_dmamap_destroy(dev->dmat, map);
+		goto fail0;
+	}
+	obj->pages = map;
+	obj->sg = sg;
+#else
 	obj->pages = sg;
+#endif
 	return 0;
 }
 
 static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj)
 {
+#ifdef __NetBSD__
+	bus_dmamap_unload(obj->base.dev->dmat, obj->pages);
+	bus_dmamap_destroy(obj->base.dev->dmat, obj->pages);
+	obj->pages = NULL;
+	dma_buf_unmap_attachment(obj->base.import_attach,
+				 obj->sg, DMA_BIDIRECTIONAL);
+	obj->sg = NULL;		/* paranoia */
+#else
 	dma_buf_unmap_attachment(obj->base.import_attach,
 				 obj->pages, DMA_BIDIRECTIONAL);
+#endif
 }
 
 static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = {

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c:1.11 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c:1.12
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c:1.11	Mon Aug 27 14:51:33 2018
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_bo.c,v 1.11 2018/08/27 14:51:33 riastradh Exp $	*/
+/*	$NetBSD: nouveau_bo.c,v 1.12 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright 2007 Dave Airlied
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_bo.c,v 1.11 2018/08/27 14:51:33 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_bo.c,v 1.12 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <linux/dma-mapping.h>
 #include <linux/swiotlb.h>
@@ -1561,24 +1561,27 @@ nouveau_ttm_tt_populate(struct ttm_tt *t
 	struct drm_device *dev;
 	struct device *pdev;
 	unsigned i;
-	int r;
 #endif
-#ifndef __NetBSD__		/* XXX drm prime */
+	int r;
 	bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
-#endif
 
 	if (ttm->state != tt_unpopulated)
 		return 0;
 
-#ifndef __NetBSD__		/* XXX drm prime */
 	if (slave && ttm->sg) {
 		/* make userspace faulting work */
+#ifdef __NetBSD__
+		r = drm_prime_bus_dmamap_load_sgt(ttm->bdev->dmat,
+		    ttm_dma->dma_address, ttm->sg);
+		if (r)
+			return r;
+#else
 		drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
 						 ttm_dma->dma_address, ttm->num_pages);
+#endif
 		ttm->state = tt_unbound;
 		return 0;
 	}
-#endif
 
 	drm = nouveau_bdev(ttm->bdev);
 #ifndef __NetBSD__

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c:1.14 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c:1.15
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c:1.14	Mon Aug 27 14:47:53 2018
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_drm.c,v 1.14 2018/08/27 14:47:53 riastradh Exp $	*/
+/*	$NetBSD: nouveau_drm.c,v 1.15 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_drm.c,v 1.14 2018/08/27 14:47:53 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_drm.c,v 1.15 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <linux/console.h>
 #include <linux/delay.h>
@@ -1030,7 +1030,6 @@ driver_stub = {
 	.fops = &nouveau_driver_fops,
 #endif
 
-#ifndef __NetBSD__		/* XXX drm prime */
 	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 	.gem_prime_export = drm_gem_prime_export,
@@ -1042,7 +1041,6 @@ driver_stub = {
 	.gem_prime_import_sg_table = nouveau_gem_prime_import_sg_table,
 	.gem_prime_vmap = nouveau_gem_prime_vmap,
 	.gem_prime_vunmap = nouveau_gem_prime_vunmap,
-#endif
 
 	.gem_free_object = nouveau_gem_object_del,
 	.gem_open_object = nouveau_gem_object_open,

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c:1.7 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c:1.8
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c:1.7	Mon Aug 27 07:37:17 2018
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_gem.c,v 1.7 2018/08/27 07:37:17 riastradh Exp $	*/
+/*	$NetBSD: nouveau_gem.c,v 1.8 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright (C) 2008 Ben Skeggs.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_gem.c,v 1.7 2018/08/27 07:37:17 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_gem.c,v 1.8 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <linux/err.h>		/* XXX */
 
@@ -52,10 +52,8 @@ nouveau_gem_object_del(struct drm_gem_ob
 	if (WARN_ON(ret < 0 && ret != -EACCES))
 		return;
 
-#ifndef __NetBSD__		/* XXX drm prime */
 	if (gem->import_attach)
 		drm_prime_gem_destroy(gem, nvbo->bo.sg);
-#endif
 
 	drm_gem_object_release(gem);
 

Index: src/sys/external/bsd/drm2/dist/drm/radeon/radeon_display.c
diff -u src/sys/external/bsd/drm2/dist/drm/radeon/radeon_display.c:1.8 src/sys/external/bsd/drm2/dist/drm/radeon/radeon_display.c:1.9
--- src/sys/external/bsd/drm2/dist/drm/radeon/radeon_display.c:1.8	Mon Aug 27 07:49:04 2018
+++ src/sys/external/bsd/drm2/dist/drm/radeon/radeon_display.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: radeon_display.c,v 1.8 2018/08/27 07:49:04 riastradh Exp $	*/
+/*	$NetBSD: radeon_display.c,v 1.9 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright 2007-8 Advanced Micro Devices, Inc.
@@ -26,7 +26,7 @@
  *          Alex Deucher
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: radeon_display.c,v 1.8 2018/08/27 07:49:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: radeon_display.c,v 1.9 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <drm/drmP.h>
 #include <drm/radeon_drm.h>
@@ -1404,13 +1404,11 @@ radeon_user_framebuffer_create(struct dr
 		return ERR_PTR(-ENOENT);
 	}
 
-#ifndef __NetBSD__		/* XXX radeon prime */
 	/* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */
 	if (obj->import_attach) {
 		DRM_DEBUG_KMS("Cannot create framebuffer from imported dma_buf\n");
 		return ERR_PTR(-EINVAL);
 	}
-#endif
 
 	radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL);
 	if (radeon_fb == NULL) {

Index: src/sys/external/bsd/drm2/dist/drm/radeon/radeon_drv.c
diff -u src/sys/external/bsd/drm2/dist/drm/radeon/radeon_drv.c:1.7 src/sys/external/bsd/drm2/dist/drm/radeon/radeon_drv.c:1.8
--- src/sys/external/bsd/drm2/dist/drm/radeon/radeon_drv.c:1.7	Mon Aug 27 07:03:26 2018
+++ src/sys/external/bsd/drm2/dist/drm/radeon/radeon_drv.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: radeon_drv.c,v 1.7 2018/08/27 07:03:26 riastradh Exp $	*/
+/*	$NetBSD: radeon_drv.c,v 1.8 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /**
  * \file radeon_drv.c
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: radeon_drv.c,v 1.7 2018/08/27 07:03:26 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: radeon_drv.c,v 1.8 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <drm/drmP.h>
 #include <drm/radeon_drm.h>
@@ -631,7 +631,6 @@ static struct drm_driver kms_driver = {
 	.fops = &radeon_driver_kms_fops,
 #endif
 
-#ifndef __NetBSD__		/* XXX drm prime */
 	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 	.gem_prime_export = radeon_gem_prime_export,
@@ -643,7 +642,6 @@ static struct drm_driver kms_driver = {
 	.gem_prime_import_sg_table = radeon_gem_prime_import_sg_table,
 	.gem_prime_vmap = radeon_gem_prime_vmap,
 	.gem_prime_vunmap = radeon_gem_prime_vunmap,
-#endif
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,

Index: src/sys/external/bsd/drm2/dist/drm/radeon/radeon_gem.c
diff -u src/sys/external/bsd/drm2/dist/drm/radeon/radeon_gem.c:1.5 src/sys/external/bsd/drm2/dist/drm/radeon/radeon_gem.c:1.6
--- src/sys/external/bsd/drm2/dist/drm/radeon/radeon_gem.c:1.5	Mon Aug 27 07:47:55 2018
+++ src/sys/external/bsd/drm2/dist/drm/radeon/radeon_gem.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: radeon_gem.c,v 1.5 2018/08/27 07:47:55 riastradh Exp $	*/
+/*	$NetBSD: radeon_gem.c,v 1.6 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright 2008 Advanced Micro Devices, Inc.
@@ -28,7 +28,7 @@
  *          Jerome Glisse
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: radeon_gem.c,v 1.5 2018/08/27 07:47:55 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: radeon_gem.c,v 1.6 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <drm/drmP.h>
 #include <drm/radeon_drm.h>
@@ -39,10 +39,8 @@ void radeon_gem_object_free(struct drm_g
 	struct radeon_bo *robj = gem_to_radeon_bo(gobj);
 
 	if (robj) {
-#ifndef __NetBSD__		/* XXX drm prime */
 		if (robj->gem_base.import_attach)
 			drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg);
-#endif
 		radeon_mn_unregister(robj);
 		radeon_bo_unref(&robj);
 	}

Index: src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c
diff -u src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c:1.14 src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c:1.15
--- src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c:1.14	Mon Aug 27 15:10:12 2018
+++ src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: radeon_ttm.c,v 1.14 2018/08/27 15:10:12 riastradh Exp $	*/
+/*	$NetBSD: radeon_ttm.c,v 1.15 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Copyright 2009 Jerome Glisse.
@@ -32,7 +32,7 @@
  *    Dave Airlie
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: radeon_ttm.c,v 1.14 2018/08/27 15:10:12 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: radeon_ttm.c,v 1.15 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <ttm/ttm_bo_api.h>
 #include <ttm/ttm_bo_driver.h>
@@ -749,8 +749,8 @@ static int radeon_ttm_tt_populate(struct
 #endif
 #ifndef __NetBSD__
 	unsigned i;
-	int r;
 #endif
+	int r;
 	bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
 
 	if (ttm->state != tt_unpopulated)
@@ -771,14 +771,17 @@ static int radeon_ttm_tt_populate(struct
 	}
 
 	if (slave && ttm->sg) {
-#ifdef __NetBSD__		/* XXX drm prime */
-		return -EINVAL;
+#ifdef __NetBSD__
+		r = drm_prime_bus_dmamap_load_sgt(ttm->bdev->dmat,
+		    gtt->ttm.dma_address, ttm->sg);
+		if (r)
+			return r;
 #else
 		drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
 						 gtt->ttm.dma_address, ttm->num_pages);
+#endif
 		ttm->state = tt_unbound;
 		return 0;
-#endif
 	}
 
 #if !defined(__NetBSD__) || IS_ENABLED(CONFIG_AGP)

Index: src/sys/external/bsd/drm2/dist/include/drm/drmP.h
diff -u src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.26 src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.27
--- src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.26	Mon Aug 27 14:42:43 2018
+++ src/sys/external/bsd/drm2/dist/include/drm/drmP.h	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drmP.h,v 1.26 2018/08/27 14:42:43 riastradh Exp $	*/
+/*	$NetBSD: drmP.h,v 1.27 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*
  * Internal Header for the Direct Rendering Manager
@@ -663,7 +663,11 @@ struct drm_driver {
 				struct sg_table *sgt);
 	void *(*gem_prime_vmap)(struct drm_gem_object *obj);
 	void (*gem_prime_vunmap)(struct drm_gem_object *obj, void *vaddr);
-#ifndef __NetBSD__		/* XXX drm prime */
+#ifdef __NetBSD__
+	int (*gem_prime_mmap)(struct drm_gem_object *obj, off_t *offp,
+	    size_t len, int prot, int *flagsp, int *advicep,
+	    struct uvm_object **uobjp, int *maxprotp);
+#else
 	int (*gem_prime_mmap)(struct drm_gem_object *obj,
 				struct vm_area_struct *vma);
 #endif
@@ -1177,12 +1181,16 @@ extern int drm_gem_prime_fd_to_handle(st
 		struct drm_file *file_priv, int prime_fd, uint32_t *handle);
 extern void drm_gem_dmabuf_release(struct dma_buf *dma_buf);
 
-#ifndef __NetBSD__		/* XXX drm prime */
+#ifdef __NetBSD__
+extern int drm_prime_bus_dmamap_load_sgt(bus_dma_tag_t, bus_dmamap_t, struct sg_table *);
+extern struct sg_table *drm_prime_pglist_to_sg(struct pglist *, unsigned);
+extern void drm_prime_sg_free(struct sg_table *);
+#else
 extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
 					    dma_addr_t *addrs, int max_pages);
+#endif
 extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages);
 extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg);
-#endif
 
 
 extern struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size,

Index: src/sys/external/bsd/drm2/dist/include/drm/drm_gem.h
diff -u src/sys/external/bsd/drm2/dist/include/drm/drm_gem.h:1.4 src/sys/external/bsd/drm2/dist/include/drm/drm_gem.h:1.5
--- src/sys/external/bsd/drm2/dist/include/drm/drm_gem.h:1.4	Mon Aug 27 15:10:25 2018
+++ src/sys/external/bsd/drm2/dist/include/drm/drm_gem.h	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_gem.h,v 1.4 2018/08/27 15:10:25 riastradh Exp $	*/
+/*	$NetBSD: drm_gem.h,v 1.5 2018/08/27 15:22:54 riastradh Exp $	*/
 
 #ifndef __DRM_GEM_H__
 #define __DRM_GEM_H__
@@ -106,7 +106,6 @@ struct drm_gem_object {
 	uint32_t pending_read_domains;
 	uint32_t pending_write_domain;
 
-#ifndef __NetBSD__	    /* XXX drm prime */
 	/**
 	 * dma_buf - dma buf associated with this GEM object
 	 *
@@ -134,7 +133,6 @@ struct drm_gem_object {
 	 * simply leave it as NULL.
 	 */
 	struct dma_buf_attachment *import_attach;
-#endif
 };
 
 void drm_gem_object_release(struct drm_gem_object *obj);

Index: src/sys/external/bsd/drm2/dist/uapi/drm/drm.h
diff -u src/sys/external/bsd/drm2/dist/uapi/drm/drm.h:1.7 src/sys/external/bsd/drm2/dist/uapi/drm/drm.h:1.8
--- src/sys/external/bsd/drm2/dist/uapi/drm/drm.h:1.7	Mon Aug 27 04:58:38 2018
+++ src/sys/external/bsd/drm2/dist/uapi/drm/drm.h	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm.h,v 1.7 2018/08/27 04:58:38 riastradh Exp $	*/
+/*	$NetBSD: drm.h,v 1.8 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /**
  * \file drm.h
@@ -55,6 +55,7 @@ typedef unsigned int drm_handle_t;
 #ifdef __NetBSD__
 #include <sys/ioccom.h>
 #include <sys/types.h>
+#include <sys/fcntl.h>
 #ifndef _KERNEL
 typedef int8_t   __s8;
 typedef uint8_t  __u8;

Index: src/sys/external/bsd/drm2/drm/drm_fops.c
diff -u src/sys/external/bsd/drm2/drm/drm_fops.c:1.13 src/sys/external/bsd/drm2/drm/drm_fops.c:1.14
--- src/sys/external/bsd/drm2/drm/drm_fops.c:1.13	Mon Aug 27 14:20:11 2018
+++ src/sys/external/bsd/drm2/drm/drm_fops.c	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_fops.c,v 1.13 2018/08/27 14:20:11 riastradh Exp $	*/
+/*	$NetBSD: drm_fops.c,v 1.14 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_fops.c,v 1.13 2018/08/27 14:20:11 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_fops.c,v 1.14 2018/08/27 15:22:54 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/select.h>
@@ -78,10 +78,8 @@ drm_open_file(struct drm_file *file, voi
 
 	if (drm_core_check_feature(dev, DRIVER_GEM))
 		drm_gem_open(dev, file);
-#ifndef __NetBSD__		/* XXX drm prime */
 	if (drm_core_check_feature(dev, DRIVER_PRIME))
 		drm_prime_init_file_private(&file->prime);
-#endif
 
 	if (dev->driver->open) {
 		ret = (*dev->driver->open)(dev, file);
@@ -109,10 +107,8 @@ fail1:	/*
 	if (dev->driver->postclose)
 		(*dev->driver->postclose)(dev, file);
 fail0:
-#ifndef __NetBSD__		/* XXX drm prime */
 	if (drm_core_check_feature(dev, DRIVER_PRIME))
 		drm_prime_destroy_file_private(&file->prime);
-#endif
 	if (drm_core_check_feature(dev, DRIVER_GEM))
 		drm_gem_release(dev, file);
 	return ret;
@@ -244,10 +240,8 @@ drm_close_file(struct drm_file *file)
 	if (dev->driver->postclose)
 		(*dev->driver->postclose)(dev, file);
 
-#ifndef __NetBSD__		/* XXX drm prime */
 	if (drm_core_check_feature(dev, DRIVER_PRIME))
 		drm_prime_destroy_file_private(&file->prime);
-#endif
 
 	seldestroy(&file->event_selq);
 	DRM_DESTROY_WAITQUEUE(&file->event_wait);

Index: src/sys/external/bsd/drm2/drm/files.drmkms
diff -u src/sys/external/bsd/drm2/drm/files.drmkms:1.27 src/sys/external/bsd/drm2/drm/files.drmkms:1.28
--- src/sys/external/bsd/drm2/drm/files.drmkms:1.27	Mon Aug 27 13:53:32 2018
+++ src/sys/external/bsd/drm2/drm/files.drmkms	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: files.drmkms,v 1.27 2018/08/27 13:53:32 riastradh Exp $
+#	$NetBSD: files.drmkms,v 1.28 2018/08/27 15:22:54 riastradh Exp $
 
 include "external/bsd/drm2/linux/files.drmkms_linux"
 
@@ -91,7 +91,7 @@ file	external/bsd/drm2/dist/drm/drm_mode
 file	external/bsd/drm2/dist/drm/drm_pci.c	drmkms
 file	external/bsd/drm2/dist/drm/drm_plane_helper.c	drmkms
 #file	external/bsd/drm2/dist/drm/drm_platform.c	drmkms
-#file	external/bsd/drm2/dist/drm/drm_prime.c	drmkms  # XXX drm prime
+file	external/bsd/drm2/dist/drm/drm_prime.c	drmkms
 file	external/bsd/drm2/dist/drm/drm_probe_helper.c	drmkms
 file	external/bsd/drm2/dist/drm/drm_rect.c	drmkms
 file	external/bsd/drm2/drm/drm_scatter.c	drmkms

Index: src/sys/external/bsd/drm2/i915drm/files.i915drmkms
diff -u src/sys/external/bsd/drm2/i915drm/files.i915drmkms:1.30 src/sys/external/bsd/drm2/i915drm/files.i915drmkms:1.31
--- src/sys/external/bsd/drm2/i915drm/files.i915drmkms:1.30	Mon Aug 27 13:54:15 2018
+++ src/sys/external/bsd/drm2/i915drm/files.i915drmkms	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: files.i915drmkms,v 1.30 2018/08/27 13:54:15 riastradh Exp $
+#	$NetBSD: files.i915drmkms,v 1.31 2018/08/27 15:22:54 riastradh Exp $
 
 define	intelfbbus	{ }
 device	i915drmkms: drmkms, drmkms_pci, intelfbbus, agp_i810
@@ -39,7 +39,7 @@ file	external/bsd/drm2/dist/drm/i915/i91
 file	external/bsd/drm2/dist/drm/i915/i915_gem_batch_pool.c	i915drmkms
 file	external/bsd/drm2/dist/drm/i915/i915_gem_context.c	i915drmkms
 file	external/bsd/drm2/dist/drm/i915/i915_gem_debug.c	i915drmkms
-#file	external/bsd/drm2/dist/drm/i915/i915_gem_dmabuf.c	i915drmkms	# XXX i915 prime
+file	external/bsd/drm2/dist/drm/i915/i915_gem_dmabuf.c	i915drmkms
 file	external/bsd/drm2/dist/drm/i915/i915_gem_evict.c	i915drmkms
 file	external/bsd/drm2/dist/drm/i915/i915_gem_execbuffer.c	i915drmkms
 file	external/bsd/drm2/dist/drm/i915/i915_gem_fence.c	i915drmkms

Index: src/sys/external/bsd/drm2/include/linux/dma-buf.h
diff -u src/sys/external/bsd/drm2/include/linux/dma-buf.h:1.2 src/sys/external/bsd/drm2/include/linux/dma-buf.h:1.3
--- src/sys/external/bsd/drm2/include/linux/dma-buf.h:1.2	Tue Mar 18 18:20:43 2014
+++ src/sys/external/bsd/drm2/include/linux/dma-buf.h	Mon Aug 27 15:22:54 2018
@@ -1,7 +1,7 @@
-/*	$NetBSD: dma-buf.h,v 1.2 2014/03/18 18:20:43 riastradh Exp $	*/
+/*	$NetBSD: dma-buf.h,v 1.3 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*-
- * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -32,4 +32,113 @@
 #ifndef _LINUX_DMA_BUF_H_
 #define _LINUX_DMA_BUF_H_
 
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/mutex.h>
+
+#include <linux/reservation.h>
+
+struct device;
+struct dma_buf;
+struct dma_buf_attachment;
+struct dma_buf_export_info;
+struct dma_buf_ops;
+struct file;
+struct module;
+struct reservation_object;
+struct sg_table;
+struct uvm_object;
+
+enum dma_data_direction {
+	DMA_NONE		= 0,
+	DMA_TO_DEVICE		= 1,
+	DMA_FROM_DEVICE		= 2,
+	DMA_BIDIRECTIONAL	= 3,
+};
+
+struct dma_buf_ops {
+	int	(*attach)(struct dma_buf *, struct device *,
+		    struct dma_buf_attachment *);
+	void	(*detach)(struct dma_buf *, struct dma_buf_attachment *);
+	struct sg_table *
+		(*map_dma_buf)(struct dma_buf_attachment *,
+		    enum dma_data_direction);
+	void	(*unmap_dma_buf)(struct dma_buf_attachment *,
+		    struct sg_table *, enum dma_data_direction);
+	void	(*release)(struct dma_buf *);
+	int	(*begin_cpu_access)(struct dma_buf *, size_t, size_t,
+		    enum dma_data_direction);
+	int	(*end_cpu_access)(struct dma_buf *, size_t, size_t,
+		    enum dma_data_direction);
+	void *	(*kmap_atomic)(struct dma_buf *, unsigned long);
+	void	(*kunmap_atomic)(struct dma_buf *, unsigned long, void *);
+	void *	(*kmap)(struct dma_buf *, unsigned long);
+	void	(*kunmap)(struct dma_buf *, unsigned long, void *);
+	int	(*mmap)(struct dma_buf *, off_t *, size_t, int, int *,
+		    int *, struct uvm_object **, int *);
+	void *	(*vmap)(struct dma_buf *);
+	void	(*vunmap)(struct dma_buf *, void *);
+};
+
+struct dma_buf {
+	void				*priv;
+	const struct dma_buf_ops	*ops;
+	size_t				size;
+	struct reservation_object	*resv;
+
+	kmutex_t			db_lock;
+	volatile unsigned		db_refcnt;
+	struct selinfo			db_selq;
+	struct reservation_object	db_resv_int[];
+};
+
+struct dma_buf_attachment {
+	void				*priv;
+	struct dma_buf			*dmabuf;
+};
+
+struct dma_buf_export_info {
+#if 0
+	const char			*exp_name;
+	struct module			*owner;
+#endif
+	const struct dma_buf_ops	*ops;
+	size_t				size;
+	int				flags;
+	struct reservation_object	*resv;
+	void				*priv;
+};
+
+#define	DEFINE_DMA_BUF_EXPORT_INFO(info)				      \
+	struct dma_buf_export_info info = { .priv = NULL }
+
+#define	dma_buf_attach		linux_dma_buf_attach
+#define	dma_buf_detach		linux_dma_buf_detach
+#define	dma_buf_export		linux_dma_buf_export
+#define	dma_buf_fd		linux_dma_buf_fd
+#define	dma_buf_get		linux_dma_buf_get
+#define	dma_buf_map_attachment	linux_dma_buf_map_attachment
+#define	dma_buf_put		linux_dma_buf_put
+#define	dma_buf_unmap_attachment linux_dma_buf_unmap_attachment
+#define	get_dma_buf		linux_get_dma_buf
+
+struct dma_buf *
+	dma_buf_export(struct dma_buf_export_info *);
+
+int	dma_buf_fd(struct dma_buf *, int);
+struct dma_buf *
+	dma_buf_get(int);
+void	get_dma_buf(struct dma_buf *);
+void	dma_buf_put(struct dma_buf *);
+
+struct dma_buf_attachment *
+	dma_buf_attach(struct dma_buf *, struct device *);
+void	dma_buf_detach(struct dma_buf *, struct dma_buf_attachment *);
+
+struct sg_table *
+	dma_buf_map_attachment(struct dma_buf_attachment *,
+	    enum dma_data_direction);
+void	dma_buf_unmap_attachment(struct dma_buf_attachment *,
+	    struct sg_table *, enum dma_data_direction);
+
 #endif  /* _LINUX_DMA_BUF_H_ */

Index: src/sys/external/bsd/drm2/include/linux/module.h
diff -u src/sys/external/bsd/drm2/include/linux/module.h:1.6 src/sys/external/bsd/drm2/include/linux/module.h:1.7
--- src/sys/external/bsd/drm2/include/linux/module.h:1.6	Mon Aug 27 07:33:53 2018
+++ src/sys/external/bsd/drm2/include/linux/module.h	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: module.h,v 1.6 2018/08/27 07:33:53 riastradh Exp $	*/
+/*	$NetBSD: module.h,v 1.7 2018/08/27 15:22:54 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -59,5 +59,6 @@ const struct linux_module_param_desc PAR
 __link_set_add_rodata(linux_module_param_desc, PARAMETER ## _desc)
 
 #define	THIS_MODULE	0
+#define	KBUILD_MODNAME	__file__
 
 #endif  /* _LINUX_MODULE_H_ */

Index: src/sys/external/bsd/drm2/linux/files.drmkms_linux
diff -u src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.16 src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.17
--- src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.16	Mon Aug 27 15:08:54 2018
+++ src/sys/external/bsd/drm2/linux/files.drmkms_linux	Mon Aug 27 15:22:54 2018
@@ -1,4 +1,4 @@
-#       $NetBSD: files.drmkms_linux,v 1.16 2018/08/27 15:08:54 riastradh Exp $
+#       $NetBSD: files.drmkms_linux,v 1.17 2018/08/27 15:22:54 riastradh Exp $
 
 define	drmkms_linux: i2cexec, i2c_bitbang
 
@@ -6,6 +6,7 @@ makeoptions 	drmkms_linux	CPPFLAGS+="-I$
 makeoptions 	drmkms_linux	CPPFLAGS+="-I$S/external/bsd/drm2/include"
 
 file	external/bsd/drm2/linux/linux_atomic64.c	drmkms_linux
+file	external/bsd/drm2/linux/linux_dma_buf.c		drmkms_linux
 file	external/bsd/drm2/linux/linux_dmi.c		drmkms_linux
 file	external/bsd/drm2/linux/linux_fence.c		drmkms_linux
 file	external/bsd/drm2/linux/linux_i2c.c		drmkms_linux

Index: src/sys/external/bsd/drm2/nouveau/files.nouveau
diff -u src/sys/external/bsd/drm2/nouveau/files.nouveau:1.17 src/sys/external/bsd/drm2/nouveau/files.nouveau:1.18
--- src/sys/external/bsd/drm2/nouveau/files.nouveau:1.17	Mon Aug 27 06:35:09 2018
+++ src/sys/external/bsd/drm2/nouveau/files.nouveau	Mon Aug 27 15:22:55 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: files.nouveau,v 1.17 2018/08/27 06:35:09 riastradh Exp $
+#	$NetBSD: files.nouveau,v 1.18 2018/08/27 15:22:55 riastradh Exp $
 
 define	nouveaufbbus	{ }
 device	nouveau: drmkms, drmkms_ttm, nouveaufbbus
@@ -64,7 +64,7 @@ file	external/bsd/drm2/dist/drm/nouveau/
 #file	external/bsd/drm2/dist/drm/nouveau/nouveau_nvc0_fbcon.c	nouveau
 file	external/bsd/drm2/dist/drm/nouveau/nouveau_nvc0_fence.c	nouveau
 file	external/bsd/drm2/dist/drm/nouveau/nouveau_nvif.c	nouveau
-#file	external/bsd/drm2/dist/drm/nouveau/nouveau_prime.c	nouveau # XXX nouveau prime
+file	external/bsd/drm2/dist/drm/nouveau/nouveau_prime.c	nouveau
 file	external/bsd/drm2/dist/drm/nouveau/nouveau_sgdma.c	nouveau
 #file	external/bsd/drm2/dist/drm/nouveau/nouveau_sysfs.c	nouveau
 file	external/bsd/drm2/dist/drm/nouveau/nouveau_ttm.c	nouveau

Index: src/sys/external/bsd/drm2/radeon/files.radeon
diff -u src/sys/external/bsd/drm2/radeon/files.radeon:1.19 src/sys/external/bsd/drm2/radeon/files.radeon:1.20
--- src/sys/external/bsd/drm2/radeon/files.radeon:1.19	Mon Aug 27 14:38:20 2018
+++ src/sys/external/bsd/drm2/radeon/files.radeon	Mon Aug 27 15:22:55 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: files.radeon,v 1.19 2018/08/27 14:38:20 riastradh Exp $
+#	$NetBSD: files.radeon,v 1.20 2018/08/27 15:22:55 riastradh Exp $
 
 define	radeonfbbus	{ }
 device	radeon: drmkms, drmkms_pci, drmkms_ttm, radeonfbbus, firmload
@@ -84,7 +84,7 @@ file	external/bsd/drm2/dist/drm/radeon/r
 file	external/bsd/drm2/dist/drm/radeon/radeon_ni_dpm.c	radeon
 file	external/bsd/drm2/dist/drm/radeon/radeon_object.c	radeon
 file	external/bsd/drm2/dist/drm/radeon/radeon_pm.c	radeon
-#file	external/bsd/drm2/dist/drm/radeon/radeon_prime.c	radeon	# XXX radeon prime
+file	external/bsd/drm2/dist/drm/radeon/radeon_prime.c	radeon
 file	external/bsd/drm2/dist/drm/radeon/radeon_r100.c	radeon
 file	external/bsd/drm2/dist/drm/radeon/radeon_r200.c	radeon
 file	external/bsd/drm2/dist/drm/radeon/radeon_r300.c	radeon

Added files:

Index: src/sys/external/bsd/drm2/linux/linux_dma_buf.c
diff -u /dev/null src/sys/external/bsd/drm2/linux/linux_dma_buf.c:1.1
--- /dev/null	Mon Aug 27 15:22:55 2018
+++ src/sys/external/bsd/drm2/linux/linux_dma_buf.c	Mon Aug 27 15:22:54 2018
@@ -0,0 +1,276 @@
+/*	$NetBSD: linux_dma_buf.c,v 1.1 2018/08/27 15:22:54 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2018 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: linux_dma_buf.c,v 1.1 2018/08/27 15:22:54 riastradh Exp $");
+
+#include <sys/types.h>
+#include <sys/atomic.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
+
+#include <linux/dma-buf.h>
+#include <linux/err.h>
+#include <linux/fence.h>
+#include <linux/reservation.h>
+
+struct dma_buf_file {
+	struct dma_buf	*dbf_dmabuf;
+};
+
+static int	dmabuf_fop_poll(struct file *, int);
+static int	dmabuf_fop_close(struct file *);
+static int	dmabuf_fop_kqfilter(struct file *, struct knote *);
+static int	dmabuf_fop_mmap(struct file *, off_t *, size_t, int, int *,
+		    int *, struct uvm_object **, int *);
+
+static const struct fileops dmabuf_fileops = {
+	.fo_name = "dmabuf",
+	.fo_read = fbadop_read,
+	.fo_write = fbadop_write,
+	.fo_ioctl = fbadop_ioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = dmabuf_fop_poll,
+	.fo_stat = fbadop_stat,
+	.fo_close = dmabuf_fop_close,
+	.fo_kqfilter = dmabuf_fop_kqfilter,
+	.fo_restart = fnullop_restart,
+	.fo_mmap = dmabuf_fop_mmap,
+};
+
+struct dma_buf *
+dma_buf_export(struct dma_buf_export_info *info)
+{
+	struct dma_buf *dmabuf;
+
+	if (info->resv == NULL) {
+		dmabuf = kmem_zalloc(offsetof(struct dma_buf, db_resv_int[1]),
+		    KM_SLEEP);
+	} else {
+		dmabuf = kmem_zalloc(sizeof(*dmabuf), KM_SLEEP);
+	}
+
+	dmabuf->priv = info->priv;
+	dmabuf->ops = info->ops;
+	dmabuf->size = info->size;
+	dmabuf->resv = info->resv;
+
+	mutex_init(&dmabuf->db_lock, MUTEX_DEFAULT, IPL_NONE);
+	dmabuf->db_refcnt = 1;
+
+	if (dmabuf->resv == NULL) {
+		dmabuf->resv = &dmabuf->db_resv_int[0];
+		reservation_object_init(dmabuf->resv);
+	}
+
+	return dmabuf;
+}
+
+int
+dma_buf_fd(struct dma_buf *dmabuf, int flags)
+{
+	struct file *file;
+	int fd;
+	unsigned refcnt __diagused;
+	int ret;
+
+	ret = -fd_allocfile(&file, &fd);
+	if (ret)
+		goto out0;
+
+	refcnt = atomic_inc_uint_nv(&dmabuf->db_refcnt);
+	KASSERT(refcnt > 1);
+
+	file->f_type = DTYPE_MISC;
+	file->f_flag = 0;	/* XXX DRM code allows only O_CLOEXEC.  */
+	file->f_ops = &dmabuf_fileops;
+	file->f_data = dmabuf;
+	fd_set_exclose(curlwp, fd, (flags & O_CLOEXEC) != 0);
+	fd_affix(curproc, file, fd);
+
+	fd_putfile(fd);
+out0:	return ret;
+}
+
+struct dma_buf *
+dma_buf_get(int fd)
+{
+	struct file *file;
+	struct dma_buf *dmabuf;
+	unsigned refcnt __diagused;
+	int error;
+
+	if ((file = fd_getfile(fd)) == NULL) {
+		error = EBADF;
+		goto fail1;
+	}
+	if (file->f_type != DTYPE_MISC || file->f_ops != &dmabuf_fileops) {
+		error = EINVAL;
+		goto fail0;
+	}
+
+	dmabuf = file->f_data;
+	refcnt = atomic_inc_uint_nv(&dmabuf->db_refcnt);
+	KASSERT(refcnt > 1);
+	fd_putfile(fd);
+	return dmabuf;
+
+fail1:	fd_putfile(fd);
+fail0:	KASSERT(error);
+	return ERR_PTR(-error);
+}
+
+void
+get_dma_buf(struct dma_buf *dmabuf)
+{
+	unsigned refcnt __diagused;
+
+	refcnt = atomic_inc_uint_nv(&dmabuf->db_refcnt);
+	KASSERT(refcnt > 1);
+}
+
+void
+dma_buf_put(struct dma_buf *dmabuf)
+{
+
+	if (atomic_dec_uint_nv(&dmabuf->db_refcnt) != 0)
+		return;
+
+	if (dmabuf->resv == &dmabuf->db_resv_int[0])
+		reservation_object_fini(dmabuf->resv);
+	if (dmabuf->resv == &dmabuf->db_resv_int[0]) {
+		kmem_free(dmabuf, offsetof(struct dma_buf, db_resv_int[1]));
+	} else {
+		kmem_free(dmabuf, sizeof(*dmabuf));
+	}
+}
+
+struct dma_buf_attachment *
+dma_buf_attach(struct dma_buf *dmabuf, struct device *dev)
+{
+	struct dma_buf_attachment *attach;
+	int ret = 0;
+
+	attach = kmem_zalloc(sizeof(*attach), KM_SLEEP);
+	attach->dmabuf = dmabuf;
+
+	mutex_enter(&dmabuf->db_lock);
+	if (dmabuf->ops->attach)
+		ret = dmabuf->ops->attach(dmabuf, dev, attach);
+	mutex_exit(&dmabuf->db_lock);
+	if (ret)
+		goto fail0;
+
+	return attach;
+
+fail0:	kmem_free(attach, sizeof(*attach));
+	return ERR_PTR(ret);
+}
+
+void
+dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
+{
+
+	mutex_enter(&dmabuf->db_lock);
+	if (dmabuf->ops->detach)
+		dmabuf->ops->detach(dmabuf, attach);
+	mutex_exit(&dmabuf->db_lock);
+
+	kmem_free(attach, sizeof(*attach));
+}
+
+struct sg_table *
+dma_buf_map_attachment(struct dma_buf_attachment *attach,
+    enum dma_data_direction dir)
+{
+
+	return attach->dmabuf->ops->map_dma_buf(attach, dir);
+}
+
+void
+dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
+    struct sg_table *sg, enum dma_data_direction dir)
+{
+
+	return attach->dmabuf->ops->unmap_dma_buf(attach, sg, dir);
+}
+
+static int
+dmabuf_fop_close(struct file *file)
+{
+	struct dma_buf_file *dbf = file->f_data;
+	struct dma_buf *dmabuf = dbf->dbf_dmabuf;
+
+	dma_buf_put(dmabuf);
+	return 0;
+}
+
+static int
+dmabuf_fop_poll(struct file *file, int events)
+{
+#ifdef notyet
+	struct dma_buf_file *dbf = file->f_data;
+	struct dma_buf *dmabuf = dbf->dbf_dmabuf;
+
+	return reservation_object_poll(dmabuf->resv, events);
+#else
+	return -ENOSYS;
+#endif
+}
+
+static int
+dmabuf_fop_kqfilter(struct file *file, struct knote *knote)
+{
+#ifdef notyet
+	struct dma_buf_file *dbf = file->f_data;
+	struct dma_buf *dmabuf = dbf->dbf_dmabuf;
+
+	return reservation_object_kqfilter(dmabuf->resv, knote);
+#else
+	return -ENOSYS;
+#endif
+}
+
+static int
+dmabuf_fop_mmap(struct file *file, off_t *offp, size_t size, int prot,
+    int *flagsp, int *advicep, struct uvm_object **uobjp, int *maxprotp)
+{
+	struct dma_buf_file *dbf = file->f_data;
+	struct dma_buf *dmabuf = dbf->dbf_dmabuf;
+
+	if (size > dmabuf->size)
+		return EINVAL;
+
+	return dmabuf->ops->mmap(dmabuf, offp, size, prot, flagsp, advicep,
+	    uobjp, maxprotp);
+}

Reply via email to