aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_drawable.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-05-28 20:09:59 -0400
committerDave Airlie <airlied@redhat.com>2008-07-13 20:45:01 -0400
commitc0e09200dc0813972442e550a5905a132768e56c (patch)
treed38e635a30ff8b0a2b98b9d7f97cab1501f8209e /drivers/gpu/drm/drm_drawable.c
parentbce7f793daec3e65ec5c5705d2457b81fe7b5725 (diff)
drm: reorganise drm tree to be more future proof.
With the coming of kernel based modesetting and the memory manager stuff, the everything in one directory approach was getting very ugly and starting to be unmanageable. This restructures the drm along the lines of other kernel components. It creates a drivers/gpu/drm directory and moves the hw drivers into subdirectores. It moves the includes into an include/drm, and sets up the unifdef for the userspace headers we should be exporting. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_drawable.c')
-rw-r--r--drivers/gpu/drm/drm_drawable.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_drawable.c b/drivers/gpu/drm/drm_drawable.c
new file mode 100644
index 000000000000..1839c57663c5
--- /dev/null
+++ b/drivers/gpu/drm/drm_drawable.c
@@ -0,0 +1,192 @@
1/**
2 * \file drm_drawable.c
3 * IOCTLs for drawables
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 * \author Michel Dänzer <michel@tungstengraphics.com>
8 */
9
10/*
11 * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
12 *
13 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
14 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
15 * Copyright 2006 Tungsten Graphics, Inc., Bismarck, North Dakota.
16 * All Rights Reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person obtaining a
19 * copy of this software and associated documentation files (the "Software"),
20 * to deal in the Software without restriction, including without limitation
21 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
22 * and/or sell copies of the Software, and to permit persons to whom the
23 * Software is furnished to do so, subject to the following conditions:
24 *
25 * The above copyright notice and this permission notice (including the next
26 * paragraph) shall be included in all copies or substantial portions of the
27 * Software.
28 *
29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
32 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
33 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
34 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
35 * OTHER DEALINGS IN THE SOFTWARE.
36 */
37
38#include "drmP.h"
39
40/**
41 * Allocate drawable ID and memory to store information about it.
42 */
43int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv)
44{
45 unsigned long irqflags;
46 struct drm_draw *draw = data;
47 int new_id = 0;
48 int ret;
49
50again:
51 if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) {
52 DRM_ERROR("Out of memory expanding drawable idr\n");
53 return -ENOMEM;
54 }
55
56 spin_lock_irqsave(&dev->drw_lock, irqflags);
57 ret = idr_get_new_above(&dev->drw_idr, NULL, 1, &new_id);
58 if (ret == -EAGAIN) {
59 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
60 goto again;
61 }
62
63 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
64
65 draw->handle = new_id;
66
67 DRM_DEBUG("%d\n", draw->handle);
68
69 return 0;
70}
71
72/**
73 * Free drawable ID and memory to store information about it.
74 */
75int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv)
76{
77 struct drm_draw *draw = data;
78 unsigned long irqflags;
79
80 spin_lock_irqsave(&dev->drw_lock, irqflags);
81
82 drm_free(drm_get_drawable_info(dev, draw->handle),
83 sizeof(struct drm_drawable_info), DRM_MEM_BUFS);
84
85 idr_remove(&dev->drw_idr, draw->handle);
86
87 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
88 DRM_DEBUG("%d\n", draw->handle);
89 return 0;
90}
91
92int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file *file_priv)
93{
94 struct drm_update_draw *update = data;
95 unsigned long irqflags;
96 struct drm_clip_rect *rects;
97 struct drm_drawable_info *info;
98 int err;
99
100 info = idr_find(&dev->drw_idr, update->handle);
101 if (!info) {
102 info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS);
103 if (!info)
104 return -ENOMEM;
105 if (IS_ERR(idr_replace(&dev->drw_idr, info, update->handle))) {
106 DRM_ERROR("No such drawable %d\n", update->handle);
107 drm_free(info, sizeof(*info), DRM_MEM_BUFS);
108 return -EINVAL;
109 }
110 }
111
112 switch (update->type) {
113 case DRM_DRAWABLE_CLIPRECTS:
114 if (update->num != info->num_rects) {
115 rects = drm_alloc(update->num * sizeof(struct drm_clip_rect),
116 DRM_MEM_BUFS);
117 } else
118 rects = info->rects;
119
120 if (update->num && !rects) {
121 DRM_ERROR("Failed to allocate cliprect memory\n");
122 err = -ENOMEM;
123 goto error;
124 }
125
126 if (update->num && DRM_COPY_FROM_USER(rects,
127 (struct drm_clip_rect __user *)
128 (unsigned long)update->data,
129 update->num *
130 sizeof(*rects))) {
131 DRM_ERROR("Failed to copy cliprects from userspace\n");
132 err = -EFAULT;
133 goto error;
134 }
135
136 spin_lock_irqsave(&dev->drw_lock, irqflags);
137
138 if (rects != info->rects) {
139 drm_free(info->rects, info->num_rects *
140 sizeof(struct drm_clip_rect), DRM_MEM_BUFS);
141 }
142
143 info->rects = rects;
144 info->num_rects = update->num;
145
146 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
147
148 DRM_DEBUG("Updated %d cliprects for drawable %d\n",
149 info->num_rects, update->handle);
150 break;
151 default:
152 DRM_ERROR("Invalid update type %d\n", update->type);
153 return -EINVAL;
154 }
155
156 return 0;
157
158error:
159 if (rects != info->rects)
160 drm_free(rects, update->num * sizeof(struct drm_clip_rect),
161 DRM_MEM_BUFS);
162
163 return err;
164}
165
166/**
167 * Caller must hold the drawable spinlock!
168 */
169struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev, drm_drawable_t id)
170{
171 return idr_find(&dev->drw_idr, id);
172}
173EXPORT_SYMBOL(drm_get_drawable_info);
174
175static int drm_drawable_free(int idr, void *p, void *data)
176{
177 struct drm_drawable_info *info = p;
178
179 if (info) {
180 drm_free(info->rects, info->num_rects *
181 sizeof(struct drm_clip_rect), DRM_MEM_BUFS);
182 drm_free(info, sizeof(*info), DRM_MEM_BUFS);
183 }
184
185 return 0;
186}
187
188void drm_drawable_free_all(struct drm_device *dev)
189{
190 idr_for_each(&dev->drw_idr, drm_drawable_free, NULL);
191 idr_remove_all(&dev->drw_idr);
192}