From 5a97f2dda4dafab395e15db762a92279fc1c4da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 17 Jun 2010 15:22:41 -0400 Subject: [PATCH] flink_to --- drivers/gpu/drm/drm_auth.c | 6 +- drivers/gpu/drm/drm_fops.c | 4 ++ drivers/gpu/drm/i915/i915_drv.h | 14 ++++++ drivers/gpu/drm/i915/i915_gem.c | 97 +++++++++++++++++++++++++++++++++++++++ include/drm/drmP.h | 6 ++ include/drm/i915_drm.h | 44 ++++++++++++++++++ 6 files changed, 168 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 3f46772..a3c8ed0 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -45,7 +45,7 @@ * the one with matching magic number, while holding the drm_device::struct_mutex * lock. */ -static struct drm_file *drm_find_file(struct drm_master *master, drm_magic_t magic) +struct drm_file *drm_find_file(struct drm_master *master, drm_magic_t magic) { struct drm_file *retval = NULL; struct drm_magic_entry *pt; @@ -60,6 +60,7 @@ static struct drm_file *drm_find_file(struct drm_master *master, drm_magic_t mag mutex_unlock(&dev->struct_mutex); return retval; } +EXPORT_SYMBOL(drm_find_file); /** * Adds a magic number. @@ -101,7 +102,7 @@ static int drm_add_magic(struct drm_master *master, struct drm_file *priv, * Searches and unlinks the entry in drm_device::magiclist with the magic * number hash key, while holding the drm_device::struct_mutex lock. */ -static int drm_remove_magic(struct drm_master *master, drm_magic_t magic) +int drm_remove_magic(struct drm_master *master, drm_magic_t magic) { struct drm_magic_entry *pt; struct drm_hash_item *hash; @@ -183,7 +184,6 @@ int drm_authmagic(struct drm_device *dev, void *data, DRM_DEBUG("%u\n", auth->magic); if ((file = drm_find_file(file_priv->master, auth->magic))) { file->authenticated = 1; - drm_remove_magic(file_priv->master, auth->magic); return 0; } return -EINVAL; diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index e7aace2..767e02d 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -488,6 +488,10 @@ int drm_release(struct inode *inode, struct file *filp) (long)old_encode_dev(file_priv->minor->device), dev->open_count); + if (file_priv->magic) + drm_remove_magic(file_priv->minor->master, + file_priv->magic); + /* if the master has gone away we can't do anything with the lock */ if (file_priv->minor->master) drm_master_release(dev, filp); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9ed8ecd..00b0831 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -124,6 +124,20 @@ struct drm_i915_fence_reg { struct list_head lru_list; }; +struct drm_i915_gem_name { + struct drm_gem_object *obj; + u32 name; + u32 x; + u32 y; + u32 width; + u32 height; + u32 stride; + u32 format; + u32 tiling_mode; + struct list_head list; +}; + + struct sdvo_device_mapping { u8 dvo_port; u8 slave_addr; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9ded3da..566d212 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -137,6 +137,103 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, return 0; } +int +i915_gem_flink_to_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_i915_gem_flink_to *args = data; + struct drm_i915_gem_name *name; + struct drm_gem_object *obj; + struct drm_file *other; + int ret; + + obj = drm_gem_object_lookup(dev, file_priv, args->handle); + if (obj == NULL) + return -EBADF; + + other = drm_find_file(file_priv->master, args->magic); + name = kmalloc(sizeof *name, GFP_KERNEL); + if (name == NULL) { + ret = -ENOMEM; + goto err; + } + + name->obj = obj; + name->x = args->x; + name->y = args->y; + name->width = args->width; + name->height = args->height; + name->stride = args->stride; + name->format = args->format; + name->tiling_mode = args->tiling_mode; + +again: + if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) { + ret = -ENOMEM; + goto err; + } + + spin_lock(&dev->object_name_lock); + ret = idr_get_new_above(&dev->object_name_idr, obj, 1, + &name->name); + args->name = (uint64_t) name->name; + if (ret == 0) + list_add_tail(&name->list, &file_priv->name_list); + spin_unlock(&dev->object_name_lock); + + if (ret == -EAGAIN) + goto again; + + if (ret != 0) + goto err; + + /* Keep the reference for the name table. */ + return 0; + +err: + drm_gem_object_unreference_unlocked(obj); + return ret; + +} + +int +i915_gem_open_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_i915_gem_open *args = data; + struct drm_i915_gem_name *name; + int ret; + + spin_lock(&dev->object_name_lock); + list_for_each_entry(name, &file_priv->name_list, list) + if (args->name == name->name) { + list_del(&name->list); + idr_remove(&dev->object_name_idr, name->name); + break; + } + spin_unlock(&dev->object_name_lock); + + if (&name->list == &file_priv->name_list) + return -ENOENT; + + ret = drm_gem_handle_create(file_priv, name->obj, &args->handle); + drm_gem_object_unreference_unlocked(name->obj); + if (ret) + return ret; + + args->size = name->obj->size; + args->x = name->x; + args->y = name->y; + args->width = name->width; + args->height = name->height; + args->stride = name->stride; + args->format = name->format; + args->tiling_mode = name->tiling_mode; + kfree(name); + + return 0; +} + static inline int fast_shmem_read(struct page **pages, loff_t page_base, int page_offset, diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c1b9871..5427173 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -422,6 +422,9 @@ struct drm_file { /** Lock for synchronization of access to object_idr. */ spinlock_t table_lock; + /** List of object names exported from other fpriv's */ + struct list_head name_list; + struct file *filp; void *driver_priv; @@ -1225,6 +1228,9 @@ extern struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev, extern void drm_drawable_free_all(struct drm_device *dev); /* Authentication IOCTL support (drm_auth.h) */ +extern struct drm_file *drm_find_file(struct drm_master *master, + drm_magic_t magic); +extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic); extern int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_authmagic(struct drm_device *dev, void *data, diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 7f0028e..0f641e4 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -189,6 +189,8 @@ typedef struct _drm_i915_sarea { #define DRM_I915_OVERLAY_PUT_IMAGE 0x27 #define DRM_I915_OVERLAY_ATTRS 0x28 #define DRM_I915_GEM_EXECBUFFER2 0x29 +#define DRM_I915_FLINK_TO 0x2a +#define DRM_I915_OPEN 0x2b #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -229,6 +231,8 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) #define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_IOCTL_I915_OVERLAY_ATTRS, struct drm_intel_overlay_put_image) #define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs) +#define DRM_IOCTL_I915_GEM_FLINK_TO DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FLINK_TO, struct drm_i915_gem_flink_to) +#define DRM_IOCTL_I915_GEM_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OPEN, struct drm_i915_gem_open) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -453,6 +457,46 @@ struct drm_i915_gem_sw_finish { __u32 handle; }; +struct drm_i915_gem_flink_to { + /** Handle for the object being named */ + __u32 handle; + + /** Magic for destination file_priv */ + __u32 magic; + + /* FIXME: format? x, y offset? */ + __u32 x; + __u32 y; + __u32 width; + __u32 height; + __u32 stride; + __u32 format; + __u32 tiling_mode; + __u32 swizzle_mode; + + /** Returned name for the object */ + __u32 name; +}; + +struct drm_i915_gem_open { + /** Name of object being opened */ + __u32 name; + + /** Returned handle for the object */ + __u32 handle; + + /** Returned size of the object */ + __u32 size; + __u32 x; + __u32 y; + __u32 width; + __u32 height; + __u32 stride; + __u32 format; + __u32 tiling_mode; + __u32 swizzle_mode; +}; + struct drm_i915_gem_relocation_entry { /** * Handle of the buffer being pointed to by this relocation entry. -- 1.7.1