summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/smartpqi/smartpqi_sis.c
diff options
context:
space:
mode:
authorKevin Barnett <kevin.barnett@microseim.com>2017-08-10 20:46:39 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2017-08-11 01:58:25 +0200
commit336b68193165b1215d21dd05619dc262340e404b (patch)
treeefc10e7e5e80f8b0d53a3c716e9ed801300a68bf /drivers/scsi/smartpqi/smartpqi_sis.c
parentscsi: dpt_i2o: remove redundant null check on array device (diff)
downloadlinux-336b68193165b1215d21dd05619dc262340e404b.tar.xz
linux-336b68193165b1215d21dd05619dc262340e404b.zip
scsi: smartpqi: add pqi reset quiesce support
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com> Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com> Signed-off-by: Don Brace <don.brace@microsemi.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/smartpqi/smartpqi_sis.c')
-rw-r--r--drivers/scsi/smartpqi/smartpqi_sis.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c
index e55dfcf200e5..9abbaced4b33 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.c
+++ b/drivers/scsi/smartpqi/smartpqi_sis.c
@@ -36,6 +36,7 @@
#define SIS_ENABLE_INTX 0x80
#define SIS_SOFT_RESET 0x100
#define SIS_TRIGGER_SHUTDOWN 0x800000
+#define SIS_PQI_RESET_QUIESCE 0x1000000
#define SIS_CMD_READY 0x200
#define SIS_CMD_COMPLETE 0x1000
#define SIS_CLEAR_CTRL_TO_HOST_DOORBELL 0x1000
@@ -47,6 +48,7 @@
#define SIS_EXTENDED_PROPERTIES_SUPPORTED 0x800000
#define SIS_SMARTARRAY_FEATURES_SUPPORTED 0x2
#define SIS_PQI_MODE_SUPPORTED 0x4
+#define SIS_PQI_RESET_QUIESCE_SUPPORTED 0x8
#define SIS_REQUIRED_EXTENDED_PROPERTIES \
(SIS_SMARTARRAY_FEATURES_SUPPORTED | SIS_PQI_MODE_SUPPORTED)
@@ -258,6 +260,9 @@ int sis_get_ctrl_properties(struct pqi_ctrl_info *ctrl_info)
SIS_REQUIRED_EXTENDED_PROPERTIES)
return -ENODEV;
+ if (extended_properties & SIS_PQI_RESET_QUIESCE_SUPPORTED)
+ ctrl_info->pqi_reset_quiesce_supported = true;
+
return 0;
}
@@ -336,9 +341,10 @@ out:
#define SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS 30
-static void sis_wait_for_doorbell_bit_to_clear(
+static int sis_wait_for_doorbell_bit_to_clear(
struct pqi_ctrl_info *ctrl_info, u32 bit)
{
+ int rc = 0;
u32 doorbell_register;
unsigned long timeout;
@@ -350,16 +356,21 @@ static void sis_wait_for_doorbell_bit_to_clear(
if ((doorbell_register & bit) == 0)
break;
if (readl(&ctrl_info->registers->sis_firmware_status) &
- SIS_CTRL_KERNEL_PANIC)
+ SIS_CTRL_KERNEL_PANIC) {
+ rc = -ENODEV;
break;
+ }
if (time_after(jiffies, timeout)) {
dev_err(&ctrl_info->pci_dev->dev,
"doorbell register bit 0x%x not cleared\n",
bit);
+ rc = -ETIMEDOUT;
break;
}
usleep_range(1000, 2000);
}
+
+ return rc;
}
/* Enable MSI-X interrupts on the controller. */
@@ -434,6 +445,21 @@ void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info)
&ctrl_info->registers->sis_host_to_ctrl_doorbell);
}
+int sis_pqi_reset_quiesce(struct pqi_ctrl_info *ctrl_info)
+{
+ u32 doorbell_register;
+
+ doorbell_register =
+ readl(&ctrl_info->registers->sis_host_to_ctrl_doorbell);
+ doorbell_register |= SIS_PQI_RESET_QUIESCE;
+
+ writel(doorbell_register,
+ &ctrl_info->registers->sis_host_to_ctrl_doorbell);
+
+ return sis_wait_for_doorbell_bit_to_clear(ctrl_info,
+ SIS_PQI_RESET_QUIESCE);
+}
+
#define SIS_MODE_READY_TIMEOUT_SECS 30
int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info)