Chapter 35. Removable Media Support

The FAT filesystem has support for Removable Media, which is implemented in conjunction with support in the FILEIO package, the generic DISKIO layer and the hardware disk driver. At present, the drivers which support this include the MMC/SD card driver in bus mode (not SPI mode), subject to the presence of underlying hardware support; and also the USB mass storage device driver.

To support Removable media, application code, or the automounter, should register a disk event callback to capture device insertion and removal. When an insert event is detected, an attempt to mount the filesystem should be made. If this is successful, then the files on the device can be accessed.

When the device is removed the hardware driver will reject all IO operations with an EIO response. The filesystem will propagate these errors back to any current file IO operations which will result in read() or write() returning an EIO error. Application code should be ready for this to happen.

A disk event callback will also be delivered and the application should arrange to call umount_force() to force the filesystem to be unmounted. The FAT filesystem handles this by releasing all resources and detaching from the disk device.

To help applications indicate to the user whether the medium may be removed (by means of a LED or an on-screen icon) the FAT filesystem supports the filesystem callback mechanism defined in the FILEIO package. This relies on the following definitions in fileio.h:

typedef void cyg_fs_callback( cyg_int32 event, CYG_ADDRWORD data );

struct cyg_fs_callback_info
{
    cyg_fs_callback     *callback;      // Callback function
    CYG_ADDRWORD        data;           // User data value
};

// Callback events
#define CYG_FS_CALLBACK_SAFE    1       // The filesystem is up to date on disk
#define CYG_FS_CALLBACK_UNSAFE  2       // The filesystem is not up to date

A callback function may be registered after a filesystem has been mounted by using cyg_fs_setinfo() as follows:

struct cyg_fs_callback_info callback;

…

callback.callback = fs_callback;
callback.data = my_data;
err = cyg_fs_setinfo("/disk0", FS_INFO_CALLBACK, &callback, sizeof(callback));

Following this, whenever the filesystem has dirty cache blocks that are not up to date on the disk, fs_callback() will be called with event set to CYG_FS_CALLBACK_UNSAFE. When all blocks become up to date on disk it will be called with CYG_FS_CALLBACK_SAFE.