Skip to content

Commit b9d2140

Browse files
Ansuelvinodkoul
authored andcommitted
dmaengine: qcom-adm: fix wrong calling convention for prep_slave_sg
The calling convention for pre_slave_sg is to return NULL on error and provide an error log to the system. Qcom-adm instead provide error pointer when an error occur. This indirectly cause kernel panic for example for the nandc driver that checks only if the pointer returned by device_prep_slave_sg is not NULL. Returning an error pointer makes nandc think the device_prep_slave_sg function correctly completed and makes the kernel panics later in the code. While nandc is the one that makes the kernel crash, it was pointed out that the real problem is qcom-adm not following calling convention for that function. To fix this, drop returning error pointer and return NULL with an error log. Fixes: 03de6b2 ("dmaengine: qcom-adm: stop abusing slave_id config") Fixes: 5c9f8c2 ("dmaengine: qcom: Add ADM driver") Signed-off-by: Christian Marangi <[email protected]> Cc: [email protected] # v5.11+ Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 7c87653 commit b9d2140

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

drivers/dma/qcom/qcom_adm.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -379,13 +379,13 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
379379
if (blk_size < 0) {
380380
dev_err(adev->dev, "invalid burst value: %d\n",
381381
burst);
382-
return ERR_PTR(-EINVAL);
382+
return NULL;
383383
}
384384

385385
crci = achan->crci & 0xf;
386386
if (!crci || achan->crci > 0x1f) {
387387
dev_err(adev->dev, "invalid crci value\n");
388-
return ERR_PTR(-EINVAL);
388+
return NULL;
389389
}
390390
}
391391

@@ -403,8 +403,10 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
403403
}
404404

405405
async_desc = kzalloc(sizeof(*async_desc), GFP_NOWAIT);
406-
if (!async_desc)
407-
return ERR_PTR(-ENOMEM);
406+
if (!async_desc) {
407+
dev_err(adev->dev, "not enough memory for async_desc struct\n");
408+
return NULL;
409+
}
408410

409411
async_desc->mux = achan->mux ? ADM_CRCI_CTL_MUX_SEL : 0;
410412
async_desc->crci = crci;
@@ -414,8 +416,10 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
414416
sizeof(*cple) + 2 * ADM_DESC_ALIGN;
415417

416418
async_desc->cpl = kzalloc(async_desc->dma_len, GFP_NOWAIT);
417-
if (!async_desc->cpl)
419+
if (!async_desc->cpl) {
420+
dev_err(adev->dev, "not enough memory for cpl struct\n");
418421
goto free;
422+
}
419423

420424
async_desc->adev = adev;
421425

@@ -437,8 +441,10 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
437441
async_desc->dma_addr = dma_map_single(adev->dev, async_desc->cpl,
438442
async_desc->dma_len,
439443
DMA_TO_DEVICE);
440-
if (dma_mapping_error(adev->dev, async_desc->dma_addr))
444+
if (dma_mapping_error(adev->dev, async_desc->dma_addr)) {
445+
dev_err(adev->dev, "dma mapping error for cpl\n");
441446
goto free;
447+
}
442448

443449
cple_addr = async_desc->dma_addr + ((void *)cple - async_desc->cpl);
444450

@@ -454,7 +460,7 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
454460

455461
free:
456462
kfree(async_desc);
457-
return ERR_PTR(-ENOMEM);
463+
return NULL;
458464
}
459465

460466
/**

0 commit comments

Comments
 (0)