From: <Takahiro.Kuwano@infineon.com>
To: <miquel.raynal@bootlin.com>, <pratyush@kernel.org>,
<mwalle@kernel.org>, <richard@nod.at>, <vigneshr@ti.com>,
<corbet@lwn.net>
Cc: <sean.anderson@linux.dev>, <thomas.petazzoni@bootlin.com>,
<STLin2@winbond.com>, <linux-mtd@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, <linux-doc@vger.kernel.org>
Subject: RE: [PATCH v4 17/27] mtd: spi-nor: debugfs: Add locking support
Date: Fri, 10 Apr 2026 04:39:22 +0000 [thread overview]
Message-ID: <c8521e12e49040ce8683f81692644574@infineon.com> (raw)
In-Reply-To: <20260403-winbond-v6-18-rc1-spi-nor-swp-v4-17-833dab5e7288@bootlin.com>
> The ioctl output may be counter intuitive in some cases. Asking for a
> "locked status" over a region that is only partially locked will return
> "unlocked" whereas in practice maybe the biggest part is actually
> locked.
>
> Knowing what is the real software locking state through debugfs would be
> very convenient for development/debugging purposes, hence this proposal
> for adding an extra block at the end of the file: a "locked sectors"
> array which lists every section, if it is locked or not, showing both
> the address ranges and the sizes in numbers of blocks.
>
> Here is an example of output, what is after the "sector map" is new.
>
> $ cat /sys/kernel/debug/spi-nor/spi0.0/params
> name (null)
> id ef a0 20 00 00 00
> size 64.0 MiB
> write size 1
> page size 256
> address nbytes 4
> flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_16BIT_SR | HAS_SR_TB_BIT6 | HAS_4BIT_BP |
> SOFT_RESET | NO_WP
>
> opcodes
> read 0xec
> dummy cycles 6
> erase 0xdc
> program 0x34
> 8D extension none
>
> protocols
> read 1S-4S-4S
> write 1S-1S-4S
> register 1S-1S-1S
>
> erase commands
> 21 (4.00 KiB) [1]
> dc (64.0 KiB) [3]
> c7 (64.0 MiB)
>
> sector map
> region (in hex) | erase mask | overlaid
> ------------------+------------+---------
> 00000000-03ffffff | [ 3] | no
>
> locked sectors
> region (in hex) | status | #blocks
> ------------------+----------+--------
> 00000000-03ffffff | unlocked | 1024
>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
> Here are below more examples of output with various situations. The full
> output of the "params" content has been manually removed to only show
> what has been added and how it behaves.
>
> $ flash_lock -l /dev/mtd0 0x3f00000 16
> $ cat /sys/kernel/debug/spi-nor/spi0.0/params
> locked sectors
> region (in hex) | status | #blocks
> ------------------+----------+--------
> 00000000-03efffff | unlocked | 1008
> 03f00000-03ffffff | locked | 16
> $
> $ flash_lock -u /dev/mtd0 0x3f00000 8
> $ cat /sys/kernel/debug/spi-nor/spi0.0/params
> locked sectors
> region (in hex) | status | #blocks
> ------------------+----------+--------
> 00000000-03f7ffff | unlocked | 1016
> 03f80000-03ffffff | locked | 8
> $
> $ flash_lock -u /dev/mtd0
> $ cat /sys/kernel/debug/spi-nor/spi0.0/params
> locked sectors
> region (in hex) | status | #blocks
> ------------------+----------+--------
> 00000000-03ffffff | unlocked | 1024
> $
> $ flash_lock -l /dev/mtd0
> $ cat /sys/kernel/debug/spi-nor/spi0.0/params
> locked sectors
> region (in hex) | status | #blocks
> ------------------+----------+--------
> 00000000-03ffffff | locked | 1024
> $
> $ flash_lock -u /dev/mtd0 0x20000 1022
> $ cat /sys/kernel/debug/spi-nor/spi0.0/params
> locked sectors
> region (in hex) | status | #blocks
> ------------------+----------+--------
> 00000000-0001ffff | locked | 2
> 00020000-03ffffff | unlocked | 1022
> ---
> drivers/mtd/spi-nor/core.h | 5 +++++
> drivers/mtd/spi-nor/debugfs.c | 27 +++++++++++++++++++++++++++
> drivers/mtd/spi-nor/swp.c | 16 ++++++++++++----
> 3 files changed, 44 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index 091eb934abe4..8717a0ad90f0 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -673,6 +673,7 @@ int spi_nor_post_bfpt_fixups(struct spi_nor *nor,
> const struct sfdp_bfpt *bfpt);
>
> void spi_nor_init_default_locking_ops(struct spi_nor *nor);
> +bool spi_nor_has_default_locking_ops(struct spi_nor *nor);
> void spi_nor_try_unlock_all(struct spi_nor *nor);
> void spi_nor_cache_sr_lock_bits(struct spi_nor *nor, u8 *sr);
> void spi_nor_set_mtd_locking_ops(struct spi_nor *nor);
> @@ -707,6 +708,10 @@ static inline bool spi_nor_needs_sfdp(const struct spi_nor *nor)
> return !nor->info->size;
> }
>
> +u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor);
> +void spi_nor_get_locked_range_sr(struct spi_nor *nor, const u8 *sr, loff_t *ofs, u64 *len);
> +bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len, const u8 *sr);
> +
> #ifdef CONFIG_DEBUG_FS
> void spi_nor_debugfs_register(struct spi_nor *nor);
> void spi_nor_debugfs_shutdown(void);
> diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c
> index d0191eb9f879..298ce3d9e905 100644
> --- a/drivers/mtd/spi-nor/debugfs.c
> +++ b/drivers/mtd/spi-nor/debugfs.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0
>
> #include <linux/debugfs.h>
> +#include <linux/math64.h>
> #include <linux/mtd/spi-nor.h>
> #include <linux/spi/spi.h>
> #include <linux/spi/spi-mem.h>
> @@ -77,10 +78,12 @@ static void spi_nor_print_flags(struct seq_file *s, unsigned long flags,
> static int spi_nor_params_show(struct seq_file *s, void *data)
> {
> struct spi_nor *nor = s->private;
> + unsigned int min_prot_len = spi_nor_get_min_prot_length_sr(nor);
> struct spi_nor_flash_parameter *params = nor->params;
> struct spi_nor_erase_map *erase_map = ¶ms->erase_map;
> struct spi_nor_erase_region *region = erase_map->regions;
> const struct flash_info *info = nor->info;
> + loff_t lock_start, lock_length;
> char buf[16], *str;
> unsigned int i;
>
> @@ -159,6 +162,30 @@ static int spi_nor_params_show(struct seq_file *s, void *data)
> region[i].overlaid ? "yes" : "no");
> }
>
> + if (!spi_nor_has_default_locking_ops(nor))
> + return 0;
> +
> + seq_puts(s, "\nlocked sectors\n");
> + seq_puts(s, " region (in hex) | status | #blocks\n");
> + seq_puts(s, " ------------------+----------+--------\n");
> +
> + spi_nor_get_locked_range_sr(nor, nor->dfs_sr_cache, &lock_start, &lock_length);
> + if (!lock_length || lock_length == params->size) {
> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, params->size - 1,
> + lock_length ? " locked" : "unlocked",
> + div_u64(params->size, min_prot_len));
> + } else if (!lock_start) {
> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, lock_length - 1,
> + " locked", div_u64(lock_length, min_prot_len));
> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", lock_length, params->size - 1,
> + "unlocked", div_u64(params->size - lock_length, min_prot_len));
> + } else {
> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, lock_start - 1,
> + "unlocked", div_u64(lock_start, min_prot_len));
> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", lock_start, params->size - 1,
> + " locked", div_u64(lock_length, min_prot_len));
> + }
> +
> return 0;
> }
> DEFINE_SHOW_ATTRIBUTE(spi_nor_params);
> diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c
> index 7a6c2b8ef921..d75ed83eb787 100644
> --- a/drivers/mtd/spi-nor/swp.c
> +++ b/drivers/mtd/spi-nor/swp.c
> @@ -32,7 +32,7 @@ static u8 spi_nor_get_sr_tb_mask(struct spi_nor *nor)
> return SR_TB_BIT5;
> }
>
> -static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
> +u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
> {
> unsigned int bp_slots, bp_slots_needed;
> /*
> @@ -53,8 +53,8 @@ static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
> return sector_size;
> }
>
> -static void spi_nor_get_locked_range_sr(struct spi_nor *nor, const u8 *sr, loff_t *ofs,
> - u64 *len)
> +void spi_nor_get_locked_range_sr(struct spi_nor *nor, const u8 *sr, loff_t *ofs,
> + u64 *len)
> {
> u64 min_prot_len;
> u8 bp_mask = spi_nor_get_sr_bp_mask(nor);
> @@ -112,7 +112,7 @@ static bool spi_nor_check_lock_status_sr(struct spi_nor *nor, loff_t ofs,
> return (ofs >= lock_offs_max) || (offs_max <= lock_offs);
> }
>
> -static bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len, const u8 *sr)
> +bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len, const u8 *sr)
> {
> return spi_nor_check_lock_status_sr(nor, ofs, len, sr, true);
> }
> @@ -410,6 +410,9 @@ static int spi_nor_sr_is_locked(struct spi_nor *nor, loff_t ofs, u64 len)
> * -is_locked(): Checks if the region is *fully* locked, returns false otherwise.
> * This feeback may be misleading because users may get an "unlocked"
> * status even though a subpart of the region is effectively locked.
> + *
> + * If in doubt during development, check-out the debugfs output which tries to
> + * be more user friendly.
> */
> static const struct spi_nor_locking_ops spi_nor_sr_locking_ops = {
> .lock = spi_nor_sr_lock,
> @@ -422,6 +425,11 @@ void spi_nor_init_default_locking_ops(struct spi_nor *nor)
> nor->params->locking_ops = &spi_nor_sr_locking_ops;
> }
>
> +bool spi_nor_has_default_locking_ops(struct spi_nor *nor)
> +{
> + return nor->params->locking_ops == &spi_nor_sr_locking_ops;
> +}
> +
> static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, u64 len)
> {
> struct spi_nor *nor = mtd_to_spi_nor(mtd);
>
> --
> 2.53.0
Reviewed-by: Takahiro Kuwano <takahiro.kuwano@infineon.com>
Thanks,
Takahiro
next prev parent reply other threads:[~2026-04-10 4:39 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-03 16:09 [PATCH v4 00/27] mtd: spi-nor: Enhance software protection Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 01/27] mtd: spi-nor: Drop duplicate Kconfig dependency Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 02/27] mtd: spi-nor: debugfs: Fix the flags list Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 03/27] mtd: spi-nor: swp: Improve locking user experience Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 04/27] mtd: spi-nor: Improve opcodes documentation Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 05/27] mtd: spi-nor: debugfs: Align variable access with the rest of the file Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 06/27] mtd: spi-nor: debugfs: Enhance output Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 07/27] mtd: spi-nor: swp: Explain the MEMLOCK ioctl implementation behaviour Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 08/27] mtd: spi-nor: swp: Clarify a comment Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 09/27] mtd: spi-nor: swp: Use a pointer for SR instead of a single byte Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 10/27] mtd: spi-nor: swp: Create a helper that writes SR, CR and checks Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 11/27] mtd: spi-nor: swp: Rename a mask Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 12/27] mtd: spi-nor: swp: Create a TB intermediate variable Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 13/27] mtd: spi-nor: swp: Create helpers for building the SR register Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 14/27] mtd: spi-nor: swp: Simplify checking the locked/unlocked range Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 15/27] mtd: spi-nor: swp: Cosmetic changes Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 16/27] mtd: spi-nor: Create a local SR cache Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 17/27] mtd: spi-nor: debugfs: Add locking support Miquel Raynal
2026-04-10 4:39 ` Takahiro.Kuwano [this message]
2026-04-03 16:09 ` [PATCH v4 18/27] mtd: spi-nor: debugfs: Add a locked sectors map Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 19/27] mtd: spi-nor: Add steps for testing locking support Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 20/27] mtd: spi-nor: swp: Add support for the complement feature Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 21/27] mtd: spi-nor: Add steps for testing locking with CMP Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 22/27] mtd: spi-nor: winbond: Add W25H512NWxxAM CMP locking support Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 23/27] mtd: spi-nor: winbond: Add W25H01NWxxAM " Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 24/27] mtd: spi-nor: winbond: Add W25H02NWxxAM " Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 25/27] mtd: spi-nor: winbond: Add W25H01NWxxIQ " Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 26/27] mtd: spi-nor: winbond: Add W25Q01NWxxIM " Miquel Raynal
2026-04-03 16:09 ` [PATCH v4 27/27] mtd: spi-nor: winbond: Add W25Q02NWxxIM " Miquel Raynal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c8521e12e49040ce8683f81692644574@infineon.com \
--to=takahiro.kuwano@infineon.com \
--cc=STLin2@winbond.com \
--cc=corbet@lwn.net \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=miquel.raynal@bootlin.com \
--cc=mwalle@kernel.org \
--cc=pratyush@kernel.org \
--cc=richard@nod.at \
--cc=sean.anderson@linux.dev \
--cc=thomas.petazzoni@bootlin.com \
--cc=vigneshr@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox