[U-Boot] [PATCH] mmc: implement mmc power on write protect function
Simon Glass
sjg at chromium.org
Fri Dec 11 04:20:28 CET 2015
Hi Lin,
On 3 December 2015 at 01:34, Lin Huang <hl at rock-chips.com> wrote:
> set the mmc specific addresss and range as power on
> write protection, and can't earse and write this range
> if you enable it after mmc power on.
>
> Signed-off-by: Lin Huang <hl at rock-chips.com>
> ---
> drivers/mmc/mmc.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/mmc.h | 10 ++++++-
> 2 files changed, 98 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 2a58702..60ff5be 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -1819,6 +1819,95 @@ int mmc_initialize(bd_t *bis)
> return 0;
> }
>
> +int mmc_get_wp_status(struct mmc *mmc, lbaint_t addr, char *status)
> +{
> + struct mmc_cmd cmd;
> + struct mmc_data data;
> + int err;
> +
> + cmd.cmdidx = MMC_CMD_WRITE_PROT_TYPE;
> + cmd.resp_type = MMC_RSP_R1;
> + cmd.cmdarg = addr;
> +
> + data.dest = status;
> + data.blocksize = 8;
> + data.blocks = 1;
> + data.flags = MMC_DATA_READ;
> +
> + err = mmc_send_cmd(mmc, &cmd, &data);
> + if (err)
> + return err;
> + return err;
return 0 I think
Unless you just want to always return err.
> +}
> +
> +int mmc_usr_power_on_wp(struct mmc *mmc, lbaint_t addr, unsigned int size)
> +{
> + int err;
> + unsigned int wp_group_size, wp_grp_num, i;
> + struct mmc_cmd cmd;
> + unsigned int timeout = 1000;
> +
drop blank line
> + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
> +
> + size = size / MMC_MAX_BLOCK_LEN;
> +
> + err = mmc_send_ext_csd(mmc, ext_csd);
> + if (err)
> + return err;
> +
> + if ((ext_csd[EXT_CSD_USER_WP] & EXT_CSD_USER_PERM_WP_EN) ||
> + (ext_csd[EXT_CSD_USER_WP] & EXT_CSD_USER_PWR_WP_DIS)) {
> + printf("Power on protection is disabled\n");
> + return -1;
Can you run a real error in errno.h to return?
> + }
> +
> + if (ext_csd[EXT_CSD_ERASE_GROUP_DEF])
> + wp_group_size = ext_csd[EXT_CSD_HC_WP_GRP_SIZE] *
> + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
> + else {
> + int erase_gsz, erase_gmul, wp_grp_size;
> +
> + erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
> + erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
> + wp_grp_size = (mmc->csd[2] & 0x0000001f);
> + wp_group_size = (erase_gsz + 1) * (erase_gmul + 1) *
> + (wp_grp_size + 1);
> + }
> +
> + if (size < wp_group_size) {
> + printf("wrong size, fail to set power on wp\n");
> + return -1;
Can you run a real error in errno.h to return?
> + }
> +
> + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
> + EXT_CSD_USER_WP, EXT_CSD_USER_PWR_WP_EN);
> + if (err)
> + return err;
> +
> + wp_grp_num = DIV_ROUND_UP(size, wp_group_size);
> + cmd.cmdidx = MMC_CMD_WRITE_PROT;
> + cmd.resp_type = MMC_RSP_R1b;
> +
> + for (i = 0; i < wp_grp_num; i++) {
> + cmd.cmdarg = addr + i * wp_group_size;
> + err = mmc_send_cmd(mmc, &cmd, NULL);
> + if (err)
> + return err;
> +
> + /* CMD28/CMD29 ON failure returns address out of range error */
> + if ((cmd.response[0] >> 31) & 0x01) {
> + printf("address for CMD28/29 out of range\n");
> + return -1;
-EINVAL?
> + }
> +
> + err = mmc_send_status(mmc, timeout);
> + if (err)
> + return err;
> + }
> +
> + return 0;
> +}
> +
> #ifdef CONFIG_SUPPORT_EMMC_BOOT
> /*
> * This function changes the size of boot partition and the size of rpmb
> diff --git a/include/mmc.h b/include/mmc.h
> index cda9a19..448d5a8 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -89,6 +89,8 @@
> #define MMC_CMD_SET_BLOCK_COUNT 23
> #define MMC_CMD_WRITE_SINGLE_BLOCK 24
> #define MMC_CMD_WRITE_MULTIPLE_BLOCK 25
> +#define MMC_CMD_WRITE_PROT 28
> +#define MMC_CMD_WRITE_PROT_TYPE 31
> #define MMC_CMD_ERASE_GROUP_START 35
> #define MMC_CMD_ERASE_GROUP_END 36
> #define MMC_CMD_ERASE 38
> @@ -175,6 +177,7 @@
> #define EXT_CSD_WR_REL_PARAM 166 /* R */
> #define EXT_CSD_WR_REL_SET 167 /* R/W */
> #define EXT_CSD_RPMB_MULT 168 /* RO */
> +#define EXT_CSD_USER_WP 171
> #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
> #define EXT_CSD_BOOT_BUS_WIDTH 177
> #define EXT_CSD_PART_CONF 179 /* R/W */
> @@ -231,6 +234,10 @@
> #define EXT_CSD_WR_DATA_REL_USR (1 << 0) /* user data area WR_REL */
> #define EXT_CSD_WR_DATA_REL_GP(x) (1 << ((x)+1)) /* GP part (x+1) WR_REL */
>
> +#define EXT_CSD_USER_PWR_WP_DIS (1 << 3) /* disable power-on write protect*/
> +#define EXT_CSD_USER_PERM_WP_EN (1 << 2) /* enable permanent write protect */
> +#define EXT_CSD_USER_PWR_WP_EN (1 << 0) /* enable power-on write protect */
> +
> #define R1_ILLEGAL_COMMAND (1 << 22)
> #define R1_APP_CMD (1 << 5)
>
> @@ -477,7 +484,8 @@ int cpu_mmc_init(bd_t *bis);
> int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr);
>
> struct pci_device_id;
> -
> +int mmc_usr_power_on_wp(struct mmc *mmc, lbaint_t addr, unsigned int size);
> +int mmc_get_wp_status(struct mmc *mmc, lbaint_t addr, char *status);
Can you please add full function comments for these?
> /**
> * pci_mmc_init() - set up PCI MMC devices
> *
> --
> 1.9.1
>
Regards,
Simon
More information about the U-Boot
mailing list