u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt) { int status = 0; u8 **ap_buffer = NULL; u32 num_bufs = args->args_strm_freebuffer.num_bufs; struct strm_res_object *strm_res; find_strm_handle(&strm_res, pr_ctxt, args->args_strm_freebuffer.stream); if (!strm_res) return -EFAULT; if (num_bufs > MAX_BUFS) return -EINVAL; ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL); if (ap_buffer == NULL) return -ENOMEM; CP_FM_USR(ap_buffer, args->args_strm_freebuffer.ap_buffer, status, num_bufs); if (!status) status = strm_free_buffer(strm_res, ap_buffer, num_bufs, pr_ctxt); CP_TO_USR(args->args_strm_freebuffer.ap_buffer, ap_buffer, status, num_bufs); kfree(ap_buffer); return status; }
/* * ======== 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; }