/*             ----> DO NOT REMOVE THE FOLLOWING NOTICE <----

                   Copyright (c) 2014-2015 Datalight, Inc.
                       All Rights Reserved Worldwide.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; use version 2 of the License.

    This program is distributed in the hope that it will be useful,
    but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*  Businesses and individuals that for commercial or other reasons cannot
    comply with the terms of the GPLv2 license may obtain a commercial license
    before incorporating Reliance Edge into proprietary software for
    distribution in any form.  Visit http://www.datalight.com/reliance-edge for
    more information.
*/
/** @file
    @brief Implements block device I/O.
*/
#include <FreeRTOS.h>

#include <redfs.h>
#include <redvolume.h>
#include <redosdeviations.h>


/*------------------------------------------------------------------------------
    Porting Note:

    Several example implementations of this module for FreeRTOS are available.
    If you are lucky, you can use one of these implementations; otherwise, these
    can serve as examples of how to implement this service.
------------------------------------------------------------------------------*/

/** @brief The F_DRIVER example implementation.

    This implementation is designed to reuse an existing block device driver
    that was written for FreeRTOS+FAT SL.  If you have such a driver, with
    little work it can be "dropped in" and used for Reliance Edge.  The only
    customization required is that gpfnRedOsBDevInit needs to be defined and
    pointed at the F_DRIVERINIT function.  This can be done in this module or in
    another C file.

    The disadantage of using the FreeRTOS F_DRIVER functions is that they only
    support single-sector reads and writes.  Reliance Edge will issue
    multi-sector requests, and servicing these one sector at a time will
    significantly slow down the file system.
*/
#define BDEV_F_DRIVER       (0U)

/** @brief The FatFs example implementation.

    This implementation is designed to reuse an existing block device driver
    that was written for FatFs.  If you have such a driver, it can be linked
    in and used immediately.  The FatFs `diskio.h` header must be in the include
    directory path.
*/
#define BDEV_FATFS          (1U)

/** @brief The Atmel Studio Framework SD/MMC driver example implementation.

    This implementation uses a modified version of the open source SD/MMC driver
    included in the Atmel Studio Framework (ASF) and will work as-is for many
    varieties of Atmel hardware.  This example assumes relatively minor
    modifications to the ASF SD/MMC driver to make it support multi-sector read
    and write requests, which greatly improves performance.  The modified driver
    is distributed with Reliance Edge and is included in FreeRTOS Atmel projects
    (such as in projects/freertos/atmel/sam4e-ek/src/ASF).

    This example can easily be modified to work with an unmodified version of
    the ASF SD/MMC driver.  Simply replace sd_mmc_mem_2_ram_multi() and
    sd_mmc_ram_2_mem_multi() with sd_mmc_mem_2_ram() and sd_mmc_ram_2_mem()
    respectively, and add a for loop to loop over each sector in the request.
    However, as described in the manual, there are considerable performance
    advantages to issuing real multi-sector requests, so using the modified
    driver is recommended.
*/
#define BDEV_ATMEL_SDMMC    (2U)

/** @brief The ST Microelectronics STM32 SDIO driver example implementation.

    This implementation accesses the microSD card through the BSP utilities
    provided as part of the STM32Cube package, used with the STM32 HAL drivers.
    The STM3240G-EVAL and STM32F746NG-Discovery boards are currently supported.
*/
#define BDEV_STM32_SDIO     (3U)

/** @brief The RAM disk example implementation.

    This implementation uses a RAM disk.  It will allow you to compile and test
    Reliance Edge even if your storage driver is not yet ready.  On typical
    target hardware, the amount of spare RAM will be limited so generally only
    very small disks will be available.
*/
#define BDEV_RAM_DISK       (4U)

/** @brief Pick which example implementation is compiled.

    Must be one of:
    - #BDEV_F_DRIVER
    - #BDEV_FATFS
    - #BDEV_ATMEL_SDMMC
    - #BDEV_STM32_SDIO
    - #BDEV_RAM_DISK
*/
#define BDEV_EXAMPLE_IMPLEMENTATION BDEV_RAM_DISK


static REDSTATUS DiskOpen(uint8_t bVolNum, BDEVOPENMODE mode);
static REDSTATUS DiskClose(uint8_t bVolNum);
static REDSTATUS DiskRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer);
#if REDCONF_READ_ONLY == 0
static REDSTATUS DiskWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer);
static REDSTATUS DiskFlush(uint8_t bVolNum);
#endif


