@@ -24,6 +24,7 @@
#include <dspbridge/devdefs.h>
#include <dspbridge/drvdefs.h>
+#include <linux/idr.h>
#define DRV_ASSIGN 1
#define DRV_RELEASE 0
@@ -81,7 +82,7 @@ struct node_res_object {
s32 node_allocated; /* Node status */
s32 heap_allocated; /* Heap status */
s32 streams_allocated; /* Streams status */
- struct node_res_object *next;
+ int id;
};
/* used to cache dma mapping information */
@@ -158,8 +159,7 @@ struct process_context {
void *hprocessor;
/* DSP Node resources */
- struct node_res_object *node_list;
- struct mutex node_mutex;
+ struct idr *node_id;
/* DMM mapped memory resources */
struct list_head dmm_map_list;
@@ -36,7 +36,7 @@
* pargs: Optional arguments to be passed to the node.
* attr_in: Optional pointer to node attributes (priority,
* timeout...)
- * ph_node: Location to store node handle on output.
+ * noderes: Location to store node resource info.
* Returns:
* 0: Success.
* -ENOMEM: Insufficient memory on GPP.
@@ -50,17 +50,17 @@
* node_init(void) called.
* hprocessor != NULL.
* node_uuid != NULL.
- * ph_node != NULL.
+ * noderes != NULL.
* Ensures:
* 0: IsValidNode(*ph_node).
- * error: *ph_node == NULL.
+ * error: *noderes == NULL.
*/
extern int node_allocate(struct proc_object *hprocessor,
const struct dsp_uuid *node_uuid,
const struct dsp_cbdata
*pargs, const struct dsp_nodeattrin
*attr_in,
- struct node_object **ph_node,
+ struct node_res_object **noderes,
struct process_context *pr_ctxt);
/*
@@ -242,7 +242,9 @@ extern int node_create_mgr(struct node_mgr **node_man,
* delete function. Loads the node's delete function if necessary.
* GPP side resources are freed after node's delete function returns.
* Parameters:
- * hnode: Node handle returned from node_allocate().
+ * noderes: Node resource info handle returned from
+ * node_allocate().
+ * pr_ctxt: Poninter to process context data.
* Returns:
* 0: Success.
* -EFAULT: Invalid hnode.
@@ -254,7 +256,7 @@ extern int node_create_mgr(struct node_mgr **node_man,
* Ensures:
* 0: hnode is invalid.
*/
-extern int node_delete(struct node_object *hnode,
+extern int node_delete(struct node_res_object *noderes,
struct process_context *pr_ctxt);
/*
@@ -34,17 +34,11 @@ extern int drv_remove_all_resources(void *process_ctxt);
extern int drv_remove_proc_context(struct drv_object *driver_obj,
void *pr_ctxt);
-extern int drv_get_node_res_element(void *hnode, void *node_resource,
- void *process_ctx);
-
extern int drv_insert_node_res_element(void *hnode, void *node_resource,
void *process_ctxt);
extern void drv_proc_node_update_heap_status(void *node_resource, s32 status);
-extern int drv_remove_node_res_element(void *node_resource,
- void *process_ctxt);
-
extern void drv_proc_node_update_status(void *node_resource, s32 status);
extern int drv_proc_update_strm_res(u32 num_bufs, void *strm_resources);
@@ -1052,6 +1052,20 @@ u32 procwrap_stop(union trapped_args *args, void *pr_ctxt)
}
/*
+ * ======== find_handle =========
+ */
+inline void find_node_handle(struct node_res_object **noderes,
+ void *pr_ctxt, void *hnode)
+{
+ rcu_read_lock();
+ *noderes = idr_find(((struct process_context *)pr_ctxt)->node_id,
+ (int)hnode);
+ rcu_read_unlock();
+ return;
+}
+
+
+/*
* ======== nodewrap_allocate ========
*/
u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
@@ -1062,7 +1076,7 @@ u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
u32 __user *psize = (u32 __user *) args->args_node_allocate.pargs;
u8 *pargs = NULL;
struct dsp_nodeattrin proc_attr_in, *attr_in = NULL;
- struct node_object *hnode;
+ struct node_res_object *node_res;
/* Optional argument */
if (psize) {
@@ -1095,13 +1109,14 @@ u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
if (!status) {
status = node_allocate(args->args_node_allocate.hprocessor,
&node_uuid, (struct dsp_cbdata *)pargs,
- attr_in, &hnode, pr_ctxt);
+ attr_in, &node_res, pr_ctxt);
}
if (!status) {
- CP_TO_USR(args->args_node_allocate.ph_node, &hnode, status, 1);
+ CP_TO_USR(args->args_node_allocate.ph_node, &node_res->id,
+ status, 1);
if (status) {
status = -EFAULT;
- node_delete(hnode, pr_ctxt);
+ node_delete(node_res, pr_ctxt);
}
}
func_cont:
@@ -1119,6 +1134,13 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
struct dsp_bufferattr *pattr = NULL;
struct dsp_bufferattr attr;
u8 *pbuffer = NULL;
+ struct node_res_object *node_res;
+
+ find_node_handle(&node_res, pr_ctxt,
+ args->args_node_allocmsgbuf.hnode);
+
+ if (!node_res)
+ return -EFAULT;
if (!args->args_node_allocmsgbuf.usize)
return -EINVAL;
@@ -1132,7 +1154,7 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
/* argument */
CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.pbuffer, status, 1);
if (!status) {
- status = node_alloc_msg_buf(args->args_node_allocmsgbuf.hnode,
+ status = node_alloc_msg_buf(node_res->hnode,
args->args_node_allocmsgbuf.usize,
pattr, &pbuffer);
}
@@ -1146,8 +1168,15 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt)
{
u32 ret;
+ struct node_res_object *node_res;
- ret = node_change_priority(args->args_node_changepriority.hnode,
+ find_node_handle(&node_res, pr_ctxt,
+ args->args_node_changepriority.hnode);
+
+ if (!node_res)
+ return -EFAULT;
+
+ ret = node_change_priority(node_res->hnode,
args->args_node_changepriority.prio);
return ret;
@@ -1164,6 +1193,29 @@ u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt)
u32 cb_data_size;
u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param;
u8 *pargs = NULL;
+ struct node_res_object *node_res1, *node_res2;
+ struct node_object *node1 = NULL, *node2 = NULL;
+
+ if ((int)args->args_node_connect.hnode != DSP_HGPPNODE) {
+ find_node_handle(&node_res1, pr_ctxt,
+ args->args_node_connect.hnode);
+ if (node_res1)
+ node1 = node_res1->hnode;
+ } else {
+ node1 = args->args_node_connect.hnode;
+ }
+
+ if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) {
+ find_node_handle(&node_res2, pr_ctxt,
+ args->args_node_connect.other_node);
+ if (node_res2)
+ node2 = node_res2->hnode;
+ } else {
+ node2 = args->args_node_connect.other_node;
+ }
+
+ if (!node1 || !node2)
+ return -EFAULT;
/* Optional argument */
if (psize) {
@@ -1191,9 +1243,9 @@ u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt)
}
if (!status) {
- status = node_connect(args->args_node_connect.hnode,
+ status = node_connect(node1,
args->args_node_connect.stream_id,
- args->args_node_connect.other_node,
+ node2,
args->args_node_connect.other_stream,
pattrs, (struct dsp_cbdata *)pargs);
}
@@ -1209,8 +1261,14 @@ func_cont:
u32 nodewrap_create(union trapped_args *args, void *pr_ctxt)
{
u32 ret;
+ struct node_res_object *node_res;
+
+ find_node_handle(&node_res, pr_ctxt, args->args_node_create.hnode);
- ret = node_create(args->args_node_create.hnode);
+ if (!node_res)
+ return -EFAULT;
+
+ ret = node_create(node_res->hnode);
return ret;
}
@@ -1221,8 +1279,14 @@ u32 nodewrap_create(union trapped_args *args, void *pr_ctxt)
u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt)
{
u32 ret;
+ struct node_res_object *node_res;
+
+ find_node_handle(&node_res, pr_ctxt, args->args_node_delete.hnode);
+
+ if (!node_res)
+ return -EFAULT;
- ret = node_delete(args->args_node_delete.hnode, pr_ctxt);
+ ret = node_delete(node_res, pr_ctxt);
return ret;
}
@@ -1235,6 +1299,13 @@ u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt)
int status = 0;
struct dsp_bufferattr *pattr = NULL;
struct dsp_bufferattr attr;
+ struct node_res_object *node_res;
+
+ find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.hnode);
+
+ if (!node_res)
+ return -EFAULT;
+
if (args->args_node_freemsgbuf.pattr) { /* Optional argument */
CP_FM_USR(&attr, args->args_node_freemsgbuf.pattr, status, 1);
if (!status)
@@ -1246,7 +1317,7 @@ u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt)
return -EFAULT;
if (!status) {
- status = node_free_msg_buf(args->args_node_freemsgbuf.hnode,
+ status = node_free_msg_buf(node_res->hnode,
args->args_node_freemsgbuf.pbuffer,
pattr);
}
@@ -1261,8 +1332,14 @@ u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt)
{
int status = 0;
struct dsp_nodeattr attr;
+ struct node_res_object *node_res;
- status = node_get_attr(args->args_node_getattr.hnode, &attr,
+ find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.hnode);
+
+ if (!node_res)
+ return -EFAULT;
+
+ status = node_get_attr(node_res->hnode, &attr,
args->args_node_getattr.attr_size);
CP_TO_USR(args->args_node_getattr.pattr, &attr, status, 1);
@@ -1276,8 +1353,14 @@ u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt)
{
int status;
struct dsp_msg msg;
+ struct node_res_object *node_res;
+
+ find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.hnode);
- status = node_get_message(args->args_node_getmessage.hnode, &msg,
+ if (!node_res)
+ return -EFAULT;
+
+ status = node_get_message(node_res->hnode, &msg,
args->args_node_getmessage.utimeout);
CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1);
@@ -1291,8 +1374,14 @@ u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt)
u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt)
{
u32 ret;
+ struct node_res_object *node_res;
+
+ find_node_handle(&node_res, pr_ctxt, args->args_node_pause.hnode);
+
+ if (!node_res)
+ return -EFAULT;
- ret = node_pause(args->args_node_pause.hnode);
+ ret = node_pause(node_res->hnode);
return ret;
}
@@ -1304,12 +1393,18 @@ u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt)
{
int status = 0;
struct dsp_msg msg;
+ struct node_res_object *node_res;
+
+ find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.hnode);
+
+ if (!node_res)
+ return -EFAULT;
CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1);
if (!status) {
status =
- node_put_message(args->args_node_putmessage.hnode, &msg,
+ node_put_message(node_res->hnode, &msg,
args->args_node_putmessage.utimeout);
}
@@ -1323,6 +1418,13 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
{
int status = 0;
struct dsp_notification notification;
+ struct node_res_object *node_res;
+
+ find_node_handle(&node_res, pr_ctxt,
+ args->args_node_registernotify.hnode);
+
+ if (!node_res)
+ return -EFAULT;
/* Initialize the notification data structure */
notification.ps_name = NULL;
@@ -1333,7 +1435,7 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
args->args_proc_register_notify.hnotification,
status, 1);
- status = node_register_notify(args->args_node_registernotify.hnode,
+ status = node_register_notify(node_res->hnode,
args->args_node_registernotify.event_mask,
args->args_node_registernotify.
notify_type, ¬ification);
@@ -1348,8 +1450,14 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
u32 nodewrap_run(union trapped_args *args, void *pr_ctxt)
{
u32 ret;
+ struct node_res_object *node_res;
+
+ find_node_handle(&node_res, pr_ctxt, args->args_node_run.hnode);
+
+ if (!node_res)
+ return -EFAULT;
- ret = node_run(args->args_node_run.hnode);
+ ret = node_run(node_res->hnode);
return ret;
}
@@ -1361,8 +1469,14 @@ u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt)
{
int status;
int tempstatus;
+ struct node_res_object *node_res;
- status = node_terminate(args->args_node_terminate.hnode, &tempstatus);
+ find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.hnode);
+
+ if (!node_res)
+ return -EFAULT;
+
+ status = node_terminate(node_res->hnode, &tempstatus);
CP_TO_USR(args->args_node_terminate.pstatus, &tempstatus, status, 1);
@@ -1548,6 +1662,12 @@ u32 strmwrap_open(union trapped_args *args, void *pr_ctxt)
struct strm_attr attr;
struct strm_object *strm_obj;
struct dsp_streamattrin strm_attr_in;
+ struct node_res_object *node_res;
+
+ find_node_handle(&node_res, pr_ctxt, args->args_strm_open.hnode);
+
+ if (!node_res)
+ return -EFAULT;
CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1);
@@ -1560,7 +1680,7 @@ u32 strmwrap_open(union trapped_args *args, void *pr_ctxt)
}
}
- status = strm_open(args->args_strm_open.hnode,
+ status = strm_open(node_res->hnode,
args->args_strm_open.direction,
args->args_strm_open.index, &attr, &strm_obj,
pr_ctxt);
@@ -73,7 +73,7 @@ static int request_bridge_resources(struct cfg_hostres *res);
/* GPP PROCESS CLEANUP CODE */
-static int drv_proc_free_node_res(void *process_ctxt);
+static int drv_proc_free_node_res(int id, void *p, void *data);
/* Allocate and add a node resource element
* This function is called from .Node_Allocate. */
@@ -84,88 +84,61 @@ int drv_insert_node_res_element(void *hnode, void *node_resource,
(struct node_res_object **)node_resource;
struct process_context *ctxt = (struct process_context *)process_ctxt;
int status = 0;
- struct node_res_object *temp_node_res = NULL;
+ int retval;
*node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL);
- if (*node_res_obj == NULL)
- status = -EFAULT;
+ if (!*node_res_obj) {
+ status = -ENOMEM;
+ goto func_end;
+ }
- if (!status) {
- if (mutex_lock_interruptible(&ctxt->node_mutex)) {
- kfree(*node_res_obj);
- return -EPERM;
+ (*node_res_obj)->hnode = hnode;
+ retval = idr_get_new(ctxt->node_id, *node_res_obj,
+ &(*node_res_obj)->id);
+ if (retval == -EAGAIN) {
+ if (!idr_pre_get(ctxt->node_id, GFP_KERNEL)) {
+ pr_err("%s: OUT OF MEMORY\n", __func__);
+ status = -ENOMEM;
+ goto func_end;
}
- (*node_res_obj)->hnode = hnode;
- if (ctxt->node_list != NULL) {
- temp_node_res = ctxt->node_list;
- while (temp_node_res->next != NULL)
- temp_node_res = temp_node_res->next;
- temp_node_res->next = *node_res_obj;
- } else {
- ctxt->node_list = *node_res_obj;
- }
- mutex_unlock(&ctxt->node_mutex);
+ retval = idr_get_new(ctxt->node_id, *node_res_obj,
+ &(*node_res_obj)->id);
+ }
+ if (retval) {
+ pr_err("%s: FAILED, IDR is FULL\n", __func__);
+ status = -EFAULT;
}
+func_end:
+ if (status)
+ kfree(*node_res_obj);
return status;
}
/* Release all Node resources and its context
-* This is called from .Node_Delete. */
-int drv_remove_node_res_element(void *node_resource, void *process_ctxt)
+ * Actual Node De-Allocation */
+static int drv_proc_free_node_res(int id, void *p, void *data)
{
- struct node_res_object *node_res_obj =
- (struct node_res_object *)node_resource;
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- struct node_res_object *temp_node;
- int status = 0;
-
- if (mutex_lock_interruptible(&ctxt->node_mutex))
- return -EPERM;
- temp_node = ctxt->node_list;
- if (temp_node == node_res_obj) {
- ctxt->node_list = node_res_obj->next;
- } else {
- while (temp_node && temp_node->next != node_res_obj)
- temp_node = temp_node->next;
- if (!temp_node)
- status = -ENOENT;
- else
- temp_node->next = node_res_obj->next;
- }
- mutex_unlock(&ctxt->node_mutex);
- kfree(node_res_obj);
- return status;
-}
-
-/* Actual Node De-Allocation */
-static int drv_proc_free_node_res(void *process_ctxt)
-{
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- int status = 0;
- struct node_res_object *node_list = NULL;
- struct node_res_object *node_res_obj = NULL;
+ struct process_context *ctxt = data;
+ int status;
+ struct node_res_object *node_res_obj = p;
u32 node_state;
- node_list = ctxt->node_list;
- while (node_list != NULL) {
- node_res_obj = node_list;
- node_list = node_list->next;
- if (node_res_obj->node_allocated) {
- node_state = node_get_state(node_res_obj->hnode);
- if (node_state <= NODE_DELETING) {
- if ((node_state == NODE_RUNNING) ||
- (node_state == NODE_PAUSED) ||
- (node_state == NODE_TERMINATING))
- status = node_terminate
- (node_res_obj->hnode, &status);
-
- status = node_delete(node_res_obj->hnode, ctxt);
- }
+ if (node_res_obj->node_allocated) {
+ node_state = node_get_state(node_res_obj->hnode);
+ if (node_state <= NODE_DELETING) {
+ if ((node_state == NODE_RUNNING) ||
+ (node_state == NODE_PAUSED) ||
+ (node_state == NODE_TERMINATING))
+ node_terminate
+ (node_res_obj->hnode, &status);
+
+ node_delete(node_res_obj, ctxt);
}
}
- return status;
+
+ return 0;
}
/* Release all Mapped and Reserved DMM resources */
@@ -220,50 +193,12 @@ void drv_proc_node_update_heap_status(void *node_resource, s32 status)
*/
int drv_remove_all_node_res_elements(void *process_ctxt)
{
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- int status = 0;
- struct node_res_object *temp_node2 = NULL;
- struct node_res_object *temp_node = NULL;
-
- drv_proc_free_node_res(ctxt);
- temp_node = ctxt->node_list;
- while (temp_node != NULL) {
- temp_node2 = temp_node;
- temp_node = temp_node->next;
- kfree(temp_node2);
- }
- ctxt->node_list = NULL;
- return status;
-}
+ struct process_context *ctxt = process_ctxt;
-/* Getting the node resource element */
-int drv_get_node_res_element(void *hnode, void *node_resource,
- void *process_ctxt)
-{
- struct node_res_object **node_res =
- (struct node_res_object **)node_resource;
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- int status = 0;
- struct node_res_object *temp_node2 = NULL;
- struct node_res_object *temp_node = NULL;
-
- if (mutex_lock_interruptible(&ctxt->node_mutex))
- return -EPERM;
-
- temp_node = ctxt->node_list;
- while ((temp_node != NULL) && (temp_node->hnode != hnode)) {
- temp_node2 = temp_node;
- temp_node = temp_node->next;
- }
+ idr_for_each(ctxt->node_id, drv_proc_free_node_res, ctxt);
+ idr_destroy(ctxt->node_id);
- mutex_unlock(&ctxt->node_mutex);
-
- if (temp_node != NULL)
- *node_res = temp_node;
- else
- status = -ENOENT;
-
- return status;
+ return 0;
}
/* Allocate the STRM resource element
@@ -511,8 +511,13 @@ static int bridge_open(struct inode *ip, struct file *filp)
INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
spin_lock_init(&pr_ctxt->dmm_rsv_lock);
INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
- mutex_init(&pr_ctxt->node_mutex);
mutex_init(&pr_ctxt->strm_mutex);
+
+ pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
+ if (pr_ctxt->node_id)
+ idr_init(pr_ctxt->node_id);
+ else
+ status = -ENOMEM;
} else {
status = -ENOMEM;
}
@@ -291,11 +291,11 @@ enum node_state node_get_state(void *hnode)
* Allocate GPP resources to manage a node on the DSP.
*/
int node_allocate(struct proc_object *hprocessor,
- const struct dsp_uuid *node_uuid,
- const struct dsp_cbdata *pargs,
- const struct dsp_nodeattrin *attr_in,
- struct node_object **ph_node,
- struct process_context *pr_ctxt)
+ const struct dsp_uuid *node_uuid,
+ const struct dsp_cbdata *pargs,
+ const struct dsp_nodeattrin *attr_in,
+ struct node_res_object **noderes,
+ struct process_context *pr_ctxt)
{
struct node_mgr *hnode_mgr;
struct dev_object *hdev_obj;
@@ -327,10 +327,10 @@ int node_allocate(struct proc_object *hprocessor,
DBC_REQUIRE(refs > 0);
DBC_REQUIRE(hprocessor != NULL);
- DBC_REQUIRE(ph_node != NULL);
+ DBC_REQUIRE(noderes != NULL);
DBC_REQUIRE(node_uuid != NULL);
- *ph_node = NULL;
+ *noderes = NULL;
status = proc_get_processor_id(hprocessor, &proc_id);
@@ -653,9 +653,6 @@ func_cont:
* (for overlay and dll) */
pnode->phase_split = true;
- if (!status)
- *ph_node = pnode;
-
/* Notify all clients registered for DSP_NODESTATECHANGE. */
proc_notify_all_clients(hprocessor, DSP_NODESTATECHANGE);
} else {
@@ -666,16 +663,21 @@ func_cont:
}
if (!status) {
- drv_insert_node_res_element(*ph_node, &node_res, pr_ctxt);
+ status = drv_insert_node_res_element(pnode, &node_res, pr_ctxt);
+ if (status) {
+ delete_node(pnode, pr_ctxt);
+ goto func_end;
+ }
+
+ *noderes = (struct node_res_object *)node_res;
drv_proc_node_update_heap_status(node_res, true);
drv_proc_node_update_status(node_res, true);
}
- DBC_ENSURE((status && (*ph_node == NULL)) ||
- (!status && *ph_node));
+ DBC_ENSURE((status && *noderes == NULL) || (!status && *noderes));
func_end:
- dev_dbg(bridge, "%s: hprocessor: %p node_uuid: %p pargs: %p attr_in:"
- " %p ph_node: %p status: 0x%x\n", __func__, hprocessor,
- node_uuid, pargs, attr_in, ph_node, status);
+ dev_dbg(bridge, "%s: hprocessor: %p pNodeId: %p pargs: %p attr_in: %p "
+ "node_res: %p status: 0x%x\n", __func__, hprocessor,
+ node_uuid, pargs, attr_in, noderes, status);
return status;
}
@@ -1433,10 +1435,10 @@ int node_create_mgr(struct node_mgr **node_man,
* Loads the node's delete function if necessary. Free GPP side resources
* after node's delete function returns.
*/
-int node_delete(struct node_object *hnode,
+int node_delete(struct node_res_object *noderes,
struct process_context *pr_ctxt)
{
- struct node_object *pnode = (struct node_object *)hnode;
+ struct node_object *pnode = noderes->hnode;
struct node_mgr *hnode_mgr;
struct proc_object *hprocessor;
struct disp_object *disp_obj;
@@ -1449,32 +1451,32 @@ int node_delete(struct node_object *hnode,
u32 proc_id;
struct bridge_drv_interface *intf_fxns;
- void *node_res;
+ void *node_res = noderes;
struct dsp_processorstate proc_state;
DBC_REQUIRE(refs > 0);
- if (!hnode) {
+ if (!pnode) {
status = -EFAULT;
goto func_end;
}
/* create struct dsp_cbdata struct for PWR call */
cb_data.cb_data = PWR_TIMEOUT;
- hnode_mgr = hnode->hnode_mgr;
- hprocessor = hnode->hprocessor;
+ hnode_mgr = pnode->hnode_mgr;
+ hprocessor = pnode->hprocessor;
disp_obj = hnode_mgr->disp_obj;
- node_type = node_get_type(hnode);
+ node_type = node_get_type(pnode);
intf_fxns = hnode_mgr->intf_fxns;
/* Enter critical section */
mutex_lock(&hnode_mgr->node_mgr_lock);
- state = node_get_state(hnode);
+ state = node_get_state(pnode);
/* Execute delete phase code for non-device node in all cases
* except when the node was only allocated. Delete phase must be
* executed even if create phase was executed, but failed.
* If the node environment pointer is non-NULL, the delete phase
* code must be executed. */
- if (!(state == NODE_ALLOCATED && hnode->node_env == (u32) NULL) &&
+ if (!(state == NODE_ALLOCATED && pnode->node_env == (u32) NULL) &&
node_type != NODE_DEVICE) {
status = proc_get_processor_id(pnode->hprocessor, &proc_id);
if (status)
@@ -1487,26 +1489,26 @@ int node_delete(struct node_object *hnode,
* is now ok to unload it. If the node is running, we
* will unload the execute phase only after deleting
* the node. */
- if (state == NODE_PAUSED && hnode->loaded &&
- hnode->phase_split) {
+ if (state == NODE_PAUSED && pnode->loaded &&
+ pnode->phase_split) {
/* Ok to unload execute code as long as node
* is not * running */
status1 =
hnode_mgr->nldr_fxns.
- pfn_unload(hnode->nldr_node_obj,
+ pfn_unload(pnode->nldr_node_obj,
NLDR_EXECUTE);
- hnode->loaded = false;
- NODE_SET_STATE(hnode, NODE_DONE);
+ pnode->loaded = false;
+ NODE_SET_STATE(pnode, NODE_DONE);
}
/* Load delete phase code if not loaded or if haven't
* * unloaded EXECUTE phase */
- if ((!(hnode->loaded) || (state == NODE_RUNNING)) &&
- hnode->phase_split) {
+ if ((!(pnode->loaded) || (state == NODE_RUNNING)) &&
+ pnode->phase_split) {
status =
hnode_mgr->nldr_fxns.
- pfn_load(hnode->nldr_node_obj, NLDR_DELETE);
+ pfn_load(pnode->nldr_node_obj, NLDR_DELETE);
if (!status)
- hnode->loaded = true;
+ pnode->loaded = true;
else
pr_err("%s: fail - load delete code:"
" 0x%x\n", __func__, status);
@@ -1515,14 +1517,14 @@ int node_delete(struct node_object *hnode,
func_cont1:
if (!status) {
/* Unblock a thread trying to terminate the node */
- (void)sync_set_event(hnode->sync_done);
+ (void)sync_set_event(pnode->sync_done);
if (proc_id == DSP_UNIT) {
/* ul_delete_fxn = address of node's delete
* function */
- status = get_fxn_address(hnode, &ul_delete_fxn,
+ status = get_fxn_address(pnode, &ul_delete_fxn,
DELETEPHASE);
} else if (proc_id == IVA_UNIT)
- ul_delete_fxn = (u32) hnode->node_env;
+ ul_delete_fxn = (u32) pnode->node_env;
if (!status) {
status = proc_get_state(hprocessor,
&proc_state,
@@ -1530,22 +1532,22 @@ func_cont1:
dsp_processorstate));
if (proc_state.proc_state != PROC_ERROR) {
status =
- disp_node_delete(disp_obj, hnode,
+ disp_node_delete(disp_obj, pnode,
hnode_mgr->
ul_fxn_addrs
[RMSDELETENODE],
ul_delete_fxn,
- hnode->node_env);
+ pnode->node_env);
} else
- NODE_SET_STATE(hnode, NODE_DONE);
+ NODE_SET_STATE(pnode, NODE_DONE);
/* Unload execute, if not unloaded, and delete
* function */
if (state == NODE_RUNNING &&
- hnode->phase_split) {
+ pnode->phase_split) {
status1 =
hnode_mgr->nldr_fxns.
- pfn_unload(hnode->nldr_node_obj,
+ pfn_unload(pnode->nldr_node_obj,
NLDR_EXECUTE);
}
if (status1)
@@ -1553,10 +1555,10 @@ func_cont1:
" 0x%x\n", __func__, status1);
status1 =
- hnode_mgr->nldr_fxns.pfn_unload(hnode->
+ hnode_mgr->nldr_fxns.pfn_unload(pnode->
nldr_node_obj,
NLDR_DELETE);
- hnode->loaded = false;
+ pnode->loaded = false;
if (status1)
pr_err("%s: fail - unload delete code: "
"0x%x\n", __func__, status1);
@@ -1565,25 +1567,28 @@ func_cont1:
}
/* Free host side resources even if a failure occurred */
/* Remove node from hnode_mgr->node_list */
- lst_remove_elem(hnode_mgr->node_list, (struct list_head *)hnode);
+ lst_remove_elem(hnode_mgr->node_list, (struct list_head *)pnode);
hnode_mgr->num_nodes--;
/* Decrement count of nodes created on DSP */
if ((state != NODE_ALLOCATED) || ((state == NODE_ALLOCATED) &&
- (hnode->node_env != (u32) NULL)))
+ (pnode->node_env != (u32) NULL)))
hnode_mgr->num_created--;
/* Free host-side resources allocated by node_create()
* delete_node() fails if SM buffers not freed by client! */
- if (drv_get_node_res_element(hnode, &node_res, pr_ctxt) !=
- -ENOENT)
- drv_proc_node_update_status(node_res, false);
- delete_node(hnode, pr_ctxt);
+ drv_proc_node_update_status(node_res, false);
+ delete_node(pnode, pr_ctxt);
+
+ /*
+ * Release all Node resources and its context
+ */
+ idr_remove(pr_ctxt->node_id, ((struct node_res_object *)node_res)->id);
+ kfree(node_res);
- drv_remove_node_res_element(node_res, pr_ctxt);
/* Exit critical section */
mutex_unlock(&hnode_mgr->node_mgr_lock);
proc_notify_clients(hprocessor, DSP_NODESTATECHANGE);
func_end:
- dev_dbg(bridge, "%s: hnode: %p status 0x%x\n", __func__, hnode, status);
+ dev_dbg(bridge, "%s: pnode: %p status 0x%x\n", __func__, pnode, status);
return status;
}