All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 00/12] hpsa updates
@ 2017-04-28 18:19 Don Brace
  2017-04-28 18:19 ` [PATCH V2 01/12] hpsa: update identify physical device structure Don Brace
                   ` (11 more replies)
  0 siblings, 12 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:19 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

These patches are based on Linus's tree

These patches are for:
 - RedHat BZ: 1404073 - [HPE 7.3 Bug] multipath failover not reliable
 - Multipath failover support in general.

The changes are:
 - update identify physical device structure
   - align with FW
 - stop getting enclosure info for externals
   - no BMIC support
 - update reset handler
   - update to match out of box driver
 - do not reset enclosures
   - reset can sometimes hang
 - rescan later if reset in progress
   - wait for devices to settle.
 - correct resets on retried commands
   - was not calling scsi_done on retried completion
 - correct queue depth for externals
   - Code not in correct function
 - separate monitor events from rescan worker
   - allows driver to check for controller events more frequently
     without affecting controller lockup detection or check
     for changes on PTRAID devices.
 - send ioaccel requests with 0 length down raid path
   - avoid hang issues for customers running older firmware.
 - remove abort handler
   - align driver with our out of box driver
 - bump driver version
   - align version with out of box driver for multi-path changes

Changes since V1:
 - changes based on Martin Wilck <mwilck@suse.com> reviews.
    - cleanup reset handler
      - added spin_lock protection around h->reset_in_progress
        - this has helped solve a multipath issue, thanks Martin.
    - renamed patch hpsa-separate-monitor-events-from-hearbeat-worker to
      hpsa-separate-monitor-events-from-rescan-worker to more correctly
         convey the patches intent.
      - split out some commonality between the rescan worker and the
        event monitor worker.
      - updated the patch description.
---

Don Brace (11):
      hpsa: update identify physical device structure
      hpsa: do not get enclosure info for external devices
      hpsa: update reset handler
      hpsa: do not reset enclosures
      hpsa: rescan later if reset in progress
      hpsa: correct resets on retried commands
      hpsa: cleanup reset handler
      hpsa: correct queue depth for externals
      hpsa: send ioaccel requests with 0 length down raid path
      hpsa: remove abort handler
      hpsa: bump driver version

Scott Teel (1):
      hpsa: separate monitor events from rescan worker


 drivers/scsi/hpsa.c     |  849 +++++++++++------------------------------------
 drivers/scsi/hpsa.h     |    4 
 drivers/scsi/hpsa_cmd.h |   20 +
 3 files changed, 208 insertions(+), 665 deletions(-)

--
Signature

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH V2 01/12] hpsa: update identify physical device structure
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
@ 2017-04-28 18:19 ` Don Brace
  2017-04-28 18:19 ` [PATCH V2 02/12] hpsa: do not get enclosure info for external devices Don Brace
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:19 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

 - align with latest spec.
 - added __attribute((aligned(512)))

Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa_cmd.h |   20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 5961705..078afe4 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -809,10 +809,7 @@ struct bmic_identify_physical_device {
 	u8     max_temperature_degreesC;
 	u8     logical_blocks_per_phys_block_exp; /* phyblocksize = 512*2^exp */
 	__le16 current_queue_depth_limit;
-	u8     switch_name[10];
-	__le16 switch_port;
-	u8     alternate_paths_switch_name[40];
-	u8     alternate_paths_switch_port[8];
+	u8     reserved_switch_stuff[60];
 	__le16 power_on_hours; /* valid only if gas gauge supported */
 	__le16 percent_endurance_used; /* valid only if gas gauge supported. */
 #define BMIC_PHYS_DRIVE_SSD_WEAROUT(idphydrv) \
@@ -828,11 +825,22 @@ struct bmic_identify_physical_device {
 	(idphydrv->smart_carrier_authentication == 0x01)
 	u8     smart_carrier_app_fw_version;
 	u8     smart_carrier_bootloader_fw_version;
+	u8     sanitize_support_flags;
+	u8     drive_key_flags;
 	u8     encryption_key_name[64];
 	__le32 misc_drive_flags;
 	__le16 dek_index;
-	u8     padding[112];
-};
+	__le16 hba_drive_encryption_flags;
+	__le16 max_overwrite_time;
+	__le16 max_block_erase_time;
+	__le16 max_crypto_erase_time;
+	u8     device_connector_info[5];
+	u8     connector_name[8][8];
+	u8     page_83_id[16];
+	u8     max_link_rate[256];
+	u8     neg_phys_link_rate[256];
+	u8     box_conn_name[8];
+} __attribute((aligned(512)));
 
 struct bmic_sense_subsystem_info {
 	u8	primary_slot_number;

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH V2 02/12] hpsa: do not get enclosure info for external devices
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
  2017-04-28 18:19 ` [PATCH V2 01/12] hpsa: update identify physical device structure Don Brace
@ 2017-04-28 18:19 ` Don Brace
  2017-04-28 18:20 ` [PATCH V2 03/12] hpsa: update reset handler Don Brace
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:19 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

external shelves do not support BMICs.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 73daace..8e22aed 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3353,6 +3353,11 @@ static void hpsa_get_enclosure_info(struct ctlr_info *h,
 
 	bmic_device_index = GET_BMIC_DRIVE_NUMBER(&rle->lunid[0]);
 
+	if (encl_dev->target == -1 || encl_dev->lun == -1) {
+		rc = IO_OK;
+		goto out;
+	}
+
 	if (bmic_device_index == 0xFF00 || MASKED_DEVICE(&rle->lunid[0])) {
 		rc = IO_OK;
 		goto out;

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH V2 03/12] hpsa: update reset handler
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
  2017-04-28 18:19 ` [PATCH V2 01/12] hpsa: update identify physical device structure Don Brace
  2017-04-28 18:19 ` [PATCH V2 02/12] hpsa: do not get enclosure info for external devices Don Brace
@ 2017-04-28 18:20 ` Don Brace
  2017-04-28 18:20 ` [PATCH V2 04/12] hpsa: do not reset enclosures Don Brace
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:20 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

Use the return from TUR as a check for the
device state.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.tell@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 8e22aed..9fb30c4 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3090,7 +3090,7 @@ static int hpsa_do_reset(struct ctlr_info *h, struct hpsa_scsi_dev_t *dev,
 	if (unlikely(rc))
 		atomic_set(&dev->reset_cmds_out, 0);
 	else
-		wait_for_device_to_become_ready(h, scsi3addr, 0);
+		rc = wait_for_device_to_become_ready(h, scsi3addr, 0);
 
 	mutex_unlock(&h->reset_mutex);
 	return rc;

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH V2 04/12] hpsa: do not reset enclosures
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
                   ` (2 preceding siblings ...)
  2017-04-28 18:20 ` [PATCH V2 03/12] hpsa: update reset handler Don Brace
@ 2017-04-28 18:20 ` Don Brace
  2017-04-28 18:20 ` [PATCH V2 05/12] hpsa: rescan later if reset in progress Don Brace
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:20 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

Prevent enclosure resets.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.tell@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9fb30c4..2990897 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5853,6 +5853,9 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 		return FAILED;
 	}
 
+	if (dev->devtype == TYPE_ENCLOSURE)
+		return SUCCESS;
+
 	/* if controller locked up, we can guarantee command won't complete */
 	if (lockup_detected(h)) {
 		snprintf(msg, sizeof(msg),

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH V2 05/12] hpsa: rescan later if reset in progress
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
                   ` (3 preceding siblings ...)
  2017-04-28 18:20 ` [PATCH V2 04/12] hpsa: do not reset enclosures Don Brace
@ 2017-04-28 18:20 ` Don Brace
  2017-04-28 18:20 ` [PATCH V2 06/12] hpsa: correct resets on retried commands Don Brace
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:20 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

 - schedule another scan.
 - mark current scan as completed

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 2990897..53a4f34 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5620,6 +5620,7 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
 	 */
 	if (h->reset_in_progress) {
 		h->drv_req_rescan = 1;
+		hpsa_scan_complete(h);
 		return;
 	}
 

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH V2 06/12] hpsa: correct resets on retried commands
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
                   ` (4 preceding siblings ...)
  2017-04-28 18:20 ` [PATCH V2 05/12] hpsa: rescan later if reset in progress Don Brace
@ 2017-04-28 18:20 ` Don Brace
  2017-04-28 18:20 ` [PATCH V2 07/12] hpsa: cleanup reset handler Don Brace
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:20 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

 - call scsi_done when the command completes.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 53a4f34..a2852da 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5465,7 +5465,7 @@ static void hpsa_command_resubmit_worker(struct work_struct *work)
 		return hpsa_cmd_free_and_done(c->h, c, cmd);
 	}
 	if (c->reset_pending)
-		return hpsa_cmd_resolve_and_free(c->h, c);
+		return hpsa_cmd_free_and_done(c->h, c, cmd);
 	if (c->abort_pending)
 		return hpsa_cmd_abort_and_free(c->h, c, cmd);
 	if (c->cmd_type == CMD_IOACCEL2) {

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH V2 07/12] hpsa: cleanup reset handler
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
                   ` (5 preceding siblings ...)
  2017-04-28 18:20 ` [PATCH V2 06/12] hpsa: correct resets on retried commands Don Brace
@ 2017-04-28 18:20 ` Don Brace
  2017-05-04 15:46   ` Tomas Henzl
  2017-04-28 18:20 ` [PATCH V2 08/12] hpsa: correct queue depth for externals Don Brace
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:20 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

 - mark device state sooner.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa.c |   59 +++++++++++++++++++++++++++++++++++++++------------
 drivers/scsi/hpsa.h |    1 +
 2 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a2852da..71f32e9 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1859,10 +1859,13 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h,
 	 * A reset can cause a device status to change
 	 * re-schedule the scan to see what happened.
 	 */
+	spin_lock_irqsave(&h->reset_lock, flags);
 	if (h->reset_in_progress) {
+		spin_unlock_irqrestore(&h->reset_lock, flags);
 		h->drv_req_rescan = 1;
 		return;
 	}
+	spin_unlock_irqrestore(&h->reset_lock, flags);
 
 	added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL);
 	removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES, GFP_KERNEL);
@@ -5618,11 +5621,14 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
 	/*
 	 * Do the scan after a reset completion
 	 */
+	spin_lock_irqsave(&h->reset_lock, flags);
 	if (h->reset_in_progress) {
+		spin_unlock_irqrestore(&h->reset_lock, flags);
 		h->drv_req_rescan = 1;
 		hpsa_scan_complete(h);
 		return;
 	}
