@@ -123,7 +123,7 @@ DRESULT disk_write (
123123
124124DRESULT disk_ioctl (
125125 bdev_t pdrv , /* Physical drive nmuber (0..) */
126- BYTE cmd , /* Control code */
126+ BYTE cmd , /* Control code */
127127 void * buff /* Buffer to send/receive control data */
128128)
129129{
@@ -133,7 +133,7 @@ DRESULT disk_ioctl (
133133 }
134134
135135 // First part: call the relevant method of the underlying block device
136- mp_obj_t ret = mp_const_none ;
136+ mp_int_t out_value = 0 ;
137137 if (vfs -> flags & FSUSER_HAVE_IOCTL ) {
138138 // new protocol with ioctl
139139 static const uint8_t op_map [8 ] = {
@@ -144,9 +144,19 @@ DRESULT disk_ioctl (
144144 };
145145 uint8_t bp_op = op_map [cmd & 7 ];
146146 if (bp_op != 0 ) {
147- vfs -> u .ioctl [2 ] = MP_OBJ_NEW_SMALL_INT (bp_op );
148- vfs -> u .ioctl [3 ] = MP_OBJ_NEW_SMALL_INT (0 ); // unused
149- ret = mp_call_method_n_kw (2 , 0 , vfs -> u .ioctl );
147+ if (vfs -> flags & FSUSER_NATIVE ) {
148+ bool (* f )(size_t , mp_int_t * ) = (void * )(uintptr_t )vfs -> u .ioctl [2 ];
149+ if (!f (bp_op , (mp_int_t * ) & out_value )) {
150+ return RES_ERROR ;
151+ }
152+ } else {
153+ vfs -> u .ioctl [2 ] = MP_OBJ_NEW_SMALL_INT (bp_op );
154+ vfs -> u .ioctl [3 ] = MP_OBJ_NEW_SMALL_INT (0 ); // unused
155+ mp_obj_t ret = mp_call_method_n_kw (2 , 0 , vfs -> u .ioctl );
156+ if (ret != mp_const_none ) {
157+ out_value = mp_obj_get_int (ret );
158+ }
159+ }
150160 }
151161 } else {
152162 // old protocol with sync and count
@@ -157,10 +167,13 @@ DRESULT disk_ioctl (
157167 }
158168 break ;
159169
160- case GET_SECTOR_COUNT :
161- ret = mp_call_method_n_kw (0 , 0 , vfs -> u .old .count );
170+ case GET_SECTOR_COUNT : {
171+ mp_obj_t ret = mp_call_method_n_kw (0 , 0 , vfs -> u .old .count );
172+ if (ret != mp_const_none ) {
173+ out_value = mp_obj_get_int (ret );
174+ }
162175 break ;
163-
176+ }
164177 case GET_SECTOR_SIZE :
165178 // old protocol has fixed sector size of 512 bytes
166179 break ;
@@ -177,16 +190,16 @@ DRESULT disk_ioctl (
177190 return RES_OK ;
178191
179192 case GET_SECTOR_COUNT : {
180- * ((DWORD * )buff ) = mp_obj_get_int ( ret ) ;
193+ * ((DWORD * )buff ) = out_value ;
181194 return RES_OK ;
182195 }
183196
184197 case GET_SECTOR_SIZE : {
185- if (ret == mp_const_none ) {
198+ if (out_value == 0 ) {
186199 // Default sector size
187200 * ((WORD * )buff ) = 512 ;
188201 } else {
189- * ((WORD * )buff ) = mp_obj_get_int ( ret ) ;
202+ * ((WORD * )buff ) = out_value ;
190203 }
191204 #if _MAX_SS != _MIN_SS
192205 // need to store ssize because we use it in disk_read/disk_write
@@ -202,7 +215,7 @@ DRESULT disk_ioctl (
202215 case IOCTL_INIT :
203216 case IOCTL_STATUS : {
204217 DSTATUS stat ;
205- if (ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE ( ret ) != 0 ) {
218+ if (out_value != 0 ) {
206219 // error initialising
207220 stat = STA_NOINIT ;
208221 } else if (vfs -> writeblocks [0 ] == MP_OBJ_NULL ) {
0 commit comments