/* * ======== 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; }
/* * ======== 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; }