Skip to content

Commit f787410

Browse files
committed
drivers: dma: stm32: add null callback checking
Fix the STM32 DMA driver did not check if the optional dma_callback was set in dma_stm32_configure(). This could lead to a hard fault when an interrupt occurs and the callback is NULL, even though the API allows the callback to be omitted. Fixes #97454 Signed-off-by: Wenxi Xu <[email protected]>
1 parent 4b3cb73 commit f787410

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

drivers/dma/dma_stm32.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id)
117117
if (!stream->hal_override) {
118118
dma_stm32_clear_ht(dma, id);
119119
}
120-
stream->dma_callback(dev, stream->user_data, callback_arg, DMA_STATUS_BLOCK);
120+
stream->dma_callback(dev, stream->user_data,
121+
callback_arg, DMA_STATUS_BLOCK);
121122
} else if (stm32_dma_is_tc_irq_active(dma, id)) {
122123
/* Circular buffer never stops receiving as long as peripheral is enabled */
123124
if (!stream->cyclic) {
@@ -127,18 +128,25 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id)
127128
if (!stream->hal_override) {
128129
dma_stm32_clear_tc(dma, id);
129130
}
130-
stream->dma_callback(dev, stream->user_data, callback_arg, DMA_STATUS_COMPLETE);
131+
if (stream->dma_callback != NULL) {
132+
stream->dma_callback(dev, stream->user_data,
133+
callback_arg, DMA_STATUS_COMPLETE);
134+
}
131135
} else if (stm32_dma_is_unexpected_irq_happened(dma, id)) {
132136
LOG_ERR("Unexpected irq happened.");
133-
stream->dma_callback(dev, stream->user_data,
137+
if (stream->dma_callback != NULL) {
138+
stream->dma_callback(dev, stream->user_data,
134139
callback_arg, -EIO);
140+
}
135141
} else {
136142
LOG_ERR("Transfer Error.");
137143
stream->busy = false;
138144
dma_stm32_dump_stream_irq(dev, id);
139145
dma_stm32_clear_stream_irq(dev, id);
140-
stream->dma_callback(dev, stream->user_data,
146+
if (stream->dma_callback != NULL) {
147+
stream->dma_callback(dev, stream->user_data,
141148
callback_arg, -EIO);
149+
}
142150
}
143151
}
144152

@@ -492,10 +500,13 @@ DMA_STM32_EXPORT_API int dma_stm32_configure(const struct device *dev,
492500
#endif
493501
LL_DMA_Init(dma, dma_stm32_id_to_stream(id), &DMA_InitStruct);
494502

495-
LL_DMA_EnableIT_TC(dma, dma_stm32_id_to_stream(id));
503+
/* Enable transfer complete ISR if in non-cyclic mode or a callback is requested */
504+
if ((!stream->cyclic) || (stream->dma_callback != NULL)) {
505+
LL_DMA_EnableIT_TC(dma, dma_stm32_id_to_stream(id));
506+
}
496507

497-
/* Enable Half-Transfer irq if circular mode is enabled */
498-
if (stream->cyclic) {
508+
/* Enable Half-Transfer irq if circular mode is enabled and a callback is requested */
509+
if (stream->cyclic && stream->dma_callback != NULL) {
499510
LL_DMA_EnableIT_HT(dma, dma_stm32_id_to_stream(id));
500511
}
501512

0 commit comments

Comments
 (0)