summaryrefslogtreecommitdiff
path: root/drivers/ata
diff options
context:
space:
mode:
authorRosen Penev <rosenp@gmail.com>2026-07-19 19:02:29 -0700
committerDamien Le Moal <dlemoal@kernel.org>2026-07-23 16:40:05 +0900
commitc303c3619a1d5cf7d4b457106062d16724724a80 (patch)
tree77d0445aeea3e12f1dbfa969dfd061b3beb083fc /drivers/ata
parent43ea91dadb35579169884f6707d43f7b2607153d (diff)
ata: pata_ep93xx: fix PIO fallback when DMA init fails
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. Propagate -EPROBE_DEFER, such that we allow the DMA controller driver to load, in case we got probed before the DMA controller driver. For all other failures (e.g. -ENODEV when the DMA controller is missing in the device tree), fall back to PIO. Assisted-by: Opencode:Big-Pickle Signed-off-by: Rosen Penev <rosenp@gmail.com> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/pata_ep93xx.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c
index 42a24dc51d26..339ee5e43e9f 100644
--- a/drivers/ata/pata_ep93xx.c
+++ b/drivers/ata/pata_ep93xx.c
@@ -656,14 +656,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;
}
@@ -674,7 +682,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;
}
@@ -685,7 +693,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;
}
@@ -693,10 +701,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)