Skip to content

Commit 9cf0c12

Browse files
Merge patch series "scsi: libsas: Fix the failure of adding phy with zero-address to new port"
Xingui Yang <[email protected]> says: This series is to solve the problem of a BUG() when adding phy with zero address to a new port. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
2 parents f92141e + 06036a0 commit 9cf0c12

File tree

2 files changed

+30
-23
lines changed

2 files changed

+30
-23
lines changed

drivers/scsi/libsas/sas_expander.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,28 @@ static int sas_configure_phy(struct domain_device *dev, int phy_id,
2626
u8 *sas_addr, int include);
2727
static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr);
2828

29+
static void sas_port_add_ex_phy(struct sas_port *port, struct ex_phy *ex_phy)
30+
{
31+
sas_port_add_phy(port, ex_phy->phy);
32+
ex_phy->port = port;
33+
ex_phy->phy_state = PHY_DEVICE_DISCOVERED;
34+
}
35+
36+
static void sas_ex_add_parent_port(struct domain_device *dev, int phy_id)
37+
{
38+
struct expander_device *ex = &dev->ex_dev;
39+
struct ex_phy *ex_phy = &ex->ex_phy[phy_id];
40+
41+
if (!ex->parent_port) {
42+
ex->parent_port = sas_port_alloc(&dev->rphy->dev, phy_id);
43+
/* FIXME: error handling */
44+
BUG_ON(!ex->parent_port);
45+
BUG_ON(sas_port_add(ex->parent_port));
46+
sas_port_mark_backlink(ex->parent_port);
47+
}
48+
sas_port_add_ex_phy(ex->parent_port, ex_phy);
49+
}
50+
2951
/* ---------- SMP task management ---------- */
3052

3153
/* Give it some long enough timeout. In seconds. */
@@ -239,8 +261,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
239261
/* help some expanders that fail to zero sas_address in the 'no
240262
* device' case
241263
*/
242-
if (phy->attached_dev_type == SAS_PHY_UNUSED ||
243-
phy->linkrate < SAS_LINK_RATE_1_5_GBPS)
264+
if (phy->attached_dev_type == SAS_PHY_UNUSED)
244265
memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
245266
else
246267
memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE);
@@ -857,9 +878,7 @@ static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
857878

858879
if (!memcmp(phy->attached_sas_addr, ephy->attached_sas_addr,
859880
SAS_ADDR_SIZE) && ephy->port) {
860-
sas_port_add_phy(ephy->port, phy->phy);
861-
phy->port = ephy->port;
862-
phy->phy_state = PHY_DEVICE_DISCOVERED;
881+
sas_port_add_ex_phy(ephy->port, phy);
863882
return true;
864883
}
865884
}
@@ -963,11 +982,11 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
963982

964983
/* Parent and domain coherency */
965984
if (!dev->parent && sas_phy_match_port_addr(dev->port, ex_phy)) {
966-
sas_add_parent_port(dev, phy_id);
985+
sas_ex_add_parent_port(dev, phy_id);
967986
return 0;
968987
}
969988
if (dev->parent && sas_phy_match_dev_addr(dev->parent, ex_phy)) {
970-
sas_add_parent_port(dev, phy_id);
989+
sas_ex_add_parent_port(dev, phy_id);
971990
if (ex_phy->routing_attr == TABLE_ROUTING)
972991
sas_configure_phy(dev, phy_id, dev->port->sas_addr, 1);
973992
return 0;
@@ -1849,9 +1868,12 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent,
18491868
if (phy->port) {
18501869
sas_port_delete_phy(phy->port, phy->phy);
18511870
sas_device_set_phy(found, phy->port);
1852-
if (phy->port->num_phys == 0)
1871+
if (phy->port->num_phys == 0) {
18531872
list_add_tail(&phy->port->del_list,
18541873
&parent->port->sas_port_del_list);
1874+
if (ex_dev->parent_port == phy->port)
1875+
ex_dev->parent_port = NULL;
1876+
}
18551877
phy->port = NULL;
18561878
}
18571879
}

drivers/scsi/libsas/sas_internal.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -189,21 +189,6 @@ static inline void sas_phy_set_target(struct asd_sas_phy *p, struct domain_devic
189189
}
190190
}
191191

192-
static inline void sas_add_parent_port(struct domain_device *dev, int phy_id)
193-
{
194-
struct expander_device *ex = &dev->ex_dev;
195-
struct ex_phy *ex_phy = &ex->ex_phy[phy_id];
196-
197-
if (!ex->parent_port) {
198-
ex->parent_port = sas_port_alloc(&dev->rphy->dev, phy_id);
199-
/* FIXME: error handling */
200-
BUG_ON(!ex->parent_port);
201-
BUG_ON(sas_port_add(ex->parent_port));
202-
sas_port_mark_backlink(ex->parent_port);
203-
}
204-
sas_port_add_phy(ex->parent_port, ex_phy->phy);
205-
}
206-
207192
static inline struct domain_device *sas_alloc_device(void)
208193
{
209194
struct domain_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);

0 commit comments

Comments
 (0)