diff options
author | Don Brace <don.brace@microsemi.com> | 2019-05-07 14:32:26 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2019-06-18 19:46:18 -0400 |
commit | 9e33f0d5788fe4aaa42b1abf6536d046c724a8cd (patch) | |
tree | a7401b47abe79adeebb1c78442ab96b0d56b89c5 | |
parent | b443d3eab600b86025ee338669c9ddd399167a4b (diff) |
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>
-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) | |||
2141 | sdev->no_uld_attach = !sd || !sd->expose_device; | 2141 | sdev->no_uld_attach = !sd || !sd->expose_device; |
2142 | 2142 | ||
2143 | if (sd) { | 2143 | if (sd) { |
2144 | sd->was_removed = 0; | ||
2144 | if (sd->external) { | 2145 | if (sd->external) { |
2145 | queue_depth = EXTERNAL_QD; | 2146 | queue_depth = EXTERNAL_QD; |
2146 | sdev->eh_timeout = HPSA_EH_PTRAID_TIMEOUT; | 2147 | sdev->eh_timeout = HPSA_EH_PTRAID_TIMEOUT; |
@@ -2160,7 +2161,12 @@ static int hpsa_slave_configure(struct scsi_device *sdev) | |||
2160 | 2161 | ||
2161 | static void hpsa_slave_destroy(struct scsi_device *sdev) | 2162 | static void hpsa_slave_destroy(struct scsi_device *sdev) |
2162 | { | 2163 | { |
2163 | /* nothing to do. */ | 2164 | struct hpsa_scsi_dev_t *hdev = NULL; |
2165 | |||
2166 | hdev = sdev->hostdata; | ||
2167 | |||
2168 | if (hdev) | ||
2169 | hdev->was_removed = 1; | ||
2164 | } | 2170 | } |
2165 | 2171 | ||
2166 | static void hpsa_free_ioaccel2_sg_chain_blocks(struct ctlr_info *h) | 2172 | static void hpsa_free_ioaccel2_sg_chain_blocks(struct ctlr_info *h) |
@@ -2588,6 +2594,12 @@ static void complete_scsi_command(struct CommandList *cp) | |||
2588 | cmd->result = (DID_OK << 16); /* host byte */ | 2594 | cmd->result = (DID_OK << 16); /* host byte */ |
2589 | cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ | 2595 | cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ |
2590 | 2596 | ||
2597 | /* SCSI command has already been cleaned up in SML */ | ||
2598 | if (dev->was_removed) { | ||
2599 | hpsa_cmd_resolve_and_free(h, cp); | ||
2600 | return; | ||
2601 | } | ||
2602 | |||
2591 | if (cp->cmd_type == CMD_IOACCEL2 || cp->cmd_type == CMD_IOACCEL1) { | 2603 | if (cp->cmd_type == CMD_IOACCEL2 || cp->cmd_type == CMD_IOACCEL1) { |
2592 | if (dev->physical_device && dev->expose_device && | 2604 | if (dev->physical_device && dev->expose_device && |
2593 | dev->removed) { | 2605 | 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 { | |||
65 | u8 physical_device : 1; | 65 | u8 physical_device : 1; |
66 | u8 expose_device; | 66 | u8 expose_device; |
67 | u8 removed : 1; /* device is marked for death */ | 67 | u8 removed : 1; /* device is marked for death */ |
68 | u8 was_removed : 1; /* device actually removed */ | ||
68 | #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" | 69 | #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" |
69 | unsigned char device_id[16]; /* from inquiry pg. 0x83 */ | 70 | unsigned char device_id[16]; /* from inquiry pg. 0x83 */ |
70 | u64 sas_address; | 71 | u64 sas_address; |