@@ -46,31 +46,38 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
4646 }
4747}
4848
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+
4970int mp_vfs_blockdev_read (mp_vfs_blockdev_t * self , size_t block_num , size_t num_blocks , uint8_t * buf ) {
5071 if (self -> flags & MP_BLOCKDEV_FLAG_NATIVE ) {
5172 mp_uint_t (* f )(uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> readblocks [2 ];
5273 return f (buf , block_num , num_blocks );
5374 } else {
54- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , buf };
55- self -> readblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
56- self -> readblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
57- mp_call_method_n_kw (2 , 0 , self -> readblocks );
58- // TODO handle error return
59- return 0 ;
75+ return mp_vfs_blockdev_call_rw (self -> readblocks , block_num , 0 , num_blocks * self -> block_size , buf , 2 );
6076 }
6177}
6278
6379int mp_vfs_blockdev_read_ext (mp_vfs_blockdev_t * self , size_t block_num , size_t block_off , size_t len , uint8_t * buf ) {
64- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , len , buf };
65- self -> readblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
66- self -> readblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
67- self -> readblocks [4 ] = MP_OBJ_NEW_SMALL_INT (block_off );
68- mp_obj_t ret = mp_call_method_n_kw (3 , 0 , self -> readblocks );
69- if (ret == mp_const_none ) {
70- return 0 ;
71- } else {
72- return MP_OBJ_SMALL_INT_VALUE (ret );
73- }
80+ return mp_vfs_blockdev_call_rw (self -> readblocks , block_num , block_off , len , buf , 3 );
7481}
7582
7683int mp_vfs_blockdev_write (mp_vfs_blockdev_t * self , size_t block_num , size_t num_blocks , const uint8_t * buf ) {
@@ -83,12 +90,7 @@ int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_
8390 mp_uint_t (* f )(const uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> writeblocks [2 ];
8491 return f (buf , block_num , num_blocks );
8592 } else {
86- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , (void * )buf };
87- self -> writeblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
88- self -> writeblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
89- mp_call_method_n_kw (2 , 0 , self -> writeblocks );
90- // TODO handle error return
91- return 0 ;
93+ return mp_vfs_blockdev_call_rw (self -> writeblocks , block_num , 0 , num_blocks * self -> block_size , (void * )buf , 2 );
9294 }
9395}
9496
@@ -97,17 +99,7 @@ int mp_vfs_blockdev_write_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t
9799 // read-only block device
98100 return - MP_EROFS ;
99101 }
100-
101- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , len , (void * )buf };
102- self -> writeblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
103- self -> writeblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
104- self -> writeblocks [4 ] = MP_OBJ_NEW_SMALL_INT (block_off );
105- mp_obj_t ret = mp_call_method_n_kw (3 , 0 , self -> writeblocks );
106- if (ret == mp_const_none ) {
107- return 0 ;
108- } else {
109- return MP_OBJ_SMALL_INT_VALUE (ret );
110- }
102+ return mp_vfs_blockdev_call_rw (self -> writeblocks , block_num , block_off , len , (void * )buf , 3 );
111103}
112104
113105mp_obj_t mp_vfs_blockdev_ioctl (mp_vfs_blockdev_t * self , uintptr_t cmd , uintptr_t arg ) {
0 commit comments