[U-Boot] [PATCH v10 22/27] cmd: spinor: sync/update protect command

Jagan Teki
2017-12-28T06:12:28Z

sync the protect command from legacy cmd/sf.c and
update them according to current spi-nor framework.

Signed-off-by: Suneel Garapati <suneelglinux@gmail.com>
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
cmd/spinor.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
drivers/mtd/mtd-uclass.c | 19 +++++++++++++++++++
include/mtd.h | 11 +++++++++++
3 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/cmd/spinor.c b/cmd/spinor.c
index b781151..ef8decf 100644
--- a/cmd/spinor.c
+++ b/cmd/spinor.c
@@ -151,6 +151,44 @@ static int do_spinor_write_read(int argc, char * const argv[])
return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
}

+static int do_spinor_protect(int argc, char * const argv[])
+{
+ struct mtd_info *mtd;
+ struct spi_nor *nor;
+ loff_t sector, len, maxsize;
+ char *endp;
+ int idx = 0;
+ bool prot = false;
+ int ret = CMD_RET_FAILURE;
+
+ if (argc != 4)
+ return CMD_RET_USAGE;
+
+ nor = init_spinor_device(curr_device, false);
+ if (!nor)
+ return CMD_RET_FAILURE;
+
+ sector = simple_strtoul(argv[2], &endp, 16);
+ if (*argv[2] == 0 || *endp != 0)
+ return CMD_RET_FAILURE;
+
+ mtd = spi_nor_get_mtd_info(nor);
+ if (mtd_arg_off_size(argc - 3, &argv[3], &idx, &sector, &len,
+ &maxsize, MTD_DEV_TYPE_NOR, mtd->size))
+ return CMD_RET_FAILURE;
+
+ if (strcmp(argv[1], "lock") == 0)
+ prot = true;
+ else if (strcmp(argv[1], "unlock") == 0)
+ prot = false;
+ else
+ return -1; /* Unknown parameter */
+
+ ret = mtd_dprotect(mtd, sector, len, prot);
+
+ return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
+}
+
static int mtd_parse_len_arg(struct mtd_info *mtd, char *arg, loff_t *len)
{
char *ep;
@@ -258,6 +296,11 @@ static int do_spinor(cmd_tbl_t *cmdtp, int flag, int argc,
goto done;
}

+ if (strcmp(cmd, "protect") == 0) {
+ ret = do_spinor_protect(argc, argv);
+ goto done;
+ }
+
done:
if (ret != -1)
return ret;
@@ -272,7 +315,9 @@ static char spinor_help_text[] =
"spinor dev [devnum] - show or set current spinor device\n"
"spinor erase offset len - erase 'len' bytes from 'offset'\n"
"spinor write addr to len - write 'len' bytes to 'to' from 'addr'\n"
- "spinor read addr from len - read 'len' bytes from 'from' to 'addr'";
+ "spinor read addr from len - read 'len' bytes from 'from' to 'addr'\n"
+ "spinor protect lock/unlock sector len - protect/unprotect 'len' bytes starting\n"
+ " at address 'sector'";

U_BOOT_CMD(
spinor, 5, 1, do_spinor,
diff --git a/drivers/mtd/mtd-uclass.c b/drivers/mtd/mtd-uclass.c
index d9ecfea..535f68e 100644
--- a/drivers/mtd/mtd-uclass.c
+++ b/drivers/mtd/mtd-uclass.c
@@ -73,6 +73,25 @@ int mtd_dwrite(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
return ops->write(dev, to, len, retlen, buf);
}

+int mtd_dprotect(struct mtd_info *mtd, loff_t ofs, uint64_t len, bool prot)
+{
+ struct udevice *dev = mtd->dev;
+ const struct mtd_ops *ops = mtd_get_ops(dev);
+
+ if (!ops->lock || !ops->unlock)
+ return -ENOSYS;
+
+ if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs)
+ return -EINVAL;
+ if (!len)
+ return 0;
+
+ if (prot)
+ return ops->lock(dev, ofs, len);
+ else
+ return ops->unlock(dev, ofs, len);
+}
+
int mtd_find_device(int mtd_if_type, int devnum, struct udevice **devp)
{
struct uclass *uc;
diff --git a/include/mtd.h b/include/mtd.h
index acb2256..6390133 100644
--- a/include/mtd.h
+++ b/include/mtd.h
@@ -61,6 +61,17 @@ int mtd_dwrite(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
const u_char *buf);

/**
+ * mtd_dprotect - protect area of MTD device
+ *
+ * @mtd: MTD device
+ * @ofs: sector start offset into device in bytes to protect to
+ * @len: len of bytes to protect
+ * @prot: protect boolean, true for lock, false for unlock
+ * @return 0 if OK, -ve on error
+ */
+int mtd_dprotect(struct mtd_info *mtd, loff_t ofs, uint64_t len, bool prot);
+
+/**
* mtd_derase() - erase blocks of the MTD device
*
* @mtd: MTD device
--
2.7.4