linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] hisi_sas internal abort support
@ 2016-08-10 13:19 John Garry
  2016-08-10 13:19 ` [PATCH 1/8] hisi_sas: add internal abort core code John Garry
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: John Garry @ 2016-08-10 13:19 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, John Garry

This patchset introduces support for the internal abort
feature for the HiSilicon SAS controller.

The internal abort feature allows commands which are active
in the controller to be aborted before being sent to the
slave device.

Only support will be added for v2 HW since v1 HW has issues
in supporting internal abort feature.

John Garry (8):
  hisi_sas: add internal abort core code
  hisi_sas: for internal abort in hisi_sas_dev_gone()
  hisi_sas: add internal abort to hisi_sas_abort_task()
  hisi_sas: add prep_abort_v2_hw()
  hisi_sas: add v2 hw slot complete internal abort support
  hisi_sas: fail tmf task prep when port detached
  hisi_sas: add TMF success check
  hisi_sas: update version to 1.6

 drivers/scsi/hisi_sas/hisi_sas.h       |   5 +-
 drivers/scsi/hisi_sas/hisi_sas_main.c  | 179 +++++++++++++++++++++++++++++++--
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c |  64 ++++++++++++
 3 files changed, 241 insertions(+), 7 deletions(-)

-- 
1.9.1

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

* [PATCH 1/8] hisi_sas: add internal abort core code
  2016-08-10 13:19 [PATCH 0/8] hisi_sas internal abort support John Garry
@ 2016-08-10 13:19 ` John Garry
  2016-08-21  0:44   ` zhangfei
  2016-08-10 13:19 ` [PATCH 2/8] hisi_sas: for internal abort in hisi_sas_dev_gone() John Garry
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 11+ messages in thread
From: John Garry @ 2016-08-10 13:19 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, John Garry

Add core code for internal abort functionality.

The internal abort features allows the host controller
to abort commands which are still active in the
controller but have not yet been sent to the slave
device.

Typically a command only spends a relatively
short time in the controller when compared to the
amount of the time after it is sent to the slave
device.
Two modes of internal abort are supported:
- device
- individual command

For device, when the internal abort is issued all
commands in the host for that device are aborted.
For a single command, only that command is aborted
if it is still in the host.

In HW the internal abort command is executed
similar to any other sort of command, like SSP.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas.h      |   3 +
 drivers/scsi/hisi_sas/hisi_sas_main.c | 154 ++++++++++++++++++++++++++++++++++
 2 files changed, 157 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 4731d32..4ae864d 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -146,6 +146,9 @@ struct hisi_sas_hw {
 			struct hisi_sas_slot *slot);
 	int (*prep_stp)(struct hisi_hba *hisi_hba,
 			struct hisi_sas_slot *slot);
+	int (*prep_abort)(struct hisi_hba *hisi_hba,
+			  struct hisi_sas_slot *slot,
+			  int device_id, int abort_flag, int tag_to_abort);
 	int (*slot_complete)(struct hisi_hba *hisi_hba,
 			     struct hisi_sas_slot *slot, int abort);
 	void (*phy_enable)(struct hisi_hba *hisi_hba, int phy_no);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 18dd5ea..d30ece2 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -17,6 +17,10 @@
 
 static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device,
 				u8 *lun, struct hisi_sas_tmf_task *tmf);