+	spin_unlock_irqrestore(&h->reset_lock, flags);
 
 	hpsa_update_scsi_devices(h);
 
@@ -5834,28 +5840,38 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h,
  */
 static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 {
-	int rc;
+	int rc = SUCCESS;
 	struct ctlr_info *h;
 	struct hpsa_scsi_dev_t *dev;
 	u8 reset_type;
 	char msg[48];
+	unsigned long flags;
 
 	/* find the controller to which the command to be aborted was sent */
 	h = sdev_to_hba(scsicmd->device);
 	if (h == NULL) /* paranoia */
 		return FAILED;
 
-	if (lockup_detected(h))
-		return FAILED;
+	spin_lock_irqsave(&h->reset_lock, flags);
+	h->reset_in_progress = 1;
+	spin_unlock_irqrestore(&h->reset_lock, flags);
+
+	if (lockup_detected(h)) {
+		rc = FAILED;
+		goto return_reset_status;
+	}
 
 	dev = scsicmd->device->hostdata;
 	if (!dev) {
 		dev_err(&h->pdev->dev, "%s: device lookup failed\n", __func__);
-		return FAILED;
+		rc = FAILED;
+		goto return_reset_status;
 	}
 
-	if (dev->devtype == TYPE_ENCLOSURE)
-		return SUCCESS;
+	if (dev->devtype == TYPE_ENCLOSURE) {
+		rc = SUCCESS;
+		goto return_reset_status;
+	}
 
 	/* if controller locked up, we can guarantee command won't complete */
 	if (lockup_detected(h)) {
@@ -5863,7 +5879,8 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 			 "cmd %d RESET FAILED, lockup detected",
 			 hpsa_get_cmd_index(scsicmd));
 		hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
-		return FAILED;
+		rc = FAILED;
+		goto return_reset_status;
 	}
 
 	/* this reset request might be the result of a lockup; check */
@@ -5872,12 +5889,15 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 			 "cmd %d RESET FAILED, new lockup detected",
 			 hpsa_get_cmd_index(scsicmd));
 		hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
-		return FAILED;
+		rc = FAILED;
+		goto return_reset_status;
 	}
 
 	/* Do not attempt on controller */
-	if (is_hba_lunid(dev->scsi3addr))
-		return SUCCESS;
+	if (is_hba_lunid(dev->scsi3addr)) {
+		rc = SUCCESS;
+		goto return_reset_status;
+	}
 
 	if (is_logical_dev_addr_mode(dev->scsi3addr))
 		reset_type = HPSA_DEVICE_RESET_MSG;
@@ -5888,17 +5908,24 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
 	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
 
-	h->reset_in_progress = 1;
-
 	/* send a reset to the SCSI LUN which the command was sent to */
 	rc = hpsa_do_reset(h, dev, dev->scsi3addr, reset_type,
 			   DEFAULT_REPLY_QUEUE);
+	if (rc == 0)
+		rc = SUCCESS;
+	else
+		rc = FAILED;
+
 	sprintf(msg, "reset %s %s",
 		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ",
-		rc == 0 ? "completed successfully" : "failed");
+		rc == SUCCESS ? "completed successfully" : "failed");
 	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
+
+return_reset_status:
+	spin_lock_irqsave(&h->reset_lock, flags);
 	h->reset_in_progress = 0;
-	return rc == 0 ? SUCCESS : FAILED;
+	spin_unlock_irqrestore(&h->reset_lock, flags);
+	return rc;
 }
 
 static void swizzle_abort_tag(u8 *tag)
@@ -8649,10 +8676,13 @@ static void hpsa_rescan_ctlr_worker(struct work_struct *work)
 	/*
 	 * Do the scan after the reset
 	 */
+	spin_lock_irqsave(&h->reset_lock, flags);
 	if (h->reset_in_progress) {
+		spin_unlock_irqrestore(&h->reset_lock, flags);
 		h->drv_req_rescan = 1;
 		return;
 	}
