Merge "qseecom: Support multiple clients." into msm-3.4
This commit is contained in:
commit
c624eef630
|
@ -609,10 +609,24 @@ static int __qseecom_check_app_exists(struct qseecom_check_app_ireq req)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp.result == QSEOS_RESULT_FAILURE)
|
if (resp.result == QSEOS_RESULT_FAILURE) {
|
||||||
return 0;
|
return 0;
|
||||||
else
|
} else {
|
||||||
return resp.data;
|
switch (resp.resp_type) {
|
||||||
|
/*qsee returned listener type response */
|
||||||
|
case QSEOS_LISTENER_ID:
|
||||||
|
pr_err("resp type is of listener type instead of app");
|
||||||
|
return -EINVAL;
|
||||||
|
break;
|
||||||
|
case QSEOS_APP_ID:
|
||||||
|
return resp.data;
|
||||||
|
default:
|
||||||
|
pr_err("invalid resp type (%d) from qsee",
|
||||||
|
resp.resp_type);
|
||||||
|
return -ENODEV;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
|
static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
|
||||||
|
@ -627,6 +641,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
struct qseecom_command_scm_resp resp;
|
struct qseecom_command_scm_resp resp;
|
||||||
struct qseecom_check_app_ireq req;
|
struct qseecom_check_app_ireq req;
|
||||||
|
struct qseecom_load_app_ireq load_req;
|
||||||
|
|
||||||
/* Copy the relevant information needed for loading the image */
|
/* Copy the relevant information needed for loading the image */
|
||||||
if (__copy_from_user(&load_img_req,
|
if (__copy_from_user(&load_img_req,
|
||||||
(void __user *)argp,
|
(void __user *)argp,
|
||||||
|
@ -642,108 +658,86 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
|
||||||
req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND;
|
req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND;
|
||||||
memcpy(req.app_name, load_img_req.img_name, MAX_APP_NAME_SIZE);
|
memcpy(req.app_name, load_img_req.img_name, MAX_APP_NAME_SIZE);
|
||||||
|
|
||||||
ret = __qseecom_check_app_exists(req);
|
pr_warn("App (%s) does not exist, loading apps for first time\n",
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
else
|
|
||||||
app_id = ret;
|
|
||||||
|
|
||||||
if (app_id) {
|
|
||||||
pr_warn("App id %d (%s) already exists\n", app_id,
|
|
||||||
(char *)(req.app_name));
|
(char *)(req.app_name));
|
||||||
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
|
/* Get the handle of the shared fd */
|
||||||
list_for_each_entry(entry,
|
ihandle = ion_import_dma_buf(qseecom.ion_clnt,
|
||||||
&qseecom.registered_app_list_head, list){
|
|
||||||
if (entry->app_id == app_id) {
|
|
||||||
entry->ref_cnt++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(
|
|
||||||
&qseecom.registered_app_list_lock, flags);
|
|
||||||
} else {
|
|
||||||
struct qseecom_load_app_ireq load_req;
|
|
||||||
|
|
||||||
pr_warn("App (%s) does not exist, loading apps for first time\n",
|
|
||||||
(char *)(req.app_name));
|
|
||||||
/* Get the handle of the shared fd */
|
|
||||||
ihandle = ion_import_dma_buf(qseecom.ion_clnt,
|
|
||||||
load_img_req.ifd_data_fd);
|
load_img_req.ifd_data_fd);
|
||||||
if (IS_ERR_OR_NULL(ihandle)) {
|
if (IS_ERR_OR_NULL(ihandle)) {
|
||||||
pr_err("Ion client could not retrieve the handle\n");
|
pr_err("Ion client could not retrieve the handle\n");
|
||||||
qsee_disable_clock_vote(CLK_SFPB);
|
qsee_disable_clock_vote(CLK_SFPB);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the physical address of the ION BUF */
|
/* Get the physical address of the ION BUF */
|
||||||
ret = ion_phys(qseecom.ion_clnt, ihandle, &pa, &len);
|
ret = ion_phys(qseecom.ion_clnt, ihandle, &pa, &len);
|
||||||
|
|
||||||
/* Populate the structure for sending scm call to load image */
|
/* Populate the structure for sending scm call to load image */
|
||||||
load_req.qsee_cmd_id = QSEOS_APP_START_COMMAND;
|
load_req.qsee_cmd_id = QSEOS_APP_START_COMMAND;
|
||||||
load_req.mdt_len = load_img_req.mdt_len;
|
load_req.mdt_len = load_img_req.mdt_len;
|
||||||
load_req.img_len = load_img_req.img_len;
|
load_req.img_len = load_img_req.img_len;
|
||||||
load_req.phy_addr = pa;
|
load_req.phy_addr = pa;
|
||||||
|
|
||||||
/* SCM_CALL to load the app and get the app_id back */
|
/* SCM_CALL to load the app and get the app_id back */
|
||||||
ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &load_req,
|
ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &load_req,
|
||||||
sizeof(struct qseecom_load_app_ireq),
|
sizeof(struct qseecom_load_app_ireq),
|
||||||
&resp, sizeof(resp));
|
&resp, sizeof(resp));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("scm_call to load app failed\n");
|
pr_err("scm_call to load app failed\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp.result == QSEOS_RESULT_FAILURE) {
|
if (resp.result == QSEOS_RESULT_FAILURE) {
|
||||||
pr_err("scm_call rsp.result is QSEOS_RESULT_FAILURE\n");
|
pr_err("scm_call rsp.result is QSEOS_RESULT_FAILURE\n");
|
||||||
if (!IS_ERR_OR_NULL(ihandle))
|
|
||||||
ion_free(qseecom.ion_clnt, ihandle);
|
|
||||||
qsee_disable_clock_vote(CLK_SFPB);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resp.result == QSEOS_RESULT_INCOMPLETE) {
|
|
||||||
ret = __qseecom_process_incomplete_cmd(data, &resp);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("process_incomplete_cmd failed err: %d\n",
|
|
||||||
ret);
|
|
||||||
if (!IS_ERR_OR_NULL(ihandle))
|
|
||||||
ion_free(qseecom.ion_clnt, ihandle);
|
|
||||||
qsee_disable_clock_vote(CLK_SFPB);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (resp.result != QSEOS_RESULT_SUCCESS) {
|
|
||||||
pr_err("scm_call failed resp.result unknown, %d\n",
|
|
||||||
resp.result);
|
|
||||||
if (!IS_ERR_OR_NULL(ihandle))
|
|
||||||
ion_free(qseecom.ion_clnt, ihandle);
|
|
||||||
qsee_disable_clock_vote(CLK_SFPB);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
app_id = resp.data;
|
|
||||||
|
|
||||||
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
|
|
||||||
if (!entry) {
|
|
||||||
pr_err("kmalloc failed\n");
|
|
||||||
qsee_disable_clock_vote(CLK_SFPB);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
entry->app_id = app_id;
|
|
||||||
entry->ref_cnt = 1;
|
|
||||||
|
|
||||||
/* Deallocate the handle */
|
|
||||||
if (!IS_ERR_OR_NULL(ihandle))
|
if (!IS_ERR_OR_NULL(ihandle))
|
||||||
ion_free(qseecom.ion_clnt, ihandle);
|
ion_free(qseecom.ion_clnt, ihandle);
|
||||||
|
qsee_disable_clock_vote(CLK_SFPB);
|
||||||
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
|
return -EFAULT;
|
||||||
list_add_tail(&entry->list, &qseecom.registered_app_list_head);
|
|
||||||
spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
pr_warn("App with id %d (%s) now loaded\n", app_id,
|
|
||||||
(char *)(req.app_name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resp.result == QSEOS_RESULT_INCOMPLETE) {
|
||||||
|
ret = __qseecom_process_incomplete_cmd(data, &resp);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("process_incomplete_cmd failed err: %d\n",
|
||||||
|
ret);
|
||||||
|
if (!IS_ERR_OR_NULL(ihandle))
|
||||||
|
ion_free(qseecom.ion_clnt, ihandle);
|
||||||
|
qsee_disable_clock_vote(CLK_SFPB);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp.result != QSEOS_RESULT_SUCCESS) {
|
||||||
|
pr_err("scm_call failed resp.result unknown, %d\n",
|
||||||
|
resp.result);
|
||||||
|
if (!IS_ERR_OR_NULL(ihandle))
|
||||||
|
ion_free(qseecom.ion_clnt, ihandle);
|
||||||
|
qsee_disable_clock_vote(CLK_SFPB);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
app_id = resp.data;
|
||||||
|
|
||||||
|
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
|
||||||
|
if (!entry) {
|
||||||
|
pr_err("kmalloc failed\n");
|
||||||
|
qsee_disable_clock_vote(CLK_SFPB);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
entry->app_id = app_id;
|
||||||
|
entry->ref_cnt = 1;
|
||||||
|
|
||||||
|
/* Deallocate the handle */
|
||||||
|
if (!IS_ERR_OR_NULL(ihandle))
|
||||||
|
ion_free(qseecom.ion_clnt, ihandle);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
|
||||||
|
list_add_tail(&entry->list, &qseecom.registered_app_list_head);
|
||||||
|
spin_unlock_irqrestore(&qseecom.registered_app_list_lock, flags);
|
||||||
|
|
||||||
|
pr_warn("App with id %d (%s) now loaded\n", app_id,
|
||||||
|
(char *)(req.app_name));
|
||||||
|
|
||||||
data->client.app_id = app_id;
|
data->client.app_id = app_id;
|
||||||
load_img_req.app_id = app_id;
|
load_img_req.app_id = app_id;
|
||||||
if (copy_to_user(argp, &load_img_req, sizeof(load_img_req))) {
|
if (copy_to_user(argp, &load_img_req, sizeof(load_img_req))) {
|
||||||
|
@ -1432,6 +1426,8 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data,
|
||||||
int32_t ret;
|
int32_t ret;
|
||||||
struct qseecom_qseos_app_load_query query_req;
|
struct qseecom_qseos_app_load_query query_req;
|
||||||
struct qseecom_check_app_ireq req;
|
struct qseecom_check_app_ireq req;
|
||||||
|
struct qseecom_registered_app_list *entry = NULL;
|
||||||
|
unsigned long flags = 0;
|
||||||
|
|
||||||
/* Copy the relevant information needed for loading the image */
|
/* Copy the relevant information needed for loading the image */
|
||||||
if (__copy_from_user(&query_req,
|
if (__copy_from_user(&query_req,
|
||||||
|
@ -1445,11 +1441,30 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data,
|
||||||
memcpy(req.app_name, query_req.app_name, MAX_APP_NAME_SIZE);
|
memcpy(req.app_name, query_req.app_name, MAX_APP_NAME_SIZE);
|
||||||
|
|
||||||
ret = __qseecom_check_app_exists(req);
|
ret = __qseecom_check_app_exists(req);
|
||||||
if (ret == -EINVAL) {
|
|
||||||
|
if ((ret == -EINVAL) || (ret == -ENODEV)) {
|
||||||
pr_err(" scm call to check if app is loaded failed");
|
pr_err(" scm call to check if app is loaded failed");
|
||||||
return ret; /* scm call failed */
|
return ret; /* scm call failed */
|
||||||
} else if (ret > 0) {
|
} else if (ret > 0) {
|
||||||
pr_err("app is already loaded in QSEE");
|
pr_warn("App id %d (%s) already exists\n", ret,
|
||||||
|
(char *)(req.app_name));
|
||||||
|
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
|
||||||
|
list_for_each_entry(entry,
|
||||||
|
&qseecom.registered_app_list_head, list){
|
||||||
|
if (entry->app_id == ret) {
|
||||||
|
entry->ref_cnt++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spin_unlock_irqrestore(
|
||||||
|
&qseecom.registered_app_list_lock, flags);
|
||||||
|
data->client.app_id = ret;
|
||||||
|
query_req.app_id = ret;
|
||||||
|
|
||||||
|
if (copy_to_user(argp, &query_req, sizeof(query_req))) {
|
||||||
|
pr_err("copy_to_user failed\n");
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
return -EEXIST; /* app already loaded */
|
return -EEXIST; /* app already loaded */
|
||||||
} else {
|
} else {
|
||||||
return 0; /* app not loaded */
|
return 0; /* app not loaded */
|
||||||
|
|
|
@ -110,9 +110,11 @@ struct qseecom_qseos_version_req {
|
||||||
/*
|
/*
|
||||||
* struct qseecom_qseos_app_load_query - verify if app is loaded in qsee
|
* struct qseecom_qseos_app_load_query - verify if app is loaded in qsee
|
||||||
* @app_name[MAX_APP_NAME_SIZE]- name of the app.
|
* @app_name[MAX_APP_NAME_SIZE]- name of the app.
|
||||||
|
* @app_id - app id.
|
||||||
*/
|
*/
|
||||||
struct qseecom_qseos_app_load_query {
|
struct qseecom_qseos_app_load_query {
|
||||||
char app_name[MAX_APP_NAME_SIZE]; /* in */
|
char app_name[MAX_APP_NAME_SIZE]; /* in */
|
||||||
|
int app_id; /* out */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QSEECOM_IOC_MAGIC 0x97
|
#define QSEECOM_IOC_MAGIC 0x97
|
||||||
|
|
Loading…
Reference in New Issue