From mboxrd@z Thu Jan 1 00:00:00 1970 From: hl Date: Mon, 14 Dec 2015 10:16:31 +0800 Subject: [U-Boot] [PATCH] mmc: implement mmc power on write protect function In-Reply-To: References: <1449131661-9139-1-git-send-email-hl@rock-chips.com> Message-ID: <566E267F.3090605@rock-chips.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 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 >> --- >> 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