summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2012-10-20 14:11:52 +0100
committerRussell King <rmk@arm.linux.org.uk>2012-10-23 11:14:45 +0100
commit17b3a94e32c4b63099f7564cb9ce9d8a91174efa (patch)
tree5b9762930a84dd288673a627e5a3944135b65249
parentc4d46b886a302defa7c99608c4761eb0fe7de340 (diff)
Move user id management into the kernel driver
Move the user id management into the kernel driver. This removes the necessity to export operations on kernel semaphores to userspace, along with the kernel shared memory.
-rw-r--r--uio_vmeta.h13
-rw-r--r--vmeta_lib.c101
2 files changed, 112 insertions, 2 deletions
diff --git a/uio_vmeta.h b/uio_vmeta.h
index bab40dd..d1cef5f 100644
--- a/uio_vmeta.h
+++ b/uio_vmeta.h
@@ -37,6 +37,11 @@ typedef struct _kernel_share
id_instance user_id_list[MAX_VMETA_INSTANCE];
}kernel_share;
+struct vmeta_lock {
+ unsigned long timeout;
+ unsigned int user_id;
+};
+
#define IOP_MAGIC 'v'
#define VMETA_CMD_POWER_ON _IO(IOP_MAGIC, 0)
@@ -52,5 +57,13 @@ typedef struct _kernel_share
#define VMETA_CMD_SUSPEND_READY _IO(IOP_MAGIC, 10)
#define VMETA_CMD_SUSPEND_SET _IO(IOP_MAGIC, 11)
#define VMETA_CMD_SUSPEND_UNSET _IO(IOP_MAGIC, 12)
+#define VMETA_CMD_GET_USER_ID _IOR(IOP_MAGIC, 13, unsigned)
+#define VMETA_CMD_FREE_USER_ID _IO(IOP_MAGIC, 14)
+#define VMETA_CMD_REGISTER_USER_ID _IO(IOP_MAGIC, 15)
+#define VMETA_CMD_UNREGISTER_USER_ID _IO(IOP_MAGIC, 16)
+#define VMETA_CMD_LOCK_USER_ID _IOW(IOP_MAGIC, 17, struct vmeta_lock)
+#define VMETA_CMD_UNLOCK_USER_ID _IO(IOP_MAGIC, 18)
+#define VMETA_CMD_FORCE_INI _IO(IOP_MAGIC, 19)
+#define VMETA_CMD_GET_USER_NUM _IOR(IOP_MAGIC, 20, unsigned)
#endif /* __UIO_VMETA_H */
diff --git a/vmeta_lib.c b/vmeta_lib.c
index de811ad..d8e7bcf 100644
--- a/vmeta_lib.c
+++ b/vmeta_lib.c
@@ -684,6 +684,14 @@ SIGN32 vdec_os_api_force_ini(void)
kernel_share *p_ks;
vdec_os_driver_cb_t *p_cb = vdec_driver_get_cb();
+ if (p_cb && p_cb->kern_ver >= 100) {
+ int ret;
+
+ ret = ioctl(p_cb->uiofd, VMETA_CMD_FORCE_INI);
+
+ return ret < 0 ? -1 : 0;
+ }
+
if(p_cb->kernel_share_va == NULL) {
vdec_os_api_get_ks(&p_ks);
} else {
@@ -703,9 +711,18 @@ SIGN32 vdec_os_api_force_ini(void)
SIGN32 vdec_os_api_get_user_id(void)
{
kernel_share *p_ks;
- SIGN32 ret = -1;
+ SIGN32 ret;
vdec_os_driver_cb_t *p_cb = vdec_driver_get_cb();
+ if (p_cb->kern_ver >= 100) {
+ unsigned id;
+
+ ret = ioctl(p_cb->uiofd, VMETA_CMD_GET_USER_ID, &id);
+
+ return ret == 0 && id < MAX_VMETA_INSTANCE ? id :
+ -VDEC_OS_DRIVER_USER_ID_FAIL;
+ }
+
if(p_cb->kernel_share_va == NULL) {
vdec_os_api_get_ks(&p_ks);
} else {
@@ -727,6 +744,14 @@ SIGN32 vdec_os_api_free_user_id(SIGN32 user_id)
kernel_share *p_ks;
vdec_os_driver_cb_t *p_cb = vdec_driver_get_cb();
+ if (p_cb->kern_ver >= 100) {
+ int ret;
+
+ ret = ioctl(p_cb->uiofd, VMETA_CMD_FREE_USER_ID, user_id);
+
+ return ret == 0 ? VDEC_OS_DRIVER_OK : VDEC_OS_DRIVER_USER_ID_FAIL;
+ }
+
if(p_cb->kernel_share_va == NULL) {
dbg_printf(VDEC_DEBUG_ALL,"vdec_os_api_free_user_id error: not init yet\n");
return VDEC_OS_DRIVER_USER_ID_FAIL;
@@ -850,6 +875,20 @@ SIGN32 vdec_os_api_register_user_id(SIGN32 user_id)
pthread_t tmp;
struct monitor_data *p_md;
+ if (p_cb->kern_ver >= 100) {
+ int ret;
+
+ ret = ioctl(p_cb->uiofd, VMETA_CMD_REGISTER_USER_ID, user_id);
+
+ if (ret < 0) {
+ dbg_printf(VDEC_DEBUG_ALL, "%s: error %d\n",
+ __FUNCTION__, errno);
+ return VDEC_OS_DRIVER_USER_ID_FAIL;
+ }
+
+ return VDEC_OS_DRIVER_OK;
+ }
+
if(user_id>=MAX_VMETA_INSTANCE || user_id<0) {
dbg_printf(VDEC_DEBUG_ALL,"vdec_os_api_register_user_id error: exceeds max user_id\n");
return VDEC_OS_DRIVER_USER_ID_FAIL;
@@ -888,6 +927,19 @@ SIGN32 vdec_os_api_unregister_user_id(SIGN32 user_id)
kernel_share *p_ks;
vdec_os_driver_cb_t *p_cb = vdec_driver_get_cb();
+ if (p_cb->kern_ver >= 100) {
+ int ret;
+
+ ret = ioctl(p_cb->uiofd, VMETA_CMD_UNREGISTER_USER_ID, user_id);
+ if (ret < 0) {
+ dbg_printf(VDEC_DEBUG_ALL, "%s: error: %d\n",
+ __FUNCTION__, errno);
+ return VDEC_OS_DRIVER_USER_ID_FAIL;
+ }
+
+ return VDEC_OS_DRIVER_OK;
+ }
+
if(user_id>=MAX_VMETA_INSTANCE || user_id<0) {
dbg_printf(VDEC_DEBUG_ALL,"vdec_os_api_unregister_user_id error: exceeds max user_id\n");
return VDEC_OS_DRIVER_USER_ID_FAIL;
@@ -933,6 +985,15 @@ SIGN32 vdec_os_api_get_user_count(void)
return -1;
}
+ if (p_cb->kern_ver >= 100) {
+ unsigned num;
+ int ret;
+
+ ret = ioctl(p_cb->uiofd, VMETA_CMD_GET_USER_NUM, &num);
+
+ return ret < 0 ? -1 : num;
+ }
+
if(p_cb->kernel_share_va == NULL) {
vdec_os_api_get_ks(&p_ks);
} else {
@@ -954,6 +1015,31 @@ SIGN32 vdec_os_api_lock(SIGN32 user_id, long to_ms)
dbg_printf(VDEC_DEBUG_ALL,"vdec_os_api_lock error: point is NULL\n");
return LOCK_RET_ERROR_UNKNOWN;
}
+
+ if (p_cb->kern_ver >= 100) {
+ struct vmeta_lock lock;
+ int ret;
+
+ lock.user_id = user_id;
+ lock.timeout = to_ms;
+
+ ret = ioctl(p_cb->uiofd, VMETA_CMD_LOCK_USER_ID, &lock);
+
+ if (ret < 0) {
+ switch (errno) {
+ case ETIME:
+ return LOCK_RET_ERROR_TIMEOUT;
+ case EDEADLOCK:
+ return LOCK_RET_ME;
+ case EUCLEAN:
+ return LOCK_RET_FORCE_INIT;
+ default:
+ return LOCK_RET_ERROR_UNKNOWN;
+ }
+ }
+ return LOCK_RET_OHTERS_NORM;
+ }
+
p_ks = p_cb->kernel_share_va;
if(p_ks->active_user_id == user_id) {
@@ -990,7 +1076,18 @@ SIGN32 vdec_os_api_unlock(SIGN32 user_id)
if(p_cb == NULL) {
dbg_printf(VDEC_DEBUG_LOCK,"vdec_os_api_unlock error: point is NULL\n");
return LOCK_RET_ERROR_UNKNOWN;
- }
+ }
+
+ if (p_cb->kern_ver >= 100) {
+ ret = ioctl(p_cb->uiofd, VMETA_CMD_UNLOCK_USER_ID, user_id);
+
+ if (ret < 0) {
+ dbg_printf(VDEC_DEBUG_LOCK, "%s: error %d\n",
+ __FUNCTION__, errno);
+ return LOCK_RET_ERROR_UNKNOWN;
+ }
+ return LOCK_RET_OHTERS_NORM;
+ }
p_ks = p_cb->kernel_share_va;
vmeta_private_lock();