From f34abe88a0857d4927506095e3e8134a57fee570 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 13 Dec 2023 17:09:14 +0100 Subject: [PATCH 1/5] drivers/mtd_sdmmc: always enable the erase function --- drivers/include/mtd_sdmmc.h | 22 ---------------------- drivers/mtd_sdmmc/Kconfig | 9 --------- drivers/mtd_sdmmc/mtd_sdmmc.c | 29 +---------------------------- 3 files changed, 1 insertion(+), 59 deletions(-) diff --git a/drivers/include/mtd_sdmmc.h b/drivers/include/mtd_sdmmc.h index 4143813177a2..913e3f6b9f4a 100644 --- a/drivers/include/mtd_sdmmc.h +++ b/drivers/include/mtd_sdmmc.h @@ -45,28 +45,6 @@ typedef struct { uint8_t sdmmc_idx; /**< SD/MMC peripheral index */ } mtd_sdmmc_t; -/** - * @defgroup drivers_mtd_sdmmc_config SD Memory Card driver compile configuration - * @ingroup config_drivers_storage - * @{ - */ -/** - * @brief Enable SD Memory Card Erase - * - * SD Memory Cards and MMCs/eMMCs handle sector erase internally - * so it's possible to directly write to the card without erasing - * the sector first. - * - * @note An erase call will NOT touch the content if `CONFIG_MTD_SDMMC_ERASE` - * is not set, so enable this feature to ensure overriding the data. - * - * @pre This feature requires the `mtd_write_page` module. - */ -#ifdef DOXYGEN -#define CONFIG_MTD_SDMMC_ERASE -#endif -/** @} */ - /** * @brief sdcard device operations table for mtd */ diff --git a/drivers/mtd_sdmmc/Kconfig b/drivers/mtd_sdmmc/Kconfig index ff0134a0c7b3..692a441e3440 100644 --- a/drivers/mtd_sdmmc/Kconfig +++ b/drivers/mtd_sdmmc/Kconfig @@ -23,13 +23,4 @@ config SDMMC_GENERIC_MTD_OFFSET the auto-configured SD Memory Card(s) or MMCs/eMMCs from mtd_sdmmc_default will come after them. -config MTD_SDMMC_ERASE - bool "Enable SD Memory Card erase" - help - Enable this to erase sector before a data write operation (SD Memory - Cards only). - SD Memory Cards and MMCs/eMMCs handle sector erase internally - so it's possible to directly write to the card without erasing - the sector first hence this feature is disabled by default. - endif # KCONFIG_USEMODULE_MTD_SDMMC diff --git a/drivers/mtd_sdmmc/mtd_sdmmc.c b/drivers/mtd_sdmmc/mtd_sdmmc.c index 615704726d6d..552ce8a0a92d 100644 --- a/drivers/mtd_sdmmc/mtd_sdmmc.c +++ b/drivers/mtd_sdmmc/mtd_sdmmc.c @@ -141,35 +141,8 @@ static int mtd_sdmmc_write_page(mtd_dev_t *dev, const void *buff, uint32_t page, static int mtd_sdmmc_erase_sector(mtd_dev_t *dev, uint32_t sector, uint32_t count) { -#if IS_ACTIVE(CONFIG_MTD_SDMMC_ERASE) && IS_USED(MODULE_MTD_WRITE_PAGE) mtd_sdmmc_t *mtd_sd = (mtd_sdmmc_t*)dev; - - DEBUG("mtd_sdmmc_erase_sector: sector: %" PRIu32 " count: %" PRIu32 "\n", - sector, count); - - if (dev->work_area == NULL) { - DEBUG("mtd_sdmmc_erase_sector: no work area\n"); - return -ENOTSUP; - } - memset(dev->work_area, 0, SDMMC_SDHC_BLOCK_SIZE); - while (count) { - if (sdmmc_write_blocks(mtd_sd->sdmmc, sector, SDMMC_SDHC_BLOCK_SIZE, - 1, dev->work_area, NULL)) { - return -EIO; - } - --count; - ++sector; - } -#else - (void)dev; - (void)sector; - (void)count; - mtd_sdmmc_t *mtd_sd = (mtd_sdmmc_t*)dev; - if (IS_ACTIVE(CONFIG_MTD_SDMMC_ERASE)) { - return sdmmc_erase_blocks(mtd_sd->sdmmc, sector, count); - } -#endif - return 0; + return sdmmc_erase_blocks(mtd_sd->sdmmc, sector, count); } static int mtd_sdmmc_power(mtd_dev_t *dev, enum mtd_power_state power) From f57f2a125f8d1086896ebaa27ba9565e3dbd4757 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 13 Dec 2023 21:57:08 +0100 Subject: [PATCH 2/5] drivers/mtd_sdmmc: set MTD_DRIVER_FLAG_DIRECT_WRITE flag --- drivers/mtd_sdmmc/mtd_sdmmc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd_sdmmc/mtd_sdmmc.c b/drivers/mtd_sdmmc/mtd_sdmmc.c index 552ce8a0a92d..77b9ef67ce67 100644 --- a/drivers/mtd_sdmmc/mtd_sdmmc.c +++ b/drivers/mtd_sdmmc/mtd_sdmmc.c @@ -191,6 +191,7 @@ const mtd_desc_t mtd_sdmmc_driver = { .write_page = mtd_sdmmc_write_page, .erase_sector = mtd_sdmmc_erase_sector, .power = mtd_sdmmc_power, + .flags = MTD_DRIVER_FLAG_DIRECT_WRITE, }; #if IS_USED(MODULE_MTD_SDMMC_DEFAULT) From bfe26c68d37683ec48a74efa6a478213bba7616a Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 13 Dec 2023 22:18:19 +0100 Subject: [PATCH 3/5] drivers/mtd: introduce mtd_write_sector() --- drivers/include/mtd.h | 24 ++++++++++++++++++++++++ drivers/mtd/mtd.c | 14 ++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/drivers/include/mtd.h b/drivers/include/mtd.h index b7bef30f57f7..065471e78e83 100644 --- a/drivers/include/mtd.h +++ b/drivers/include/mtd.h @@ -73,6 +73,7 @@ #ifndef MTD_H #define MTD_H +#include #include #include @@ -505,6 +506,29 @@ int mtd_erase(mtd_dev_t *mtd, uint32_t addr, uint32_t count); */ int mtd_erase_sector(mtd_dev_t *mtd, uint32_t sector, uint32_t num); +/** + * @brief Write data to a MTD device with whole sector writes + * + * The MTD layer will take care of splitting up the transaction into multiple + * writes if it is required by the underlying storage media. + * + * The sectors will be erased before writing if needed. + * + * @param mtd Device to write to + * @param[in] src Buffer to write + * @param[in] sector Sector number to start writing to + * @param[in] num Number of sectors to write + * + * @retval n number of bytes written on success + * @retval <0 value on error + * @retval -ENODEV if @p mtd is not a valid device + * @retval -ENOTSUP if operation is not supported on @p mtd + * @retval -EOVERFLOW if @p addr or @p count are not valid, i.e. outside memory, + * @retval -EIO if I/O error occurred + * @retval -EINVAL if parameters are invalid + */ +int mtd_write_sector(mtd_dev_t *mtd, const void *src, uint32_t sector, uint32_t num); + /** * @brief Set power mode on a MTD device * diff --git a/drivers/mtd/mtd.c b/drivers/mtd/mtd.c index f9a6bec4b47b..8d6455039c13 100644 --- a/drivers/mtd/mtd.c +++ b/drivers/mtd/mtd.c @@ -393,6 +393,20 @@ int mtd_erase_sector(mtd_dev_t *mtd, uint32_t sector, uint32_t count) return mtd->driver->erase_sector(mtd, sector, count); } +int mtd_write_sector(mtd_dev_t *mtd, const void *data, uint32_t sector, + uint32_t count) +{ + if (!(mtd->driver->flags & MTD_DRIVER_FLAG_DIRECT_WRITE)) { + int res = mtd_erase_sector(mtd, sector, count); + if (res) { + return res; + } + } + + uint32_t page = sector * mtd->pages_per_sector; + return mtd_write_page_raw(mtd, data, page, 0, page * mtd->page_size); +} + int mtd_power(mtd_dev_t *mtd, enum mtd_power_state power) { if (!mtd || !mtd->driver) { From 31e4592827a8ad6ff684cdebf6ee6d38908d9b40 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 13 Dec 2023 22:20:50 +0100 Subject: [PATCH 4/5] pkg/fatfs: make use of mtd_write_sector() --- pkg/fatfs/fatfs_diskio/mtd/mtd_diskio.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/pkg/fatfs/fatfs_diskio/mtd/mtd_diskio.c b/pkg/fatfs/fatfs_diskio/mtd/mtd_diskio.c index 4c853d27fc20..0fed887f0f36 100644 --- a/pkg/fatfs/fatfs_diskio/mtd/mtd_diskio.c +++ b/pkg/fatfs/fatfs_diskio/mtd/mtd_diskio.c @@ -130,24 +130,13 @@ DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count) */ DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count) { + mtd_dev_t *mtd = fatfs_mtd_devs[pdrv]; DEBUG("disk_write: %d, %lu, %d\n", pdrv, (long unsigned)sector, count); - if ((pdrv >= FF_VOLUMES) || (fatfs_mtd_devs[pdrv]->driver == NULL)) { + if ((pdrv >= FF_VOLUMES) || (mtd->driver == NULL)) { return RES_PARERR; } - /* erase memory before writing to it */ - int res = mtd_erase_sector(fatfs_mtd_devs[pdrv], sector, count); - - if (res != 0) { - return RES_ERROR; /* erase failed! */ - } - - uint32_t sector_size = fatfs_mtd_devs[pdrv]->page_size - * fatfs_mtd_devs[pdrv]->pages_per_sector; - - res = mtd_write_page_raw(fatfs_mtd_devs[pdrv], buff, - sector, 0, count * sector_size); - + int res = mtd_write_sector(mtd, buff, sector, count); if (res != 0) { return RES_ERROR; } From 5e30c0ec8587117096dbebfae6d9bfa7651ea6ad Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 13 Dec 2023 22:23:07 +0100 Subject: [PATCH 5/5] pkg/lwext4: make use of mtd_write_sector() --- pkg/lwext4/fs/lwext4_fs.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/pkg/lwext4/fs/lwext4_fs.c b/pkg/lwext4/fs/lwext4_fs.c index 56abfdb9ea01..55cd18207f6c 100644 --- a/pkg/lwext4/fs/lwext4_fs.c +++ b/pkg/lwext4/fs/lwext4_fs.c @@ -94,20 +94,12 @@ static int blockdev_bwrite(struct ext4_blockdev *bdev, const void *buf, { mtd_dev_t *dev = bdev->bdif->p_user; - uint32_t page = blk_id * dev->pages_per_sector; - uint32_t size = blk_cnt * dev->pages_per_sector * dev->page_size; - assert(blk_id <= UINT32_MAX); - DEBUG("lwext4: erase %"PRIu32" sectors starting with %"PRIu64"\n", blk_cnt, blk_id); - int res = mtd_erase_sector(dev, blk_id, blk_cnt); - if (res) { - return -res; - } - - DEBUG("lwext4: write %"PRIu32" bytes to page %"PRIu32"\n", size, page); + DEBUG("lwext4: write %"PRIu32" bytes to sector %"PRIu32"\n", + blk_cnt * dev->pages_per_sector * dev->page_size, (uint32_t)blk_id); - return -mtd_write_page_raw(dev, buf, page, 0, size); + return -mtd_write_sector(dev, buf, blk_id, blk_cnt); } static int prepare(lwext4_desc_t *fs, const char *mount_point)