From patchwork Wed Mar 22 17:25:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 95788 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp334871qgd; Wed, 22 Mar 2017 09:58:47 -0700 (PDT) X-Received: by 10.98.142.1 with SMTP id k1mr45963663pfe.98.1490201927786; Wed, 22 Mar 2017 09:58:47 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s9si2441968pgo.309.2017.03.22.09.58.47; Wed, 22 Mar 2017 09:58:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760862AbdCVQ63 (ORCPT + 10 others); Wed, 22 Mar 2017 12:58:29 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:4372 "EHLO dggrg02-dlp.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1760831AbdCVQ61 (ORCPT ); Wed, 22 Mar 2017 12:58:27 -0400 Received: from 172.30.72.57 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.57]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AKI19574; Thu, 23 Mar 2017 00:54:47 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Thu, 23 Mar 2017 00:54:37 +0800 From: John Garry To: , CC: , , , , , John Garry , Xiang Chen Subject: [PATCH 01/23] scsi: hisi_sas: add to_hisi_sas_port() Date: Thu, 23 Mar 2017 01:25:17 +0800 Message-ID: <1490203539-228029-2-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com> References: <1490203539-228029-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.58D2AC57.0514, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: cb1672ffba6fe18a86080a7a3bb6f553 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Introduce function to get hisi_sas_port from asd_sas_port. Signed-off-by: John Garry Signed-off-by: Xiang Chen --- drivers/scsi/hisi_sas/hisi_sas.h | 2 ++ drivers/scsi/hisi_sas/hisi_sas_main.c | 17 +++++++++++++---- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 4 +++- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 6 ++++-- 4 files changed, 22 insertions(+), 7 deletions(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 9216dea..a018a8a 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -346,6 +346,8 @@ struct hisi_sas_command_table_ssp { struct hisi_sas_command_table_smp smp; struct hisi_sas_command_table_stp stp; }; + +extern struct hisi_sas_port *to_hisi_sas_port(struct asd_sas_port *sas_port); extern int hisi_sas_probe(struct platform_device *pdev, const struct hisi_sas_hw *ops); extern int hisi_sas_remove(struct platform_device *pdev); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 53637a9..11f32d2 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -27,6 +27,12 @@ static struct hisi_hba *dev_to_hisi_hba(struct domain_device *device) return device->port->ha->lldd_ha; } +struct hisi_sas_port *to_hisi_sas_port(struct asd_sas_port *sas_port) +{ + return container_of(sas_port, struct hisi_sas_port, sas_port); +} +EXPORT_SYMBOL_GPL(to_hisi_sas_port); + static void hisi_sas_slot_index_clear(struct hisi_hba *hisi_hba, int slot_idx) { void *bitmap = hisi_hba->slot_index_tags; @@ -178,10 +184,11 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, struct hisi_sas_port *port; struct hisi_sas_slot *slot; struct hisi_sas_cmd_hdr *cmd_hdr_base; + struct asd_sas_port *sas_port = device->port; struct device *dev = &hisi_hba->pdev->dev; int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx; - if (!device->port) { + if (!sas_port) { struct task_status_struct *ts = &task->task_status; ts->resp = SAS_TASK_UNDELIVERED; @@ -206,7 +213,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, rc = SAS_PHY_DOWN; return rc; } - port = device->port->lldd_port; + + port = to_hisi_sas_port(sas_port); if (port && !port->port_attached) { dev_info(dev, "task prep: %s port%d not attach device\n", (sas_protocol_ata(task->task_proto)) ? @@ -545,7 +553,7 @@ static void hisi_sas_port_notify_formed(struct asd_sas_phy *sas_phy) struct hisi_hba *hisi_hba = sas_ha->lldd_ha; struct hisi_sas_phy *phy = sas_phy->lldd_phy; struct asd_sas_port *sas_port = sas_phy->port; - struct hisi_sas_port *port = &hisi_hba->port[phy->port_id]; + struct hisi_sas_port *port = to_hisi_sas_port(sas_port); unsigned long flags; if (!sas_port) @@ -990,13 +998,14 @@ static int hisi_sas_query_task(struct sas_task *task) struct device *dev = &hisi_hba->pdev->dev; struct hisi_sas_port *port; struct hisi_sas_slot *slot; + struct asd_sas_port *sas_port = device->port; 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; + port = to_hisi_sas_port(sas_port); /* simply get a slot and send abort command */ rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 854fbea..022ad10 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -508,6 +508,8 @@ static void setup_itct_v1_hw(struct hisi_hba *hisi_hba, struct device *dev = &hisi_hba->pdev->dev; u64 qw0, device_id = sas_dev->device_id; struct hisi_sas_itct *itct = &hisi_hba->itct[device_id]; + struct asd_sas_port *sas_port = device->port; + struct hisi_sas_port *port = to_hisi_sas_port(sas_port); memset(itct, 0, sizeof(*itct)); @@ -528,7 +530,7 @@ static void setup_itct_v1_hw(struct hisi_hba *hisi_hba, (1 << ITCT_HDR_AWT_CONTROL_OFF) | (device->max_linkrate << ITCT_HDR_MAX_CONN_RATE_OFF) | (1 << ITCT_HDR_VALID_LINK_NUM_OFF) | - (device->port->id << ITCT_HDR_PORT_ID_OFF)); + (port->id << ITCT_HDR_PORT_ID_OFF)); itct->qw0 = cpu_to_le64(qw0); /* qw1 */ diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 1b21445..1590e2f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -676,7 +676,8 @@ static void setup_itct_v2_hw(struct hisi_hba *hisi_hba, u64 qw0, device_id = sas_dev->device_id; struct hisi_sas_itct *itct = &hisi_hba->itct[device_id]; struct domain_device *parent_dev = device->parent; - struct hisi_sas_port *port = device->port->lldd_port; + struct asd_sas_port *sas_port = device->port; + struct hisi_sas_port *port = to_hisi_sas_port(sas_port); memset(itct, 0, sizeof(*itct)); @@ -1920,7 +1921,8 @@ static int prep_ata_v2_hw(struct hisi_hba *hisi_hba, struct domain_device *parent_dev = device->parent; struct hisi_sas_device *sas_dev = device->lldd_dev; struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr; - struct hisi_sas_port *port = device->port->lldd_port; + struct asd_sas_port *sas_port = device->port; + struct hisi_sas_port *port = to_hisi_sas_port(sas_port); u8 *buf_cmd; int has_data = 0, rc = 0, hdr_tag = 0; u32 dw1 = 0, dw2 = 0; From patchwork Wed Mar 22 17:25:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 95805 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp338641qgd; Wed, 22 Mar 2017 10:05:23 -0700 (PDT) X-Received: by 10.84.129.195 with SMTP id b61mr56653512plb.83.1490202323756; Wed, 22 Mar 2017 10:05:23 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 1si2468288plh.210.2017.03.22.10.05.23; Wed, 22 Mar 2017 10:05:23 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965062AbdCVRFV (ORCPT + 11 others); Wed, 22 Mar 2017 13:05:21 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:4367 "EHLO dggrg02-dlp.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1760826AbdCVQ6Z (ORCPT ); Wed, 22 Mar 2017 12:58:25 -0400 Received: from 172.30.72.57 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.57]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AKI19578; Thu, 23 Mar 2017 00:54:48 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Thu, 23 Mar 2017 00:54:37 +0800 From: John Garry To: , CC: , , , , , Xiang Chen , "Xiaofei Tan" , John Garry Subject: [PATCH 02/23] scsi: hisi_sas: add controller reset Date: Thu, 23 Mar 2017 01:25:18 +0800 Message-ID: <1490203539-228029-3-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com> References: <1490203539-228029-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.58D2AC58.0468, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: d470ab6970f73cce10528287e17b0792 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xiang Chen There are some scenarios that we need to warm-rest to reset registers of SAS controller. During reset we disable interrupts/DQs/PHYs, and after reset we re-init the hardware and rescan the topology to see if anything changed. Signed-off-by: Xiang Chen Signed-off-by: Xiaofei Tan Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas.h | 7 ++ drivers/scsi/hisi_sas/hisi_sas_main.c | 134 +++++++++++++++++++++++++++++++-- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 94 +++++++++++++++++++++++ 3 files changed, 227 insertions(+), 8 deletions(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index a018a8a..fd76a02 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -31,6 +31,7 @@ #define HISI_SAS_QUEUE_SLOTS 512 #define HISI_SAS_MAX_ITCT_ENTRIES 2048 #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES +#define HISI_SAS_RESET_BIT 0 #define HISI_SAS_STATUS_BUF_SZ \ (sizeof(struct hisi_sas_err_record) + 1024) @@ -175,6 +176,7 @@ struct hisi_sas_hw { void (*free_device)(struct hisi_hba *hisi_hba, struct hisi_sas_device *dev); int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id); + int (*soft_reset)(struct hisi_hba *hisi_hba); int max_command_entries; int complete_hdr_size; }; @@ -233,7 +235,9 @@ struct hisi_hba { struct hisi_sas_breakpoint *sata_breakpoint; dma_addr_t sata_breakpoint_dma; struct hisi_sas_slot *slot_info; + unsigned long flags; const struct hisi_sas_hw *hw; /* Low level hw interface */ + struct work_struct rst_work; }; /* Generic HW DMA host memory structures */ @@ -356,4 +360,7 @@ extern int hisi_sas_probe(struct platform_device *pdev, extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, struct hisi_sas_slot *slot); +extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba); +extern void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 old_state, + u32 state); #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 11f32d2..cbaef90 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -351,6 +351,9 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags, struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev); struct device *dev = &hisi_hba->pdev->dev; + if (unlikely(test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))) + return -EINVAL; + /* protect task_prep and start_delivery sequence */ spin_lock_irqsave(&hisi_hba->lock, flags); rc = hisi_sas_task_prep(task, hisi_hba, is_tmf, tmf, &pass); @@ -613,6 +616,20 @@ static void hisi_sas_release_task(struct hisi_hba *hisi_hba, hisi_sas_do_release_task(hisi_hba, sas_phy->id, device); } +static void hisi_sas_release_tasks(struct hisi_hba *hisi_hba) +{ + int i; + + for (i = 0; i < HISI_SAS_MAX_PHYS; i++) { + struct hisi_sas_phy *phy = &hisi_hba->phy[i]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + + if (!sas_phy->port) + continue; + hisi_sas_port_notify_deformed(sas_phy); + } +} + static void hisi_sas_dev_gone(struct domain_device *device) { struct hisi_sas_device *sas_dev = device->lldd_dev; @@ -803,6 +820,40 @@ static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device, sizeof(ssp_task), tmf); } +static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) +{ + int rc; + + if (!hisi_hba->hw->soft_reset) + return -1; + + if (!test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) { + struct device *dev = &hisi_hba->pdev->dev; + struct sas_ha_struct *sas_ha = &hisi_hba->sha; + unsigned long flags; + + dev_dbg(dev, "controller reset begins!\n"); + scsi_block_requests(hisi_hba->shost); + rc = hisi_hba->hw->soft_reset(hisi_hba); + if (rc) { + dev_warn(dev, "controller reset failed (%d)\n", rc); + goto out; + } + spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_release_tasks(hisi_hba); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + + sas_ha->notify_ha_event(sas_ha, HAE_RESET); + dev_dbg(dev, "controller reset successful!\n"); + } else + return -1; + +out: + scsi_unblock_requests(hisi_hba->shost); + clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + return rc; +} + static int hisi_sas_abort_task(struct sas_task *task) { struct scsi_lun lun; @@ -1002,6 +1053,9 @@ static int hisi_sas_query_task(struct sas_task *task) struct hisi_sas_cmd_hdr *cmd_hdr_base; int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx; + if (unlikely(test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))) + return -EINVAL; + if (!device->port) return -1; @@ -1190,6 +1244,37 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) } EXPORT_SYMBOL_GPL(hisi_sas_phy_down); +void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 old_state, + u32 state) +{ + struct sas_ha_struct *sas_ha = &hisi_hba->sha; + int phy_no; + + for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct asd_sas_port *sas_port = sas_phy->port; + struct domain_device *dev; + + if (sas_phy->enabled) { + /* Report PHY state change to libsas */ + if (state & (1 << phy_no)) + continue; + + if (old_state & (1 << phy_no)) + /* PHY down but was up before */ + hisi_sas_phy_down(hisi_hba, phy_no, 0); + } + if (!sas_port) + continue; + dev = sas_port->port_dev; + + if (DEV_IS_EXPANDER(dev->dev_type)) + sas_ha->notify_phy_event(sas_phy, PORTE_BROADCAST_RCVD); + } +} +EXPORT_SYMBOL_GPL(hisi_sas_rescan_topology); + static struct scsi_transport_template *hisi_sas_stt; static struct scsi_host_template hisi_sas_sht = { @@ -1228,6 +1313,37 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) .lldd_port_deformed = hisi_sas_port_deformed, }; +void hisi_sas_init_mem(struct hisi_hba *hisi_hba) +{ + int i, s, max_command_entries = hisi_hba->hw->max_command_entries; + + for (i = 0; i < hisi_hba->queue_count; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; + struct hisi_sas_dq *dq = &hisi_hba->dq[i]; + + s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; + memset(hisi_hba->cmd_hdr[i], 0, s); + dq->wr_point = 0; + + s = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + memset(hisi_hba->complete_hdr[i], 0, s); + cq->rd_point = 0; + } + + s = sizeof(struct hisi_sas_initial_fis) * hisi_hba->n_phy; + memset(hisi_hba->initial_fis, 0, s); + + s = max_command_entries * sizeof(struct hisi_sas_iost); + memset(hisi_hba->iost, 0, s); + + s = max_command_entries * sizeof(struct hisi_sas_breakpoint); + memset(hisi_hba->breakpoint, 0, s); + + s = max_command_entries * sizeof(struct hisi_sas_breakpoint) * 2; + memset(hisi_hba->sata_breakpoint, 0, s); +} +EXPORT_SYMBOL_GPL(hisi_sas_init_mem); + static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) { struct platform_device *pdev = hisi_hba->pdev; @@ -1266,7 +1382,6 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) &hisi_hba->cmd_hdr_dma[i], GFP_KERNEL); if (!hisi_hba->cmd_hdr[i]) goto err_out; - memset(hisi_hba->cmd_hdr[i], 0, s); /* Completion queue */ s = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; @@ -1274,7 +1389,6 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) &hisi_hba->complete_hdr_dma[i], GFP_KERNEL); if (!hisi_hba->complete_hdr[i]) goto err_out; - memset(hisi_hba->complete_hdr[i], 0, s); } s = HISI_SAS_STATUS_BUF_SZ; @@ -1309,16 +1423,12 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) if (!hisi_hba->iost) goto err_out; - memset(hisi_hba->iost, 0, s); - s = max_command_entries * sizeof(struct hisi_sas_breakpoint); hisi_hba->breakpoint = dma_alloc_coherent(dev, s, &hisi_hba->breakpoint_dma, GFP_KERNEL); if (!hisi_hba->breakpoint) goto err_out; - memset(hisi_hba->breakpoint, 0, s); - hisi_hba->slot_index_count = max_command_entries; s = hisi_hba->slot_index_count / BITS_PER_BYTE; hisi_hba->slot_index_tags = devm_kzalloc(dev, s, GFP_KERNEL); @@ -1335,14 +1445,13 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) &hisi_hba->initial_fis_dma, GFP_KERNEL); if (!hisi_hba->initial_fis) goto err_out; - memset(hisi_hba->initial_fis, 0, s); s = max_command_entries * sizeof(struct hisi_sas_breakpoint) * 2; hisi_hba->sata_breakpoint = dma_alloc_coherent(dev, s, &hisi_hba->sata_breakpoint_dma, GFP_KERNEL); if (!hisi_hba->sata_breakpoint) goto err_out; - memset(hisi_hba->sata_breakpoint, 0, s); + hisi_sas_init_mem(hisi_hba); hisi_sas_slot_index_init(hisi_hba); @@ -1413,6 +1522,14 @@ static void hisi_sas_free(struct hisi_hba *hisi_hba) destroy_workqueue(hisi_hba->wq); } +static void hisi_sas_rst_work_handler(struct work_struct *work) +{ + struct hisi_hba *hisi_hba = + container_of(work, struct hisi_hba, rst_work); + + hisi_sas_controller_reset(hisi_hba); +} + static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, const struct hisi_sas_hw *hw) { @@ -1430,6 +1547,7 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, } hisi_hba = shost_priv(shost); + INIT_WORK(&hisi_hba->rst_work, hisi_sas_rst_work_handler); hisi_hba->hw = hw; hisi_hba->pdev = pdev; hisi_hba->shost = shost; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 1590e2f..53651cf 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -257,6 +257,10 @@ #define AM_CFG_MAX_TRANS (0x5010) #define AM_CFG_SINGLE_PORT_MAX_TRANS (0x5014) +#define AXI_MASTER_CFG_BASE (0x5000) +#define AM_CTRL_GLOBAL (0x0) +#define AM_CURR_TRANS_RETURN (0x150) + /* HW dma structures */ /* Delivery queue header */ /* dw0 */ @@ -1079,6 +1083,14 @@ static void stop_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no) disable_phy_v2_hw(hisi_hba, phy_no); } +static void stop_phys_v2_hw(struct hisi_hba *hisi_hba) +{ + int i; + + for (i = 0; i < hisi_hba->n_phy; i++) + stop_phy_v2_hw(hisi_hba, i); +} + static void phy_hard_reset_v2_hw(struct hisi_hba *hisi_hba, int phy_no) { struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; @@ -2857,6 +2869,87 @@ static int hisi_sas_v2_init(struct hisi_hba *hisi_hba) return 0; } +static void interrupt_disable_v2_hw(struct hisi_hba *hisi_hba) +{ + struct platform_device *pdev = hisi_hba->pdev; + int i; + + for (i = 0; i < hisi_hba->queue_count; i++) + hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0x1); + + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xffffffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xffffffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffffffff); + hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0xffffffff); + + for (i = 0; i < hisi_hba->n_phy; i++) { + hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xffffffff); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffffff); + } + + for (i = 0; i < 128; i++) + synchronize_irq(platform_get_irq(pdev, i)); +} + +static int soft_reset_v2_hw(struct hisi_hba *hisi_hba) +{ + struct device *dev = &hisi_hba->pdev->dev; + u32 old_state, state; + int rc, cnt; + int phy_no; + + old_state = hisi_sas_read32(hisi_hba, PHY_STATE); + + interrupt_disable_v2_hw(hisi_hba); + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); + + stop_phys_v2_hw(hisi_hba); + + mdelay(10); + + hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE + AM_CTRL_GLOBAL, 0x1); + + /* wait until bus idle */ + cnt = 0; + while (1) { + u32 status = hisi_sas_read32_relaxed(hisi_hba, + AXI_MASTER_CFG_BASE + AM_CURR_TRANS_RETURN); + + if (status == 0x3) + break; + + udelay(10); + if (cnt++ > 10) { + dev_info(dev, "wait axi bus state to idle timeout!\n"); + return -1; + } + } + + hisi_sas_init_mem(hisi_hba); + + rc = hw_init_v2_hw(hisi_hba); + if (rc) + return rc; + + /* Re-enable the PHYs */ + for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + + if (sas_phy->enabled) + start_phy_v2_hw(hisi_hba, phy_no); + } + + /* Wait for the PHYs to come up and read the PHY state */ + msleep(1000); + + state = hisi_sas_read32(hisi_hba, PHY_STATE); + + hisi_sas_rescan_topology(hisi_hba, old_state, state); + + return 0; +} + static const struct hisi_sas_hw hisi_sas_v2_hw = { .hw_init = hisi_sas_v2_init, .setup_itct = setup_itct_v2_hw, @@ -2879,6 +2972,7 @@ static int hisi_sas_v2_init(struct hisi_hba *hisi_hba) .phy_get_max_linkrate = phy_get_max_linkrate_v2_hw, .max_command_entries = HISI_SAS_COMMAND_ENTRIES_V2_HW, .complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr), + .soft_reset = soft_reset_v2_hw, }; static int hisi_sas_v2_probe(struct platform_device *pdev) From patchwork Wed Mar 22 17:25:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 95801 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp336894qgd; Wed, 22 Mar 2017 10:02:30 -0700 (PDT) X-Received: by 10.99.170.5 with SMTP id e5mr44767087pgf.89.1490202150867; Wed, 22 Mar 2017 10:02:30 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j17si2453182pgh.264.2017.03.22.10.02.30; Wed, 22 Mar 2017 10:02:30 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964945AbdCVRCX (ORCPT + 11 others); Wed, 22 Mar 2017 13:02:23 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:4379 "EHLO dggrg02-dlp.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S935047AbdCVQ66 (ORCPT ); Wed, 22 Mar 2017 12:58:58 -0400 Received: from 172.30.72.57 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.57]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AKI19573; Thu, 23 Mar 2017 00:54:47 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Thu, 23 Mar 2017 00:54:37 +0800 From: John Garry To: , CC: , , , , , John Garry , Xiang Chen Subject: [PATCH 03/23] scsi: hisi_sas: move PHY init to hisi_sas_scan_start() Date: Thu, 23 Mar 2017 01:25:19 +0800 Message-ID: <1490203539-228029-4-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com> References: <1490203539-228029-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.58D2AC58.0017, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: a41a14baea958ba017f4687192be9d77 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Relocate the PHY init code from LLDD hw init path to hisi_sas_scan_start(). Signed-off-by: John Garry Signed-off-by: Xiang Chen --- drivers/scsi/hisi_sas/hisi_sas.h | 2 +- drivers/scsi/hisi_sas/hisi_sas_main.c | 9 +++------ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 3 +-- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 3 +-- 4 files changed, 6 insertions(+), 11 deletions(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index fd76a02..2135de9 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -167,6 +167,7 @@ struct hisi_sas_hw { 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 (*phys_init)(struct hisi_hba *hisi_hba); void (*phy_enable)(struct hisi_hba *hisi_hba, int phy_no); void (*phy_disable)(struct hisi_hba *hisi_hba, int phy_no); void (*phy_hard_reset)(struct hisi_hba *hisi_hba, int phy_no); @@ -195,7 +196,6 @@ struct hisi_hba { u8 sas_addr[SAS_ADDR_SIZE]; int n_phy; - int scan_finished; spinlock_t lock; struct timer_list timer; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index cbaef90..b86a228 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -493,12 +493,8 @@ static int hisi_sas_slave_configure(struct scsi_device *sdev) static void hisi_sas_scan_start(struct Scsi_Host *shost) { struct hisi_hba *hisi_hba = shost_priv(shost); - int i; - - for (i = 0; i < hisi_hba->n_phy; ++i) - hisi_sas_bytes_dmaed(hisi_hba, i); - hisi_hba->scan_finished = 1; + hisi_hba->hw->phys_init(hisi_hba); } static int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time) @@ -506,7 +502,8 @@ static int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time) struct hisi_hba *hisi_hba = shost_priv(shost); struct sas_ha_struct *sha = &hisi_hba->sha; - if (hisi_hba->scan_finished == 0) + /* Wait for PHY up interrupt to occur */ + if (time < HZ) return 0; sas_drain_work(sha); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 022ad10..43988eb 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1847,8 +1847,6 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) if (rc) return rc; - phys_init_v1_hw(hisi_hba); - return 0; } @@ -1862,6 +1860,7 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) .get_free_slot = get_free_slot_v1_hw, .start_delivery = start_delivery_v1_hw, .slot_complete = slot_complete_v1_hw, + .phys_init = phys_init_v1_hw, .phy_enable = enable_phy_v1_hw, .phy_disable = disable_phy_v1_hw, .phy_hard_reset = phy_hard_reset_v1_hw, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 53651cf..73e4f66 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2864,8 +2864,6 @@ static int hisi_sas_v2_init(struct hisi_hba *hisi_hba) if (rc) return rc; - phys_init_v2_hw(hisi_hba); - return 0; } @@ -2965,6 +2963,7 @@ static int soft_reset_v2_hw(struct hisi_hba *hisi_hba) .get_free_slot = get_free_slot_v2_hw, .start_delivery = start_delivery_v2_hw, .slot_complete = slot_complete_v2_hw, + .phys_init = phys_init_v2_hw, .phy_enable = enable_phy_v2_hw, .phy_disable = disable_phy_v2_hw, .phy_hard_reset = phy_hard_reset_v2_hw, From patchwork Wed Mar 22 17:25:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 95790 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp335057qgd; Wed, 22 Mar 2017 09:59:15 -0700 (PDT) X-Received: by 10.99.149.66 with SMTP id t2mr45811747pgn.152.1490201955721; Wed, 22 Mar 2017 09:59:15 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e70si1755797pfc.37.2017.03.22.09.59.15; Wed, 22 Mar 2017 09:59:15 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935150AbdCVQ65 (ORCPT + 11 others); Wed, 22 Mar 2017 12:58:57 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:4374 "EHLO dggrg02-dlp.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1760866AbdCVQ6i (ORCPT ); Wed, 22 Mar 2017 12:58:38 -0400 Received: from 172.30.72.57 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.57]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AKI19572; Thu, 23 Mar 2017 00:54:47 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Thu, 23 Mar 2017 00:54:39 +0800 From: John Garry To: , CC: , , , , , John Garry , Xiang Chen Subject: [PATCH 07/23] scsi: hisi_sas: only reset link for PHY_FUNC_LINK_RESET Date: Thu, 23 Mar 2017 01:25:23 +0800 Message-ID: <1490203539-228029-8-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com> References: <1490203539-228029-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.58D2AC57.0330, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 42cb81b505b3f9a7030863f907f75f0a Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We currently do a hard reset for a link reset. Change this to do a link reset only. Signed-off-by: John Garry Signed-off-by: Xiang Chen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 7c1fb75..00068d2 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -659,8 +659,9 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, break; case PHY_FUNC_LINK_RESET: + hisi_hba->hw->phy_disable(hisi_hba, phy_no); + msleep(100); hisi_hba->hw->phy_enable(hisi_hba, phy_no); - hisi_hba->hw->phy_hard_reset(hisi_hba, phy_no); break; case PHY_FUNC_DISABLE: From patchwork Wed Mar 22 17:25:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 95794 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp335475qgd; Wed, 22 Mar 2017 10:00:10 -0700 (PDT) X-Received: by 10.84.231.206 with SMTP id g14mr28458298pln.13.1490202010049; Wed, 22 Mar 2017 10:00:10 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g5si2433792pgi.386.2017.03.22.10.00.09; Wed, 22 Mar 2017 10:00:10 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964930AbdCVQ7r (ORCPT + 11 others); Wed, 22 Mar 2017 12:59:47 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:4384 "EHLO dggrg02-dlp.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S935525AbdCVQ7Z (ORCPT ); Wed, 22 Mar 2017 12:59:25 -0400 Received: from 172.30.72.56 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.56]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AKI19598; Thu, 23 Mar 2017 00:54:54 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Thu, 23 Mar 2017 00:54:39 +0800 From: John Garry To: , CC: , , , , , John Garry , Xiang Chen Subject: [PATCH 09/23] scsi: hisi_sas: modify hisi_sas_abort_task() for SSP Date: Thu, 23 Mar 2017 01:25:25 +0800 Message-ID: <1490203539-228029-10-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com> References: <1490203539-228029-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020206.58D2AC8C.0147, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 25afe644d4ffd2f8351f9c1c05916083 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Currently an internal abort is executed regardless of the result of the TMF. We should also check the result of the internal abort to see if we should free the slot. So change the status code STAT_IO_COMPLETE to TMF_RESP_FUNC_SUCC, meaning the slot has been successfully aborted. Signed-off-by: John Garry Signed-off-by: Xiang Chen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 28 ++++++++++++++++++---------- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +- 2 files changed, 19 insertions(+), 11 deletions(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 00068d2..36d4e5a 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -935,6 +935,7 @@ static int hisi_sas_abort_task(struct sas_task *task) struct scsi_cmnd *cmnd = task->uldd_task; struct hisi_sas_slot *slot = task->lldd_task; u32 tag = slot->idx; + int rc2; int_to_scsilun(cmnd->device->lun, &lun); tmf_task.tmf = TMF_ABORT_TASK; @@ -943,21 +944,22 @@ static int hisi_sas_abort_task(struct sas_task *task) rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun, &tmf_task); - /* if successful, clear the task and callback forwards.*/ - if (rc == TMF_RESP_FUNC_COMPLETE) { + rc2 = hisi_sas_internal_task_abort(hisi_hba, device, + HISI_SAS_INT_ABT_CMD, tag); + /* + * If the TMF finds that the IO is not in the device and also + * the internal abort does not succeed, then it is safe to + * free the slot. + * Note: if the internal abort succeeds then the slot + * will have already been completed + */ + if (rc == TMF_RESP_FUNC_COMPLETE && rc2 != TMF_RESP_FUNC_SUCC) { if (task->lldd_task) { - struct hisi_sas_slot *slot; - - slot = &hisi_hba->slot_info - [tmf_task.tag_of_task_to_be_managed]; spin_lock_irqsave(&hisi_hba->lock, flags); - hisi_hba->hw->slot_complete(hisi_hba, slot); + hisi_sas_do_release_task(hisi_hba, task, slot); spin_unlock_irqrestore(&hisi_hba->lock, flags); } } - - hisi_sas_internal_task_abort(hisi_hba, device, - HISI_SAS_INT_ABT_CMD, tag); } else if (task->task_proto & SAS_PROTOCOL_SATA || task->task_proto & SAS_PROTOCOL_STP) { if (task->dev->dev_type == SAS_SATA_DEV) { @@ -1220,6 +1222,12 @@ static int hisi_sas_query_task(struct sas_task *task) goto exit; } + if (task->task_status.resp == SAS_TASK_COMPLETE && + task->task_status.stat == TMF_RESP_FUNC_SUCC) { + res = TMF_RESP_FUNC_SUCC; + 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)) { diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index a35f881..ad5a7e6 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -1766,7 +1766,7 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba, goto out; case STAT_IO_COMPLETE: /* internal abort command complete */ - ts->stat = TMF_RESP_FUNC_COMPLETE; + ts->stat = TMF_RESP_FUNC_SUCC; goto out; case STAT_IO_NO_DEVICE: ts->stat = TMF_RESP_FUNC_COMPLETE; From patchwork Wed Mar 22 17:25:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 95798 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp335845qgd; Wed, 22 Mar 2017 10:00:47 -0700 (PDT) X-Received: by 10.99.131.195 with SMTP id h186mr6214661pge.57.1490202047131; Wed, 22 Mar 2017 10:00:47 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x124si920614pgb.253.2017.03.22.10.00.46; Wed, 22 Mar 2017 10:00:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760940AbdCVRAh (ORCPT + 11 others); Wed, 22 Mar 2017 13:00:37 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:4386 "EHLO dggrg02-dlp.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1759400AbdCVRAH (ORCPT ); Wed, 22 Mar 2017 13:00:07 -0400 Received: from 172.30.72.56 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.56]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AKI19585; Thu, 23 Mar 2017 00:54:51 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Thu, 23 Mar 2017 00:54:40 +0800 From: John Garry To: , CC: , , , , , John Garry , Xiang Chen Subject: [PATCH 10/23] scsi: hisi_sas: hardreset for SATA disk in LU reset Date: Thu, 23 Mar 2017 01:25:26 +0800 Message-ID: <1490203539-228029-11-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com> References: <1490203539-228029-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.58D2AC5B.03E9, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 33b5b89d5ebfd1189d0cc69f6d6f9b90 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When issuing an LU reset for a SATA target, issue an internal abort and a hard reset. Signed-off-by: John Garry Signed-off-by: Xiang Chen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 38 ++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 36d4e5a..19f2892 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1037,23 +1037,43 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device) static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun) { - struct hisi_sas_tmf_task tmf_task; struct hisi_sas_device *sas_dev = device->lldd_dev; struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); struct device *dev = &hisi_hba->pdev->dev; unsigned long flags; int rc = TMF_RESP_FUNC_FAILED; - tmf_task.tmf = TMF_LU_RESET; sas_dev->dev_status = HISI_SAS_DEV_EH; - rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task); - 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); - } + if (dev_is_sata(device)) { + struct sas_phy *phy; + + /* Clear internal IO and then hardreset */ + rc = hisi_sas_internal_task_abort(hisi_hba, device, + HISI_SAS_INT_ABT_DEV, 0); + if (rc == TMF_RESP_FUNC_FAILED) + goto out; - /* If failed, fall-through I_T_Nexus reset */ + phy = sas_get_local_phy(device); + + rc = sas_phy_reset(phy, 1); + + if (rc == 0) { + spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_release_task(hisi_hba, device); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + } + sas_put_local_phy(phy); + } else { + struct hisi_sas_tmf_task tmf_task = { .tmf = TMF_LU_RESET }; + + rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task); + 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); + } + } +out: dev_err(dev, "lu_reset: for device[%llx]:rc= %d\n", sas_dev->device_id, rc); return rc; From patchwork Wed Mar 22 17:25:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 95789 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp334876qgd; Wed, 22 Mar 2017 09:58:48 -0700 (PDT) X-Received: by 10.99.23.102 with SMTP id 38mr45662308pgx.188.1490201928910; Wed, 22 Mar 2017 09:58:48 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s9si2441968pgo.309.2017.03.22.09.58.48; Wed, 22 Mar 2017 09:58:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760891AbdCVQ6q (ORCPT + 10 others); Wed, 22 Mar 2017 12:58:46 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:4373 "EHLO dggrg02-dlp.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1760864AbdCVQ6f (ORCPT ); Wed, 22 Mar 2017 12:58:35 -0400 Received: from 172.30.72.56 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.56]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AKI19597; Thu, 23 Mar 2017 00:54:53 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Thu, 23 Mar 2017 00:54:40 +0800 From: John Garry To: , CC: , , , , , John Garry Subject: [PATCH 11/23] scsi: hisi_sas: check for SAS_TASK_STATE_ABORTED in slot complete Date: Thu, 23 Mar 2017 01:25:27 +0800 Message-ID: <1490203539-228029-12-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com> References: <1490203539-228029-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.58D2AC5E.0322, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: f5458b82d5acbd7e1ebc2bd4a5eb1896 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Check in slot_complete_v2_hw() for whether a task has already been completed by upper layer. Signed-off-by: John Garry Reviewed-by: Xiang Chen --- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 10 ++++++++++ 1 file changed, 10 insertions(+) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index ad5a7e6..f4d8200 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -1737,6 +1737,7 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba, hisi_hba->complete_hdr[slot->cmplt_queue]; struct hisi_sas_complete_v2_hdr *complete_hdr = &complete_queue[slot->cmplt_queue_slot]; + int aborted; if (unlikely(!task || !task->lldd_task || !task->dev)) return -EINVAL; @@ -1745,12 +1746,21 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba, device = task->dev; sas_dev = device->lldd_dev; + spin_lock(&task->task_state_lock); + aborted = task->task_state_flags & SAS_TASK_STATE_ABORTED; task->task_state_flags &= ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); + spin_unlock(&task->task_state_lock); memset(ts, 0, sizeof(*ts)); ts->resp = SAS_TASK_COMPLETE; + if (unlikely(aborted)) { + ts->stat = SAS_ABORTED_TASK; + hisi_sas_slot_task_free(hisi_hba, task, slot); + return -1; + } + if (unlikely(!sas_dev)) { dev_dbg(dev, "slot complete: port has no device\n"); ts->stat = SAS_PHY_DOWN; From patchwork Wed Mar 22 17:25:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 95797 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp335844qgd; Wed, 22 Mar 2017 10:00:46 -0700 (PDT) X-Received: by 10.98.166.132 with SMTP id r4mr46231831pfl.191.1490202046803; Wed, 22 Mar 2017 10:00:46 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x124si920614pgb.253.2017.03.22.10.00.46; Wed, 22 Mar 2017 10:00:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760960AbdCVRAm (ORCPT + 11 others); Wed, 22 Mar 2017 13:00:42 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:4387 "EHLO dggrg02-dlp.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1760942AbdCVRAj (ORCPT ); Wed, 22 Mar 2017 13:00:39 -0400 Received: from 172.30.72.56 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.56]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AKI19590; Thu, 23 Mar 2017 00:54:52 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Thu, 23 Mar 2017 00:54:40 +0800 From: John Garry To: , CC: , , , , , Xiang Chen , John Garry Subject: [PATCH 12/23] scsi: hisi_sas: free slots after hardreset Date: Thu, 23 Mar 2017 01:25:28 +0800 Message-ID: <1490203539-228029-13-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com> References: <1490203539-228029-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.58D2AC5C.03F2, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 7871ed11edc2fe076d7f42e3be85f520 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xiang Chen After hardreset, we clear up IOs of remote disks, so we need to free those slots in LLDD. Signed-off-by: Xiang Chen Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas_main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 19f2892..49cac22 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1028,11 +1028,12 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device) rc = hisi_sas_debug_I_T_nexus_reset(device); - spin_lock_irqsave(&hisi_hba->lock, flags); - hisi_sas_release_task(hisi_hba, device); - spin_unlock_irqrestore(&hisi_hba->lock, flags); - - return 0; + 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_lu_reset(struct domain_device *device, u8 *lun) From patchwork Wed Mar 22 17:25:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 95791 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp335060qgd; Wed, 22 Mar 2017 09:59:16 -0700 (PDT) X-Received: by 10.84.141.1 with SMTP id 1mr57247545plu.178.1490201956355; Wed, 22 Mar 2017 09:59:16 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e70si1755797pfc.37.2017.03.22.09.59.16; Wed, 22 Mar 2017 09:59:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935490AbdCVQ7G (ORCPT + 11 others); Wed, 22 Mar 2017 12:59:06 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:4377 "EHLO dggrg02-dlp.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1760881AbdCVQ6q (ORCPT ); Wed, 22 Mar 2017 12:58:46 -0400 Received: from 172.30.72.56 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.56]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AKI19595; Thu, 23 Mar 2017 00:54:53 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Thu, 23 Mar 2017 00:54:41 +0800 From: John Garry To: , CC: , , , , , John Garry , Xiang Chen Subject: [PATCH 13/23] scsi: hisi_sas: fix some sas_task.task_state_lock locking Date: Thu, 23 Mar 2017 01:25:29 +0800 Message-ID: <1490203539-228029-14-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com> References: <1490203539-228029-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.58D2AC5E.00C4, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: a6ea1beb01ccbadd9fa9749fccc96931 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some more locking needs to be added/modified for when read-modify-writing sas_task.task_state_flags. Note: since we can attempt to grab this lock in interrupt context we should use irq variant of spin_lock. Signed-off-by: John Garry Signed-off-by: Xiang Chen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 13 ++++++------- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 3 +++ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 7 +++++-- 3 files changed, 14 insertions(+), 9 deletions(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 49cac22..f9ea5cc 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -188,6 +188,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, struct asd_sas_port *sas_port = device->port; struct device *dev = &hisi_hba->pdev->dev; int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx; + unsigned long flags; if (!sas_port) { struct task_status_struct *ts = &task->task_status; @@ -308,9 +309,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba, } list_add_tail(&slot->entry, &sas_dev->list); - spin_lock(&task->task_state_lock); + spin_lock_irqsave(&task->task_state_lock, flags); task->task_state_flags |= SAS_TASK_AT_INITIATOR; - spin_unlock(&task->task_state_lock); + spin_unlock_irqrestore(&task->task_state_lock, flags); hisi_hba->slot_prep = slot; @@ -922,14 +923,11 @@ static int hisi_sas_abort_task(struct sas_task *task) return TMF_RESP_FUNC_FAILED; } - spin_lock_irqsave(&task->task_state_lock, flags); if (task->task_state_flags & SAS_TASK_STATE_DONE) { - spin_unlock_irqrestore(&task->task_state_lock, flags); rc = TMF_RESP_FUNC_COMPLETE; goto out; } - spin_unlock_irqrestore(&task->task_state_lock, flags); sas_dev->dev_status = HISI_SAS_DEV_EH; if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) { struct scsi_cmnd *cmnd = task->uldd_task; @@ -1127,6 +1125,7 @@ static int hisi_sas_query_task(struct sas_task *task) struct asd_sas_port *sas_port = device->port; struct hisi_sas_cmd_hdr *cmd_hdr_base; int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx; + unsigned long flags; if (unlikely(test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))) return -EINVAL; @@ -1167,9 +1166,9 @@ static int hisi_sas_query_task(struct sas_task *task) list_add_tail(&slot->entry, &sas_dev->list); - spin_lock(&task->task_state_lock); + spin_lock_irqsave(&task->task_state_lock, flags); task->task_state_flags |= SAS_TASK_AT_INITIATOR; - spin_unlock(&task->task_state_lock); + spin_unlock_irqrestore(&task->task_state_lock, flags); hisi_hba->slot_prep = slot; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 2f3e877..fc1c1b2 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1288,6 +1288,7 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, struct hisi_sas_complete_v1_hdr *complete_queue = hisi_hba->complete_hdr[slot->cmplt_queue]; struct hisi_sas_complete_v1_hdr *complete_hdr; + unsigned long flags; u32 cmplt_hdr_data; complete_hdr = &complete_queue[slot->cmplt_queue_slot]; @@ -1300,9 +1301,11 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, device = task->dev; sas_dev = device->lldd_dev; + spin_lock_irqsave(&task->task_state_lock, flags); task->task_state_flags &= ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); task->task_state_flags |= SAS_TASK_STATE_DONE; + spin_unlock_irqrestore(&task->task_state_lock, flags); memset(ts, 0, sizeof(*ts)); ts->resp = SAS_TASK_COMPLETE; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index f4d8200..2b6e64c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -1737,6 +1737,7 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba, hisi_hba->complete_hdr[slot->cmplt_queue]; struct hisi_sas_complete_v2_hdr *complete_hdr = &complete_queue[slot->cmplt_queue_slot]; + unsigned long flags; int aborted; if (unlikely(!task || !task->lldd_task || !task->dev)) @@ -1746,11 +1747,11 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba, device = task->dev; sas_dev = device->lldd_dev; - spin_lock(&task->task_state_lock); + spin_lock_irqsave(&task->task_state_lock, flags); aborted = task->task_state_flags & SAS_TASK_STATE_ABORTED; task->task_state_flags &= ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); - spin_unlock(&task->task_state_lock); + spin_unlock_irqrestore(&task->task_state_lock, flags); memset(ts, 0, sizeof(*ts)); ts->resp = SAS_TASK_COMPLETE; @@ -1849,7 +1850,9 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba, } out: + spin_lock_irqsave(&task->task_state_lock, flags); task->task_state_flags |= SAS_TASK_STATE_DONE; + spin_unlock_irqrestore(&task->task_state_lock, flags); hisi_sas_slot_task_free(hisi_hba, task, slot); sts = ts->stat; From patchwork Wed Mar 22 17:25:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 95796 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp335699qgd; Wed, 22 Mar 2017 10:00:32 -0700 (PDT) X-Received: by 10.99.112.22 with SMTP id l22mr12229791pgc.94.1490202032166; Wed, 22 Mar 2017 10:00:32 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b35si2468426plh.95.2017.03.22.10.00.31; Wed, 22 Mar 2017 10:00:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760904AbdCVRAO (ORCPT + 11 others); Wed, 22 Mar 2017 13:00:14 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:4380 "EHLO dggrg02-dlp.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S935167AbdCVQ7B (ORCPT ); Wed, 22 Mar 2017 12:59:01 -0400 Received: from 172.30.72.56 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.56]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AKI19580; Thu, 23 Mar 2017 00:54:50 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Thu, 23 Mar 2017 00:54:43 +0800 From: John Garry To: , CC: , , , , , Xiang Chen , John Garry Subject: [PATCH 20/23] scsi: hisi_sas: release SMP slot in lldd_abort_task Date: Thu, 23 Mar 2017 01:25:36 +0800 Message-ID: <1490203539-228029-21-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com> References: <1490203539-228029-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.58D2AC5B.002A, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 4201291cc8401290291c97e27d288722 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xiang Chen When an SMP task timeouts, it will call lldd_abort_task to release the associated slot, and then will release the sas_task. Currently in lldd_abort_task, if we fail to internally abort IO, then the slot of SMP IO is not released, but sas_task will still be later released, so the slot's sas_task is NULL, which will cause NULL pointer when hisi_sas_slot_task_free happens later. To resolve, check the return value of internal abort, and release the slot if it failed. Signed-off-by: Xiang Chen Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas_main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index f86263b..1391f2d 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -962,8 +962,13 @@ static int hisi_sas_abort_task(struct sas_task *task) struct hisi_sas_slot *slot = task->lldd_task; u32 tag = slot->idx; - hisi_sas_internal_task_abort(hisi_hba, device, - HISI_SAS_INT_ABT_CMD, tag); + rc = hisi_sas_internal_task_abort(hisi_hba, device, + HISI_SAS_INT_ABT_CMD, tag); + if (rc == TMF_RESP_FUNC_FAILED) { + spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_do_release_task(hisi_hba, task, slot); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + } } out: From patchwork Wed Mar 22 17:25:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 95793 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp335168qgd; Wed, 22 Mar 2017 09:59:33 -0700 (PDT) X-Received: by 10.98.103.146 with SMTP id t18mr47504978pfj.135.1490201973183; Wed, 22 Mar 2017 09:59:33 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r26si2432142pge.381.2017.03.22.09.59.32; Wed, 22 Mar 2017 09:59:33 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964912AbdCVQ7a (ORCPT + 11 others); Wed, 22 Mar 2017 12:59:30 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:4383 "EHLO dggrg02-dlp.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S935301AbdCVQ7S (ORCPT ); Wed, 22 Mar 2017 12:59:18 -0400 Received: from 172.30.72.56 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.56]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AKI19583; Thu, 23 Mar 2017 00:54:50 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Thu, 23 Mar 2017 00:54:44 +0800 From: John Garry To: , CC: , , , , , Xiaofei Tan , John Garry Subject: [PATCH 23/23] scsi: hisi_sas: add is_sata_phy_v2_hw() Date: Thu, 23 Mar 2017 01:25:39 +0800 Message-ID: <1490203539-228029-24-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490203539-228029-1-git-send-email-john.garry@huawei.com> References: <1490203539-228029-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.58D2AC5B.0144, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 92e6d924029a8bcee17eff62b8d13b35 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xiaofei Tan Add helper function is_sata_phy_v2_hw() to judge whether the attached device is SATA disk for a root PHY. Signed-off-by: Xiaofei Tan Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index e9c7188..a3af380 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -1075,6 +1075,17 @@ static void enable_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no) hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); } +static bool is_sata_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 context; + + context = hisi_sas_read32(hisi_hba, PHY_CONTEXT); + if (context & (1 << phy_no)) + return true; + + return false; +} + static void disable_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no) { u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG); @@ -2286,7 +2297,7 @@ static int prep_abort_v2_hw(struct hisi_hba *hisi_hba, static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba) { int i, res = IRQ_HANDLED; - u32 context, port_id, link_rate, hard_phy_linkrate; + u32 port_id, link_rate, hard_phy_linkrate; struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; struct asd_sas_phy *sas_phy = &phy->sas_phy; struct device *dev = &hisi_hba->pdev->dev; @@ -2295,9 +2306,7 @@ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba) hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); - /* Check for SATA dev */ - context = hisi_sas_read32(hisi_hba, PHY_CONTEXT); - if (context & (1 << phy_no)) + if (is_sata_phy_v2_hw(hisi_hba, phy_no)) goto end; if (phy_no == 8) {