diff options
author | Kevin Barnett <kevin.barnett@microseim.com> | 2017-08-10 20:46:39 +0200 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-08-11 01:58:25 +0200 |
commit | 336b68193165b1215d21dd05619dc262340e404b (patch) | |
tree | efc10e7e5e80f8b0d53a3c716e9ed801300a68bf /drivers/scsi/smartpqi/smartpqi_sis.c | |
parent | scsi: dpt_i2o: remove redundant null check on array device (diff) | |
download | linux-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.c | 30 |
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) |