Skip to content

Commit

Permalink
sata_dwc_460ex: fix resource leak on error path
Browse files Browse the repository at this point in the history
commit 4aaa718 upstream.

DMA mapped IO should be unmapped on the error path in probe() and
unconditionally on remove().

Fixes: 6293600 ([libata] Add 460EX on-chip SATA driver, sata_dwc_460ex)
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
andy-shev authored and gregkh committed Jan 30, 2015
1 parent 26dc532 commit e8eb477
Showing 1 changed file with 12 additions and 14 deletions.
26 changes: 12 additions & 14 deletions drivers/ata/sata_dwc_460ex.c
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq)
if (err) {
dev_err(host_pvt.dwc_dev, "%s: dma_request_interrupts returns"
" %d\n", __func__, err);
goto error_out;
return err;
}

/* Enabe DMA */
Expand All @@ -808,11 +808,6 @@ static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq)
sata_dma_regs);

return 0;

error_out:
dma_dwc_exit(hsdev);

return err;
}

static int sata_dwc_scr_read(struct ata_link *link, unsigned int scr, u32 *val)
Expand Down Expand Up @@ -1662,7 +1657,7 @@ static int sata_dwc_probe(struct platform_device *ofdev)
char *ver = (char *)&versionr;
u8 *base = NULL;
int err = 0;
int irq, rc;
int irq;
struct ata_host *host;
struct ata_port_info pi = sata_dwc_port_info[0];
const struct ata_port_info *ppi[] = { &pi, NULL };
Expand Down Expand Up @@ -1725,7 +1720,7 @@ static int sata_dwc_probe(struct platform_device *ofdev)
if (irq == NO_IRQ) {
dev_err(&ofdev->dev, "no SATA DMA irq\n");
err = -ENODEV;
goto error_out;
goto error_iomap;
}

/* Get physical SATA DMA register base address */
Expand All @@ -1734,14 +1729,16 @@ static int sata_dwc_probe(struct platform_device *ofdev)
dev_err(&ofdev->dev, "ioremap failed for AHBDMA register"
" address\n");
err = -ENODEV;
goto error_out;
goto error_iomap;
}

/* Save dev for later use in dev_xxx() routines */
host_pvt.dwc_dev = &ofdev->dev;

/* Initialize AHB DMAC */
dma_dwc_init(hsdev, irq);
err = dma_dwc_init(hsdev, irq);
if (err)
goto error_dma_iomap;

/* Enable SATA Interrupts */
sata_dwc_enable_interrupts(hsdev);
Expand All @@ -1759,9 +1756,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
* device discovery process, invoking our port_start() handler &
* error_handler() to execute a dummy Softreset EH session
*/
rc = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht);

if (rc != 0)
err = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht);
if (err)
dev_err(&ofdev->dev, "failed to activate host");

dev_set_drvdata(&ofdev->dev, host);
Expand All @@ -1770,7 +1766,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
error_out:
/* Free SATA DMA resources */
dma_dwc_exit(hsdev);

error_dma_iomap:
iounmap((void __iomem *)host_pvt.sata_dma_regs);
error_iomap:
iounmap(base);
error_kmalloc:
Expand All @@ -1791,6 +1788,7 @@ static int sata_dwc_remove(struct platform_device *ofdev)
/* Free SATA DMA resources */
dma_dwc_exit(hsdev);

iounmap((void __iomem *)host_pvt.sata_dma_regs);
iounmap(hsdev->reg_base);
kfree(hsdev);
kfree(host);
Expand Down

0 comments on commit e8eb477

Please sign in to comment.