diff options
author | Don Brace <don.brace@microsemi.com> | 2019-05-07 13:32:26 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2019-06-18 19:46:18 -0400 |
commit | 9e33f0d5788fe4aaa42b1abf6536d046c724a8cd (patch) | |
tree | a7401b47abe79adeebb1c78442ab96b0d56b89c5 /drivers/scsi | |
parent | b443d3eab600b86025ee338669c9ddd399167a4b (diff) | |
download | linux-9e33f0d5788fe4aaa42b1abf6536d046c724a8cd.tar.bz2 |
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')
-rw-r--r-- | drivers/scsi/hpsa.c | 14 | ||||
-rw-r--r-- | drivers/scsi/hpsa.h | 1 |
2 files changed, 14 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) { diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index 75210de71917..a013c16af5f1 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h @@ -65,6 +65,7 @@ struct hpsa_scsi_dev_t { u8 physical_device : 1; u8 expose_device; u8 removed : 1; /* device is marked for death */ + u8 was_removed : 1; /* device actually removed */ #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" unsigned char device_id[16]; /* from inquiry pg. 0x83 */ u64 sas_address; |