summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt3sas/mpt3sas_transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt3sas/mpt3sas_transport.c')
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_transport.c74
1 files changed, 47 insertions, 27 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c
index aab3b1451e31..54c004e96170 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -64,6 +64,7 @@
* _transport_sas_node_find_by_sas_address - sas node search
* @ioc: per adapter object
* @sas_address: sas address of expander or sas host
+ * @port: hba port entry
* Context: Calling function should acquire ioc->sas_node_lock.
*
* Search for either hba phys or expander device based on handle, then returns
@@ -71,13 +72,13 @@
*/
static struct _sas_node *
_transport_sas_node_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
- u64 sas_address)
+ u64 sas_address, struct hba_port *port)
{
if (ioc->sas_hba.sas_address == sas_address)
return &ioc->sas_hba;
else
return mpt3sas_scsih_expander_find_by_sas_address(ioc,
- sas_address);
+ sas_address, port);
}
/**
@@ -439,6 +440,7 @@ _transport_delete_port(struct MPT3SAS_ADAPTER *ioc,
struct _sas_port *mpt3sas_port)
{
u64 sas_address = mpt3sas_port->remote_identify.sas_address;
+ struct hba_port *port = mpt3sas_port->hba_port;
enum sas_device_type device_type =
mpt3sas_port->remote_identify.device_type;
@@ -448,10 +450,11 @@ _transport_delete_port(struct MPT3SAS_ADAPTER *ioc,
ioc->logging_level |= MPT_DEBUG_TRANSPORT;
if (device_type == SAS_END_DEVICE)
- mpt3sas_device_remove_by_sas_address(ioc, sas_address);
+ mpt3sas_device_remove_by_sas_address(ioc,
+ sas_address, port);
else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
device_type == SAS_FANOUT_EXPANDER_DEVICE)
- mpt3sas_expander_remove(ioc, sas_address);
+ mpt3sas_expander_remove(ioc, sas_address, port);
ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
}
@@ -571,18 +574,21 @@ _transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc,
* @ioc: per adapter object
* @sas_node: sas node object (either expander or sas host)
* @sas_address: sas address of device being added
+ * @port: hba port entry
*
* See the explanation above from _transport_delete_duplicate_port
*/
static void
_transport_sanity_check(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node,
- u64 sas_address)
+ u64 sas_address, struct hba_port *port)
{
int i;
for (i = 0; i < sas_node->num_phys; i++) {
if (sas_node->phy[i].remote_identify.sas_address != sas_address)
continue;
+ if (sas_node->phy[i].port != port)
+ continue;
if (sas_node->phy[i].phy_belongs_to_port == 1)
_transport_del_phy_from_an_existing_port(ioc, sas_node,
&sas_node->phy[i]);
@@ -631,7 +637,8 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
INIT_LIST_HEAD(&mpt3sas_port->port_list);
INIT_LIST_HEAD(&mpt3sas_port->phy_list);
spin_lock_irqsave(&ioc->sas_node_lock, flags);
- sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
+ sas_node = _transport_sas_node_find_by_sas_address(ioc,
+ sas_address, hba_port);
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
if (!sas_node) {
@@ -655,7 +662,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
mpt3sas_port->hba_port = hba_port;
_transport_sanity_check(ioc, sas_node,
- mpt3sas_port->remote_identify.sas_address);
+ mpt3sas_port->remote_identify.sas_address, hba_port);
for (i = 0; i < sas_node->num_phys; i++) {
if (sas_node->phy[i].remote_identify.sas_address !=
@@ -676,6 +683,18 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
goto out_fail;
}
+ if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
+ sas_device = mpt3sas_get_sdev_by_addr(ioc,
+ mpt3sas_port->remote_identify.sas_address,
+ mpt3sas_port->hba_port);
+ if (!sas_device) {
+ ioc_err(ioc, "failure at %s:%d/%s()!\n",
+ __FILE__, __LINE__, __func__);
+ goto out_fail;
+ }
+ sas_device->pend_sas_rphy_add = 1;
+ }
+
if (!sas_node->parent_dev) {
ioc_err(ioc, "failure at %s:%d/%s()!\n",
__FILE__, __LINE__, __func__);
@@ -716,18 +735,6 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
rphy->identify = mpt3sas_port->remote_identify;
- if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
- sas_device = mpt3sas_get_sdev_by_addr(ioc,
- mpt3sas_port->remote_identify.sas_address);
- if (!sas_device) {
- dfailprintk(ioc,
- ioc_info(ioc, "failure at %s:%d/%s()!\n",
- __FILE__, __LINE__, __func__));
- goto out_fail;
- }
- sas_device->pend_sas_rphy_add = 1;
- }
-
if ((sas_rphy_add(rphy))) {
ioc_err(ioc, "failure at %s:%d/%s()!\n",
__FILE__, __LINE__, __func__);
@@ -793,7 +800,7 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
spin_lock_irqsave(&ioc->sas_node_lock, flags);
sas_node = _transport_sas_node_find_by_sas_address(ioc,
- sas_address_parent);
+ sas_address_parent, port);
if (!sas_node) {
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
return;
@@ -1020,7 +1027,8 @@ mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc,
return;
spin_lock_irqsave(&ioc->sas_node_lock, flags);
- sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
+ sas_node = _transport_sas_node_find_by_sas_address(ioc,
+ sas_address, port);
if (!sas_node) {
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
return;
@@ -1267,10 +1275,13 @@ _transport_get_linkerrors(struct sas_phy *phy)
unsigned long flags;
Mpi2ConfigReply_t mpi_reply;
Mpi2SasPhyPage1_t phy_pg1;
+ struct hba_port *port = phy->hostdata;
+ int port_id = port->port_id;
spin_lock_irqsave(&ioc->sas_node_lock, flags);
if (_transport_sas_node_find_by_sas_address(ioc,
- phy->identify.sas_address) == NULL) {
+ phy->identify.sas_address,
+ mpt3sas_get_port_by_id(ioc, port_id)) == NULL) {
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
return -EINVAL;
}
@@ -1321,7 +1332,7 @@ _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
spin_lock_irqsave(&ioc->sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
- rphy->identify.sas_address);
+ rphy->identify.sas_address, 0);
if (sas_device) {
*identifier = sas_device->enclosure_logical_id;
rc = 0;
@@ -1351,7 +1362,7 @@ _transport_get_bay_identifier(struct sas_rphy *rphy)
spin_lock_irqsave(&ioc->sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
- rphy->identify.sas_address);
+ rphy->identify.sas_address, 0);
if (sas_device) {
rc = sas_device->slot;
sas_device_put(sas_device);
@@ -1554,11 +1565,14 @@ _transport_phy_reset(struct sas_phy *phy, int hard_reset)
struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
Mpi2SasIoUnitControlReply_t mpi_reply;
Mpi2SasIoUnitControlRequest_t mpi_request;
+ struct hba_port *port = phy->hostdata;
+ int port_id = port->port_id;
unsigned long flags;
spin_lock_irqsave(&ioc->sas_node_lock, flags);
if (_transport_sas_node_find_by_sas_address(ioc,
- phy->identify.sas_address) == NULL) {
+ phy->identify.sas_address,
+ mpt3sas_get_port_by_id(ioc, port_id)) == NULL) {
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
return -EINVAL;
}
@@ -1611,10 +1625,13 @@ _transport_phy_enable(struct sas_phy *phy, int enable)
int rc = 0;
unsigned long flags;
int i, discovery_active;
+ struct hba_port *port = phy->hostdata;
+ int port_id = port->port_id;
spin_lock_irqsave(&ioc->sas_node_lock, flags);
if (_transport_sas_node_find_by_sas_address(ioc,
- phy->identify.sas_address) == NULL) {
+ phy->identify.sas_address,
+ mpt3sas_get_port_by_id(ioc, port_id)) == NULL) {
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
return -EINVAL;
}
@@ -1748,10 +1765,13 @@ _transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
int i;
int rc = 0;
unsigned long flags;
+ struct hba_port *port = phy->hostdata;
+ int port_id = port->port_id;
spin_lock_irqsave(&ioc->sas_node_lock, flags);
if (_transport_sas_node_find_by_sas_address(ioc,
- phy->identify.sas_address) == NULL) {
+ phy->identify.sas_address,
+ mpt3sas_get_port_by_id(ioc, port_id)) == NULL) {
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
return -EINVAL;
}