From 102d6dba306c825cd5c310f73868b130931f47aa Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 9 Apr 2013 09:18:44 +0200 Subject: drm: add unpin function to prime helpers Prevents buffers from being pinned forever. Signed-off-by: Maarten Lankhorst Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index dcde35231e25..1a36b0c22732 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -92,10 +92,13 @@ static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, static void drm_gem_dmabuf_release(struct dma_buf *dma_buf) { struct drm_gem_object *obj = dma_buf->priv; + struct drm_device *dev = obj->dev; if (obj->export_dma_buf == dma_buf) { /* drop the reference on the export fd holds */ obj->export_dma_buf = NULL; + if (dev->driver->gem_prime_unpin) + dev->driver->gem_prime_unpin(obj); drm_gem_object_unreference_unlocked(obj); } } @@ -185,13 +188,19 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { struct dma_buf *drm_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) { + struct dma_buf *buf; + if (dev->driver->gem_prime_pin) { int ret = dev->driver->gem_prime_pin(obj); if (ret) return ERR_PTR(ret); } - return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, - 0600); + buf = dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, + 0600); + + if (IS_ERR(buf) && dev->driver->gem_prime_unpin) + dev->driver->gem_prime_unpin(obj); + return buf; } EXPORT_SYMBOL(drm_gem_prime_export); -- cgit v1.2.3 From ca793f75d91d61fd0009c4179eb88aac54a74239 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 9 Apr 2013 09:52:54 +0200 Subject: drm: move pinning/unpinning to buffer attach This allows importing bo's to own device to work without requiring that the buffer is pinned in GART. Signed-off-by: Maarten Lankhorst Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 1a36b0c22732..58ac6770a8c6 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -64,6 +64,29 @@ struct drm_prime_member { }; static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle); +static int drm_gem_map_attach(struct dma_buf *dma_buf, + struct device *target_dev, + struct dma_buf_attachment *attach) +{ + struct drm_gem_object *obj = dma_buf->priv; + struct drm_device *dev = obj->dev; + + if (!dev->driver->gem_prime_pin) + return 0; + + return dev->driver->gem_prime_pin(obj); +} + +static void drm_gem_map_detach(struct dma_buf *dma_buf, + struct dma_buf_attachment *attach) +{ + struct drm_gem_object *obj = dma_buf->priv; + struct drm_device *dev = obj->dev; + + if (dev->driver->gem_prime_unpin) + dev->driver->gem_prime_unpin(obj); +} + static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, enum dma_data_direction dir) { @@ -92,13 +115,10 @@ static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, static void drm_gem_dmabuf_release(struct dma_buf *dma_buf) { struct drm_gem_object *obj = dma_buf->priv; - struct drm_device *dev = obj->dev; if (obj->export_dma_buf == dma_buf) { /* drop the reference on the export fd holds */ obj->export_dma_buf = NULL; - if (dev->driver->gem_prime_unpin) - dev->driver->gem_prime_unpin(obj); drm_gem_object_unreference_unlocked(obj); } } @@ -149,6 +169,8 @@ static int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, } static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { + .attach = drm_gem_map_attach, + .detach = drm_gem_map_detach, .map_dma_buf = drm_gem_map_dma_buf, .unmap_dma_buf = drm_gem_unmap_dma_buf, .release = drm_gem_dmabuf_release, @@ -188,19 +210,8 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { struct dma_buf *drm_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) { - struct dma_buf *buf; - - if (dev->driver->gem_prime_pin) { - int ret = dev->driver->gem_prime_pin(obj); - if (ret) - return ERR_PTR(ret); - } - buf = dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, + return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, 0600); - - if (IS_ERR(buf) && dev->driver->gem_prime_unpin) - dev->driver->gem_prime_unpin(obj); - return buf; } EXPORT_SYMBOL(drm_gem_prime_export); -- cgit v1.2.3 From f2a5da4ff2d4085ef5c777cad8a57e083d037809 Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Sat, 1 Jun 2013 10:09:27 +0000 Subject: drm/prime: Cocci spatch "err_cast.spatch" Signed-off-by: Thomas Meyer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 58ac6770a8c6..d92853e06dbb 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -297,7 +297,7 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, attach = dma_buf_attach(dma_buf, dev->dev); if (IS_ERR(attach)) - return ERR_PTR(PTR_ERR(attach)); + return ERR_CAST(attach); get_dma_buf(dma_buf); -- cgit v1.2.3 From b720d54a5caf077011f0dc6ba7792866d2828d16 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 24 Jun 2013 15:34:21 +0900 Subject: drm/prime: fix to check return of dma_map_sg in prime helper The dma_map_sg(), in map_dma_buf callback operation of prime helper, can return 0 when it fails to map, so it needs to release related resources. Signed-off-by: YoungJun Cho Signed-off-by: Seung-Woo Kim Signed-off-by: Kyungmin Park Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index e57c675db840..0daf2122a91d 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -97,8 +97,13 @@ static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, sgt = obj->dev->driver->gem_prime_get_sg_table(obj); - if (!IS_ERR_OR_NULL(sgt)) - dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir); + if (!IS_ERR_OR_NULL(sgt)) { + if (!dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir)) { + sg_free_table(sgt); + kfree(sgt); + sgt = ERR_PTR(-ENOMEM); + } + } mutex_unlock(&obj->dev->struct_mutex); return sgt; -- cgit v1.2.3 From 7e3d88f9cce3ea3350fa25b89393a6dd2b8e5ed4 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 24 Jun 2013 16:40:53 +0900 Subject: drm/prime: replace NULL with error value in drm_prime_pages_to_sg Instead of NULL, error value is casted with ERR_PTR() for drm_prime_pages_to_sg() and IS_ERR_OR_NULL() macro is replaced with IS_ERR() macro for drm_gem_map_dma_buf(). Signed-off-by: YoungJun Cho Signed-off-by: Seung-Woo Kim Signed-off-by: Kyungmin Park Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 0daf2122a91d..4ad2c45090b3 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -97,7 +97,7 @@ static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, sgt = obj->dev->driver->gem_prime_get_sg_table(obj); - if (!IS_ERR_OR_NULL(sgt)) { + if (!IS_ERR(sgt)) { if (!dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir)) { sg_free_table(sgt); kfree(sgt); @@ -437,8 +437,10 @@ struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) int ret; sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!sg) + if (!sg) { + ret = -ENOMEM; goto out; + } ret = sg_alloc_table_from_pages(sg, pages, nr_pages, 0, nr_pages << PAGE_SHIFT, GFP_KERNEL); @@ -448,7 +450,7 @@ struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) return sg; out: kfree(sg); - return NULL; + return ERR_PTR(ret); } EXPORT_SYMBOL(drm_prime_pages_to_sg); -- cgit v1.2.3 From 538d6661f5d8ad9dcf4ab66c9a99407464111e7a Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Wed, 19 Jun 2013 15:03:05 +0900 Subject: drm/prime: support to cache mapping The drm prime also can support it like GEM CMA supports to cache mapping. It doesn't allow multiple mappings for one attachment. [airlied: rebased on top of other prime changes] Signed-off-by: Joonyoung Shim Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 52 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 4ad2c45090b3..b1cd47438850 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -62,15 +62,29 @@ struct drm_prime_member { struct dma_buf *dma_buf; uint32_t handle; }; + +struct drm_prime_attachment { + struct sg_table *sgt; + enum dma_data_direction dir; +}; + static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle); static int drm_gem_map_attach(struct dma_buf *dma_buf, struct device *target_dev, struct dma_buf_attachment *attach) { + struct drm_prime_attachment *prime_attach; struct drm_gem_object *obj = dma_buf->priv; struct drm_device *dev = obj->dev; + prime_attach = kzalloc(sizeof(*prime_attach), GFP_KERNEL); + if (!prime_attach) + return -ENOMEM; + + prime_attach->dir = DMA_NONE; + attach->priv = prime_attach; + if (!dev->driver->gem_prime_pin) return 0; @@ -80,19 +94,50 @@ static int drm_gem_map_attach(struct dma_buf *dma_buf, static void drm_gem_map_detach(struct dma_buf *dma_buf, struct dma_buf_attachment *attach) { + struct drm_prime_attachment *prime_attach = attach->priv; struct drm_gem_object *obj = dma_buf->priv; struct drm_device *dev = obj->dev; + struct sg_table *sgt; if (dev->driver->gem_prime_unpin) dev->driver->gem_prime_unpin(obj); + + if (!prime_attach) + return; + + sgt = prime_attach->sgt; + + if (prime_attach->dir != DMA_NONE) + dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, + prime_attach->dir); + + sg_free_table(sgt); + kfree(sgt); + kfree(prime_attach); + attach->priv = NULL; } static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, enum dma_data_direction dir) { + struct drm_prime_attachment *prime_attach = attach->priv; struct drm_gem_object *obj = attach->dmabuf->priv; struct sg_table *sgt; + if (WARN_ON(dir == DMA_NONE || !prime_attach)) + return ERR_PTR(-EINVAL); + + /* return the cached mapping when possible */ + if (prime_attach->dir == dir) + return prime_attach->sgt; + + /* + * two mappings with different directions for the same attachment are + * not allowed + */ + if (WARN_ON(prime_attach->dir != DMA_NONE)) + return ERR_PTR(-EBUSY); + mutex_lock(&obj->dev->struct_mutex); sgt = obj->dev->driver->gem_prime_get_sg_table(obj); @@ -102,6 +147,9 @@ static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, sg_free_table(sgt); kfree(sgt); sgt = ERR_PTR(-ENOMEM); + } else { + prime_attach->sgt = sgt; + prime_attach->dir = dir; } } @@ -112,9 +160,7 @@ static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, struct sg_table *sgt, enum dma_data_direction dir) { - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); - sg_free_table(sgt); - kfree(sgt); + /* nothing to be done here */ } static void drm_gem_dmabuf_release(struct dma_buf *dma_buf) -- cgit v1.2.3 From 7d8f06ac901300e0b517a263f571531ca27e47b6 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Wed, 26 Jun 2013 10:21:40 +0900 Subject: drm/prime: fix to put an exported dma_buf for adding handle failure When drm_prime_add_buf_handle() returns failure for an exported dma_buf, the dma_buf was already allocated and its refcount was increased, so it needs to be put. Signed-off-by: YoungJun Cho Signed-off-by: Seung-Woo Kim Signed-off-by: Kyungmin Park Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index b1cd47438850..340caabc0424 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -306,7 +306,7 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, ret = drm_prime_add_buf_handle(&file_priv->prime, obj->export_dma_buf, handle); if (ret) - goto out; + goto fail_put_dmabuf; *prime_fd = dma_buf_fd(buf, flags); mutex_unlock(&file_priv->prime.lock); @@ -315,6 +315,12 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, out_have_obj: get_dma_buf(dmabuf); *prime_fd = dma_buf_fd(dmabuf, flags); + goto out; + +fail_put_dmabuf: + /* clear NOT to be checked when releasing dma_buf */ + obj->export_dma_buf = NULL; + dma_buf_put(buf); out: drm_gem_object_unreference_unlocked(obj); mutex_unlock(&file_priv->prime.lock); -- cgit v1.2.3 From ce92e3c9613b51adccaf4d3c04eef53aee981e10 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Wed, 26 Jun 2013 10:21:41 +0900 Subject: drm/prime: reorder drm_prime_add_buf_handle and remove prototype Signed-off-by: Seung-Woo Kim Signed-off-by: YoungJun Cho Signed-off-by: Kyungmin Park Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 340caabc0424..117ffe32a7af 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -68,7 +68,20 @@ struct drm_prime_attachment { enum dma_data_direction dir; }; -static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle); +static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle) +{ + struct drm_prime_member *member; + + member = kmalloc(sizeof(*member), GFP_KERNEL); + if (!member) + return -ENOMEM; + + get_dma_buf(dma_buf); + member->dma_buf = dma_buf; + member->handle = handle; + list_add(&member->entry, &prime_fpriv->head); + return 0; +} static int drm_gem_map_attach(struct dma_buf *dma_buf, struct device *target_dev, @@ -571,21 +584,6 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv) } EXPORT_SYMBOL(drm_prime_destroy_file_private); -static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle) -{ - struct drm_prime_member *member; - - member = kmalloc(sizeof(*member), GFP_KERNEL); - if (!member) - return -ENOMEM; - - get_dma_buf(dma_buf); - member->dma_buf = dma_buf; - member->handle = handle; - list_add(&member->entry, &prime_fpriv->head); - return 0; -} - int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle) { struct drm_prime_member *member; -- cgit v1.2.3 From da34242e5e0638312130f5bd5d2d277afbc6f806 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Wed, 26 Jun 2013 10:21:42 +0900 Subject: drm/prime: add return check for dma_buf_fd The dma_buf_fd() can return error when it fails to prepare fd, so the dma_buf needs to be put. Signed-off-by: YoungJun Cho Signed-off-by: Seung-Woo Kim Signed-off-by: Kyungmin Park Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 117ffe32a7af..52709f2171fb 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -130,6 +130,21 @@ static void drm_gem_map_detach(struct dma_buf *dma_buf, attach->priv = NULL; } +static void drm_prime_remove_buf_handle_locked( + struct drm_prime_file_private *prime_fpriv, + struct dma_buf *dma_buf) +{ + struct drm_prime_member *member, *safe; + + list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) { + if (member->dma_buf == dma_buf) { + dma_buf_put(dma_buf); + list_del(&member->entry); + kfree(member); + } + } +} + static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, enum dma_data_direction dir) { @@ -321,15 +336,25 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, if (ret) goto fail_put_dmabuf; - *prime_fd = dma_buf_fd(buf, flags); + ret = dma_buf_fd(buf, flags); + if (ret < 0) + goto fail_rm_handle; + + *prime_fd = ret; mutex_unlock(&file_priv->prime.lock); return 0; out_have_obj: get_dma_buf(dmabuf); - *prime_fd = dma_buf_fd(dmabuf, flags); + ret = dma_buf_fd(dmabuf, flags); + if (ret < 0) + dma_buf_put(dmabuf); + else + *prime_fd = ret; goto out; +fail_rm_handle: + drm_prime_remove_buf_handle_locked(&file_priv->prime, buf); fail_put_dmabuf: /* clear NOT to be checked when releasing dma_buf */ obj->export_dma_buf = NULL; @@ -600,16 +625,8 @@ EXPORT_SYMBOL(drm_prime_lookup_buf_handle); void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf) { - struct drm_prime_member *member, *safe; - mutex_lock(&prime_fpriv->lock); - list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) { - if (member->dma_buf == dma_buf) { - dma_buf_put(dma_buf); - list_del(&member->entry); - kfree(member); - } - } + drm_prime_remove_buf_handle_locked(prime_fpriv, dma_buf); mutex_unlock(&prime_fpriv->lock); } EXPORT_SYMBOL(drm_prime_remove_buf_handle); -- cgit v1.2.3 From 4a88f73f14f6d6c94616538427e1235a6d0a5885 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 2 Jul 2013 09:18:39 +0200 Subject: drm/prime: fix up handle_to_fd ioctl return value In commit da34242e5e0638312130f5bd5d2d277afbc6f806 Author: YoungJun Cho Date: Wed Jun 26 10:21:42 2013 +0900 drm/prime: add return check for dma_buf_fd the failure case handling was fixed up. But in the case when we already had the buffer exported it changed the return value: Previously we've return 0 on success, now we return the fd. This ABI change has been caught by i-g-t/prime_self_import/with_one_bo. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66436 Cc: YoungJun Cho Cc: Seung-Woo Kim Cc: Kyungmin Park Tested-by: lu hua Signed-off-by: Daniel Vetter Reviewed-by: YoungJun Cho Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 52709f2171fb..1e0de41f085c 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -347,10 +347,13 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, out_have_obj: get_dma_buf(dmabuf); ret = dma_buf_fd(dmabuf, flags); - if (ret < 0) + if (ret < 0) { dma_buf_put(dmabuf); - else + } else { *prime_fd = ret; + ret = 0; + } + goto out; fail_rm_handle: -- cgit v1.2.3 From f9d8a1294d37449f3f1b842ffb275e2ca41f5cf4 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Thu, 4 Jul 2013 16:19:12 +0900 Subject: drm/prime: fix sgt NULL checking The drm_gem_map_detach() can be called with sgt is NULL. Signed-off-by: Joonyoung Shim Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 1e0de41f085c..ff5fecef367b 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -119,12 +119,13 @@ static void drm_gem_map_detach(struct dma_buf *dma_buf, return; sgt = prime_attach->sgt; + if (sgt) { + if (prime_attach->dir != DMA_NONE) + dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, + prime_attach->dir); + sg_free_table(sgt); + } - if (prime_attach->dir != DMA_NONE) - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, - prime_attach->dir); - - sg_free_table(sgt); kfree(sgt); kfree(prime_attach); attach->priv = NULL; -- cgit v1.2.3 From 7c397cd97b8f46659698396b420bd48c3e6703e6 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Fri, 28 Jun 2013 14:24:53 +0900 Subject: drm: add mmap function to prime helpers This adds to call low-level mmap() from prime helpers. Signed-off-by: Joonyoung Shim Acked-by: Laurent Pinchart Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_prime.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/drm_prime.c') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index ff5fecef367b..85e450e3241c 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -245,7 +245,13 @@ static void drm_gem_dmabuf_kunmap(struct dma_buf *dma_buf, static int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma) { - return -EINVAL; + struct drm_gem_object *obj = dma_buf->priv; + struct drm_device *dev = obj->dev; + + if (!dev->driver->gem_prime_mmap) + return -ENOSYS; + + return dev->driver->gem_prime_mmap(obj, vma); } static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { -- cgit v1.2.3