storage_erase.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * MultiMediaCard (MMC), eMMC and Secure Digital (SD) erase support code. 4 * This code is controller independent. 5 */ 6 7 #include "sd_mmc.h" 8 #include "storage.h" 9 10 uint64_t storage_block_erase(struct storage_media *media, uint64_t start, 11 uint64_t count) 12 { 13 struct mmc_command cmd; 14 struct sd_mmc_ctrlr *ctrlr = media->ctrlr; 15 16 if (storage_block_setup(media, start, count, 0) == 0) 17 return 0; 18 19 cmd.cmdidx = MMC_CMD_ERASE_GROUP_START; 20 cmd.resp_type = CARD_RSP_R1; 21 cmd.cmdarg = start; 22 cmd.flags = 0; 23 24 if (ctrlr->send_cmd(ctrlr, &cmd, NULL)) 25 return 0; 26 27 cmd.cmdidx = MMC_CMD_ERASE_GROUP_END; 28 cmd.cmdarg = start + count - 1; 29 cmd.resp_type = CARD_RSP_R1; 30 cmd.flags = 0; 31 32 if (ctrlr->send_cmd(ctrlr, &cmd, NULL)) 33 return 0; 34 35 cmd.cmdidx = MMC_CMD_ERASE; 36 cmd.cmdarg = MMC_TRIM_ARG; /* just unmap blocks */ 37 cmd.resp_type = CARD_RSP_R1; 38 cmd.flags = 0; 39 40 if (ctrlr->send_cmd(ctrlr, &cmd, NULL)) 41 return 0; 42 43 size_t erase_blocks; 44 /* 45 * Timeout for TRIM operation on one erase group is defined as: 46 * TRIM timeout = 300ms x TRIM_MULT 47 * 48 * This timeout is expressed in units of 100us to sd_mmc_send_status. 49 * 50 * Hence, timeout_per_erase_block = TRIM timeout * 1000us/100us; 51 */ 52 size_t timeout_per_erase_block = (media->trim_mult * 300) * 10; 53 int err = 0; 54 55 erase_blocks = ALIGN_UP(count, media->erase_blocks) 56 / media->erase_blocks; 57 58 while (erase_blocks) { 59 /* 60 * To avoid overflow of timeout value, loop in calls to 61 * sd_mmc_send_status for erase_blocks number of times. 62 */ 63 err = sd_mmc_send_status(media, timeout_per_erase_block); 64 65 /* Send status successful, erase action complete. */ 66 if (err == 0) 67 break; 68 69 erase_blocks--; 70 } 71 72 /* Total timeout done. Still status not successful. */ 73 if (err) { 74 sd_mmc_error("TRIM operation not successful within timeout.\n"); 75 return 0; 76 } 77 78 return count; 79 }