From patchwork Tue May 22 04:21:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sayali Lokhande X-Patchwork-Id: 10417321 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7C9E66016C for ; Tue, 22 May 2018 04:23:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6C0BA28802 for ; Tue, 22 May 2018 04:23:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 60E4428843; Tue, 22 May 2018 04:23:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B323528802 for ; Tue, 22 May 2018 04:23:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751336AbeEVEX1 (ORCPT ); Tue, 22 May 2018 00:23:27 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:53084 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751261AbeEVEXX (ORCPT ); Tue, 22 May 2018 00:23:23 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 2330860767; Tue, 22 May 2018 04:23:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1526963003; bh=3lxapwrhIVsrXicTslpL4EhhkpuQgiX/9ZRTS5grua4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H/iK2ID5WJqrrG1LMk57sePfYti7RRgJPxg/X3EytvhAAdVf7EE2HAz7cG/aBe+Dl I/T03hVMsuyGlG6LkpBSzdIv4zGFoQ5+3v1aq9K2arD85c+CYHYu0kDoasD3/8CwLw NhBfFy0XozGzYnHCBnO8/DGr6CREA0Zs4PGZwsXE= Received: from sayalil-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: sayalil@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 659606028C; Tue, 22 May 2018 04:23:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1526963002; bh=3lxapwrhIVsrXicTslpL4EhhkpuQgiX/9ZRTS5grua4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gDslLtQYvuiiqcXMtzz2sUYwnXlnQePLkQJazhBxbOinQeVHt7SLvXCzOmeLFPqkn Nl/gpU/7IKIFOh1fRkyZBDe5XPiZQZuUb2fRHgxRswJeTXDL80Te2/JAhu/wzakuiT uOjqXDMV+uqSyu8ASb0zg9Ysrf7jQxSk0VuTT/UE= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 659606028C Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=sayalil@codeaurora.org From: Sayali Lokhande To: subhashj@codeaurora.org, cang@codeaurora.org, vivek.gautam@codeaurora.org, rnayak@codeaurora.org, vinholikatti@gmail.com, jejb@linux.vnet.ibm.com, martin.petersen@oracle.com, asutoshd@codeaurora.org Cc: linux-scsi@vger.kernel.org, Sayali Lokhande , linux-kernel@vger.kernel.org (open list) Subject: [PATCH RFC 3/3] scsi: ufs: Add sysfs support for ufs provision Date: Tue, 22 May 2018 09:51:40 +0530 Message-Id: <1526962900-20683-4-git-send-email-sayalil@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1526962900-20683-1-git-send-email-sayalil@codeaurora.org> References: <1526962900-20683-1-git-send-email-sayalil@codeaurora.org> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add sysfs support to trigger ufs provisioning at runtime. Usage : echo > /sys/bus/platform/devices/1d84000.ufshcd/ufs_provision To check provisioning status: cat /sys/bus/platform/devices/1d84000.ufshc/ufs_provision 1 -> Success (Reboot device to check updated provisioning) Signed-off-by: Sayali Lokhande --- drivers/scsi/ufs/ufs.h | 2 + drivers/scsi/ufs/ufshcd.c | 125 +++++++++++++++++++++++++++++++++++++++++++++- drivers/scsi/ufs/ufshcd.h | 6 +++ 3 files changed, 132 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 1f99904..0b497fc 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -427,6 +427,7 @@ enum { }; struct ufs_unit_desc { + u8 LUNum; u8 bLUEnable; /* 1 for enabled LU */ u8 bBootLunID; /* 0 for using this LU for boot */ u8 bLUWriteProtect; /* 1 = power on WP, 2 = permanent WP */ @@ -451,6 +452,7 @@ struct ufs_config_descr { u32 qVendorConfigCode; /* Vendor specific configuration code */ struct ufs_unit_desc unit[8]; u8 lun_to_grow; + u8 num_luns; }; /* Task management service response */ diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 9ae64e2..0c94885 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1580,6 +1580,106 @@ void ufshcd_release(struct ufs_hba *hba) } EXPORT_SYMBOL_GPL(ufshcd_release); +static ssize_t ufshcd_desc_config_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", hba->ufs_provision.is_enabled); +} + +static ssize_t ufshcd_desc_config_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + struct ufs_config_descr *cfg = &hba->cfgs; + char *strbuf; + char *strbuf_copy; + int desc_buf[count]; + int *pt; + char *token; + int i, ret; + int value, commit = 0; + int num_luns = 0; + int KB_per_block = 4; + + /* reserve one byte for null termination */ + strbuf = kmalloc(count + 1, GFP_KERNEL); + if (!strbuf) + return -ENOMEM; + + strbuf_copy = strbuf; + strlcpy(strbuf, buf, count + 1); + + for (i = 0; i < count; i++) { + token = strsep(&strbuf, " "); + if (!token) { + num_luns = desc_buf[i-1]; + dev_dbg(hba->dev, "%s: token %s, num_luns %d\n", + __func__, token, num_luns); + break; + } + + ret = kstrtoint(token, 0, &value); + if (ret) { + dev_err(hba->dev, "%s: kstrtoint failed %d %s\n", + __func__, ret, token); + break; + } + desc_buf[i] = value; + dev_dbg(hba->dev, " desc_buf[%d] 0x%x", i, desc_buf[i]); + } + + /* Fill in the descriptors with parsed configuration data */ + pt = desc_buf; + cfg->bNumberLU = *pt++; + cfg->bBootEnable = *pt++; + cfg->bDescrAccessEn = *pt++; + cfg->bInitPowerMode = *pt++; + cfg->bHighPriorityLUN = *pt++; + cfg->bSecureRemovalType = *pt++; + cfg->bInitActiveICCLevel = *pt++; + cfg->wPeriodicRTCUpdate = *pt++; + cfg->bConfigDescrLock = *pt++; + dev_dbg(hba->dev, "%s: %u %u %u %u %u %u %u %u %u\n", __func__, + cfg->bNumberLU, cfg->bBootEnable, cfg->bDescrAccessEn, + cfg->bInitPowerMode, cfg->bHighPriorityLUN, cfg->bSecureRemovalType, + cfg->bInitActiveICCLevel, cfg->wPeriodicRTCUpdate, + cfg->bConfigDescrLock); + + for (i = 0; i < num_luns; i++) { + cfg->unit[i].LUNum = *pt++; + cfg->unit[i].bLUEnable = *pt++; + cfg->unit[i].bBootLunID = *pt++; + /* dNumAllocUnits = size_in_kb/KB_per_block */ + cfg->unit[i].dNumAllocUnits = (u32)(*pt++ / KB_per_block); + cfg->unit[i].bDataReliability = *pt++; + cfg->unit[i].bLUWriteProtect = *pt++; + cfg->unit[i].bMemoryType = *pt++; + cfg->unit[i].bLogicalBlockSize = *pt++; + cfg->unit[i].bProvisioningType = *pt++; + cfg->unit[i].wContextCapabilities = *pt++; + } + + cfg->lun_to_grow = *pt++; + commit = *pt++; + cfg->num_luns = *pt; + dev_dbg(hba->dev, "%s: lun_to_grow %u, commit %u num_luns %u\n", + __func__, cfg->lun_to_grow, commit, cfg->num_luns); + if (commit == 1) { + ret = ufshcd_do_config_device(hba); + if (!ret) { + hba->ufs_provision.is_enabled = 1; + dev_err(hba->dev, + "%s: UFS Provisioning completed,num_luns %u, reboot now !\n", + __func__, cfg->num_luns); + } + } + + kfree(strbuf_copy); + return count; +} + static ssize_t ufshcd_clkgate_delay_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1638,6 +1738,23 @@ static ssize_t ufshcd_clkgate_enable_store(struct device *dev, return count; } +static void ufshcd_init_ufs_provision(struct ufs_hba *hba) +{ + hba->ufs_provision.enable_attr.show = ufshcd_desc_config_show; + hba->ufs_provision.enable_attr.store = ufshcd_desc_config_store; + sysfs_attr_init(&hba->ufs_provision.enable_attr.attr); + hba->ufs_provision.enable_attr.attr.name = "ufs_provision"; + hba->ufs_provision.enable_attr.attr.mode = 0644; + if (device_create_file(hba->dev, &hba->ufs_provision.enable_attr)) + dev_err(hba->dev, "%s: Failed to create sysfs for ufs_provision\n", + __func__); +} + +static void ufshcd_exit_ufs_provision(struct ufs_hba *hba) +{ + device_remove_file(hba->dev, &hba->ufs_provision.enable_attr); +} + static void ufshcd_init_clk_gating(struct ufs_hba *hba) { if (!ufshcd_is_clkgating_allowed(hba)) @@ -6383,7 +6500,7 @@ static int ufshcd_do_config_device(struct ufs_hba *hba) u32 blocks_per_alloc_unit = 1024; int geo_len = hba->desc_size.geom_desc; u8 geo_buf[hba->desc_size.geom_desc]; - unsigned int max_partitions = 9; + unsigned int max_partitions = 8; WARN_ON(!hba || !cfg); ufshcd_set_dev_ref_clk(hba); @@ -6530,6 +6647,9 @@ static int ufshcd_do_config_device(struct ufs_hba *hba) pt = pt + 3; // Reserved fields set to 0 } + for (i = 0; i < buff_len; i++) + dev_dbg(hba->dev, " desc_buf[%d] 0x%x", i, desc_buf[i]); + ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_WRITE_DESC, QUERY_DESC_IDN_CONFIGURATION, 0, 0, desc_buf, &buff_len); @@ -7888,6 +8008,7 @@ void ufshcd_remove(struct ufs_hba *hba) ufshcd_hba_stop(hba, true); ufshcd_exit_clk_gating(hba); + ufshcd_exit_ufs_provision(hba); if (ufshcd_is_clkscaling_supported(hba)) device_remove_file(hba->dev, &hba->clk_scaling.enable_attr); ufshcd_hba_exit(hba); @@ -8050,6 +8171,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) init_waitqueue_head(&hba->dev_cmd.tag_wq); ufshcd_init_clk_gating(hba); + ufshcd_init_ufs_provision(hba); /* * In order to avoid any spurious interrupt immediately after @@ -8142,6 +8264,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) scsi_remove_host(hba->host); exit_gating: ufshcd_exit_clk_gating(hba); + ufshcd_exit_ufs_provision(hba); out_disable: hba->is_irq_enabled = false; ufshcd_hba_exit(hba); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 0c4b683..3580631 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -364,6 +364,11 @@ struct ufs_clk_gating { int active_reqs; }; +struct ufs_provisioning { + struct device_attribute enable_attr; + bool is_enabled; +}; + struct ufs_saved_pwr_info { struct ufs_pa_layer_attr info; bool is_valid; @@ -652,6 +657,7 @@ struct ufs_hba { struct ufs_pwr_mode_info max_pwr_info; struct ufs_clk_gating clk_gating; + struct ufs_provisioning ufs_provision; /* Control to enable/disable host capabilities */ u32 caps; /* Allow dynamic clk gating */