summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/tlk_driver/ote_comms.c159
-rw-r--r--security/tlk_driver/ote_device.c298
-rw-r--r--security/tlk_driver/ote_protocol.h105
3 files changed, 562 insertions, 0 deletions
diff --git a/security/tlk_driver/ote_comms.c b/security/tlk_driver/ote_comms.c
index eb9fc688e384..46d7fc679b78 100644
--- a/security/tlk_driver/ote_comms.c
+++ b/security/tlk_driver/ote_comms.c
@@ -102,6 +102,42 @@ static int te_setup_temp_buffers(struct te_request *request,
return ret;
}
+static int te_setup_temp_buffers_compat(struct te_request_compat *request,
+ struct tlk_context *context)
+{
+ uint32_t i;
+ int ret = OTE_SUCCESS;
+ struct te_oper_param_compat *params;
+
+ params = (struct te_oper_param_compat *)(uintptr_t)request->params;
+ for (i = 0; i < request->params_size; i++) {
+ switch (params[i].type) {
+ case TE_PARAM_TYPE_NONE:
+ case TE_PARAM_TYPE_INT_RO:
+ case TE_PARAM_TYPE_INT_RW:
+ break;
+ case TE_PARAM_TYPE_MEM_RO:
+ case TE_PARAM_TYPE_MEM_RW:
+ ret = te_pin_mem_buffers(
+ (void *)(uintptr_t)params[i].u.Mem.base,
+ params[i].u.Mem.len,
+ context);
+ if (ret < 0) {
+ pr_err("%s failed with err (%d)\n",
+ __func__, ret);
+ ret = OTE_ERROR_BAD_PARAMETERS;
+ break;
+ }
+ break;
+ default:
+ pr_err("%s: OTE_ERROR_BAD_PARAMETERS\n", __func__);
+ ret = OTE_ERROR_BAD_PARAMETERS;
+ break;
+ }
+ }
+ return ret;
+}
+
static void te_del_shmem_desc(void *buffer, struct tlk_context *context)
{
struct te_shmem_desc *shmem_desc, *tmp_shmem_desc;
@@ -150,6 +186,32 @@ static void te_unpin_temp_buffers(struct te_request *request,
}
}
+static void te_unpin_temp_buffers_compat(struct te_request_compat *request,
+ struct tlk_context *context)
+{
+ uint32_t i;
+ struct te_oper_param_compat *params;
+
+ params = (struct te_oper_param_compat *)(uintptr_t)request->params;
+ for (i = 0; i < request->params_size; i++) {
+ switch (params[i].type) {
+ case TE_PARAM_TYPE_NONE:
+ case TE_PARAM_TYPE_INT_RO:
+ case TE_PARAM_TYPE_INT_RW:
+ break;
+ case TE_PARAM_TYPE_MEM_RO:
+ case TE_PARAM_TYPE_MEM_RW:
+ te_unregister_memory(
+ (void *)(uintptr_t)params[i].u.Mem.base,
+ context);
+ break;
+ default:
+ pr_err("%s: OTE_ERROR_BAD_PARAMETERS\n", __func__);
+ break;
+ }
+ }
+}
+
#ifdef CONFIG_SMP
cpumask_t saved_cpu_mask;
static void switch_cpumask_to_cpu0(void)
@@ -278,6 +340,30 @@ static void do_smc(struct te_request *request, struct tlk_device *dev)
}
/*
+ * Do an SMC call
+ */
+static void do_smc_compat(struct te_request_compat *request,
+ struct tlk_device *dev)
+{
+ uint32_t smc_args;
+ uint32_t smc_params = 0;
+
+ smc_args = (char *)request - dev->req_param_buf;
+ if (request->params) {
+ smc_params =
+ (char *)(uintptr_t)request->params - dev->req_param_buf;
+ }
+
+ tlk_generic_smc(request->type, smc_args, smc_params);
+
+ /*
+ * Check to see if there are any logs in written by TLK.
+ * If there are, print them out.
+ */
+ ote_print_logs();
+}
+
+/*
* VPR programming SMC
*/
int te_set_vpr_params(void *vpr_base, size_t vpr_size)
@@ -373,6 +459,79 @@ void te_launch_operation(struct te_launchop *cmd,
te_unpin_temp_buffers(request, context);
}
+/*
+ * Open session SMC (supporting client-based te_open_session() calls)
+ */
+void te_open_session_compat(struct te_opensession_compat *cmd,
+ struct te_request_compat *request,
+ struct tlk_context *context)
+{
+ int ret;
+
+ ret = te_setup_temp_buffers_compat(request, context);
+ if (ret != OTE_SUCCESS) {
+ pr_err("te_setup_temp_buffers failed err (0x%x)\n", ret);
+ SET_RESULT(request, ret, OTE_RESULT_ORIGIN_API);
+ return;
+ }
+
+ memcpy(&request->dest_uuid,
+ &cmd->dest_uuid,
+ sizeof(struct te_service_id));
+
+ pr_info("OPEN_CLIENT_SESSION_COMPAT: 0x%x 0x%x 0x%x 0x%x\n",
+ request->dest_uuid[0],
+ request->dest_uuid[1],
+ request->dest_uuid[2],
+ request->dest_uuid[3]);
+
+ request->type = TE_SMC_OPEN_SESSION;
+
+ do_smc_compat(request, context->dev);
+
+ te_unpin_temp_buffers_compat(request, context);
+}
+
+/*
+ * Close session SMC (supporting client-based te_close_session() calls)
+ */
+void te_close_session_compat(struct te_closesession_compat *cmd,
+ struct te_request_compat *request,
+ struct tlk_context *context)
+{
+ request->session_id = cmd->session_id;
+ request->type = TE_SMC_CLOSE_SESSION;
+
+ do_smc_compat(request, context->dev);
+ if (request->result)
+ pr_info("Error closing session: %08x\n", request->result);
+}
+
+/*
+ * Launch operation SMC (supporting client-based te_launch_operation() calls)
+ */
+void te_launch_operation_compat(struct te_launchop_compat *cmd,
+ struct te_request_compat *request,
+ struct tlk_context *context)
+{
+ int ret;
+
+ ret = te_setup_temp_buffers_compat(request, context);
+ if (ret != OTE_SUCCESS) {
+ pr_err("te_setup_temp_buffers failed err (0x%x)\n", ret);
+ SET_RESULT(request, ret, OTE_RESULT_ORIGIN_API);
+ return;
+ }
+
+ request->session_id = cmd->session_id;
+ request->command_id = cmd->operation.command;
+ request->type = TE_SMC_LAUNCH_OPERATION;
+
+ do_smc_compat(request, context->dev);
+
+ te_unpin_temp_buffers_compat(request, context);
+}
+
static int __init tlk_register_irq_handler(void)
{
tlk_generic_smc(TE_SMC_REGISTER_IRQ_HANDLER,
diff --git a/security/tlk_driver/ote_device.c b/security/tlk_driver/ote_device.c
index 03fa1acc2129..170f46c06e14 100644
--- a/security/tlk_driver/ote_device.c
+++ b/security/tlk_driver/ote_device.c
@@ -41,6 +41,7 @@ static int te_create_free_cmd_list(struct tlk_device *dev)
{
int cmd_desc_count, ret = 0;
struct te_cmd_req_desc *req_desc;
+ struct te_cmd_req_desc_compat *req_desc_compat;
int bitmap_size;
bool use_reqbuf;
@@ -80,6 +81,12 @@ static int te_create_free_cmd_list(struct tlk_device *dev)
goto error;
}
+ /* requests in the first page, params in the second */
+ dev->req_addr_compat = (struct te_request_compat *)
+ dev->req_param_buf;
+ dev->param_addr_compat = (struct te_oper_param_compat *)
+ (dev->req_param_buf + PAGE_SIZE);
+
/* alloc param bitmap allocator */
bitmap_size = BITS_TO_LONGS(TE_PARAM_MAX) * sizeof(long);
dev->param_bitmap = kzalloc(bitmap_size, GFP_KERNEL);
@@ -99,6 +106,25 @@ static int te_create_free_cmd_list(struct tlk_device *dev)
/* Add the cmd param descriptor to free list */
list_add_tail(&req_desc->list, &(dev->free_cmd_list));
}
+
+ for (cmd_desc_count = 0;
+ cmd_desc_count < TE_CMD_DESC_MAX_COMPAT; cmd_desc_count++) {
+
+ req_desc_compat = kzalloc(sizeof(struct te_cmd_req_desc_compat),
+ GFP_KERNEL);
+ if (req_desc_compat == NULL) {
+ pr_err("Failed to allocate cmd req descriptor\n");
+ ret = -ENOMEM;
+ goto error;
+ }
+ req_desc_compat->req_addr =
+ dev->req_addr_compat + cmd_desc_count;
+ INIT_LIST_HEAD(&(req_desc_compat->list));
+
+ /* Add the cmd param descriptor to free list */
+ list_add_tail(&req_desc_compat->list, &(dev->free_cmd_list));
+ }
+
error:
return ret;
}
@@ -129,6 +155,32 @@ static void te_put_free_params(struct tlk_device *dev,
bitmap_release_region(dev->param_bitmap, idx, nbits);
}
+static struct te_oper_param_compat *
+ te_get_free_params_compat(struct tlk_device *dev, unsigned int nparams)
+{
+ struct te_oper_param_compat *params = NULL;
+ int idx, nbits;
+
+ if (nparams) {
+ nbits = get_count_order(nparams);
+ idx = bitmap_find_free_region(dev->param_bitmap,
+ TE_PARAM_MAX, nbits);
+ if (idx >= 0)
+ params = dev->param_addr_compat + idx;
+ }
+ return params;
+}
+
+static void te_put_free_params_compat(struct tlk_device *dev,
+ struct te_oper_param_compat *params, uint32_t nparams)
+{
+ int idx, nbits;
+
+ idx = (params - dev->param_addr_compat);
+ nbits = get_count_order(nparams);
+ bitmap_release_region(dev->param_bitmap, idx, nbits);
+}
+
static struct te_cmd_req_desc *te_get_free_cmd_desc(struct tlk_device *dev)
{
struct te_cmd_req_desc *cmd_desc = NULL;
@@ -159,6 +211,37 @@ static void te_put_used_cmd_desc(struct tlk_device *dev,
}
}
+static struct te_cmd_req_desc_compat *
+te_get_free_cmd_desc_compat(struct tlk_device *dev)
+{
+ struct te_cmd_req_desc_compat *cmd_desc = NULL;
+
+ if (!(list_empty(&(dev->free_cmd_list)))) {
+ cmd_desc = list_first_entry(&(dev->free_cmd_list),
+ struct te_cmd_req_desc_compat, list);
+ list_del(&(cmd_desc->list));
+ list_add_tail(&cmd_desc->list, &(dev->used_cmd_list));
+ }
+ return cmd_desc;
+}
+
+static void te_put_used_cmd_desc_compat(struct tlk_device *dev,
+ struct te_cmd_req_desc_compat *cmd_desc)
+{
+ struct te_cmd_req_desc_compat *param_desc, *tmp_param_desc;
+
+ if (cmd_desc) {
+ list_for_each_entry_safe(param_desc, tmp_param_desc,
+ &(dev->used_cmd_list), list) {
+ if (cmd_desc->req_addr == param_desc->req_addr) {
+ list_del(&param_desc->list);
+ list_add_tail(&param_desc->list,
+ &(dev->free_cmd_list));
+ }
+ }
+ }
+}
+
static void __attribute__((unused)) te_print_cmd_list(
struct tlk_device *dev, int used_list)
{
@@ -403,6 +486,209 @@ error:
return err;
}
+static int copy_params_from_user_compat(struct te_request_compat *req,
+ struct te_operation_compat *operation)
+{
+ struct te_oper_param_compat *param_array;
+ struct te_oper_param_compat *user_param;
+ uint32_t i;
+
+ if (operation->list_count == 0)
+ return 0;
+
+ param_array = (struct te_oper_param_compat *)(uintptr_t)req->params;
+ if (param_array == NULL) {
+ pr_err("param_array empty\n");
+ return 1;
+ }
+
+ user_param = (struct te_oper_param_compat *)(uintptr_t)
+ operation->list_head;
+ for (i = 0; i < operation->list_count && user_param != NULL; i++) {
+ if (copy_from_user(param_array + i, user_param,
+ sizeof(struct te_oper_param_compat))) {
+ pr_err("Failed to copy operation parameter:%d, %p, " \
+ "list_count: %d\n",
+ i, user_param, operation->list_count);
+ return 1;
+ }
+ user_param = (struct te_oper_param_compat *)(uintptr_t)
+ param_array[i].next_ptr_user;
+ }
+ return 0;
+}
+
+static int copy_params_to_user_compat(struct te_request_compat *req,
+ struct te_operation_compat *operation)
+{
+ struct te_oper_param_compat *param_array;
+ struct te_oper_param_compat *user_param;
+ uint32_t i;
+
+ if (operation->list_count == 0)
+ return 0;
+
+ param_array =
+ (struct te_oper_param_compat *)(uintptr_t)req->params;
+ if (param_array == NULL) {
+ pr_err("param_array empty\n");
+ return 1;
+ }
+
+ user_param =
+ (struct te_oper_param_compat *)(uintptr_t)operation->list_head;
+ for (i = 0; i < req->params_size; i++) {
+ if (copy_to_user(user_param, param_array + i,
+ sizeof(struct te_oper_param_compat))) {
+ pr_err("Failed to copy back parameter:%d %p\n", i,
+ user_param);
+ return 1;
+ }
+ user_param = (struct te_oper_param_compat *)(uintptr_t)
+ param_array[i].next_ptr_user;
+ }
+ return 0;
+}
+
+static long te_handle_trustedapp_ioctl_compat(struct file *file,
+ unsigned int ioctl_num, unsigned long ioctl_param)
+{
+ long err = 0;
+ union te_cmd_compat cmd_compat;
+ struct te_operation_compat *operation = NULL;
+ struct te_oper_param_compat *params = NULL;
+ struct te_request_compat *request;
+ void __user *ptr_user_answer = NULL;
+ struct te_answer answer;
+ struct te_cmd_req_desc_compat *cmd_desc = NULL;
+ struct tlk_context *context = file->private_data;
+ struct tlk_device *dev = context->dev;
+
+ if (copy_from_user(&cmd_compat, (void __user *)ioctl_param,
+ sizeof(union te_cmd_compat))) {
+ pr_err("Failed to copy command request\n");
+ err = -EFAULT;
+ goto error;
+ }
+
+ memset(&answer, 0, sizeof(struct te_answer));
+
+ switch (ioctl_num) {
+ case TE_IOCTL_OPEN_CLIENT_SESSION_COMPAT:
+ operation = &cmd_compat.opensession.operation;
+ ptr_user_answer = (void *)(uintptr_t)
+ cmd_compat.opensession.answer;
+
+ cmd_desc = te_get_free_cmd_desc_compat(dev);
+ params = te_get_free_params_compat(dev, operation->list_count);
+
+ if (!cmd_desc || (operation->list_count && !params)) {
+ SET_ANSWER(answer,
+ OTE_ERROR_OUT_OF_MEMORY,
+ OTE_RESULT_ORIGIN_COMMS);
+ pr_err("failed to get cmd_desc/params\n");
+ goto error;
+ }
+
+ request = cmd_desc->req_addr;
+ memset(request, 0, sizeof(struct te_request_compat));
+
+ request->params = (uintptr_t)params;
+ request->params_size = operation->list_count;
+
+ if (copy_params_from_user_compat(request, operation)) {
+ err = -EFAULT;
+ pr_info("failed to copy params from user\n");
+ goto error;
+ }
+
+ te_open_session_compat(&cmd_compat.opensession,
+ request, context);
+
+ SET_ANSWER(answer, request->result, request->result_origin);
+ answer.session_id = request->session_id;
+ break;
+
+ case TE_IOCTL_CLOSE_CLIENT_SESSION_COMPAT:
+ ptr_user_answer = (void *)(uintptr_t)
+ cmd_compat.closesession.answer;
+ cmd_desc = te_get_free_cmd_desc_compat(dev);
+ if (!cmd_desc) {
+ SET_ANSWER(answer,
+ OTE_ERROR_OUT_OF_MEMORY,
+ OTE_RESULT_ORIGIN_COMMS);
+ pr_err("failed to get cmd_desc\n");
+ goto error;
+ }
+
+ request = cmd_desc->req_addr;
+ memset(request, 0, sizeof(struct te_request_compat));
+
+ /* close session cannot fail */
+ te_close_session_compat(&cmd_compat.closesession,
+ request, context);
+ break;
+
+ case TE_IOCTL_LAUNCH_OPERATION_COMPAT:
+ operation = &cmd_compat.launchop.operation;
+ ptr_user_answer = (void *)(uintptr_t)cmd_compat.launchop.answer;
+
+ cmd_desc = te_get_free_cmd_desc_compat(dev);
+ params = te_get_free_params_compat(dev, operation->list_count);
+
+ if (!cmd_desc || (operation->list_count && !params)) {
+ SET_ANSWER(answer,
+ OTE_ERROR_OUT_OF_MEMORY,
+ OTE_RESULT_ORIGIN_COMMS);
+ pr_err("failed to get cmd_desc/params\n");
+ goto error;
+ }
+
+ request = cmd_desc->req_addr;
+ memset(request, 0, sizeof(struct te_request_compat));
+
+ request->params = (uintptr_t)params;
+ request->params_size = operation->list_count;
+
+ if (copy_params_from_user_compat(request, operation)) {
+ err = -EFAULT;
+ pr_info("failed to copy params from user\n");
+ goto error;
+ }
+
+ te_launch_operation_compat(&cmd_compat.launchop,
+ request, context);
+
+ SET_ANSWER(answer, request->result, request->result_origin);
+ break;
+
+ default:
+ pr_err("Invalid IOCTL Cmd\n");
+ err = -EINVAL;
+ goto error;
+ }
+ if (ptr_user_answer && !err) {
+ if (copy_to_user(ptr_user_answer, &answer,
+ sizeof(struct te_answer))) {
+ pr_err("Failed to copy answer\n");
+ err = -EFAULT;
+ }
+ }
+ if (request->params && !err) {
+ if (copy_params_to_user_compat(request, operation)) {
+ pr_err("Failed to copy return params\n");
+ err = -EFAULT;
+ }
+ }
+
+error:
+ if (cmd_desc)
+ te_put_used_cmd_desc_compat(dev, cmd_desc);
+ if (params)
+ te_put_free_params_compat(dev, params, operation->list_count);
+ return err;
+}
+
static long tlk_device_ioctl(struct file *file, unsigned int ioctl_num,
unsigned long ioctl_param)
{
@@ -417,6 +703,15 @@ static long tlk_device_ioctl(struct file *file, unsigned int ioctl_num,
mutex_unlock(&smc_lock);
break;
+ case TE_IOCTL_OPEN_CLIENT_SESSION_COMPAT:
+ case TE_IOCTL_CLOSE_CLIENT_SESSION_COMPAT:
+ case TE_IOCTL_LAUNCH_OPERATION_COMPAT:
+ mutex_lock(&smc_lock);
+ err = te_handle_trustedapp_ioctl_compat(file, ioctl_num,
+ ioctl_param);
+ mutex_unlock(&smc_lock);
+ break;
+
case TE_IOCTL_FILE_NEW_REQ:
case TE_IOCTL_FILE_FILL_BUF:
case TE_IOCTL_FILE_REQ_COMPLETE:
@@ -446,6 +741,9 @@ static const struct file_operations tlk_device_fops = {
.open = tlk_device_open,
.release = tlk_device_release,
.unlocked_ioctl = tlk_device_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = tlk_device_ioctl,
+#endif
};
struct miscdevice tlk_misc_device = {
diff --git a/security/tlk_driver/ote_protocol.h b/security/tlk_driver/ote_protocol.h
index f74e1734df7a..66228e4a9eaa 100644
--- a/security/tlk_driver/ote_protocol.h
+++ b/security/tlk_driver/ote_protocol.h
@@ -28,6 +28,15 @@
_IOWR(TE_IOCTL_MAGIC_NUMBER, 0x11, union te_cmd)
#define TE_IOCTL_LAUNCH_OPERATION \
_IOWR(TE_IOCTL_MAGIC_NUMBER, 0x14, union te_cmd)
+
+/* ioctls using new structs (eventually to replace current ioctls) */
+#define TE_IOCTL_OPEN_CLIENT_SESSION_COMPAT \
+ _IOWR(TE_IOCTL_MAGIC_NUMBER, 0x10, union te_cmd_compat)
+#define TE_IOCTL_CLOSE_CLIENT_SESSION_COMPAT \
+ _IOWR(TE_IOCTL_MAGIC_NUMBER, 0x11, union te_cmd_compat)
+#define TE_IOCTL_LAUNCH_OPERATION_COMPAT \
+ _IOWR(TE_IOCTL_MAGIC_NUMBER, 0x14, union te_cmd_compat)
+
#define TE_IOCTL_FILE_NEW_REQ \
_IOR(TE_IOCTL_MAGIC_NUMBER, 0x16, struct te_file_req)
#define TE_IOCTL_FILE_FILL_BUF \
@@ -46,6 +55,11 @@
#define TE_CMD_DESC_MAX (PAGE_SIZE / sizeof(struct te_request))
#define TE_PARAM_MAX (PAGE_SIZE / sizeof(struct te_oper_param))
+#define TE_CMD_DESC_MAX_COMPAT \
+ (PAGE_SIZE / sizeof(struct te_request_compat))
+#define TE_PARAM_MAX_COMPAT \
+ (PAGE_SIZE / sizeof(struct te_oper_param_compat))
+
#define MAX_EXT_SMC_ARGS 12
extern struct mutex smc_lock;
@@ -60,6 +74,9 @@ struct tlk_device {
struct te_oper_param *param_addr;
dma_addr_t param_addr_phys;
+ struct te_request_compat *req_addr_compat;
+ struct te_oper_param_compat *param_addr_compat;
+
char *req_param_buf;
unsigned long *param_bitmap;
@@ -73,6 +90,11 @@ struct te_cmd_req_desc {
struct list_head list;
};
+struct te_cmd_req_desc_compat {
+ struct te_request_compat *req_addr;
+ struct list_head list;
+};
+
struct te_shmem_desc {
struct list_head list;
void *buffer;
@@ -126,6 +148,21 @@ struct te_oper_param {
void *next_ptr_user;
};
+struct te_oper_param_compat {
+ uint32_t index;
+ uint32_t type;
+ union {
+ struct {
+ uint32_t val;
+ } Int;
+ struct {
+ uint64_t base;
+ uint32_t len;
+ } Mem;
+ } u;
+ uint64_t next_ptr_user;
+};
+
struct te_operation {
uint32_t command;
struct te_oper_param *list_head;
@@ -175,6 +212,51 @@ union te_cmd {
struct te_launchop launchop;
};
+/*
+ * Compat versions of the original structs (eventually to replace
+ * the old structs, once the lib/TLK kernel changes are in).
+ */
+struct te_operation_compat {
+ uint32_t command;
+ uint32_t status;
+ uint64_t list_head;
+ uint64_t list_tail;
+ uint32_t list_count;
+ uint32_t interface_side;
+};
+
+/*
+ * OpenSession
+ */
+struct te_opensession_compat {
+ struct te_service_id dest_uuid;
+ struct te_operation_compat operation;
+ uint64_t answer;
+};
+
+/*
+ * CloseSession
+ */
+struct te_closesession_compat {
+ uint32_t session_id;
+ uint64_t answer;
+};
+
+/*
+ * LaunchOperation
+ */
+struct te_launchop_compat {
+ uint32_t session_id;
+ struct te_operation_compat operation;
+ uint64_t answer;
+};
+
+union te_cmd_compat {
+ struct te_opensession_compat opensession;
+ struct te_closesession_compat closesession;
+ struct te_launchop_compat launchop;
+};
+
struct te_request {
uint32_t type;
uint32_t session_id;
@@ -186,6 +268,17 @@ struct te_request {
uint32_t result_origin;
};
+struct te_request_compat {
+ uint32_t type;
+ uint32_t session_id;
+ uint32_t command_id;
+ uint64_t params;
+ uint32_t params_size;
+ uint32_t dest_uuid[4];
+ uint32_t result;
+ uint32_t result_origin;
+};
+
struct te_answer {
uint32_t result;
uint32_t session_id;
@@ -204,6 +297,18 @@ void te_launch_operation(struct te_launchop *cmd,
struct te_request *request,
struct tlk_context *context);
+void te_open_session_compat(struct te_opensession_compat *cmd,
+ struct te_request_compat *request,
+ struct tlk_context *context);
+
+void te_close_session_compat(struct te_closesession_compat *cmd,
+ struct te_request_compat *request,
+ struct tlk_context *context);
+
+void te_launch_operation_compat(struct te_launchop_compat *cmd,
+ struct te_request_compat *request,
+ struct tlk_context *context);
+
#define TE_MAX_FILE_NAME_LEN 64
enum te_file_req_type {