aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErnesto Ramos <ernesto@ti.com>2010-07-28 17:04:53 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-02 20:11:02 -0400
commit0624f52f77e11a6edfc48827a12190f874d572b8 (patch)
treef937621ed5b31f83af7ac6f23b4340c672c2a74a
parent35f338e4f2fcd2614f6fdff33f38920cf9434f86 (diff)
staging: ti dspbridge: use node id instead of kernel address
Use idr kernel library to send/receive node ids to the user instead of kernel address. This id will be use to access the node handles at the kernel side, if id does not match to any handle error -EFAULT is returned. Signed-off-by: Ernesto Ramos <ernesto@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/drv.h6
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/node.h14
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h6
-rw-r--r--drivers/staging/tidspbridge/pmgr/dspapi.c158
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv.c153
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv_interface.c7
-rw-r--r--drivers/staging/tidspbridge/rmgr/node.c109
7 files changed, 257 insertions, 196 deletions
diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h
index 28541f7f07ef..0b36a11820b5 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/drv.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h
@@ -24,6 +24,7 @@
24#include <dspbridge/devdefs.h> 24#include <dspbridge/devdefs.h>
25 25
26#include <dspbridge/drvdefs.h> 26#include <dspbridge/drvdefs.h>
27#include <linux/idr.h>
27 28
28#define DRV_ASSIGN 1 29#define DRV_ASSIGN 1
29#define DRV_RELEASE 0 30#define DRV_RELEASE 0
@@ -81,7 +82,7 @@ struct node_res_object {
81 s32 node_allocated; /* Node status */ 82 s32 node_allocated; /* Node status */
82 s32 heap_allocated; /* Heap status */ 83 s32 heap_allocated; /* Heap status */
83 s32 streams_allocated; /* Streams status */ 84 s32 streams_allocated; /* Streams status */
84 struct node_res_object *next; 85 int id;
85}; 86};
86 87
87/* used to cache dma mapping information */ 88/* used to cache dma mapping information */
@@ -158,8 +159,7 @@ struct process_context {
158 void *hprocessor; 159 void *hprocessor;
159 160
160 /* DSP Node resources */ 161 /* DSP Node resources */
161 struct node_res_object *node_list; 162 struct idr *node_id;
162 struct mutex node_mutex;
163 163
164 /* DMM mapped memory resources */ 164 /* DMM mapped memory resources */
165 struct list_head dmm_map_list; 165 struct list_head dmm_map_list;
diff --git a/drivers/staging/tidspbridge/include/dspbridge/node.h b/drivers/staging/tidspbridge/include/dspbridge/node.h
index 61d2d9b7cc9d..49ed5c1128e5 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/node.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/node.h
@@ -36,7 +36,7 @@
36 * pargs: Optional arguments to be passed to the node. 36 * pargs: Optional arguments to be passed to the node.
37 * attr_in: Optional pointer to node attributes (priority, 37 * attr_in: Optional pointer to node attributes (priority,
38 * timeout...) 38 * timeout...)
39 * ph_node: Location to store node handle on output. 39 * noderes: Location to store node resource info.
40 * Returns: 40 * Returns:
41 * 0: Success. 41 * 0: Success.
42 * -ENOMEM: Insufficient memory on GPP. 42 * -ENOMEM: Insufficient memory on GPP.
@@ -50,17 +50,17 @@
50 * node_init(void) called. 50 * node_init(void) called.
51 * hprocessor != NULL. 51 * hprocessor != NULL.
52 * node_uuid != NULL. 52 * node_uuid != NULL.
53 * ph_node != NULL. 53 * noderes != NULL.
54 * Ensures: 54 * Ensures:
55 * 0: IsValidNode(*ph_node). 55 * 0: IsValidNode(*ph_node).
56 * error: *ph_node == NULL. 56 * error: *noderes == NULL.
57 */ 57 */
58extern int node_allocate(struct proc_object *hprocessor, 58extern int node_allocate(struct proc_object *hprocessor,
59 const struct dsp_uuid *node_uuid, 59 const struct dsp_uuid *node_uuid,
60 const struct dsp_cbdata 60 const struct dsp_cbdata
61 *pargs, const struct dsp_nodeattrin 61 *pargs, const struct dsp_nodeattrin
62 *attr_in, 62 *attr_in,
63 struct node_object **ph_node, 63 struct node_res_object **noderes,
64 struct process_context *pr_ctxt); 64 struct process_context *pr_ctxt);
65 65
66/* 66/*
@@ -242,7 +242,9 @@ extern int node_create_mgr(struct node_mgr **node_man,
242 * delete function. Loads the node's delete function if necessary. 242 * delete function. Loads the node's delete function if necessary.
243 * GPP side resources are freed after node's delete function returns. 243 * GPP side resources are freed after node's delete function returns.
244 * Parameters: 244 * Parameters:
245 * hnode: Node handle returned from node_allocate(). 245 * noderes: Node resource info handle returned from
246 * node_allocate().
247 * pr_ctxt: Poninter to process context data.
246 * Returns: 248 * Returns:
247 * 0: Success. 249 * 0: Success.
248 * -EFAULT: Invalid hnode. 250 * -EFAULT: Invalid hnode.
@@ -254,7 +256,7 @@ extern int node_create_mgr(struct node_mgr **node_man,
254 * Ensures: 256 * Ensures:
255 * 0: hnode is invalid. 257 * 0: hnode is invalid.
256 */ 258 */
257extern int node_delete(struct node_object *hnode, 259extern int node_delete(struct node_res_object *noderes,
258 struct process_context *pr_ctxt); 260 struct process_context *pr_ctxt);
259 261
260/* 262/*
diff --git a/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h b/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h
index 4e1b8a29825a..d17c7fb69d92 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h
@@ -34,17 +34,11 @@ extern int drv_remove_all_resources(void *process_ctxt);
34extern int drv_remove_proc_context(struct drv_object *driver_obj, 34extern int drv_remove_proc_context(struct drv_object *driver_obj,
35 void *pr_ctxt); 35 void *pr_ctxt);
36 36
37extern int drv_get_node_res_element(void *hnode, void *node_resource,
38 void *process_ctx);
39
40extern int drv_insert_node_res_element(void *hnode, void *node_resource, 37extern int drv_insert_node_res_element(void *hnode, void *node_resource,
41 void *process_ctxt); 38 void *process_ctxt);
42 39
43extern void drv_proc_node_update_heap_status(void *node_resource, s32 status); 40extern void drv_proc_node_update_heap_status(void *node_resource, s32 status);
44 41
45extern int drv_remove_node_res_element(void *node_resource,
46 void *process_ctxt);
47
48extern void drv_proc_node_update_status(void *node_resource, s32 status); 42extern void drv_proc_node_update_status(void *node_resource, s32 status);
49 43
50extern int drv_proc_update_strm_res(u32 num_bufs, void *strm_resources); 44extern int drv_proc_update_strm_res(u32 num_bufs, void *strm_resources);
diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c
index da08dfc64593..6eda7c5324a8 100644
--- a/drivers/staging/tidspbridge/pmgr/dspapi.c
+++ b/drivers/staging/tidspbridge/pmgr/dspapi.c
@@ -1052,6 +1052,20 @@ u32 procwrap_stop(union trapped_args *args, void *pr_ctxt)
1052} 1052}
1053 1053
1054/* 1054/*
1055 * ======== find_handle =========
1056 */
1057inline void find_node_handle(struct node_res_object **noderes,
1058 void *pr_ctxt, void *hnode)
1059{
1060 rcu_read_lock();
1061 *noderes = idr_find(((struct process_context *)pr_ctxt)->node_id,
1062 (int)hnode);
1063 rcu_read_unlock();
1064 return;
1065}
1066
1067
1068/*
1055 * ======== nodewrap_allocate ======== 1069 * ======== nodewrap_allocate ========
1056 */ 1070 */
1057u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt) 1071u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
@@ -1062,7 +1076,7 @@ u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
1062 u32 __user *psize = (u32 __user *) args->args_node_allocate.pargs; 1076 u32 __user *psize = (u32 __user *) args->args_node_allocate.pargs;
1063 u8 *pargs = NULL; 1077 u8 *pargs = NULL;
1064 struct dsp_nodeattrin proc_attr_in, *attr_in = NULL; 1078 struct dsp_nodeattrin proc_attr_in, *attr_in = NULL;
1065 struct node_object *hnode; 1079 struct node_res_object *node_res;
1066 1080
1067 /* Optional argument */ 1081 /* Optional argument */
1068 if (psize) { 1082 if (psize) {
@@ -1095,13 +1109,14 @@ u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
1095 if (!status) { 1109 if (!status) {
1096 status = node_allocate(args->args_node_allocate.hprocessor, 1110 status = node_allocate(args->args_node_allocate.hprocessor,
1097 &node_uuid, (struct dsp_cbdata *)pargs, 1111 &node_uuid, (struct dsp_cbdata *)pargs,
1098 attr_in, &hnode, pr_ctxt); 1112 attr_in, &node_res, pr_ctxt);
1099 } 1113 }
1100 if (!status) { 1114 if (!status) {
1101 CP_TO_USR(args->args_node_allocate.ph_node, &hnode, status, 1); 1115 CP_TO_USR(args->args_node_allocate.ph_node, &node_res->id,
1116 status, 1);
1102 if (status) { 1117 if (status) {
1103 status = -EFAULT; 1118 status = -EFAULT;
1104 node_delete(hnode, pr_ctxt); 1119 node_delete(node_res, pr_ctxt);
1105 } 1120 }
1106 } 1121 }
1107func_cont: 1122func_cont:
@@ -1119,6 +1134,13 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
1119 struct dsp_bufferattr *pattr = NULL; 1134 struct dsp_bufferattr *pattr = NULL;
1120 struct dsp_bufferattr attr; 1135 struct dsp_bufferattr attr;
1121 u8 *pbuffer = NULL; 1136 u8 *pbuffer = NULL;
1137 struct node_res_object *node_res;
1138
1139 find_node_handle(&node_res, pr_ctxt,
1140 args->args_node_allocmsgbuf.hnode);
1141
1142 if (!node_res)
1143 return -EFAULT;
1122 1144
1123 if (!args->args_node_allocmsgbuf.usize) 1145 if (!args->args_node_allocmsgbuf.usize)
1124 return -EINVAL; 1146 return -EINVAL;
@@ -1132,7 +1154,7 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
1132 /* argument */ 1154 /* argument */
1133 CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.pbuffer, status, 1); 1155 CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.pbuffer, status, 1);
1134 if (!status) { 1156 if (!status) {
1135 status = node_alloc_msg_buf(args->args_node_allocmsgbuf.hnode, 1157 status = node_alloc_msg_buf(node_res->hnode,
1136 args->args_node_allocmsgbuf.usize, 1158 args->args_node_allocmsgbuf.usize,
1137 pattr, &pbuffer); 1159 pattr, &pbuffer);
1138 } 1160 }
@@ -1146,8 +1168,15 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
1146u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt) 1168u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt)
1147{ 1169{
1148 u32 ret; 1170 u32 ret;
1171 struct node_res_object *node_res;
1149 1172
1150 ret = node_change_priority(args->args_node_changepriority.hnode, 1173 find_node_handle(&node_res, pr_ctxt,
1174 args->args_node_changepriority.hnode);
1175
1176 if (!node_res)
1177 return -EFAULT;
1178
1179 ret = node_change_priority(node_res->hnode,
1151 args->args_node_changepriority.prio); 1180 args->args_node_changepriority.prio);
1152 1181
1153 return ret; 1182 return ret;
@@ -1164,6 +1193,29 @@ u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt)
1164 u32 cb_data_size; 1193 u32 cb_data_size;
1165 u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param; 1194 u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param;
1166 u8 *pargs = NULL; 1195 u8 *pargs = NULL;
1196 struct node_res_object *node_res1, *node_res2;
1197 struct node_object *node1 = NULL, *node2 = NULL;
1198
1199 if ((int)args->args_node_connect.hnode != DSP_HGPPNODE) {
1200 find_node_handle(&node_res1, pr_ctxt,
1201 args->args_node_connect.hnode);
1202 if (node_res1)
1203 node1 = node_res1->hnode;
1204 } else {
1205 node1 = args->args_node_connect.hnode;
1206 }
1207
1208 if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) {
1209 find_node_handle(&node_res2, pr_ctxt,
1210 args->args_node_connect.other_node);
1211 if (node_res2)
1212 node2 = node_res2->hnode;
1213 } else {
1214 node2 = args->args_node_connect.other_node;
1215 }
1216
1217 if (!node1 || !node2)
1218 return -EFAULT;
1167 1219
1168 /* Optional argument */ 1220 /* Optional argument */
1169 if (psize) { 1221 if (psize) {
@@ -1191,9 +1243,9 @@ u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt)
1191 1243
1192 } 1244 }
1193 if (!status) { 1245 if (!status) {
1194 status = node_connect(args->args_node_connect.hnode, 1246 status = node_connect(node1,
1195 args->args_node_connect.stream_id, 1247 args->args_node_connect.stream_id,
1196 args->args_node_connect.other_node, 1248 node2,
1197 args->args_node_connect.other_stream, 1249 args->args_node_connect.other_stream,
1198 pattrs, (struct dsp_cbdata *)pargs); 1250 pattrs, (struct dsp_cbdata *)pargs);
1199 } 1251 }
@@ -1209,8 +1261,14 @@ func_cont:
1209u32 nodewrap_create(union trapped_args *args, void *pr_ctxt) 1261u32 nodewrap_create(union trapped_args *args, void *pr_ctxt)
1210{ 1262{
1211 u32 ret; 1263 u32 ret;
1264 struct node_res_object *node_res;
1265
1266 find_node_handle(&node_res, pr_ctxt, args->args_node_create.hnode);
1212 1267
1213 ret = node_create(args->args_node_create.hnode); 1268 if (!node_res)
1269 return -EFAULT;
1270
1271 ret = node_create(node_res->hnode);
1214 1272
1215 return ret; 1273 return ret;
1216} 1274}
@@ -1221,8 +1279,14 @@ u32 nodewrap_create(union trapped_args *args, void *pr_ctxt)
1221u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt) 1279u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt)
1222{ 1280{
1223 u32 ret; 1281 u32 ret;
1282 struct node_res_object *node_res;
1283
1284 find_node_handle(&node_res, pr_ctxt, args->args_node_delete.hnode);
1285
1286 if (!node_res)
1287 return -EFAULT;
1224 1288
1225 ret = node_delete(args->args_node_delete.hnode, pr_ctxt); 1289 ret = node_delete(node_res, pr_ctxt);
1226 1290
1227 return ret; 1291 return ret;
1228} 1292}
@@ -1235,6 +1299,13 @@ u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt)
1235 int status = 0; 1299 int status = 0;
1236 struct dsp_bufferattr *pattr = NULL; 1300 struct dsp_bufferattr *pattr = NULL;
1237 struct dsp_bufferattr attr; 1301 struct dsp_bufferattr attr;
1302 struct node_res_object *node_res;
1303
1304 find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.hnode);
1305
1306 if (!node_res)
1307 return -EFAULT;
1308
1238 if (args->args_node_freemsgbuf.pattr) { /* Optional argument */ 1309 if (args->args_node_freemsgbuf.pattr) { /* Optional argument */
1239 CP_FM_USR(&attr, args->args_node_freemsgbuf.pattr, status, 1); 1310 CP_FM_USR(&attr, args->args_node_freemsgbuf.pattr, status, 1);
1240 if (!status) 1311 if (!status)
@@ -1246,7 +1317,7 @@ u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt)
1246 return -EFAULT; 1317 return -EFAULT;
1247 1318
1248 if (!status) { 1319 if (!status) {
1249 status = node_free_msg_buf(args->args_node_freemsgbuf.hnode, 1320 status = node_free_msg_buf(node_res->hnode,
1250 args->args_node_freemsgbuf.pbuffer, 1321 args->args_node_freemsgbuf.pbuffer,
1251 pattr); 1322 pattr);
1252 } 1323 }
@@ -1261,8 +1332,14 @@ u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt)
1261{ 1332{
1262 int status = 0; 1333 int status = 0;
1263 struct dsp_nodeattr attr; 1334 struct dsp_nodeattr attr;
1335 struct node_res_object *node_res;
1264 1336
1265 status = node_get_attr(args->args_node_getattr.hnode, &attr, 1337 find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.hnode);
1338
1339 if (!node_res)
1340 return -EFAULT;
1341
1342 status = node_get_attr(node_res->hnode, &attr,
1266 args->args_node_getattr.attr_size); 1343 args->args_node_getattr.attr_size);
1267 CP_TO_USR(args->args_node_getattr.pattr, &attr, status, 1); 1344 CP_TO_USR(args->args_node_getattr.pattr, &attr, status, 1);
1268 1345
@@ -1276,8 +1353,14 @@ u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt)
1276{ 1353{
1277 int status; 1354 int status;
1278 struct dsp_msg msg; 1355 struct dsp_msg msg;
1356 struct node_res_object *node_res;
1357
1358 find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.hnode);
1279 1359
1280 status = node_get_message(args->args_node_getmessage.hnode, &msg, 1360 if (!node_res)
1361 return -EFAULT;
1362
1363 status = node_get_message(node_res->hnode, &msg,
1281 args->args_node_getmessage.utimeout); 1364 args->args_node_getmessage.utimeout);
1282 1365
1283 CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1); 1366 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)
1291u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt) 1374u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt)
1292{ 1375{
1293 u32 ret; 1376 u32 ret;
1377 struct node_res_object *node_res;
1378
1379 find_node_handle(&node_res, pr_ctxt, args->args_node_pause.hnode);
1380
1381 if (!node_res)
1382 return -EFAULT;
1294 1383
1295 ret = node_pause(args->args_node_pause.hnode); 1384 ret = node_pause(node_res->hnode);
1296 1385
1297 return ret; 1386 return ret;
1298} 1387}
@@ -1304,12 +1393,18 @@ u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt)
1304{ 1393{
1305 int status = 0; 1394 int status = 0;
1306 struct dsp_msg msg; 1395 struct dsp_msg msg;
1396 struct node_res_object *node_res;
1397
1398 find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.hnode);
1399
1400 if (!node_res)
1401 return -EFAULT;
1307 1402
1308 CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1); 1403 CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1);
1309 1404
1310 if (!status) { 1405 if (!status) {
1311 status = 1406 status =
1312 node_put_message(args->args_node_putmessage.hnode, &msg, 1407 node_put_message(node_res->hnode, &msg,
1313 args->args_node_putmessage.utimeout); 1408 args->args_node_putmessage.utimeout);
1314 } 1409 }
1315 1410
@@ -1323,6 +1418,13 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
1323{ 1418{
1324 int status = 0; 1419 int status = 0;
1325 struct dsp_notification notification; 1420 struct dsp_notification notification;
1421 struct node_res_object *node_res;
1422
1423 find_node_handle(&node_res, pr_ctxt,
1424 args->args_node_registernotify.hnode);
1425
1426 if (!node_res)
1427 return -EFAULT;
1326 1428
1327 /* Initialize the notification data structure */ 1429 /* Initialize the notification data structure */
1328 notification.ps_name = NULL; 1430 notification.ps_name = NULL;
@@ -1333,7 +1435,7 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
1333 args->args_proc_register_notify.hnotification, 1435 args->args_proc_register_notify.hnotification,
1334 status, 1); 1436 status, 1);
1335 1437
1336 status = node_register_notify(args->args_node_registernotify.hnode, 1438 status = node_register_notify(node_res->hnode,
1337 args->args_node_registernotify.event_mask, 1439 args->args_node_registernotify.event_mask,
1338 args->args_node_registernotify. 1440 args->args_node_registernotify.
1339 notify_type, &notification); 1441 notify_type, &notification);
@@ -1348,8 +1450,14 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
1348u32 nodewrap_run(union trapped_args *args, void *pr_ctxt) 1450u32 nodewrap_run(union trapped_args *args, void *pr_ctxt)
1349{ 1451{
1350 u32 ret; 1452 u32 ret;
1453 struct node_res_object *node_res;
1454
1455 find_node_handle(&node_res, pr_ctxt, args->args_node_run.hnode);
1456
1457 if (!node_res)
1458 return -EFAULT;
1351 1459
1352 ret = node_run(args->args_node_run.hnode); 1460 ret = node_run(node_res->hnode);
1353 1461
1354 return ret; 1462 return ret;
1355} 1463}
@@ -1361,8 +1469,14 @@ u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt)
1361{ 1469{
1362 int status; 1470 int status;
1363 int tempstatus; 1471 int tempstatus;
1472 struct node_res_object *node_res;
1364 1473
1365 status = node_terminate(args->args_node_terminate.hnode, &tempstatus); 1474 find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.hnode);
1475
1476 if (!node_res)
1477 return -EFAULT;
1478
1479 status = node_terminate(node_res->hnode, &tempstatus);
1366 1480
1367 CP_TO_USR(args->args_node_terminate.pstatus, &tempstatus, status, 1); 1481 CP_TO_USR(args->args_node_terminate.pstatus, &tempstatus, status, 1);
1368 1482
@@ -1548,6 +1662,12 @@ u32 strmwrap_open(union trapped_args *args, void *pr_ctxt)
1548 struct strm_attr attr; 1662 struct strm_attr attr;
1549 struct strm_object *strm_obj; 1663 struct strm_object *strm_obj;
1550 struct dsp_streamattrin strm_attr_in; 1664 struct dsp_streamattrin strm_attr_in;
1665 struct node_res_object *node_res;
1666
1667 find_node_handle(&node_res, pr_ctxt, args->args_strm_open.hnode);
1668
1669 if (!node_res)
1670 return -EFAULT;
1551 1671
1552 CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1); 1672 CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1);
1553 1673
@@ -1560,7 +1680,7 @@ u32 strmwrap_open(union trapped_args *args, void *pr_ctxt)
1560 } 1680 }
1561 1681
1562 } 1682 }
1563 status = strm_open(args->args_strm_open.hnode, 1683 status = strm_open(node_res->hnode,
1564 args->args_strm_open.direction, 1684 args->args_strm_open.direction,
1565 args->args_strm_open.index, &attr, &strm_obj, 1685 args->args_strm_open.index, &attr, &strm_obj,
1566 pr_ctxt); 1686 pr_ctxt);
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
index 12c270aa7ac9..c8d9d2551ff0 100644
--- a/drivers/staging/tidspbridge/rmgr/drv.c
+++ b/drivers/staging/tidspbridge/rmgr/drv.c
@@ -73,7 +73,7 @@ static int request_bridge_resources(struct cfg_hostres *res);
73 73
74/* GPP PROCESS CLEANUP CODE */ 74/* GPP PROCESS CLEANUP CODE */
75 75
76static int drv_proc_free_node_res(void *process_ctxt); 76static int drv_proc_free_node_res(int id, void *p, void *data);
77 77
78/* Allocate and add a node resource element 78/* Allocate and add a node resource element
79* This function is called from .Node_Allocate. */ 79* This function is called from .Node_Allocate. */
@@ -84,88 +84,61 @@ int drv_insert_node_res_element(void *hnode, void *node_resource,
84 (struct node_res_object **)node_resource; 84 (struct node_res_object **)node_resource;
85 struct process_context *ctxt = (struct process_context *)process_ctxt; 85 struct process_context *ctxt = (struct process_context *)process_ctxt;
86 int status = 0; 86 int status = 0;
87 struct node_res_object *temp_node_res = NULL; 87 int retval;
88 88
89 *node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL); 89 *node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL);
90 if (*node_res_obj == NULL) 90 if (!*node_res_obj) {
91 status = -EFAULT; 91 status = -ENOMEM;
92 goto func_end;
93 }
92 94
93 if (!status) { 95 (*node_res_obj)->hnode = hnode;
94 if (mutex_lock_interruptible(&ctxt->node_mutex)) { 96 retval = idr_get_new(ctxt->node_id, *node_res_obj,
95 kfree(*node_res_obj); 97 &(*node_res_obj)->id);
96 return -EPERM; 98 if (retval == -EAGAIN) {
99 if (!idr_pre_get(ctxt->node_id, GFP_KERNEL)) {
100 pr_err("%s: OUT OF MEMORY\n", __func__);
101 status = -ENOMEM;
102 goto func_end;
97 } 103 }
98 (*node_res_obj)->hnode = hnode;
99 if (ctxt->node_list != NULL) {
100 temp_node_res = ctxt->node_list;
101 while (temp_node_res->next != NULL)
102 temp_node_res = temp_node_res->next;
103 104
104 temp_node_res->next = *node_res_obj; 105 retval = idr_get_new(ctxt->node_id, *node_res_obj,
105 } else { 106 &(*node_res_obj)->id);
106 ctxt->node_list = *node_res_obj; 107 }
107 } 108 if (retval) {
108 mutex_unlock(&ctxt->node_mutex); 109 pr_err("%s: FAILED, IDR is FULL\n", __func__);
110 status = -EFAULT;
109 } 111 }
112func_end:
113 if (status)
114 kfree(*node_res_obj);
110 115
111 return status; 116 return status;
112} 117}
113 118
114/* Release all Node resources and its context 119/* Release all Node resources and its context
115* This is called from .Node_Delete. */ 120 * Actual Node De-Allocation */
116int drv_remove_node_res_element(void *node_resource, void *process_ctxt) 121static int drv_proc_free_node_res(int id, void *p, void *data)
117{ 122{
118 struct node_res_object *node_res_obj = 123 struct process_context *ctxt = data;
119 (struct node_res_object *)node_resource; 124 int status;
120 struct process_context *ctxt = (struct process_context *)process_ctxt; 125 struct node_res_object *node_res_obj = p;
121 struct node_res_object *temp_node;
122 int status = 0;
123
124 if (mutex_lock_interruptible(&ctxt->node_mutex))
125 return -EPERM;
126 temp_node = ctxt->node_list;
127 if (temp_node == node_res_obj) {
128 ctxt->node_list = node_res_obj->next;
129 } else {
130 while (temp_node && temp_node->next != node_res_obj)
131 temp_node = temp_node->next;
132 if (!temp_node)
133 status = -ENOENT;
134 else
135 temp_node->next = node_res_obj->next;
136 }
137 mutex_unlock(&ctxt->node_mutex);
138 kfree(node_res_obj);
139 return status;
140}
141
142/* Actual Node De-Allocation */
143static int drv_proc_free_node_res(void *process_ctxt)
144{
145 struct process_context *ctxt = (struct process_context *)process_ctxt;
146 int status = 0;
147 struct node_res_object *node_list = NULL;
148 struct node_res_object *node_res_obj = NULL;
149 u32 node_state; 126 u32 node_state;
150 127
151 node_list = ctxt->node_list; 128 if (node_res_obj->node_allocated) {
152 while (node_list != NULL) { 129 node_state = node_get_state(node_res_obj->hnode);
153 node_res_obj = node_list; 130 if (node_state <= NODE_DELETING) {
154 node_list = node_list->next; 131 if ((node_state == NODE_RUNNING) ||
155 if (node_res_obj->node_allocated) { 132 (node_state == NODE_PAUSED) ||
156 node_state = node_get_state(node_res_obj->hnode); 133 (node_state == NODE_TERMINATING))
157 if (node_state <= NODE_DELETING) { 134 node_terminate
158 if ((node_state == NODE_RUNNING) || 135 (node_res_obj->hnode, &status);
159 (node_state == NODE_PAUSED) || 136
160 (node_state == NODE_TERMINATING)) 137 node_delete(node_res_obj, ctxt);
161 status = node_terminate
162 (node_res_obj->hnode, &status);
163
164 status = node_delete(node_res_obj->hnode, ctxt);
165 }
166 } 138 }
167 } 139 }
168 return status; 140
141 return 0;
169} 142}
170 143
171/* Release all Mapped and Reserved DMM resources */ 144/* Release all Mapped and Reserved DMM resources */
@@ -220,50 +193,12 @@ void drv_proc_node_update_heap_status(void *node_resource, s32 status)
220 */ 193 */
221int drv_remove_all_node_res_elements(void *process_ctxt) 194int drv_remove_all_node_res_elements(void *process_ctxt)
222{ 195{
223 struct process_context *ctxt = (struct process_context *)process_ctxt; 196 struct process_context *ctxt = process_ctxt;
224 int status = 0;
225 struct node_res_object *temp_node2 = NULL;
226 struct node_res_object *temp_node = NULL;
227
228 drv_proc_free_node_res(ctxt);
229 temp_node = ctxt->node_list;
230 while (temp_node != NULL) {
231 temp_node2 = temp_node;
232 temp_node = temp_node->next;
233 kfree(temp_node2);
234 }
235 ctxt->node_list = NULL;
236 return status;
237}
238 197
239/* Getting the node resource element */ 198 idr_for_each(ctxt->node_id, drv_proc_free_node_res, ctxt);
240int drv_get_node_res_element(void *hnode, void *node_resource, 199 idr_destroy(ctxt->node_id);
241 void *process_ctxt)
242{
243 struct node_res_object **node_res =
244 (struct node_res_object **)node_resource;
245 struct process_context *ctxt = (struct process_context *)process_ctxt;
246 int status = 0;
247 struct node_res_object *temp_node2 = NULL;
248 struct node_res_object *temp_node = NULL;
249
250 if (mutex_lock_interruptible(&ctxt->node_mutex))
251 return -EPERM;
252
253 temp_node = ctxt->node_list;
254 while ((temp_node != NULL) && (temp_node->hnode != hnode)) {
255 temp_node2 = temp_node;
256 temp_node = temp_node->next;
257 }
258 200
259 mutex_unlock(&ctxt->node_mutex); 201 return 0;
260
261 if (temp_node != NULL)
262 *node_res = temp_node;
263 else
264 status = -ENOENT;
265
266 return status;
267} 202}
268 203
269/* Allocate the STRM resource element 204/* Allocate the STRM resource element
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c
index aec7cf7d0d58..900cdd356f76 100644
--- a/drivers/staging/tidspbridge/rmgr/drv_interface.c
+++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c
@@ -511,8 +511,13 @@ static int bridge_open(struct inode *ip, struct file *filp)
511 INIT_LIST_HEAD(&pr_ctxt->dmm_map_list); 511 INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
512 spin_lock_init(&pr_ctxt->dmm_rsv_lock); 512 spin_lock_init(&pr_ctxt->dmm_rsv_lock);
513 INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list); 513 INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
514 mutex_init(&pr_ctxt->node_mutex);
515 mutex_init(&pr_ctxt->strm_mutex); 514 mutex_init(&pr_ctxt->strm_mutex);
515
516 pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
517 if (pr_ctxt->node_id)
518 idr_init(pr_ctxt->node_id);
519 else
520 status = -ENOMEM;
516 } else { 521 } else {
517 status = -ENOMEM; 522 status = -ENOMEM;
518 } 523 }
diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c
index e2d02c410e04..6e9441e21265 100644
--- a/drivers/staging/tidspbridge/rmgr/node.c
+++ b/drivers/staging/tidspbridge/rmgr/node.c
@@ -291,11 +291,11 @@ enum node_state node_get_state(void *hnode)
291 * Allocate GPP resources to manage a node on the DSP. 291 * Allocate GPP resources to manage a node on the DSP.
292 */ 292 */
293int node_allocate(struct proc_object *hprocessor, 293int node_allocate(struct proc_object *hprocessor,
294 const struct dsp_uuid *node_uuid, 294 const struct dsp_uuid *node_uuid,
295 const struct dsp_cbdata *pargs, 295 const struct dsp_cbdata *pargs,
296 const struct dsp_nodeattrin *attr_in, 296 const struct dsp_nodeattrin *attr_in,
297 struct node_object **ph_node, 297 struct node_res_object **noderes,
298 struct process_context *pr_ctxt) 298 struct process_context *pr_ctxt)
299{ 299{
300 struct node_mgr *hnode_mgr; 300 struct node_mgr *hnode_mgr;
301 struct dev_object *hdev_obj; 301 struct dev_object *hdev_obj;
@@ -327,10 +327,10 @@ int node_allocate(struct proc_object *hprocessor,
327 327
328 DBC_REQUIRE(refs > 0); 328 DBC_REQUIRE(refs > 0);
329 DBC_REQUIRE(hprocessor != NULL); 329 DBC_REQUIRE(hprocessor != NULL);
330 DBC_REQUIRE(ph_node != NULL); 330 DBC_REQUIRE(noderes != NULL);
331 DBC_REQUIRE(node_uuid != NULL); 331 DBC_REQUIRE(node_uuid != NULL);
332 332
333 *ph_node = NULL; 333 *noderes = NULL;
334 334
335 status = proc_get_processor_id(hprocessor, &proc_id); 335 status = proc_get_processor_id(hprocessor, &proc_id);
336 336
@@ -653,9 +653,6 @@ func_cont:
653 * (for overlay and dll) */ 653 * (for overlay and dll) */
654 pnode->phase_split = true; 654 pnode->phase_split = true;
655 655
656 if (!status)
657 *ph_node = pnode;
658
659 /* Notify all clients registered for DSP_NODESTATECHANGE. */ 656 /* Notify all clients registered for DSP_NODESTATECHANGE. */
660 proc_notify_all_clients(hprocessor, DSP_NODESTATECHANGE); 657 proc_notify_all_clients(hprocessor, DSP_NODESTATECHANGE);
661 } else { 658 } else {
@@ -666,16 +663,21 @@ func_cont:
666 } 663 }
667 664
668 if (!status) { 665 if (!status) {
669 drv_insert_node_res_element(*ph_node, &node_res, pr_ctxt); 666 status = drv_insert_node_res_element(pnode, &node_res, pr_ctxt);
667 if (status) {
668 delete_node(pnode, pr_ctxt);
669 goto func_end;
670 }
671
672 *noderes = (struct node_res_object *)node_res;
670 drv_proc_node_update_heap_status(node_res, true); 673 drv_proc_node_update_heap_status(node_res, true);
671 drv_proc_node_update_status(node_res, true); 674 drv_proc_node_update_status(node_res, true);
672 } 675 }
673 DBC_ENSURE((status && (*ph_node == NULL)) || 676 DBC_ENSURE((status && *noderes == NULL) || (!status && *noderes));
674 (!status && *ph_node));
675func_end: 677func_end:
676 dev_dbg(bridge, "%s: hprocessor: %p node_uuid: %p pargs: %p attr_in:" 678 dev_dbg(bridge, "%s: hprocessor: %p pNodeId: %p pargs: %p attr_in: %p "
677 " %p ph_node: %p status: 0x%x\n", __func__, hprocessor, 679 "node_res: %p status: 0x%x\n", __func__, hprocessor,
678 node_uuid, pargs, attr_in, ph_node, status); 680 node_uuid, pargs, attr_in, noderes, status);
679 return status; 681 return status;
680} 682}
681 683
@@ -1433,10 +1435,10 @@ int node_create_mgr(struct node_mgr **node_man,
1433 * Loads the node's delete function if necessary. Free GPP side resources 1435 * Loads the node's delete function if necessary. Free GPP side resources
1434 * after node's delete function returns. 1436 * after node's delete function returns.
1435 */ 1437 */
1436int node_delete(struct node_object *hnode, 1438int node_delete(struct node_res_object *noderes,
1437 struct process_context *pr_ctxt) 1439 struct process_context *pr_ctxt)
1438{ 1440{
1439 struct node_object *pnode = (struct node_object *)hnode; 1441 struct node_object *pnode = noderes->hnode;
1440 struct node_mgr *hnode_mgr; 1442 struct node_mgr *hnode_mgr;
1441 struct proc_object *hprocessor; 1443 struct proc_object *hprocessor;
1442 struct disp_object *disp_obj; 1444 struct disp_object *disp_obj;
@@ -1449,32 +1451,32 @@ int node_delete(struct node_object *hnode,
1449 u32 proc_id; 1451 u32 proc_id;
1450 struct bridge_drv_interface *intf_fxns; 1452 struct bridge_drv_interface *intf_fxns;
1451 1453
1452 void *node_res; 1454 void *node_res = noderes;
1453 1455
1454 struct dsp_processorstate proc_state; 1456 struct dsp_processorstate proc_state;
1455 DBC_REQUIRE(refs > 0); 1457 DBC_REQUIRE(refs > 0);
1456 1458
1457 if (!hnode) { 1459 if (!pnode) {
1458 status = -EFAULT; 1460 status = -EFAULT;
1459 goto func_end; 1461 goto func_end;
1460 } 1462 }
1461 /* create struct dsp_cbdata struct for PWR call */ 1463 /* create struct dsp_cbdata struct for PWR call */
1462 cb_data.cb_data = PWR_TIMEOUT; 1464 cb_data.cb_data = PWR_TIMEOUT;
1463 hnode_mgr = hnode->hnode_mgr; 1465 hnode_mgr = pnode->hnode_mgr;
1464 hprocessor = hnode->hprocessor; 1466 hprocessor = pnode->hprocessor;
1465 disp_obj = hnode_mgr->disp_obj; 1467 disp_obj = hnode_mgr->disp_obj;
1466 node_type = node_get_type(hnode); 1468 node_type = node_get_type(pnode);
1467 intf_fxns = hnode_mgr->intf_fxns; 1469 intf_fxns = hnode_mgr->intf_fxns;
1468 /* Enter critical section */ 1470 /* Enter critical section */
1469 mutex_lock(&hnode_mgr->node_mgr_lock); 1471 mutex_lock(&hnode_mgr->node_mgr_lock);
1470 1472
1471 state = node_get_state(hnode); 1473 state = node_get_state(pnode);
1472 /* Execute delete phase code for non-device node in all cases 1474 /* Execute delete phase code for non-device node in all cases
1473 * except when the node was only allocated. Delete phase must be 1475 * except when the node was only allocated. Delete phase must be
1474 * executed even if create phase was executed, but failed. 1476 * executed even if create phase was executed, but failed.
1475 * If the node environment pointer is non-NULL, the delete phase 1477 * If the node environment pointer is non-NULL, the delete phase
1476 * code must be executed. */ 1478 * code must be executed. */
1477 if (!(state == NODE_ALLOCATED && hnode->node_env == (u32) NULL) && 1479 if (!(state == NODE_ALLOCATED && pnode->node_env == (u32) NULL) &&
1478 node_type != NODE_DEVICE) { 1480 node_type != NODE_DEVICE) {
1479 status = proc_get_processor_id(pnode->hprocessor, &proc_id); 1481 status = proc_get_processor_id(pnode->hprocessor, &proc_id);
1480 if (status) 1482 if (status)
@@ -1487,26 +1489,26 @@ int node_delete(struct node_object *hnode,
1487 * is now ok to unload it. If the node is running, we 1489 * is now ok to unload it. If the node is running, we
1488 * will unload the execute phase only after deleting 1490 * will unload the execute phase only after deleting
1489 * the node. */ 1491 * the node. */
1490 if (state == NODE_PAUSED && hnode->loaded && 1492 if (state == NODE_PAUSED && pnode->loaded &&
1491 hnode->phase_split) { 1493 pnode->phase_split) {
1492 /* Ok to unload execute code as long as node 1494 /* Ok to unload execute code as long as node
1493 * is not * running */ 1495 * is not * running */
1494 status1 = 1496 status1 =
1495 hnode_mgr->nldr_fxns. 1497 hnode_mgr->nldr_fxns.
1496 pfn_unload(hnode->nldr_node_obj, 1498 pfn_unload(pnode->nldr_node_obj,
1497 NLDR_EXECUTE); 1499 NLDR_EXECUTE);
1498 hnode->loaded = false; 1500 pnode->loaded = false;
1499 NODE_SET_STATE(hnode, NODE_DONE); 1501 NODE_SET_STATE(pnode, NODE_DONE);
1500 } 1502 }
1501 /* Load delete phase code if not loaded or if haven't 1503 /* Load delete phase code if not loaded or if haven't
1502 * * unloaded EXECUTE phase */ 1504 * * unloaded EXECUTE phase */
1503 if ((!(hnode->loaded) || (state == NODE_RUNNING)) && 1505 if ((!(pnode->loaded) || (state == NODE_RUNNING)) &&
1504 hnode->phase_split) { 1506 pnode->phase_split) {
1505 status = 1507 status =
1506 hnode_mgr->nldr_fxns. 1508 hnode_mgr->nldr_fxns.
1507 pfn_load(hnode->nldr_node_obj, NLDR_DELETE); 1509 pfn_load(pnode->nldr_node_obj, NLDR_DELETE);
1508 if (!status) 1510 if (!status)
1509 hnode->loaded = true; 1511 pnode->loaded = true;
1510 else 1512 else
1511 pr_err("%s: fail - load delete code:" 1513 pr_err("%s: fail - load delete code:"
1512 " 0x%x\n", __func__, status); 1514 " 0x%x\n", __func__, status);
@@ -1515,14 +1517,14 @@ int node_delete(struct node_object *hnode,
1515func_cont1: 1517func_cont1:
1516 if (!status) { 1518 if (!status) {
1517 /* Unblock a thread trying to terminate the node */ 1519 /* Unblock a thread trying to terminate the node */
1518 (void)sync_set_event(hnode->sync_done); 1520 (void)sync_set_event(pnode->sync_done);
1519 if (proc_id == DSP_UNIT) { 1521 if (proc_id == DSP_UNIT) {
1520 /* ul_delete_fxn = address of node's delete 1522 /* ul_delete_fxn = address of node's delete
1521 * function */ 1523 * function */
1522 status = get_fxn_address(hnode, &ul_delete_fxn, 1524 status = get_fxn_address(pnode, &ul_delete_fxn,
1523 DELETEPHASE); 1525 DELETEPHASE);
1524 } else if (proc_id == IVA_UNIT) 1526 } else if (proc_id == IVA_UNIT)
1525 ul_delete_fxn = (u32) hnode->node_env; 1527 ul_delete_fxn = (u32) pnode->node_env;
1526 if (!status) { 1528 if (!status) {
1527 status = proc_get_state(hprocessor, 1529 status = proc_get_state(hprocessor,
1528 &proc_state, 1530 &proc_state,
@@ -1530,22 +1532,22 @@ func_cont1:
1530 dsp_processorstate)); 1532 dsp_processorstate));
1531 if (proc_state.proc_state != PROC_ERROR) { 1533 if (proc_state.proc_state != PROC_ERROR) {
1532 status = 1534 status =
1533 disp_node_delete(disp_obj, hnode, 1535 disp_node_delete(disp_obj, pnode,
1534 hnode_mgr-> 1536 hnode_mgr->
1535 ul_fxn_addrs 1537 ul_fxn_addrs
1536 [RMSDELETENODE], 1538 [RMSDELETENODE],
1537 ul_delete_fxn, 1539 ul_delete_fxn,
1538 hnode->node_env); 1540 pnode->node_env);
1539 } else 1541 } else
1540 NODE_SET_STATE(hnode, NODE_DONE); 1542 NODE_SET_STATE(pnode, NODE_DONE);
1541 1543
1542 /* Unload execute, if not unloaded, and delete 1544 /* Unload execute, if not unloaded, and delete
1543 * function */ 1545 * function */
1544 if (state == NODE_RUNNING && 1546 if (state == NODE_RUNNING &&
1545 hnode->phase_split) { 1547 pnode->phase_split) {
1546 status1 = 1548 status1 =
1547 hnode_mgr->nldr_fxns. 1549 hnode_mgr->nldr_fxns.
1548 pfn_unload(hnode->nldr_node_obj, 1550 pfn_unload(pnode->nldr_node_obj,
1549 NLDR_EXECUTE); 1551 NLDR_EXECUTE);
1550 } 1552 }
1551 if (status1) 1553 if (status1)
@@ -1553,10 +1555,10 @@ func_cont1:
1553 " 0x%x\n", __func__, status1); 1555 " 0x%x\n", __func__, status1);
1554 1556
1555 status1 = 1557 status1 =
1556 hnode_mgr->nldr_fxns.pfn_unload(hnode-> 1558 hnode_mgr->nldr_fxns.pfn_unload(pnode->
1557 nldr_node_obj, 1559 nldr_node_obj,
1558 NLDR_DELETE); 1560 NLDR_DELETE);
1559 hnode->loaded = false; 1561 pnode->loaded = false;
1560 if (status1) 1562 if (status1)
1561 pr_err("%s: fail - unload delete code: " 1563 pr_err("%s: fail - unload delete code: "
1562 "0x%x\n", __func__, status1); 1564 "0x%x\n", __func__, status1);
@@ -1565,25 +1567,28 @@ func_cont1:
1565 } 1567 }
1566 /* Free host side resources even if a failure occurred */ 1568 /* Free host side resources even if a failure occurred */
1567 /* Remove node from hnode_mgr->node_list */ 1569 /* Remove node from hnode_mgr->node_list */
1568 lst_remove_elem(hnode_mgr->node_list, (struct list_head *)hnode); 1570 lst_remove_elem(hnode_mgr->node_list, (struct list_head *)pnode);
1569 hnode_mgr->num_nodes--; 1571 hnode_mgr->num_nodes--;
1570 /* Decrement count of nodes created on DSP */ 1572 /* Decrement count of nodes created on DSP */
1571 if ((state != NODE_ALLOCATED) || ((state == NODE_ALLOCATED) && 1573 if ((state != NODE_ALLOCATED) || ((state == NODE_ALLOCATED) &&
1572 (hnode->node_env != (u32) NULL))) 1574 (pnode->node_env != (u32) NULL)))
1573 hnode_mgr->num_created--; 1575 hnode_mgr->num_created--;
1574 /* Free host-side resources allocated by node_create() 1576 /* Free host-side resources allocated by node_create()
1575 * delete_node() fails if SM buffers not freed by client! */ 1577 * delete_node() fails if SM buffers not freed by client! */
1576 if (drv_get_node_res_element(hnode, &node_res, pr_ctxt) != 1578 drv_proc_node_update_status(node_res, false);
1577 -ENOENT) 1579 delete_node(pnode, pr_ctxt);
1578 drv_proc_node_update_status(node_res, false); 1580
1579 delete_node(hnode, pr_ctxt); 1581 /*
1582 * Release all Node resources and its context
1583 */
1584 idr_remove(pr_ctxt->node_id, ((struct node_res_object *)node_res)->id);
1585 kfree(node_res);
1580 1586
1581 drv_remove_node_res_element(node_res, pr_ctxt);
1582 /* Exit critical section */ 1587 /* Exit critical section */
1583 mutex_unlock(&hnode_mgr->node_mgr_lock); 1588 mutex_unlock(&hnode_mgr->node_mgr_lock);
1584 proc_notify_clients(hprocessor, DSP_NODESTATECHANGE); 1589 proc_notify_clients(hprocessor, DSP_NODESTATECHANGE);
1585func_end: 1590func_end:
1586 dev_dbg(bridge, "%s: hnode: %p status 0x%x\n", __func__, hnode, status); 1591 dev_dbg(bridge, "%s: pnode: %p status 0x%x\n", __func__, pnode, status);
1587 return status; 1592 return status;
1588} 1593}
1589 1594