/** @brief Initialize a block device.

    This function is called when the file system needs access to a block
    device.

    Upon successful return, the block device should be fully initialized and
    ready to service read/write/flush/close requests.

    The behavior of calling this function on a block device which is already
    open is undefined.

    @param bVolNum  The volume number of the volume whose block device is being
                    initialized.
    @param mode     The open mode, indicating the type of access required.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EINVAL @p bVolNum is an invalid volume number.
    @retval -RED_EIO    A disk I/O error occurred.
*/
REDSTATUS RedOsBDevOpen(
    uint8_t         bVolNum,
    BDEVOPENMODE    mode)
{
    REDSTATUS       ret;

    if(bVolNum >= REDCONF_VOLUME_COUNT)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        ret = DiskOpen(bVolNum, mode);
    }

    return ret;
}


/** @brief Uninitialize a block device.

    This function is called when the file system no longer needs access to a
    block device.  If any resource were allocated by RedOsBDevOpen() to service
    block device requests, they should be freed at this time.

    Upon successful return, the block device must be in such a state that it
    can be opened again.

    The behavior of calling this function on a block device which is already
    closed is undefined.

    @param bVolNum  The volume number of the volume whose block device is being
                    uninitialized.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EINVAL @p bVolNum is an invalid volume number.
*/
REDSTATUS RedOsBDevClose(
    uint8_t     bVolNum)
{
    REDSTATUS   ret;

    if(bVolNum >= REDCONF_VOLUME_COUNT)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        ret = DiskClose(bVolNum);
    }

    return ret;
}


/** @brief Read sectors from a physical block device.

    The behavior of calling this function is undefined if the block device is
    closed or if it was opened with ::BDEV_O_WRONLY.

    @param bVolNum          The volume number of the volume whose block device
                            is being read from.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to read.
    @param pBuffer          The buffer into which to read the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is
                        `NULL`, or @p ullStartSector and/or @p ulSectorCount
                        refer to an invalid range of sectors.
    @retval -RED_EIO    A disk I/O error occurred.
*/
REDSTATUS RedOsBDevRead(
    uint8_t     bVolNum,
    uint64_t    ullSectorStart,
    uint32_t    ulSectorCount,
    void       *pBuffer)
{
    REDSTATUS   ret = 0;

    if(    (bVolNum >= REDCONF_VOLUME_COUNT)
        || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount)
        || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount)
        || (pBuffer == NULL))
    {
        ret = -RED_EINVAL;
    }
    else
    {
        ret = DiskRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
    }

    return ret;
}


#if REDCONF_READ_ONLY == 0
/** @brief Write sectors to a physical block device.

    The behavior of calling this function is undefined if the block device is
    closed or if it was opened with ::BDEV_O_RDONLY.

    @param bVolNum          The volume number of the volume whose block device
                            is being written to.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to write.
    @param pBuffer          The buffer from which to write the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is
                        `NULL`, or @p ullStartSector and/or @p ulSectorCount
                        refer to an invalid range of sectors.
    @retval -RED_EIO    A disk I/O error occurred.
*/
REDSTATUS RedOsBDevWrite(
    uint8_t     bVolNum,
    uint64_t    ullSectorStart,
    uint32_t    ulSectorCount,
    const void *pBuffer)
{
    REDSTATUS   ret = 0;

    if(    (bVolNum >= REDCONF_VOLUME_COUNT)
        || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount)
        || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount)
        || (pBuffer == NULL))
    {
        ret = -RED_EINVAL;
    }
    else
    {
        ret = DiskWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
    }

    return ret;
}


/** @brief Flush any caches beneath the file system.

    This function must synchronously flush all software and hardware caches
    beneath the file system, ensuring that all sectors written previously are
    committed to permanent storage.

    If the environment has no caching beneath the file system, the
    implementation of this function can do nothing and return success.

    The behavior of calling this function is undefined if the block device is
    closed or if it was opened with ::BDEV_O_RDONLY.

    @param bVolNum  The volume number of the volume whose block device is being
                    flushed.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EINVAL @p bVolNum is an invalid volume number.
    @retval -RED_EIO    A disk I/O error occurred.
*/
REDSTATUS RedOsBDevFlush(
    uint8_t     bVolNum)
{
    REDSTATUS   ret;

    if(bVolNum >= REDCONF_VOLUME_COUNT)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        ret = DiskFlush(bVolNum);
    }

    return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */


#if BDEV_EXAMPLE_IMPLEMENTATION == BDEV_F_DRIVER

#include <api_mdriver.h>


/*  This must be declared and initialized elsewere (e.g., in project code) to
    point at the initialization function for the F_DRIVER block device.
*/
extern const F_DRIVERINIT gpfnRedOsBDevInit;

static F_DRIVER *gapFDriver[REDCONF_VOLUME_COUNT];


