Exemple #1
0
/*
 *  ======== MGR_WaitForBridgeEvents ========
 *      Block on any Bridge event(s)
 */
DSP_STATUS MGR_WaitForBridgeEvents(struct DSP_NOTIFICATION **aNotifications,
				  u32 uCount, OUT u32 *puIndex, u32 uTimeout)
{
	DSP_STATUS status;
	struct SYNC_OBJECT *hSyncEvents[MAX_EVENTS];
	u32 i;

	DBC_Require(uCount < MAX_EVENTS);

	for (i = 0; i < uCount; i++)
		hSyncEvents[i] = aNotifications[i]->handle;

	status = SYNC_WaitOnMultipleEvents(hSyncEvents, uCount, uTimeout,
					 puIndex);

	return status;

}
Exemple #2
0
/*
 *  ======== STRM_Select ========
 *  Purpose:
 *      Selects a ready stream.
 */
DSP_STATUS STRM_Select(IN struct STRM_OBJECT **aStrmTab, u32 nStrms,
		      OUT u32 *pMask, u32 uTimeout)
{
	u32 uIndex;
	struct CHNL_INFO chnlInfo;
	struct WMD_DRV_INTERFACE *pIntfFxns;
	struct SYNC_OBJECT **hSyncEvents = NULL;
	u32 i;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(cRefs > 0);
	DBC_Require(aStrmTab != NULL);
	DBC_Require(pMask != NULL);
	DBC_Require(nStrms > 0);

	GT_4trace(STRM_debugMask, GT_ENTER,
		 "STRM_Select: aStrmTab: 0x%x \tnStrms: "
		 "0x%x\tpMask: 0x%x\tuTimeout: 0x%x\n", aStrmTab,
		 nStrms, pMask, uTimeout);
	*pMask = 0;
	for (i = 0; i < nStrms; i++) {
		if (!MEM_IsValidHandle(aStrmTab[i], STRM_SIGNATURE)) {
			status = DSP_EHANDLE;
			break;
		}
	}
	if (DSP_FAILED(status))
		goto func_end;

	/* Determine which channels have IO ready */
	for (i = 0; i < nStrms; i++) {
		pIntfFxns = aStrmTab[i]->hStrmMgr->pIntfFxns;
		status = (*pIntfFxns->pfnChnlGetInfo)(aStrmTab[i]->hChnl,
			 &chnlInfo);
		if (DSP_FAILED(status)) {
			break;
		} else {
			if (chnlInfo.cIOCs > 0)
				*pMask |= (1 << i);

		}
	}
	if (DSP_SUCCEEDED(status) && uTimeout > 0 && *pMask == 0) {
		/* Non-zero timeout */
		hSyncEvents = (struct SYNC_OBJECT **)MEM_Alloc(nStrms *
			      sizeof(struct SYNC_OBJECT *), MEM_PAGED);
		if (hSyncEvents == NULL) {
			status = DSP_EMEMORY;
		} else {
			for (i = 0; i < nStrms; i++) {
				pIntfFxns = aStrmTab[i]->hStrmMgr->pIntfFxns;
				status = (*pIntfFxns->pfnChnlGetInfo)
					 (aStrmTab[i]->hChnl, &chnlInfo);
				if (DSP_FAILED(status))
					break;
				else
					hSyncEvents[i] = chnlInfo.hSyncEvent;

			}
		}
		if (DSP_SUCCEEDED(status)) {
			status = SYNC_WaitOnMultipleEvents(hSyncEvents, nStrms,
				uTimeout, &uIndex);
			if (DSP_SUCCEEDED(status)) {
				/* Since we waited on the event, we have to
				 * reset it */
				SYNC_SetEvent(hSyncEvents[uIndex]);
				*pMask = 1 << uIndex;
			}
		}
	}
func_end:
	if (hSyncEvents)
		MEM_Free(hSyncEvents);

	DBC_Ensure((DSP_SUCCEEDED(status) && (*pMask != 0 || uTimeout == 0)) ||
		  (DSP_FAILED(status) && *pMask == 0));

	return status;
}
Exemple #3
0
/*
 *  ======== WMD_MSG_Put ========
 *      Put a message onto a MSG queue.
 */
