diff options
author | James Bottomley <JBottomley@Parallels.com> | 2012-10-02 03:55:12 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-10-02 03:55:12 -0400 |
commit | fe709ed827d370e6b0c0a9f9456da1c22bdcd118 (patch) | |
tree | c5a7fd72a745a5f6656a58acc9a1d277e26f9595 /drivers/ata/libata-core.c | |
parent | 1c4cf1d5845b59cdcbfad8e67272cf5b219ab062 (diff) | |
parent | 0644f5393e915f13733bcc65f13195ff39aeb63e (diff) |
Merge SCSI misc branch into isci-for-3.6 tag
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 8e1039c8e159..abd729fc094a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -5253,16 +5253,20 @@ bool ata_link_offline(struct ata_link *link) | |||
5253 | #ifdef CONFIG_PM | 5253 | #ifdef CONFIG_PM |
5254 | static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, | 5254 | static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, |
5255 | unsigned int action, unsigned int ehi_flags, | 5255 | unsigned int action, unsigned int ehi_flags, |
5256 | int wait) | 5256 | int *async) |
5257 | { | 5257 | { |
5258 | struct ata_link *link; | 5258 | struct ata_link *link; |
5259 | unsigned long flags; | 5259 | unsigned long flags; |
5260 | int rc; | 5260 | int rc = 0; |
5261 | 5261 | ||
5262 | /* Previous resume operation might still be in | 5262 | /* Previous resume operation might still be in |
5263 | * progress. Wait for PM_PENDING to clear. | 5263 | * progress. Wait for PM_PENDING to clear. |
5264 | */ | 5264 | */ |
5265 | if (ap->pflags & ATA_PFLAG_PM_PENDING) { | 5265 | if (ap->pflags & ATA_PFLAG_PM_PENDING) { |
5266 | if (async) { | ||
5267 | *async = -EAGAIN; | ||
5268 | return 0; | ||
5269 | } | ||
5266 | ata_port_wait_eh(ap); | 5270 | ata_port_wait_eh(ap); |
5267 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); | 5271 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); |
5268 | } | 5272 | } |
@@ -5271,10 +5275,10 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, | |||
5271 | spin_lock_irqsave(ap->lock, flags); | 5275 | spin_lock_irqsave(ap->lock, flags); |
5272 | 5276 | ||
5273 | ap->pm_mesg = mesg; | 5277 | ap->pm_mesg = mesg; |
5274 | if (wait) { | 5278 | if (async) |
5275 | rc = 0; | 5279 | ap->pm_result = async; |
5280 | else | ||
5276 | ap->pm_result = &rc; | 5281 | ap->pm_result = &rc; |
5277 | } | ||
5278 | 5282 | ||
5279 | ap->pflags |= ATA_PFLAG_PM_PENDING; | 5283 | ap->pflags |= ATA_PFLAG_PM_PENDING; |
5280 | ata_for_each_link(link, ap, HOST_FIRST) { | 5284 | ata_for_each_link(link, ap, HOST_FIRST) { |
@@ -5287,7 +5291,7 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, | |||
5287 | spin_unlock_irqrestore(ap->lock, flags); | 5291 | spin_unlock_irqrestore(ap->lock, flags); |
5288 | 5292 | ||
5289 | /* wait and check result */ | 5293 | /* wait and check result */ |
5290 | if (wait) { | 5294 | if (!async) { |
5291 | ata_port_wait_eh(ap); | 5295 | ata_port_wait_eh(ap); |
5292 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); | 5296 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); |
5293 | } | 5297 | } |
@@ -5295,9 +5299,8 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, | |||
5295 | return rc; | 5299 | return rc; |
5296 | } | 5300 | } |
5297 | 5301 | ||
5298 | static int ata_port_suspend_common(struct device *dev, pm_message_t mesg) | 5302 | static int __ata_port_suspend_common(struct ata_port *ap, pm_message_t mesg, int *async) |
5299 | { | 5303 | { |
5300 | struct ata_port *ap = to_ata_port(dev); | ||
5301 | unsigned int ehi_flags = ATA_EHI_QUIET; | 5304 | unsigned int ehi_flags = ATA_EHI_QUIET; |
5302 | int rc; | 5305 | int rc; |
5303 | 5306 | ||
@@ -5312,10 +5315,17 @@ static int ata_port_suspend_common(struct device *dev, pm_message_t mesg) | |||
5312 | if (mesg.event == PM_EVENT_SUSPEND) | 5315 | if (mesg.event == PM_EVENT_SUSPEND) |
5313 | ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY; | 5316 | ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY; |
5314 | 5317 | ||
5315 | rc = ata_port_request_pm(ap, mesg, 0, ehi_flags, 1); | 5318 | rc = ata_port_request_pm(ap, mesg, 0, ehi_flags, async); |
5316 | return rc; | 5319 | return rc; |
5317 | } | 5320 | } |
5318 | 5321 | ||
5322 | static int ata_port_suspend_common(struct device *dev, pm_message_t mesg) | ||
5323 | { | ||
5324 | struct ata_port *ap = to_ata_port(dev); | ||
5325 | |||
5326 | return __ata_port_suspend_common(ap, mesg, NULL); | ||
5327 | } | ||
5328 | |||
5319 | static int ata_port_suspend(struct device *dev) | 5329 | static int ata_port_suspend(struct device *dev) |
5320 | { | 5330 | { |
5321 | if (pm_runtime_suspended(dev)) | 5331 | if (pm_runtime_suspended(dev)) |
@@ -5340,16 +5350,22 @@ static int ata_port_poweroff(struct device *dev) | |||
5340 | return ata_port_suspend_common(dev, PMSG_HIBERNATE); | 5350 | return ata_port_suspend_common(dev, PMSG_HIBERNATE); |
5341 | } | 5351 | } |
5342 | 5352 | ||
5343 | static int ata_port_resume_common(struct device *dev) | 5353 | static int __ata_port_resume_common(struct ata_port *ap, int *async) |
5344 | { | 5354 | { |
5345 | struct ata_port *ap = to_ata_port(dev); | ||
5346 | int rc; | 5355 | int rc; |
5347 | 5356 | ||
5348 | rc = ata_port_request_pm(ap, PMSG_ON, ATA_EH_RESET, | 5357 | rc = ata_port_request_pm(ap, PMSG_ON, ATA_EH_RESET, |
5349 | ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 1); | 5358 | ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, async); |
5350 | return rc; | 5359 | return rc; |
5351 | } | 5360 | } |
5352 | 5361 | ||
5362 | static int ata_port_resume_common(struct device *dev) | ||
5363 | { | ||
5364 | struct ata_port *ap = to_ata_port(dev); | ||
5365 | |||
5366 | return __ata_port_resume_common(ap, NULL); | ||
5367 | } | ||
5368 | |||
5353 | static int ata_port_resume(struct device *dev) | 5369 | static int ata_port_resume(struct device *dev) |
5354 | { | 5370 | { |
5355 | int rc; | 5371 | int rc; |
@@ -5382,6 +5398,24 @@ static const struct dev_pm_ops ata_port_pm_ops = { | |||
5382 | .runtime_idle = ata_port_runtime_idle, | 5398 | .runtime_idle = ata_port_runtime_idle, |
5383 | }; | 5399 | }; |
5384 | 5400 | ||
5401 | /* sas ports don't participate in pm runtime management of ata_ports, | ||
5402 | * and need to resume ata devices at the domain level, not the per-port | ||
5403 | * level. sas suspend/resume is async to allow parallel port recovery | ||
5404 | * since sas has multiple ata_port instances per Scsi_Host. | ||
5405 | */ | ||
5406 | int ata_sas_port_async_suspend(struct ata_port *ap, int *async) | ||
5407 | { | ||
5408 | return __ata_port_suspend_common(ap, PMSG_SUSPEND, async); | ||
5409 | } | ||
5410 | EXPORT_SYMBOL_GPL(ata_sas_port_async_suspend); | ||
5411 | |||
5412 | int ata_sas_port_async_resume(struct ata_port *ap, int *async) | ||
5413 | { | ||
5414 | return __ata_port_resume_common(ap, async); | ||
5415 | } | ||
5416 | EXPORT_SYMBOL_GPL(ata_sas_port_async_resume); | ||
5417 | |||
5418 | |||
5385 | /** | 5419 | /** |
5386 | * ata_host_suspend - suspend host | 5420 | * ata_host_suspend - suspend host |
5387 | * @host: host to suspend | 5421 | * @host: host to suspend |
@@ -5927,24 +5961,18 @@ int ata_host_start(struct ata_host *host) | |||
5927 | } | 5961 | } |
5928 | 5962 | ||
5929 | /** | 5963 | /** |
5930 | * ata_sas_host_init - Initialize a host struct | 5964 | * ata_sas_host_init - Initialize a host struct for sas (ipr, libsas) |
5931 | * @host: host to initialize | 5965 | * @host: host to initialize |
5932 | * @dev: device host is attached to | 5966 | * @dev: device host is attached to |
5933 | * @flags: host flags | ||
5934 | * @ops: port_ops | 5967 | * @ops: port_ops |
5935 | * | 5968 | * |
5936 | * LOCKING: | ||
5937 | * PCI/etc. bus probe sem. | ||
5938 | * | ||
5939 | */ | 5969 | */ |
5940 | /* KILLME - the only user left is ipr */ | ||
5941 | void ata_host_init(struct ata_host *host, struct device *dev, | 5970 | void ata_host_init(struct ata_host *host, struct device *dev, |
5942 | unsigned long flags, struct ata_port_operations *ops) | 5971 | struct ata_port_operations *ops) |
5943 | { | 5972 | { |
5944 | spin_lock_init(&host->lock); | 5973 | spin_lock_init(&host->lock); |
5945 | mutex_init(&host->eh_mutex); | 5974 | mutex_init(&host->eh_mutex); |
5946 | host->dev = dev; | 5975 | host->dev = dev; |
5947 | host->flags = flags; | ||
5948 | host->ops = ops; | 5976 | host->ops = ops; |
5949 | } | 5977 | } |
5950 | 5978 | ||
@@ -6388,6 +6416,7 @@ static int __init ata_parse_force_one(char **cur, | |||
6388 | { "nohrst", .lflags = ATA_LFLAG_NO_HRST }, | 6416 | { "nohrst", .lflags = ATA_LFLAG_NO_HRST }, |
6389 | { "nosrst", .lflags = ATA_LFLAG_NO_SRST }, | 6417 | { "nosrst", .lflags = ATA_LFLAG_NO_SRST }, |
6390 | { "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST }, | 6418 | { "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST }, |
6419 | { "rstonce", .lflags = ATA_LFLAG_RST_ONCE }, | ||
6391 | }; | 6420 | }; |
6392 | char *start = *cur, *p = *cur; | 6421 | char *start = *cur, *p = *cur; |
6393 | char *id, *val, *endp; | 6422 | char *id, *val, *endp; |