/* * protect: 1 means permanent write protect. Right now only allow this * protection method */ static ssize_t gpp_wp_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) { long protect; struct mmc_card *card = mmc_dev_to_card(dev); int err; if (card == NULL) return -ENODEV; if (kstrtol(buf, 10, &protect) != 0 || protect != (u32)protect) return -EINVAL; if (protect != PERMANENT_PROTECT) return -EINVAL; device_lock(dev); if (gpp_wppart != EXT_CSD_PART_CONFIG_ACC_GP0 || gpp_wpgroup != GPP_WPG0) { device_unlock(dev); return -EINVAL; } err = mmc_set_user_wp(card, gpp_wppart, gpp_wpgroup); if (err) { pr_err("%s: err to set write protect\n", __func__); n = err; } device_unlock(dev); return n; }
int mmc_write_prot_on_part(const char *part, mmc_write_prot_type type) { int rc, fd; struct mmc_part_info info; char device[PATH_MAX], *test; __u8 extcsd[512]; __u32 rca, wp_grp_sz; uint32_t i, wpst, wped; rc = mmc_part_info_get(part, &info); if (rc < 0) return -1; strncpy(device, info.path, sizeof(device)); test = strstr(device, "mmcblk"); if (test) { test += 6; while (isdigit(*test)) test++; *test = '\0'; } fd = open(device, O_RDWR); if (fd < 0) return -1; rc = mmc_read_extcsd(fd, extcsd); if (rc) { close(fd); return -1; } rc = mmc_get_wp_grp_sz(extcsd, &wp_grp_sz); if (rc) { close(fd); return -1; } rc = mmc_send_rca(fd, &rca); if (rc) { // close(fd); // return -1; rca = 0x0001; } rc = mmc_set_class_6_ctrl(fd, 0); if (rc) { close(fd); return -1; } rc = mmc_set_user_wp(fd, type); if (rc) { close(fd); return -1; } wpst = info.offset & ~(wp_grp_sz - 1); wped = (info.offset + info.size) & ~(wp_grp_sz - 1); for (i = wpst; i < wped; i += wp_grp_sz) { // set 1 group // printf("%08x\n", i); rc = mmc_set_write_prot(fd, i); if (rc) { // printf("failed 2\n"); break; } } mmc_clr_user_wp(fd); close(fd); return i == wped ? 0 : -1; }