/*             ----> 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 using logical blocks as the units.

    The OS block device implementations operate on sectors.  The core does I/O
    in terms of logical blocks: this module translates from logical blocks to
    sectors.

    If bBlockIoRetries is greater than 0 for the current volume, then this
    module will retry block device calls on failure up to the configured number
    of times.  This behavior caters to the type of unreliable hardware and
    drivers that are sometimes found in the IoT world, where one operation may
    fail but the next may still succeed.
*/
#include <redfs.h>
#include <redcore.h>


/** @brief Read a range of logical blocks.

    @param bVolNum      The volume whose block device is being read from.
    @param ulBlockStart The first block to read.
    @param ulBlockCount The number of blocks to read.
    @param pBuffer      The buffer to populate with the data read.

    @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_EINVAL Invalid parameters.
*/
REDSTATUS RedIoRead(
    uint8_t     bVolNum,
    uint32_t    ulBlockStart,
    uint32_t    ulBlockCount,
    void       *pBuffer)
{
    REDSTATUS   ret = 0;

    if(    (bVolNum >= REDCONF_VOLUME_COUNT)
        || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
        || ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)
        || (ulBlockCount == 0U)
        || (pBuffer == NULL))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else
    {
        uint8_t  bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
        uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
        uint32_t ulSectorCount = ulBlockCount << bSectorShift;
        uint8_t  bRetryIdx;

        REDASSERT(bSectorShift < 32U);
        REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);

        for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++)
        {
            ret = RedOsBDevRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer);

            if(ret == 0)
            {
                break;
            }
        }
    }

    CRITICAL_ASSERT(ret == 0);

    return ret;
}


#if REDCONF_READ_ONLY == 0
/** @brief Write a range of logical blocks.

    @param bVolNum      The volume whose block device is being written to.
    @param ulBlockStart The first block to write.
    @param ulBlockCount The number of blocks to write.
    @param pBuffer      The buffer containing the data to write.

    @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_EINVAL Invalid parameters.
*/
REDSTATUS RedIoWrite(
    uint8_t     bVolNum,
    uint32_t    ulBlockStart,
    uint32_t    ulBlockCount,
    const void *pBuffer)
{
    REDSTATUS   ret = 0;

    if(    (bVolNum >= REDCONF_VOLUME_COUNT)
        || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
        || ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)
        || (ulBlockCount == 0U)
        || (pBuffer == NULL))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else
    {
        uint8_t  bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
        uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
        uint32_t ulSectorCount = ulBlockCount << bSectorShift;
        uint8_t  bRetryIdx;

        REDASSERT(bSectorShift < 32U);
        REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);

        for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++)
        {
            ret = RedOsBDevWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer);

            if(ret == 0)
            {
                break;
            }
        }
    }

    CRITICAL_ASSERT(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.
    @retval -RED_EINVAL @p bVolNum is an invalid volume number.
    @retval -RED_EIO    A disk I/O error occurred.
*/
REDSTATUS RedIoFlush(
    uint8_t     bVolNum)
{
    REDSTATUS   ret = 0;

    if(bVolNum >= REDCONF_VOLUME_COUNT)
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else
    {
        uint8_t  bRetryIdx;

        for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++)
        {
            ret = RedOsBDevFlush(bVolNum);

            if(ret == 0)
            {
                break;
            }
        }
    }

    CRITICAL_ASSERT(ret == 0);

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

