[U-Boot] [PATCH] mmc: implement mmc power on write protect function

hl hl at rock-chips.com
Mon Dec 14 03:16:31 CET 2015


Hi Simon,

     Thanks for reviewing, i have upload a new patch to fix your comment.

On 11/12/15 11:20, Simon Glass wrote:
> 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
>
>
>

-- 
Lin Huang




More information about the U-Boot mailing list