DSP_STATUS WMD_MSG_Put(struct MSG_QUEUE *hMsgQueue,
		      IN CONST struct DSP_MSG *pMsg, u32 uTimeout)
{
	struct MSG_FRAME *pMsgFrame;
	struct MSG_MGR *hMsgMgr;
	bool fPutMsg = false;
	struct SYNC_OBJECT *hSyncs[2];
	u32 uIndex;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(MEM_IsValidHandle(hMsgQueue, MSGQ_SIGNATURE));
	DBC_Require(pMsg != NULL);

	hMsgMgr = hMsgQueue->hMsgMgr;

       if (!hMsgMgr->msgFreeList) {
               status = DSP_EHANDLE;
               goto func_end;
       }


	(void) SYNC_EnterCS(hMsgMgr->hSyncCS);

	/* If a message frame is available, use it */
	if (!LST_IsEmpty(hMsgMgr->msgFreeList)) {
		pMsgFrame = (struct MSG_FRAME *)LST_GetHead(hMsgMgr->
			    msgFreeList);
		if (pMsgFrame != NULL) {
			pMsgFrame->msgData.msg = *pMsg;
			pMsgFrame->msgData.dwId = hMsgQueue->dwId;
			LST_PutTail(hMsgMgr->msgUsedList, (struct LST_ELEM *)
				   pMsgFrame);
			hMsgMgr->uMsgsPending++;
			fPutMsg = true;
		}
		if (LST_IsEmpty(hMsgMgr->msgFreeList))
			SYNC_ResetEvent(hMsgMgr->hSyncEvent);

		/* Release critical section before scheduling DPC */
		(void)SYNC_LeaveCS(hMsgMgr->hSyncCS);
		/* Schedule a DPC, to do the actual data transfer: */
		IO_Schedule(hMsgMgr->hIOMgr);
	} else {
		if (hMsgQueue->fDone)
			status = DSP_EFAIL;
		else
			hMsgQueue->refCount++;

		(void)SYNC_LeaveCS(hMsgMgr->hSyncCS);
	}
	if (DSP_SUCCEEDED(status) && !fPutMsg) {
		/* Wait til a free message frame is available, timeout,
		 * or done */
		hSyncs[0] = hMsgMgr->hSyncEvent;
		hSyncs[1] = hMsgQueue->hSyncDone;
		status = SYNC_WaitOnMultipleEvents(hSyncs, 2, uTimeout,
			 &uIndex);
		/* Enter critical section */
		(void)SYNC_EnterCS(hMsgMgr->hSyncCS);
		if (hMsgQueue->fDone) {
			hMsgQueue->refCount--;
			/* Exit critical section */
			(void)SYNC_LeaveCS(hMsgMgr->hSyncCS);
			 /*  Signal that we're not going to access hMsgQueue
			  *  anymore, so it can be deleted.  */
			(void)SYNC_SetEvent(hMsgQueue->hSyncDoneAck);
			status = DSP_EFAIL;
		} else {
			if (DSP_SUCCEEDED(status)) {
                               if (LST_IsEmpty(hMsgMgr->msgFreeList)) {
                                       status = DSP_EPOINTER;
                                       goto func_cont;
                               }
				/* Get msg from free list */
				pMsgFrame = (struct MSG_FRAME *)
					    LST_GetHead(hMsgMgr->msgFreeList);
				/* Copy message into pMsg and put frame on the
				 * used list */
				if (pMsgFrame != NULL) {
					pMsgFrame->msgData.msg = *pMsg;
					pMsgFrame->msgData.dwId =
						hMsgQueue->dwId;
					LST_PutTail(hMsgMgr->msgUsedList,
						   (struct LST_ELEM *)
						   pMsgFrame);
					hMsgMgr->uMsgsPending++;
					/* Schedule a DPC, to do the actual
					 * data transfer: */
					IO_Schedule(hMsgMgr->hIOMgr);
				}
			}
			hMsgQueue->refCount--;
			/* Reset event if there are still frames available */
			if (!LST_IsEmpty(hMsgMgr->msgFreeList))
				SYNC_SetEvent(hMsgMgr->hSyncEvent);
func_cont:
			/* Exit critical section */
			(void) SYNC_LeaveCS(hMsgMgr->hSyncCS);
		}
	}
func_end:
	return status;
}
Exemple #4
0
/*
 *  ======== WMD_MSG_Get ========
 *      Get a message from a MSG queue.
 */
