@@ -36,16 +36,16 @@ fatfs_fs_driver_mount_info fs_driver_mount_info[FF_VOLUMES];
3636#define FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_DEFINITIONS (varname ) \
3737 const char *modified_##varname;
3838
39- #define FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (varname , fd ) \
39+ #define FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (varname , vol ) \
4040 { \
41- if ((fd)->unit != 0) \
41+ if ((vol) != 0) \
4242 { \
4343 int strlen_##varname; \
4444 char *modified_scope_##varname; \
4545 \
4646 strlen_##varname = strlen(varname); \
4747 modified_scope_##varname = __builtin_alloca(3 + strlen_##varname + 1); \
48- modified_scope_##varname[0] = '0' + (fd)->unit ; \
48+ modified_scope_##varname[0] = '0' + (vol) ; \
4949 modified_scope_##varname[1] = ':'; \
5050 modified_scope_##varname[2] = '/'; \
5151 memcpy((modified_scope_##varname) + 3, varname, strlen_##varname); \
@@ -192,12 +192,87 @@ static void fatfs_fs_driver_stop_all_bd(void)
192192 }
193193}
194194
195+ // Pool of dynamically-registered iop_device_t instances, one per unique bd->path value.
196+ // "mass" is always registered separately; this pool handles all other path values.
197+ #define FS_MAX_TYPED_DRIVERS 8
198+ static iop_device_t fs_typed_drivers [FS_MAX_TYPED_DRIVERS ];
199+ static char fs_typed_driver_names [FS_MAX_TYPED_DRIVERS ][16 ];
200+ static int fs_typed_driver_count = 0 ;
201+
202+ // Forward declaration for the shared ops table used by all typed drivers.
203+ static iop_device_ops_t fs_functarray ;
204+
205+ // Ensures an iop_device_t named `path` is registered with iomanX.
206+ // No-op if already registered or if the pool is exhausted.
207+ static void fs_ensure_typed_driver (const char * path )
208+ {
209+ int i ;
210+
211+ if (path == NULL || strcmp (path , "mass" ) == 0 )
212+ return ;
213+
214+ for (i = 0 ; i < fs_typed_driver_count ; i ++ ) {
215+ if (strcmp (fs_typed_driver_names [i ], path ) == 0 )
216+ return ; // already registered
217+ }
218+
219+ if (fs_typed_driver_count >= FS_MAX_TYPED_DRIVERS ) {
220+ M_DEBUG ("fs_ensure_typed_driver: pool exhausted, cannot register '%s'\n" , path );
221+ return ;
222+ }
223+
224+ i = fs_typed_driver_count ;
225+ strncpy (fs_typed_driver_names [i ], path , sizeof (fs_typed_driver_names [i ]) - 1 );
226+ fs_typed_driver_names [i ][sizeof (fs_typed_driver_names [i ]) - 1 ] = '\0' ;
227+
228+ fs_typed_drivers [i ].name = fs_typed_driver_names [i ];
229+ fs_typed_drivers [i ].type = IOP_DT_FS | IOP_DT_FSEXT ;
230+ fs_typed_drivers [i ].version = 2 ;
231+ fs_typed_drivers [i ].desc = "FATFS driver" ;
232+ fs_typed_drivers [i ].ops = & fs_functarray ;
233+
234+ DelDrv (fs_typed_driver_names [i ]);
235+ if (AddDrv (& fs_typed_drivers [i ]) == 0 ) {
236+ M_DEBUG ("fs_ensure_typed_driver: registered '%s'\n" , path );
237+ fs_typed_driver_count ++ ;
238+ }
239+ }
240+
241+ // Maps (iomanX driver name, unit) to a FatFs volume index (mount_info_index).
242+ // "mass" uses global connection order for full backward compatibility.
243+ // Any other name matches bd->path of mounted devices.
244+ // Returns -1 if no matching mounted volume is found.
245+ static int fs_driver_resolve_volume (const char * driver_name , int unit )
246+ {
247+ int i , count ;
248+
249+ if (strcmp (driver_name , "mass" ) == 0 ) {
250+ if (unit >= 0 && unit < FATFS_FS_DRIVER_MOUNT_INFO_MAX )
251+ return unit ;
252+ return -1 ;
253+ }
254+
255+ count = 0 ;
256+ for (i = 0 ; i < FATFS_FS_DRIVER_MOUNT_INFO_MAX ; i ++ ) {
257+ struct block_device * bd = fs_driver_mount_info [i ].mounted_bd ;
258+ if (bd != NULL && bd -> path != NULL && strcmp (bd -> path , driver_name ) == 0 ) {
259+ if (count == unit )
260+ return i ;
261+ count ++ ;
262+ }
263+ }
264+ return -1 ;
265+ }
266+
195267int connect_bd (struct block_device * bd )
196268{
197269 int mount_info_index ;
198270
199271 M_DEBUG ("%s\n" , __func__ );
200272
273+ // Dynamically register a typed iop_device_t for this device's path prefix.
274+ fs_ensure_typed_driver (bd -> path );
275+
201276 _fs_lock ();
202277 mount_info_index = fatfs_fs_driver_find_mount_info_index_free ();
203278 if (mount_info_index != -1 ) {
@@ -266,12 +341,17 @@ static int fs_open(iop_file_t *fd, const char *name, int flags, int mode)
266341 M_DEBUG ("%s: %s flags=%X mode=%X\n" , __func__ , name , flags , mode );
267342
268343 int ret ;
344+ int vol ;
269345 BYTE f_mode = FA_OPEN_EXISTING ;
270346 FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_DEFINITIONS (name );
271347
272348 (void )mode ;
273349
274- FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (name , fd );
350+ vol = fs_driver_resolve_volume (fd -> device -> name , fd -> unit );
351+ if (vol < 0 )
352+ return - ENXIO ;
353+
354+ FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (name , vol );
275355
276356 _fs_lock ();
277357
@@ -406,9 +486,14 @@ static int fs_remove(iop_file_t *fd, const char *name)
406486 M_DEBUG ("%s\n" , __func__ );
407487
408488 int ret ;
489+ int vol ;
409490 FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_DEFINITIONS (name );
410491
411- FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (name , fd );
492+ vol = fs_driver_resolve_volume (fd -> device -> name , fd -> unit );
493+ if (vol < 0 )
494+ return - ENXIO ;
495+
496+ FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (name , vol );
412497
413498 _fs_lock ();
414499
@@ -424,11 +509,16 @@ static int fs_mkdir(iop_file_t *fd, const char *name, int mode)
424509 M_DEBUG ("%s\n" , __func__ );
425510
426511 int ret ;
512+ int vol ;
427513 FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_DEFINITIONS (name );
428514
429515 (void )mode ;
430516
431- FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (name , fd );
517+ vol = fs_driver_resolve_volume (fd -> device -> name , fd -> unit );
518+ if (vol < 0 )
519+ return - ENXIO ;
520+
521+ FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (name , vol );
432522
433523 _fs_lock ();
434524
@@ -444,9 +534,14 @@ static int fs_dopen(iop_file_t *fd, const char *name)
444534 M_DEBUG ("%s: unit %d name %s\n" , __func__ , fd -> unit , name );
445535
446536 int ret ;
537+ int vol ;
447538 FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_DEFINITIONS (name );
448539
449- FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (name , fd );
540+ vol = fs_driver_resolve_volume (fd -> device -> name , fd -> unit );
541+ if (vol < 0 )
542+ return - ENXIO ;
543+
544+ FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (name , vol );
450545
451546 _fs_lock ();
452547
@@ -565,17 +660,22 @@ static int fs_getstat(iop_file_t *fd, const char *name, iox_stat_t *stat)
565660 M_DEBUG ("%s: unit %d name %s\n" , __func__ , fd -> unit , name );
566661
567662 int ret ;
663+ int vol ;
568664 FILINFO fno ;
569665 FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_DEFINITIONS (name );
570666
667+ vol = fs_driver_resolve_volume (fd -> device -> name , fd -> unit );
668+ if (vol < 0 )
669+ return - ENXIO ;
670+
571671 // FatFs f_stat doesn't handle the root directory, so we'll handle this case ourselves.
572672 {
573673 const char * name_no_leading_slash = name ;
574674 while (* name_no_leading_slash == '/' ) {
575675 name_no_leading_slash += 1 ;
576676 }
577677 if ((strcmp (name_no_leading_slash , "" ) == 0 ) || (strcmp (name_no_leading_slash , "." ) == 0 )) {
578- if (fatfs_fs_driver_get_mounted_bd_from_index (fd -> unit ) == NULL ) {
678+ if (fatfs_fs_driver_get_mounted_bd_from_index (vol ) == NULL ) {
579679 return - ENXIO ;
580680 }
581681 // Return data indicating that it is a directory.
@@ -585,7 +685,7 @@ static int fs_getstat(iop_file_t *fd, const char *name, iox_stat_t *stat)
585685 }
586686 }
587687
588- FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (name , fd );
688+ FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (name , vol );
589689
590690 _fs_lock ();
591691
@@ -675,7 +775,7 @@ int fs_ioctl2(iop_file_t *fd, int cmd, void *data, unsigned int datalen, void *r
675775 ret = 0 ;
676776 break ;
677777 case USBMASS_IOCTL_GET_DRIVERNAME : {
678- struct block_device * mounted_bd = fatfs_fs_driver_get_mounted_bd_from_index (fd -> unit );
778+ struct block_device * mounted_bd = fatfs_fs_driver_get_mounted_bd_from_index (file -> obj . fs -> pdrv );
679779 ret = (mounted_bd == NULL ) ? - ENXIO : * (int * )(mounted_bd -> name );
680780
681781 // Check for a return buffer and copy the whole name.
@@ -727,11 +827,16 @@ int fs_rename(iop_file_t *fd, const char *path, const char *newpath)
727827 M_DEBUG ("%s\n" , __func__ );
728828
729829 int ret ;
830+ int vol ;
730831 FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_DEFINITIONS (path );
731832 FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_DEFINITIONS (newpath );
732833
733- FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (path , fd );
734- FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (newpath , fd );
834+ vol = fs_driver_resolve_volume (fd -> device -> name , fd -> unit );
835+ if (vol < 0 )
836+ return - ENXIO ;
837+
838+ FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (path , vol );
839+ FATFS_FS_DRIVER_NAME_ALLOC_ON_STACK_IMPLEMENTATION (newpath , vol );
735840
736841 // If old and new path are the same, no need to do anything
737842 if (strcmp (modified_path , modified_newpath ) == 0 ) {
@@ -766,8 +871,10 @@ static int fs_devctl(iop_file_t *fd, const char *name, int cmd, void *arg, unsig
766871 break ;
767872 }
768873 case USBMASS_DEVCTL_STOP_ALL : {
769- fatfs_fs_driver_stop_single_bd (fd -> unit );
770- ret = FR_OK ;
874+ int vol = fs_driver_resolve_volume (fd -> device -> name , fd -> unit );
875+ if (vol >= 0 )
876+ fatfs_fs_driver_stop_single_bd (vol );
877+ ret = FR_OK ;
771878 break ;
772879 }
773880 default : {
@@ -828,6 +935,7 @@ int InitFS(void)
828935
829936 fs_reset ();
830937 fatfs_fs_driver_initialize_all_mount_info ();
938+ fs_typed_driver_count = 0 ;
831939
832940 DelDrv (fs_driver .name );
833941 return (AddDrv (& fs_driver ) == 0 ? 0 : -1 );
0 commit comments