Home | History | Annotate | Line # | Download | only in drm
drm_prime.c revision 1.3
      1  1.2  riastrad /*	$NetBSD: drm_prime.c,v 1.3 2018/08/27 15:22:54 riastradh Exp $	*/
      2  1.2  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * Copyright  2012 Red Hat
      5  1.1  riastrad  *
      6  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      7  1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
      8  1.1  riastrad  * to deal in the Software without restriction, including without limitation
      9  1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     11  1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     12  1.1  riastrad  *
     13  1.1  riastrad  * The above copyright notice and this permission notice (including the next
     14  1.1  riastrad  * paragraph) shall be included in all copies or substantial portions of the
     15  1.1  riastrad  * Software.
     16  1.1  riastrad  *
     17  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  1.1  riastrad  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  1.1  riastrad  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     22  1.1  riastrad  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     23  1.1  riastrad  * IN THE SOFTWARE.
     24  1.1  riastrad  *
     25  1.1  riastrad  * Authors:
     26  1.1  riastrad  *      Dave Airlie <airlied (at) redhat.com>
     27  1.1  riastrad  *      Rob Clark <rob.clark (at) linaro.org>
     28  1.1  riastrad  *
     29  1.1  riastrad  */
     30  1.1  riastrad 
     31  1.2  riastrad #include <sys/cdefs.h>
     32  1.2  riastrad __KERNEL_RCSID(0, "$NetBSD: drm_prime.c,v 1.3 2018/08/27 15:22:54 riastradh Exp $");
     33  1.2  riastrad 
     34  1.1  riastrad #include <linux/export.h>
     35  1.1  riastrad #include <linux/dma-buf.h>
     36  1.1  riastrad #include <drm/drmP.h>
     37  1.2  riastrad #include <drm/drm_gem.h>
     38  1.2  riastrad 
     39  1.2  riastrad #include "drm_internal.h"
     40  1.1  riastrad 
     41  1.3  riastrad struct sg_table {
     42  1.3  riastrad 	bus_dma_segment_t	*sgt_segs;
     43  1.3  riastrad 	int			sgt_nsegs;
     44  1.3  riastrad 	bus_size_t		sgt_size;
     45  1.3  riastrad };
     46  1.3  riastrad 
     47  1.3  riastrad static int
     48  1.3  riastrad sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages,
     49  1.3  riastrad     unsigned npages, bus_size_t offset, bus_size_t size, gfp_t gfp)
     50  1.3  riastrad {
     51  1.3  riastrad 	unsigned i;
     52  1.3  riastrad 
     53  1.3  riastrad 	KASSERT(offset == 0);
     54  1.3  riastrad 	KASSERT(size == npages << PAGE_SHIFT);
     55  1.3  riastrad 
     56  1.3  riastrad 	sgt->sgt_segs = kcalloc(npages, sizeof(sgt->sgt_segs[0]), gfp);
     57  1.3  riastrad 	if (sgt->sgt_segs == NULL)
     58  1.3  riastrad 		return -ENOMEM;
     59  1.3  riastrad 	sgt->sgt_nsegs = npages;
     60  1.3  riastrad 	sgt->sgt_size = size;
     61  1.3  riastrad 
     62  1.3  riastrad 	for (i = 0; i < npages; i++) {
     63  1.3  riastrad 		sgt->sgt_segs[i].ds_addr = VM_PAGE_TO_PHYS(&pages[i]->p_vmp);
     64  1.3  riastrad 		sgt->sgt_segs[i].ds_len = PAGE_SIZE;
     65  1.3  riastrad 	}
     66  1.3  riastrad 
     67  1.3  riastrad 	return 0;
     68  1.3  riastrad }
     69  1.3  riastrad 
     70  1.3  riastrad static int
     71  1.3  riastrad sg_alloc_table_from_pglist(struct sg_table *sgt, struct pglist *pglist,
     72  1.3  riastrad     unsigned npages, bus_size_t offset, bus_size_t size, gfp_t gfp)
     73  1.3  riastrad {
     74  1.3  riastrad 	struct vm_page *pg;
     75  1.3  riastrad 	unsigned i;
     76  1.3  riastrad 
     77  1.3  riastrad 	KASSERT(offset == 0);
     78  1.3  riastrad 	KASSERT(size == npages << PAGE_SHIFT);
     79  1.3  riastrad 
     80  1.3  riastrad 	sgt->sgt_segs = kcalloc(npages, sizeof(sgt->sgt_segs[0]), gfp);
     81  1.3  riastrad 	if (sgt->sgt_segs == NULL)
     82  1.3  riastrad 		return -ENOMEM;
     83  1.3  riastrad 	sgt->sgt_nsegs = npages;
     84  1.3  riastrad 	sgt->sgt_size = size;
     85  1.3  riastrad 
     86  1.3  riastrad 	i = 0;
     87  1.3  riastrad 	TAILQ_FOREACH(pg, pglist, pageq.queue) {
     88  1.3  riastrad 		KASSERT(i < npages);
     89  1.3  riastrad 		sgt->sgt_segs[i].ds_addr = VM_PAGE_TO_PHYS(pg);
     90  1.3  riastrad 		sgt->sgt_segs[i].ds_len = PAGE_SIZE;
     91  1.3  riastrad 	}
     92  1.3  riastrad 	KASSERT(i == npages);
     93  1.3  riastrad 
     94  1.3  riastrad 	return 0;
     95  1.3  riastrad }
     96  1.3  riastrad 
     97  1.3  riastrad static void
     98  1.3  riastrad sg_free_table(struct sg_table *sgt)
     99  1.3  riastrad {
    100  1.3  riastrad 
    101  1.3  riastrad 	kfree(sgt->sgt_segs);
    102  1.3  riastrad 	sgt->sgt_segs = NULL;
    103  1.3  riastrad 	sgt->sgt_nsegs = 0;
    104  1.3  riastrad 	sgt->sgt_size = 0;
    105  1.3  riastrad }
    106  1.3  riastrad 
    107  1.1  riastrad /*
    108  1.1  riastrad  * DMA-BUF/GEM Object references and lifetime overview:
    109  1.1  riastrad  *
    110  1.1  riastrad  * On the export the dma_buf holds a reference to the exporting GEM
    111  1.1  riastrad  * object. It takes this reference in handle_to_fd_ioctl, when it
    112  1.1  riastrad  * first calls .prime_export and stores the exporting GEM object in
    113  1.1  riastrad  * the dma_buf priv. This reference is released when the dma_buf
    114  1.1  riastrad  * object goes away in the driver .release function.
    115  1.1  riastrad  *
    116  1.1  riastrad  * On the import the importing GEM object holds a reference to the
    117  1.1  riastrad  * dma_buf (which in turn holds a ref to the exporting GEM object).
    118  1.1  riastrad  * It takes that reference in the fd_to_handle ioctl.
    119  1.1  riastrad  * It calls dma_buf_get, creates an attachment to it and stores the
    120  1.1  riastrad  * attachment in the GEM object. When this attachment is destroyed
    121  1.1  riastrad  * when the imported object is destroyed, we remove the attachment
    122  1.1  riastrad  * and drop the reference to the dma_buf.
    123  1.1  riastrad  *
    124  1.1  riastrad  * Thus the chain of references always flows in one direction
    125  1.1  riastrad  * (avoiding loops): importing_gem -> dmabuf -> exporting_gem
    126  1.1  riastrad  *
    127  1.1  riastrad  * Self-importing: if userspace is using PRIME as a replacement for flink
    128  1.1  riastrad  * then it will get a fd->handle request for a GEM object that it created.
    129  1.1  riastrad  * Drivers should detect this situation and return back the gem object
    130  1.2  riastrad  * from the dma-buf private.  Prime will do this automatically for drivers that
    131  1.2  riastrad  * use the drm_gem_prime_{import,export} helpers.
    132  1.1  riastrad  */
    133  1.1  riastrad 
    134  1.1  riastrad struct drm_prime_member {
    135  1.1  riastrad 	struct list_head entry;
    136  1.1  riastrad 	struct dma_buf *dma_buf;
    137  1.1  riastrad 	uint32_t handle;
    138  1.1  riastrad };
    139  1.1  riastrad 
    140  1.2  riastrad struct drm_prime_attachment {
    141  1.2  riastrad 	struct sg_table *sgt;
    142  1.2  riastrad 	enum dma_data_direction dir;
    143  1.2  riastrad };
    144  1.2  riastrad 
    145  1.2  riastrad static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv,
    146  1.2  riastrad 				    struct dma_buf *dma_buf, uint32_t handle)
    147  1.2  riastrad {
    148  1.2  riastrad 	struct drm_prime_member *member;
    149  1.2  riastrad 
    150  1.2  riastrad 	member = kmalloc(sizeof(*member), GFP_KERNEL);
    151  1.2  riastrad 	if (!member)
    152  1.2  riastrad 		return -ENOMEM;
    153  1.2  riastrad 
    154  1.2  riastrad 	get_dma_buf(dma_buf);
    155  1.2  riastrad 	member->dma_buf = dma_buf;
    156  1.2  riastrad 	member->handle = handle;
    157  1.2  riastrad 	list_add(&member->entry, &prime_fpriv->head);
    158  1.2  riastrad 	return 0;
    159  1.2  riastrad }
    160  1.2  riastrad 
    161  1.2  riastrad static struct dma_buf *drm_prime_lookup_buf_by_handle(struct drm_prime_file_private *prime_fpriv,
    162  1.2  riastrad 						      uint32_t handle)
    163  1.2  riastrad {
    164  1.2  riastrad 	struct drm_prime_member *member;
    165  1.2  riastrad 
    166  1.2  riastrad 	list_for_each_entry(member, &prime_fpriv->head, entry) {
    167  1.2  riastrad 		if (member->handle == handle)
    168  1.2  riastrad 			return member->dma_buf;
    169  1.2  riastrad 	}
    170  1.2  riastrad 
    171  1.2  riastrad 	return NULL;
    172  1.2  riastrad }
    173  1.2  riastrad 
    174  1.2  riastrad static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpriv,
    175  1.2  riastrad 				       struct dma_buf *dma_buf,
    176  1.2  riastrad 				       uint32_t *handle)
    177  1.2  riastrad {
    178  1.2  riastrad 	struct drm_prime_member *member;
    179  1.2  riastrad 
    180  1.2  riastrad 	list_for_each_entry(member, &prime_fpriv->head, entry) {
    181  1.2  riastrad 		if (member->dma_buf == dma_buf) {
    182  1.2  riastrad 			*handle = member->handle;
    183  1.2  riastrad 			return 0;
    184  1.2  riastrad 		}
    185  1.2  riastrad 	}
    186  1.2  riastrad 	return -ENOENT;
    187  1.2  riastrad }
    188  1.2  riastrad 
    189  1.2  riastrad static int drm_gem_map_attach(struct dma_buf *dma_buf,
    190  1.2  riastrad 			      struct device *target_dev,
    191  1.2  riastrad 			      struct dma_buf_attachment *attach)
    192  1.2  riastrad {
    193  1.2  riastrad 	struct drm_prime_attachment *prime_attach;
    194  1.2  riastrad 	struct drm_gem_object *obj = dma_buf->priv;
    195  1.2  riastrad 	struct drm_device *dev = obj->dev;
    196  1.2  riastrad 
    197  1.2  riastrad 	prime_attach = kzalloc(sizeof(*prime_attach), GFP_KERNEL);
    198  1.2  riastrad 	if (!prime_attach)
    199  1.2  riastrad 		return -ENOMEM;
    200  1.2  riastrad 
    201  1.2  riastrad 	prime_attach->dir = DMA_NONE;
    202  1.2  riastrad 	attach->priv = prime_attach;
    203  1.2  riastrad 
    204  1.2  riastrad 	if (!dev->driver->gem_prime_pin)
    205  1.2  riastrad 		return 0;
    206  1.2  riastrad 
    207  1.2  riastrad 	return dev->driver->gem_prime_pin(obj);
    208  1.2  riastrad }
    209  1.2  riastrad 
    210  1.2  riastrad static void drm_gem_map_detach(struct dma_buf *dma_buf,
    211  1.2  riastrad 			       struct dma_buf_attachment *attach)
    212  1.2  riastrad {
    213  1.2  riastrad 	struct drm_prime_attachment *prime_attach = attach->priv;
    214  1.2  riastrad 	struct drm_gem_object *obj = dma_buf->priv;
    215  1.2  riastrad 	struct drm_device *dev = obj->dev;
    216  1.2  riastrad 	struct sg_table *sgt;
    217  1.2  riastrad 
    218  1.2  riastrad 	if (dev->driver->gem_prime_unpin)
    219  1.2  riastrad 		dev->driver->gem_prime_unpin(obj);
    220  1.2  riastrad 
    221  1.2  riastrad 	if (!prime_attach)
    222  1.2  riastrad 		return;
    223  1.2  riastrad 
    224  1.2  riastrad 	sgt = prime_attach->sgt;
    225  1.2  riastrad 	if (sgt) {
    226  1.3  riastrad #ifndef __NetBSD__		/* We map/unmap elsewhere.  */
    227  1.2  riastrad 		if (prime_attach->dir != DMA_NONE)
    228  1.2  riastrad 			dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents,
    229  1.2  riastrad 					prime_attach->dir);
    230  1.3  riastrad #endif
    231  1.2  riastrad 		sg_free_table(sgt);
    232  1.2  riastrad 	}
    233  1.2  riastrad 
    234  1.2  riastrad 	kfree(sgt);
    235  1.2  riastrad 	kfree(prime_attach);
    236  1.2  riastrad 	attach->priv = NULL;
    237  1.2  riastrad }
    238  1.2  riastrad 
    239  1.2  riastrad void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv,
    240  1.2  riastrad 					struct dma_buf *dma_buf)
    241  1.2  riastrad {
    242  1.2  riastrad 	struct drm_prime_member *member, *safe;
    243  1.2  riastrad 
    244  1.2  riastrad 	list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) {
    245  1.2  riastrad 		if (member->dma_buf == dma_buf) {
    246  1.2  riastrad 			dma_buf_put(dma_buf);
    247  1.2  riastrad 			list_del(&member->entry);
    248  1.2  riastrad 			kfree(member);
    249  1.2  riastrad 		}
    250  1.2  riastrad 	}
    251  1.2  riastrad }
    252  1.2  riastrad 
    253  1.2  riastrad static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
    254  1.3  riastrad 						enum dma_data_direction dir)
    255  1.2  riastrad {
    256  1.2  riastrad 	struct drm_prime_attachment *prime_attach = attach->priv;
    257  1.2  riastrad 	struct drm_gem_object *obj = attach->dmabuf->priv;
    258  1.2  riastrad 	struct sg_table *sgt;
    259  1.2  riastrad 
    260  1.2  riastrad 	if (WARN_ON(dir == DMA_NONE || !prime_attach))
    261  1.2  riastrad 		return ERR_PTR(-EINVAL);
    262  1.2  riastrad 
    263  1.2  riastrad 	/* return the cached mapping when possible */
    264  1.2  riastrad 	if (prime_attach->dir == dir)
    265  1.2  riastrad 		return prime_attach->sgt;
    266  1.2  riastrad 
    267  1.2  riastrad 	/*
    268  1.2  riastrad 	 * two mappings with different directions for the same attachment are
    269  1.2  riastrad 	 * not allowed
    270  1.2  riastrad 	 */
    271  1.2  riastrad 	if (WARN_ON(prime_attach->dir != DMA_NONE))
    272  1.2  riastrad 		return ERR_PTR(-EBUSY);
    273  1.2  riastrad 
    274  1.2  riastrad 	sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
    275  1.2  riastrad 	if (!IS_ERR(sgt)) {
    276  1.3  riastrad #ifdef __NetBSD__		/* We map/unmap elsewhere.  */
    277  1.3  riastrad 		prime_attach->sgt = sgt;
    278  1.3  riastrad 		prime_attach->dir = dir;
    279  1.3  riastrad #else
    280  1.2  riastrad 		if (!dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir)) {
    281  1.2  riastrad 			sg_free_table(sgt);
    282  1.2  riastrad 			kfree(sgt);
    283  1.2  riastrad 			sgt = ERR_PTR(-ENOMEM);
    284  1.2  riastrad 		} else {
    285  1.2  riastrad 			prime_attach->sgt = sgt;
    286  1.2  riastrad 			prime_attach->dir = dir;
    287  1.2  riastrad 		}
    288  1.3  riastrad #endif
    289  1.2  riastrad 	}
    290  1.2  riastrad 
    291  1.2  riastrad 	return sgt;
    292  1.2  riastrad }
    293  1.2  riastrad 
    294  1.2  riastrad static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
    295  1.2  riastrad 				  struct sg_table *sgt,
    296  1.2  riastrad 				  enum dma_data_direction dir)
    297  1.2  riastrad {
    298  1.2  riastrad 	/* nothing to be done here */
    299  1.2  riastrad }
    300  1.2  riastrad 
    301  1.2  riastrad /**
    302  1.2  riastrad  * drm_gem_dmabuf_release - dma_buf release implementation for GEM
    303  1.2  riastrad  * @dma_buf: buffer to be released
    304  1.2  riastrad  *
    305  1.2  riastrad  * Generic release function for dma_bufs exported as PRIME buffers. GEM drivers
    306  1.2  riastrad  * must use this in their dma_buf ops structure as the release callback.
    307  1.2  riastrad  */
    308  1.2  riastrad void drm_gem_dmabuf_release(struct dma_buf *dma_buf)
    309  1.2  riastrad {
    310  1.2  riastrad 	struct drm_gem_object *obj = dma_buf->priv;
    311  1.2  riastrad 
    312  1.2  riastrad 	/* drop the reference on the export fd holds */
    313  1.2  riastrad 	drm_gem_object_unreference_unlocked(obj);
    314  1.2  riastrad }
    315  1.2  riastrad EXPORT_SYMBOL(drm_gem_dmabuf_release);
    316  1.2  riastrad 
    317  1.2  riastrad static void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf)
    318  1.2  riastrad {
    319  1.2  riastrad 	struct drm_gem_object *obj = dma_buf->priv;
    320  1.2  riastrad 	struct drm_device *dev = obj->dev;
    321  1.2  riastrad 
    322  1.2  riastrad 	return dev->driver->gem_prime_vmap(obj);
    323  1.2  riastrad }
    324  1.2  riastrad 
    325  1.2  riastrad static void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
    326  1.2  riastrad {
    327  1.2  riastrad 	struct drm_gem_object *obj = dma_buf->priv;
    328  1.2  riastrad 	struct drm_device *dev = obj->dev;
    329  1.2  riastrad 
    330  1.2  riastrad 	dev->driver->gem_prime_vunmap(obj, vaddr);
    331  1.2  riastrad }
    332  1.2  riastrad 
    333  1.2  riastrad static void *drm_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf,
    334  1.2  riastrad 					unsigned long page_num)
    335  1.2  riastrad {
    336  1.2  riastrad 	return NULL;
    337  1.2  riastrad }
    338  1.2  riastrad 
    339  1.2  riastrad static void drm_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf,
    340  1.2  riastrad 					 unsigned long page_num, void *addr)
    341  1.2  riastrad {
    342  1.2  riastrad 
    343  1.2  riastrad }
    344  1.2  riastrad static void *drm_gem_dmabuf_kmap(struct dma_buf *dma_buf,
    345  1.2  riastrad 				 unsigned long page_num)
    346  1.2  riastrad {
    347  1.2  riastrad 	return NULL;
    348  1.2  riastrad }
    349  1.2  riastrad 
    350  1.2  riastrad static void drm_gem_dmabuf_kunmap(struct dma_buf *dma_buf,
    351  1.2  riastrad 				  unsigned long page_num, void *addr)
    352  1.2  riastrad {
    353  1.2  riastrad 
    354  1.2  riastrad }
    355  1.2  riastrad 
    356  1.3  riastrad #ifdef __NetBSD__
    357  1.3  riastrad static int
    358  1.3  riastrad drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, off_t *offp, size_t size,
    359  1.3  riastrad     int prot, int *flagsp, int *advicep, struct uvm_object **uobjp,
    360  1.3  riastrad     int *maxprotp)
    361  1.3  riastrad #else
    362  1.2  riastrad static int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf,
    363  1.2  riastrad 			       struct vm_area_struct *vma)
    364  1.3  riastrad #endif
    365  1.2  riastrad {
    366  1.2  riastrad 	struct drm_gem_object *obj = dma_buf->priv;
    367  1.2  riastrad 	struct drm_device *dev = obj->dev;
    368  1.2  riastrad 
    369  1.2  riastrad 	if (!dev->driver->gem_prime_mmap)
    370  1.2  riastrad 		return -ENOSYS;
    371  1.2  riastrad 
    372  1.3  riastrad #ifdef __NetBSD__
    373  1.3  riastrad 	return dev->driver->gem_prime_mmap(obj, offp, size, prot, flagsp,
    374  1.3  riastrad 	    advicep, uobjp, maxprotp);
    375  1.3  riastrad #else
    376  1.2  riastrad 	return dev->driver->gem_prime_mmap(obj, vma);
    377  1.3  riastrad #endif
    378  1.2  riastrad }
    379  1.2  riastrad 
    380  1.2  riastrad static const struct dma_buf_ops drm_gem_prime_dmabuf_ops =  {
    381  1.2  riastrad 	.attach = drm_gem_map_attach,
    382  1.2  riastrad 	.detach = drm_gem_map_detach,
    383  1.2  riastrad 	.map_dma_buf = drm_gem_map_dma_buf,
    384  1.2  riastrad 	.unmap_dma_buf = drm_gem_unmap_dma_buf,
    385  1.2  riastrad 	.release = drm_gem_dmabuf_release,
    386  1.2  riastrad 	.kmap = drm_gem_dmabuf_kmap,
    387  1.2  riastrad 	.kmap_atomic = drm_gem_dmabuf_kmap_atomic,
    388  1.2  riastrad 	.kunmap = drm_gem_dmabuf_kunmap,
    389  1.2  riastrad 	.kunmap_atomic = drm_gem_dmabuf_kunmap_atomic,
    390  1.2  riastrad 	.mmap = drm_gem_dmabuf_mmap,
    391  1.2  riastrad 	.vmap = drm_gem_dmabuf_vmap,
    392  1.2  riastrad 	.vunmap = drm_gem_dmabuf_vunmap,
    393  1.2  riastrad };
    394  1.2  riastrad 
    395  1.2  riastrad /**
    396  1.2  riastrad  * DOC: PRIME Helpers
    397  1.2  riastrad  *
    398  1.2  riastrad  * Drivers can implement @gem_prime_export and @gem_prime_import in terms of
    399  1.2  riastrad  * simpler APIs by using the helper functions @drm_gem_prime_export and
    400  1.2  riastrad  * @drm_gem_prime_import.  These functions implement dma-buf support in terms of
    401  1.2  riastrad  * six lower-level driver callbacks:
    402  1.2  riastrad  *
    403  1.2  riastrad  * Export callbacks:
    404  1.2  riastrad  *
    405  1.2  riastrad  *  - @gem_prime_pin (optional): prepare a GEM object for exporting
    406  1.2  riastrad  *
    407  1.2  riastrad  *  - @gem_prime_get_sg_table: provide a scatter/gather table of pinned pages
    408  1.2  riastrad  *
    409  1.2  riastrad  *  - @gem_prime_vmap: vmap a buffer exported by your driver
    410  1.2  riastrad  *
    411  1.2  riastrad  *  - @gem_prime_vunmap: vunmap a buffer exported by your driver
    412  1.2  riastrad  *
    413  1.2  riastrad  *  - @gem_prime_mmap (optional): mmap a buffer exported by your driver
    414  1.2  riastrad  *
    415  1.2  riastrad  * Import callback:
    416  1.2  riastrad  *
    417  1.2  riastrad  *  - @gem_prime_import_sg_table (import): produce a GEM object from another
    418  1.2  riastrad  *    driver's scatter/gather table
    419  1.2  riastrad  */
    420  1.2  riastrad 
    421  1.2  riastrad /**
    422  1.2  riastrad  * drm_gem_prime_export - helper library implementation of the export callback
    423  1.2  riastrad  * @dev: drm_device to export from
    424  1.2  riastrad  * @obj: GEM object to export
    425  1.2  riastrad  * @flags: flags like DRM_CLOEXEC
    426  1.2  riastrad  *
    427  1.2  riastrad  * This is the implementation of the gem_prime_export functions for GEM drivers
    428  1.2  riastrad  * using the PRIME helpers.
    429  1.2  riastrad  */
    430  1.2  riastrad struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
    431  1.2  riastrad 				     struct drm_gem_object *obj,
    432  1.2  riastrad 				     int flags)
    433  1.2  riastrad {
    434  1.2  riastrad 	struct dma_buf_export_info exp_info = {
    435  1.3  riastrad #ifndef __NetBSD__
    436  1.2  riastrad 		.exp_name = KBUILD_MODNAME, /* white lie for debug */
    437  1.2  riastrad 		.owner = dev->driver->fops->owner,
    438  1.3  riastrad #endif
    439  1.2  riastrad 		.ops = &drm_gem_prime_dmabuf_ops,
    440  1.2  riastrad 		.size = obj->size,
    441  1.2  riastrad 		.flags = flags,
    442  1.2  riastrad 		.priv = obj,
    443  1.2  riastrad 	};
    444  1.2  riastrad 
    445  1.2  riastrad 	if (dev->driver->gem_prime_res_obj)
    446  1.2  riastrad 		exp_info.resv = dev->driver->gem_prime_res_obj(obj);
    447  1.2  riastrad 
    448  1.2  riastrad 	return dma_buf_export(&exp_info);
    449  1.2  riastrad }
    450  1.2  riastrad EXPORT_SYMBOL(drm_gem_prime_export);
    451  1.2  riastrad 
    452  1.2  riastrad static struct dma_buf *export_and_register_object(struct drm_device *dev,
    453  1.2  riastrad 						  struct drm_gem_object *obj,
    454  1.2  riastrad 						  uint32_t flags)
    455  1.2  riastrad {
    456  1.2  riastrad 	struct dma_buf *dmabuf;
    457  1.2  riastrad 
    458  1.2  riastrad 	/* prevent races with concurrent gem_close. */
    459  1.2  riastrad 	if (obj->handle_count == 0) {
    460  1.2  riastrad 		dmabuf = ERR_PTR(-ENOENT);
    461  1.2  riastrad 		return dmabuf;
    462  1.2  riastrad 	}
    463  1.2  riastrad 
    464  1.2  riastrad 	dmabuf = dev->driver->gem_prime_export(dev, obj, flags);
    465  1.2  riastrad 	if (IS_ERR(dmabuf)) {
    466  1.2  riastrad 		/* normally the created dma-buf takes ownership of the ref,
    467  1.2  riastrad 		 * but if that fails then drop the ref
    468  1.2  riastrad 		 */
    469  1.2  riastrad 		return dmabuf;
    470  1.2  riastrad 	}
    471  1.2  riastrad 
    472  1.2  riastrad 	/*
    473  1.2  riastrad 	 * Note that callers do not need to clean up the export cache
    474  1.2  riastrad 	 * since the check for obj->handle_count guarantees that someone
    475  1.2  riastrad 	 * will clean it up.
    476  1.2  riastrad 	 */
    477  1.2  riastrad 	obj->dma_buf = dmabuf;
    478  1.2  riastrad 	get_dma_buf(obj->dma_buf);
    479  1.2  riastrad 	/* Grab a new ref since the callers is now used by the dma-buf */
    480  1.2  riastrad 	drm_gem_object_reference(obj);
    481  1.2  riastrad 
    482  1.2  riastrad 	return dmabuf;
    483  1.2  riastrad }
    484  1.2  riastrad 
    485  1.2  riastrad /**
    486  1.2  riastrad  * drm_gem_prime_handle_to_fd - PRIME export function for GEM drivers
    487  1.2  riastrad  * @dev: dev to export the buffer from
    488  1.2  riastrad  * @file_priv: drm file-private structure
    489  1.2  riastrad  * @handle: buffer handle to export
    490  1.2  riastrad  * @flags: flags like DRM_CLOEXEC
    491  1.2  riastrad  * @prime_fd: pointer to storage for the fd id of the create dma-buf
    492  1.2  riastrad  *
    493  1.2  riastrad  * This is the PRIME export function which must be used mandatorily by GEM
    494  1.2  riastrad  * drivers to ensure correct lifetime management of the underlying GEM object.
    495  1.2  riastrad  * The actual exporting from GEM object to a dma-buf is done through the
    496  1.2  riastrad  * gem_prime_export driver callback.
    497  1.2  riastrad  */
    498  1.1  riastrad int drm_gem_prime_handle_to_fd(struct drm_device *dev,
    499  1.2  riastrad 			       struct drm_file *file_priv, uint32_t handle,
    500  1.2  riastrad 			       uint32_t flags,
    501  1.2  riastrad 			       int *prime_fd)
    502  1.1  riastrad {
    503  1.1  riastrad 	struct drm_gem_object *obj;
    504  1.2  riastrad 	int ret = 0;
    505  1.2  riastrad 	struct dma_buf *dmabuf;
    506  1.1  riastrad 
    507  1.2  riastrad 	mutex_lock(&file_priv->prime.lock);
    508  1.1  riastrad 	obj = drm_gem_object_lookup(dev, file_priv, handle);
    509  1.2  riastrad 	if (!obj)  {
    510  1.2  riastrad 		ret = -ENOENT;
    511  1.2  riastrad 		goto out_unlock;
    512  1.2  riastrad 	}
    513  1.2  riastrad 
    514  1.2  riastrad 	dmabuf = drm_prime_lookup_buf_by_handle(&file_priv->prime, handle);
    515  1.2  riastrad 	if (dmabuf) {
    516  1.2  riastrad 		get_dma_buf(dmabuf);
    517  1.2  riastrad 		goto out_have_handle;
    518  1.2  riastrad 	}
    519  1.1  riastrad 
    520  1.2  riastrad 	mutex_lock(&dev->object_name_lock);
    521  1.1  riastrad 	/* re-export the original imported object */
    522  1.1  riastrad 	if (obj->import_attach) {
    523  1.2  riastrad 		dmabuf = obj->import_attach->dmabuf;
    524  1.2  riastrad 		get_dma_buf(dmabuf);
    525  1.2  riastrad 		goto out_have_obj;
    526  1.2  riastrad 	}
    527  1.2  riastrad 
    528  1.2  riastrad 	if (obj->dma_buf) {
    529  1.2  riastrad 		get_dma_buf(obj->dma_buf);
    530  1.2  riastrad 		dmabuf = obj->dma_buf;
    531  1.2  riastrad 		goto out_have_obj;
    532  1.2  riastrad 	}
    533  1.2  riastrad 
    534  1.2  riastrad 	dmabuf = export_and_register_object(dev, obj, flags);
    535  1.2  riastrad 	if (IS_ERR(dmabuf)) {
    536  1.2  riastrad 		/* normally the created dma-buf takes ownership of the ref,
    537  1.2  riastrad 		 * but if that fails then drop the ref
    538  1.2  riastrad 		 */
    539  1.2  riastrad 		ret = PTR_ERR(dmabuf);
    540  1.2  riastrad 		mutex_unlock(&dev->object_name_lock);
    541  1.2  riastrad 		goto out;
    542  1.1  riastrad 	}
    543  1.1  riastrad 
    544  1.2  riastrad out_have_obj:
    545  1.2  riastrad 	/*
    546  1.2  riastrad 	 * If we've exported this buffer then cheat and add it to the import list
    547  1.2  riastrad 	 * so we get the correct handle back. We must do this under the
    548  1.2  riastrad 	 * protection of dev->object_name_lock to ensure that a racing gem close
    549  1.2  riastrad 	 * ioctl doesn't miss to remove this buffer handle from the cache.
    550  1.2  riastrad 	 */
    551  1.2  riastrad 	ret = drm_prime_add_buf_handle(&file_priv->prime,
    552  1.2  riastrad 				       dmabuf, handle);
    553  1.2  riastrad 	mutex_unlock(&dev->object_name_lock);
    554  1.2  riastrad 	if (ret)
    555  1.2  riastrad 		goto fail_put_dmabuf;
    556  1.2  riastrad 
    557  1.2  riastrad out_have_handle:
    558  1.2  riastrad 	ret = dma_buf_fd(dmabuf, flags);
    559  1.2  riastrad 	/*
    560  1.2  riastrad 	 * We must _not_ remove the buffer from the handle cache since the newly
    561  1.2  riastrad 	 * created dma buf is already linked in the global obj->dma_buf pointer,
    562  1.2  riastrad 	 * and that is invariant as long as a userspace gem handle exists.
    563  1.2  riastrad 	 * Closing the handle will clean out the cache anyway, so we don't leak.
    564  1.2  riastrad 	 */
    565  1.2  riastrad 	if (ret < 0) {
    566  1.2  riastrad 		goto fail_put_dmabuf;
    567  1.1  riastrad 	} else {
    568  1.2  riastrad 		*prime_fd = ret;
    569  1.2  riastrad 		ret = 0;
    570  1.2  riastrad 	}
    571  1.2  riastrad 
    572  1.2  riastrad 	goto out;
    573  1.2  riastrad 
    574  1.2  riastrad fail_put_dmabuf:
    575  1.2  riastrad 	dma_buf_put(dmabuf);
    576  1.2  riastrad out:
    577  1.2  riastrad 	drm_gem_object_unreference_unlocked(obj);
    578  1.2  riastrad out_unlock:
    579  1.2  riastrad 	mutex_unlock(&file_priv->prime.lock);
    580  1.2  riastrad 
    581  1.2  riastrad 	return ret;
    582  1.2  riastrad }
    583  1.2  riastrad EXPORT_SYMBOL(drm_gem_prime_handle_to_fd);
    584  1.2  riastrad 
    585  1.2  riastrad /**
    586  1.2  riastrad  * drm_gem_prime_import - helper library implementation of the import callback
    587  1.2  riastrad  * @dev: drm_device to import into
    588  1.2  riastrad  * @dma_buf: dma-buf object to import
    589  1.2  riastrad  *
    590  1.2  riastrad  * This is the implementation of the gem_prime_import functions for GEM drivers
    591  1.2  riastrad  * using the PRIME helpers.
    592  1.2  riastrad  */
    593  1.2  riastrad struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
    594  1.2  riastrad 					    struct dma_buf *dma_buf)
    595  1.2  riastrad {
    596  1.2  riastrad 	struct dma_buf_attachment *attach;
    597  1.2  riastrad 	struct sg_table *sgt;
    598  1.2  riastrad 	struct drm_gem_object *obj;
    599  1.2  riastrad 	int ret;
    600  1.2  riastrad 
    601  1.2  riastrad 	if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
    602  1.2  riastrad 		obj = dma_buf->priv;
    603  1.2  riastrad 		if (obj->dev == dev) {
    604  1.2  riastrad 			/*
    605  1.2  riastrad 			 * Importing dmabuf exported from out own gem increases
    606  1.2  riastrad 			 * refcount on gem itself instead of f_count of dmabuf.
    607  1.1  riastrad 			 */
    608  1.2  riastrad 			drm_gem_object_reference(obj);
    609  1.2  riastrad 			return obj;
    610  1.1  riastrad 		}
    611  1.1  riastrad 	}
    612  1.2  riastrad 
    613  1.2  riastrad 	if (!dev->driver->gem_prime_import_sg_table)
    614  1.2  riastrad 		return ERR_PTR(-EINVAL);
    615  1.2  riastrad 
    616  1.2  riastrad 	attach = dma_buf_attach(dma_buf, dev->dev);
    617  1.2  riastrad 	if (IS_ERR(attach))
    618  1.2  riastrad 		return ERR_CAST(attach);
    619  1.2  riastrad 
    620  1.2  riastrad 	get_dma_buf(dma_buf);
    621  1.2  riastrad 
    622  1.2  riastrad 	sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
    623  1.2  riastrad 	if (IS_ERR(sgt)) {
    624  1.2  riastrad 		ret = PTR_ERR(sgt);
    625  1.2  riastrad 		goto fail_detach;
    626  1.2  riastrad 	}
    627  1.2  riastrad 
    628  1.2  riastrad 	obj = dev->driver->gem_prime_import_sg_table(dev, attach, sgt);
    629  1.2  riastrad 	if (IS_ERR(obj)) {
    630  1.2  riastrad 		ret = PTR_ERR(obj);
    631  1.2  riastrad 		goto fail_unmap;
    632  1.1  riastrad 	}
    633  1.1  riastrad 
    634  1.2  riastrad 	obj->import_attach = attach;
    635  1.2  riastrad 
    636  1.2  riastrad 	return obj;
    637  1.2  riastrad 
    638  1.2  riastrad fail_unmap:
    639  1.2  riastrad 	dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
    640  1.2  riastrad fail_detach:
    641  1.2  riastrad 	dma_buf_detach(dma_buf, attach);
    642  1.2  riastrad 	dma_buf_put(dma_buf);
    643  1.2  riastrad 
    644  1.2  riastrad 	return ERR_PTR(ret);
    645  1.1  riastrad }
    646  1.2  riastrad EXPORT_SYMBOL(drm_gem_prime_import);
    647  1.1  riastrad 
    648  1.2  riastrad /**
    649  1.2  riastrad  * drm_gem_prime_fd_to_handle - PRIME import function for GEM drivers
    650  1.2  riastrad  * @dev: dev to export the buffer from
    651  1.2  riastrad  * @file_priv: drm file-private structure
    652  1.2  riastrad  * @prime_fd: fd id of the dma-buf which should be imported
    653  1.2  riastrad  * @handle: pointer to storage for the handle of the imported buffer object
    654  1.2  riastrad  *
    655  1.2  riastrad  * This is the PRIME import function which must be used mandatorily by GEM
    656  1.2  riastrad  * drivers to ensure correct lifetime management of the underlying GEM object.
    657  1.2  riastrad  * The actual importing of GEM object from the dma-buf is done through the
    658  1.2  riastrad  * gem_import_export driver callback.
    659  1.2  riastrad  */
    660  1.1  riastrad int drm_gem_prime_fd_to_handle(struct drm_device *dev,
    661  1.2  riastrad 			       struct drm_file *file_priv, int prime_fd,
    662  1.2  riastrad 			       uint32_t *handle)
    663  1.1  riastrad {
    664  1.1  riastrad 	struct dma_buf *dma_buf;
    665  1.1  riastrad 	struct drm_gem_object *obj;
    666  1.1  riastrad 	int ret;
    667  1.1  riastrad 
    668  1.1  riastrad 	dma_buf = dma_buf_get(prime_fd);
    669  1.1  riastrad 	if (IS_ERR(dma_buf))
    670  1.1  riastrad 		return PTR_ERR(dma_buf);
    671  1.1  riastrad 
    672  1.1  riastrad 	mutex_lock(&file_priv->prime.lock);
    673  1.1  riastrad 
    674  1.2  riastrad 	ret = drm_prime_lookup_buf_handle(&file_priv->prime,
    675  1.1  riastrad 			dma_buf, handle);
    676  1.2  riastrad 	if (ret == 0)
    677  1.1  riastrad 		goto out_put;
    678  1.1  riastrad 
    679  1.1  riastrad 	/* never seen this one, need to import */
    680  1.2  riastrad 	mutex_lock(&dev->object_name_lock);
    681  1.1  riastrad 	obj = dev->driver->gem_prime_import(dev, dma_buf);
    682  1.1  riastrad 	if (IS_ERR(obj)) {
    683  1.1  riastrad 		ret = PTR_ERR(obj);
    684  1.2  riastrad 		goto out_unlock;
    685  1.2  riastrad 	}
    686  1.2  riastrad 
    687  1.2  riastrad 	if (obj->dma_buf) {
    688  1.2  riastrad 		WARN_ON(obj->dma_buf != dma_buf);
    689  1.2  riastrad 	} else {
    690  1.2  riastrad 		obj->dma_buf = dma_buf;
    691  1.2  riastrad 		get_dma_buf(dma_buf);
    692  1.1  riastrad 	}
    693  1.1  riastrad 
    694  1.2  riastrad 	/* drm_gem_handle_create_tail unlocks dev->object_name_lock. */
    695  1.2  riastrad 	ret = drm_gem_handle_create_tail(file_priv, obj, handle);
    696  1.1  riastrad 	drm_gem_object_unreference_unlocked(obj);
    697  1.1  riastrad 	if (ret)
    698  1.1  riastrad 		goto out_put;
    699  1.1  riastrad 
    700  1.2  riastrad 	ret = drm_prime_add_buf_handle(&file_priv->prime,
    701  1.1  riastrad 			dma_buf, *handle);
    702  1.1  riastrad 	if (ret)
    703  1.1  riastrad 		goto fail;
    704  1.1  riastrad 
    705  1.1  riastrad 	mutex_unlock(&file_priv->prime.lock);
    706  1.2  riastrad 
    707  1.2  riastrad 	dma_buf_put(dma_buf);
    708  1.2  riastrad 
    709  1.1  riastrad 	return 0;
    710  1.1  riastrad 
    711  1.1  riastrad fail:
    712  1.1  riastrad 	/* hmm, if driver attached, we are relying on the free-object path
    713  1.1  riastrad 	 * to detach.. which seems ok..
    714  1.1  riastrad 	 */
    715  1.2  riastrad 	drm_gem_handle_delete(file_priv, *handle);
    716  1.2  riastrad out_unlock:
    717  1.2  riastrad 	mutex_unlock(&dev->object_name_lock);
    718  1.1  riastrad out_put:
    719  1.1  riastrad 	dma_buf_put(dma_buf);
    720  1.1  riastrad 	mutex_unlock(&file_priv->prime.lock);
    721  1.1  riastrad 	return ret;
    722  1.1  riastrad }
    723  1.1  riastrad EXPORT_SYMBOL(drm_gem_prime_fd_to_handle);
    724  1.1  riastrad 
    725  1.1  riastrad int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
    726  1.1  riastrad 				 struct drm_file *file_priv)
    727  1.1  riastrad {
    728  1.1  riastrad 	struct drm_prime_handle *args = data;
    729  1.1  riastrad 	uint32_t flags;
    730  1.1  riastrad 
    731  1.1  riastrad 	if (!drm_core_check_feature(dev, DRIVER_PRIME))
    732  1.1  riastrad 		return -EINVAL;
    733  1.1  riastrad 
    734  1.1  riastrad 	if (!dev->driver->prime_handle_to_fd)
    735  1.1  riastrad 		return -ENOSYS;
    736  1.1  riastrad 
    737  1.1  riastrad 	/* check flags are valid */
    738  1.1  riastrad 	if (args->flags & ~DRM_CLOEXEC)
    739  1.1  riastrad 		return -EINVAL;
    740  1.1  riastrad 
    741  1.1  riastrad 	/* we only want to pass DRM_CLOEXEC which is == O_CLOEXEC */
    742  1.1  riastrad 	flags = args->flags & DRM_CLOEXEC;
    743  1.1  riastrad 
    744  1.1  riastrad 	return dev->driver->prime_handle_to_fd(dev, file_priv,
    745  1.1  riastrad 			args->handle, flags, &args->fd);
    746  1.1  riastrad }
    747  1.1  riastrad 
    748  1.1  riastrad int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
    749  1.1  riastrad 				 struct drm_file *file_priv)
    750  1.1  riastrad {
    751  1.1  riastrad 	struct drm_prime_handle *args = data;
    752  1.1  riastrad 
    753  1.1  riastrad 	if (!drm_core_check_feature(dev, DRIVER_PRIME))
    754  1.1  riastrad 		return -EINVAL;
    755  1.1  riastrad 
    756  1.1  riastrad 	if (!dev->driver->prime_fd_to_handle)
    757  1.1  riastrad 		return -ENOSYS;
    758  1.1  riastrad 
    759  1.1  riastrad 	return dev->driver->prime_fd_to_handle(dev, file_priv,
    760  1.1  riastrad 			args->fd, &args->handle);
    761  1.1  riastrad }
    762  1.1  riastrad 
    763  1.2  riastrad /**
    764  1.2  riastrad  * drm_prime_pages_to_sg - converts a page array into an sg list
    765  1.2  riastrad  * @pages: pointer to the array of page pointers to convert
    766  1.2  riastrad  * @nr_pages: length of the page vector
    767  1.1  riastrad  *
    768  1.2  riastrad  * This helper creates an sg table object from a set of pages
    769  1.1  riastrad  * the driver is responsible for mapping the pages into the
    770  1.2  riastrad  * importers address space for use with dma_buf itself.
    771  1.1  riastrad  */
    772  1.2  riastrad struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages)
    773  1.1  riastrad {
    774  1.1  riastrad 	struct sg_table *sg = NULL;
    775  1.1  riastrad 	int ret;
    776  1.1  riastrad 
    777  1.1  riastrad 	sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
    778  1.2  riastrad 	if (!sg) {
    779  1.2  riastrad 		ret = -ENOMEM;
    780  1.1  riastrad 		goto out;
    781  1.2  riastrad 	}
    782  1.1  riastrad 
    783  1.2  riastrad 	ret = sg_alloc_table_from_pages(sg, pages, nr_pages, 0,
    784  1.2  riastrad 				nr_pages << PAGE_SHIFT, GFP_KERNEL);
    785  1.1  riastrad 	if (ret)
    786  1.1  riastrad 		goto out;
    787  1.1  riastrad 
    788  1.1  riastrad 	return sg;
    789  1.1  riastrad out:
    790  1.1  riastrad 	kfree(sg);
    791  1.2  riastrad 	return ERR_PTR(ret);
    792  1.1  riastrad }
    793  1.1  riastrad EXPORT_SYMBOL(drm_prime_pages_to_sg);
    794  1.1  riastrad 
    795  1.3  riastrad #ifdef __NetBSD__
    796  1.3  riastrad 
    797  1.3  riastrad struct sg_table *
    798  1.3  riastrad drm_prime_pglist_to_sg(struct pglist *pglist, unsigned npages)
    799  1.3  riastrad {
    800  1.3  riastrad 	struct sg_table *sg;
    801  1.3  riastrad 	int ret;
    802  1.3  riastrad 
    803  1.3  riastrad 	sg = kmalloc(sizeof(*sg), GFP_KERNEL);
    804  1.3  riastrad 	if (sg == NULL) {
    805  1.3  riastrad 		ret = -ENOMEM;
    806  1.3  riastrad 		goto out;
    807  1.3  riastrad 	}
    808  1.3  riastrad 
    809  1.3  riastrad 	ret = sg_alloc_table_from_pglist(sg, pglist, 0, npages << PAGE_SHIFT,
    810  1.3  riastrad 	    npages, GFP_KERNEL);
    811  1.3  riastrad 	if (ret)
    812  1.3  riastrad 		goto out;
    813  1.3  riastrad 
    814  1.3  riastrad 	return sg;
    815  1.3  riastrad 
    816  1.3  riastrad out:
    817  1.3  riastrad 	kfree(sg);
    818  1.3  riastrad 	return ERR_PTR(ret);
    819  1.3  riastrad }
    820  1.3  riastrad 
    821  1.3  riastrad void
    822  1.3  riastrad drm_prime_sg_free(struct sg_table *sg)
    823  1.3  riastrad {
    824  1.3  riastrad 
    825  1.3  riastrad 	sg_free_table(sg);
    826  1.3  riastrad 	kfree(sg);
    827  1.3  riastrad }
    828  1.3  riastrad 
    829  1.3  riastrad int
    830  1.3  riastrad drm_prime_bus_dmamap_load_sgt(bus_dma_tag_t dmat, bus_dmamap_t map,
    831  1.3  riastrad     struct sg_table *sgt)
    832  1.3  riastrad {
    833  1.3  riastrad 
    834  1.3  riastrad 	/* XXX errno NetBSD->Linux */
    835  1.3  riastrad 	return -bus_dmamap_load_raw(dmat, map, sgt->sgt_segs, sgt->sgt_nsegs,
    836  1.3  riastrad 	    sgt->sgt_size, BUS_DMA_NOWAIT);
    837  1.3  riastrad }
    838  1.3  riastrad 
    839  1.3  riastrad #else  /* !__NetBSD__ */
    840  1.3  riastrad 
    841  1.2  riastrad /**
    842  1.2  riastrad  * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array
    843  1.2  riastrad  * @sgt: scatter-gather table to convert
    844  1.2  riastrad  * @pages: array of page pointers to store the page array in
    845  1.2  riastrad  * @addrs: optional array to store the dma bus address of each page
    846  1.2  riastrad  * @max_pages: size of both the passed-in arrays
    847  1.2  riastrad  *
    848  1.2  riastrad  * Exports an sg table into an array of pages and addresses. This is currently
    849  1.2  riastrad  * required by the TTM driver in order to do correct fault handling.
    850  1.2  riastrad  */
    851  1.1  riastrad int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
    852  1.1  riastrad 				     dma_addr_t *addrs, int max_pages)
    853  1.1  riastrad {
    854  1.1  riastrad 	unsigned count;
    855  1.1  riastrad 	struct scatterlist *sg;
    856  1.1  riastrad 	struct page *page;
    857  1.2  riastrad 	u32 len;
    858  1.1  riastrad 	int pg_index;
    859  1.1  riastrad 	dma_addr_t addr;
    860  1.1  riastrad 
    861  1.1  riastrad 	pg_index = 0;
    862  1.1  riastrad 	for_each_sg(sgt->sgl, sg, sgt->nents, count) {
    863  1.1  riastrad 		len = sg->length;
    864  1.1  riastrad 		page = sg_page(sg);
    865  1.1  riastrad 		addr = sg_dma_address(sg);
    866  1.1  riastrad 
    867  1.1  riastrad 		while (len > 0) {
    868  1.1  riastrad 			if (WARN_ON(pg_index >= max_pages))
    869  1.1  riastrad 				return -1;
    870  1.1  riastrad 			pages[pg_index] = page;
    871  1.1  riastrad 			if (addrs)
    872  1.1  riastrad 				addrs[pg_index] = addr;
    873  1.1  riastrad 
    874  1.1  riastrad 			page++;
    875  1.1  riastrad 			addr += PAGE_SIZE;
    876  1.1  riastrad 			len -= PAGE_SIZE;
    877  1.1  riastrad 			pg_index++;
    878  1.1  riastrad 		}
    879  1.1  riastrad 	}
    880  1.1  riastrad 	return 0;
    881  1.1  riastrad }
    882  1.1  riastrad EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays);
    883  1.2  riastrad 
    884  1.3  riastrad #endif	/* __NetBSD__ */
    885  1.3  riastrad 
    886  1.2  riastrad /**
    887  1.2  riastrad  * drm_prime_gem_destroy - helper to clean up a PRIME-imported GEM object
    888  1.2  riastrad  * @obj: GEM object which was created from a dma-buf
    889  1.2  riastrad  * @sg: the sg-table which was pinned at import time
    890  1.2  riastrad  *
    891  1.2  riastrad  * This is the cleanup functions which GEM drivers need to call when they use
    892  1.2  riastrad  * @drm_gem_prime_import to import dma-bufs.
    893  1.2  riastrad  */
    894  1.1  riastrad void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg)
    895  1.1  riastrad {
    896  1.1  riastrad 	struct dma_buf_attachment *attach;
    897  1.1  riastrad 	struct dma_buf *dma_buf;
    898  1.1  riastrad 	attach = obj->import_attach;
    899  1.1  riastrad 	if (sg)
    900  1.1  riastrad 		dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
    901  1.1  riastrad 	dma_buf = attach->dmabuf;
    902  1.1  riastrad 	dma_buf_detach(attach->dmabuf, attach);
    903  1.1  riastrad 	/* remove the reference */
    904  1.1  riastrad 	dma_buf_put(dma_buf);
    905  1.1  riastrad }
    906  1.1  riastrad EXPORT_SYMBOL(drm_prime_gem_destroy);
    907  1.1  riastrad 
    908  1.1  riastrad void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv)
    909  1.1  riastrad {
    910  1.1  riastrad 	INIT_LIST_HEAD(&prime_fpriv->head);
    911  1.3  riastrad #ifdef __NetBSD__
    912  1.3  riastrad 	linux_mutex_init(&prime_fpriv->lock);
    913  1.3  riastrad #else
    914  1.1  riastrad 	mutex_init(&prime_fpriv->lock);
    915  1.3  riastrad #endif
    916  1.1  riastrad }
    917  1.1  riastrad 
    918  1.1  riastrad void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv)
    919  1.1  riastrad {
    920  1.2  riastrad 	/* by now drm_gem_release should've made sure the list is empty */
    921  1.2  riastrad 	WARN_ON(!list_empty(&prime_fpriv->head));
    922  1.3  riastrad #ifdef __NetBSD__
    923  1.3  riastrad 	linux_mutex_destroy(&prime_fpriv->lock);
    924  1.3  riastrad #else
    925  1.3  riastrad 	mutex_destroy(&prime_fpriv->lock);
    926  1.3  riastrad #endif
    927  1.1  riastrad }
    928