diff options
author | Don Brace <don.brace@microsemi.com> | 2019-05-07 21:32:26 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2019-06-19 02:46:18 +0300 |
commit | 9e33f0d5788fe4aaa42b1abf6536d046c724a8cd (patch) | |
tree | a7401b47abe79adeebb1c78442ab96b0d56b89c5 /drivers/scsi/hpsa.c | |
parent | b443d3eab600b86025ee338669c9ddd399167a4b (diff) | |
download | linux-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.c | 14 |
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) { |