You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
804 lines
30 KiB
804 lines
30 KiB
From a3acf223af8462a6cf293b2587f0f31bc139930a Mon Sep 17 00:00:00 2001
|
|
From: Tomas Henzl <thenzl@redhat.com>
|
|
Date: Fri, 13 Nov 2020 18:42:49 -0500
|
|
Subject: [PATCH 24/33] [scsi] scsi: mpt3sas: Get device objects using
|
|
sas_address & portID
|
|
|
|
Message-id: <20201113184258.11169-6-thenzl@redhat.com>
|
|
Patchwork-id: 339463
|
|
Patchwork-instance: patchwork
|
|
O-Subject: [RHEL8.4 e-stor PATCH 05/14] scsi: mpt3sas: Get device objects using sas_address & portID
|
|
Bugzilla: 1888543
|
|
RH-Acked-by: Ewan Milne <emilne@redhat.com>
|
|
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
|
|
Currently driver retrieves the sas_device/sas_expander objects from
|
|
corresponding object's lists using just device's SAS Address.
|
|
|
|
Make driver retrieve the objects from the corresponding objects list using
|
|
device's SAS Address and PhysicalPort (or PortID) number. PhysicalPort
|
|
number is the port number of the HBA through which this device is accessed.
|
|
|
|
Link: https://lore.kernel.org/r/20201027130847.9962-6-sreekanth.reddy@broadcom.com
|
|
Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
|
|
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
|
(cherry picked from commit 7d310f241001e090cf1ec0f3ae836b38d8c6ebec)
|
|
Signed-off-by: Tomas Henzl <thenzl@redhat.com>
|
|
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
|
---
|
|
drivers/scsi/mpt3sas/mpt3sas_base.h | 16 ++-
|
|
drivers/scsi/mpt3sas/mpt3sas_scsih.c | 175 +++++++++++++++++++++----------
|
|
drivers/scsi/mpt3sas/mpt3sas_transport.c | 74 ++++++++-----
|
|
3 files changed, 178 insertions(+), 87 deletions(-)
|
|
|
|
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
|
|
index aef872aa509d..b5d1fc5b665b 100644
|
|
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
|
|
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
|
|
@@ -1652,20 +1652,26 @@ int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
|
|
|
void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
|
void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
|
-void mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
|
+void mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
|
|
+ struct hba_port *port);
|
|
void mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
|
|
- u64 sas_address);
|
|
+ u64 sas_address, struct hba_port *port);
|
|
u8 mpt3sas_check_for_pending_internal_cmds(struct MPT3SAS_ADAPTER *ioc,
|
|
u16 smid);
|
|
+struct hba_port *
|
|
+mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, u8 port);
|
|
|
|
struct _sas_node *mpt3sas_scsih_expander_find_by_handle(
|
|
struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
|
struct _sas_node *mpt3sas_scsih_expander_find_by_sas_address(
|
|
- struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
|
+ struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
|
|
+ struct hba_port *port);
|
|
struct _sas_device *mpt3sas_get_sdev_by_addr(
|
|
- struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
|
+ struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
|
|
+ struct hba_port *port);
|
|
struct _sas_device *__mpt3sas_get_sdev_by_addr(
|
|
- struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
|
+ struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
|
|
+ struct hba_port *port);
|
|
struct _sas_device *mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
|
|
u16 handle);
|
|
struct _pcie_device *mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
|
|
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
index c80646740542..597b2464222f 100644
|
|
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
@@ -638,48 +638,67 @@ mpt3sas_get_pdev_from_target(struct MPT3SAS_ADAPTER *ioc,
|
|
return ret;
|
|
}
|
|
|
|
+/**
|
|
+ * mpt3sas_get_sdev_by_addr - get _sas_device object corresponding to provided
|
|
+ * sas address from sas_device_list list
|
|
+ * @ioc: per adapter object
|
|
+ * @port: port number
|
|
+ *
|
|
+ * Search for _sas_device object corresponding to provided sas address,
|
|
+ * if available return _sas_device object address otherwise return NULL.
|
|
+ */
|
|
struct _sas_device *
|
|
__mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc,
|
|
- u64 sas_address)
|
|
+ u64 sas_address, struct hba_port *port)
|
|
{
|
|
struct _sas_device *sas_device;
|
|
|
|
+ if (!port)
|
|
+ return NULL;
|
|
+
|
|
assert_spin_locked(&ioc->sas_device_lock);
|
|
|
|
- list_for_each_entry(sas_device, &ioc->sas_device_list, list)
|
|
- if (sas_device->sas_address == sas_address)
|
|
- goto found_device;
|
|
+ list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
|
|
+ if (sas_device->sas_address != sas_address)
|
|
+ continue;
|
|
+ if (sas_device->port != port)
|
|
+ continue;
|
|
+ sas_device_get(sas_device);
|
|
+ return sas_device;
|
|
+ }
|
|
|
|
- list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
|
|
- if (sas_device->sas_address == sas_address)
|
|
- goto found_device;
|
|
+ list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) {
|
|
+ if (sas_device->sas_address != sas_address)
|
|
+ continue;
|
|
+ if (sas_device->port != port)
|
|
+ continue;
|
|
+ sas_device_get(sas_device);
|
|
+ return sas_device;
|
|
+ }
|
|
|
|
return NULL;
|
|
-
|
|
-found_device:
|
|
- sas_device_get(sas_device);
|
|
- return sas_device;
|
|
}
|
|
|
|
/**
|
|
* mpt3sas_get_sdev_by_addr - sas device search
|
|
* @ioc: per adapter object
|
|
* @sas_address: sas address
|
|
+ * @port: hba port entry
|
|
* Context: Calling function should acquire ioc->sas_device_lock
|
|
*
|
|
- * This searches for sas_device based on sas_address, then return sas_device
|
|
- * object.
|
|
+ * This searches for sas_device based on sas_address & port number,
|
|
+ * then return sas_device object.
|
|
*/
|
|
struct _sas_device *
|
|
mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc,
|
|
- u64 sas_address)
|
|
+ u64 sas_address, struct hba_port *port)
|
|
{
|
|
struct _sas_device *sas_device;
|
|
unsigned long flags;
|
|
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
|
|
- sas_address);
|
|
+ sas_address, port);
|
|
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
|
|
|
return sas_device;
|
|
@@ -848,13 +867,17 @@ _scsih_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|
}
|
|
|
|
/**
|
|
- * mpt3sas_device_remove_by_sas_address - removing device object by sas address
|
|
+ * mpt3sas_device_remove_by_sas_address - removing device object by
|
|
+ * sas address & port number
|
|
* @ioc: per adapter object
|
|
* @sas_address: device sas_address
|
|
+ * @port: hba port entry
|
|
+ *
|
|
+ * Return nothing.
|
|
*/
|
|
void
|
|
mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
|
|
- u64 sas_address)
|
|
+ u64 sas_address, struct hba_port *port)
|
|
{
|
|
struct _sas_device *sas_device;
|
|
unsigned long flags;
|
|
@@ -863,7 +886,7 @@ mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
|
|
return;
|
|
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
- sas_device = __mpt3sas_get_sdev_by_addr(ioc, sas_address);
|
|
+ sas_device = __mpt3sas_get_sdev_by_addr(ioc, sas_address, port);
|
|
if (sas_device) {
|
|
list_del_init(&sas_device->list);
|
|
sas_device_put(sas_device);
|
|
@@ -1457,21 +1480,26 @@ mpt3sas_scsih_enclosure_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|
* mpt3sas_scsih_expander_find_by_sas_address - expander device search
|
|
* @ioc: per adapter object
|
|
* @sas_address: sas address
|
|
+ * @port: hba port entry
|
|
* Context: Calling function should acquire ioc->sas_node_lock.
|
|
*
|
|
- * This searches for expander device based on sas_address, then returns the
|
|
- * sas_node object.
|
|
+ * This searches for expander device based on sas_address & port number,
|
|
+ * then returns the sas_node object.
|
|
*/
|
|
struct _sas_node *
|
|
mpt3sas_scsih_expander_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
|
|
- u64 sas_address)
|
|
+ u64 sas_address, struct hba_port *port)
|
|
{
|
|
- struct _sas_node *sas_expander, *r;
|
|
+ struct _sas_node *sas_expander, *r = NULL;
|
|
+
|
|
+ if (!port)
|
|
+ return r;
|
|
|
|
- r = NULL;
|
|
list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
|
|
if (sas_expander->sas_address != sas_address)
|
|
continue;
|
|
+ if (sas_expander->port != port)
|
|
+ continue;
|
|
r = sas_expander;
|
|
goto out;
|
|
}
|
|
@@ -1788,7 +1816,7 @@ scsih_target_alloc(struct scsi_target *starget)
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
rphy = dev_to_rphy(starget->dev.parent);
|
|
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
|
|
- rphy->identify.sas_address);
|
|
+ rphy->identify.sas_address, NULL);
|
|
|
|
if (sas_device) {
|
|
sas_target_priv_data->handle = sas_device->handle;
|
|
@@ -1949,7 +1977,8 @@ scsih_slave_alloc(struct scsi_device *sdev)
|
|
} else if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
|
|
- sas_target_priv_data->sas_address);
|
|
+ sas_target_priv_data->sas_address,
|
|
+ sas_target_priv_data->port);
|
|
if (sas_device && (sas_device->starget == NULL)) {
|
|
sdev_printk(KERN_INFO, sdev,
|
|
"%s : sas_device->starget set to starget @ %d\n",
|
|
@@ -2554,7 +2583,8 @@ scsih_slave_configure(struct scsi_device *sdev)
|
|
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
|
|
- sas_device_priv_data->sas_target->sas_address);
|
|
+ sas_device_priv_data->sas_target->sas_address,
|
|
+ sas_device_priv_data->sas_target->port);
|
|
if (!sas_device) {
|
|
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
|
dfailprintk(ioc,
|
|
@@ -3669,11 +3699,13 @@ _scsih_ublock_io_all_device(struct MPT3SAS_ADAPTER *ioc)
|
|
* _scsih_ublock_io_device - prepare device to be deleted
|
|
* @ioc: per adapter object
|
|
* @sas_address: sas address
|
|
+ * @port: hba port entry
|
|
*
|
|
* unblock then put device in offline state
|
|
*/
|
|
static void
|
|
-_scsih_ublock_io_device(struct MPT3SAS_ADAPTER *ioc, u64 sas_address)
|
|
+_scsih_ublock_io_device(struct MPT3SAS_ADAPTER *ioc,
|
|
+ u64 sas_address, struct hba_port *port)
|
|
{
|
|
struct MPT3SAS_DEVICE *sas_device_priv_data;
|
|
struct scsi_device *sdev;
|
|
@@ -3685,6 +3717,8 @@ _scsih_ublock_io_device(struct MPT3SAS_ADAPTER *ioc, u64 sas_address)
|
|
if (sas_device_priv_data->sas_target->sas_address
|
|
!= sas_address)
|
|
continue;
|
|
+ if (sas_device_priv_data->sas_target->port != port)
|
|
+ continue;
|
|
if (sas_device_priv_data->block)
|
|
_scsih_internal_device_unblock(sdev,
|
|
sas_device_priv_data);
|
|
@@ -3785,7 +3819,8 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT3SAS_ADAPTER *ioc,
|
|
SAS_END_DEVICE) {
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
|
|
- mpt3sas_port->remote_identify.sas_address);
|
|
+ mpt3sas_port->remote_identify.sas_address,
|
|
+ mpt3sas_port->hba_port);
|
|
if (sas_device) {
|
|
set_bit(sas_device->handle,
|
|
ioc->blocking_handles);
|
|
@@ -3804,7 +3839,8 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT3SAS_ADAPTER *ioc,
|
|
SAS_FANOUT_EXPANDER_DEVICE) {
|
|
expander_sibling =
|
|
mpt3sas_scsih_expander_find_by_sas_address(
|
|
- ioc, mpt3sas_port->remote_identify.sas_address);
|
|
+ ioc, mpt3sas_port->remote_identify.sas_address,
|
|
+ mpt3sas_port->hba_port);
|
|
_scsih_block_io_to_children_attached_to_ex(ioc,
|
|
expander_sibling);
|
|
}
|
|
@@ -3893,6 +3929,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|
struct _tr_list *delayed_tr;
|
|
u32 ioc_state;
|
|
u8 tr_method = 0;
|
|
+ struct hba_port *port = NULL;
|
|
|
|
if (ioc->pci_error_recovery) {
|
|
dewtprintk(ioc,
|
|
@@ -3921,6 +3958,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|
sas_target_priv_data = sas_device->starget->hostdata;
|
|
sas_target_priv_data->deleted = 1;
|
|
sas_address = sas_device->sas_address;
|
|
+ port = sas_device->port;
|
|
}
|
|
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
|
if (!sas_device) {
|
|
@@ -3968,7 +4006,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|
pcie_device->enclosure_level,
|
|
pcie_device->connector_name));
|
|
}
|
|
- _scsih_ublock_io_device(ioc, sas_address);
|
|
+ _scsih_ublock_io_device(ioc, sas_address, port);
|
|
sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
|
|
}
|
|
|
|
@@ -6036,7 +6074,7 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|
if (sas_address_parent != ioc->sas_hba.sas_address) {
|
|
spin_lock_irqsave(&ioc->sas_node_lock, flags);
|
|
sas_expander = mpt3sas_scsih_expander_find_by_sas_address(ioc,
|
|
- sas_address_parent);
|
|
+ sas_address_parent, mpt3sas_get_port_by_id(ioc, port_id));
|
|
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
|
|
if (!sas_expander) {
|
|
rc = _scsih_expander_add(ioc, parent_handle);
|
|
@@ -6048,7 +6086,7 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|
spin_lock_irqsave(&ioc->sas_node_lock, flags);
|
|
sas_address = le64_to_cpu(expander_pg0.SASAddress);
|
|
sas_expander = mpt3sas_scsih_expander_find_by_sas_address(ioc,
|
|
- sas_address);
|
|
+ sas_address, mpt3sas_get_port_by_id(ioc, port_id));
|
|
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
|
|
|
|
if (sas_expander)
|
|
@@ -6149,7 +6187,8 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|
* @sas_address: expander sas_address
|
|
*/
|
|
void
|
|
-mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address)
|
|
+mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
|
|
+ struct hba_port *port)
|
|
{
|
|
struct _sas_node *sas_expander;
|
|
unsigned long flags;
|
|
@@ -6157,9 +6196,12 @@ mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address)
|
|
if (ioc->shost_recovery)
|
|
return;
|
|
|
|
+ if (!port)
|
|
+ return;
|
|
+
|
|
spin_lock_irqsave(&ioc->sas_node_lock, flags);
|
|
sas_expander = mpt3sas_scsih_expander_find_by_sas_address(ioc,
|
|
- sas_address);
|
|
+ sas_address, port);
|
|
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
|
|
if (sas_expander)
|
|
_scsih_expander_node_remove(ioc, sas_expander);
|
|
@@ -6282,7 +6324,7 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc,
|
|
{
|
|
Mpi2ConfigReply_t mpi_reply;
|
|
Mpi2SasDevicePage0_t sas_device_pg0;
|
|
- struct _sas_device *sas_device;
|
|
+ struct _sas_device *sas_device = NULL;
|
|
struct _enclosure_node *enclosure_dev = NULL;
|
|
u32 ioc_status;
|
|
unsigned long flags;
|
|
@@ -6290,6 +6332,7 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc,
|
|
struct scsi_target *starget;
|
|
struct MPT3SAS_TARGET *sas_target_priv_data;
|
|
u32 device_info;
|
|
+ struct hba_port *port;
|
|
|
|
if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
|
|
MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle)))
|
|
@@ -6312,8 +6355,11 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc,
|
|
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
|
|
+ port = mpt3sas_get_port_by_id(ioc, sas_device_pg0.PhysicalPort);
|
|
+ if (!port)
|
|
+ goto out_unlock;
|
|
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
|
|
- sas_address);
|
|
+ sas_address, port);
|
|
|
|
if (!sas_device)
|
|
goto out_unlock;
|
|
@@ -6369,7 +6415,7 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc,
|
|
goto out_unlock;
|
|
|
|
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
|
- _scsih_ublock_io_device(ioc, sas_address);
|
|
+ _scsih_ublock_io_device(ioc, sas_address, port);
|
|
|
|
if (sas_device)
|
|
sas_device_put(sas_device);
|
|
@@ -6442,7 +6488,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
|
|
|
|
port_id = sas_device_pg0.PhysicalPort;
|
|
sas_device = mpt3sas_get_sdev_by_addr(ioc,
|
|
- sas_address);
|
|
+ sas_address, mpt3sas_get_port_by_id(ioc, port_id));
|
|
if (sas_device) {
|
|
clear_bit(handle, ioc->pend_os_device_add);
|
|
sas_device_put(sas_device);
|
|
@@ -6555,7 +6601,8 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc,
|
|
if (sas_device->starget && sas_device->starget->hostdata) {
|
|
sas_target_priv_data = sas_device->starget->hostdata;
|
|
sas_target_priv_data->deleted = 1;
|
|
- _scsih_ublock_io_device(ioc, sas_device->sas_address);
|
|
+ _scsih_ublock_io_device(ioc, sas_device->sas_address,
|
|
+ sas_device->port);
|
|
sas_target_priv_data->handle =
|
|
MPT3SAS_INVALID_DEVICE_HANDLE;
|
|
}
|
|
@@ -6787,7 +6834,7 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc,
|
|
/* handle expander removal */
|
|
if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
|
|
sas_expander)
|
|
- mpt3sas_expander_remove(ioc, sas_address);
|
|
+ mpt3sas_expander_remove(ioc, sas_address, port);
|
|
|
|
return 0;
|
|
}
|
|
@@ -6888,7 +6935,7 @@ _scsih_sas_device_status_change_event(struct MPT3SAS_ADAPTER *ioc,
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
sas_address = le64_to_cpu(event_data->SASAddress);
|
|
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
|
|
- sas_address);
|
|
+ sas_address, mpt3sas_get_port_by_id(ioc, event_data->PhysicalPort));
|
|
|
|
if (!sas_device || !sas_device->starget)
|
|
goto out;
|
|
@@ -7037,7 +7084,7 @@ _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
|
|
if (pcie_device->starget && pcie_device->starget->hostdata) {
|
|
sas_target_priv_data = pcie_device->starget->hostdata;
|
|
sas_target_priv_data->deleted = 1;
|
|
- _scsih_ublock_io_device(ioc, pcie_device->wwid);
|
|
+ _scsih_ublock_io_device(ioc, pcie_device->wwid, NULL);
|
|
sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
|
|
}
|
|
|
|
@@ -7159,7 +7206,7 @@ _scsih_pcie_check_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|
spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
|
|
pcie_device_put(pcie_device);
|
|
|
|
- _scsih_ublock_io_device(ioc, wwid);
|
|
+ _scsih_ublock_io_device(ioc, wwid, NULL);
|
|
|
|
return;
|
|
}
|
|
@@ -8762,6 +8809,8 @@ Mpi2SasDevicePage0_t *sas_device_pg0)
|
|
struct _sas_device *sas_device = NULL;
|
|
struct _enclosure_node *enclosure_dev = NULL;
|
|
unsigned long flags;
|
|
+ struct hba_port *port = mpt3sas_get_port_by_id(
|
|
+ ioc, sas_device_pg0->PhysicalPort);
|
|
|
|
if (sas_device_pg0->EnclosureHandle) {
|
|
enclosure_dev =
|
|
@@ -8778,6 +8827,8 @@ Mpi2SasDevicePage0_t *sas_device_pg0)
|
|
continue;
|
|
if (sas_device->slot != le16_to_cpu(sas_device_pg0->Slot))
|
|
continue;
|
|
+ if (sas_device->port != port)
|
|
+ continue;
|
|
sas_device->responding = 1;
|
|
starget = sas_device->starget;
|
|
if (starget && starget->hostdata) {
|
|
@@ -9186,6 +9237,8 @@ _scsih_mark_responding_expander(struct MPT3SAS_ADAPTER *ioc,
|
|
u16 handle = le16_to_cpu(expander_pg0->DevHandle);
|
|
u16 enclosure_handle = le16_to_cpu(expander_pg0->EnclosureHandle);
|
|
u64 sas_address = le64_to_cpu(expander_pg0->SASAddress);
|
|
+ struct hba_port *port = mpt3sas_get_port_by_id(
|
|
+ ioc, expander_pg0->PhysicalPort);
|
|
|
|
if (enclosure_handle)
|
|
enclosure_dev =
|
|
@@ -9196,6 +9249,8 @@ _scsih_mark_responding_expander(struct MPT3SAS_ADAPTER *ioc,
|
|
list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
|
|
if (sas_expander->sas_address != sas_address)
|
|
continue;
|
|
+ if (sas_expander->port != port)
|
|
+ continue;
|
|
sas_expander->responding = 1;
|
|
|
|
if (enclosure_dev) {
|
|
@@ -9252,9 +9307,10 @@ _scsih_search_responding_expanders(struct MPT3SAS_ADAPTER *ioc)
|
|
|
|
handle = le16_to_cpu(expander_pg0.DevHandle);
|
|
sas_address = le64_to_cpu(expander_pg0.SASAddress);
|
|
- pr_info("\texpander present: handle(0x%04x), sas_addr(0x%016llx)\n",
|
|
- handle,
|
|
- (unsigned long long)sas_address);
|
|
+ pr_info(
|
|
+ "\texpander present: handle(0x%04x), sas_addr(0x%016llx), port:%d\n",
|
|
+ handle, (unsigned long long)sas_address,
|
|
+ expander_pg0.PhysicalPort);
|
|
_scsih_mark_responding_expander(ioc, &expander_pg0);
|
|
}
|
|
|
|
@@ -9426,8 +9482,10 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
|
|
}
|
|
handle = le16_to_cpu(expander_pg0.DevHandle);
|
|
spin_lock_irqsave(&ioc->sas_node_lock, flags);
|
|
+ port_id = expander_pg0.PhysicalPort;
|
|
expander_device = mpt3sas_scsih_expander_find_by_sas_address(
|
|
- ioc, le64_to_cpu(expander_pg0.SASAddress));
|
|
+ ioc, le64_to_cpu(expander_pg0.SASAddress),
|
|
+ mpt3sas_get_port_by_id(ioc, port_id));
|
|
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
|
|
if (expander_device)
|
|
_scsih_refresh_expander_links(ioc, expander_device,
|
|
@@ -9578,7 +9636,8 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
|
|
continue;
|
|
port_id = sas_device_pg0.PhysicalPort;
|
|
sas_device = mpt3sas_get_sdev_by_addr(ioc,
|
|
- le64_to_cpu(sas_device_pg0.SASAddress));
|
|
+ le64_to_cpu(sas_device_pg0.SASAddress),
|
|
+ mpt3sas_get_port_by_id(ioc, port_id));
|
|
if (sas_device) {
|
|
sas_device_put(sas_device);
|
|
continue;
|
|
@@ -10023,21 +10082,25 @@ _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc,
|
|
if (mpt3sas_port->remote_identify.device_type ==
|
|
SAS_END_DEVICE)
|
|
mpt3sas_device_remove_by_sas_address(ioc,
|
|
- mpt3sas_port->remote_identify.sas_address);
|
|
+ mpt3sas_port->remote_identify.sas_address,
|
|
+ mpt3sas_port->hba_port);
|
|
else if (mpt3sas_port->remote_identify.device_type ==
|
|
SAS_EDGE_EXPANDER_DEVICE ||
|
|
mpt3sas_port->remote_identify.device_type ==
|
|
SAS_FANOUT_EXPANDER_DEVICE)
|
|
mpt3sas_expander_remove(ioc,
|
|
- mpt3sas_port->remote_identify.sas_address);
|
|
+ mpt3sas_port->remote_identify.sas_address,
|
|
+ mpt3sas_port->hba_port);
|
|
}
|
|
|
|
mpt3sas_transport_port_remove(ioc, sas_expander->sas_address,
|
|
sas_expander->sas_address_parent, sas_expander->port);
|
|
|
|
- ioc_info(ioc, "expander_remove: handle(0x%04x), sas_addr(0x%016llx)\n",
|
|
- sas_expander->handle, (unsigned long long)
|
|
- sas_expander->sas_address);
|
|
+ ioc_info(ioc,
|
|
+ "expander_remove: handle(0x%04x), sas_addr(0x%016llx), port:%d\n",
|
|
+ sas_expander->handle, (unsigned long long)
|
|
+ sas_expander->sas_address,
|
|
+ sas_expander->port->port_id);
|
|
|
|
spin_lock_irqsave(&ioc->sas_node_lock, flags);
|
|
list_del(&sas_expander->list);
|
|
@@ -10283,13 +10346,15 @@ static void scsih_remove(struct pci_dev *pdev)
|
|
if (mpt3sas_port->remote_identify.device_type ==
|
|
SAS_END_DEVICE)
|
|
mpt3sas_device_remove_by_sas_address(ioc,
|
|
- mpt3sas_port->remote_identify.sas_address);
|
|
+ mpt3sas_port->remote_identify.sas_address,
|
|
+ mpt3sas_port->hba_port);
|
|
else if (mpt3sas_port->remote_identify.device_type ==
|
|
SAS_EDGE_EXPANDER_DEVICE ||
|
|
mpt3sas_port->remote_identify.device_type ==
|
|
SAS_FANOUT_EXPANDER_DEVICE)
|
|
mpt3sas_expander_remove(ioc,
|
|
- mpt3sas_port->remote_identify.sas_address);
|
|
+ mpt3sas_port->remote_identify.sas_address,
|
|
+ mpt3sas_port->hba_port);
|
|
}
|
|
|
|
list_for_each_entry_safe(port, port_next,
|
|
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;
|
|
}
|
|
--
|
|
2.13.6
|
|
|