storage_write.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * MultiMediaCard (MMC), eMMC and Secure Digital (SD) write support code. 4 * This code is controller independent. 5 */ 6 7 #include <stdlib.h> 8 9 #include "sd_mmc.h" 10 #include "storage.h" 11 12 static uint32_t storage_write(struct storage_media *media, uint32_t start, 13 uint64_t block_count, const void *src) 14 { 15 struct mmc_command cmd; 16 struct sd_mmc_ctrlr *ctrlr = media->ctrlr; 17 18 cmd.resp_type = CARD_RSP_R1; 19 cmd.flags = 0; 20 21 if (block_count > 1) 22 cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; 23 else 24 cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK; 25 26 if (media->high_capacity) 27 cmd.cmdarg = start; 28 else 29 cmd.cmdarg = start * media->write_bl_len; 30 31 struct mmc_data data; 32 data.src = src; 33 data.blocks = block_count; 34 data.blocksize = media->write_bl_len; 35 data.flags = DATA_FLAG_WRITE; 36 37 if (ctrlr->send_cmd(ctrlr, &cmd, &data)) { 38 sd_mmc_error("Write failed\n"); 39 return 0; 40 } 41 42 /* SPI multiblock writes terminate using a special 43 * token, not a STOP_TRANSMISSION request. 44 */ 45 if ((block_count > 1) && !(ctrlr->caps 46 & DRVR_CAP_AUTO_CMD12)) { 47 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; 48 cmd.cmdarg = 0; 49 cmd.resp_type = CARD_RSP_R1b; 50 cmd.flags = CMD_FLAG_IGNORE_INHIBIT; 51 if (ctrlr->send_cmd(ctrlr, &cmd, NULL)) { 52 sd_mmc_error("Failed to send stop cmd\n"); 53 return 0; 54 } 55 56 /* Waiting for the ready status */ 57 sd_mmc_send_status(media, SD_MMC_IO_RETRIES); 58 } 59 60 return block_count; 61 } 62 63 uint64_t storage_block_write(struct storage_media *media, uint64_t start, 64 uint64_t count, const void *buffer) 65 { 66 const uint8_t *src = (const uint8_t *)buffer; 67 68 if (storage_block_setup(media, start, count, 0) == 0) 69 return 0; 70 71 uint64_t todo = count; 72 struct sd_mmc_ctrlr *ctrlr = media->ctrlr; 73 do { 74 uint64_t cur = MIN(todo, ctrlr->b_max); 75 if (storage_write(media, start, cur, src) != cur) 76 return 0; 77 todo -= cur; 78 start += cur; 79 src += cur * media->write_bl_len; 80 } while (todo > 0); 81 return count; 82 } 83 84 uint64_t storage_block_fill_write(struct storage_media *media, uint64_t start, 85 uint64_t count, uint32_t fill_pattern) 86 { 87 if (storage_block_setup(media, start, count, 0) == 0) 88 return 0; 89 90 struct sd_mmc_ctrlr *ctrlr = media->ctrlr; 91 uint64_t block_size = media->write_bl_len; 92 /* 93 * We allocate max 4 MiB buffer on heap and set it to fill_pattern and 94 * perform mmc_write operation using this 4MiB buffer until requested 95 * size on disk is written by the fill byte. 96 * 97 * 4MiB was chosen after repeating several experiments with the max 98 * buffer size to be used. Using 1 lba i.e. block_size buffer results in 99 * very large fill_write time. On the other hand, choosing 4MiB, 8MiB or 100 * even 128 Mib resulted in similar write times. With 2MiB, the 101 * fill_write time increased by several seconds. So, 4MiB was chosen as 102 * the default max buffer size. 103 */ 104 uint64_t heap_lba = (4 * MiB) / block_size; 105 /* 106 * Actual allocated buffer size is minimum of three entities: 107 * 1) 4MiB equivalent in lba 108 * 2) count: Number of lbas to overwrite 109 * 3) ctrlr->b_max: Max lbas that the block device allows write 110 * operation on at a time. 111 */ 112 uint64_t buffer_lba = MIN(MIN(heap_lba, count), ctrlr->b_max); 113 114 uint64_t buffer_bytes = buffer_lba * block_size; 115 uint64_t buffer_words = buffer_bytes / sizeof(uint32_t); 116 uint32_t *buffer = malloc(buffer_bytes); 117 uint32_t *ptr = buffer; 118 119 for (; buffer_words ; buffer_words--) 120 *ptr++ = fill_pattern; 121 122 uint64_t todo = count; 123 int ret = 0; 124 125 do { 126 uint64_t curr_lba = MIN(buffer_lba, todo); 127 128 if (storage_write(media, start, curr_lba, buffer) != curr_lba) 129 goto cleanup; 130 todo -= curr_lba; 131 start += curr_lba; 132 } while (todo > 0); 133 134 ret = count; 135 136 cleanup: 137 free(buffer); 138 return ret; 139 }