Skip to content

Commit

Permalink
ata: sata_mv: Cleanup only the initialized ports
Browse files Browse the repository at this point in the history
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: Mikael Pettersson <mikpelinux@gmail.com>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: stable@vger.kernel.org
  • Loading branch information
Ezequiel Garcia authored and Tejun Heo committed Feb 16, 2014
1 parent 9f9c47f commit 8ad116e
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions drivers/ata/sata_mv.c
Original file line number Diff line number Diff line change
Expand Up @@ -4104,7 +4104,6 @@ static int mv_platform_probe(struct platform_device *pdev)
if (!hpriv->port_phys)
return -ENOMEM;
host->private_data = hpriv;
hpriv->n_ports = n_ports;
hpriv->board_idx = chip_soc;

host->iomap = NULL;
Expand Down Expand Up @@ -4132,11 +4131,17 @@ static int mv_platform_probe(struct platform_device *pdev)
hpriv->port_phys[port] = NULL;
if ((rc != -EPROBE_DEFER) && (rc != -ENODEV))
dev_warn(&pdev->dev, "error getting phy");

/* Cleanup only the initialized ports */
hpriv->n_ports = port;
goto err;
} else
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.
*/
Expand Down Expand Up @@ -4174,7 +4179,7 @@ static int mv_platform_probe(struct platform_device *pdev)
clk_disable_unprepare(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])) {
clk_disable_unprepare(hpriv->port_clks[port]);
clk_put(hpriv->port_clks[port]);
Expand Down

0 comments on commit 8ad116e

Please sign in to comment.