/** @brief Initialize a disk.

    @param bVolNum  The volume number of the volume whose block device is being
                    initialized.
    @param mode     The open mode, indicating the type of access required.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
*/
static REDSTATUS DiskOpen(
    uint8_t         bVolNum,
    BDEVOPENMODE    mode)
{
    REDSTATUS       ret;

    (void)mode;

    if((gpfnRedOsBDevInit == NULL) || (gapFDriver[bVolNum] != NULL))
    {
        ret = -RED_EINVAL;
    }
    else
    {
        F_DRIVER *pDriver;

        pDriver = gpfnRedOsBDevInit(bVolNum);
        if(pDriver != NULL)
        {
            F_PHY   geom;
            int     iErr;

            /*  Validate that the geometry is consistent with the volume
                configuration.
            */
            iErr = pDriver->getphy(pDriver, &geom);
            if(iErr == 0)
            {
                if(    (geom.bytes_per_sector != gaRedVolConf[bVolNum].ulSectorSize)
                    || (geom.number_of_sectors < gaRedVolConf[bVolNum].ullSectorCount))
                {
                    ret = -RED_EINVAL;
                }
                else
                {
                    gapFDriver[bVolNum] = pDriver;
                    ret = 0;
                }
            }
            else
            {
                ret = -RED_EIO;
            }

            if(ret != 0)
            {
                pDriver->release(pDriver);
            }
        }
        else
        {
            ret = -RED_EIO;
        }
    }

    return ret;
}


/** @brief Uninitialize a disk.

    @param bVolNum  The volume number of the volume whose block device is being
                    uninitialized.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskClose(
    uint8_t     bVolNum)
{
    REDSTATUS   ret;

    if(gapFDriver[bVolNum] == NULL)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        gapFDriver[bVolNum]->release(gapFDriver[bVolNum]);
        gapFDriver[bVolNum] = NULL;

        ret = 0;
    }

    return ret;
}


/** @brief Read sectors from a disk.

    @param bVolNum          The volume number of the volume whose block device
                            is being read from.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to read.
    @param pBuffer          The buffer into which to read the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
*/
static REDSTATUS DiskRead(
    uint8_t     bVolNum,
    uint64_t    ullSectorStart,
    uint32_t    ulSectorCount,
    void       *pBuffer)
{
    REDSTATUS   ret = 0;
    F_DRIVER   *pDriver = gapFDriver[bVolNum];

    if(pDriver == NULL)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        uint8_t    *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer);
        uint32_t    ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
        uint32_t    ulSectorIdx;
        int         iErr;

        for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++)
        {
            iErr = pDriver->readsector(pDriver, &pbBuffer[ulSectorIdx * ulSectorSize],
                                       CAST_ULONG(ullSectorStart + ulSectorIdx));
            if(iErr != 0)
            {
                ret = -RED_EIO;
                break;
            }
        }
    }

    return ret;
}


#if REDCONF_READ_ONLY == 0
/** @brief Write sectors to a disk.

    @param bVolNum          The volume number of the volume whose block device
                            is being written to.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to write.
    @param pBuffer          The buffer from which to write the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EINVAL The block device is not open.
    @retval -RED_EIO    A disk I/O error occurred.
*/
static REDSTATUS DiskWrite(
    uint8_t     bVolNum,
    uint64_t    ullSectorStart,
    uint32_t    ulSectorCount,
    const void *pBuffer)
{
    REDSTATUS   ret = 0;
    F_DRIVER   *pDriver = gapFDriver[bVolNum];

    if(pDriver == NULL)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        const uint8_t  *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);
        uint32_t        ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
        uint32_t        ulSectorIdx;
        int             iErr;

        for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++)
        {
            /*  We have to cast pbBuffer to non-const since the writesector
                prototype is flawed, using a non-const pointer for the buffer.
            */
            iErr = pDriver->writesector(pDriver, CAST_AWAY_CONST(uint8_t, &pbBuffer[ulSectorIdx * ulSectorSize]),
                                        CAST_ULONG(ullSectorStart + ulSectorIdx));
            if(iErr != 0)
            {
                ret = -RED_EIO;
                break;
            }
        }
    }

    return ret;
}


/** @brief Flush any caches beneath the file system.

    @param bVolNum  The volume number of the volume whose block device is being
                    flushed.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskFlush(
    uint8_t     bVolNum)
{
    REDSTATUS   ret;

    if(gapFDriver[bVolNum] == NULL)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        /*  The F_DRIVER interface does not include a flush function, so to be
            reliable the F_DRIVER implementation must use synchronous writes.
        */
        ret = 0;
    }

    return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */


#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_FATFS

#include <task.h>
#include <diskio.h>

/*  disk_read() and disk_write() use an unsigned 8-bit value to specify the
    sector count, so no transfer can be larger than 255 sectors.
*/
#define MAX_SECTOR_TRANSFER UINT8_MAX


/** @brief Initialize a disk.

    @param bVolNum  The volume number of the volume whose block device is being
                    initialized.
    @param mode     The open mode, indicating the type of access required.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
*/
static REDSTATUS DiskOpen(
    uint8_t         bVolNum,
    BDEVOPENMODE    mode)
{
    DSTATUS         status;
    uint32_t        ulTries;
    REDSTATUS       ret = 0;

    /*  With some implementations of disk_initialize(), such as the one
        implemented by Atmel for the ASF, the first time the disk is opened, the
        SD card can take a while to get ready, in which time disk_initialize()
        returns an error.  Try numerous times, waiting half a second after each
        failure.  Empirically, this has been observed to succeed on the second
        try, so trying 10x more than that provides a margin of error.
    */
    for(ulTries = 0U; ulTries < 20U; ulTries++)
    {
        /*  Assuming that the volume number is also the correct drive number.
            If this is not the case in your environment, a static constant array
            can be declared to map volume numbers to the correct driver number.
        */
        status = disk_initialize(bVolNum);
        if(status == 0)
        {
            break;
        }

        vTaskDelay(500U / portTICK_PERIOD_MS);
    }

    if(status != 0)
    {
        ret = -RED_EIO;
    }

    /*  Retrieve the sector size and sector count to ensure they are compatible
        with our compile-time geometry.
    */
    if(ret == 0)
    {
        WORD    wSectorSize;
        DWORD   dwSectorCount;
        DRESULT result;

        result = disk_ioctl(bVolNum, GET_SECTOR_SIZE, &wSectorSize);
        if(result == RES_OK)
        {
            result = disk_ioctl(bVolNum, GET_SECTOR_COUNT, &dwSectorCount);
            if(result == RES_OK)
            {
                if(    (wSectorSize != gaRedVolConf[bVolNum].ulSectorSize)
                    || (dwSectorCount < gaRedVolConf[bVolNum].ullSectorCount))
                {
                    ret = -RED_EINVAL;
                }
            }
            else
            {
                ret = -RED_EIO;
            }
        }
        else
        {
            ret = -RED_EIO;
        }
    }

    return ret;
}


/** @brief Uninitialize a disk.

    @param bVolNum  The volume number of the volume whose block device is being
                    uninitialized.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskClose(
    uint8_t     bVolNum)
{
    (void)bVolNum;
    return 0;
}


/** @brief Read sectors from a disk.

    @param bVolNum          The volume number of the volume whose block device
                            is being read from.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to read.
    @param pBuffer          The buffer into which to read the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
*/
static REDSTATUS DiskRead(
    uint8_t     bVolNum,
    uint64_t    ullSectorStart,
    uint32_t    ulSectorCount,
    void       *pBuffer)
{
    REDSTATUS   ret = 0;
    uint32_t    ulSectorIdx = 0U;
    uint32_t    ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
    uint8_t    *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer);

    while(ulSectorIdx < ulSectorCount)
    {
        uint32_t    ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER);
        DRESULT     result;

        result = disk_read(bVolNum, &pbBuffer[ulSectorIdx * ulSectorSize], (DWORD)(ullSectorStart + ulSectorIdx), (BYTE)ulTransfer);
        if(result != RES_OK)
        {
            ret = -RED_EIO;
            break;
        }

        ulSectorIdx += ulTransfer;
    }

    return ret;
}


#if REDCONF_READ_ONLY == 0
/** @brief Write sectors to a disk.

    @param bVolNum          The volume number of the volume whose block device
                            is being written to.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to write.
    @param pBuffer          The buffer from which to write the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
*/
static REDSTATUS DiskWrite(
    uint8_t         bVolNum,
    uint64_t        ullSectorStart,
    uint32_t        ulSectorCount,
    const void     *pBuffer)
{
    REDSTATUS       ret = 0;
    uint32_t        ulSectorIdx = 0U;
    uint32_t        ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
    const uint8_t  *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);

    while(ulSectorIdx < ulSectorCount)
    {
        uint32_t    ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER);
        DRESULT     result;

        result = disk_write(bVolNum, &pbBuffer[ulSectorIdx * ulSectorSize], (DWORD)(ullSectorStart + ulSectorIdx), (BYTE)ulTransfer);
        if(result != RES_OK)
        {
            ret = -RED_EIO;
            break;
        }

        ulSectorIdx += ulTransfer;
    }

    return ret;
}


