From: Don Brace <don.brace@pmcs.com>
To: scott.teel@pmcs.com, Kevin.Barnett@pmcs.com,
james.bottomley@parallels.com, hch@infradead.org,
Justin.Lindley@pmcs.com, brace@pmcs.com
Cc: linux-scsi@vger.kernel.org
Subject: [PATCH 29/43] hpsa: refactor and rework support for sending TEST_UNIT_READY
Date: Sat, 21 Feb 2015 16:20:06 -0600 [thread overview]
Message-ID: <20150221222006.21954.4601.stgit@brunhilda> (raw)
In-Reply-To: <20150221221553.21954.32599.stgit@brunhilda>
From: Webb Scales <webbnh@hp.com>
Factor out the code which sends the TEST_UNIT_READY from
wait_for_device_to_become_ready() into its own function.
Move the code which waits for the TEST_UNIT_READY from
wait_for_device_to_become_ready() into its own function.
If a logical drive has failed, resetting it will ensure
outstanding commands are completed, but polling it with
TURs after the reset will not work because the TURs will
never report good status. So successful TUR should not
be a condition of success for the device reset error
handler.
Reviewed-by: Scott Teel <scott.teel@pmcs.com>
Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com>
Signed-off-by: Webb Scales <webbnh@hp.com>
Signed-off-by: Don Brace <don.brace@pmcs.com>
---
drivers/scsi/hpsa.c | 117 ++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 87 insertions(+), 30 deletions(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 6676517..ae3789b 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4838,51 +4838,108 @@ static int hpsa_register_scsi(struct ctlr_info *h)
return -ENOMEM;
}
-static int wait_for_device_to_become_ready(struct ctlr_info *h,
- unsigned char lunaddr[])
+/*
+ * Send a TEST_UNIT_READY command to the specified LUN using the specified
+ * reply queue; returns zero if the unit is ready, and non-zero otherwise.
+ */
+static int hpsa_send_test_unit_ready(struct ctlr_info *h,
+ struct CommandList *c, unsigned char lunaddr[],
+ int reply_queue)
+{
+ int rc;
+
+ /* Send the Test Unit Ready, fill_cmd can't fail, no mapping */
+ (void) fill_cmd(c, TEST_UNIT_READY, h,
+ NULL, 0, 0, lunaddr, TYPE_CMD);
+ rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
+ if (rc)
+ return rc;
+ /* no unmap needed here because no data xfer. */
+
+ /* Check if the unit is already ready. */
+ if (c->err_info->CommandStatus == CMD_SUCCESS)
+ return 0;
+
+ /*
+ * The first command sent after reset will receive "unit attention" to
+ * indicate that the LUN has been reset...this is actually what we're
+ * looking for (but, success is good too).
+ */
+ if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
+ c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION &&
+ (c->err_info->SenseInfo[2] == NO_SENSE ||
+ c->err_info->SenseInfo[2] == UNIT_ATTENTION))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Wait for a TEST_UNIT_READY command to complete, retrying as necessary;
+ * returns zero when the unit is ready, and non-zero when giving up.
+ */
+static int hpsa_wait_for_test_unit_ready(struct ctlr_info *h,
+ struct CommandList *c,
+ unsigned char lunaddr[], int reply_queue)
{
int rc;
int count = 0;
int waittime = 1; /* seconds */
- struct CommandList *c;
-
- c = cmd_alloc(h);
/* Send test unit ready until device ready, or give up. */
- while (count < HPSA_TUR_RETRY_LIMIT) {
+ for (count = 0; count < HPSA_TUR_RETRY_LIMIT; count++) {
- /* Wait for a bit. do this first, because if we send
+ /*
+ * Wait for a bit. do this first, because if we send
* the TUR right away, the reset will just abort it.
*/
msleep(1000 * waittime);
- count++;
- rc = 0; /* Device ready. */
+
+ rc = hpsa_send_test_unit_ready(h, c, lunaddr, reply_queue);
+ if (!rc)
+ break;
/* Increase wait time with each try, up to a point. */
if (waittime < HPSA_MAX_WAIT_INTERVAL_SECS)
- waittime = waittime * 2;
+ waittime *= 2;
- /* Send the Test Unit Ready, fill_cmd can't fail, no mapping */
- (void) fill_cmd(c, TEST_UNIT_READY, h,
- NULL, 0, 0, lunaddr, TYPE_CMD);
- rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
- NO_TIMEOUT);
- if (rc)
- goto do_it_again;
- /* no unmap needed here because no data xfer. */
+ dev_warn(&h->pdev->dev,
+ "waiting %d secs for device to become ready.\n",
+ waittime);
+ }
- if (c->err_info->CommandStatus == CMD_SUCCESS)
- break;
+ return rc;
+}
- if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
- c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION &&
- (c->err_info->SenseInfo[2] == NO_SENSE ||
- c->err_info->SenseInfo[2] == UNIT_ATTENTION))
+static int wait_for_device_to_become_ready(struct ctlr_info *h,
+ unsigned char lunaddr[],
+ int reply_queue)
+{
+ int first_queue;
+ int last_queue;
+ int rq;
+ int rc = 0;
+ struct CommandList *c;
+
+ c = cmd_alloc(h);
+
+ /*
+ * If no specific reply queue was requested, then send the TUR
+ * repeatedly, requesting a reply on each reply queue; otherwise execute
+ * the loop exactly once using only the specified queue.
+ */
+ if (reply_queue == DEFAULT_REPLY_QUEUE) {
+ first_queue = 0;
+ last_queue = h->nreply_queues - 1;
+ } else {
+ first_queue = reply_queue;
+ last_queue = reply_queue;
+ }
+
+ for (rq = first_queue; rq <= last_queue; rq++) {
+ rc = hpsa_wait_for_test_unit_ready(h, c, lunaddr, rq);
+ if (rc)
break;
-do_it_again:
- dev_warn(&h->pdev->dev, "waiting %d secs "
- "for device to become ready.\n", waittime);
- rc = 1; /* device not ready. */
}
if (rc)
@@ -4951,7 +5008,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
/* send a reset to the SCSI LUN which the command was sent to */
rc = hpsa_send_reset(h, dev->scsi3addr, HPSA_RESET_TYPE_LUN,
DEFAULT_REPLY_QUEUE);
- if (rc == 0 && wait_for_device_to_become_ready(h, dev->scsi3addr) == 0)
+ if (rc == 0)
return SUCCESS;
dev_warn(&h->pdev->dev,
@@ -5146,7 +5203,7 @@ static int hpsa_send_reset_as_abort_ioaccel2(struct ctlr_info *h,
}
/* wait for device to recover */
- if (wait_for_device_to_become_ready(h, psa) != 0) {
+ 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%02x%02x%02x%02x%02x%02x%02x%02x\n",
psa[0], psa[1], psa[2], psa[3],
next prev parent reply other threads:[~2015-02-21 22:21 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-21 22:17 [PATCH 00/43] hpsa updates Don Brace
2015-02-21 22:17 ` [PATCH 01/43] hpsa: add masked physical devices into h->dev[] array Don Brace
2015-02-23 20:14 ` Christoph Hellwig
2015-02-26 15:17 ` brace
2015-03-05 13:34 ` Christoph Hellwig
2015-02-21 22:17 ` [PATCH 02/43] hpsa: clean up host, channel, target, lun prints Don Brace
2015-02-23 20:16 ` Christoph Hellwig
2015-02-26 14:50 ` brace
2015-02-21 22:17 ` [PATCH 03/43] hpsa: rework controller command submission Don Brace
2015-02-21 22:17 ` [PATCH 04/43] hpsa: clean up aborts Don Brace
2015-02-21 22:17 ` [PATCH 05/43] hpsa: decrement h->commands_outstanding in fail_all_outstanding_cmds Don Brace
2015-02-21 22:18 ` [PATCH 06/43] hpsa: hpsa decode sense data for io and tmf Don Brace
2015-02-23 20:18 ` Christoph Hellwig
2015-02-25 18:06 ` brace
2015-02-21 22:18 ` [PATCH 07/43] hpsa: allow lockup detected to be viewed via sysfs Don Brace
2015-02-21 22:18 ` [PATCH 08/43] hpsa: make function names consistent Don Brace
2015-02-21 22:18 ` [PATCH 09/43] hpsa: factor out hpsa_init_cmd function Don Brace
2015-02-21 22:18 ` [PATCH 10/43] hpsa: do not ignore return value of hpsa_register_scsi Don Brace
2015-02-23 20:18 ` Christoph Hellwig
2015-02-21 22:18 ` [PATCH 11/43] hpsa: try resubmitting down raid path on task set full Don Brace
2015-02-21 22:18 ` [PATCH 12/43] hpsa: factor out hpsa_ioaccel_submit function Don Brace
2015-02-21 22:18 ` [PATCH 13/43] hpsa: print accurate SSD Smart Path Enabled status Don Brace
2015-02-21 22:18 ` [PATCH 14/43] hpsa: use ioaccel2 path to submit IOs to physical drives in HBA mode Don Brace
2015-02-21 22:18 ` [PATCH 15/43] hpsa: Get queue depth from identify physical bmic for physical disks Don Brace
2015-02-21 22:18 ` [PATCH 16/43] hpsa: break hpsa_free_irqs_and_disable_msix into two functions Don Brace
2015-02-21 22:19 ` [PATCH 17/43] hpsa: clean up error handling Don Brace
2015-02-21 22:19 ` [PATCH 18/43] hpsa: refactor freeing of resources into more logical functions Don Brace
2015-02-21 22:19 ` [PATCH 19/43] hpsa: add ioaccel sg chaining for the ioaccel2 path Don Brace
2015-02-21 22:19 ` [PATCH 20/43] hpsa: add more ioaccel2 error handling, including underrun statuses Don Brace
2015-02-21 22:19 ` [PATCH 21/43] hpsa: do not check cmd_alloc return value - it cannnot return NULL Don Brace
2015-02-21 22:19 ` [PATCH 22/43] hpsa: correct return values from driver functions Don Brace
2015-02-21 22:19 ` [PATCH 23/43] hpsa: clean up driver init Don Brace
2015-02-21 22:19 ` [PATCH 24/43] hpsa: clean up some error reporting output in abort handler Don Brace
2015-02-21 22:19 ` [PATCH 25/43] hpsa: do not print ioaccel2 warning messages about unusual completions Don Brace
2015-02-21 22:19 ` [PATCH 26/43] hpsa: add support sending aborts to physical devices via the ioaccel2 path Don Brace
2015-02-21 22:19 ` [PATCH 27/43] hpsa: use helper routines for finishing commands Don Brace
2015-02-21 22:20 ` [PATCH 28/43] hpsa: don't return abort request until target is complete Don Brace
2015-02-21 22:20 ` Don Brace [this message]
2015-02-21 22:20 ` [PATCH 30/43] hpsa: performance tweak for hpsa_scatter_gather() Don Brace
2015-02-21 22:20 ` [PATCH 31/43] hpsa: call pci_release_regions after pci_disable_device Don Brace
2015-02-21 22:20 ` [PATCH 32/43] hpsa: skip free_irq calls if irqs are not allocated Don Brace
2015-02-21 22:20 ` [PATCH 33/43] hpsa: cleanup for init_one step 2 in kdump Don Brace
2015-02-21 22:20 ` [PATCH 34/43] hpsa: fix try_soft_reset error handling Don Brace
2015-02-21 22:20 ` [PATCH 35/43] hpsa: create workqueue after the driver is ready for use Don Brace
2015-02-21 22:20 ` [PATCH 36/43] hpsa: add interrupt number to /proc/interrupts interrupt name Don Brace
2015-02-21 22:20 ` [PATCH 37/43] hpsa: use block layer tag for command allocation Don Brace
2015-02-23 20:25 ` Christoph Hellwig
2015-02-24 20:51 ` brace
2015-02-21 22:20 ` [PATCH 38/43] hpsa: clean up new block layer tag error handling Don Brace
2015-02-23 20:25 ` Christoph Hellwig
2015-02-24 17:39 ` brace
2015-02-21 22:21 ` [PATCH 39/43] hpsa: use scsi host_no as hpsa controller number Don Brace
2015-02-21 22:21 ` [PATCH 40/43] hpsa: cleanup initialization code Don Brace
2015-02-23 20:26 ` Christoph Hellwig
2015-02-24 21:29 ` brace
2015-02-21 22:21 ` [PATCH 41/43] hpsa: propagate the error code in hpsa_kdump_soft_reset Don Brace
2015-02-21 22:21 ` [PATCH 42/43] hpsa: cleanup reset Don Brace
2015-02-21 22:21 ` [PATCH 43/43] hpsa: change driver version Don Brace
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150221222006.21954.4601.stgit@brunhilda \
--to=don.brace@pmcs.com \
--cc=Justin.Lindley@pmcs.com \
--cc=Kevin.Barnett@pmcs.com \
--cc=brace@pmcs.com \
--cc=hch@infradead.org \
--cc=james.bottomley@parallels.com \
--cc=linux-scsi@vger.kernel.org \
--cc=scott.teel@pmcs.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox