aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/tidspbridge/rmgr/drv.c
diff options
context:
space:
mode:
authorErnesto Ramos <ernesto@ti.com>2010-07-28 16:04:56 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-02 17:11:03 -0700
commit4ec09714a0a5861c3e786967024ddfff00b0add6 (patch)
tree1004c64c1886e958f4a284a72f0f7770e75cdaed /drivers/staging/tidspbridge/rmgr/drv.c
parentstaging: ti dspbridge: use processor handle from context instead of user's (diff)
downloadlinux-dev-4ec09714a0a5861c3e786967024ddfff00b0add6.tar.xz
linux-dev-4ec09714a0a5861c3e786967024ddfff00b0add6.zip
staging: ti dspbridge: use stream id instead of kernel address
Send stream ids to the user instead of handles, then when the id is coming from user dspbridge can retrive the handle using id and avoid using invalid handles. Signed-off-by: Ernesto Ramos <ernesto@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/tidspbridge/rmgr/drv.c')
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv.c146
1 files changed, 47 insertions, 99 deletions
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
index c8d9d2551ff0..8a8dea6efeda 100644
--- a/drivers/staging/tidspbridge/rmgr/drv.c
+++ b/drivers/staging/tidspbridge/rmgr/drv.c
@@ -211,70 +211,40 @@ int drv_proc_insert_strm_res_element(void *stream_obj,
(struct strm_res_object **)strm_res;
struct process_context *ctxt = (struct process_context *)process_ctxt;
int status = 0;
- struct strm_res_object *temp_strm_res = NULL;
+ int retval;
*pstrm_res = kzalloc(sizeof(struct strm_res_object), GFP_KERNEL);
- if (*pstrm_res == NULL)
+ if (*pstrm_res == NULL) {
status = -EFAULT;
+ goto func_end;
+ }
- if (!status) {
- if (mutex_lock_interruptible(&ctxt->strm_mutex)) {
- kfree(*pstrm_res);
- return -EPERM;
+ (*pstrm_res)->hstream = stream_obj;
+ retval = idr_get_new(ctxt->stream_id, *pstrm_res,
+ &(*pstrm_res)->id);
+ if (retval == -EAGAIN) {
+ if (!idr_pre_get(ctxt->stream_id, GFP_KERNEL)) {
+ pr_err("%s: OUT OF MEMORY\n", __func__);
+ status = -ENOMEM;
+ goto func_end;
}
- (*pstrm_res)->hstream = stream_obj;
- if (ctxt->pstrm_list != NULL) {
- temp_strm_res = ctxt->pstrm_list;
- while (temp_strm_res->next != NULL)
- temp_strm_res = temp_strm_res->next;
- temp_strm_res->next = *pstrm_res;
- } else {
- ctxt->pstrm_list = *pstrm_res;
- }
- mutex_unlock(&ctxt->strm_mutex);
+ retval = idr_get_new(ctxt->stream_id, *pstrm_res,
+ &(*pstrm_res)->id);
}
- return status;
-}
-
-/* Release Stream resource element context
-* This function called after the actual resource is freed
- */
-int drv_proc_remove_strm_res_element(void *strm_res, void *process_ctxt)
-{
- struct strm_res_object *pstrm_res = (struct strm_res_object *)strm_res;
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- struct strm_res_object *temp_strm_res;
- int status = 0;
-
- if (mutex_lock_interruptible(&ctxt->strm_mutex))
- return -EPERM;
- temp_strm_res = ctxt->pstrm_list;
-
- if (ctxt->pstrm_list == pstrm_res) {
- ctxt->pstrm_list = pstrm_res->next;
- } else {
- while (temp_strm_res && temp_strm_res->next != pstrm_res)
- temp_strm_res = temp_strm_res->next;
- if (temp_strm_res == NULL)
- status = -ENOENT;
- else
- temp_strm_res->next = pstrm_res->next;
+ if (retval) {
+ pr_err("%s: FAILED, IDR is FULL\n", __func__);
+ status = -EPERM;
}
- mutex_unlock(&ctxt->strm_mutex);
- kfree(pstrm_res);
+
+func_end:
return status;
}
-/* Release all Stream resources and its context
-* This is called from .bridge_release.
- */
-int drv_remove_all_strm_res_elements(void *process_ctxt)
+static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt)
{
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- int status = 0;
- struct strm_res_object *strm_res = NULL;
- struct strm_res_object *strm_tmp = NULL;
+ struct process_context *ctxt = process_ctxt;
+ struct strm_res_object *strm_res = p;
struct stream_info strm_info;
struct dsp_streaminfo user;
u8 **ap_buffer = NULL;
@@ -283,60 +253,38 @@ int drv_remove_all_strm_res_elements(void *process_ctxt)
u32 dw_arg;
s32 ul_buf_size;
- strm_tmp = ctxt->pstrm_list;
- while (strm_tmp) {
- strm_res = strm_tmp;
- strm_tmp = strm_tmp->next;
- if (strm_res->num_bufs) {
- ap_buffer = kmalloc((strm_res->num_bufs *
- sizeof(u8 *)), GFP_KERNEL);
- if (ap_buffer) {
- status = strm_free_buffer(strm_res->hstream,
- ap_buffer,
- strm_res->num_bufs,
- ctxt);
- kfree(ap_buffer);
- }
+ if (strm_res->num_bufs) {
+ ap_buffer = kmalloc((strm_res->num_bufs *
+ sizeof(u8 *)), GFP_KERNEL);
+ if (ap_buffer) {
+ strm_free_buffer(strm_res,
+ ap_buffer,
+ strm_res->num_bufs,
+ ctxt);
+ kfree(ap_buffer);
}
- strm_info.user_strm = &user;
- user.number_bufs_in_stream = 0;
- strm_get_info(strm_res->hstream, &strm_info, sizeof(strm_info));
- while (user.number_bufs_in_stream--)
- strm_reclaim(strm_res->hstream, &buf_ptr, &ul_bytes,
- (u32 *) &ul_buf_size, &dw_arg);
- status = strm_close(strm_res->hstream, ctxt);
}
- return status;
+ strm_info.user_strm = &user;
+ user.number_bufs_in_stream = 0;
+ strm_get_info(strm_res->hstream, &strm_info, sizeof(strm_info));
+ while (user.number_bufs_in_stream--)
+ strm_reclaim(strm_res->hstream, &buf_ptr, &ul_bytes,
+ (u32 *) &ul_buf_size, &dw_arg);
+ strm_close(strm_res, ctxt);
+ return 0;
}
-/* Getting the stream resource element */
-int drv_get_strm_res_element(void *stream_obj, void *strm_resources,
- void *process_ctxt)
+/* Release all Stream resources and its context
+* This is called from .bridge_release.
+ */
+int drv_remove_all_strm_res_elements(void *process_ctxt)
{
- struct strm_res_object **strm_res =
- (struct strm_res_object **)strm_resources;
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- int status = 0;
- struct strm_res_object *temp_strm2 = NULL;
- struct strm_res_object *temp_strm;
-
- if (mutex_lock_interruptible(&ctxt->strm_mutex))
- return -EPERM;
-
- temp_strm = ctxt->pstrm_list;
- while ((temp_strm != NULL) && (temp_strm->hstream != stream_obj)) {
- temp_strm2 = temp_strm;
- temp_strm = temp_strm->next;
- }
-
- mutex_unlock(&ctxt->strm_mutex);
+ struct process_context *ctxt = process_ctxt;
- if (temp_strm != NULL)
- *strm_res = temp_strm;
- else
- status = -ENOENT;
+ idr_for_each(ctxt->stream_id, drv_proc_free_strm_res, ctxt);
+ idr_destroy(ctxt->stream_id);
- return status;
+ return 0;
}
/* Updating the stream resource element */