fix(csi): move csi_fsm init before resource allocation to fix err-path leak

CSI_FSM_INIT is 1, but the controller struct is zero-allocated.
Any failure before the former csi_fsm assignment (near the end of
esp_cam_new_csi_ctlr) jumped to err: which called s_del_csi_ctlr.
That function bailed out immediately because csi_fsm == 0, leaking
the claimed slot, queue, bridge, DMA channel, PM lock, and backup
buffer. Move csi_fsm = CSI_FSM_INIT right after a successful claim
so the err: path properly tears down all allocated resources.
This commit is contained in:
morris
2026-06-30 16:52:19 +08:00
parent 05ebe7ad4b
commit 4f054f74bb

View File

@@ -107,6 +107,7 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_
free(ctlr);
ESP_RETURN_ON_ERROR(ret, TAG, "no available csi controller");
}
ctlr->csi_fsm = CSI_FSM_INIT;
ESP_LOGD(TAG, "config->queue_items: %d", config->queue_items);
ctlr->trans_que = xQueueCreateWithCaps(config->queue_items, sizeof(esp_cam_ctlr_trans_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
@@ -209,7 +210,6 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_
ESP_GOTO_ON_ERROR(dw_gdma_channel_register_event_callbacks(csi_dma_chan, &csi_dma_cbs, ctlr), err, TAG, "failed to register dwgdma callback");
ctlr->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
ctlr->csi_fsm = CSI_FSM_INIT;
ctlr->base.del = s_ctlr_del;
ctlr->base.enable = s_csi_ctlr_enable;
ctlr->base.start = s_ctlr_csi_start;
@@ -252,7 +252,9 @@ esp_err_t s_del_csi_ctlr(csi_controller_t *ctlr)
if (!ctlr->bk_buffer_dis) {
free(ctlr->backup_buffer);
}
vQueueDeleteWithCaps(ctlr->trans_que);
if (ctlr->trans_que) {
vQueueDeleteWithCaps(ctlr->trans_que);
}
free(ctlr);
return ESP_OK;