Beispiel #1
0
/*
 *  ======== cmm_xlator_alloc_buf ========
 */
void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator, void *pVaBuf,
			   u32 uPaSize)
{
	struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
	void *pbuf = NULL;
	struct cmm_attrs attrs;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(xlator != NULL);
	DBC_REQUIRE(xlator_obj->hcmm_mgr != NULL);
	DBC_REQUIRE(pVaBuf != NULL);
	DBC_REQUIRE(uPaSize > 0);
	DBC_REQUIRE(xlator_obj->ul_seg_id > 0);

	if (xlator_obj) {
		attrs.ul_seg_id = xlator_obj->ul_seg_id;
		*(volatile u32 *)pVaBuf = 0;
		/* Alloc SM */
		pbuf =
		    cmm_calloc_buf(xlator_obj->hcmm_mgr, uPaSize, &attrs, NULL);
		if (pbuf) {
			/* convert to translator(node/strm) process Virtual
			 * address */
			*(volatile u32 **)pVaBuf =
			    (u32 *) cmm_xlator_translate(xlator,
							 pbuf, CMM_PA2VA);
		}
	}
	return pbuf;
}
Beispiel #2
0
/*
 *  ======== cmm_xlator_free_buf ========
 *  Purpose:
 *      Free the given SM buffer and descriptor.
 *      Does not free virtual memory.
 */
int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *pBufVa)
{
	struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
	int status = -EPERM;
	void *buf_pa = NULL;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(pBufVa != NULL);
	DBC_REQUIRE(xlator_obj->ul_seg_id > 0);

	if (xlator_obj) {
		/* convert Va to Pa so we can free it. */
		buf_pa = cmm_xlator_translate(xlator, pBufVa, CMM_VA2PA);
		if (buf_pa) {
			status = cmm_free_buf(xlator_obj->hcmm_mgr, buf_pa,
					      xlator_obj->ul_seg_id);
			if (DSP_FAILED(status)) {
				/* Uh oh, this shouldn't happen. Descriptor
				 * gone! */
				DBC_ASSERT(false);	/* CMM is leaking mem */
			}
		}
	}
	return status;
}
Beispiel #3
0
Datei: strm.c Projekt: 7799/linux
/*
 *  ======== strm_issue ========
 *  Purpose:
 *      Issues a buffer on a stream
 */
int strm_issue(struct strm_object *stream_obj, u8 *pbuf, u32 ul_bytes,
		      u32 ul_buf_size, u32 dw_arg)
{
	struct bridge_drv_interface *intf_fxns;
	int status = 0;
	void *tmp_buf = NULL;

	if (!stream_obj) {
		status = -EFAULT;
	} else {
		intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;

		if (stream_obj->segment_id != 0) {
			tmp_buf = cmm_xlator_translate(stream_obj->xlator,
						       (void *)pbuf,
						       CMM_VA2DSPPA);
			if (tmp_buf == NULL)
				status = -ESRCH;

		}
		if (!status) {
			status = (*intf_fxns->chnl_add_io_req)
			    (stream_obj->chnl_obj, pbuf, ul_bytes, ul_buf_size,
			     (u32) tmp_buf, dw_arg);
		}
		if (status == -EIO)
			status = -ENOSR;
	}

	dev_dbg(bridge, "%s: stream_obj: %p pbuf: %p ul_bytes: 0x%x dw_arg:"
		" 0x%x status: 0x%x\n", __func__, stream_obj, pbuf,
		ul_bytes, dw_arg, status);
	return status;
}
Beispiel #4
0
/*
 *  ======== strm_reclaim ========
 *  Purpose:
 *      Relcaims a buffer from a stream.
 */
int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr,
			u32 *nbytes, u32 *buff_size, u32 *pdw_arg)
{
	struct bridge_drv_interface *intf_fxns;
	struct chnl_ioc chnl_ioc_obj;
	int status = 0;
	void *tmp_buf = NULL;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(buf_ptr != NULL);
	DBC_REQUIRE(nbytes != NULL);
	DBC_REQUIRE(pdw_arg != NULL);

	if (!stream_obj) {
		status = -EFAULT;
		goto func_end;
	}
	intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;

	status =
	    (*intf_fxns->chnl_get_ioc) (stream_obj->chnl_obj,
					    stream_obj->timeout,
					    &chnl_ioc_obj);
	if (!status) {
		*nbytes = chnl_ioc_obj.byte_size;
		if (buff_size)
			*buff_size = chnl_ioc_obj.buf_size;

		*pdw_arg = chnl_ioc_obj.arg;
		if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
			if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) {
				status = -ETIME;
			} else {
				/* Allow reclaims after idle to succeed */
				if (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj))
					status = -EPERM;

			}
		}
		/* Translate zerocopy buffer if channel not canceled. */
		if (!status
		    && (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj))
		    && (stream_obj->strm_mode == STRMMODE_ZEROCOPY)) {
			/*
			 *  This is a zero-copy channel so chnl_ioc_obj.buf
			 *  contains the DSP address of SM. We need to
			 *  translate it to a virtual address for the user
			 *  thread to access.
			 *  Note: Could add CMM_DSPPA2VA to CMM in the future.
			 */
			tmp_buf = cmm_xlator_translate(stream_obj->xlator,
						       chnl_ioc_obj.buf,
						       CMM_DSPPA2PA);
			if (tmp_buf != NULL) {
				/* now convert this GPP Pa to Va */
				tmp_buf = cmm_xlator_translate(stream_obj->
							       xlator,
							       tmp_buf,
							       CMM_PA2VA);
			}
			if (tmp_buf == NULL)
				status = -ESRCH;

			chnl_ioc_obj.buf = tmp_buf;
		}
		*buf_ptr = chnl_ioc_obj.buf;
	}
func_end:
	/* ensure we return a documented return code */
	DBC_ENSURE(!status || status == -EFAULT ||
		   status == -ETIME || status == -ESRCH ||
		   status == -EPERM);

	dev_dbg(bridge, "%s: stream_obj: %p buf_ptr: %p nbytes: %p "
		"pdw_arg: %p status 0x%x\n", __func__, stream_obj,
		buf_ptr, nbytes, pdw_arg, status);
	return status;
}