aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2014-03-14 16:52:48 -0400
committerTejun Heo <tj@kernel.org>2014-03-18 16:08:38 -0400
commitbc6e7c4b0d1a1f742d96556f63d68f17f4e232c3 (patch)
tree1253c9a09dc834bbb42ef02e58ee0a117ed17ff8 /drivers
parent6a96918a6aa7b434d15710fc9e06589c6c8bd3a6 (diff)
libata, libsas: kill pm_result and related cleanup
Tejun says: "At least for libata, worrying about suspend/resume failures don't make whole lot of sense. If suspend failed, just proceed with suspend. If the device can't be woken up afterwards, that's that. There isn't anything we could have done differently anyway. The same for resume, if spinup fails, the device is dud and the following commands will invoke EH actions and will eventually fail. Again, there really isn't any *choice* to make. Just making sure the errors are handled gracefully (ie. don't crash) and the following commands are handled correctly should be enough." The only libata user that actually cares about the result from a suspend operation is libsas. However, it only cares about whether queuing a new operation collides with an in-flight one. All libsas does with the error is retry, but we can just let libata wait for the previous operation before continuing. Other cleanups include: 1/ Unifying all ata port pm operations on an ata_port_pm_ prefix 2/ Marking all ata port pm helper routines as returning void, only ata_port_pm_ entry points need to fake a 0 return value. 3/ Killing ata_port_{suspend|resume}_common() in favor of calling ata_port_request_pm() directly 4/ Killing the wrappers that just do a to_ata_port() conversion 5/ Clearly marking the entry points that do async operations with an _async suffix. Reference: http://marc.info/?l=linux-scsi&m=138995409532286&w=2 Cc: Phillip Susi <psusi@ubuntu.com> Cc: Alan Stern <stern@rowland.harvard.edu> Suggested-by: Tejun Heo <tj@kernel.org> Signed-off-by: Todd Brandt <todd.e.brandt@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-core.c135
-rw-r--r--drivers/ata/libata-eh.c13
-rw-r--r--drivers/scsi/libsas/sas_ata.c35
3 files changed, 67 insertions, 116 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 1a3dbd1b196e..66110ed2c1c0 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5351,22 +5351,17 @@ bool ata_link_offline(struct ata_link *link)
5351} 5351}
5352 5352
5353#ifdef CONFIG_PM 5353#ifdef CONFIG_PM
5354static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, 5354static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
5355 unsigned int action, unsigned int ehi_flags, 5355 unsigned int action, unsigned int ehi_flags,
5356 int *async) 5356 bool async)
5357{ 5357{
5358 struct ata_link *link; 5358 struct ata_link *link;
5359 unsigned long flags; 5359 unsigned long flags;
5360 int rc = 0;
5361 5360
5362 /* Previous resume operation might still be in 5361 /* Previous resume operation might still be in
5363 * progress. Wait for PM_PENDING to clear. 5362 * progress. Wait for PM_PENDING to clear.
5364 */ 5363 */
5365 if (ap->pflags & ATA_PFLAG_PM_PENDING) { 5364 if (ap->pflags & ATA_PFLAG_PM_PENDING) {
5366 if (async) {
5367 *async = -EAGAIN;
5368 return 0;
5369 }
5370 ata_port_wait_eh(ap); 5365 ata_port_wait_eh(ap);
5371 WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); 5366 WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
5372 } 5367 }
@@ -5375,11 +5370,6 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
5375 spin_lock_irqsave(ap->lock, flags); 5370 spin_lock_irqsave(ap->lock, flags);
5376 5371
5377 ap->pm_mesg = mesg; 5372 ap->pm_mesg = mesg;
5378 if (async)
5379 ap->pm_result = async;
5380 else
5381 ap->pm_result = &rc;
5382
5383 ap->pflags |= ATA_PFLAG_PM_PENDING; 5373 ap->pflags |= ATA_PFLAG_PM_PENDING;
5384 ata_for_each_link(link, ap, HOST_FIRST) { 5374 ata_for_each_link(link, ap, HOST_FIRST) {
5385 link->eh_info.action |= action; 5375 link->eh_info.action |= action;
@@ -5390,87 +5380,81 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
5390 5380
5391 spin_unlock_irqrestore(ap->lock, flags); 5381 spin_unlock_irqrestore(ap->lock, flags);
5392 5382
5393 /* wait and check result */
5394 if (!async) { 5383 if (!async) {
5395 ata_port_wait_eh(ap); 5384 ata_port_wait_eh(ap);
5396 WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); 5385 WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
5397 } 5386 }
5398
5399 return rc;
5400} 5387}
5401 5388
5402static int __ata_port_suspend_common(struct ata_port *ap, pm_message_t mesg, int *async) 5389/*
5390 * On some hardware, device fails to respond after spun down for suspend. As
5391 * the device won't be used before being resumed, we don't need to touch the
5392 * device. Ask EH to skip the usual stuff and proceed directly to suspend.
5393 *
5394 * http://thread.gmane.org/gmane.linux.ide/46764
5395 */
5396static const unsigned int ata_port_suspend_ehi = ATA_EHI_QUIET
5397 | ATA_EHI_NO_AUTOPSY
5398 | ATA_EHI_NO_RECOVERY;
5399
5400static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg)
5403{ 5401{
5404 /* 5402 ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false);
5405 * On some hardware, device fails to respond after spun down
5406 * for suspend. As the device won't be used before being
5407 * resumed, we don't need to touch the device. Ask EH to skip
5408 * the usual stuff and proceed directly to suspend.
5409 *
5410 * http://thread.gmane.org/gmane.linux.ide/46764
5411 */
5412 unsigned int ehi_flags = ATA_EHI_QUIET | ATA_EHI_NO_AUTOPSY |
5413 ATA_EHI_NO_RECOVERY;
5414 return ata_port_request_pm(ap, mesg, 0, ehi_flags, async);
5415} 5403}
5416 5404
5417static int ata_port_suspend_common(struct device *dev, pm_message_t mesg) 5405static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg)
5418{ 5406{
5419 struct ata_port *ap = to_ata_port(dev); 5407 ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true);
5420
5421 return __ata_port_suspend_common(ap, mesg, NULL);
5422} 5408}
5423 5409
5424static int ata_port_suspend(struct device *dev) 5410static int ata_port_pm_suspend(struct device *dev)
5425{ 5411{
5412 struct ata_port *ap = to_ata_port(dev);
5413
5426 if (pm_runtime_suspended(dev)) 5414 if (pm_runtime_suspended(dev))
5427 return 0; 5415 return 0;
5428 5416
5429 return ata_port_suspend_common(dev, PMSG_SUSPEND); 5417 ata_port_suspend(ap, PMSG_SUSPEND);
5418 return 0;
5430} 5419}
5431 5420
5432static int ata_port_do_freeze(struct device *dev) 5421static int ata_port_pm_freeze(struct device *dev)
5433{ 5422{
5423 struct ata_port *ap = to_ata_port(dev);
5424
5434 if (pm_runtime_suspended(dev)) 5425 if (pm_runtime_suspended(dev))
5435 return 0; 5426 return 0;
5436 5427
5437 return ata_port_suspend_common(dev, PMSG_FREEZE); 5428 ata_port_suspend(ap, PMSG_FREEZE);
5429 return 0;
5438} 5430}
5439 5431
5440static int ata_port_poweroff(struct device *dev) 5432static int ata_port_pm_poweroff(struct device *dev)
5441{ 5433{
5442 return ata_port_suspend_common(dev, PMSG_HIBERNATE); 5434 ata_port_suspend(to_ata_port(dev), PMSG_HIBERNATE);
5435 return 0;
5443} 5436}
5444 5437
5445static int __ata_port_resume_common(struct ata_port *ap, pm_message_t mesg, 5438static const unsigned int ata_port_resume_ehi = ATA_EHI_NO_AUTOPSY
5446 int *async) 5439 | ATA_EHI_QUIET;
5447{
5448 int rc;
5449 5440
5450 rc = ata_port_request_pm(ap, mesg, ATA_EH_RESET, 5441static void ata_port_resume(struct ata_port *ap, pm_message_t mesg)
5451 ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, async); 5442{
5452 return rc; 5443 ata_port_request_pm(ap, mesg, ATA_EH_RESET, ata_port_resume_ehi, false);
5453} 5444}
5454 5445
5455static int ata_port_resume_common(struct device *dev, pm_message_t mesg) 5446static void ata_port_resume_async(struct ata_port *ap, pm_message_t mesg)
5456{ 5447{
5457 struct ata_port *ap = to_ata_port(dev); 5448 ata_port_request_pm(ap, mesg, ATA_EH_RESET, ata_port_resume_ehi, true);
5458
5459 return __ata_port_resume_common(ap, mesg, NULL);
5460} 5449}
5461 5450
5462static int ata_port_resume(struct device *dev) 5451static int ata_port_pm_resume(struct device *dev)
5463{ 5452{
5464 int rc; 5453 ata_port_resume(to_ata_port(dev), PMSG_RESUME);
5465 5454 pm_runtime_disable(dev);
5466 rc = ata_port_resume_common(dev, PMSG_RESUME); 5455 pm_runtime_set_active(dev);
5467 if (!rc) { 5456 pm_runtime_enable(dev);
5468 pm_runtime_disable(dev); 5457 return 0;
5469 pm_runtime_set_active(dev);
5470 pm_runtime_enable(dev);
5471 }
5472
5473 return rc;
5474} 5458}
5475 5459
5476/* 5460/*
@@ -5499,21 +5483,23 @@ static int ata_port_runtime_idle(struct device *dev)
5499 5483
5500static int ata_port_runtime_suspend(struct device *dev) 5484static int ata_port_runtime_suspend(struct device *dev)
5501{ 5485{
5502 return ata_port_suspend_common(dev, PMSG_AUTO_SUSPEND); 5486 ata_port_suspend(to_ata_port(dev), PMSG_AUTO_SUSPEND);
5487 return 0;
5503} 5488}
5504 5489
5505static int ata_port_runtime_resume(struct device *dev) 5490static int ata_port_runtime_resume(struct device *dev)
5506{ 5491{
5507 return ata_port_resume_common(dev, PMSG_AUTO_RESUME); 5492 ata_port_resume(to_ata_port(dev), PMSG_AUTO_RESUME);
5493 return 0;
5508} 5494}
5509 5495
5510static const struct dev_pm_ops ata_port_pm_ops = { 5496static const struct dev_pm_ops ata_port_pm_ops = {
5511 .suspend = ata_port_suspend, 5497 .suspend = ata_port_pm_suspend,
5512 .resume = ata_port_resume, 5498 .resume = ata_port_pm_resume,
5513 .freeze = ata_port_do_freeze, 5499 .freeze = ata_port_pm_freeze,
5514 .thaw = ata_port_resume, 5500 .thaw = ata_port_pm_resume,
5515 .poweroff = ata_port_poweroff, 5501 .poweroff = ata_port_pm_poweroff,
5516 .restore = ata_port_resume, 5502 .restore = ata_port_pm_resume,
5517 5503
5518 .runtime_suspend = ata_port_runtime_suspend, 5504 .runtime_suspend = ata_port_runtime_suspend,
5519 .runtime_resume = ata_port_runtime_resume, 5505 .runtime_resume = ata_port_runtime_resume,
@@ -5525,18 +5511,17 @@ static const struct dev_pm_ops ata_port_pm_ops = {
5525 * level. sas suspend/resume is async to allow parallel port recovery 5511 * level. sas suspend/resume is async to allow parallel port recovery
5526 * since sas has multiple ata_port instances per Scsi_Host. 5512 * since sas has multiple ata_port instances per Scsi_Host.
5527 */ 5513 */
5528int ata_sas_port_async_suspend(struct ata_port *ap, int *async) 5514void ata_sas_port_suspend(struct ata_port *ap)
5529{ 5515{
5530 return __ata_port_suspend_common(ap, PMSG_SUSPEND, async); 5516 ata_port_suspend_async(ap, PMSG_SUSPEND);
5531} 5517}
5532EXPORT_SYMBOL_GPL(ata_sas_port_async_suspend); 5518EXPORT_SYMBOL_GPL(ata_sas_port_suspend);
5533 5519
5534int ata_sas_port_async_resume(struct ata_port *ap, int *async) 5520void ata_sas_port_resume(struct ata_port *ap)
5535{ 5521{
5536 return __ata_port_resume_common(ap, PMSG_RESUME, async); 5522 ata_port_resume_async(ap, PMSG_RESUME);
5537} 5523}
5538EXPORT_SYMBOL_GPL(ata_sas_port_async_resume); 5524EXPORT_SYMBOL_GPL(ata_sas_port_resume);
5539
5540 5525
5541/** 5526/**
5542 * ata_host_suspend - suspend host 5527 * ata_host_suspend - suspend host
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index c1d0170a6585..6760fc4e85b8 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -4070,7 +4070,7 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
4070 4070
4071 ata_acpi_set_state(ap, ap->pm_mesg); 4071 ata_acpi_set_state(ap, ap->pm_mesg);
4072 out: 4072 out:
4073 /* report result */ 4073 /* update the flags */
4074 spin_lock_irqsave(ap->lock, flags); 4074 spin_lock_irqsave(ap->lock, flags);
4075 4075
4076 ap->pflags &= ~ATA_PFLAG_PM_PENDING; 4076 ap->pflags &= ~ATA_PFLAG_PM_PENDING;
@@ -4079,11 +4079,6 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
4079 else if (ap->pflags & ATA_PFLAG_FROZEN) 4079 else if (ap->pflags & ATA_PFLAG_FROZEN)
4080 ata_port_schedule_eh(ap); 4080 ata_port_schedule_eh(ap);
4081 4081
4082 if (ap->pm_result) {
4083 *ap->pm_result = rc;
4084 ap->pm_result = NULL;
4085 }
4086
4087 spin_unlock_irqrestore(ap->lock, flags); 4082 spin_unlock_irqrestore(ap->lock, flags);
4088 4083
4089 return; 4084 return;
@@ -4135,13 +4130,9 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
4135 /* tell ACPI that we're resuming */ 4130 /* tell ACPI that we're resuming */
4136 ata_acpi_on_resume(ap); 4131 ata_acpi_on_resume(ap);
4137 4132
4138 /* report result */ 4133 /* update the flags */
4139 spin_lock_irqsave(ap->lock, flags); 4134 spin_lock_irqsave(ap->lock, flags);
4140 ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); 4135 ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
4141 if (ap->pm_result) {
4142 *ap->pm_result = rc;
4143 ap->pm_result = NULL;
4144 }
4145 spin_unlock_irqrestore(ap->lock, flags); 4136 spin_unlock_irqrestore(ap->lock, flags);
4146} 4137}
4147#endif /* CONFIG_PM */ 4138#endif /* CONFIG_PM */
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index d2895836f9fa..766098af4eb7 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -700,46 +700,26 @@ void sas_probe_sata(struct asd_sas_port *port)
700 700
701} 701}
702 702
703static bool sas_ata_flush_pm_eh(struct asd_sas_port *port, const char *func) 703static void sas_ata_flush_pm_eh(struct asd_sas_port *port, const char *func)
704{ 704{
705 struct domain_device *dev, *n; 705 struct domain_device *dev, *n;
706 bool retry = false;
707 706
708 list_for_each_entry_safe(dev, n, &port->dev_list, dev_list_node) { 707 list_for_each_entry_safe(dev, n, &port->dev_list, dev_list_node) {
709 int rc;
710
711 if (!dev_is_sata(dev)) 708 if (!dev_is_sata(dev))
712 continue; 709 continue;
713 710
714 sas_ata_wait_eh(dev); 711 sas_ata_wait_eh(dev);
715 rc = dev->sata_dev.pm_result;
716 if (rc == -EAGAIN)
717 retry = true;
718 else if (rc) {
719 /* since we don't have a
720 * ->port_{suspend|resume} routine in our
721 * ata_port ops, and no entanglements with
722 * acpi, suspend should just be mechanical trip
723 * through eh, catch cases where these
724 * assumptions are invalidated
725 */
726 WARN_ONCE(1, "failed %s %s error: %d\n", func,
727 dev_name(&dev->rphy->dev), rc);
728 }
729 712
730 /* if libata failed to power manage the device, tear it down */ 713 /* if libata failed to power manage the device, tear it down */
731 if (ata_dev_disabled(sas_to_ata_dev(dev))) 714 if (ata_dev_disabled(sas_to_ata_dev(dev)))
732 sas_fail_probe(dev, func, -ENODEV); 715 sas_fail_probe(dev, func, -ENODEV);
733 } 716 }
734
735 return retry;
736} 717}
737 718
738void sas_suspend_sata(struct asd_sas_port *port) 719void sas_suspend_sata(struct asd_sas_port *port)
739{ 720{
740 struct domain_device *dev; 721 struct domain_device *dev;
741 722
742 retry:
743 mutex_lock(&port->ha->disco_mutex); 723 mutex_lock(&port->ha->disco_mutex);
744 list_for_each_entry(dev, &port->dev_list, dev_list_node) { 724 list_for_each_entry(dev, &port->dev_list, dev_list_node) {
745 struct sata_device *sata; 725 struct sata_device *sata;
@@ -751,20 +731,17 @@ void sas_suspend_sata(struct asd_sas_port *port)
751 if (sata->ap->pm_mesg.event == PM_EVENT_SUSPEND) 731 if (sata->ap->pm_mesg.event == PM_EVENT_SUSPEND)
752 continue; 732 continue;
753 733
754 sata->pm_result = -EIO; 734 ata_sas_port_suspend(sata->ap);
755 ata_sas_port_async_suspend(sata->ap, &sata->pm_result);
756 } 735 }
757 mutex_unlock(&port->ha->disco_mutex); 736 mutex_unlock(&port->ha->disco_mutex);
758 737
759 if (sas_ata_flush_pm_eh(port, __func__)) 738 sas_ata_flush_pm_eh(port, __func__);
760 goto retry;
761} 739}
762 740
763void sas_resume_sata(struct asd_sas_port *port) 741void sas_resume_sata(struct asd_sas_port *port)
764{ 742{
765 struct domain_device *dev; 743 struct domain_device *dev;
766 744
767 retry:
768 mutex_lock(&port->ha->disco_mutex); 745 mutex_lock(&port->ha->disco_mutex);
769 list_for_each_entry(dev, &port->dev_list, dev_list_node) { 746 list_for_each_entry(dev, &port->dev_list, dev_list_node) {
770 struct sata_device *sata; 747 struct sata_device *sata;
@@ -776,13 +753,11 @@ void sas_resume_sata(struct asd_sas_port *port)
776 if (sata->ap->pm_mesg.event == PM_EVENT_ON) 753 if (sata->ap->pm_mesg.event == PM_EVENT_ON)
777 continue; 754 continue;
778 755
779 sata->pm_result = -EIO; 756 ata_sas_port_resume(sata->ap);
780 ata_sas_port_async_resume(sata->ap, &sata->pm_result);
781 } 757 }
782 mutex_unlock(&port->ha->disco_mutex); 758 mutex_unlock(&port->ha->disco_mutex);
783 759
784 if (sas_ata_flush_pm_eh(port, __func__)) 760 sas_ata_flush_pm_eh(port, __func__);
785 goto retry;
786} 761}
787 762
788/** 763/**