From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Yael Samet Date: Mon, 14 Aug 2017 11:32:37 +0300 Subject: [PATCH] mei: dal: add test module DAL test module allows the user space to test the DAL kernel space api. It exposes a character device to the user space, and calls DAL api's according to the protocol which is defined in kdi_cmd_defs.h header file. This patch adds the code of DAL test module. Change-Id: Id7ec2e7d3f22b07c41941dc5bada6edaf16e893b Signed-off-by: Tomas Winkler Signed-off-by: Yael Samet --- drivers/misc/mei/dal/Kconfig | 8 + drivers/misc/mei/dal/Makefile | 2 + drivers/misc/mei/dal/dal_test.c | 775 +++++++++++++++++++++++ drivers/misc/mei/dal/uapi/kdi_cmd_defs.h | 176 +++++ 4 files changed, 961 insertions(+) create mode 100644 drivers/misc/mei/dal/dal_test.c create mode 100644 drivers/misc/mei/dal/uapi/kdi_cmd_defs.h diff --git a/drivers/misc/mei/dal/Kconfig b/drivers/misc/mei/dal/Kconfig index 5d8356ae931e..8943d4f7f7e4 100644 --- a/drivers/misc/mei/dal/Kconfig +++ b/drivers/misc/mei/dal/Kconfig @@ -5,3 +5,11 @@ config INTEL_MEI_DAL Dynamic Application Loader enables downloading java applets to DAL FW and run it in a secure environment. The DAL module exposes both user space api and kernel space api. + +config INTEL_MEI_DAL_TEST + tristate "Test Module for Dynamic Application Loader for ME" + depends on INTEL_MEI_DAL + help + Testing Module for Dynamic Application Loader, to test the + kernel space api from a user space client. The test module + calls the kernel space api functions of DAL module. diff --git a/drivers/misc/mei/dal/Makefile b/drivers/misc/mei/dal/Makefile index b8d5456c94a1..fa3f8150131e 100644 --- a/drivers/misc/mei/dal/Makefile +++ b/drivers/misc/mei/dal/Makefile @@ -10,3 +10,5 @@ mei_dal-objs += bh_internal.o mei_dal-objs += dal_cdev.o mei_dal-objs += dal_kdi.o mei_dal-objs += dal_ta_access.o + +obj-$(CONFIG_INTEL_MEI_DAL_TEST) += dal_test.o diff --git a/drivers/misc/mei/dal/dal_test.c b/drivers/misc/mei/dal/dal_test.c new file mode 100644 index 000000000000..56da059e5cc6 --- /dev/null +++ b/drivers/misc/mei/dal/dal_test.c @@ -0,0 +1,775 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "uapi/kdi_cmd_defs.h" +#define KDI_MODULE "mei_dal" + +/** + * this is the max data size possible: + * there is no actually max size for acp file, + * but for testing 512k is good enough + */ +#define MAX_DATA_SIZE SZ_512K + +#define KDI_TEST_OPENED 0 + +/** + * struct dal_test_data - dal test cmd and response data + * + * @cmd_data_size: size of cmd got from user space + * @cmd_data: the cmd got from user space + * @cmd_lock: protects cmd_data buffer + * + * @resp_data_size: size of response from kdi + * @resp_data: the response from kdi + * @resp_lock: protects resp_data buffer + */ +struct dal_test_data { + u32 cmd_data_size; + u8 *cmd_data; + struct mutex cmd_lock; /* protects cmd_data buffer */ + + u32 resp_data_size; + u8 *resp_data; + struct mutex resp_lock; /* protects resp_data buffer */ +}; + +/** + * struct dal_test_device - dal test private data + * + * @dev: the device structure + * @cdev: character device + * + * @kdi_test_status: status of test module + * @data: cmd and response data + */ +static struct dal_test_device { + struct device *dev; + struct cdev cdev; + + unsigned long kdi_test_status; + struct dal_test_data *data; +} dal_test_dev; + +#if IS_MODULE(CONFIG_INTEL_MEI_DAL) +/** + * dal_test_find_module - find the given module + * + * @mod_name: the module name to find + * + * Return: pointer to the module if it is found + * NULL otherwise + */ +static struct module *dal_test_find_module(const char *mod_name) +{ + struct module *mod; + + mutex_lock(&module_mutex); + mod = find_module(mod_name); + mutex_unlock(&module_mutex); + + return mod; +} + +/** + * dal_test_load_kdi - load kdi module + * + * @dev: dal test device + * + * Return: 0 on success + * <0 on failure + */ +static int dal_test_load_kdi(struct dal_test_device *dev) +{ + struct module *mod; + + /* load KDI if it wasn't loaded */ + request_module(KDI_MODULE); + + mod = dal_test_find_module(KDI_MODULE); + if (!mod) { + dev_err(dev->dev, "failed to find KDI module: %s\n", + KDI_MODULE); + return -ENODEV; + } + + if (!try_module_get(mod)) { + dev_err(dev->dev, "failed to get KDI module\n"); + return -EFAULT; + } + + return 0; +} + +/** + * dal_test_unload_kdi - unload kdi module + * + * @dev: dal test device + * + * Return: 0 on success + * <0 on failure + */ +static int dal_test_unload_kdi(struct dal_test_device *dev) +{ + struct module *mod; + + mod = dal_test_find_module(KDI_MODULE); + if (!mod) { + dev_err(dev->dev, "failed to find KDI module: %s\n", + KDI_MODULE); + return -ENODEV; + } + module_put(mod); + + return 0; +} +#else +static inline int dal_test_load_kdi(struct dal_test_device *dev) { return 0; } +static inline int dal_test_unload_kdi(struct dal_test_device *dev) { return 0; } +#endif + +/** + * dal_test_result_set - set data to the result buffer + * + * @test_data: test command and response buffers + * @data: new data + * @size: size of the data buffer + */ +static void dal_test_result_set(struct dal_test_data *test_data, + void *data, u32 size) +{ + memcpy(test_data->resp_data, data, size); + test_data->resp_data_size = size; +} + +/** + * dal_test_result_append - append data to the result buffer + * + * @test_data: test command and response buffers + * @data: new data + * @size: size of the data buffer + */ +static void dal_test_result_append(struct dal_test_data *test_data, + void *data, u32 size) +{ + size_t offset = test_data->resp_data_size; + + memcpy(test_data->resp_data + offset, data, size); + test_data->resp_data_size += size; +} + +/** + * dal_test_send_and_recv - call send and receive function of kdi + * + * @dev: dal test device + * @t_cmd: the command to send kdi + * @t_data: test command and response buffers + */ +static void dal_test_send_and_recv(struct dal_test_device *dev, + struct kdi_test_command *t_cmd, + struct dal_test_data *t_data) +{ + struct send_and_rcv_cmd *cmd; + struct send_and_rcv_resp resp; + ssize_t data_size; + size_t output_len; + s32 response_code; + u8 *input; + u8 *output; + s32 status; + + memset(&resp, 0, sizeof(resp)); + + cmd = (struct send_and_rcv_cmd *)t_cmd->data; + data_size = t_data->cmd_data_size - sizeof(t_cmd->cmd_id) - + sizeof(*cmd); + if (data_size < 0) { + dev_dbg(dev->dev, "malformed command struct: data_size = %zu\n", + data_size); + resp.test_mod_status = -EINVAL; + + mutex_lock(&t_data->resp_lock); + dal_test_result_set(t_data, &resp, sizeof(resp)); + mutex_unlock(&t_data->resp_lock); + return; + } + + response_code = 0; + output = NULL; + input = (data_size) ? cmd->input : NULL; + output_len = (cmd->is_output_len_ptr) ? cmd->output_buf_len : 0; + + dev_dbg(dev->dev, "call dal_send_and_receive: handle=%llu command_id=%d input_len=%zd\n", + cmd->session_handle, cmd->command_id, data_size); + + status = dal_send_and_receive(cmd->session_handle, cmd->command_id, + input, data_size, + cmd->is_output_buf ? &output : NULL, + cmd->is_output_len_ptr ? + &output_len : NULL, + cmd->is_response_code_ptr ? + &response_code : NULL); + + dev_dbg(dev->dev, "dal_send_and_receive return: status=%d output_len=%zu response_code=%d\n", + status, output_len, response_code); + + resp.output_len = (u32)output_len; + resp.response_code = response_code; + resp.status = status; + resp.test_mod_status = 0; + + /* in case the call failed we don't copy the data */ + mutex_lock(&t_data->resp_lock); + dal_test_result_set(t_data, &resp, sizeof(resp)); + if (output && resp.output_len) + dal_test_result_append(t_data, output, resp.output_len); + mutex_unlock(&t_data->resp_lock); + + kfree(output); +} + +/** + * dal_test_create_session - call create session function of kdi + * + * @dev: dal test device + * @t_cmd: the command to send kdi + * @t_data: test command and response buffers + */ +static void dal_test_create_session(struct dal_test_device *dev, + struct kdi_test_command *t_cmd, + struct dal_test_data *t_data) +{ + struct session_create_cmd *cmd; + struct session_create_resp resp; + u32 data_size; + u64 handle; + char *app_id; + u8 *acp_pkg; + u8 *init_params; + u32 offset; + s32 status; + + memset(&resp, 0, sizeof(resp)); + + cmd = (struct session_create_cmd *)t_cmd->data; + data_size = t_data->cmd_data_size - sizeof(t_cmd->cmd_id) - + sizeof(*cmd); + + if (cmd->app_id_len + cmd->acp_pkg_len + cmd->init_param_len != + data_size) { + dev_dbg(dev->dev, "malformed command struct: data_size = %d\n", + data_size); + resp.test_mod_status = -EINVAL; + + mutex_lock(&t_data->resp_lock); + dal_test_result_set(t_data, &resp, sizeof(resp)); + mutex_unlock(&t_data->resp_lock); + return; + } + + handle = 0; + + offset = 0; + app_id = (cmd->app_id_len) ? cmd->data + offset : NULL; + offset += cmd->app_id_len; + + acp_pkg = (cmd->acp_pkg_len) ? cmd->data + offset : NULL; + offset += cmd->acp_pkg_len; + + init_params = (cmd->init_param_len) ? cmd->data + offset : NULL; + offset += cmd->init_param_len; + + dev_dbg(dev->dev, "call dal_create_session params: app_id = %s, app_id len = %d, acp pkg len = %d, init params len = %d\n", + app_id, cmd->app_id_len, cmd->acp_pkg_len, cmd->init_param_len); + + status = dal_create_session(cmd->is_session_handle_ptr ? + &handle : NULL, + app_id, acp_pkg, + cmd->acp_pkg_len, + init_params, + cmd->init_param_len); + dev_dbg(dev->dev, "dal_create_session return: status = %d, handle = %llu\n", + status, handle); + + resp.session_handle = handle; + resp.status = status; + resp.test_mod_status = 0; + + mutex_lock(&t_data->resp_lock); + dal_test_result_set(t_data, &resp, sizeof(resp)); + mutex_unlock(&t_data->resp_lock); +} + +/** + * dal_test_close_session - call close session function of kdi + * + * @dev: dal test device + * @t_cmd: the command to send kdi + * @t_data: test command and response buffers + */ +static void dal_test_close_session(struct dal_test_device *dev, + struct kdi_test_command *t_cmd, + struct dal_test_data *t_data) +{ + struct session_close_cmd *cmd; + struct session_close_resp resp; + + memset(&resp, 0, sizeof(resp)); + + cmd = (struct session_close_cmd *)t_cmd->data; + if (t_data->cmd_data_size != sizeof(t_cmd->cmd_id) + sizeof(*cmd)) { + dev_dbg(dev->dev, "malformed command struct\n"); + resp.test_mod_status = -EINVAL; + + mutex_lock(&t_data->resp_lock); + dal_test_result_set(t_data, &resp, sizeof(resp)); + mutex_unlock(&t_data->resp_lock); + return; + } + + resp.status = dal_close_session(cmd->session_handle); + resp.test_mod_status = 0; + + mutex_lock(&t_data->resp_lock); + dal_test_result_set(t_data, &resp, sizeof(resp)); + mutex_unlock(&t_data->resp_lock); +} + +/** + * dal_test_version_info - call get version function of kdi + * + * @dev: dal test device + * @t_cmd: the command to send kdi + * @t_data: test command and response buffers + */ +static void dal_test_version_info(struct dal_test_device *dev, + struct kdi_test_command *t_cmd, + struct dal_test_data *t_data) +{ + struct version_get_info_cmd *cmd; + struct version_get_info_resp resp; + struct dal_version_info *version; + + memset(&resp, 0, sizeof(resp)); + + cmd = (struct version_get_info_cmd *)t_cmd->data; + if (t_data->cmd_data_size != sizeof(t_cmd->cmd_id) + sizeof(*cmd)) { + dev_dbg(dev->dev, "malformed command struct\n"); + resp.test_mod_status = -EINVAL; + mutex_lock(&t_data->resp_lock); + dal_test_result_set(t_data, &resp, sizeof(resp)); + mutex_unlock(&t_data->resp_lock); + return; + } + + version = (cmd->is_version_ptr) ? + (struct dal_version_info *)resp.kdi_version : NULL; + + resp.status = dal_get_version_info(version); + resp.test_mod_status = 0; + + mutex_lock(&t_data->resp_lock); + dal_test_result_set(t_data, &resp, sizeof(resp)); + mutex_unlock(&t_data->resp_lock); +} + +/** + * dal_test_set_ex_access - call set/remove access function of kdi + * + * @dev: dal test device + * @t_cmd: the command to send kdi + * @t_data: test command and response buffers + * @set_access: true when calling set access function + * false when calling remove access function + */ +static void dal_test_set_ex_access(struct dal_test_device *dev, + struct kdi_test_command *t_cmd, + struct dal_test_data *t_data, + bool set_access) +{ + struct ta_access_set_remove_cmd *cmd; + struct ta_access_set_remove_resp resp; + u32 data_size; + uuid_t app_uuid; + char *app_id; + s32 status; + + memset(&resp, 0, sizeof(resp)); + + cmd = (struct ta_access_set_remove_cmd *)t_cmd->data; + data_size = t_data->cmd_data_size - sizeof(t_cmd->cmd_id) - + sizeof(*cmd); + + if (cmd->app_id_len != data_size) { + dev_dbg(dev->dev, "malformed command struct\n"); + resp.test_mod_status = -EINVAL; + + mutex_lock(&t_data->resp_lock); + dal_test_result_set(t_data, &resp, sizeof(resp)); + mutex_unlock(&t_data->resp_lock); + return; + } + + app_id = (cmd->app_id_len) ? cmd->data : NULL; + + status = dal_uuid_parse(app_id, &app_uuid); + if (status < 0) + goto out; + + if (set_access) + status = dal_set_ta_exclusive_access(&app_uuid); + else + status = dal_unset_ta_exclusive_access(&app_uuid); + +out: + resp.status = status; + resp.test_mod_status = 0; + + mutex_lock(&t_data->resp_lock); + dal_test_result_set(t_data, &resp, sizeof(resp)); + mutex_unlock(&t_data->resp_lock); +} + +/** + * dal_test_kdi_command - parse and invoke the requested command + * + * @dev: dal test device + */ +static void dal_test_kdi_command(struct dal_test_device *dev) +{ + struct dal_test_data *test_data; + struct kdi_test_command *cmd; + s32 status; + + test_data = dev->data; + cmd = (struct kdi_test_command *)test_data->cmd_data; + + if (test_data->cmd_data_size < sizeof(cmd->cmd_id)) { + dev_dbg(dev->dev, "malformed command struct\n"); + status = -EINVAL; + goto prep_err_test_mod; + } + + switch (cmd->cmd_id) { + case KDI_SESSION_CREATE: { + dev_dbg(dev->dev, "KDI_CREATE_SESSION[%d]\n", cmd->cmd_id); + dal_test_create_session(dev, cmd, test_data); + break; + } + case KDI_SESSION_CLOSE: { + dev_dbg(dev->dev, "KDI_CLOSE_SESSION[%d]\n", cmd->cmd_id); + dal_test_close_session(dev, cmd, test_data); + break; + } + case KDI_SEND_AND_RCV: { + dev_dbg(dev->dev, "KDI_SEND_AND_RCV[%d]\n", cmd->cmd_id); + dal_test_send_and_recv(dev, cmd, test_data); + break; + } + case KDI_VERSION_GET_INFO: { + dev_dbg(dev->dev, "KDI_GET_VERSION_INFO[%d]\n", cmd->cmd_id); + dal_test_version_info(dev, cmd, test_data); + break; + } + case KDI_EXCLUSIVE_ACCESS_SET: + case KDI_EXCLUSIVE_ACCESS_REMOVE: { + dev_dbg(dev->dev, "KDI_SET_EXCLUSIVE_ACCESS or KDI_REMOVE_EXCLUSIVE_ACCESS[%d]\n", + cmd->cmd_id); + dal_test_set_ex_access(dev, cmd, test_data, + cmd->cmd_id == KDI_EXCLUSIVE_ACCESS_SET); + break; + } + default: + dev_dbg(dev->dev, "unknown command %d\n", cmd->cmd_id); + status = -EINVAL; + goto prep_err_test_mod; + } + + return; + +prep_err_test_mod: + mutex_lock(&test_data->resp_lock); + dal_test_result_set(test_data, &status, sizeof(status)); + mutex_unlock(&test_data->resp_lock); +} + +/** + * dal_test_read - dal test read function + * + * @filp: pointer to file structure + * @buff: pointer to user buffer + * @count: buffer length + * @offp: data offset in buffer + * + * Return: >=0 data length on success + * <0 on failure + */ +static ssize_t dal_test_read(struct file *filp, char __user *buff, size_t count, + loff_t *offp) +{ + struct dal_test_device *dev; + struct dal_test_data *test_data; + int ret; + + dev = filp->private_data; + test_data = dev->data; + + mutex_lock(&test_data->resp_lock); + + if (test_data->resp_data_size > count) { + ret = -EMSGSIZE; + goto unlock; + } + + dev_dbg(dev->dev, "copying %d bytes to userspace\n", + test_data->resp_data_size); + if (copy_to_user(buff, test_data->resp_data, + test_data->resp_data_size)) { + dev_dbg(dev->dev, "copy_to_user failed\n"); + ret = -EFAULT; + goto unlock; + } + ret = test_data->resp_data_size; + +unlock: + mutex_unlock(&test_data->resp_lock); + + return ret; +} + +/** + * dal_test_write - dal test write function + * + * @filp: pointer to file structure + * @buff: pointer to user buffer + * @count: buffer length + * @offp: data offset in buffer + * + * Return: >=0 data length on success + * <0 on failure + */ +static ssize_t dal_test_write(struct file *filp, const char __user *buff, + size_t count, loff_t *offp) +{ + struct dal_test_device *dev; + struct dal_test_data *test_data; + + dev = filp->private_data; + test_data = dev->data; + + if (count > MAX_DATA_SIZE) + return -EMSGSIZE; + + mutex_lock(&test_data->cmd_lock); + + if (copy_from_user(test_data->cmd_data, buff, count)) { + mutex_unlock(&test_data->cmd_lock); + dev_dbg(dev->dev, "copy_from_user failed\n"); + return -EFAULT; + } + + test_data->cmd_data_size = count; + dev_dbg(dev->dev, "write %zu bytes\n", count); + + dal_test_kdi_command(dev); + + mutex_unlock(&test_data->cmd_lock); + + return count; +} + +/** + * dal_test_open - dal test open function + * + * @inode: pointer to inode structure + * @filp: pointer to file structure + * + * Return: 0 on success + * <0 on failure + */ +static int dal_test_open(struct inode *inode, struct file *filp) +{ + struct dal_test_device *dev; + struct dal_test_data *test_data; + int ret; + + dev = container_of(inode->i_cdev, struct dal_test_device, cdev); + if (!dev) + return -ENODEV; + + /* single open */ + if (test_and_set_bit(KDI_TEST_OPENED, &dev->kdi_test_status)) + return -EBUSY; + + test_data = kzalloc(sizeof(*test_data), GFP_KERNEL); + if (!test_data) { + ret = -ENOMEM; + goto err_clear_bit; + } + + test_data->cmd_data = kzalloc(MAX_DATA_SIZE, GFP_KERNEL); + test_data->resp_data = kzalloc(MAX_DATA_SIZE, GFP_KERNEL); + if (!test_data->cmd_data || !test_data->resp_data) { + ret = -ENOMEM; + goto err_free; + } + + mutex_init(&test_data->cmd_lock); + mutex_init(&test_data->resp_lock); + + ret = dal_test_load_kdi(dev); + if (ret) + goto err_free; + + dev->data = test_data; + filp->private_data = dev; + + return nonseekable_open(inode, filp); + +err_free: + kfree(test_data->cmd_data); + kfree(test_data->resp_data); + kfree(test_data); + +err_clear_bit: + clear_bit(KDI_TEST_OPENED, &dev->kdi_test_status); + + return ret; +} + +/** + * dal_test_release - dal test release function + * + * @inode: pointer to inode structure + * @filp: pointer to file structure + * + * Return: 0 on success + * <0 on failure + */ +static int dal_test_release(struct inode *inode, struct file *filp) +{ + struct dal_test_device *dev; + struct dal_test_data *test_data; + + dev = filp->private_data; + if (!dev) + return -ENODEV; + + dal_test_unload_kdi(dev); + + test_data = dev->data; + if (test_data) { + kfree(test_data->cmd_data); + kfree(test_data->resp_data); + kfree(test_data); + } + + clear_bit(KDI_TEST_OPENED, &dev->kdi_test_status); + + filp->private_data = NULL; + + return 0; +} + +static const struct file_operations dal_test_fops = { + .owner = THIS_MODULE, + .open = dal_test_open, + .release = dal_test_release, + .read = dal_test_read, + .write = dal_test_write, + .llseek = no_llseek, +}; + +/** + * dal_test_exit - destroy dal test device + */ +static void __exit dal_test_exit(void) +{ + struct dal_test_device *dev = &dal_test_dev; + struct class *dal_test_class; + static dev_t devt; + + dal_test_class = dev->dev->class; + devt = dev->dev->devt; + + cdev_del(&dev->cdev); + unregister_chrdev_region(devt, MINORMASK); + device_destroy(dal_test_class, devt); + class_destroy(dal_test_class); +} + +/** + * dal_test_init - initiallize dal test device + * + * Return: 0 on success + * <0 on failure + */ +static int __init dal_test_init(void) +{ + struct dal_test_device *dev = &dal_test_dev; + struct class *dal_test_class; + static dev_t devt; + int ret; + + ret = alloc_chrdev_region(&devt, 0, 1, "mei_dal_test"); + if (ret) + return ret; + + dal_test_class = class_create(THIS_MODULE, "mei_dal_test"); + if (IS_ERR(dal_test_class)) { + ret = PTR_ERR(dal_test_class); + dal_test_class = NULL; + goto err_unregister_cdev; + } + + dev->dev = device_create(dal_test_class, NULL, devt, dev, "dal_test0"); + if (IS_ERR(dev->dev)) { + ret = PTR_ERR(dev->dev); + goto err_class_destroy; + } + + cdev_init(&dev->cdev, &dal_test_fops); + dev->cdev.owner = THIS_MODULE; + ret = cdev_add(&dev->cdev, devt, 1); + if (ret) + goto err_device_destroy; + + return 0; + +err_device_destroy: + device_destroy(dal_test_class, devt); +err_class_destroy: + class_destroy(dal_test_class); +err_unregister_cdev: + unregister_chrdev_region(devt, 1); + + return ret; +} + +module_init(dal_test_init); +module_exit(dal_test_exit); + +MODULE_AUTHOR("Intel Corporation"); +MODULE_DESCRIPTION("Intel(R) DAL test"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mei/dal/uapi/kdi_cmd_defs.h b/drivers/misc/mei/dal/uapi/kdi_cmd_defs.h new file mode 100644 index 000000000000..13717df1ae54 --- /dev/null +++ b/drivers/misc/mei/dal/uapi/kdi_cmd_defs.h @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. + */ + +#ifndef KDI_CMD_DEFS_H +#define KDI_CMD_DEFS_H + +/** + * enum kdi_command_id - cmd id to invoke in kdi module + * + * @KDI_SESSION_CREATE: call kdi "create session" function + * @KDI_SESSION_CLOSE: call kdi "close session" function + * @KDI_SEND_AND_RCV: call kdi "send and receive" function + * @KDI_VERSION_GET_INFO: call kdi "get version" function + * @KDI_EXCLUSIVE_ACCESS_SET: call kdi "set exclusive access" function + * @KDI_EXCLUSIVE_ACCESS_REMOVE: call kdi "unset exclusive access" function + */ +enum kdi_command_id { + KDI_SESSION_CREATE, + KDI_SESSION_CLOSE, + KDI_SEND_AND_RCV, + KDI_VERSION_GET_INFO, + KDI_EXCLUSIVE_ACCESS_SET, + KDI_EXCLUSIVE_ACCESS_REMOVE +}; + +/** + * struct kdi_test_command - contains the command received from user space + * + * @cmd_id: the command id + * @data: the command data + */ +struct kdi_test_command { + __u8 cmd_id; + unsigned char data[0]; +} __packed; + +/** + * struct session_create_cmd - create session cmd data + * + * @app_id_len: length of app_id arg + * @acp_pkg_len: length of the acp_pkg arg + * @init_param_len: length of init param arg + * @is_session_handle_ptr: either send kdi a valid ptr to hold the + * session handle or NULL + * @data: buffer to hold the cmd arguments + */ +struct session_create_cmd { + __u32 app_id_len; + __u32 acp_pkg_len; + __u32 init_param_len; + __u8 is_session_handle_ptr; + unsigned char data[0]; +} __packed; + +/** + * struct session_create_resp - create session response + * + * @session_handle: the session handle + * @test_mod_status: status returned from the test module + * @status: status returned from kdi + */ +struct session_create_resp { + __u64 session_handle; + __s32 test_mod_status; + __s32 status; +} __packed; + +/** + * struct session_close_cmd - close session cmd + * + * @session_handle: the session handle to close + */ +struct session_close_cmd { + __u64 session_handle; +} __packed; + +/** + * struct session_close_resp - close session response + * + * @test_mod_status: status returned from the test module + * @status: status returned from kdi + */ +struct session_close_resp { + __s32 test_mod_status; + __s32 status; +} __packed; + +/** + * struct send_and_rcv_cmd - send and receive cmd + * + * @session_handle: the session handle + * @command_id: the cmd id to send the applet + * @output_buf_len: the size of the output buffer + * @is_output_buf: either send kdi a valid ptr to hold the output buffer or NULL + * @is_output_len_ptr: either send kdi a valid ptr to hold + * the output len or NULL + * @is_response_code_ptr: either send kdi a valid ptr to hold + * the applet response code or NULL + * @input: the input data to send the applet + */ +struct send_and_rcv_cmd { + __u64 session_handle; + __u32 command_id; + __u32 output_buf_len; + __u8 is_output_buf; + __u8 is_output_len_ptr; + __u8 is_response_code_ptr; + unsigned char input[0]; +} __packed; + +/** + * struct send_and_rcv_resp - send and receive response + * + * @test_mod_status: status returned from the test module + * @status: status returned from kdi + * @response_code: response code returned from the applet + * @output_len: length of output from the applet + * @output: the output got from the applet + */ +struct send_and_rcv_resp { + __s32 test_mod_status; + __s32 status; + __s32 response_code; + __u32 output_len; + unsigned char output[0]; +} __packed; + +/** + * struct version_get_info_cmd - get version cmd + * + * @is_version_ptr: either send kdi a valid ptr to hold the version info or NULL + */ +struct version_get_info_cmd { + __u8 is_version_ptr; +} __packed; + +/** + * struct version_get_info_resp - get version response + * + * @kdi_version: kdi version + * @reserved: reserved bytes + * @test_mod_status: status returned from the test module + * @status: status returned from kdi + */ +struct version_get_info_resp { + char kdi_version[32]; + __u32 reserved[4]; + __s32 test_mod_status; + __s32 status; +} __packed; + +/** + * struct ta_access_set_remove_cmd - set/remove access cmd + * + * @app_id_len: length of app_id arg + * @data: the cmd data. contains the app_id + */ +struct ta_access_set_remove_cmd { + __u32 app_id_len; + unsigned char data[0]; +} __packed; + +/** + * struct ta_access_set_remove_resp - set/remove access response + * + * @test_mod_status: status returned from the test module + * @status: status returned from kdi + */ +struct ta_access_set_remove_resp { + __s32 test_mod_status; + __s32 status; +} __packed; + +#endif /* KDI_CMD_DEFS_H */ -- https://clearlinux.org