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.
This commit is contained in:
parent
3846fd56c1
commit
c33ad60a67
|
@ -76,8 +76,15 @@ STATIC mp_obj_t fatfs_mount_mkfs(mp_uint_t n_args, const mp_obj_t *pos_args, mp_
|
||||||
// load block protocol methods
|
// load block protocol methods
|
||||||
mp_load_method(device, MP_QSTR_readblocks, vfs->readblocks);
|
mp_load_method(device, MP_QSTR_readblocks, vfs->readblocks);
|
||||||
mp_load_method_maybe(device, MP_QSTR_writeblocks, vfs->writeblocks);
|
mp_load_method_maybe(device, MP_QSTR_writeblocks, vfs->writeblocks);
|
||||||
mp_load_method_maybe(device, MP_QSTR_sync, vfs->sync);
|
mp_load_method_maybe(device, MP_QSTR_ioctl, vfs->u.ioctl);
|
||||||
mp_load_method(device, MP_QSTR_count, vfs->count);
|
if (vfs->u.ioctl[0] != MP_OBJ_NULL) {
|
||||||
|
// device supports new block protocol, so indicate it
|
||||||
|
vfs->u.old.count[1] = MP_OBJ_SENTINEL;
|
||||||
|
} else {
|
||||||
|
// no ioctl method, so assume the device uses the old block protocol
|
||||||
|
mp_load_method_maybe(device, MP_QSTR_sync, vfs->u.old.sync);
|
||||||
|
mp_load_method(device, MP_QSTR_count, vfs->u.old.count);
|
||||||
|
}
|
||||||
|
|
||||||
// Read-only device indicated by writeblocks[0] == MP_OBJ_NULL.
|
// Read-only device indicated by writeblocks[0] == MP_OBJ_NULL.
|
||||||
// User can specify read-only device by:
|
// User can specify read-only device by:
|
||||||
|
|
|
@ -29,8 +29,15 @@ typedef struct _fs_user_mount_t {
|
||||||
mp_uint_t len;
|
mp_uint_t len;
|
||||||
mp_obj_t readblocks[4];
|
mp_obj_t readblocks[4];
|
||||||
mp_obj_t writeblocks[4];
|
mp_obj_t writeblocks[4];
|
||||||
|
// new protocol uses just ioctl, old uses sync (optional) and count
|
||||||
|
// if ioctl[3]=count[1]=MP_OBJ_SENTINEL then we have the new protocol, else old
|
||||||
|
union {
|
||||||
|
mp_obj_t ioctl[4];
|
||||||
|
struct {
|
||||||
mp_obj_t sync[2];
|
mp_obj_t sync[2];
|
||||||
mp_obj_t count[2];
|
mp_obj_t count[2];
|
||||||
|
} old;
|
||||||
|
} u;
|
||||||
FATFS fatfs;
|
FATFS fatfs;
|
||||||
} fs_user_mount_t;
|
} fs_user_mount_t;
|
||||||
|
|
||||||
|
|
|
@ -675,6 +675,7 @@ Q(readonly)
|
||||||
Q(mkfs)
|
Q(mkfs)
|
||||||
Q(readblocks)
|
Q(readblocks)
|
||||||
Q(writeblocks)
|
Q(writeblocks)
|
||||||
|
Q(ioctl)
|
||||||
Q(sync)
|
Q(sync)
|
||||||
Q(count)
|
Q(count)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,6 +39,12 @@
|
||||||
#include "sdcard.h"
|
#include "sdcard.h"
|
||||||
#include "extmod/fsusermount.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 */
|
/* Initialize a Drive */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -242,30 +248,58 @@ DRESULT disk_ioctl (
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case PD_USER:
|
case PD_USER: {
|
||||||
if (MP_STATE_PORT(fs_user_mount) == NULL) {
|
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount);
|
||||||
|
if (vfs == NULL) {
|
||||||
// nothing mounted
|
// nothing mounted
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
}
|
}
|
||||||
|
if (vfs->u.old.count[1] == MP_OBJ_SENTINEL) {
|
||||||
|
// new protocol with ioctl
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case CTRL_SYNC:
|
case CTRL_SYNC:
|
||||||
if (MP_STATE_PORT(fs_user_mount)->sync[0] != MP_OBJ_NULL) {
|
vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SYNC);
|
||||||
mp_call_method_n_kw(0, 0, MP_STATE_PORT(fs_user_mount)->sync);
|
vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused
|
||||||
}
|
mp_call_method_n_kw(2, 0, vfs->u.ioctl);
|
||||||
return RES_OK;
|
vfs->u.ioctl[3] = MP_OBJ_SENTINEL; // indicate new protocol
|
||||||
|
|
||||||
case GET_BLOCK_SIZE:
|
|
||||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) bl
|
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
|
|
||||||
case GET_SECTOR_COUNT: {
|
case GET_SECTOR_COUNT: {
|
||||||
mp_obj_t ret = mp_call_method_n_kw(0, 0, MP_STATE_PORT(fs_user_mount)->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);
|
*((DWORD*)buff) = mp_obj_get_int(ret);
|
||||||
|
vfs->u.ioctl[3] = MP_OBJ_SENTINEL; // indicate new protocol
|
||||||
|
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_BLOCK_SIZE:
|
||||||
|
*((DWORD*)buff) = 1; // erase block size in units of sector size
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return RES_PARERR;
|
return RES_PARERR;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue