Commit 7cc7646b authored by Jason Yan's avatar Jason Yan Committed by Martin K. Petersen

scsi: libsas: Factor out sas_ata_add_dev()

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@oracle.com>
Signed-off-by: default avatarJason Yan <yanaijie@huawei.com>
Reviewed-by: default avatarJohn Garry <john.g.garry@oracle.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 8d2c9d25
......@@ -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;
......
......@@ -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 */
......
......@@ -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_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment