summaryrefslogtreecommitdiff
path: root/extmod/vfs_blockdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'extmod/vfs_blockdev.c')
-rw-r--r--extmod/vfs_blockdev.c63
1 files changed, 25 insertions, 38 deletions
diff --git a/extmod/vfs_blockdev.c b/extmod/vfs_blockdev.c
index 05b71ea1d..a7c14b76e 100644
--- a/extmod/vfs_blockdev.c
+++ b/extmod/vfs_blockdev.c
@@ -32,19 +32,6 @@
#if MICROPY_VFS
-// Block device functions are expected to return 0 on success
-// and negative integer on errors. Check for positive integer
-// results as some callers (i.e. littlefs) will produce corrupt
-// results from these.
-static int mp_vfs_check_result(mp_obj_t ret) {
- if (ret == mp_const_none) {
- return 0;
- } else {
- int i = MP_OBJ_SMALL_INT_VALUE(ret);
- return i > 0 ? (-MP_EINVAL) : i;
- }
-}
-
void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
mp_load_method(bdev, MP_QSTR_readblocks, self->readblocks);
mp_load_method_maybe(bdev, MP_QSTR_writeblocks, self->writeblocks);
@@ -59,27 +46,38 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
}
}
+// Helper function to minimise code size of read/write functions
+// note the n_args argument is moved to the end for further code size reduction (args keep same position in caller and callee).
+static int mp_vfs_blockdev_call_rw(mp_obj_t *args, size_t block_num, size_t block_off, size_t len, void *buf, size_t n_args) {
+ mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, len, buf};
+ args[2] = MP_OBJ_NEW_SMALL_INT(block_num);
+ args[3] = MP_OBJ_FROM_PTR(&ar);
+ args[4] = MP_OBJ_NEW_SMALL_INT(block_off); // ignored for n_args == 2
+ mp_obj_t ret = mp_call_method_n_kw(n_args, 0, args);
+
+ if (ret == mp_const_none) {
+ return 0;
+ } else {
+ // Block device functions are expected to return 0 on success
+ // and negative integer on errors. Check for positive integer
+ // results as some callers (i.e. littlefs) will produce corrupt
+ // results from these.
+ int i = MP_OBJ_SMALL_INT_VALUE(ret);
+ return i > 0 ? (-MP_EINVAL) : i;
+ }
+}
+
int mp_vfs_blockdev_read(mp_vfs_blockdev_t *self, size_t block_num, size_t num_blocks, uint8_t *buf) {
if (self->flags & MP_BLOCKDEV_FLAG_NATIVE) {
mp_uint_t (*f)(uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->readblocks[2];
return f(buf, block_num, num_blocks);
} else {
- mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, num_blocks *self->block_size, buf};
- self->readblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
- self->readblocks[3] = MP_OBJ_FROM_PTR(&ar);
- mp_call_method_n_kw(2, 0, self->readblocks);
- // TODO handle error return
- return 0;
+ return mp_vfs_blockdev_call_rw(self->readblocks, block_num, 0, num_blocks * self->block_size, buf, 2);
}
}
int mp_vfs_blockdev_read_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t block_off, size_t len, uint8_t *buf) {
- mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, len, buf};
- self->readblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
- self->readblocks[3] = MP_OBJ_FROM_PTR(&ar);
- self->readblocks[4] = MP_OBJ_NEW_SMALL_INT(block_off);
- mp_obj_t ret = mp_call_method_n_kw(3, 0, self->readblocks);
- return mp_vfs_check_result(ret);
+ return mp_vfs_blockdev_call_rw(self->readblocks, block_num, block_off, len, buf, 3);
}
int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_blocks, const uint8_t *buf) {
@@ -92,12 +90,7 @@ int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_
mp_uint_t (*f)(const uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->writeblocks[2];
return f(buf, block_num, num_blocks);
} else {
- mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, num_blocks *self->block_size, (void *)buf};
- self->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
- self->writeblocks[3] = MP_OBJ_FROM_PTR(&ar);
- mp_call_method_n_kw(2, 0, self->writeblocks);
- // TODO handle error return
- return 0;
+ return mp_vfs_blockdev_call_rw(self->writeblocks, block_num, 0, num_blocks * self->block_size, (void *)buf, 2);
}
}
@@ -106,13 +99,7 @@ int mp_vfs_blockdev_write_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t
// read-only block device
return -MP_EROFS;
}
-
- mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, len, (void *)buf};
- self->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
- self->writeblocks[3] = MP_OBJ_FROM_PTR(&ar);
- self->writeblocks[4] = MP_OBJ_NEW_SMALL_INT(block_off);
- mp_obj_t ret = mp_call_method_n_kw(3, 0, self->writeblocks);
- return mp_vfs_check_result(ret);
+ return mp_vfs_blockdev_call_rw(self->writeblocks, block_num, block_off, len, (void *)buf, 3);
}
mp_obj_t mp_vfs_blockdev_ioctl(mp_vfs_blockdev_t *self, uintptr_t cmd, uintptr_t arg) {