[PATCHv2] ata: pata_ep93xx: fix PIO fallback when DMA init fails
Rosen Penev <[email protected]> Sun, 19 Jul 2026 19:02:29 -0700
| Newsgroups | gmane.linux.kernel,gmane.linux.ide |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- v2: fix EPROBE_DEFER description 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 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) -- 2.55.0