+static int
+hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
+			     struct domain_device *device,
+			     int abort_flag, int tag);
 
 static struct hisi_hba *dev_to_hisi_hba(struct domain_device *device)
 {
@@ -116,6 +120,14 @@ static int hisi_sas_task_prep_ata(struct hisi_hba *hisi_hba,
 	return hisi_hba->hw->prep_stp(hisi_hba, slot);
 }
 
+static int hisi_sas_task_prep_abort(struct hisi_hba *hisi_hba,
+		struct hisi_sas_slot *slot,
+		int device_id, int abort_flag, int tag_to_abort)
+{
+	return hisi_hba->hw->prep_abort(hisi_hba, slot,
+			device_id, abort_flag, tag_to_abort);
+}
+
 /*
  * This function will issue an abort TMF regardless of whether the
  * task is in the sdev or not. Then it will do the task complete
@@ -954,6 +966,148 @@ static int hisi_sas_query_task(struct sas_task *task)
 	return rc;
 }
 
+static int
+hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, u64 device_id,
+				  struct sas_task *task, int abort_flag,
+				  int task_tag)
+{
+	struct domain_device *device = task->dev;
+	struct hisi_sas_device *sas_dev = device->lldd_dev;
+	struct device *dev = &hisi_hba->pdev->dev;
+	struct hisi_sas_port *port;
+	struct hisi_sas_slot *slot;
+	struct hisi_sas_cmd_hdr *cmd_hdr_base;
+	int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx;
+
+	if (!device->port)
+		return -1;
+
+	port = device->port->lldd_port;
+
+	/* simply get a slot and send abort command */
+	rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
+	if (rc)
+		goto err_out;
+	rc = hisi_hba->hw->get_free_slot(hisi_hba, &dlvry_queue,
+					 &dlvry_queue_slot);
+	if (rc)
+		goto err_out_tag;
+
+	slot = &hisi_hba->slot_info[slot_idx];
+	memset(slot, 0, sizeof(struct hisi_sas_slot));
+
+	slot->idx = slot_idx;
+	slot->n_elem = n_elem;
+	slot->dlvry_queue = dlvry_queue;
+	slot->dlvry_queue_slot = dlvry_queue_slot;
+	cmd_hdr_base = hisi_hba->cmd_hdr[dlvry_queue];
+	slot->cmd_hdr = &cmd_hdr_base[dlvry_queue_slot];
+	slot->task = task;
+	slot->port = port;
+	task->lldd_task = slot;
+
+	memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr));
+
+	rc = hisi_sas_task_prep_abort(hisi_hba, slot, device_id,
+				      abort_flag, task_tag);
+	if (rc)
+		goto err_out_tag;
+
+	/* Port structure is static for the HBA, so
+	*  even if the port is deformed it is ok
+	*  to reference.
+	*/
+	list_add_tail(&slot->entry, &port->list);
+	spin_lock(&task->task_state_lock);
+	task->task_state_flags |= SAS_TASK_AT_INITIATOR;
+	spin_unlock(&task->task_state_lock);
+
+	hisi_hba->slot_prep = slot;
+
+	sas_dev->running_req++;
+	/* send abort command to our chip */
+	hisi_hba->hw->start_delivery(hisi_hba);
+
+	return 0;
+
+err_out_tag:
+	hisi_sas_slot_index_free(hisi_hba, slot_idx);
+err_out:
+	dev_err(dev, "internal abort task prep: failed[%d]!\n", rc);
+
+	return rc;
+}
+
+static int
+hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
+			     struct domain_device *device,
+			     int abort_flag, int tag)
+{
+	struct sas_task *task;
+	struct hisi_sas_device *sas_dev = device->lldd_dev;
+	struct device *dev = &hisi_hba->pdev->dev;
+	int res;
+	unsigned long flags;
+
+	if (!hisi_hba->hw->prep_abort)
+		return -EOPNOTSUPP;
+
+	task = sas_alloc_slow_task(GFP_KERNEL);
+	if (!task)
+		return -ENOMEM;
+
+	task->dev = device;
+	task->task_proto = device->tproto;
+	task->task_done = hisi_sas_task_done;
+	task->slow_task->timer.data = (unsigned long)task;
+	task->slow_task->timer.function = hisi_sas_tmf_timedout;
+	task->slow_task->timer.expires = jiffies + 20*HZ;
+	add_timer(&task->slow_task->timer);
+
+	/* Lock as we are alloc'ing a slot, which cannot be interrupted */
+	spin_lock_irqsave(&hisi_hba->lock, flags);
+	res = hisi_sas_internal_abort_task_exec(hisi_hba, sas_dev->device_id,
+						task, abort_flag, tag);
+	spin_unlock_irqrestore(&hisi_hba->lock, flags);
+	if (res) {
+		del_timer(&task->slow_task->timer);
+		dev_err(dev, "internal task abort: executing internal task failed: %d\n",
+			res);
+		goto exit;
+	}
+	wait_for_completion(&task->slow_task->completion);
+	res = TMF_RESP_FUNC_FAILED;
+
+	if (task->task_status.resp == SAS_TASK_COMPLETE &&
+		task->task_status.stat == TMF_RESP_FUNC_COMPLETE) {
+		res = TMF_RESP_FUNC_COMPLETE;
+		goto exit;
+	}
+
+	/* TMF timed out, return direct. */
+	if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
+		if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
+			dev_err(dev, "internal task abort: timeout.\n");
+			if (task->lldd_task) {
+				struct hisi_sas_slot *slot = task->lldd_task;
+
+				hisi_sas_slot_task_free(hisi_hba, task, slot);
+			}
+		}
+	}
+
+exit:
+	dev_info(dev, "internal task abort: task to dev %016llx task=%p "
+		"resp: 0x%x sts 0x%x\n",
+		SAS_ADDR(device->sas_addr),
+		task,
+		task->task_status.resp, /* 0 is complete, -1 is undelivered */
+		task->task_status.stat);
+	sas_free_task(task);
+
+	return res;
+}
+
 static void hisi_sas_port_formed(struct asd_sas_phy *sas_phy)
 {
 	hisi_sas_port_notify_formed(sas_phy);
-- 
1.9.1

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

* [PATCH 2/8] hisi_sas: for internal abort in hisi_sas_dev_gone()
  2016-08-10 13:19 [PATCH 0/8] hisi_sas internal abort support John Garry
  2016-08-10 13:19 ` [PATCH 1/8] hisi_sas: add internal abort core code John Garry
@ 2016-08-10 13:19 ` John Garry
  2016-08-10 13:20 ` [PATCH 3/8] hisi_sas: add internal abort to hisi_sas_abort_task() John Garry
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2016-08-10 13:19 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, John Garry

Execute an internal abort for that device when it is removed,
so that commands for that device are not processed.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index d30ece2..9540953 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -621,6 +621,8 @@ static void hisi_sas_dev_gone(struct domain_device *device)
 	dev_info(dev, "found dev[%lld:%x] is gone\n",
 		 sas_dev->device_id, sas_dev->dev_type);
 
+	hisi_sas_internal_task_abort(hisi_hba, device, 1, 0);
+
 	hisi_hba->hw->free_device(hisi_hba, sas_dev);
 	device->lldd_dev = NULL;
 	memset(sas_dev, 0, sizeof(*sas_dev));
-- 
1.9.1

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

* [PATCH 3/8] hisi_sas: add internal abort to hisi_sas_abort_task()
  2016-08-10 13:19 [PATCH 0/8] hisi_sas internal abort support John Garry
  2016-08-10 13:19 ` [PATCH 1/8] hisi_sas: add internal abort core code John Garry
  2016-08-10 13:19 ` [PATCH 2/8] hisi_sas: for internal abort in hisi_sas_dev_gone() John Garry
@ 2016-08-10 13:20 ` John Garry
  2016-08-10 13:20 ` [PATCH 4/8] hisi_sas: add prep_abort_v2_hw() John Garry
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2016-08-10 13:20 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, John Garry

Execute an internal abort for executing an internal
task abort. This is for case of command still being
present in host when abort is executed.

For a SATA internal abort, we set abort for all tasks
associated with the device.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_main.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 9540953..6c82e07 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -840,18 +840,23 @@ static int hisi_sas_abort_task(struct sas_task *task)
 			}
 		}
 
+		hisi_sas_internal_task_abort(hisi_hba, device, 0, tag);
 	} else if (task->task_proto & SAS_PROTOCOL_SATA ||
 		task->task_proto & SAS_PROTOCOL_STP) {
 		if (task->dev->dev_type == SAS_SATA_DEV) {
-			struct hisi_slot_info *slot = task->lldd_task;
+			struct hisi_sas_slot *slot = task->lldd_task;
+			u32 tag = slot->idx;
 
-			dev_notice(dev, "abort task: hba=%p task=%p slot=%p\n",
-				   hisi_hba, task, slot);
-			task->task_state_flags |= SAS_TASK_STATE_ABORTED;
+			hisi_sas_internal_task_abort(hisi_hba, device,
+						     1, tag);
 			rc = TMF_RESP_FUNC_COMPLETE;
-			goto out;
 		}
+	} else if (task->task_proto & SAS_PROTOCOL_SMP) {
+		/* SMP */
+		struct hisi_sas_slot *slot = task->lldd_task;
+		u32 tag = slot->idx;
 
+		hisi_sas_internal_task_abort(hisi_hba, device, 0, tag);
 	}
 
 out:
-- 
1.9.1

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

* [PATCH 4/8] hisi_sas: add prep_abort_v2_hw()
  2016-08-10 13:19 [PATCH 0/8] hisi_sas internal abort support John Garry
                   ` (2 preceding siblings ...)
  2016-08-10 13:20 ` [PATCH 3/8] hisi_sas: add internal abort to hisi_sas_abort_task() John Garry
@ 2016-08-10 13:20 ` John Garry
  2016-08-10 13:20 ` [PATCH 5/8] hisi_sas: add v2 hw slot complete internal abort support John Garry
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2016-08-10 13:20 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, John Garry

Add function to prepare the an internal abort
for v2 hw.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index f965604..fec1675 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -174,6 +174,10 @@
 /* HW dma structures */
 /* Delivery queue header */
 /* dw0 */
+#define CMD_HDR_ABORT_FLAG_OFF		0
+#define CMD_HDR_ABORT_FLAG_MSK		(0x3 << CMD_HDR_ABORT_FLAG_OFF)
+#define CMD_HDR_ABORT_DEVICE_TYPE_OFF	2
+#define CMD_HDR_ABORT_DEVICE_TYPE_MSK	(0x1 << CMD_HDR_ABORT_DEVICE_TYPE_OFF)
 #define CMD_HDR_RESP_REPORT_OFF		5
 #define CMD_HDR_RESP_REPORT_MSK		(0x1 << CMD_HDR_RESP_REPORT_OFF)
 #define CMD_HDR_TLR_CTRL_OFF		6
@@ -214,6 +218,8 @@
 #define CMD_HDR_DIF_SGL_LEN_MSK		(0xffff << CMD_HDR_DIF_SGL_LEN_OFF)
 #define CMD_HDR_DATA_SGL_LEN_OFF	16
 #define CMD_HDR_DATA_SGL_LEN_MSK	(0xffff << CMD_HDR_DATA_SGL_LEN_OFF)
+#define CMD_HDR_ABORT_IPTT_OFF		16
+#define CMD_HDR_ABORT_IPTT_MSK		(0xffff << CMD_HDR_ABORT_IPTT_OFF)
 
 /* Completion header */
 /* dw0 */
@@ -1775,6 +1781,32 @@ static int prep_ata_v2_hw(struct hisi_hba *hisi_hba,
 	return 0;
 }
 
+static int prep_abort_v2_hw(struct hisi_hba *hisi_hba,
+		struct hisi_sas_slot *slot,
+		int device_id, int abort_flag, int tag_to_abort)
+{
+	struct sas_task *task = slot->task;
+	struct domain_device *dev = task->dev;
+	struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+	struct hisi_sas_port *port = slot->port;
+
+	/* dw0 */
+	hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/
+			       (port->id << CMD_HDR_PORT_OFF) |
+			       ((dev_is_sata(dev) ? 1:0) <<
+				CMD_HDR_ABORT_DEVICE_TYPE_OFF) |
+			       (abort_flag << CMD_HDR_ABORT_FLAG_OFF));
+
+	/* dw1 */
+	hdr->dw1 = cpu_to_le32(device_id << CMD_HDR_DEV_ID_OFF);
+
+	/* dw7 */
+	hdr->dw7 = cpu_to_le32(tag_to_abort << CMD_HDR_ABORT_IPTT_OFF);
+	hdr->transfer_tags = cpu_to_le32(slot->idx);
+
+	return 0;
+}
+
 static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
 {
 	int i, res = 0;
@@ -2239,6 +2271,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
 	.prep_smp = prep_smp_v2_hw,
 	.prep_ssp = prep_ssp_v2_hw,
 	.prep_stp = prep_ata_v2_hw,
+	.prep_abort = prep_abort_v2_hw,
 	.get_free_slot = get_free_slot_v2_hw,
 	.start_delivery = start_delivery_v2_hw,
 	.slot_complete = slot_complete_v2_hw,
-- 
1.9.1

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

* [PATCH 5/8] hisi_sas: add v2 hw slot complete internal abort support
  2016-08-10 13:19 [PATCH 0/8] hisi_sas internal abort support John Garry
                   ` (3 preceding siblings ...)
  2016-08-10 13:20 ` [PATCH 4/8] hisi_sas: add prep_abort_v2_hw() John Garry
@ 2016-08-10 13:20 ` John Garry
  2016-08-10 13:20 ` [PATCH 6/8] hisi_sas: fail tmf task prep when port detached John Garry
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2016-08-10 13:20 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, John Garry

Add code in slot_complete_v2_hw() to deal with the
slots which have completed due to internal abort.

The status codes have the following meaning:
- STAT_IO_ABORTED: the IO has been aborted due to
internal abort, whether by device or individual
abort command
- STAT_IO_COMPLETE: internal abort command has
completed successfully for device or individual
abort command
- STAT_IO_NO_DEVICE: internal abort command has
completed for device but cannot find any IO
- STAT_IO_NOT_VALID: internal abort command has
completed for single command but could not
find the command

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index fec1675..bf9b693 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -227,6 +227,13 @@
 #define CMPLT_HDR_RSPNS_XFRD_MSK	(0x1 << CMPLT_HDR_RSPNS_XFRD_OFF)
 #define CMPLT_HDR_ERX_OFF		12
 #define CMPLT_HDR_ERX_MSK		(0x1 << CMPLT_HDR_ERX_OFF)
+#define CMPLT_HDR_ABORT_STAT_OFF	13
+#define CMPLT_HDR_ABORT_STAT_MSK	(0x7 << CMPLT_HDR_ABORT_STAT_OFF)
+/* abort_stat */
+#define STAT_IO_NOT_VALID		0x1
+#define STAT_IO_NO_DEVICE		0x2
+#define STAT_IO_COMPLETE		0x3
+#define STAT_IO_ABORTED			0x4
 /* dw1 */
 #define CMPLT_HDR_IPTT_OFF		0
 #define CMPLT_HDR_IPTT_MSK		(0xffff << CMPLT_HDR_IPTT_OFF)
@@ -1569,6 +1576,30 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot,
 		goto out;
 	}
 
+	/* Use SAS+TMF status codes */
+	switch ((complete_hdr->dw0 & CMPLT_HDR_ABORT_STAT_MSK)
+			>> CMPLT_HDR_ABORT_STAT_OFF) {
+	case STAT_IO_ABORTED:
+		/* this io has been aborted by abort command */
+		ts->stat = SAS_ABORTED_TASK;
+		goto out;
+	case STAT_IO_COMPLETE:
+		/* internal abort command complete */
+		ts->stat = TMF_RESP_FUNC_COMPLETE;
+		goto out;
+	case STAT_IO_NO_DEVICE:
+		ts->stat = TMF_RESP_FUNC_COMPLETE;
+		goto out;
+	case STAT_IO_NOT_VALID:
+		/* abort single io, controller don't find
+		 * the io need to abort
+		 */
+		ts->stat = TMF_RESP_FUNC_FAILED;
+		goto out;
+	default:
+		break;
+	}
+
 	if ((complete_hdr->dw0 & CMPLT_HDR_ERX_MSK) &&
 		(!(complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))) {
 
-- 
1.9.1

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

* [PATCH 6/8] hisi_sas: fail tmf task prep when port detached
  2016-08-10 13:19 [PATCH 0/8] hisi_sas internal abort support John Garry
                   ` (4 preceding siblings ...)
  2016-08-10 13:20 ` [PATCH 5/8] hisi_sas: add v2 hw slot complete internal abort support John Garry
@ 2016-08-10 13:20 ` John Garry
  2016-08-10 13:20 ` [PATCH 7/8] hisi_sas: add TMF success check John Garry
  2016-08-10 13:20 ` [PATCH 8/8] hisi_sas: update version to 1.6 John Garry
  7 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2016-08-10 13:20 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, John Garry

When the port is detached we cannot execute a TMF,
as there can be no device attached to the port.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 6c82e07..af92b137 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -204,7 +204,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba,
 		return rc;
 	}
 	port = device->port->lldd_port;