/** @brief Flush any caches beneath the file system.

    @param bVolNum  The volume number of the volume whose block device is being
                    flushed.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskFlush(
    uint8_t     bVolNum)
{
    REDSTATUS   ret;
    DRESULT     result;

    result = disk_ioctl(bVolNum, CTRL_SYNC, NULL);
    if(result == RES_OK)
    {
        ret = 0;
    }
    else
    {
        ret = -RED_EIO;
    }

    return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */


#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_ATMEL_SDMMC

#include <task.h>

#include <conf_sd_mmc.h>
#include <sd_mmc.h>
#include <sd_mmc_mem.h>
#include <ctrl_access.h>

/*  sd_mmc_mem_2_ram_multi() and sd_mmc_ram_2_mem_multi() use an unsigned
    16-bit value to specify the sector count, so no transfer can be larger
    than UINT16_MAX sectors.
*/
#define MAX_SECTOR_TRANSFER UINT16_MAX


/** @brief Initialize a disk.

    @param bVolNum  The volume number of the volume whose block device is being
                    initialized.
    @param mode     The open mode, indicating the type of access required.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
    @retval -RED_EROFS  The device is read-only media and write access was
                        requested.
*/
static REDSTATUS DiskOpen(
    uint8_t         bVolNum,
    BDEVOPENMODE    mode)
{
    REDSTATUS       ret = 0;
    uint32_t        ulTries;
    Ctrl_status     cs;

    /*  Note: Assuming the volume number is the same as the SD card slot.  The
        ASF SD/MMC driver supports two SD slots.  This implementation will need
        to be modified if multiple volumes share a single SD card.
    */

    /*  The first time the disk is opened, the SD card can take a while to get
        ready, in which time sd_mmc_test_unit_ready() returns either CTRL_BUSY
        or CTRL_NO_PRESENT.  Try numerous times, waiting half a second after
        each failure.  Empirically, this has been observed to succeed on the
        second try, so trying 10x more than that provides a margin of error.
    */
    for(ulTries = 0U; ulTries < 20U; ulTries++)
    {
        cs = sd_mmc_test_unit_ready(bVolNum);
        if((cs != CTRL_NO_PRESENT) && (cs != CTRL_BUSY))
        {
            break;
        }

        vTaskDelay(500U / portTICK_PERIOD_MS);
    }

    if(cs == CTRL_GOOD)
    {
      #if REDCONF_READ_ONLY == 0
        if(mode != BDEV_O_RDONLY)
        {
            if(sd_mmc_wr_protect(bVolNum))
            {
                ret = -RED_EROFS;
            }
        }

        if(ret == 0)
      #endif
        {
            uint32_t ulSectorLast;

            IGNORE_ERRORS(sd_mmc_read_capacity(bVolNum, &ulSectorLast));

            /*  The ASF SD/MMC driver only supports 512-byte sectors.
            */
            if(    (gaRedVolConf[bVolNum].ulSectorSize != 512U)
                || (((uint64_t)ulSectorLast + 1U) < gaRedVolConf[bVolNum].ullSectorCount))
            {
                ret = -RED_EINVAL;
            }
        }
    }
    else
    {
        ret = -RED_EIO;
    }

    return ret;
}


