示例#1
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;
}
示例#2
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;
}
示例#3
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;
    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 + ulSectorCount));
            if(iErr != 0)
            {
                ret = -RED_EIO;
                break;
            }
        }
    }

    return ret;
}
示例#4
0
/** @brief Initialize a buffer with the specified byte value.

    This function should only be called from RedMemSet().

    @param pDest    The buffer to initialize.
    @param bVal     The byte value with which to initialize @p pDest.
    @param ulLen    The number of bytes to initialize.
*/
static void RedMemSetUnchecked(
    void       *pDest,
    uint8_t     bVal,
    uint32_t    ulLen)
{
    uint8_t    *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest);
    uint32_t    ulIdx;

    for(ulIdx = 0U; ulIdx < ulLen; ulIdx++)
    {
        pbDest[ulIdx] = bVal;
    }
}
示例#5
0
/** @brief Copy memory from one address to another.

    This function should only be called from RedMemCpy().

    @param pDest    The destination buffer.
    @param pSrc     The source buffer.
    @param ulLen    The number of bytes to copy.
*/
static void RedMemCpyUnchecked(
    void           *pDest,
    const void     *pSrc,
    uint32_t        ulLen)
{
    uint8_t        *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest);
    const uint8_t  *pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pSrc);
    uint32_t        ulIdx;

    for(ulIdx = 0U; ulIdx < ulLen; ulIdx++)
    {
        pbDest[ulIdx] = pbSrc[ulIdx];
    }
}
示例#6
0
/** @brief Move memory from one address to another.

    This function should only be called from RedMemMove().

    @param pDest    The destination buffer.
    @param pSrc     The source buffer.
    @param ulLen    The number of bytes to copy.
*/
static void RedMemMoveUnchecked(
    void           *pDest,
    const void     *pSrc,
    uint32_t        ulLen)
{
    uint8_t        *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest);
    const uint8_t  *pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pSrc);
    uint32_t        ulIdx;

    if(MEMMOVE_MUST_COPY_FORWARD(pbDest, pbSrc))
    {
        /*  If the destination is lower than the source with overlapping memory
            regions, we must copy from start to end in order to copy the memory
            correctly.

            Don't use RedMemCpy() to do this.  It is possible that RedMemCpy()
            has been replaced (even though this function has not been replaced)
            with an implementation that cannot handle any kind of buffer
            overlap.
        */
        for(ulIdx = 0U; ulIdx < ulLen; ulIdx++)
        {
            pbDest[ulIdx] = pbSrc[ulIdx];
        }
    }
    else
    {
        ulIdx = ulLen;

        while(ulIdx > 0U)
        {
            ulIdx--;
            pbDest[ulIdx] = pbSrc[ulIdx];
        }
    }
}