DSP_STATUS WMD_MSG_Get(struct MSG_QUEUE *hMsgQueue,
		      struct DSP_MSG *pMsg, u32 uTimeout)
{
	struct MSG_FRAME *pMsgFrame;
	struct MSG_MGR *hMsgMgr;
	bool fGotMsg = false;
	struct SYNC_OBJECT *hSyncs[2];
	u32 uIndex;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(MEM_IsValidHandle(hMsgQueue, MSGQ_SIGNATURE));
	DBC_Require(pMsg != NULL);

	hMsgMgr = hMsgQueue->hMsgMgr;
       if (!hMsgQueue->msgUsedList) {
               status = DSP_EHANDLE;
               goto func_end;
       }

	/* Enter critical section */
	(void)SYNC_EnterCS(hMsgMgr->hSyncCS);
	/* If a message is already there, get it */
	if (!LST_IsEmpty(hMsgQueue->msgUsedList)) {
		pMsgFrame = (struct MSG_FRAME *)LST_GetHead(hMsgQueue->
			    msgUsedList);
		if (pMsgFrame != NULL) {
			*pMsg = pMsgFrame->msgData.msg;
			LST_PutTail(hMsgQueue->msgFreeList,
				   (struct LST_ELEM *)pMsgFrame);
			if (LST_IsEmpty(hMsgQueue->msgUsedList))
				SYNC_ResetEvent(hMsgQueue->hSyncEvent);
			else {
				NTFY_Notify(hMsgQueue->hNtfy,
				    DSP_NODEMESSAGEREADY);
				SYNC_SetEvent(hMsgQueue->hSyncEvent);
			}

			fGotMsg = true;
		}
	} else {
		if (hMsgQueue->fDone)
			status = DSP_EFAIL;
		else
			hMsgQueue->refCount++;

	}
	/* Exit critical section */
	(void)SYNC_LeaveCS(hMsgMgr->hSyncCS);
	if (DSP_SUCCEEDED(status) && !fGotMsg) {
		/*  Wait til message is available, timeout, or done. We don't
		 *  have to schedule the DPC, since the DSP will send messages
		 *  when they are available.  */
		hSyncs[0] = hMsgQueue->hSyncEvent;
		hSyncs[1] = hMsgQueue->hSyncDone;
		status = SYNC_WaitOnMultipleEvents(hSyncs, 2, uTimeout,
			 &uIndex);
		/* Enter critical section */
		(void)SYNC_EnterCS(hMsgMgr->hSyncCS);
		if (hMsgQueue->fDone) {
			hMsgQueue->refCount--;
			/* Exit critical section */
			(void)SYNC_LeaveCS(hMsgMgr->hSyncCS);
			 /*  Signal that we're not going to access hMsgQueue
			  *  anymore, so it can be deleted.  */
			(void)SYNC_SetEvent(hMsgQueue->hSyncDoneAck);
			status = DSP_EFAIL;
		} else {
			if (DSP_SUCCEEDED(status)) {
				DBC_Assert(!LST_IsEmpty(hMsgQueue->
					  msgUsedList));
				/* Get msg from used list */
				pMsgFrame = (struct MSG_FRAME *)
					   LST_GetHead(hMsgQueue->msgUsedList);
				/* Copy message into pMsg and put frame on the
				 * free list */
				if (pMsgFrame != NULL) {
					*pMsg = pMsgFrame->msgData.msg;
					LST_PutTail(hMsgQueue->msgFreeList,
					(struct LST_ELEM *)pMsgFrame);
				}
			}
			hMsgQueue->refCount--;
			/* Reset the event if there are still queued messages */
			if (!LST_IsEmpty(hMsgQueue->msgUsedList)) {
				NTFY_Notify(hMsgQueue->hNtfy,
					DSP_NODEMESSAGEREADY);
				SYNC_SetEvent(hMsgQueue->hSyncEvent);
			}

			/* Exit critical section */
			(void)SYNC_LeaveCS(hMsgMgr->hSyncCS);
		}
	}
func_end:
	return status;
}