1 /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
3 Copyright (c) 2014-2015 Datalight, Inc.
4 All Rights Reserved Worldwide.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; use version 2 of the License.
10 This program is distributed in the hope that it will be useful,
11 but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty
12 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 /* Businesses and individuals that for commercial or other reasons cannot
20 comply with the terms of the GPLv2 license may obtain a commercial license
21 before incorporating Reliance Edge into proprietary software for
22 distribution in any form. Visit http://www.datalight.com/reliance-edge for
26 @brief Implements block device I/O using logical blocks as the units.
28 The OS block device implementations operate on sectors. The core does I/O
29 in terms of logical blocks: this module translates from logical blocks to
32 If bBlockIoRetries is greater than 0 for the current volume, then this
33 module will retry block device calls on failure up to the configured number
34 of times. This behavior caters to the type of unreliable hardware and
35 drivers that are sometimes found in the IoT world, where one operation may
36 fail but the next may still succeed.
42 /** @brief Read a range of logical blocks.
44 @param bVolNum The volume whose block device is being read from.
45 @param ulBlockStart The first block to read.
46 @param ulBlockCount The number of blocks to read.
47 @param pBuffer The buffer to populate with the data read.
49 @return A negated ::REDSTATUS code indicating the operation result.
51 @retval 0 Operation was successful.
52 @retval -RED_EIO A disk I/O error occurred.
53 @retval -RED_EINVAL Invalid parameters.
57 uint32_t ulBlockStart,
58 uint32_t ulBlockCount,
63 if( (bVolNum >= REDCONF_VOLUME_COUNT)
64 || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
65 || ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)
66 || (ulBlockCount == 0U)
74 uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
75 uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
76 uint32_t ulSectorCount = ulBlockCount << bSectorShift;
79 REDASSERT(bSectorShift < 32U);
80 REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);
82 for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++)
84 ret = RedOsBDevRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
93 CRITICAL_ASSERT(ret == 0);
99 #if REDCONF_READ_ONLY == 0
100 /** @brief Write a range of logical blocks.
102 @param bVolNum The volume whose block device is being written to.
103 @param ulBlockStart The first block to write.
104 @param ulBlockCount The number of blocks to write.
105 @param pBuffer The buffer containing the data to write.
107 @return A negated ::REDSTATUS code indicating the operation result.
109 @retval 0 Operation was successful.
110 @retval -RED_EIO A disk I/O error occurred.
111 @retval -RED_EINVAL Invalid parameters.
113 REDSTATUS RedIoWrite(
115 uint32_t ulBlockStart,
116 uint32_t ulBlockCount,
121 if( (bVolNum >= REDCONF_VOLUME_COUNT)
122 || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
123 || ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)
124 || (ulBlockCount == 0U)
125 || (pBuffer == NULL))
132 uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
133 uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
134 uint32_t ulSectorCount = ulBlockCount << bSectorShift;
137 REDASSERT(bSectorShift < 32U);
138 REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);
140 for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++)
142 ret = RedOsBDevWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
151 CRITICAL_ASSERT(ret == 0);
157 /** @brief Flush any caches beneath the file system.
159 @param bVolNum The volume number of the volume whose block device is being
162 @return A negated ::REDSTATUS code indicating the operation result.
164 @retval 0 Operation was successful.
165 @retval -RED_EINVAL @p bVolNum is an invalid volume number.
166 @retval -RED_EIO A disk I/O error occurred.
168 REDSTATUS RedIoFlush(
173 if(bVolNum >= REDCONF_VOLUME_COUNT)
182 for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++)
184 ret = RedOsBDevFlush(bVolNum);
193 CRITICAL_ASSERT(ret == 0);
197 #endif /* REDCONF_READ_ONLY == 0 */