diff options
author | Dan Williams <dan.j.williams@intel.com> | 2012-06-22 02:36:20 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-08-09 11:27:34 -0400 |
commit | 3f67ec4b517d985ac6961a1a03f91339e62657c0 (patch) | |
tree | 1305d7aed880c49dd1ccf35fac67faf230c714a4 | |
parent | 2da74cd8a6bad64d02207396c76d0939f3c57aaa (diff) |
SCSI: libsas: fix sas_discover_devices return code handling
commit b17caa174a7e1fd2e17b26e210d4ee91c4c28b37 upstream.
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.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 e8ebe688326..d2f95761ba3 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -770,7 +770,7 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
770 | } | 770 | } |
771 | 771 | ||
772 | /* See if this phy is part of a wide port */ | 772 | /* See if this phy is part of a wide port */ |
773 | static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) | 773 | static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id) |
774 | { | 774 | { |
775 | struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id]; | 775 | struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id]; |
776 | int i; | 776 | int i; |
@@ -786,11 +786,11 @@ static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) | |||
786 | sas_port_add_phy(ephy->port, phy->phy); | 786 | sas_port_add_phy(ephy->port, phy->phy); |
787 | phy->port = ephy->port; | 787 | phy->port = ephy->port; |
788 | phy->phy_state = PHY_DEVICE_DISCOVERED; | 788 | phy->phy_state = PHY_DEVICE_DISCOVERED; |
789 | return 0; | 789 | return true; |
790 | } | 790 | } |
791 | } | 791 | } |
792 | 792 | ||
793 | return -ENODEV; | 793 | return false; |
794 | } | 794 | } |
795 | 795 | ||
796 | static struct domain_device *sas_ex_discover_expander( | 796 | static struct domain_device *sas_ex_discover_expander( |
@@ -928,8 +928,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) | |||
928 | return res; | 928 | return res; |
929 | } | 929 | } |
930 | 930 | ||
931 | res = sas_ex_join_wide_port(dev, phy_id); | 931 | if (sas_ex_join_wide_port(dev, phy_id)) { |
932 | if (!res) { | ||
933 | SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", | 932 | SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", |
934 | phy_id, SAS_ADDR(ex_phy->attached_sas_addr)); | 933 | phy_id, SAS_ADDR(ex_phy->attached_sas_addr)); |
935 | return res; | 934 | return res; |
@@ -974,8 +973,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) | |||
974 | if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) == | 973 | if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) == |
975 | SAS_ADDR(child->sas_addr)) { | 974 | SAS_ADDR(child->sas_addr)) { |
976 | ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED; | 975 | ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED; |
977 | res = sas_ex_join_wide_port(dev, i); | 976 | if (sas_ex_join_wide_port(dev, i)) |
978 | if (!res) | ||
979 | SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", | 977 | SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", |
980 | i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr)); | 978 | i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr)); |
981 | 979 | ||
@@ -1838,32 +1836,20 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) | |||
1838 | { | 1836 | { |
1839 | struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id]; | 1837 | struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id]; |
1840 | struct domain_device *child; | 1838 | struct domain_device *child; |
1841 | bool found = false; | 1839 | int res; |
1842 | int res, i; | ||
1843 | 1840 | ||
1844 | SAS_DPRINTK("ex %016llx phy%d new device attached\n", | 1841 | SAS_DPRINTK("ex %016llx phy%d new device attached\n", |
1845 | SAS_ADDR(dev->sas_addr), phy_id); | 1842 | SAS_ADDR(dev->sas_addr), phy_id); |
1846 | res = sas_ex_phy_discover(dev, phy_id); | 1843 | res = sas_ex_phy_discover(dev, phy_id); |
1847 | if (res) | 1844 | if (res) |
1848 | goto out; | 1845 | return res; |
1849 | /* to support the wide port inserted */ | 1846 | |
1850 | for (i = 0; i < dev->ex_dev.num_phys; i++) { | 1847 | if (sas_ex_join_wide_port(dev, phy_id)) |
1851 | struct ex_phy *ex_phy_temp = &dev->ex_dev.ex_phy[i]; | ||
1852 | if (i == phy_id) | ||
1853 | continue; | ||
1854 | if (SAS_ADDR(ex_phy_temp->attached_sas_addr) == | ||
1855 | SAS_ADDR(ex_phy->attached_sas_addr)) { | ||
1856 | found = true; | ||
1857 | break; | ||
1858 | } | ||
1859 | } | ||
1860 | if (found) { | ||
1861 | sas_ex_join_wide_port(dev, phy_id); | ||
1862 | return 0; | 1848 | return 0; |
1863 | } | 1849 | |
1864 | res = sas_ex_discover_devices(dev, phy_id); | 1850 | res = sas_ex_discover_devices(dev, phy_id); |
1865 | if (!res) | 1851 | if (res) |
1866 | goto out; | 1852 | return res; |
1867 | list_for_each_entry(child, &dev->ex_dev.children, siblings) { | 1853 | list_for_each_entry(child, &dev->ex_dev.children, siblings) { |
1868 | if (SAS_ADDR(child->sas_addr) == | 1854 | if (SAS_ADDR(child->sas_addr) == |
1869 | SAS_ADDR(ex_phy->attached_sas_addr)) { | 1855 | SAS_ADDR(ex_phy->attached_sas_addr)) { |
@@ -1873,7 +1859,6 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) | |||
1873 | break; | 1859 | break; |
1874 | } | 1860 | } |
1875 | } | 1861 | } |
1876 | out: | ||
1877 | return res; | 1862 | return res; |
1878 | } | 1863 | } |
1879 | 1864 | ||