diff options
author | Ionut Nicu <ionut.nicu@gmail.com> | 2010-11-21 05:46:24 -0500 |
---|---|---|
committer | Omar Ramirez Luna <omar.ramirez@ti.com> | 2011-02-04 21:11:35 -0500 |
commit | 3c6bf30f1e520b250242da39a493986b8b2cef53 (patch) | |
tree | 9fdeb810a478c67530e3fe4a77b7a67ba773729d /drivers/staging/tidspbridge/core | |
parent | 6d7e925b88cd8436b1284158876580ea431cb954 (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.h | 12 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/core/chnl_sm.c | 245 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/core/io_sm.c | 142 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/core/msg_sm.c | 236 |
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 */ |
76 | static struct lst_list *create_chirp_list(u32 chirps); | 76 | static int create_chirp_list(struct list_head *list, u32 chirps); |
77 | 77 | ||
78 | static void free_chirp_list(struct lst_list *chirp_list); | 78 | static void free_chirp_list(struct list_head *list); |
79 | |||
80 | static struct chnl_irp *make_new_chirp(void); | ||
81 | 79 | ||
82 | static int search_free_channel(struct chnl_mgr *chnl_mgr_obj, | 80 | static 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 | } |
302 | func_cont: | 299 | func_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 | */ |
933 | static struct lst_list *create_chirp_list(u32 chirps) | 914 | static 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 | */ |
965 | static void free_chirp_list(struct lst_list *chirp_list) | 943 | static 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 | */ | ||
979 | static 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 | } |
1495 | func_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 */ |
41 | static int add_new_msg(struct lst_list *msg_list); | 40 | static int add_new_msg(struct list_head *msg_list); |
42 | static void delete_msg_mgr(struct msg_mgr *hmsg_mgr); | 41 | static void delete_msg_mgr(struct msg_mgr *hmsg_mgr); |
43 | static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp); | 42 | static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp); |
44 | static void free_msg_list(struct lst_list *msg_list); | 43 | static 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); |
278 | func_cont: | 255 | |
279 | spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); | 256 | spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); |
280 | func_end: | 257 | func_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); |
484 | func_cont: | 448 | func_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 | */ |
554 | static int add_new_msg(struct lst_list *msg_list) | 518 | static 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: | |||
605 | static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp) | 555 | static 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 | */ |
658 | static void free_msg_list(struct lst_list *msg_list) | 597 | static 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); | ||
671 | func_end: | 609 | func_end: |
672 | return; | 610 | return; |
673 | } | 611 | } |