3232
3333#if MICROPY_VFS
3434
35- // Block device functions are expected to return 0 on success
36- // and negative integer on errors. Check for positive integer
37- // results as some callers (i.e. littlefs) will produce corrupt
38- // results from these.
39- static int mp_vfs_check_result (mp_obj_t ret ) {
40- if (ret == mp_const_none ) {
41- return 0 ;
42- } else {
43- int i = MP_OBJ_SMALL_INT_VALUE (ret );
44- return i > 0 ? (- MP_EINVAL ) : i ;
45- }
46- }
47-
4835void mp_vfs_blockdev_init (mp_vfs_blockdev_t * self , mp_obj_t bdev ) {
4936 mp_load_method (bdev , MP_QSTR_readblocks , self -> readblocks );
5037 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) {
5946 }
6047}
6148
49+ // Helper function to minimise code size of read/write functions
50+ // note the n_args argument is moved to the end for further code size reduction (args keep same position in caller and callee).
51+ 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 ) {
52+ mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , len , buf };
53+ args [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
54+ args [3 ] = MP_OBJ_FROM_PTR (& ar );
55+ args [4 ] = MP_OBJ_NEW_SMALL_INT (block_off ); // ignored for n_args == 2
56+ mp_obj_t ret = mp_call_method_n_kw (n_args , 0 , args );
57+
58+ if (ret == mp_const_none ) {
59+ return 0 ;
60+ } else {
61+ // Block device functions are expected to return 0 on success
62+ // and negative integer on errors. Check for positive integer
63+ // results as some callers (i.e. littlefs) will produce corrupt
64+ // results from these.
65+ int i = MP_OBJ_SMALL_INT_VALUE (ret );
66+ return i > 0 ? (- MP_EINVAL ) : i ;
67+ }
68+ }
69+
6270int mp_vfs_blockdev_read (mp_vfs_blockdev_t * self , size_t block_num , size_t num_blocks , uint8_t * buf ) {
6371 if (self -> flags & MP_BLOCKDEV_FLAG_NATIVE ) {
6472 mp_uint_t (* f )(uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> readblocks [2 ];
6573 return f (buf , block_num , num_blocks );
6674 } else {
67- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , buf };
68- self -> readblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
69- self -> readblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
70- mp_call_method_n_kw (2 , 0 , self -> readblocks );
71- // TODO handle error return
72- return 0 ;
75+ return mp_vfs_blockdev_call_rw (self -> readblocks , block_num , 0 , num_blocks * self -> block_size , buf , 2 );
7376 }
7477}
7578
7679int mp_vfs_blockdev_read_ext (mp_vfs_blockdev_t * self , size_t block_num , size_t block_off , size_t len , uint8_t * buf ) {
77- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , len , buf };
78- self -> readblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
79- self -> readblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
80- self -> readblocks [4 ] = MP_OBJ_NEW_SMALL_INT (block_off );
81- mp_obj_t ret = mp_call_method_n_kw (3 , 0 , self -> readblocks );
82- return mp_vfs_check_result (ret );
80+ return mp_vfs_blockdev_call_rw (self -> readblocks , block_num , block_off , len , buf , 3 );
8381}
8482
8583int 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_
9290 mp_uint_t (* f )(const uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> writeblocks [2 ];
9391 return f (buf , block_num , num_blocks );
9492 } else {
95- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , (void * )buf };
96- self -> writeblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
97- self -> writeblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
98- mp_call_method_n_kw (2 , 0 , self -> writeblocks );
99- // TODO handle error return
100- return 0 ;
93+ return mp_vfs_blockdev_call_rw (self -> writeblocks , block_num , 0 , num_blocks * self -> block_size , (void * )buf , 2 );
10194 }
10295}
10396
@@ -106,13 +99,7 @@ int mp_vfs_blockdev_write_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t
10699 // read-only block device
107100 return - MP_EROFS ;
108101 }
109-
110- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , len , (void * )buf };
111- self -> writeblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
112- self -> writeblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
113- self -> writeblocks [4 ] = MP_OBJ_NEW_SMALL_INT (block_off );
114- mp_obj_t ret = mp_call_method_n_kw (3 , 0 , self -> writeblocks );
115- return mp_vfs_check_result (ret );
102+ return mp_vfs_blockdev_call_rw (self -> writeblocks , block_num , block_off , len , (void * )buf , 3 );
116103}
117104
118105mp_obj_t mp_vfs_blockdev_ioctl (mp_vfs_blockdev_t * self , uintptr_t cmd , uintptr_t arg ) {
0 commit comments