#include <linux/math64.h>
#include "mmc_private.h"
-static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
+static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args)
{
struct mmc_cmd cmd;
ulong end;
goto err_out;
cmd.cmdidx = MMC_CMD_ERASE;
- cmd.cmdarg = MMC_ERASE_ARG;
+ cmd.cmdarg = args ? args : MMC_ERASE_ARG;
cmd.resp_type = MMC_RSP_R1b;
err = mmc_send_cmd(mmc, &cmd, NULL);
#endif
int dev_num = block_dev->devnum;
int err = 0;
- u32 start_rem, blkcnt_rem;
+ u32 start_rem, blkcnt_rem, erase_args = 0;
struct mmc *mmc = find_mmc_device(dev_num);
lbaint_t blk = 0, blk_r = 0;
int timeout_ms = 1000;
*/
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 - 1)
- & ~(mmc->erase_grp_size - 1)) - 1);
+ if (start_rem || blkcnt_rem) {
+ if (mmc->can_trim) {
+ /* Trim function applies the erase operation to write
+ * blocks instead of erase groups.
+ */
+ erase_args = MMC_TRIM_ARG;
+ } else {
+ /* The card ignores all LSB's below the erase group
+ * size, rounding down the addess to a erase group
+ * boundary.
+ */
+ 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 - 1)
+ & ~(mmc->erase_grp_size - 1)) - 1);
+ }
+ }
while (blk < blkcnt) {
if (IS_SD(mmc) && mmc->ssr.au) {
blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
mmc->erase_grp_size : (blkcnt - blk);
}
- err = mmc_erase_t(mmc, start + blk, blk_r);
+ err = mmc_erase_t(mmc, start + blk, blk_r, erase_args);
if (err)
break;