From patchwork Tue Nov 14 15:46:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 837903 X-Patchwork-Delegate: boris.brezillon@free-electrons.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=65.50.211.133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="HMkO9Mmk"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3ybsMr50KMz9s03 for ; Wed, 15 Nov 2017 02:47:36 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=gmNI0cbT/fzByWxSpo84lf5cd3CsXCtnqoDY/a4/ylQ=; b=HMkO9Mmkz5NRNKGe/AFIt2FuqE N7pVzsVAnrenOCTO5YXGwDijl+QlZuFdRKXqr6JHOdMXQlKBoOM9/K6YzHW5TdC43n7PH02eZQfn5 Xgfr4mcb9nUNK6D8d3sDRRz9Cd5Fd6C+g5qJDftEarwi3KWc07DmWLmg0Oy7teVHkcybGo7auE7G9 sDwXM7ryXSHvv42lr9W7+c3cLgW7TERc+jxsDTJ2800YOL0MwB5sbXJ4QApQxwMMr1W6c8874DgtR wBhX/ZfuoiTuFwfedBXGCUBaDAHYt2Rpd1F0nhX5z+KcqfSvF/d5FHsAKx1OiY66OQ6qPv0qXQ6oi JpSB4S/w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eEdQz-0002xP-2P; Tue, 14 Nov 2017 15:47:33 +0000 Received: from mail.free-electrons.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eEdQS-0002Sm-32 for linux-mtd@lists.infradead.org; Tue, 14 Nov 2017 15:47:06 +0000 Received: by mail.free-electrons.com (Postfix, from userid 110) id 4DCD62083F; Tue, 14 Nov 2017 16:46:37 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 074B820850; Tue, 14 Nov 2017 16:46:27 +0100 (CET) From: Miquel Raynal To: Boris Brezillon , Richard Weinberger , David Woodhouse , Brian Norris , Marek Vasut , Cyrille Pitchen Subject: [PATCH 3/3] mtd: nand: add sysfs entry for NAND chip unique ID Date: Tue, 14 Nov 2017 16:46:22 +0100 Message-Id: <20171114154622.5493-4-miquel.raynal@free-electrons.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171114154622.5493-1-miquel.raynal@free-electrons.com> References: <20171114154622.5493-1-miquel.raynal@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171114_074700_469044_E6ADD9DE X-CRM114-Status: GOOD ( 19.37 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Petazzoni , Quentin Schulz , linux-mtd@lists.infradead.org, Miquel Raynal MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org ONFI NAND chips may support the unique ID feature which is, once concatenated with the NAND manufacturer ID, a real unique ID. It has been tried to make the NAND framework declare a "nand" bus type, with NAND chips being the bus devices and having their particular unique ID. But in this configuration, the chips could not be attached to the MTD class anymore. No easy solution was doable in a reasonable amount of time, so instead it has been chosen to use the mtd_info structure to store the ID and turn it visible only if filled by the NAND framework. Signed-off-by: Miquel Raynal --- drivers/mtd/mtdcore.c | 33 ++++++++++++++++++++++++++++++++- drivers/mtd/nand/nand_base.c | 26 +++++++++++++++++++------- include/linux/mtd/mtd.h | 1 + 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index e7ea842ba3db..d43090348295 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -319,6 +319,15 @@ static ssize_t mtd_bbtblocks_show(struct device *dev, } static DEVICE_ATTR(bbt_blocks, S_IRUGO, mtd_bbtblocks_show, NULL); +static ssize_t nand_unique_id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mtd_info *mtd = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%s\n", mtd->nand_unique_id); +} +static DEVICE_ATTR_RO(nand_unique_id); + static struct attribute *mtd_attrs[] = { &dev_attr_type.attr, &dev_attr_flags.attr, @@ -336,9 +345,31 @@ static struct attribute *mtd_attrs[] = { &dev_attr_bad_blocks.attr, &dev_attr_bbt_blocks.attr, &dev_attr_bitflip_threshold.attr, + &dev_attr_nand_unique_id.attr, + NULL, +}; + +static umode_t mtd_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = kobj_to_dev(kobj); + struct mtd_info *mtd = dev_get_drvdata(dev); + + if (attr == &dev_attr_nand_unique_id.attr && !mtd->nand_unique_id) + return 0; + + return attr->mode; +} + +static const struct attribute_group mtd_group = { + .attrs = mtd_attrs, + .is_visible = mtd_attr_is_visible, +}; + +static const struct attribute_group *mtd_groups[] = { + &mtd_group, NULL, }; -ATTRIBUTE_GROUPS(mtd); static const struct device_type mtd_devtype = { .name = "mtd", diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 0bbc1fc04e01..e5ea3b159551 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -6368,7 +6368,6 @@ int nand_scan_tail(struct mtd_info *mtd) struct nand_chip *chip = mtd_to_nand(mtd); struct nand_ecc_ctrl *ecc = &chip->ecc; struct nand_buffers *nbuf = NULL; - char unique_id[ONFI_FULL_UNIQUEID_STRING_LEN]; int ret, i; /* New bad blocks should be marked in OOB, flash-based BBT, or both */ @@ -6666,9 +6665,15 @@ int nand_scan_tail(struct mtd_info *mtd) mtd->writebufsize = mtd->writesize; /* Read the unique ID from the first die if available */ - chip->select_chip(mtd, 0); - nand_read_unique_id(chip, unique_id); - chip->select_chip(mtd, -1); + mtd->nand_unique_id = kmalloc(ONFI_FULL_UNIQUEID_STRING_LEN, + GFP_KERNEL); + if (mtd->nand_unique_id) { + chip->select_chip(mtd, 0); + ret = nand_read_unique_id(chip, mtd->nand_unique_id); + chip->select_chip(mtd, -1); + if (ret) + kfree(mtd->nand_unique_id); + } /* * Initialize bitflip_threshold to its default prior scan_bbt() call. @@ -6681,7 +6686,7 @@ int nand_scan_tail(struct mtd_info *mtd) /* Initialize the ->data_interface field. */ ret = nand_init_data_interface(chip); if (ret) - goto err_nand_manuf_cleanup; + goto err_free_unique_id; /* Enter fastest possible mode on all dies. */ for (i = 0; i < chip->numchips; i++) { @@ -6690,7 +6695,7 @@ int nand_scan_tail(struct mtd_info *mtd) chip->select_chip(mtd, -1); if (ret) - goto err_nand_manuf_cleanup; + goto err_free_unique_id; } /* Check, if we should skip the bad block table scan */ @@ -6700,10 +6705,12 @@ int nand_scan_tail(struct mtd_info *mtd) /* Build bad block table */ ret = chip->scan_bbt(mtd); if (ret) - goto err_nand_manuf_cleanup; + goto err_free_unique_id; return 0; +err_free_unique_id: + kfree(mtd->nand_unique_id); err_nand_manuf_cleanup: nand_manufacturer_cleanup(chip); @@ -6758,10 +6765,15 @@ EXPORT_SYMBOL(nand_scan); */ void nand_cleanup(struct nand_chip *chip) { + struct mtd_info *mtd = nand_to_mtd(chip); + if (chip->ecc.mode == NAND_ECC_SOFT && chip->ecc.algo == NAND_ECC_BCH) nand_bch_free((struct nand_bch_control *)chip->ecc.priv); + /* Free unique ID if existing */ + kfree(mtd->nand_unique_id); + /* Free bad block table memory */ kfree(chip->bbt); if (!(chip->options & NAND_OWN_BUFFERS) && chip->buffers) { diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 6cd0f6b7658b..817eecd08fb5 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -269,6 +269,7 @@ struct mtd_info { // Kernel-only stuff starts here. const char *name; + u8 *nand_unique_id; int index; /* OOB layout description */