From patchwork Mon Oct 12 15:20:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 54785 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f200.google.com (mail-wi0-f200.google.com [209.85.212.200]) by patches.linaro.org (Postfix) with ESMTPS id 6FE4223001 for ; Mon, 12 Oct 2015 15:07:41 +0000 (UTC) Received: by wibzt1 with SMTP id zt1sf16749717wib.0 for ; Mon, 12 Oct 2015 08:07:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-type:sender:precedence :list-id:x-original-sender:x-original-authentication-results :mailing-list:list-post:list-help:list-archive:list-unsubscribe; bh=Hgr5HD51DvifUNcE1XrRWMX+b4FhAEQgl8QerwoV1ig=; b=Rhho3l7obLPNPMooQxII8WW5UJklEuP6/lVCQ0b4eAWjQNo9tZ9EGL5Ar5LBCifyrb 4lrVmX9DJRTDcjyDlBwutwdnE9dK4yxNbbEJjtGtQcP92SJUz6s7ecMVMozVy+gcQdh4 u7cgEDlkFSqroCZiZBguOLAny6Zzc2cjRaOX5yfc33nLXAX6D5V8bVFKT9P59gR1Imco 6ahJMRZKkcnGQWyMwGdDA3ibyf0hzUuODtyjVgE5uPwTk2blSwCuTWJbiGZMmHZlw8oN SPpDnPiP0u5qdX+Yoi3Ua4SuF8kpVEEjQy5f42GbpUtiFb+0jf+Z4rJGKXcSsRi4qbov gvrw== X-Gm-Message-State: ALoCoQl2sPPP44TEczbVqn96cV/fYmRY1pjG7Ss3CMsn5zbmUnOC7bfEvXZ4eOXw6I7Dfeh+Mfy0 X-Received: by 10.180.107.167 with SMTP id hd7mr3014866wib.6.1444662460789; Mon, 12 Oct 2015 08:07:40 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.25.160.13 with SMTP id j13ls518201lfe.67.gmail; Mon, 12 Oct 2015 08:07:40 -0700 (PDT) X-Received: by 10.25.144.82 with SMTP id s79mr5670120lfd.34.1444662460637; Mon, 12 Oct 2015 08:07:40 -0700 (PDT) Received: from mail-lb0-f169.google.com (mail-lb0-f169.google.com. [209.85.217.169]) by mx.google.com with ESMTPS id g5si11540395lbs.7.2015.10.12.08.07.40 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Oct 2015 08:07:40 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.169 as permitted sender) client-ip=209.85.217.169; Received: by lbcao8 with SMTP id ao8so146252432lbc.3 for ; Mon, 12 Oct 2015 08:07:40 -0700 (PDT) X-Received: by 10.25.150.199 with SMTP id y190mr8513385lfd.35.1444662460521; Mon, 12 Oct 2015 08:07:40 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp1600449lbq; Mon, 12 Oct 2015 08:07:39 -0700 (PDT) X-Received: by 10.50.79.133 with SMTP id j5mr12521197igx.59.1444662459476; Mon, 12 Oct 2015 08:07:39 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j199si12406431ioe.58.2015.10.12.08.07.39; Mon, 12 Oct 2015 08:07:39 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751616AbbJLPHb (ORCPT + 7 others); Mon, 12 Oct 2015 11:07:31 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:12427 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751073AbbJLPHa (ORCPT ); Mon, 12 Oct 2015 11:07:30 -0400 Received: from 172.24.1.51 (EHLO szxeml432-hub.china.huawei.com) ([172.24.1.51]) by szxrg02-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id CUB61533; Mon, 12 Oct 2015 23:05:16 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by szxeml432-hub.china.huawei.com (10.82.67.209) with Microsoft SMTP Server id 14.3.235.1; Mon, 12 Oct 2015 23:05:03 +0800 From: John Garry To: CC: , , , , , , , , , John Garry Subject: [PATCH 16/25] scsi: hisi_sas: add dev_found and port_formed Date: Mon, 12 Oct 2015 23:20:28 +0800 Message-ID: <1444663237-238302-17-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1444663237-238302-1-git-send-email-john.garry@huawei.com> References: <1444663237-238302-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected Sender: devicetree-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: devicetree@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: john.garry@huawei.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.169 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add functions to deal with lldd_dev_found and lldd_port_formed. Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas.h | 12 ++++ drivers/scsi/hisi_sas/hisi_sas_init.c | 2 + drivers/scsi/hisi_sas/hisi_sas_main.c | 125 +++++++++++++++++++++++++++++++++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 41 +++++++++++ 4 files changed, 180 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 976964f..3516d6f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -47,6 +47,12 @@ enum dev_status { HISI_SAS_DEV_EH, }; +enum hisi_sas_dev_type { + HISI_SAS_DEV_TYPE_STP = 0, + HISI_SAS_DEV_TYPE_SSP, + HISI_SAS_DEV_TYPE_SATA, +}; + struct hisi_sas_phy { struct hisi_hba *hisi_hba; struct hisi_sas_port *port; @@ -345,12 +351,16 @@ union hisi_sas_command_table { void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba); void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int i); +int hisi_sas_dev_found(struct domain_device *dev); int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags); +void hisi_sas_port_formed(struct asd_sas_phy *sas_phy); void hisi_sas_wq_process(struct work_struct *work); void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, struct hisi_sas_slot *slot); /* hw specific functions */ +extern void hisi_sas_setup_itct_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *device); extern void start_delivery_v1_hw(struct hisi_hba *hisi_hba); extern int get_free_slot_v1_hw(struct hisi_hba *hisi_hba, int *q, int *s); extern int prep_ssp_v1_hw(struct hisi_hba *hisi_hba, @@ -361,4 +371,6 @@ extern int interrupt_openall_v1_hw(struct hisi_hba *hisi_hba); extern int hw_init_v1_hw(struct hisi_hba *hisi_hba); extern int phys_init_v1_hw(struct hisi_hba *hisi_hba); extern void sl_notify_v1_hw(struct hisi_hba *hisi_hba, int phy_no); +extern void setup_itct_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *device); #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_init.c b/drivers/scsi/hisi_sas/hisi_sas_init.c index c681b21..703527b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_init.c +++ b/drivers/scsi/hisi_sas/hisi_sas_init.c @@ -33,7 +33,9 @@ static struct scsi_host_template hisi_sas_sht = { }; static struct sas_domain_function_template hisi_sas_transport_ops = { + .lldd_dev_found = hisi_sas_dev_found, .lldd_execute_task = hisi_sas_queue_command, + .lldd_port_formed = hisi_sas_port_formed, }; static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 74084c2..44cb9085 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -11,6 +11,9 @@ #include "hisi_sas.h" +#define DEV_IS_EXPANDER(type) \ + ((type == SAS_EDGE_EXPANDER_DEVICE) || \ + (type == SAS_FANOUT_EXPANDER_DEVICE)) #define DEV_IS_GONE(dev) \ ((!dev) || (dev->dev_type == SAS_PHY_UNUSED)) @@ -352,6 +355,79 @@ void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) sas_ha->notify_port_event(sas_phy, PORTE_BYTES_DMAED); } +struct hisi_sas_device *hisi_sas_alloc_dev(struct hisi_hba *hisi_hba) +{ + int dev_id; + struct device *dev = &hisi_hba->pdev->dev; + + for (dev_id = 0; dev_id < HISI_SAS_MAX_DEVICES; dev_id++) { + if (hisi_hba->devices[dev_id].dev_type == SAS_PHY_UNUSED) { + hisi_hba->devices[dev_id].device_id = dev_id; + return &hisi_hba->devices[dev_id]; + } + } + + dev_err(dev, "alloc dev: max support %d devices - could not alloc\n", + HISI_SAS_MAX_DEVICES); + + return NULL; +} + +int hisi_sas_dev_found_notify(struct domain_device *device, int lock) +{ + unsigned long flags = 0; + int res = 0; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct domain_device *parent_dev = device->parent; + struct hisi_sas_device *sas_dev; + struct device *dev = &hisi_hba->pdev->dev; + + if (lock) + spin_lock_irqsave(&hisi_hba->lock, flags); + + sas_dev = hisi_sas_alloc_dev(hisi_hba); + if (!sas_dev) { + res = -EINVAL; + goto found_out; + } + + device->lldd_dev = sas_dev; + sas_dev->dev_status = HISI_SAS_DEV_NORMAL; + sas_dev->dev_type = device->dev_type; + sas_dev->hisi_hba = hisi_hba; + sas_dev->sas_device = device; + setup_itct_v1_hw(hisi_hba, sas_dev); + + if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) { + int phy_no; + u8 phy_num = parent_dev->ex_dev.num_phys; + struct ex_phy *phy; + + for (phy_no = 0; phy_no < phy_num; phy_no++) { + phy = &parent_dev->ex_dev.ex_phy[phy_no]; + if (SAS_ADDR(phy->attached_sas_addr) == + SAS_ADDR(device->sas_addr)) { + sas_dev->attached_phy = phy_no; + break; + } + } + + if (phy_no == phy_num) { + dev_info(dev, + "dev found: no attached " + "dev:%016llx at ex:%016llx\n", + SAS_ADDR(device->sas_addr), + SAS_ADDR(parent_dev->sas_addr)); + res = -EINVAL; + } + } + +found_out: + if (lock) + spin_unlock_irqrestore(&hisi_hba->lock, flags); + return res; +} + static void hisi_sas_phyup_work(struct hisi_hba *hisi_hba, int phy_no) @@ -400,7 +476,56 @@ void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) sas_phy->lldd_phy = phy; } +void hisi_sas_port_notify_formed(struct asd_sas_phy *sas_phy, int lock) +{ + struct sas_ha_struct *sas_ha = sas_phy->ha; + struct hisi_hba *hisi_hba = NULL; + int i = 0; + struct hisi_sas_phy *phy = sas_phy->lldd_phy; + struct asd_sas_port *sas_port = sas_phy->port; + struct hisi_sas_port *port; + unsigned long flags = 0; + + if (!sas_port) + return; + + while (sas_ha->sas_phy[i]) { + if (sas_ha->sas_phy[i] == sas_phy) { + hisi_hba = (struct hisi_hba *)sas_ha->lldd_ha; + port = &hisi_hba->port[i]; + break; + } + i++; + } + + if (hisi_hba == NULL) { + pr_err("%s: could not find hba\n", __func__); + return; + } + + if (lock) + spin_lock_irqsave(&hisi_hba->lock, flags); + port->port_attached = 1; + port->id = phy->port_id; + phy->port = port; + sas_port->lldd_port = port; + + if (lock) + spin_unlock_irqrestore(&hisi_hba->lock, flags); +} + + +int hisi_sas_dev_found(struct domain_device *device) +{ + return hisi_sas_dev_found_notify(device, 1); +} + int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) { return hisi_sas_task_exec(task, gfp_flags, NULL, 0, NULL); } + +void hisi_sas_port_formed(struct asd_sas_phy *sas_phy) +{ + hisi_sas_port_notify_formed(sas_phy, 1); +} diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 4cb0e1b..e8b9dc3 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -493,6 +493,47 @@ static void init_id_frame_v1_hw(struct hisi_hba *hisi_hba) config_id_frame_v1_hw(hisi_hba, i); } +void setup_itct_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *sas_dev) +{ + struct domain_device *device = sas_dev->sas_device; + 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]; + + memset(itct, 0, sizeof(*itct)); + + /* qw0 */ + qw0 = 0; + switch (sas_dev->dev_type) { + case SAS_END_DEVICE: + case SAS_EDGE_EXPANDER_DEVICE: + case SAS_FANOUT_EXPANDER_DEVICE: + qw0 = HISI_SAS_DEV_TYPE_SSP << ITCT_HDR_DEV_TYPE_OFF; + break; + default: + dev_warn(dev, "setup itct: unsupported dev type (%d)\n", + sas_dev->dev_type); + } + + qw0 |= ((1 << ITCT_HDR_VALID_OFF) | + (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)); + itct->qw0 = cpu_to_le64(qw0); + + /* qw1 */ + memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE); + itct->sas_addr = __swab64(itct->sas_addr); + + /* qw2 */ + itct->qw2 = cpu_to_le64((500 < ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) | + (0xff00 < ITCT_HDR_BUS_INACTIVE_TL_OFF) | + (0xff00 < ITCT_HDR_MAX_CONN_TL_OFF) | + (0xff00 < ITCT_HDR_REJ_OPEN_TL_OFF)); +} + static int reset_hw_v1_hw(struct hisi_hba *hisi_hba) { int i;