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 26/43] hpsa: add support sending aborts to physical devices via the ioaccel2 path
Date: Sat, 21 Feb 2015 16:19:50 -0600 [thread overview]
Message-ID: <20150221221950.21954.42547.stgit@brunhilda> (raw)
In-Reply-To: <20150221221553.21954.32599.stgit@brunhilda>
From: Stephen Cameron <stephenmcameron@gmail.com>
add support for tmf when in ioaccel2 mode
Reviewed-by: Scott Teel <scott.teel@pmcs.com>
Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com>
Signed-off-by: Joe Handzik <joseph.t.handzik@hp.com>
Signed-off-by: Don Brace <don.brace@pmcs.com>
---
drivers/scsi/hpsa.c | 136 +++++++++++++++++++++++++++++++++++++++++++++--
drivers/scsi/hpsa.h | 1
drivers/scsi/hpsa_cmd.h | 6 +-
3 files changed, 135 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index bbbc309..14e5973 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -868,6 +868,28 @@ static void set_ioaccel1_performant_mode(struct ctlr_info *h,
IOACCEL1_BUSADDR_CMDTYPE;
}
+static void set_ioaccel2_tmf_performant_mode(struct ctlr_info *h,
+ struct CommandList *c,
+ int reply_queue)
+{
+ struct hpsa_tmf_struct *cp = (struct hpsa_tmf_struct *)
+ &h->ioaccel2_cmd_pool[c->cmdindex];
+
+ /* Tell the controller to post the reply to the queue for this
+ * processor. This seems to give the best I/O throughput.
+ */
+ if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
+ cp->reply_queue = smp_processor_id() % h->nreply_queues;
+ else
+ cp->reply_queue = reply_queue % h->nreply_queues;
+ /* Set the bits in the address sent down to include:
+ * - performant mode bit not used in ioaccel mode 2
+ * - pull count (bits 0-3)
+ * - command type isn't needed for ioaccel2
+ */
+ c->busaddr |= h->ioaccel2_blockFetchTable[0];
+}
+
static void set_ioaccel2_performant_mode(struct ctlr_info *h,
struct CommandList *c,
int reply_queue)
@@ -934,6 +956,10 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h,
set_ioaccel2_performant_mode(h, c, reply_queue);
writel(c->busaddr, h->vaddr + IOACCEL2_INBOUND_POSTQ_32);
break;
+ case IOACCEL2_TMF:
+ set_ioaccel2_tmf_performant_mode(h, c, reply_queue);
+ writel(c->busaddr, h->vaddr + IOACCEL2_INBOUND_POSTQ_32);
+ break;
default:
set_performant_mode(h, c, reply_queue);
h->access.submit_command(h, c);
@@ -4970,6 +4996,47 @@ static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr,
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 =
+ (struct scsi_cmnd *) command_to_abort->scsi_cmd;
+ struct hpsa_scsi_dev_t *dev = scmd->device->hostdata;
+
+ /*
+ * 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;
+ /* 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.
@@ -5047,17 +5114,72 @@ static int hpsa_send_reset_as_abort_ioaccel2(struct ctlr_info *h,
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->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, NO_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,
unsigned char *scsi3addr, struct CommandList *abort, int reply_queue)
{
- /* ioccelerator mode 2 commands should be aborted via the
+ /*
+ * ioccelerator mode 2 commands should be aborted via the
* accelerated path, since RAID path is unaware of these commands,
- * but underlying firmware can't handle abort TMF.
- * Change abort to physical device reset.
+ * 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)
- return hpsa_send_reset_as_abort_ioaccel2(h, scsi3addr,
+ if (abort->cmd_type == CMD_IOACCEL2) {
+ if (HPSATMF_IOACCEL_ENABLED & h->TMFSupportFlags)
+ return hpsa_send_abort_ioaccel2(h, abort,
+ reply_queue);
+ else
+ return hpsa_send_reset_as_abort_ioaccel2(h, scsi3addr,
abort, reply_queue);
+ }
return hpsa_send_abort(h, scsi3addr, abort, reply_queue);
}
@@ -5941,7 +6063,7 @@ static inline void finish_cmd(struct CommandList *c)
if (likely(c->cmd_type == CMD_IOACCEL1 || c->cmd_type == CMD_SCSI
|| c->cmd_type == CMD_IOACCEL2))
complete_scsi_command(c);
- else if (c->cmd_type == CMD_IOCTL_PEND)
+ else if (c->cmd_type == CMD_IOCTL_PEND || c->cmd_type == IOACCEL2_TMF)
complete(c->waiting);
}
@@ -6730,6 +6852,8 @@ static void hpsa_find_board_params(struct ctlr_info *h)
dev_warn(&h->pdev->dev, "Physical aborts not supported\n");
if (!(HPSATMF_LOG_TASK_ABORT & h->TMFSupportFlags))
dev_warn(&h->pdev->dev, "Logical aborts not supported\n");
+ if (!(HPSATMF_IOACCEL_ENABLED & h->TMFSupportFlags))
+ dev_warn(&h->pdev->dev, "HP SSD Smart Path aborts not supported\n");
}
static inline bool hpsa_CISS_signature_present(struct ctlr_info *h)
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 3acacf6..28b5d79 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -231,6 +231,7 @@ struct ctlr_info {
#define HPSATMF_PHYS_QRY_TASK (1 << 7)
#define HPSATMF_PHYS_QRY_TSET (1 << 8)
#define HPSATMF_PHYS_QRY_ASYNC (1 << 9)
+#define HPSATMF_IOACCEL_ENABLED (1 << 15)
#define HPSATMF_MASK_SUPPORTED (1 << 16)
#define HPSATMF_LOG_LUN_RESET (1 << 17)
#define HPSATMF_LOG_NEX_RESET (1 << 18)
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index cecb62b..3719592 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -396,6 +396,7 @@ struct ErrorInfo {
#define CMD_SCSI 0x03
#define CMD_IOACCEL1 0x04
#define CMD_IOACCEL2 0x05
+#define IOACCEL2_TMF 0x06
#define DIRECT_LOOKUP_SHIFT 4
#define DIRECT_LOOKUP_MASK (~((1 << DIRECT_LOOKUP_SHIFT) - 1))
@@ -590,6 +591,7 @@ struct io_accel2_cmd {
#define IOACCEL2_DIR_NO_DATA 0x00
#define IOACCEL2_DIR_DATA_IN 0x01
#define IOACCEL2_DIR_DATA_OUT 0x02
+#define IOACCEL2_TMF_ABORT 0x01
/*
* SCSI Task Management Request format for Accelerator Mode 2
*/
@@ -598,13 +600,13 @@ struct hpsa_tmf_struct {
u8 reply_queue; /* Reply Queue ID */
u8 tmf; /* Task Management Function */
u8 reserved1; /* byte 3 Reserved */
- u32 it_nexus; /* SCSI I-T Nexus */
+ __le32 it_nexus; /* SCSI I-T Nexus */
u8 lun_id[8]; /* LUN ID for TMF request */
__le64 tag; /* cciss tag associated w/ request */
__le64 abort_tag; /* cciss tag of SCSI cmd or TMF to abort */
__le64 error_ptr; /* Error Pointer */
__le32 error_len; /* Error Length */
-};
+} __aligned(IOACCEL2_COMMANDLIST_ALIGNMENT);
/* Configuration Table Structure */
struct HostWrite {
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 ` Don Brace [this message]
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 ` [PATCH 29/43] hpsa: refactor and rework support for sending TEST_UNIT_READY Don Brace
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=20150221221950.21954.42547.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