-	if (port && !port->port_attached && !tmf) {
+	if (port && !port->port_attached) {
 		if (sas_protocol_ata(task->task_proto)) {
 			struct task_status_struct *ts = &task->task_status;
 
-- 
1.9.1

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

* [PATCH 7/8] hisi_sas: add TMF success check
  2016-08-10 13:19 [PATCH 0/8] hisi_sas internal abort support John Garry
                   ` (5 preceding siblings ...)
  2016-08-10 13:20 ` [PATCH 6/8] hisi_sas: fail tmf task prep when port detached John Garry
@ 2016-08-10 13:20 ` John Garry
  2016-08-10 13:20 ` [PATCH 8/8] hisi_sas: update version to 1.6 John Garry
  7 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2016-08-10 13:20 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, John Garry

When a tmf is issued, various response codes can be
returned from the target. For a query tmf the
response may be TMF_RESP_FUNC_COMPLETE or
TMF_RESP_FUNC_SUCC.
Add a condition for TMF_RESP_FUNC_SUCC to
hisi_sas_exec_internal_tmf_task().
This affects query tmf, as the result is success
the returned value was for failure.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index af92b137..3ba8dc7 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -743,6 +743,12 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device,
 		}
 
 		if (task->task_status.resp == SAS_TASK_COMPLETE &&
+			task->task_status.stat == TMF_RESP_FUNC_SUCC) {
+			res = TMF_RESP_FUNC_SUCC;
+			break;
+		}
+
+		if (task->task_status.resp == SAS_TASK_COMPLETE &&
 		      task->task_status.stat == SAS_DATA_UNDERRUN) {
 			/* no error, but return the number of bytes of
 			 * underrun
-- 
1.9.1

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

* [PATCH 8/8] hisi_sas: update version to 1.6
  2016-08-10 13:19 [PATCH 0/8] hisi_sas internal abort support John Garry
                   ` (6 preceding siblings ...)
  2016-08-10 13:20 ` [PATCH 7/8] hisi_sas: add TMF success check John Garry
@ 2016-08-10 13:20 ` John Garry
  7 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2016-08-10 13:20 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, John Garry

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 4ae864d..fc51e87 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -23,7 +23,7 @@
 #include <scsi/sas_ata.h>
 #include <scsi/libsas.h>
 
-#define DRV_VERSION "v1.5"
+#define DRV_VERSION "v1.6"
 
 #define HISI_SAS_MAX_PHYS	9
 #define HISI_SAS_MAX_QUEUES	32
-- 
1.9.1

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

* Re: [PATCH 1/8] hisi_sas: add internal abort core code
  2016-08-10 13:19 ` [PATCH 1/8] hisi_sas: add internal abort core code John Garry
@ 2016-08-21  0:44   ` zhangfei
  2016-08-22  7:50     ` John Garry
  0 siblings, 1 reply; 11+ messages in thread
From: zhangfei @ 2016-08-21  0:44 UTC (permalink / raw)
  To: John Garry, jejb, martin.petersen
  Cc: linuxarm, xuwei5, john.garry2, linux-scsi, linux-kernel



On 2016年08月10日 21:19, John Garry wrote:
> Add core code for internal abort functionality.
>
> The internal abort features allows the host controller
> to abort commands which are still active in the
> controller but have not yet been sent to the slave
> device.
>
> Typically a command only spends a relatively
> short time in the controller when compared to the
> amount of the time after it is sent to the slave
> device.
> Two modes of internal abort are supported:
> - device
> - individual command
>
> For device, when the internal abort is issued all
> commands in the host for that device are aborted.
> For a single command, only that command is aborted
> if it is still in the host.
>
> In HW the internal abort command is executed
> similar to any other sort of command, like SSP.
>
> Signed-off-by: John Garry <john.garry@huawei.com>
> ---
>   drivers/scsi/hisi_sas/hisi_sas.h      |   3 +
>   drivers/scsi/hisi_sas/hisi_sas_main.c | 154 ++++++++++++++++++++++++++++++++++
>   2 files changed, 157 insertions(+)
>
> diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
> index 4731d32..4ae864d 100644
> --- a/drivers/scsi/hisi_sas/hisi_sas.h
> +++ b/drivers/scsi/hisi_sas/hisi_sas.h
> @@ -146,6 +146,9 @@ struct hisi_sas_hw {
>   			struct hisi_sas_slot *slot);
>   	int (*prep_stp)(struct hisi_hba *hisi_hba,
>   			struct hisi_sas_slot *slot);
> +	int (*prep_abort)(struct hisi_hba *hisi_hba,
> +			  struct hisi_sas_slot *slot,
> +			  int device_id, int abort_flag, int tag_to_abort);

How about add comments to abort_flag and tag_to_abort.
As a result, not sure why differently calling in hisi_sas_abort_task
hisi_sas_internal_task_abort(hisi_hba, device, 1, tag);
hisi_sas_internal_task_abort(hisi_hba, device, 0, tag);

Thanks

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

* Re: [PATCH 1/8] hisi_sas: add internal abort core code
  2016-08-21  0:44   ` zhangfei
@ 2016-08-22  7:50     ` John Garry
  0 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2016-08-22  7:50 UTC (permalink / raw)
  To: zhangfei, jejb, martin.petersen
  Cc: linuxarm, xuwei5, john.garry2, linux-scsi, linux-kernel

On 21/08/2016 01:44, zhangfei wrote:
>
>
> On 2016年08月10日 21:19, John Garry wrote:
>> Add core code for internal abort functionality.
>>
>> The internal abort features allows the host controller
>> to abort commands which are still active in the
>> controller but have not yet been sent to the slave
>> device.
>>
>> Typically a command only spends a relatively
>> short time in the controller when compared to the
>> amount of the time after it is sent to the slave
>> device.
>> Two modes of internal abort are supported:
>> - device
>> - individual command
>>
>> For device, when the internal abort is issued all
>> commands in the host for that device are aborted.
>> For a single command, only that command is aborted
>> if it is still in the host.
>>
>> In HW the internal abort command is executed
>> similar to any other sort of command, like SSP.
>>
>> Signed-off-by: John Garry <john.garry@huawei.com>
>> ---
>>   drivers/scsi/hisi_sas/hisi_sas.h      |   3 +
>>   drivers/scsi/hisi_sas/hisi_sas_main.c | 154
>> ++++++++++++++++++++++++++++++++++
>>   2 files changed, 157 insertions(+)
>>
>> diff --git a/drivers/scsi/hisi_sas/hisi_sas.h
>> b/drivers/scsi/hisi_sas/hisi_sas.h
>> index 4731d32..4ae864d 100644
>> --- a/drivers/scsi/hisi_sas/hisi_sas.h
>> +++ b/drivers/scsi/hisi_sas/hisi_sas.h
>> @@ -146,6 +146,9 @@ struct hisi_sas_hw {
>>               struct hisi_sas_slot *slot);
>>       int (*prep_stp)(struct hisi_hba *hisi_hba,
>>               struct hisi_sas_slot *slot);
>> +    int (*prep_abort)(struct hisi_hba *hisi_hba,
>> +              struct hisi_sas_slot *slot,
>> +              int device_id, int abort_flag, int tag_to_abort);
>
> How about add comments to abort_flag and tag_to_abort.
> As a result, not sure why differently calling in hisi_sas_abort_task
> hisi_sas_internal_task_abort(hisi_hba, device, 1, tag);
> hisi_sas_internal_task_abort(hisi_hba, device, 0, tag);
>
> Thanks
>
>
> .
>

OK, I can do.

I will add a MACRO for the abort flag, whether device abort or single IO 
abort modes.

I will also mention for device abort mode that the tag is unused.

Thanks,
John

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

end of thread, other threads:[~2016-08-22  7:51 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-10 13:19 [PATCH 0/8] hisi_sas internal abort support John Garry
2016-08-10 13:19 ` [PATCH 1/8] hisi_sas: add internal abort core code John Garry
2016-08-21  0:44   ` zhangfei
2016-08-22  7:50     ` John Garry
2016-08-10 13:19 ` [PATCH 2/8] hisi_sas: for internal abort in hisi_sas_dev_gone() John Garry
2016-08-10 13:20 ` [PATCH 3/8] hisi_sas: add internal abort to hisi_sas_abort_task() John Garry
2016-08-10 13:20 ` [PATCH 4/8] hisi_sas: add prep_abort_v2_hw() John Garry
2016-08-10 13:20 ` [PATCH 5/8] hisi_sas: add v2 hw slot complete internal abort support John Garry
2016-08-10 13:20 ` [PATCH 6/8] hisi_sas: fail tmf task prep when port detached John Garry
2016-08-10 13:20 ` [PATCH 7/8] hisi_sas: add TMF success check John Garry
2016-08-10 13:20 ` [PATCH 8/8] hisi_sas: update version to 1.6 John Garry

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).