Skip to content

Commit b899202

Browse files
suganathprabu0512martinkpetersen
authored andcommitted
scsi: mpt3sas: Add separate function for aero doorbell reads
Sometimes Aero controllers appears to be returning bad data (0) for doorbell register read and if retries are performed immediately after the bad read, they return good data. Workaround is added to retry read from doorbell registers for maximum three times if driver get the zero. Added functions base_readl_aero for Aero IOC and base_readl for gen35 and other controllers. Signed-off-by: Suganath Prabu <suganath-prabu.subramani@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent cc68e60 commit b899202

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

drivers/scsi/mpt3sas/mpt3sas_base.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,32 @@ _scsih_set_fwfault_debug(const char *val, const struct kernel_param *kp)
156156
module_param_call(mpt3sas_fwfault_debug, _scsih_set_fwfault_debug,
157157
param_get_int, &mpt3sas_fwfault_debug, 0644);
158158

159+
/**
160+
* _base_readl_aero - retry readl for max three times.
161+
* @addr - MPT Fusion system interface register address
162+
*
163+
* Retry the readl() for max three times if it gets zero value
164+
* while reading the system interface register.
165+
*/
166+
static inline u32
167+
_base_readl_aero(const volatile void __iomem *addr)
168+
{
169+
u32 i = 0, ret_val;
170+
171+
do {
172+
ret_val = readl(addr);
173+
i++;
174+
} while (ret_val == 0 && i < 3);
175+
176+
return ret_val;
177+
}
178+
179+
static inline u32
180+
_base_readl(const volatile void __iomem *addr)
181+
{
182+
return readl(addr);
183+
}
184+
159185
/**
160186
* _base_clone_reply_to_sys_mem - copies reply to reply free iomem
161187
* in BAR0 space.
@@ -6398,6 +6424,10 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
63986424

63996425
ioc->rdpq_array_enable_assigned = 0;
64006426
ioc->dma_mask = 0;
6427+
if (ioc->is_aero_ioc)
6428+
ioc->base_readl = &_base_readl_aero;
6429+
else
6430+
ioc->base_readl = &_base_readl;
64016431
r = mpt3sas_base_map_resources(ioc);
64026432
if (r)
64036433
goto out_free_resources;

drivers/scsi/mpt3sas/mpt3sas_base.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,7 @@ typedef void (*NVME_BUILD_PRP)(struct MPT3SAS_ADAPTER *ioc, u16 smid,
912912
typedef void (*PUT_SMID_IO_FP_HIP) (struct MPT3SAS_ADAPTER *ioc, u16 smid,
913913
u16 funcdep);
914914
typedef void (*PUT_SMID_DEFAULT) (struct MPT3SAS_ADAPTER *ioc, u16 smid);
915+
typedef u32 (*BASE_READ_REG) (const volatile void __iomem *addr);
915916

916917
/* IOC Facts and Port Facts converted from little endian to cpu */
917918
union mpi3_version_union {
@@ -1392,6 +1393,7 @@ struct MPT3SAS_ADAPTER {
13921393
u8 hide_drives;
13931394
spinlock_t diag_trigger_lock;
13941395
u8 diag_trigger_active;
1396+
BASE_READ_REG base_readl;
13951397
struct SL_WH_MASTER_TRIGGER_T diag_trigger_master;
13961398
struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event;
13971399
struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi;

0 commit comments

Comments
 (0)