Received: by 10.223.176.5 with SMTP id f5csp2444050wra; Mon, 5 Feb 2018 04:17:39 -0800 (PST) X-Google-Smtp-Source: AH8x225/12uWvIpxGVp8WskLzJbybSAC+NG5QajJUx96zk9Wvre5PTKQ7zhej4n1FRfxUWwrLLLK X-Received: by 10.101.65.205 with SMTP id b13mr9233305pgq.280.1517833059019; Mon, 05 Feb 2018 04:17:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517833058; cv=none; d=google.com; s=arc-20160816; b=qQxTFnDGh/kq3U8mZH8FHd3miR89S+AD28SzyUX9g6m8yj5dUWMTk0s1k+dXgYu98j pUF460wNu8pVZZRYR3mQiMIlHAs8c7qWHNyorBGiiZ1+TCATUb2q9kEVLW9Cw9TmCefx 9NcIkpZJqwbFgSdkA3Ebe8ENHjczSza0MdFd++b3305pbz1X7QYgJBK9NNKi/JdjTYjD LvSuc3l9vi/ME7M3zaBPW50W82Mh1DH9aMmvLX2v/fSqw8eJYOxtzmcNwvgZxvEtQWfM PCH62z/cNWEffX7n0qSHL3jW/DKj5mpBbVnX5X6FbmeCNJUC+8jmuIfvm1JhxQqGz/j7 HfGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=1r4433ENx8y4H/ckBWfOVbluQFxF6eqymljGoXAsiCk=; b=jbFMHP3HpQ+RoxTE/5f3VJ3VixNDkh1Bd4PlK6G1HYNcfuLBfExTDi+FLosxv205RO CDe9YF5jS70MoGqz/7qXsSX1LfxioCUEKnoYByXV8CFnY5JBGseZy7NCdnV6HX7FEG7I mKRSncmGEMuINvn2NarydqzJdkHETiHnouahIvJYJWSE7fEazXLFOi2J3ecHxdPrpOJn r7d4F7MOaQJ3a8Tjaa6eEmMyn1OB49LOT1DMs49aQgtxCOcJlauWp0V6lxSp4tT94Skg qa4dqbIutw0g99OsDHJ88VrN8NnE5lPbo4TjxkOexnur2+JVsxCj1Hn4gUI5jz7ZKzYF HfoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lightnvm-io.20150623.gappssmtp.com header.s=20150623 header.b=xO+d4r9q; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e11si3764525pgn.374.2018.02.05.04.17.24; Mon, 05 Feb 2018 04:17:38 -0800 (PST) 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; dkim=pass header.i=@lightnvm-io.20150623.gappssmtp.com header.s=20150623 header.b=xO+d4r9q; 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 S1753032AbeBEMQN (ORCPT + 99 others); Mon, 5 Feb 2018 07:16:13 -0500 Received: from mail-lf0-f67.google.com ([209.85.215.67]:41811 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752843AbeBEMPk (ORCPT ); Mon, 5 Feb 2018 07:15:40 -0500 Received: by mail-lf0-f67.google.com with SMTP id f136so41401814lff.8 for ; Mon, 05 Feb 2018 04:15:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lightnvm-io.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1r4433ENx8y4H/ckBWfOVbluQFxF6eqymljGoXAsiCk=; b=xO+d4r9qSQ0GXk9ds9tr9d58N3vaArQa56x8MnmQzE3AvI1RDSenfkjts6Ohyd8vZ3 GiX3S5s90uUyMiyUCJ8njlNbTRbkb3rHR9db4hmFY1vQyLvTf5KepG53+g65TyBm6MYF DEhi4irlW2uR9B6lozx0j3Q2n0W8VBjpkJgM5oD5bepWc2yz+xjQc83xOiHnXRRPDqzC XmfxpBbQzNUDPR8pu8a7WVo6OBVn8Avnj2zWl2hR8spTxuX3EujfKvpP6IAt7URh5qYf Ujm6kqdHoyR3IhePB/qQ5JWW4sp11DfqPmMOCot/IuPBYRhSKRLTFmYrwiXDY/jj0vSm VazQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1r4433ENx8y4H/ckBWfOVbluQFxF6eqymljGoXAsiCk=; b=Q4sCrlowok0YX6ZxbwC0BzP1EeOw4i2h+sZYe1CtjbA+A2TTeSCPmR6PKTdLih/pjs o5TE22tRvccmfgVI6e3HL4/WgxtBfEzUhA1OObzlMNUr1qT8zmMwE71WmArp9P7dbvqR azGA5Nd6lSvQXlzq6k/rZybFPe2ZB21tdDzEybADOFkhhnWP/+b4pUp1GmlBFfWsAxug tynSYfF3g90WU85LBCwMYsGaHbcm4oZliLGxw9xVnoXlM1UqgM4rRszHiV4koQqc0uiI hRJhRBUq9FvfcWad91Kj7mIjArOLttHamK2YXeX82w1qUi/WEtf7Q42AU8l2makSgo29 fdNA== X-Gm-Message-State: AKwxytePgS8i+s4Rkqilncfme15ClUfg1lhbneUlE8Aet0oNQ69MSblW PDEa2wWW7VWi6ZVwMXewwFMlsA== X-Received: by 10.25.228.146 with SMTP id x18mr30153893lfi.115.1517832937823; Mon, 05 Feb 2018 04:15:37 -0800 (PST) Received: from Macroninja.cnexlabs.com (x1-6-a4-08-f5-18-3c-3a.cpe.webspeed.dk. [188.176.29.198]) by smtp.gmail.com with ESMTPSA id r88sm1784817lje.30.2018.02.05.04.15.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 05 Feb 2018 04:15:36 -0800 (PST) From: =?UTF-8?q?Matias=20Bj=C3=B8rling?= To: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org, javier@cnexlabs.com, =?UTF-8?q?Matias=20Bj=C3=B8rling?= Subject: [PATCH 3/4] lightnvm: add 2.0 geometry identification Date: Mon, 5 Feb 2018 13:15:04 +0100 Message-Id: <20180205121505.27563-4-mb@lightnvm.io> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180205121505.27563-1-mb@lightnvm.io> References: <20180205121505.27563-1-mb@lightnvm.io> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Implement the geometry data structures for 2.0 and enable a drive to be identified as one, including exposing the appropriate 2.0 sysfs entries. Signed-off-by: Matias Bjørling --- drivers/lightnvm/core.c | 2 +- drivers/nvme/host/lightnvm.c | 334 +++++++++++++++++++++++++++++++++++++------ include/linux/lightnvm.h | 11 +- 3 files changed, 295 insertions(+), 52 deletions(-) diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index c72863b36439..250e74dfa120 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c @@ -934,7 +934,7 @@ static int nvm_init(struct nvm_dev *dev) pr_debug("nvm: ver:%x nvm_vendor:%x\n", dev->identity.ver_id, dev->identity.vmnt); - if (dev->identity.ver_id != 1) { + if (dev->identity.ver_id != 1 && dev->identity.ver_id != 2) { pr_err("nvm: device not supported by kernel."); goto err; } diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c index 6412551ecc65..a9c010655ccc 100644 --- a/drivers/nvme/host/lightnvm.c +++ b/drivers/nvme/host/lightnvm.c @@ -184,6 +184,58 @@ struct nvme_nvm_bb_tbl { __u8 blk[0]; }; +struct nvme_nvm_id20_addrf { + __u8 grp_len; + __u8 pu_len; + __u8 chk_len; + __u8 lba_len; + __u8 resv[4]; +}; + +struct nvme_nvm_id20 { + __u8 mjr; + __u8 mnr; + __u8 resv[6]; + + struct nvme_nvm_id20_addrf lbaf; + + __u32 mccap; + __u8 resv2[12]; + + __u8 wit; + __u8 resv3[31]; + + /* Geometry */ + __u16 num_grp; + __u16 num_pu; + __u32 num_chk; + __u32 clba; + __u8 resv4[52]; + + /* Write data requirements */ + __u32 ws_min; + __u32 ws_opt; + __u32 mw_cunits; + __u32 maxoc; + __u32 maxocpu; + __u8 resv5[44]; + + /* Performance related metrics */ + __u32 trdt; + __u32 trdm; + __u32 twrt; + __u32 twrm; + __u32 tcrst; + __u32 tcrsm; + __u8 resv6[40]; + + /* Reserved area */ + __u8 resv7[2816]; + + /* Vendor specific */ + __u8 vs[1024]; +}; + /* * Check we didn't inadvertently grow the command struct */ @@ -198,6 +250,8 @@ static inline void _nvme_nvm_check_size(void) BUILD_BUG_ON(sizeof(struct nvme_nvm_id12_addrf) != 16); BUILD_BUG_ON(sizeof(struct nvme_nvm_id12) != NVME_IDENTIFY_DATA_SIZE); BUILD_BUG_ON(sizeof(struct nvme_nvm_bb_tbl) != 64); + BUILD_BUG_ON(sizeof(struct nvme_nvm_id20_addrf) != 8); + BUILD_BUG_ON(sizeof(struct nvme_nvm_id20) != NVME_IDENTIFY_DATA_SIZE); } static int init_grp(struct nvm_id *nvm_id, struct nvme_nvm_id12 *id12) @@ -256,6 +310,49 @@ static int init_grp(struct nvm_id *nvm_id, struct nvme_nvm_id12 *id12) return 0; } +static int nvme_nvm_setup_12(struct nvm_dev *nvmdev, struct nvm_id *nvm_id, + struct nvme_nvm_id12 *id) +{ + nvm_id->ver_id = id->ver_id; + nvm_id->vmnt = id->vmnt; + nvm_id->cap = le32_to_cpu(id->cap); + nvm_id->dom = le32_to_cpu(id->dom); + memcpy(&nvm_id->ppaf, &id->ppaf, + sizeof(struct nvm_addr_format)); + + return init_grp(nvm_id, id); +} + +static int nvme_nvm_setup_20(struct nvm_dev *nvmdev, struct nvm_id *nvm_id, + struct nvme_nvm_id20 *id) +{ + nvm_id->ver_id = id->mjr; + + nvm_id->num_ch = le16_to_cpu(id->num_grp); + nvm_id->num_lun = le16_to_cpu(id->num_pu); + nvm_id->num_chk = le32_to_cpu(id->num_chk); + nvm_id->clba = le32_to_cpu(id->clba); + + nvm_id->ws_min = le32_to_cpu(id->ws_min); + nvm_id->ws_opt = le32_to_cpu(id->ws_opt); + nvm_id->mw_cunits = le32_to_cpu(id->mw_cunits); + + nvm_id->trdt = le32_to_cpu(id->trdt); + nvm_id->trdm = le32_to_cpu(id->trdm); + nvm_id->tprt = le32_to_cpu(id->twrt); + nvm_id->tprm = le32_to_cpu(id->twrm); + nvm_id->tbet = le32_to_cpu(id->tcrst); + nvm_id->tbem = le32_to_cpu(id->tcrsm); + + /* calculated values */ + nvm_id->ws_per_chk = nvm_id->clba / nvm_id->ws_min; + + /* 1.2 compatibility */ + nvm_id->ws_seq = NVM_IO_SNGL_ACCESS; + + return 0; +} + static int nvme_nvm_identity(struct nvm_dev *nvmdev, struct nvm_id *nvm_id) { struct nvme_ns *ns = nvmdev->q->queuedata; @@ -277,14 +374,24 @@ static int nvme_nvm_identity(struct nvm_dev *nvmdev, struct nvm_id *nvm_id) goto out; } - nvm_id->ver_id = id->ver_id; - nvm_id->vmnt = id->vmnt; - nvm_id->cap = le32_to_cpu(id->cap); - nvm_id->dom = le32_to_cpu(id->dom); - memcpy(&nvm_id->ppaf, &id->ppaf, - sizeof(struct nvm_addr_format)); - - ret = init_grp(nvm_id, id); + /* + * The 1.2 and 2.0 specifications share the first byte in their geometry + * command to make it possible to know what version a device implements. + */ + switch (id->ver_id) { + case 1: + ret = nvme_nvm_setup_12(nvmdev, nvm_id, id); + break; + case 2: + ret = nvme_nvm_setup_20(nvmdev, nvm_id, + (struct nvme_nvm_id20 *)id); + break; + default: + dev_err(ns->ctrl->device, + "OCSSD revision not supported (%d)\n", + nvm_id->ver_id); + ret = -EINVAL; + } out: kfree(id); return ret; @@ -733,7 +840,7 @@ void nvme_nvm_unregister(struct nvme_ns *ns) } static ssize_t nvm_dev_attr_show(struct device *dev, - struct device_attribute *dattr, char *page) + struct device_attribute *dattr, char *page) { struct nvme_ns *ns = nvme_get_ns_from_dev(dev); struct nvm_dev *ndev = ns->ndev; @@ -748,10 +855,36 @@ static ssize_t nvm_dev_attr_show(struct device *dev, if (strcmp(attr->name, "version") == 0) { return scnprintf(page, PAGE_SIZE, "%u\n", id->ver_id); - } else if (strcmp(attr->name, "vendor_opcode") == 0) { - return scnprintf(page, PAGE_SIZE, "%u\n", id->vmnt); } else if (strcmp(attr->name, "capabilities") == 0) { return scnprintf(page, PAGE_SIZE, "%u\n", id->cap); + } else if (strcmp(attr->name, "read_typ") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->trdt); + } else if (strcmp(attr->name, "read_max") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->trdm); + } else { + return scnprintf(page, + PAGE_SIZE, + "Unhandled attr(%s) in `nvm_dev_attr_show`\n", + attr->name); + } +} + +static ssize_t nvm_dev_attr_show_12(struct device *dev, + struct device_attribute *dattr, char *page) +{ + struct nvme_ns *ns = nvme_get_ns_from_dev(dev); + struct nvm_dev *ndev = ns->ndev; + struct nvm_id *id; + struct attribute *attr; + + if (!ndev) + return 0; + + id = &ndev->identity; + attr = &dattr->attr; + + if (strcmp(attr->name, "vendor_opcode") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->vmnt); } else if (strcmp(attr->name, "device_mode") == 0) { return scnprintf(page, PAGE_SIZE, "%u\n", id->dom); /* kept for compatibility */ @@ -786,10 +919,6 @@ static ssize_t nvm_dev_attr_show(struct device *dev, return scnprintf(page, PAGE_SIZE, "%u\n", id->csecs); } else if (strcmp(attr->name, "oob_sector_size") == 0) {/* u32 */ return scnprintf(page, PAGE_SIZE, "%u\n", id->sos); - } else if (strcmp(attr->name, "read_typ") == 0) { - return scnprintf(page, PAGE_SIZE, "%u\n", id->trdt); - } else if (strcmp(attr->name, "read_max") == 0) { - return scnprintf(page, PAGE_SIZE, "%u\n", id->trdm); } else if (strcmp(attr->name, "prog_typ") == 0) { return scnprintf(page, PAGE_SIZE, "%u\n", id->tprt); } else if (strcmp(attr->name, "prog_max") == 0) { @@ -808,48 +937,99 @@ static ssize_t nvm_dev_attr_show(struct device *dev, } else { return scnprintf(page, PAGE_SIZE, - "Unhandled attr(%s) in `nvm_dev_attr_show`\n", + "Unhandled attr(%s) in `nvm_dev_attr_show_12`\n", attr->name); } } -#define NVM_DEV_ATTR_RO(_name) \ +static ssize_t nvm_dev_attr_show_20(struct device *dev, + struct device_attribute *dattr, char *page) +{ + struct nvme_ns *ns = nvme_get_ns_from_dev(dev); + struct nvm_dev *ndev = ns->ndev; + struct nvm_id *id; + struct attribute *attr; + + if (!ndev) + return 0; + + id = &ndev->identity; + attr = &dattr->attr; + + if (strcmp(attr->name, "groups") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->num_ch); + } else if (strcmp(attr->name, "punits") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->num_lun); + } else if (strcmp(attr->name, "chunks") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->num_chk); + } else if (strcmp(attr->name, "clba") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->clba); + } else if (strcmp(attr->name, "ws_min") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->ws_min); + } else if (strcmp(attr->name, "ws_opt") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->ws_opt); + } else if (strcmp(attr->name, "mw_cunits") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->mw_cunits); + } else if (strcmp(attr->name, "write_typ") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->tprt); + } else if (strcmp(attr->name, "write_max") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->tprm); + } else if (strcmp(attr->name, "reset_typ") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->tbet); + } else if (strcmp(attr->name, "reset_max") == 0) { + return scnprintf(page, PAGE_SIZE, "%u\n", id->tbem); + } else { + return scnprintf(page, + PAGE_SIZE, + "Unhandled attr(%s) in `nvm_dev_attr_show_20`\n", + attr->name); + } +} + +#define NVM_DEV_ATTR_RO(_name) \ DEVICE_ATTR(_name, S_IRUGO, nvm_dev_attr_show, NULL) +#define NVM_DEV_ATTR_12_RO(_name) \ + DEVICE_ATTR(_name, S_IRUGO, nvm_dev_attr_show_12, NULL) +#define NVM_DEV_ATTR_20_RO(_name) \ + DEVICE_ATTR(_name, S_IRUGO, nvm_dev_attr_show_20, NULL) +/* general attributes */ static NVM_DEV_ATTR_RO(version); -static NVM_DEV_ATTR_RO(vendor_opcode); static NVM_DEV_ATTR_RO(capabilities); -static NVM_DEV_ATTR_RO(device_mode); -static NVM_DEV_ATTR_RO(ppa_format); -static NVM_DEV_ATTR_RO(media_manager); -static NVM_DEV_ATTR_RO(media_type); -static NVM_DEV_ATTR_RO(flash_media_type); -static NVM_DEV_ATTR_RO(num_channels); -static NVM_DEV_ATTR_RO(num_luns); -static NVM_DEV_ATTR_RO(num_planes); -static NVM_DEV_ATTR_RO(num_blocks); -static NVM_DEV_ATTR_RO(num_pages); -static NVM_DEV_ATTR_RO(page_size); -static NVM_DEV_ATTR_RO(hw_sector_size); -static NVM_DEV_ATTR_RO(oob_sector_size); static NVM_DEV_ATTR_RO(read_typ); static NVM_DEV_ATTR_RO(read_max); -static NVM_DEV_ATTR_RO(prog_typ); -static NVM_DEV_ATTR_RO(prog_max); -static NVM_DEV_ATTR_RO(erase_typ); -static NVM_DEV_ATTR_RO(erase_max); -static NVM_DEV_ATTR_RO(multiplane_modes); -static NVM_DEV_ATTR_RO(media_capabilities); -static NVM_DEV_ATTR_RO(max_phys_secs); -static struct attribute *nvm_dev_attrs[] = { +/* 1.2 values */ +static NVM_DEV_ATTR_12_RO(vendor_opcode); +static NVM_DEV_ATTR_12_RO(device_mode); +static NVM_DEV_ATTR_12_RO(ppa_format); +static NVM_DEV_ATTR_12_RO(media_manager); +static NVM_DEV_ATTR_12_RO(media_type); +static NVM_DEV_ATTR_12_RO(flash_media_type); +static NVM_DEV_ATTR_12_RO(num_channels); +static NVM_DEV_ATTR_12_RO(num_luns); +static NVM_DEV_ATTR_12_RO(num_planes); +static NVM_DEV_ATTR_12_RO(num_blocks); +static NVM_DEV_ATTR_12_RO(num_pages); +static NVM_DEV_ATTR_12_RO(page_size); +static NVM_DEV_ATTR_12_RO(hw_sector_size); +static NVM_DEV_ATTR_12_RO(oob_sector_size); +static NVM_DEV_ATTR_12_RO(prog_typ); +static NVM_DEV_ATTR_12_RO(prog_max); +static NVM_DEV_ATTR_12_RO(erase_typ); +static NVM_DEV_ATTR_12_RO(erase_max); +static NVM_DEV_ATTR_12_RO(multiplane_modes); +static NVM_DEV_ATTR_12_RO(media_capabilities); +static NVM_DEV_ATTR_12_RO(max_phys_secs); + +static struct attribute *nvm_dev_attrs_12[] = { &dev_attr_version.attr, + &dev_attr_capabilities.attr, + &dev_attr_vendor_opcode.attr, - &dev_attr_capabilities.attr, &dev_attr_device_mode.attr, &dev_attr_media_manager.attr, - &dev_attr_ppa_format.attr, &dev_attr_media_type.attr, &dev_attr_flash_media_type.attr, @@ -870,22 +1050,82 @@ static struct attribute *nvm_dev_attrs[] = { &dev_attr_multiplane_modes.attr, &dev_attr_media_capabilities.attr, &dev_attr_max_phys_secs.attr, + + NULL, +}; + +static const struct attribute_group nvm_dev_attr_group_12 = { + .name = "lightnvm", + .attrs = nvm_dev_attrs_12, +}; + +/* 2.0 values */ +static NVM_DEV_ATTR_20_RO(groups); +static NVM_DEV_ATTR_20_RO(punits); +static NVM_DEV_ATTR_20_RO(chunks); +static NVM_DEV_ATTR_20_RO(clba); +static NVM_DEV_ATTR_20_RO(ws_min); +static NVM_DEV_ATTR_20_RO(ws_opt); +static NVM_DEV_ATTR_20_RO(mw_cunits); +static NVM_DEV_ATTR_20_RO(write_typ); +static NVM_DEV_ATTR_20_RO(write_max); +static NVM_DEV_ATTR_20_RO(reset_typ); +static NVM_DEV_ATTR_20_RO(reset_max); + +static struct attribute *nvm_dev_attrs_20[] = { + &dev_attr_version.attr, + &dev_attr_capabilities.attr, + + &dev_attr_groups.attr, + &dev_attr_punits.attr, + &dev_attr_chunks.attr, + &dev_attr_clba.attr, + &dev_attr_ws_min.attr, + &dev_attr_ws_opt.attr, + &dev_attr_mw_cunits.attr, + + &dev_attr_read_typ.attr, + &dev_attr_read_max.attr, + &dev_attr_write_typ.attr, + &dev_attr_write_max.attr, + &dev_attr_reset_typ.attr, + &dev_attr_reset_max.attr, + NULL, }; -static const struct attribute_group nvm_dev_attr_group = { +static const struct attribute_group nvm_dev_attr_group_20 = { .name = "lightnvm", - .attrs = nvm_dev_attrs, + .attrs = nvm_dev_attrs_20, }; int nvme_nvm_register_sysfs(struct nvme_ns *ns) { - return sysfs_create_group(&disk_to_dev(ns->disk)->kobj, - &nvm_dev_attr_group); + if (!ns->ndev) + return -EINVAL; + + switch (ns->ndev->identity.ver_id) { + case 1: + return sysfs_create_group(&disk_to_dev(ns->disk)->kobj, + &nvm_dev_attr_group_12); + case 2: + return sysfs_create_group(&disk_to_dev(ns->disk)->kobj, + &nvm_dev_attr_group_20); + } + + return -EINVAL; } void nvme_nvm_unregister_sysfs(struct nvme_ns *ns) { - sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, - &nvm_dev_attr_group); + switch (ns->ndev->identity.ver_id) { + case 1: + sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, + &nvm_dev_attr_group_12); + break; + case 2: + sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, + &nvm_dev_attr_group_20); + break; + } } diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h index 94b704a8d83d..b717c000b712 100644 --- a/include/linux/lightnvm.h +++ b/include/linux/lightnvm.h @@ -184,10 +184,9 @@ struct nvm_id { u16 csecs; u16 sos; - u16 ws_min; - u16 ws_opt; - u16 ws_seq; - u16 ws_per_chk; + u32 ws_min; + u32 ws_opt; + u32 mw_cunits; u32 trdt; u32 trdm; @@ -199,6 +198,10 @@ struct nvm_id { u32 mccap; u16 cpar; + /* calculated values */ + u16 ws_seq; + u16 ws_per_chk; + /* 1.2 compatibility */ u8 mtype; u8 fmtype; -- 2.11.0