@@ -123,7 +123,7 @@ DRESULT disk_write (
123
123
124
124
DRESULT disk_ioctl (
125
125
bdev_t pdrv , /* Physical drive nmuber (0..) */
126
- BYTE cmd , /* Control code */
126
+ BYTE cmd , /* Control code */
127
127
void * buff /* Buffer to send/receive control data */
128
128
)
129
129
{
@@ -133,7 +133,7 @@ DRESULT disk_ioctl (
133
133
}
134
134
135
135
// 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 ;
137
137
if (vfs -> flags & FSUSER_HAVE_IOCTL ) {
138
138
// new protocol with ioctl
139
139
static const uint8_t op_map [8 ] = {
@@ -144,9 +144,19 @@ DRESULT disk_ioctl (
144
144
};
145
145
uint8_t bp_op = op_map [cmd & 7 ];
146
146
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
+ }
150
160
}
151
161
} else {
152
162
// old protocol with sync and count
@@ -157,10 +167,13 @@ DRESULT disk_ioctl (
157
167
}
158
168
break ;
159
169
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
+ }
162
175
break ;
163
-
176
+ }
164
177
case GET_SECTOR_SIZE :
165
178
// old protocol has fixed sector size of 512 bytes
166
179
break ;
@@ -177,16 +190,16 @@ DRESULT disk_ioctl (
177
190
return RES_OK ;
178
191
179
192
case GET_SECTOR_COUNT : {
180
- * ((DWORD * )buff ) = mp_obj_get_int ( ret ) ;
193
+ * ((DWORD * )buff ) = out_value ;
181
194
return RES_OK ;
182
195
}
183
196
184
197
case GET_SECTOR_SIZE : {
185
- if (ret == mp_const_none ) {
198
+ if (out_value == 0 ) {
186
199
// Default sector size
187
200
* ((WORD * )buff ) = 512 ;
188
201
} else {
189
- * ((WORD * )buff ) = mp_obj_get_int ( ret ) ;
202
+ * ((WORD * )buff ) = out_value ;
190
203
}
191
204
#if _MAX_SS != _MIN_SS
192
205
// need to store ssize because we use it in disk_read/disk_write
@@ -202,7 +215,7 @@ DRESULT disk_ioctl (
202
215
case IOCTL_INIT :
203
216
case IOCTL_STATUS : {
204
217
DSTATUS stat ;
205
- if (ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE ( ret ) != 0 ) {
218
+ if (out_value != 0 ) {
206
219
// error initialising
207
220
stat = STA_NOINIT ;
208
221
} else if (vfs -> writeblocks [0 ] == MP_OBJ_NULL ) {
0 commit comments