From: Jie Zhan zhanjie9@hisilicon.com
mainline inclusion from mainline-v6.2-rc1 commit 9181ce3cb5d9 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I6V6I1
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
----------------------------------------------------------------------
Create function smp_ata_check_ready_type() for LLDDs to wait for SATA devices to come up after a link reset.
Signed-off-by: Jie Zhan zhanjie9@hisilicon.com Link: https://lore.kernel.org/r/20221118083714.4034612-4-zhanjie9@hisilicon.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: xiabing xiabing12@h-partners.com Signed-off-by: Li Nan linan122@huawei.com --- drivers/scsi/libsas/sas_internal.h | 2 ++ include/scsi/sas_ata.h | 6 ++++++ drivers/scsi/libsas/sas_ata.c | 25 +++++++++++++++++++++++++ drivers/scsi/libsas/sas_expander.c | 4 ++-- 4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index acd515c01861..18749b2a6502 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -86,6 +86,8 @@ struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id); int sas_ex_phy_discover(struct domain_device *dev, int single); int sas_get_report_phy_sata(struct domain_device *dev, int phy_id, struct smp_resp *rps_resp); +int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id, + u8 *sas_addr, enum sas_device_type *type); int sas_try_ata_reset(struct asd_sas_phy *phy); void sas_hae_reset(struct work_struct *work);
diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h index e0d2d4915257..74e8feea85b4 100644 --- a/include/scsi/sas_ata.h +++ b/include/scsi/sas_ata.h @@ -34,6 +34,7 @@ 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); +int smp_ata_check_ready_type(struct ata_link *link); #else
@@ -92,6 +93,11 @@ static inline int sas_ata_wait_after_reset(struct domain_device *dev, { return -ETIMEDOUT; } + +static inline int smp_ata_check_ready_type(struct ata_link *link) +{ + return 0; +} #endif
#endif /* _SAS_ATA_H_ */ diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index d54f91636ad1..ff09e0ff00d2 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -301,6 +301,31 @@ static int sas_ata_clear_pending(struct domain_device *dev, struct ex_phy *phy) return 1; }
+int smp_ata_check_ready_type(struct ata_link *link) +{ + struct domain_device *dev = link->ap->private_data; + struct sas_phy *phy = sas_get_local_phy(dev); + struct domain_device *ex_dev = dev->parent; + enum sas_device_type type = SAS_PHY_UNUSED; + u8 sas_addr[SAS_ADDR_SIZE]; + int res; + + res = sas_get_phy_attached_dev(ex_dev, phy->number, sas_addr, &type); + sas_put_local_phy(phy); + if (res) + return res; + + switch (type) { + case SAS_SATA_PENDING: + return 0; + case SAS_END_DEVICE: + return 1; + default: + return -ENODEV; + } +} +EXPORT_SYMBOL_GPL(smp_ata_check_ready_type); + static int smp_ata_check_ready(struct ata_link *link) { int res; diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index dd22c7a32059..2287f8e07968 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -1727,8 +1727,8 @@ static int sas_get_phy_change_count(struct domain_device *dev, return res; }
-static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id, - u8 *sas_addr, enum sas_device_type *type) +int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id, + u8 *sas_addr, enum sas_device_type *type) { int res; struct smp_disc_resp *disc_resp;