/** * sst_drain_stream - Send msg for draining stream * @str_id: stream ID * * This function is called by any function which wants to drain * a stream. */ int sst_drain_stream(int str_id, bool partial_drain) { int retval = 0, pvt_id, len; struct ipc_post *msg = NULL; struct stream_info *str_info; struct intel_sst_ops *ops; unsigned long irq_flags; struct sst_block *block = NULL; struct ipc_dsp_hdr dsp_hdr; pr_debug("SST DBG:sst_drain_stream for %d\n", str_id); str_info = get_stream_info(str_id); if (!str_info) return -EINVAL; ops = sst_drv_ctx->ops; if (str_info->status != STREAM_RUNNING && str_info->status != STREAM_INIT && str_info->status != STREAM_PAUSED) { pr_err("SST ERR: BADQRC for stream = %d\n", str_info->status); return -EBADRQC; } if (!sst_drv_ctx->use_32bit_ops) { pvt_id = sst_assign_pvt_id(sst_drv_ctx); retval = sst_create_block_and_ipc_msg(&msg, true, sst_drv_ctx, &block, IPC_CMD, pvt_id); if (retval) return retval; sst_fill_header_mrfld(&msg->mrfld_header, IPC_CMD, str_info->task_id, 1, pvt_id); pr_debug("header:%x\n", (unsigned int)msg->mrfld_header.p.header_high.full); msg->mrfld_header.p.header_high.part.res_rqd = 1; len = sizeof(u8) + sizeof(dsp_hdr); msg->mrfld_header.p.header_low_payload = len; sst_fill_header_dsp(&dsp_hdr, IPC_IA_DRAIN_STREAM_MRFLD, str_info->pipe_id, sizeof(u8)); memcpy(msg->mailbox_data, &dsp_hdr, sizeof(dsp_hdr)); memcpy(msg->mailbox_data + sizeof(dsp_hdr), &partial_drain, sizeof(u8)); } else { retval = sst_create_block_and_ipc_msg(&msg, false, sst_drv_ctx, &block, IPC_IA_DRAIN_STREAM, str_id); if (retval) return retval; sst_fill_header(&msg->header, IPC_IA_DRAIN_STREAM, 0, str_id); msg->header.part.data = partial_drain; } spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags); list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list); spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags); ops->post_message(&sst_drv_ctx->ipc_post_msg_wq); retval = sst_wait_interruptible(sst_drv_ctx, block); sst_free_block(sst_drv_ctx, block); return retval; }
/** * sst_drain_stream - Send msg for draining stream * @str_id: stream ID * * This function is called by any function which wants to drain * a stream. */ int sst_drain_stream(int str_id) { int retval = 0; struct ipc_post *msg = NULL; struct stream_info *str_info; struct intel_sst_ops *ops; unsigned long irq_flags; pr_debug("SST DBG:sst_drain_stream for %d\n", str_id); str_info = get_stream_info(str_id); if (!str_info) return -EINVAL; ops = sst_drv_ctx->ops; if (str_info->status != STREAM_RUNNING && str_info->status != STREAM_INIT && str_info->status != STREAM_PAUSED) { pr_err("SST ERR: BADQRC for stream = %d\n", str_info->status); return -EBADRQC; } if (str_info->status == STREAM_INIT) { if (sst_create_short_msg(&msg)) { pr_err("SST ERR: mem allocation failed\n"); return -ENOMEM; } sst_fill_header(&msg->header, IPC_IA_DRAIN_STREAM, 0, str_id); spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags); list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list); spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags); ops->post_message(&sst_drv_ctx->ipc_post_msg_wq); str_info->data_blk.condition = false; str_info->data_blk.ret_code = 0; str_info->data_blk.on = true; retval = sst_wait_interruptible(sst_drv_ctx, &str_info->data_blk); } return retval; }