diff options
-rw-r--r-- | sys/dev/pci/drm/drmP.h | 1 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_drawable.c | 70 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_drv.c | 2 |
3 files changed, 58 insertions, 15 deletions
diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h index c9a2b235992..09f0627976f 100644 --- a/sys/dev/pci/drm/drmP.h +++ b/sys/dev/pci/drm/drmP.h @@ -1095,6 +1095,7 @@ int drm_getsareactx(drm_device_t *dev, void *data, struct drm_file *file_priv); int drm_adddraw(drm_device_t *dev, void *data, struct drm_file *file_priv); int drm_rmdraw(drm_device_t *dev, void *data, struct drm_file *file_priv); int drm_update_draw(drm_device_t *dev, void *data, struct drm_file *file_priv); +void drm_drawable_free_all(struct drm_device *); struct drm_drawable_info *drm_get_drawable_info(drm_device_t *dev, int handle); /* Authentication IOCTL support (drm_auth.c) */ diff --git a/sys/dev/pci/drm/drm_drawable.c b/sys/dev/pci/drm/drm_drawable.c index 021f348136e..306f4bf5627 100644 --- a/sys/dev/pci/drm/drm_drawable.c +++ b/sys/dev/pci/drm/drm_drawable.c @@ -35,8 +35,14 @@ #include "drmP.h" +struct bsd_drm_drawable_info; + int drm_drawable_compare(struct bsd_drm_drawable_info *, struct bsd_drm_drawable_info *); +void drm_drawable_free(struct drm_device *dev, + struct bsd_drm_drawable_info *draw); +struct bsd_drm_drawable_info * + drm_get_drawable(struct drm_device *, int); #ifdef __OpenBSD__ RB_PROTOTYPE(drawable_tree, bsd_drm_drawable_info, tree, @@ -68,18 +74,24 @@ RB_GENERATE(drawable_tree, bsd_drm_drawable_info, tree, drm_drawable_compare); #endif -struct drm_drawable_info * -drm_get_drawable_info(drm_device_t *dev, int handle) +struct bsd_drm_drawable_info * +drm_get_drawable(struct drm_device *dev, int handle) { - struct bsd_drm_drawable_info find, *result = NULL; + struct bsd_drm_drawable_info find; find.handle = handle; - result = RB_FIND(drawable_tree, &dev->drw_head, &find); + return (RB_FIND(drawable_tree, &dev->drw_head, &find)); +} + +struct drm_drawable_info * +drm_get_drawable_info(drm_device_t *dev, int handle) +{ + struct bsd_drm_drawable_info *result = NULL; - if (result) + if ((result = drm_get_drawable(dev, handle))) return &result->info; - return NULL; + return (NULL); } int @@ -112,19 +124,13 @@ int drm_rmdraw(drm_device_t *dev, void *data, struct drm_file *file_priv) { drm_draw_t *draw = (drm_draw_t *)data; - struct drm_drawable_info *info; + struct bsd_drm_drawable_info *info; DRM_SPINLOCK(&dev->drw_lock); - info = drm_get_drawable_info(dev, draw->handle); + info = drm_get_drawable(dev, draw->handle); if (info != NULL) { - RB_REMOVE(drawable_tree, &dev->drw_head, - (struct bsd_drm_drawable_info *)info); + drm_drawable_free(dev, 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); @@ -176,3 +182,37 @@ drm_update_draw(drm_device_t *dev, void *data, struct drm_file *file_priv) return EINVAL; } } + +void +drm_drawable_free(struct drm_device *dev, struct bsd_drm_drawable_info *draw) +{ + if (draw) { + RB_REMOVE(drawable_tree, &dev->drw_head, draw); + if (draw->info.rects) + drm_free(draw->info.rects, + sizeof(*draw->info.rects) * draw->info.num_rects, + DRM_MEM_DRAWABLE); +#ifdef __FreeBSD__ + free_unr(dev->drw_unrhdr, draw->info->handle); +#endif + drm_free(draw, sizeof(*draw), + DRM_MEM_DRAWABLE); + } +} + +void +drm_drawable_free_all(struct drm_device *dev) +{ + struct bsd_drm_drawable_info *draw, *nxt; + + DRM_SPINLOCK(&dev->drw_lock); + + for (draw = RB_MIN(drawable_tree, &dev->drw_head); draw != NULL; + draw = nxt) { + nxt = RB_NEXT(drawable_tree, &dev->drw_head, draw); + drm_drawable_free(dev, draw); + + } + DRM_SPINUNLOCK(&dev->drw_lock); + +} diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index a36ac17f9fb..0be2df47f88 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -426,6 +426,8 @@ drm_lastclose(drm_device_t *dev) dev->unique = NULL; dev->unique_len = 0; } + + drm_drawable_free_all(dev); /* Clear pid list */ for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) { while ((pt = TAILQ_FIRST(&dev->magiclist[i])) != NULL) { |