aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2012-06-22 02:36:20 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-07-20 03:58:53 -0400
commitb17caa174a7e1fd2e17b26e210d4ee91c4c28b37 (patch)
tree5ecdb47d968389d9386e5e5c96fe647a8bb04e7b /drivers/scsi/libsas
parent26f2f199ff150d8876b2641c41e60d1c92d2fb81 (diff)
[SCSI] libsas: fix sas_discover_devices return code handling
commit 198439e4 [SCSI] libsas: do not set res = 0 in sas_ex_discover_dev() commit 19252de6 [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>
Diffstat (limited to 'drivers/scsi/libsas')
-rw-r--r--drivers/scsi/libsas/sas_expander.c39
1 files changed, 12 insertions, 27 deletions
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 63c574227ebf..879dbbe69799 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -868,7 +868,7 @@ static struct domain_device *sas_ex_discover_end_dev(
868} 868}
869 869
870/* See if this phy is part of a wide port */ 870/* See if this phy is part of a wide port */
871static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) 871static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
872{ 872{
873 struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id]; 873 struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
874 int i; 874 int i;
@@ -884,11 +884,11 @@ static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
884 sas_port_add_phy(ephy->port, phy->phy); 884 sas_port_add_phy(ephy->port, phy->phy);
885 phy->port = ephy->port; 885 phy->port = ephy->port;
886 phy->phy_state = PHY_DEVICE_DISCOVERED; 886 phy->phy_state = PHY_DEVICE_DISCOVERED;
887 return 0; 887 return true;
888 } 888 }
889 } 889 }
890 890
891 return -ENODEV; 891 return false;
892} 892}
893 893
894static struct domain_device *sas_ex_discover_expander( 894static struct domain_device *sas_ex_discover_expander(
@@ -1030,8 +1030,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
1030 return res; 1030 return res;
1031 } 1031 }
1032 1032
1033 res = sas_ex_join_wide_port(dev, phy_id); 1033 if (sas_ex_join_wide_port(dev, phy_id)) {
1034 if (!res) {
1035 SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", 1034 SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
1036 phy_id, SAS_ADDR(ex_phy->attached_sas_addr)); 1035 phy_id, SAS_ADDR(ex_phy->attached_sas_addr));
1037 return res; 1036 return res;
@@ -1077,8 +1076,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
1077 if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) == 1076 if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) ==
1078 SAS_ADDR(child->sas_addr)) { 1077 SAS_ADDR(child->sas_addr)) {
1079 ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED; 1078 ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED;
1080 res = sas_ex_join_wide_port(dev, i); 1079 if (sas_ex_join_wide_port(dev, i))
1081 if (!res)
1082 SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", 1080 SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
1083 i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr)); 1081 i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr));
1084 1082
@@ -1943,32 +1941,20 @@ static int sas_discover_new(struct domain_device *dev, int phy_id)
1943{ 1941{
1944 struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id]; 1942 struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id];
1945 struct domain_device *child; 1943 struct domain_device *child;
1946 bool found = false; 1944 int res;
1947 int res, i;
1948 1945
1949 SAS_DPRINTK("ex %016llx phy%d new device attached\n", 1946 SAS_DPRINTK("ex %016llx phy%d new device attached\n",
1950 SAS_ADDR(dev->sas_addr), phy_id); 1947 SAS_ADDR(dev->sas_addr), phy_id);
1951 res = sas_ex_phy_discover(dev, phy_id); 1948 res = sas_ex_phy_discover(dev, phy_id);
1952 if (res) 1949 if (res)
1953 goto out; 1950 return res;
1954 /* to support the wide port inserted */ 1951
1955 for (i = 0; i < dev->ex_dev.num_phys; i++) { 1952 if (sas_ex_join_wide_port(dev, phy_id))
1956 struct ex_phy *ex_phy_temp = &dev->ex_dev.ex_phy[i];
1957 if (i == phy_id)
1958 continue;
1959 if (SAS_ADDR(ex_phy_temp->attached_sas_addr) ==
1960 SAS_ADDR(ex_phy->attached_sas_addr)) {
1961 found = true;
1962 break;
1963 }
1964 }
1965 if (found) {
1966 sas_ex_join_wide_port(dev, phy_id);
1967 return 0; 1953 return 0;
1968 } 1954
1969 res = sas_ex_discover_devices(dev, phy_id); 1955 res = sas_ex_discover_devices(dev, phy_id);
1970 if (!res) 1956 if (res)
1971 goto out; 1957 return res;
1972 list_for_each_entry(child, &dev->ex_dev.children, siblings) { 1958 list_for_each_entry(child, &dev->ex_dev.children, siblings) {
1973 if (SAS_ADDR(child->sas_addr) == 1959 if (SAS_ADDR(child->sas_addr) ==
1974 SAS_ADDR(ex_phy->attached_sas_addr)) { 1960 SAS_ADDR(ex_phy->attached_sas_addr)) {
@@ -1978,7 +1964,6 @@ static int sas_discover_new(struct domain_device *dev, int phy_id)
1978 break; 1964 break;
1979 } 1965 }
1980 } 1966 }
1981out:
1982 return res; 1967 return res;
1983} 1968}
1984 1969