[PATCH] ata: pata_ep93xx: fix PIO fallback when DMA init fails
From: Rosen Penev
Date: Mon Jun 01 2026 - 15:08:13 EST
ep93xx_pata_dma_init() returns an error when dma_request_chan() fails,
which causes ep93xx_pata_probe() to abort entirely. The probe function
already has a PIO fallback path (it checks both channel pointers before
enabling UDMA), so the DMA init should not fail the probe on non-fatal
errors.
Treat only -EPROBE_DEFER as a fatal error. For all other failures
(ENODEV, ENXIO, configuration errors), release any allocated channels,
NULL the pointers, warn, and return 0 so the driver continues in PIO mode.
Assisted-by: Opencode:Big-Pickle
Signed-off-by: Rosen Penev <rosenp@xxxxxxxxx>
---
drivers/ata/pata_ep93xx.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c
index b2b9e0058333..3f61712af5bb 100644
--- a/drivers/ata/pata_ep93xx.c
+++ b/drivers/ata/pata_ep93xx.c
@@ -652,14 +652,22 @@ static int ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data)
* start of new transfer.
*/
drv_data->dma_rx_channel = dma_request_chan(dev, "rx");
- if (IS_ERR(drv_data->dma_rx_channel))
- return dev_err_probe(dev, PTR_ERR(drv_data->dma_rx_channel),
- "rx DMA setup failed\n");
+ if (IS_ERR(drv_data->dma_rx_channel)) {
+ ret = PTR_ERR(drv_data->dma_rx_channel);
+ drv_data->dma_rx_channel = NULL;
+ if (ret == -EPROBE_DEFER)
+ return ret;
+ dev_warn(dev, "rx DMA unavailable, using PIO\n");
+ return 0;
+ }
drv_data->dma_tx_channel = dma_request_chan(&pdev->dev, "tx");
if (IS_ERR(drv_data->dma_tx_channel)) {
- ret = dev_err_probe(dev, PTR_ERR(drv_data->dma_tx_channel),
- "tx DMA setup failed\n");
+ ret = PTR_ERR(drv_data->dma_tx_channel);
+ drv_data->dma_tx_channel = NULL;
+ if (ret == -EPROBE_DEFER)
+ goto fail_release_rx;
+ dev_warn(dev, "tx DMA unavailable, using PIO\n");
goto fail_release_rx;
}
@@ -670,7 +678,7 @@ static int ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data)
conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
ret = dmaengine_slave_config(drv_data->dma_rx_channel, &conf);
if (ret) {
- dev_err_probe(dev, ret, "failed to configure rx dma channel");
+ dev_warn(dev, "failed to configure rx dma channel, using PIO\n");
goto fail_release_dma;
}
@@ -681,7 +689,7 @@ static int ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data)
conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
ret = dmaengine_slave_config(drv_data->dma_tx_channel, &conf);
if (ret) {
- dev_err_probe(dev, ret, "failed to configure tx dma channel");
+ dev_warn(dev, "failed to configure tx dma channel, using PIO\n");
goto fail_release_dma;
}
@@ -689,10 +697,14 @@ static int ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data)
fail_release_rx:
dma_release_channel(drv_data->dma_rx_channel);
+ drv_data->dma_rx_channel = NULL;
+ if (ret == -EPROBE_DEFER)
+ return ret;
+ return 0;
+
fail_release_dma:
ep93xx_pata_release_dma(drv_data);
-
- return ret;
+ return 0;
}
static void ep93xx_pata_dma_start(struct ata_queued_cmd *qc)
--
2.54.0