summaryrefslogtreecommitdiff
path: root/drivers/scsi/hpsa.c
diff options
context:
space:
mode:
authorDon Brace <don.brace@microsemi.com>2019-05-07 21:32:26 +0300
committerMartin K. Petersen <martin.petersen@oracle.com>2019-06-19 02:46:18 +0300
commit9e33f0d5788fe4aaa42b1abf6536d046c724a8cd (patch)
treea7401b47abe79adeebb1c78442ab96b0d56b89c5 /drivers/scsi/hpsa.c
parentb443d3eab600b86025ee338669c9ddd399167a4b (diff)
downloadlinux-9e33f0d5788fe4aaa42b1abf6536d046c724a8cd.tar.xz
scsi: hpsa: do-not-complete-cmds-for-deleted-devices
Close up a rare multipath issue. Close up small hole where a command completes after a device has been removed from SML and before the device is re-added. - Mark device as removed in slave_destroy - Do not complete commands for deleted devices Reviewed-by: Justin Lindley <justin.lindley@microsemi.com> Reviewed-by: David Carroll <david.carroll@microsemi.com> Reviewed-by: Scott Teel <scott.teel@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/hpsa.c')
-rw-r--r--drivers/scsi/hpsa.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index df447f1d6311..42d51951b61a 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2141,6 +2141,7 @@ static int hpsa_slave_configure(struct scsi_device *sdev)
sdev->no_uld_attach = !sd || !sd->expose_device;
if (sd) {
+ sd->was_removed = 0;
if (sd->external) {
queue_depth = EXTERNAL_QD;
sdev->eh_timeout = HPSA_EH_PTRAID_TIMEOUT;
@@ -2160,7 +2161,12 @@ static int hpsa_slave_configure(struct scsi_device *sdev)
static void hpsa_slave_destroy(struct scsi_device *sdev)
{
- /* nothing to do. */
+ struct hpsa_scsi_dev_t *hdev = NULL;
+
+ hdev = sdev->hostdata;
+
+ if (hdev)
+ hdev->was_removed = 1;
}
static void hpsa_free_ioaccel2_sg_chain_blocks(struct ctlr_info *h)
@@ -2588,6 +2594,12 @@ static void complete_scsi_command(struct CommandList *cp)
cmd->result = (DID_OK << 16); /* host byte */
cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
+ /* SCSI command has already been cleaned up in SML */
+ if (dev->was_removed) {
+ hpsa_cmd_resolve_and_free(h, cp);
+ return;
+ }
+
if (cp->cmd_type == CMD_IOACCEL2 || cp->cmd_type == CMD_IOACCEL1) {
if (dev->physical_device && dev->expose_device &&
dev->removed) {