/** @brief Uninitialize a disk.

    @param bVolNum  The volume number of the volume whose block device is being
                    uninitialized.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskClose(
    uint8_t     bVolNum)
{
    (void)bVolNum;
    return 0;
}


/** @brief Read sectors from a disk.

    @param bVolNum          The volume number of the volume whose block device
                            is being read from.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to read.
    @param pBuffer          The buffer into which to read the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskRead(
    uint8_t     bVolNum,
    uint64_t    ullSectorStart,
    uint32_t    ulSectorCount,
    void       *pBuffer)
{
    REDSTATUS   ret = 0;
    uint32_t    ulSectorIdx = 0U;
    uint32_t    ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
    uint8_t    *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer);

    while(ulSectorIdx < ulSectorCount)
    {
        uint32_t    ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER);
        Ctrl_status cs;

        cs = sd_mmc_mem_2_ram_multi(bVolNum, (uint32_t)(ullSectorStart + ulSectorIdx),
                                    (uint16_t)ulTransfer, &pbBuffer[ulSectorIdx * ulSectorSize]);
        if(cs != CTRL_GOOD)
        {
            ret = -RED_EIO;
            break;
        }

        ulSectorIdx += ulTransfer;
    }

    return ret;
}


#if REDCONF_READ_ONLY == 0
/** @brief Write sectors to a disk.

    @param bVolNum          The volume number of the volume whose block device
                            is being written to.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to write.
    @param pBuffer          The buffer from which to write the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskWrite(
    uint8_t         bVolNum,
    uint64_t        ullSectorStart,
    uint32_t        ulSectorCount,
    const void     *pBuffer)
{
    REDSTATUS       ret = 0;
    uint32_t        ulSectorIdx = 0U;
    uint32_t        ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
    const uint8_t  *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);

    while(ulSectorIdx < ulSectorCount)
    {
        uint32_t    ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER);
        Ctrl_status cs;

        cs = sd_mmc_ram_2_mem_multi(bVolNum, (uint32_t)(ullSectorStart + ulSectorIdx),
                                    (uint16_t)ulTransfer, &pbBuffer[ulSectorIdx * ulSectorSize]);
        if(cs != CTRL_GOOD)
        {
            ret = -RED_EIO;
            break;
        }

        ulSectorIdx += ulTransfer;
    }

    return ret;
}


/** @brief Flush any caches beneath the file system.

    @param bVolNum  The volume number of the volume whose block device is being
                    flushed.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskFlush(
    uint8_t     bVolNum)
{
    REDSTATUS   ret;
    Ctrl_status cs;

    /*  The ASF SD/MMC driver appears to write sectors synchronously, so it
        should be fine to do nothing and return success.  However, Atmel's
        implementation of the FatFs diskio.c file does the equivalent of the
        below when the disk is flushed.  Just in case this is important for some
        non-obvious reason, do the same.
    */
    cs = sd_mmc_test_unit_ready(bVolNum);
    if(cs == CTRL_GOOD)
    {
        ret = 0;
    }
    else
    {
        ret = -RED_EIO;
    }

    return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */

#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_STM32_SDIO

#ifdef USE_STM324xG_EVAL
  #include <stm324xg_eval.h>
  #include <stm324xg_eval_sd.h>
#elif defined(USE_STM32746G_DISCO)
  #include <stm32746g_discovery.h>
  #include <stm32746g_discovery_sd.h>
#else
  /*  If you are using a compatible STM32 device other than the two listed above
      and you have SD card driver headers, you can try adding them to the above
      list.
  */
  #error "Unsupported device."
#endif

#if REDCONF_VOLUME_COUNT > 1
  #error "The STM32 SDIO block device implementation does not support multiple volumes."
#endif


#ifndef USE_HAL_DRIVER
  #error "The STM32 StdPeriph driver is not supported. Please use the HAL driver or modify the Reliance Edge block device interface."
#endif


/** @brief Number of times to call BSP_SD_GetStatus() before timing out and
           returning an error.

    See ::CheckStatus().

    NOTE: Datalight has not observed a scenario where BSP_SD_GetStatus()
    returns SD_TRANSFER_BUSY after a transfer command returns successfully.
    Set SD_STATUS_TIMEOUT to 0U to skip checking BSP_SD_GetStatus().
*/
#define SD_STATUS_TIMEOUT (100000U)

/** @brief 4-byte aligned buffer to use for DMA transfers when passed in
           an unaligned buffer.
*/
static uint32_t gaulAlignedBuffer[512U / sizeof(uint32_t)];


#if SD_STATUS_TIMEOUT > 0U
static REDSTATUS CheckStatus(void);
#endif


/** @brief Initialize a disk.

    @param bVolNum  The volume number of the volume whose block device is being
                    initialized.
    @param mode     The open mode, indicating the type of access required.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    No SD card was found; or BSP_SD_Init() failed.
    @retval -RED_EINVAL The SD card's block size is not the same as the
                        configured sector size; or the SD card is not large
                        enough for the volume; or the volume size is above
                        4GiB, meaning that part of it cannot be accessed
                        through the STM32 SDIO driver.
*/
static REDSTATUS DiskOpen(
    uint8_t         bVolNum,
    BDEVOPENMODE    mode)
{
    REDSTATUS       ret = 0;
    static bool     fSdInitted = false;

    (void) mode;

    if(!fSdInitted)
    {
        if(BSP_SD_Init() == MSD_OK)
        {
            fSdInitted = true;
        }
    }

    if(!fSdInitted)
    {
        /*  Above initialization attempt failed.
        */
        ret = -RED_EIO;
    }
    else if(BSP_SD_IsDetected() == SD_NOT_PRESENT)
    {
        ret = -RED_EIO;
    }
    else
    {
        uint32_t                ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
        HAL_SD_CardInfoTypedef  sdCardInfo = {{0}};

        BSP_SD_GetCardInfo(&sdCardInfo);

        /*  Note: the actual card block size is sdCardInfo.CardBlockSize,
            but the interface only supports a 512 byte block size. Further,
            one card has been observed to report a 1024-byte block size,
            but it worked fine with a 512-byte Reliance Edge ulSectorSize.
        */
        if(    (ulSectorSize != 512U)
            || (sdCardInfo.CardCapacity < (gaRedVolConf[bVolNum].ullSectorCount * ulSectorSize)))
        {
            ret = -RED_EINVAL;
        }
    }

    return ret;
}


