mirror of
https://github.com/apache/nuttx.git
synced 2026-05-18 00:34:10 +08:00
drivers/bch: Add CONFIG_BCH_FORCE_INDIRECT
This implements similar functionality than CONFIG_FAT_FORCE_INDIRECT because in some use cases (e.g. when CONFIG_BUILD_KERNEL) it is not possible to write directly from user buffer. Signed-off-by: Jani Paalijarvi <jani.paalijarvi@unikie.com>
This commit is contained in:
committed by
Xiang Xiao
parent
95ba78e1bd
commit
02c9030e88
@@ -34,4 +34,13 @@ config BCH_DEVICE_READONLY
|
||||
---help---
|
||||
Set bch devices read-only
|
||||
|
||||
config BCH_FORCE_INDIRECT
|
||||
bool "Force indirect transfers in BCH"
|
||||
default n
|
||||
---help---
|
||||
Force all data transfers in BCH to be indirect,
|
||||
using an intermediate buffer.
|
||||
This is needed because in some use cases (e.g. when CONFIG_BUILD_KERNEL)
|
||||
it is not possible to write directly from user buffer.
|
||||
|
||||
endif # BCH
|
||||
|
||||
@@ -56,7 +56,9 @@ ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, off_t offset,
|
||||
size_t len)
|
||||
{
|
||||
FAR struct bchlib_s *bch = (FAR struct bchlib_s *)handle;
|
||||
#ifndef CONFIG_BCH_FORCE_INDIRECT
|
||||
size_t nsectors;
|
||||
#endif
|
||||
size_t sector;
|
||||
uint16_t sectoffset;
|
||||
size_t nbytes;
|
||||
@@ -121,8 +123,48 @@ ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, off_t offset,
|
||||
len -= nbytes;
|
||||
}
|
||||
|
||||
/* Then write all of the full sectors following the partial sector
|
||||
* directly from the user buffer.
|
||||
/* Then write all of the full sectors following the partial sector.. */
|
||||
|
||||
#ifdef CONFIG_BCH_FORCE_INDIRECT
|
||||
|
||||
/* indirectly by using sector buffer.
|
||||
*/
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
/* Read the sector into the sector buffer */
|
||||
|
||||
ret = bchlib_readsector(bch, sector);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Copy the data from the user buffer to the sector buffer */
|
||||
|
||||
nbytes = len > bch->sectsize ? bch->sectsize : len;
|
||||
memcpy(bch->buffer, buffer, nbytes);
|
||||
bch->dirty = true;
|
||||
|
||||
/* Write the sector back to the block device */
|
||||
|
||||
ret = bchlib_flushsector(bch, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
ferr("ERROR: Flush failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Adjust pointers and counts */
|
||||
|
||||
buffer += nbytes;
|
||||
len -= nbytes;
|
||||
byteswritten += nbytes;
|
||||
sector++;
|
||||
}
|
||||
#else
|
||||
|
||||
/* directly from the user buffer.
|
||||
*/
|
||||
|
||||
if (len >= bch->sectsize)
|
||||
@@ -189,6 +231,7 @@ ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, off_t offset,
|
||||
|
||||
byteswritten += len;
|
||||
}
|
||||
#endif /* CONFIG_BCH_FORCE_INDIRECT */
|
||||
|
||||
return byteswritten;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user