Commit 32698c95 authored by Damien Le Moal's avatar Damien Le Moal Committed by Martin K. Petersen

scsi: libsas: Clean up sas_form_port()

Sparse throws a warning about context imbalance ("different lock contexts
for basic block") in sas_form_port() as it gets confused with the fact that
a port is locked within one of the two search loops and unlocked afterward
outside of the search loops once the phy is added to the port. Since this
code is not easy to follow, improve it by factoring out the code adding the
phy to the port once the port is locked into the helper function
sas_form_port_add_phy(). This helper can then be called directly within the
port search loops, avoiding confusion and clearing the sparse warning.

Link: https://lore.kernel.org/r/20220228094857.557329-1-damien.lemoal@opensource.wdc.comReviewed-by: default avatarJohn Garry <john.garry@huawei.com>
Signed-off-by: default avatarDamien Le Moal <damien.lemoal@opensource.wdc.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 26440303
...@@ -67,6 +67,34 @@ static void sas_resume_port(struct asd_sas_phy *phy) ...@@ -67,6 +67,34 @@ static void sas_resume_port(struct asd_sas_phy *phy)
sas_discover_event(port, DISCE_RESUME); sas_discover_event(port, DISCE_RESUME);
} }
static void sas_form_port_add_phy(struct asd_sas_port *port,
struct asd_sas_phy *phy, bool wideport)
{
list_add_tail(&phy->port_phy_el, &port->phy_list);
sas_phy_set_target(phy, port->port_dev);
phy->port = port;
port->num_phys++;
port->phy_mask |= (1U << phy->id);
if (wideport)
pr_debug("phy%d matched wide port%d\n", phy->id,
port->id);
else
memcpy(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE);
if (*(u64 *)port->attached_sas_addr == 0) {
port->class = phy->class;
memcpy(port->attached_sas_addr, phy->attached_sas_addr,
SAS_ADDR_SIZE);
port->iproto = phy->iproto;
port->tproto = phy->tproto;
port->oob_mode = phy->oob_mode;
port->linkrate = phy->linkrate;
} else {
port->linkrate = max(port->linkrate, phy->linkrate);
}
}
/** /**
* sas_form_port - add this phy to a port * sas_form_port - add this phy to a port
* @phy: the phy of interest * @phy: the phy of interest
...@@ -79,7 +107,7 @@ static void sas_form_port(struct asd_sas_phy *phy) ...@@ -79,7 +107,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
int i; int i;
struct sas_ha_struct *sas_ha = phy->ha; struct sas_ha_struct *sas_ha = phy->ha;
struct asd_sas_port *port = phy->port; struct asd_sas_port *port = phy->port;
struct domain_device *port_dev; struct domain_device *port_dev = NULL;
struct sas_internal *si = struct sas_internal *si =
to_sas_internal(sas_ha->core.shost->transportt); to_sas_internal(sas_ha->core.shost->transportt);
unsigned long flags; unsigned long flags;
...@@ -110,8 +138,9 @@ static void sas_form_port(struct asd_sas_phy *phy) ...@@ -110,8 +138,9 @@ static void sas_form_port(struct asd_sas_phy *phy)
if (*(u64 *) port->sas_addr && if (*(u64 *) port->sas_addr &&
phy_is_wideport_member(port, phy) && port->num_phys > 0) { phy_is_wideport_member(port, phy) && port->num_phys > 0) {
/* wide port */ /* wide port */
pr_debug("phy%d matched wide port%d\n", phy->id, port_dev = port->port_dev;
port->id); sas_form_port_add_phy(port, phy, true);
spin_unlock(&port->phy_list_lock);
break; break;
} }
spin_unlock(&port->phy_list_lock); spin_unlock(&port->phy_list_lock);
...@@ -122,40 +151,22 @@ static void sas_form_port(struct asd_sas_phy *phy) ...@@ -122,40 +151,22 @@ static void sas_form_port(struct asd_sas_phy *phy)
port = sas_ha->sas_port[i]; port = sas_ha->sas_port[i];
spin_lock(&port->phy_list_lock); spin_lock(&port->phy_list_lock);
if (*(u64 *)port->sas_addr == 0 if (*(u64 *)port->sas_addr == 0
&& port->num_phys == 0) { && port->num_phys == 0) {
memcpy(port->sas_addr, phy->sas_addr, port_dev = port->port_dev;
SAS_ADDR_SIZE); sas_form_port_add_phy(port, phy, false);
spin_unlock(&port->phy_list_lock);
break; break;
} }
spin_unlock(&port->phy_list_lock); spin_unlock(&port->phy_list_lock);
} }
}
if (i >= sas_ha->num_phys) { if (i >= sas_ha->num_phys) {
pr_err("%s: couldn't find a free port, bug?\n", __func__); pr_err("%s: couldn't find a free port, bug?\n",
spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); __func__);
return; spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
return;
}
} }
/* add the phy to the port */
port_dev = port->port_dev;
list_add_tail(&phy->port_phy_el, &port->phy_list);
sas_phy_set_target(phy, port_dev);
phy->port = port;
port->num_phys++;
port->phy_mask |= (1U << phy->id);
if (*(u64 *)port->attached_sas_addr == 0) {
port->class = phy->class;
memcpy(port->attached_sas_addr, phy->attached_sas_addr,
SAS_ADDR_SIZE);
port->iproto = phy->iproto;
port->tproto = phy->tproto;
port->oob_mode = phy->oob_mode;
port->linkrate = phy->linkrate;
} else
port->linkrate = max(port->linkrate, phy->linkrate);
spin_unlock(&port->phy_list_lock);
spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
if (!port->port) { if (!port->port) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment