On Tue, Jul 15, 2025 at 06:04:07PM +0300, Роман wrote: > >From 29246e776674a73e4dd93ee15f7c94cb5d99a797 Mon Sep 17 00:00:00 2001 >From: Urovsky R <urov...@swemel.ru> >Date: Sat, 12 Jul 2025 19:29:53 +0300 >Subject: [PATCH] mmc: Set write protect for eMMC user area > >Set write protect configuration for the specified region of the user area for >the device. >Available modes for region are: 'none', 'temp', 'poweron'. >'perm' mode not realized. You better use mmc-utils from Linux for that mode. >The idea and most of the source code take from project "mmc-utils"
Please explain a bit here why you wanna introduce this in U-Boot and the benefit. > >Signed-off-by: Urovsky Roman <r...@inbox.ru> >--- > cmd/mmc.c | 373 ++++++++++++++++++++++++++++++++++++++++++++++ > drivers/mmc/mmc.c | 2 +- > include/mmc.h | 16 ++ Please also update doc/usage/cmd/mmc.rst > 3 files changed, 390 insertions(+), 1 deletion(-) > >diff --git a/cmd/mmc.c b/cmd/mmc.c >index 5340a58be8e..d8c6def4a1a 100644 >--- a/cmd/mmc.c >+++ b/cmd/mmc.c >@@ -18,6 +18,26 @@ > #include <vsprintf.h> > #include <linux/ctype.h> > >+extern int mmc_poll_for_busy(struct mmc *mmc, int timeout_ms); >+extern int mmc_send_cmd_retry(struct mmc *mmc, struct mmc_cmd *cmd, struct >mmc_data *data, uint retries); This is in mmc_private.h, please not use extern and run checkpatch.pl for your patch. To add write protect, need put code under drivers/mmc/ and export API to cmd/mmc.c >+ >+#define WP_BLKS_PER_QUERY 32 >+ >+#define WPTYPE_NONE 0 >+#define WPTYPE_TEMP 1 >+#define WPTYPE_PWRON 2 >+#define WPTYPE_PERM 3 >+ >+static int do_writeprotect_user_get(void); >+static int do_writeprotect_user_set(int argc, char *const argv[]); >+ >+static char *prot_desc[] = { >+ "No", >+ "Temporary", >+ "Power-on", >+ "Permanent" >+}; >+ > static int curr_device = -1; > > static void print_mmcinfo(struct mmc *mmc) >@@ -1228,10 +1248,33 @@ static int do_mmc_reg(struct cmd_tbl *cmdtp, int flag, > } > #endif > >+int do_mmc_user_wp(struct cmd_tbl *cmdtp, int flag, >+ int argc, char * const argv[]) >+{ >+ int err; >+/* >+ printf("argc = %d\n", argc); >+ for (int i = 0; i < argc; i++) { >+ printf("argv[%d] = %s\n", i, argv[i]); >+ } >+*/ Drop this. >+ if ( argc >= 2 ) { >+ err = do_writeprotect_user_set(argc, argv); >+ >+ if (err) >+ return CMD_RET_FAILURE; >+ } >+ >+ do_writeprotect_user_get(); check return value? >+ >+ return CMD_RET_SUCCESS; >+} >+ > static struct cmd_tbl cmd_mmc[] = { > U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""), > U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""), > U_BOOT_CMD_MKENT(wp, 2, 0, do_mmc_boot_wp, "", ""), >+ U_BOOT_CMD_MKENT(user-wp, 4, 0, do_mmc_user_wp, "", ""), > #if CONFIG_IS_ENABLED(MMC_WRITE) > U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""), > U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""), >@@ -1315,6 +1358,15 @@ U_BOOT_CMD( > " PART - [0|1]\n" > " : 0 - first boot partition, 1 - second boot partition\n" > " if not assigned, write protect all boot partitions\n" >+ "mmc user-wp - Get the write protect info for user area\n" >+ "mmc user-wp [type] all - Set the write protect for the full region of >the user area\n" >+ "mmc user-wp [type] [start-block] [blocks] - Set the write protect for >the specified region of the user area\n" >+ " type: \n" >+ " none - Clear temporary write protection\n" >+ " temp - Set temporary write protection\n" >+ " pwron - Set write protection until the next power on\n" >+ " start-block - specifies the first block of the protected area. 'all' >- to protect all user area\n" >+ " blocks - specifies the size of the protected area in blocks \n" > #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING) > "mmc hwpartition <USER> <GP> <MODE> - does hardware partitioning\n" > " arguments (sizes in 512-byte blocks):\n" >@@ -1366,3 +1418,324 @@ U_BOOT_CMD( > "display MMC info", > "- display info of the current MMC device" > ); >+ >+ >+static int get_wp_group_size_in_blks(u8 *ext_csd, u32 *size) >+{ >+ u8 ext_csd_rev = ext_csd[EXT_CSD_REV]; >+ >+ if ((ext_csd_rev < 5) || (ext_csd[EXT_CSD_ERASE_GROUP_DEF] == 0)) { >+ printf("EXT_CSD_REV = %d\n", ext_csd[EXT_CSD_REV]); >+ printf("EXT_CSD_ERASE_GROUP_DEF = %d\n", >ext_csd[EXT_CSD_ERASE_GROUP_DEF]); >+ return 1; >+ } >+ >+ *size = ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * >+ ext_csd[EXT_CSD_HC_WP_GRP_SIZE] * 1024; Add blank line. >+ return 0; >+} >+ >+ >+static int send_write_protect_type(struct mmc *mmc, u32 blk_addr, u64 >*group_bits) >+{ >+ int ret = 0; >+ >+ struct mmc_cmd cmd; >+ struct mmc_data data; >+ >+ u8 buf[8] = {0}; >+ u64 bits = 0; >+ int x; >+ >+ Extra blank line. >+ /* Get the Card Status Register */ >+ cmd.cmdidx = MMC_SEND_WRITE_PROT_TYPE; >+ cmd.resp_type = MMC_RSP_R1 | MMC_CMD_ADTC; >+ cmd.cmdarg = blk_addr; >+ >+ data.dest = (char *)buf; >+ data.blocks = 1; >+ data.blocksize = 8; >+ data.flags = MMC_DATA_READ; >+ >+ ret = mmc_send_cmd(mmc, &cmd, &data); >+ if ( ret != 0 ) { >+ printf("Error: mmc_send_cmd()\n"); >+ return 1; >+ } >+ >+ >+ for (x = 0; x < sizeof(buf); x++) >+ bits |= (u64)(buf[7 - x]) << (x * 8); >+ *group_bits = bits; >+ >+ return 0; >+} >+ >+ Extra blank line. Please cleanup your patch first and run checkpatch, I will look into details on V2. Thanks, Peng