3030#include "py/mperrno.h"
3131#include "extmod/vfs.h"
3232
33+ #if CIRCUITPY_SDCARDIO
34+ #include "shared-bindings/sdcardio/SDCard.h"
35+ #endif
36+ #if CIRCUITPY_SDIOIO
37+ #include "shared-bindings/sdioio/SDCard.h"
38+ #endif
39+
40+
3341#if MICROPY_VFS
3442
3543void mp_vfs_blockdev_init (mp_vfs_blockdev_t * self , mp_obj_t bdev ) {
3644 mp_load_method (bdev , MP_QSTR_readblocks , self -> readblocks );
3745 mp_load_method_maybe (bdev , MP_QSTR_writeblocks , self -> writeblocks );
3846 mp_load_method_maybe (bdev , MP_QSTR_ioctl , self -> u .ioctl );
47+
48+ // CIRCUITPY-CHANGE: Support native SD cards.
49+ #if CIRCUITPY_SDCARDIO
50+ if (mp_obj_get_type (bdev ) == & sdcardio_SDCard_type ) {
51+ self -> flags |= MP_BLOCKDEV_FLAG_NATIVE | MP_BLOCKDEV_FLAG_HAVE_IOCTL ;
52+ self -> readblocks [0 ] = mp_const_none ;
53+ self -> readblocks [1 ] = bdev ;
54+ self -> readblocks [2 ] = (mp_obj_t )sdcardio_sdcard_readblocks ; // native version
55+ self -> writeblocks [0 ] = mp_const_none ;
56+ self -> writeblocks [1 ] = bdev ;
57+ self -> writeblocks [2 ] = (mp_obj_t )sdcardio_sdcard_writeblocks ; // native version
58+ self -> u .ioctl [0 ] = mp_const_none ;
59+ self -> u .ioctl [1 ] = bdev ;
60+ self -> u .ioctl [2 ] = (mp_obj_t )sdcardio_sdcard_ioctl ; // native version
61+ }
62+ #endif
63+ #if CIRCUITPY_SDIOIO
64+ if (mp_obj_get_type (bdev ) == & sdioio_SDCard_type ) {
65+ // TODO: Enable native blockdev for SDIO too.
66+ }
67+ #endif
3968 if (self -> u .ioctl [0 ] != MP_OBJ_NULL ) {
4069 // Device supports new block protocol, so indicate it
4170 self -> flags |= MP_BLOCKDEV_FLAG_HAVE_IOCTL ;
@@ -48,8 +77,8 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
4877
4978int mp_vfs_blockdev_read (mp_vfs_blockdev_t * self , size_t block_num , size_t num_blocks , uint8_t * buf ) {
5079 if (self -> flags & MP_BLOCKDEV_FLAG_NATIVE ) {
51- mp_uint_t (* f )(uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> readblocks [2 ];
52- return f (buf , block_num , num_blocks );
80+ mp_uint_t (* f )(mp_obj_t self , uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> readblocks [2 ];
81+ return f (self -> readblocks [ 1 ], buf , block_num , num_blocks );
5382 } else {
5483 mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , buf };
5584 self -> readblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
@@ -80,8 +109,8 @@ int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_
80109 }
81110
82111 if (self -> flags & MP_BLOCKDEV_FLAG_NATIVE ) {
83- mp_uint_t (* f )(const uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> writeblocks [2 ];
84- return f (buf , block_num , num_blocks );
112+ mp_uint_t (* f )(mp_obj_t self , const uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> writeblocks [2 ];
113+ return f (self -> writeblocks [ 1 ], buf , block_num , num_blocks );
85114 } else {
86115 mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , (void * )buf };
87116 self -> writeblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
@@ -112,6 +141,15 @@ int mp_vfs_blockdev_write_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t
112141
113142mp_obj_t mp_vfs_blockdev_ioctl (mp_vfs_blockdev_t * self , uintptr_t cmd , uintptr_t arg ) {
114143 if (self -> flags & MP_BLOCKDEV_FLAG_HAVE_IOCTL ) {
144+ if (self -> flags & MP_BLOCKDEV_FLAG_NATIVE ) {
145+ size_t out_value ;
146+ bool (* f )(mp_obj_t self , uint32_t , uint32_t , size_t * ) = (void * )(uintptr_t )self -> u .ioctl [2 ];
147+ bool b = f (self -> u .ioctl [1 ], cmd , arg , & out_value );
148+ if (!b ) {
149+ return mp_const_none ;
150+ }
151+ return MP_OBJ_NEW_SMALL_INT (out_value );
152+ }
115153 // New protocol with ioctl
116154 self -> u .ioctl [2 ] = MP_OBJ_NEW_SMALL_INT (cmd );
117155 self -> u .ioctl [3 ] = MP_OBJ_NEW_SMALL_INT (arg );
0 commit comments