[SCSI] libsas: fix sas_discover_devices return code handling
commit198439e4
[SCSI] libsas: do not set res = 0 in sas_ex_discover_dev() commit19252de6
[SCSI] libsas: fix wide port hotplug issues The above commits seem to have confused the return value of sas_ex_discover_dev which is non-zero on failure and sas_ex_join_wide_port which just indicates short circuiting discovery on already established ports. The result is random discovery failures depending on configuration. Calls to sas_ex_join_wide_port are the source of the trouble as its return value is errantly assigned to 'res'. Convert it to bool and stop returning its result up the stack. Cc: <stable@vger.kernel.org> Tested-by: Dan Melnic <dan.melnic@amd.com> Reported-by: Dan Melnic <dan.melnic@amd.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Reviewed-by: Jack Wang <jack_wang@usish.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
committed by
James Bottomley
parent
26f2f199ff
commit
b17caa174a
@@ -868,7 +868,7 @@ static struct domain_device *sas_ex_discover_end_dev(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* See if this phy is part of a wide port */
|
/* See if this phy is part of a wide port */
|
||||||
static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
|
static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
|
||||||
{
|
{
|
||||||
struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
|
struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
|
||||||
int i;
|
int i;
|
||||||
@@ -884,11 +884,11 @@ static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
|
|||||||
sas_port_add_phy(ephy->port, phy->phy);
|
sas_port_add_phy(ephy->port, phy->phy);
|
||||||
phy->port = ephy->port;
|
phy->port = ephy->port;
|
||||||
phy->phy_state = PHY_DEVICE_DISCOVERED;
|
phy->phy_state = PHY_DEVICE_DISCOVERED;
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -ENODEV;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct domain_device *sas_ex_discover_expander(
|
static struct domain_device *sas_ex_discover_expander(
|
||||||
@@ -1030,8 +1030,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = sas_ex_join_wide_port(dev, phy_id);
|
if (sas_ex_join_wide_port(dev, phy_id)) {
|
||||||
if (!res) {
|
|
||||||
SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
|
SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
|
||||||
phy_id, SAS_ADDR(ex_phy->attached_sas_addr));
|
phy_id, SAS_ADDR(ex_phy->attached_sas_addr));
|
||||||
return res;
|
return res;
|
||||||
@@ -1077,8 +1076,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
|
|||||||
if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) ==
|
if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) ==
|
||||||
SAS_ADDR(child->sas_addr)) {
|
SAS_ADDR(child->sas_addr)) {
|
||||||
ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED;
|
ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED;
|
||||||
res = sas_ex_join_wide_port(dev, i);
|
if (sas_ex_join_wide_port(dev, i))
|
||||||
if (!res)
|
|
||||||
SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
|
SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
|
||||||
i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr));
|
i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr));
|
||||||
|
|
||||||
@@ -1943,32 +1941,20 @@ static int sas_discover_new(struct domain_device *dev, int phy_id)
|
|||||||
{
|
{
|
||||||
struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id];
|
struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id];
|
||||||
struct domain_device *child;
|
struct domain_device *child;
|
||||||
bool found = false;
|
int res;
|
||||||
int res, i;
|
|
||||||
|
|
||||||
SAS_DPRINTK("ex %016llx phy%d new device attached\n",
|
SAS_DPRINTK("ex %016llx phy%d new device attached\n",
|
||||||
SAS_ADDR(dev->sas_addr), phy_id);
|
SAS_ADDR(dev->sas_addr), phy_id);
|
||||||
res = sas_ex_phy_discover(dev, phy_id);
|
res = sas_ex_phy_discover(dev, phy_id);
|
||||||
if (res)
|
if (res)
|
||||||
goto out;
|
return res;
|
||||||
/* to support the wide port inserted */
|
|
||||||
for (i = 0; i < dev->ex_dev.num_phys; i++) {
|
if (sas_ex_join_wide_port(dev, phy_id))
|
||||||
struct ex_phy *ex_phy_temp = &dev->ex_dev.ex_phy[i];
|
|
||||||
if (i == phy_id)
|
|
||||||
continue;
|
|
||||||
if (SAS_ADDR(ex_phy_temp->attached_sas_addr) ==
|
|
||||||
SAS_ADDR(ex_phy->attached_sas_addr)) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found) {
|
|
||||||
sas_ex_join_wide_port(dev, phy_id);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
res = sas_ex_discover_devices(dev, phy_id);
|
res = sas_ex_discover_devices(dev, phy_id);
|
||||||
if (!res)
|
if (res)
|
||||||
goto out;
|
return res;
|
||||||
list_for_each_entry(child, &dev->ex_dev.children, siblings) {
|
list_for_each_entry(child, &dev->ex_dev.children, siblings) {
|
||||||
if (SAS_ADDR(child->sas_addr) ==
|
if (SAS_ADDR(child->sas_addr) ==
|
||||||
SAS_ADDR(ex_phy->attached_sas_addr)) {
|
SAS_ADDR(ex_phy->attached_sas_addr)) {
|
||||||
@@ -1978,7 +1964,6 @@ static int sas_discover_new(struct domain_device *dev, int phy_id)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user