diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index f4ad985eb17..c6fb382b358 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -49,7 +49,7 @@ static enum vidc_status hfi_map_err_status(int hfi_err) vidc_err = VIDC_ERR_NOT_SUPPORTED; break; case HFI_ERR_SYS_MAX_SESSIONS_REACHED: - vidc_err = VIDC_ERR_MAX_CLIENT; + vidc_err = VIDC_ERR_MAX_CLIENTS; break; case HFI_ERR_SYS_SESSION_IN_USE: vidc_err = VIDC_ERR_CLIENT_PRESENT; @@ -75,6 +75,8 @@ static enum vidc_status hfi_map_err_status(int hfi_err) vidc_err = VIDC_ERR_FAIL; break; } + if (vidc_err != HFI_ERR_NONE) + dprintk(VIDC_ERR, "HFI Error: %d\n", vidc_err); return vidc_err; } @@ -108,7 +110,8 @@ static void hfi_process_sess_evt_seq_changed( struct hfi_frame_size frame_sz; u8 *data_ptr; int prop_id; - dprintk(VIDC_DBG, "RECEIVED:EVENT_NOTIFY"); + dprintk(VIDC_DBG, "RECEIVED: EVENT_NOTIFY[%u]: %d, 0x%x\n", + pkt->session_id, pkt->event_data1, pkt->event_data2); if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) { dprintk(VIDC_ERR, "hal_process_session_init_done:bad_pkt_size"); @@ -248,27 +251,33 @@ static void hfi_process_event_notify( hfi_process_sys_error(callback, device_id); break; case HFI_EVENT_SESSION_ERROR: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR"); + dprintk(VIDC_INFO, + "HFI_EVENT_SESSION_ERROR[%u]\n", pkt->session_id); if (!validate_session_pkt(sessions, sess, session_lock)) hfi_process_session_error(callback, device_id, pkt); break; case HFI_EVENT_SESSION_SEQUENCE_CHANGED: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED"); + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%u]\n", + pkt->session_id); if (!validate_session_pkt(sessions, sess, session_lock)) hfi_process_sess_evt_seq_changed(callback, device_id, pkt); break; case HFI_EVENT_SESSION_PROPERTY_CHANGED: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED"); + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED[%u]\n", + pkt->session_id); break; case HFI_EVENT_RELEASE_BUFFER_REFERENCE: - dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE\n"); + dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%u]\n", + pkt->session_id); if (!validate_session_pkt(sessions, sess, session_lock)) hfi_process_evt_release_buffer_ref(callback, device_id, pkt); break; default: - dprintk(VIDC_WARN, "hal_process_event_notify:unkown_event_id"); + dprintk(VIDC_WARN, + "hal_process_event_notify: unknown_event_id[%u]\n", + pkt->session_id); break; } } @@ -758,7 +767,8 @@ static void hfi_process_session_prop_info( struct msm_vidc_cb_cmd_done cmd_done; struct buffer_requirements buff_req; - dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO"); + dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%u]\n", + pkt->session_id); if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) { dprintk(VIDC_ERR, "hal_process_session_prop_info:bad_pkt_size"); @@ -800,7 +810,8 @@ static void hfi_process_session_init_done( struct msm_vidc_cb_cmd_done cmd_done; struct vidc_hal_session_init_done session_init_done; struct hal_session *sess_close = NULL; - dprintk(VIDC_DBG, "RECEIVED:SESSION_INIT_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%u]\n", + pkt->session_id); if (sizeof(struct hfi_msg_sys_session_init_done_packet) > pkt->size) { dprintk(VIDC_ERR, "hal_process_session_init_done:bad_pkt_size"); @@ -839,7 +850,8 @@ static void hfi_process_session_load_res_done( struct hfi_msg_session_load_resources_done_packet *pkt) { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_LOAD_RESOURCES_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%u]\n", + pkt->session_id); if (sizeof(struct hfi_msg_session_load_resources_done_packet) != pkt->size) { @@ -865,7 +877,8 @@ static void hfi_process_session_flush_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_FLUSH_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%u]\n", + pkt->session_id); if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) { dprintk(VIDC_ERR, "hal_process_session_flush_done: " @@ -889,7 +902,8 @@ static void hfi_process_session_etb_done( { struct msm_vidc_cb_data_done data_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_ETB_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size < sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { @@ -930,7 +944,8 @@ static void hfi_process_session_ftb_done( session = (struct hal_session *) ((struct hal_session *) pack->session_id)->session_id; - dprintk(VIDC_DBG, "RECEIVED:SESSION_FTB_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%u]\n", + pack->session_id); memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done)); @@ -1028,7 +1043,8 @@ static void hfi_process_session_start_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_START_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_start_done_packet)) { @@ -1053,7 +1069,8 @@ static void hfi_process_session_stop_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_STOP_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_stop_done_packet)) { @@ -1078,7 +1095,8 @@ static void hfi_process_session_rel_res_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_RESOURCES_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_release_resources_done_packet)) { @@ -1102,6 +1120,8 @@ static void hfi_process_session_rel_buf_done( struct hfi_msg_session_release_buffers_done_packet *pkt) { struct msm_vidc_cb_cmd_done cmd_done; + dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_release_buffers_done_packet)) { @@ -1129,7 +1149,8 @@ static void hfi_process_session_end_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_END_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_end_done_packet)) { @@ -1154,8 +1175,8 @@ static void hfi_process_session_abort_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_ABORT_DONE"); - + dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_abort_done_packet)) { dprintk(VIDC_ERR, "%s: bad packet/packet size: %d", @@ -1184,6 +1205,8 @@ static void hfi_process_session_get_seq_hdr_done( dprintk(VIDC_ERR, "bad packet/packet size: %d", pkt->size); return; } + dprintk(VIDC_DBG, "RECEIVED:SESSION_GET_SEQ_HDR_DONE[%u]\n", + pkt->session_id); memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done)); data_done.device_id = device_id; data_done.size = sizeof(struct msm_vidc_cb_data_done); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index c8cd75e84bf..fcd2e5e1d62 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -391,8 +391,9 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst, &inst->completions[SESSION_MSG_INDEX(cmd)], msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", - SESSION_MSG_INDEX(cmd)); + dprintk(VIDC_ERR, + "%s: Wait interrupted or timeout[%u]: %d\n", + __func__, (u32)inst->session, SESSION_MSG_INDEX(cmd)); msm_comm_recover_from_session_error(inst); rc = -EIO; } else { @@ -440,6 +441,21 @@ static void msm_comm_generate_session_error(struct msm_vidc_inst *inst) mutex_unlock(&inst->lock); } +static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst) +{ + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); + return; + } + mutex_lock(&inst->sync_lock); + inst->session = NULL; + inst->state = MSM_VIDC_CORE_INVALID; + msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_MAX_CLIENTS); + dprintk(VIDC_WARN, + "%s: Too many clients\n", __func__); + mutex_unlock(&inst->sync_lock); +} + static void handle_session_init_done(enum command_response cmd, void *data) { struct msm_vidc_cb_cmd_done *response = data; @@ -477,7 +493,10 @@ static void handle_session_init_done(enum command_response cmd, void *data) dprintk(VIDC_ERR, "Session init response from FW : 0x%x", response->status); - msm_comm_generate_session_error(inst); + if (response->status == VIDC_ERR_MAX_CLIENTS) + msm_comm_generate_max_clients_error(inst); + else + msm_comm_generate_session_error(inst); } signal_session_msg_receipt(cmd, inst); } else { @@ -1573,8 +1592,8 @@ static int msm_comm_unset_ocmem(struct msm_vidc_core *core) &core->completions[SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)], msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", - SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)); + dprintk(VIDC_ERR, "%s: Wait interrupted or timeout: %d\n", + __func__, SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)); rc = -EIO; } release_ocmem_failed: @@ -1596,8 +1615,8 @@ static int msm_comm_init_core_done(struct msm_vidc_inst *inst) &core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)], msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", - SYS_MSG_INDEX(SYS_INIT_DONE)); + dprintk(VIDC_ERR, "%s: Wait interrupted or timeout: %d\n", + __func__, SYS_MSG_INDEX(SYS_INIT_DONE)); rc = -EIO; goto exit; } else { @@ -2693,7 +2712,8 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { dprintk(VIDC_ERR, - "Wait interrupted or timeout: %d\n", + "%s: Wait interrupted or timeout[%u]: %d\n", + __func__, (u32)inst->session, SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)); inst->state = MSM_VIDC_CORE_INVALID; msm_comm_recover_from_session_error(inst); @@ -3470,7 +3490,11 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) mutex_lock(&inst->sync_lock); inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->sync_lock); - msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); + msm_vidc_queue_v4l2_event(inst, + V4L2_EVENT_MSM_VIDC_HW_OVERLOAD); + dprintk(VIDC_WARN, + "%s: Hardware is overloaded\n", __func__); + wake_up(&inst->kernel_event_queue); } return rc; } @@ -3520,8 +3544,9 @@ int msm_comm_recover_from_session_error(struct msm_vidc_inst *inst) &inst->completions[SESSION_MSG_INDEX(SESSION_ABORT_DONE)], msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, "%s: Wait interrupted or timeout: %d\n", - __func__, SESSION_MSG_INDEX(SESSION_ABORT_DONE)); + dprintk(VIDC_ERR, "%s: Wait interrupted or timeout[%u]: %d\n", + __func__, (u32)inst->session, + SESSION_MSG_INDEX(SESSION_ABORT_DONE)); msm_comm_generate_sys_error(inst); } else change_inst_state(inst, MSM_VIDC_CLOSE_DONE); diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h index 309164a4132..7c0eb1b07ed 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h @@ -63,7 +63,7 @@ enum vidc_status { VIDC_ERR_BAD_HANDLE, VIDC_ERR_NOT_SUPPORTED, VIDC_ERR_BAD_STATE, - VIDC_ERR_MAX_CLIENT, + VIDC_ERR_MAX_CLIENTS, VIDC_ERR_IFRAME_EXPECTED, VIDC_ERR_HW_FATAL, VIDC_ERR_BITSTREAM_ERR, diff --git a/include/linux/msm_vidc_dec.h b/include/linux/msm_vidc_dec.h index 35279bfc970..b09fc2dd3d9 100644 --- a/include/linux/msm_vidc_dec.h +++ b/include/linux/msm_vidc_dec.h @@ -58,6 +58,8 @@ #define VDEC_MSG_EVT_HW_ERROR (VDEC_MSG_BASE + 14) #define VDEC_MSG_EVT_INFO_CONFIG_CHANGED (VDEC_MSG_BASE + 15) #define VDEC_MSG_EVT_INFO_FIELD_DROPPED (VDEC_MSG_BASE + 16) +#define VDEC_MSG_EVT_HW_OVERLOAD (VDEC_MSG_BASE + 17) +#define VDEC_MSG_EVT_MAX_CLIENTS (VDEC_MSG_BASE + 18) /*Buffer flags bits masks.*/ #define VDEC_BUFFERFLAG_EOS 0x00000001 diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h index 4ce3db18839..36625a70cb1 100644 --- a/include/linux/msm_vidc_enc.h +++ b/include/linux/msm_vidc_enc.h @@ -45,7 +45,8 @@ #define VEN_MSG_RESUME 9 #define VEN_MSG_STOP_READING_MSG 10 #define VEN_MSG_LTRUSE_FAILED 11 - +#define VEN_MSG_HW_OVERLOAD 12 +#define VEN_MSG_MAX_CLIENTS 13 /*Buffer flags bits masks*/ #define VEN_BUFFLAG_EOS 0x00000001 diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 1531aa400e8..174829da8c6 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -2512,6 +2512,8 @@ struct v4l2_streamparm { (V4L2_EVENT_MSM_VIDC_START + 6) #define V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER \ (V4L2_EVENT_MSM_VIDC_START + 7) +#define V4L2_EVENT_MSM_VIDC_HW_OVERLOAD (V4L2_EVENT_MSM_VIDC_START + 8) +#define V4L2_EVENT_MSM_VIDC_MAX_CLIENTS (V4L2_EVENT_MSM_VIDC_START + 9) /* Payload for V4L2_EVENT_VSYNC */ struct v4l2_event_vsync {