summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel@tungstengraphics.com>2006-08-30 19:24:04 +0200
committerMichel Dänzer <michel@tungstengraphics.com>2006-09-29 12:55:08 +0200
commit00531cecad3cf9a1ec230f7f33535d153b9d9bd0 (patch)
tree0b8a06357a35f8a7f924482e825675a62161f7ff
parent7d487602a31dd886037417db088b6e643ed86918 (diff)
Change first valid DRM drawable ID to be 1 instead of 0.
This makes it easier for userspace to know when it needs to allocate an ID. Also free drawable information memory when it's no longer needed. (cherry picked from df7551ef7334d728ec0371423661bb403d3e270a commit)
-rw-r--r--linux-core/drm_drv.c12
-rw-r--r--shared-core/drm_drawable.c35
2 files changed, 35 insertions, 12 deletions
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index d4ef1306..37539f34 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -163,6 +163,18 @@ int drm_lastclose(drm_device_t * dev)
if (dev->irq_enabled)
drm_irq_uninstall(dev);
+ /* Free drawable information memory */
+ for (i = 0; i < dev->drw_bitfield_length / sizeof(*dev->drw_bitfield);
+ i++) {
+ drm_drawable_info_t *info = drm_get_drawable_info(dev, i);
+
+ 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);
+ }
+ }
+
mutex_lock(&dev->struct_mutex);
del_timer(&dev->timer);
diff --git a/shared-core/drm_drawable.c b/shared-core/drm_drawable.c
index bbfaf139..5e2fc86c 100644
--- a/shared-core/drm_drawable.c
+++ b/shared-core/drm_drawable.c
@@ -92,13 +92,13 @@ done:
bitfield[i] = 0;
}
- draw.handle = i * 8 * sizeof(*bitfield) + j;
+ draw.handle = i * 8 * sizeof(*bitfield) + j + 1;
DRM_DEBUG("%d\n", draw.handle);
spin_lock_irqsave(&dev->drw_lock, irqflags);
bitfield[i] |= 1 << j;
- info[draw.handle] = NULL;
+ info[draw.handle - 1] = NULL;
if (bitfield != dev->drw_bitfield) {
memcpy(bitfield, dev->drw_bitfield, dev->drw_bitfield_length *
@@ -132,7 +132,7 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_draw_t draw;
- unsigned int idx, shift;
+ unsigned int id, idx, shift;
unsigned int irqflags;
u32 *bitfield = dev->drw_bitfield;
unsigned int bitfield_length = dev->drw_bitfield_length;
@@ -142,10 +142,11 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data,
sizeof(draw));
- idx = draw.handle / (8 * sizeof(*bitfield));
- shift = draw.handle % (8 * sizeof(*bitfield));
+ id = draw.handle - 1;
+ idx = id / (8 * sizeof(*bitfield));
+ shift = id % (8 * sizeof(*bitfield));
- if (idx >= bitfield_length ||
+ if (idx < 0 || idx >= bitfield_length ||
!(bitfield[idx] & (1 << shift))) {
DRM_DEBUG("No such drawable %d\n", draw.handle);
return 0;
@@ -157,6 +158,12 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
+ if (info[id]) {
+ drm_free(info[id]->rects, info[id]->num_rects *
+ sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
+ drm_free(info[id], sizeof(**info), DRM_MEM_BUFS);
+ }
+
/* Can we shrink the arrays? */
if (idx == bitfield_length - 1) {
while (idx >= 0 && !bitfield[idx])
@@ -164,7 +171,7 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
bitfield_length = idx + 1;
- if (idx != draw.handle / (8 * sizeof(*bitfield)))
+ if (idx != id / (8 * sizeof(*bitfield)))
bitfield = drm_alloc(bitfield_length *
sizeof(*bitfield), DRM_MEM_BUFS);
@@ -222,11 +229,12 @@ int drm_update_drawable_info(DRM_IOCTL_ARGS) {
DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data,
sizeof(update));
- id = update.handle;
+ id = update.handle - 1;
idx = id / (8 * sizeof(*bitfield));
shift = id % (8 * sizeof(*bitfield));
- if (idx >= bitfield_length || !(bitfield[idx] & (1 << shift))) {
+ if (idx < 0 || idx >= bitfield_length ||
+ !(bitfield[idx] & (1 << shift))) {
DRM_ERROR("No such drawable %d\n", update.handle);
return DRM_ERR(EINVAL);
}
@@ -304,10 +312,13 @@ error:
*/
drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) {
u32 *bitfield = dev->drw_bitfield;
- unsigned int idx = id / (8 * sizeof(*bitfield));
- unsigned int shift = id % (8 * sizeof(*bitfield));
+ unsigned int idx, shift;
+
+ id--;
+ idx = id / (8 * sizeof(*bitfield));
+ shift = id % (8 * sizeof(*bitfield));
- if (idx >= dev->drw_bitfield_length ||
+ if (idx < 0 || idx >= dev->drw_bitfield_length ||
!(bitfield[idx] & (1 << shift))) {
DRM_DEBUG("No such drawable %d\n", id);
return NULL;