aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorJames Bottomley <JBottomley@Parallels.com>2012-10-02 03:55:12 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-10-02 03:55:12 -0400
commitfe709ed827d370e6b0c0a9f9456da1c22bdcd118 (patch)
treec5a7fd72a745a5f6656a58acc9a1d277e26f9595 /drivers/ata/libata-core.c
parent1c4cf1d5845b59cdcbfad8e67272cf5b219ab062 (diff)
parent0644f5393e915f13733bcc65f13195ff39aeb63e (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.c69
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
5254static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, 5254static 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
5298static int ata_port_suspend_common(struct device *dev, pm_message_t mesg) 5302static 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
5322static 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
5319static int ata_port_suspend(struct device *dev) 5329static 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
5343static int ata_port_resume_common(struct device *dev) 5353static 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
5362static 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
5353static int ata_port_resume(struct device *dev) 5369static 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 */
5406int ata_sas_port_async_suspend(struct ata_port *ap, int *async)
5407{
5408 return __ata_port_suspend_common(ap, PMSG_SUSPEND, async);
5409}
5410EXPORT_SYMBOL_GPL(ata_sas_port_async_suspend);
5411
5412int ata_sas_port_async_resume(struct ata_port *ap, int *async)
5413{
5414 return __ata_port_resume_common(ap, async);
5415}
5416EXPORT_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 */
5941void ata_host_init(struct ata_host *host, struct device *dev, 5970void 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;