+++ /dev/null
-From e2189a84d0da40b46c3406860fe087b7b09420b3 Mon Sep 17 00:00:00 2001
-From: Prajwal Mohan <prajwal.karur.mohan@intel.com>
-Date: Wed, 10 Oct 2012 09:56:06 -0700
-Subject: [PATCH] Adding slp subpackage
-
----
- Makefile.am | 6 +-
- libkms/Makefile.am | 5 +
- libkms/slp.c | 222 +++++++++++++
- slp/Makefile.am | 22 ++
- slp/drm_slp_bufmgr.c | 847 ++++++++++++++++++++++++++++++++++++++++++++++++++
- slp/drm_slp_bufmgr.h | 201 ++++++++++++
- slp/libdrm_slp.pc.in | 11 +
- slp/list.h | 131 ++++++++
- 8 files changed, 1444 insertions(+), 1 deletions(-)
- create mode 100644 libkms/slp.c
- create mode 100644 slp/Makefile.am
- create mode 100644 slp/drm_slp_bufmgr.c
- create mode 100644 slp/drm_slp_bufmgr.h
- create mode 100644 slp/libdrm_slp.pc.in
- create mode 100644 slp/list.h
-
-diff --git a/Makefile.am b/Makefile.am
-index 256a8cc..6e74607 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -49,7 +49,11 @@ if HAVE_EXYNOS
- EXYNOS_SUBDIR = exynos
- endif
-
--SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include
-+if HAVE_SLP
-+SLP_SUBDIR = slp
-+endif
-+
-+SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) $(SLP_SUBDIR) tests include
-
- libdrm_la_LTLIBRARIES = libdrm.la
- libdrm_ladir = $(libdir)
-diff --git a/libkms/Makefile.am b/libkms/Makefile.am
-index fa379a4..df74b7e 100644
---- a/libkms/Makefile.am
-+++ b/libkms/Makefile.am
-@@ -31,6 +31,11 @@ if HAVE_RADEON
- libkms_la_SOURCES += radeon.c
- endif
-
-+if HAVE_SLP
-+libkms_la_SOURCES += slp.c
-+AM_CFLAGS += -I$(top_srcdir)/exynos
-+endif
-+
- libkmsincludedir = ${includedir}/libkms
- libkmsinclude_HEADERS = libkms.h
-
-diff --git a/libkms/slp.c b/libkms/slp.c
-new file mode 100644
-index 0000000..263f2ab
---- /dev/null
-+++ b/libkms/slp.c
-@@ -0,0 +1,222 @@
-+/**************************************************************************
-+ *
-+ * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA
-+ * All Rights Reserved.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the
-+ * "Software"), to deal in the Software without restriction, including
-+ * without limitation the rights to use, copy, modify, merge, publish,
-+ * distribute, sub license, and/or sell copies of the Software, and to
-+ * permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * The above copyright notice and this permission notice (including the
-+ * next paragraph) shall be included in all copies or substantial portions
-+ * of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
-+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ **************************************************************************/
-+
-+
-+#define HAVE_STDINT_H
-+#define _FILE_OFFSET_BITS 64
-+
-+#include <errno.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include "internal.h"
-+
-+#include <sys/mman.h>
-+#include <sys/ioctl.h>
-+#include "xf86drm.h"
-+
-+#include "exynos_drm.h"
-+
-+struct slp_bo
-+{
-+ struct kms_bo base;
-+ unsigned map_count;
-+};
-+
-+static int
-+slp_get_prop(struct kms_driver *kms, unsigned key, unsigned *out)
-+{
-+ switch (key) {
-+ case KMS_BO_TYPE:
-+ *out = KMS_BO_TYPE_SCANOUT_X8R8G8B8 | KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ return 0;
-+}
-+
-+static int
-+slp_destroy(struct kms_driver *kms)
-+{
-+ free(kms);
-+ return 0;
-+}
-+
-+static int
-+slp_bo_create(struct kms_driver *kms,
-+ const unsigned width, const unsigned height,
-+ const enum kms_bo_type type, const unsigned *attr,
-+ struct kms_bo **out)
-+{
-+ struct drm_exynos_gem_create arg;
-+ unsigned size, pitch;
-+ struct slp_bo *bo;
-+ int i, ret;
-+
-+ for (i = 0; attr[i]; i += 2) {
-+ switch (attr[i]) {
-+ case KMS_WIDTH:
-+ case KMS_HEIGHT:
-+ case KMS_BO_TYPE:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ }
-+
-+ bo = calloc(1, sizeof(*bo));
-+ if (!bo)
-+ return -ENOMEM;
-+
-+ if (type == KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8) {
-+ pitch = 64 * 4;
-+ size = 64 * 64 * 4;
-+ } else if (type == KMS_BO_TYPE_SCANOUT_X8R8G8B8) {
-+ pitch = width * 4;
-+ pitch = (pitch + 512 - 1) & ~(512 - 1);
-+ size = pitch * ((height + 4 - 1) & ~(4 - 1));
-+ } else {
-+ return -EINVAL;
-+ }
-+
-+ memset(&arg, 0, sizeof(arg));
-+ arg.size = size;
-+
-+ ret = drmCommandWriteRead(kms->fd, DRM_EXYNOS_GEM_CREATE, &arg, sizeof(arg));
-+ if (ret)
-+ goto err_free;
-+
-+ bo->base.kms = kms;
-+ bo->base.handle = arg.handle;
-+ bo->base.size = size;
-+ bo->base.pitch = pitch;
-+
-+ *out = &bo->base;
-+
-+ return 0;
-+
-+err_free:
-+ free(bo);
-+ return ret;
-+}
-+
-+static int
-+slp_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out)
-+{
-+ switch (key) {
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static int
-+slp_bo_map(struct kms_bo *_bo, void **out)
-+{
-+ struct slp_bo *bo = (struct slp_bo *)_bo;
-+ struct drm_exynos_gem_map_off arg;
-+ void *map = NULL;
-+ int ret;
-+
-+ if (bo->base.ptr) {
-+ bo->map_count++;
-+ *out = bo->base.ptr;
-+ return 0;
-+ }
-+
-+ memset(&arg, 0, sizeof(arg));
-+ arg.handle = bo->base.handle;
-+
-+ ret = drmCommandWriteRead(bo->base.kms->fd, DRM_EXYNOS_GEM_MAP_OFFSET, &arg, sizeof(arg));
-+ if (ret)
-+ return ret;
-+
-+ map = mmap(0, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, arg.offset);
-+ if (map == MAP_FAILED)
-+ return -errno;
-+
-+ bo->base.ptr = map;
-+ bo->map_count++;
-+ *out = bo->base.ptr;
-+
-+ return 0;
-+}
-+
-+static int
-+slp_bo_unmap(struct kms_bo *_bo)
-+{
-+ struct slp_bo *bo = (struct slp_bo *)_bo;
-+ bo->map_count--;
-+ return 0;
-+}
-+
-+static int
-+slp_bo_destroy(struct kms_bo *_bo)
-+{
-+ struct slp_bo *bo = (struct slp_bo *)_bo;
-+ struct drm_gem_close arg;
-+ int ret;
-+
-+ if (bo->base.ptr) {
-+ /* XXX Sanity check map_count */
-+ munmap(bo->base.ptr, bo->base.size);
-+ bo->base.ptr = NULL;
-+ }
-+
-+ memset(&arg, 0, sizeof(arg));
-+ arg.handle = bo->base.handle;
-+
-+ ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_GEM_CLOSE, &arg);
-+ if (ret)
-+ return -errno;
-+
-+ free(bo);
-+ return 0;
-+}
-+
-+int
-+slp_create(int fd, struct kms_driver **out)
-+{
-+ struct kms_driver *kms;
-+
-+ kms = calloc(1, sizeof(*kms));
-+ if (!kms)
-+ return -ENOMEM;
-+
-+ kms->fd = fd;
-+
-+ kms->bo_create = slp_bo_create;
-+ kms->bo_map = slp_bo_map;
-+ kms->bo_unmap = slp_bo_unmap;
-+ kms->bo_get_prop = slp_bo_get_prop;
-+ kms->bo_destroy = slp_bo_destroy;
-+ kms->get_prop = slp_get_prop;
-+ kms->destroy = slp_destroy;
-+ *out = kms;
-+
-+ return 0;
-+}
-diff --git a/slp/Makefile.am b/slp/Makefile.am
-new file mode 100644
-index 0000000..132662b
---- /dev/null
-+++ b/slp/Makefile.am
-@@ -0,0 +1,22 @@
-+SUBDIRS = .
-+
-+AM_CFLAGS = \
-+ $(WARN_CFLAGS) \
-+ -I$(top_srcdir) \
-+ -I$(top_srcdir)/slp \
-+ $(PTHREADSTUBS_CFLAGS) \
-+ -I$(top_srcdir)/include/drm
-+
-+libdrm_slp_la_LTLIBRARIES = libdrm_slp.la
-+libdrm_slp_ladir = $(libdir)
-+libdrm_slp_la_LDFLAGS = -version-number 1:0:0 -no-undefined
-+libdrm_slp_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ @CLOCK_LIB@ -ldl
-+
-+libdrm_slp_la_SOURCES = \
-+ drm_slp_bufmgr.c \
-+ drm_slp_bufmgr.h
-+
-+libdrm_slpincludedir = ${includedir}/libdrm
-+libdrm_slpinclude_HEADERS = drm_slp_bufmgr.h
-+
-+pkgconfig_DATA = libdrm_slp.pc
-diff --git a/slp/drm_slp_bufmgr.c b/slp/drm_slp_bufmgr.c
-new file mode 100644
-index 0000000..f723ded
---- /dev/null
-+++ b/slp/drm_slp_bufmgr.c
-@@ -0,0 +1,847 @@
-+/**************************************************************************
-+
-+xserver-xorg-video-sec
-+
-+Copyright 2011 Samsung Electronics co., Ltd. All Rights Reserved.
-+
-+Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
-+
-+Permission is hereby granted, free of charge, to any person obtaining a
-+copy of this software and associated documentation files (the
-+"Software"), to deal in the Software without restriction, including
-+without limitation the rights to use, copy, modify, merge, publish,
-+distribute, sub license, and/or sell copies of the Software, and to
-+permit persons to whom the Software is furnished to do so, subject to
-+the following conditions:
-+
-+The above copyright notice and this permission notice (including the
-+next paragraph) shall be included in all copies or substantial portions
-+of the Software.
-+
-+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-+
-+**************************************************************************/
-+
-+#include "config.h"
-+
-+#include <unistd.h>
-+#include <limits.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <dlfcn.h>
-+#include <dirent.h>
-+#include <string.h>
-+#include <errno.h>
-+
-+#include "drm_slp_bufmgr.h"
-+#include "list.h"
-+
-+#define PREFIX_LIB "libdrm_slp_"
-+#define SUFFIX_LIB ".so"
-+#define DEFAULT_LIB PREFIX_LIB"default"SUFFIX_LIB
-+
-+#define NUM_TRY_LOCK 10
-+#define SEM_NAME "pixmap_1"
-+#define SEM_DEBUG 0
-+
-+#define DRM_RETURN_IF_FAIL(cond) {if (!(cond)) { fprintf (stderr, "[%s] : '%s' failed.\n", __FUNCTION__, #cond); return; }}
-+#define DRM_RETURN_VAL_IF_FAIL(cond, val) {if (!(cond)) { fprintf (stderr, "[%s] : '%s' failed.\n", __FUNCTION__, #cond); return val; }}
-+
-+#define MGR_IS_VALID(mgr) (mgr && \
-+ mgr->link.next && \
-+ mgr->link.next->prev == &mgr->link)
-+#define BO_IS_VALID(bo) (bo && \
-+ MGR_IS_VALID(bo->bufmgr) && \
-+ bo->list.next && \
-+ bo->list.next->prev == &bo->list)
-+
-+typedef struct{
-+ void* data;
-+
-+ int is_valid;
-+ drm_data_free free_func ;
-+}drm_slp_user_data;
-+
-+static struct list_head *gBufMgrs = NULL;
-+
-+static int
-+_sem_wait_wrapper(sem_t* sem)
-+{
-+ int res = 0;
-+ int num_try = NUM_TRY_LOCK;
-+
-+ do
-+ {
-+ res = sem_wait(sem);
-+ num_try--;
-+ } while((res == -1) && (errno == EINTR) && (num_try >= 0));
-+
-+ if(res == -1)
-+ {
-+ fprintf(stderr,
-+ "[libdrm] error %s:%d(sem:%p, num_try:%d) PID:%04d\n",
-+ __FUNCTION__,
-+ __LINE__,
-+ sem,
-+ num_try,
-+ getpid());
-+ return 0;
-+ }
-+#if SEM_DEBUG
-+ else
-+ {
-+ fprintf(stderr,
-+ "[libdrm] LOCK >> %s:%d(sem:%p, num_try:%d) PID:%04d\n",
-+ __FUNCTION__,
-+ __LINE__,
-+ sem,
-+ num_try,
-+ getpid());
-+ }
-+#endif
-+
-+ return 1;
-+}
-+
-+static int
-+_sem_post_wrapper(sem_t* sem)
-+{
-+ int res = 0;
-+ int num_try = NUM_TRY_LOCK;
-+
-+ do
-+ {
-+ res = sem_post(sem);
-+ num_try--;
-+
-+ } while((res == -1) && (errno == EINTR) && (num_try >= 0));
-+
-+ if(res == -1)
-+ {
-+ fprintf(stderr,
-+ "[libdrm] error %s:%d(sem:%p, num_try:%d) PID:%04d\n",
-+ __FUNCTION__,
-+ __LINE__,
-+ sem,
-+ num_try,
-+ getpid());
-+ return 0;
-+ }
-+#if SEM_DEBUG
-+ else
-+ {
-+ fprintf(stderr,
-+ "[libdrm] UNLOCK << %s:%d(sem:%p, num_try:%d) PID:%04d\n",
-+ __FUNCTION__,
-+ __LINE__,
-+ sem,
-+ num_try,
-+ getpid());
-+ }
-+#endif
-+
-+ return 1;
-+}
-+
-+static int
-+_sem_open(drm_slp_bufmgr bufmgr)
-+{
-+ bufmgr->semObj.handle = sem_open(SEM_NAME, O_CREAT, 0777, 1);
-+ if(bufmgr->semObj.handle == SEM_FAILED)
-+ {
-+ fprintf(stderr,
-+ "[libdrm] error %s:%d(name:%s) PID:%04d\n",
-+ __FUNCTION__,
-+ __LINE__,
-+ SEM_NAME,
-+ getpid());
-+ bufmgr->semObj.handle = NULL;
-+ return 0;
-+ }
-+#if SEM_DEBUG
-+ else
-+ {
-+ fprintf(stderr,
-+ "[libdrm] OPEN %s:%d(sem:%p) PID:%04d\n",
-+ __FUNCTION__,
-+ __LINE__,
-+ bufmgr->semObj.handle,
-+ getpid());
-+ }
-+#endif
-+
-+ bufmgr->semObj.status = STATUS_UNLOCK;
-+
-+ return 1;
-+}
-+
-+static int
-+_sem_close(drm_slp_bufmgr bufmgr)
-+{
-+ _sem_wait_wrapper(bufmgr->semObj.handle);
-+ sem_unlink(SEM_NAME);
-+ return 1;
-+}
-+
-+static int
-+_sem_lock(drm_slp_bufmgr bufmgr)
-+{
-+ if(bufmgr->semObj.status != STATUS_UNLOCK) return 0;
-+
-+ if(!_sem_wait_wrapper(bufmgr->semObj.handle)) return 0;
-+ bufmgr->semObj.status = STATUS_LOCK;
-+ return 1;
-+}
-+
-+static int
-+_sem_unlock(drm_slp_bufmgr bufmgr)
-+{
-+ if(bufmgr->semObj.status != STATUS_LOCK) return 0;
-+
-+ _sem_post_wrapper(bufmgr->semObj.handle);
-+ bufmgr->semObj.status = STATUS_UNLOCK;
-+ return 1;
-+}
-+
-+static drm_slp_bufmgr
-+_load_bufmgr(int fd, const char *file, void *arg)
-+{
-+ char path[PATH_MAX] = {0,};
-+ drm_slp_bufmgr bufmgr = NULL;
-+ int (*bufmgr_init)(drm_slp_bufmgr bufmgr, int fd, void *arg);
-+ void *module;
-+
-+ snprintf(path, sizeof(path), BUFMGR_DIR "/%s", file);
-+
-+ module = dlopen(path, RTLD_LAZY);
-+ if (!module) {
-+ fprintf(stderr,
-+ "[libdrm] failed to load module: %s(%s)\n",
-+ dlerror(), file);
-+ return NULL;
-+ }
-+
-+ bufmgr_init = dlsym(module, "init_slp_bufmgr");
-+ if (!bufmgr_init) {
-+ fprintf(stderr,
-+ "[libdrm] failed to lookup init function: %s(%s)\n",
-+ dlerror(), file);
-+ return NULL;
-+ }
-+
-+ bufmgr = calloc(sizeof(struct _drm_slp_bufmgr), 1);
-+ if(!bufmgr)
-+ {
-+ return NULL;
-+ }
-+
-+ if(!bufmgr_init(bufmgr, fd, arg))
-+ {
-+ fprintf(stderr,"[libdrm] Fail to init module(%s)\n", file);
-+ free(bufmgr);
-+ bufmgr = NULL;
-+ return NULL;
-+ }
-+
-+ fprintf(stderr,"[libdrm] Success to load module(%s)\n", file);
-+
-+ return bufmgr;
-+}
-+
-+drm_slp_bufmgr
-+drm_slp_bufmgr_init(int fd, void *arg)
-+{
-+ drm_slp_bufmgr bufmgr = NULL;
-+ const char *p = NULL;
-+
-+ if (fd < 0)
-+ return NULL;
-+
-+ if(gBufMgrs == NULL)
-+ {
-+ gBufMgrs = malloc(sizeof(struct list_head));
-+ LIST_INITHEAD(gBufMgrs);
-+ }
-+ else
-+ {
-+ LIST_FOR_EACH_ENTRY(bufmgr, gBufMgrs, link)
-+ {
-+ if(bufmgr->drm_fd == fd)
-+ {
-+ bufmgr->ref_count++;
-+ fprintf(stderr, "[libdrm] bufmgr ref: fd=%d, ref_count:%d\n", fd, bufmgr->ref_count);
-+ return bufmgr;
-+ }
-+ }
-+ bufmgr = NULL;
-+ }
-+ fprintf(stderr, "[libdrm] bufmgr init: fd=%d\n", fd);
-+
-+ p = getenv ("SLP_BUFMGR_MODULE");
-+ if (p)
-+ {
-+ char file[PATH_MAX] = {0,};
-+ snprintf(file, sizeof(file), PREFIX_LIB"%s"SUFFIX_LIB, p);
-+ bufmgr = _load_bufmgr (fd, file, arg);
-+ }
-+
-+ if (!bufmgr)
-+ bufmgr = _load_bufmgr (fd, DEFAULT_LIB, arg);
-+
-+ if (!bufmgr)
-+ {
-+ struct dirent **namelist;
-+ int found = 0;
-+ int n;
-+
-+ n = scandir(BUFMGR_DIR, &namelist, 0, alphasort);
-+ if (n < 0)
-+ fprintf(stderr,"[libdrm] no files : %s\n", BUFMGR_DIR);
-+ else
-+ {
-+ while(n--)
-+ {
-+ if (!found && strstr (namelist[n]->d_name, PREFIX_LIB))
-+ {
-+ char *p = strstr (namelist[n]->d_name, SUFFIX_LIB);
-+ if (!strcmp (p, SUFFIX_LIB))
-+ {
-+ bufmgr = _load_bufmgr (fd, namelist[n]->d_name, arg);
-+ if (bufmgr)
-+ found = 1;
-+ }
-+ }
-+ free(namelist[n]);
-+ }
-+ free(namelist);
-+ }
-+ }
-+
-+ if (!bufmgr)
-+ {
-+ fprintf(stderr,"[libdrm] backend is NULL.\n");
-+ return NULL;
-+ }
-+
-+ if (pthread_mutex_init(&bufmgr->lock, NULL) != 0)
-+ {
-+ bufmgr->bufmgr_destroy(bufmgr);
-+ free(bufmgr);
-+ return NULL;
-+ }
-+
-+ bufmgr->ref_count = 1;
-+ bufmgr->drm_fd = fd;
-+
-+ LIST_INITHEAD(&bufmgr->bos);
-+ LIST_ADD(&bufmgr->link, gBufMgrs);
-+
-+ return bufmgr;
-+}
-+
-+void
-+drm_slp_bufmgr_destroy(drm_slp_bufmgr bufmgr)
-+{
-+ DRM_RETURN_IF_FAIL(MGR_IS_VALID(bufmgr));
-+
-+ fprintf(stderr, "[DRM] bufmgr destroy: bufmgr:%p, drm_fd:%d\n",
-+ bufmgr, bufmgr->drm_fd);
-+
-+ /*Check and Free bos*/
-+ if(!LIST_IS_EMPTY(&bufmgr->bos))
-+ {
-+ drm_slp_bo bo, tmp;
-+
-+ LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bos, list)
-+ {
-+ fprintf(stderr, "[libdrm] Un-freed bo(%p, ref:%d) \n", bo, bo->ref_cnt);
-+ bo->ref_cnt = 1;
-+ drm_slp_bo_unref(bo);
-+ }
-+ }
-+
-+ LIST_DEL(&bufmgr->link);
-+ bufmgr->bufmgr_destroy(bufmgr);
-+
-+ if(bufmgr->semObj.isOpened)
-+ {
-+ _sem_close(bufmgr);
-+ }
-+
-+ pthread_mutex_destroy(&bufmgr->lock);
-+ free(bufmgr);
-+}
-+
-+int
-+drm_slp_bufmgr_lock(drm_slp_bufmgr bufmgr)
-+{
-+ DRM_RETURN_VAL_IF_FAIL(MGR_IS_VALID(bufmgr), 0);
-+
-+ pthread_mutex_lock(&bufmgr->lock);
-+
-+ if(bufmgr->bufmgr_lock)
-+ {
-+ int ret;
-+ ret = bufmgr->bufmgr_lock(bufmgr);
-+ pthread_mutex_unlock(&bufmgr->lock);
-+ return ret;
-+ }
-+
-+ if(!bufmgr->semObj.isOpened)
-+ {
-+ if(_sem_open(bufmgr) != 1)
-+ {
-+ pthread_mutex_unlock(&bufmgr->lock);
-+ return 0;
-+ }
-+ bufmgr->semObj.isOpened = 1;
-+ }
-+
-+ if(_sem_lock(bufmgr) != 1)
-+ {
-+ pthread_mutex_unlock(&bufmgr->lock);
-+ return 0;
-+ }
-+
-+ pthread_mutex_unlock(&bufmgr->lock);
-+
-+ return 1;
-+}
-+
-+int
-+drm_slp_bufmgr_unlock(drm_slp_bufmgr bufmgr)
-+{
-+ DRM_RETURN_VAL_IF_FAIL(MGR_IS_VALID(bufmgr), 0);
-+
-+ pthread_mutex_lock(&bufmgr->lock);
-+
-+ if(bufmgr->bufmgr_unlock)
-+ {
-+ int ret;
-+ ret = bufmgr->bufmgr_unlock(bufmgr);
-+ pthread_mutex_unlock(&bufmgr->lock);
-+ return ret;
-+ }
-+
-+ if(_sem_unlock(bufmgr) != 1)
-+ {
-+ pthread_mutex_unlock(&bufmgr->lock);
-+ return 0;
-+ }
-+
-+ pthread_mutex_unlock(&bufmgr->lock);
-+
-+ return 1;
-+}
-+
-+int
-+drm_slp_bufmgr_cache_flush(drm_slp_bufmgr bufmgr, drm_slp_bo bo, int flags)
-+{
-+ int ret;
-+
-+ DRM_RETURN_VAL_IF_FAIL(MGR_IS_VALID(bufmgr) || BO_IS_VALID(bo), 0);
-+
-+ if (!bo)
-+ flags |= DRM_SLP_CACHE_ALL;
-+
-+ if (bo)
-+ {
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
-+
-+ if(!bo->bufmgr)
-+ return 0;
-+
-+ pthread_mutex_lock(&bo->bufmgr->lock);
-+ ret = bo->bufmgr->bufmgr_cache_flush(bufmgr, bo, flags);
-+ pthread_mutex_unlock(&bo->bufmgr->lock);
-+ }
-+ else
-+ {
-+ pthread_mutex_lock(&bufmgr->lock);
-+ ret = bufmgr->bufmgr_cache_flush(bufmgr, NULL, flags);
-+ pthread_mutex_unlock(&bufmgr->lock);
-+ }
-+
-+ return ret;
-+}
-+
-+int
-+drm_slp_bo_size(drm_slp_bo bo)
-+{
-+ int size;
-+ drm_slp_bufmgr bufmgr;
-+
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
-+
-+ bufmgr = bo->bufmgr;
-+
-+ pthread_mutex_lock(&bufmgr->lock);
-+ size = bo->bufmgr->bo_size(bo);
-+ pthread_mutex_unlock(&bufmgr->lock);
-+
-+ return size;
-+}
-+
-+drm_slp_bo
-+drm_slp_bo_ref(drm_slp_bo bo)
-+{
-+ drm_slp_bufmgr bufmgr;
-+
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), NULL);
-+
-+ bufmgr = bo->bufmgr;
-+
-+ pthread_mutex_lock(&bufmgr->lock);
-+
-+ bo->ref_cnt++;
-+
-+ pthread_mutex_unlock(&bufmgr->lock);
-+
-+ return bo;
-+}
-+
-+void
-+drm_slp_bo_unref(drm_slp_bo bo)
-+{
-+ drm_slp_bufmgr bufmgr;
-+
-+ DRM_RETURN_IF_FAIL(BO_IS_VALID(bo));
-+
-+ bufmgr = bo->bufmgr;
-+
-+ if(0 >= bo->ref_cnt)
-+ return;
-+
-+ pthread_mutex_lock(&bufmgr->lock);
-+
-+ bo->ref_cnt--;
-+ if(bo->ref_cnt == 0)
-+ {
-+ if(bo->user_data)
-+ {
-+ void* rd;
-+ drm_slp_user_data* old_data;
-+ unsigned long key;
-+
-+ while(1==drmSLFirst(bo->user_data, &key, &rd))
-+ {
-+ old_data = (drm_slp_user_data*)rd;
-+
-+ if(old_data->is_valid && old_data->free_func)
-+ {
-+ if(old_data->data)
-+ old_data->free_func(old_data->data);
-+ old_data->data = NULL;
-+ free(old_data);
-+ }
-+ drmSLDelete(bo->user_data, key);
-+ }
-+
-+ drmSLDestroy(bo->user_data);
-+ bo->user_data = (void*)0;
-+ }
-+
-+ LIST_DEL(&bo->list);
-+ bufmgr->bo_free(bo);
-+
-+ free(bo);
-+ }
-+
-+ pthread_mutex_unlock(&bufmgr->lock);
-+}
-+
-+drm_slp_bo
-+drm_slp_bo_alloc(drm_slp_bufmgr bufmgr, const char * name, int size, int flags)
-+{
-+ drm_slp_bo bo=NULL;
-+
-+ DRM_RETURN_VAL_IF_FAIL( MGR_IS_VALID(bufmgr) && (size > 0), NULL);
-+
-+ bo = calloc(sizeof(struct _drm_slp_bo), 1);
-+ if(!bo)
-+ return NULL;
-+
-+ bo->bufmgr = bufmgr;
-+
-+ pthread_mutex_lock(&bufmgr->lock);
-+ if(!bufmgr->bo_alloc(bo, name, size, flags))
-+ {
-+ free(bo);
-+ pthread_mutex_unlock(&bufmgr->lock);
-+ return NULL;
-+ }
-+ bo->ref_cnt = 1;
-+ LIST_ADD(&bo->list, &bufmgr->bos);
-+ pthread_mutex_unlock(&bufmgr->lock);
-+
-+ return bo;
-+}
-+
-+drm_slp_bo
-+drm_slp_bo_attach(drm_slp_bufmgr bufmgr,
-+ const char* name,
-+ int type,
-+ int size,
-+ unsigned int handle)
-+{
-+ drm_slp_bo bo;
-+
-+ DRM_RETURN_VAL_IF_FAIL(MGR_IS_VALID(bufmgr), NULL);
-+
-+ bo = calloc(sizeof(struct _drm_slp_bo), 1);
-+ if(!bo)
-+ return NULL;
-+
-+ bo->bufmgr = bufmgr;
-+
-+ pthread_mutex_lock(&bufmgr->lock);
-+ if(!bufmgr->bo_attach(bo, name, type, size, handle))
-+ {
-+ free(bo);
-+ pthread_mutex_unlock(&bufmgr->lock);
-+ return NULL;
-+ }
-+ bo->ref_cnt = 1;
-+ LIST_ADD(&bo->list, &bufmgr->bos);
-+ pthread_mutex_unlock(&bufmgr->lock);
-+
-+ return bo;
-+}
-+
-+drm_slp_bo
-+drm_slp_bo_import(drm_slp_bufmgr bufmgr, unsigned int key)
-+{
-+ drm_slp_bo bo;
-+
-+ DRM_RETURN_VAL_IF_FAIL(MGR_IS_VALID(bufmgr), NULL);
-+
-+ bo = calloc(sizeof(struct _drm_slp_bo), 1);
-+ if(!bo)
-+ return NULL;
-+
-+ bo->bufmgr = bufmgr;
-+
-+ pthread_mutex_lock(&bufmgr->lock);
-+ if(!bufmgr->bo_import(bo, key))
-+ {
-+ free(bo);
-+ pthread_mutex_unlock(&bufmgr->lock);
-+ return NULL;
-+ }
-+ bo->ref_cnt = 1;
-+ LIST_ADD(&bo->list, &bufmgr->bos);
-+ pthread_mutex_unlock(&bufmgr->lock);
-+
-+ return bo;
-+}
-+
-+unsigned int
-+drm_slp_bo_export(drm_slp_bo bo)
-+{
-+ int ret;
-+
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
-+
-+ pthread_mutex_lock(&bo->bufmgr->lock);
-+ ret = bo->bufmgr->bo_export(bo);
-+ pthread_mutex_unlock(&bo->bufmgr->lock);
-+
-+ return ret;
-+}
-+
-+unsigned int
-+drm_slp_bo_get_handle(drm_slp_bo bo, int device)
-+{
-+ unsigned int ret;
-+
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
-+
-+ pthread_mutex_lock(&bo->bufmgr->lock);
-+ ret = bo->bufmgr->bo_get_handle(bo, device);
-+ pthread_mutex_unlock(&bo->bufmgr->lock);
-+
-+ return ret;
-+}
-+
-+unsigned int
-+drm_slp_bo_map(drm_slp_bo bo, int device, int opt)
-+{
-+ unsigned int ret;
-+
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
-+
-+ pthread_mutex_lock(&bo->bufmgr->lock);
-+ if(bo->bufmgr->bo_lock)
-+ {
-+ bo->bufmgr->bo_lock(bo, 0, (void*)0);
-+ }
-+
-+ ret = bo->bufmgr->bo_map(bo, device, opt);
-+ pthread_mutex_unlock(&bo->bufmgr->lock);
-+
-+ return ret;
-+}
-+
-+int
-+drm_slp_bo_unmap(drm_slp_bo bo, int device)
-+{
-+ int ret;
-+
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
-+
-+ pthread_mutex_lock(&bo->bufmgr->lock);
-+ ret = bo->bufmgr->bo_unmap(bo, device);
-+
-+ if(bo->bufmgr->bo_unlock)
-+ {
-+ bo->bufmgr->bo_unlock(bo);
-+ }
-+ pthread_mutex_unlock(&bo->bufmgr->lock);
-+
-+ return 0;
-+}
-+
-+int
-+drm_slp_bo_swap(drm_slp_bo bo1, drm_slp_bo bo2)
-+{
-+ void* temp;
-+
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo1), 0);
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo2), 0);
-+
-+ if(bo1->bufmgr->bo_size(bo1) != bo2->bufmgr->bo_size(bo2))
-+ return 0;
-+
-+ pthread_mutex_lock(&bo1->bufmgr->lock);
-+ temp = bo1->priv;
-+ bo1->priv = bo2->priv;
-+ bo2->priv = temp;
-+ pthread_mutex_unlock(&bo1->bufmgr->lock);
-+
-+ return 1;
-+}
-+
-+int
-+drm_slp_bo_add_user_data(drm_slp_bo bo, unsigned long key, drm_data_free data_free_func)
-+{
-+ int ret;
-+ drm_slp_user_data* data;
-+
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
-+
-+ if(!bo->user_data)
-+ bo->user_data = drmSLCreate();
-+
-+ data = calloc(1, sizeof(drm_slp_user_data));
-+ if(!data)
-+ return 0;
-+
-+ data->free_func = data_free_func;
-+ data->data = (void*)0;
-+ data->is_valid = 0;
-+
-+ ret = drmSLInsert(bo->user_data, key, data);
-+ if(ret == 1) /* Already in list */
-+ {
-+ free(data);
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+int
-+drm_slp_bo_set_user_data(drm_slp_bo bo, unsigned long key, void* data)
-+{
-+ void *rd;
-+ drm_slp_user_data* old_data;
-+
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
-+
-+ if(!bo->user_data)
-+ return 0;
-+
-+ if(drmSLLookup(bo->user_data, key, &rd))
-+ return 0;
-+
-+ old_data = (drm_slp_user_data*)rd;
-+ if (!old_data)
-+ return 0;
-+
-+ if(old_data->is_valid)
-+ {
-+ if(old_data->free_func)
-+ {
-+ if(old_data->data)
-+ old_data->free_func(old_data->data);
-+ old_data->data = NULL;
-+ }
-+ }
-+ else
-+ old_data->is_valid = 1;
-+
-+ old_data->data = data;
-+
-+ return 1;
-+}
-+
-+int
-+drm_slp_bo_get_user_data(drm_slp_bo bo, unsigned long key, void** data)
-+{
-+ void *rd;
-+ drm_slp_user_data* old_data;
-+
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo) && data && bo->user_data, 0);
-+
-+ if(drmSLLookup(bo->user_data, key, &rd))
-+ {
-+ *data = NULL;
-+ return 0;
-+ }
-+
-+ old_data = (drm_slp_user_data*)rd;
-+ if (!old_data)
-+ {
-+ *data = NULL;
-+ return 0;
-+ }
-+
-+ *data = old_data->data;
-+
-+ return 1;
-+}
-+
-+int
-+drm_slp_bo_delete_user_data(drm_slp_bo bo, unsigned long key)
-+{
-+ void *rd;
-+ drm_slp_user_data* old_data=(void*)0;
-+
-+ DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo) && bo->user_data, 0);
-+
-+ if(drmSLLookup(bo->user_data, key, &rd))
-+ return 0;
-+
-+ old_data = (drm_slp_user_data*)rd;
-+ if (!old_data)
-+ return 0;
-+
-+ if(old_data->is_valid && old_data->free_func)
-+ {
-+ if(old_data->data)
-+ old_data->free_func(old_data->data);
-+ free(old_data);
-+ }
-+ drmSLDelete(bo->user_data, key);
-+
-+ return 1;
-+}
-diff --git a/slp/drm_slp_bufmgr.h b/slp/drm_slp_bufmgr.h
-new file mode 100644
-index 0000000..a4adef5
---- /dev/null
-+++ b/slp/drm_slp_bufmgr.h
-@@ -0,0 +1,201 @@
-+/**************************************************************************
-+
-+xserver-xorg-video-sec
-+
-+Copyright 2011 Samsung Electronics co., Ltd. All Rights Reserved.
-+
-+Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
-+
-+Permission is hereby granted, free of charge, to any person obtaining a
-+copy of this software and associated documentation files (the
-+"Software"), to deal in the Software without restriction, including
-+without limitation the rights to use, copy, modify, merge, publish,
-+distribute, sub license, and/or sell copies of the Software, and to
-+permit persons to whom the Software is furnished to do so, subject to
-+the following conditions:
-+
-+The above copyright notice and this permission notice (including the
-+next paragraph) shall be included in all copies or substantial portions
-+of the Software.
-+
-+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-+
-+**************************************************************************/
-+
-+#ifndef _DRM_SLP_BUFMGR_H_
-+#define _DRM_SLP_BUFMGR_H_
-+
-+#include <semaphore.h>
-+#include <pthread.h>
-+#include <xf86drm.h>
-+
-+typedef struct _drm_slp_bo * drm_slp_bo;
-+typedef struct _drm_slp_bufmgr * drm_slp_bufmgr;
-+
-+struct list_head
-+{
-+ struct list_head *prev;
-+ struct list_head *next;
-+};
-+
-+struct _drm_slp_bo
-+{
-+ struct list_head list;
-+ drm_slp_bufmgr bufmgr;
-+ int ref_cnt; /*atomic count*/
-+ void *user_data;
-+
-+ /* private data */
-+ void *priv;
-+};
-+
-+typedef enum
-+{
-+ STATUS_UNLOCK,
-+ STATUS_READY_TO_LOCK,
-+ STATUS_LOCK,
-+} lock_status;
-+
-+struct _drm_slp_bufmgr
-+{
-+ struct list_head bos; /*list head of bo*/
-+
-+ pthread_mutex_t lock;
-+ struct {
-+ int isOpened;
-+ lock_status status;
-+ sem_t* handle;
-+ } semObj;
-+
-+ void (*bufmgr_destroy)(drm_slp_bufmgr bufmgr);
-+ int (*bufmgr_cache_flush)(drm_slp_bufmgr bufmgr, drm_slp_bo bo, int flags);
-+
-+ int (*bo_size)(drm_slp_bo bo);
-+
-+ void (*bo_free)(drm_slp_bo bo);
-+ int (*bo_alloc)(drm_slp_bo bo,
-+ const char* name,
-+ int size,
-+ int flags);
-+ int (*bo_attach)(drm_slp_bo bo,
-+ const char* name,
-+ int type,
-+ int size,
-+ unsigned int handle);
-+ int (*bo_import)(drm_slp_bo bo, unsigned int key);
-+ unsigned int (*bo_export)(drm_slp_bo bo);
-+
-+ unsigned int (*bo_get_handle)(drm_slp_bo bo, int device);
-+ unsigned int (*bo_map)(drm_slp_bo bo, int device, int opt);
-+ int (*bo_unmap)(drm_slp_bo bo, int device);
-+
-+
-+ /* Padding for future extension */
-+ int (*bufmgr_lock) (drm_slp_bufmgr bufmgr);
-+ int (*bufmgr_unlock) (drm_slp_bufmgr bufmgr);
-+ int (*bo_lock) (drm_slp_bo bo, unsigned int checkOnly, unsigned int* isLocked);
-+ int (*bo_unlock) (drm_slp_bo bo);
-+ void (*reserved5) (void);
-+ void (*reserved6) (void);
-+
-+ /* private data */
-+ void *priv;
-+
-+ struct list_head link; /*link of bufmgr*/
-+
-+ int drm_fd;
-+ int ref_count;
-+};
-+
-+/* DRM_SLP_MEM_TYPE */
-+#define DRM_SLP_MEM_GEM 0
-+#define DRM_SLP_MEM_USERPTR 1
-+#define DRM_SLP_MEM_DMABUF 2
-+#define DRM_SLP_MEM_GPU 3
-+
-+/* DRM_SLP_DEVICE_TYPE */
-+#define DRM_SLP_DEVICE_DEFAULT 0 //Default handle
-+#define DRM_SLP_DEVICE_CPU 1
-+#define DRM_SLP_DEVICE_2D 2
-+#define DRM_SLP_DEVICE_3D 3
-+#define DRM_SLP_DEVICE_MM 4
-+
-+/* DRM_SLP_OPTION */
-+#define DRM_SLP_OPTION_READ (1 << 0)
-+#define DRM_SLP_OPTION_WRITE (1 << 1)
-+
-+/* DRM_SLP_CACHE */
-+#define DRM_SLP_CACHE_INV 0x01
-+#define DRM_SLP_CACHE_CLN 0x02
-+#define DRM_SLP_CACHE_ALL 0x10
-+#define DRM_SLP_CACHE_FLUSH (DRM_SLP_CACHE_INV|DRM_SLP_CACHE_CLN)
-+#define DRM_SLP_CACHE_FLUSH_ALL (DRM_SLP_CACHE_FLUSH|DRM_SLP_CACHE_ALL)
-+
-+enum DRM_SLP_BO_FLAGS{
-+ DRM_SLP_BO_DEFAULT = 0,
-+ DRM_SLP_BO_SCANOUT = (1<<0),
-+ DRM_SLP_BO_NONCACHABLE = (1<<1),
-+ DRM_SLP_BO_WC = (1<<2),
-+};
-+
-+/* Functions for buffer mnager */
-+drm_slp_bufmgr
-+drm_slp_bufmgr_init(int fd, void * arg);
-+void
-+drm_slp_bufmgr_destroy(drm_slp_bufmgr bufmgr);
-+int
-+drm_slp_bufmgr_lock(drm_slp_bufmgr bufmgr);
-+int
-+drm_slp_bufmgr_unlock(drm_slp_bufmgr bufmgr);
-+int
-+drm_slp_bufmgr_cache_flush(drm_slp_bufmgr bufmgr, drm_slp_bo bo, int flags);
-+
-+
-+/*Functions for bo*/
-+int
-+drm_slp_bo_size (drm_slp_bo bo);
-+drm_slp_bo
-+drm_slp_bo_ref(drm_slp_bo bo);
-+void
-+drm_slp_bo_unref(drm_slp_bo bo);
-+drm_slp_bo
-+drm_slp_bo_alloc(drm_slp_bufmgr bufmgr,
-+ const char* name,
-+ int size,
-+ int flags);
-+drm_slp_bo
-+drm_slp_bo_attach(drm_slp_bufmgr bufmgr,
-+ const char* name,
-+ int type,
-+ int size,
-+ unsigned int handle);
-+drm_slp_bo
-+drm_slp_bo_import(drm_slp_bufmgr bufmgr, unsigned int key);
-+unsigned int
-+drm_slp_bo_export(drm_slp_bo bo);
-+unsigned int
-+drm_slp_bo_get_handle(drm_slp_bo, int device);
-+unsigned int
-+drm_slp_bo_map(drm_slp_bo bo, int device, int opt);
-+int
-+drm_slp_bo_unmap(drm_slp_bo bo, int device);
-+int
-+drm_slp_bo_swap(drm_slp_bo bo1, drm_slp_bo bo2);
-+
-+/*Functions for userdata of bo*/
-+typedef void (*drm_data_free)(void *);
-+int
-+drm_slp_bo_add_user_data(drm_slp_bo bo, unsigned long key, drm_data_free data_free_func);
-+int
-+drm_slp_bo_delete_user_data(drm_slp_bo bo, unsigned long key);
-+int
-+drm_slp_bo_set_user_data(drm_slp_bo bo, unsigned long key, void* data);
-+int
-+drm_slp_bo_get_user_data(drm_slp_bo bo, unsigned long key, void** data);
-+#endif /* _DRM_SLP_BUFMGR_H_ */
-diff --git a/slp/libdrm_slp.pc.in b/slp/libdrm_slp.pc.in
-new file mode 100644
-index 0000000..220d38b
---- /dev/null
-+++ b/slp/libdrm_slp.pc.in
-@@ -0,0 +1,11 @@
-+prefix=@prefix@
-+exec_prefix=@exec_prefix@
-+libdir=@libdir@
-+includedir=@includedir@
-+
-+Name: libdrm
-+Description: Userspace interface to kernel DRM services
-+Version: @PACKAGE_VERSION@
-+Requires: libdrm
-+Libs: -L${libdir} -ldrm_slp
-+Cflags: -I${includedir} -I${includedir}/libdrm
-diff --git a/slp/list.h b/slp/list.h
-new file mode 100644
-index 0000000..e967b93
---- /dev/null
-+++ b/slp/list.h
-@@ -0,0 +1,131 @@
-+/*
-+ *
-+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
-+ * All Rights Reserved.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the
-+ * "Software"), to deal in the Software without restriction, including
-+ * without limitation the rights to use, copy, modify, merge, publish,
-+ * distribute, sub license, and/or sell copies of the Software, and to
-+ * permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
-+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * The above copyright notice and this permission notice (including the
-+ * next paragraph) shall be included in all copies or substantial portions
-+ * of the Software.
-+ *
-+ */
-+
-+/**
-+ * \file
-+ * List macros heavily inspired by the Linux kernel
-+ * list handling. No list looping yet.
-+ *
-+ * Is not threadsafe, so common operations need to
-+ * be protected using an external mutex.
-+ */
-+#ifndef _U_DOUBLE_LIST_H_
-+#define _U_DOUBLE_LIST_H_
-+
-+#include <stddef.h>
-+
-+static void list_inithead(struct list_head *item)
-+{
-+ item->prev = item;
-+ item->next = item;
-+}
-+
-+static inline void list_add(struct list_head *item, struct list_head *list)
-+{
-+ item->prev = list;
-+ item->next = list->next;
-+ list->next->prev = item;
-+ list->next = item;
-+}
-+
-+static inline void list_addtail(struct list_head *item, struct list_head *list)
-+{
-+ item->next = list;
-+ item->prev = list->prev;
-+ list->prev->next = item;
-+ list->prev = item;
-+}
-+
-+static inline void list_replace(struct list_head *from, struct list_head *to)
-+{
-+ to->prev = from->prev;
-+ to->next = from->next;
-+ from->next->prev = to;
-+ from->prev->next = to;
-+}
-+
-+static inline void list_del(struct list_head *item)
-+{
-+ item->prev->next = item->next;
-+ item->next->prev = item->prev;
-+}
-+
-+static inline void list_delinit(struct list_head *item)
-+{
-+ item->prev->next = item->next;
-+ item->next->prev = item->prev;
-+ item->next = item;
-+ item->prev = item;
-+}
-+
-+#define LIST_INITHEAD(__item) list_inithead(__item)
-+#define LIST_ADD(__item, __list) list_add(__item, __list)
-+#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list)
-+#define LIST_REPLACE(__from, __to) list_replace(__from, __to)
-+#define LIST_DEL(__item) list_del(__item)
-+#define LIST_DELINIT(__item) list_delinit(__item)
-+
-+#define LIST_ENTRY(__type, __item, __field) \
-+ ((__type *)(((char *)(__item)) - offsetof(__type, __field)))
-+
-+#define LIST_IS_EMPTY(__list) \
-+ ((__list)->next == (__list))
-+
-+#ifndef container_of
-+#define container_of(ptr, sample, member) \
-+ (void *)((char *)(ptr) \
-+ - ((char *)&(sample)->member - (char *)(sample)))
-+#endif
-+
-+#define LIST_FOR_EACH_ENTRY(pos, head, member) \
-+ for (pos = container_of((head)->next, pos, member); \
-+ &pos->member != (head); \
-+ pos = container_of(pos->member.next, pos, member))
-+
-+#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \
-+ for (pos = container_of((head)->next, pos, member), \
-+ storage = container_of(pos->member.next, pos, member); \
-+ &pos->member != (head); \
-+ pos = storage, storage = container_of(storage->member.next, storage, member))
-+
-+#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \
-+ for (pos = container_of((head)->prev, pos, member), \
-+ storage = container_of(pos->member.prev, pos, member); \
-+ &pos->member != (head); \
-+ pos = storage, storage = container_of(storage->member.prev, storage, member))
-+
-+#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \
-+ for (pos = container_of((start), pos, member); \
-+ &pos->member != (head); \
-+ pos = container_of(pos->member.next, pos, member))
-+
-+#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \
-+ for (pos = container_of((start), pos, member); \
-+ &pos->member != (head); \
-+ pos = container_of(pos->member.prev, pos, member))
-+
-+#endif /*_U_DOUBLE_LIST_H_*/
---
-1.7.3.4
-