diff options
author | Dan Williams <dan.j.williams@intel.com> | 2012-06-22 02:36:20 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-07-20 03:58:53 -0400 |
commit | b17caa174a7e1fd2e17b26e210d4ee91c4c28b37 (patch) | |
tree | 5ecdb47d968389d9386e5e5c96fe647a8bb04e7b /drivers/scsi/libsas | |
parent | 26f2f199ff150d8876b2641c41e60d1c92d2fb81 (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.c | 39 |
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 */ |
871 | static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) | 871 | static 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 | ||
894 | static struct domain_device *sas_ex_discover_expander( | 894 | 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) | |||
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 | } |
1981 | out: | ||
1982 | return res; | 1967 | return res; |
1983 | } | 1968 | } |
1984 | 1969 | ||