@@ -53,59 +53,6 @@ STATIC fs_user_mount_t *disk_get_device(void *bdev) {
5353 return (fs_user_mount_t * )bdev ;
5454}
5555
56- /*-----------------------------------------------------------------------*/
57- /* Initialize a Drive */
58- /*-----------------------------------------------------------------------*/
59-
60- STATIC
61- DSTATUS disk_initialize (
62- bdev_t pdrv /* Physical drive nmuber (0..) */
63- )
64- {
65- fs_user_mount_t * vfs = disk_get_device (pdrv );
66- if (vfs == NULL ) {
67- return STA_NOINIT ;
68- }
69-
70- if (vfs -> flags & FSUSER_HAVE_IOCTL ) {
71- // new protocol with ioctl; call ioctl(INIT, 0)
72- vfs -> u .ioctl [2 ] = MP_OBJ_NEW_SMALL_INT (BP_IOCTL_INIT );
73- vfs -> u .ioctl [3 ] = MP_OBJ_NEW_SMALL_INT (0 ); // unused
74- mp_obj_t ret = mp_call_method_n_kw (2 , 0 , vfs -> u .ioctl );
75- if (ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE (ret ) != 0 ) {
76- // error initialising
77- return STA_NOINIT ;
78- }
79- }
80-
81- if (vfs -> writeblocks [0 ] == MP_OBJ_NULL ) {
82- return STA_PROTECT ;
83- } else {
84- return 0 ;
85- }
86- }
87-
88- /*-----------------------------------------------------------------------*/
89- /* Get Disk Status */
90- /*-----------------------------------------------------------------------*/
91-
92- STATIC
93- DSTATUS disk_status (
94- bdev_t pdrv /* Physical drive nmuber (0..) */
95- )
96- {
97- fs_user_mount_t * vfs = disk_get_device (pdrv );
98- if (vfs == NULL ) {
99- return STA_NOINIT ;
100- }
101-
102- if (vfs -> writeblocks [0 ] == MP_OBJ_NULL ) {
103- return STA_PROTECT ;
104- } else {
105- return 0 ;
106- }
107- }
108-
10956/*-----------------------------------------------------------------------*/
11057/* Read Sector(s) */
11158/*-----------------------------------------------------------------------*/
@@ -191,54 +138,21 @@ DRESULT disk_ioctl (
191138 return RES_PARERR ;
192139 }
193140
141+ // First part: call the relevant method of the underlying block device
142+ mp_obj_t ret = mp_const_none ;
194143 if (vfs -> flags & FSUSER_HAVE_IOCTL ) {
195144 // new protocol with ioctl
196- switch (cmd ) {
197- case CTRL_SYNC :
198- vfs -> u .ioctl [2 ] = MP_OBJ_NEW_SMALL_INT (BP_IOCTL_SYNC );
199- vfs -> u .ioctl [3 ] = MP_OBJ_NEW_SMALL_INT (0 ); // unused
200- mp_call_method_n_kw (2 , 0 , vfs -> u .ioctl );
201- return RES_OK ;
202-
203- case GET_SECTOR_COUNT : {
204- vfs -> u .ioctl [2 ] = MP_OBJ_NEW_SMALL_INT (BP_IOCTL_SEC_COUNT );
205- vfs -> u .ioctl [3 ] = MP_OBJ_NEW_SMALL_INT (0 ); // unused
206- mp_obj_t ret = mp_call_method_n_kw (2 , 0 , vfs -> u .ioctl );
207- * ((DWORD * )buff ) = mp_obj_get_int (ret );
208- return RES_OK ;
209- }
210-
211- case GET_SECTOR_SIZE : {
212- vfs -> u .ioctl [2 ] = MP_OBJ_NEW_SMALL_INT (BP_IOCTL_SEC_SIZE );
213- vfs -> u .ioctl [3 ] = MP_OBJ_NEW_SMALL_INT (0 ); // unused
214- mp_obj_t ret = mp_call_method_n_kw (2 , 0 , vfs -> u .ioctl );
215- if (ret == mp_const_none ) {
216- // Default sector size
217- * ((WORD * )buff ) = 512 ;
218- } else {
219- * ((WORD * )buff ) = mp_obj_get_int (ret );
220- }
221- #if _MAX_SS != _MIN_SS
222- // need to store ssize because we use it in disk_read/disk_write
223- vfs -> fatfs .ssize = * ((WORD * )buff );
224- #endif
225- return RES_OK ;
226- }
227-
228- case GET_BLOCK_SIZE :
229- * ((DWORD * )buff ) = 1 ; // erase block size in units of sector size
230- return RES_OK ;
231-
232- case IOCTL_INIT :
233- * ((DSTATUS * )buff ) = disk_initialize (pdrv );
234- return RES_OK ;
235-
236- case IOCTL_STATUS :
237- * ((DSTATUS * )buff ) = disk_status (pdrv );
238- return RES_OK ;
239-
240- default :
241- return RES_PARERR ;
145+ static const uint8_t op_map [8 ] = {
146+ [CTRL_SYNC ] = BP_IOCTL_SYNC ,
147+ [GET_SECTOR_COUNT ] = BP_IOCTL_SEC_COUNT ,
148+ [GET_SECTOR_SIZE ] = BP_IOCTL_SEC_SIZE ,
149+ [IOCTL_INIT ] = BP_IOCTL_INIT ,
150+ };
151+ uint8_t bp_op = op_map [cmd & 7 ];
152+ if (bp_op != 0 ) {
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+ ret = mp_call_method_n_kw (2 , 0 , vfs -> u .ioctl );
242156 }
243157 } else {
244158 // old protocol with sync and count
@@ -247,37 +161,67 @@ DRESULT disk_ioctl (
247161 if (vfs -> u .old .sync [0 ] != MP_OBJ_NULL ) {
248162 mp_call_method_n_kw (0 , 0 , vfs -> u .old .sync );
249163 }
250- return RES_OK ;
164+ break ;
251165
252- case GET_SECTOR_COUNT : {
253- mp_obj_t ret = mp_call_method_n_kw (0 , 0 , vfs -> u .old .count );
254- * ((DWORD * )buff ) = mp_obj_get_int (ret );
255- return RES_OK ;
256- }
166+ case GET_SECTOR_COUNT :
167+ ret = mp_call_method_n_kw (0 , 0 , vfs -> u .old .count );
168+ break ;
257169
258170 case GET_SECTOR_SIZE :
259- * ((WORD * )buff ) = 512 ; // old protocol had fixed sector size
260- #if _MAX_SS != _MIN_SS
261- // need to store ssize because we use it in disk_read/disk_write
262- vfs -> fatfs .ssize = 512 ;
263- #endif
264- return RES_OK ;
265-
266- case GET_BLOCK_SIZE :
267- * ((DWORD * )buff ) = 1 ; // erase block size in units of sector size
268- return RES_OK ;
171+ // old protocol has fixed sector size of 512 bytes
172+ break ;
269173
270174 case IOCTL_INIT :
271- * ((DSTATUS * )buff ) = disk_initialize (pdrv );
272- return RES_OK ;
175+ // old protocol doesn't have init
176+ break ;
177+ }
178+ }
273179
274- case IOCTL_STATUS :
275- * ((DSTATUS * )buff ) = disk_status (pdrv );
276- return RES_OK ;
180+ // Second part: convert the result for return
181+ switch (cmd ) {
182+ case CTRL_SYNC :
183+ return RES_OK ;
277184
278- default :
279- return RES_PARERR ;
185+ case GET_SECTOR_COUNT : {
186+ * ((DWORD * )buff ) = mp_obj_get_int (ret );
187+ return RES_OK ;
280188 }
189+
190+ case GET_SECTOR_SIZE : {
191+ if (ret == mp_const_none ) {
192+ // Default sector size
193+ * ((WORD * )buff ) = 512 ;
194+ } else {
195+ * ((WORD * )buff ) = mp_obj_get_int (ret );
196+ }
197+ #if _MAX_SS != _MIN_SS
198+ // need to store ssize because we use it in disk_read/disk_write
199+ vfs -> fatfs .ssize = * ((WORD * )buff );
200+ #endif
201+ return RES_OK ;
202+ }
203+
204+ case GET_BLOCK_SIZE :
205+ * ((DWORD * )buff ) = 1 ; // erase block size in units of sector size
206+ return RES_OK ;
207+
208+ case IOCTL_INIT :
209+ case IOCTL_STATUS : {
210+ DSTATUS stat ;
211+ if (ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE (ret ) != 0 ) {
212+ // error initialising
213+ stat = STA_NOINIT ;
214+ } else if (vfs -> writeblocks [0 ] == MP_OBJ_NULL ) {
215+ stat = STA_PROTECT ;
216+ } else {
217+ stat = 0 ;
218+ }
219+ * ((DSTATUS * )buff ) = stat ;
220+ return RES_OK ;
221+ }
222+
223+ default :
224+ return RES_PARERR ;
281225 }
282226}
283227
0 commit comments