|
@@ -24,7 +24,6 @@
|
|
|
#include <dspbridge/dbc.h>
|
|
|
|
|
|
/* ----------------------------------- OS Adaptation Layer */
|
|
|
-#include <dspbridge/list.h>
|
|
|
#include <dspbridge/sync.h>
|
|
|
|
|
|
/* ----------------------------------- Platform Manager */
|
|
@@ -38,10 +37,10 @@
|
|
|
#include <dspbridge/dspmsg.h>
|
|
|
|
|
|
/* ----------------------------------- Function Prototypes */
|
|
|
-static int add_new_msg(struct lst_list *msg_list);
|
|
|
+static int add_new_msg(struct list_head *msg_list);
|
|
|
static void delete_msg_mgr(struct msg_mgr *hmsg_mgr);
|
|
|
static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp);
|
|
|
-static void free_msg_list(struct lst_list *msg_list);
|
|
|
+static void free_msg_list(struct list_head *msg_list);
|
|
|
|
|
|
/*
|
|
|
* ======== bridge_msg_create ========
|
|
@@ -73,25 +72,13 @@ int bridge_msg_create(struct msg_mgr **msg_man,
|
|
|
msg_mgr_obj->on_exit = msg_callback;
|
|
|
msg_mgr_obj->hio_mgr = hio_mgr;
|
|
|
/* List of MSG_QUEUEs */
|
|
|
- msg_mgr_obj->queue_list = kzalloc(sizeof(struct lst_list),
|
|
|
- GFP_KERNEL);
|
|
|
+ INIT_LIST_HEAD(&msg_mgr_obj->queue_list);
|
|
|
/* Queues of message frames for messages to the DSP. Message
|
|
|
* frames will only be added to the free queue when a
|
|
|
* msg_queue object is created. */
|
|
|
- msg_mgr_obj->msg_free_list = kzalloc(sizeof(struct lst_list),
|
|
|
- GFP_KERNEL);
|
|
|
- msg_mgr_obj->msg_used_list = kzalloc(sizeof(struct lst_list),
|
|
|
- GFP_KERNEL);
|
|
|
- if (msg_mgr_obj->queue_list == NULL ||
|
|
|
- msg_mgr_obj->msg_free_list == NULL ||
|
|
|
- msg_mgr_obj->msg_used_list == NULL) {
|
|
|
- status = -ENOMEM;
|
|
|
- } else {
|
|
|
- INIT_LIST_HEAD(&msg_mgr_obj->queue_list->head);
|
|
|
- INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list->head);
|
|
|
- INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list->head);
|
|
|
- spin_lock_init(&msg_mgr_obj->msg_mgr_lock);
|
|
|
- }
|
|
|
+ INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list);
|
|
|
+ INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list);
|
|
|
+ spin_lock_init(&msg_mgr_obj->msg_mgr_lock);
|
|
|
|
|
|
/* Create an event to be used by bridge_msg_put() in waiting
|
|
|
* for an available free frame from the message manager. */
|
|
@@ -128,7 +115,7 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr,
|
|
|
struct msg_queue *msg_q;
|
|
|
int status = 0;
|
|
|
|
|
|
- if (!hmsg_mgr || msgq == NULL || !hmsg_mgr->msg_free_list) {
|
|
|
+ if (!hmsg_mgr || msgq == NULL) {
|
|
|
status = -EFAULT;
|
|
|
goto func_end;
|
|
|
}
|
|
@@ -140,20 +127,13 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr,
|
|
|
status = -ENOMEM;
|
|
|
goto func_end;
|
|
|
}
|
|
|
- lst_init_elem((struct list_head *)msg_q);
|
|
|
msg_q->max_msgs = max_msgs;
|
|
|
msg_q->hmsg_mgr = hmsg_mgr;
|
|
|
msg_q->arg = arg; /* Node handle */
|
|
|
msg_q->msgq_id = msgq_id; /* Node env (not valid yet) */
|
|
|
/* Queues of Message frames for messages from the DSP */
|
|
|
- msg_q->msg_free_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL);
|
|
|
- msg_q->msg_used_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL);
|
|
|
- if (msg_q->msg_free_list == NULL || msg_q->msg_used_list == NULL)
|
|
|
- status = -ENOMEM;
|
|
|
- else {
|
|
|
- INIT_LIST_HEAD(&msg_q->msg_free_list->head);
|
|
|
- INIT_LIST_HEAD(&msg_q->msg_used_list->head);
|
|
|
- }
|
|
|
+ INIT_LIST_HEAD(&msg_q->msg_free_list);
|
|
|
+ INIT_LIST_HEAD(&msg_q->msg_used_list);
|
|
|
|
|
|
/* Create event that will be signalled when a message from
|
|
|
* the DSP is available. */
|
|
@@ -204,10 +184,10 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr,
|
|
|
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
|
|
|
/* Initialize message frames and put in appropriate queues */
|
|
|
for (i = 0; i < max_msgs && !status; i++) {
|
|
|
- status = add_new_msg(hmsg_mgr->msg_free_list);
|
|
|
+ status = add_new_msg(&hmsg_mgr->msg_free_list);
|
|
|
if (!status) {
|
|
|
num_allocated++;
|
|
|
- status = add_new_msg(msg_q->msg_free_list);
|
|
|
+ status = add_new_msg(&msg_q->msg_free_list);
|
|
|
}
|
|
|
}
|
|
|
if (status) {
|
|
@@ -215,11 +195,11 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr,
|
|
|
* of the newly allocated message frames. */
|
|
|
delete_msg_queue(msg_q, num_allocated);
|
|
|
} else {
|
|
|
- lst_put_tail(hmsg_mgr->queue_list,
|
|
|
- (struct list_head *)msg_q);
|
|
|
+ list_add_tail(&msg_q->list_elem,
|
|
|
+ &hmsg_mgr->queue_list);
|
|
|
*msgq = msg_q;
|
|
|
/* Signal that free frames are now available */
|
|
|
- if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list))
|
|
|
+ if (!list_empty(&hmsg_mgr->msg_free_list))
|
|
|
sync_set_event(hmsg_mgr->sync_event);
|
|
|
|
|
|
}
|
|
@@ -267,15 +247,12 @@ void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj)
|
|
|
}
|
|
|
/* Remove message queue from hmsg_mgr->queue_list */
|
|
|
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
|
|
|
- lst_remove_elem(hmsg_mgr->queue_list,
|
|
|
- (struct list_head *)msg_queue_obj);
|
|
|
+ list_del(&msg_queue_obj->list_elem);
|
|
|
/* Free the message queue object */
|
|
|
delete_msg_queue(msg_queue_obj, msg_queue_obj->max_msgs);
|
|
|
- if (!hmsg_mgr->msg_free_list)
|
|
|
- goto func_cont;
|
|
|
- if (LST_IS_EMPTY(hmsg_mgr->msg_free_list))
|
|
|
+ if (list_empty(&hmsg_mgr->msg_free_list))
|
|
|
sync_reset_event(hmsg_mgr->sync_event);
|
|
|
-func_cont:
|
|
|
+
|
|
|
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
|
|
|
func_end:
|
|
|
return;
|
|
@@ -301,26 +278,21 @@ int bridge_msg_get(struct msg_queue *msg_queue_obj,
|
|
|
}
|
|
|
|
|
|
hmsg_mgr = msg_queue_obj->hmsg_mgr;
|
|
|
- if (!msg_queue_obj->msg_used_list) {
|
|
|
- status = -EFAULT;
|
|
|
- goto func_end;
|
|
|
- }
|
|
|
|
|
|
/* Enter critical section */
|
|
|
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
|
|
|
/* If a message is already there, get it */
|
|
|
- if (!LST_IS_EMPTY(msg_queue_obj->msg_used_list)) {
|
|
|
- msg_frame_obj = (struct msg_frame *)
|
|
|
- lst_get_head(msg_queue_obj->msg_used_list);
|
|
|
- if (msg_frame_obj != NULL) {
|
|
|
- *pmsg = msg_frame_obj->msg_data.msg;
|
|
|
- lst_put_tail(msg_queue_obj->msg_free_list,
|
|
|
- (struct list_head *)msg_frame_obj);
|
|
|
- if (LST_IS_EMPTY(msg_queue_obj->msg_used_list))
|
|
|
- sync_reset_event(msg_queue_obj->sync_event);
|
|
|
-
|
|
|
- got_msg = true;
|
|
|
- }
|
|
|
+ if (!list_empty(&msg_queue_obj->msg_used_list)) {
|
|
|
+ msg_frame_obj = list_first_entry(&msg_queue_obj->msg_used_list,
|
|
|
+ struct msg_frame, list_elem);
|
|
|
+ list_del(&msg_frame_obj->list_elem);
|
|
|
+ *pmsg = msg_frame_obj->msg_data.msg;
|
|
|
+ list_add_tail(&msg_frame_obj->list_elem,
|
|
|
+ &msg_queue_obj->msg_free_list);
|
|
|
+ if (list_empty(&msg_queue_obj->msg_used_list))
|
|
|
+ sync_reset_event(msg_queue_obj->sync_event);
|
|
|
+
|
|
|
+ got_msg = true;
|
|
|
} else {
|
|
|
if (msg_queue_obj->done)
|
|
|
status = -EPERM;
|
|
@@ -349,25 +321,22 @@ int bridge_msg_get(struct msg_queue *msg_queue_obj,
|
|
|
(void)sync_set_event(msg_queue_obj->sync_done_ack);
|
|
|
status = -EPERM;
|
|
|
} else {
|
|
|
- if (!status) {
|
|
|
- DBC_ASSERT(!LST_IS_EMPTY
|
|
|
- (msg_queue_obj->msg_used_list));
|
|
|
+ if (!status && !list_empty(&msg_queue_obj->
|
|
|
+ msg_used_list)) {
|
|
|
/* Get msg from used list */
|
|
|
- msg_frame_obj = (struct msg_frame *)
|
|
|
- lst_get_head(msg_queue_obj->msg_used_list);
|
|
|
+ msg_frame_obj = list_first_entry(
|
|
|
+ &msg_queue_obj->msg_used_list,
|
|
|
+ struct msg_frame, list_elem);
|
|
|
+ list_del(&msg_frame_obj->list_elem);
|
|
|
/* Copy message into pmsg and put frame on the
|
|
|
* free list */
|
|
|
- if (msg_frame_obj != NULL) {
|
|
|
- *pmsg = msg_frame_obj->msg_data.msg;
|
|
|
- lst_put_tail
|
|
|
- (msg_queue_obj->msg_free_list,
|
|
|
- (struct list_head *)
|
|
|
- msg_frame_obj);
|
|
|
- }
|
|
|
+ *pmsg = msg_frame_obj->msg_data.msg;
|
|
|
+ list_add_tail(&msg_frame_obj->list_elem,
|
|
|
+ &msg_queue_obj->msg_free_list);
|
|
|
}
|
|
|
msg_queue_obj->io_msg_pend--;
|
|
|
/* Reset the event if there are still queued messages */
|
|
|
- if (!LST_IS_EMPTY(msg_queue_obj->msg_used_list))
|
|
|
+ if (!list_empty(&msg_queue_obj->msg_used_list))
|
|
|
sync_set_event(msg_queue_obj->sync_event);
|
|
|
|
|
|
/* Exit critical section */
|
|
@@ -397,27 +366,22 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj,
|
|
|
goto func_end;
|
|
|
}
|
|
|
hmsg_mgr = msg_queue_obj->hmsg_mgr;
|
|
|
- if (!hmsg_mgr->msg_free_list) {
|
|
|
- status = -EFAULT;
|
|
|
- goto func_end;
|
|
|
- }
|
|
|
|
|
|
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
|
|
|
|
|
|
/* If a message frame is available, use it */
|
|
|
- if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) {
|
|
|
- msg_frame_obj =
|
|
|
- (struct msg_frame *)lst_get_head(hmsg_mgr->msg_free_list);
|
|
|
- if (msg_frame_obj != NULL) {
|
|
|
- msg_frame_obj->msg_data.msg = *pmsg;
|
|
|
- msg_frame_obj->msg_data.msgq_id =
|
|
|
- msg_queue_obj->msgq_id;
|
|
|
- lst_put_tail(hmsg_mgr->msg_used_list,
|
|
|
- (struct list_head *)msg_frame_obj);
|
|
|
- hmsg_mgr->msgs_pending++;
|
|
|
- put_msg = true;
|
|
|
- }
|
|
|
- if (LST_IS_EMPTY(hmsg_mgr->msg_free_list))
|
|
|
+ if (!list_empty(&hmsg_mgr->msg_free_list)) {
|
|
|
+ msg_frame_obj = list_first_entry(&hmsg_mgr->msg_free_list,
|
|
|
+ struct msg_frame, list_elem);
|
|
|
+ list_del(&msg_frame_obj->list_elem);
|
|
|
+ msg_frame_obj->msg_data.msg = *pmsg;
|
|
|
+ msg_frame_obj->msg_data.msgq_id =
|
|
|
+ msg_queue_obj->msgq_id;
|
|
|
+ list_add_tail(&msg_frame_obj->list_elem,
|
|
|
+ &hmsg_mgr->msg_used_list);
|
|
|
+ hmsg_mgr->msgs_pending++;
|
|
|
+ put_msg = true;
|
|
|
+ if (list_empty(&hmsg_mgr->msg_free_list))
|
|
|
sync_reset_event(hmsg_mgr->sync_event);
|
|
|
|
|
|
/* Release critical section before scheduling DPC */
|
|
@@ -452,34 +416,34 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj,
|
|
|
(void)sync_set_event(msg_queue_obj->sync_done_ack);
|
|
|
status = -EPERM;
|
|
|
} else {
|
|
|
- if (LST_IS_EMPTY(hmsg_mgr->msg_free_list)) {
|
|
|
+ if (list_empty(&hmsg_mgr->msg_free_list)) {
|
|
|
status = -EFAULT;
|
|
|
goto func_cont;
|
|
|
}
|
|
|
/* Get msg from free list */
|
|
|
- msg_frame_obj = (struct msg_frame *)
|
|
|
- lst_get_head(hmsg_mgr->msg_free_list);
|
|
|
+ msg_frame_obj = list_first_entry(
|
|
|
+ &hmsg_mgr->msg_free_list,
|
|
|
+ struct msg_frame, list_elem);
|
|
|
+ list_del(&msg_frame_obj->list_elem);
|
|
|
/*
|
|
|
* Copy message into pmsg and put frame on the
|
|
|
* used list.
|
|
|
*/
|
|
|
- if (msg_frame_obj) {
|
|
|
- msg_frame_obj->msg_data.msg = *pmsg;
|
|
|
- msg_frame_obj->msg_data.msgq_id =
|
|
|
- msg_queue_obj->msgq_id;
|
|
|
- lst_put_tail(hmsg_mgr->msg_used_list,
|
|
|
- (struct list_head *)msg_frame_obj);
|
|
|
- hmsg_mgr->msgs_pending++;
|
|
|
- /*
|
|
|
- * Schedule a DPC, to do the actual
|
|
|
- * data transfer.
|
|
|
- */
|
|
|
- iosm_schedule(hmsg_mgr->hio_mgr);
|
|
|
- }
|
|
|
+ msg_frame_obj->msg_data.msg = *pmsg;
|
|
|
+ msg_frame_obj->msg_data.msgq_id =
|
|
|
+ msg_queue_obj->msgq_id;
|
|
|
+ list_add_tail(&msg_frame_obj->list_elem,
|
|
|
+ &hmsg_mgr->msg_used_list);
|
|
|
+ hmsg_mgr->msgs_pending++;
|
|
|
+ /*
|
|
|
+ * Schedule a DPC, to do the actual
|
|
|
+ * data transfer.
|
|
|
+ */
|
|
|
+ iosm_schedule(hmsg_mgr->hio_mgr);
|
|
|
|
|
|
msg_queue_obj->io_msg_pend--;
|
|
|
/* Reset event if there are still frames available */
|
|
|
- if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list))
|
|
|
+ if (!list_empty(&hmsg_mgr->msg_free_list))
|
|
|
sync_set_event(hmsg_mgr->sync_event);
|
|
|
func_cont:
|
|
|
/* Exit critical section */
|
|
@@ -551,15 +515,14 @@ void bridge_msg_set_queue_id(struct msg_queue *msg_queue_obj, u32 msgq_id)
|
|
|
* ======== add_new_msg ========
|
|
|
* Must be called in message manager critical section.
|
|
|
*/
|
|
|
-static int add_new_msg(struct lst_list *msg_list)
|
|
|
+static int add_new_msg(struct list_head *msg_list)
|
|
|
{
|
|
|
struct msg_frame *pmsg;
|
|
|
int status = 0;
|
|
|
|
|
|
pmsg = kzalloc(sizeof(struct msg_frame), GFP_ATOMIC);
|
|
|
if (pmsg != NULL) {
|
|
|
- lst_init_elem((struct list_head *)pmsg);
|
|
|
- lst_put_tail(msg_list, (struct list_head *)pmsg);
|
|
|
+ list_add_tail(&pmsg->list_elem, msg_list);
|
|
|
} else {
|
|
|
status = -ENOMEM;
|
|
|
}
|
|
@@ -575,22 +538,9 @@ static void delete_msg_mgr(struct msg_mgr *hmsg_mgr)
|
|
|
if (!hmsg_mgr)
|
|
|
goto func_end;
|
|
|
|
|
|
- if (hmsg_mgr->queue_list) {
|
|
|
- if (LST_IS_EMPTY(hmsg_mgr->queue_list)) {
|
|
|
- kfree(hmsg_mgr->queue_list);
|
|
|
- hmsg_mgr->queue_list = NULL;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (hmsg_mgr->msg_free_list) {
|
|
|
- free_msg_list(hmsg_mgr->msg_free_list);
|
|
|
- hmsg_mgr->msg_free_list = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- if (hmsg_mgr->msg_used_list) {
|
|
|
- free_msg_list(hmsg_mgr->msg_used_list);
|
|
|
- hmsg_mgr->msg_used_list = NULL;
|
|
|
- }
|
|
|
+ /* FIXME: free elements from queue_list? */
|
|
|
+ free_msg_list(&hmsg_mgr->msg_free_list);
|
|
|
+ free_msg_list(&hmsg_mgr->msg_used_list);
|
|
|
|
|
|
kfree(hmsg_mgr->sync_event);
|
|
|
|
|
@@ -605,37 +555,26 @@ func_end:
|
|
|
static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp)
|
|
|
{
|
|
|
struct msg_mgr *hmsg_mgr;
|
|
|
- struct msg_frame *pmsg;
|
|
|
+ struct msg_frame *pmsg, *tmp;
|
|
|
u32 i;
|
|
|
|
|
|
- if (!msg_queue_obj ||
|
|
|
- !msg_queue_obj->hmsg_mgr || !msg_queue_obj->hmsg_mgr->msg_free_list)
|
|
|
+ if (!msg_queue_obj || !msg_queue_obj->hmsg_mgr)
|
|
|
goto func_end;
|
|
|
|
|
|
hmsg_mgr = msg_queue_obj->hmsg_mgr;
|
|
|
|
|
|
/* Pull off num_to_dsp message frames from Msg manager and free */
|
|
|
- for (i = 0; i < num_to_dsp; i++) {
|
|
|
-
|
|
|
- if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) {
|
|
|
- pmsg = (struct msg_frame *)
|
|
|
- lst_get_head(hmsg_mgr->msg_free_list);
|
|
|
- kfree(pmsg);
|
|
|
- } else {
|
|
|
- /* Cannot free all of the message frames */
|
|
|
+ i = 0;
|
|
|
+ list_for_each_entry_safe(pmsg, tmp, &hmsg_mgr->msg_free_list,
|
|
|
+ list_elem) {
|
|
|
+ list_del(&pmsg->list_elem);
|
|
|
+ kfree(pmsg);
|
|
|
+ if (i++ >= num_to_dsp)
|
|
|
break;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
- if (msg_queue_obj->msg_free_list) {
|
|
|
- free_msg_list(msg_queue_obj->msg_free_list);
|
|
|
- msg_queue_obj->msg_free_list = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- if (msg_queue_obj->msg_used_list) {
|
|
|
- free_msg_list(msg_queue_obj->msg_used_list);
|
|
|
- msg_queue_obj->msg_used_list = NULL;
|
|
|
- }
|
|
|
+ free_msg_list(&msg_queue_obj->msg_free_list);
|
|
|
+ free_msg_list(&msg_queue_obj->msg_used_list);
|
|
|
|
|
|
if (msg_queue_obj->ntfy_obj) {
|
|
|
ntfy_delete(msg_queue_obj->ntfy_obj);
|
|
@@ -655,19 +594,18 @@ func_end:
|
|
|
/*
|
|
|
* ======== free_msg_list ========
|
|
|
*/
|
|
|
-static void free_msg_list(struct lst_list *msg_list)
|
|
|
+static void free_msg_list(struct list_head *msg_list)
|
|
|
{
|
|
|
- struct msg_frame *pmsg;
|
|
|
+ struct msg_frame *pmsg, *tmp;
|
|
|
|
|
|
if (!msg_list)
|
|
|
goto func_end;
|
|
|
|
|
|
- while ((pmsg = (struct msg_frame *)lst_get_head(msg_list)) != NULL)
|
|
|
+ list_for_each_entry_safe(pmsg, tmp, msg_list, list_elem) {
|
|
|
+ list_del(&pmsg->list_elem);
|
|
|
kfree(pmsg);
|
|
|
+ }
|
|
|
|
|
|
- DBC_ASSERT(LST_IS_EMPTY(msg_list));
|
|
|
-
|
|
|
- kfree(msg_list);
|
|
|
func_end:
|
|
|
return;
|
|
|
}
|