Esempio n. 1
0
/*
 *  ======== strm_allocate_buffer ========
 *  Purpose:
 *      Allocates buffers for a stream.
 */
int strm_allocate_buffer(struct strm_res_object *strmres, u32 usize,
				u8 **ap_buffer, u32 num_bufs,
				struct process_context *pr_ctxt)
{
	int status = 0;
	u32 alloc_cnt = 0;
	u32 i;
	struct strm_object *stream_obj = strmres->stream;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(ap_buffer != NULL);

	if (stream_obj) {
		/*
		 * Allocate from segment specified at time of stream open.
		 */
		if (usize == 0)
			status = -EINVAL;

	} else {
		status = -EFAULT;
	}

	if (status)
		goto func_end;

	for (i = 0; i < num_bufs; i++) {
		DBC_ASSERT(stream_obj->xlator != NULL);
		(void)cmm_xlator_alloc_buf(stream_obj->xlator, &ap_buffer[i],
					   usize);
		if (ap_buffer[i] == NULL) {
			status = -ENOMEM;
			alloc_cnt = i;
			break;
		}
	}
	if (status)
		strm_free_buffer(strmres, ap_buffer, alloc_cnt, pr_ctxt);

	if (status)
		goto func_end;

	drv_proc_update_strm_res(num_bufs, strmres);

func_end:
	return status;
}
Esempio n. 2
0
/*
 *  ======== node_alloc_msg_buf ========
 *  Purpose:
 *      Allocates buffer for zero copy messaging.
 */
DBAPI node_alloc_msg_buf(struct node_object *hnode, u32 usize,
			 struct dsp_bufferattr *pattr,
			 u8 **pbuffer)
{
	struct node_object *pnode = (struct node_object *)hnode;
	int status = 0;
	bool va_flag = false;
	bool set_info;
	u32 proc_id;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(pbuffer != NULL);

	DBC_REQUIRE(usize > 0);

	if (!pnode)
		status = -EFAULT;
	else if (node_get_type(pnode) == NODE_DEVICE)
		status = -EPERM;

	if (status)
		goto func_end;

	if (pattr == NULL)
		pattr = &node_dfltbufattrs;	/* set defaults */

	status = proc_get_processor_id(pnode->hprocessor, &proc_id);
	if (proc_id != DSP_UNIT) {
		DBC_ASSERT(NULL);
		goto func_end;
	}
	/*  If segment ID includes MEM_SETVIRTUALSEGID then pbuffer is a
	 *  virt  address, so set this info in this node's translator
	 *  object for  future ref. If MEM_GETVIRTUALSEGID then retrieve
	 *  virtual address  from node's translator. */
	if ((pattr->segment_id & MEM_SETVIRTUALSEGID) ||
	    (pattr->segment_id & MEM_GETVIRTUALSEGID)) {
		va_flag = true;
		set_info = (pattr->segment_id & MEM_SETVIRTUALSEGID) ?
		    true : false;
		/* Clear mask bits */
		pattr->segment_id &= ~MEM_MASKVIRTUALSEGID;
		/* Set/get this node's translators virtual address base/size */
		status = cmm_xlator_info(pnode->xlator, pbuffer, usize,
					 pattr->segment_id, set_info);
	}
	if (!status && (!va_flag)) {
		if (pattr->segment_id != 1) {
			/* Node supports single SM segment only. */
			status = -EBADR;
		}
		/*  Arbitrary SM buffer alignment not supported for host side
		 *  allocs, but guaranteed for the following alignment
		 *  values. */
		switch (pattr->buf_alignment) {
		case 0:
		case 1:
		case 2:
		case 4:
			break;
		default:
			/* alignment value not suportted */
			status = -EPERM;
			break;
		}
		if (!status) {
			/* allocate physical buffer from seg_id in node's
			 * translator */
			(void)cmm_xlator_alloc_buf(pnode->xlator, pbuffer,
						   usize);
			if (*pbuffer == NULL) {
				pr_err("%s: error - Out of shared memory\n",
				       __func__);
				status = -ENOMEM;
			}
		}
	}
func_end:
	return status;
}