diff options
author | Damien George <damien.p.george@gmail.com> | 2016-02-09 14:28:50 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2016-02-10 08:59:31 +0000 |
commit | c33ad60a676d46cb18883beedd6c383d6fae9dd8 (patch) | |
tree | 2ac56735b689abc47fb435268ce1e9fdaa7d459c /stmhal/diskio.c | |
parent | 3846fd56c150646099d530196fd6ab9a54536a24 (diff) |
extmod/fsusermount: Change block protocol to support ioctl method.
The new block protocol is:
- readblocks(self, n, buf)
- writeblocks(self, n, buf)
- ioctl(self, cmd, arg)
The new ioctl method handles the old sync and count methods, as well as
a new "get sector size" method.
The old protocol is still supported, and used if the device doesn't have
the ioctl method.
Diffstat (limited to 'stmhal/diskio.c')
-rw-r--r-- | stmhal/diskio.c | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/stmhal/diskio.c b/stmhal/diskio.c index 3e53cdaa5..14eb9e297 100644 --- a/stmhal/diskio.c +++ b/stmhal/diskio.c @@ -39,6 +39,12 @@ #include "sdcard.h" #include "extmod/fsusermount.h" +// constants for block protocol ioctl +//#define BP_IOCTL_INIT (1) // unused +//#define BP_IOCTL_DEINIT (2) // unused +#define BP_IOCTL_SYNC (3) +#define BP_IOCTL_SEC_COUNT (4) + /*-----------------------------------------------------------------------*/ /* Initialize a Drive */ /*-----------------------------------------------------------------------*/ @@ -242,29 +248,57 @@ DRESULT disk_ioctl ( break; #endif - case PD_USER: - if (MP_STATE_PORT(fs_user_mount) == NULL) { + case PD_USER: { + fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount); + if (vfs == NULL) { // nothing mounted return RES_ERROR; } - switch (cmd) { - case CTRL_SYNC: - if (MP_STATE_PORT(fs_user_mount)->sync[0] != MP_OBJ_NULL) { - mp_call_method_n_kw(0, 0, MP_STATE_PORT(fs_user_mount)->sync); + if (vfs->u.old.count[1] == MP_OBJ_SENTINEL) { + // new protocol with ioctl + switch (cmd) { + case CTRL_SYNC: + vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SYNC); + vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused + mp_call_method_n_kw(2, 0, vfs->u.ioctl); + vfs->u.ioctl[3] = MP_OBJ_SENTINEL; // indicate new protocol + return RES_OK; + + case GET_SECTOR_COUNT: { + vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SEC_COUNT); + vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused + mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl); + *((DWORD*)buff) = mp_obj_get_int(ret); + vfs->u.ioctl[3] = MP_OBJ_SENTINEL; // indicate new protocol + return RES_OK; } - return RES_OK; - case GET_BLOCK_SIZE: - *((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) bl - return RES_OK; + case GET_BLOCK_SIZE: + *((DWORD*)buff) = 1; // erase block size in units of sector size + return RES_OK; + } + } else { + // old protocol with sync and count + switch (cmd) { + case CTRL_SYNC: + if (vfs->u.old.sync[0] != MP_OBJ_NULL) { + mp_call_method_n_kw(0, 0, vfs->u.old.sync); + } + return RES_OK; + + case GET_SECTOR_COUNT: { + mp_obj_t ret = mp_call_method_n_kw(0, 0, vfs->u.old.count); + *((DWORD*)buff) = mp_obj_get_int(ret); + return RES_OK; + } - case GET_SECTOR_COUNT: { - mp_obj_t ret = mp_call_method_n_kw(0, 0, MP_STATE_PORT(fs_user_mount)->count); - *((DWORD*)buff) = mp_obj_get_int(ret); - return RES_OK; + case GET_BLOCK_SIZE: + *((DWORD*)buff) = 1; // erase block size in units of sector size + return RES_OK; } } break; + } } return RES_PARERR; |