/** * Free drawable ID and memory to store information about it. */ int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_draw *draw = data; unsigned long irqflags; 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); spin_unlock_irqrestore(&dev->drw_lock, irqflags); DRM_DEBUG("%d\n", draw->handle); return 0; }
int drm_update_draw(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_drawable_info *info; struct drm_update_draw *update = (struct drm_update_draw *)data; int ret; info = drm_get_drawable_info(dev, update->handle); if (info == NULL) return EINVAL; switch (update->type) { case DRM_DRAWABLE_CLIPRECTS: DRM_SPINLOCK(&dev->drw_lock); if (update->num != info->num_rects) { drm_free(info->rects, sizeof(*info->rects) * info->num_rects, DRM_MEM_DRAWABLE); info->rects = NULL; info->num_rects = 0; } if (update->num == 0) { DRM_SPINUNLOCK(&dev->drw_lock); return 0; } if (info->rects == NULL) { info->rects = drm_alloc(sizeof(*info->rects) * update->num, DRM_MEM_DRAWABLE); if (info->rects == NULL) { DRM_SPINUNLOCK(&dev->drw_lock); return ENOMEM; } info->num_rects = update->num; } /* For some reason the pointer arg is unsigned long long. */ ret = copyin((void *)(intptr_t)update->data, info->rects, sizeof(*info->rects) * info->num_rects); DRM_SPINUNLOCK(&dev->drw_lock); return ret; default: return EINVAL; } }
int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_draw *draw = (struct drm_draw *)data; struct drm_drawable_info *info; DRM_SPINLOCK(&dev->drw_lock); info = drm_get_drawable_info(dev, draw->handle); if (info != NULL) { RB_REMOVE(drawable_tree, &dev->drw_head, (struct bsd_drm_drawable_info *)info); DRM_SPINUNLOCK(&dev->drw_lock); free_unr(dev->drw_unrhdr, draw->handle); free(info->rects, DRM_MEM_DRAWABLE); free(info, DRM_MEM_DRAWABLE); return 0; } else { DRM_SPINUNLOCK(&dev->drw_lock); return EINVAL; } }
int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_draw_t *draw = (drm_draw_t *)data; struct drm_drawable_info *info; DRM_SPINLOCK(&dev->drw_lock); info = drm_get_drawable_info(dev, draw->handle); if (info != NULL) { RB_REMOVE(drawable_tree, &dev->drw_head, (struct bsd_drm_drawable_info *)info); DRM_SPINUNLOCK(&dev->drw_lock); #ifdef __FreeBSD__ free_unr(dev->drw_unrhdr, draw->handle); #endif drm_free(info, sizeof(struct bsd_drm_drawable_info), DRM_MEM_DRAWABLE); return 0; } else { DRM_SPINUNLOCK(&dev->drw_lock); return EINVAL; } }