1247834Skib/************************************************************************** 2247834Skib * 3247834Skib * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA 4247834Skib * All Rights Reserved. 5247834Skib * 6247834Skib * Permission is hereby granted, free of charge, to any person obtaining a 7247834Skib * copy of this software and associated documentation files (the 8247834Skib * "Software"), to deal in the Software without restriction, including 9247834Skib * without limitation the rights to use, copy, modify, merge, publish, 10247834Skib * distribute, sub license, and/or sell copies of the Software, and to 11247834Skib * permit persons to whom the Software is furnished to do so, subject to 12247834Skib * the following conditions: 13247834Skib * 14247834Skib * The above copyright notice and this permission notice (including the 15247834Skib * next paragraph) shall be included in all copies or substantial portions 16247834Skib * of the Software. 17247834Skib * 18247834Skib * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19247834Skib * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20247834Skib * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21247834Skib * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 22247834Skib * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23247834Skib * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24247834Skib * USE OR OTHER DEALINGS IN THE SOFTWARE. 25247834Skib * 26247834Skib **************************************************************************/ 27247834Skib/* 28247834Skib * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> 29247834Skib */ 30247834Skib 31247834Skib#include <sys/cdefs.h> 32247834Skib__FBSDID("$FreeBSD$"); 33247834Skib 34247834Skib#include <dev/drm2/drmP.h> 35247834Skib#include <dev/drm2/drm_global.h> 36247834Skib 37247834SkibMALLOC_DEFINE(M_DRM_GLOBAL, "drm_global", "DRM Global Items"); 38247834Skib 39247834Skibstruct drm_global_item { 40247834Skib struct sx mutex; 41247834Skib void *object; 42247834Skib int refcount; 43247834Skib}; 44247834Skib 45247834Skibstatic struct drm_global_item glob[DRM_GLOBAL_NUM]; 46247834Skib 47247834Skibvoid drm_global_init(void) 48247834Skib{ 49247834Skib int i; 50247834Skib 51247834Skib for (i = 0; i < DRM_GLOBAL_NUM; ++i) { 52247834Skib struct drm_global_item *item = &glob[i]; 53247834Skib sx_init(&item->mutex, "drmgi"); 54247834Skib item->object = NULL; 55247834Skib item->refcount = 0; 56247834Skib } 57247834Skib} 58247834Skib 59247834Skibvoid drm_global_release(void) 60247834Skib{ 61247834Skib int i; 62247834Skib for (i = 0; i < DRM_GLOBAL_NUM; ++i) { 63247834Skib struct drm_global_item *item = &glob[i]; 64247834Skib MPASS(item->object == NULL); 65247834Skib MPASS(item->refcount == 0); 66247839Sdumbbell sx_destroy(&item->mutex); 67247834Skib } 68247834Skib} 69247834Skib 70247834Skibint drm_global_item_ref(struct drm_global_reference *ref) 71247834Skib{ 72247834Skib int ret; 73247834Skib struct drm_global_item *item = &glob[ref->global_type]; 74247834Skib void *object; 75247834Skib 76247834Skib sx_xlock(&item->mutex); 77247834Skib if (item->refcount == 0) { 78247834Skib item->object = malloc(ref->size, M_DRM_GLOBAL, 79247834Skib M_WAITOK | M_ZERO); 80247834Skib 81247834Skib ref->object = item->object; 82247834Skib ret = ref->init(ref); 83247834Skib if (unlikely(ret != 0)) 84247834Skib goto out_err; 85247834Skib 86247834Skib } 87247834Skib ++item->refcount; 88247834Skib ref->object = item->object; 89247834Skib object = item->object; 90247834Skib sx_xunlock(&item->mutex); 91247834Skib return 0; 92247834Skibout_err: 93247834Skib sx_xunlock(&item->mutex); 94247834Skib item->object = NULL; 95247834Skib return ret; 96247834Skib} 97247834Skib 98247834Skibvoid drm_global_item_unref(struct drm_global_reference *ref) 99247834Skib{ 100247834Skib struct drm_global_item *item = &glob[ref->global_type]; 101247834Skib 102247834Skib sx_xlock(&item->mutex); 103247834Skib MPASS(item->refcount != 0); 104247834Skib MPASS(ref->object == item->object); 105247834Skib if (--item->refcount == 0) { 106247834Skib ref->release(ref); 107248060Sdumbbell free(item->object, M_DRM_GLOBAL); 108247834Skib item->object = NULL; 109247834Skib } 110247834Skib sx_xunlock(&item->mutex); 111247834Skib} 112