Current Design Target
Four NAND Volume States
The state of the NAND volume may exist in one of the following four states:
typedef enum _nand_volume_state_t {
NAND_VOLUME_STATE_EJECTED = 0,
NAND_VOLUME_STATE_SHARED_READONLY,
NAND_VOLUME_STATE_FW_EXCLUSIVE,
NAND_VOLUME_STATE_HOST_EXCLUSIVE,
} nand_volume_state_t;
In addition, there is a MediaChangeNotification
flag, which stores whether the host must see a sequence of Sense/ASC/ASCQ errors when it tries to access the volume.
State Transition Table
from \ to | ejected |
shared R/O |
FW Exc |
Host Exc |
---|---|---|---|---|
ejected |
Y |
M |
Y |
M |
shared R/O |
Y |
Y |
Y |
M |
FW Exc |
Y |
M |
Y |
M |
Host Exc |
Y |
X |
Y |
Y |
Where M
indicates allowed, but must set MediaChangeNotification
flag.
Where X
may not be permitted … to be decided later.
Main Transition Events
Transition to NAND_VOLUME_STATE_FW_EXCLUSIVE
, unless media is ejected (e.g., in process of formatting, mounting, …):
-
nand/nand/ftl_diskio.c / diskio_write()
When calling f_close()
, check if the handle being closed is a write-capable handle. If so, and this is the final write-capable handle being closed:
- Assert state is
NAND_VOLUME_STATE_FW_EXCLUSIVE
and transition to stateNAND_VOLUME_STATE_SHARED_RO
Non-FileHandle Events
The following FW APIs do not use a file handle, but may change the media state. Therefore, they should set the MediaChangeNotification
flag explicitly on success. Note that it’s safe to set this flag even if the host is not permitted to access the volume:
-
f_mkdir()
-
f_unlink()
-
f_rename()
-
f_chmod()
-
f_setlabel()
Events to be specially handled
The following change the volume state at a fundamental level. Transition to NAND_VOLUME_STATE_SHARED_RO
AND set MediaChangeNotification
:
-
f_mkfs()
-
f_mount()
-
f_fdisk()
Assertions to help validate correctness
The following APIs each require the use of a write-capable file handle. To help catch any missed edge cases, assert that state ends up as NAND_VOLUME_STATE_FW_EXCLUSIVE
for successful calls to:
-
f_write()
-
f_truncate()
-
f_sync()
-
f_forward()
-
f_expand()
-
f_putc()
-
f_puts()
-
f_printf()
It seems this is doable, and that it will require careful review to ensure all edge cases are caught. However, the user experience should be quite friendly.