Browse Source

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>
Tejun Heo 18 years ago
parent
commit
1aa506e437
1 changed files with 10 additions and 6 deletions
  1. 10 6
      drivers/ata/libata-core.c

+ 10 - 6
drivers/ata/libata-core.c

@@ -5685,18 +5685,22 @@ static void ata_host_release(struct device *gendev, void *res)
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
 
-		if (!ap)
-			continue;
-
-		if (ap->ops->port_stop)
+		if (ap && ap->ops->port_stop)
 			ap->ops->port_stop(ap);
-
-		scsi_host_put(ap->scsi_host);
 	}
 
 	if (host->ops->host_stop)
 		host->ops->host_stop(host);
 
+	for (i = 0; i < host->n_ports; i++) {
+		struct ata_port *ap = host->ports[i];
+
+		if (ap)
+			scsi_host_put(ap->scsi_host);
+
+		host->ports[i] = NULL;
+	}
+
 	dev_set_drvdata(gendev, NULL);
 }