/** @brief Uninitialize a disk.

    @param bVolNum  The volume number of the volume whose block device is being
                    uninitialized.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskClose(
    uint8_t     bVolNum)
{
    (void)bVolNum;
    return 0;
}


/** @brief Read sectors from a disk.

    @param bVolNum          The volume number of the volume whose block device
                            is being read from.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to read.
    @param pBuffer          The buffer into which to read the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
*/
static REDSTATUS DiskRead(
    uint8_t     bVolNum,
    uint64_t    ullSectorStart,
    uint32_t    ulSectorCount,
    void       *pBuffer)
{
    REDSTATUS   redStat = 0;
    uint32_t    ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
    uint8_t     bSdError;

    if(IS_UINT32_ALIGNED_PTR(pBuffer))
    {
        bSdError = BSP_SD_ReadBlocks_DMA(CAST_UINT32_PTR(pBuffer), ullSectorStart * ulSectorSize, ulSectorSize, ulSectorCount);

        if(bSdError != MSD_OK)
        {
            redStat = -RED_EIO;
        }
      #if SD_STATUS_TIMEOUT > 0U
        else
        {
            redStat = CheckStatus();
        }
      #endif
    }
    else
    {
        uint32_t ulSectorIdx;

        for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++)
        {
            bSdError = BSP_SD_ReadBlocks_DMA(gaulAlignedBuffer, (ullSectorStart + ulSectorIdx) * ulSectorSize, ulSectorSize, 1U);

            if(bSdError != MSD_OK)
            {
                redStat = -RED_EIO;
            }
          #if SD_STATUS_TIMEOUT > 0U
            else
            {
                redStat = CheckStatus();
            }
          #endif

            if(redStat == 0)
            {
                uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer);

                RedMemCpy(&pbBuffer[ulSectorIdx * ulSectorSize], gaulAlignedBuffer, ulSectorSize);
            }
            else
            {
                break;
            }
        }
    }

    return redStat;
}


#if REDCONF_READ_ONLY == 0
/** @brief Write sectors to a disk.

    @param bVolNum          The volume number of the volume whose block device
                            is being written to.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to write.
    @param pBuffer          The buffer from which to write the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
*/
static REDSTATUS DiskWrite(
    uint8_t         bVolNum,
    uint64_t        ullSectorStart,
    uint32_t        ulSectorCount,
    const void     *pBuffer)
{
    REDSTATUS       redStat = 0;
    uint32_t        ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
    uint8_t         bSdError;

    if(IS_UINT32_ALIGNED_PTR(pBuffer))
    {
        bSdError = BSP_SD_WriteBlocks_DMA(CAST_UINT32_PTR(CAST_AWAY_CONST(void, pBuffer)), ullSectorStart * ulSectorSize,
                                          ulSectorSize, ulSectorCount);

        if(bSdError != MSD_OK)
        {
            redStat = -RED_EIO;
        }
      #if SD_STATUS_TIMEOUT > 0U
        else
        {
            redStat = CheckStatus();
        }
      #endif
    }
    else
    {
        uint32_t ulSectorIdx;

        for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++)
        {
            const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);

            RedMemCpy(gaulAlignedBuffer, &pbBuffer[ulSectorIdx * ulSectorSize], ulSectorSize);

            bSdError = BSP_SD_WriteBlocks_DMA(gaulAlignedBuffer, (ullSectorStart + ulSectorIdx) * ulSectorSize, ulSectorSize, 1U);

            if(bSdError != MSD_OK)
            {
                redStat = -RED_EIO;
            }
          #if SD_STATUS_TIMEOUT > 0U
            else
            {
                redStat = CheckStatus();
            }
          #endif

            if(redStat != 0)
            {
                break;
            }
        }
    }

    return redStat;
}


/** @brief Flush any caches beneath the file system.

    @param bVolNum  The volume number of the volume whose block device is being
                    flushed.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskFlush(
    uint8_t     bVolNum)
{
    /*  Disk transfer is synchronous; nothing to flush.
    */
    (void) bVolNum;
    return 0;
}


