|
@@ -3250,7 +3250,6 @@ int cam_req_mgr_process_error(void *priv, void *data)
|
|
|
struct cam_req_mgr_error_notify *err_info = NULL;
|
|
|
struct cam_req_mgr_core_link *link = NULL;
|
|
|
struct cam_req_mgr_req_queue *in_q = NULL;
|
|
|
- struct cam_req_mgr_slot *slot = NULL;
|
|
|
struct crm_task_payload *task_data = NULL;
|
|
|
|
|
|
if (!data || !priv) {
|
|
@@ -3281,25 +3280,11 @@ int cam_req_mgr_process_error(void *priv, void *data)
|
|
|
} else {
|
|
|
CAM_DBG(CAM_CRM, "req_id %lld found at idx %d last_applied %d",
|
|
|
err_info->req_id, idx, in_q->last_applied_idx);
|
|
|
- slot = &in_q->slot[idx];
|
|
|
- if (!slot->recover) {
|
|
|
- CAM_WARN(CAM_CRM,
|
|
|
- "err recovery disabled req_id %lld",
|
|
|
- err_info->req_id);
|
|
|
- mutex_unlock(&link->req.lock);
|
|
|
- return 0;
|
|
|
- } else if (slot->status != CRM_SLOT_STATUS_REQ_PENDING
|
|
|
- && slot->status != CRM_SLOT_STATUS_REQ_APPLIED) {
|
|
|
- CAM_WARN(CAM_CRM,
|
|
|
- "req_id %lld can not be recovered %d",
|
|
|
- err_info->req_id, slot->status);
|
|
|
- mutex_unlock(&link->req.lock);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
+
|
|
|
/* Bring processing pointer to bubbled req id */
|
|
|
__cam_req_mgr_tbl_set_all_skip_cnt(&link->req.l_tbl);
|
|
|
in_q->rd_idx = idx;
|
|
|
- in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED;
|
|
|
+
|
|
|
if (link->sync_link[0]) {
|
|
|
in_q->slot[idx].sync_mode = 0;
|
|
|
__cam_req_mgr_inc_idx(&idx, 1,
|
|
@@ -3651,9 +3636,11 @@ end:
|
|
|
static int cam_req_mgr_cb_notify_err(
|
|
|
struct cam_req_mgr_error_notify *err_info)
|
|
|
{
|
|
|
- int rc = 0;
|
|
|
+ int rc = 0, idx = -1;
|
|
|
struct crm_workq_task *task = NULL;
|
|
|
struct cam_req_mgr_core_link *link = NULL;
|
|
|
+ struct cam_req_mgr_req_queue *in_q = NULL;
|
|
|
+ struct cam_req_mgr_slot *slot = NULL;
|
|
|
struct cam_req_mgr_error_notify *notify_err;
|
|
|
struct crm_task_payload *task_data;
|
|
|
|
|
@@ -3679,6 +3666,43 @@ static int cam_req_mgr_cb_notify_err(
|
|
|
goto end;
|
|
|
}
|
|
|
crm_timer_reset(link->watchdog);
|
|
|
+ switch (err_info->error) {
|
|
|
+ case CRM_KMD_ERR_BUBBLE:
|
|
|
+ case CRM_KMD_WARN_INTERNAL_RECOVERY:
|
|
|
+ in_q = link->req.in_q;
|
|
|
+ idx = __cam_req_mgr_find_slot_for_req(in_q, err_info->req_id);
|
|
|
+ if (idx < 0) {
|
|
|
+ CAM_ERR_RATE_LIMIT(CAM_CRM,
|
|
|
+ "req_id %lld not found in input queue",
|
|
|
+ err_info->req_id);
|
|
|
+ spin_unlock_bh(&link->link_state_spin_lock);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ slot = &in_q->slot[idx];
|
|
|
+
|
|
|
+ if (!slot->recover) {
|
|
|
+ CAM_WARN(CAM_CRM,
|
|
|
+ "err recovery disabled req_id %lld",
|
|
|
+ err_info->req_id);
|
|
|
+ spin_unlock_bh(&link->link_state_spin_lock);
|
|
|
+ rc = 0;
|
|
|
+ goto end;
|
|
|
+ } else if (slot->status != CRM_SLOT_STATUS_REQ_PENDING
|
|
|
+ && slot->status != CRM_SLOT_STATUS_REQ_APPLIED) {
|
|
|
+ CAM_WARN(CAM_CRM,
|
|
|
+ "req_id %lld can not be recovered %d",
|
|
|
+ err_info->req_id, slot->status);
|
|
|
+ spin_unlock_bh(&link->link_state_spin_lock);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ in_q->rd_idx = idx;
|
|
|
+ in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
spin_unlock_bh(&link->link_state_spin_lock);
|
|
|
|
|
|
task = cam_req_mgr_workq_get_task(link->workq);
|