From f5d04750dbd13bfc10498e20428b1a285ec417af Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Mon, 27 Jul 2015 23:52:56 +0100
Subject: [PATCH] stmhal: Put fs_user_mount pointer in root ptr section of
 global state.

Should fix issue #1393.
---
 stmhal/diskio.c       | 34 +++++++++++++++++-----------------
 stmhal/ffconf.c       |  8 ++++----
 stmhal/fsusermount.c  | 39 ++++++++++++++++++---------------------
 stmhal/fsusermount.h  |  2 --
 stmhal/moduos.c       |  7 +++----
 stmhal/mpconfigport.h |  3 +++
 6 files changed, 45 insertions(+), 48 deletions(-)

diff --git a/stmhal/diskio.c b/stmhal/diskio.c
index 3b0c86d5b..abad2f41a 100644
--- a/stmhal/diskio.c
+++ b/stmhal/diskio.c
@@ -78,10 +78,10 @@ DSTATUS disk_initialize (
 #endif
 
         case PD_USER:
-            if (fs_user_mount == NULL) {
+            if (MP_STATE_PORT(fs_user_mount) == NULL) {
                 return STA_NODISK;
             }
-            if (fs_user_mount->writeblocks[0] == MP_OBJ_NULL) {
+            if (MP_STATE_PORT(fs_user_mount)->writeblocks[0] == MP_OBJ_NULL) {
                 return STA_PROTECT;
             }
             return 0;
@@ -110,10 +110,10 @@ DSTATUS disk_status (
 #endif
 
         case PD_USER:
-            if (fs_user_mount == NULL) {
+            if (MP_STATE_PORT(fs_user_mount) == NULL) {
                 return STA_NODISK;
             }
-            if (fs_user_mount->writeblocks[0] == MP_OBJ_NULL) {
+            if (MP_STATE_PORT(fs_user_mount)->writeblocks[0] == MP_OBJ_NULL) {
                 return STA_PROTECT;
             }
             return 0;
@@ -151,13 +151,13 @@ DRESULT disk_read (
 #endif
 
         case PD_USER:
-            if (fs_user_mount == NULL) {
+            if (MP_STATE_PORT(fs_user_mount) == NULL) {
                 // nothing mounted
                 return RES_ERROR;
             }
-            fs_user_mount->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
-            fs_user_mount->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff);
-            mp_call_method_n_kw(2, 0, fs_user_mount->readblocks);
+            MP_STATE_PORT(fs_user_mount)->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
+            MP_STATE_PORT(fs_user_mount)->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff);
+            mp_call_method_n_kw(2, 0, MP_STATE_PORT(fs_user_mount)->readblocks);
             return RES_OK;
     }
 
@@ -194,17 +194,17 @@ DRESULT disk_write (
 #endif
 
         case PD_USER:
-            if (fs_user_mount == NULL) {
+            if (MP_STATE_PORT(fs_user_mount) == NULL) {
                 // nothing mounted
                 return RES_ERROR;
             }
-            if (fs_user_mount->writeblocks[0] == MP_OBJ_NULL) {
+            if (MP_STATE_PORT(fs_user_mount)->writeblocks[0] == MP_OBJ_NULL) {
                 // read-only block device
                 return RES_ERROR;
             }
-            fs_user_mount->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
-            fs_user_mount->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void*)buff);
-            mp_call_method_n_kw(2, 0, fs_user_mount->writeblocks);
+            MP_STATE_PORT(fs_user_mount)->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
+            MP_STATE_PORT(fs_user_mount)->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void*)buff);
+            mp_call_method_n_kw(2, 0, MP_STATE_PORT(fs_user_mount)->writeblocks);
             return RES_OK;
     }
 
@@ -251,14 +251,14 @@ DRESULT disk_ioctl (
 #endif
 
         case PD_USER:
-            if (fs_user_mount == NULL) {
+            if (MP_STATE_PORT(fs_user_mount) == NULL) {
                 // nothing mounted
                 return RES_ERROR;
             }
             switch (cmd) {
                 case CTRL_SYNC:
-                    if (fs_user_mount->sync[0] != MP_OBJ_NULL) {
-                        mp_call_method_n_kw(0, 0, fs_user_mount->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);
                     }
                     return RES_OK;
 
@@ -267,7 +267,7 @@ DRESULT disk_ioctl (
                     return RES_OK;
 
                 case GET_SECTOR_COUNT: {
-                    mp_obj_t ret = mp_call_method_n_kw(0, 0, fs_user_mount->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;
                 }
diff --git a/stmhal/ffconf.c b/stmhal/ffconf.c
index 4a51d193c..6557b193a 100644
--- a/stmhal/ffconf.c
+++ b/stmhal/ffconf.c
@@ -26,7 +26,7 @@
 
 #include <string.h>
 
-#include "py/obj.h"
+#include "py/mpstate.h"
 #include "lib/fatfs/ff.h"
 #include "ffconf.h"
 #include "fsusermount.h"
@@ -63,7 +63,7 @@ int ff_get_ldnumber (const TCHAR **path) {
         return 0;
     } else if (check_path(path, "/sd", 3)) {
         return 1;
-    } else if (fs_user_mount != NULL && check_path(path, fs_user_mount->str, fs_user_mount->len)) {
+    } else if (MP_STATE_PORT(fs_user_mount) != NULL && check_path(path, MP_STATE_PORT(fs_user_mount)->str, MP_STATE_PORT(fs_user_mount)->len)) {
         return 2;
     } else {
         return -1;
@@ -78,7 +78,7 @@ void ff_get_volname(BYTE vol, TCHAR **dest) {
         memcpy(*dest, "/sd", 3);
         *dest += 3;
     } else {
-        memcpy(*dest, fs_user_mount->str, fs_user_mount->len);
-        *dest += fs_user_mount->len;
+        memcpy(*dest, MP_STATE_PORT(fs_user_mount)->str, MP_STATE_PORT(fs_user_mount)->len);
+        *dest += MP_STATE_PORT(fs_user_mount)->len;
     }
 }
diff --git a/stmhal/fsusermount.c b/stmhal/fsusermount.c
index 5ddb4c29b..2fc24be1b 100644
--- a/stmhal/fsusermount.c
+++ b/stmhal/fsusermount.c
@@ -29,9 +29,6 @@
 #include "lib/fatfs/ff.h"
 #include "fsusermount.h"
 
-// for user-mountable block device
-fs_user_mount_t *fs_user_mount;
-
 STATIC mp_obj_t pyb_mount(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
     static const mp_arg_t allowed_args[] = {
         { MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
@@ -51,46 +48,46 @@ STATIC mp_obj_t pyb_mount(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *
     if (device == mp_const_none) {
         // umount
         FRESULT res = FR_NO_FILESYSTEM;
-        if (fs_user_mount != NULL) {
-            res = f_mount(NULL, fs_user_mount->str, 0);
-            m_del_obj(fs_user_mount_t, fs_user_mount);
-            fs_user_mount = NULL;
+        if (MP_STATE_PORT(fs_user_mount) != NULL) {
+            res = f_mount(NULL, MP_STATE_PORT(fs_user_mount)->str, 0);
+            m_del_obj(fs_user_mount_t, MP_STATE_PORT(fs_user_mount));
+            MP_STATE_PORT(fs_user_mount) = NULL;
         }
         if (res != FR_OK) {
             nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't umount"));
         }
     } else {
         // mount
-        if (fs_user_mount != NULL) {
+        if (MP_STATE_PORT(fs_user_mount) != NULL) {
             nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "device already mounted"));
         }
 
         // create new object
-        fs_user_mount = m_new_obj(fs_user_mount_t);
-        fs_user_mount->str = mnt_str;
-        fs_user_mount->len = mnt_len;
+        MP_STATE_PORT(fs_user_mount) = m_new_obj(fs_user_mount_t);
+        MP_STATE_PORT(fs_user_mount)->str = mnt_str;
+        MP_STATE_PORT(fs_user_mount)->len = mnt_len;
 
         // load block protocol methods
-        mp_load_method(device, MP_QSTR_readblocks, fs_user_mount->readblocks);
-        mp_load_method_maybe(device, MP_QSTR_writeblocks, fs_user_mount->writeblocks);
-        mp_load_method_maybe(device, MP_QSTR_sync, fs_user_mount->sync);
-        mp_load_method(device, MP_QSTR_count, fs_user_mount->count);
+        mp_load_method(device, MP_QSTR_readblocks, MP_STATE_PORT(fs_user_mount)->readblocks);
+        mp_load_method_maybe(device, MP_QSTR_writeblocks, MP_STATE_PORT(fs_user_mount)->writeblocks);
+        mp_load_method_maybe(device, MP_QSTR_sync, MP_STATE_PORT(fs_user_mount)->sync);
+        mp_load_method(device, MP_QSTR_count, MP_STATE_PORT(fs_user_mount)->count);
 
         // Read-only device indicated by writeblocks[0] == MP_OBJ_NULL.
         // User can specify read-only device by:
         //  1. readonly=True keyword argument
         //  2. nonexistent writeblocks method (then writeblocks[0] == MP_OBJ_NULL already)
         if (args[0].u_bool) {
-            fs_user_mount->writeblocks[0] = MP_OBJ_NULL;
+            MP_STATE_PORT(fs_user_mount)->writeblocks[0] = MP_OBJ_NULL;
         }
 
         // mount the block device
-        FRESULT res = f_mount(&fs_user_mount->fatfs, fs_user_mount->str, 1);
+        FRESULT res = f_mount(&MP_STATE_PORT(fs_user_mount)->fatfs, MP_STATE_PORT(fs_user_mount)->str, 1);
 
         // check the result
         if (res == FR_OK) {
         } else if (res == FR_NO_FILESYSTEM && args[1].u_bool) {
-            res = f_mkfs(fs_user_mount->str, 1, 0);
+            res = f_mkfs(MP_STATE_PORT(fs_user_mount)->str, 1, 0);
             if (res != FR_OK) {
                 nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't mkfs"));
             }
@@ -99,15 +96,15 @@ STATIC mp_obj_t pyb_mount(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *
         }
 
         /*
-        if (fs_user_mount->writeblocks[0] == MP_OBJ_NULL) {
+        if (MP_STATE_PORT(fs_user_mount)->writeblocks[0] == MP_OBJ_NULL) {
             printf("mounted read-only");
         } else {
             printf("mounted read-write");
         }
         DWORD nclst;
         FATFS *fatfs;
-        f_getfree(fs_user_mount.str, &nclst, &fatfs);
-        printf(" on %s with %u bytes free\n", fs_user_mount.str, (uint)(nclst * fatfs->csize * 512));
+        f_getfree(MP_STATE_PORT(fs_user_mount)->str, &nclst, &fatfs);
+        printf(" on %s with %u bytes free\n", MP_STATE_PORT(fs_user_mount)->str, (uint)(nclst * fatfs->csize * 512));
         */
     }
     return mp_const_none;
diff --git a/stmhal/fsusermount.h b/stmhal/fsusermount.h
index 5a983464e..a6f54b878 100644
--- a/stmhal/fsusermount.h
+++ b/stmhal/fsusermount.h
@@ -34,6 +34,4 @@ typedef struct _fs_user_mount_t {
     FATFS fatfs;
 } fs_user_mount_t;
 
-extern fs_user_mount_t *fs_user_mount;
-
 MP_DECLARE_CONST_FUN_OBJ(pyb_mount_obj);
diff --git a/stmhal/moduos.c b/stmhal/moduos.c
index 55404c77b..4a8261e41 100644
--- a/stmhal/moduos.c
+++ b/stmhal/moduos.c
@@ -27,8 +27,7 @@
 #include <stdint.h>
 #include <string.h>
 
-#include "py/nlr.h"
-#include "py/obj.h"
+#include "py/mpstate.h"
 #include "py/objtuple.h"
 #include "py/objstr.h"
 #include "genhdr/mpversion.h"
@@ -148,8 +147,8 @@ STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
         if (sd_in_root()) {
             mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_sd));
         }
-        if (fs_user_mount != NULL) {
-            mp_obj_list_append(dir_list, mp_obj_new_str(fs_user_mount->str + 1, fs_user_mount->len - 1, false));
+        if (MP_STATE_PORT(fs_user_mount) != NULL) {
+            mp_obj_list_append(dir_list, mp_obj_new_str(MP_STATE_PORT(fs_user_mount)->str + 1, MP_STATE_PORT(fs_user_mount)->len - 1, false));
         }
         return dir_list;
     }
diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h
index a6dba431f..67efd091b 100644
--- a/stmhal/mpconfigport.h
+++ b/stmhal/mpconfigport.h
@@ -166,6 +166,9 @@ extern const struct _mp_obj_module_t mp_module_network;
     /* pointers to all CAN objects (if they have been created) */ \
     struct _pyb_can_obj_t *pyb_can_obj_all[2]; \
     \
+    /* for user-mountable block device */ \
+    struct _fs_user_mount_t *fs_user_mount; \
+    \
     /* list of registered NICs */ \
     mp_obj_list_t mod_network_nic_list; \
 
-- 
GitLab