Commit 8ad116e6 authored by Ezequiel Garcia's avatar Ezequiel Garcia Committed by Tejun Heo

ata: sata_mv: Cleanup only the initialized ports

When an error occurs in the port initialization loop, currently the
driver tries to cleanup all the ports. This results in a NULL pointer
dereference if the ports were only partially initialized.

Fix this by updating only the number of initialized ports (either
with failure or successfully), before jumping to the error path
and looping over that number in the cleanup loop.

Cc: Andrew Lunn <andrew@lunn.ch>
Reported-by: default avatarMikael Pettersson <mikpelinux@gmail.com>
Signed-off-by: default avatarEzequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Cc: stable@vger.kernel.org
parent 9f9c47f0
...@@ -4104,7 +4104,6 @@ static int mv_platform_probe(struct platform_device *pdev) ...@@ -4104,7 +4104,6 @@ static int mv_platform_probe(struct platform_device *pdev)
if (!hpriv->port_phys) if (!hpriv->port_phys)
return -ENOMEM; return -ENOMEM;
host->private_data = hpriv; host->private_data = hpriv;
hpriv->n_ports = n_ports;
hpriv->board_idx = chip_soc; hpriv->board_idx = chip_soc;
host->iomap = NULL; host->iomap = NULL;
...@@ -4132,11 +4131,17 @@ static int mv_platform_probe(struct platform_device *pdev) ...@@ -4132,11 +4131,17 @@ static int mv_platform_probe(struct platform_device *pdev)
hpriv->port_phys[port] = NULL; hpriv->port_phys[port] = NULL;
if ((rc != -EPROBE_DEFER) && (rc != -ENODEV)) if ((rc != -EPROBE_DEFER) && (rc != -ENODEV))
dev_warn(&pdev->dev, "error getting phy"); dev_warn(&pdev->dev, "error getting phy");
/* Cleanup only the initialized ports */
hpriv->n_ports = port;
goto err; goto err;
} else } else
phy_power_on(hpriv->port_phys[port]); phy_power_on(hpriv->port_phys[port]);
} }
/* All the ports have been initialized */
hpriv->n_ports = n_ports;
/* /*
* (Re-)program MBUS remapping windows if we are asked to. * (Re-)program MBUS remapping windows if we are asked to.
*/ */
...@@ -4174,7 +4179,7 @@ static int mv_platform_probe(struct platform_device *pdev) ...@@ -4174,7 +4179,7 @@ static int mv_platform_probe(struct platform_device *pdev)
clk_disable_unprepare(hpriv->clk); clk_disable_unprepare(hpriv->clk);
clk_put(hpriv->clk); clk_put(hpriv->clk);
} }
for (port = 0; port < n_ports; port++) { for (port = 0; port < hpriv->n_ports; port++) {
if (!IS_ERR(hpriv->port_clks[port])) { if (!IS_ERR(hpriv->port_clks[port])) {
clk_disable_unprepare(hpriv->port_clks[port]); clk_disable_unprepare(hpriv->port_clks[port]);
clk_put(hpriv->port_clks[port]); clk_put(hpriv->port_clks[port]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment