Factor out sas_ata_add_dev() and put it in sas_ata.c since it is a sata related interface. Also follow the standard coding style to define an inline empty function when CONFIG_SCSI_SAS_ATA is not enabled. Cc: John Garry <john.g.garry@xxxxxxxxxx> Signed-off-by: Jason Yan <yanaijie@xxxxxxxxxx> Reviewed-by: John Garry <john.g.garry@xxxxxxxxxx> --- drivers/scsi/libsas/sas_ata.c | 62 ++++++++++++++++++++++++++++++ drivers/scsi/libsas/sas_expander.c | 54 +------------------------- include/scsi/sas_ata.h | 9 +++++ 3 files changed, 73 insertions(+), 52 deletions(-) diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index de3439ae358d..13fbb8629057 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -675,6 +675,68 @@ void sas_probe_sata(struct asd_sas_port *port) } +int sas_ata_add_dev(struct domain_device *parent, struct ex_phy *phy, + struct domain_device *child, int phy_id) +{ + struct sas_rphy *rphy; + int ret; + + if (child->linkrate > parent->min_linkrate) { + struct sas_phy *cphy = child->phy; + enum sas_linkrate min_prate = cphy->minimum_linkrate, + parent_min_lrate = parent->min_linkrate, + min_linkrate = (min_prate > parent_min_lrate) ? + parent_min_lrate : 0; + struct sas_phy_linkrates rates = { + .maximum_linkrate = parent->min_linkrate, + .minimum_linkrate = min_linkrate, + }; + + pr_notice("ex %016llx phy%02d SATA device linkrate > min pathway connection rate, attempting to lower device linkrate\n", + SAS_ADDR(child->sas_addr), phy_id); + ret = sas_smp_phy_control(parent, phy_id, + PHY_FUNC_LINK_RESET, &rates); + if (ret) { + pr_err("ex %016llx phy%02d SATA device could not set linkrate (%d)\n", + SAS_ADDR(child->sas_addr), phy_id, ret); + return ret; + } + pr_notice("ex %016llx phy%02d SATA device set linkrate successfully\n", + SAS_ADDR(child->sas_addr), phy_id); + child->linkrate = child->min_linkrate; + } + ret = sas_get_ata_info(child, phy); + if (ret) + return ret; + + sas_init_dev(child); + ret = sas_ata_init(child); + if (ret) + return ret; + + rphy = sas_end_device_alloc(phy->port); + if (!rphy) + return ret; + + rphy->identify.phy_identifier = phy_id; + child->rphy = rphy; + get_device(&rphy->dev); + + list_add_tail(&child->disco_list_node, &parent->port->disco_list); + + ret = sas_discover_sata(child); + if (ret) { + pr_notice("sas_discover_sata() for device %16llx at %016llx:%02d returned 0x%x\n", + SAS_ADDR(child->sas_addr), + SAS_ADDR(parent->sas_addr), phy_id, ret); + sas_rphy_free(child->rphy); + list_del(&child->disco_list_node); + return ret; + } + + return 0; +} + static void sas_ata_flush_pm_eh(struct asd_sas_port *port, const char *func) { struct domain_device *dev, *n; diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 29e1b93b0964..0e4e09a0286a 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -785,61 +785,11 @@ static struct domain_device *sas_ex_discover_end_dev( sas_ex_get_linkrate(parent, child, phy); sas_device_set_phy(child, phy->port); -#ifdef CONFIG_SCSI_SAS_ATA if ((phy->attached_tproto & SAS_PROTOCOL_STP) || phy->attached_sata_dev) { - if (child->linkrate > parent->min_linkrate) { - struct sas_phy *cphy = child->phy; - enum sas_linkrate min_prate = cphy->minimum_linkrate, - parent_min_lrate = parent->min_linkrate, - min_linkrate = (min_prate > parent_min_lrate) ? - parent_min_lrate : 0; - struct sas_phy_linkrates rates = { - .maximum_linkrate = parent->min_linkrate, - .minimum_linkrate = min_linkrate, - }; - int ret; - - pr_notice("ex %016llx phy%02d SATA device linkrate > min pathway connection rate, attempting to lower device linkrate\n", - SAS_ADDR(child->sas_addr), phy_id); - ret = sas_smp_phy_control(parent, phy_id, - PHY_FUNC_LINK_RESET, &rates); - if (ret) { - pr_err("ex %016llx phy%02d SATA device could not set linkrate (%d)\n", - SAS_ADDR(child->sas_addr), phy_id, ret); - goto out_free; - } - pr_notice("ex %016llx phy%02d SATA device set linkrate successfully\n", - SAS_ADDR(child->sas_addr), phy_id); - child->linkrate = child->min_linkrate; - } - res = sas_get_ata_info(child, phy); - if (res) - goto out_free; - - sas_init_dev(child); - res = sas_ata_init(child); + res = sas_ata_add_dev(parent, phy, child, phy_id); if (res) goto out_free; - rphy = sas_end_device_alloc(phy->port); - if (!rphy) - goto out_free; - rphy->identify.phy_identifier = phy_id; - - child->rphy = rphy; - get_device(&rphy->dev); - - list_add_tail(&child->disco_list_node, &parent->port->disco_list); - - res = sas_discover_sata(child); - if (res) { - pr_notice("sas_discover_sata() for device %16llx at %016llx:%02d returned 0x%x\n", - SAS_ADDR(child->sas_addr), - SAS_ADDR(parent->sas_addr), phy_id, res); - goto out_list_del; - } - } else -#endif - if (phy->attached_tproto & SAS_PROTOCOL_SSP) { + } else if (phy->attached_tproto & SAS_PROTOCOL_SSP) { child->dev_type = SAS_END_DEVICE; rphy = sas_end_device_alloc(phy->port); /* FIXME: error handling */ diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h index 606b4496ecaf..2f8c719840a6 100644 --- a/include/scsi/sas_ata.h +++ b/include/scsi/sas_ata.h @@ -37,6 +37,8 @@ int sas_execute_ata_cmd(struct domain_device *device, u8 *fis, int force_phy_id); int smp_ata_check_ready_type(struct ata_link *link); int sas_discover_sata(struct domain_device *dev); +int sas_ata_add_dev(struct domain_device *parent, struct ex_phy *phy, + struct domain_device *child, int phy_id); #else static inline void sas_ata_disabled_notice(void) @@ -114,6 +116,13 @@ static inline int sas_discover_sata(struct domain_device *dev) sas_ata_disabled_notice(); return -ENXIO; } + +static inline int sas_ata_add_dev(struct domain_device *parent, struct ex_phy *phy, + struct domain_device *child, int phy_id) +{ + sas_ata_disabled_notice(); + return -ENODEV; +} #endif #endif /* _SAS_ATA_H_ */ -- 2.31.1