Skip to content

Commit 4ca10f3

Browse files
Ranjan Kumarmartinkpetersen
authored andcommitted
scsi: mpt3sas: Perform additional retries if doorbell read returns 0
The driver retries certain register reads 3 times if the returned value is 0. This was done because the controller could return 0 for certain registers if other registers were being accessed concurrently by the BMC. In certain systems with increased BMC interactions, the register values returned can be 0 for longer than 3 retries. Change the retry count from 3 to 30 for the affected registers to prevent problems with out-of-band management. Fixes: b899202 ("scsi: mpt3sas: Add separate function for aero doorbell reads") Cc: [email protected] Signed-off-by: Ranjan Kumar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent be946e3 commit 4ca10f3

File tree

2 files changed

+34
-13
lines changed

2 files changed

+34
-13
lines changed

drivers/scsi/mpt3sas/mpt3sas_base.c

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc);
138138
static void
139139
_base_clear_outstanding_commands(struct MPT3SAS_ADAPTER *ioc);
140140

141+
static u32
142+
_base_readl_ext_retry(const volatile void __iomem *addr);
143+
141144
/**
142145
* mpt3sas_base_check_cmd_timeout - Function
143146
* to check timeout and command termination due
@@ -213,6 +216,20 @@ _base_readl_aero(const volatile void __iomem *addr)
213216
return ret_val;
214217
}
215218

219+
static u32
220+
_base_readl_ext_retry(const volatile void __iomem *addr)
221+
{
222+
u32 i, ret_val;
223+
224+
for (i = 0 ; i < 30 ; i++) {
225+
ret_val = readl(addr);
226+
if (ret_val == 0)
227+
continue;
228+
}
229+
230+
return ret_val;
231+
}
232+
216233
static inline u32
217234
_base_readl(const volatile void __iomem *addr)
218235
{
@@ -940,7 +957,7 @@ mpt3sas_halt_firmware(struct MPT3SAS_ADAPTER *ioc)
940957

941958
dump_stack();
942959

943-
doorbell = ioc->base_readl(&ioc->chip->Doorbell);
960+
doorbell = ioc->base_readl_ext_retry(&ioc->chip->Doorbell);
944961
if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
945962
mpt3sas_print_fault_code(ioc, doorbell &
946963
MPI2_DOORBELL_DATA_MASK);
@@ -6686,7 +6703,7 @@ mpt3sas_base_get_iocstate(struct MPT3SAS_ADAPTER *ioc, int cooked)
66866703
{
66876704
u32 s, sc;
66886705

6689-
s = ioc->base_readl(&ioc->chip->Doorbell);
6706+
s = ioc->base_readl_ext_retry(&ioc->chip->Doorbell);
66906707
sc = s & MPI2_IOC_STATE_MASK;
66916708
return cooked ? sc : s;
66926709
}
@@ -6831,7 +6848,7 @@ _base_wait_for_doorbell_ack(struct MPT3SAS_ADAPTER *ioc, int timeout)
68316848
__func__, count, timeout));
68326849
return 0;
68336850
} else if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) {
6834-
doorbell = ioc->base_readl(&ioc->chip->Doorbell);
6851+
doorbell = ioc->base_readl_ext_retry(&ioc->chip->Doorbell);
68356852
if ((doorbell & MPI2_IOC_STATE_MASK) ==
68366853
MPI2_IOC_STATE_FAULT) {
68376854
mpt3sas_print_fault_code(ioc, doorbell);
@@ -6871,7 +6888,7 @@ _base_wait_for_doorbell_not_used(struct MPT3SAS_ADAPTER *ioc, int timeout)
68716888
count = 0;
68726889
cntdn = 1000 * timeout;
68736890
do {
6874-
doorbell_reg = ioc->base_readl(&ioc->chip->Doorbell);
6891+
doorbell_reg = ioc->base_readl_ext_retry(&ioc->chip->Doorbell);
68756892
if (!(doorbell_reg & MPI2_DOORBELL_USED)) {
68766893
dhsprintk(ioc,
68776894
ioc_info(ioc, "%s: successful count(%d), timeout(%d)\n",
@@ -7019,7 +7036,7 @@ _base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes,
70197036
__le32 *mfp;
70207037

70217038
/* make sure doorbell is not in use */
7022-
if ((ioc->base_readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) {
7039+
if ((ioc->base_readl_ext_retry(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) {
70237040
ioc_err(ioc, "doorbell is in use (line=%d)\n", __LINE__);
70247041
return -EFAULT;
70257042
}
@@ -7068,15 +7085,15 @@ _base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes,
70687085
}
70697086

70707087
/* read the first two 16-bits, it gives the total length of the reply */
7071-
reply[0] = le16_to_cpu(ioc->base_readl(&ioc->chip->Doorbell)
7088+
reply[0] = le16_to_cpu(ioc->base_readl_ext_retry(&ioc->chip->Doorbell)
70727089
& MPI2_DOORBELL_DATA_MASK);
70737090
writel(0, &ioc->chip->HostInterruptStatus);
70747091
if ((_base_wait_for_doorbell_int(ioc, 5))) {
70757092
ioc_err(ioc, "doorbell handshake int failed (line=%d)\n",
70767093
__LINE__);
70777094
return -EFAULT;
70787095
}
7079-
reply[1] = le16_to_cpu(ioc->base_readl(&ioc->chip->Doorbell)
7096+
reply[1] = le16_to_cpu(ioc->base_readl_ext_retry(&ioc->chip->Doorbell)
70807097
& MPI2_DOORBELL_DATA_MASK);
70817098
writel(0, &ioc->chip->HostInterruptStatus);
70827099

@@ -7087,10 +7104,10 @@ _base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes,
70877104
return -EFAULT;
70887105
}
70897106
if (i >= reply_bytes/2) /* overflow case */
7090-
ioc->base_readl(&ioc->chip->Doorbell);
7107+
ioc->base_readl_ext_retry(&ioc->chip->Doorbell);
70917108
else
70927109
reply[i] = le16_to_cpu(
7093-
ioc->base_readl(&ioc->chip->Doorbell)
7110+
ioc->base_readl_ext_retry(&ioc->chip->Doorbell)
70947111
& MPI2_DOORBELL_DATA_MASK);
70957112
writel(0, &ioc->chip->HostInterruptStatus);
70967113
}
@@ -7949,7 +7966,7 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
79497966
goto out;
79507967
}
79517968

7952-
host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic);
7969+
host_diagnostic = ioc->base_readl_ext_retry(&ioc->chip->HostDiagnostic);
79537970
drsprintk(ioc,
79547971
ioc_info(ioc, "wrote magic sequence: count(%d), host_diagnostic(0x%08x)\n",
79557972
count, host_diagnostic));
@@ -7969,7 +7986,7 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
79697986
for (count = 0; count < (300000000 /
79707987
MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) {
79717988

7972-
host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic);
7989+
host_diagnostic = ioc->base_readl_ext_retry(&ioc->chip->HostDiagnostic);
79737990

79747991
if (host_diagnostic == 0xFFFFFFFF) {
79757992
ioc_info(ioc,
@@ -8359,10 +8376,13 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
83598376
ioc->rdpq_array_enable_assigned = 0;
83608377
ioc->use_32bit_dma = false;
83618378
ioc->dma_mask = 64;
8362-
if (ioc->is_aero_ioc)
8379+
if (ioc->is_aero_ioc) {
83638380
ioc->base_readl = &_base_readl_aero;
8364-
else
8381+
ioc->base_readl_ext_retry = &_base_readl_ext_retry;
8382+
} else {
83658383
ioc->base_readl = &_base_readl;
8384+
ioc->base_readl_ext_retry = &_base_readl;
8385+
}
83668386
r = mpt3sas_base_map_resources(ioc);
83678387
if (r)
83688388
goto out_free_resources;

drivers/scsi/mpt3sas/mpt3sas_base.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,7 @@ struct MPT3SAS_ADAPTER {
16181618
u8 diag_trigger_active;
16191619
u8 atomic_desc_capable;
16201620
BASE_READ_REG base_readl;
1621+
BASE_READ_REG base_readl_ext_retry;
16211622
struct SL_WH_MASTER_TRIGGER_T diag_trigger_master;
16221623
struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event;
16231624
struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi;

0 commit comments

Comments
 (0)