mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: John Garry <john.garry@huawei.com>
To: <jejb@linux.vnet.ibm.com>, <martin.petersen@oracle.com>
Cc: <linuxarm@huawei.com>, <john.garry2@mail.dcu.ie>,
	<linux-scsi@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<zhangfei.gao@linaro.org>, Xiang Chen <chenxiang66@hisilicon.com>,
	John Garry <john.garry@huawei.com>
Subject: [PATCH 04/23] scsi: hisi_sas: add softreset function for SATA disk
Date: Thu, 23 Mar 2017 01:25:20 +0800	[thread overview]
Message-ID: <1490203539-228029-5-git-send-email-john.garry@huawei.com> (raw)
In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com>

From: Xiang Chen <chenxiang66@hisilicon.com>

Add softreset to clear IO after internal abort device
for SATA disk.

The SATA error handling for the controller is based on
device internal abort and softreset function.

The controller does not support internal abort for single
IO, so we need to execute internal abort for device.

Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/Kconfig          |  2 +-
 drivers/scsi/hisi_sas/hisi_sas_main.c  | 70 ++++++++++++++++++++++++++++++++--
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c |  3 +-
 3 files changed, 69 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/hisi_sas/Kconfig b/drivers/scsi/hisi_sas/Kconfig
index d1dd161..ded2c20 100644
--- a/drivers/scsi/hisi_sas/Kconfig
+++ b/drivers/scsi/hisi_sas/Kconfig
@@ -2,7 +2,7 @@ config SCSI_HISI_SAS
 	tristate "HiSilicon SAS"
 	depends on HAS_DMA && HAS_IOMEM
 	depends on ARM64 || COMPILE_TEST
-	select SCSI_SAS_LIBSAS
+	depends on SCSI_SAS_ATA
 	select BLK_DEV_INTEGRITY
 	help
 		This driver supports HiSilicon's SAS HBA
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index b86a228..9d9f305 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -21,6 +21,7 @@ static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device,
 hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
 			     struct domain_device *device,
 			     int abort_flag, int tag);
+static int hisi_sas_softreset_ata_disk(struct domain_device *device);
 
 static struct hisi_hba *dev_to_hisi_hba(struct domain_device *device)
 {
@@ -720,7 +721,12 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device,
 		task->dev = device;
 		task->task_proto = device->tproto;
 
-		memcpy(&task->ssp_task, parameter, para_len);
+		if (dev_is_sata(device)) {
+			task->ata_task.device_control_reg_update = 1;
+			memcpy(&task->ata_task.fis, parameter, para_len);
+		} else {
+			memcpy(&task->ssp_task, parameter, para_len);
+		}
 		task->task_done = hisi_sas_task_done;
 
 		task->slow_task->timer.data = (unsigned long) task;
@@ -742,8 +748,7 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device,
 		/* Even 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, "abort tmf: TMF task[%d] timeout\n",
-					tmf->tag_of_task_to_be_managed);
+				dev_err(dev, "abort tmf: TMF task timeout\n");
 				if (task->lldd_task) {
 					struct hisi_sas_slot *slot =
 						task->lldd_task;
@@ -803,6 +808,63 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device,
 	return res;
 }
 
+static void hisi_sas_fill_ata_reset_cmd(struct ata_device *dev,
+		bool reset, int pmp, u8 *fis)
+{
+	struct ata_taskfile tf;
+
+	ata_tf_init(dev, &tf);
+	if (reset)
+		tf.ctl |= ATA_SRST;
+	else
+		tf.ctl &= ~ATA_SRST;
+	tf.command = ATA_CMD_DEV_RESET;
+	ata_tf_to_fis(&tf, pmp, 0, fis);
+}
+
+static int hisi_sas_softreset_ata_disk(struct domain_device *device)
+{
+	u8 fis[20] = {0};
+	struct ata_port *ap = device->sata_dev.ap;
+	struct ata_link *link;
+	int rc = TMF_RESP_FUNC_FAILED;
+	struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+	struct device *dev = &hisi_hba->pdev->dev;
+	int s = sizeof(struct host_to_dev_fis);
+	unsigned long flags;
+
+	ata_for_each_link(link, ap, EDGE) {
+		int pmp = sata_srst_pmp(link);
+
+		hisi_sas_fill_ata_reset_cmd(link->device, 1, pmp, fis);
+		rc = hisi_sas_exec_internal_tmf_task(device, fis, s, NULL);
+		if (rc != TMF_RESP_FUNC_COMPLETE)
+			break;
+	}
+
+	if (rc == TMF_RESP_FUNC_COMPLETE) {
+		ata_for_each_link(link, ap, EDGE) {
+			int pmp = sata_srst_pmp(link);
+
+			hisi_sas_fill_ata_reset_cmd(link->device, 0, pmp, fis);
+			rc = hisi_sas_exec_internal_tmf_task(device, fis,
+							     s, NULL);
+			if (rc != TMF_RESP_FUNC_COMPLETE)
+				dev_err(dev, "ata disk de-reset failed\n");
+		}
+	} else {
+		dev_err(dev, "ata disk reset failed\n");
+	}
+
+	if (rc == TMF_RESP_FUNC_COMPLETE) {
+		spin_lock_irqsave(&hisi_hba->lock, flags);
+		hisi_sas_release_task(hisi_hba, device);
+		spin_unlock_irqrestore(&hisi_hba->lock, flags);
+	}
+
+	return rc;
+}
+
 static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device,
 				u8 *lun, struct hisi_sas_tmf_task *tmf)
 {
@@ -908,7 +970,7 @@ static int hisi_sas_abort_task(struct sas_task *task)
 		if (task->dev->dev_type == SAS_SATA_DEV) {
 			hisi_sas_internal_task_abort(hisi_hba, device,
 						     HISI_SAS_INT_ABT_DEV, 0);
-			rc = TMF_RESP_FUNC_COMPLETE;
+			rc = hisi_sas_softreset_ata_disk(device);
 		}
 	} else if (task->task_proto & SAS_PROTOCOL_SMP) {
 		/* SMP */
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 73e4f66..401e5c6 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -1961,7 +1961,8 @@ static int prep_ata_v2_hw(struct hisi_hba *hisi_hba,
 		dw1 &= ~CMD_HDR_DIR_MSK;
 	}
 
-	if (0 == task->ata_task.fis.command)
+	if ((task->ata_task.fis.command == ATA_CMD_DEV_RESET) &&
+			(task->ata_task.fis.control & ATA_SRST))
 		dw1 |= 1 << CMD_HDR_RESET_OFF;
 
 	dw1 |= (get_ata_protocol(task->ata_task.fis.command, task->data_dir))
-- 
1.9.1

  parent reply	other threads:[~2017-03-22 17:02 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-22 17:25 [PATCH 00/23] hisi_sas: error handling and other misc fixes and improvements John Garry
2017-03-22 17:25 ` [PATCH 01/23] scsi: hisi_sas: add to_hisi_sas_port() John Garry
2017-03-22 17:25 ` [PATCH 02/23] scsi: hisi_sas: add controller reset John Garry
2017-03-22 17:25 ` [PATCH 03/23] scsi: hisi_sas: move PHY init to hisi_sas_scan_start() John Garry
2017-03-22 17:25 ` John Garry [this message]
2017-03-22 17:25 ` [PATCH 05/23] scsi: hisi_sas: remove hisi_sas_port_deformed() John Garry
2017-03-22 17:25 ` [PATCH 06/23] scsi: hisi_sas: error hisi_sas_task_prep() when port down John Garry
2017-03-22 17:25 ` [PATCH 07/23] scsi: hisi_sas: only reset link for PHY_FUNC_LINK_RESET John Garry
2017-03-22 17:25 ` [PATCH 08/23] scsi: hisi_sas: modify error handling for v2 hw John Garry
2017-03-22 17:25 ` [PATCH 09/23] scsi: hisi_sas: modify hisi_sas_abort_task() for SSP John Garry
2017-03-22 17:25 ` [PATCH 10/23] scsi: hisi_sas: hardreset for SATA disk in LU reset John Garry
2017-03-22 17:25 ` [PATCH 11/23] scsi: hisi_sas: check for SAS_TASK_STATE_ABORTED in slot complete John Garry
2017-03-22 17:25 ` [PATCH 12/23] scsi: hisi_sas: free slots after hardreset John Garry
2017-03-22 17:25 ` [PATCH 13/23] scsi: hisi_sas: fix some sas_task.task_state_lock locking John Garry
2017-03-22 17:25 ` [PATCH 14/23] scsi: hisi_sas: remove task free'ing for timeouts John Garry
2017-03-22 17:25 ` [PATCH 15/23] scsi: hisi_sas: process error codes according to their priority John Garry
2017-03-22 17:25 ` [PATCH 16/23] scsi: hisi_sas: some modifications to v2 hw reg init values John Garry
2017-03-22 17:25 ` [PATCH 17/23] scsi: hisi_sas: handle PHY UP+DOWN simultaneous irq John Garry
2017-03-22 17:25 ` [PATCH 18/23] scsi: hisi_sas: rename hisi_sas_link_timeout_{enable, disable}_link John Garry
2017-03-22 17:25 ` [PATCH 19/23] scsi: hisi_sas: add hisi_sas_clear_nexus_ha() John Garry
2017-03-22 17:25 ` [PATCH 20/23] scsi: hisi_sas: release SMP slot in lldd_abort_task John Garry
2017-03-22 17:25 ` [PATCH 21/23] scsi: hisi_sas: check hisi_sas_lu_reset() error message John Garry
2017-03-22 17:25 ` [PATCH 22/23] scsi: hisi_sas: use dev_is_sata to identify SATA or SAS disk John Garry
2017-03-22 17:25 ` [PATCH 23/23] scsi: hisi_sas: add is_sata_phy_v2_hw() John Garry
2017-03-23 15:12 ` [PATCH 00/23] hisi_sas: error handling and other misc fixes and improvements Martin K. Petersen

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=1490203539-228029-5-git-send-email-john.garry@huawei.com \
    --to=john.garry@huawei.com \
    --cc=chenxiang66@hisilicon.com \
    --cc=jejb@linux.vnet.ibm.com \
    --cc=john.garry2@mail.dcu.ie \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linuxarm@huawei.com \
    --cc=martin.petersen@oracle.com \
    --cc=zhangfei.gao@linaro.org \
    /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

all inboxes | Powered by JetHome®