From: John Garry john.garry@huawei.com
mainline inclusion from mainline-v5.19-rc1 commit 057e5fc03369 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5WRGD CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
----------------------------------------------------------------------
Create function sas_ata_wait_after_reset() from sas_ata_hard_reset() as some LLDDs may want to check for a remote ATA phy is up after reset.
Link: https://lore.kernel.org/r/1652354134-171343-2-git-send-email-john.garry@huaw... Tested-by: Yihang Li liyihang6@hisilicon.com Reviewed-by: Xiang Chen chenxiang66@hisilicon.com Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: xiabing xiabing12@h-partners.com Reviewed-by: Jason Yan yanaijie@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/scsi/libsas/sas_ata.c | 41 +++++++++++++++++++++++------------ include/scsi/sas_ata.h | 7 ++++++ 2 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index f92b889369c3..d54f91636ad1 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -372,22 +372,14 @@ static int sas_ata_printk(const char *level, const struct domain_device *ddev, return r; }
-static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, - unsigned long deadline) +int sas_ata_wait_after_reset(struct domain_device *dev, unsigned long deadline) { - int ret = 0, res; - struct sas_phy *phy; - struct ata_port *ap = link->ap; + struct sata_device *sata_dev = &dev->sata_dev; int (*check_ready)(struct ata_link *link); - struct domain_device *dev = ap->private_data; - struct sas_internal *i = dev_to_sas_internal(dev); - - res = i->dft->lldd_I_T_nexus_reset(dev); - if (res == -ENODEV) - return res; - - if (res != TMF_RESP_FUNC_COMPLETE) - sas_ata_printk(KERN_DEBUG, dev, "Unable to reset ata device?\n"); + struct ata_port *ap = sata_dev->ap; + struct ata_link *link = &ap->link; + struct sas_phy *phy; + int ret;
phy = sas_get_local_phy(dev); if (scsi_is_sas_phy_local(phy)) @@ -400,6 +392,27 @@ static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, if (ret && ret != -EAGAIN) sas_ata_printk(KERN_ERR, dev, "reset failed (errno=%d)\n", ret);
+ return ret; +} +EXPORT_SYMBOL_GPL(sas_ata_wait_after_reset); + +static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, + unsigned long deadline) +{ + struct ata_port *ap = link->ap; + struct domain_device *dev = ap->private_data; + struct sas_internal *i = dev_to_sas_internal(dev); + int ret; + + ret = i->dft->lldd_I_T_nexus_reset(dev); + if (ret == -ENODEV) + return ret; + + if (ret != TMF_RESP_FUNC_COMPLETE) + sas_ata_printk(KERN_DEBUG, dev, "Unable to reset ata device?\n"); + + ret = sas_ata_wait_after_reset(dev, deadline); + *class = dev->sata_dev.class;
ap->cbl = ATA_CBL_SATA; diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h index 416c9c47d0e7..e0d2d4915257 100644 --- a/include/scsi/sas_ata.h +++ b/include/scsi/sas_ata.h @@ -33,6 +33,7 @@ void sas_probe_sata(struct asd_sas_port *port); void sas_suspend_sata(struct asd_sas_port *port); void sas_resume_sata(struct asd_sas_port *port); void sas_ata_end_eh(struct ata_port *ap); +int sas_ata_wait_after_reset(struct domain_device *dev, unsigned long deadline); #else
@@ -85,6 +86,12 @@ static inline int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy static inline void sas_ata_end_eh(struct ata_port *ap) { } + +static inline int sas_ata_wait_after_reset(struct domain_device *dev, + unsigned long deadline) +{ + return -ETIMEDOUT; +} #endif
#endif /* _SAS_ATA_H_ */