Blob Blame History Raw
From: Mike McGowen <mike.mcgowen@microchip.com>
Date: Fri, 8 Jul 2022 13:47:05 -0500
Subject: scsi: smartpqi: Close write read holes
Patch-mainline: v6.0-rc1
Git-commit: 297bdc540f0e391568788f8ece3020653748a26f
References: jsc#PED-1557

Insert a minimum 1 millisecond delay after writing to a register before
reading from it.

SIS and PQI registers that can be both written to and read from can return
stale data if read from too soon after having been written to.

There is no read/write ordering or hazard detection on the inbound path to
the MSGU from the PCIe bus, therefore reads could pass writes.

Link: https://lore.kernel.org/r/165730602555.177165.11181012469428348394.stgit@brunhilda
Reviewed-by: Scott Teel <scott.teel@microchip.com>
Signed-off-by: Mike McGowen <mike.mcgowen@microchip.com>
Co-developed-by: Kevin Barnett <kevin.barnett@microchip.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microchip.com>
Signed-off-by: Don Brace <don.brace@microchip.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Acked-by: Martin Wilck <mwilck@suse.com>
---
 drivers/scsi/smartpqi/smartpqi_sis.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/scsi/smartpqi/smartpqi_sis.c
+++ b/drivers/scsi/smartpqi/smartpqi_sis.c
@@ -194,6 +194,7 @@ static int sis_send_sync_cmd(struct pqi_
 
 	/* Disable doorbell interrupts by masking all interrupts. */
 	writel(~0, &registers->sis_interrupt_mask);
+	usleep_range(1000, 2000);
 
 	/*
 	 * Force the completion of the interrupt mask register write before
@@ -383,6 +384,7 @@ static int sis_wait_for_doorbell_bit_to_
 static inline int sis_set_doorbell_bit(struct pqi_ctrl_info *ctrl_info, u32 bit)
 {
 	writel(bit, &ctrl_info->registers->sis_host_to_ctrl_doorbell);
+	usleep_range(1000, 2000);
 
 	return sis_wait_for_doorbell_bit_to_clear(ctrl_info, bit);
 }
@@ -423,6 +425,7 @@ int sis_reenable_sis_mode(struct pqi_ctr
 void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value)
 {
 	writel(value, &ctrl_info->registers->sis_driver_scratch);
+	usleep_range(1000, 2000);
 }
 
 u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info)