diff --git a/SDBlockDevice.cpp b/SDBlockDevice.cpp index e47f6d593e..6dcd502390 100644 --- a/SDBlockDevice.cpp +++ b/SDBlockDevice.cpp @@ -545,9 +545,17 @@ int SDBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size) return status; } -int SDBlockDevice::erase(bd_addr_t addr, bd_size_t size) +bool SDBlockDevice::_is_valid_trim(bd_addr_t addr, bd_size_t size) { - if (!is_valid_erase(addr, size)) { + return ( + addr % _erase_size == 0 && + size % _erase_size == 0 && + addr + size <= this->size()); +} + +int SDBlockDevice::trim(bd_addr_t addr, bd_size_t size) +{ + if (!_is_valid_trim(addr, size)) { return SD_BLOCK_DEVICE_ERROR_PARAMETER; } @@ -558,15 +566,7 @@ int SDBlockDevice::erase(bd_addr_t addr, bd_size_t size) } int status = BD_ERROR_OK; - // Toss out erases that are too small, this is fine as the block device api - // doesn't garuntee the final state of erased bytes and a following program - // will still work fine. - if (size < _erase_size) { - _lock.unlock(); - return status; - } - - size -= _erase_size; + size -= _block_size; // SDSC Card (CCS=0) uses byte unit address // SDHC and SDXC Cards (CCS=1) use block unit address (512 Bytes unit) if (SDCARD_V2HC == _card_type) { @@ -600,11 +600,6 @@ bd_size_t SDBlockDevice::get_program_size() const return _block_size; } -bd_size_t SDBlockDevice::get_erase_size() const -{ - return _block_size; -} - bd_size_t SDBlockDevice::size() const { bd_size_t sectors = 0; diff --git a/SDBlockDevice.h b/SDBlockDevice.h index 8d46a986de..8da96d79c3 100644 --- a/SDBlockDevice.h +++ b/SDBlockDevice.h @@ -85,15 +85,18 @@ public: */ virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size); - /** Erase blocks on a block device + /** Mark blocks as no longer in use * - * The state of an erased block is undefined until it has been programmed + * This function provides a hint to the underlying block device that a region of blocks + * is no longer in use and may be erased without side effects. Erase must still be called + * before programming, but trimming allows flash-translation-layers to schedule erases when + * the device is not busy. * - * @param addr Address of block to begin erasing - * @param size Size to erase in bytes, must be a multiple of erase block size + * @param addr Address of block to mark as unused + * @param size Size to mark as unused in bytes, must be a multiple of erase block size * @return 0 on success, negative error code on failure */ - virtual int erase(bd_addr_t addr, bd_size_t size); + virtual int trim(bd_addr_t addr, bd_size_t size); /** Get the size of a readable block * @@ -108,13 +111,6 @@ public: */ virtual bd_size_t get_program_size() const; - /** Get the size of a eraseable block - * - * @return Size of a eraseable block in bytes - * @note Must be a multiple of the program size - */ - virtual bd_size_t get_erase_size() const; - /** Get the total size of the underlying device * * @return Size of the underlying device in bytes @@ -196,6 +192,8 @@ private: uint32_t _sectors; uint32_t _sd_sectors(); + bool _is_valid_trim(bd_addr_t addr, bd_size_t size); + /* SPI functions */ Timer _spi_timer; /**< Timer Class object used for busy wait */ uint32_t _init_sck; /**< Intial SPI frequency */