4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * DSP/BIOS Bridge Stream Manager.
8 * Copyright (C) 2005-2006 Texas Instruments, Inc.
10 * This package is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 /* ----------------------------------- Host OS */
20 #include <dspbridge/host_os.h>
22 /* ----------------------------------- DSP/BIOS Bridge */
23 #include <dspbridge/std.h>
24 #include <dspbridge/dbdefs.h>
26 /* ----------------------------------- Trace & Debug */
27 #include <dspbridge/dbc.h>
29 /* ----------------------------------- OS Adaptation Layer */
30 #include <dspbridge/sync.h>
32 /* ----------------------------------- Bridge Driver */
33 #include <dspbridge/dspdefs.h>
35 /* ----------------------------------- Resource Manager */
36 #include <dspbridge/nodepriv.h>
38 /* ----------------------------------- Others */
39 #include <dspbridge/cmm.h>
41 /* ----------------------------------- This */
42 #include <dspbridge/strm.h>
44 #include <dspbridge/cfg.h>
45 #include <dspbridge/resourcecleanup.h>
47 /* ----------------------------------- Defines, Data Structures, Typedefs */
48 #define DEFAULTTIMEOUT 10000
49 #define DEFAULTNUMBUFS 2
52 * ======== strm_mgr ========
53 * The strm_mgr contains device information needed to open the underlying
54 * channels of a stream.
57 struct dev_object
*dev_obj
; /* Device for this processor */
58 struct chnl_mgr
*hchnl_mgr
; /* Channel manager */
59 /* Function interface to Bridge driver */
60 struct bridge_drv_interface
*intf_fxns
;
64 * ======== strm_object ========
65 * This object is allocated in strm_open().
68 struct strm_mgr
*strm_mgr_obj
;
69 struct chnl_object
*chnl_obj
;
70 u32 dir
; /* DSP_TONODE or DSP_FROMNODE */
72 u32 num_bufs
; /* Max # of bufs allowed in stream */
73 u32 un_bufs_in_strm
; /* Current # of bufs in stream */
74 u32 ul_n_bytes
; /* bytes transferred since idled */
75 /* STREAM_IDLE, STREAM_READY, ... */
76 enum dsp_streamstate strm_state
;
77 void *user_event
; /* Saved for strm_get_info() */
78 enum dsp_strmmode strm_mode
; /* STRMMODE_[PROCCOPY][ZEROCOPY]... */
79 u32 udma_chnl_id
; /* DMA chnl id */
80 u32 udma_priority
; /* DMA priority:DMAPRI_[LOW][HIGH] */
81 u32 segment_id
; /* >0 is SM segment.=0 is local heap */
82 u32 buf_alignment
; /* Alignment for stream bufs */
83 /* Stream's SM address translator */
84 struct cmm_xlatorobject
*xlator
;
87 /* ----------------------------------- Globals */
88 static u32 refs
; /* module reference count */
90 /* ----------------------------------- Function Prototypes */
91 static int delete_strm(struct strm_object
*stream_obj
);
92 static void delete_strm_mgr(struct strm_mgr
*strm_mgr_obj
);
95 * ======== strm_allocate_buffer ========
97 * Allocates buffers for a stream.
99 int strm_allocate_buffer(struct strm_object
*stream_obj
, u32 usize
,
100 OUT u8
**ap_buffer
, u32 num_bufs
,
101 struct process_context
*pr_ctxt
)
109 DBC_REQUIRE(refs
> 0);
110 DBC_REQUIRE(ap_buffer
!= NULL
);
114 * Allocate from segment specified at time of stream open.
123 if (DSP_FAILED(status
))
126 for (i
= 0; i
< num_bufs
; i
++) {
127 DBC_ASSERT(stream_obj
->xlator
!= NULL
);
128 (void)cmm_xlator_alloc_buf(stream_obj
->xlator
, &ap_buffer
[i
],
130 if (ap_buffer
[i
] == NULL
) {
136 if (DSP_FAILED(status
))
137 strm_free_buffer(stream_obj
, ap_buffer
, alloc_cnt
, pr_ctxt
);
139 if (DSP_FAILED(status
))
142 if (drv_get_strm_res_element(stream_obj
, &hstrm_res
, pr_ctxt
) !=
144 drv_proc_update_strm_res(num_bufs
, hstrm_res
);
151 * ======== strm_close ========
153 * Close a stream opened with strm_open().
155 int strm_close(struct strm_object
*stream_obj
,
156 struct process_context
*pr_ctxt
)
158 struct bridge_drv_interface
*intf_fxns
;
159 struct chnl_info chnl_info_obj
;
164 DBC_REQUIRE(refs
> 0);
169 /* Have all buffers been reclaimed? If not, return
171 intf_fxns
= stream_obj
->strm_mgr_obj
->intf_fxns
;
173 (*intf_fxns
->pfn_chnl_get_info
) (stream_obj
->chnl_obj
,
175 DBC_ASSERT(DSP_SUCCEEDED(status
));
177 if (chnl_info_obj
.cio_cs
> 0 || chnl_info_obj
.cio_reqs
> 0)
180 status
= delete_strm(stream_obj
);
183 if (DSP_FAILED(status
))
186 if (drv_get_strm_res_element(stream_obj
, &hstrm_res
, pr_ctxt
) !=
188 drv_proc_remove_strm_res_element(hstrm_res
, pr_ctxt
);
190 DBC_ENSURE(status
== 0 || status
== -EFAULT
||
191 status
== -EPIPE
|| status
== -EPERM
);
193 dev_dbg(bridge
, "%s: stream_obj: %p, status 0x%x\n", __func__
,
199 * ======== strm_create ========
201 * Create a STRM manager object.
203 int strm_create(OUT
struct strm_mgr
**phStrmMgr
,
204 struct dev_object
*dev_obj
)
206 struct strm_mgr
*strm_mgr_obj
;
209 DBC_REQUIRE(refs
> 0);
210 DBC_REQUIRE(phStrmMgr
!= NULL
);
211 DBC_REQUIRE(dev_obj
!= NULL
);
214 /* Allocate STRM manager object */
215 strm_mgr_obj
= kzalloc(sizeof(struct strm_mgr
), GFP_KERNEL
);
216 if (strm_mgr_obj
== NULL
)
219 strm_mgr_obj
->dev_obj
= dev_obj
;
221 /* Get Channel manager and Bridge function interface */
222 if (DSP_SUCCEEDED(status
)) {
223 status
= dev_get_chnl_mgr(dev_obj
, &(strm_mgr_obj
->hchnl_mgr
));
224 if (DSP_SUCCEEDED(status
)) {
225 (void)dev_get_intf_fxns(dev_obj
,
226 &(strm_mgr_obj
->intf_fxns
));
227 DBC_ASSERT(strm_mgr_obj
->intf_fxns
!= NULL
);
231 if (DSP_SUCCEEDED(status
))
232 *phStrmMgr
= strm_mgr_obj
;
234 delete_strm_mgr(strm_mgr_obj
);
236 DBC_ENSURE((DSP_SUCCEEDED(status
) && *phStrmMgr
) ||
237 (DSP_FAILED(status
) && *phStrmMgr
== NULL
));
243 * ======== strm_delete ========
245 * Delete the STRM Manager Object.
247 void strm_delete(struct strm_mgr
*strm_mgr_obj
)
249 DBC_REQUIRE(refs
> 0);
250 DBC_REQUIRE(strm_mgr_obj
);
252 delete_strm_mgr(strm_mgr_obj
);
256 * ======== strm_exit ========
258 * Discontinue usage of STRM module.
262 DBC_REQUIRE(refs
> 0);
266 DBC_ENSURE(refs
>= 0);
270 * ======== strm_free_buffer ========
272 * Frees the buffers allocated for a stream.
274 int strm_free_buffer(struct strm_object
*stream_obj
, u8
** ap_buffer
,
275 u32 num_bufs
, struct process_context
*pr_ctxt
)
280 void *hstrm_res
= NULL
;
282 DBC_REQUIRE(refs
> 0);
283 DBC_REQUIRE(ap_buffer
!= NULL
);
288 if (DSP_SUCCEEDED(status
)) {
289 for (i
= 0; i
< num_bufs
; i
++) {
290 DBC_ASSERT(stream_obj
->xlator
!= NULL
);
292 cmm_xlator_free_buf(stream_obj
->xlator
,
294 if (DSP_FAILED(status
))
299 if (drv_get_strm_res_element(stream_obj
, hstrm_res
, pr_ctxt
) !=
301 drv_proc_update_strm_res(num_bufs
- i
, hstrm_res
);
307 * ======== strm_get_info ========
309 * Retrieves information about a stream.
311 int strm_get_info(struct strm_object
*stream_obj
,
312 OUT
struct stream_info
*stream_info
,
313 u32 stream_info_size
)
315 struct bridge_drv_interface
*intf_fxns
;
316 struct chnl_info chnl_info_obj
;
318 void *virt_base
= NULL
; /* NULL if no SM used */
320 DBC_REQUIRE(refs
> 0);
321 DBC_REQUIRE(stream_info
!= NULL
);
322 DBC_REQUIRE(stream_info_size
>= sizeof(struct stream_info
));
327 if (stream_info_size
< sizeof(struct stream_info
)) {
328 /* size of users info */
332 if (DSP_FAILED(status
))
335 intf_fxns
= stream_obj
->strm_mgr_obj
->intf_fxns
;
337 (*intf_fxns
->pfn_chnl_get_info
) (stream_obj
->chnl_obj
,
339 if (DSP_FAILED(status
))
342 if (stream_obj
->xlator
) {
343 /* We have a translator */
344 DBC_ASSERT(stream_obj
->segment_id
> 0);
345 cmm_xlator_info(stream_obj
->xlator
, (u8
**) &virt_base
, 0,
346 stream_obj
->segment_id
, false);
348 stream_info
->segment_id
= stream_obj
->segment_id
;
349 stream_info
->strm_mode
= stream_obj
->strm_mode
;
350 stream_info
->virt_base
= virt_base
;
351 stream_info
->user_strm
->number_bufs_allowed
= stream_obj
->num_bufs
;
352 stream_info
->user_strm
->number_bufs_in_stream
= chnl_info_obj
.cio_cs
+
353 chnl_info_obj
.cio_reqs
;
354 /* # of bytes transferred since last call to DSPStream_Idle() */
355 stream_info
->user_strm
->ul_number_bytes
= chnl_info_obj
.bytes_tx
;
356 stream_info
->user_strm
->sync_object_handle
= chnl_info_obj
.event_obj
;
357 /* Determine stream state based on channel state and info */
358 if (chnl_info_obj
.dw_state
& CHNL_STATEEOS
) {
359 stream_info
->user_strm
->ss_stream_state
= STREAM_DONE
;
361 if (chnl_info_obj
.cio_cs
> 0)
362 stream_info
->user_strm
->ss_stream_state
= STREAM_READY
;
363 else if (chnl_info_obj
.cio_reqs
> 0)
364 stream_info
->user_strm
->ss_stream_state
=
367 stream_info
->user_strm
->ss_stream_state
= STREAM_IDLE
;
375 * ======== strm_idle ========
377 * Idles a particular stream.
379 int strm_idle(struct strm_object
*stream_obj
, bool flush_data
)
381 struct bridge_drv_interface
*intf_fxns
;
384 DBC_REQUIRE(refs
> 0);
389 intf_fxns
= stream_obj
->strm_mgr_obj
->intf_fxns
;
391 status
= (*intf_fxns
->pfn_chnl_idle
) (stream_obj
->chnl_obj
,
392 stream_obj
->utimeout
,
396 dev_dbg(bridge
, "%s: stream_obj: %p flush_data: 0x%x status: 0x%x\n",
397 __func__
, stream_obj
, flush_data
, status
);
402 * ======== strm_init ========
404 * Initialize the STRM module.
410 DBC_REQUIRE(refs
>= 0);
415 DBC_ENSURE((ret
&& (refs
> 0)) || (!ret
&& (refs
>= 0)));
421 * ======== strm_issue ========
423 * Issues a buffer on a stream
425 int strm_issue(struct strm_object
*stream_obj
, IN u8
*pbuf
, u32 ul_bytes
,
426 u32 ul_buf_size
, u32 dw_arg
)
428 struct bridge_drv_interface
*intf_fxns
;
430 void *tmp_buf
= NULL
;
432 DBC_REQUIRE(refs
> 0);
433 DBC_REQUIRE(pbuf
!= NULL
);
438 intf_fxns
= stream_obj
->strm_mgr_obj
->intf_fxns
;
440 if (stream_obj
->segment_id
!= 0) {
441 tmp_buf
= cmm_xlator_translate(stream_obj
->xlator
,
448 if (DSP_SUCCEEDED(status
)) {
449 status
= (*intf_fxns
->pfn_chnl_add_io_req
)
450 (stream_obj
->chnl_obj
, pbuf
, ul_bytes
, ul_buf_size
,
451 (u32
) tmp_buf
, dw_arg
);
457 dev_dbg(bridge
, "%s: stream_obj: %p pbuf: %p ul_bytes: 0x%x dw_arg:"
458 " 0x%x status: 0x%x\n", __func__
, stream_obj
, pbuf
,
459 ul_bytes
, dw_arg
, status
);
464 * ======== strm_open ========
466 * Open a stream for sending/receiving data buffers to/from a task or
467 * XDAIS socket node on the DSP.
469 int strm_open(struct node_object
*hnode
, u32 dir
, u32 index
,
470 IN
struct strm_attr
*pattr
,
471 OUT
struct strm_object
**phStrm
,
472 struct process_context
*pr_ctxt
)
474 struct strm_mgr
*strm_mgr_obj
;
475 struct bridge_drv_interface
*intf_fxns
;
477 struct strm_object
*strm_obj
= NULL
;
479 struct chnl_attr chnl_attr_obj
;
481 struct cmm_object
*hcmm_mgr
= NULL
; /* Shared memory manager hndl */
485 DBC_REQUIRE(refs
> 0);
486 DBC_REQUIRE(phStrm
!= NULL
);
487 DBC_REQUIRE(pattr
!= NULL
);
489 if (dir
!= DSP_TONODE
&& dir
!= DSP_FROMNODE
) {
492 /* Get the channel id from the node (set in node_connect()) */
493 status
= node_get_channel_id(hnode
, dir
, index
, &ul_chnl_id
);
495 if (DSP_SUCCEEDED(status
))
496 status
= node_get_strm_mgr(hnode
, &strm_mgr_obj
);
498 if (DSP_SUCCEEDED(status
)) {
499 strm_obj
= kzalloc(sizeof(struct strm_object
), GFP_KERNEL
);
500 if (strm_obj
== NULL
) {
503 strm_obj
->strm_mgr_obj
= strm_mgr_obj
;
505 strm_obj
->strm_state
= STREAM_IDLE
;
506 strm_obj
->user_event
= pattr
->user_event
;
507 if (pattr
->stream_attr_in
!= NULL
) {
509 pattr
->stream_attr_in
->utimeout
;
511 pattr
->stream_attr_in
->num_bufs
;
512 strm_obj
->strm_mode
=
513 pattr
->stream_attr_in
->strm_mode
;
514 strm_obj
->segment_id
=
515 pattr
->stream_attr_in
->segment_id
;
516 strm_obj
->buf_alignment
=
517 pattr
->stream_attr_in
->buf_alignment
;
518 strm_obj
->udma_chnl_id
=
519 pattr
->stream_attr_in
->udma_chnl_id
;
520 strm_obj
->udma_priority
=
521 pattr
->stream_attr_in
->udma_priority
;
522 chnl_attr_obj
.uio_reqs
=
523 pattr
->stream_attr_in
->num_bufs
;
525 strm_obj
->utimeout
= DEFAULTTIMEOUT
;
526 strm_obj
->num_bufs
= DEFAULTNUMBUFS
;
527 strm_obj
->strm_mode
= STRMMODE_PROCCOPY
;
528 strm_obj
->segment_id
= 0; /* local mem */
529 strm_obj
->buf_alignment
= 0;
530 strm_obj
->udma_chnl_id
= 0;
531 strm_obj
->udma_priority
= 0;
532 chnl_attr_obj
.uio_reqs
= DEFAULTNUMBUFS
;
534 chnl_attr_obj
.reserved1
= NULL
;
535 /* DMA chnl flush timeout */
536 chnl_attr_obj
.reserved2
= strm_obj
->utimeout
;
537 chnl_attr_obj
.event_obj
= NULL
;
538 if (pattr
->user_event
!= NULL
)
539 chnl_attr_obj
.event_obj
= pattr
->user_event
;
543 if (DSP_FAILED(status
))
546 if ((pattr
->virt_base
== NULL
) || !(pattr
->ul_virt_size
> 0))
550 DBC_ASSERT(strm_obj
->strm_mode
!= STRMMODE_LDMA
);
551 /* Get the shared mem mgr for this streams dev object */
552 status
= dev_get_cmm_mgr(strm_mgr_obj
->dev_obj
, &hcmm_mgr
);
553 if (DSP_SUCCEEDED(status
)) {
554 /*Allocate a SM addr translator for this strm. */
555 status
= cmm_xlator_create(&strm_obj
->xlator
, hcmm_mgr
, NULL
);
556 if (DSP_SUCCEEDED(status
)) {
557 DBC_ASSERT(strm_obj
->segment_id
> 0);
558 /* Set translators Virt Addr attributes */
559 status
= cmm_xlator_info(strm_obj
->xlator
,
560 (u8
**) &pattr
->virt_base
,
562 strm_obj
->segment_id
, true);
566 if (DSP_SUCCEEDED(status
)) {
568 chnl_mode
= (dir
== DSP_TONODE
) ?
569 CHNL_MODETODSP
: CHNL_MODEFROMDSP
;
570 intf_fxns
= strm_mgr_obj
->intf_fxns
;
571 status
= (*intf_fxns
->pfn_chnl_open
) (&(strm_obj
->chnl_obj
),
572 strm_mgr_obj
->hchnl_mgr
,
573 chnl_mode
, ul_chnl_id
,
575 if (DSP_FAILED(status
)) {
577 * over-ride non-returnable status codes so we return
578 * something documented
580 if (status
!= -ENOMEM
&& status
!=
581 -EINVAL
&& status
!= -EPERM
) {
583 * We got a status that's not return-able.
584 * Assert that we got something we were
585 * expecting (-EFAULT isn't acceptable,
586 * strm_mgr_obj->hchnl_mgr better be valid or we
587 * assert here), and then return -EPERM.
589 DBC_ASSERT(status
== -ENOSR
||
591 status
== -EALREADY
||
597 if (DSP_SUCCEEDED(status
)) {
599 drv_proc_insert_strm_res_element(*phStrm
, &hstrm_res
, pr_ctxt
);
601 (void)delete_strm(strm_obj
);
604 /* ensure we return a documented error code */
605 DBC_ENSURE((DSP_SUCCEEDED(status
) && *phStrm
) ||
606 (*phStrm
== NULL
&& (status
== -EFAULT
||
608 || status
== -EINVAL
)));
610 dev_dbg(bridge
, "%s: hnode: %p dir: 0x%x index: 0x%x pattr: %p "
611 "phStrm: %p status: 0x%x\n", __func__
,
612 hnode
, dir
, index
, pattr
, phStrm
, status
);
617 * ======== strm_reclaim ========
619 * Relcaims a buffer from a stream.
621 int strm_reclaim(struct strm_object
*stream_obj
, OUT u8
** buf_ptr
,
622 u32
*pulBytes
, u32
*pulBufSize
, u32
*pdw_arg
)
624 struct bridge_drv_interface
*intf_fxns
;
625 struct chnl_ioc chnl_ioc_obj
;
627 void *tmp_buf
= NULL
;
629 DBC_REQUIRE(refs
> 0);
630 DBC_REQUIRE(buf_ptr
!= NULL
);
631 DBC_REQUIRE(pulBytes
!= NULL
);
632 DBC_REQUIRE(pdw_arg
!= NULL
);
638 intf_fxns
= stream_obj
->strm_mgr_obj
->intf_fxns
;
641 (*intf_fxns
->pfn_chnl_get_ioc
) (stream_obj
->chnl_obj
,
642 stream_obj
->utimeout
,
644 if (DSP_SUCCEEDED(status
)) {
645 *pulBytes
= chnl_ioc_obj
.byte_size
;
647 *pulBufSize
= chnl_ioc_obj
.buf_size
;
649 *pdw_arg
= chnl_ioc_obj
.dw_arg
;
650 if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj
)) {
651 if (CHNL_IS_TIMED_OUT(chnl_ioc_obj
)) {
654 /* Allow reclaims after idle to succeed */
655 if (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj
))
660 /* Translate zerocopy buffer if channel not canceled. */
661 if (DSP_SUCCEEDED(status
)
662 && (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj
))
663 && (stream_obj
->strm_mode
== STRMMODE_ZEROCOPY
)) {
665 * This is a zero-copy channel so chnl_ioc_obj.pbuf
666 * contains the DSP address of SM. We need to
667 * translate it to a virtual address for the user
669 * Note: Could add CMM_DSPPA2VA to CMM in the future.
671 tmp_buf
= cmm_xlator_translate(stream_obj
->xlator
,
674 if (tmp_buf
!= NULL
) {
675 /* now convert this GPP Pa to Va */
676 tmp_buf
= cmm_xlator_translate(stream_obj
->
684 chnl_ioc_obj
.pbuf
= tmp_buf
;
686 *buf_ptr
= chnl_ioc_obj
.pbuf
;
689 /* ensure we return a documented return code */
690 DBC_ENSURE(DSP_SUCCEEDED(status
) || status
== -EFAULT
||
691 status
== -ETIME
|| status
== -ESRCH
||
694 dev_dbg(bridge
, "%s: stream_obj: %p buf_ptr: %p pulBytes: %p "
695 "pdw_arg: %p status 0x%x\n", __func__
, stream_obj
,
696 buf_ptr
, pulBytes
, pdw_arg
, status
);
701 * ======== strm_register_notify ========
703 * Register to be notified on specific events for this stream.
705 int strm_register_notify(struct strm_object
*stream_obj
, u32 event_mask
,
706 u32 notify_type
, struct dsp_notification
709 struct bridge_drv_interface
*intf_fxns
;
712 DBC_REQUIRE(refs
> 0);
713 DBC_REQUIRE(hnotification
!= NULL
);
717 } else if ((event_mask
& ~((DSP_STREAMIOCOMPLETION
) |
718 DSP_STREAMDONE
)) != 0) {
721 if (notify_type
!= DSP_SIGNALEVENT
)
725 if (DSP_SUCCEEDED(status
)) {
726 intf_fxns
= stream_obj
->strm_mgr_obj
->intf_fxns
;
729 (*intf_fxns
->pfn_chnl_register_notify
) (stream_obj
->
735 /* ensure we return a documented return code */
736 DBC_ENSURE(DSP_SUCCEEDED(status
) || status
== -EFAULT
||
737 status
== -ETIME
|| status
== -ESRCH
||
738 status
== -ENOSYS
|| status
== -EPERM
);
743 * ======== strm_select ========
745 * Selects a ready stream.
747 int strm_select(IN
struct strm_object
**strm_tab
, u32 strms
,
748 OUT u32
*pmask
, u32 utimeout
)
751 struct chnl_info chnl_info_obj
;
752 struct bridge_drv_interface
*intf_fxns
;
753 struct sync_object
**sync_events
= NULL
;
757 DBC_REQUIRE(refs
> 0);
758 DBC_REQUIRE(strm_tab
!= NULL
);
759 DBC_REQUIRE(pmask
!= NULL
);
760 DBC_REQUIRE(strms
> 0);
763 for (i
= 0; i
< strms
; i
++) {
769 if (DSP_FAILED(status
))
772 /* Determine which channels have IO ready */
773 for (i
= 0; i
< strms
; i
++) {
774 intf_fxns
= strm_tab
[i
]->strm_mgr_obj
->intf_fxns
;
775 status
= (*intf_fxns
->pfn_chnl_get_info
) (strm_tab
[i
]->chnl_obj
,
777 if (DSP_FAILED(status
)) {
780 if (chnl_info_obj
.cio_cs
> 0)
785 if (DSP_SUCCEEDED(status
) && utimeout
> 0 && *pmask
== 0) {
786 /* Non-zero timeout */
787 sync_events
= kmalloc(strms
* sizeof(struct sync_object
*),
790 if (sync_events
== NULL
) {
793 for (i
= 0; i
< strms
; i
++) {
795 strm_tab
[i
]->strm_mgr_obj
->intf_fxns
;
796 status
= (*intf_fxns
->pfn_chnl_get_info
)
797 (strm_tab
[i
]->chnl_obj
, &chnl_info_obj
);
798 if (DSP_FAILED(status
))
802 chnl_info_obj
.sync_event
;
806 if (DSP_SUCCEEDED(status
)) {
808 sync_wait_on_multiple_events(sync_events
, strms
,
810 if (DSP_SUCCEEDED(status
)) {
811 /* Since we waited on the event, we have to
813 sync_set_event(sync_events
[index
]);
821 DBC_ENSURE((DSP_SUCCEEDED(status
) && (*pmask
!= 0 || utimeout
== 0)) ||
822 (DSP_FAILED(status
) && *pmask
== 0));
828 * ======== delete_strm ========
830 * Frees the resources allocated for a stream.
832 static int delete_strm(struct strm_object
*stream_obj
)
834 struct bridge_drv_interface
*intf_fxns
;
838 if (stream_obj
->chnl_obj
) {
839 intf_fxns
= stream_obj
->strm_mgr_obj
->intf_fxns
;
840 /* Channel close can fail only if the channel handle
842 status
= (*intf_fxns
->pfn_chnl_close
)
843 (stream_obj
->chnl_obj
);
844 /* Free all SM address translator resources */
845 if (DSP_SUCCEEDED(status
)) {
846 if (stream_obj
->xlator
) {
848 (void)cmm_xlator_delete(stream_obj
->
862 * ======== delete_strm_mgr ========
864 * Frees stream manager.
866 static void delete_strm_mgr(struct strm_mgr
*strm_mgr_obj
)