- 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@xxxxxxxxxxxxx> Reviewed-by: David Carroll <david.carroll@xxxxxxxxxxxxx> Reviewed-by: Scott Teel <scott.teel@xxxxxxxxxxxxx> Signed-off-by: Don Brace <don.brace@xxxxxxxxxxxxx> --- drivers/scsi/hpsa.c | 14 +++++++++++++- drivers/scsi/hpsa.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 5c02163c7cea..0480e3c34217 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;