summaryrefslogtreecommitdiff
path: root/linux-core/drm_drawable.c
diff options
context:
space:
mode:
authorIan Romanick <idr@us.ibm.com>2007-07-12 15:28:17 -0700
committerIan Romanick <idr@us.ibm.com>2007-07-12 15:28:17 -0700
commit5522136b7f01402ae02cbe35180e3d80f850a6b3 (patch)
tree275da77af4df8b332f17cb503a4b58b608de8620 /linux-core/drm_drawable.c
parent76ca1e858fb8e1a65ea49c0c62350d7ca91044a2 (diff)
parent851c950d988e5a47fa6add71427e5ef8d4dcf231 (diff)
Merge branch 'master' into xgi-0-0-2
Diffstat (limited to 'linux-core/drm_drawable.c')
-rw-r--r--linux-core/drm_drawable.c65
1 files changed, 28 insertions, 37 deletions
diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c
index eb44a189..7129980b 100644
--- a/linux-core/drm_drawable.c
+++ b/linux-core/drm_drawable.c
@@ -44,24 +44,18 @@ int drm_adddraw(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
unsigned long irqflags;
- struct drm_drawable_list *draw_info;
drm_draw_t draw;
int new_id = 0;
int ret;
- draw_info = drm_calloc(1, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
- if (!draw_info)
- return -ENOMEM;
-
again:
if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) {
DRM_ERROR("Out of memory expanding drawable idr\n");
- drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
return -ENOMEM;
}
spin_lock_irqsave(&dev->drw_lock, irqflags);
- ret = idr_get_new_above(&dev->drw_idr, draw_info, 1, &new_id);
+ ret = idr_get_new_above(&dev->drw_idr, NULL, 1, &new_id);
if (ret == -EAGAIN) {
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
goto again;
@@ -86,47 +80,46 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
DRM_DEVICE;
drm_draw_t draw;
unsigned long irqflags;
- struct drm_drawable_list *draw_info;
DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data,
sizeof(draw));
- draw_info = idr_find(&dev->drw_idr, draw.handle);
- if (!draw_info) {
- DRM_DEBUG("No such drawable %d\n", draw.handle);
- return -EINVAL;
- }
-
spin_lock_irqsave(&dev->drw_lock, irqflags);
+ drm_free(drm_get_drawable_info(dev, draw.handle),
+ sizeof(struct drm_drawable_info), DRM_MEM_BUFS);
+
idr_remove(&dev->drw_idr, draw.handle);
- drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
DRM_DEBUG("%d\n", draw.handle);
return 0;
}
-int drm_update_drawable_info(DRM_IOCTL_ARGS) {
+int drm_update_drawable_info(DRM_IOCTL_ARGS)
+{
DRM_DEVICE;
drm_update_draw_t update;
unsigned long irqflags;
- drm_drawable_info_t *info;
drm_clip_rect_t *rects;
- struct drm_drawable_list *draw_info;
+ struct drm_drawable_info *info;
int err;
DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data,
sizeof(update));
- draw_info = idr_find(&dev->drw_idr, update.handle);
- if (!draw_info) {
- DRM_ERROR("No such drawable %d\n", update.handle);
- return DRM_ERR(EINVAL);
+ info = idr_find(&dev->drw_idr, update.handle);
+ if (!info) {
+ info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS);
+ if (!info)
+ return -ENOMEM;
+ if (IS_ERR(idr_replace(&dev->drw_idr, info, update.handle))) {
+ DRM_ERROR("No such drawable %d\n", update.handle);
+ drm_free(info, sizeof(*info), DRM_MEM_BUFS);
+ return -EINVAL;
+ }
}
- info = &draw_info->info;
-
switch (update.type) {
case DRM_DRAWABLE_CLIPRECTS:
if (update.num != info->num_rects) {
@@ -184,24 +177,22 @@ error:
/**
* Caller must hold the drawable spinlock!
*/
-drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) {
- struct drm_drawable_list *draw_info;
- draw_info = idr_find(&dev->drw_idr, id);
- if (!draw_info) {
- DRM_DEBUG("No such drawable %d\n", id);
- return NULL;
- }
-
- return &draw_info->info;
+drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id)
+{
+ return idr_find(&dev->drw_idr, id);
}
EXPORT_SYMBOL(drm_get_drawable_info);
static int drm_drawable_free(int idr, void *p, void *data)
{
- struct drm_drawable_list *drw_entry = p;
- drm_free(drw_entry->info.rects, drw_entry->info.num_rects *
- sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
- drm_free(drw_entry, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
+ struct drm_drawable_info *info = p;
+
+ if (info) {
+ drm_free(info->rects, info->num_rects *
+ sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
+ drm_free(info, sizeof(*info), DRM_MEM_BUFS);
+ }
+
return 0;
}