#if SD_STATUS_TIMEOUT > 0U
/** @brief Wait until BSP_SD_GetStatus returns SD_TRANSFER_OK.

    This function calls BSP_SD_GetStatus repeatedly as long as it returns
    SD_TRANSFER_BUSY up to SD_STATUS_TIMEOUT times.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           SD_TRANSFER_OK was returned.
    @retval -RED_EIO    SD_TRANSFER_ERROR received, or timed out waiting for
                        SD_TRANSFER_OK.
*/
static REDSTATUS CheckStatus(void)
{
    REDSTATUS                   redStat = 0;
    uint32_t                    ulTimeout = SD_STATUS_TIMEOUT;
    HAL_SD_TransferStateTypedef transferState;

    do
    {
        transferState = BSP_SD_GetStatus();
        ulTimeout--;
    } while((transferState == SD_TRANSFER_BUSY) && (ulTimeout > 0U));

    if(transferState != SD_TRANSFER_OK)
    {
        redStat = -RED_EIO;
    }

    return redStat;
}
#endif

#endif /* REDCONF_READ_ONLY == 0 */

#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_RAM_DISK

#include <stdlib.h> /* For ALLOCATE_CLEARED_MEMORY(), which expands to calloc(). */


static uint8_t *gapbRamDisk[REDCONF_VOLUME_COUNT];


/** @brief Initialize a disk.

    @param bVolNum  The volume number of the volume whose block device is being
                    initialized.
    @param mode     The open mode, indicating the type of access required.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
*/
static REDSTATUS DiskOpen(
    uint8_t         bVolNum,
    BDEVOPENMODE    mode)
{
    REDSTATUS       ret = 0;

    (void)mode;

    if(gapbRamDisk[bVolNum] == NULL)
    {
        gapbRamDisk[bVolNum] = ALLOCATE_CLEARED_MEMORY(gaRedVolume[bVolNum].ulBlockCount, REDCONF_BLOCK_SIZE);
        if(gapbRamDisk[bVolNum] == NULL)
        {
            ret = -RED_EIO;
        }
    }

    return ret;
}


/** @brief Uninitialize a disk.

    @param bVolNum  The volume number of the volume whose block device is being
                    uninitialized.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskClose(
    uint8_t     bVolNum)
{
    REDSTATUS   ret;

    if(gapbRamDisk[bVolNum] == NULL)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        /*  This implementation uses dynamically allocated memory, but must
            retain previously written data after the block device is closed, and
            thus the memory cannot be freed and will remain allocated until
            reboot.
        */
        ret = 0;
    }

    return ret;
}


/** @brief Read sectors from a disk.

    @param bVolNum          The volume number of the volume whose block device
                            is being read from.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to read.
    @param pBuffer          The buffer into which to read the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskRead(
    uint8_t     bVolNum,
    uint64_t    ullSectorStart,
    uint32_t    ulSectorCount,
    void       *pBuffer)
{
    REDSTATUS   ret;

    if(gapbRamDisk[bVolNum] == NULL)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[bVolNum].ulSectorSize;
        uint32_t ulByteCount = ulSectorCount * gaRedVolConf[bVolNum].ulSectorSize;

        RedMemCpy(pBuffer, &gapbRamDisk[bVolNum][ullByteOffset], ulByteCount);

        ret = 0;
    }

    return ret;
}


#if REDCONF_READ_ONLY == 0
/** @brief Write sectors to a disk.

    @param bVolNum          The volume number of the volume whose block device
                            is being written to.
    @param ullSectorStart   The starting sector number.
    @param ulSectorCount    The number of sectors to write.
    @param pBuffer          The buffer from which to write the sector data.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskWrite(
    uint8_t     bVolNum,
    uint64_t    ullSectorStart,
    uint32_t    ulSectorCount,
    const void *pBuffer)
{
    REDSTATUS   ret;

    if(gapbRamDisk[bVolNum] == NULL)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[bVolNum].ulSectorSize;
        uint32_t ulByteCount = ulSectorCount * gaRedVolConf[bVolNum].ulSectorSize;

        RedMemCpy(&gapbRamDisk[bVolNum][ullByteOffset], pBuffer, ulByteCount);

        ret = 0;
    }

    return ret;
}


/** @brief Flush any caches beneath the file system.

    @param bVolNum  The volume number of the volume whose block device is being
                    flushed.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0   Operation was successful.
*/
static REDSTATUS DiskFlush(
    uint8_t     bVolNum)
{
    REDSTATUS   ret;

    if(gapbRamDisk[bVolNum] == NULL)
    {
        ret = -RED_EINVAL;
    }
    else
    {
        ret = 0;
    }

    return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */

#else

#error "Invalid BDEV_EXAMPLE_IMPLEMENTATION value"

#endif /* BDEV_EXAMPLE_IMPLEMENTATION == ... */

