[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