ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, const void *src) #endif { #ifdef CONFIG_BLK struct blk_desc *block_dev = dev_get_uclass_platdata(dev); #endif int dev_num = block_dev->devnum; lbaint_t cur, blocks_todo = blkcnt; int err; struct mmc *mmc = find_mmc_device(dev_num); if (!mmc) return 0; err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, block_dev->hwpart); if (err < 0) return 0; if (mmc_set_blocklen(mmc, mmc->write_bl_len)) return 0; do { cur = (blocks_todo > mmc->cfg->b_max) ? mmc->cfg->b_max : blocks_todo; if (mmc_write_blocks(mmc, start, cur, src) != cur) return 0; blocks_todo -= cur; start += cur; src += cur * mmc->write_bl_len; } while (blocks_todo > 0); return blkcnt; }
static void fini_mmc_for_env(struct mmc *mmc) { #ifdef CONFIG_SYS_MMC_ENV_PART int dev = mmc_get_env_dev(); blk_select_hwpart_devnum(IF_TYPE_MMC, dev, env_mmc_orig_hwpart); #endif }
static int mmc_set_env_part(struct mmc *mmc) { uint part = mmc_get_env_part(mmc); int dev = mmc_get_env_dev(); int ret = 0; env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart; ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part); if (ret) puts("MMC partition switch failed\n"); return ret; }
unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) { int dev_num = block_dev->devnum; int err = 0; u32 start_rem, blkcnt_rem; struct mmc *mmc = find_mmc_device(dev_num); lbaint_t blk = 0, blk_r = 0; int timeout = 1000; if (!mmc) return -1; err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, block_dev->hwpart); if (err < 0) return -1; /* * We want to see if the requested start or total block count are * unaligned. We discard the whole numbers and only care about the * remainder. */ err = div_u64_rem(start, mmc->erase_grp_size, &start_rem); err = div_u64_rem(blkcnt, mmc->erase_grp_size, &blkcnt_rem); if (start_rem || blkcnt_rem) printf("\n\nCaution! Your devices Erase group is 0x%x\n" "The erase range would be change to " "0x" LBAF "~0x" LBAF "\n\n", mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1), ((start + blkcnt + mmc->erase_grp_size) & ~(mmc->erase_grp_size - 1)) - 1); while (blk < blkcnt) { blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ? mmc->erase_grp_size : (blkcnt - blk); err = mmc_erase_t(mmc, start + blk, blk_r); if (err) break; blk += blk_r; /* Waiting for the ready status */ if (mmc_send_status(mmc, timeout)) return 0; } return blk; }