]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/char/drm/i915_mem.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-2.6-omap-h63xx.git] / drivers / char / drm / i915_mem.c
index ba87ff17ff64cfaf123afe895a4b0d6a5a0bc262..56fb9b30a5d7453aa824a31b1e6ec93c988d5c6d 100644 (file)
  * block to allocate, and the ring is drained prior to allocations --
  * in other words allocation is expensive.
  */
-static void mark_block(drm_device_t * dev, struct mem_block *p, int in_use)
+static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       drm_tex_region_t *list;
+       struct drm_tex_region *list;
        unsigned shift, nr;
        unsigned start;
        unsigned end;
@@ -89,7 +89,7 @@ static void mark_block(drm_device_t * dev, struct mem_block *p, int in_use)
  */
 
 static struct mem_block *split_block(struct mem_block *p, int start, int size,
-                                    DRMFILE filp)
+                                    struct drm_file *file_priv)
 {
        /* Maybe cut off the start of an existing block */
        if (start > p->start) {
@@ -99,7 +99,7 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size,
                        goto out;
                newblock->start = start;
                newblock->size = p->size - (start - p->start);
-               newblock->filp = NULL;
+               newblock->file_priv = NULL;
                newblock->next = p->next;
                newblock->prev = p;
                p->next->prev = newblock;
@@ -116,7 +116,7 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size,
                        goto out;
                newblock->start = start + size;
                newblock->size = p->size - size;
-               newblock->filp = NULL;
+               newblock->file_priv = NULL;
                newblock->next = p->next;
                newblock->prev = p;
                p->next->prev = newblock;
@@ -126,20 +126,20 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size,
 
       out:
        /* Our block is in the middle */
-       p->filp = filp;
+       p->file_priv = file_priv;
        return p;
 }
 
 static struct mem_block *alloc_block(struct mem_block *heap, int size,
-                                    int align2, DRMFILE filp)
+                                    int align2, struct drm_file *file_priv)
 {
        struct mem_block *p;
        int mask = (1 << align2) - 1;
 
        for (p = heap->next; p != heap; p = p->next) {
                int start = (p->start + mask) & ~mask;
-               if (p->filp == NULL && start + size <= p->start + p->size)
-                       return split_block(p, start, size, filp);
+               if (p->file_priv == NULL && start + size <= p->start + p->size)
+                       return split_block(p, start, size, file_priv);
        }
 
        return NULL;
@@ -158,12 +158,12 @@ static struct mem_block *find_block(struct mem_block *heap, int start)
 
 static void free_block(struct mem_block *p)
 {
-       p->filp = NULL;
+       p->file_priv = NULL;
 
-       /* Assumes a single contiguous range.  Needs a special filp in
+       /* Assumes a single contiguous range.  Needs a special file_priv in
         * 'heap' to stop it being subsumed.
         */
-       if (p->next->filp == NULL) {
+       if (p->next->file_priv == NULL) {
                struct mem_block *q = p->next;
                p->size += q->size;
                p->next = q->next;
@@ -171,7 +171,7 @@ static void free_block(struct mem_block *p)
                drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS);
        }
 
-       if (p->prev->filp == NULL) {
+       if (p->prev->file_priv == NULL) {
                struct mem_block *q = p->prev;
                q->size += p->size;
                q->next = p->next;
@@ -197,18 +197,19 @@ static int init_heap(struct mem_block **heap, int start, int size)
 
        blocks->start = start;
        blocks->size = size;
-       blocks->filp = NULL;
+       blocks->file_priv = NULL;
        blocks->next = blocks->prev = *heap;
 
        memset(*heap, 0, sizeof(**heap));
-       (*heap)->filp = (DRMFILE) - 1;
+       (*heap)->file_priv = (struct drm_file *) - 1;
        (*heap)->next = (*heap)->prev = blocks;
        return 0;
 }
 
 /* Free all blocks associated with the releasing file.
  */
-void i915_mem_release(drm_device_t * dev, DRMFILE filp, struct mem_block *heap)
+void i915_mem_release(struct drm_device * dev, struct drm_file *file_priv,
+                     struct mem_block *heap)
 {
        struct mem_block *p;
 
@@ -216,17 +217,17 @@ void i915_mem_release(drm_device_t * dev, DRMFILE filp, struct mem_block *heap)
                return;
 
        for (p = heap->next; p != heap; p = p->next) {
-               if (p->filp == filp) {
-                       p->filp = NULL;
+               if (p->file_priv == file_priv) {
+                       p->file_priv = NULL;
                        mark_block(dev, p, 0);
                }
        }
 
-       /* Assumes a single contiguous range.  Needs a special filp in
+       /* Assumes a single contiguous range.  Needs a special file_priv in
         * 'heap' to stop it being subsumed.
         */
        for (p = heap->next; p != heap; p = p->next) {
-               while (p->filp == NULL && p->next->filp == NULL) {
+               while (p->file_priv == NULL && p->next->file_priv == NULL) {
                        struct mem_block *q = p->next;
                        p->size += q->size;
                        p->next = q->next;
@@ -267,101 +268,120 @@ static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region)
 
 /* IOCTL HANDLERS */
 
-int i915_mem_alloc(DRM_IOCTL_ARGS)
+int i915_mem_alloc(struct drm_device *dev, void *data,
+                  struct drm_file *file_priv)
 {
-       DRM_DEVICE;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_mem_alloc_t alloc;
+       drm_i915_mem_alloc_t *alloc = data;
        struct mem_block *block, **heap;
 
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
 
-       DRM_COPY_FROM_USER_IOCTL(alloc, (drm_i915_mem_alloc_t __user *) data,
-                                sizeof(alloc));
-
-       heap = get_heap(dev_priv, alloc.region);
+       heap = get_heap(dev_priv, alloc->region);
        if (!heap || !*heap)
-               return DRM_ERR(EFAULT);
+               return -EFAULT;
 
        /* Make things easier on ourselves: all allocations at least
         * 4k aligned.
         */
-       if (alloc.alignment < 12)
-               alloc.alignment = 12;
+       if (alloc->alignment < 12)
+               alloc->alignment = 12;
 
-       block = alloc_block(*heap, alloc.size, alloc.alignment, filp);
+       block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv);
 
        if (!block)
-               return DRM_ERR(ENOMEM);
+               return -ENOMEM;
 
        mark_block(dev, block, 1);
 
-       if (DRM_COPY_TO_USER(alloc.region_offset, &block->start, sizeof(int))) {
+       if (DRM_COPY_TO_USER(alloc->region_offset, &block->start,
+                            sizeof(int))) {
                DRM_ERROR("copy_to_user\n");
-               return DRM_ERR(EFAULT);
+               return -EFAULT;
        }
 
        return 0;
 }
 
-int i915_mem_free(DRM_IOCTL_ARGS)
+int i915_mem_free(struct drm_device *dev, void *data,
+                 struct drm_file *file_priv)
 {
-       DRM_DEVICE;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_mem_free_t memfree;
+       drm_i915_mem_free_t *memfree = data;
        struct mem_block *block, **heap;
 
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
 
-       DRM_COPY_FROM_USER_IOCTL(memfree, (drm_i915_mem_free_t __user *) data,
-                                sizeof(memfree));
-
-       heap = get_heap(dev_priv, memfree.region);
+       heap = get_heap(dev_priv, memfree->region);
        if (!heap || !*heap)
-               return DRM_ERR(EFAULT);
+               return -EFAULT;
 
-       block = find_block(*heap, memfree.region_offset);
+       block = find_block(*heap, memfree->region_offset);
        if (!block)
-               return DRM_ERR(EFAULT);
+               return -EFAULT;
 
-       if (block->filp != filp)
-               return DRM_ERR(EPERM);
+       if (block->file_priv != file_priv)
+               return -EPERM;
 
        mark_block(dev, block, 0);
        free_block(block);
        return 0;
 }
 
-int i915_mem_init_heap(DRM_IOCTL_ARGS)
+int i915_mem_init_heap(struct drm_device *dev, void *data,
+                      struct drm_file *file_priv)
 {
-       DRM_DEVICE;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_mem_init_heap_t initheap;
+       drm_i915_mem_init_heap_t *initheap = data;
        struct mem_block **heap;
 
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
 
-       DRM_COPY_FROM_USER_IOCTL(initheap,
-                                (drm_i915_mem_init_heap_t __user *) data,
-                                sizeof(initheap));
-
-       heap = get_heap(dev_priv, initheap.region);
+       heap = get_heap(dev_priv, initheap->region);
        if (!heap)
-               return DRM_ERR(EFAULT);
+               return -EFAULT;
 
        if (*heap) {
                DRM_ERROR("heap already initialized?");
-               return DRM_ERR(EFAULT);
+               return -EFAULT;
+       }
+
+       return init_heap(heap, initheap->start, initheap->size);
+}
+
+int i915_mem_destroy_heap( struct drm_device *dev, void *data,
+                          struct drm_file *file_priv )
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       drm_i915_mem_destroy_heap_t *destroyheap = data;
+       struct mem_block **heap;
+
+       if ( !dev_priv ) {
+               DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+               return -EINVAL;
        }
 
-       return init_heap(heap, initheap.start, initheap.size);
+       heap = get_heap( dev_priv, destroyheap->region );
+       if (!heap) {
+               DRM_ERROR("get_heap failed");
+               return -EFAULT;
+       }
+       
+       if (!*heap) {
+               DRM_ERROR("heap not initialized?");
+               return -EFAULT;
+       }
+
+       i915_mem_takedown( heap );
+       return 0;
 }
+