aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-03-09 05:36:12 -0500
committerJeff Garzik <jeff@garzik.org>2007-03-09 08:41:16 -0500
commit1aa506e437a94d520f852d39d5d6a6e7f2e01901 (patch)
treef001596d659c278ef8d78de1e11eae7b9198705c /drivers/ata
parent8ba5e4cbe444f10352756b6c7715bb26bb087680 (diff)
libata: fix ata_host_release() free order
host->ops->host_stop() might access ports. Free ports after host_stop. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-core.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index f6408ca82062..3c1f8830ac8b 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5685,18 +5685,22 @@ static void ata_host_release(struct device *gendev, void *res)
5685 for (i = 0; i < host->n_ports; i++) { 5685 for (i = 0; i < host->n_ports; i++) {
5686 struct ata_port *ap = host->ports[i]; 5686 struct ata_port *ap = host->ports[i];
5687 5687
5688 if (!ap) 5688 if (ap && ap->ops->port_stop)
5689 continue;
5690
5691 if (ap->ops->port_stop)
5692 ap->ops->port_stop(ap); 5689 ap->ops->port_stop(ap);
5693
5694 scsi_host_put(ap->scsi_host);
5695 } 5690 }
5696 5691
5697 if (host->ops->host_stop) 5692 if (host->ops->host_stop)
5698 host->ops->host_stop(host); 5693 host->ops->host_stop(host);
5699 5694
5695 for (i = 0; i < host->n_ports; i++) {
5696 struct ata_port *ap = host->ports[i];
5697
5698 if (ap)
5699 scsi_host_put(ap->scsi_host);
5700
5701 host->ports[i] = NULL;
5702 }
5703
5700 dev_set_drvdata(gendev, NULL); 5704 dev_set_drvdata(gendev, NULL);
5701} 5705}
5702 5706