|
@@ -6821,19 +6821,6 @@ static void ata_host_release(struct device *gendev, void *res)
|
|
struct ata_host *host = dev_get_drvdata(gendev);
|
|
struct ata_host *host = dev_get_drvdata(gendev);
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- for (i = 0; i < host->n_ports; i++) {
|
|
|
|
- struct ata_port *ap = host->ports[i];
|
|
|
|
-
|
|
|
|
- if (!ap)
|
|
|
|
- continue;
|
|
|
|
-
|
|
|
|
- if ((host->flags & ATA_HOST_STARTED) && ap->ops->port_stop)
|
|
|
|
- ap->ops->port_stop(ap);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ((host->flags & ATA_HOST_STARTED) && host->ops->host_stop)
|
|
|
|
- host->ops->host_stop(host);
|
|
|
|
-
|
|
|
|
for (i = 0; i < host->n_ports; i++) {
|
|
for (i = 0; i < host->n_ports; i++) {
|
|
struct ata_port *ap = host->ports[i];
|
|
struct ata_port *ap = host->ports[i];
|
|
|
|
|
|
@@ -6966,6 +6953,24 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
|
|
return host;
|
|
return host;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void ata_host_stop(struct device *gendev, void *res)
|
|
|
|
+{
|
|
|
|
+ struct ata_host *host = dev_get_drvdata(gendev);
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ WARN_ON(!(host->flags & ATA_HOST_STARTED));
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < host->n_ports; i++) {
|
|
|
|
+ struct ata_port *ap = host->ports[i];
|
|
|
|
+
|
|
|
|
+ if (ap->ops->port_stop)
|
|
|
|
+ ap->ops->port_stop(ap);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (host->ops->host_stop)
|
|
|
|
+ host->ops->host_stop(host);
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* ata_host_start - start and freeze ports of an ATA host
|
|
* ata_host_start - start and freeze ports of an ATA host
|
|
* @host: ATA host to start ports for
|
|
* @host: ATA host to start ports for
|
|
@@ -6984,6 +6989,8 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
|
|
*/
|
|
*/
|
|
int ata_host_start(struct ata_host *host)
|
|
int ata_host_start(struct ata_host *host)
|
|
{
|
|
{
|
|
|
|
+ int have_stop = 0;
|
|
|
|
+ void *start_dr = NULL;
|
|
int i, rc;
|
|
int i, rc;
|
|
|
|
|
|
if (host->flags & ATA_HOST_STARTED)
|
|
if (host->flags & ATA_HOST_STARTED)
|
|
@@ -6995,6 +7002,22 @@ int ata_host_start(struct ata_host *host)
|
|
if (!host->ops && !ata_port_is_dummy(ap))
|
|
if (!host->ops && !ata_port_is_dummy(ap))
|
|
host->ops = ap->ops;
|
|
host->ops = ap->ops;
|
|
|
|
|
|
|
|
+ if (ap->ops->port_stop)
|
|
|
|
+ have_stop = 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (host->ops->host_stop)
|
|
|
|
+ have_stop = 1;
|
|
|
|
+
|
|
|
|
+ if (have_stop) {
|
|
|
|
+ start_dr = devres_alloc(ata_host_stop, 0, GFP_KERNEL);
|
|
|
|
+ if (!start_dr)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < host->n_ports; i++) {
|
|
|
|
+ struct ata_port *ap = host->ports[i];
|
|
|
|
+
|
|
if (ap->ops->port_start) {
|
|
if (ap->ops->port_start) {
|
|
rc = ap->ops->port_start(ap);
|
|
rc = ap->ops->port_start(ap);
|
|
if (rc) {
|
|
if (rc) {
|
|
@@ -7007,6 +7030,8 @@ int ata_host_start(struct ata_host *host)
|
|
ata_eh_freeze_port(ap);
|
|
ata_eh_freeze_port(ap);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (start_dr)
|
|
|
|
+ devres_add(host->dev, start_dr);
|
|
host->flags |= ATA_HOST_STARTED;
|
|
host->flags |= ATA_HOST_STARTED;
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
@@ -7017,6 +7042,7 @@ int ata_host_start(struct ata_host *host)
|
|
if (ap->ops->port_stop)
|
|
if (ap->ops->port_stop)
|
|
ap->ops->port_stop(ap);
|
|
ap->ops->port_stop(ap);
|
|
}
|
|
}
|
|
|
|
+ devres_free(start_dr);
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|