aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_mv.c
diff options
context:
space:
mode:
authorEzequiel Garcia <ezequiel.garcia@free-electrons.com>2014-02-16 10:29:53 -0500
committerTejun Heo <tj@kernel.org>2014-02-16 11:51:17 -0500
commit8ad116e649b21a42e3cccfb3c1b8d5ea52ba19e5 (patch)
treec5a69d0a235864821b6ad4d46c9a280b72f95e7f /drivers/ata/sata_mv.c
parent9f9c47f00ce99329b1a82e2ac4f70f0fe3db549c (diff)
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: 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
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r--drivers/ata/sata_mv.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 20a7517bd339..9c1a11de3044 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -4104,7 +4104,6 @@ static int mv_platform_probe(struct platform_device *pdev)
4104 if (!hpriv->port_phys) 4104 if (!hpriv->port_phys)
4105 return -ENOMEM; 4105 return -ENOMEM;
4106 host->private_data = hpriv; 4106 host->private_data = hpriv;
4107 hpriv->n_ports = n_ports;
4108 hpriv->board_idx = chip_soc; 4107 hpriv->board_idx = chip_soc;
4109 4108
4110 host->iomap = NULL; 4109 host->iomap = NULL;
@@ -4132,11 +4131,17 @@ static int mv_platform_probe(struct platform_device *pdev)
4132 hpriv->port_phys[port] = NULL; 4131 hpriv->port_phys[port] = NULL;
4133 if ((rc != -EPROBE_DEFER) && (rc != -ENODEV)) 4132 if ((rc != -EPROBE_DEFER) && (rc != -ENODEV))
4134 dev_warn(&pdev->dev, "error getting phy"); 4133 dev_warn(&pdev->dev, "error getting phy");
4134
4135 /* Cleanup only the initialized ports */
4136 hpriv->n_ports = port;
4135 goto err; 4137 goto err;
4136 } else 4138 } else
4137 phy_power_on(hpriv->port_phys[port]); 4139 phy_power_on(hpriv->port_phys[port]);
4138 } 4140 }
4139 4141
4142 /* All the ports have been initialized */
4143 hpriv->n_ports = n_ports;
4144
4140 /* 4145 /*
4141 * (Re-)program MBUS remapping windows if we are asked to. 4146 * (Re-)program MBUS remapping windows if we are asked to.
4142 */ 4147 */
@@ -4174,7 +4179,7 @@ err:
4174 clk_disable_unprepare(hpriv->clk); 4179 clk_disable_unprepare(hpriv->clk);
4175 clk_put(hpriv->clk); 4180 clk_put(hpriv->clk);
4176 } 4181 }
4177 for (port = 0; port < n_ports; port++) { 4182 for (port = 0; port < hpriv->n_ports; port++) {
4178 if (!IS_ERR(hpriv->port_clks[port])) { 4183 if (!IS_ERR(hpriv->port_clks[port])) {
4179 clk_disable_unprepare(hpriv->port_clks[port]); 4184 clk_disable_unprepare(hpriv->port_clks[port]);
4180 clk_put(hpriv->port_clks[port]); 4185 clk_put(hpriv->port_clks[port]);