static u32 vcd_stop_cmn(struct vcd_clnt_ctxt *cctxt) { struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; u32 rc = VCD_S_SUCCESS; struct vcd_transc *transc; VCD_MSG_LOW("vcd_stop_cmn in %d:", cctxt->clnt_state.state); rc = vcd_flush_buffers(cctxt, VCD_FLUSH_ALL); VCD_FAILED_RETURN(rc, "Failed: vcd_flush_buffers"); if (!cctxt->status.frame_submitted) { if (vcd_get_command_channel(dev_ctxt, &transc)) { rc = vcd_power_event(dev_ctxt, cctxt, VCD_EVT_PWR_CLNT_CMD_BEGIN); if (!VCD_FAILED(rc)) { transc->type = VCD_CMD_CODEC_STOP; transc->cctxt = cctxt; rc = vcd_submit_cmd_sess_end(transc); } else { VCD_MSG_ERROR("Failed:" " VCD_EVT_PWR_CLNT_CMD_BEGIN"); } if (VCD_FAILED(rc)) { vcd_release_command_channel(dev_ctxt, transc); } } else { vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CODEC_STOP); } } if (VCD_FAILED(rc)) { (void)vcd_power_event(dev_ctxt, cctxt, VCD_EVT_PWR_CLNT_CMD_FAIL); } else { vcd_do_client_state_transition(cctxt, VCD_CLIENT_STATE_STOPPING, CLIENT_STATE_EVENT_NUMBER (stop)); } return rc; }
static void vcd_clnt_cb_in_stopping (struct vcd_clnt_ctxt *cctxt, u32 event, u32 status, void *payload, size_t sz, u32 *ddl_handle, void *const client_data) { struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; u32 rc = VCD_S_SUCCESS; u32 frm_trans_end = false; VCD_MSG_LOW("vcd_clnt_cb_in_stopping:"); if (cctxt->ddl_handle != ddl_handle) { VCD_MSG_ERROR("ddl_handle mismatch"); return; } switch (event) { case VCD_EVT_RESP_INPUT_DONE: { rc = vcd_handle_input_done(cctxt, payload, VCD_EVT_RESP_INPUT_FLUSHED, status); break; } case VCD_EVT_RESP_OUTPUT_DONE: { rc = vcd_handle_frame_done(cctxt, payload, VCD_EVT_RESP_OUTPUT_FLUSHED, status); break; } case VCD_EVT_RESP_OUTPUT_REQ: { rc = vcd_handle_output_required_in_flushing(cctxt, payload); break; } case VCD_EVT_RESP_STOP: { vcd_handle_stop_done(cctxt, (struct vcd_transc *) client_data, status); break; } case VCD_EVT_IND_OUTPUT_RECONFIG: { (void) vcd_handle_ind_output_reconfig(cctxt, payload, status); frm_trans_end = true; payload = NULL; break; } case VCD_EVT_IND_HWERRFATAL: { vcd_handle_ind_hw_err_fatal(cctxt, VCD_EVT_RESP_STOP, status); break; } default: { VCD_MSG_ERROR ("Unexpected callback event=%d status=%d from DDL", event, status); dev_ctxt->command_continue = false; break; } } if (!VCD_FAILED(rc) && ((event == VCD_EVT_RESP_INPUT_DONE || event == VCD_EVT_RESP_OUTPUT_DONE) || event == VCD_EVT_RESP_OUTPUT_REQ || event == VCD_EVT_IND_OUTPUT_RECONFIG)) { if (payload && ((struct ddl_frame_data_tag *)\ payload)->frm_trans_end) { vcd_mark_frame_channel(cctxt->dev_ctxt); frm_trans_end = true; } if (frm_trans_end && !cctxt->status.frame_submitted) { VCD_MSG_HIGH ("All pending frames recvd from DDL"); vcd_flush_bframe_buffers(cctxt, VCD_FLUSH_INPUT); vcd_flush_output_buffers(cctxt); cctxt->status.mask &= ~VCD_FLUSH_ALL; vcd_release_all_clnt_frm_transc(cctxt); VCD_MSG_HIGH ("All buffers flushed. Enqueuing stop cmd"); vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CODEC_STOP); } } }
static void vcd_clnt_cb_in_stopping (struct vcd_clnt_ctxt_type_t *p_cctxt, u32 event, u32 status, void *p_payload, u32 n_size, u32 *ddl_handle, void *const p_client_data) { struct vcd_dev_ctxt_type *p_dev_ctxt = p_cctxt->p_dev_ctxt; u32 rc = VCD_S_SUCCESS; u32 b_frm_trans_end = FALSE; VCD_MSG_LOW("vcd_clnt_cb_in_stopping:"); if (p_cctxt->ddl_handle != ddl_handle) { VCD_MSG_ERROR("ddl_handle mismatch"); return; } switch (event) { case VCD_EVT_RESP_INPUT_DONE: { rc = vcd_handle_input_done(p_cctxt, p_payload, VCD_EVT_RESP_INPUT_FLUSHED, status); break; } case VCD_EVT_RESP_OUTPUT_DONE: { rc = vcd_handle_frame_done(p_cctxt, p_payload, VCD_EVT_RESP_OUTPUT_FLUSHED, status); break; } case VCD_EVT_RESP_OUTPUT_REQ: { rc = vcd_handle_output_required_in_flushing(p_cctxt, p_payload); break; } case VCD_EVT_RESP_STOP: { vcd_handle_stop_done(p_cctxt, (struct vcd_transc_type *) p_client_data, status); break; } case VCD_EVT_IND_OUTPUT_RECONFIG: { (void) vcd_handle_ind_output_reconfig(p_cctxt, p_payload, status); vcd_mark_frame_channel(p_cctxt->p_dev_ctxt); b_frm_trans_end = TRUE; p_payload = NULL; break; } case VCD_EVT_IND_HWERRFATAL: { vcd_handle_ind_hw_err_fatal(p_cctxt, VCD_EVT_RESP_STOP, status); break; } default: { VCD_MSG_ERROR ("Unexpected callback event=%d status=%d from DDL", event, status); p_dev_ctxt->b_continue = FALSE; break; } } if (!VCD_FAILED(rc) && ((event == VCD_EVT_RESP_INPUT_DONE || event == VCD_EVT_RESP_OUTPUT_DONE) || event == VCD_EVT_RESP_OUTPUT_REQ || event == VCD_EVT_IND_OUTPUT_RECONFIG)) { if (p_payload && ((struct ddl_frame_data_type_tag *)\ p_payload)->b_frm_trans_end) { vcd_mark_frame_channel(p_cctxt->p_dev_ctxt); b_frm_trans_end = TRUE; } if (b_frm_trans_end && !p_cctxt->status.n_frame_submitted) { VCD_MSG_HIGH ("All pending frames recvd from DDL"); vcd_flush_output_buffers(p_cctxt); p_cctxt->status.n_flush_mode = 0; vcd_release_all_clnt_frm_transc(p_cctxt); VCD_MSG_HIGH ("All buffers flushed. Enqueuing stop cmd"); vcd_client_cmd_flush_and_en_q(p_cctxt, VCD_CMD_CODEC_STOP); } } }