Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Dan Williams and committed by
Tejun Heo
bc6e7c4b 6a96918a

+85 -138
+74 -89
drivers/ata/libata-core.c
··· 5351 5351 } 5352 5352 5353 5353 #ifdef CONFIG_PM 5354 - static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, 5355 - unsigned int action, unsigned int ehi_flags, 5356 - int *async) 5354 + static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, 5355 + unsigned int action, unsigned int ehi_flags, 5356 + bool async) 5357 5357 { 5358 5358 struct ata_link *link; 5359 5359 unsigned long flags; 5360 - int rc = 0; 5361 5360 5362 5361 /* Previous resume operation might still be in 5363 5362 * progress. Wait for PM_PENDING to clear. 5364 5363 */ 5365 5364 if (ap->pflags & ATA_PFLAG_PM_PENDING) { 5366 - if (async) { 5367 - *async = -EAGAIN; 5368 - return 0; 5369 - } 5370 5365 ata_port_wait_eh(ap); 5371 5366 WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); 5372 5367 } ··· 5370 5375 spin_lock_irqsave(ap->lock, flags); 5371 5376 5372 5377 ap->pm_mesg = mesg; 5373 - if (async) 5374 - ap->pm_result = async; 5375 - else 5376 - ap->pm_result = &rc; 5377 - 5378 5378 ap->pflags |= ATA_PFLAG_PM_PENDING; 5379 5379 ata_for_each_link(link, ap, HOST_FIRST) { 5380 5380 link->eh_info.action |= action; ··· 5380 5390 5381 5391 spin_unlock_irqrestore(ap->lock, flags); 5382 5392 5383 - /* wait and check result */ 5384 5393 if (!async) { 5385 5394 ata_port_wait_eh(ap); 5386 5395 WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); 5387 5396 } 5388 - 5389 - return rc; 5390 5397 } 5391 5398 5392 - static int __ata_port_suspend_common(struct ata_port *ap, pm_message_t mesg, int *async) 5399 + /* 5400 + * On some hardware, device fails to respond after spun down for suspend. As 5401 + * the device won't be used before being resumed, we don't need to touch the 5402 + * device. Ask EH to skip the usual stuff and proceed directly to suspend. 5403 + * 5404 + * http://thread.gmane.org/gmane.linux.ide/46764 5405 + */ 5406 + static const unsigned int ata_port_suspend_ehi = ATA_EHI_QUIET 5407 + | ATA_EHI_NO_AUTOPSY 5408 + | ATA_EHI_NO_RECOVERY; 5409 + 5410 + static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg) 5393 5411 { 5394 - /* 5395 - * On some hardware, device fails to respond after spun down 5396 - * for suspend. As the device won't be used before being 5397 - * resumed, we don't need to touch the device. Ask EH to skip 5398 - * the usual stuff and proceed directly to suspend. 5399 - * 5400 - * http://thread.gmane.org/gmane.linux.ide/46764 5401 - */ 5402 - unsigned int ehi_flags = ATA_EHI_QUIET | ATA_EHI_NO_AUTOPSY | 5403 - ATA_EHI_NO_RECOVERY; 5404 - return ata_port_request_pm(ap, mesg, 0, ehi_flags, async); 5412 + ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false); 5405 5413 } 5406 5414 5407 - static int ata_port_suspend_common(struct device *dev, pm_message_t mesg) 5415 + static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg) 5408 5416 { 5409 - struct ata_port *ap = to_ata_port(dev); 5410 - 5411 - return __ata_port_suspend_common(ap, mesg, NULL); 5417 + ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true); 5412 5418 } 5413 5419 5414 - static int ata_port_suspend(struct device *dev) 5415 - { 5416 - if (pm_runtime_suspended(dev)) 5417 - return 0; 5418 - 5419 - return ata_port_suspend_common(dev, PMSG_SUSPEND); 5420 - } 5421 - 5422 - static int ata_port_do_freeze(struct device *dev) 5423 - { 5424 - if (pm_runtime_suspended(dev)) 5425 - return 0; 5426 - 5427 - return ata_port_suspend_common(dev, PMSG_FREEZE); 5428 - } 5429 - 5430 - static int ata_port_poweroff(struct device *dev) 5431 - { 5432 - return ata_port_suspend_common(dev, PMSG_HIBERNATE); 5433 - } 5434 - 5435 - static int __ata_port_resume_common(struct ata_port *ap, pm_message_t mesg, 5436 - int *async) 5437 - { 5438 - int rc; 5439 - 5440 - rc = ata_port_request_pm(ap, mesg, ATA_EH_RESET, 5441 - ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, async); 5442 - return rc; 5443 - } 5444 - 5445 - static int ata_port_resume_common(struct device *dev, pm_message_t mesg) 5420 + static int ata_port_pm_suspend(struct device *dev) 5446 5421 { 5447 5422 struct ata_port *ap = to_ata_port(dev); 5448 5423 5449 - return __ata_port_resume_common(ap, mesg, NULL); 5424 + if (pm_runtime_suspended(dev)) 5425 + return 0; 5426 + 5427 + ata_port_suspend(ap, PMSG_SUSPEND); 5428 + return 0; 5450 5429 } 5451 5430 5452 - static int ata_port_resume(struct device *dev) 5431 + static int ata_port_pm_freeze(struct device *dev) 5453 5432 { 5454 - int rc; 5433 + struct ata_port *ap = to_ata_port(dev); 5455 5434 5456 - rc = ata_port_resume_common(dev, PMSG_RESUME); 5457 - if (!rc) { 5458 - pm_runtime_disable(dev); 5459 - pm_runtime_set_active(dev); 5460 - pm_runtime_enable(dev); 5461 - } 5435 + if (pm_runtime_suspended(dev)) 5436 + return 0; 5462 5437 5463 - return rc; 5438 + ata_port_suspend(ap, PMSG_FREEZE); 5439 + return 0; 5440 + } 5441 + 5442 + static int ata_port_pm_poweroff(struct device *dev) 5443 + { 5444 + ata_port_suspend(to_ata_port(dev), PMSG_HIBERNATE); 5445 + return 0; 5446 + } 5447 + 5448 + static const unsigned int ata_port_resume_ehi = ATA_EHI_NO_AUTOPSY 5449 + | ATA_EHI_QUIET; 5450 + 5451 + static void ata_port_resume(struct ata_port *ap, pm_message_t mesg) 5452 + { 5453 + ata_port_request_pm(ap, mesg, ATA_EH_RESET, ata_port_resume_ehi, false); 5454 + } 5455 + 5456 + static void ata_port_resume_async(struct ata_port *ap, pm_message_t mesg) 5457 + { 5458 + ata_port_request_pm(ap, mesg, ATA_EH_RESET, ata_port_resume_ehi, true); 5459 + } 5460 + 5461 + static int ata_port_pm_resume(struct device *dev) 5462 + { 5463 + ata_port_resume(to_ata_port(dev), PMSG_RESUME); 5464 + pm_runtime_disable(dev); 5465 + pm_runtime_set_active(dev); 5466 + pm_runtime_enable(dev); 5467 + return 0; 5464 5468 } 5465 5469 5466 5470 /* ··· 5483 5499 5484 5500 static int ata_port_runtime_suspend(struct device *dev) 5485 5501 { 5486 - return ata_port_suspend_common(dev, PMSG_AUTO_SUSPEND); 5502 + ata_port_suspend(to_ata_port(dev), PMSG_AUTO_SUSPEND); 5503 + return 0; 5487 5504 } 5488 5505 5489 5506 static int ata_port_runtime_resume(struct device *dev) 5490 5507 { 5491 - return ata_port_resume_common(dev, PMSG_AUTO_RESUME); 5508 + ata_port_resume(to_ata_port(dev), PMSG_AUTO_RESUME); 5509 + return 0; 5492 5510 } 5493 5511 5494 5512 static const struct dev_pm_ops ata_port_pm_ops = { 5495 - .suspend = ata_port_suspend, 5496 - .resume = ata_port_resume, 5497 - .freeze = ata_port_do_freeze, 5498 - .thaw = ata_port_resume, 5499 - .poweroff = ata_port_poweroff, 5500 - .restore = ata_port_resume, 5513 + .suspend = ata_port_pm_suspend, 5514 + .resume = ata_port_pm_resume, 5515 + .freeze = ata_port_pm_freeze, 5516 + .thaw = ata_port_pm_resume, 5517 + .poweroff = ata_port_pm_poweroff, 5518 + .restore = ata_port_pm_resume, 5501 5519 5502 5520 .runtime_suspend = ata_port_runtime_suspend, 5503 5521 .runtime_resume = ata_port_runtime_resume, ··· 5511 5525 * level. sas suspend/resume is async to allow parallel port recovery 5512 5526 * since sas has multiple ata_port instances per Scsi_Host. 5513 5527 */ 5514 - int ata_sas_port_async_suspend(struct ata_port *ap, int *async) 5528 + void ata_sas_port_suspend(struct ata_port *ap) 5515 5529 { 5516 - return __ata_port_suspend_common(ap, PMSG_SUSPEND, async); 5530 + ata_port_suspend_async(ap, PMSG_SUSPEND); 5517 5531 } 5518 - EXPORT_SYMBOL_GPL(ata_sas_port_async_suspend); 5532 + EXPORT_SYMBOL_GPL(ata_sas_port_suspend); 5519 5533 5520 - int ata_sas_port_async_resume(struct ata_port *ap, int *async) 5534 + void ata_sas_port_resume(struct ata_port *ap) 5521 5535 { 5522 - return __ata_port_resume_common(ap, PMSG_RESUME, async); 5536 + ata_port_resume_async(ap, PMSG_RESUME); 5523 5537 } 5524 - EXPORT_SYMBOL_GPL(ata_sas_port_async_resume); 5525 - 5538 + EXPORT_SYMBOL_GPL(ata_sas_port_resume); 5526 5539 5527 5540 /** 5528 5541 * ata_host_suspend - suspend host
+2 -11
drivers/ata/libata-eh.c
··· 4070 4070 4071 4071 ata_acpi_set_state(ap, ap->pm_mesg); 4072 4072 out: 4073 - /* report result */ 4073 + /* update the flags */ 4074 4074 spin_lock_irqsave(ap->lock, flags); 4075 4075 4076 4076 ap->pflags &= ~ATA_PFLAG_PM_PENDING; ··· 4078 4078 ap->pflags |= ATA_PFLAG_SUSPENDED; 4079 4079 else if (ap->pflags & ATA_PFLAG_FROZEN) 4080 4080 ata_port_schedule_eh(ap); 4081 - 4082 - if (ap->pm_result) { 4083 - *ap->pm_result = rc; 4084 - ap->pm_result = NULL; 4085 - } 4086 4081 4087 4082 spin_unlock_irqrestore(ap->lock, flags); 4088 4083 ··· 4130 4135 /* tell ACPI that we're resuming */ 4131 4136 ata_acpi_on_resume(ap); 4132 4137 4133 - /* report result */ 4138 + /* update the flags */ 4134 4139 spin_lock_irqsave(ap->lock, flags); 4135 4140 ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); 4136 - if (ap->pm_result) { 4137 - *ap->pm_result = rc; 4138 - ap->pm_result = NULL; 4139 - } 4140 4141 spin_unlock_irqrestore(ap->lock, flags); 4141 4142 } 4142 4143 #endif /* CONFIG_PM */
+5 -30
drivers/scsi/libsas/sas_ata.c
··· 700 700 701 701 } 702 702 703 - static bool sas_ata_flush_pm_eh(struct asd_sas_port *port, const char *func) 703 + static void sas_ata_flush_pm_eh(struct asd_sas_port *port, const char *func) 704 704 { 705 705 struct domain_device *dev, *n; 706 - bool retry = false; 707 706 708 707 list_for_each_entry_safe(dev, n, &port->dev_list, dev_list_node) { 709 - int rc; 710 - 711 708 if (!dev_is_sata(dev)) 712 709 continue; 713 710 714 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 713 /* if libata failed to power manage the device, tear it down */ 731 714 if (ata_dev_disabled(sas_to_ata_dev(dev))) 732 715 sas_fail_probe(dev, func, -ENODEV); 733 716 } 734 - 735 - return retry; 736 717 } 737 718 738 719 void sas_suspend_sata(struct asd_sas_port *port) 739 720 { 740 721 struct domain_device *dev; 741 722 742 - retry: 743 723 mutex_lock(&port->ha->disco_mutex); 744 724 list_for_each_entry(dev, &port->dev_list, dev_list_node) { 745 725 struct sata_device *sata; ··· 731 751 if (sata->ap->pm_mesg.event == PM_EVENT_SUSPEND) 732 752 continue; 733 753 734 - sata->pm_result = -EIO; 735 - ata_sas_port_async_suspend(sata->ap, &sata->pm_result); 754 + ata_sas_port_suspend(sata->ap); 736 755 } 737 756 mutex_unlock(&port->ha->disco_mutex); 738 757 739 - if (sas_ata_flush_pm_eh(port, __func__)) 740 - goto retry; 758 + sas_ata_flush_pm_eh(port, __func__); 741 759 } 742 760 743 761 void sas_resume_sata(struct asd_sas_port *port) 744 762 { 745 763 struct domain_device *dev; 746 764 747 - retry: 748 765 mutex_lock(&port->ha->disco_mutex); 749 766 list_for_each_entry(dev, &port->dev_list, dev_list_node) { 750 767 struct sata_device *sata; ··· 753 776 if (sata->ap->pm_mesg.event == PM_EVENT_ON) 754 777 continue; 755 778 756 - sata->pm_result = -EIO; 757 - ata_sas_port_async_resume(sata->ap, &sata->pm_result); 779 + ata_sas_port_resume(sata->ap); 758 780 } 759 781 mutex_unlock(&port->ha->disco_mutex); 760 782 761 - if (sas_ata_flush_pm_eh(port, __func__)) 762 - goto retry; 783 + sas_ata_flush_pm_eh(port, __func__); 763 784 } 764 785 765 786 /**
+4 -7
include/linux/libata.h
··· 848 848 struct completion park_req_pending; 849 849 850 850 pm_message_t pm_mesg; 851 - int *pm_result; 852 851 enum ata_lpm_policy target_lpm_policy; 853 852 854 853 struct timer_list fastdrain_timer; ··· 1139 1140 #ifdef CONFIG_PM 1140 1141 extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); 1141 1142 extern void ata_host_resume(struct ata_host *host); 1142 - extern int ata_sas_port_async_suspend(struct ata_port *ap, int *async); 1143 - extern int ata_sas_port_async_resume(struct ata_port *ap, int *async); 1143 + extern void ata_sas_port_suspend(struct ata_port *ap); 1144 + extern void ata_sas_port_resume(struct ata_port *ap); 1144 1145 #else 1145 - static inline int ata_sas_port_async_suspend(struct ata_port *ap, int *async) 1146 + static inline void ata_sas_port_suspend(struct ata_port *ap) 1146 1147 { 1147 - return 0; 1148 1148 } 1149 - static inline int ata_sas_port_async_resume(struct ata_port *ap, int *async) 1149 + static inline void ata_sas_port_async_resume(struct ata_port *ap) 1150 1150 { 1151 - return 0; 1152 1151 } 1153 1152 #endif 1154 1153 extern int ata_ratelimit(void);
-1
include/scsi/libsas.h
··· 172 172 enum ata_command_set command_set; 173 173 struct smp_resp rps_resp; /* report_phy_sata_resp */ 174 174 u8 port_no; /* port number, if this is a PM (Port) */ 175 - int pm_result; 176 175 177 176 struct ata_port *ap; 178 177 struct ata_host ata_host;