示例#1
0
/*
 *  ======== STRM_Close ========
 *  Purpose:
 *      Close a stream opened with STRM_Open().
 */
DSP_STATUS STRM_Close(struct STRM_OBJECT *hStrm,
		struct PROCESS_CONTEXT *pr_ctxt)
{
	struct WMD_DRV_INTERFACE *pIntfFxns;
	struct CHNL_INFO chnlInfo;
	DSP_STATUS status = DSP_SOK;

	HANDLE	      hSTRMRes;

	DBC_Require(cRefs > 0);

	GT_1trace(STRM_debugMask, GT_ENTER, "STRM_Close: hStrm: 0x%x\n", hStrm);


	/* Have all buffers been reclaimed? If not, return
	 * DSP_EPENDING */
	pIntfFxns = hStrm->hStrmMgr->pIntfFxns;
	status = (*pIntfFxns->pfnChnlGetInfo) (hStrm->hChnl, &chnlInfo);
	DBC_Assert(DSP_SUCCEEDED(status));

	if (chnlInfo.cIOCs > 0 || chnlInfo.cIOReqs > 0)
		status = DSP_EPENDING;
	else
		status = DeleteStrm(hStrm);

	if (DSP_FAILED(status))
		goto func_end;

	if (DRV_GetSTRMResElement(hStrm, &hSTRMRes, pr_ctxt) !=
			DSP_ENOTFOUND)
		DRV_ProcRemoveSTRMResElement(hSTRMRes, pr_ctxt);
func_end:
	DBC_Ensure(status == DSP_SOK || status == DSP_EHANDLE ||
		  status == DSP_EPENDING || status == DSP_EFAIL);

	return status;
}
示例#2
0
/*
 *  ======== STRM_Open ========
 *  Purpose:
 *      Open a stream for sending/receiving data buffers to/from a task or
 *      XDAIS socket node on the DSP.
 */
