aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/tidspbridge/core
diff options
context:
space:
mode:
authorIonut Nicu <ionut.nicu@gmail.com>2010-11-21 05:46:24 -0500
committerOmar Ramirez Luna <omar.ramirez@ti.com>2011-02-04 21:11:35 -0500
commit3c6bf30f1e520b250242da39a493986b8b2cef53 (patch)
tree9fdeb810a478c67530e3fe4a77b7a67ba773729d /drivers/staging/tidspbridge/core
parent6d7e925b88cd8436b1284158876580ea431cb954 (diff)
staging: tidspbridge: convert core to list_head
Convert the core module of the tidspbridge driver to use struct list_head instead of struct lst_list. Signed-off-by: Ionut Nicu <ionut.nicu@mindbit.ro> Signed-off-by: Omar Ramirez Luna <omar.ramirez@ti.com>
Diffstat (limited to 'drivers/staging/tidspbridge/core')
-rw-r--r--drivers/staging/tidspbridge/core/_msg_sm.h12
-rw-r--r--drivers/staging/tidspbridge/core/chnl_sm.c245
-rw-r--r--drivers/staging/tidspbridge/core/io_sm.c142
-rw-r--r--drivers/staging/tidspbridge/core/msg_sm.c236
4 files changed, 259 insertions, 376 deletions
diff --git a/drivers/staging/tidspbridge/core/_msg_sm.h b/drivers/staging/tidspbridge/core/_msg_sm.h
index 556de5c025d..b78d1a65530 100644
--- a/drivers/staging/tidspbridge/core/_msg_sm.h
+++ b/drivers/staging/tidspbridge/core/_msg_sm.h
@@ -20,7 +20,7 @@
20#ifndef _MSG_SM_ 20#ifndef _MSG_SM_
21#define _MSG_SM_ 21#define _MSG_SM_
22 22
23#include <dspbridge/list.h> 23#include <linux/list.h>
24#include <dspbridge/msgdefs.h> 24#include <dspbridge/msgdefs.h>
25 25
26/* 26/*
@@ -86,12 +86,12 @@ struct msg_mgr {
86 struct bridge_drv_interface *intf_fxns; 86 struct bridge_drv_interface *intf_fxns;
87 87
88 struct io_mgr *hio_mgr; /* IO manager */ 88 struct io_mgr *hio_mgr; /* IO manager */
89 struct lst_list *queue_list; /* List of MSG_QUEUEs */ 89 struct list_head queue_list; /* List of MSG_QUEUEs */
90 spinlock_t msg_mgr_lock; /* For critical sections */ 90 spinlock_t msg_mgr_lock; /* For critical sections */
91 /* Signalled when MsgFrame is available */ 91 /* Signalled when MsgFrame is available */
92 struct sync_object *sync_event; 92 struct sync_object *sync_event;
93 struct lst_list *msg_free_list; /* Free MsgFrames ready to be filled */ 93 struct list_head msg_free_list; /* Free MsgFrames ready to be filled */
94 struct lst_list *msg_used_list; /* MsgFrames ready to go to DSP */ 94 struct list_head msg_used_list; /* MsgFrames ready to go to DSP */
95 u32 msgs_pending; /* # of queued messages to go to DSP */ 95 u32 msgs_pending; /* # of queued messages to go to DSP */
96 u32 max_msgs; /* Max # of msgs that fit in buffer */ 96 u32 max_msgs; /* Max # of msgs that fit in buffer */
97 msg_onexit on_exit; /* called when RMS_EXIT is received */ 97 msg_onexit on_exit; /* called when RMS_EXIT is received */
@@ -111,9 +111,9 @@ struct msg_queue {
111 struct msg_mgr *hmsg_mgr; 111 struct msg_mgr *hmsg_mgr;
112 u32 max_msgs; /* Node message depth */ 112 u32 max_msgs; /* Node message depth */
113 u32 msgq_id; /* Node environment pointer */ 113 u32 msgq_id; /* Node environment pointer */
114 struct lst_list *msg_free_list; /* Free MsgFrames ready to be filled */ 114 struct list_head msg_free_list; /* Free MsgFrames ready to be filled */
115 /* Filled MsgFramess waiting to be read */ 115 /* Filled MsgFramess waiting to be read */
116 struct lst_list *msg_used_list; 116 struct list_head msg_used_list;
117 void *arg; /* Handle passed to mgr on_exit callback */ 117 void *arg; /* Handle passed to mgr on_exit callback */
118 struct sync_object *sync_event; /* Signalled when message is ready */ 118 struct sync_object *sync_event; /* Signalled when message is ready */
119 struct sync_object *sync_done; /* For synchronizing cleanup */ 119 struct sync_object *sync_done; /* For synchronizing cleanup */
diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c
index 662a5b5a58e..f9550363b94 100644
--- a/drivers/staging/tidspbridge/core/chnl_sm.c
+++ b/drivers/staging/tidspbridge/core/chnl_sm.c
@@ -37,9 +37,9 @@
37 * which may cause timeouts and/or failure offunction sync_wait_on_event. 37 * which may cause timeouts and/or failure offunction sync_wait_on_event.
38 * This invariant condition is: 38 * This invariant condition is:
39 * 39 *
40 * LST_Empty(pchnl->pio_completions) ==> pchnl->sync_event is reset 40 * list_empty(&pchnl->pio_completions) ==> pchnl->sync_event is reset
41 * and 41 * and
42 * !LST_Empty(pchnl->pio_completions) ==> pchnl->sync_event is set. 42 * !list_empty(&pchnl->pio_completions) ==> pchnl->sync_event is set.
43 */ 43 */
44 44
45#include <linux/types.h> 45#include <linux/types.h>
@@ -73,11 +73,9 @@
73#define MAILBOX_IRQ INT_MAIL_MPU_IRQ 73#define MAILBOX_IRQ INT_MAIL_MPU_IRQ
74 74
75/* ----------------------------------- Function Prototypes */ 75/* ----------------------------------- Function Prototypes */
76static struct lst_list *create_chirp_list(u32 chirps); 76static int create_chirp_list(struct list_head *list, u32 chirps);
77 77
78static void free_chirp_list(struct lst_list *chirp_list); 78static void free_chirp_list(struct list_head *list);
79
80static struct chnl_irp *make_new_chirp(void);
81 79
82static int search_free_channel(struct chnl_mgr *chnl_mgr_obj, 80static int search_free_channel(struct chnl_mgr *chnl_mgr_obj,
83 u32 *chnl); 81 u32 *chnl);
@@ -179,10 +177,14 @@ func_cont:
179 } 177 }
180 if (!status) { 178 if (!status) {
181 /* Get a free chirp: */ 179 /* Get a free chirp: */
182 chnl_packet_obj = 180 if (!list_empty(&pchnl->free_packets_list)) {
183 (struct chnl_irp *)lst_get_head(pchnl->free_packets_list); 181 chnl_packet_obj = list_first_entry(
184 if (chnl_packet_obj == NULL) 182 &pchnl->free_packets_list,
183 struct chnl_irp, link);
184 list_del(&chnl_packet_obj->link);
185 } else {
185 status = -EIO; 186 status = -EIO;
187 }
186 188
187 } 189 }
188 if (!status) { 190 if (!status) {
@@ -206,8 +208,7 @@ func_cont:
206 chnl_packet_obj->dw_arg = dw_arg; 208 chnl_packet_obj->dw_arg = dw_arg;
207 chnl_packet_obj->status = (is_eos ? CHNL_IOCSTATEOS : 209 chnl_packet_obj->status = (is_eos ? CHNL_IOCSTATEOS :
208 CHNL_IOCSTATCOMPLETE); 210 CHNL_IOCSTATCOMPLETE);
209 lst_put_tail(pchnl->pio_requests, 211 list_add_tail(&chnl_packet_obj->link, &pchnl->pio_requests);
210 (struct list_head *)chnl_packet_obj);
211 pchnl->cio_reqs++; 212 pchnl->cio_reqs++;
212 DBC_ASSERT(pchnl->cio_reqs <= pchnl->chnl_packets); 213 DBC_ASSERT(pchnl->cio_reqs <= pchnl->chnl_packets);
213 /* 214 /*
@@ -254,7 +255,7 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj)
254 struct chnl_object *pchnl = (struct chnl_object *)chnl_obj; 255 struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
255 u32 chnl_id = -1; 256 u32 chnl_id = -1;
256 s8 chnl_mode; 257 s8 chnl_mode;
257 struct chnl_irp *chnl_packet_obj; 258 struct chnl_irp *chirp, *tmp;
258 struct chnl_mgr *chnl_mgr_obj = NULL; 259 struct chnl_mgr *chnl_mgr_obj = NULL;
259 260
260 /* Check args: */ 261 /* Check args: */
@@ -272,7 +273,7 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj)
272 * IORequests or dispatching. */ 273 * IORequests or dispatching. */
273 spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock); 274 spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock);
274 pchnl->dw_state |= CHNL_STATECANCEL; 275 pchnl->dw_state |= CHNL_STATECANCEL;
275 if (LST_IS_EMPTY(pchnl->pio_requests)) 276 if (list_empty(&pchnl->pio_requests))
276 goto func_cont; 277 goto func_cont;
277 278
278 if (pchnl->chnl_type == CHNL_PCPY) { 279 if (pchnl->chnl_type == CHNL_PCPY) {
@@ -286,18 +287,14 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj)
286 } 287 }
287 } 288 }
288 /* Move all IOR's to IOC queue: */ 289 /* Move all IOR's to IOC queue: */
289 while (!LST_IS_EMPTY(pchnl->pio_requests)) { 290 list_for_each_entry_safe(chirp, tmp, &pchnl->pio_requests, link) {
290 chnl_packet_obj = 291 list_del(&chirp->link);
291 (struct chnl_irp *)lst_get_head(pchnl->pio_requests); 292 chirp->byte_size = 0;
292 if (chnl_packet_obj) { 293 chirp->status |= CHNL_IOCSTATCANCEL;
293 chnl_packet_obj->byte_size = 0; 294 list_add_tail(&chirp->link, &pchnl->pio_completions);
294 chnl_packet_obj->status |= CHNL_IOCSTATCANCEL; 295 pchnl->cio_cs++;
295 lst_put_tail(pchnl->pio_completions, 296 pchnl->cio_reqs--;
296 (struct list_head *)chnl_packet_obj); 297 DBC_ASSERT(pchnl->cio_reqs >= 0);
297 pchnl->cio_cs++;
298 pchnl->cio_reqs--;
299 DBC_ASSERT(pchnl->cio_reqs >= 0);
300 }
301 } 298 }
302func_cont: 299func_cont:
303 spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); 300 spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock);
@@ -353,20 +350,14 @@ func_cont:
353 pchnl->sync_event = NULL; 350 pchnl->sync_event = NULL;
354 } 351 }
355 /* Free I/O request and I/O completion queues: */ 352 /* Free I/O request and I/O completion queues: */
356 if (pchnl->pio_completions) { 353 free_chirp_list(&pchnl->pio_completions);
357 free_chirp_list(pchnl->pio_completions); 354 pchnl->cio_cs = 0;
358 pchnl->pio_completions = NULL; 355
359 pchnl->cio_cs = 0; 356 free_chirp_list(&pchnl->pio_requests);
360 } 357 pchnl->cio_reqs = 0;
361 if (pchnl->pio_requests) { 358
362 free_chirp_list(pchnl->pio_requests); 359 free_chirp_list(&pchnl->free_packets_list);
363 pchnl->pio_requests = NULL; 360
364 pchnl->cio_reqs = 0;
365 }
366 if (pchnl->free_packets_list) {
367 free_chirp_list(pchnl->free_packets_list);
368 pchnl->free_packets_list = NULL;
369 }
370 /* Release channel object. */ 361 /* Release channel object. */
371 kfree(pchnl); 362 kfree(pchnl);
372 pchnl = NULL; 363 pchnl = NULL;
@@ -505,7 +496,7 @@ int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout)
505 && (pchnl->chnl_type == CHNL_PCPY)) { 496 && (pchnl->chnl_type == CHNL_PCPY)) {
506 /* Wait for IO completions, up to the specified 497 /* Wait for IO completions, up to the specified
507 * timeout: */ 498 * timeout: */
508 while (!LST_IS_EMPTY(pchnl->pio_requests) && !status) { 499 while (!list_empty(&pchnl->pio_requests) && !status) {
509 status = bridge_chnl_get_ioc(chnl_obj, 500 status = bridge_chnl_get_ioc(chnl_obj,
510 timeout, &chnl_ioc_obj); 501 timeout, &chnl_ioc_obj);
511 if (status) 502 if (status)
@@ -521,7 +512,7 @@ int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout)
521 pchnl->dw_state &= ~CHNL_STATECANCEL; 512 pchnl->dw_state &= ~CHNL_STATECANCEL;
522 } 513 }
523 } 514 }
524 DBC_ENSURE(status || LST_IS_EMPTY(pchnl->pio_requests)); 515 DBC_ENSURE(status || list_empty(&pchnl->pio_requests));
525 return status; 516 return status;
526} 517}
527 518
@@ -581,7 +572,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout,
581 if (!chan_ioc || !pchnl) { 572 if (!chan_ioc || !pchnl) {
582 status = -EFAULT; 573 status = -EFAULT;
583 } else if (timeout == CHNL_IOCNOWAIT) { 574 } else if (timeout == CHNL_IOCNOWAIT) {
584 if (LST_IS_EMPTY(pchnl->pio_completions)) 575 if (list_empty(&pchnl->pio_completions))
585 status = -EREMOTEIO; 576 status = -EREMOTEIO;
586 577
587 } 578 }
@@ -596,7 +587,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout,
596 587
597 ioc.status = CHNL_IOCSTATCOMPLETE; 588 ioc.status = CHNL_IOCSTATCOMPLETE;
598 if (timeout != 589 if (timeout !=
599 CHNL_IOCNOWAIT && LST_IS_EMPTY(pchnl->pio_completions)) { 590 CHNL_IOCNOWAIT && list_empty(&pchnl->pio_completions)) {
600 if (timeout == CHNL_IOCINFINITE) 591 if (timeout == CHNL_IOCINFINITE)
601 timeout = SYNC_INFINITE; 592 timeout = SYNC_INFINITE;
602 593
@@ -611,7 +602,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout,
611 * fails due to unkown causes. */ 602 * fails due to unkown causes. */
612 /* Even though Wait failed, there may be something in 603 /* Even though Wait failed, there may be something in
613 * the Q: */ 604 * the Q: */
614 if (LST_IS_EMPTY(pchnl->pio_completions)) { 605 if (list_empty(&pchnl->pio_completions)) {
615 ioc.status |= CHNL_IOCSTATCANCEL; 606 ioc.status |= CHNL_IOCSTATCANCEL;
616 dequeue_ioc = false; 607 dequeue_ioc = false;
617 } 608 }
@@ -622,30 +613,26 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout,
622 omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX); 613 omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX);
623 if (dequeue_ioc) { 614 if (dequeue_ioc) {
624 /* Dequeue IOC and set chan_ioc; */ 615 /* Dequeue IOC and set chan_ioc; */
625 DBC_ASSERT(!LST_IS_EMPTY(pchnl->pio_completions)); 616 DBC_ASSERT(!list_empty(&pchnl->pio_completions));
626 chnl_packet_obj = 617 chnl_packet_obj = list_first_entry(&pchnl->pio_completions,
627 (struct chnl_irp *)lst_get_head(pchnl->pio_completions); 618 struct chnl_irp, link);
619 list_del(&chnl_packet_obj->link);
628 /* Update chan_ioc from channel state and chirp: */ 620 /* Update chan_ioc from channel state and chirp: */
629 if (chnl_packet_obj) { 621 pchnl->cio_cs--;
630 pchnl->cio_cs--; 622 /*
631 /* If this is a zero-copy channel, then set IOC's pbuf 623 * If this is a zero-copy channel, then set IOC's pbuf
632 * to the DSP's address. This DSP address will get 624 * to the DSP's address. This DSP address will get
633 * translated to user's virtual addr later. */ 625 * translated to user's virtual addr later.
634 { 626 */
635 host_sys_buf = chnl_packet_obj->host_sys_buf; 627 host_sys_buf = chnl_packet_obj->host_sys_buf;
636 ioc.pbuf = chnl_packet_obj->host_user_buf; 628 ioc.pbuf = chnl_packet_obj->host_user_buf;
637 } 629 ioc.byte_size = chnl_packet_obj->byte_size;
638 ioc.byte_size = chnl_packet_obj->byte_size; 630 ioc.buf_size = chnl_packet_obj->buf_size;
639 ioc.buf_size = chnl_packet_obj->buf_size; 631 ioc.dw_arg = chnl_packet_obj->dw_arg;
640 ioc.dw_arg = chnl_packet_obj->dw_arg; 632 ioc.status |= chnl_packet_obj->status;
641 ioc.status |= chnl_packet_obj->status; 633 /* Place the used chirp on the free list: */
642 /* Place the used chirp on the free list: */ 634 list_add_tail(&chnl_packet_obj->link,
643 lst_put_tail(pchnl->free_packets_list, 635 &pchnl->free_packets_list);
644 (struct list_head *)chnl_packet_obj);
645 } else {
646 ioc.pbuf = NULL;
647 ioc.byte_size = 0;
648 }
649 } else { 636 } else {
650 ioc.pbuf = NULL; 637 ioc.pbuf = NULL;
651 ioc.byte_size = 0; 638 ioc.byte_size = 0;
@@ -653,7 +640,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout,
653 ioc.buf_size = 0; 640 ioc.buf_size = 0;
654 } 641 }
655 /* Ensure invariant: If any IOC's are queued for this channel... */ 642 /* Ensure invariant: If any IOC's are queued for this channel... */
656 if (!LST_IS_EMPTY(pchnl->pio_completions)) { 643 if (!list_empty(&pchnl->pio_completions)) {
657 /* Since DSPStream_Reclaim() does not take a timeout 644 /* Since DSPStream_Reclaim() does not take a timeout
658 * parameter, we pass the stream's timeout value to 645 * parameter, we pass the stream's timeout value to
659 * bridge_chnl_get_ioc. We cannot determine whether or not 646 * bridge_chnl_get_ioc. We cannot determine whether or not
@@ -818,9 +805,16 @@ int bridge_chnl_open(struct chnl_object **chnl,
818 /* Protect queues from io_dpc: */ 805 /* Protect queues from io_dpc: */
819 pchnl->dw_state = CHNL_STATECANCEL; 806 pchnl->dw_state = CHNL_STATECANCEL;
820 /* Allocate initial IOR and IOC queues: */ 807 /* Allocate initial IOR and IOC queues: */
821 pchnl->free_packets_list = create_chirp_list(pattrs->uio_reqs); 808 status = create_chirp_list(&pchnl->free_packets_list,
822 pchnl->pio_requests = create_chirp_list(0); 809 pattrs->uio_reqs);
823 pchnl->pio_completions = create_chirp_list(0); 810 if (status) {
811 kfree(pchnl);
812 goto func_end;
813 }
814
815 INIT_LIST_HEAD(&pchnl->pio_requests);
816 INIT_LIST_HEAD(&pchnl->pio_completions);
817
824 pchnl->chnl_packets = pattrs->uio_reqs; 818 pchnl->chnl_packets = pattrs->uio_reqs;
825 pchnl->cio_cs = 0; 819 pchnl->cio_cs = 0;
826 pchnl->cio_reqs = 0; 820 pchnl->cio_reqs = 0;
@@ -840,40 +834,26 @@ int bridge_chnl_open(struct chnl_object **chnl,
840 } 834 }
841 835
842 if (!status) { 836 if (!status) {
843 if (pchnl->pio_completions && pchnl->pio_requests && 837 /* Initialize CHNL object fields: */
844 pchnl->free_packets_list) { 838 pchnl->chnl_mgr_obj = chnl_mgr_obj;
845 /* Initialize CHNL object fields: */ 839 pchnl->chnl_id = ch_id;
846 pchnl->chnl_mgr_obj = chnl_mgr_obj; 840 pchnl->chnl_mode = chnl_mode;
847 pchnl->chnl_id = ch_id; 841 pchnl->user_event = sync_event;
848 pchnl->chnl_mode = chnl_mode; 842 pchnl->sync_event = sync_event;
849 pchnl->user_event = sync_event; 843 /* Get the process handle */
850 pchnl->sync_event = sync_event; 844 pchnl->process = current->tgid;
851 /* Get the process handle */ 845 pchnl->pcb_arg = 0;
852 pchnl->process = current->tgid; 846 pchnl->bytes_moved = 0;
853 pchnl->pcb_arg = 0; 847 /* Default to proc-copy */
854 pchnl->bytes_moved = 0; 848 pchnl->chnl_type = CHNL_PCPY;
855 /* Default to proc-copy */
856 pchnl->chnl_type = CHNL_PCPY;
857 } else {
858 status = -ENOMEM;
859 }
860 } 849 }
861 850
862 if (status) { 851 if (status) {
863 /* Free memory */ 852 /* Free memory */
864 if (pchnl->pio_completions) { 853 free_chirp_list(&pchnl->pio_completions);
865 free_chirp_list(pchnl->pio_completions); 854 pchnl->cio_cs = 0;
866 pchnl->pio_completions = NULL; 855 free_chirp_list(&pchnl->pio_requests);
867 pchnl->cio_cs = 0; 856 free_chirp_list(&pchnl->free_packets_list);
868 }
869 if (pchnl->pio_requests) {
870 free_chirp_list(pchnl->pio_requests);
871 pchnl->pio_requests = NULL;
872 }
873 if (pchnl->free_packets_list) {
874 free_chirp_list(pchnl->free_packets_list);
875 pchnl->free_packets_list = NULL;
876 }
877 kfree(sync_event); 857 kfree(sync_event);
878 sync_event = NULL; 858 sync_event = NULL;
879 859
@@ -924,37 +904,35 @@ int bridge_chnl_register_notify(struct chnl_object *chnl_obj,
924 * Purpose: 904 * Purpose:
925 * Initialize a queue of channel I/O Request/Completion packets. 905 * Initialize a queue of channel I/O Request/Completion packets.
926 * Parameters: 906 * Parameters:
907 * list: Pointer to a list_head
927 * chirps: Number of Chirps to allocate. 908 * chirps: Number of Chirps to allocate.
928 * Returns: 909 * Returns:
929 * Pointer to queue of IRPs, or NULL. 910 * 0 if successful, error code otherwise.
930 * Requires: 911 * Requires:
931 * Ensures: 912 * Ensures:
932 */ 913 */
933static struct lst_list *create_chirp_list(u32 chirps) 914static int create_chirp_list(struct list_head *list, u32 chirps)
934{ 915{
935 struct lst_list *chirp_list; 916 struct chnl_irp *chirp;
936 struct chnl_irp *chnl_packet_obj;
937 u32 i; 917 u32 i;
938 918
939 chirp_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL); 919 INIT_LIST_HEAD(list);
940 920
941 if (chirp_list) { 921 /* Make N chirps and place on queue. */
942 INIT_LIST_HEAD(&chirp_list->head); 922 for (i = 0; i < chirps; i++) {
943 /* Make N chirps and place on queue. */ 923 chirp = kzalloc(sizeof(struct chnl_irp), GFP_KERNEL);
944 for (i = 0; (i < chirps) 924 if (!chirp)
945 && ((chnl_packet_obj = make_new_chirp()) != NULL); i++) { 925 break;
946 lst_put_tail(chirp_list, 926 list_add_tail(&chirp->link, list);
947 (struct list_head *)chnl_packet_obj); 927 }
948 }
949 928
950 /* If we couldn't allocate all chirps, free those allocated: */ 929 /* If we couldn't allocate all chirps, free those allocated: */
951 if (i != chirps) { 930 if (i != chirps) {
952 free_chirp_list(chirp_list); 931 free_chirp_list(list);
953 chirp_list = NULL; 932 return -ENOMEM;
954 }
955 } 933 }
956 934
957 return chirp_list; 935 return 0;
958} 936}
959 937
960/* 938/*
@@ -962,31 +940,16 @@ static struct lst_list *create_chirp_list(u32 chirps)
962 * Purpose: 940 * Purpose:
963 * Free the queue of Chirps. 941 * Free the queue of Chirps.
964 */ 942 */
965static void free_chirp_list(struct lst_list *chirp_list) 943static void free_chirp_list(struct list_head *chirp_list)
966{ 944{
967 DBC_REQUIRE(chirp_list != NULL); 945 struct chnl_irp *chirp, *tmp;
968
969 while (!LST_IS_EMPTY(chirp_list))
970 kfree(lst_get_head(chirp_list));
971 946
972 kfree(chirp_list); 947 DBC_REQUIRE(chirp_list != NULL);
973}
974
975/*
976 * ======== make_new_chirp ========
977 * Allocate the memory for a new channel IRP.
978 */
979static struct chnl_irp *make_new_chirp(void)
980{
981 struct chnl_irp *chnl_packet_obj;
982 948
983 chnl_packet_obj = kzalloc(sizeof(struct chnl_irp), GFP_KERNEL); 949 list_for_each_entry_safe(chirp, tmp, chirp_list, link) {
984 if (chnl_packet_obj != NULL) { 950 list_del(&chirp->link);
985 /* lst_init_elem only resets the list's member values. */ 951 kfree(chirp);
986 lst_init_elem(&chnl_packet_obj->link);
987 } 952 }
988
989 return chnl_packet_obj;
990} 953}
991 954
992/* 955/*
diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c
index 9cea3eacf1a..2a48f3db0e2 100644
--- a/drivers/staging/tidspbridge/core/io_sm.c
+++ b/drivers/staging/tidspbridge/core/io_sm.c
@@ -24,6 +24,7 @@
24 * function. 24 * function.
25 */ 25 */
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/list.h>
27 28
28/* Host OS */ 29/* Host OS */
29#include <dspbridge/host_os.h> 30#include <dspbridge/host_os.h>
@@ -1092,15 +1093,17 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
1092 pchnl = chnl_mgr_obj->ap_channel[chnl_id]; 1093 pchnl = chnl_mgr_obj->ap_channel[chnl_id];
1093 if ((pchnl != NULL) && CHNL_IS_INPUT(pchnl->chnl_mode)) { 1094 if ((pchnl != NULL) && CHNL_IS_INPUT(pchnl->chnl_mode)) {
1094 if ((pchnl->dw_state & ~CHNL_STATEEOS) == CHNL_STATEREADY) { 1095 if ((pchnl->dw_state & ~CHNL_STATEEOS) == CHNL_STATEREADY) {
1095 if (!pchnl->pio_requests)
1096 goto func_end;
1097 /* Get the I/O request, and attempt a transfer */ 1096 /* Get the I/O request, and attempt a transfer */
1098 chnl_packet_obj = (struct chnl_irp *) 1097 if (!list_empty(&pchnl->pio_requests)) {
1099 lst_get_head(pchnl->pio_requests); 1098 if (!pchnl->cio_reqs)
1100 if (chnl_packet_obj) {
1101 pchnl->cio_reqs--;
1102 if (pchnl->cio_reqs < 0)
1103 goto func_end; 1099 goto func_end;
1100
1101 chnl_packet_obj = list_first_entry(
1102 &pchnl->pio_requests,
1103 struct chnl_irp, link);
1104 list_del(&chnl_packet_obj->link);
1105 pchnl->cio_reqs--;
1106
1104 /* 1107 /*
1105 * Ensure we don't overflow the client's 1108 * Ensure we don't overflow the client's
1106 * buffer. 1109 * buffer.
@@ -1127,21 +1130,18 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
1127 * the channel state. 1130 * the channel state.
1128 */ 1131 */
1129 chnl_packet_obj->status |= 1132 chnl_packet_obj->status |=
1130 CHNL_IOCSTATEOS; 1133 CHNL_IOCSTATEOS;
1131 pchnl->dw_state |= CHNL_STATEEOS; 1134 pchnl->dw_state |= CHNL_STATEEOS;
1132 /* 1135 /*
1133 * Notify that end of stream has 1136 * Notify that end of stream has
1134 * occurred. 1137 * occurred.
1135 */ 1138 */
1136 ntfy_notify(pchnl->ntfy_obj, 1139 ntfy_notify(pchnl->ntfy_obj,
1137 DSP_STREAMDONE); 1140 DSP_STREAMDONE);
1138 } 1141 }
1139 /* Tell DSP if no more I/O buffers available */ 1142 /* Tell DSP if no more I/O buffers available */
1140 if (!pchnl->pio_requests) 1143 if (list_empty(&pchnl->pio_requests))
1141 goto func_end;
1142 if (LST_IS_EMPTY(pchnl->pio_requests)) {
1143 set_chnl_free(sm, pchnl->chnl_id); 1144 set_chnl_free(sm, pchnl->chnl_id);
1144 }
1145 clear_chnl = true; 1145 clear_chnl = true;
1146 notify_client = true; 1146 notify_client = true;
1147 } else { 1147 } else {
@@ -1213,21 +1213,18 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr)
1213 msg.msgq_id = 1213 msg.msgq_id =
1214 read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); 1214 read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr);
1215 msg_input += sizeof(struct msg_dspmsg); 1215 msg_input += sizeof(struct msg_dspmsg);
1216 if (!hmsg_mgr->queue_list)
1217 goto func_end;
1218 1216
1219 /* Determine which queue to put the message in */ 1217 /* Determine which queue to put the message in */
1220 msg_queue_obj =
1221 (struct msg_queue *)lst_first(hmsg_mgr->queue_list);
1222 dev_dbg(bridge, "input msg: dw_cmd=0x%x dw_arg1=0x%x " 1218 dev_dbg(bridge, "input msg: dw_cmd=0x%x dw_arg1=0x%x "
1223 "dw_arg2=0x%x msgq_id=0x%x \n", msg.msg.dw_cmd, 1219 "dw_arg2=0x%x msgq_id=0x%x\n", msg.msg.dw_cmd,
1224 msg.msg.dw_arg1, msg.msg.dw_arg2, msg.msgq_id); 1220 msg.msg.dw_arg1, msg.msg.dw_arg2, msg.msgq_id);
1225 /* 1221 /*
1226 * Interrupt may occur before shared memory and message 1222 * Interrupt may occur before shared memory and message
1227 * input locations have been set up. If all nodes were 1223 * input locations have been set up. If all nodes were
1228 * cleaned up, hmsg_mgr->max_msgs should be 0. 1224 * cleaned up, hmsg_mgr->max_msgs should be 0.
1229 */ 1225 */
1230 while (msg_queue_obj != NULL) { 1226 list_for_each_entry(msg_queue_obj, &hmsg_mgr->queue_list,
1227 list_elem) {
1231 if (msg.msgq_id == msg_queue_obj->msgq_id) { 1228 if (msg.msgq_id == msg_queue_obj->msgq_id) {
1232 /* Found it */ 1229 /* Found it */
1233 if (msg.msg.dw_cmd == RMS_EXITACK) { 1230 if (msg.msg.dw_cmd == RMS_EXITACK) {
@@ -1237,47 +1234,39 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr)
1237 * queued. 1234 * queued.
1238 */ 1235 */
1239 (*hmsg_mgr->on_exit) ((void *) 1236 (*hmsg_mgr->on_exit) ((void *)
1240 msg_queue_obj->arg, 1237 msg_queue_obj->arg,
1241 msg.msg.dw_arg1); 1238 msg.msg.dw_arg1);
1239 break;
1240 }
1241 /*
1242 * Not an exit acknowledgement, queue
1243 * the message.
1244 */
1245 if (!list_empty(&msg_queue_obj->
1246 msg_free_list)) {
1247 pmsg = list_first_entry(
1248 &msg_queue_obj->msg_free_list,
1249 struct msg_frame, list_elem);
1250 list_del(&pmsg->list_elem);
1251 pmsg->msg_data = msg;
1252 list_add_tail(&pmsg->list_elem,
1253 &msg_queue_obj->msg_used_list);
1254 ntfy_notify
1255 (msg_queue_obj->ntfy_obj,
1256 DSP_NODEMESSAGEREADY);
1257 sync_set_event
1258 (msg_queue_obj->sync_event);
1242 } else { 1259 } else {
1243 /* 1260 /*
1244 * Not an exit acknowledgement, queue 1261 * No free frame to copy the
1245 * the message. 1262 * message into.
1246 */ 1263 */
1247 if (!msg_queue_obj->msg_free_list) 1264 pr_err("%s: no free msg frames,"
1248 goto func_end; 1265 " discarding msg\n",
1249 pmsg = (struct msg_frame *)lst_get_head 1266 __func__);
1250 (msg_queue_obj->msg_free_list);
1251 if (msg_queue_obj->msg_used_list
1252 && pmsg) {
1253 pmsg->msg_data = msg;
1254 lst_put_tail
1255 (msg_queue_obj->msg_used_list,
1256 (struct list_head *)pmsg);
1257 ntfy_notify
1258 (msg_queue_obj->ntfy_obj,
1259 DSP_NODEMESSAGEREADY);
1260 sync_set_event
1261 (msg_queue_obj->sync_event);
1262 } else {
1263 /*
1264 * No free frame to copy the
1265 * message into.
1266 */
1267 pr_err("%s: no free msg frames,"
1268 " discarding msg\n",
1269 __func__);
1270 }
1271 } 1267 }
1272 break; 1268 break;
1273 } 1269 }
1274
1275 if (!hmsg_mgr->queue_list || !msg_queue_obj)
1276 goto func_end;
1277 msg_queue_obj =
1278 (struct msg_queue *)lst_next(hmsg_mgr->queue_list,
1279 (struct list_head *)
1280 msg_queue_obj);
1281 } 1270 }
1282 } 1271 }
1283 /* Set the post SWI flag */ 1272 /* Set the post SWI flag */
@@ -1301,8 +1290,7 @@ static void notify_chnl_complete(struct chnl_object *pchnl,
1301{ 1290{
1302 bool signal_event; 1291 bool signal_event;
1303 1292
1304 if (!pchnl || !pchnl->sync_event || 1293 if (!pchnl || !pchnl->sync_event || !chnl_packet_obj)
1305 !pchnl->pio_completions || !chnl_packet_obj)
1306 goto func_end; 1294 goto func_end;
1307 1295
1308 /* 1296 /*
@@ -1311,10 +1299,9 @@ static void notify_chnl_complete(struct chnl_object *pchnl,
1311 * signalled by the only IO completion list consumer: 1299 * signalled by the only IO completion list consumer:
1312 * bridge_chnl_get_ioc(). 1300 * bridge_chnl_get_ioc().
1313 */ 1301 */
1314 signal_event = LST_IS_EMPTY(pchnl->pio_completions); 1302 signal_event = list_empty(&pchnl->pio_completions);
1315 /* Enqueue the IO completion info for the client */ 1303 /* Enqueue the IO completion info for the client */
1316 lst_put_tail(pchnl->pio_completions, 1304 list_add_tail(&chnl_packet_obj->link, &pchnl->pio_completions);
1317 (struct list_head *)chnl_packet_obj);
1318 pchnl->cio_cs++; 1305 pchnl->cio_cs++;
1319 1306
1320 if (pchnl->cio_cs > pchnl->chnl_packets) 1307 if (pchnl->cio_cs > pchnl->chnl_packets)
@@ -1361,21 +1348,23 @@ static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
1361 goto func_end; 1348 goto func_end;
1362 1349
1363 pchnl = chnl_mgr_obj->ap_channel[chnl_id]; 1350 pchnl = chnl_mgr_obj->ap_channel[chnl_id];
1364 if (!pchnl || !pchnl->pio_requests) { 1351 if (!pchnl || list_empty(&pchnl->pio_requests)) {
1365 /* Shouldn't get here */ 1352 /* Shouldn't get here */
1366 goto func_end; 1353 goto func_end;
1367 } 1354 }
1368 /* Get the I/O request, and attempt a transfer */ 1355
1369 chnl_packet_obj = (struct chnl_irp *)lst_get_head(pchnl->pio_requests); 1356 if (!pchnl->cio_reqs)
1370 if (!chnl_packet_obj)
1371 goto func_end; 1357 goto func_end;
1372 1358
1359 /* Get the I/O request, and attempt a transfer */
1360 chnl_packet_obj = list_first_entry(&pchnl->pio_requests,
1361 struct chnl_irp, link);
1362 list_del(&chnl_packet_obj->link);
1363
1373 pchnl->cio_reqs--; 1364 pchnl->cio_reqs--;
1374 if (pchnl->cio_reqs < 0 || !pchnl->pio_requests)
1375 goto func_end;
1376 1365
1377 /* Record fact that no more I/O buffers available */ 1366 /* Record fact that no more I/O buffers available */
1378 if (LST_IS_EMPTY(pchnl->pio_requests)) 1367 if (list_empty(&pchnl->pio_requests))
1379 chnl_mgr_obj->dw_output_mask &= ~(1 << chnl_id); 1368 chnl_mgr_obj->dw_output_mask &= ~(1 << chnl_id);
1380 1369
1381 /* Transfer buffer to DSP side */ 1370 /* Transfer buffer to DSP side */
@@ -1436,14 +1425,11 @@ static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr)
1436 msg_output = pio_mgr->msg_output; 1425 msg_output = pio_mgr->msg_output;
1437 /* Copy num_msgs messages into shared memory */ 1426 /* Copy num_msgs messages into shared memory */
1438 for (i = 0; i < num_msgs; i++) { 1427 for (i = 0; i < num_msgs; i++) {
1439 if (!hmsg_mgr->msg_used_list) { 1428 if (!list_empty(&hmsg_mgr->msg_used_list)) {
1440 pmsg = NULL; 1429 pmsg = list_first_entry(
1441 goto func_end; 1430 &hmsg_mgr->msg_used_list,
1442 } else { 1431 struct msg_frame, list_elem);
1443 pmsg = (struct msg_frame *) 1432 list_del(&pmsg->list_elem);
1444 lst_get_head(hmsg_mgr->msg_used_list);
1445 }
1446 if (pmsg != NULL) {
1447 val = (pmsg->msg_data).msgq_id; 1433 val = (pmsg->msg_data).msgq_id;
1448 addr = (u32) &(((struct msg_dspmsg *) 1434 addr = (u32) &(((struct msg_dspmsg *)
1449 msg_output)->msgq_id); 1435 msg_output)->msgq_id);
@@ -1465,10 +1451,8 @@ static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr)
1465 write_ext32_bit_dsp_data( 1451 write_ext32_bit_dsp_data(
1466 pio_mgr->hbridge_context, addr, val); 1452 pio_mgr->hbridge_context, addr, val);
1467 msg_output += sizeof(struct msg_dspmsg); 1453 msg_output += sizeof(struct msg_dspmsg);
1468 if (!hmsg_mgr->msg_free_list) 1454 list_add_tail(&pmsg->list_elem,
1469 goto func_end; 1455 &hmsg_mgr->msg_free_list);
1470 lst_put_tail(hmsg_mgr->msg_free_list,
1471 (struct list_head *)pmsg);
1472 sync_set_event(hmsg_mgr->sync_event); 1456 sync_set_event(hmsg_mgr->sync_event);
1473 } 1457 }
1474 } 1458 }
@@ -1492,8 +1476,6 @@ static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr)
1492 MBX_PCPY_CLASS); 1476 MBX_PCPY_CLASS);
1493 } 1477 }
1494 } 1478 }
1495func_end:
1496 return;
1497} 1479}
1498 1480
1499/* 1481/*
diff --git a/drivers/staging/tidspbridge/core/msg_sm.c b/drivers/staging/tidspbridge/core/msg_sm.c
index 87712e24dfb..de2cb835fbb 100644
--- a/drivers/staging/tidspbridge/core/msg_sm.c
+++ b/drivers/staging/tidspbridge/core/msg_sm.c
@@ -24,7 +24,6 @@
24#include <dspbridge/dbc.h> 24#include <dspbridge/dbc.h>
25 25
26/* ----------------------------------- OS Adaptation Layer */ 26/* ----------------------------------- OS Adaptation Layer */
27#include <dspbridge/list.h>
28#include <dspbridge/sync.h> 27#include <dspbridge/sync.h>
29 28
30/* ----------------------------------- Platform Manager */ 29/* ----------------------------------- Platform Manager */
@@ -38,10 +37,10 @@
38#include <dspbridge/dspmsg.h> 37#include <dspbridge/dspmsg.h>
39 38
40/* ----------------------------------- Function Prototypes */ 39/* ----------------------------------- Function Prototypes */
41static int add_new_msg(struct lst_list *msg_list); 40static int add_new_msg(struct list_head *msg_list);
42static void delete_msg_mgr(struct msg_mgr *hmsg_mgr); 41static void delete_msg_mgr(struct msg_mgr *hmsg_mgr);
43static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp); 42static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp);
44static void free_msg_list(struct lst_list *msg_list); 43static void free_msg_list(struct list_head *msg_list);
45 44
46/* 45/*
47 * ======== bridge_msg_create ======== 46 * ======== bridge_msg_create ========
@@ -73,25 +72,13 @@ int bridge_msg_create(struct msg_mgr **msg_man,
73 msg_mgr_obj->on_exit = msg_callback; 72 msg_mgr_obj->on_exit = msg_callback;
74 msg_mgr_obj->hio_mgr = hio_mgr; 73 msg_mgr_obj->hio_mgr = hio_mgr;
75 /* List of MSG_QUEUEs */ 74 /* List of MSG_QUEUEs */
76 msg_mgr_obj->queue_list = kzalloc(sizeof(struct lst_list), 75 INIT_LIST_HEAD(&msg_mgr_obj->queue_list);
77 GFP_KERNEL);
78 /* Queues of message frames for messages to the DSP. Message 76 /* Queues of message frames for messages to the DSP. Message
79 * frames will only be added to the free queue when a 77 * frames will only be added to the free queue when a
80 * msg_queue object is created. */ 78 * msg_queue object is created. */
81 msg_mgr_obj->msg_free_list = kzalloc(sizeof(struct lst_list), 79 INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list);
82 GFP_KERNEL); 80 INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list);
83 msg_mgr_obj->msg_used_list = kzalloc(sizeof(struct lst_list), 81 spin_lock_init(&msg_mgr_obj->msg_mgr_lock);
84 GFP_KERNEL);
85 if (msg_mgr_obj->queue_list == NULL ||
86 msg_mgr_obj->msg_free_list == NULL ||
87 msg_mgr_obj->msg_used_list == NULL) {
88 status = -ENOMEM;
89 } else {
90 INIT_LIST_HEAD(&msg_mgr_obj->queue_list->head);
91 INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list->head);
92 INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list->head);
93 spin_lock_init(&msg_mgr_obj->msg_mgr_lock);
94 }
95 82
96 /* Create an event to be used by bridge_msg_put() in waiting 83 /* Create an event to be used by bridge_msg_put() in waiting
97 * for an available free frame from the message manager. */ 84 * for an available free frame from the message manager. */
@@ -128,7 +115,7 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr,
128 struct msg_queue *msg_q; 115 struct msg_queue *msg_q;
129 int status = 0; 116 int status = 0;
130 117
131 if (!hmsg_mgr || msgq == NULL || !hmsg_mgr->msg_free_list) { 118 if (!hmsg_mgr || msgq == NULL) {
132 status = -EFAULT; 119 status = -EFAULT;
133 goto func_end; 120 goto func_end;
134 } 121 }
@@ -140,20 +127,13 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr,
140 status = -ENOMEM; 127 status = -ENOMEM;
141 goto func_end; 128 goto func_end;
142 } 129 }
143 lst_init_elem((struct list_head *)msg_q);
144 msg_q->max_msgs = max_msgs; 130 msg_q->max_msgs = max_msgs;
145 msg_q->hmsg_mgr = hmsg_mgr; 131 msg_q->hmsg_mgr = hmsg_mgr;
146 msg_q->arg = arg; /* Node handle */ 132 msg_q->arg = arg; /* Node handle */
147 msg_q->msgq_id = msgq_id; /* Node env (not valid yet) */ 133 msg_q->msgq_id = msgq_id; /* Node env (not valid yet) */
148 /* Queues of Message frames for messages from the DSP */ 134 /* Queues of Message frames for messages from the DSP */
149 msg_q->msg_free_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL); 135 INIT_LIST_HEAD(&msg_q->msg_free_list);
150 msg_q->msg_used_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL); 136 INIT_LIST_HEAD(&msg_q->msg_used_list);
151 if (msg_q->msg_free_list == NULL || msg_q->msg_used_list == NULL)
152 status = -ENOMEM;
153 else {
154 INIT_LIST_HEAD(&msg_q->msg_free_list->head);
155 INIT_LIST_HEAD(&msg_q->msg_used_list->head);
156 }
157 137
158 /* Create event that will be signalled when a message from 138 /* Create event that will be signalled when a message from
159 * the DSP is available. */ 139 * the DSP is available. */
@@ -204,10 +184,10 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr,
204 spin_lock_bh(&hmsg_mgr->msg_mgr_lock); 184 spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
205 /* Initialize message frames and put in appropriate queues */ 185 /* Initialize message frames and put in appropriate queues */
206 for (i = 0; i < max_msgs && !status; i++) { 186 for (i = 0; i < max_msgs && !status; i++) {
207 status = add_new_msg(hmsg_mgr->msg_free_list); 187 status = add_new_msg(&hmsg_mgr->msg_free_list);
208 if (!status) { 188 if (!status) {
209 num_allocated++; 189 num_allocated++;
210 status = add_new_msg(msg_q->msg_free_list); 190 status = add_new_msg(&msg_q->msg_free_list);
211 } 191 }
212 } 192 }
213 if (status) { 193 if (status) {
@@ -215,11 +195,11 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr,
215 * of the newly allocated message frames. */ 195 * of the newly allocated message frames. */
216 delete_msg_queue(msg_q, num_allocated); 196 delete_msg_queue(msg_q, num_allocated);
217 } else { 197 } else {
218 lst_put_tail(hmsg_mgr->queue_list, 198 list_add_tail(&msg_q->list_elem,
219 (struct list_head *)msg_q); 199 &hmsg_mgr->queue_list);
220 *msgq = msg_q; 200 *msgq = msg_q;
221 /* Signal that free frames are now available */ 201 /* Signal that free frames are now available */
222 if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) 202 if (!list_empty(&hmsg_mgr->msg_free_list))
223 sync_set_event(hmsg_mgr->sync_event); 203 sync_set_event(hmsg_mgr->sync_event);
224 204
225 } 205 }
@@ -267,15 +247,12 @@ void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj)
267 } 247 }
268 /* Remove message queue from hmsg_mgr->queue_list */ 248 /* Remove message queue from hmsg_mgr->queue_list */
269 spin_lock_bh(&hmsg_mgr->msg_mgr_lock); 249 spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
270 lst_remove_elem(hmsg_mgr->queue_list, 250 list_del(&msg_queue_obj->list_elem);
271 (struct list_head *)msg_queue_obj);
272 /* Free the message queue object */ 251 /* Free the message queue object */
273 delete_msg_queue(msg_queue_obj, msg_queue_obj->max_msgs); 252 delete_msg_queue(msg_queue_obj, msg_queue_obj->max_msgs);
274 if (!hmsg_mgr->msg_free_list) 253 if (list_empty(&hmsg_mgr->msg_free_list))
275 goto func_cont;
276 if (LST_IS_EMPTY(hmsg_mgr->msg_free_list))
277 sync_reset_event(hmsg_mgr->sync_event); 254 sync_reset_event(hmsg_mgr->sync_event);
278func_cont: 255
279 spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); 256 spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
280func_end: 257func_end:
281 return; 258 return;
@@ -301,26 +278,21 @@ int bridge_msg_get(struct msg_queue *msg_queue_obj,
301 } 278 }
302 279
303 hmsg_mgr = msg_queue_obj->hmsg_mgr; 280 hmsg_mgr = msg_queue_obj->hmsg_mgr;
304 if (!msg_queue_obj->msg_used_list) {
305 status = -EFAULT;
306 goto func_end;
307 }
308 281
309 /* Enter critical section */ 282 /* Enter critical section */
310 spin_lock_bh(&hmsg_mgr->msg_mgr_lock); 283 spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
311 /* If a message is already there, get it */ 284 /* If a message is already there, get it */
312 if (!LST_IS_EMPTY(msg_queue_obj->msg_used_list)) { 285 if (!list_empty(&msg_queue_obj->msg_used_list)) {
313 msg_frame_obj = (struct msg_frame *) 286 msg_frame_obj = list_first_entry(&msg_queue_obj->msg_used_list,
314 lst_get_head(msg_queue_obj->msg_used_list); 287 struct msg_frame, list_elem);
315 if (msg_frame_obj != NULL) { 288 list_del(&msg_frame_obj->list_elem);
316 *pmsg = msg_frame_obj->msg_data.msg; 289 *pmsg = msg_frame_obj->msg_data.msg;
317 lst_put_tail(msg_queue_obj->msg_free_list, 290 list_add_tail(&msg_frame_obj->list_elem,
318 (struct list_head *)msg_frame_obj); 291 &msg_queue_obj->msg_free_list);
319 if (LST_IS_EMPTY(msg_queue_obj->msg_used_list)) 292 if (list_empty(&msg_queue_obj->msg_used_list))
320 sync_reset_event(msg_queue_obj->sync_event); 293 sync_reset_event(msg_queue_obj->sync_event);
321 294
322 got_msg = true; 295 got_msg = true;
323 }
324 } else { 296 } else {
325 if (msg_queue_obj->done) 297 if (msg_queue_obj->done)
326 status = -EPERM; 298 status = -EPERM;
@@ -349,25 +321,22 @@ int bridge_msg_get(struct msg_queue *msg_queue_obj,
349 (void)sync_set_event(msg_queue_obj->sync_done_ack); 321 (void)sync_set_event(msg_queue_obj->sync_done_ack);
350 status = -EPERM; 322 status = -EPERM;
351 } else { 323 } else {
352 if (!status) { 324 if (!status && !list_empty(&msg_queue_obj->
353 DBC_ASSERT(!LST_IS_EMPTY 325 msg_used_list)) {
354 (msg_queue_obj->msg_used_list));
355 /* Get msg from used list */ 326 /* Get msg from used list */
356 msg_frame_obj = (struct msg_frame *) 327 msg_frame_obj = list_first_entry(
357 lst_get_head(msg_queue_obj->msg_used_list); 328 &msg_queue_obj->msg_used_list,
329 struct msg_frame, list_elem);
330 list_del(&msg_frame_obj->list_elem);
358 /* Copy message into pmsg and put frame on the 331 /* Copy message into pmsg and put frame on the
359 * free list */ 332 * free list */
360 if (msg_frame_obj != NULL) { 333 *pmsg = msg_frame_obj->msg_data.msg;
361 *pmsg = msg_frame_obj->msg_data.msg; 334 list_add_tail(&msg_frame_obj->list_elem,
362 lst_put_tail 335 &msg_queue_obj->msg_free_list);
363 (msg_queue_obj->msg_free_list,
364 (struct list_head *)
365 msg_frame_obj);
366 }
367 } 336 }
368 msg_queue_obj->io_msg_pend--; 337 msg_queue_obj->io_msg_pend--;
369 /* Reset the event if there are still queued messages */ 338 /* Reset the event if there are still queued messages */
370 if (!LST_IS_EMPTY(msg_queue_obj->msg_used_list)) 339 if (!list_empty(&msg_queue_obj->msg_used_list))
371 sync_set_event(msg_queue_obj->sync_event); 340 sync_set_event(msg_queue_obj->sync_event);
372 341
373 /* Exit critical section */ 342 /* Exit critical section */
@@ -397,27 +366,22 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj,
397 goto func_end; 366 goto func_end;
398 } 367 }
399 hmsg_mgr = msg_queue_obj->hmsg_mgr; 368 hmsg_mgr = msg_queue_obj->hmsg_mgr;
400 if (!hmsg_mgr->msg_free_list) {
401 status = -EFAULT;
402 goto func_end;
403 }
404 369
405 spin_lock_bh(&hmsg_mgr->msg_mgr_lock); 370 spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
406 371
407 /* If a message frame is available, use it */ 372 /* If a message frame is available, use it */
408 if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) { 373 if (!list_empty(&hmsg_mgr->msg_free_list)) {
409 msg_frame_obj = 374 msg_frame_obj = list_first_entry(&hmsg_mgr->msg_free_list,
410 (struct msg_frame *)lst_get_head(hmsg_mgr->msg_free_list); 375 struct msg_frame, list_elem);
411 if (msg_frame_obj != NULL) { 376 list_del(&msg_frame_obj->list_elem);
412 msg_frame_obj->msg_data.msg = *pmsg; 377 msg_frame_obj->msg_data.msg = *pmsg;
413 msg_frame_obj->msg_data.msgq_id = 378 msg_frame_obj->msg_data.msgq_id =
414 msg_queue_obj->msgq_id; 379 msg_queue_obj->msgq_id;
415 lst_put_tail(hmsg_mgr->msg_used_list, 380 list_add_tail(&msg_frame_obj->list_elem,
416 (struct list_head *)msg_frame_obj); 381 &hmsg_mgr->msg_used_list);
417 hmsg_mgr->msgs_pending++; 382 hmsg_mgr->msgs_pending++;
418 put_msg = true; 383 put_msg = true;
419 } 384 if (list_empty(&hmsg_mgr->msg_free_list))
420 if (LST_IS_EMPTY(hmsg_mgr->msg_free_list))
421 sync_reset_event(hmsg_mgr->sync_event); 385 sync_reset_event(hmsg_mgr->sync_event);
422 386
423 /* Release critical section before scheduling DPC */ 387 /* Release critical section before scheduling DPC */
@@ -452,34 +416,34 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj,
452 (void)sync_set_event(msg_queue_obj->sync_done_ack); 416 (void)sync_set_event(msg_queue_obj->sync_done_ack);
453 status = -EPERM; 417 status = -EPERM;
454 } else { 418 } else {
455 if (LST_IS_EMPTY(hmsg_mgr->msg_free_list)) { 419 if (list_empty(&hmsg_mgr->msg_free_list)) {
456 status = -EFAULT; 420 status = -EFAULT;
457 goto func_cont; 421 goto func_cont;
458 } 422 }
459 /* Get msg from free list */ 423 /* Get msg from free list */
460 msg_frame_obj = (struct msg_frame *) 424 msg_frame_obj = list_first_entry(
461 lst_get_head(hmsg_mgr->msg_free_list); 425 &hmsg_mgr->msg_free_list,
426 struct msg_frame, list_elem);
427 list_del(&msg_frame_obj->list_elem);
462 /* 428 /*
463 * Copy message into pmsg and put frame on the 429 * Copy message into pmsg and put frame on the
464 * used list. 430 * used list.
465 */ 431 */
466 if (msg_frame_obj) { 432 msg_frame_obj->msg_data.msg = *pmsg;
467 msg_frame_obj->msg_data.msg = *pmsg; 433 msg_frame_obj->msg_data.msgq_id =
468 msg_frame_obj->msg_data.msgq_id = 434 msg_queue_obj->msgq_id;
469 msg_queue_obj->msgq_id; 435 list_add_tail(&msg_frame_obj->list_elem,
470 lst_put_tail(hmsg_mgr->msg_used_list, 436 &hmsg_mgr->msg_used_list);
471 (struct list_head *)msg_frame_obj); 437 hmsg_mgr->msgs_pending++;
472 hmsg_mgr->msgs_pending++; 438 /*
473 /* 439 * Schedule a DPC, to do the actual
474 * Schedule a DPC, to do the actual 440 * data transfer.
475 * data transfer. 441 */
476 */ 442 iosm_schedule(hmsg_mgr->hio_mgr);
477 iosm_schedule(hmsg_mgr->hio_mgr);
478 }
479 443
480 msg_queue_obj->io_msg_pend--; 444 msg_queue_obj->io_msg_pend--;
481 /* Reset event if there are still frames available */ 445 /* Reset event if there are still frames available */
482 if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) 446 if (!list_empty(&hmsg_mgr->msg_free_list))
483 sync_set_event(hmsg_mgr->sync_event); 447 sync_set_event(hmsg_mgr->sync_event);
484func_cont: 448func_cont:
485 /* Exit critical section */ 449 /* Exit critical section */
@@ -551,15 +515,14 @@ void bridge_msg_set_queue_id(struct msg_queue *msg_queue_obj, u32 msgq_id)
551 * ======== add_new_msg ======== 515 * ======== add_new_msg ========
552 * Must be called in message manager critical section. 516 * Must be called in message manager critical section.
553 */ 517 */
554static int add_new_msg(struct lst_list *msg_list) 518static int add_new_msg(struct list_head *msg_list)
555{ 519{
556 struct msg_frame *pmsg; 520 struct msg_frame *pmsg;
557 int status = 0; 521 int status = 0;
558 522
559 pmsg = kzalloc(sizeof(struct msg_frame), GFP_ATOMIC); 523 pmsg = kzalloc(sizeof(struct msg_frame), GFP_ATOMIC);
560 if (pmsg != NULL) { 524 if (pmsg != NULL) {
561 lst_init_elem((struct list_head *)pmsg); 525 list_add_tail(&pmsg->list_elem, msg_list);
562 lst_put_tail(msg_list, (struct list_head *)pmsg);
563 } else { 526 } else {
564 status = -ENOMEM; 527 status = -ENOMEM;
565 } 528 }
@@ -575,22 +538,9 @@ static void delete_msg_mgr(struct msg_mgr *hmsg_mgr)
575 if (!hmsg_mgr) 538 if (!hmsg_mgr)
576 goto func_end; 539 goto func_end;
577 540
578 if (hmsg_mgr->queue_list) { 541 /* FIXME: free elements from queue_list? */
579 if (LST_IS_EMPTY(hmsg_mgr->queue_list)) { 542 free_msg_list(&hmsg_mgr->msg_free_list);
580 kfree(hmsg_mgr->queue_list); 543 free_msg_list(&hmsg_mgr->msg_used_list);
581 hmsg_mgr->queue_list = NULL;
582 }
583 }
584
585 if (hmsg_mgr->msg_free_list) {
586 free_msg_list(hmsg_mgr->msg_free_list);
587 hmsg_mgr->msg_free_list = NULL;
588 }
589
590 if (hmsg_mgr->msg_used_list) {
591 free_msg_list(hmsg_mgr->msg_used_list);
592 hmsg_mgr->msg_used_list = NULL;
593 }
594 544
595 kfree(hmsg_mgr->sync_event); 545 kfree(hmsg_mgr->sync_event);
596 546
@@ -605,37 +555,26 @@ func_end:
605static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp) 555static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp)
606{ 556{
607 struct msg_mgr *hmsg_mgr; 557 struct msg_mgr *hmsg_mgr;
608 struct msg_frame *pmsg; 558 struct msg_frame *pmsg, *tmp;
609 u32 i; 559 u32 i;
610 560
611 if (!msg_queue_obj || 561 if (!msg_queue_obj || !msg_queue_obj->hmsg_mgr)
612 !msg_queue_obj->hmsg_mgr || !msg_queue_obj->hmsg_mgr->msg_free_list)
613 goto func_end; 562 goto func_end;
614 563
615 hmsg_mgr = msg_queue_obj->hmsg_mgr; 564 hmsg_mgr = msg_queue_obj->hmsg_mgr;
616 565
617 /* Pull off num_to_dsp message frames from Msg manager and free */ 566 /* Pull off num_to_dsp message frames from Msg manager and free */
618 for (i = 0; i < num_to_dsp; i++) { 567 i = 0;
619 568 list_for_each_entry_safe(pmsg, tmp, &hmsg_mgr->msg_free_list,
620 if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) { 569 list_elem) {
621 pmsg = (struct msg_frame *) 570 list_del(&pmsg->list_elem);
622 lst_get_head(hmsg_mgr->msg_free_list); 571 kfree(pmsg);
623 kfree(pmsg); 572 if (i++ >= num_to_dsp)
624 } else {
625 /* Cannot free all of the message frames */
626 break; 573 break;
627 }
628 } 574 }
629 575
630 if (msg_queue_obj->msg_free_list) { 576 free_msg_list(&msg_queue_obj->msg_free_list);
631 free_msg_list(msg_queue_obj->msg_free_list); 577 free_msg_list(&msg_queue_obj->msg_used_list);
632 msg_queue_obj->msg_free_list = NULL;
633 }
634
635 if (msg_queue_obj->msg_used_list) {
636 free_msg_list(msg_queue_obj->msg_used_list);
637 msg_queue_obj->msg_used_list = NULL;
638 }
639 578
640 if (msg_queue_obj->ntfy_obj) { 579 if (msg_queue_obj->ntfy_obj) {
641 ntfy_delete(msg_queue_obj->ntfy_obj); 580 ntfy_delete(msg_queue_obj->ntfy_obj);
@@ -655,19 +594,18 @@ func_end:
655/* 594/*
656 * ======== free_msg_list ======== 595 * ======== free_msg_list ========
657 */ 596 */
658static void free_msg_list(struct lst_list *msg_list) 597static void free_msg_list(struct list_head *msg_list)
659{ 598{
660 struct msg_frame *pmsg; 599 struct msg_frame *pmsg, *tmp;
661 600
662 if (!msg_list) 601 if (!msg_list)
663 goto func_end; 602 goto func_end;
664 603
665 while ((pmsg = (struct msg_frame *)lst_get_head(msg_list)) != NULL) 604 list_for_each_entry_safe(pmsg, tmp, msg_list, list_elem) {
605 list_del(&pmsg->list_elem);
666 kfree(pmsg); 606 kfree(pmsg);
607 }
667 608
668 DBC_ASSERT(LST_IS_EMPTY(msg_list));
669
670 kfree(msg_list);
671func_end: 609func_end:
672 return; 610 return;
673} 611}