From 2dec896bb3c4f24aed1766531784ce90f45a6875 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Thu, 21 Jan 2021 09:58:55 -0500 Subject: [PATCH] import kmod-redhat-mpt3sas-35.101.00.00_dup8.3-1.el8_3 --- .gitignore | 1 + .kmod-redhat-mpt3sas.metadata | 1 + ...si-scsi-mpt3sas-Fix-spelling-mistake.patch | 57 ++ ...si-scsi-mpt3sas-Fix-unlock-imbalance.patch | 90 ++ ...s-Fix-error-returns-in-BRM_status_sh.patch | 89 ++ ...-mpt3sas-Fix-set-but-unused-variable.patch | 59 ++ ...csi-mpt3sas-Fix-kdoc-comments-format.patch | 135 +++ ...s-Memset-config_cmds.reply-buffer-wi.patch | 50 ++ ...s-Dump-system-registers-for-debuggin.patch | 85 ++ ...s-Cancel-the-running-work-during-hos.patch | 139 +++ ...s-Rename-and-export-interrupt-mask-u.patch | 140 +++ ...s-Add-functions-to-check-if-any-cmd-.patch | 243 ++++++ ...s-Postprocessing-of-target-and-LUN-r.patch | 258 ++++++ ...s-Update-driver-version-to-35.100.00.patch | 46 + ...si-mpt3sas-Remove-superfluous-memset.patch | 46 + ...as-Remove-pci-dma-compat-wrapper-API.patch | 136 +++ ...s-Don-t-call-disable_irq-from-IRQ-po.patch | 45 + ...s-Detect-tampered-Aero-and-Sea-adapt.patch | 270 ++++++ ...0017-scsi-scsi-mpt3sas-Fix-sync-irqs.patch | 67 ++ ...s-A-small-correction-in-_base_proces.patch | 44 + ...s-Fix-timeouts-observed-while-reenab.patch | 56 ++ ...si-mpt3sas-Define-hba_port-structure.patch | 171 ++++ ...s-Allocate-memory-for-hba_port-objec.patch | 171 ++++ ...s-Rearrange-_scsih_mark_responding_s.patch | 161 ++++ ...s-Update-hba_port-s-sas_address-phy_.patch | 587 +++++++++++++ ...s-Get-device-objects-using-sas_addre.patch | 803 ++++++++++++++++++ ...s-Rename-transport_del_phy_from_an_e.patch | 160 ++++ ...s-Get-sas_device-objects-using-devic.patch | 166 ++++ ...s-Update-hba_port-objects-after-host.patch | 509 +++++++++++ ...s-Set-valid-PhysicalPort-in-SMPPassT.patch | 221 +++++ ...csi-mpt3sas-Handling-HBA-vSES-device.patch | 385 +++++++++ ...s-Add-bypass_dirty_port_flag-paramet.patch | 327 +++++++ ...s-Handle-vSES-vphy-object-during-HBA.patch | 339 ++++++++ ...s-Add-module-parameter-multipath_on_.patch | 231 +++++ ...s-Bump-driver-version-to-35.101.00.0.patch | 45 + SOURCES/9000-version-bump.patch | 22 + SPECS/kmod-redhat-mpt3sas.spec | 364 ++++++++ 37 files changed, 6719 insertions(+) create mode 100644 .gitignore create mode 100644 .kmod-redhat-mpt3sas.metadata create mode 100644 SOURCES/0001-scsi-scsi-mpt3sas-Fix-spelling-mistake.patch create mode 100644 SOURCES/0002-scsi-scsi-mpt3sas-Fix-unlock-imbalance.patch create mode 100644 SOURCES/0003-scsi-scsi-mpt3sas-Fix-error-returns-in-BRM_status_sh.patch create mode 100644 SOURCES/0004-scsi-scsi-mpt3sas-Fix-set-but-unused-variable.patch create mode 100644 SOURCES/0005-scsi-scsi-mpt3sas-Fix-kdoc-comments-format.patch create mode 100644 SOURCES/0006-scsi-scsi-mpt3sas-Memset-config_cmds.reply-buffer-wi.patch create mode 100644 SOURCES/0007-scsi-scsi-mpt3sas-Dump-system-registers-for-debuggin.patch create mode 100644 SOURCES/0008-scsi-scsi-mpt3sas-Cancel-the-running-work-during-hos.patch create mode 100644 SOURCES/0009-scsi-scsi-mpt3sas-Rename-and-export-interrupt-mask-u.patch create mode 100644 SOURCES/0010-scsi-scsi-mpt3sas-Add-functions-to-check-if-any-cmd-.patch create mode 100644 SOURCES/0011-scsi-scsi-mpt3sas-Postprocessing-of-target-and-LUN-r.patch create mode 100644 SOURCES/0012-scsi-scsi-mpt3sas-Update-driver-version-to-35.100.00.patch create mode 100644 SOURCES/0013-scsi-scsi-mpt3sas-Remove-superfluous-memset.patch create mode 100644 SOURCES/0014-scsi-scsi-mpt3sas-Remove-pci-dma-compat-wrapper-API.patch create mode 100644 SOURCES/0015-scsi-scsi-mpt3sas-Don-t-call-disable_irq-from-IRQ-po.patch create mode 100644 SOURCES/0016-scsi-scsi-mpt3sas-Detect-tampered-Aero-and-Sea-adapt.patch create mode 100644 SOURCES/0017-scsi-scsi-mpt3sas-Fix-sync-irqs.patch create mode 100644 SOURCES/0018-scsi-scsi-mpt3sas-A-small-correction-in-_base_proces.patch create mode 100644 SOURCES/0019-scsi-scsi-mpt3sas-Fix-timeouts-observed-while-reenab.patch create mode 100644 SOURCES/0020-scsi-scsi-mpt3sas-Define-hba_port-structure.patch create mode 100644 SOURCES/0021-scsi-scsi-mpt3sas-Allocate-memory-for-hba_port-objec.patch create mode 100644 SOURCES/0022-scsi-scsi-mpt3sas-Rearrange-_scsih_mark_responding_s.patch create mode 100644 SOURCES/0023-scsi-scsi-mpt3sas-Update-hba_port-s-sas_address-phy_.patch create mode 100644 SOURCES/0024-scsi-scsi-mpt3sas-Get-device-objects-using-sas_addre.patch create mode 100644 SOURCES/0025-scsi-scsi-mpt3sas-Rename-transport_del_phy_from_an_e.patch create mode 100644 SOURCES/0026-scsi-scsi-mpt3sas-Get-sas_device-objects-using-devic.patch create mode 100644 SOURCES/0027-scsi-scsi-mpt3sas-Update-hba_port-objects-after-host.patch create mode 100644 SOURCES/0028-scsi-scsi-mpt3sas-Set-valid-PhysicalPort-in-SMPPassT.patch create mode 100644 SOURCES/0029-scsi-scsi-mpt3sas-Handling-HBA-vSES-device.patch create mode 100644 SOURCES/0030-scsi-scsi-mpt3sas-Add-bypass_dirty_port_flag-paramet.patch create mode 100644 SOURCES/0031-scsi-scsi-mpt3sas-Handle-vSES-vphy-object-during-HBA.patch create mode 100644 SOURCES/0032-scsi-scsi-mpt3sas-Add-module-parameter-multipath_on_.patch create mode 100644 SOURCES/0033-scsi-scsi-mpt3sas-Bump-driver-version-to-35.101.00.0.patch create mode 100644 SOURCES/9000-version-bump.patch create mode 100644 SPECS/kmod-redhat-mpt3sas.spec diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..17b4e22 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/mpt3sas-redhat-35.101.00.00_dup8.3.tar.bz2 diff --git a/.kmod-redhat-mpt3sas.metadata b/.kmod-redhat-mpt3sas.metadata new file mode 100644 index 0000000..24ebe86 --- /dev/null +++ b/.kmod-redhat-mpt3sas.metadata @@ -0,0 +1 @@ +8fd56336803c09de449ddc220cbc2a4c0d603181 SOURCES/mpt3sas-redhat-35.101.00.00_dup8.3.tar.bz2 diff --git a/SOURCES/0001-scsi-scsi-mpt3sas-Fix-spelling-mistake.patch b/SOURCES/0001-scsi-scsi-mpt3sas-Fix-spelling-mistake.patch new file mode 100644 index 0000000..f3ba235 --- /dev/null +++ b/SOURCES/0001-scsi-scsi-mpt3sas-Fix-spelling-mistake.patch @@ -0,0 +1,57 @@ +From 0d117a6fdcb2fb322fd92fff364e5645863b2cbe Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:19 -0400 +Subject: [PATCH 01/33] [scsi] scsi: mpt3sas: Fix spelling mistake + +Message-id: <20201009140636.7976-2-thenzl@redhat.com> +Patchwork-id: 330364 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 01/18] scsi: mpt3sas: Fix spelling mistake +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +Fix typo: "tigger" --> "trigger" + +Link: https://lore.kernel.org/r/20200609161313.32098-1-f.suligoi@asem.it +Signed-off-by: Flavio Suligoi +Signed-off-by: Martin K. Petersen +(cherry picked from commit 896c9b4907c59c3f24f27ae7f2a57bda0f3476f3) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 2 +- + drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 4fca3939c034..4ff876c31272 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -1770,7 +1770,7 @@ void mpt3sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc, + void mpt3sas_process_trigger_data(struct MPT3SAS_ADAPTER *ioc, + struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data); + void mpt3sas_trigger_master(struct MPT3SAS_ADAPTER *ioc, +- u32 tigger_bitmask); ++ u32 trigger_bitmask); + void mpt3sas_trigger_event(struct MPT3SAS_ADAPTER *ioc, u16 event, + u16 log_entry_qualifier); + void mpt3sas_trigger_scsi(struct MPT3SAS_ADAPTER *ioc, u8 sense_key, +diff --git a/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h b/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h +index 6586a463bea9..405eada2669d 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h +@@ -69,7 +69,7 @@ + #define MASTER_TRIGGER_TASK_MANAGMENT (0x00000004) + #define MASTER_TRIGGER_DEVICE_REMOVAL (0x00000008) + +-/* fake firmware event for tigger */ ++/* fake firmware event for trigger */ + #define MPI3_EVENT_DIAGNOSTIC_TRIGGER_FIRED (0x6E) + + /** +-- +2.13.6 + diff --git a/SOURCES/0002-scsi-scsi-mpt3sas-Fix-unlock-imbalance.patch b/SOURCES/0002-scsi-scsi-mpt3sas-Fix-unlock-imbalance.patch new file mode 100644 index 0000000..aff86af --- /dev/null +++ b/SOURCES/0002-scsi-scsi-mpt3sas-Fix-unlock-imbalance.patch @@ -0,0 +1,90 @@ +From 2b9cc52581a6487af21aac2a978d563077390025 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:20 -0400 +Subject: [PATCH 02/33] [scsi] scsi: mpt3sas: Fix unlock imbalance + +Message-id: <20201009140636.7976-3-thenzl@redhat.com> +Patchwork-id: 330363 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 02/18] scsi: mpt3sas: Fix unlock imbalance +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +In BRM_status_show(), if the condition "!ioc->is_warpdrive" tested on entry +to the function is true, a "goto out" is called. This results in unlocking +ioc->pci_access_mutex without this mutex lock being taken. This generates +the following splat: + +[ 1148.539883] mpt3sas_cm2: BRM_status_show: BRM attribute is only for warpdrive +[ 1148.547184] +[ 1148.548708] ===================================== +[ 1148.553501] WARNING: bad unlock balance detected! +[ 1148.558277] 5.8.0-rc3+ #827 Not tainted +[ 1148.562183] ------------------------------------- +[ 1148.566959] cat/5008 is trying to release lock (&ioc->pci_access_mutex) at: +[ 1148.574035] [] BRM_status_show+0xd3/0x100 [mpt3sas] +[ 1148.580574] but there are no more locks to release! +[ 1148.585524] +[ 1148.585524] other info that might help us debug this: +[ 1148.599624] 3 locks held by cat/5008: +[ 1148.607085] #0: ffff92aea3e392c0 (&p->lock){+.+.}-{3:3}, at: seq_read+0x34/0x480 +[ 1148.618509] #1: ffff922ef14c4888 (&of->mutex){+.+.}-{3:3}, at: kernfs_seq_start+0x2a/0xb0 +[ 1148.630729] #2: ffff92aedb5d7310 (kn->active#224){.+.+}-{0:0}, at: kernfs_seq_start+0x32/0xb0 +[ 1148.643347] +[ 1148.643347] stack backtrace: +[ 1148.655259] CPU: 73 PID: 5008 Comm: cat Not tainted 5.8.0-rc3+ #827 +[ 1148.665309] Hardware name: HGST H4060-S/S2600STB, BIOS SE5C620.86B.02.01.0008.031920191559 03/19/2019 +[ 1148.678394] Call Trace: +[ 1148.684750] dump_stack+0x78/0xa0 +[ 1148.691802] lock_release.cold+0x45/0x4a +[ 1148.699451] __mutex_unlock_slowpath+0x35/0x270 +[ 1148.707675] BRM_status_show+0xd3/0x100 [mpt3sas] +[ 1148.716092] dev_attr_show+0x19/0x40 +[ 1148.723664] sysfs_kf_seq_show+0x87/0x100 +[ 1148.731193] seq_read+0xbc/0x480 +[ 1148.737882] vfs_read+0xa0/0x160 +[ 1148.744514] ksys_read+0x58/0xd0 +[ 1148.751129] do_syscall_64+0x4c/0xa0 +[ 1148.757941] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 1148.766240] RIP: 0033:0x7f1230566542 +[ 1148.772957] Code: Bad RIP value. +[ 1148.779206] RSP: 002b:00007ffeac1bcac8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 +[ 1148.790063] RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007f1230566542 +[ 1148.800284] RDX: 0000000000020000 RSI: 00007f1223460000 RDI: 0000000000000003 +[ 1148.810474] RBP: 00007f1223460000 R08: 00007f122345f010 R09: 0000000000000000 +[ 1148.820641] R10: 0000000000000022 R11: 0000000000000246 R12: 0000000000000000 +[ 1148.830728] R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000 + +Fix this by returning immediately instead of jumping to the out label. + +Link: https://lore.kernel.org/r/20200701085254.51740-1-damien.lemoal@wdc.com +Reviewed-by: Johannes Thumshirn +Acked-by: Sreekanth Reddy +Signed-off-by: Damien Le Moal +Signed-off-by: Martin K. Petersen +(cherry picked from commit cb551b8dc079d2ef189145782627c99cb68c0255) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_ctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index 62e552838565..e94e72de2fc6 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -3145,7 +3145,7 @@ BRM_status_show(struct device *cdev, struct device_attribute *attr, + if (!ioc->is_warpdrive) { + ioc_err(ioc, "%s: BRM attribute is only for warpdrive\n", + __func__); +- goto out; ++ return 0; + } + /* pci_access_mutex lock acquired by sysfs show path */ + mutex_lock(&ioc->pci_access_mutex); +-- +2.13.6 + diff --git a/SOURCES/0003-scsi-scsi-mpt3sas-Fix-error-returns-in-BRM_status_sh.patch b/SOURCES/0003-scsi-scsi-mpt3sas-Fix-error-returns-in-BRM_status_sh.patch new file mode 100644 index 0000000..fed801d --- /dev/null +++ b/SOURCES/0003-scsi-scsi-mpt3sas-Fix-error-returns-in-BRM_status_sh.patch @@ -0,0 +1,89 @@ +From 991921b40a30e900fd436eb48932de2759ea5e2e Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:21 -0400 +Subject: [PATCH 03/33] [scsi] scsi: mpt3sas: Fix error returns in + BRM_status_show + +Message-id: <20201009140636.7976-4-thenzl@redhat.com> +Patchwork-id: 330358 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 03/18] scsi: mpt3sas: Fix error returns in BRM_status_show +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +BRM_status_show() has several error branches, but none of them record the +error in the error return. + +Also while at it remove the manual mutex_unlock() of the pci_access_mutex +in case of an ongoing pci error recovery or host removal and jump to the +cleanup label instead. + +Note: We can safely jump to out from here as io_unit_pg3 is initialized to +NULL and if it hasn't been allocated, kfree() skips the NULL pointer. + +[mkp: compilation warning] + +Link: https://lore.kernel.org/r/20200701131454.5255-1-johannes.thumshirn@wdc.com +Reviewed-by: Damien Le Moal +Acked-by: Sreekanth Reddy +Signed-off-by: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +(cherry picked from commit 0fd181456aa0826057adbfb6c79c40f4083cfd75) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_ctl.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index e94e72de2fc6..983e568ff231 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -3149,15 +3149,14 @@ BRM_status_show(struct device *cdev, struct device_attribute *attr, + } + /* pci_access_mutex lock acquired by sysfs show path */ + mutex_lock(&ioc->pci_access_mutex); +- if (ioc->pci_error_recovery || ioc->remove_host) { +- mutex_unlock(&ioc->pci_access_mutex); +- return 0; +- } ++ if (ioc->pci_error_recovery || ioc->remove_host) ++ goto out; + + /* allocate upto GPIOVal 36 entries */ + sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36); + io_unit_pg3 = kzalloc(sz, GFP_KERNEL); + if (!io_unit_pg3) { ++ rc = -ENOMEM; + ioc_err(ioc, "%s: failed allocating memory for iounit_pg3: (%d) bytes\n", + __func__, sz); + goto out; +@@ -3167,6 +3166,7 @@ BRM_status_show(struct device *cdev, struct device_attribute *attr, + 0) { + ioc_err(ioc, "%s: failed reading iounit_pg3\n", + __func__); ++ rc = -EINVAL; + goto out; + } + +@@ -3174,12 +3174,14 @@ BRM_status_show(struct device *cdev, struct device_attribute *attr, + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { + ioc_err(ioc, "%s: iounit_pg3 failed with ioc_status(0x%04x)\n", + __func__, ioc_status); ++ rc = -EINVAL; + goto out; + } + + if (io_unit_pg3->GPIOCount < 25) { + ioc_err(ioc, "%s: iounit_pg3->GPIOCount less than 25 entries, detected (%d) entries\n", + __func__, io_unit_pg3->GPIOCount); ++ rc = -EINVAL; + goto out; + } + +-- +2.13.6 + diff --git a/SOURCES/0004-scsi-scsi-mpt3sas-Fix-set-but-unused-variable.patch b/SOURCES/0004-scsi-scsi-mpt3sas-Fix-set-but-unused-variable.patch new file mode 100644 index 0000000..89b680b --- /dev/null +++ b/SOURCES/0004-scsi-scsi-mpt3sas-Fix-set-but-unused-variable.patch @@ -0,0 +1,59 @@ +From 5c4527400712fbbde9125b6c0dd25c030d274b1d Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:22 -0400 +Subject: [PATCH 04/33] [scsi] scsi: mpt3sas: Fix set but unused variable + +Message-id: <20201009140636.7976-5-thenzl@redhat.com> +Patchwork-id: 330366 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 04/18] scsi: mpt3sas: Fix set but unused variable +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +In _config_request(), the variable issue_reset is set using the macro +mpt3sas_check_cmd_timeout() but otherwise unused, causing a compiler +warning when compiling with W=1. Avoid this warning by removing this +variable, using the function mpt3sas_base_check_cmd_timeout() directly +instead of the mpt3sas_check_cmd_timeout() macro. + +Link: https://lore.kernel.org/r/20200706123356.452135-1-damien.lemoal@wdc.com +Signed-off-by: Damien Le Moal +Signed-off-by: Martin K. Petersen +(cherry picked from commit 2eab3eb043ad60184ec49dd2d387ce942a8f6d4d) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_config.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c +index 62ddf53ab3ae..11026e0ef3d0 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_config.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_config.c +@@ -303,7 +303,6 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t + u8 retry_count, issue_host_reset = 0; + struct config_request mem; + u32 ioc_status = UINT_MAX; +- u8 issue_reset = 0; + + mutex_lock(&ioc->config_cmds.mutex); + if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) { +@@ -386,9 +385,9 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t + if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) + _config_display_some_debug(ioc, + smid, "config_request", NULL); +- mpt3sas_check_cmd_timeout(ioc, +- ioc->config_cmds.status, mpi_request, +- sizeof(Mpi2ConfigRequest_t)/4, issue_reset); ++ ioc_err(ioc, "%s: command timeout\n", __func__); ++ mpt3sas_base_check_cmd_timeout(ioc, ioc->config_cmds.status, ++ mpi_request, sizeof(Mpi2ConfigRequest_t) / 4); + retry_count++; + if (ioc->config_cmds.smid == smid) + mpt3sas_base_free_smid(ioc, smid); +-- +2.13.6 + diff --git a/SOURCES/0005-scsi-scsi-mpt3sas-Fix-kdoc-comments-format.patch b/SOURCES/0005-scsi-scsi-mpt3sas-Fix-kdoc-comments-format.patch new file mode 100644 index 0000000..96cabe2 --- /dev/null +++ b/SOURCES/0005-scsi-scsi-mpt3sas-Fix-kdoc-comments-format.patch @@ -0,0 +1,135 @@ +From a2370100396a4f123256dcd5842c26c8848f7c05 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:23 -0400 +Subject: [PATCH 05/33] [scsi] scsi: mpt3sas: Fix kdoc comments format + +Message-id: <20201009140636.7976-6-thenzl@redhat.com> +Patchwork-id: 330360 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 05/18] scsi: mpt3sas: Fix kdoc comments format +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +Fix kdoc comments format to avoid compiler warnings when compiling with +W=1. + +No functional changes. + +Link: https://lore.kernel.org/r/20200706123358.452180-1-damien.lemoal@wdc.com +Signed-off-by: Damien Le Moal +Signed-off-by: Martin K. Petersen +(cherry picked from commit 9133d27ef104207416db7a97204c0062d27f8b33) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 14 ++++++++------ + drivers/scsi/mpt3sas/mpt3sas_ctl.c | 16 ++++++++++------ + 2 files changed, 18 insertions(+), 12 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 96b78fdc6b8a..1d64524cd863 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -190,7 +190,7 @@ module_param_call(mpt3sas_fwfault_debug, _scsih_set_fwfault_debug, + + /** + * _base_readl_aero - retry readl for max three times. +- * @addr - MPT Fusion system interface register address ++ * @addr: MPT Fusion system interface register address + * + * Retry the readl() for max three times if it gets zero value + * while reading the system interface register. +@@ -817,6 +817,7 @@ mpt3sas_base_coredump_info(struct MPT3SAS_ADAPTER *ioc, u16 fault_code) + * mpt3sas_base_wait_for_coredump_completion - Wait until coredump + * completes or times out + * @ioc: per adapter object ++ * @caller: caller function name + * + * Returns 0 for success, non-zero for failure. + */ +@@ -1718,8 +1719,8 @@ _base_interrupt(int irq, void *bus_id) + + /** + * _base_irqpoll - IRQ poll callback handler +- * @irqpoll - irq_poll object +- * @budget - irq poll weight ++ * @irqpoll: irq_poll object ++ * @budget: irq poll weight + * + * returns number of reply descriptors processed + */ +@@ -3048,8 +3049,8 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) + + /** + * _base_check_and_enable_high_iops_queues - enable high iops mode +- * @ ioc - per adapter object +- * @ hba_msix_vector_count - msix vectors supported by HBA ++ * @ioc: per adapter object ++ * @hba_msix_vector_count: msix vectors supported by HBA + * + * Enable high iops queues only if + * - HBA is a SEA/AERO controller and +@@ -5621,6 +5622,7 @@ _base_wait_on_iocstate(struct MPT3SAS_ADAPTER *ioc, u32 ioc_state, int timeout) + * _base_wait_for_doorbell_int - waiting for controller interrupt(generated by + * a write to the doorbell) + * @ioc: per adapter object ++ * @timeout: timeout in seconds + * + * Return: 0 for success, non-zero for failure. + * +@@ -5833,7 +5835,7 @@ _base_send_ioc_reset(struct MPT3SAS_ADAPTER *ioc, u8 reset_type, int timeout) + /** + * mpt3sas_wait_for_ioc - IOC's operational state is checked here. + * @ioc: per adapter object +- * @wait_count: timeout in seconds ++ * @timeout: timeout in seconds + * + * Return: Waits up to timeout seconds for the IOC to + * become operational. Returns 0 if IOC is present +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index 983e568ff231..43260306668c 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -3662,8 +3662,9 @@ static DEVICE_ATTR_RW(diag_trigger_mpi); + + /** + * drv_support_bitmap_show - driver supported feature bitmap +- * @cdev - pointer to embedded class device +- * @buf - the buffer returned ++ * @cdev: pointer to embedded class device ++ * @attr: unused ++ * @buf: the buffer returned + * + * A sysfs 'read-only' shost attribute. + */ +@@ -3680,8 +3681,9 @@ static DEVICE_ATTR_RO(drv_support_bitmap); + + /** + * enable_sdev_max_qd_show - display whether sdev max qd is enabled/disabled +- * @cdev - pointer to embedded class device +- * @buf - the buffer returned ++ * @cdev: pointer to embedded class device ++ * @attr: unused ++ * @buf: the buffer returned + * + * A sysfs read/write shost attribute. This attribute is used to set the + * targets queue depth to HBA IO queue depth if this attribute is enabled. +@@ -3698,8 +3700,10 @@ enable_sdev_max_qd_show(struct device *cdev, + + /** + * enable_sdev_max_qd_store - Enable/disable sdev max qd +- * @cdev - pointer to embedded class device +- * @buf - the buffer returned ++ * @cdev: pointer to embedded class device ++ * @attr: unused ++ * @buf: the buffer returned ++ * @count: unused + * + * A sysfs read/write shost attribute. This attribute is used to set the + * targets queue depth to HBA IO queue depth if this attribute is enabled. +-- +2.13.6 + diff --git a/SOURCES/0006-scsi-scsi-mpt3sas-Memset-config_cmds.reply-buffer-wi.patch b/SOURCES/0006-scsi-scsi-mpt3sas-Memset-config_cmds.reply-buffer-wi.patch new file mode 100644 index 0000000..ef47206 --- /dev/null +++ b/SOURCES/0006-scsi-scsi-mpt3sas-Memset-config_cmds.reply-buffer-wi.patch @@ -0,0 +1,50 @@ +From e72e2a468d703f2cd4be3d05a0562cf6fe683952 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:24 -0400 +Subject: [PATCH 06/33] [scsi] scsi: mpt3sas: Memset config_cmds.reply buffer + with zeros + +Message-id: <20201009140636.7976-7-thenzl@redhat.com> +Patchwork-id: 330359 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 06/18] scsi: mpt3sas: Memset config_cmds.reply buffer with zeros +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +Currently config_cmds.reply buffer is not memset to zero before posting +config page request message. In some cases, for the current config +request, the previous config reply is getting processed and we will observe +PageType mismatch between request to reply buffer. It will be difficult to +debug this type of issue and it confuses by thinking that HBA Firmware +itself posted the wrong config reply. So it is better to memset the +config_cmds.reply buffer with zeros before issuing the config request. + +Link: https://lore.kernel.org/r/1596096229-3341-2-git-send-email-suganath-prabu.subramani@broadcom.com +Signed-off-by: Suganath Prabu S +Signed-off-by: Martin K. Petersen +(cherry picked from commit f09219e48b401c961f9d2f8f97a0c0b55b7894e1) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c +index 11026e0ef3d0..4a0ddc7c95e4 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_config.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_config.c +@@ -371,7 +371,7 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t + } + + r = 0; +- memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t)); ++ memset(ioc->config_cmds.reply, 0, sizeof(Mpi2ConfigReply_t)); + ioc->config_cmds.status = MPT3_CMD_PENDING; + config_request = mpt3sas_base_get_msg_frame(ioc, smid); + ioc->config_cmds.smid = smid; +-- +2.13.6 + diff --git a/SOURCES/0007-scsi-scsi-mpt3sas-Dump-system-registers-for-debuggin.patch b/SOURCES/0007-scsi-scsi-mpt3sas-Dump-system-registers-for-debuggin.patch new file mode 100644 index 0000000..b426325 --- /dev/null +++ b/SOURCES/0007-scsi-scsi-mpt3sas-Dump-system-registers-for-debuggin.patch @@ -0,0 +1,85 @@ +From a8d65a860991cc816cdf1a03ce90e3d7aa41cd2c Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:25 -0400 +Subject: [PATCH 07/33] [scsi] scsi: mpt3sas: Dump system registers for + debugging + +Message-id: <20201009140636.7976-8-thenzl@redhat.com> +Patchwork-id: 330362 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 07/18] scsi: mpt3sas: Dump system registers for debugging +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +When controller fails to transition to READY state during driver probe, +dump the system interface register set. This will give snapshot of the +firmware status for debugging driver load issues. + +Link: https://lore.kernel.org/r/1596096229-3341-3-git-send-email-suganath-prabu.subramani@broadcom.com +Signed-off-by: Suganath Prabu S +Signed-off-by: Martin K. Petersen +(cherry picked from commit af6ec1eee5ed680df0b5e0e49aa6b2673ef6e237) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 1d64524cd863..712f7f1cb219 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -5619,6 +5619,23 @@ _base_wait_on_iocstate(struct MPT3SAS_ADAPTER *ioc, u32 ioc_state, int timeout) + } + + /** ++ * _base_dump_reg_set - This function will print hexdump of register set. ++ * @ioc: per adapter object ++ * ++ * Returns nothing. ++ */ ++static inline void ++_base_dump_reg_set(struct MPT3SAS_ADAPTER *ioc) ++{ ++ unsigned int i, sz = 256; ++ u32 __iomem *reg = (u32 __iomem *)ioc->chip; ++ ++ ioc_info(ioc, "System Register set:\n"); ++ for (i = 0; i < (sz / sizeof(u32)); i++) ++ pr_info("%08x: %08x\n", (i * 4), readl(®[i])); ++} ++ ++/** + * _base_wait_for_doorbell_int - waiting for controller interrupt(generated by + * a write to the doorbell) + * @ioc: per adapter object +@@ -6797,6 +6814,7 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc) + if (count++ > 20) { + ioc_info(ioc, + "Stop writing magic sequence after 20 retries\n"); ++ _base_dump_reg_set(ioc); + goto out; + } + +@@ -6825,6 +6843,7 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc) + if (host_diagnostic == 0xFFFFFFFF) { + ioc_info(ioc, + "Invalid host diagnostic register value\n"); ++ _base_dump_reg_set(ioc); + goto out; + } + if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER)) +@@ -6859,6 +6878,7 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc) + if (ioc_state) { + ioc_err(ioc, "%s: failed going to ready state (ioc_state=0x%x)\n", + __func__, ioc_state); ++ _base_dump_reg_set(ioc); + goto out; + } + +-- +2.13.6 + diff --git a/SOURCES/0008-scsi-scsi-mpt3sas-Cancel-the-running-work-during-hos.patch b/SOURCES/0008-scsi-scsi-mpt3sas-Cancel-the-running-work-during-hos.patch new file mode 100644 index 0000000..c9357ea --- /dev/null +++ b/SOURCES/0008-scsi-scsi-mpt3sas-Cancel-the-running-work-during-hos.patch @@ -0,0 +1,139 @@ +From 5bbc3c6ca3bae6952d472ad5ea3f18241153252f Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:26 -0400 +Subject: [PATCH 08/33] [scsi] scsi: mpt3sas: Cancel the running work during + host reset + +Message-id: <20201009140636.7976-9-thenzl@redhat.com> +Patchwork-id: 330361 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 08/18] scsi: mpt3sas: Cancel the running work during host reset +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +It is not recommended to issue back-to-back host reset without any delay. +However, if someone issues back-to-back host reset then we observe that +target devices get unregistered and re-register with SML. And if OS drive +is behind the HBA when it gets unregistered, then file-system goes into +read-only mode. + +Normally during host reset, driver marks accessible target devices as +responding and triggers the event MPT3SAS_REMOVE_UNRESPONDING_DEVICES to +remove any non-responding devices through FW worker thread. While +processing this event, driver unregisters the non-responding devices and +clears the responding flag for all the devices. + +Currently, during host reset, driver is cancelling only those Firmware +event works which are pending in Firmware event workqueue. It is not +cancelling work which is currently running. Change the driver to cancel all +events. + +Link: https://lore.kernel.org/r/1596096229-3341-4-git-send-email-suganath-prabu.subramani@broadcom.com +Signed-off-by: Suganath Prabu S +Signed-off-by: Martin K. Petersen +(cherry picked from commit 9e73ed2e4cf51878ad2e5c5cff6146844f5960b7) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++++ + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 17 ++++++++++++----- + 2 files changed, 16 insertions(+), 5 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 4ff876c31272..2718207dfe17 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -1036,6 +1036,8 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); + * @firmware_event_thread: "" + * @fw_event_lock: + * @fw_event_list: list of fw events ++ * @current_evet: current processing firmware event ++ * @fw_event_cleanup: set to one while cleaning up the fw events + * @aen_event_read_flag: event log was read + * @broadcast_aen_busy: broadcast aen waiting to be serviced + * @shost_recovery: host reset in progress +@@ -1217,6 +1219,8 @@ struct MPT3SAS_ADAPTER { + struct workqueue_struct *firmware_event_thread; + spinlock_t fw_event_lock; + struct list_head fw_event_list; ++ struct fw_event_work *current_event; ++ u8 fw_events_cleanup; + + /* misc flags */ + int aen_event_read_flag; +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 5a81581665a3..51965b80a51f 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -3323,11 +3323,13 @@ _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc) + { + struct fw_event_work *fw_event; + +- if (list_empty(&ioc->fw_event_list) || ++ if ((list_empty(&ioc->fw_event_list) && !ioc->current_event) || + !ioc->firmware_event_thread || in_interrupt()) + return; + +- while ((fw_event = dequeue_next_fw_event(ioc))) { ++ ioc->fw_events_cleanup = 1; ++ while ((fw_event = dequeue_next_fw_event(ioc)) || ++ (fw_event = ioc->current_event)) { + /* + * Wait on the fw_event to complete. If this returns 1, then + * the event was never executed, and we need a put for the +@@ -3341,6 +3343,7 @@ _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc) + + fw_event_work_put(fw_event); + } ++ ioc->fw_events_cleanup = 0; + } + + /** +@@ -9421,11 +9424,13 @@ mpt3sas_scsih_reset_done_handler(struct MPT3SAS_ADAPTER *ioc) + static void + _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) + { ++ ioc->current_event = fw_event; + _scsih_fw_event_del_from_list(ioc, fw_event); + + /* the queue is being flushed so ignore this event */ + if (ioc->remove_host || ioc->pci_error_recovery) { + fw_event_work_put(fw_event); ++ ioc->current_event = NULL; + return; + } + +@@ -9439,10 +9444,10 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) + while (scsi_host_in_recovery(ioc->shost) || + ioc->shost_recovery) { + /* +- * If we're unloading, bail. Otherwise, this can become +- * an infinite loop. ++ * If we're unloading or cancelling the work, bail. ++ * Otherwise, this can become an infinite loop. + */ +- if (ioc->remove_host) ++ if (ioc->remove_host || ioc->fw_events_cleanup) + goto out; + ssleep(1); + } +@@ -9503,11 +9508,13 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) + break; + case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST: + _scsih_pcie_topology_change_event(ioc, fw_event); ++ ioc->current_event = NULL; + return; + break; + } + out: + fw_event_work_put(fw_event); ++ ioc->current_event = NULL; + } + + /** +-- +2.13.6 + diff --git a/SOURCES/0009-scsi-scsi-mpt3sas-Rename-and-export-interrupt-mask-u.patch b/SOURCES/0009-scsi-scsi-mpt3sas-Rename-and-export-interrupt-mask-u.patch new file mode 100644 index 0000000..b4e0ff7 --- /dev/null +++ b/SOURCES/0009-scsi-scsi-mpt3sas-Rename-and-export-interrupt-mask-u.patch @@ -0,0 +1,140 @@ +From 800d934ea23483775f078f5577eef196c1af0c11 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:27 -0400 +Subject: [PATCH 09/33] [scsi] scsi: mpt3sas: Rename and export interrupt + mask/unmask functions + +Message-id: <20201009140636.7976-10-thenzl@redhat.com> +Patchwork-id: 330374 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 09/18] scsi: mpt3sas: Rename and export interrupt mask/unmask functions +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +Rename Function _base_unmask_interrupts() to +mpt3sas_base_unmask_interrupts() and _base_mask_interrupts() to +mpt3sas_base_mask_interrupts(). Also add function declarion to +mpt3sas_base.h + +Link: https://lore.kernel.org/r/1596096229-3341-5-git-send-email-suganath-prabu.subramani@broadcom.com +Signed-off-by: Suganath Prabu S +Signed-off-by: Martin K. Petersen +(cherry picked from commit 5afa9d4444070ec313672bc7009315a951c28200) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 24 +++++++++++------------- + drivers/scsi/mpt3sas/mpt3sas_base.h | 2 ++ + 2 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 712f7f1cb219..7f0de6a96b88 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -129,8 +129,6 @@ _base_wait_on_iocstate(struct MPT3SAS_ADAPTER *ioc, + static int + _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc); + static void +-_base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc); +-static void + _base_clear_outstanding_commands(struct MPT3SAS_ADAPTER *ioc); + + /** +@@ -680,7 +678,7 @@ _base_fault_reset_work(struct work_struct *work) + ioc->shost_recovery = 1; + spin_unlock_irqrestore( + &ioc->ioc_reset_in_progress_lock, flags); +- _base_mask_interrupts(ioc); ++ mpt3sas_base_mask_interrupts(ioc); + _base_clear_outstanding_commands(ioc); + } + +@@ -1466,13 +1464,13 @@ _base_get_cb_idx(struct MPT3SAS_ADAPTER *ioc, u16 smid) + } + + /** +- * _base_mask_interrupts - disable interrupts ++ * mpt3sas_base_mask_interrupts - disable interrupts + * @ioc: per adapter object + * + * Disabling ResetIRQ, Reply and Doorbell Interrupts + */ +-static void +-_base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc) ++void ++mpt3sas_base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc) + { + u32 him_register; + +@@ -1484,13 +1482,13 @@ _base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc) + } + + /** +- * _base_unmask_interrupts - enable interrupts ++ * mpt3sas_base_unmask_interrupts - enable interrupts + * @ioc: per adapter object + * + * Enabling only Reply Interrupts + */ +-static void +-_base_unmask_interrupts(struct MPT3SAS_ADAPTER *ioc) ++void ++mpt3sas_base_unmask_interrupts(struct MPT3SAS_ADAPTER *ioc) + { + u32 him_register; + +@@ -3372,7 +3370,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) + goto out_fail; + } + +- _base_mask_interrupts(ioc); ++ mpt3sas_base_mask_interrupts(ioc); + + r = _base_get_ioc_facts(ioc); + if (r) { +@@ -7121,7 +7119,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc) + + skip_init_reply_post_host_index: + +- _base_unmask_interrupts(ioc); ++ mpt3sas_base_unmask_interrupts(ioc); + + if (ioc->hba_mpi_version_belonged != MPI2_VERSION) { + r = _base_display_fwpkg_version(ioc); +@@ -7170,7 +7168,7 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc) + /* synchronizing freeing resource with pci_access_mutex lock */ + mutex_lock(&ioc->pci_access_mutex); + if (ioc->chip_phys && ioc->chip) { +- _base_mask_interrupts(ioc); ++ mpt3sas_base_mask_interrupts(ioc); + ioc->shost_recovery = 1; + _base_make_ioc_ready(ioc, SOFT_RESET); + ioc->shost_recovery = 0; +@@ -7736,7 +7734,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, + } + _base_pre_reset_handler(ioc); + mpt3sas_wait_for_commands_to_complete(ioc); +- _base_mask_interrupts(ioc); ++ mpt3sas_base_mask_interrupts(ioc); + r = _base_make_ioc_ready(ioc, type); + if (r) + goto out; +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 2718207dfe17..d3062de217c6 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -1529,6 +1529,8 @@ __le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, + void *mpt3sas_base_get_pcie_sgl(struct MPT3SAS_ADAPTER *ioc, u16 smid); + dma_addr_t mpt3sas_base_get_pcie_sgl_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid); + void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc); ++void mpt3sas_base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc); ++void mpt3sas_base_unmask_interrupts(struct MPT3SAS_ADAPTER *ioc); + + void mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, + u16 handle); +-- +2.13.6 + diff --git a/SOURCES/0010-scsi-scsi-mpt3sas-Add-functions-to-check-if-any-cmd-.patch b/SOURCES/0010-scsi-scsi-mpt3sas-Add-functions-to-check-if-any-cmd-.patch new file mode 100644 index 0000000..eab18a9 --- /dev/null +++ b/SOURCES/0010-scsi-scsi-mpt3sas-Add-functions-to-check-if-any-cmd-.patch @@ -0,0 +1,243 @@ +From c5f66ce1fe8556c98df0c2ebdf0d300adb042742 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:28 -0400 +Subject: [PATCH 10/33] [scsi] scsi: mpt3sas: Add functions to check if any cmd + is outstanding on Target and LUN + +Message-id: <20201009140636.7976-11-thenzl@redhat.com> +Patchwork-id: 330365 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 10/18] scsi: mpt3sas: Add functions to check if any cmd is outstanding on Target and LUN +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +Add helper functions to check whether any SCSI command is outstanding on +particular Target, LUN device. + +Also add function parameters 'channel', 'id' to function +mpt3sas_scsih_issue_tm(). + +Link: https://lore.kernel.org/r/1596096229-3341-6-git-send-email-suganath-prabu.subramani@broadcom.com +Signed-off-by: Suganath Prabu S +Signed-off-by: Martin K. Petersen +(cherry picked from commit 521e9c0b62860ed3b6899c771c1ab82b51009311) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 9 ++-- + drivers/scsi/mpt3sas/mpt3sas_ctl.c | 6 ++- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 92 +++++++++++++++++++++++++++++++----- + 3 files changed, 88 insertions(+), 19 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index d3062de217c6..bd892230a87b 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -1610,11 +1610,12 @@ void mpt3sas_scsih_clear_outstanding_scsi_tm_commands( + struct MPT3SAS_ADAPTER *ioc); + void mpt3sas_scsih_reset_done_handler(struct MPT3SAS_ADAPTER *ioc); + +-int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, u64 lun, +- u8 type, u16 smid_task, u16 msix_task, u8 timeout, u8 tr_method); ++int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ uint channel, uint id, u64 lun, u8 type, u16 smid_task, ++ u16 msix_task, u8 timeout, u8 tr_method); + int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, +- u64 lun, u8 type, u16 smid_task, u16 msix_task, +- u8 timeout, u8 tr_method); ++ uint channel, uint id, u64 lun, u8 type, u16 smid_task, ++ u16 msix_task, u8 timeout, u8 tr_method); + + void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle); + void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle); +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index 43260306668c..194ac9d03bc9 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -1109,13 +1109,15 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + pcie_device->device_info)))) + mpt3sas_scsih_issue_locked_tm(ioc, + le16_to_cpu(mpi_request->FunctionDependent1), +- 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, ++ 0, 0, 0, ++ MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, + 0, pcie_device->reset_timeout, + MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE); + else + mpt3sas_scsih_issue_locked_tm(ioc, + le16_to_cpu(mpi_request->FunctionDependent1), +- 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, ++ 0, 0, 0, ++ MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, + 0, 30, MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET); + } else + mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 51965b80a51f..83bef0809f47 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -1513,6 +1513,66 @@ _scsih_is_nvme_pciescsi_device(u32 device_info) + } + + /** ++ * _scsih_scsi_lookup_find_by_target - search for matching channel:id ++ * @ioc: per adapter object ++ * @id: target id ++ * @channel: channel ++ * Context: This function will acquire ioc->scsi_lookup_lock. ++ * ++ * This will search for a matching channel:id in the scsi_lookup array, ++ * returning 1 if found. ++ */ ++static u8 ++_scsih_scsi_lookup_find_by_target(struct MPT3SAS_ADAPTER *ioc, int id, ++ int channel) ++{ ++ int smid; ++ struct scsi_cmnd *scmd; ++ ++ for (smid = 1; ++ smid <= ioc->shost->can_queue; smid++) { ++ scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid); ++ if (!scmd) ++ continue; ++ if (scmd->device->id == id && ++ scmd->device->channel == channel) ++ return 1; ++ } ++ return 0; ++} ++ ++/** ++ * _scsih_scsi_lookup_find_by_lun - search for matching channel:id:lun ++ * @ioc: per adapter object ++ * @id: target id ++ * @lun: lun number ++ * @channel: channel ++ * Context: This function will acquire ioc->scsi_lookup_lock. ++ * ++ * This will search for a matching channel:id:lun in the scsi_lookup array, ++ * returning 1 if found. ++ */ ++static u8 ++_scsih_scsi_lookup_find_by_lun(struct MPT3SAS_ADAPTER *ioc, int id, ++ unsigned int lun, int channel) ++{ ++ int smid; ++ struct scsi_cmnd *scmd; ++ ++ for (smid = 1; smid <= ioc->shost->can_queue; smid++) { ++ ++ scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid); ++ if (!scmd) ++ continue; ++ if (scmd->device->id == id && ++ scmd->device->channel == channel && ++ scmd->device->lun == lun) ++ return 1; ++ } ++ return 0; ++} ++ ++/** + * mpt3sas_scsih_scsi_lookup_get - returns scmd entry + * @ioc: per adapter object + * @smid: system request message index +@@ -2704,6 +2764,8 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle) + * mpt3sas_scsih_issue_tm - main routine for sending tm requests + * @ioc: per adapter struct + * @handle: device handle ++ * @channel: the channel assigned by the OS ++ * @id: the id assigned by the OS + * @lun: lun number + * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h) + * @smid_task: smid assigned to the task +@@ -2720,8 +2782,9 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle) + * Return: SUCCESS or FAILED. + */ + int +-mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, u64 lun, +- u8 type, u16 smid_task, u16 msix_task, u8 timeout, u8 tr_method) ++mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ++ uint id, u64 lun, u8 type, u16 smid_task, u16 msix_task, ++ u8 timeout, u8 tr_method) + { + Mpi2SCSITaskManagementRequest_t *mpi_request; + Mpi2SCSITaskManagementReply_t *mpi_reply; +@@ -2826,14 +2889,14 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, u64 lun, + } + + int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, +- u64 lun, u8 type, u16 smid_task, u16 msix_task, +- u8 timeout, u8 tr_method) ++ uint channel, uint id, u64 lun, u8 type, u16 smid_task, ++ u16 msix_task, u8 timeout, u8 tr_method) + { + int ret; + + mutex_lock(&ioc->tm_cmds.mutex); +- ret = mpt3sas_scsih_issue_tm(ioc, handle, lun, type, smid_task, +- msix_task, timeout, tr_method); ++ ret = mpt3sas_scsih_issue_tm(ioc, handle, channel, id, lun, type, ++ smid_task, msix_task, timeout, tr_method); + mutex_unlock(&ioc->tm_cmds.mutex); + + return ret; +@@ -2980,7 +3043,8 @@ scsih_abort(struct scsi_cmnd *scmd) + if (pcie_device && (!ioc->tm_custom_handling) && + (!(mpt3sas_scsih_is_pcie_scsi_device(pcie_device->device_info)))) + timeout = ioc->nvme_abort_timeout; +- r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->lun, ++ r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel, ++ scmd->device->id, scmd->device->lun, + MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, + st->smid, st->msix_io, timeout, 0); + /* Command must be cleared after abort */ +@@ -3056,7 +3120,8 @@ scsih_dev_reset(struct scsi_cmnd *scmd) + } else + tr_method = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET; + +- r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->lun, ++ r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel, ++ scmd->device->id, scmd->device->lun, + MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 0, + tr_timeout, tr_method); + /* Check for busy commands after reset */ +@@ -3134,7 +3199,8 @@ scsih_target_reset(struct scsi_cmnd *scmd) + tr_method = MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE; + } else + tr_method = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET; +- r = mpt3sas_scsih_issue_locked_tm(ioc, handle, 0, ++ r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel, ++ scmd->device->id, 0, + MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 0, + tr_timeout, tr_method); + /* Check for busy commands after reset */ +@@ -7530,7 +7596,7 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc, + goto out; + + spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); +- r = mpt3sas_scsih_issue_tm(ioc, handle, lun, ++ r = mpt3sas_scsih_issue_tm(ioc, handle, 0, 0, lun, + MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, st->smid, + st->msix_io, 30, 0); + if (r == FAILED) { +@@ -7571,9 +7637,9 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc, + if (ioc->shost_recovery) + goto out_no_lock; + +- r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->lun, +- MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, st->smid, +- st->msix_io, 30, 0); ++ r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id, ++ sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, ++ st->smid, st->msix_io, 30, 0); + if (r == FAILED || st->cb_idx != 0xFF) { + sdev_printk(KERN_WARNING, sdev, + "mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : " +-- +2.13.6 + diff --git a/SOURCES/0011-scsi-scsi-mpt3sas-Postprocessing-of-target-and-LUN-r.patch b/SOURCES/0011-scsi-scsi-mpt3sas-Postprocessing-of-target-and-LUN-r.patch new file mode 100644 index 0000000..7106b55 --- /dev/null +++ b/SOURCES/0011-scsi-scsi-mpt3sas-Postprocessing-of-target-and-LUN-r.patch @@ -0,0 +1,258 @@ +From f0241cb5899f514e51799f85fc884d30210e00a4 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:29 -0400 +Subject: [PATCH 11/33] [scsi] scsi: mpt3sas: Postprocessing of target and LUN + reset + +Message-id: <20201009140636.7976-12-thenzl@redhat.com> +Patchwork-id: 330368 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 11/18] scsi: mpt3sas: Postprocessing of target and LUN reset +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +If driver has not received the interrupt for the aborted SCSI command +before processing the TM reply, driver polls all the reply descriptor pools +looking for the reply for the aborted SCSI command before marking TM as +FAILED. If it finds the reply, then it marks the TM as SUCCESS otherwise it +marks it FAILED. + +scsih_tm_cmd_map_status() checks whether TM has aborted the timed out SCSI +command or not. If TM has aborted the IO, then it returns SUCCESS else it +returns FAILED. + +Link: https://lore.kernel.org/r/1596096229-3341-7-git-send-email-suganath-prabu.subramani@broadcom.com +Signed-off-by: Suganath Prabu S +Signed-off-by: Martin K. Petersen +(cherry picked from commit 711a923c14d9a48d15a30a2c085184954bf04931) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 6 +- + drivers/scsi/mpt3sas/mpt3sas_base.h | 2 +- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 136 ++++++++++++++++++++++++++++++++++- + 3 files changed, 139 insertions(+), 5 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 7f0de6a96b88..53a835b37fa9 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -1785,12 +1785,14 @@ _base_is_controller_msix_enabled(struct MPT3SAS_ADAPTER *ioc) + /** + * mpt3sas_base_sync_reply_irqs - flush pending MSIX interrupts + * @ioc: per adapter object ++ * @poll: poll over reply descriptor pools incase interrupt for ++ * timed-out SCSI command got delayed + * Context: non ISR conext + * + * Called when a Task Management request has completed. + */ + void +-mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc) ++mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc, u8 poll) + { + struct adapter_reply_queue *reply_q; + +@@ -1820,6 +1822,8 @@ mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc) + } + synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index)); + } ++ if (poll) ++ _base_process_reply_queue(reply_q); + } + + /** +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index bd892230a87b..87b50f59c2eb 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -1528,7 +1528,7 @@ __le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, + u16 smid); + void *mpt3sas_base_get_pcie_sgl(struct MPT3SAS_ADAPTER *ioc, u16 smid); + dma_addr_t mpt3sas_base_get_pcie_sgl_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid); +-void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc); ++void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc, u8 poll); + void mpt3sas_base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc); + void mpt3sas_base_unmask_interrupts(struct MPT3SAS_ADAPTER *ioc); + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 83bef0809f47..8e9edfd8239c 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -2761,6 +2761,96 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle) + } + + /** ++ * scsih_tm_cmd_map_status - map the target reset & LUN reset TM status ++ * @ioc - per adapter object ++ * @channel - the channel assigned by the OS ++ * @id: the id assigned by the OS ++ * @lun: lun number ++ * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h) ++ * @smid_task: smid assigned to the task ++ * ++ * Look whether TM has aborted the timed out SCSI command, if ++ * TM has aborted the IO then return SUCCESS else return FAILED. ++ */ ++static int ++scsih_tm_cmd_map_status(struct MPT3SAS_ADAPTER *ioc, uint channel, ++ uint id, uint lun, u8 type, u16 smid_task) ++{ ++ ++ if (smid_task <= ioc->shost->can_queue) { ++ switch (type) { ++ case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: ++ if (!(_scsih_scsi_lookup_find_by_target(ioc, ++ id, channel))) ++ return SUCCESS; ++ break; ++ case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: ++ case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: ++ if (!(_scsih_scsi_lookup_find_by_lun(ioc, id, ++ lun, channel))) ++ return SUCCESS; ++ break; ++ default: ++ return SUCCESS; ++ } ++ } else if (smid_task == ioc->scsih_cmds.smid) { ++ if ((ioc->scsih_cmds.status & MPT3_CMD_COMPLETE) || ++ (ioc->scsih_cmds.status & MPT3_CMD_NOT_USED)) ++ return SUCCESS; ++ } else if (smid_task == ioc->ctl_cmds.smid) { ++ if ((ioc->ctl_cmds.status & MPT3_CMD_COMPLETE) || ++ (ioc->ctl_cmds.status & MPT3_CMD_NOT_USED)) ++ return SUCCESS; ++ } ++ ++ return FAILED; ++} ++ ++/** ++ * scsih_tm_post_processing - post processing of target & LUN reset ++ * @ioc - per adapter object ++ * @handle: device handle ++ * @channel - the channel assigned by the OS ++ * @id: the id assigned by the OS ++ * @lun: lun number ++ * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h) ++ * @smid_task: smid assigned to the task ++ * ++ * Post processing of target & LUN reset. Due to interrupt latency ++ * issue it possible that interrupt for aborted IO might not be ++ * received yet. So before returning failure status, poll the ++ * reply descriptor pools for the reply of timed out SCSI command. ++ * Return FAILED status if reply for timed out is not received ++ * otherwise return SUCCESS. ++ */ ++static int ++scsih_tm_post_processing(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ uint channel, uint id, uint lun, u8 type, u16 smid_task) ++{ ++ int rc; ++ ++ rc = scsih_tm_cmd_map_status(ioc, channel, id, lun, type, smid_task); ++ if (rc == SUCCESS) ++ return rc; ++ ++ ioc_info(ioc, ++ "Poll ReplyDescriptor queues for completion of" ++ " smid(%d), task_type(0x%02x), handle(0x%04x)\n", ++ smid_task, type, handle); ++ ++ /* ++ * Due to interrupt latency issues, driver may receive interrupt for ++ * TM first and then for aborted SCSI IO command. So, poll all the ++ * ReplyDescriptor pools before returning the FAILED status to SML. ++ */ ++ mpt3sas_base_mask_interrupts(ioc); ++ mpt3sas_base_sync_reply_irqs(ioc, 1); ++ mpt3sas_base_unmask_interrupts(ioc); ++ ++ return scsih_tm_cmd_map_status(ioc, channel, id, lun, type, smid_task); ++} ++ ++/** + * mpt3sas_scsih_issue_tm - main routine for sending tm requests + * @ioc: per adapter struct + * @handle: device handle +@@ -2788,6 +2878,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, + { + Mpi2SCSITaskManagementRequest_t *mpi_request; + Mpi2SCSITaskManagementReply_t *mpi_reply; ++ Mpi25SCSIIORequest_t *request; + u16 smid = 0; + u32 ioc_state; + int rc; +@@ -2843,7 +2934,9 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, + mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; + mpi_request->DevHandle = cpu_to_le16(handle); + mpi_request->TaskType = type; +- mpi_request->MsgFlags = tr_method; ++ if (type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK || ++ type == MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) ++ mpi_request->MsgFlags = tr_method; + mpi_request->TaskMID = cpu_to_le16(smid_task); + int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); + mpt3sas_scsih_set_tm_flag(ioc, handle); +@@ -2863,7 +2956,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, + } + + /* sync IRQs in case those were busy during flush. */ +- mpt3sas_base_sync_reply_irqs(ioc); ++ mpt3sas_base_sync_reply_irqs(ioc, 0); + + if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) { + mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT); +@@ -2880,7 +2973,44 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, + sizeof(Mpi2SCSITaskManagementRequest_t)/4); + } + } +- rc = SUCCESS; ++ ++ switch (type) { ++ case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: ++ rc = SUCCESS; ++ /* ++ * If DevHandle filed in smid_task's entry of request pool ++ * doesn't match with device handle on which this task abort ++ * TM is received then it means that TM has successfully ++ * aborted the timed out command. Since smid_task's entry in ++ * request pool will be memset to zero once the timed out ++ * command is returned to the SML. If the command is not ++ * aborted then smid_task’s entry won’t be cleared and it ++ * will have same DevHandle value on which this task abort TM ++ * is received and driver will return the TM status as FAILED. ++ */ ++ request = mpt3sas_base_get_msg_frame(ioc, smid_task); ++ if (le16_to_cpu(request->DevHandle) != handle) ++ break; ++ ++ ioc_info(ioc, "Task abort tm failed: handle(0x%04x)," ++ "timeout(%d) tr_method(0x%x) smid(%d) msix_index(%d)\n", ++ handle, timeout, tr_method, smid_task, msix_task); ++ rc = FAILED; ++ break; ++ ++ case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: ++ case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: ++ case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: ++ rc = scsih_tm_post_processing(ioc, handle, channel, id, lun, ++ type, smid_task); ++ break; ++ case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK: ++ rc = SUCCESS; ++ break; ++ default: ++ rc = FAILED; ++ break; ++ } + + out: + mpt3sas_scsih_clear_tm_flag(ioc, handle); +-- +2.13.6 + diff --git a/SOURCES/0012-scsi-scsi-mpt3sas-Update-driver-version-to-35.100.00.patch b/SOURCES/0012-scsi-scsi-mpt3sas-Update-driver-version-to-35.100.00.patch new file mode 100644 index 0000000..20370a8 --- /dev/null +++ b/SOURCES/0012-scsi-scsi-mpt3sas-Update-driver-version-to-35.100.00.patch @@ -0,0 +1,46 @@ +From 57a999fa21a0696a61b23dcfdc826a7062b75861 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:30 -0400 +Subject: [PATCH 12/33] [scsi] scsi: mpt3sas: Update driver version to + 35.100.00.00 + +Message-id: <20201009140636.7976-13-thenzl@redhat.com> +Patchwork-id: 330367 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 12/18] scsi: mpt3sas: Update driver version to 35.100.00.00 +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +Updated driver version to 35.100.00.00 + +Link: https://lore.kernel.org/r/1596096229-3341-8-git-send-email-suganath-prabu.subramani@broadcom.com +Signed-off-by: Suganath Prabu S +Signed-off-by: Martin K. Petersen +(cherry picked from commit 0491bdc7ee1ec212bdb2fac8ed375283922fd828) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 87b50f59c2eb..bc8beb10f3fc 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -76,8 +76,8 @@ + #define MPT3SAS_DRIVER_NAME "mpt3sas" + #define MPT3SAS_AUTHOR "Avago Technologies " + #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" +-#define MPT3SAS_DRIVER_VERSION "34.100.00.00" +-#define MPT3SAS_MAJOR_VERSION 34 ++#define MPT3SAS_DRIVER_VERSION "35.100.00.00" ++#define MPT3SAS_MAJOR_VERSION 35 + #define MPT3SAS_MINOR_VERSION 100 + #define MPT3SAS_BUILD_VERSION 0 + #define MPT3SAS_RELEASE_VERSION 00 +-- +2.13.6 + diff --git a/SOURCES/0013-scsi-scsi-mpt3sas-Remove-superfluous-memset.patch b/SOURCES/0013-scsi-scsi-mpt3sas-Remove-superfluous-memset.patch new file mode 100644 index 0000000..df3ff55 --- /dev/null +++ b/SOURCES/0013-scsi-scsi-mpt3sas-Remove-superfluous-memset.patch @@ -0,0 +1,46 @@ +From 0ab9801eaedaa796d86505ee3022d80cf1b8d755 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:31 -0400 +Subject: [PATCH 13/33] [scsi] scsi: mpt3sas: Remove superfluous memset() + +Message-id: <20201009140636.7976-14-thenzl@redhat.com> +Patchwork-id: 330369 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 13/18] scsi: mpt3sas: Remove superfluous memset() +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +Fixes coccicheck warning: + +./drivers/scsi/mpt3sas/mpt3sas_base.c:5247:16-34: WARNING: dma_alloc_coherent use in ioc -> request already zeroes out memory, so memset is not needed + +dma_alloc_coherent() already zeroes out memory so memset() is not needed. + +Link: https://lore.kernel.org/r/1596079918-41115-4-git-send-email-liheng40@huawei.com +Signed-off-by: Li Heng +Signed-off-by: Martin K. Petersen +(cherry picked from commit 4a636e9c7a2107b9a590f08d6f8f8a917e6b85de) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 53a835b37fa9..4aae441211bd 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -5259,7 +5259,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) + _base_release_memory_pools(ioc); + goto retry_allocation; + } +- memset(ioc->request, 0, sz); + + if (retry_sz) + ioc_err(ioc, "request pool: dma_alloc_coherent succeed: hba_depth(%d), chains_per_io(%d), frame_sz(%d), total(%d kb)\n", +-- +2.13.6 + diff --git a/SOURCES/0014-scsi-scsi-mpt3sas-Remove-pci-dma-compat-wrapper-API.patch b/SOURCES/0014-scsi-scsi-mpt3sas-Remove-pci-dma-compat-wrapper-API.patch new file mode 100644 index 0000000..209acc9 --- /dev/null +++ b/SOURCES/0014-scsi-scsi-mpt3sas-Remove-pci-dma-compat-wrapper-API.patch @@ -0,0 +1,136 @@ +From 99de4d2f928d9ee96162ec22a59c764aeb065ed3 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:32 -0400 +Subject: [PATCH 14/33] [scsi] scsi: mpt3sas: Remove pci-dma-compat wrapper API + +Message-id: <20201009140636.7976-15-thenzl@redhat.com> +Patchwork-id: 330370 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 14/18] scsi: mpt3sas: Remove pci-dma-compat wrapper API +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +The legacy API wrappers in include/linux/pci-dma-compat.h should go away as +they create unnecessary midlayering for include/linux/dma-mapping.h API. +Instead use dma-mapping.h API directly. + +The patch has been generated with the coccinelle script below. Compile +tested. + +@@@@ +- PCI_DMA_BIDIRECTIONAL ++ DMA_BIDIRECTIONAL + +@@@@ +- PCI_DMA_TODEVICE ++ DMA_TO_DEVICE + +@@@@ +- PCI_DMA_FROMDEVICE ++ DMA_FROM_DEVICE + +@@@@ +- PCI_DMA_NONE ++ DMA_NONE + +@@ expression E1, E2, E3; @@ +- pci_alloc_consistent(E1, E2, E3) ++ dma_alloc_coherent(&E1->dev, E2, E3, GFP_) + +@@ expression E1, E2, E3; @@ +- pci_zalloc_consistent(E1, E2, E3) ++ dma_alloc_coherent(&E1->dev, E2, E3, GFP_) + +@@ expression E1, E2, E3, E4; @@ +- pci_free_consistent(E1, E2, E3, E4) ++ dma_free_coherent(&E1->dev, E2, E3, E4) + +@@ expression E1, E2, E3, E4; @@ +- pci_map_single(E1, E2, E3, E4) ++ dma_map_single(&E1->dev, E2, E3, E4) + +@@ expression E1, E2, E3, E4; @@ +- pci_unmap_single(E1, E2, E3, E4) ++ dma_unmap_single(&E1->dev, E2, E3, E4) + +@@ expression E1, E2, E3, E4, E5; @@ +- pci_map_page(E1, E2, E3, E4, E5) ++ dma_map_page(&E1->dev, E2, E3, E4, E5) + +@@ expression E1, E2, E3, E4; @@ +- pci_unmap_page(E1, E2, E3, E4) ++ dma_unmap_page(&E1->dev, E2, E3, E4) + +@@ expression E1, E2, E3, E4; @@ +- pci_map_sg(E1, E2, E3, E4) ++ dma_map_sg(&E1->dev, E2, E3, E4) + +@@ expression E1, E2, E3, E4; @@ +- pci_unmap_sg(E1, E2, E3, E4) ++ dma_unmap_sg(&E1->dev, E2, E3, E4) + +@@ expression E1, E2, E3, E4; @@ +- pci_dma_sync_single_for_cpu(E1, E2, E3, E4) ++ dma_sync_single_for_cpu(&E1->dev, E2, E3, E4) + +@@ expression E1, E2, E3, E4; @@ +- pci_dma_sync_single_for_device(E1, E2, E3, E4) ++ dma_sync_single_for_device(&E1->dev, E2, E3, E4) + +@@ expression E1, E2, E3, E4; @@ +- pci_dma_sync_sg_for_cpu(E1, E2, E3, E4) ++ dma_sync_sg_for_cpu(&E1->dev, E2, E3, E4) + +@@ expression E1, E2, E3, E4; @@ +- pci_dma_sync_sg_for_device(E1, E2, E3, E4) ++ dma_sync_sg_for_device(&E1->dev, E2, E3, E4) + +@@ expression E1, E2; @@ +- pci_dma_mapping_error(E1, E2) ++ dma_mapping_error(&E1->dev, E2) + +@@ expression E1, E2; @@ +- pci_set_consistent_dma_mask(E1, E2) ++ dma_set_coherent_mask(&E1->dev, E2) + +@@ expression E1, E2; @@ +- pci_set_dma_mask(E1, E2) ++ dma_set_mask(&E1->dev, E2) + +Link: https://lore.kernel.org/r/e825ac7108092cc8fa8d462dc702098ef10fc6a2.1596045683.git.usuraj35@gmail.com +Signed-off-by: Suraj Upadhyay +Signed-off-by: Martin K. Petersen +(cherry picked from commit a5a20c4a294ed3ecfe5f22f1232ce6ad2430a7d9) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_ctl.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index 194ac9d03bc9..5c32dbb8b2f0 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -3386,12 +3386,10 @@ host_trace_buffer_enable_store(struct device *cdev, + && + (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & + MPT3_DIAG_BUFFER_IS_APP_OWNED)) { +- pci_free_consistent(ioc->pdev, +- ioc->diag_buffer_sz[ +- MPI2_DIAG_BUF_TYPE_TRACE], +- ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE], +- ioc->diag_buffer_dma[ +- MPI2_DIAG_BUF_TYPE_TRACE]); ++ dma_free_coherent(&ioc->pdev->dev, ++ ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE], ++ ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE], ++ ioc->diag_buffer_dma[MPI2_DIAG_BUF_TYPE_TRACE]); + ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE] = + NULL; + } +-- +2.13.6 + diff --git a/SOURCES/0015-scsi-scsi-mpt3sas-Don-t-call-disable_irq-from-IRQ-po.patch b/SOURCES/0015-scsi-scsi-mpt3sas-Don-t-call-disable_irq-from-IRQ-po.patch new file mode 100644 index 0000000..21a81ab --- /dev/null +++ b/SOURCES/0015-scsi-scsi-mpt3sas-Don-t-call-disable_irq-from-IRQ-po.patch @@ -0,0 +1,45 @@ +From c92c9fc8098777df0c9f4180507f49fbf743aae2 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:33 -0400 +Subject: [PATCH 15/33] [scsi] scsi: mpt3sas: Don't call disable_irq from IRQ + poll handler + +Message-id: <20201009140636.7976-16-thenzl@redhat.com> +Patchwork-id: 330372 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 15/18] scsi: mpt3sas: Don't call disable_irq from IRQ poll handler +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +disable_irq() might sleep, replace it with disable_irq_nosync(). For +synchronisation 'irq_poll_scheduled' is sufficient + +Fixes: 320e77acb3 scsi: mpt3sas: Irq poll to avoid CPU hard lockups +Link: https://lore.kernel.org/r/20200901145026.12174-1-thenzl@redhat.com +Signed-off-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +(cherry picked from commit b614d55b970d08bcac5b0bc15a5526181b3e4459) +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 4aae441211bd..24dd90a72a80 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -1731,7 +1731,7 @@ _base_irqpoll(struct irq_poll *irqpoll, int budget) + reply_q = container_of(irqpoll, struct adapter_reply_queue, + irqpoll); + if (reply_q->irq_line_enable) { +- disable_irq(reply_q->os_irq); ++ disable_irq_nosync(reply_q->os_irq); + reply_q->irq_line_enable = false; + } + num_entries = _base_process_reply_queue(reply_q); +-- +2.13.6 + diff --git a/SOURCES/0016-scsi-scsi-mpt3sas-Detect-tampered-Aero-and-Sea-adapt.patch b/SOURCES/0016-scsi-scsi-mpt3sas-Detect-tampered-Aero-and-Sea-adapt.patch new file mode 100644 index 0000000..b3788bf --- /dev/null +++ b/SOURCES/0016-scsi-scsi-mpt3sas-Detect-tampered-Aero-and-Sea-adapt.patch @@ -0,0 +1,270 @@ +From a8fa1817bd98ccc79eefa6b2e779afb3be6b2e56 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:34 -0400 +Subject: [PATCH 16/33] [scsi] scsi: mpt3sas: Detect tampered Aero and Sea + adapters + +Message-id: <20201009140636.7976-17-thenzl@redhat.com> +Patchwork-id: 330371 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 16/18] scsi: mpt3sas: Detect tampered Aero and Sea adapters +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +The driver will throw an error message when a tampered type controller +is detected. The intent is to avoid interacting with any firmware +which is not secured/signed by Broadcom. Any tampering on firmware +component will be detected by hardware and it will be communicated to +the driver to avoid any further interaction with that component. + +[mkp: switched back to dev_err] + +Link: https://lore.kernel.org/r/20200814130426.2741171-1-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit f38c43a0e9007e1f21a47a199643a16666902928) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 121 ++++++++++++++++++++++++++++++----- + 1 file changed, 105 insertions(+), 16 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 8e9edfd8239c..8c14908e39ca 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -10092,6 +10092,34 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc) + } + + /** ++ * _scsih_get_shost_and_ioc - get shost and ioc ++ * and verify whether they are NULL or not ++ * @pdev: PCI device struct ++ * @shost: address of scsi host pointer ++ * @ioc: address of HBA adapter pointer ++ * ++ * Return zero if *shost and *ioc are not NULL otherwise return error number. ++ */ ++static int ++_scsih_get_shost_and_ioc(struct pci_dev *pdev, ++ struct Scsi_Host **shost, struct MPT3SAS_ADAPTER **ioc) ++{ ++ *shost = pci_get_drvdata(pdev); ++ if (*shost == NULL) { ++ dev_err(&pdev->dev, "pdev's driver data is null\n"); ++ return -ENXIO; ++ } ++ ++ *ioc = shost_priv(*shost); ++ if (*ioc == NULL) { ++ dev_err(&pdev->dev, "shost's private data is null\n"); ++ return -ENXIO; ++ } ++ ++ return 0; ++} ++ ++/** + * scsih_remove - detach and remove add host + * @pdev: PCI device struct + * +@@ -10099,8 +10127,8 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc) + */ + static void scsih_remove(struct pci_dev *pdev) + { +- struct Scsi_Host *shost = pci_get_drvdata(pdev); +- struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; + struct _sas_port *mpt3sas_port, *next_port; + struct _raid_device *raid_device, *next; + struct MPT3SAS_TARGET *sas_target_priv_data; +@@ -10109,6 +10137,9 @@ static void scsih_remove(struct pci_dev *pdev) + unsigned long flags; + Mpi2ConfigReply_t mpi_reply; + ++ if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc)) ++ return; ++ + ioc->remove_host = 1; + + if (!pci_device_is_present(pdev)) +@@ -10188,12 +10219,15 @@ static void scsih_remove(struct pci_dev *pdev) + static void + scsih_shutdown(struct pci_dev *pdev) + { +- struct Scsi_Host *shost = pci_get_drvdata(pdev); +- struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; + struct workqueue_struct *wq; + unsigned long flags; + Mpi2ConfigReply_t mpi_reply; + ++ if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc)) ++ return; ++ + ioc->remove_host = 1; + + if (!pci_device_is_present(pdev)) +@@ -10764,6 +10798,10 @@ _scsih_determine_hba_mpi_version(struct pci_dev *pdev) + case MPI26_MFGPAGE_DEVID_HARD_SEC_3916: + case MPI26_MFGPAGE_DEVID_CFG_SEC_3816: + case MPI26_MFGPAGE_DEVID_HARD_SEC_3816: ++ case MPI26_MFGPAGE_DEVID_INVALID0_3916: ++ case MPI26_MFGPAGE_DEVID_INVALID1_3916: ++ case MPI26_MFGPAGE_DEVID_INVALID0_3816: ++ case MPI26_MFGPAGE_DEVID_INVALID1_3816: + return MPI26_VERSION; + } + return 0; +@@ -10853,6 +10891,20 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) + case MPI26_ATLAS_PCIe_SWITCH_DEVID: + ioc->is_gen35_ioc = 1; + break; ++ case MPI26_MFGPAGE_DEVID_INVALID0_3816: ++ case MPI26_MFGPAGE_DEVID_INVALID0_3916: ++ dev_err(&pdev->dev, ++ "HBA with DeviceId 0x%04x, sub VendorId 0x%04x, sub DeviceId 0x%04x is Invalid", ++ pdev->device, pdev->subsystem_vendor, ++ pdev->subsystem_device); ++ return 1; ++ case MPI26_MFGPAGE_DEVID_INVALID1_3816: ++ case MPI26_MFGPAGE_DEVID_INVALID1_3916: ++ dev_err(&pdev->dev, ++ "HBA with DeviceId 0x%04x, sub VendorId 0x%04x, sub DeviceId 0x%04x is Tampered", ++ pdev->device, pdev->subsystem_vendor, ++ pdev->subsystem_device); ++ return 1; + case MPI26_MFGPAGE_DEVID_CFG_SEC_3816: + case MPI26_MFGPAGE_DEVID_CFG_SEC_3916: + dev_info(&pdev->dev, +@@ -11044,9 +11096,14 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) + static int + scsih_suspend(struct pci_dev *pdev, pm_message_t state) + { +- struct Scsi_Host *shost = pci_get_drvdata(pdev); +- struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; + pci_power_t device_state; ++ int rc; ++ ++ rc = _scsih_get_shost_and_ioc(pdev, &shost, &ioc); ++ if (rc) ++ return rc; + + mpt3sas_base_stop_watchdog(ioc); + flush_scheduled_work(); +@@ -11071,11 +11128,15 @@ scsih_suspend(struct pci_dev *pdev, pm_message_t state) + static int + scsih_resume(struct pci_dev *pdev) + { +- struct Scsi_Host *shost = pci_get_drvdata(pdev); +- struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; + pci_power_t device_state = pdev->current_state; + int r; + ++ r = _scsih_get_shost_and_ioc(pdev, &shost, &ioc); ++ if (r) ++ return r; ++ + ioc_info(ioc, "pdev=0x%p, slot=%s, previous operating state [D%d]\n", + pdev, pci_name(pdev), device_state); + +@@ -11106,8 +11167,11 @@ scsih_resume(struct pci_dev *pdev) + static pci_ers_result_t + scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) + { +- struct Scsi_Host *shost = pci_get_drvdata(pdev); +- struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; ++ ++ if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc)) ++ return PCI_ERS_RESULT_DISCONNECT; + + ioc_info(ioc, "PCI error: detected callback, state(%d)!!\n", state); + +@@ -11142,10 +11206,13 @@ scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) + static pci_ers_result_t + scsih_pci_slot_reset(struct pci_dev *pdev) + { +- struct Scsi_Host *shost = pci_get_drvdata(pdev); +- struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; + int rc; + ++ if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc)) ++ return PCI_ERS_RESULT_DISCONNECT; ++ + ioc_info(ioc, "PCI error: slot reset callback!!\n"); + + ioc->pci_error_recovery = 0; +@@ -11178,8 +11245,11 @@ scsih_pci_slot_reset(struct pci_dev *pdev) + static void + scsih_pci_resume(struct pci_dev *pdev) + { +- struct Scsi_Host *shost = pci_get_drvdata(pdev); +- struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; ++ ++ if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc)) ++ return; + + ioc_info(ioc, "PCI error: resume callback!!\n"); + +@@ -11194,8 +11264,11 @@ scsih_pci_resume(struct pci_dev *pdev) + static pci_ers_result_t + scsih_pci_mmio_enabled(struct pci_dev *pdev) + { +- struct Scsi_Host *shost = pci_get_drvdata(pdev); +- struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; ++ ++ if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc)) ++ return PCI_ERS_RESULT_DISCONNECT; + + ioc_info(ioc, "PCI error: mmio enabled callback!!\n"); + +@@ -11322,6 +11395,14 @@ static const struct pci_device_id mpt3sas_pci_table[] = { + { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_HARD_SEC_3916, + PCI_ANY_ID, PCI_ANY_ID }, + ++ /* ++ * Aero SI –> 0x00E0 Invalid, 0x00E3 Tampered ++ */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_INVALID0_3916, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_INVALID1_3916, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ + /* Atlas PCIe Switch Management Port */ + { MPI2_MFGPAGE_VENDORID_LSI, MPI26_ATLAS_PCIe_SWITCH_DEVID, + PCI_ANY_ID, PCI_ANY_ID }, +@@ -11334,6 +11415,14 @@ static const struct pci_device_id mpt3sas_pci_table[] = { + { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_HARD_SEC_3816, + PCI_ANY_ID, PCI_ANY_ID }, + ++ /* ++ * Sea SI –> 0x00E4 Invalid, 0x00E7 Tampered ++ */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_INVALID0_3816, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_INVALID1_3816, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ + {0} /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(pci, mpt3sas_pci_table); +-- +2.13.6 + diff --git a/SOURCES/0017-scsi-scsi-mpt3sas-Fix-sync-irqs.patch b/SOURCES/0017-scsi-scsi-mpt3sas-Fix-sync-irqs.patch new file mode 100644 index 0000000..cbf8039 --- /dev/null +++ b/SOURCES/0017-scsi-scsi-mpt3sas-Fix-sync-irqs.patch @@ -0,0 +1,67 @@ +From 363658dad96139188f639c72def9119c643717f1 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:35 -0400 +Subject: [PATCH 17/33] [scsi] scsi: mpt3sas: Fix sync irqs + +Message-id: <20201009140636.7976-18-thenzl@redhat.com> +Patchwork-id: 330373 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 17/18] scsi: mpt3sas: Fix sync irqs +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +_base_process_reply_queue() called from _base_interrupt() may schedule a +new irq poll. Fix this by calling synchronize_irq() first. + +Also ensure that enable_irq() is called only when necessary to avoid +"Unbalanced enable for IRQ..." errors. + +Link: https://lore.kernel.org/r/20200910142126.8147-1-thenzl@redhat.com +Fixes: 320e77acb327 ("scsi: mpt3sas: Irq poll to avoid CPU hard lockups") +Acked-by: Sreekanth Reddy +Signed-off-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +(cherry picked from commit 45181eab8ba79ed7a41b549f00500c0093828521) +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 24dd90a72a80..e08ad13714d4 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -1809,18 +1809,22 @@ mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc, u8 poll) + /* TMs are on msix_index == 0 */ + if (reply_q->msix_index == 0) + continue; ++ synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index)); + if (reply_q->irq_poll_scheduled) { + /* Calling irq_poll_disable will wait for any pending + * callbacks to have completed. + */ + irq_poll_disable(&reply_q->irqpoll); + irq_poll_enable(&reply_q->irqpoll); +- reply_q->irq_poll_scheduled = false; +- reply_q->irq_line_enable = true; +- enable_irq(reply_q->os_irq); +- continue; ++ /* check how the scheduled poll has ended, ++ * clean up only if necessary ++ */ ++ if (reply_q->irq_poll_scheduled) { ++ reply_q->irq_poll_scheduled = false; ++ reply_q->irq_line_enable = true; ++ enable_irq(reply_q->os_irq); ++ } + } +- synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index)); + } + if (poll) + _base_process_reply_queue(reply_q); +-- +2.13.6 + diff --git a/SOURCES/0018-scsi-scsi-mpt3sas-A-small-correction-in-_base_proces.patch b/SOURCES/0018-scsi-scsi-mpt3sas-A-small-correction-in-_base_proces.patch new file mode 100644 index 0000000..3836c98 --- /dev/null +++ b/SOURCES/0018-scsi-scsi-mpt3sas-A-small-correction-in-_base_proces.patch @@ -0,0 +1,44 @@ +From 353229f2ce45e0831715c34d64d4621561eb020d Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 9 Oct 2020 14:06:36 -0400 +Subject: [PATCH 18/33] [scsi] scsi: mpt3sas: A small correction in + _base_process_reply_queue + +Message-id: <20201009140636.7976-19-thenzl@redhat.com> +Patchwork-id: 330375 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 18/18] scsi: mpt3sas: A small correction in _base_process_reply_queue +Bugzilla: 1851440 +RH-Acked-by: Ewan Milne +RH-Acked-by: Jarod Wilson +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: Tony Camuso + +There is no need to compute modulo. A simple comparison is good enough. + +Link: https://lore.kernel.org/r/20200911180057.14633-1-thenzl@redhat.com +Acked-by: sreekanth reddy +Signed-off-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +(cherry picked from commit 3d49f7426e6c4e9c41d0aa88f0a76616912a383e) +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index e08ad13714d4..b096917fc314 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -1626,7 +1626,7 @@ _base_process_reply_queue(struct adapter_reply_queue *reply_q) + * So that FW can find enough entries to post the Reply + * Descriptors in the reply descriptor post queue. + */ +- if (!base_mod64(completed_cmds, ioc->thresh_hold)) { ++ if (completed_cmds >= ioc->thresh_hold) { + if (ioc->combined_reply_queue) { + writel(reply_q->reply_post_host_index | + ((msix_index & 7) << +-- +2.13.6 + diff --git a/SOURCES/0019-scsi-scsi-mpt3sas-Fix-timeouts-observed-while-reenab.patch b/SOURCES/0019-scsi-scsi-mpt3sas-Fix-timeouts-observed-while-reenab.patch new file mode 100644 index 0000000..c26151e --- /dev/null +++ b/SOURCES/0019-scsi-scsi-mpt3sas-Fix-timeouts-observed-while-reenab.patch @@ -0,0 +1,56 @@ +From 563c853944c49fd4ef847f722ab97ad6760a58f7 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Mon, 23 Nov 2020 17:12:04 -0500 +Subject: [PATCH 19/33] [scsi] scsi: mpt3sas: Fix timeouts observed while + reenabling IRQ + +Message-id: <20201123171204.21755-2-thenzl@redhat.com> +Patchwork-id: 341324 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 1/1] scsi: mpt3sas: Fix timeouts observed while reenabling IRQ +Bugzilla: 1880114 +RH-Acked-by: Maurizio Lombardi +RH-Acked-by: David Milburn + +While reenabling the IRQ after irq poll there may be small time window +where HBA firmware has posted some replies and raise the interrupts but +driver has not received the interrupts. So we may observe I/O timeouts as +the driver has not processed the replies as interrupts got missed while +reenabling the IRQ. + +To fix this issue the driver has to go for one more round of processing the +reply descriptors from reply descriptor post queue after enabling the IRQ. + +Link: https://lore.kernel.org/r/20201102072746.27410-1-sreekanth.reddy@broadcom.com +Reported-by: Tomas Henzl +Reviewed-by: Tomas Henzl +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit 5feed64f9199ff90c4239971733f23f30aeb2484) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index b096917fc314..a0ab44d520f6 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -1740,6 +1740,13 @@ _base_irqpoll(struct irq_poll *irqpoll, int budget) + reply_q->irq_poll_scheduled = false; + reply_q->irq_line_enable = true; + enable_irq(reply_q->os_irq); ++ /* ++ * Go for one more round of processing the ++ * reply descriptor post queue incase if HBA ++ * Firmware has posted some reply descriptors ++ * while reenabling the IRQ. ++ */ ++ _base_process_reply_queue(reply_q); + } + + return num_entries; +-- +2.13.6 + diff --git a/SOURCES/0020-scsi-scsi-mpt3sas-Define-hba_port-structure.patch b/SOURCES/0020-scsi-scsi-mpt3sas-Define-hba_port-structure.patch new file mode 100644 index 0000000..6a8d84e --- /dev/null +++ b/SOURCES/0020-scsi-scsi-mpt3sas-Define-hba_port-structure.patch @@ -0,0 +1,171 @@ +From 800fe460de3a40b08c5fbf1e2e84a101ce803a67 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:45 -0500 +Subject: [PATCH 20/33] [scsi] scsi: mpt3sas: Define hba_port structure + +Message-id: <20201113184258.11169-2-thenzl@redhat.com> +Patchwork-id: 339459 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 01/14] scsi: mpt3sas: Define hba_port structure +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +Define a new hba_port structure which holds the following variables: + + - port_id: Port ID of the narrow/wide port of the HBA + + - sas_address: SAS Address of the remote device that is attached to the + current HBA port + + - phy_mask: HBA's phy bits to which above SAS addressed device is attached + + - flags: This field is used to refresh port details during HBA reset + +Link: https://lore.kernel.org/r/20201027130847.9962-2-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit b22a0fac8c056e88fc72f7241fa9077b804634a6) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 35 ++++++++++++++++++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index bc8beb10f3fc..2dde574ccff2 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -420,6 +420,7 @@ struct Mpi2ManufacturingPage11_t { + * @flags: MPT_TARGET_FLAGS_XXX flags + * @deleted: target flaged for deletion + * @tm_busy: target is busy with TM request. ++ * @port: hba port entry containing target's port number info + * @sas_dev: The sas_device associated with this target + * @pcie_dev: The pcie device associated with this target + */ +@@ -432,6 +433,7 @@ struct MPT3SAS_TARGET { + u32 flags; + u8 deleted; + u8 tm_busy; ++ struct hba_port *port; + struct _sas_device *sas_dev; + struct _pcie_device *pcie_dev; + }; +@@ -534,6 +536,7 @@ struct _internal_cmd { + * addition routine. + * @chassis_slot: chassis slot + * @is_chassis_slot_valid: chassis slot valid or not ++ * @port: hba port entry containing device's port number info + */ + struct _sas_device { + struct list_head list; +@@ -560,6 +563,7 @@ struct _sas_device { + u8 is_chassis_slot_valid; + u8 connector_name[5]; + struct kref refcount; ++ struct hba_port *port; + }; + + static inline void sas_device_get(struct _sas_device *s) +@@ -730,6 +734,7 @@ struct _boot_device { + * @remote_identify: attached device identification + * @rphy: sas transport rphy object + * @port: sas transport wide/narrow port object ++ * @hba_port: hba port entry containing port's port number info + * @phy_list: _sas_phy list objects belonging to this port + */ + struct _sas_port { +@@ -738,6 +743,7 @@ struct _sas_port { + struct sas_identify remote_identify; + struct sas_rphy *rphy; + struct sas_port *port; ++ struct hba_port *hba_port; + struct list_head phy_list; + }; + +@@ -751,6 +757,7 @@ struct _sas_port { + * @handle: device handle for this phy + * @attached_handle: device handle for attached device + * @phy_belongs_to_port: port has been created for this phy ++ * @port: hba port entry containing port number info + */ + struct _sas_phy { + struct list_head port_siblings; +@@ -761,6 +768,7 @@ struct _sas_phy { + u16 handle; + u16 attached_handle; + u8 phy_belongs_to_port; ++ struct hba_port *port; + }; + + /** +@@ -776,6 +784,7 @@ struct _sas_phy { + * @responding: used in _scsih_expander_device_mark_responding + * @phy: a list of phys that make up this sas_host/expander + * @sas_port_list: list of ports attached to this sas_host/expander ++ * @port: hba port entry containing node's port number info + */ + struct _sas_node { + struct list_head list; +@@ -787,11 +796,11 @@ struct _sas_node { + u16 enclosure_handle; + u64 enclosure_logical_id; + u8 responding; ++ struct hba_port *port; + struct _sas_phy *phy; + struct list_head sas_port_list; + }; + +- + /** + * struct _enclosure_node - enclosure information + * @list: list of enclosures +@@ -1009,6 +1018,27 @@ struct reply_post_struct { + dma_addr_t reply_post_free_dma; + }; + ++/** ++ * struct hba_port - Saves each HBA's Wide/Narrow port info ++ * @sas_address: sas address of this wide/narrow port's attached device ++ * @phy_mask: HBA PHY's belonging to this port ++ * @port_id: port number ++ * @flags: hba port flags ++ */ ++struct hba_port { ++ struct list_head list; ++ u64 sas_address; ++ u32 phy_mask; ++ u8 port_id; ++ u8 flags; ++}; ++ ++/* hba port flags */ ++#define HBA_PORT_FLAG_DIRTY_PORT 0x01 ++#define HBA_PORT_FLAG_NEW_PORT 0x02 ++ ++#define MULTIPATH_DISABLED_PORT_ID 0xFF ++ + typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); + /** + * struct MPT3SAS_ADAPTER - per adapter struct +@@ -1191,6 +1221,7 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); + * which ensures the syncrhonization between cli/sysfs_show path. + * @atomic_desc_capable: Atomic Request Descriptor support. + * @GET_MSIX_INDEX: Get the msix index of high iops queues. ++ * @port_table_list: list containing HBA's wide/narrow port's info + */ + struct MPT3SAS_ADAPTER { + struct list_head list; +@@ -1483,6 +1514,8 @@ struct MPT3SAS_ADAPTER { + PUT_SMID_IO_FP_HIP put_smid_hi_priority; + PUT_SMID_DEFAULT put_smid_default; + GET_MSIX_INDEX get_msix_index_for_smlio; ++ ++ struct list_head port_table_list; + }; + + struct mpt3sas_debugfs_buffer { +-- +2.13.6 + diff --git a/SOURCES/0021-scsi-scsi-mpt3sas-Allocate-memory-for-hba_port-objec.patch b/SOURCES/0021-scsi-scsi-mpt3sas-Allocate-memory-for-hba_port-objec.patch new file mode 100644 index 0000000..c9c161b --- /dev/null +++ b/SOURCES/0021-scsi-scsi-mpt3sas-Allocate-memory-for-hba_port-objec.patch @@ -0,0 +1,171 @@ +From f0c23648d85ad8195aec2cb98e476aa5b263a22d Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:46 -0500 +Subject: [PATCH 21/33] [scsi] scsi: mpt3sas: Allocate memory for hba_port + objects + +Message-id: <20201113184258.11169-3-thenzl@redhat.com> +Patchwork-id: 339460 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 02/14] scsi: mpt3sas: Allocate memory for hba_port objects +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +Allocate hba_port object whenever a new HBA's wide/narrow port is +identified while processing the SASIOUnitPage0's phy data and add this +object to port_table_list. Deallocate these objects during driver unload. + +Link: https://lore.kernel.org/r/20201027130847.9962-3-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit e238e71b6cb2b7b06224b31eb31892d1acb75f1d) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 73 ++++++++++++++++++++++++++++++++++-- + 1 file changed, 69 insertions(+), 4 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 8c14908e39ca..0fbc7b65ebb0 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -357,6 +357,30 @@ _scsih_srch_boot_encl_slot(u64 enclosure_logical_id, u16 slot_number, + } + + /** ++ * mpt3sas_get_port_by_id - get hba port entry corresponding to provided ++ * port number from port list ++ * @ioc: per adapter object ++ * @port_id: port number ++ * ++ * Search for hba port entry corresponding to provided port number, ++ * if available return port object otherwise return NULL. ++ */ ++struct hba_port * ++mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, u8 port_id) ++{ ++ struct hba_port *port, *port_next; ++ ++ list_for_each_entry_safe(port, port_next, ++ &ioc->port_table_list, list) { ++ if (port->port_id == port_id && ++ !(port->flags & HBA_PORT_FLAG_DIRTY_PORT)) ++ return port; ++ } ++ ++ return NULL; ++} ++ ++/** + * _scsih_is_boot_device - search for matching boot device. + * @sas_address: sas address + * @device_name: device name specified in INDENTIFY fram +@@ -5732,7 +5756,8 @@ _scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc) + Mpi2ConfigReply_t mpi_reply; + Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; + u16 attached_handle; +- u8 link_rate; ++ u8 link_rate, port_id; ++ struct hba_port *port; + + dtmprintk(ioc, + ioc_info(ioc, "updating handles for sas_host(0x%016llx)\n", +@@ -5756,13 +5781,28 @@ _scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc) + for (i = 0; i < ioc->sas_hba.num_phys ; i++) { + link_rate = sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4; + if (i == 0) +- ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> +- PhyData[0].ControllerDevHandle); ++ ioc->sas_hba.handle = le16_to_cpu( ++ sas_iounit_pg0->PhyData[0].ControllerDevHandle); ++ port_id = sas_iounit_pg0->PhyData[i].Port; ++ if (!(mpt3sas_get_port_by_id(ioc, port_id))) { ++ port = kzalloc(sizeof(struct hba_port), GFP_KERNEL); ++ if (!port) ++ goto out; ++ ++ port->port_id = port_id; ++ ioc_info(ioc, ++ "hba_port entry: %p, port: %d is added to hba_port list\n", ++ port, port->port_id); ++ if (ioc->shost_recovery) ++ port->flags = HBA_PORT_FLAG_NEW_PORT; ++ list_add_tail(&port->list, &ioc->port_table_list); ++ } + ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; + attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i]. + AttachedDevHandle); + if (attached_handle && link_rate < MPI2_SAS_NEG_LINK_RATE_1_5) + link_rate = MPI2_SAS_NEG_LINK_RATE_1_5; ++ ioc->sas_hba.phy[i].port = mpt3sas_get_port_by_id(ioc, port_id); + mpt3sas_transport_update_links(ioc, ioc->sas_hba.sas_address, + attached_handle, i, link_rate); + } +@@ -5789,7 +5829,8 @@ _scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc) + u16 ioc_status; + u16 sz; + u8 device_missing_delay; +- u8 num_phys; ++ u8 num_phys, port_id; ++ struct hba_port *port; + + mpt3sas_config_get_number_hba_phys(ioc, &num_phys); + if (!num_phys) { +@@ -5882,8 +5923,24 @@ _scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc) + if (i == 0) + ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> + PhyData[0].ControllerDevHandle); ++ ++ port_id = sas_iounit_pg0->PhyData[i].Port; ++ if (!(mpt3sas_get_port_by_id(ioc, port_id))) { ++ port = kzalloc(sizeof(struct hba_port), GFP_KERNEL); ++ if (!port) ++ goto out; ++ ++ port->port_id = port_id; ++ ioc_info(ioc, ++ "hba_port entry: %p, port: %d is added to hba_port list\n", ++ port, port->port_id); ++ list_add_tail(&port->list, ++ &ioc->port_table_list); ++ } ++ + ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; + ioc->sas_hba.phy[i].phy_id = i; ++ ioc->sas_hba.phy[i].port = mpt3sas_get_port_by_id(ioc, port_id); + mpt3sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], + phy_pg0, ioc->sas_hba.parent_dev); + } +@@ -10136,6 +10193,7 @@ static void scsih_remove(struct pci_dev *pdev) + struct workqueue_struct *wq; + unsigned long flags; + Mpi2ConfigReply_t mpi_reply; ++ struct hba_port *port, *port_next; + + if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc)) + return; +@@ -10198,6 +10256,12 @@ static void scsih_remove(struct pci_dev *pdev) + mpt3sas_port->remote_identify.sas_address); + } + ++ list_for_each_entry_safe(port, port_next, ++ &ioc->port_table_list, list) { ++ list_del(&port->list); ++ kfree(port); ++ } ++ + /* free phys attached to the sas_host */ + if (ioc->sas_hba.num_phys) { + kfree(ioc->sas_hba.phy); +@@ -10988,6 +11052,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) + INIT_LIST_HEAD(&ioc->delayed_event_ack_list); + INIT_LIST_HEAD(&ioc->delayed_tr_volume_list); + INIT_LIST_HEAD(&ioc->reply_queue_list); ++ INIT_LIST_HEAD(&ioc->port_table_list); + + sprintf(ioc->name, "%s_cm%d", ioc->driver_name, ioc->id); + +-- +2.13.6 + diff --git a/SOURCES/0022-scsi-scsi-mpt3sas-Rearrange-_scsih_mark_responding_s.patch b/SOURCES/0022-scsi-scsi-mpt3sas-Rearrange-_scsih_mark_responding_s.patch new file mode 100644 index 0000000..8bb1af9 --- /dev/null +++ b/SOURCES/0022-scsi-scsi-mpt3sas-Rearrange-_scsih_mark_responding_s.patch @@ -0,0 +1,161 @@ +From d67ff22c2c9316c6d78a54919b234f70494c9e37 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:47 -0500 +Subject: [PATCH 22/33] [scsi] scsi: mpt3sas: Rearrange + _scsih_mark_responding_sas_device() + +Message-id: <20201113184258.11169-4-thenzl@redhat.com> +Patchwork-id: 339461 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 03/14] scsi: mpt3sas: Rearrange _scsih_mark_responding_sas_device() +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +Rearrange _scsih_mark_responding_sas_device function. No functional change. + +Link: https://lore.kernel.org/r/20201027130847.9962-4-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit 78ca700342a5df21d80515a36ba17c4962efb35b) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 116 +++++++++++++++++------------------ + 1 file changed, 58 insertions(+), 58 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 0fbc7b65ebb0..537ebd142cc3 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -8742,69 +8742,69 @@ Mpi2SasDevicePage0_t *sas_device_pg0) + } + spin_lock_irqsave(&ioc->sas_device_lock, flags); + list_for_each_entry(sas_device, &ioc->sas_device_list, list) { +- if ((sas_device->sas_address == le64_to_cpu( +- sas_device_pg0->SASAddress)) && (sas_device->slot == +- le16_to_cpu(sas_device_pg0->Slot))) { +- sas_device->responding = 1; +- starget = sas_device->starget; +- if (starget && starget->hostdata) { +- sas_target_priv_data = starget->hostdata; +- sas_target_priv_data->tm_busy = 0; +- sas_target_priv_data->deleted = 0; +- } else +- sas_target_priv_data = NULL; +- if (starget) { +- starget_printk(KERN_INFO, starget, +- "handle(0x%04x), sas_addr(0x%016llx)\n", +- le16_to_cpu(sas_device_pg0->DevHandle), +- (unsigned long long) +- sas_device->sas_address); ++ if (sas_device->sas_address != le64_to_cpu( ++ sas_device_pg0->SASAddress)) ++ continue; ++ if (sas_device->slot != le16_to_cpu(sas_device_pg0->Slot)) ++ continue; ++ sas_device->responding = 1; ++ starget = sas_device->starget; ++ if (starget && starget->hostdata) { ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->tm_busy = 0; ++ sas_target_priv_data->deleted = 0; ++ } else ++ sas_target_priv_data = NULL; ++ if (starget) { ++ starget_printk(KERN_INFO, starget, ++ "handle(0x%04x), sas_addr(0x%016llx)\n", ++ le16_to_cpu(sas_device_pg0->DevHandle), ++ (unsigned long long) ++ sas_device->sas_address); + +- if (sas_device->enclosure_handle != 0) +- starget_printk(KERN_INFO, starget, +- "enclosure logical id(0x%016llx)," +- " slot(%d)\n", +- (unsigned long long) +- sas_device->enclosure_logical_id, +- sas_device->slot); +- } +- if (le16_to_cpu(sas_device_pg0->Flags) & +- MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { +- sas_device->enclosure_level = +- sas_device_pg0->EnclosureLevel; +- memcpy(&sas_device->connector_name[0], +- &sas_device_pg0->ConnectorName[0], 4); +- } else { +- sas_device->enclosure_level = 0; +- sas_device->connector_name[0] = '\0'; +- } ++ if (sas_device->enclosure_handle != 0) ++ starget_printk(KERN_INFO, starget, ++ "enclosure logical id(0x%016llx), slot(%d)\n", ++ (unsigned long long) ++ sas_device->enclosure_logical_id, ++ sas_device->slot); ++ } ++ if (le16_to_cpu(sas_device_pg0->Flags) & ++ MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { ++ sas_device->enclosure_level = ++ sas_device_pg0->EnclosureLevel; ++ memcpy(&sas_device->connector_name[0], ++ &sas_device_pg0->ConnectorName[0], 4); ++ } else { ++ sas_device->enclosure_level = 0; ++ sas_device->connector_name[0] = '\0'; ++ } + +- sas_device->enclosure_handle = +- le16_to_cpu(sas_device_pg0->EnclosureHandle); +- sas_device->is_chassis_slot_valid = 0; +- if (enclosure_dev) { +- sas_device->enclosure_logical_id = le64_to_cpu( +- enclosure_dev->pg0.EnclosureLogicalID); +- if (le16_to_cpu(enclosure_dev->pg0.Flags) & +- MPI2_SAS_ENCLS0_FLAGS_CHASSIS_SLOT_VALID) { +- sas_device->is_chassis_slot_valid = 1; +- sas_device->chassis_slot = +- enclosure_dev->pg0.ChassisSlot; +- } ++ sas_device->enclosure_handle = ++ le16_to_cpu(sas_device_pg0->EnclosureHandle); ++ sas_device->is_chassis_slot_valid = 0; ++ if (enclosure_dev) { ++ sas_device->enclosure_logical_id = le64_to_cpu( ++ enclosure_dev->pg0.EnclosureLogicalID); ++ if (le16_to_cpu(enclosure_dev->pg0.Flags) & ++ MPI2_SAS_ENCLS0_FLAGS_CHASSIS_SLOT_VALID) { ++ sas_device->is_chassis_slot_valid = 1; ++ sas_device->chassis_slot = ++ enclosure_dev->pg0.ChassisSlot; + } ++ } + +- if (sas_device->handle == le16_to_cpu( +- sas_device_pg0->DevHandle)) +- goto out; +- pr_info("\thandle changed from(0x%04x)!!!\n", +- sas_device->handle); +- sas_device->handle = le16_to_cpu( +- sas_device_pg0->DevHandle); +- if (sas_target_priv_data) +- sas_target_priv_data->handle = +- le16_to_cpu(sas_device_pg0->DevHandle); ++ if (sas_device->handle == le16_to_cpu( ++ sas_device_pg0->DevHandle)) + goto out; +- } ++ pr_info("\thandle changed from(0x%04x)!!!\n", ++ sas_device->handle); ++ sas_device->handle = le16_to_cpu( ++ sas_device_pg0->DevHandle); ++ if (sas_target_priv_data) ++ sas_target_priv_data->handle = ++ le16_to_cpu(sas_device_pg0->DevHandle); ++ goto out; + } + out: + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); +-- +2.13.6 + diff --git a/SOURCES/0023-scsi-scsi-mpt3sas-Update-hba_port-s-sas_address-phy_.patch b/SOURCES/0023-scsi-scsi-mpt3sas-Update-hba_port-s-sas_address-phy_.patch new file mode 100644 index 0000000..6a76ee7 --- /dev/null +++ b/SOURCES/0023-scsi-scsi-mpt3sas-Update-hba_port-s-sas_address-phy_.patch @@ -0,0 +1,587 @@ +From ed8d152dda9374007095f9e611816ba9cdb028cd Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:48 -0500 +Subject: [PATCH 23/33] [scsi] scsi: mpt3sas: Update hba_port's sas_address & + phy_mask + +Message-id: <20201113184258.11169-5-thenzl@redhat.com> +Patchwork-id: 339466 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 04/14] scsi: mpt3sas: Update hba_port's sas_address & phy_mask +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +Update hba_port's sas_address & phy_mask fields whenever a direct expander +or sas/sata target devices are added or removed. + +When any direct attached device is discovered then driver: + + - Gets the hba_port object corresponding to device's PhysicalPort + number; + + - Updates the hba_port's sas_address field with device's SAS + Address; + + - Updates the hba_port's phy_mask filed with device's narrow/wide + port Phy number bits; + + - If a sas/sata end device (not only direct-attached devices) is added + then corresponding sas_device object's port variable is assigned with + hba_port object's address whose port_id matches the device's + PhysicalPort number. + + - If an expander device is added then corresponding sas_expander object's + port variable is assigned with hba_port object's address whose port_id + matches the expander device's PhysicalPort number. + +When any direct attached device is detached then driver will delete the +hba_port object corresponding to device's PhysicalPort number. + +Whenever any HBA phy's link (of direct attached device's port) comes up +then update the phy_mask field of corresponding hba_port object. + +Link: https://lore.kernel.org/r/20201027130847.9962-5-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit e2f0cdf7525353d87ed4f51ea69ca7986070ddd5) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 7 +-- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 81 ++++++++++++++++++++++++-------- + drivers/scsi/mpt3sas/mpt3sas_transport.c | 65 +++++++++++++++++++++++-- + 3 files changed, 126 insertions(+), 27 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 2dde574ccff2..aef872aa509d 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -1792,16 +1792,17 @@ extern struct scsi_transport_template *mpt3sas_transport_template; + u8 mpt3sas_transport_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, + u32 reply); + struct _sas_port *mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, +- u16 handle, u64 sas_address); ++ u16 handle, u64 sas_address, struct hba_port *port); + void mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, +- u64 sas_address_parent); ++ u64 sas_address_parent, struct hba_port *port); + int mpt3sas_transport_add_host_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy + *mpt3sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev); + int mpt3sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, + struct _sas_phy *mpt3sas_phy, Mpi2ExpanderPage1_t expander_pg1, + struct device *parent_dev); + void mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, +- u64 sas_address, u16 handle, u8 phy_number, u8 link_rate); ++ u64 sas_address, u16 handle, u8 phy_number, u8 link_rate, ++ struct hba_port *port); + extern struct sas_function_template mpt3sas_transport_functions; + extern struct scsi_transport_template *mpt3sas_transport_template; + /* trigger data externs */ +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 537ebd142cc3..c80646740542 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -908,7 +908,7 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc, + } + + if (!mpt3sas_transport_port_add(ioc, sas_device->handle, +- sas_device->sas_address_parent)) { ++ sas_device->sas_address_parent, sas_device->port)) { + _scsih_sas_device_remove(ioc, sas_device); + } else if (!sas_device->starget) { + /* +@@ -919,7 +919,8 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc, + if (!ioc->is_driver_loading) { + mpt3sas_transport_port_remove(ioc, + sas_device->sas_address, +- sas_device->sas_address_parent); ++ sas_device->sas_address_parent, ++ sas_device->port); + _scsih_sas_device_remove(ioc, sas_device); + } + } else +@@ -1768,6 +1769,7 @@ scsih_target_alloc(struct scsi_target *starget) + if (pcie_device) { + sas_target_priv_data->handle = pcie_device->handle; + sas_target_priv_data->sas_address = pcie_device->wwid; ++ sas_target_priv_data->port = NULL; + sas_target_priv_data->pcie_dev = pcie_device; + pcie_device->starget = starget; + pcie_device->id = starget->id; +@@ -1791,6 +1793,7 @@ scsih_target_alloc(struct scsi_target *starget) + if (sas_device) { + sas_target_priv_data->handle = sas_device->handle; + sas_target_priv_data->sas_address = sas_device->sas_address; ++ sas_target_priv_data->port = sas_device->port; + sas_target_priv_data->sas_dev = sas_device; + sas_device->starget = starget; + sas_device->id = starget->id; +@@ -5804,7 +5807,8 @@ _scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc) + link_rate = MPI2_SAS_NEG_LINK_RATE_1_5; + ioc->sas_hba.phy[i].port = mpt3sas_get_port_by_id(ioc, port_id); + mpt3sas_transport_update_links(ioc, ioc->sas_hba.sas_address, +- attached_handle, i, link_rate); ++ attached_handle, i, link_rate, ++ ioc->sas_hba.phy[i].port); + } + out: + kfree(sas_iounit_pg0); +@@ -5994,6 +5998,7 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) + int i; + unsigned long flags; + struct _sas_port *mpt3sas_port = NULL; ++ u8 port_id; + + int rc = 0; + +@@ -6026,6 +6031,8 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) + __FILE__, __LINE__, __func__); + return -1; + } ++ ++ port_id = expander_pg0.PhysicalPort; + 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, +@@ -6059,6 +6066,13 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) + sas_expander->num_phys = expander_pg0.NumPhys; + sas_expander->sas_address_parent = sas_address_parent; + sas_expander->sas_address = sas_address; ++ sas_expander->port = mpt3sas_get_port_by_id(ioc, port_id); ++ if (!sas_expander->port) { ++ ioc_err(ioc, "failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ rc = -1; ++ goto out_fail; ++ } + + ioc_info(ioc, "expander_add: handle(0x%04x), parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", + handle, parent_handle, +@@ -6077,7 +6091,7 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) + + INIT_LIST_HEAD(&sas_expander->sas_port_list); + mpt3sas_port = mpt3sas_transport_port_add(ioc, handle, +- sas_address_parent); ++ sas_address_parent, sas_expander->port); + if (!mpt3sas_port) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); +@@ -6096,6 +6110,7 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) + } + sas_expander->phy[i].handle = handle; + sas_expander->phy[i].phy_id = i; ++ sas_expander->phy[i].port = mpt3sas_get_port_by_id(ioc, port_id); + + if ((mpt3sas_transport_add_expander_phy(ioc, + &sas_expander->phy[i], expander_pg1, +@@ -6123,7 +6138,7 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) + + if (mpt3sas_port) + mpt3sas_transport_port_remove(ioc, sas_expander->sas_address, +- sas_address_parent); ++ sas_address_parent, sas_expander->port); + kfree(sas_expander); + return rc; + } +@@ -6388,6 +6403,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, + u32 ioc_status; + u64 sas_address; + u32 device_info; ++ u8 port_id; + + if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, + MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { +@@ -6424,6 +6440,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, + sas_device_pg0.AccessStatus)) + return -1; + ++ port_id = sas_device_pg0.PhysicalPort; + sas_device = mpt3sas_get_sdev_by_addr(ioc, + sas_address); + if (sas_device) { +@@ -6466,6 +6483,12 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, + sas_device->phy = sas_device_pg0.PhyNum; + sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) & + MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0; ++ sas_device->port = mpt3sas_get_port_by_id(ioc, port_id); ++ if (!sas_device->port) { ++ ioc_err(ioc, "failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ goto out; ++ } + + if (le16_to_cpu(sas_device_pg0.Flags) + & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { +@@ -6499,6 +6522,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, + else + _scsih_sas_device_add(ioc, sas_device); + ++out: + sas_device_put(sas_device); + return 0; + } +@@ -6539,7 +6563,8 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, + if (!ioc->hide_drives) + mpt3sas_transport_port_remove(ioc, + sas_device->sas_address, +- sas_device->sas_address_parent); ++ sas_device->sas_address_parent, ++ sas_device->port); + + ioc_info(ioc, "removing handle(0x%04x), sas_addr(0x%016llx)\n", + sas_device->handle, (u64)sas_device->sas_address); +@@ -6650,6 +6675,7 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc, + u64 sas_address; + unsigned long flags; + u8 link_rate, prev_link_rate; ++ struct hba_port *port; + Mpi2EventDataSasTopologyChangeList_t *event_data = + (Mpi2EventDataSasTopologyChangeList_t *) + fw_event->event_data; +@@ -6671,6 +6697,7 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc, + } + + parent_handle = le16_to_cpu(event_data->ExpanderDevHandle); ++ port = mpt3sas_get_port_by_id(ioc, event_data->PhysicalPort); + + /* handle expander add */ + if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED) +@@ -6683,6 +6710,7 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc, + if (sas_expander) { + sas_address = sas_expander->sas_address; + max_phys = sas_expander->num_phys; ++ port = sas_expander->port; + } else if (parent_handle < ioc->sas_hba.num_phys) { + sas_address = ioc->sas_hba.sas_address; + max_phys = ioc->sas_hba.num_phys; +@@ -6725,7 +6753,7 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc, + break; + + mpt3sas_transport_update_links(ioc, sas_address, +- handle, phy_number, link_rate); ++ handle, phy_number, link_rate, port); + + if (link_rate < MPI2_SAS_NEG_LINK_RATE_1_5) + break; +@@ -6744,7 +6772,7 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc, + break; + + mpt3sas_transport_update_links(ioc, sas_address, +- handle, phy_number, link_rate); ++ handle, phy_number, link_rate, port); + + _scsih_add_device(ioc, handle, phy_number, 0); + +@@ -8300,7 +8328,8 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc, + parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); + if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) + mpt3sas_transport_update_links(ioc, sas_address, handle, +- sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); ++ sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5, ++ mpt3sas_get_port_by_id(ioc, sas_device_pg0.PhysicalPort)); + + _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); + _scsih_add_device(ioc, handle, 0, 1); +@@ -8606,7 +8635,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc, + parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); + if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) + mpt3sas_transport_update_links(ioc, sas_address, handle, +- sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); ++ sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5, ++ mpt3sas_get_port_by_id(ioc, ++ sas_device_pg0.PhysicalPort)); + + _scsih_add_device(ioc, handle, 0, 1); + +@@ -9345,7 +9376,8 @@ _scsih_refresh_expander_links(struct MPT3SAS_ADAPTER *ioc, + + mpt3sas_transport_update_links(ioc, sas_expander->sas_address, + le16_to_cpu(expander_pg1.AttachedDevHandle), i, +- expander_pg1.NegotiatedLinkRate >> 4); ++ expander_pg1.NegotiatedLinkRate >> 4, ++ sas_expander->port); + } + } + +@@ -9364,7 +9396,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) + Mpi2RaidPhysDiskPage0_t pd_pg0; + Mpi2EventIrConfigElement_t element; + Mpi2ConfigReply_t mpi_reply; +- u8 phys_disk_num; ++ u8 phys_disk_num, port_id; + u16 ioc_status; + u16 handle, parent_handle; + u64 sas_address; +@@ -9454,9 +9486,11 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) + ioc_info(ioc, "\tBEFORE adding phys disk: handle (0x%04x), sas_addr(0x%016llx)\n", + handle, + (u64)le64_to_cpu(sas_device_pg0.SASAddress)); ++ port_id = sas_device_pg0.PhysicalPort; + mpt3sas_transport_update_links(ioc, sas_address, + handle, sas_device_pg0.PhyNum, +- MPI2_SAS_NEG_LINK_RATE_1_5); ++ MPI2_SAS_NEG_LINK_RATE_1_5, ++ mpt3sas_get_port_by_id(ioc, port_id)); + set_bit(handle, ioc->pd_handles); + retry_count = 0; + /* This will retry adding the end device. +@@ -9542,6 +9576,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) + if (!(_scsih_is_end_device( + le32_to_cpu(sas_device_pg0.DeviceInfo)))) + continue; ++ port_id = sas_device_pg0.PhysicalPort; + sas_device = mpt3sas_get_sdev_by_addr(ioc, + le64_to_cpu(sas_device_pg0.SASAddress)); + if (sas_device) { +@@ -9554,7 +9589,8 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) + handle, + (u64)le64_to_cpu(sas_device_pg0.SASAddress)); + mpt3sas_transport_update_links(ioc, sas_address, handle, +- sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); ++ sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5, ++ mpt3sas_get_port_by_id(ioc, port_id)); + retry_count = 0; + /* This will retry adding the end device. + * _scsih_add_device() will decide on retries and +@@ -9997,7 +10033,7 @@ _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc, + } + + mpt3sas_transport_port_remove(ioc, sas_expander->sas_address, +- sas_expander->sas_address_parent); ++ 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) +@@ -10341,6 +10377,7 @@ _scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc) + unsigned long flags; + int rc; + int tid; ++ struct hba_port *port; + + /* no Bios, return immediately */ + if (!ioc->bios_pg3.BiosVersion) +@@ -10382,19 +10419,24 @@ _scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc) + handle = sas_device->handle; + sas_address_parent = sas_device->sas_address_parent; + sas_address = sas_device->sas_address; ++ port = sas_device->port; + list_move_tail(&sas_device->list, &ioc->sas_device_list); + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + + if (ioc->hide_drives) + return; ++ ++ if (!port) ++ return; ++ + if (!mpt3sas_transport_port_add(ioc, handle, +- sas_address_parent)) { ++ sas_address_parent, port)) { + _scsih_sas_device_remove(ioc, sas_device); + } else if (!sas_device->starget) { + if (!ioc->is_driver_loading) { + mpt3sas_transport_port_remove(ioc, + sas_address, +- sas_address_parent); ++ sas_address_parent, port); + _scsih_sas_device_remove(ioc, sas_device); + } + } +@@ -10482,7 +10524,7 @@ _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc) + + while ((sas_device = get_next_sas_device(ioc))) { + if (!mpt3sas_transport_port_add(ioc, sas_device->handle, +- sas_device->sas_address_parent)) { ++ sas_device->sas_address_parent, sas_device->port)) { + _scsih_sas_device_remove(ioc, sas_device); + sas_device_put(sas_device); + continue; +@@ -10496,7 +10538,8 @@ _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc) + if (!ioc->is_driver_loading) { + mpt3sas_transport_port_remove(ioc, + sas_device->sas_address, +- sas_device->sas_address_parent); ++ sas_device->sas_address_parent, ++ sas_device->port); + _scsih_sas_device_remove(ioc, sas_device); + sas_device_put(sas_device); + continue; +diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c +index 6ec5b7f33dfd..aab3b1451e31 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c +@@ -594,6 +594,7 @@ _transport_sanity_check(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node, + * @ioc: per adapter object + * @handle: handle of attached device + * @sas_address: sas address of parent expander or sas host ++ * @port: hba port entry + * Context: This function will acquire ioc->sas_node_lock. + * + * Adding new port object to the sas_node->sas_port_list. +@@ -602,7 +603,7 @@ _transport_sanity_check(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node, + */ + struct _sas_port * + mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, +- u64 sas_address) ++ u64 sas_address, struct hba_port *hba_port) + { + struct _sas_phy *mpt3sas_phy, *next; + struct _sas_port *mpt3sas_port; +@@ -613,6 +614,12 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, + int i; + struct sas_port *port; + ++ if (!hba_port) { ++ ioc_err(ioc, "failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return NULL; ++ } ++ + mpt3sas_port = kzalloc(sizeof(struct _sas_port), + GFP_KERNEL); + if (!mpt3sas_port) { +@@ -646,6 +653,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, + goto out_fail; + } + ++ mpt3sas_port->hba_port = hba_port; + _transport_sanity_check(ioc, sas_node, + mpt3sas_port->remote_identify.sas_address); + +@@ -653,8 +661,12 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, + if (sas_node->phy[i].remote_identify.sas_address != + mpt3sas_port->remote_identify.sas_address) + continue; ++ if (sas_node->phy[i].port != hba_port) ++ continue; + list_add_tail(&sas_node->phy[i].port_siblings, + &mpt3sas_port->phy_list); ++ if (sas_node->handle <= ioc->sas_hba.num_phys) ++ hba_port->phy_mask |= (1 << i); + mpt3sas_port->num_phys++; + } + +@@ -686,14 +698,21 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, + mpt3sas_phy->phy_id); + sas_port_add_phy(port, mpt3sas_phy->phy); + mpt3sas_phy->phy_belongs_to_port = 1; ++ mpt3sas_phy->port = hba_port; + } + + mpt3sas_port->port = port; +- if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) ++ if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { + rphy = sas_end_device_alloc(port); +- else ++ if (sas_node->handle <= ioc->sas_hba.num_phys) ++ hba_port->sas_address = sas_device->sas_address; ++ } else { + rphy = sas_expander_alloc(port, + mpt3sas_port->remote_identify.device_type); ++ if (sas_node->handle <= ioc->sas_hba.num_phys) ++ hba_port->sas_address = ++ mpt3sas_port->remote_identify.sas_address; ++ } + + rphy->identify = mpt3sas_port->remote_identify; + +@@ -751,6 +770,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, + * @ioc: per adapter object + * @sas_address: sas address of attached device + * @sas_address_parent: sas address of parent expander or sas host ++ * @port: hba port entry + * Context: This function will acquire ioc->sas_node_lock. + * + * Removing object and freeing associated memory from the +@@ -758,7 +778,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, + */ + void + mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, +- u64 sas_address_parent) ++ u64 sas_address_parent, struct hba_port *port) + { + int i; + unsigned long flags; +@@ -766,6 +786,10 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + struct _sas_node *sas_node; + u8 found = 0; + struct _sas_phy *mpt3sas_phy, *next_phy; ++ struct hba_port *hba_port_next, *hba_port = NULL; ++ ++ if (!port) ++ return; + + spin_lock_irqsave(&ioc->sas_node_lock, flags); + sas_node = _transport_sas_node_find_by_sas_address(ioc, +@@ -778,6 +802,8 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + port_list) { + if (mpt3sas_port->remote_identify.sas_address != sas_address) + continue; ++ if (mpt3sas_port->hba_port != port) ++ continue; + found = 1; + list_del(&mpt3sas_port->port_list); + goto out; +@@ -788,6 +814,21 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + return; + } + ++ if (sas_node->handle <= ioc->sas_hba.num_phys) { ++ list_for_each_entry_safe(hba_port, hba_port_next, ++ &ioc->port_table_list, list) { ++ if (hba_port != port) ++ continue; ++ if (hba_port->sas_address != sas_address) ++ continue; ++ ioc_info(ioc, ++ "remove hba_port entry: %p port: %d from hba_port list\n", ++ hba_port, hba_port->port_id); ++ list_del(&hba_port->list); ++ kfree(hba_port); ++ } ++ } ++ + for (i = 0; i < sas_node->num_phys; i++) { + if (sas_node->phy[i].remote_identify.sas_address == sas_address) + memset(&sas_node->phy[i].remote_identify, 0 , +@@ -961,14 +1002,19 @@ mpt3sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy + * @handle: attached device handle + * @phy_number: phy number + * @link_rate: new link rate ++ * @port: hba port entry ++ * ++ * Return nothing. + */ + void + mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, +- u64 sas_address, u16 handle, u8 phy_number, u8 link_rate) ++ u64 sas_address, u16 handle, u8 phy_number, u8 link_rate, ++ struct hba_port *port) + { + unsigned long flags; + struct _sas_node *sas_node; + struct _sas_phy *mpt3sas_phy; ++ struct hba_port *hba_port = NULL; + + if (ioc->shost_recovery || ioc->pci_error_recovery) + return; +@@ -988,6 +1034,15 @@ mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, + &mpt3sas_phy->remote_identify); + _transport_add_phy_to_an_existing_port(ioc, sas_node, + mpt3sas_phy, mpt3sas_phy->remote_identify.sas_address); ++ if (sas_node->handle <= ioc->sas_hba.num_phys) { ++ list_for_each_entry(hba_port, ++ &ioc->port_table_list, list) { ++ if (hba_port->sas_address == sas_address && ++ hba_port == port) ++ hba_port->phy_mask |= ++ (1 << mpt3sas_phy->phy_id); ++ } ++ } + } else + memset(&mpt3sas_phy->remote_identify, 0 , sizeof(struct + sas_identify)); +-- +2.13.6 + diff --git a/SOURCES/0024-scsi-scsi-mpt3sas-Get-device-objects-using-sas_addre.patch b/SOURCES/0024-scsi-scsi-mpt3sas-Get-device-objects-using-sas_addre.patch new file mode 100644 index 0000000..b747019 --- /dev/null +++ b/SOURCES/0024-scsi-scsi-mpt3sas-Get-device-objects-using-sas_addre.patch @@ -0,0 +1,803 @@ +From a3acf223af8462a6cf293b2587f0f31bc139930a Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +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 +RH-Acked-by: Tony Camuso + +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 +Signed-off-by: Martin K. Petersen +(cherry picked from commit 7d310f241001e090cf1ec0f3ae836b38d8c6ebec) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + 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 + diff --git a/SOURCES/0025-scsi-scsi-mpt3sas-Rename-transport_del_phy_from_an_e.patch b/SOURCES/0025-scsi-scsi-mpt3sas-Rename-transport_del_phy_from_an_e.patch new file mode 100644 index 0000000..c657f68 --- /dev/null +++ b/SOURCES/0025-scsi-scsi-mpt3sas-Rename-transport_del_phy_from_an_e.patch @@ -0,0 +1,160 @@ +From 4f9cb26b852566482d4c87b5b8ffa4ee8fcb880b Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:50 -0500 +Subject: [PATCH 25/33] [scsi] scsi: mpt3sas: Rename + transport_del_phy_from_an_existing_port() + +Message-id: <20201113184258.11169-7-thenzl@redhat.com> +Patchwork-id: 339462 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 06/14] scsi: mpt3sas: Rename transport_del_phy_from_an_existing_port() +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +Renamed _transport_add_phy_to_an_existing_port() to +mpt3sas_transport_add_phy_to_an_existing_port() and +_transport_del_phy_from_an_existing_port() to +mpt3sas_transport_del_phy_from_an_existing_port() as the driver needs to +call these functions from outside mpt3sas_transport.c file. + +Added extra function argument 'port' of type struct hba_port to above +functions and check for portID before adding/removing the phy from the +_sas_port object. I.e. add/remove the phy from _sas_port object only if +_sas_port's port object and phy's port object are the same. + +Link: https://lore.kernel.org/r/20201027130847.9962-7-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit c71ccf93c00c0cef062c2371e9a614526fee9adb) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 7 +++++++ + drivers/scsi/mpt3sas/mpt3sas_transport.c | 35 +++++++++++++++++++++----------- + 2 files changed, 30 insertions(+), 12 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index b5d1fc5b665b..24db6273e5f5 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -1811,6 +1811,13 @@ void mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, + struct hba_port *port); + extern struct sas_function_template mpt3sas_transport_functions; + extern struct scsi_transport_template *mpt3sas_transport_template; ++void ++mpt3sas_transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy); ++void ++mpt3sas_transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy, ++ u64 sas_address, struct hba_port *port); + /* trigger data externs */ + void mpt3sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc, + struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data); +diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c +index 54c004e96170..560ce323646f 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c +@@ -503,16 +503,17 @@ _transport_add_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_port *mpt3sas_port, + } + + /** +- * _transport_add_phy_to_an_existing_port - adding new phy to existing port ++ * mpt3sas_transport_add_phy_to_an_existing_port - adding new phy to existing port + * @ioc: per adapter object + * @sas_node: sas node object (either expander or sas host) + * @mpt3sas_phy: mpt3sas per phy object + * @sas_address: sas address of device/expander were phy needs to be added to ++ * @port: hba port entry + */ +-static void +-_transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc, ++void ++mpt3sas_transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc, + struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy, +- u64 sas_address) ++ u64 sas_address, struct hba_port *port) + { + struct _sas_port *mpt3sas_port; + struct _sas_phy *phy_srch; +@@ -520,11 +521,16 @@ _transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc, + if (mpt3sas_phy->phy_belongs_to_port == 1) + return; + ++ if (!port) ++ return; ++ + list_for_each_entry(mpt3sas_port, &sas_node->sas_port_list, + port_list) { + if (mpt3sas_port->remote_identify.sas_address != + sas_address) + continue; ++ if (mpt3sas_port->hba_port != port) ++ continue; + list_for_each_entry(phy_srch, &mpt3sas_port->phy_list, + port_siblings) { + if (phy_srch == mpt3sas_phy) +@@ -537,13 +543,13 @@ _transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc, + } + + /** +- * _transport_del_phy_from_an_existing_port - delete phy from existing port ++ * mpt3sas_transport_del_phy_from_an_existing_port - delete phy from existing port + * @ioc: per adapter object + * @sas_node: sas node object (either expander or sas host) + * @mpt3sas_phy: mpt3sas per phy object + */ +-static void +-_transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc, ++void ++mpt3sas_transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc, + struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy) + { + struct _sas_port *mpt3sas_port, *next; +@@ -559,7 +565,11 @@ _transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc, + if (phy_srch != mpt3sas_phy) + continue; + +- if (mpt3sas_port->num_phys == 1) ++ /* ++ * Don't delete port during host reset, ++ * just delete phy. ++ */ ++ if (mpt3sas_port->num_phys == 1 && !ioc->shost_recovery) + _transport_delete_port(ioc, mpt3sas_port); + else + _transport_delete_phy(ioc, mpt3sas_port, +@@ -590,8 +600,8 @@ _transport_sanity_check(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node, + 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]); ++ mpt3sas_transport_del_phy_from_an_existing_port(ioc, ++ sas_node, &sas_node->phy[i]); + } + } + +@@ -1040,8 +1050,6 @@ mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, + if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { + _transport_set_identify(ioc, handle, + &mpt3sas_phy->remote_identify); +- _transport_add_phy_to_an_existing_port(ioc, sas_node, +- mpt3sas_phy, mpt3sas_phy->remote_identify.sas_address); + if (sas_node->handle <= ioc->sas_hba.num_phys) { + list_for_each_entry(hba_port, + &ioc->port_table_list, list) { +@@ -1051,6 +1059,9 @@ mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, + (1 << mpt3sas_phy->phy_id); + } + } ++ mpt3sas_transport_add_phy_to_an_existing_port(ioc, sas_node, ++ mpt3sas_phy, mpt3sas_phy->remote_identify.sas_address, ++ port); + } else + memset(&mpt3sas_phy->remote_identify, 0 , sizeof(struct + sas_identify)); +-- +2.13.6 + diff --git a/SOURCES/0026-scsi-scsi-mpt3sas-Get-sas_device-objects-using-devic.patch b/SOURCES/0026-scsi-scsi-mpt3sas-Get-sas_device-objects-using-devic.patch new file mode 100644 index 0000000..1ec3d83 --- /dev/null +++ b/SOURCES/0026-scsi-scsi-mpt3sas-Get-sas_device-objects-using-devic.patch @@ -0,0 +1,166 @@ +From 1a115069ae8ddff904289d5687092df836ff3392 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:51 -0500 +Subject: [PATCH 26/33] [scsi] scsi: mpt3sas: Get sas_device objects using + device's rphy + +Message-id: <20201113184258.11169-8-thenzl@redhat.com> +Patchwork-id: 339470 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 07/14] scsi: mpt3sas: Get sas_device objects using device's rphy +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +In the following scsi_host_template and sas_function_template callback +functions the driver does not have PhysicalPort number information to +retrieve the sas_device object using SAS Address & PhysicalPort number. In +these callback functions the device's rphy object is used to retrieve +sas_device object for the device. + +.target_alloc, +.get_enclosure_identifier +.get_bay_identifier + +When a rphy (of type sas_rphy) object is allocated then its address is +saved in corresponding sas_device object's rphy field. In +__mpt3sas_get_sdev_by_rphy(), the driver loops over all the sas_device +objects from sas_device_list list to retrieve the sas_device objects whose +rphy matches the provided rphy. + +Link: https://lore.kernel.org/r/20201027130847.9962-8-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit 6df6be9168f50369ba843f2a12fe8537effbaff1) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 5 ++++ + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 41 ++++++++++++++++++++++++++++++-- + drivers/scsi/mpt3sas/mpt3sas_transport.c | 7 +++--- + 3 files changed, 47 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 24db6273e5f5..047d234cc784 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -537,6 +537,8 @@ struct _internal_cmd { + * @chassis_slot: chassis slot + * @is_chassis_slot_valid: chassis slot valid or not + * @port: hba port entry containing device's port number info ++ * @rphy: device's sas_rphy address used to identify this device structure in ++ * target_alloc callback function + */ + struct _sas_device { + struct list_head list; +@@ -564,6 +566,7 @@ struct _sas_device { + u8 connector_name[5]; + struct kref refcount; + struct hba_port *port; ++ struct sas_rphy *rphy; + }; + + static inline void sas_device_get(struct _sas_device *s) +@@ -1681,6 +1684,8 @@ void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc); + struct _raid_device * + mpt3sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle); + void mpt3sas_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth); ++struct _sas_device * ++__mpt3sas_get_sdev_by_rphy(struct MPT3SAS_ADAPTER *ioc, struct sas_rphy *rphy); + + /* config shared API */ + u8 mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 597b2464222f..2f4766ce0afe 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -638,6 +638,44 @@ mpt3sas_get_pdev_from_target(struct MPT3SAS_ADAPTER *ioc, + return ret; + } + ++ ++/** ++ * __mpt3sas_get_sdev_by_rphy - sas device search ++ * @ioc: per adapter object ++ * @rphy: sas_rphy pointer ++ * ++ * Context: This function will acquire ioc->sas_device_lock and will release ++ * before returning the sas_device object. ++ * ++ * This searches for sas_device from rphy object ++ * then return sas_device object. ++ */ ++struct _sas_device * ++__mpt3sas_get_sdev_by_rphy(struct MPT3SAS_ADAPTER *ioc, ++ struct sas_rphy *rphy) ++{ ++ struct _sas_device *sas_device; ++ ++ assert_spin_locked(&ioc->sas_device_lock); ++ ++ list_for_each_entry(sas_device, &ioc->sas_device_list, list) { ++ if (sas_device->rphy != rphy) ++ continue; ++ sas_device_get(sas_device); ++ return sas_device; ++ } ++ ++ sas_device = NULL; ++ list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) { ++ if (sas_device->rphy != rphy) ++ continue; ++ sas_device_get(sas_device); ++ return sas_device; ++ } ++ ++ return NULL; ++} ++ + /** + * mpt3sas_get_sdev_by_addr - get _sas_device object corresponding to provided + * sas address from sas_device_list list +@@ -1815,8 +1853,7 @@ scsih_target_alloc(struct scsi_target *starget) + /* sas/sata devices */ + 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, NULL); ++ sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy); + + if (sas_device) { + sas_target_priv_data->handle = sas_device->handle; +diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c +index 560ce323646f..3cc78c214ec4 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c +@@ -733,6 +733,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, + mpt3sas_port->port = port; + if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { + rphy = sas_end_device_alloc(port); ++ sas_device->rphy = rphy; + if (sas_node->handle <= ioc->sas_hba.num_phys) + hba_port->sas_address = sas_device->sas_address; + } else { +@@ -1342,8 +1343,7 @@ _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier) + int rc; + + spin_lock_irqsave(&ioc->sas_device_lock, flags); +- sas_device = __mpt3sas_get_sdev_by_addr(ioc, +- rphy->identify.sas_address, 0); ++ sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy); + if (sas_device) { + *identifier = sas_device->enclosure_logical_id; + rc = 0; +@@ -1372,8 +1372,7 @@ _transport_get_bay_identifier(struct sas_rphy *rphy) + int rc; + + spin_lock_irqsave(&ioc->sas_device_lock, flags); +- sas_device = __mpt3sas_get_sdev_by_addr(ioc, +- rphy->identify.sas_address, 0); ++ sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy); + if (sas_device) { + rc = sas_device->slot; + sas_device_put(sas_device); +-- +2.13.6 + diff --git a/SOURCES/0027-scsi-scsi-mpt3sas-Update-hba_port-objects-after-host.patch b/SOURCES/0027-scsi-scsi-mpt3sas-Update-hba_port-objects-after-host.patch new file mode 100644 index 0000000..ee66938 --- /dev/null +++ b/SOURCES/0027-scsi-scsi-mpt3sas-Update-hba_port-objects-after-host.patch @@ -0,0 +1,509 @@ +From 250b49deb1ea1e9e5759e4087e028f871d178e6a Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:52 -0500 +Subject: [PATCH 27/33] [scsi] scsi: mpt3sas: Update hba_port objects after + host reset + +Message-id: <20201113184258.11169-9-thenzl@redhat.com> +Patchwork-id: 339465 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 08/14] scsi: mpt3sas: Update hba_port objects after host reset +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +During host reset there is a chance that the Port number allocated by the +firmware for the attached devices may change. Also, it may be possible that +some HBA phy's can go down/come up after reset. As a result, the driver +can't just trust the HBA Port table that it has populated before host reset +as valid. Instead it has to update the HBA Port table in such a way that it +shouldn't disturb the drives which are still accessible even after host +reset. + +Use the following algorithm to update the HBA Port table during host reset: + +I. After host reset operation and before marking the devices as + responding/non-responding, create a temporary Port table called "New + Port table" by parsing each of the HBA phy's Phy data info read from SAS + IOUnit Page0: + + a. Check whether Phy's negotiated link rate is greater than 1.5Gbps, if + not go to next Phy; + + b. Get the SAS Address of the attached device; + + c. Create a new entry in the "New Port table" with SAS Address field + filled with attached device's SAS Address, port number with Phy's + Port number (read from SAS IOUnit Page0) and enable bit in the 'Phy + mask' field corresponding to current Phy number. New entry is + created only if the driver can't find an entry in the "New Port + table" which matches with attached device 'SAS Address' & 'Port + Number'. If it finds an entry with matches with attached device 'SAS + Address' & 'Port Number' then the driver takes that matched entry and + will enable current Phy number bit in the 'Phy mask' field; + + d. After parsing all the HBA phy's info, the driver will have complete + Port table info in "New Port table". + +II. Mark all the existing sas_device & sas_expander device structures as + 'dirty'. + +III. Mark each entry of the HBA Port lists as 'dirty'. + +IV. Take each entry from 'New Port table' one by one and check whether the + entry has any corresponding matched entry (which is marked as 'dirty') + in the HBA Port table or not. While looking for a corresponding + matched entry, look for matched entry in the sequence from top row to + bottom row listed in the following table. If you find any matched entry + (according to any of the rules tabulated below) then perform the action + mentioned in the 'Action' column in that matched rule. + + =========================================================================== + |Search |SAS | Phy Mask | Port | Possibilities| Action | + |every |Address | or | Number | | required | + |entry |matched?| subset of| matched?| | | + |in below| | phy mask | | | | + |sequence| | matched? | | | | + =========================================================================== + | 1 |matched | matched | matched | nothing |* unmark HBA port | + | | | | | changed |table entry as | + | | | | | |dirty | + --------------------------------------------------------------------------- + | 2 |matched | matched | not | port number |* Update port | + | | | | matched | is changed |number in the | + | | | | | |matched port table | + | | | | | |entry | + | | | | | |* unmask HBA port | + | | | | | |table entry as | + | | | | | |dirty | + --------------------------------------------------------------------------- + | 3.a |matched | subset of| matched |some phys |* Add these new | + | | | phy mask | (or) |might have |phys to current | + | | | matched | not |enabled which |port in STL | + | | | | matched |are previously|* Update phy mask | + | | | | (but |disabled |field in HBA's port| + | | | | first | |table's matched | + | | | | look for| |entry, | + | | | | matched | |* Update port | + | | | | one) | |number in the | + | | | | | |matched port | + | | | | | |table entry (if | + | | | | | |port number is | + | | | | | |changed), | + | | | | | |* Unmask HBA port | + | | | | | |table entry as | + | | | | | |dirty | + --------------------------------------------------------------------------- + | 3.b |matched | subset of| matched |some phys |*Remove these phys | + | | | phy mask | (or) |might have |from current port | + | | | matched | not |disabled which|in STL | + | | | | matched |are previously|* Update phy mask | + | | | | (but |enabled |field in HBA's port| + | | | | first | |tables's matched | + | | | | look for| |entry, | + | | | | matched | |*Update port number| + | | | | one) | |in the matched port| + | | | | | |table entry (if | + | | | | | |port number is | + | | | | | |changed), | + | | | | | |* Unmask HBA port | + | | | | | |table entry as | + | | | | | |dirty | + --------------------------------------------------------------------------- + | 4 |matched | not | matched |A cable |*Remove old phys & | + | | | matched | (or) |attached to an|new phys to current| + | | | | not |expander is |port in STL | + | | | | matched |changed to |* Update phy mask | + | | | | |another HBA |field in HBA's port| + | | | | |port during |tables's matched | + | | | | |reset |entry, | + | | | | | |*Update port number| + | | | | | |in the matched port| + | | | | | |table entry (if | + | | | | | |port number is | + | | | | | |changed), | + | | | | | |* Unmask HBA port | + | | | | | |table entry as | + | | | | | |dirty | + --------------------------------------------------------------------------- + +V. Delete the hba_port objects which are still marked as dirty. + +Link: https://lore.kernel.org/r/20201027130847.9962-9-sreekanth.reddy@broadcom.com +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit a5e99fda017218516d3c66bec5ed346283ae722b) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 338 +++++++++++++++++++++++++++++++++++ + 1 file changed, 338 insertions(+) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 2f4766ce0afe..ce8d3c7e7f6e 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -5817,6 +5817,342 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) + } + + /** ++ * _scsih_get_port_table_after_reset - Construct temporary port table ++ * @ioc: per adapter object ++ * @port_table: address where port table needs to be constructed ++ * ++ * return number of HBA port entries available after reset. ++ */ ++static int ++_scsih_get_port_table_after_reset(struct MPT3SAS_ADAPTER *ioc, ++ struct hba_port *port_table) ++{ ++ u16 sz, ioc_status; ++ int i, j; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; ++ u16 attached_handle; ++ u64 attached_sas_addr; ++ u8 found = 0, port_count = 0, port_id; ++ ++ sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys ++ * sizeof(Mpi2SasIOUnit0PhyData_t)); ++ sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg0) { ++ ioc_err(ioc, "failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return port_count; ++ } ++ ++ if ((mpt3sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, ++ sas_iounit_pg0, sz)) != 0) ++ goto out; ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ goto out; ++ for (i = 0; i < ioc->sas_hba.num_phys; i++) { ++ found = 0; ++ if ((sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4) < ++ MPI2_SAS_NEG_LINK_RATE_1_5) ++ continue; ++ attached_handle = ++ le16_to_cpu(sas_iounit_pg0->PhyData[i].AttachedDevHandle); ++ if (_scsih_get_sas_address( ++ ioc, attached_handle, &attached_sas_addr) != 0) { ++ ioc_err(ioc, "failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ continue; ++ } ++ ++ for (j = 0; j < port_count; j++) { ++ port_id = sas_iounit_pg0->PhyData[i].Port; ++ if (port_table[j].port_id == port_id && ++ port_table[j].sas_address == attached_sas_addr) { ++ port_table[j].phy_mask |= (1 << i); ++ found = 1; ++ break; ++ } ++ } ++ ++ if (found) ++ continue; ++ ++ port_id = sas_iounit_pg0->PhyData[i].Port; ++ port_table[port_count].port_id = port_id; ++ port_table[port_count].phy_mask = (1 << i); ++ port_table[port_count].sas_address = attached_sas_addr; ++ port_count++; ++ } ++out: ++ kfree(sas_iounit_pg0); ++ return port_count; ++} ++ ++enum hba_port_matched_codes { ++ NOT_MATCHED = 0, ++ MATCHED_WITH_ADDR_AND_PHYMASK, ++ MATCHED_WITH_ADDR_SUBPHYMASK_AND_PORT, ++ MATCHED_WITH_ADDR_AND_SUBPHYMASK, ++ MATCHED_WITH_ADDR, ++}; ++ ++/** ++ * _scsih_look_and_get_matched_port_entry - Get matched hba port entry ++ * from HBA port table ++ * @ioc: per adapter object ++ * @port_entry - hba port entry from temporary port table which needs to be ++ * searched for matched entry in the HBA port table ++ * @matched_port_entry - save matched hba port entry here ++ * @count - count of matched entries ++ * ++ * return type of matched entry found. ++ */ ++static enum hba_port_matched_codes ++_scsih_look_and_get_matched_port_entry(struct MPT3SAS_ADAPTER *ioc, ++ struct hba_port *port_entry, ++ struct hba_port **matched_port_entry, int *count) ++{ ++ struct hba_port *port_table_entry, *matched_port = NULL; ++ enum hba_port_matched_codes matched_code = NOT_MATCHED; ++ int lcount = 0; ++ *matched_port_entry = NULL; ++ ++ list_for_each_entry(port_table_entry, &ioc->port_table_list, list) { ++ if (!(port_table_entry->flags & HBA_PORT_FLAG_DIRTY_PORT)) ++ continue; ++ ++ if ((port_table_entry->sas_address == port_entry->sas_address) ++ && (port_table_entry->phy_mask == port_entry->phy_mask)) { ++ matched_code = MATCHED_WITH_ADDR_AND_PHYMASK; ++ matched_port = port_table_entry; ++ break; ++ } ++ ++ if ((port_table_entry->sas_address == port_entry->sas_address) ++ && (port_table_entry->phy_mask & port_entry->phy_mask) ++ && (port_table_entry->port_id == port_entry->port_id)) { ++ matched_code = MATCHED_WITH_ADDR_SUBPHYMASK_AND_PORT; ++ matched_port = port_table_entry; ++ continue; ++ } ++ ++ if ((port_table_entry->sas_address == port_entry->sas_address) ++ && (port_table_entry->phy_mask & port_entry->phy_mask)) { ++ if (matched_code == ++ MATCHED_WITH_ADDR_SUBPHYMASK_AND_PORT) ++ continue; ++ matched_code = MATCHED_WITH_ADDR_AND_SUBPHYMASK; ++ matched_port = port_table_entry; ++ continue; ++ } ++ ++ if (port_table_entry->sas_address == port_entry->sas_address) { ++ if (matched_code == ++ MATCHED_WITH_ADDR_SUBPHYMASK_AND_PORT) ++ continue; ++ if (matched_code == MATCHED_WITH_ADDR_AND_SUBPHYMASK) ++ continue; ++ matched_code = MATCHED_WITH_ADDR; ++ matched_port = port_table_entry; ++ lcount++; ++ } ++ } ++ ++ *matched_port_entry = matched_port; ++ if (matched_code == MATCHED_WITH_ADDR) ++ *count = lcount; ++ return matched_code; ++} ++ ++/** ++ * _scsih_del_phy_part_of_anther_port - remove phy if it ++ * is a part of anther port ++ *@ioc: per adapter object ++ *@port_table: port table after reset ++ *@index: hba port entry index ++ *@port_count: number of ports available after host reset ++ *@offset: HBA phy bit offset ++ * ++ */ ++static void ++_scsih_del_phy_part_of_anther_port(struct MPT3SAS_ADAPTER *ioc, ++ struct hba_port *port_table, ++ int index, u8 port_count, int offset) ++{ ++ struct _sas_node *sas_node = &ioc->sas_hba; ++ u32 i, found = 0; ++ ++ for (i = 0; i < port_count; i++) { ++ if (i == index) ++ continue; ++ ++ if (port_table[i].phy_mask & (1 << offset)) { ++ mpt3sas_transport_del_phy_from_an_existing_port( ++ ioc, sas_node, &sas_node->phy[offset]); ++ found = 1; ++ break; ++ } ++ } ++ if (!found) ++ port_table[index].phy_mask |= (1 << offset); ++} ++ ++/** ++ * _scsih_add_or_del_phys_from_existing_port - add/remove phy to/from ++ * right port ++ *@ioc: per adapter object ++ *@hba_port_entry: hba port table entry ++ *@port_table: temporary port table ++ *@index: hba port entry index ++ *@port_count: number of ports available after host reset ++ * ++ */ ++static void ++_scsih_add_or_del_phys_from_existing_port(struct MPT3SAS_ADAPTER *ioc, ++ struct hba_port *hba_port_entry, struct hba_port *port_table, ++ int index, int port_count) ++{ ++ u32 phy_mask, offset = 0; ++ struct _sas_node *sas_node = &ioc->sas_hba; ++ ++ phy_mask = hba_port_entry->phy_mask ^ port_table[index].phy_mask; ++ ++ for (offset = 0; offset < ioc->sas_hba.num_phys; offset++) { ++ if (phy_mask & (1 << offset)) { ++ if (!(port_table[index].phy_mask & (1 << offset))) { ++ _scsih_del_phy_part_of_anther_port( ++ ioc, port_table, index, port_count, ++ offset); ++ continue; ++ } ++ if (sas_node->phy[offset].phy_belongs_to_port) ++ mpt3sas_transport_del_phy_from_an_existing_port( ++ ioc, sas_node, &sas_node->phy[offset]); ++ mpt3sas_transport_add_phy_to_an_existing_port( ++ ioc, sas_node, &sas_node->phy[offset], ++ hba_port_entry->sas_address, ++ hba_port_entry); ++ } ++ } ++} ++ ++/** ++ * _scsih_del_dirty_port_entries - delete dirty port entries from port list ++ * after host reset ++ *@ioc: per adapter object ++ * ++ */ ++static void ++_scsih_del_dirty_port_entries(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct hba_port *port, *port_next; ++ ++ list_for_each_entry_safe(port, port_next, ++ &ioc->port_table_list, list) { ++ if (!(port->flags & HBA_PORT_FLAG_DIRTY_PORT) || ++ port->flags & HBA_PORT_FLAG_NEW_PORT) ++ continue; ++ ++ drsprintk(ioc, ioc_info(ioc, ++ "Deleting port table entry %p having Port: %d\t Phy_mask 0x%08x\n", ++ port, port->port_id, port->phy_mask)); ++ list_del(&port->list); ++ kfree(port); ++ } ++} ++ ++/** ++ * _scsih_sas_port_refresh - Update HBA port table after host reset ++ * @ioc: per adapter object ++ */ ++static void ++_scsih_sas_port_refresh(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u32 port_count = 0; ++ struct hba_port *port_table; ++ struct hba_port *port_table_entry; ++ struct hba_port *port_entry = NULL; ++ int i, j, count = 0, lcount = 0; ++ int ret; ++ u64 sas_addr; ++ ++ drsprintk(ioc, ioc_info(ioc, ++ "updating ports for sas_host(0x%016llx)\n", ++ (unsigned long long)ioc->sas_hba.sas_address)); ++ ++ port_table = kcalloc(ioc->sas_hba.num_phys, ++ sizeof(struct hba_port), GFP_KERNEL); ++ if (!port_table) ++ return; ++ ++ port_count = _scsih_get_port_table_after_reset(ioc, port_table); ++ if (!port_count) ++ return; ++ ++ drsprintk(ioc, ioc_info(ioc, "New Port table\n")); ++ for (j = 0; j < port_count; j++) ++ drsprintk(ioc, ioc_info(ioc, ++ "Port: %d\t Phy_mask 0x%08x\t sas_addr(0x%016llx)\n", ++ port_table[j].port_id, ++ port_table[j].phy_mask, port_table[j].sas_address)); ++ ++ list_for_each_entry(port_table_entry, &ioc->port_table_list, list) ++ port_table_entry->flags |= HBA_PORT_FLAG_DIRTY_PORT; ++ ++ drsprintk(ioc, ioc_info(ioc, "Old Port table\n")); ++ port_table_entry = NULL; ++ list_for_each_entry(port_table_entry, &ioc->port_table_list, list) { ++ drsprintk(ioc, ioc_info(ioc, ++ "Port: %d\t Phy_mask 0x%08x\t sas_addr(0x%016llx)\n", ++ port_table_entry->port_id, ++ port_table_entry->phy_mask, ++ port_table_entry->sas_address)); ++ } ++ ++ for (j = 0; j < port_count; j++) { ++ ret = _scsih_look_and_get_matched_port_entry(ioc, ++ &port_table[j], &port_entry, &count); ++ if (!port_entry) { ++ drsprintk(ioc, ioc_info(ioc, ++ "No Matched entry for sas_addr(0x%16llx), Port:%d\n", ++ port_table[j].sas_address, ++ port_table[j].port_id)); ++ continue; ++ } ++ ++ switch (ret) { ++ case MATCHED_WITH_ADDR_SUBPHYMASK_AND_PORT: ++ case MATCHED_WITH_ADDR_AND_SUBPHYMASK: ++ _scsih_add_or_del_phys_from_existing_port(ioc, ++ port_entry, port_table, j, port_count); ++ break; ++ case MATCHED_WITH_ADDR: ++ sas_addr = port_table[j].sas_address; ++ for (i = 0; i < port_count; i++) { ++ if (port_table[i].sas_address == sas_addr) ++ lcount++; ++ } ++ ++ if (count > 1 || lcount > 1) ++ port_entry = NULL; ++ else ++ _scsih_add_or_del_phys_from_existing_port(ioc, ++ port_entry, port_table, j, port_count); ++ } ++ ++ if (!port_entry) ++ continue; ++ ++ if (port_entry->port_id != port_table[j].port_id) ++ port_entry->port_id = port_table[j].port_id; ++ port_entry->flags &= ~HBA_PORT_FLAG_DIRTY_PORT; ++ port_entry->phy_mask = port_table[j].phy_mask; ++ } ++ ++ port_table_entry = NULL; ++} ++ ++/** + * _scsih_sas_host_refresh - refreshing sas host object contents + * @ioc: per adapter object + * Context: user +@@ -9790,6 +10126,7 @@ mpt3sas_scsih_reset_done_handler(struct MPT3SAS_ADAPTER *ioc) + dtmprintk(ioc, ioc_info(ioc, "%s: MPT3_IOC_DONE_RESET\n", __func__)); + if ((!ioc->is_driver_loading) && !(disable_discovery > 0 && + !ioc->sas_hba.num_phys)) { ++ _scsih_sas_port_refresh(ioc); + _scsih_prep_device_scan(ioc); + _scsih_create_enclosure_list_after_reset(ioc); + _scsih_search_responding_sas_devices(ioc); +@@ -9837,6 +10174,7 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) + ssleep(1); + } + _scsih_remove_unresponding_devices(ioc); ++ _scsih_del_dirty_port_entries(ioc); + _scsih_scan_for_devices_after_reset(ioc); + _scsih_set_nvme_max_shutdown_latency(ioc); + break; +-- +2.13.6 + diff --git a/SOURCES/0028-scsi-scsi-mpt3sas-Set-valid-PhysicalPort-in-SMPPassT.patch b/SOURCES/0028-scsi-scsi-mpt3sas-Set-valid-PhysicalPort-in-SMPPassT.patch new file mode 100644 index 0000000..745d178 --- /dev/null +++ b/SOURCES/0028-scsi-scsi-mpt3sas-Set-valid-PhysicalPort-in-SMPPassT.patch @@ -0,0 +1,221 @@ +From 079d207dcc48755b9b3bfe1ca440c04e5e09d132 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:53 -0500 +Subject: [PATCH 28/33] [scsi] scsi: mpt3sas: Set valid PhysicalPort in + SMPPassThrough + +Message-id: <20201113184258.11169-10-thenzl@redhat.com> +Patchwork-id: 339464 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 09/14] scsi: mpt3sas: Set valid PhysicalPort in SMPPassThrough +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +The driver currently sets PhysicalPort field to 0xFF for SMPPassthrough +Request message. In zoning topologies this SMPPassthrough command always +operates on devices in one zone (default zone) even when user issues SMP +command for other zone drives. + +Define _transport_get_port_id_by_rphy() and +_transport_get_port_id_by_sas_phy() helper functions to get Physical Port +number from sas_rphy & sas_phy respectively for SMPPassthrough request +message so that SMP Passthrough request message is sent to intended zone +device. + +Link: https://lore.kernel.org/r/20201027130847.9962-10-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit 9d0348a9d8e35142b809d0b92534312a22f6fd78) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 2 + + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 1 + + drivers/scsi/mpt3sas/mpt3sas_transport.c | 75 +++++++++++++++++++++++++++++--- + 3 files changed, 72 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 047d234cc784..a8e42d1ba2e5 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -788,6 +788,7 @@ struct _sas_phy { + * @phy: a list of phys that make up this sas_host/expander + * @sas_port_list: list of ports attached to this sas_host/expander + * @port: hba port entry containing node's port number info ++ * @rphy: sas_rphy object of this expander + */ + struct _sas_node { + struct list_head list; +@@ -802,6 +803,7 @@ struct _sas_node { + struct hba_port *port; + struct _sas_phy *phy; + struct list_head sas_port_list; ++ struct sas_rphy *rphy; + }; + + /** +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index ce8d3c7e7f6e..38dfd6eefc65 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -6510,6 +6510,7 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) + goto out_fail; + } + sas_expander->parent_dev = &mpt3sas_port->rphy->dev; ++ sas_expander->rphy = mpt3sas_port->rphy; + + for (i = 0 ; i < sas_expander->num_phys ; i++) { + if ((mpt3sas_config_get_expander_pg1(ioc, &mpi_reply, +diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c +index 3cc78c214ec4..d52d8b3161f2 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c +@@ -61,6 +61,24 @@ + #include "mpt3sas_base.h" + + /** ++ * _transport_get_port_id_by_sas_phy - get zone's port id that Phy belong to ++ * @phy - sas_phy object ++ * ++ * Return Port number ++ */ ++static inline u8 ++_transport_get_port_id_by_sas_phy(struct sas_phy *phy) ++{ ++ u8 port_id = 0xFF; ++ struct hba_port *port = phy->hostdata; ++ ++ if (port) ++ port_id = port->port_id; ++ ++ return port_id; ++} ++ ++/** + * _transport_sas_node_find_by_sas_address - sas node search + * @ioc: per adapter object + * @sas_address: sas address of expander or sas host +@@ -82,6 +100,49 @@ _transport_sas_node_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc, + } + + /** ++ * _transport_get_port_id_by_rphy - Get Port number from rphy object ++ * @ioc: per adapter object ++ * @rphy: sas_rphy object ++ * ++ * Returns Port number. ++ */ ++static u8 ++_transport_get_port_id_by_rphy(struct MPT3SAS_ADAPTER *ioc, ++ struct sas_rphy *rphy) ++{ ++ struct _sas_node *sas_expander; ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ u8 port_id = 0xFF; ++ ++ if (!rphy) ++ return port_id; ++ ++ if (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE || ++ rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) { ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ list_for_each_entry(sas_expander, ++ &ioc->sas_expander_list, list) { ++ if (sas_expander->rphy == rphy) { ++ port_id = sas_expander->port->port_id; ++ break; ++ } ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ } else if (rphy->identify.device_type == SAS_END_DEVICE) { ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy); ++ if (sas_device) { ++ port_id = sas_device->port->port_id; ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ } ++ ++ return port_id; ++} ++ ++/** + * _transport_convert_phy_link_rate - + * @link_rate: link rate returned from mpt firmware + * +@@ -289,7 +350,7 @@ struct rep_manu_reply { + */ + static int + _transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc, +- u64 sas_address, struct sas_expander_device *edev) ++ u64 sas_address, struct sas_expander_device *edev, u8 port_id) + { + Mpi2SmpPassthroughRequest_t *mpi_request; + Mpi2SmpPassthroughReply_t *mpi_reply; +@@ -356,7 +417,7 @@ _transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc, + + memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); + mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; +- mpi_request->PhysicalPort = 0xFF; ++ mpi_request->PhysicalPort = port_id; + mpi_request->SASAddress = cpu_to_le64(sas_address); + mpi_request->RequestDataLength = cpu_to_le16(data_out_sz); + psge = &mpi_request->SGL; +@@ -772,7 +833,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, + MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) + _transport_expander_report_manufacture(ioc, + mpt3sas_port->remote_identify.sas_address, +- rphy_to_expander_device(rphy)); ++ rphy_to_expander_device(rphy), hba_port->port_id); + return mpt3sas_port; + + out_fail: +@@ -923,6 +984,7 @@ mpt3sas_transport_add_host_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy + phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); + phy->maximum_linkrate = _transport_convert_phy_link_rate( + phy_pg0.ProgrammedLinkRate >> 4); ++ phy->hostdata = mpt3sas_phy->port; + + if ((sas_phy_add(phy))) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", +@@ -993,6 +1055,7 @@ mpt3sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy + expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); + phy->maximum_linkrate = _transport_convert_phy_link_rate( + expander_pg1.ProgrammedLinkRate >> 4); ++ phy->hostdata = mpt3sas_phy->port; + + if ((sas_phy_add(phy))) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", +@@ -1197,7 +1260,7 @@ _transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER *ioc, + + memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); + mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; +- mpi_request->PhysicalPort = 0xFF; ++ mpi_request->PhysicalPort = _transport_get_port_id_by_sas_phy(phy); + mpi_request->VF_ID = 0; /* TODO */ + mpi_request->VP_ID = 0; + mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); +@@ -1493,7 +1556,7 @@ _transport_expander_phy_control(struct MPT3SAS_ADAPTER *ioc, + + memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); + mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; +- mpi_request->PhysicalPort = 0xFF; ++ mpi_request->PhysicalPort = _transport_get_port_id_by_sas_phy(phy); + mpi_request->VF_ID = 0; /* TODO */ + mpi_request->VP_ID = 0; + mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); +@@ -1983,7 +2046,7 @@ _transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, + + memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); + mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; +- mpi_request->PhysicalPort = 0xFF; ++ mpi_request->PhysicalPort = _transport_get_port_id_by_rphy(ioc, rphy); + mpi_request->SASAddress = (rphy) ? + cpu_to_le64(rphy->identify.sas_address) : + cpu_to_le64(ioc->sas_hba.sas_address); +-- +2.13.6 + diff --git a/SOURCES/0029-scsi-scsi-mpt3sas-Handling-HBA-vSES-device.patch b/SOURCES/0029-scsi-scsi-mpt3sas-Handling-HBA-vSES-device.patch new file mode 100644 index 0000000..f173992 --- /dev/null +++ b/SOURCES/0029-scsi-scsi-mpt3sas-Handling-HBA-vSES-device.patch @@ -0,0 +1,385 @@ +From 2d52f9213dc81071fefae74e56ec162e54045261 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:54 -0500 +Subject: [PATCH 29/33] [scsi] scsi: mpt3sas: Handling HBA vSES device + +Message-id: <20201113184258.11169-11-thenzl@redhat.com> +Patchwork-id: 339471 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 10/14] scsi: mpt3sas: Handling HBA vSES device +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +Each direct attached device will have a unique Port ID, but with an +exception. HBA vSES may use the same Port ID of another direct attached +device Port's ID. As a result, special handling is needed for vSES. + +Create a virtual_phy object when a new HBA vSES device is detected and add +this virtual_phy object to vphys_list of port ID's hba_port object. When +the HBA vSES device is removed then remove the corresponding virtual_phy +object from its parent's hba_port's vphy_list and free this virtual_vphy +object. + +In hba_port object add vphy_mask field to hold the list of HBA phy bits +which are assigned to vSES devices. Also add vphy_list list to hold list of +virtual_phy objects which holds the same portID of current hba_port's +portID. + +Also, add a hba_vphy field in _sas_phy object to determine whether this +_sas_phy object belongs to vSES device or not. + + - Allocate a virtual_phy object whenever a virtual phy is detected while + processing the SASIOUnitPage0's phy data. And this allocated virtual_phy + object to corresponding PortID's hba_port's vphy_list. + + - When a vSES device is added to the SML then initialize the corresponding + virtual_phy objects's sas_address field with vSES device's SAS Address. + + - Free this virtual_phy object during driver unload time and when this + vSES device is removed. + +Link: https://lore.kernel.org/r/20201027130847.9962-11-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit ccc59923ba8d44ecf7cb60135e9934bbb619da10) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 23 +++++++ + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 106 +++++++++++++++++++++++++++++++ + drivers/scsi/mpt3sas/mpt3sas_transport.c | 80 +++++++++++++++++++---- + 3 files changed, 198 insertions(+), 11 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index a8e42d1ba2e5..e7d047adbe86 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -771,6 +771,7 @@ struct _sas_phy { + u16 handle; + u16 attached_handle; + u8 phy_belongs_to_port; ++ u8 hba_vphy; + struct hba_port *port; + }; + +@@ -1024,11 +1025,28 @@ struct reply_post_struct { + }; + + /** ++ * struct virtual_phy - vSES phy structure ++ * sas_address: SAS Address of vSES device ++ * phy_mask: vSES device's phy number ++ * flags: flags used to manage this structure ++ */ ++struct virtual_phy { ++ struct list_head list; ++ u64 sas_address; ++ u32 phy_mask; ++ u8 flags; ++}; ++ ++#define MPT_VPHY_FLAG_DIRTY_PHY 0x01 ++ ++/** + * struct hba_port - Saves each HBA's Wide/Narrow port info + * @sas_address: sas address of this wide/narrow port's attached device + * @phy_mask: HBA PHY's belonging to this port + * @port_id: port number + * @flags: hba port flags ++ * @vphys_mask : mask of vSES devices Phy number ++ * @vphys_list : list containing vSES device structures + */ + struct hba_port { + struct list_head list; +@@ -1036,6 +1054,8 @@ struct hba_port { + u32 phy_mask; + u8 port_id; + u8 flags; ++ u32 vphys_mask; ++ struct list_head vphys_list; + }; + + /* hba port flags */ +@@ -1688,6 +1708,9 @@ mpt3sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle); + void mpt3sas_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth); + struct _sas_device * + __mpt3sas_get_sdev_by_rphy(struct MPT3SAS_ADAPTER *ioc, struct sas_rphy *rphy); ++struct virtual_phy * ++mpt3sas_get_vphy_by_phy(struct MPT3SAS_ADAPTER *ioc, ++ struct hba_port *port, u32 phy); + + /* config shared API */ + u8 mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 38dfd6eefc65..6dfb1b7d3839 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -381,6 +381,30 @@ mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, u8 port_id) + } + + /** ++ * mpt3sas_get_vphy_by_phy - get virtual_phy object corresponding to phy number ++ * @ioc: per adapter object ++ * @port: hba_port object ++ * @phy: phy number ++ * ++ * Return virtual_phy object corresponding to phy number. ++ */ ++struct virtual_phy * ++mpt3sas_get_vphy_by_phy(struct MPT3SAS_ADAPTER *ioc, ++ struct hba_port *port, u32 phy) ++{ ++ struct virtual_phy *vphy, *vphy_next; ++ ++ if (!port->vphys_mask) ++ return NULL; ++ ++ list_for_each_entry_safe(vphy, vphy_next, &port->vphys_list, list) { ++ if (vphy->phy_mask & (1 << phy)) ++ return vphy; ++ } ++ return NULL; ++} ++ ++/** + * _scsih_is_boot_device - search for matching boot device. + * @sas_address: sas address + * @device_name: device name specified in INDENTIFY fram +@@ -6153,6 +6177,47 @@ _scsih_sas_port_refresh(struct MPT3SAS_ADAPTER *ioc) + } + + /** ++ * _scsih_alloc_vphy - allocate virtual_phy object ++ * @ioc: per adapter object ++ * @port_id: Port ID number ++ * @phy_num: HBA Phy number ++ * ++ * Returns allocated virtual_phy object. ++ */ ++static struct virtual_phy * ++_scsih_alloc_vphy(struct MPT3SAS_ADAPTER *ioc, u8 port_id, u8 phy_num) ++{ ++ struct virtual_phy *vphy; ++ struct hba_port *port; ++ ++ port = mpt3sas_get_port_by_id(ioc, port_id); ++ if (!port) ++ return NULL; ++ ++ vphy = mpt3sas_get_vphy_by_phy(ioc, port, phy_num); ++ if (!vphy) { ++ vphy = kzalloc(sizeof(struct virtual_phy), GFP_KERNEL); ++ if (!vphy) ++ return NULL; ++ ++ /* ++ * Enable bit corresponding to HBA phy number on its ++ * parent hba_port object's vphys_mask field. ++ */ ++ port->vphys_mask |= (1 << phy_num); ++ vphy->phy_mask |= (1 << phy_num); ++ ++ INIT_LIST_HEAD(&port->vphys_list); ++ list_add_tail(&vphy->list, &port->vphys_list); ++ ++ ioc_info(ioc, ++ "vphy entry: %p, port id: %d, phy:%d is added to port's vphys_list\n", ++ vphy, port->port_id, phy_num); ++ } ++ return vphy; ++} ++ ++/** + * _scsih_sas_host_refresh - refreshing sas host object contents + * @ioc: per adapter object + * Context: user +@@ -6172,6 +6237,7 @@ _scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc) + u16 attached_handle; + u8 link_rate, port_id; + struct hba_port *port; ++ Mpi2SasPhyPage0_t phy_pg0; + + dtmprintk(ioc, + ioc_info(ioc, "updating handles for sas_host(0x%016llx)\n", +@@ -6211,6 +6277,31 @@ _scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc) + port->flags = HBA_PORT_FLAG_NEW_PORT; + list_add_tail(&port->list, &ioc->port_table_list); + } ++ /* ++ * Check whether current Phy belongs to HBA vSES device or not. ++ */ ++ if (le32_to_cpu(sas_iounit_pg0->PhyData[i].ControllerPhyDeviceInfo) & ++ MPI2_SAS_DEVICE_INFO_SEP && ++ (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { ++ if ((mpt3sas_config_get_phy_pg0(ioc, &mpi_reply, ++ &phy_pg0, i))) { ++ ioc_err(ioc, ++ "failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ if (!(le32_to_cpu(phy_pg0.PhyInfo) & ++ MPI2_SAS_PHYINFO_VIRTUAL_PHY)) ++ continue; ++ /* ++ * Allocate a virtual_phy object for vSES device, if ++ * this vSES device is hot added. ++ */ ++ if (!_scsih_alloc_vphy(ioc, port_id, i)) ++ goto out; ++ ioc->sas_hba.phy[i].hba_vphy = 1; ++ } ++ + ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; + attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i]. + AttachedDevHandle); +@@ -6353,6 +6444,21 @@ _scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc) + &ioc->port_table_list); + } + ++ /* ++ * Check whether current Phy belongs to HBA vSES device or not. ++ */ ++ if ((le32_to_cpu(phy_pg0.PhyInfo) & ++ MPI2_SAS_PHYINFO_VIRTUAL_PHY) && ++ (phy_pg0.NegotiatedLinkRate >> 4) >= ++ MPI2_SAS_NEG_LINK_RATE_1_5) { ++ /* ++ * Allocate a virtual_phy object for vSES device. ++ */ ++ if (!_scsih_alloc_vphy(ioc, port_id, i)) ++ goto out; ++ ioc->sas_hba.phy[i].hba_vphy = 1; ++ } ++ + ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; + ioc->sas_hba.phy[i].phy_id = i; + ioc->sas_hba.phy[i].port = mpt3sas_get_port_by_id(ioc, port_id); +diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c +index d52d8b3161f2..256dae106ec6 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c +@@ -690,6 +690,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, + struct _sas_device *sas_device = NULL; + int i; + struct sas_port *port; ++ struct virtual_phy *vphy = NULL; + + if (!hba_port) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", +@@ -743,9 +744,20 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, + continue; + list_add_tail(&sas_node->phy[i].port_siblings, + &mpt3sas_port->phy_list); +- if (sas_node->handle <= ioc->sas_hba.num_phys) +- hba_port->phy_mask |= (1 << i); + mpt3sas_port->num_phys++; ++ if (sas_node->handle <= ioc->sas_hba.num_phys) { ++ if (!sas_node->phy[i].hba_vphy) { ++ hba_port->phy_mask |= (1 << i); ++ continue; ++ } ++ ++ vphy = mpt3sas_get_vphy_by_phy(ioc, hba_port, i); ++ if (!vphy) { ++ ioc_err(ioc, "failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ goto out_fail; ++ } ++ } + } + + if (!mpt3sas_port->num_phys) { +@@ -795,8 +807,14 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, + if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { + rphy = sas_end_device_alloc(port); + sas_device->rphy = rphy; +- if (sas_node->handle <= ioc->sas_hba.num_phys) +- hba_port->sas_address = sas_device->sas_address; ++ if (sas_node->handle <= ioc->sas_hba.num_phys) { ++ if (!vphy) ++ hba_port->sas_address = ++ sas_device->sas_address; ++ else ++ vphy->sas_address = ++ sas_device->sas_address; ++ } + } else { + rphy = sas_expander_alloc(port, + mpt3sas_port->remote_identify.device_type); +@@ -866,6 +884,7 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + u8 found = 0; + struct _sas_phy *mpt3sas_phy, *next_phy; + struct hba_port *hba_port_next, *hba_port = NULL; ++ struct virtual_phy *vphy, *vphy_next = NULL; + + if (!port) + return; +@@ -894,17 +913,56 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + } + + if (sas_node->handle <= ioc->sas_hba.num_phys) { ++ if (port->vphys_mask) { ++ list_for_each_entry_safe(vphy, vphy_next, ++ &port->vphys_list, list) { ++ if (vphy->sas_address != sas_address) ++ continue; ++ ioc_info(ioc, ++ "remove vphy entry: %p of port:%p,from %d port's vphys list\n", ++ vphy, port, port->port_id); ++ port->vphys_mask &= ~vphy->phy_mask; ++ list_del(&vphy->list); ++ kfree(vphy); ++ } ++ } ++ + list_for_each_entry_safe(hba_port, hba_port_next, + &ioc->port_table_list, list) { + if (hba_port != port) + continue; +- if (hba_port->sas_address != sas_address) +- continue; +- ioc_info(ioc, +- "remove hba_port entry: %p port: %d from hba_port list\n", +- hba_port, hba_port->port_id); +- list_del(&hba_port->list); +- kfree(hba_port); ++ /* ++ * Delete hba_port object if ++ * - hba_port object's sas address matches with current ++ * removed device's sas address and no vphy's ++ * associated with it. ++ * - Current removed device is a vSES device and ++ * none of the other direct attached device have ++ * this vSES device's port number (hence hba_port ++ * object sas_address field will be zero). ++ */ ++ if ((hba_port->sas_address == sas_address || ++ !hba_port->sas_address) && !hba_port->vphys_mask) { ++ ioc_info(ioc, ++ "remove hba_port entry: %p port: %d from hba_port list\n", ++ hba_port, hba_port->port_id); ++ list_del(&hba_port->list); ++ kfree(hba_port); ++ } else if (hba_port->sas_address == sas_address && ++ hba_port->vphys_mask) { ++ /* ++ * Current removed device is a non vSES device ++ * and a vSES device has the same port number ++ * as of current device's port number. Hence ++ * only clear the sas_address filed, don't ++ * delete the hba_port object. ++ */ ++ ioc_info(ioc, ++ "clearing sas_address from hba_port entry: %p port: %d from hba_port list\n", ++ hba_port, hba_port->port_id); ++ port->sas_address = 0; ++ } ++ break; + } + } + +-- +2.13.6 + diff --git a/SOURCES/0030-scsi-scsi-mpt3sas-Add-bypass_dirty_port_flag-paramet.patch b/SOURCES/0030-scsi-scsi-mpt3sas-Add-bypass_dirty_port_flag-paramet.patch new file mode 100644 index 0000000..310aea2 --- /dev/null +++ b/SOURCES/0030-scsi-scsi-mpt3sas-Add-bypass_dirty_port_flag-paramet.patch @@ -0,0 +1,327 @@ +From 65de4561cff13a6abfb73e86f7e4dc8fc89354f5 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:55 -0500 +Subject: [PATCH 30/33] [scsi] scsi: mpt3sas: Add bypass_dirty_port_flag + parameter + +Message-id: <20201113184258.11169-12-thenzl@redhat.com> +Patchwork-id: 339467 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 11/14] scsi: mpt3sas: Add bypass_dirty_port_flag parameter +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +Added a new parameter bypass_dirty_port_flag in function +mpt3sas_get_port_by_id(). When this parameter is set to one then search for +matching hba port entry from port_table_list even when this hba_port entry +is marked as dirty. + +Link: https://lore.kernel.org/r/20201027130847.9962-12-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit 34b0a78532f61e6059a26c0252fbc28c73761384) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 3 +- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 63 +++++++++++++++++++------------- + drivers/scsi/mpt3sas/mpt3sas_transport.c | 8 ++-- + 3 files changed, 44 insertions(+), 30 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index e7d047adbe86..cca14ab570f5 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -1684,7 +1684,8 @@ void mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc, + 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); ++mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, u8 port, ++ u8 bypass_dirty_port_flag); + + struct _sas_node *mpt3sas_scsih_expander_find_by_handle( + struct MPT3SAS_ADAPTER *ioc, u16 handle); +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 6dfb1b7d3839..c3bbf0957d78 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -361,20 +361,27 @@ _scsih_srch_boot_encl_slot(u64 enclosure_logical_id, u16 slot_number, + * port number from port list + * @ioc: per adapter object + * @port_id: port number ++ * @bypass_dirty_port_flag: when set look the matching hba port entry even ++ * if hba port entry is marked as dirty. + * + * Search for hba port entry corresponding to provided port number, + * if available return port object otherwise return NULL. + */ + struct hba_port * +-mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, u8 port_id) ++mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, ++ u8 port_id, u8 bypass_dirty_port_flag) + { + struct hba_port *port, *port_next; + + list_for_each_entry_safe(port, port_next, + &ioc->port_table_list, list) { +- if (port->port_id == port_id && +- !(port->flags & HBA_PORT_FLAG_DIRTY_PORT)) ++ if (port->port_id != port_id) ++ continue; ++ if (bypass_dirty_port_flag) + return port; ++ if (port->flags & HBA_PORT_FLAG_DIRTY_PORT) ++ continue; ++ return port; + } + + return NULL; +@@ -6190,7 +6197,7 @@ _scsih_alloc_vphy(struct MPT3SAS_ADAPTER *ioc, u8 port_id, u8 phy_num) + struct virtual_phy *vphy; + struct hba_port *port; + +- port = mpt3sas_get_port_by_id(ioc, port_id); ++ port = mpt3sas_get_port_by_id(ioc, port_id, 0); + if (!port) + return NULL; + +@@ -6264,7 +6271,7 @@ _scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc) + ioc->sas_hba.handle = le16_to_cpu( + sas_iounit_pg0->PhyData[0].ControllerDevHandle); + port_id = sas_iounit_pg0->PhyData[i].Port; +- if (!(mpt3sas_get_port_by_id(ioc, port_id))) { ++ if (!(mpt3sas_get_port_by_id(ioc, port_id, 0))) { + port = kzalloc(sizeof(struct hba_port), GFP_KERNEL); + if (!port) + goto out; +@@ -6307,7 +6314,8 @@ _scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc) + AttachedDevHandle); + if (attached_handle && link_rate < MPI2_SAS_NEG_LINK_RATE_1_5) + link_rate = MPI2_SAS_NEG_LINK_RATE_1_5; +- ioc->sas_hba.phy[i].port = mpt3sas_get_port_by_id(ioc, port_id); ++ ioc->sas_hba.phy[i].port = ++ mpt3sas_get_port_by_id(ioc, port_id, 0); + mpt3sas_transport_update_links(ioc, ioc->sas_hba.sas_address, + attached_handle, i, link_rate, + ioc->sas_hba.phy[i].port); +@@ -6431,7 +6439,7 @@ _scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc) + PhyData[0].ControllerDevHandle); + + port_id = sas_iounit_pg0->PhyData[i].Port; +- if (!(mpt3sas_get_port_by_id(ioc, port_id))) { ++ if (!(mpt3sas_get_port_by_id(ioc, port_id, 0))) { + port = kzalloc(sizeof(struct hba_port), GFP_KERNEL); + if (!port) + goto out; +@@ -6461,7 +6469,8 @@ _scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc) + + ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; + ioc->sas_hba.phy[i].phy_id = i; +- ioc->sas_hba.phy[i].port = mpt3sas_get_port_by_id(ioc, port_id); ++ ioc->sas_hba.phy[i].port = ++ mpt3sas_get_port_by_id(ioc, port_id, 0); + mpt3sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], + phy_pg0, ioc->sas_hba.parent_dev); + } +@@ -6553,7 +6562,8 @@ _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, mpt3sas_get_port_by_id(ioc, port_id)); ++ sas_address_parent, ++ mpt3sas_get_port_by_id(ioc, port_id, 0)); + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + if (!sas_expander) { + rc = _scsih_expander_add(ioc, parent_handle); +@@ -6565,7 +6575,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, mpt3sas_get_port_by_id(ioc, port_id)); ++ sas_address, mpt3sas_get_port_by_id(ioc, port_id, 0)); + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + + if (sas_expander) +@@ -6583,7 +6593,7 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) + sas_expander->num_phys = expander_pg0.NumPhys; + sas_expander->sas_address_parent = sas_address_parent; + sas_expander->sas_address = sas_address; +- sas_expander->port = mpt3sas_get_port_by_id(ioc, port_id); ++ sas_expander->port = mpt3sas_get_port_by_id(ioc, port_id, 0); + if (!sas_expander->port) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); +@@ -6628,7 +6638,8 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) + } + sas_expander->phy[i].handle = handle; + sas_expander->phy[i].phy_id = i; +- sas_expander->phy[i].port = mpt3sas_get_port_by_id(ioc, port_id); ++ sas_expander->phy[i].port = ++ mpt3sas_get_port_by_id(ioc, port_id, 0); + + if ((mpt3sas_transport_add_expander_phy(ioc, + &sas_expander->phy[i], expander_pg1, +@@ -6835,7 +6846,7 @@ _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); ++ port = mpt3sas_get_port_by_id(ioc, sas_device_pg0.PhysicalPort, 0); + if (!port) + goto out_unlock; + sas_device = __mpt3sas_get_sdev_by_addr(ioc, +@@ -6968,7 +6979,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, mpt3sas_get_port_by_id(ioc, port_id)); ++ sas_address, mpt3sas_get_port_by_id(ioc, port_id, 0)); + if (sas_device) { + clear_bit(handle, ioc->pend_os_device_add); + sas_device_put(sas_device); +@@ -7009,7 +7020,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, + sas_device->phy = sas_device_pg0.PhyNum; + sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) & + MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0; +- sas_device->port = mpt3sas_get_port_by_id(ioc, port_id); ++ sas_device->port = mpt3sas_get_port_by_id(ioc, port_id, 0); + if (!sas_device->port) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); +@@ -7224,7 +7235,7 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc, + } + + parent_handle = le16_to_cpu(event_data->ExpanderDevHandle); +- port = mpt3sas_get_port_by_id(ioc, event_data->PhysicalPort); ++ port = mpt3sas_get_port_by_id(ioc, event_data->PhysicalPort, 0); + + /* handle expander add */ + if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED) +@@ -7415,7 +7426,8 @@ _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, mpt3sas_get_port_by_id(ioc, event_data->PhysicalPort)); ++ sas_address, ++ mpt3sas_get_port_by_id(ioc, event_data->PhysicalPort, 0)); + + if (!sas_device || !sas_device->starget) + goto out; +@@ -8856,7 +8868,8 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc, + if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) + mpt3sas_transport_update_links(ioc, sas_address, handle, + sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5, +- mpt3sas_get_port_by_id(ioc, sas_device_pg0.PhysicalPort)); ++ mpt3sas_get_port_by_id(ioc, ++ sas_device_pg0.PhysicalPort, 0)); + + _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); + _scsih_add_device(ioc, handle, 0, 1); +@@ -9164,7 +9177,7 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc, + mpt3sas_transport_update_links(ioc, sas_address, handle, + sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5, + mpt3sas_get_port_by_id(ioc, +- sas_device_pg0.PhysicalPort)); ++ sas_device_pg0.PhysicalPort, 0)); + + _scsih_add_device(ioc, handle, 0, 1); + +@@ -9290,7 +9303,7 @@ Mpi2SasDevicePage0_t *sas_device_pg0) + struct _enclosure_node *enclosure_dev = NULL; + unsigned long flags; + struct hba_port *port = mpt3sas_get_port_by_id( +- ioc, sas_device_pg0->PhysicalPort); ++ ioc, sas_device_pg0->PhysicalPort, 0); + + if (sas_device_pg0->EnclosureHandle) { + enclosure_dev = +@@ -9718,7 +9731,7 @@ _scsih_mark_responding_expander(struct MPT3SAS_ADAPTER *ioc, + 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); ++ ioc, expander_pg0->PhysicalPort, 0); + + if (enclosure_handle) + enclosure_dev = +@@ -9965,7 +9978,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) + port_id = expander_pg0.PhysicalPort; + expander_device = mpt3sas_scsih_expander_find_by_sas_address( + ioc, le64_to_cpu(expander_pg0.SASAddress), +- mpt3sas_get_port_by_id(ioc, port_id)); ++ mpt3sas_get_port_by_id(ioc, port_id, 0)); + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + if (expander_device) + _scsih_refresh_expander_links(ioc, expander_device, +@@ -10028,7 +10041,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) + mpt3sas_transport_update_links(ioc, sas_address, + handle, sas_device_pg0.PhyNum, + MPI2_SAS_NEG_LINK_RATE_1_5, +- mpt3sas_get_port_by_id(ioc, port_id)); ++ mpt3sas_get_port_by_id(ioc, port_id, 0)); + set_bit(handle, ioc->pd_handles); + retry_count = 0; + /* This will retry adding the end device. +@@ -10117,7 +10130,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) + port_id = sas_device_pg0.PhysicalPort; + sas_device = mpt3sas_get_sdev_by_addr(ioc, + le64_to_cpu(sas_device_pg0.SASAddress), +- mpt3sas_get_port_by_id(ioc, port_id)); ++ mpt3sas_get_port_by_id(ioc, port_id, 0)); + if (sas_device) { + sas_device_put(sas_device); + continue; +@@ -10129,7 +10142,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) + (u64)le64_to_cpu(sas_device_pg0.SASAddress)); + mpt3sas_transport_update_links(ioc, sas_address, handle, + sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5, +- mpt3sas_get_port_by_id(ioc, port_id)); ++ mpt3sas_get_port_by_id(ioc, port_id, 0)); + retry_count = 0; + /* This will retry adding the end device. + * _scsih_add_device() will decide on retries and +diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c +index 256dae106ec6..0d06025d7102 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c +@@ -1414,7 +1414,7 @@ _transport_get_linkerrors(struct sas_phy *phy) + spin_lock_irqsave(&ioc->sas_node_lock, flags); + if (_transport_sas_node_find_by_sas_address(ioc, + phy->identify.sas_address, +- mpt3sas_get_port_by_id(ioc, port_id)) == NULL) { ++ mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) { + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + return -EINVAL; + } +@@ -1703,7 +1703,7 @@ _transport_phy_reset(struct sas_phy *phy, int hard_reset) + spin_lock_irqsave(&ioc->sas_node_lock, flags); + if (_transport_sas_node_find_by_sas_address(ioc, + phy->identify.sas_address, +- mpt3sas_get_port_by_id(ioc, port_id)) == NULL) { ++ mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) { + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + return -EINVAL; + } +@@ -1762,7 +1762,7 @@ _transport_phy_enable(struct sas_phy *phy, int enable) + spin_lock_irqsave(&ioc->sas_node_lock, flags); + if (_transport_sas_node_find_by_sas_address(ioc, + phy->identify.sas_address, +- mpt3sas_get_port_by_id(ioc, port_id)) == NULL) { ++ mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) { + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + return -EINVAL; + } +@@ -1902,7 +1902,7 @@ _transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) + spin_lock_irqsave(&ioc->sas_node_lock, flags); + if (_transport_sas_node_find_by_sas_address(ioc, + phy->identify.sas_address, +- mpt3sas_get_port_by_id(ioc, port_id)) == NULL) { ++ mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) { + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + return -EINVAL; + } +-- +2.13.6 + diff --git a/SOURCES/0031-scsi-scsi-mpt3sas-Handle-vSES-vphy-object-during-HBA.patch b/SOURCES/0031-scsi-scsi-mpt3sas-Handle-vSES-vphy-object-during-HBA.patch new file mode 100644 index 0000000..1a2469e --- /dev/null +++ b/SOURCES/0031-scsi-scsi-mpt3sas-Handle-vSES-vphy-object-during-HBA.patch @@ -0,0 +1,339 @@ +From ea9b56343c1d57917f11bfa9fcd57c6f44238996 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:56 -0500 +Subject: [PATCH 31/33] [scsi] scsi: mpt3sas: Handle vSES vphy object during + HBA reset + +Message-id: <20201113184258.11169-13-thenzl@redhat.com> +Patchwork-id: 339472 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 12/14] scsi: mpt3sas: Handle vSES vphy object during HBA reset +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +During HBA reset the Port ID of vSES device may change. As a result, it is +necessary to refresh virtual_phy objects after reset. + +Each Port's vphy_list table needs to be updated after updating the +HBA port table. The algorithm is as follows: + + - Loop over each port entry from HBA port table + * Loop over each virtual phy entry from port's vphys_list table + - Mark virtual phy entry as dirty by setting dirty bit in virtual phy + entry's flags field + - Read SASIOUnitPage0 page + - Loop over each HBA Phy's Phy data from SASIOUnitPage0 + * If phy's remote attached device is not SES device then continue with + processing next HBA Phy's Phy data; + * Read SASPhyPage0 data for this Phy number and determine whether + current phy is a virtual phy or not. If it is not a virtual phy then + continue with next Phy data; + * Get the current phy's remote attached vSES device's SAS Address; + * Loop over each port entry from HBA port table + - If Port's vphys_mask field is zero then continue with + next Port entry, + - Loop over each virtual phy entry from Port's vphy_list table + - If the current phy's remote SAS Address is different from + virtual phy entry's SAS Address then continue with next + virtual phy entry, + - Set bit corresponding to current phy number in virtual phy + entry's phy_mask field, + - Get the HBA port table's Port entry corresponding to + Phy data's 'Port' value, + * If there is no Port entry corresponding to Phy data's + 'Port' value in HBA port table then create a new port entry + and add it to HBA port table. + - If this retrieved Port entry is the same as the current Port + entry then don't do anything, just clear the dirty bit from + virtual phy entry's flag field and continue with processing + next HBA Phy's Phy data. + - If this retrieved Port entry is different from the current Port + entry then move the current virtual phy entry from current Port's + vphys_list to retrieved Port entry's vphys_list. + * Clear current phy bit in current Port entry's vphys_mask and + set the current phy bit in the retrieved Port entry's + vphys_mask field. + * Clear the dirty bit from virtual phy entry's flag field and + continue with next HBA Phy's Phy data. + - Delete the 'virtual phy' entries and HBA's 'Port table' entries which + are still marked as 'dirty'. + +Link: https://lore.kernel.org/r/20201027130847.9962-13-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit ffa381d6373b10e83dbdac425fb72affc64084f3) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 233 +++++++++++++++++++++++++++++++++++ + 1 file changed, 233 insertions(+) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index c3bbf0957d78..e81c0267027b 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -5848,6 +5848,204 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) + } + + /** ++ * _scsih_update_vphys_after_reset - update the Port's ++ * vphys_list after reset ++ * @ioc: per adapter object ++ * ++ * Returns nothing. ++ */ ++static void ++_scsih_update_vphys_after_reset(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u16 sz, ioc_status; ++ int i; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; ++ u16 attached_handle; ++ u64 attached_sas_addr; ++ u8 found = 0, port_id; ++ Mpi2SasPhyPage0_t phy_pg0; ++ struct hba_port *port, *port_next, *mport; ++ struct virtual_phy *vphy, *vphy_next; ++ struct _sas_device *sas_device; ++ ++ /* ++ * Mark all the vphys objects as dirty. ++ */ ++ list_for_each_entry_safe(port, port_next, ++ &ioc->port_table_list, list) { ++ if (!port->vphys_mask) ++ continue; ++ list_for_each_entry_safe(vphy, vphy_next, ++ &port->vphys_list, list) { ++ vphy->flags |= MPT_VPHY_FLAG_DIRTY_PHY; ++ } ++ } ++ ++ /* ++ * Read SASIOUnitPage0 to get each HBA Phy's data. ++ */ ++ sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + ++ (ioc->sas_hba.num_phys * sizeof(Mpi2SasIOUnit0PhyData_t)); ++ sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg0) { ++ ioc_err(ioc, "failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return; ++ } ++ if ((mpt3sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, ++ sas_iounit_pg0, sz)) != 0) ++ goto out; ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ goto out; ++ /* ++ * Loop over each HBA Phy. ++ */ ++ for (i = 0; i < ioc->sas_hba.num_phys; i++) { ++ /* ++ * Check whether Phy's Negotiation Link Rate is > 1.5G or not. ++ */ ++ if ((sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4) < ++ MPI2_SAS_NEG_LINK_RATE_1_5) ++ continue; ++ /* ++ * Check whether Phy is connected to SEP device or not, ++ * if it is SEP device then read the Phy's SASPHYPage0 data to ++ * determine whether Phy is a virtual Phy or not. if it is ++ * virtual phy then it is conformed that the attached remote ++ * device is a HBA's vSES device. ++ */ ++ if (!(le32_to_cpu( ++ sas_iounit_pg0->PhyData[i].ControllerPhyDeviceInfo) & ++ MPI2_SAS_DEVICE_INFO_SEP)) ++ continue; ++ ++ if ((mpt3sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0, ++ i))) { ++ ioc_err(ioc, "failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ continue; ++ } ++ ++ if (!(le32_to_cpu(phy_pg0.PhyInfo) & ++ MPI2_SAS_PHYINFO_VIRTUAL_PHY)) ++ continue; ++ /* ++ * Get the vSES device's SAS Address. ++ */ ++ attached_handle = le16_to_cpu( ++ sas_iounit_pg0->PhyData[i].AttachedDevHandle); ++ if (_scsih_get_sas_address(ioc, attached_handle, ++ &attached_sas_addr) != 0) { ++ ioc_err(ioc, "failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ continue; ++ } ++ ++ found = 0; ++ port = port_next = NULL; ++ /* ++ * Loop over each virtual_phy object from ++ * each port's vphys_list. ++ */ ++ list_for_each_entry_safe(port, ++ port_next, &ioc->port_table_list, list) { ++ if (!port->vphys_mask) ++ continue; ++ list_for_each_entry_safe(vphy, vphy_next, ++ &port->vphys_list, list) { ++ /* ++ * Continue with next virtual_phy object ++ * if the object is not marked as dirty. ++ */ ++ if (!(vphy->flags & MPT_VPHY_FLAG_DIRTY_PHY)) ++ continue; ++ ++ /* ++ * Continue with next virtual_phy object ++ * if the object's SAS Address is not equals ++ * to current Phy's vSES device SAS Address. ++ */ ++ if (vphy->sas_address != attached_sas_addr) ++ continue; ++ /* ++ * Enable current Phy number bit in object's ++ * phy_mask field. ++ */ ++ if (!(vphy->phy_mask & (1 << i))) ++ vphy->phy_mask = (1 << i); ++ /* ++ * Get hba_port object from hba_port table ++ * corresponding to current phy's Port ID. ++ * if there is no hba_port object corresponding ++ * to Phy's Port ID then create a new hba_port ++ * object & add to hba_port table. ++ */ ++ port_id = sas_iounit_pg0->PhyData[i].Port; ++ mport = mpt3sas_get_port_by_id(ioc, port_id, 1); ++ if (!mport) { ++ mport = kzalloc( ++ sizeof(struct hba_port), GFP_KERNEL); ++ if (!mport) ++ break; ++ mport->port_id = port_id; ++ ioc_info(ioc, ++ "%s: hba_port entry: %p, port: %d is added to hba_port list\n", ++ __func__, mport, mport->port_id); ++ list_add_tail(&mport->list, ++ &ioc->port_table_list); ++ } ++ /* ++ * If mport & port pointers are not pointing to ++ * same hba_port object then it means that vSES ++ * device's Port ID got changed after reset and ++ * hence move current virtual_phy object from ++ * port's vphys_list to mport's vphys_list. ++ */ ++ if (port != mport) { ++ if (!mport->vphys_mask) ++ INIT_LIST_HEAD( ++ &mport->vphys_list); ++ mport->vphys_mask |= (1 << i); ++ port->vphys_mask &= ~(1 << i); ++ list_move(&vphy->list, ++ &mport->vphys_list); ++ sas_device = mpt3sas_get_sdev_by_addr( ++ ioc, attached_sas_addr, port); ++ if (sas_device) ++ sas_device->port = mport; ++ } ++ /* ++ * Earlier while updating the hba_port table, ++ * it is determined that there is no other ++ * direct attached device with mport's Port ID, ++ * Hence mport was marked as dirty. Only vSES ++ * device has this Port ID, so unmark the mport ++ * as dirt. ++ */ ++ if (mport->flags & HBA_PORT_FLAG_DIRTY_PORT) { ++ mport->sas_address = 0; ++ mport->phy_mask = 0; ++ mport->flags &= ++ ~HBA_PORT_FLAG_DIRTY_PORT; ++ } ++ /* ++ * Unmark current virtual_phy object as dirty. ++ */ ++ vphy->flags &= ~MPT_VPHY_FLAG_DIRTY_PHY; ++ found = 1; ++ break; ++ } ++ if (found) ++ break; ++ } ++ } ++out: ++ kfree(sas_iounit_pg0); ++} ++ ++/** + * _scsih_get_port_table_after_reset - Construct temporary port table + * @ioc: per adapter object + * @port_table: address where port table needs to be constructed +@@ -6068,6 +6266,39 @@ _scsih_add_or_del_phys_from_existing_port(struct MPT3SAS_ADAPTER *ioc, + } + + /** ++ * _scsih_del_dirty_vphy - delete virtual_phy objects marked as dirty. ++ * @ioc: per adapter object ++ * ++ * Returns nothing. ++ */ ++static void ++_scsih_del_dirty_vphy(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct hba_port *port, *port_next; ++ struct virtual_phy *vphy, *vphy_next; ++ ++ list_for_each_entry_safe(port, port_next, ++ &ioc->port_table_list, list) { ++ if (!port->vphys_mask) ++ continue; ++ list_for_each_entry_safe(vphy, vphy_next, ++ &port->vphys_list, list) { ++ if (vphy->flags & MPT_VPHY_FLAG_DIRTY_PHY) { ++ drsprintk(ioc, ioc_info(ioc, ++ "Deleting vphy %p entry from port id: %d\t, Phy_mask 0x%08x\n", ++ vphy, port->port_id, ++ vphy->phy_mask)); ++ port->vphys_mask &= ~vphy->phy_mask; ++ list_del(&vphy->list); ++ kfree(vphy); ++ } ++ } ++ if (!port->vphys_mask && !port->sas_address) ++ port->flags |= HBA_PORT_FLAG_DIRTY_PORT; ++ } ++} ++ ++/** + * _scsih_del_dirty_port_entries - delete dirty port entries from port list + * after host reset + *@ioc: per adapter object +@@ -10247,6 +10478,7 @@ mpt3sas_scsih_reset_done_handler(struct MPT3SAS_ADAPTER *ioc) + if ((!ioc->is_driver_loading) && !(disable_discovery > 0 && + !ioc->sas_hba.num_phys)) { + _scsih_sas_port_refresh(ioc); ++ _scsih_update_vphys_after_reset(ioc); + _scsih_prep_device_scan(ioc); + _scsih_create_enclosure_list_after_reset(ioc); + _scsih_search_responding_sas_devices(ioc); +@@ -10294,6 +10526,7 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) + ssleep(1); + } + _scsih_remove_unresponding_devices(ioc); ++ _scsih_del_dirty_vphy(ioc); + _scsih_del_dirty_port_entries(ioc); + _scsih_scan_for_devices_after_reset(ioc); + _scsih_set_nvme_max_shutdown_latency(ioc); +-- +2.13.6 + diff --git a/SOURCES/0032-scsi-scsi-mpt3sas-Add-module-parameter-multipath_on_.patch b/SOURCES/0032-scsi-scsi-mpt3sas-Add-module-parameter-multipath_on_.patch new file mode 100644 index 0000000..54d3952 --- /dev/null +++ b/SOURCES/0032-scsi-scsi-mpt3sas-Add-module-parameter-multipath_on_.patch @@ -0,0 +1,231 @@ +From 2d5d86f58af2097347c8177ad56c29075307aa8a Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:57 -0500 +Subject: [PATCH 32/33] [scsi] scsi: mpt3sas: Add module parameter + multipath_on_hba + +Message-id: <20201113184258.11169-14-thenzl@redhat.com> +Patchwork-id: 339468 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 13/14] scsi: mpt3sas: Add module parameter multipath_on_hba +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +Add module parameter multipath_on_hba to enable/disable multi-port path +topology support. By default this feature is enabled on SAS3.5 HBA device +and disabled on SAS3 &SAS2.5 HBA devices. + +When this feature is disabled then driver uses a default +PhysicalPort(PortID) number i.e. 255 instead of the PhysicalPort number +provided by HBA firmware. + +Link: https://lore.kernel.org/r/20201027130847.9962-14-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit 324c122fc0a41d258239c853854eefd186ae1290) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 2 + + drivers/scsi/mpt3sas/mpt3sas_ctl.c | 6 ++- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 69 ++++++++++++++++++++++++++++++-- + drivers/scsi/mpt3sas/mpt3sas_transport.c | 6 ++- + 4 files changed, 76 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index cca14ab570f5..badd8230cce2 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -1246,6 +1246,7 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); + * which ensures the syncrhonization between cli/sysfs_show path. + * @atomic_desc_capable: Atomic Request Descriptor support. + * @GET_MSIX_INDEX: Get the msix index of high iops queues. ++ * @multipath_on_hba: flag to determine multipath on hba is enabled or not + * @port_table_list: list containing HBA's wide/narrow port's info + */ + struct MPT3SAS_ADAPTER { +@@ -1540,6 +1541,7 @@ struct MPT3SAS_ADAPTER { + PUT_SMID_DEFAULT put_smid_default; + GET_MSIX_INDEX get_msix_index_for_smlio; + ++ u8 multipath_on_hba; + struct list_head port_table_list; + }; + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index 5c32dbb8b2f0..af2d3e3cc2eb 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -902,8 +902,10 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + (Mpi2SmpPassthroughRequest_t *)mpi_request; + u8 *data; + +- /* ioc determines which port to use */ +- smp_request->PhysicalPort = 0xFF; ++ if (!ioc->multipath_on_hba) { ++ /* ioc determines which port to use */ ++ smp_request->PhysicalPort = 0xFF; ++ } + if (smp_request->PassthroughFlags & + MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE) + data = (u8 *)&smp_request->SGL; +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index e81c0267027b..378470a2f366 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -159,6 +159,15 @@ module_param(enable_sdev_max_qd, bool, 0444); + MODULE_PARM_DESC(enable_sdev_max_qd, + "Enable sdev max qd as can_queue, def=disabled(0)"); + ++static int multipath_on_hba = -1; ++module_param(multipath_on_hba, int, 0); ++MODULE_PARM_DESC(multipath_on_hba, ++ "Multipath support to add same target device\n\t\t" ++ "as many times as it is visible to HBA from various paths\n\t\t" ++ "(by default:\n\t\t" ++ "\t SAS 2.0 & SAS 3.0 HBA - This will be disabled,\n\t\t" ++ "\t SAS 3.5 HBA - This will be enabled)"); ++ + /* raid transport support */ + static struct raid_template *mpt3sas_raid_template; + static struct raid_template *mpt2sas_raid_template; +@@ -373,6 +382,14 @@ mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, + { + struct hba_port *port, *port_next; + ++ /* ++ * When multipath_on_hba is disabled then ++ * search the hba_port entry using default ++ * port id i.e. 255 ++ */ ++ if (!ioc->multipath_on_hba) ++ port_id = MULTIPATH_DISABLED_PORT_ID; ++ + list_for_each_entry_safe(port, port_next, + &ioc->port_table_list, list) { + if (port->port_id != port_id) +@@ -384,6 +401,24 @@ mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, + return port; + } + ++ /* ++ * Allocate hba_port object for default port id (i.e. 255) ++ * when multipath_on_hba is disabled for the HBA. ++ * And add this object to port_table_list. ++ */ ++ if (!ioc->multipath_on_hba) { ++ port = kzalloc(sizeof(struct hba_port), GFP_KERNEL); ++ if (!port) ++ return NULL; ++ ++ port->port_id = port_id; ++ ioc_info(ioc, ++ "hba_port entry: %p, port: %d is added to hba_port list\n", ++ port, port->port_id); ++ list_add_tail(&port->list, ++ &ioc->port_table_list); ++ return port; ++ } + return NULL; + } + +@@ -10014,6 +10049,7 @@ _scsih_search_responding_expanders(struct MPT3SAS_ADAPTER *ioc) + u16 ioc_status; + u64 sas_address; + u16 handle; ++ u8 port; + + ioc_info(ioc, "search for expanders: start\n"); + +@@ -10031,10 +10067,12 @@ _scsih_search_responding_expanders(struct MPT3SAS_ADAPTER *ioc) + + handle = le16_to_cpu(expander_pg0.DevHandle); + sas_address = le64_to_cpu(expander_pg0.SASAddress); ++ port = expander_pg0.PhysicalPort; + pr_info( + "\texpander present: handle(0x%04x), sas_addr(0x%016llx), port:%d\n", + handle, (unsigned long long)sas_address, +- expander_pg0.PhysicalPort); ++ (ioc->multipath_on_hba ? ++ port : MULTIPATH_DISABLED_PORT_ID)); + _scsih_mark_responding_expander(ioc, &expander_pg0); + } + +@@ -10477,8 +10515,10 @@ mpt3sas_scsih_reset_done_handler(struct MPT3SAS_ADAPTER *ioc) + dtmprintk(ioc, ioc_info(ioc, "%s: MPT3_IOC_DONE_RESET\n", __func__)); + if ((!ioc->is_driver_loading) && !(disable_discovery > 0 && + !ioc->sas_hba.num_phys)) { +- _scsih_sas_port_refresh(ioc); +- _scsih_update_vphys_after_reset(ioc); ++ if (ioc->multipath_on_hba) { ++ _scsih_sas_port_refresh(ioc); ++ _scsih_update_vphys_after_reset(ioc); ++ } + _scsih_prep_device_scan(ioc); + _scsih_create_enclosure_list_after_reset(ioc); + _scsih_search_responding_sas_devices(ioc); +@@ -11767,6 +11807,12 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) + ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS; + break; + } ++ ++ if (multipath_on_hba == -1 || multipath_on_hba == 0) ++ ioc->multipath_on_hba = 0; ++ else ++ ioc->multipath_on_hba = 1; ++ + break; + case MPI25_VERSION: + case MPI26_VERSION: +@@ -11828,6 +11874,23 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) + ioc->combined_reply_index_count = + MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G3; + } ++ ++ switch (ioc->is_gen35_ioc) { ++ case 0: ++ if (multipath_on_hba == -1 || multipath_on_hba == 0) ++ ioc->multipath_on_hba = 0; ++ else ++ ioc->multipath_on_hba = 1; ++ break; ++ case 1: ++ if (multipath_on_hba == -1 || multipath_on_hba > 0) ++ ioc->multipath_on_hba = 1; ++ else ++ ioc->multipath_on_hba = 0; ++ default: ++ break; ++ } ++ + break; + default: + return -ENODEV; +diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c +index 0d06025d7102..6f4708224755 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c +@@ -912,7 +912,8 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + return; + } + +- if (sas_node->handle <= ioc->sas_hba.num_phys) { ++ if (sas_node->handle <= ioc->sas_hba.num_phys && ++ (ioc->multipath_on_hba)) { + if (port->vphys_mask) { + list_for_each_entry_safe(vphy, vphy_next, + &port->vphys_list, list) { +@@ -1172,7 +1173,8 @@ mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, + if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { + _transport_set_identify(ioc, handle, + &mpt3sas_phy->remote_identify); +- if (sas_node->handle <= ioc->sas_hba.num_phys) { ++ if ((sas_node->handle <= ioc->sas_hba.num_phys) && ++ (ioc->multipath_on_hba)) { + list_for_each_entry(hba_port, + &ioc->port_table_list, list) { + if (hba_port->sas_address == sas_address && +-- +2.13.6 + diff --git a/SOURCES/0033-scsi-scsi-mpt3sas-Bump-driver-version-to-35.101.00.0.patch b/SOURCES/0033-scsi-scsi-mpt3sas-Bump-driver-version-to-35.101.00.0.patch new file mode 100644 index 0000000..26d5a6a --- /dev/null +++ b/SOURCES/0033-scsi-scsi-mpt3sas-Bump-driver-version-to-35.101.00.0.patch @@ -0,0 +1,45 @@ +From 3a452f745463a7f4857f809916bdc16e9cecaa56 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 13 Nov 2020 18:42:58 -0500 +Subject: [PATCH 33/33] [scsi] scsi: mpt3sas: Bump driver version to + 35.101.00.00 + +Message-id: <20201113184258.11169-15-thenzl@redhat.com> +Patchwork-id: 339469 +Patchwork-instance: patchwork +O-Subject: [RHEL8.4 e-stor PATCH 14/14] scsi: mpt3sas: Bump driver version to 35.101.00.00 +Bugzilla: 1888543 +RH-Acked-by: Ewan Milne +RH-Acked-by: Tony Camuso + +Bump mpt3sas driver version to 35.101.00.00 + +Link: https://lore.kernel.org/r/20201027130847.9962-15-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +(cherry picked from commit 2030745877bdd2ecbeb43ff1846242d004482587) +Signed-off-by: Tomas Henzl +Signed-off-by: Jan Stancek +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index badd8230cce2..7dab579dbc20 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -76,9 +76,9 @@ + #define MPT3SAS_DRIVER_NAME "mpt3sas" + #define MPT3SAS_AUTHOR "Avago Technologies " + #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" +-#define MPT3SAS_DRIVER_VERSION "35.100.00.00" ++#define MPT3SAS_DRIVER_VERSION "35.101.00.00" + #define MPT3SAS_MAJOR_VERSION 35 +-#define MPT3SAS_MINOR_VERSION 100 ++#define MPT3SAS_MINOR_VERSION 101 + #define MPT3SAS_BUILD_VERSION 0 + #define MPT3SAS_RELEASE_VERSION 00 + +-- +2.13.6 + diff --git a/SOURCES/9000-version-bump.patch b/SOURCES/9000-version-bump.patch new file mode 100644 index 0000000..aa5e1f2 --- /dev/null +++ b/SOURCES/9000-version-bump.patch @@ -0,0 +1,22 @@ +Index: src/drivers/scsi/mpt3sas/mpt3sas_base.h +=================================================================== +--- src.orig/drivers/scsi/mpt3sas/mpt3sas_base.h 2021-01-04 05:31:41.522935379 +0100 ++++ src/drivers/scsi/mpt3sas/mpt3sas_base.h 2021-01-04 05:32:44.359382013 +0100 +@@ -76,7 +76,7 @@ + #define MPT3SAS_DRIVER_NAME "mpt3sas" + #define MPT3SAS_AUTHOR "Avago Technologies " + #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" +-#define MPT3SAS_DRIVER_VERSION "35.101.00.00" ++#define MPT3SAS_DRIVER_VERSION "35.101.00.00_dup8.3" + #define MPT3SAS_MAJOR_VERSION 35 + #define MPT3SAS_MINOR_VERSION 101 + #define MPT3SAS_BUILD_VERSION 0 +@@ -84,7 +84,7 @@ + + #define MPT2SAS_DRIVER_NAME "mpt2sas" + #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" +-#define MPT2SAS_DRIVER_VERSION "20.102.00.00" ++#define MPT2SAS_DRIVER_VERSION "20.102.00.00_dup8.3" + #define MPT2SAS_MAJOR_VERSION 20 + #define MPT2SAS_MINOR_VERSION 102 + #define MPT2SAS_BUILD_VERSION 0 diff --git a/SPECS/kmod-redhat-mpt3sas.spec b/SPECS/kmod-redhat-mpt3sas.spec new file mode 100644 index 0000000..66933ca --- /dev/null +++ b/SPECS/kmod-redhat-mpt3sas.spec @@ -0,0 +1,364 @@ +%define kmod_name mpt3sas +%define kmod_vendor redhat +%define kmod_rpm_name kmod-redhat-mpt3sas +%define kmod_driver_version 35.101.00.00_dup8.3 +%define kmod_driver_epoch %{nil} +%define kmod_rpm_release 1 +%define kmod_kernel_version 4.18.0-240.el8 +%define kmod_kernel_version_min %{nil} +%define kmod_kernel_version_dep %{nil} +%define kmod_kbuild_dir drivers/scsi/mpt3sas +%define kmod_dependencies %{nil} +%define kmod_dist_build_deps %{nil} +%define kmod_build_dependencies %{nil} +%define kmod_provides %{nil} +%define kmod_devel_package 0 +%define kmod_devel_src_paths %{nil} +%define kmod_install_path extra/kmod-redhat-mpt3sas +%define kernel_pkg kernel +%define kernel_devel_pkg kernel-devel +%define kernel_modules_pkg kernel-modules + +%{!?dist: %define dist .el8_3} +%{!?make_build: %define make_build make} + +%if "%{kmod_kernel_version_dep}" == "" +%define kmod_kernel_version_dep %{kmod_kernel_version} +%endif + +%if "%{kmod_dist_build_deps}" == "" +%if (0%{?rhel} > 7) || (0%{?centos} > 7) +%define kmod_dist_build_deps redhat-rpm-config kernel-abi-whitelists elfutils-libelf-devel kernel-rpm-macros kmod +%else +%define kmod_dist_build_deps redhat-rpm-config kernel-abi-whitelists +%endif +%endif + +Source0: %{kmod_name}-%{kmod_vendor}-%{kmod_driver_version}.tar.bz2 +# Source code patches +Patch0: 0001-scsi-scsi-mpt3sas-Fix-spelling-mistake.patch +Patch1: 0002-scsi-scsi-mpt3sas-Fix-unlock-imbalance.patch +Patch2: 0003-scsi-scsi-mpt3sas-Fix-error-returns-in-BRM_status_sh.patch +Patch3: 0004-scsi-scsi-mpt3sas-Fix-set-but-unused-variable.patch +Patch4: 0005-scsi-scsi-mpt3sas-Fix-kdoc-comments-format.patch +Patch5: 0006-scsi-scsi-mpt3sas-Memset-config_cmds.reply-buffer-wi.patch +Patch6: 0007-scsi-scsi-mpt3sas-Dump-system-registers-for-debuggin.patch +Patch7: 0008-scsi-scsi-mpt3sas-Cancel-the-running-work-during-hos.patch +Patch8: 0009-scsi-scsi-mpt3sas-Rename-and-export-interrupt-mask-u.patch +Patch9: 0010-scsi-scsi-mpt3sas-Add-functions-to-check-if-any-cmd-.patch +Patch10: 0011-scsi-scsi-mpt3sas-Postprocessing-of-target-and-LUN-r.patch +Patch11: 0012-scsi-scsi-mpt3sas-Update-driver-version-to-35.100.00.patch +Patch12: 0013-scsi-scsi-mpt3sas-Remove-superfluous-memset.patch +Patch13: 0014-scsi-scsi-mpt3sas-Remove-pci-dma-compat-wrapper-API.patch +Patch14: 0015-scsi-scsi-mpt3sas-Don-t-call-disable_irq-from-IRQ-po.patch +Patch15: 0016-scsi-scsi-mpt3sas-Detect-tampered-Aero-and-Sea-adapt.patch +Patch16: 0017-scsi-scsi-mpt3sas-Fix-sync-irqs.patch +Patch17: 0018-scsi-scsi-mpt3sas-A-small-correction-in-_base_proces.patch +Patch18: 0019-scsi-scsi-mpt3sas-Fix-timeouts-observed-while-reenab.patch +Patch19: 0020-scsi-scsi-mpt3sas-Define-hba_port-structure.patch +Patch20: 0021-scsi-scsi-mpt3sas-Allocate-memory-for-hba_port-objec.patch +Patch21: 0022-scsi-scsi-mpt3sas-Rearrange-_scsih_mark_responding_s.patch +Patch22: 0023-scsi-scsi-mpt3sas-Update-hba_port-s-sas_address-phy_.patch +Patch23: 0024-scsi-scsi-mpt3sas-Get-device-objects-using-sas_addre.patch +Patch24: 0025-scsi-scsi-mpt3sas-Rename-transport_del_phy_from_an_e.patch +Patch25: 0026-scsi-scsi-mpt3sas-Get-sas_device-objects-using-devic.patch +Patch26: 0027-scsi-scsi-mpt3sas-Update-hba_port-objects-after-host.patch +Patch27: 0028-scsi-scsi-mpt3sas-Set-valid-PhysicalPort-in-SMPPassT.patch +Patch28: 0029-scsi-scsi-mpt3sas-Handling-HBA-vSES-device.patch +Patch29: 0030-scsi-scsi-mpt3sas-Add-bypass_dirty_port_flag-paramet.patch +Patch30: 0031-scsi-scsi-mpt3sas-Handle-vSES-vphy-object-during-HBA.patch +Patch31: 0032-scsi-scsi-mpt3sas-Add-module-parameter-multipath_on_.patch +Patch32: 0033-scsi-scsi-mpt3sas-Bump-driver-version-to-35.101.00.0.patch +Patch33: 9000-version-bump.patch + +%define findpat %( echo "%""P" ) +%define __find_requires /usr/lib/rpm/redhat/find-requires.ksyms +%define __find_provides /usr/lib/rpm/redhat/find-provides.ksyms %{kmod_name} %{?epoch:%{epoch}:}%{version}-%{release} +%define sbindir %( if [ -d "/sbin" -a \! -h "/sbin" ]; then echo "/sbin"; else echo %{_sbindir}; fi ) +%define dup_state_dir %{_localstatedir}/lib/rpm-state/kmod-dups +%define kver_state_dir %{dup_state_dir}/kver +%define kver_state_file %{kver_state_dir}/%{kmod_kernel_version}.%(arch) +%define dup_module_list %{dup_state_dir}/rpm-kmod-%{kmod_name}-modules + +Name: kmod-redhat-mpt3sas +Version: %{kmod_driver_version} +Release: %{kmod_rpm_release}%{?dist} +%if "%{kmod_driver_epoch}" != "" +Epoch: %{kmod_driver_epoch} +%endif +Summary: mpt3sas kernel module for Driver Update Program +Group: System/Kernel +License: GPLv2 +URL: https://www.kernel.org/ +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) +BuildRequires: %kernel_devel_pkg = %kmod_kernel_version +%if "%{kmod_dist_build_deps}" != "" +BuildRequires: %{kmod_dist_build_deps} +%endif +ExclusiveArch: x86_64 +%global kernel_source() /usr/src/kernels/%{kmod_kernel_version}.$(arch) + +%global _use_internal_dependency_generator 0 +%if "%{?kmod_kernel_version_min}" != "" +Provides: %kernel_modules_pkg >= %{kmod_kernel_version_min}.%{_target_cpu} +%else +Provides: %kernel_modules_pkg = %{kmod_kernel_version_dep}.%{_target_cpu} +%endif +Provides: kmod-%{kmod_name} = %{?epoch:%{epoch}:}%{version}-%{release} +Requires(post): %{sbindir}/weak-modules +Requires(postun): %{sbindir}/weak-modules +Requires: kernel >= 4.18.0-240.el8 + +Requires: kernel < 4.18.0-241.el8 +%if 0 +Requires: firmware(%{kmod_name}) = ENTER_FIRMWARE_VERSION +%endif +%if "%{kmod_build_dependencies}" != "" +BuildRequires: %{kmod_build_dependencies} +%endif +%if "%{kmod_dependencies}" != "" +Requires: %{kmod_dependencies} +%endif +%if "%{kmod_provides}" != "" +Provides: %{kmod_provides} +%endif +# if there are multiple kmods for the same driver from different vendors, +# they should conflict with each other. +Conflicts: kmod-%{kmod_name} + +%description +mpt3sas kernel module for Driver Update Program + +%if 0 + +%package -n kmod-redhat-mpt3sas-firmware +Version: ENTER_FIRMWARE_VERSION +Summary: mpt3sas firmware for Driver Update Program +Provides: firmware(%{kmod_name}) = ENTER_FIRMWARE_VERSION +%if "%{kmod_kernel_version_min}" != "" +Provides: %kernel_modules_pkg >= %{kmod_kernel_version_min}.%{_target_cpu} +%else +Provides: %kernel_modules_pkg = %{kmod_kernel_version_dep}.%{_target_cpu} +%endif +%description -n kmod-redhat-mpt3sas-firmware +mpt3sas firmware for Driver Update Program + + +%files -n kmod-redhat-mpt3sas-firmware +%defattr(644,root,root,755) +%{FIRMWARE_FILES} + +%endif + +# Development package +%if 0%{kmod_devel_package} +%package -n kmod-redhat-mpt3sas-devel +Version: %{kmod_driver_version} +Requires: kernel >= 4.18.0-240.el8 + +Requires: kernel < 4.18.0-241.el8 +Summary: mpt3sas development files for Driver Update Program + +%description -n kmod-redhat-mpt3sas-devel +mpt3sas development files for Driver Update Program + + +%files -n kmod-redhat-mpt3sas-devel +%defattr(644,root,root,755) +/lib/modules/%{kmod_rpm_name}-%{kmod_driver_version}/ +%endif + +%post +modules=( $(find /lib/modules/%{kmod_kernel_version}.%(arch)/%{kmod_install_path} | grep '\.ko$') ) +printf '%s\n' "${modules[@]}" | %{sbindir}/weak-modules --add-modules --no-initramfs + +mkdir -p "%{kver_state_dir}" +touch "%{kver_state_file}" + +exit 0 + +%posttrans +# We have to re-implement part of weak-modules here because it doesn't allow +# calling initramfs regeneration separately +if [ -f "%{kver_state_file}" ]; then + kver_base="%{kmod_kernel_version_dep}" + kvers=$(ls -d "/lib/modules/${kver_base%%.*}"*) + + for k_dir in $kvers; do + k="${k_dir#/lib/modules/}" + + tmp_initramfs="/boot/initramfs-$k.tmp" + dst_initramfs="/boot/initramfs-$k.img" + + # The same check as in weak-modules: we assume that the kernel present + # if the symvers file exists. + if [ -e "/boot/symvers-$k.gz" ] || [ -e "$k_dir/symvers.gz" ]; then + /usr/bin/dracut -f "$tmp_initramfs" "$k" || exit 1 + cmp -s "$tmp_initramfs" "$dst_initramfs" + if [ "$?" = 1 ]; then + mv "$tmp_initramfs" "$dst_initramfs" + else + rm -f "$tmp_initramfs" + fi + fi + done + + rm -f "%{kver_state_file}" + rmdir "%{kver_state_dir}" 2> /dev/null +fi + +rmdir "%{dup_state_dir}" 2> /dev/null + +exit 0 + +%preun +if rpm -q --filetriggers kmod 2> /dev/null| grep -q "Trigger for weak-modules call on kmod removal"; then + mkdir -p "%{kver_state_dir}" + touch "%{kver_state_file}" +fi + +mkdir -p "%{dup_state_dir}" +rpm -ql kmod-redhat-mpt3sas-%{kmod_driver_version}-%{kmod_rpm_release}%{?dist}.$(arch) | \ + grep '\.ko$' > "%{dup_module_list}" + +%postun +if rpm -q --filetriggers kmod 2> /dev/null| grep -q "Trigger for weak-modules call on kmod removal"; then + initramfs_opt="--no-initramfs" +else + initramfs_opt="" +fi + +modules=( $(cat "%{dup_module_list}") ) +rm -f "%{dup_module_list}" +printf '%s\n' "${modules[@]}" | %{sbindir}/weak-modules --remove-modules $initramfs_opt + +rmdir "%{dup_state_dir}" 2> /dev/null + +exit 0 + +%files +%defattr(644,root,root,755) +/lib/modules/%{kmod_kernel_version}.%(arch) +/etc/depmod.d/%{kmod_name}.conf +%doc /usr/share/doc/%{kmod_rpm_name}/greylist.txt + + + +%prep +%setup -n %{kmod_name}-%{kmod_vendor}-%{kmod_driver_version} + +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +set -- * +mkdir source +mv "$@" source/ +mkdir obj + +%build +rm -rf obj +cp -r source obj + +PWD_PATH="$PWD" +%if "%{workaround_no_pwd_rel_path}" != "1" +PWD_PATH=$(realpath --relative-to="%{kernel_source}" . 2>/dev/null || echo "$PWD") +%endif +%{make_build} -C %{kernel_source} V=1 M="$PWD_PATH/obj/%{kmod_kbuild_dir}" \ + NOSTDINC_FLAGS="-I$PWD_PATH/obj/include -I$PWD_PATH/obj/include/uapi %{nil}" \ + EXTRA_CFLAGS="%{nil}" \ + %{nil} +# mark modules executable so that strip-to-file can strip them +find obj/%{kmod_kbuild_dir} -name "*.ko" -type f -exec chmod u+x '{}' + + +whitelist="/lib/modules/kabi-current/kabi_whitelist_%{_target_cpu}" +for modules in $( find obj/%{kmod_kbuild_dir} -name "*.ko" -type f -printf "%{findpat}\n" | sed 's|\.ko$||' | sort -u ) ; do + # update depmod.conf + module_weak_path=$(echo "$modules" | sed 's/[\/]*[^\/]*$//') + if [ -z "$module_weak_path" ]; then + module_weak_path=%{name} + else + module_weak_path=%{name}/$module_weak_path + fi + echo "override $(echo $modules | sed 's/.*\///')" \ + "$(echo "%{kmod_kernel_version_dep}" | + sed 's/\.[^\.]*$//; + s/\([.+?^$\/\\|()\[]\|\]\)/\\\0/g').*" \ + "weak-updates/$module_weak_path" >> source/depmod.conf + + # update greylist + nm -u obj/%{kmod_kbuild_dir}/$modules.ko | sed 's/.*U //' | sed 's/^\.//' | sort -u | while read -r symbol; do + grep -q "^\s*$symbol\$" $whitelist || echo "$symbol" >> source/greylist + done +done +sort -u source/greylist | uniq > source/greylist.txt + +%install +export INSTALL_MOD_PATH=$RPM_BUILD_ROOT +export INSTALL_MOD_DIR=%{kmod_install_path} +PWD_PATH="$PWD" +%if "%{workaround_no_pwd_rel_path}" != "1" +PWD_PATH=$(realpath --relative-to="%{kernel_source}" . 2>/dev/null || echo "$PWD") +%endif +make -C %{kernel_source} modules_install \ + M=$PWD_PATH/obj/%{kmod_kbuild_dir} +# Cleanup unnecessary kernel-generated module dependency files. +find $INSTALL_MOD_PATH/lib/modules -iname 'modules.*' -exec rm {} \; + +install -m 644 -D source/depmod.conf $RPM_BUILD_ROOT/etc/depmod.d/%{kmod_name}.conf +install -m 644 -D source/greylist.txt $RPM_BUILD_ROOT/usr/share/doc/%{kmod_rpm_name}/greylist.txt +%if 0 +%{FIRMWARE_FILES_INSTALL} +%endif +%if 0%{kmod_devel_package} +install -m 644 -D $PWD/obj/%{kmod_kbuild_dir}/Module.symvers $RPM_BUILD_ROOT/lib/modules/%{kmod_rpm_name}-%{kmod_driver_version}/build/Module.symvers + +if [ -n "%{kmod_devel_src_paths}" ]; then + for i in %{kmod_devel_src_paths}; do + mkdir -p "$RPM_BUILD_ROOT/lib/modules/%{kmod_rpm_name}-%{kmod_driver_version}/build/$(dirname "$i")" + cp -rv "$PWD/source/$i" \ + "$RPM_BUILD_ROOT/lib/modules/%{kmod_rpm_name}-%{kmod_driver_version}/build/$i" + done +fi +%endif + + + +%clean +rm -rf $RPM_BUILD_ROOT + +%changelog +* Tue Jan 12 2021 Eugene Syromiatnikov 35.101.00.00_dup8.3-1 +- bfcc924fa05e36abe7a039ac5ec2be581e20c288 +- mpt3sas kernel module for Driver Update Program +- Resolves: #bz1915214