DSP_STATUS STRM_Open(struct NODE_OBJECT *hNode, u32 uDir, u32 uIndex,
		    IN struct STRM_ATTR *pAttr, OUT struct STRM_OBJECT **phStrm)
{
	struct STRM_MGR *hStrmMgr;
	struct WMD_DRV_INTERFACE *pIntfFxns;
	u32 ulChnlId;
	struct STRM_OBJECT *pStrm = NULL;
	CHNL_MODE uMode;
	struct CHNL_ATTRS chnlAttrs;
	DSP_STATUS status = DSP_SOK;
	struct CMM_OBJECT *hCmmMgr = NULL;	/* Shared memory manager hndl */

	#ifndef RES_CLEANUP_DISABLE
	DSP_STATUS res_status = DSP_SOK;
       u32                  hProcess;
	HANDLE	     pCtxt = NULL;
	HANDLE	     hDrvObject;
	HANDLE 		    hSTRMRes;
	#endif
	DBC_Require(cRefs > 0);
	DBC_Require(phStrm != NULL);
	DBC_Require(pAttr != NULL);
	GT_5trace(STRM_debugMask, GT_ENTER,
		 "STRM_Open: hNode: 0x%x\tuDir: 0x%x\t"
		 "uIndex: 0x%x\tpAttr: 0x%x\tphStrm: 0x%x\n",
		 hNode, uDir, uIndex, pAttr, phStrm);
	*phStrm = NULL;
	if (uDir != DSP_TONODE && uDir != DSP_FROMNODE) {
		status = DSP_EDIRECTION;
	} else {
		/* Get the channel id from the node (set in NODE_Connect()) */
		status = NODE_GetChannelId(hNode, uDir, uIndex, &ulChnlId);
	}
	if (DSP_SUCCEEDED(status))
		status = NODE_GetStrmMgr(hNode, &hStrmMgr);

	if (DSP_SUCCEEDED(status)) {
		MEM_AllocObject(pStrm, struct STRM_OBJECT, STRM_SIGNATURE);
		if (pStrm == NULL) {
			status = DSP_EMEMORY;
			GT_0trace(STRM_debugMask, GT_6CLASS,
				 "STRM_Open: MEM_AllocObject() failed!\n ");
		} else {
			pStrm->hStrmMgr = hStrmMgr;
			pStrm->uDir = uDir;
			pStrm->strmState = STREAM_IDLE;
			pStrm->hUserEvent = pAttr->hUserEvent;
			if (pAttr->pStreamAttrIn != NULL) {
				pStrm->uTimeout = pAttr->pStreamAttrIn->
						  uTimeout;
				pStrm->uNumBufs = pAttr->pStreamAttrIn->
						  uNumBufs;
				pStrm->lMode = pAttr->pStreamAttrIn->lMode;
				pStrm->uSegment = pAttr->pStreamAttrIn->
						  uSegment;
				pStrm->uAlignment = pAttr->pStreamAttrIn->
						    uAlignment;
				pStrm->uDMAChnlId = pAttr->pStreamAttrIn->
						    uDMAChnlId;
				pStrm->uDMAPriority = pAttr->pStreamAttrIn->
						      uDMAPriority;
				chnlAttrs.uIOReqs = pAttr->pStreamAttrIn->
						    uNumBufs;
			} else {
				pStrm->uTimeout = DEFAULTTIMEOUT;
				pStrm->uNumBufs = DEFAULTNUMBUFS;
				pStrm->lMode = STRMMODE_PROCCOPY;
				pStrm->uSegment = 0;	/* local memory */
				pStrm->uAlignment = 0;
				pStrm->uDMAChnlId = 0;
				pStrm->uDMAPriority = 0;
				chnlAttrs.uIOReqs = DEFAULTNUMBUFS;
			}
			chnlAttrs.hReserved1 = NULL;
			/* DMA chnl flush timeout */
			chnlAttrs.hReserved2 = pStrm->uTimeout;
			chnlAttrs.hEvent = NULL;
			if (pAttr->hUserEvent != NULL)
				chnlAttrs.hEvent = pAttr->hUserEvent;

		}
	}
	if (DSP_FAILED(status))
		goto func_cont;

	if ((pAttr->pVirtBase == NULL) || !(pAttr->ulVirtSize > 0))
		goto func_cont;

	DBC_Assert(pStrm->lMode != STRMMODE_LDMA);	/* no System DMA */
	/* Get the shared mem mgr for this streams dev object */
	status = DEV_GetCmmMgr(hStrmMgr->hDev, &hCmmMgr);
	if (DSP_FAILED(status)) {
		GT_1trace(STRM_debugMask, GT_6CLASS, "STRM_Open: Failed to get "
			 "CMM Mgr handle: 0x%x\n", status);
	} else {
		/*Allocate a SM addr translator for this strm.*/
		status = CMM_XlatorCreate(&pStrm->hXlator, hCmmMgr, NULL);
		if (DSP_FAILED(status)) {
			GT_1trace(STRM_debugMask, GT_6CLASS,
				 "STRM_Open: Failed to "
				 "create SM translator: 0x%x\n", status);
		} else {
			DBC_Assert(pStrm->uSegment > 0);
			/*  Set translators Virt Addr attributes */
			status = CMM_XlatorInfo(pStrm->hXlator,
				 (u8 **)&pAttr->pVirtBase, pAttr->ulVirtSize,
				 pStrm->uSegment, true);
			if (status != DSP_SOK) {
				GT_0trace(STRM_debugMask, GT_6CLASS,
					 "STRM_Open: ERROR: "
					 "in setting CMM_XlatorInfo.\n");
			}
		}
	}
func_cont:
	if (DSP_SUCCEEDED(status)) {
		/* Open channel */
		uMode = (uDir == DSP_TONODE) ?
			CHNL_MODETODSP : CHNL_MODEFROMDSP;
		pIntfFxns = hStrmMgr->pIntfFxns;
		status = (*pIntfFxns->pfnChnlOpen) (&(pStrm->hChnl),
			 hStrmMgr->hChnlMgr, uMode, ulChnlId, &chnlAttrs);
		if (DSP_FAILED(status)) {
			/*
			 * over-ride non-returnable status codes so we return
			 * something documented
			 */
			if (status != DSP_EMEMORY && status !=
			   DSP_EINVALIDARG && status != DSP_EFAIL) {
				/*
				 * We got a status that's not return-able.
				 * Assert that we got something we were
				 * expecting (DSP_EHANDLE isn't acceptable,
				 * hStrmMgr->hChnlMgr better be valid or we
				 * assert here), and then return DSP_EFAIL.
				 */
				DBC_Assert(status == CHNL_E_OUTOFSTREAMS ||
					   status == CHNL_E_BADCHANID ||
					   status == CHNL_E_CHANBUSY ||
					   status == CHNL_E_NOIORPS);
				status = DSP_EFAIL;
			}
			GT_2trace(STRM_debugMask, GT_6CLASS,
				  "STRM_Open: Channel open failed, "
				  "chnl id = %d, status = 0x%x\n", ulChnlId,
				  status);
		}
	}
	if (DSP_SUCCEEDED(status))
		*phStrm = pStrm;
	else
		(void)DeleteStrm(pStrm);

#ifndef RES_CLEANUP_DISABLE
       /* Return PID instead of process handle */
       hProcess = current->pid;

	res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT);
	if (DSP_SUCCEEDED(res_status)) {
               DRV_GetProcContext(hProcess,
				 (struct DRV_OBJECT *)hDrvObject, &pCtxt,
				 hNode, 0);
		if (pCtxt != NULL)
			DRV_ProcInsertSTRMResElement(*phStrm, &hSTRMRes, pCtxt);

	}
#endif

	 /* ensure we return a documented error code */
	DBC_Ensure((DSP_SUCCEEDED(status) &&
		  MEM_IsValidHandle((*phStrm), STRM_SIGNATURE)) ||
		  (*phStrm == NULL && (status == DSP_EHANDLE ||
		  status == DSP_EDIRECTION || status == DSP_EVALUE ||
		  status == DSP_EFAIL)));
	return status;
}
示例#3
0
/*
 *  ======== STRM_Close ========
 *  Purpose:
 *      Close a stream opened with STRM_Open().
 */
DSP_STATUS STRM_Close(struct STRM_OBJECT *hStrm)
{
	struct WMD_DRV_INTERFACE *pIntfFxns;
	struct CHNL_INFO chnlInfo;
	DSP_STATUS status = DSP_SOK;


#ifndef RES_CLEANUP_DISABLE
    u32                      hProcess;
    HANDLE	      pCtxt = NULL;
    HANDLE	      hDrvObject;
    HANDLE	      hSTRMRes;
    DSP_STATUS	  res_status = DSP_SOK;
#endif


	DBC_Require(cRefs > 0);

	GT_1trace(STRM_debugMask, GT_ENTER, "STRM_Close: hStrm: 0x%x\n", hStrm);

	if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) {
		status = DSP_EHANDLE;
	} else {
		/* Have all buffers been reclaimed? If not, return
		 * DSP_EPENDING */
		pIntfFxns = hStrm->hStrmMgr->pIntfFxns;
		status = (*pIntfFxns->pfnChnlGetInfo) (hStrm->hChnl, &chnlInfo);
		DBC_Assert(DSP_SUCCEEDED(status));

		if (chnlInfo.cIOCs > 0 || chnlInfo.cIOReqs > 0) {
			status = DSP_EPENDING;
		} else {

			status = DeleteStrm(hStrm);

			if (DSP_FAILED(status)) {
				/* we already validated the handle. */
				DBC_Assert(status != DSP_EHANDLE);

				/* make sure we return a documented result */
				status = DSP_EFAIL;
			}
		}
	}
#ifndef RES_CLEANUP_DISABLE
	if (DSP_FAILED(status))
		goto func_end;

	/* Update the node and stream resource status */
       /* Return PID instead of process handle */
       hProcess = current->pid;

	res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT);
	if (DSP_FAILED(res_status))
		goto func_end;

       DRV_GetProcContext(hProcess, (struct DRV_OBJECT *)hDrvObject,
			 &pCtxt, NULL, 0);
	if (pCtxt != NULL) {
		if (DRV_GetSTRMResElement(hStrm, &hSTRMRes, pCtxt) !=
		   DSP_ENOTFOUND) {
			DRV_ProcRemoveSTRMResElement(hSTRMRes, pCtxt);
		}
	}
func_end:
#endif
	DBC_Ensure(status == DSP_SOK || status == DSP_EHANDLE ||
		  status == DSP_EPENDING || status == DSP_EFAIL);

	return status;
}