+	spin_unlock_irqrestore(&h->reset_lock, flags);
 
 	if (hpsa_ctlr_needs_rescan(h) || hpsa_offline_devices_ready(h)) {
 		scsi_host_get(h->scsi_host);
@@ -8759,6 +8789,7 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	spin_lock_init(&h->lock);
 	spin_lock_init(&h->offline_device_lock);
 	spin_lock_init(&h->scan_lock);
+	spin_lock_init(&h->reset_lock);
 	atomic_set(&h->passthru_cmds_avail, HPSA_MAX_CONCURRENT_PASSTHRUS);
 	atomic_set(&h->abort_cmds_available, HPSA_CMDS_RESERVED_FOR_ABORTS);
 
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 6f04f2a..5352664 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -301,6 +301,7 @@ struct ctlr_info {
 	struct mutex reset_mutex;
 	u8 reset_in_progress;
 	struct hpsa_sas_node *sas_host;
+	spinlock_t reset_lock;
 };
 
 struct offline_device_entry {

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH V2 08/12] hpsa: correct queue depth for externals
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
                   ` (6 preceding siblings ...)
  2017-04-28 18:20 ` [PATCH V2 07/12] hpsa: cleanup reset handler Don Brace
@ 2017-04-28 18:20 ` Don Brace
  2017-04-28 18:20 ` [PATCH V2 09/12] hpsa: separate monitor events from rescan worker Don Brace
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:20 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

 - queue depth assignment not in correct place, had no effect.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa.c |   22 ++++++++++------------
 drivers/scsi/hpsa.h |    1 +
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 71f32e9..b2827be 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2069,10 +2069,13 @@ static int hpsa_slave_configure(struct scsi_device *sdev)
 	sd = sdev->hostdata;
 	sdev->no_uld_attach = !sd || !sd->expose_device;
 
-	if (sd)
-		queue_depth = sd->queue_depth != 0 ?
-			sd->queue_depth : sdev->host->can_queue;
-	else
+	if (sd) {
+		if (sd->external)
+			queue_depth = EXTERNAL_QD;
+		else
+			queue_depth = sd->queue_depth != 0 ?
+					sd->queue_depth : sdev->host->can_queue;
+	} else
 		queue_depth = sdev->host->can_queue;
 
 	scsi_change_queue_depth(sdev, queue_depth);
@@ -3915,6 +3918,9 @@ static int hpsa_update_device_info(struct ctlr_info *h,
 		this_device->queue_depth = h->nr_cmds;
 	}
 
+	if (this_device->external)
+		this_device->queue_depth = EXTERNAL_QD;
+
 	if (is_OBDR_device) {
 		/* See if this is a One-Button-Disaster-Recovery device
 		 * by looking for "$DR-10" at offset 43 in inquiry data.
@@ -4123,14 +4129,6 @@ static void hpsa_get_ioaccel_drive_info(struct ctlr_info *h,
 	int rc;
 	struct ext_report_lun_entry *rle;
 
-	/*
-	 * external targets don't support BMIC
-	 */
-	if (dev->external) {
-		dev->queue_depth = 7;
-		return;
-	}
-
 	rle = &rlep->LUN[rle_index];
 
 	dev->ioaccel_handle = rle->ioaccel_handle;
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 5352664..61dd54a 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -57,6 +57,7 @@ struct hpsa_sas_phy {
 	bool added_to_port;
 };
 
+#define EXTERNAL_QD 7
 struct hpsa_scsi_dev_t {
 	unsigned int devtype;
 	int bus, target, lun;		/* as presented to the OS */

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH V2 09/12] hpsa: separate monitor events from rescan worker
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
                   ` (7 preceding siblings ...)
  2017-04-28 18:20 ` [PATCH V2 08/12] hpsa: correct queue depth for externals Don Brace
@ 2017-04-28 18:20 ` Don Brace
  2017-04-28 18:20 ` [PATCH V2 10/12] hpsa: send ioaccel requests with 0 length down raid path Don Brace
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:20 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Scott Teel <scott.teel@microsemi.com>

create new worker thread to monitor controller events
 - both the rescan and event monitor workers can cause a
   rescan to occur however for multipath we have found
   that we need to respond faster than the normal scheduled
   rescan interval for path fail-overs.
 - getting controller events only involves reading a register, but
   the rescan worker can obtain an updated LUN list when there
   is a PTRAID device present.
 - move common code to a separate function.
advantages:
 - detect controller events more frequently.
 - leave rescan thread interval at 30 seconds.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa.c |   76 +++++++++++++++++++++++++++++++++++++++------------
 drivers/scsi/hpsa.h |    1 +
 2 files changed, 59 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index b2827be..49f5ccf 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1110,6 +1110,7 @@ static int is_firmware_flash_cmd(u8 *cdb)
  */
 #define HEARTBEAT_SAMPLE_INTERVAL_DURING_FLASH (240 * HZ)
 #define HEARTBEAT_SAMPLE_INTERVAL (30 * HZ)
+#define HPSA_EVENT_MONITOR_INTERVAL (15 * HZ)
 static void dial_down_lockup_detection_during_fw_flash(struct ctlr_info *h,
 		struct CommandList *c)
 {
@@ -8661,15 +8662,10 @@ static int hpsa_luns_changed(struct ctlr_info *h)
 	return rc;
 }
 
-static void hpsa_rescan_ctlr_worker(struct work_struct *work)
+static void hpsa_perform_rescan(struct ctlr_info *h)
 {
+	struct Scsi_Host *sh = NULL;
 	unsigned long flags;
-	struct ctlr_info *h = container_of(to_delayed_work(work),
-					struct ctlr_info, rescan_ctlr_work);
-
-
-	if (h->remove_in_progress)
-		return;
 
 	/*
 	 * Do the scan after the reset
@@ -8682,23 +8678,63 @@ static void hpsa_rescan_ctlr_worker(struct work_struct *work)
 	}
 	spin_unlock_irqrestore(&h->reset_lock, flags);
 
-	if (hpsa_ctlr_needs_rescan(h) || hpsa_offline_devices_ready(h)) {
-		scsi_host_get(h->scsi_host);
+	sh = scsi_host_get(h->scsi_host);
+	if (sh != NULL) {
+		hpsa_scan_start(sh);
+		scsi_host_put(sh);
+		h->drv_req_rescan = 0;
+	}
+}
+
+/*
+ * watch for controller events
+ */
+static void hpsa_event_monitor_worker(struct work_struct *work)
+{
+	struct ctlr_info *h = container_of(to_delayed_work(work),
+					struct ctlr_info, event_monitor_work);
+	unsigned long flags;
+
+	spin_lock_irqsave(&h->lock, flags);
+	if (h->remove_in_progress) {
+		spin_unlock_irqrestore(&h->lock, flags);
+		return;
+	}
+	spin_unlock_irqrestore(&h->lock, flags);
+
+	if (hpsa_ctlr_needs_rescan(h)) {
 		hpsa_ack_ctlr_events(h);
-		hpsa_scan_start(h->scsi_host);
-		scsi_host_put(h->scsi_host);
+		hpsa_perform_rescan(h);
+	}
+
+	spin_lock_irqsave(&h->lock, flags);
+	if (!h->remove_in_progress)
+		schedule_delayed_work(&h->event_monitor_work,
+					HPSA_EVENT_MONITOR_INTERVAL);
+	spin_unlock_irqrestore(&h->lock, flags);
+}
+
+static void hpsa_rescan_ctlr_worker(struct work_struct *work)
+{
+	unsigned long flags;
+	struct ctlr_info *h = container_of(to_delayed_work(work),
+					struct ctlr_info, rescan_ctlr_work);
+
+	spin_lock_irqsave(&h->lock, flags);
+	if (h->remove_in_progress) {
+		spin_unlock_irqrestore(&h->lock, flags);
+		return;
+	}
+	spin_unlock_irqrestore(&h->lock, flags);
+
+	if (h->drv_req_rescan || hpsa_offline_devices_ready(h)) {
+		hpsa_perform_rescan(h);
 	} else if (h->discovery_polling) {
 		hpsa_disable_rld_caching(h);
 		if (hpsa_luns_changed(h)) {
-			struct Scsi_Host *sh = NULL;
-
 			dev_info(&h->pdev->dev,
 				"driver discovery polling rescan.\n");
-			sh = scsi_host_get(h->scsi_host);
-			if (sh != NULL) {
-				hpsa_scan_start(sh);
-				scsi_host_put(sh);
-			}
+			hpsa_perform_rescan(h);
 		}
 	}
 	spin_lock_irqsave(&h->lock, flags);
@@ -8964,6 +9000,9 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	INIT_DELAYED_WORK(&h->rescan_ctlr_work, hpsa_rescan_ctlr_worker);
 	queue_delayed_work(h->rescan_ctlr_wq, &h->rescan_ctlr_work,
 				h->heartbeat_sample_interval);
+	INIT_DELAYED_WORK(&h->event_monitor_work, hpsa_event_monitor_worker);
+	schedule_delayed_work(&h->event_monitor_work,
+				HPSA_EVENT_MONITOR_INTERVAL);
 	return 0;
 
 clean7: /* perf, sg, cmd, irq, shost, pci, lu, aer/h */
@@ -9132,6 +9171,7 @@ static void hpsa_remove_one(struct pci_dev *pdev)
 	spin_unlock_irqrestore(&h->lock, flags);
 	cancel_delayed_work_sync(&h->monitor_ctlr_work);
 	cancel_delayed_work_sync(&h->rescan_ctlr_work);
+	cancel_delayed_work_sync(&h->event_monitor_work);
 	destroy_workqueue(h->rescan_ctlr_wq);
 	destroy_workqueue(h->resubmit_wq);
 
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 61dd54a..c9c4927 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -245,6 +245,7 @@ struct ctlr_info {
 	u32 __percpu *lockup_detected;
 	struct delayed_work monitor_ctlr_work;
 	struct delayed_work rescan_ctlr_work;
+	struct delayed_work event_monitor_work;
 	int remove_in_progress;
 	/* Address of h->q[x] is passed to intr handler to know which queue */
 	u8 q[MAX_REPLY_QUEUES];

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH V2 10/12] hpsa: send ioaccel requests with 0 length down raid path
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
                   ` (8 preceding siblings ...)
  2017-04-28 18:20 ` [PATCH V2 09/12] hpsa: separate monitor events from rescan worker Don Brace
@ 2017-04-28 18:20 ` Don Brace
  2017-04-28 18:20 ` [PATCH V2 11/12] hpsa: remove abort handler Don Brace
  2017-04-28 18:20 ` [PATCH V2 12/12] hpsa: bump driver version Don Brace
  11 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:20 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

 - Block I/O requests with 0 length transfers which go down
   the ioaccel path. This causes lockup issues down in the basecode.
   - These issues have been fixed, but there are customers who are
     experiencing the issues when running older firmware.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 49f5ccf..9e18ab1 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4591,7 +4591,55 @@ static int hpsa_scatter_gather(struct ctlr_info *h,
 	return 0;
 }
 
-#define IO_ACCEL_INELIGIBLE (1)
+#define BUFLEN 128
+static inline void warn_zero_length_transfer(struct ctlr_info *h,
+						u8 *cdb, int cdb_len,
+						const char *func)
+{
+	char buf[BUFLEN];
+	int outlen;
+	int i;
+
+	outlen = scnprintf(buf, BUFLEN,
+				"%s: Blocking zero-length request: CDB:", func);
+	for (i = 0; i < cdb_len; i++)
+		outlen += scnprintf(buf+outlen, BUFLEN - outlen,
+					"%02hhx", cdb[i]);
+	dev_warn(&h->pdev->dev, "%s\n", buf);
+}
+
+#define IO_ACCEL_INELIGIBLE 1
+/* zero-length transfers trigger hardware errors. */
+static bool is_zero_length_transfer(u8 *cdb)
+{
+	u32 block_cnt;
+
+	/* Block zero-length transfer sizes on certain commands. */
+	switch (cdb[0]) {
+	case READ_10:
+	case WRITE_10:
+	case VERIFY:		/* 0x2F */
+	case WRITE_VERIFY:	/* 0x2E */
+		block_cnt = get_unaligned_be16(&cdb[7]);
+		break;
+	case READ_12:
+	case WRITE_12:
+	case VERIFY_12: /* 0xAF */
+	case WRITE_VERIFY_12:	/* 0xAE */
+		block_cnt = get_unaligned_be32(&cdb[6]);
+		break;
+	case READ_16:
+	case WRITE_16:
+	case VERIFY_16:		/* 0x8F */
+		block_cnt = get_unaligned_be32(&cdb[10]);
+		break;
+	default:
+		return false;
+	}
+
+	return block_cnt == 0;
+}
+
 static int fixup_ioaccel_cdb(u8 *cdb, int *cdb_len)
 {
 	int is_write = 0;
@@ -4658,6 +4706,12 @@ static int hpsa_scsi_ioaccel1_queue_command(struct ctlr_info *h,
 
 	BUG_ON(cmd->cmd_len > IOACCEL1_IOFLAGS_CDBLEN_MAX);
 
+	if (is_zero_length_transfer(cdb)) {
+		warn_zero_length_transfer(h, cdb, cdb_len, __func__);
+		atomic_dec(&phys_disk->ioaccel_cmds_out);
+		return IO_ACCEL_INELIGIBLE;
+	}
+
 	if (fixup_ioaccel_cdb(cdb, &cdb_len)) {
 		atomic_dec(&phys_disk->ioaccel_cmds_out);
 		return IO_ACCEL_INELIGIBLE;
@@ -4822,6 +4876,12 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
 
 	BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
 
+	if (is_zero_length_transfer(cdb)) {
+		warn_zero_length_transfer(h, cdb, cdb_len, __func__);
+		atomic_dec(&phys_disk->ioaccel_cmds_out);
+		return IO_ACCEL_INELIGIBLE;
+	}
+
 	if (fixup_ioaccel_cdb(cdb, &cdb_len)) {
 		atomic_dec(&phys_disk->ioaccel_cmds_out);
 		return IO_ACCEL_INELIGIBLE;

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH V2 11/12] hpsa: remove abort handler
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
                   ` (9 preceding siblings ...)
  2017-04-28 18:20 ` [PATCH V2 10/12] hpsa: send ioaccel requests with 0 length down raid path Don Brace
@ 2017-04-28 18:20 ` Don Brace
  2017-04-28 18:20 ` [PATCH V2 12/12] hpsa: bump driver version Don Brace
  11 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:20 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

 - simplify the driver
 - there are a lot of quirky racy conditions not handled
 - causes more aborts/resets when the number of commands to
   be aborted is large, such as in multi-path fail-overs.
 - has been turned off in our internal driver since 8/31/2015

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa.c |  621 +--------------------------------------------------
 drivers/scsi/hpsa.h |    1 
 2 files changed, 8 insertions(+), 614 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9e18ab1..f1d7d1e 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -258,7 +258,6 @@ static int hpsa_scan_finished(struct Scsi_Host *sh,
 static int hpsa_change_queue_depth(struct scsi_device *sdev, int qdepth);
 
 static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd);
-static int hpsa_eh_abort_handler(struct scsi_cmnd *scsicmd);
 static int hpsa_slave_alloc(struct scsi_device *sdev);
 static int hpsa_slave_configure(struct scsi_device *sdev);
 static void hpsa_slave_destroy(struct scsi_device *sdev);
@@ -326,7 +325,7 @@ static inline bool hpsa_is_cmd_idle(struct CommandList *c)
 
 static inline bool hpsa_is_pending_event(struct CommandList *c)
 {
-	return c->abort_pending || c->reset_pending;
+	return c->reset_pending;
 }
 
 /* extract sense key, asc, and ascq from sense data.  -1 means invalid. */
@@ -581,12 +580,6 @@ static u32 soft_unresettable_controller[] = {
 	0x409D0E11, /* Smart Array 6400 EM */
 };
 
-static u32 needs_abort_tags_swizzled[] = {
-	0x323D103C, /* Smart Array P700m */
-	0x324a103C, /* Smart Array P712m */
-	0x324b103C, /* SmartArray P711m */
-};
-
 static int board_id_in_array(u32 a[], int nelems, u32 board_id)
 {
 	int i;
@@ -615,12 +608,6 @@ static int ctlr_is_resettable(u32 board_id)
 		ctlr_is_soft_resettable(board_id);
 }
 
-static int ctlr_needs_abort_tags_swizzled(u32 board_id)
-{
-	return board_id_in_array(needs_abort_tags_swizzled,
-			ARRAY_SIZE(needs_abort_tags_swizzled), board_id);
-}
-
 static ssize_t host_show_resettable(struct device *dev,
 	struct device_attribute *attr, char *buf)
 {
@@ -928,8 +915,8 @@ static struct device_attribute *hpsa_shost_attrs[] = {
 	NULL,
 };
 
-#define HPSA_NRESERVED_CMDS	(HPSA_CMDS_RESERVED_FOR_ABORTS + \
-		HPSA_CMDS_RESERVED_FOR_DRIVER + HPSA_MAX_CONCURRENT_PASSTHRUS)
+#define HPSA_NRESERVED_CMDS	(HPSA_CMDS_RESERVED_FOR_DRIVER +\
+				 HPSA_MAX_CONCURRENT_PASSTHRUS)
 
 static struct scsi_host_template hpsa_driver_template = {
 	.module			= THIS_MODULE,
@@ -941,7 +928,6 @@ static struct scsi_host_template hpsa_driver_template = {
 	.change_queue_depth	= hpsa_change_queue_depth,
 	.this_id		= -1,
 	.use_clustering		= ENABLE_CLUSTERING,
-	.eh_abort_handler	= hpsa_eh_abort_handler,
 	.eh_device_reset_handler = hpsa_eh_device_reset_handler,
 	.ioctl			= hpsa_ioctl,
 	.slave_alloc		= hpsa_slave_alloc,
@@ -2361,26 +2347,12 @@ static void hpsa_cmd_resolve_events(struct ctlr_info *h,
 	bool do_wake = false;
 
 	/*
-	 * Prevent the following race in the abort handler:
-	 *
-	 * 1. LLD is requested to abort a SCSI command
-	 * 2. The SCSI command completes
-	 * 3. The struct CommandList associated with step 2 is made available
-	 * 4. New I/O request to LLD to another LUN re-uses struct CommandList
-	 * 5. Abort handler follows scsi_cmnd->host_scribble and
-	 *    finds struct CommandList and tries to aborts it
-	 * Now we have aborted the wrong command.
-	 *
-	 * Reset c->scsi_cmd here so that the abort or reset handler will know
+	 * Reset c->scsi_cmd here so that the reset handler will know
 	 * this command has completed.  Then, check to see if the handler is
 	 * waiting for this command, and, if so, wake it.
 	 */
 	c->scsi_cmd = SCSI_CMD_IDLE;
 	mb();	/* Declare command idle before checking for pending events. */
-	if (c->abort_pending) {
-		do_wake = true;
-		c->abort_pending = false;
-	}
 	if (c->reset_pending) {
 		unsigned long flags;
 		struct hpsa_scsi_dev_t *dev;
@@ -2423,20 +2395,6 @@ static void hpsa_retry_cmd(struct ctlr_info *h, struct CommandList *c)
 	queue_work_on(raw_smp_processor_id(), h->resubmit_wq, &c->work);
 }
 
-static void hpsa_set_scsi_cmd_aborted(struct scsi_cmnd *cmd)
-{
-	cmd->result = DID_ABORT << 16;
-}
-
-static void hpsa_cmd_abort_and_free(struct ctlr_info *h, struct CommandList *c,
-				    struct scsi_cmnd *cmd)
-{
-	hpsa_set_scsi_cmd_aborted(cmd);
-	dev_warn(&h->pdev->dev, "CDB %16phN was aborted with status 0x%x\n",
-			 c->Request.CDB, c->err_info->ScsiStatus);
-	hpsa_cmd_resolve_and_free(h, c);
-}
-
 static void process_ioaccel2_completion(struct ctlr_info *h,
 		struct CommandList *c, struct scsi_cmnd *cmd,
 		struct hpsa_scsi_dev_t *dev)
@@ -2561,12 +2519,9 @@ static void complete_scsi_command(struct CommandList *cp)
 		return hpsa_cmd_free_and_done(h, cp, cmd);
 	}
 
-	if ((unlikely(hpsa_is_pending_event(cp)))) {
+	if ((unlikely(hpsa_is_pending_event(cp))))
 		if (cp->reset_pending)
 			return hpsa_cmd_free_and_done(h, cp, cmd);
-		if (cp->abort_pending)
-			return hpsa_cmd_abort_and_free(h, cp, cmd);
-	}
 
 	if (cp->cmd_type == CMD_IOACCEL2)
 		return process_ioaccel2_completion(h, cp, cmd, dev);
@@ -2686,8 +2641,8 @@ static void complete_scsi_command(struct CommandList *cp)
 			cp->Request.CDB);
 		break;
 	case CMD_ABORTED:
-		/* Return now to avoid calling scsi_done(). */
-		return hpsa_cmd_abort_and_free(h, cp, cmd);
+		cmd->result = DID_ABORT << 16;
+		break;
 	case CMD_ABORT_FAILED:
 		cmd->result = DID_ERROR << 16;
 		dev_warn(&h->pdev->dev, "CDB %16phN : abort failed\n",
@@ -3793,53 +3748,6 @@ static unsigned char hpsa_volume_offline(struct ctlr_info *h,
 	return HPSA_LV_OK;
 }
 
-/*
- * Find out if a logical device supports aborts by simply trying one.
- * Smart Array may claim not to support aborts on logical drives, but
- * if a MSA2000 * is connected, the drives on that will be presented
- * by the Smart Array as logical drives, and aborts may be sent to
- * those devices successfully.  So the simplest way to find out is
- * to simply try an abort and see how the device responds.
- */
-static int hpsa_device_supports_aborts(struct ctlr_info *h,
-					unsigned char *scsi3addr)
-{
-	struct CommandList *c;
-	struct ErrorInfo *ei;
-	int rc = 0;
-
-	u64 tag = (u64) -1; /* bogus tag */
-
-	/* Assume that physical devices support aborts */
-	if (!is_logical_dev_addr_mode(scsi3addr))
-		return 1;
-
-	c = cmd_alloc(h);
-
-	(void) fill_cmd(c, HPSA_ABORT_MSG, h, &tag, 0, 0, scsi3addr, TYPE_MSG);
-	(void) hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
-					DEFAULT_TIMEOUT);
-	/* no unmap needed here because no data xfer. */
-	ei = c->err_info;
-	switch (ei->CommandStatus) {
-	case CMD_INVALID:
-		rc = 0;
-		break;
-	case CMD_UNABORTABLE:
-	case CMD_ABORT_FAILED:
-		rc = 1;
-		break;
-	case CMD_TMF_STATUS:
-		rc = hpsa_evaluate_tmf_status(h, c);
-		break;
-	default:
-		rc = 0;
-		break;
-	}
-	cmd_free(h, c);
-	return rc;
-}
-
 static int hpsa_update_device_info(struct ctlr_info *h,
 	unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
 	unsigned char *is_OBDR_device)
@@ -3939,31 +3847,6 @@ static int hpsa_update_device_info(struct ctlr_info *h,
 	return rc;
 }
 
-static void hpsa_update_device_supports_aborts(struct ctlr_info *h,
-			struct hpsa_scsi_dev_t *dev, u8 *scsi3addr)
-{
-	unsigned long flags;
-	int rc, entry;
-	/*
-	 * See if this device supports aborts.  If we already know
-	 * the device, we already know if it supports aborts, otherwise
-	 * we have to find out if it supports aborts by trying one.
-	 */
-	spin_lock_irqsave(&h->devlock, flags);
-	rc = hpsa_scsi_find_entry(dev, h->dev, h->ndevices, &entry);
-	if ((rc == DEVICE_SAME || rc == DEVICE_UPDATED) &&
-		entry >= 0 && entry < h->ndevices) {
-		dev->supports_aborts = h->dev[entry]->supports_aborts;
-		spin_unlock_irqrestore(&h->devlock, flags);
-	} else {
-		spin_unlock_irqrestore(&h->devlock, flags);
-		dev->supports_aborts =
-				hpsa_device_supports_aborts(h, scsi3addr);
-		if (dev->supports_aborts < 0)
-			dev->supports_aborts = 0;
-	}
-}
-
 /*
  * Helper function to assign bus, target, lun mapping of devices.
  * Logical drive target and lun are assigned at this time, but
@@ -4001,35 +3884,6 @@ static void figure_bus_target_lun(struct ctlr_info *h,
 				0, lunid & 0x3fff);
 }
 
-
-/*
- * Get address of physical disk used for an ioaccel2 mode command:
- *	1. Extract ioaccel2 handle from the command.
- *	2. Find a matching ioaccel2 handle from list of physical disks.
- *	3. Return:
- *		1 and set scsi3addr to address of matching physical
- *		0 if no matching physical disk was found.
- */
-static int hpsa_get_pdisk_of_ioaccel2(struct ctlr_info *h,
-	struct CommandList *ioaccel2_cmd_to_abort, unsigned char *scsi3addr)
-{
-	struct io_accel2_cmd *c2 =
-			&h->ioaccel2_cmd_pool[ioaccel2_cmd_to_abort->cmdindex];
-	unsigned long flags;
-	int i;
-
-	spin_lock_irqsave(&h->devlock, flags);
-	for (i = 0; i < h->ndevices; i++)
-		if (h->dev[i]->ioaccel_handle == le32_to_cpu(c2->scsi_nexus)) {
-			memcpy(scsi3addr, h->dev[i]->scsi3addr,
-				sizeof(h->dev[i]->scsi3addr));
-			spin_unlock_irqrestore(&h->devlock, flags);
-			return 1;
-		}
-	spin_unlock_irqrestore(&h->devlock, flags);
-	return 0;
-}
-
 static int  figure_external_status(struct ctlr_info *h, int raid_ctlr_position,
 	int i, int nphysicals, int nlocal_logicals)
 {
@@ -4394,7 +4248,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
 		}
 
 		figure_bus_target_lun(h, lunaddrbytes, tmpdevice);
-		hpsa_update_device_supports_aborts(h, tmpdevice, lunaddrbytes);
 		this_device = currentsd[ncurrent];
 
 		/* Turn on discovery_polling if there are ext target devices.
@@ -5528,8 +5381,6 @@ static void hpsa_command_resubmit_worker(struct work_struct *work)
 	}
 	if (c->reset_pending)
 		return hpsa_cmd_free_and_done(c->h, c, cmd);
-	if (c->abort_pending)
-		return hpsa_cmd_abort_and_free(c->h, c, cmd);
 	if (c->cmd_type == CMD_IOACCEL2) {
 		struct ctlr_info *h = c->h;
 		struct io_accel2_cmd *c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
@@ -5987,433 +5838,6 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 	return rc;
 }
 
-static void swizzle_abort_tag(u8 *tag)
-{
-	u8 original_tag[8];
-
-	memcpy(original_tag, tag, 8);
-	tag[0] = original_tag[3];
-	tag[1] = original_tag[2];
-	tag[2] = original_tag[1];
-	tag[3] = original_tag[0];
-	tag[4] = original_tag[7];
-	tag[5] = original_tag[6];
-	tag[6] = original_tag[5];
-	tag[7] = original_tag[4];
-}
-
-static void hpsa_get_tag(struct ctlr_info *h,
-	struct CommandList *c, __le32 *taglower, __le32 *tagupper)
-{
-	u64 tag;
-	if (c->cmd_type == CMD_IOACCEL1) {
-		struct io_accel1_cmd *cm1 = (struct io_accel1_cmd *)
-			&h->ioaccel_cmd_pool[c->cmdindex];
-		tag = le64_to_cpu(cm1->tag);
-		*tagupper = cpu_to_le32(tag >> 32);
-		*taglower = cpu_to_le32(tag);
-		return;
-	}
-	if (c->cmd_type == CMD_IOACCEL2) {
-		struct io_accel2_cmd *cm2 = (struct io_accel2_cmd *)
-			&h->ioaccel2_cmd_pool[c->cmdindex];
-		/* upper tag not used in ioaccel2 mode */
-		memset(tagupper, 0, sizeof(*tagupper));
-		*taglower = cm2->Tag;
-		return;
-	}
-	tag = le64_to_cpu(c->Header.tag);
-	*tagupper = cpu_to_le32(tag >> 32);
-	*taglower = cpu_to_le32(tag);
-}
-
-static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr,
-	struct CommandList *abort, int reply_queue)
-{
-	int rc = IO_OK;
-	struct CommandList *c;
-	struct ErrorInfo *ei;
-	__le32 tagupper, taglower;
-
-	c = cmd_alloc(h);
-
-	/* fill_cmd can't fail here, no buffer to map */
-	(void) fill_cmd(c, HPSA_ABORT_MSG, h, &abort->Header.tag,
-		0, 0, scsi3addr, TYPE_MSG);
-	if (h->needs_abort_tags_swizzled)
-		swizzle_abort_tag(&c->Request.CDB[4]);
-	(void) hpsa_scsi_do_simple_cmd(h, c, reply_queue, DEFAULT_TIMEOUT);
-	hpsa_get_tag(h, abort, &taglower, &tagupper);
-	dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: do_simple_cmd(abort) completed.\n",
-		__func__, tagupper, taglower);
-	/* no unmap needed here because no data xfer. */
-
-	ei = c->err_info;
-	switch (ei->CommandStatus) {
-	case CMD_SUCCESS:
-		break;
-	case CMD_TMF_STATUS:
-		rc = hpsa_evaluate_tmf_status(h, c);
-		break;
-	case CMD_UNABORTABLE: /* Very common, don't make noise. */
-		rc = -1;
-		break;
-	default:
-		dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: interpreting error.\n",
-			__func__, tagupper, taglower);
-		hpsa_scsi_interpret_error(h, c);
-		rc = -1;
-		break;
-	}
-	cmd_free(h, c);
-	dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: Finished.\n",
-		__func__, tagupper, taglower);
-	return rc;
-}
-
-static void setup_ioaccel2_abort_cmd(struct CommandList *c, struct ctlr_info *h,
-	struct CommandList *command_to_abort, int reply_queue)
-{
-	struct io_accel2_cmd *c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
-	struct hpsa_tmf_struct *ac = (struct hpsa_tmf_struct *) c2;
-	struct io_accel2_cmd *c2a =
-		&h->ioaccel2_cmd_pool[command_to_abort->cmdindex];
-	struct scsi_cmnd *scmd = command_to_abort->scsi_cmd;
-	struct hpsa_scsi_dev_t *dev = scmd->device->hostdata;
-
-	if (!dev)
-		return;
-
-	/*
-	 * We're overlaying struct hpsa_tmf_struct on top of something which
-	 * was allocated as a struct io_accel2_cmd, so we better be sure it
-	 * actually fits, and doesn't overrun the error info space.
-	 */
-	BUILD_BUG_ON(sizeof(struct hpsa_tmf_struct) >
-			sizeof(struct io_accel2_cmd));
-	BUG_ON(offsetof(struct io_accel2_cmd, error_data) <
-			offsetof(struct hpsa_tmf_struct, error_len) +
-				sizeof(ac->error_len));
-
-	c->cmd_type = IOACCEL2_TMF;
-	c->scsi_cmd = SCSI_CMD_BUSY;
-
-	/* Adjust the DMA address to point to the accelerated command buffer */
-	c->busaddr = (u32) h->ioaccel2_cmd_pool_dhandle +
-				(c->cmdindex * sizeof(struct io_accel2_cmd));
-	BUG_ON(c->busaddr & 0x0000007F);
-
-	memset(ac, 0, sizeof(*c2)); /* yes this is correct */
-	ac->iu_type = IOACCEL2_IU_TMF_TYPE;
-	ac->reply_queue = reply_queue;
-	ac->tmf = IOACCEL2_TMF_ABORT;
-	ac->it_nexus = cpu_to_le32(dev->ioaccel_handle);
-	memset(ac->lun_id, 0, sizeof(ac->lun_id));
-	ac->tag = cpu_to_le64(c->cmdindex << DIRECT_LOOKUP_SHIFT);
-	ac->abort_tag = cpu_to_le64(le32_to_cpu(c2a->Tag));
-	ac->error_ptr = cpu_to_le64(c->busaddr +
-			offsetof(struct io_accel2_cmd, error_data));
-	ac->error_len = cpu_to_le32(sizeof(c2->error_data));
-}
-
-/* ioaccel2 path firmware cannot handle abort task requests.
- * Change abort requests to physical target reset, and send to the
- * address of the physical disk used for the ioaccel 2 command.
- * Return 0 on success (IO_OK)
- *	 -1 on failure
- */
-
-static int hpsa_send_reset_as_abort_ioaccel2(struct ctlr_info *h,
-	unsigned char *scsi3addr, struct CommandList *abort, int reply_queue)
-{
-	int rc = IO_OK;
-	struct scsi_cmnd *scmd; /* scsi command within request being aborted */
-	struct hpsa_scsi_dev_t *dev; /* device to which scsi cmd was sent */
-	unsigned char phys_scsi3addr[8]; /* addr of phys disk with volume */
-	unsigned char *psa = &phys_scsi3addr[0];
-
-	/* Get a pointer to the hpsa logical device. */
-	scmd = abort->scsi_cmd;
-	dev = (struct hpsa_scsi_dev_t *)(scmd->device->hostdata);
-	if (dev == NULL) {
-		dev_warn(&h->pdev->dev,
-			"Cannot abort: no device pointer for command.\n");
-			return -1; /* not abortable */
-	}
-
-	if (h->raid_offload_debug > 0)
-		dev_info(&h->pdev->dev,
-			"scsi %d:%d:%d:%d %s scsi3addr 0x%8phN\n",
-			h->scsi_host->host_no, dev->bus, dev->target, dev->lun,
-			"Reset as abort", scsi3addr);
-
-	if (!dev->offload_enabled) {
-		dev_warn(&h->pdev->dev,
-			"Can't abort: device is not operating in HP SSD Smart Path mode.\n");
-		return -1; /* not abortable */
-	}
-
-	/* Incoming scsi3addr is logical addr. We need physical disk addr. */
-	if (!hpsa_get_pdisk_of_ioaccel2(h, abort, psa)) {
-		dev_warn(&h->pdev->dev, "Can't abort: Failed lookup of physical address.\n");
-		return -1; /* not abortable */
-	}
-
-	/* send the reset */
-	if (h->raid_offload_debug > 0)
-		dev_info(&h->pdev->dev,
-			"Reset as abort: Resetting physical device at scsi3addr 0x%8phN\n",
-			psa);
-	rc = hpsa_do_reset(h, dev, psa, HPSA_PHYS_TARGET_RESET, reply_queue);
-	if (rc != 0) {
-		dev_warn(&h->pdev->dev,
-			"Reset as abort: Failed on physical device at scsi3addr 0x%8phN\n",
-			psa);
-		return rc; /* failed to reset */
-	}
-
-	/* wait for device to recover */
-	if (wait_for_device_to_become_ready(h, psa, reply_queue) != 0) {
-		dev_warn(&h->pdev->dev,
-			"Reset as abort: Failed: Device never recovered from reset: 0x%8phN\n",
-			psa);
-		return -1;  /* failed to recover */
-	}
-
-	/* device recovered */
-	dev_info(&h->pdev->dev,
-		"Reset as abort: Device recovered from reset: scsi3addr 0x%8phN\n",
-		psa);
-
-	return rc; /* success */
-}
-
-static int hpsa_send_abort_ioaccel2(struct ctlr_info *h,
-	struct CommandList *abort, int reply_queue)
-{
-	int rc = IO_OK;
-	struct CommandList *c;
-	__le32 taglower, tagupper;
-	struct hpsa_scsi_dev_t *dev;
-	struct io_accel2_cmd *c2;
-
-	dev = abort->scsi_cmd->device->hostdata;
-	if (!dev)
-		return -1;
-
-	if (!dev->offload_enabled && !dev->hba_ioaccel_enabled)
-		return -1;
-
-	c = cmd_alloc(h);
-	setup_ioaccel2_abort_cmd(c, h, abort, reply_queue);
-	c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
-	(void) hpsa_scsi_do_simple_cmd(h, c, reply_queue, DEFAULT_TIMEOUT);
-	hpsa_get_tag(h, abort, &taglower, &tagupper);
-	dev_dbg(&h->pdev->dev,
-		"%s: Tag:0x%08x:%08x: do_simple_cmd(ioaccel2 abort) completed.\n",
-		__func__, tagupper, taglower);
-	/* no unmap needed here because no data xfer. */
-
-	dev_dbg(&h->pdev->dev,
-		"%s: Tag:0x%08x:%08x: abort service response = 0x%02x.\n",
-		__func__, tagupper, taglower, c2->error_data.serv_response);
-	switch (c2->error_data.serv_response) {
-	case IOACCEL2_SERV_RESPONSE_TMF_COMPLETE:
-	case IOACCEL2_SERV_RESPONSE_TMF_SUCCESS:
-		rc = 0;
-		break;
-	case IOACCEL2_SERV_RESPONSE_TMF_REJECTED:
-	case IOACCEL2_SERV_RESPONSE_FAILURE:
-	case IOACCEL2_SERV_RESPONSE_TMF_WRONG_LUN:
-		rc = -1;
-		break;
-	default:
-		dev_warn(&h->pdev->dev,
-			"%s: Tag:0x%08x:%08x: unknown abort service response 0x%02x\n",
-			__func__, tagupper, taglower,
-			c2->error_data.serv_response);
-		rc = -1;
-	}
-	cmd_free(h, c);
-	dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: Finished.\n", __func__,
-		tagupper, taglower);
-	return rc;
-}
-
-static int hpsa_send_abort_both_ways(struct ctlr_info *h,
-	struct hpsa_scsi_dev_t *dev, struct CommandList *abort, int reply_queue)
-{
-	/*
-	 * ioccelerator mode 2 commands should be aborted via the
-	 * accelerated path, since RAID path is unaware of these commands,
-	 * but not all underlying firmware can handle abort TMF.
-	 * Change abort to physical device reset when abort TMF is unsupported.
-	 */
-	if (abort->cmd_type == CMD_IOACCEL2) {
-		if ((HPSATMF_IOACCEL_ENABLED & h->TMFSupportFlags) ||
-			dev->physical_device)
-			return hpsa_send_abort_ioaccel2(h, abort,
-						reply_queue);
-		else
-			return hpsa_send_reset_as_abort_ioaccel2(h,
-							dev->scsi3addr,
-							abort, reply_queue);
-	}
-	return hpsa_send_abort(h, dev->scsi3addr, abort, reply_queue);
-}
-
-/* Find out which reply queue a command was meant to return on */
-static int hpsa_extract_reply_queue(struct ctlr_info *h,
-					struct CommandList *c)
-{
-	if (c->cmd_type == CMD_IOACCEL2)
-		return h->ioaccel2_cmd_pool[c->cmdindex].reply_queue;
-	return c->Header.ReplyQueue;
-}
-
-/*
- * Limit concurrency of abort commands to prevent
- * over-subscription of commands
- */
-static inline int wait_for_available_abort_cmd(struct ctlr_info *h)
-{
-#define ABORT_CMD_WAIT_MSECS 5000
-	return !wait_event_timeout(h->abort_cmd_wait_queue,
-			atomic_dec_if_positive(&h->abort_cmds_available) >= 0,
-			msecs_to_jiffies(ABORT_CMD_WAIT_MSECS));
-}
-
-/* Send an abort for the specified command.
- *	If the device and controller support it,
- *		send a task abort request.
- */
-static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
-{
-
-	int rc;
-	struct ctlr_info *h;
-	struct hpsa_scsi_dev_t *dev;
-	struct CommandList *abort; /* pointer to command to be aborted */
-	struct scsi_cmnd *as;	/* ptr to scsi cmd inside aborted command. */
-	char msg[256];		/* For debug messaging. */
-	int ml = 0;
-	__le32 tagupper, taglower;
-	int refcount, reply_queue;
-
-	if (sc == NULL)
-		return FAILED;
-
-	if (sc->device == NULL)
-		return FAILED;
-
-	/* Find the controller of the command to be aborted */
-	h = sdev_to_hba(sc->device);
-	if (h == NULL)
-		return FAILED;
-
-	/* Find the device of the command to be aborted */
-	dev = sc->device->hostdata;
-	if (!dev) {
-		dev_err(&h->pdev->dev, "%s FAILED, Device lookup failed.\n",
-				msg);
-		return FAILED;
-	}
-
-	/* If controller locked up, we can guarantee command won't complete */
-	if (lockup_detected(h)) {
-		hpsa_show_dev_msg(KERN_WARNING, h, dev,
-					"ABORT FAILED, lockup detected");
-		return FAILED;
-	}
-
-	/* This is a good time to check if controller lockup has occurred */
-	if (detect_controller_lockup(h)) {
-		hpsa_show_dev_msg(KERN_WARNING, h, dev,
-					"ABORT FAILED, new lockup detected");
-		return FAILED;
-	}
-
-	/* Check that controller supports some kind of task abort */
-	if (!(HPSATMF_PHYS_TASK_ABORT & h->TMFSupportFlags) &&
-		!(HPSATMF_LOG_TASK_ABORT & h->TMFSupportFlags))
-		return FAILED;
-
-	memset(msg, 0, sizeof(msg));
-	ml += sprintf(msg+ml, "scsi %d:%d:%d:%llu %s %p",
-		h->scsi_host->host_no, sc->device->channel,
-		sc->device->id, sc->device->lun,
-		"Aborting command", sc);
-
-	/* Get SCSI command to be aborted */
-	abort = (struct CommandList *) sc->host_scribble;
-	if (abort == NULL) {
-		/* This can happen if the command already completed. */
-		return SUCCESS;
-	}
-	refcount = atomic_inc_return(&abort->refcount);
-	if (refcount == 1) { /* Command is done already. */
-		cmd_free(h, abort);
-		return SUCCESS;
-	}
-
-	/* Don't bother trying the abort if we know it won't work. */
-	if (abort->cmd_type != CMD_IOACCEL2 &&
-		abort->cmd_type != CMD_IOACCEL1 && !dev->supports_aborts) {
-		cmd_free(h, abort);
-		return FAILED;
-	}
-
-	/*
-	 * Check that we're aborting the right command.
-	 * It's possible the CommandList already completed and got re-used.
-	 */
-	if (abort->scsi_cmd != sc) {
-		cmd_free(h, abort);
-		return SUCCESS;
-	}
-
-	abort->abort_pending = true;
-	hpsa_get_tag(h, abort, &taglower, &tagupper);
-	reply_queue = hpsa_extract_reply_queue(h, abort);
-	ml += sprintf(msg+ml, "Tag:0x%08x:%08x ", tagupper, taglower);
-	as  = abort->scsi_cmd;
-	if (as != NULL)
-		ml += sprintf(msg+ml,
-			"CDBLen: %d CDB: 0x%02x%02x... SN: 0x%lx ",
-			as->cmd_len, as->cmnd[0], as->cmnd[1],
-			as->serial_number);
-	dev_warn(&h->pdev->dev, "%s BEING SENT\n", msg);
-	hpsa_show_dev_msg(KERN_WARNING, h, dev, "Aborting command");
-
-	/*
-	 * Command is in flight, or possibly already completed
-	 * by the firmware (but not to the scsi mid layer) but we can't
-	 * distinguish which.  Send the abort down.
-	 */
-	if (wait_for_available_abort_cmd(h)) {
-		dev_warn(&h->pdev->dev,
-			"%s FAILED, timeout waiting for an abort command to become available.\n",
-			msg);
-		cmd_free(h, abort);
-		return FAILED;
-	}
-	rc = hpsa_send_abort_both_ways(h, dev, abort, reply_queue);
-	atomic_inc(&h->abort_cmds_available);
-	wake_up_all(&h->abort_cmd_wait_queue);
-	if (rc != 0) {
-		dev_warn(&h->pdev->dev, "%s SENT, FAILED\n", msg);
-		hpsa_show_dev_msg(KERN_WARNING, h, dev,
-				"FAILED to abort command");
-		cmd_free(h, abort);
-		return FAILED;
-	}
-	dev_info(&h->pdev->dev, "%s SENT, SUCCESS\n", msg);
-	wait_event(h->event_sync_wait_queue,
-		   abort->scsi_cmd != sc || lockup_detected(h));
-	cmd_free(h, abort);
-	return !lockup_detected(h) ? SUCCESS : FAILED;
-}
-
 /*
  * For operations with an associated SCSI command, a command block is allocated
  * at init, and managed by cmd_tagged_alloc() and cmd_tagged_free() using the
@@ -6459,9 +5883,7 @@ static void cmd_tagged_free(struct ctlr_info *h, struct CommandList *c)
 {
 	/*
 	 * Release our reference to the block.  We don't need to do anything
-	 * else to free it, because it is accessed by index.  (There's no point
-	 * in checking the result of the decrement, since we cannot guarantee
-	 * that there isn't a concurrent abort which is also accessing it.)
+	 * else to free it, because it is accessed by index.
 	 */
 	(void)atomic_dec(&c->refcount);
 }
@@ -7000,7 +6422,6 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
 	int cmd_type)
 {
 	int pci_dir = XFER_NONE;
-	u64 tag; /* for commands to be aborted */
 
 	c->cmd_type = CMD_IOCTL_PEND;
 	c->scsi_cmd = SCSI_CMD_BUSY;
@@ -7184,27 +6605,6 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
 			c->Request.CDB[6] = 0x00;
 			c->Request.CDB[7] = 0x00;
 			break;
-		case  HPSA_ABORT_MSG:
-			memcpy(&tag, buff, sizeof(tag));
-			dev_dbg(&h->pdev->dev,
-				"Abort Tag:0x%016llx using rqst Tag:0x%016llx",
-				tag, c->Header.tag);
-			c->Request.CDBLen = 16;
-			c->Request.type_attr_dir =
-					TYPE_ATTR_DIR(cmd_type,
-						ATTR_SIMPLE, XFER_WRITE);
-			c->Request.Timeout = 0; /* Don't time out */
-			c->Request.CDB[0] = HPSA_TASK_MANAGEMENT;
-			c->Request.CDB[1] = HPSA_TMF_ABORT_TASK;
-			c->Request.CDB[2] = 0x00; /* reserved */
-			c->Request.CDB[3] = 0x00; /* reserved */
-			/* Tag to abort goes in CDB[4]-CDB[11] */
-			memcpy(&c->Request.CDB[4], &tag, sizeof(tag));
-			c->Request.CDB[12] = 0x00; /* reserved */
-			c->Request.CDB[13] = 0x00; /* reserved */
-			c->Request.CDB[14] = 0x00; /* reserved */
-			c->Request.CDB[15] = 0x00; /* reserved */
-		break;
 		default:
 			dev_warn(&h->pdev->dev, "unknown message type %d\n",
 				cmd);
@@ -8162,9 +7562,6 @@ static int hpsa_pci_init(struct ctlr_info *h)
 	h->product_name = products[prod_index].product_name;
 	h->access = *(products[prod_index].access);
 
-	h->needs_abort_tags_swizzled =
-		ctlr_needs_abort_tags_swizzled(h->board_id);
-
 	pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S |
 			       PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
 
@@ -8885,7 +8282,6 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	spin_lock_init(&h->scan_lock);
 	spin_lock_init(&h->reset_lock);
 	atomic_set(&h->passthru_cmds_avail, HPSA_MAX_CONCURRENT_PASSTHRUS);
-	atomic_set(&h->abort_cmds_available, HPSA_CMDS_RESERVED_FOR_ABORTS);
 
 	/* Allocate and clear per-cpu variable lockup_detected */
 	h->lockup_detected = alloc_percpu(u32);
@@ -8937,7 +8333,6 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (rc)
 		goto clean5;	/* cmd, irq, shost, pci, lu, aer/h */
 	init_waitqueue_head(&h->scan_wait_queue);
-	init_waitqueue_head(&h->abort_cmd_wait_queue);
 	init_waitqueue_head(&h->event_sync_wait_queue);
 	mutex_init(&h->reset_mutex);
 	h->scan_finished = 1; /* no scan currently in progress */
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index c9c4927..1c49741 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -298,7 +298,6 @@ struct ctlr_info {
 	struct workqueue_struct *resubmit_wq;
 	struct workqueue_struct *rescan_ctlr_wq;
 	atomic_t abort_cmds_available;
-	wait_queue_head_t abort_cmd_wait_queue;
 	wait_queue_head_t event_sync_wait_queue;
 	struct mutex reset_mutex;
 	u8 reset_in_progress;

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH V2 12/12] hpsa: bump driver version
  2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
                   ` (10 preceding siblings ...)
  2017-04-28 18:20 ` [PATCH V2 11/12] hpsa: remove abort handler Don Brace
@ 2017-04-28 18:20 ` Don Brace
  11 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-04-28 18:20 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/hpsa.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index f1d7d1e..3d337bf 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -60,7 +60,7 @@
  * HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.'
  * with an optional trailing '-' followed by a byte value (0-255).
  */
-#define HPSA_DRIVER_VERSION "3.4.18-0"
+#define HPSA_DRIVER_VERSION "3.4.20-0"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
 #define HPSA "hpsa"
 

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH V2 07/12] hpsa: cleanup reset handler
  2017-04-28 18:20 ` [PATCH V2 07/12] hpsa: cleanup reset handler Don Brace
@ 2017-05-04 15:46   ` Tomas Henzl
  2017-05-04 18:29     ` Don Brace
  0 siblings, 1 reply; 15+ messages in thread
From: Tomas Henzl @ 2017-05-04 15:46 UTC (permalink / raw)
  To: Don Brace, joseph.szczypek, gerry.morong, john.hall, jejb,
	Kevin.Barnett, Mahesh.Rajashekhara, bader.alisaleh, hch,
	scott.teel, Viswas.G, Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

On 28.4.2017 20:20, Don Brace wrote:
>  - mark device state sooner.
>
> Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
> Reviewed-by: Scott Teel <scott.teel@microsemi.com>
> Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
> Signed-off-by: Don Brace <don.brace@microsemi.com>
> ---
>  drivers/scsi/hpsa.c |   59 +++++++++++++++++++++++++++++++++++++++------------
>  drivers/scsi/hpsa.h |    1 +
>  2 files changed, 46 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
> index a2852da..71f32e9 100644
> --- a/drivers/scsi/hpsa.c
> +++ b/drivers/scsi/hpsa.c
> @@ -1859,10 +1859,13 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h,
>  	 * A reset can cause a device status to change
>  	 * re-schedule the scan to see what happened.
>  	 */
> +	spin_lock_irqsave(&h->reset_lock, flags);
>  	if (h->reset_in_progress) {
> +		spin_unlock_irqrestore(&h->reset_lock, flags);
>  		h->drv_req_rescan = 1;
>  		return;
>  	}
> +	spin_unlock_irqrestore(&h->reset_lock, flags);
>  
>  	added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL);
>  	removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES, GFP_KERNEL);
> @@ -5618,11 +5621,14 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
>  	/*
>  	 * Do the scan after a reset completion
>  	 */
> +	spin_lock_irqsave(&h->reset_lock, flags);
>  	if (h->reset_in_progress) {
> +		spin_unlock_irqrestore(&h->reset_lock, flags);
>  		h->drv_req_rescan = 1;
>  		hpsa_scan_complete(h);
>  		return;
>  	}
> +	spin_unlock_irqrestore(&h->reset_lock, flags);

Hi Don,
I glad the spinlock helped, but how is the code protected when another thread
enters hpsa_eh_device_reset_handler in parallel when the first thread just 
called the 'spin_unlock_irqrestore(&h->reset_lock' ?

tomash 

 

>  
>  	hpsa_update_scsi_devices(h);
>  
> @@ -5834,28 +5840,38 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h,
>   */
>  static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
>  {
> -	int rc;
> +	int rc = SUCCESS;
>  	struct ctlr_info *h;
>  	struct hpsa_scsi_dev_t *dev;
>  	u8 reset_type;
>  	char msg[48];
> +	unsigned long flags;
>  
>  	/* find the controller to which the command to be aborted was sent */
>  	h = sdev_to_hba(scsicmd->device);
>  	if (h == NULL) /* paranoia */
>  		return FAILED;
>  
> -	if (lockup_detected(h))
> -		return FAILED;
> +	spin_lock_irqsave(&h->reset_lock, flags);
> +	h->reset_in_progress = 1;
> +	spin_unlock_irqrestore(&h->reset_lock, flags);
> +
> +	if (lockup_detected(h)) {
> +		rc = FAILED;
> +		goto return_reset_status;
> +	}
>  
>  	dev = scsicmd->device->hostdata;
>  	if (!dev) {
>  		dev_err(&h->pdev->dev, "%s: device lookup failed\n", __func__);
> -		return FAILED;
> +		rc = FAILED;
> +		goto return_reset_status;
>  	}
>  
> -	if (dev->devtype == TYPE_ENCLOSURE)
> -		return SUCCESS;
> +	if (dev->devtype == TYPE_ENCLOSURE) {
> +		rc = SUCCESS;
> +		goto return_reset_status;
> +	}
>  
>  	/* if controller locked up, we can guarantee command won't complete */
>  	if (lockup_detected(h)) {
> @@ -5863,7 +5879,8 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
>  			 "cmd %d RESET FAILED, lockup detected",
>  			 hpsa_get_cmd_index(scsicmd));
>  		hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
> -		return FAILED;
> +		rc = FAILED;
> +		goto return_reset_status;
>  	}
>  
>  	/* this reset request might be the result of a lockup; check */
> @@ -5872,12 +5889,15 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
>  			 "cmd %d RESET FAILED, new lockup detected",
>  			 hpsa_get_cmd_index(scsicmd));
>  		hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
> -		return FAILED;
> +		rc = FAILED;
> +		goto return_reset_status;
>  	}
>  
>  	/* Do not attempt on controller */
> -	if (is_hba_lunid(dev->scsi3addr))
> -		return SUCCESS;
> +	if (is_hba_lunid(dev->scsi3addr)) {
> +		rc = SUCCESS;
> +		goto return_reset_status;
> +	}
>  
>  	if (is_logical_dev_addr_mode(dev->scsi3addr))
>  		reset_type = HPSA_DEVICE_RESET_MSG;
> @@ -5888,17 +5908,24 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
>  		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
>  	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
>  
> -	h->reset_in_progress = 1;
> -
>  	/* send a reset to the SCSI LUN which the command was sent to */
>  	rc = hpsa_do_reset(h, dev, dev->scsi3addr, reset_type,
>  			   DEFAULT_REPLY_QUEUE);
> +	if (rc == 0)
> +		rc = SUCCESS;
> +	else
> +		rc = FAILED;
> +
>  	sprintf(msg, "reset %s %s",
>  		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ",
> -		rc == 0 ? "completed successfully" : "failed");
> +		rc == SUCCESS ? "completed successfully" : "failed");
>  	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
> +
> +return_reset_status:
> +	spin_lock_irqsave(&h->reset_lock, flags);
>  	h->reset_in_progress = 0;
> -	return rc == 0 ? SUCCESS : FAILED;
> +	spin_unlock_irqrestore(&h->reset_lock, flags);
> +	return rc;
>  }
>  
>  static void swizzle_abort_tag(u8 *tag)
> @@ -8649,10 +8676,13 @@ static void hpsa_rescan_ctlr_worker(struct work_struct *work)
>  	/*
>  	 * Do the scan after the reset
>  	 */
> +	spin_lock_irqsave(&h->reset_lock, flags);
>  	if (h->reset_in_progress) {
> +		spin_unlock_irqrestore(&h->reset_lock, flags);
>  		h->drv_req_rescan = 1;
>  		return;
>  	}
> +	spin_unlock_irqrestore(&h->reset_lock, flags);
>  
>  	if (hpsa_ctlr_needs_rescan(h) || hpsa_offline_devices_ready(h)) {
>  		scsi_host_get(h->scsi_host);
> @@ -8759,6 +8789,7 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>  	spin_lock_init(&h->lock);
>  	spin_lock_init(&h->offline_device_lock);
>  	spin_lock_init(&h->scan_lock);
> +	spin_lock_init(&h->reset_lock);
>  	atomic_set(&h->passthru_cmds_avail, HPSA_MAX_CONCURRENT_PASSTHRUS);
>  	atomic_set(&h->abort_cmds_available, HPSA_CMDS_RESERVED_FOR_ABORTS);
>  
> diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
> index 6f04f2a..5352664 100644
> --- a/drivers/scsi/hpsa.h
> +++ b/drivers/scsi/hpsa.h
> @@ -301,6 +301,7 @@ struct ctlr_info {
>  	struct mutex reset_mutex;
>  	u8 reset_in_progress;
>  	struct hpsa_sas_node *sas_host;
> +	spinlock_t reset_lock;
>  };
>  
>  struct offline_device_entry {
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH V2 07/12] hpsa: cleanup reset handler
  2017-05-04 15:46   ` Tomas Henzl
@ 2017-05-04 18:29     ` Don Brace
  0 siblings, 0 replies; 15+ messages in thread
From: Don Brace @ 2017-05-04 18:29 UTC (permalink / raw)
  To: Tomas Henzl, joseph.szczypek, Gerry Morong, John Hall, jejb,
	Kevin Barnett, Mahesh Rajashekhara, Bader Ali - Saleh, hch,
	Scott Teel, Viswas G, Justin Lindley, Scott Benesh, POSWALD
  Cc: linux-scsi

> -----Original Message-----
> From: Tomas Henzl [mailto:thenzl@redhat.com]
> Sent: Thursday, May 04, 2017 10:47 AM
> To: Don Brace <don.brace@microsemi.com>; joseph.szczypek@hpe.com;
> Gerry Morong <gerry.morong@microsemi.com>; John Hall
> <John.Hall@microsemi.com>; jejb@linux.vnet.ibm.com; Kevin Barnett
> <kevin.barnett@microsemi.com>; Mahesh Rajashekhara
> <mahesh.rajashekhara@microsemi.com>; Bader Ali - Saleh
> <bader.alisaleh@microsemi.com>; hch@infradead.org; Scott Teel
> <scott.teel@microsemi.com>; Viswas G <viswas.g@microsemi.com>; Justin
> Lindley <justin.lindley@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>; POSWALD@suse.com
> Cc: linux-scsi@vger.kernel.org
> Subject: Re: [PATCH V2 07/12] hpsa: cleanup reset handler
> 
> EXTERNAL EMAIL
> 
> 
> On 28.4.2017 20:20, Don Brace wrote:
> >  - mark device state sooner.
> >
> > Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
> > Reviewed-by: Scott Teel <scott.teel@microsemi.com>
> > Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
> > Signed-off-by: Don Brace <don.brace@microsemi.com>
> > ---
> >  drivers/scsi/hpsa.c |   59
> +++++++++++++++++++++++++++++++++++++++------------
> >  drivers/scsi/hpsa.h |    1 +
> >  2 files changed, 46 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
> > index a2852da..71f32e9 100644
> > --- a/drivers/scsi/hpsa.c
> > +++ b/drivers/scsi/hpsa.c
> > @@ -1859,10 +1859,13 @@ static void adjust_hpsa_scsi_table(struct
> ctlr_info *h,
> >        * A reset can cause a device status to change
> >        * re-schedule the scan to see what happened.
> >        */
> > +     spin_lock_irqsave(&h->reset_lock, flags);
> >       if (h->reset_in_progress) {
> > +             spin_unlock_irqrestore(&h->reset_lock, flags);
> >               h->drv_req_rescan = 1;
> >               return;
> >       }
> > +     spin_unlock_irqrestore(&h->reset_lock, flags);
> >
> >       added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL);
> >       removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES,
> GFP_KERNEL);
> > @@ -5618,11 +5621,14 @@ static void hpsa_scan_start(struct Scsi_Host
> *sh)
> >       /*
> >        * Do the scan after a reset completion
> >        */
> > +     spin_lock_irqsave(&h->reset_lock, flags);
> >       if (h->reset_in_progress) {
> > +             spin_unlock_irqrestore(&h->reset_lock, flags);
> >               h->drv_req_rescan = 1;
> >               hpsa_scan_complete(h);
> >               return;
> >       }
> > +     spin_unlock_irqrestore(&h->reset_lock, flags);
> 
> Hi Don,
> I glad the spinlock helped, but how is the code protected when another
> thread
> enters hpsa_eh_device_reset_handler in parallel when the first thread just
> called the 'spin_unlock_irqrestore(&h->reset_lock' ?
> 
> tomash
> 
I am wondering  that too!
I'll correct this and send up a V3.
Thanks for your review Tomas.

Thanks,
Don Brace
ESC - Smart Storage
Microsemi Corporation


> 
> 
> >
> >       hpsa_update_scsi_devices(h);
> >
> > @@ -5834,28 +5840,38 @@ static int
> wait_for_device_to_become_ready(struct ctlr_info *h,
> >   */
> >  static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
> >  {
> > -     int rc;
> > +     int rc = SUCCESS;
> >       struct ctlr_info *h;
> >       struct hpsa_scsi_dev_t *dev;
> >       u8 reset_type;
> >       char msg[48];
> > +     unsigned long flags;
> >
> >       /* find the controller to which the command to be aborted was sent */
> >       h = sdev_to_hba(scsicmd->device);
> >       if (h == NULL) /* paranoia */
> >               return FAILED;
> >
> > -     if (lockup_detected(h))
> > -             return FAILED;
> > +     spin_lock_irqsave(&h->reset_lock, flags);
> > +     h->reset_in_progress = 1;
> > +     spin_unlock_irqrestore(&h->reset_lock, flags);
> > +
> > +     if (lockup_detected(h)) {
> > +             rc = FAILED;
> > +             goto return_reset_status;
> > +     }
> >
> >       dev = scsicmd->device->hostdata;
> >       if (!dev) {
> >               dev_err(&h->pdev->dev, "%s: device lookup failed\n", __func__);
> > -             return FAILED;
> > +             rc = FAILED;
> > +             goto return_reset_status;
> >       }
> >
> > -     if (dev->devtype == TYPE_ENCLOSURE)
> > -             return SUCCESS;
> > +     if (dev->devtype == TYPE_ENCLOSURE) {
> > +             rc = SUCCESS;
> > +             goto return_reset_status;
> > +     }
> >
> >       /* if controller locked up, we can guarantee command won't complete
> */
> >       if (lockup_detected(h)) {
> > @@ -5863,7 +5879,8 @@ static int hpsa_eh_device_reset_handler(struct
> scsi_cmnd *scsicmd)
> >                        "cmd %d RESET FAILED, lockup detected",
> >                        hpsa_get_cmd_index(scsicmd));
> >               hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
> > -             return FAILED;
> > +             rc = FAILED;
> > +             goto return_reset_status;
> >       }
> >
> >       /* this reset request might be the result of a lockup; check */
> > @@ -5872,12 +5889,15 @@ static int hpsa_eh_device_reset_handler(struct
> scsi_cmnd *scsicmd)
> >                        "cmd %d RESET FAILED, new lockup detected",
> >                        hpsa_get_cmd_index(scsicmd));
> >               hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
> > -             return FAILED;
> > +             rc = FAILED;
> > +             goto return_reset_status;
> >       }
> >
> >       /* Do not attempt on controller */
> > -     if (is_hba_lunid(dev->scsi3addr))
> > -             return SUCCESS;
> > +     if (is_hba_lunid(dev->scsi3addr)) {
> > +             rc = SUCCESS;
> > +             goto return_reset_status;
> > +     }
> >
> >       if (is_logical_dev_addr_mode(dev->scsi3addr))
> >               reset_type = HPSA_DEVICE_RESET_MSG;
> > @@ -5888,17 +5908,24 @@ static int hpsa_eh_device_reset_handler(struct
> scsi_cmnd *scsicmd)
> >               reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
> >       hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
> >
> > -     h->reset_in_progress = 1;
> > -
> >       /* send a reset to the SCSI LUN which the command was sent to */
> >       rc = hpsa_do_reset(h, dev, dev->scsi3addr, reset_type,
> >                          DEFAULT_REPLY_QUEUE);
> > +     if (rc == 0)
> > +             rc = SUCCESS;
> > +     else
> > +             rc = FAILED;
> > +
> >       sprintf(msg, "reset %s %s",
> >               reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ",
> > -             rc == 0 ? "completed successfully" : "failed");
> > +             rc == SUCCESS ? "completed successfully" : "failed");
> >       hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
> > +
> > +return_reset_status:
> > +     spin_lock_irqsave(&h->reset_lock, flags);
> >       h->reset_in_progress = 0;
> > -     return rc == 0 ? SUCCESS : FAILED;
> > +     spin_unlock_irqrestore(&h->reset_lock, flags);
> > +     return rc;
> >  }
> >
> >  static void swizzle_abort_tag(u8 *tag)
> > @@ -8649,10 +8676,13 @@ static void hpsa_rescan_ctlr_worker(struct
> work_struct *work)
> >       /*
> >        * Do the scan after the reset
> >        */
> > +     spin_lock_irqsave(&h->reset_lock, flags);
> >       if (h->reset_in_progress) {
> > +             spin_unlock_irqrestore(&h->reset_lock, flags);
> >               h->drv_req_rescan = 1;
> >               return;
> >       }
> > +     spin_unlock_irqrestore(&h->reset_lock, flags);
> >
> >       if (hpsa_ctlr_needs_rescan(h) || hpsa_offline_devices_ready(h)) {
> >               scsi_host_get(h->scsi_host);
> > @@ -8759,6 +8789,7 @@ static int hpsa_init_one(struct pci_dev *pdev,
> const struct pci_device_id *ent)
> >       spin_lock_init(&h->lock);
> >       spin_lock_init(&h->offline_device_lock);
> >       spin_lock_init(&h->scan_lock);
> > +     spin_lock_init(&h->reset_lock);
> >       atomic_set(&h->passthru_cmds_avail,
> HPSA_MAX_CONCURRENT_PASSTHRUS);
> >       atomic_set(&h->abort_cmds_available,
> HPSA_CMDS_RESERVED_FOR_ABORTS);
> >
> > diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
> > index 6f04f2a..5352664 100644
> > --- a/drivers/scsi/hpsa.h
> > +++ b/drivers/scsi/hpsa.h
> > @@ -301,6 +301,7 @@ struct ctlr_info {
> >       struct mutex reset_mutex;
> >       u8 reset_in_progress;
> >       struct hpsa_sas_node *sas_host;
> > +     spinlock_t reset_lock;
> >  };
> >
> >  struct offline_device_entry {
> >


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2017-05-04 18:30 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-28 18:19 [PATCH V2 00/12] hpsa updates Don Brace
2017-04-28 18:19 ` [PATCH V2 01/12] hpsa: update identify physical device structure Don Brace
2017-04-28 18:19 ` [PATCH V2 02/12] hpsa: do not get enclosure info for external devices Don Brace
2017-04-28 18:20 ` [PATCH V2 03/12] hpsa: update reset handler Don Brace
2017-04-28 18:20 ` [PATCH V2 04/12] hpsa: do not reset enclosures Don Brace
2017-04-28 18:20 ` [PATCH V2 05/12] hpsa: rescan later if reset in progress Don Brace
2017-04-28 18:20 ` [PATCH V2 06/12] hpsa: correct resets on retried commands Don Brace
2017-04-28 18:20 ` [PATCH V2 07/12] hpsa: cleanup reset handler Don Brace
2017-05-04 15:46   ` Tomas Henzl
2017-05-04 18:29     ` Don Brace
2017-04-28 18:20 ` [PATCH V2 08/12] hpsa: correct queue depth for externals Don Brace
2017-04-28 18:20 ` [PATCH V2 09/12] hpsa: separate monitor events from rescan worker Don Brace
2017-04-28 18:20 ` [PATCH V2 10/12] hpsa: send ioaccel requests with 0 length down raid path Don Brace
2017-04-28 18:20 ` [PATCH V2 11/12] hpsa: remove abort handler Don Brace
2017-04-28 18:20 ` [PATCH V2 12/12] hpsa: bump driver version Don Brace

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.