diff options
| -rw-r--r-- | drivers/ata/libata-core.c | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fd332612d64a..81898036dbca 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -6827,19 +6827,6 @@ static void ata_host_release(struct device *gendev, void *res) | |||
| 6827 | if (!ap) | 6827 | if (!ap) |
| 6828 | continue; | 6828 | continue; |
| 6829 | 6829 | ||
| 6830 | if ((host->flags & ATA_HOST_STARTED) && ap->ops->port_stop) | ||
| 6831 | ap->ops->port_stop(ap); | ||
| 6832 | } | ||
| 6833 | |||
| 6834 | if ((host->flags & ATA_HOST_STARTED) && host->ops->host_stop) | ||
| 6835 | host->ops->host_stop(host); | ||
| 6836 | |||
| 6837 | for (i = 0; i < host->n_ports; i++) { | ||
| 6838 | struct ata_port *ap = host->ports[i]; | ||
| 6839 | |||
| 6840 | if (!ap) | ||
| 6841 | continue; | ||
| 6842 | |||
| 6843 | if (ap->scsi_host) | 6830 | if (ap->scsi_host) |
| 6844 | scsi_host_put(ap->scsi_host); | 6831 | scsi_host_put(ap->scsi_host); |
| 6845 | 6832 | ||
| @@ -6966,6 +6953,24 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, | |||
| 6966 | return host; | 6953 | return host; |
| 6967 | } | 6954 | } |
| 6968 | 6955 | ||
| 6956 | static void ata_host_stop(struct device *gendev, void *res) | ||
| 6957 | { | ||
| 6958 | struct ata_host *host = dev_get_drvdata(gendev); | ||
| 6959 | int i; | ||
| 6960 | |||
| 6961 | WARN_ON(!(host->flags & ATA_HOST_STARTED)); | ||
| 6962 | |||
| 6963 | for (i = 0; i < host->n_ports; i++) { | ||
| 6964 | struct ata_port *ap = host->ports[i]; | ||
| 6965 | |||
| 6966 | if (ap->ops->port_stop) | ||
| 6967 | ap->ops->port_stop(ap); | ||
| 6968 | } | ||
| 6969 | |||
| 6970 | if (host->ops->host_stop) | ||
| 6971 | host->ops->host_stop(host); | ||
| 6972 | } | ||
| 6973 | |||
| 6969 | /** | 6974 | /** |
| 6970 | * ata_host_start - start and freeze ports of an ATA host | 6975 | * ata_host_start - start and freeze ports of an ATA host |
| 6971 | * @host: ATA host to start ports for | 6976 | * @host: ATA host to start ports for |
| @@ -6984,6 +6989,8 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, | |||
| 6984 | */ | 6989 | */ |
| 6985 | int ata_host_start(struct ata_host *host) | 6990 | int ata_host_start(struct ata_host *host) |
| 6986 | { | 6991 | { |
| 6992 | int have_stop = 0; | ||
| 6993 | void *start_dr = NULL; | ||
| 6987 | int i, rc; | 6994 | int i, rc; |
| 6988 | 6995 | ||
| 6989 | if (host->flags & ATA_HOST_STARTED) | 6996 | if (host->flags & ATA_HOST_STARTED) |
| @@ -6995,6 +7002,22 @@ int ata_host_start(struct ata_host *host) | |||
| 6995 | if (!host->ops && !ata_port_is_dummy(ap)) | 7002 | if (!host->ops && !ata_port_is_dummy(ap)) |
| 6996 | host->ops = ap->ops; | 7003 | host->ops = ap->ops; |
| 6997 | 7004 | ||
| 7005 | if (ap->ops->port_stop) | ||
| 7006 | have_stop = 1; | ||
| 7007 | } | ||
| 7008 | |||
| 7009 | if (host->ops->host_stop) | ||
| 7010 | have_stop = 1; | ||
| 7011 | |||
| 7012 | if (have_stop) { | ||
| 7013 | start_dr = devres_alloc(ata_host_stop, 0, GFP_KERNEL); | ||
| 7014 | if (!start_dr) | ||
| 7015 | return -ENOMEM; | ||
| 7016 | } | ||
| 7017 | |||
| 7018 | for (i = 0; i < host->n_ports; i++) { | ||
| 7019 | struct ata_port *ap = host->ports[i]; | ||
| 7020 | |||
| 6998 | if (ap->ops->port_start) { | 7021 | if (ap->ops->port_start) { |
| 6999 | rc = ap->ops->port_start(ap); | 7022 | rc = ap->ops->port_start(ap); |
| 7000 | if (rc) { | 7023 | if (rc) { |
| @@ -7007,6 +7030,8 @@ int ata_host_start(struct ata_host *host) | |||
| 7007 | ata_eh_freeze_port(ap); | 7030 | ata_eh_freeze_port(ap); |
| 7008 | } | 7031 | } |
| 7009 | 7032 | ||
| 7033 | if (start_dr) | ||
| 7034 | devres_add(host->dev, start_dr); | ||
| 7010 | host->flags |= ATA_HOST_STARTED; | 7035 | host->flags |= ATA_HOST_STARTED; |
| 7011 | return 0; | 7036 | return 0; |
| 7012 | 7037 | ||
| @@ -7017,6 +7042,7 @@ int ata_host_start(struct ata_host *host) | |||
| 7017 | if (ap->ops->port_stop) | 7042 | if (ap->ops->port_stop) |
| 7018 | ap->ops->port_stop(ap); | 7043 | ap->ops->port_stop(ap); |
| 7019 | } | 7044 | } |
| 7045 | devres_free(start_dr); | ||
| 7020 | return rc; | 7046 | return rc; |
| 7021 | } | 7047 | } |
| 7022 | 7048 | ||
