[PATCH 1/7] drm: base prime support
2012? 2? 23? ?? 4:29, Ben Widawsky ?? ?: > From: Dave Airlie > > --- > drivers/gpu/drm/Makefile|2 +- > drivers/gpu/drm/drm_drv.c |3 + > drivers/gpu/drm/drm_gem.c |3 +- > drivers/gpu/drm/drm_prime.c | 126 > +++ > include/drm/drm.h | 10 +++- > include/drm/drmP.h | 35 > 6 files changed, 176 insertions(+), 3 deletions(-) > create mode 100644 drivers/gpu/drm/drm_prime.c > > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index 0cde1b8..202f650 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -12,7 +12,7 @@ drm-y :=drm_auth.o drm_buffer.o drm_bufs.o > drm_cache.o \ >drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ >drm_crtc.o drm_modes.o drm_edid.o \ >drm_info.o drm_debugfs.o drm_encoder_slave.o \ > - drm_trace_points.o drm_global.o drm_usb.o > + drm_trace_points.o drm_global.o drm_usb.o drm_prime.o > > drm-$(CONFIG_COMPAT) += drm_ioc32.o > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > index ebf7d3f..786b134 100644 > --- a/drivers/gpu/drm/drm_drv.c > +++ b/drivers/gpu/drm/drm_drv.c > @@ -135,6 +135,9 @@ static struct drm_ioctl_desc drm_ioctls[] = { >DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, > DRM_AUTH|DRM_UNLOCKED), >DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, > DRM_AUTH|DRM_UNLOCKED), > > + DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, > drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED), > + DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, > drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED), > + >DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), >DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), >DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), > diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c > index f8625e2..e19a958 100644 > --- a/drivers/gpu/drm/drm_gem.c > +++ b/drivers/gpu/drm/drm_gem.c > @@ -145,6 +145,7 @@ int drm_gem_object_init(struct drm_device *dev, >kref_init(>refcount); >atomic_set(>handle_count, 0); >obj->size = size; > + obj->prime_fd = -1; > >return 0; > } > @@ -166,7 +167,7 @@ int drm_gem_private_object_init(struct drm_device *dev, >kref_init(>refcount); >atomic_set(>handle_count, 0); >obj->size = size; > - > + obj->prime_fd = -1; >return 0; > } > EXPORT_SYMBOL(drm_gem_private_object_init); > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c > new file mode 100644 > index 000..11f142f > --- /dev/null > +++ b/drivers/gpu/drm/drm_prime.c > @@ -0,0 +1,126 @@ > +#include > +#include > +#include "drmP.h" > + > +struct drm_prime_member { > + struct list_head entry; > + struct dma_buf *dma_buf; > + uint32_t handle; > +}; > + > +int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, > +struct drm_file *file_priv) > +{ > + struct drm_prime_handle *args = data; > + > + if (!drm_core_check_feature(dev, DRIVER_PRIME)) > + return -EINVAL; > + > + return dev->driver->prime_handle_to_fd(dev, file_priv, args->handle, > >fd); > +} > + > +int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, > +struct drm_file *file_priv) > +{ > + struct drm_prime_handle *args = data; > + > + if (!drm_core_check_feature(dev, DRIVER_PRIME)) > + return -EINVAL; > + > + return dev->driver->prime_fd_to_handle(dev, file_priv, args->fd, > >handle); > +} > + > +struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) > +{ > + struct sg_table *sg = NULL; > + struct scatterlist *iter; > + int i; > + int ret; > + > + sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); > + if (!sg) > + goto out; > + > + ret = sg_alloc_table(sg, nr_pages, GFP_KERNEL); > + if (ret) > + goto out; > + > + for_each_sg(sg->sgl, iter, nr_pages, i) > + sg_set_page(iter, pages[i], PAGE_SIZE, 0); > + > + return sg; > +out: > + kfree(sg); > + return NULL; > +} > +EXPORT_SYMBOL(drm_prime_pages_to_sg); > + > +/* helper function to cleanup a GEM/prime object */ > +void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) > +{ > + struct dma_buf_attachment *attach; > + > + attach = obj->import_attach; > + if (sg) > + dma_buf_unmap_attachment(attach, sg); > + dma_buf_detach(attach->dmabuf, attach); > +} > +EXPORT_SYMBOL(drm_prime_gem_destroy); > + > +void
Re: [PATCH 1/7] drm: base prime support
2012년 2월 23일 오전 4:29, Ben Widawsky b...@bwidawsk.net님의 말: From: Dave Airlie airl...@redhat.com --- drivers/gpu/drm/Makefile|2 +- drivers/gpu/drm/drm_drv.c |3 + drivers/gpu/drm/drm_gem.c |3 +- drivers/gpu/drm/drm_prime.c | 126 +++ include/drm/drm.h | 10 +++- include/drm/drmP.h | 35 6 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/drm_prime.c diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 0cde1b8..202f650 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -12,7 +12,7 @@ drm-y :=drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ drm_crtc.o drm_modes.o drm_edid.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o \ - drm_trace_points.o drm_global.o drm_usb.o + drm_trace_points.o drm_global.o drm_usb.o drm_prime.o drm-$(CONFIG_COMPAT) += drm_ioc32.o diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ebf7d3f..786b134 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -135,6 +135,9 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index f8625e2..e19a958 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -145,6 +145,7 @@ int drm_gem_object_init(struct drm_device *dev, kref_init(obj-refcount); atomic_set(obj-handle_count, 0); obj-size = size; + obj-prime_fd = -1; return 0; } @@ -166,7 +167,7 @@ int drm_gem_private_object_init(struct drm_device *dev, kref_init(obj-refcount); atomic_set(obj-handle_count, 0); obj-size = size; - + obj-prime_fd = -1; return 0; } EXPORT_SYMBOL(drm_gem_private_object_init); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c new file mode 100644 index 000..11f142f --- /dev/null +++ b/drivers/gpu/drm/drm_prime.c @@ -0,0 +1,126 @@ +#include linux/export.h +#include linux/dma-buf.h +#include drmP.h + +struct drm_prime_member { + struct list_head entry; + struct dma_buf *dma_buf; + uint32_t handle; +}; + +int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + struct drm_prime_handle *args = data; + + if (!drm_core_check_feature(dev, DRIVER_PRIME)) + return -EINVAL; + + return dev-driver-prime_handle_to_fd(dev, file_priv, args-handle, args-fd); +} + +int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + struct drm_prime_handle *args = data; + + if (!drm_core_check_feature(dev, DRIVER_PRIME)) + return -EINVAL; + + return dev-driver-prime_fd_to_handle(dev, file_priv, args-fd, args-handle); +} + +struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) +{ + struct sg_table *sg = NULL; + struct scatterlist *iter; + int i; + int ret; + + sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!sg) + goto out; + + ret = sg_alloc_table(sg, nr_pages, GFP_KERNEL); + if (ret) + goto out; + + for_each_sg(sg-sgl, iter, nr_pages, i) + sg_set_page(iter, pages[i], PAGE_SIZE, 0); + + return sg; +out: + kfree(sg); + return NULL; +} +EXPORT_SYMBOL(drm_prime_pages_to_sg); + +/* helper function to cleanup a GEM/prime object */ +void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) +{ + struct dma_buf_attachment *attach; + + attach = obj-import_attach; + if (sg) + dma_buf_unmap_attachment(attach, sg); + dma_buf_detach(attach-dmabuf, attach); +} +EXPORT_SYMBOL(drm_prime_gem_destroy); + +void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) +{ +
[PATCH 1/7] drm: base prime support
From: Dave Airlie--- drivers/gpu/drm/Makefile|2 +- drivers/gpu/drm/drm_drv.c |3 + drivers/gpu/drm/drm_gem.c |3 +- drivers/gpu/drm/drm_prime.c | 126 +++ include/drm/drm.h | 10 +++- include/drm/drmP.h | 35 6 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/drm_prime.c diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 0cde1b8..202f650 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -12,7 +12,7 @@ drm-y :=drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ drm_crtc.o drm_modes.o drm_edid.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o \ - drm_trace_points.o drm_global.o drm_usb.o + drm_trace_points.o drm_global.o drm_usb.o drm_prime.o drm-$(CONFIG_COMPAT) += drm_ioc32.o diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ebf7d3f..786b134 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -135,6 +135,9 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index f8625e2..e19a958 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -145,6 +145,7 @@ int drm_gem_object_init(struct drm_device *dev, kref_init(>refcount); atomic_set(>handle_count, 0); obj->size = size; + obj->prime_fd = -1; return 0; } @@ -166,7 +167,7 @@ int drm_gem_private_object_init(struct drm_device *dev, kref_init(>refcount); atomic_set(>handle_count, 0); obj->size = size; - + obj->prime_fd = -1; return 0; } EXPORT_SYMBOL(drm_gem_private_object_init); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c new file mode 100644 index 000..11f142f --- /dev/null +++ b/drivers/gpu/drm/drm_prime.c @@ -0,0 +1,126 @@ +#include +#include +#include "drmP.h" + +struct drm_prime_member { + struct list_head entry; + struct dma_buf *dma_buf; + uint32_t handle; +}; + +int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + struct drm_prime_handle *args = data; + + if (!drm_core_check_feature(dev, DRIVER_PRIME)) + return -EINVAL; + + return dev->driver->prime_handle_to_fd(dev, file_priv, args->handle, >fd); +} + +int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + struct drm_prime_handle *args = data; + + if (!drm_core_check_feature(dev, DRIVER_PRIME)) + return -EINVAL; + + return dev->driver->prime_fd_to_handle(dev, file_priv, args->fd, >handle); +} + +struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) +{ + struct sg_table *sg = NULL; + struct scatterlist *iter; + int i; + int ret; + + sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!sg) + goto out; + + ret = sg_alloc_table(sg, nr_pages, GFP_KERNEL); + if (ret) + goto out; + + for_each_sg(sg->sgl, iter, nr_pages, i) + sg_set_page(iter, pages[i], PAGE_SIZE, 0); + + return sg; +out: + kfree(sg); + return NULL; +} +EXPORT_SYMBOL(drm_prime_pages_to_sg); + +/* helper function to cleanup a GEM/prime object */ +void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) +{ + struct dma_buf_attachment *attach; + + attach = obj->import_attach; + if (sg) + dma_buf_unmap_attachment(attach, sg); + dma_buf_detach(attach->dmabuf, attach); +} +EXPORT_SYMBOL(drm_prime_gem_destroy); + +void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) +{ + INIT_LIST_HEAD(_fpriv->head); +} +EXPORT_SYMBOL(drm_prime_init_file_private); + +void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv) +{ + struct drm_prime_member *member, *safe; +
[PATCH 1/7] drm: base prime support
On Wed, Feb 22, 2012 at 2:29 PM, Ben Widawsky wrote: > From: Dave Airlie > > --- > ?drivers/gpu/drm/Makefile ? ?| ? ?2 +- > ?drivers/gpu/drm/drm_drv.c ? | ? ?3 + > ?drivers/gpu/drm/drm_gem.c ? | ? ?3 +- > ?drivers/gpu/drm/drm_prime.c | ?126 > +++ > ?include/drm/drm.h ? ? ? ? ? | ? 10 +++- > ?include/drm/drmP.h ? ? ? ? ?| ? 35 > ?6 files changed, 176 insertions(+), 3 deletions(-) > ?create mode 100644 drivers/gpu/drm/drm_prime.c > > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index 0cde1b8..202f650 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -12,7 +12,7 @@ drm-y ? ? ? := ? ? ? ?drm_auth.o drm_buffer.o drm_bufs.o > drm_cache.o \ > ? ? ? ? ? ? ? ?drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ > ? ? ? ? ? ? ? ?drm_crtc.o drm_modes.o drm_edid.o \ > ? ? ? ? ? ? ? ?drm_info.o drm_debugfs.o drm_encoder_slave.o \ > - ? ? ? ? ? ? ? drm_trace_points.o drm_global.o drm_usb.o > + ? ? ? ? ? ? ? drm_trace_points.o drm_global.o drm_usb.o drm_prime.o > > ?drm-$(CONFIG_COMPAT) += drm_ioc32.o > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > index ebf7d3f..786b134 100644 > --- a/drivers/gpu/drm/drm_drv.c > +++ b/drivers/gpu/drm/drm_drv.c > @@ -135,6 +135,9 @@ static struct drm_ioctl_desc drm_ioctls[] = { > ? ? ? ?DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, > DRM_AUTH|DRM_UNLOCKED), > ? ? ? ?DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, > DRM_AUTH|DRM_UNLOCKED), > > + ? ? ? DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, > drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED), > + ? ? ? DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, > drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED), > + > ? ? ? ?DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), > ? ? ? ?DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), > ? ? ? ?DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), > diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c > index f8625e2..e19a958 100644 > --- a/drivers/gpu/drm/drm_gem.c > +++ b/drivers/gpu/drm/drm_gem.c > @@ -145,6 +145,7 @@ int drm_gem_object_init(struct drm_device *dev, > ? ? ? ?kref_init(>refcount); > ? ? ? ?atomic_set(>handle_count, 0); > ? ? ? ?obj->size = size; > + ? ? ? obj->prime_fd = -1; > > ? ? ? ?return 0; > ?} > @@ -166,7 +167,7 @@ int drm_gem_private_object_init(struct drm_device *dev, > ? ? ? ?kref_init(>refcount); > ? ? ? ?atomic_set(>handle_count, 0); > ? ? ? ?obj->size = size; > - > + ? ? ? obj->prime_fd = -1; > ? ? ? ?return 0; > ?} > ?EXPORT_SYMBOL(drm_gem_private_object_init); > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c > new file mode 100644 > index 000..11f142f > --- /dev/null > +++ b/drivers/gpu/drm/drm_prime.c > @@ -0,0 +1,126 @@ > +#include > +#include > +#include "drmP.h" > + > +struct drm_prime_member { > + ? ? ? struct list_head entry; > + ? ? ? struct dma_buf *dma_buf; > + ? ? ? uint32_t handle; > +}; > + > +int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct drm_file *file_priv) > +{ > + ? ? ? struct drm_prime_handle *args = data; > + > + ? ? ? if (!drm_core_check_feature(dev, DRIVER_PRIME)) > + ? ? ? ? ? ? ? return -EINVAL; > + > + ? ? ? return dev->driver->prime_handle_to_fd(dev, file_priv, args->handle, > >fd); We need a way to pass flags to this so we can pass DRM_PRIME_CLOEXEC (or whatever, but not O_CLOEXEC) to create the fd in close-on-exec mode, and it needs to be available in the libdrm API. See man epoll_create1 for an example where we had to add a new brown-bag syscall to allow this. > +} > + > +int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct drm_file *file_priv) > +{ > + ? ? ? struct drm_prime_handle *args = data; > + > + ? ? ? if (!drm_core_check_feature(dev, DRIVER_PRIME)) > + ? ? ? ? ? ? ? return -EINVAL; > + > + ? ? ? return dev->driver->prime_fd_to_handle(dev, file_priv, args->fd, > >handle); > +} > + > +struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) > +{ > + ? ? ? struct sg_table *sg = NULL; > + ? ? ? struct scatterlist *iter; > + ? ? ? int i; > + ? ? ? int ret; > + > + ? ? ? sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); > + ? ? ? if (!sg) > + ? ? ? ? ? ? ? goto out; > + > + ? ? ? ret = sg_alloc_table(sg, nr_pages, GFP_KERNEL); > + ? ? ? if (ret) > + ? ? ? ? ? ? ? goto out; > + > + ? ? ? for_each_sg(sg->sgl, iter, nr_pages, i) > + ? ? ? ? ? ? ? sg_set_page(iter, pages[i], PAGE_SIZE, 0); > + > + ? ? ? return sg; > +out: > + ? ? ? kfree(sg); > + ? ? ? return NULL; > +} > +EXPORT_SYMBOL(drm_prime_pages_to_sg); > + > +/* helper function to cleanup a GEM/prime object */ > +void drm_prime_gem_destroy(struct drm_gem_object *obj,
[PATCH 1/7] drm: base prime support
From: Dave Airlie airl...@redhat.com --- drivers/gpu/drm/Makefile|2 +- drivers/gpu/drm/drm_drv.c |3 + drivers/gpu/drm/drm_gem.c |3 +- drivers/gpu/drm/drm_prime.c | 126 +++ include/drm/drm.h | 10 +++- include/drm/drmP.h | 35 6 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/drm_prime.c diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 0cde1b8..202f650 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -12,7 +12,7 @@ drm-y :=drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ drm_crtc.o drm_modes.o drm_edid.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o \ - drm_trace_points.o drm_global.o drm_usb.o + drm_trace_points.o drm_global.o drm_usb.o drm_prime.o drm-$(CONFIG_COMPAT) += drm_ioc32.o diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ebf7d3f..786b134 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -135,6 +135,9 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index f8625e2..e19a958 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -145,6 +145,7 @@ int drm_gem_object_init(struct drm_device *dev, kref_init(obj-refcount); atomic_set(obj-handle_count, 0); obj-size = size; + obj-prime_fd = -1; return 0; } @@ -166,7 +167,7 @@ int drm_gem_private_object_init(struct drm_device *dev, kref_init(obj-refcount); atomic_set(obj-handle_count, 0); obj-size = size; - + obj-prime_fd = -1; return 0; } EXPORT_SYMBOL(drm_gem_private_object_init); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c new file mode 100644 index 000..11f142f --- /dev/null +++ b/drivers/gpu/drm/drm_prime.c @@ -0,0 +1,126 @@ +#include linux/export.h +#include linux/dma-buf.h +#include drmP.h + +struct drm_prime_member { + struct list_head entry; + struct dma_buf *dma_buf; + uint32_t handle; +}; + +int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + struct drm_prime_handle *args = data; + + if (!drm_core_check_feature(dev, DRIVER_PRIME)) + return -EINVAL; + + return dev-driver-prime_handle_to_fd(dev, file_priv, args-handle, args-fd); +} + +int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + struct drm_prime_handle *args = data; + + if (!drm_core_check_feature(dev, DRIVER_PRIME)) + return -EINVAL; + + return dev-driver-prime_fd_to_handle(dev, file_priv, args-fd, args-handle); +} + +struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) +{ + struct sg_table *sg = NULL; + struct scatterlist *iter; + int i; + int ret; + + sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!sg) + goto out; + + ret = sg_alloc_table(sg, nr_pages, GFP_KERNEL); + if (ret) + goto out; + + for_each_sg(sg-sgl, iter, nr_pages, i) + sg_set_page(iter, pages[i], PAGE_SIZE, 0); + + return sg; +out: + kfree(sg); + return NULL; +} +EXPORT_SYMBOL(drm_prime_pages_to_sg); + +/* helper function to cleanup a GEM/prime object */ +void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) +{ + struct dma_buf_attachment *attach; + + attach = obj-import_attach; + if (sg) + dma_buf_unmap_attachment(attach, sg); + dma_buf_detach(attach-dmabuf, attach); +} +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); +} +EXPORT_SYMBOL(drm_prime_init_file_private); + +void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv) +{ + struct
Re: [PATCH 1/7] drm: base prime support
On Wed, Feb 22, 2012 at 2:29 PM, Ben Widawsky b...@bwidawsk.net wrote: From: Dave Airlie airl...@redhat.com --- drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/drm_drv.c | 3 + drivers/gpu/drm/drm_gem.c | 3 +- drivers/gpu/drm/drm_prime.c | 126 +++ include/drm/drm.h | 10 +++- include/drm/drmP.h | 35 6 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/drm_prime.c diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 0cde1b8..202f650 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -12,7 +12,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ drm_crtc.o drm_modes.o drm_edid.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o \ - drm_trace_points.o drm_global.o drm_usb.o + drm_trace_points.o drm_global.o drm_usb.o drm_prime.o drm-$(CONFIG_COMPAT) += drm_ioc32.o diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ebf7d3f..786b134 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -135,6 +135,9 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index f8625e2..e19a958 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -145,6 +145,7 @@ int drm_gem_object_init(struct drm_device *dev, kref_init(obj-refcount); atomic_set(obj-handle_count, 0); obj-size = size; + obj-prime_fd = -1; return 0; } @@ -166,7 +167,7 @@ int drm_gem_private_object_init(struct drm_device *dev, kref_init(obj-refcount); atomic_set(obj-handle_count, 0); obj-size = size; - + obj-prime_fd = -1; return 0; } EXPORT_SYMBOL(drm_gem_private_object_init); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c new file mode 100644 index 000..11f142f --- /dev/null +++ b/drivers/gpu/drm/drm_prime.c @@ -0,0 +1,126 @@ +#include linux/export.h +#include linux/dma-buf.h +#include drmP.h + +struct drm_prime_member { + struct list_head entry; + struct dma_buf *dma_buf; + uint32_t handle; +}; + +int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_prime_handle *args = data; + + if (!drm_core_check_feature(dev, DRIVER_PRIME)) + return -EINVAL; + + return dev-driver-prime_handle_to_fd(dev, file_priv, args-handle, args-fd); We need a way to pass flags to this so we can pass DRM_PRIME_CLOEXEC (or whatever, but not O_CLOEXEC) to create the fd in close-on-exec mode, and it needs to be available in the libdrm API. See man epoll_create1 for an example where we had to add a new brown-bag syscall to allow this. +} + +int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_prime_handle *args = data; + + if (!drm_core_check_feature(dev, DRIVER_PRIME)) + return -EINVAL; + + return dev-driver-prime_fd_to_handle(dev, file_priv, args-fd, args-handle); +} + +struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) +{ + struct sg_table *sg = NULL; + struct scatterlist *iter; + int i; + int ret; + + sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!sg) + goto out; + + ret = sg_alloc_table(sg, nr_pages, GFP_KERNEL); + if (ret) + goto out; + + for_each_sg(sg-sgl, iter, nr_pages, i) + sg_set_page(iter, pages[i], PAGE_SIZE, 0); + + return sg; +out: + kfree(sg); + return NULL; +} +EXPORT_SYMBOL(drm_prime_pages_to_sg); + +/* helper function to cleanup a GEM/prime object */ +void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) +{ + struct dma_buf_attachment