[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