Merge "video: driver: add stop cmd allow checks inside state handler"

This commit is contained in:
qctecmdr
2023-02-23 18:24:11 -08:00
committed by Gerrit - the friendly Code Review server
8 changed files with 110 additions and 152 deletions

View File

@@ -492,10 +492,6 @@ bool msm_vidc_allow_metadata_subscription(struct msm_vidc_inst *inst,
bool msm_vidc_allow_property(struct msm_vidc_inst *inst, u32 hfi_id);
int msm_vidc_update_property_cap(struct msm_vidc_inst *inst, u32 hfi_id,
bool allow);
bool msm_vidc_allow_reqbufs(struct msm_vidc_inst *inst, u32 type);
enum msm_vidc_allow msm_vidc_allow_stop(struct msm_vidc_inst *inst);
bool msm_vidc_allow_start(struct msm_vidc_inst *inst);
bool msm_vidc_allow_streamon(struct msm_vidc_inst *inst, u32 type);
enum msm_vidc_allow msm_vidc_allow_input_psc(struct msm_vidc_inst *inst);
bool msm_vidc_allow_drain_last_flag(struct msm_vidc_inst *inst);
bool msm_vidc_allow_psc_last_flag(struct msm_vidc_inst *inst);

View File

@@ -91,6 +91,8 @@ const char *core_state_name(enum msm_vidc_core_state state);
const char *core_sub_state_name(enum msm_vidc_core_sub_state sub_state);
/* inst statemachine functions */
bool is_drc_pending(struct msm_vidc_inst *inst);
bool is_drain_pending(struct msm_vidc_inst *inst);
int msm_vidc_update_state(struct msm_vidc_inst *inst,
enum msm_vidc_state request_state, const char *func);
int msm_vidc_change_state(struct msm_vidc_inst *inst,

View File

@@ -2091,17 +2091,9 @@ static int msm_vdec_alloc_and_queue_additional_dpb_buffers(struct msm_vidc_inst
int msm_vdec_stop_cmd(struct msm_vidc_inst *inst)
{
enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
int rc = 0;
i_vpr_h(inst, "received cmd: drain\n");
allow = msm_vidc_allow_stop(inst);
if (allow == MSM_VIDC_DISALLOW)
return -EBUSY;
else if (allow == MSM_VIDC_IGNORE)
return 0;
else if (allow != MSM_VIDC_ALLOW)
return -EINVAL;
rc = msm_vidc_process_drain(inst);
if (rc)
return rc;
@@ -2132,9 +2124,6 @@ int msm_vdec_start_cmd(struct msm_vidc_inst *inst)
return -EINVAL;
}
if (!msm_vidc_allow_start(inst))
return -EBUSY;
/* tune power features */
inst->decode_batch.enable = msm_vidc_allow_decode_batch(inst);
msm_vidc_allow_dcvs(inst);

View File

@@ -921,17 +921,9 @@ int msm_venc_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
int msm_venc_stop_cmd(struct msm_vidc_inst *inst)
{
enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
int rc = 0;
i_vpr_h(inst, "received cmd: drain\n");
allow = msm_vidc_allow_stop(inst);
if (allow == MSM_VIDC_DISALLOW)
return -EBUSY;
else if (allow == MSM_VIDC_IGNORE)
return 0;
else if (allow != MSM_VIDC_ALLOW)
return -EINVAL;
rc = msm_vidc_process_drain(inst);
if (rc)
return rc;
@@ -944,8 +936,7 @@ int msm_venc_start_cmd(struct msm_vidc_inst *inst)
int rc = 0;
i_vpr_h(inst, "received cmd: resume\n");
if (!msm_vidc_allow_start(inst))
return -EBUSY;
vb2_clear_last_buffer_dequeued(inst->bufq[OUTPUT_META_PORT].vb2q);
vb2_clear_last_buffer_dequeued(inst->bufq[OUTPUT_PORT].vb2q);

View File

@@ -253,9 +253,6 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
return -EINVAL;
}
if (!msm_vidc_allow_s_fmt(inst, f->type))
return -EBUSY;
if (inst->domain == MSM_VIDC_DECODER)
rc = msm_vdec_s_fmt(inst, f);
if (inst->domain == MSM_VIDC_ENCODER)
@@ -400,11 +397,6 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
return -EINVAL;
}
if (!msm_vidc_allow_reqbufs(inst, b->type)) {
rc = -EBUSY;
goto exit;
}
port = v4l2_type_to_driver_port(inst, b->type, __func__);
if (port < 0) {
rc = -EINVAL;

View File

@@ -1115,111 +1115,6 @@ int msm_vidc_update_property_cap(struct msm_vidc_inst *inst, u32 hfi_id,
return rc;
}
bool msm_vidc_allow_reqbufs(struct msm_vidc_inst *inst, u32 type)
{
bool allow = false;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return false;
}
if (is_state(inst, MSM_VIDC_OPEN)) {
allow = true;
goto exit;
}
if (type == OUTPUT_MPLANE || type == OUTPUT_META_PLANE) {
if (is_state(inst, MSM_VIDC_INPUT_STREAMING)) {
allow = true;
goto exit;
}
}
if (type == INPUT_MPLANE || type == INPUT_META_PLANE) {
if (is_state(inst, MSM_VIDC_OUTPUT_STREAMING)) {
allow = true;
goto exit;
}
}
exit:
if (!allow)
i_vpr_e(inst, "%s: type %d not allowed in state %s\n",
__func__, type, state_name(inst->state));
return allow;
}
enum msm_vidc_allow msm_vidc_allow_stop(struct msm_vidc_inst *inst)
{
enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return allow;
}
/* allow stop (drain) if input port is streaming */
if (is_state(inst, MSM_VIDC_INPUT_STREAMING) ||
is_state(inst, MSM_VIDC_STREAMING)) {
/* do not allow back to back drain */
if (!(is_sub_state(inst, MSM_VIDC_DRAIN)))
allow = MSM_VIDC_ALLOW;
} else if (is_state(inst, MSM_VIDC_OPEN)) {
allow = MSM_VIDC_IGNORE;
i_vpr_e(inst, "%s: ignored in state %s, sub state %s\n",
__func__, state_name(inst->state), inst->sub_state_name);
} else {
i_vpr_e(inst, "%s: not allowed in state %s, sub state %s\n",
__func__, state_name(inst->state), inst->sub_state_name);
}
return allow;
}
bool msm_vidc_allow_start(struct msm_vidc_inst *inst)
{
bool allow = false;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return allow;
}
/* client would call start (resume) to complete DRC/drain sequence */
if (inst->state == MSM_VIDC_INPUT_STREAMING ||
inst->state == MSM_VIDC_OUTPUT_STREAMING ||
inst->state == MSM_VIDC_STREAMING) {
if ((is_sub_state(inst, MSM_VIDC_DRC) &&
is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER)) ||
(is_sub_state(inst, MSM_VIDC_DRAIN) &&
is_sub_state(inst, MSM_VIDC_DRAIN_LAST_BUFFER)))
allow = true;
}
if (!allow)
i_vpr_e(inst, "%s: not allowed in state %s, sub state %s\n",
__func__, state_name(inst->state), inst->sub_state_name);
return allow;
}
bool msm_vidc_allow_streamon(struct msm_vidc_inst *inst, u32 type)
{
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return false;
}
if (type == INPUT_MPLANE || type == INPUT_META_PLANE) {
if (is_state(inst, MSM_VIDC_OPEN) ||
is_state(inst, MSM_VIDC_OUTPUT_STREAMING))
return true;
} else if (type == OUTPUT_MPLANE || type == OUTPUT_META_PLANE) {
if (is_state(inst, MSM_VIDC_OPEN) ||
is_state(inst, MSM_VIDC_INPUT_STREAMING))
return true;
}
i_vpr_e(inst, "%s: type %d not allowed in state %s\n",
__func__, type, state_name(inst->state));
return false;
}
enum msm_vidc_allow msm_vidc_allow_input_psc(struct msm_vidc_inst *inst)
{
enum msm_vidc_allow allow = MSM_VIDC_ALLOW;

View File

@@ -24,6 +24,18 @@ bool is_core_state(struct msm_vidc_core *core, enum msm_vidc_core_state state)
return core->state == state;
}
bool is_drc_pending(struct msm_vidc_inst *inst)
{
return is_sub_state(inst, MSM_VIDC_DRC) &&
is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER);
}
bool is_drain_pending(struct msm_vidc_inst *inst)
{
return is_sub_state(inst, MSM_VIDC_DRAIN) &&
is_sub_state(inst, MSM_VIDC_DRAIN_LAST_BUFFER);
}
static const char * const core_state_name_arr[] =
FOREACH_CORE_STATE(GENERATE_STRING);
@@ -648,6 +660,7 @@ static int msm_vidc_open_state(struct msm_vidc_inst *inst,
{
struct v4l2_format *f = (struct v4l2_format *)data;
/* allow s_fmt request in open state */
rc = msm_vidc_s_fmt(inst, f);
if (rc)
return rc;
@@ -667,6 +680,7 @@ static int msm_vidc_open_state(struct msm_vidc_inst *inst,
{
struct v4l2_requestbuffers *b = (struct v4l2_requestbuffers *)data;
/* allow reqbufs request in open state */
rc = msm_vidc_reqbufs(inst, b);
if (rc)
return rc;
@@ -676,6 +690,7 @@ static int msm_vidc_open_state(struct msm_vidc_inst *inst,
{
struct vb2_queue *q = (struct vb2_queue *)data;
/* allow streamon request in open state */
rc = msm_vidc_start_streaming(inst, q);
if (rc)
return rc;
@@ -692,16 +707,17 @@ static int msm_vidc_open_state(struct msm_vidc_inst *inst,
}
case MSM_VIDC_CMD_START:
{
rc = msm_vidc_start_cmd(inst);
if (rc)
return rc;
break;
/* disallow start cmd request in open state */
i_vpr_e(inst, "%s: (%s) not allowed, sub_state (%s)\n",
__func__, event_name(event), inst->sub_state_name);
return -EBUSY;
}
case MSM_VIDC_CMD_STOP:
{
rc = msm_vidc_stop_cmd(inst);
if (rc)
return rc;
/* ignore stop cmd request in open state */
i_vpr_h(inst, "%s: (%s) ignored, sub_state (%s)\n",
__func__, event_name(event), inst->sub_state_name);
break;
}
case MSM_VIDC_BUF_QUEUE:
@@ -771,6 +787,13 @@ static int msm_vidc_input_streaming_state(struct msm_vidc_inst *inst,
{
struct v4l2_format *f = (struct v4l2_format *)data;
/* disallow */
if (f->type == INPUT_MPLANE || f->type == INPUT_META_PLANE) {
i_vpr_e(inst, "%s: (%s) not allowed for (%s) port\n",
__func__, event_name(event), v4l2_type_name(f->type));
return -EBUSY;
}
rc = msm_vidc_s_fmt(inst, f);
if (rc)
return rc;
@@ -805,6 +828,13 @@ static int msm_vidc_input_streaming_state(struct msm_vidc_inst *inst,
{
struct v4l2_requestbuffers *b = (struct v4l2_requestbuffers *)data;
/* disallow */
if (b->type == INPUT_MPLANE || b->type == INPUT_META_PLANE) {
i_vpr_e(inst, "%s: (%s) not allowed for (%s) port\n",
__func__, event_name(event), v4l2_type_name(b->type));
return -EBUSY;
}
rc = msm_vidc_reqbufs(inst, b);
if (rc)
return rc;
@@ -814,6 +844,13 @@ static int msm_vidc_input_streaming_state(struct msm_vidc_inst *inst,
{
struct vb2_queue *q = (struct vb2_queue *)data;
/* disallow */
if (q->type == INPUT_MPLANE || q->type == INPUT_META_PLANE) {
i_vpr_e(inst, "%s: (%s) not allowed for (%s) type\n",
__func__, event_name(event), v4l2_type_name(q->type));
return -EBUSY;
}
rc = msm_vidc_start_streaming(inst, q);
if (rc)
return rc;
@@ -850,6 +887,14 @@ static int msm_vidc_input_streaming_state(struct msm_vidc_inst *inst,
}
case MSM_VIDC_CMD_START:
{
/* disallow if START called for non DRC/drain cases */
if (!is_drc_pending(inst) && !is_drain_pending(inst)) {
i_vpr_e(inst, "%s: (%s) not allowed, sub_state (%s)\n",
__func__, event_name(event), inst->sub_state_name);
return -EBUSY;
}
/* client would call start(resume) to complete DRC/drain sequence */
rc = msm_vidc_start_cmd(inst);
if (rc)
return rc;
@@ -857,6 +902,13 @@ static int msm_vidc_input_streaming_state(struct msm_vidc_inst *inst,
}
case MSM_VIDC_CMD_STOP:
{
/* back to back drain not allowed */
if (is_sub_state(inst, MSM_VIDC_DRAIN)) {
i_vpr_e(inst, "%s: drain (%s) not allowed, sub_state (%s)\n\n",
__func__, event_name(event), inst->sub_state_name);
return -EBUSY;
}
rc = msm_vidc_stop_cmd(inst);
if (rc)
return rc;
@@ -921,6 +973,13 @@ static int msm_vidc_output_streaming_state(struct msm_vidc_inst *inst,
{
struct v4l2_format *f = (struct v4l2_format *)data;
/* disallow */
if (f->type == OUTPUT_MPLANE || f->type == OUTPUT_META_PLANE) {
i_vpr_e(inst, "%s: (%s) not allowed for (%s) port\n",
__func__, event_name(event), v4l2_type_name(f->type));
return -EBUSY;
}
rc = msm_vidc_s_fmt(inst, f);
if (rc)
return rc;
@@ -955,6 +1014,13 @@ static int msm_vidc_output_streaming_state(struct msm_vidc_inst *inst,
{
struct v4l2_requestbuffers *b = (struct v4l2_requestbuffers *)data;
/* disallow */
if (b->type == OUTPUT_MPLANE || b->type == OUTPUT_META_PLANE) {
i_vpr_e(inst, "%s: (%s) not allowed for (%s) port\n",
__func__, event_name(event), v4l2_type_name(b->type));
return -EBUSY;
}
rc = msm_vidc_reqbufs(inst, b);
if (rc)
return rc;
@@ -964,6 +1030,13 @@ static int msm_vidc_output_streaming_state(struct msm_vidc_inst *inst,
{
struct vb2_queue *q = (struct vb2_queue *)data;
/* disallow */
if (q->type == OUTPUT_MPLANE || q->type == OUTPUT_META_PLANE) {
i_vpr_e(inst, "%s: (%s) not allowed for (%s) type\n",
__func__, event_name(event), v4l2_type_name(q->type));
return -EBUSY;
}
rc = msm_vidc_start_streaming(inst, q);
if (rc)
return rc;
@@ -1000,6 +1073,14 @@ static int msm_vidc_output_streaming_state(struct msm_vidc_inst *inst,
}
case MSM_VIDC_CMD_START:
{
/* disallow if START called for non DRC/drain cases */
if (!is_drc_pending(inst) && !is_drain_pending(inst)) {
i_vpr_e(inst, "%s: (%s) not allowed, sub_state (%s)\n",
__func__, event_name(event), inst->sub_state_name);
return -EBUSY;
}
/* client would call start(resume) to complete DRC/drain sequence */
rc = msm_vidc_start_cmd(inst);
if (rc)
return rc;
@@ -1007,10 +1088,10 @@ static int msm_vidc_output_streaming_state(struct msm_vidc_inst *inst,
}
case MSM_VIDC_CMD_STOP:
{
rc = msm_vidc_stop_cmd(inst);
if (rc)
return rc;
break;
/* drain not allowed as input is not streaming */
i_vpr_e(inst, "%s: drain (%s) not allowed, sub state %s\n",
__func__, event_name(event), inst->sub_state_name);
return -EBUSY;
}
default: {
i_vpr_e(inst, "%s: unexpected event %s\n", __func__, event_name(event));
@@ -1106,6 +1187,14 @@ static int msm_vidc_streaming_state(struct msm_vidc_inst *inst,
}
case MSM_VIDC_CMD_START:
{
/* disallow if START called for non DRC/drain cases */
if (!is_drc_pending(inst) && !is_drain_pending(inst)) {
i_vpr_e(inst, "%s: (%s) not allowed, sub_state (%s)\n",
__func__, event_name(event), inst->sub_state_name);
return -EBUSY;
}
/* client would call start(resume) to complete DRC/drain sequence */
rc = msm_vidc_start_cmd(inst);
if (rc)
return rc;
@@ -1113,6 +1202,13 @@ static int msm_vidc_streaming_state(struct msm_vidc_inst *inst,
}
case MSM_VIDC_CMD_STOP:
{
/* back to back drain not allowed */
if (is_sub_state(inst, MSM_VIDC_DRAIN)) {
i_vpr_e(inst, "%s: drain (%s) not allowed, sub_state (%s)\n\n",
__func__, event_name(event), inst->sub_state_name);
return -EBUSY;
}
rc = msm_vidc_stop_cmd(inst);
if (rc)
return rc;

View File

@@ -415,9 +415,6 @@ int msm_vidc_start_streaming(struct msm_vidc_inst *inst, struct vb2_queue *q)
return -EINVAL;
}
if (!msm_vidc_allow_streamon(inst, q->type))
return -EBUSY;
if (q->type == INPUT_META_PLANE || q->type == OUTPUT_META_PLANE) {
i_vpr_h(inst, "%s: nothing to start on %s\n",
__func__, v4l2_type_name(q->type));