Index: soft/giet_vm/giet_fat32/fat32.c
===================================================================
--- soft/giet_vm/giet_fat32/fat32.c	(revision 707)
+++ soft/giet_vm/giet_fat32/fat32.c	(revision 709)
@@ -38,4 +38,5 @@
 #include <vmem.h>
 #include <kernel_malloc.h>
+#include <ctx_handler.h>
 #include <bdv_driver.h>
 #include <hba_driver.h>
@@ -93,13 +94,4 @@
 #if GIET_DEBUG_FAT
 static void _display_fat_descriptor();
-#endif
-
-/////////////////////////////////////////////////////////////////////////////////
-// This debug function displays the sequence of clusters allocated to a 
-// file (or directory) identified by the "inode" argument.
-/////////////////////////////////////////////////////////////////////////////////
-
-#if GIET_DEBUG_FAT
-static void _display_clusters_list( fat_inode_t* inode );
 #endif
 
@@ -593,5 +585,5 @@
 
 
-#if GIET_DEBUG_FAT
+#if 0
 ////////////////////////////////////////////////////////
 static void _display_clusters_list( fat_inode_t* inode )
@@ -2832,6 +2824,9 @@
     }
 
-    // takes the lock
+    // takes the FAT lock and register it in thread context
+    static_scheduler_t*  psched = _get_sched();
+    unsigned int         ltid   = _get_thread_ltid();
     _spin_lock_acquire( &_fat.fat_lock );
+    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 
 
     // get inode pointer
@@ -2841,4 +2836,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_open(): path to parent not found"
                 " for file <%s>\n", pathname );
@@ -2848,4 +2845,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_open(): one name in path too long"
                 " for file <%s>\n", pathname );
@@ -2855,4 +2854,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_open(): file not found"
                 " for file <%s>\n", pathname );
@@ -2890,4 +2891,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_open(): cannot update parent directory"
                     " for file <%s>\n" , pathname );
@@ -2901,4 +2904,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_open(): cannot update DATA region "
                     " for parent of file <%s>\n", pathname );
@@ -2912,4 +2917,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_open(): cannot update FAT region"
                     " for file <%s>\n", pathname );
@@ -2921,4 +2928,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_open(): cannot update FS-INFO"
                     " for file <%s>\n", pathname );
@@ -2952,4 +2961,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_open(): File-Descriptors-Array full\n");
         return GIET_FAT32_TOO_MANY_OPEN_FILES;
@@ -2979,4 +2990,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_open(): can't truncate file\n");
             return GIET_FAT32_IO_ERROR;
@@ -2987,4 +3000,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_open(): can't truncate file\n");
             return GIET_FAT32_IO_ERROR;
@@ -2994,4 +3009,6 @@
     // releases the lock
     _spin_lock_release( &_fat.fat_lock );
+    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
 
 #if GIET_DEBUG_FAT
@@ -3036,10 +3053,15 @@
     } 
 
-    // takes lock
+    // takes the FAT lock and register it in thread context
+    static_scheduler_t*  psched = _get_sched();
+    unsigned int         ltid   = _get_thread_ltid();
     _spin_lock_acquire( &_fat.fat_lock );
+    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 
 
     if( _fat.fd[fd_id].allocated == 0 )
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_close(): file not open\n");
         return GIET_FAT32_NOT_OPEN;
@@ -3067,4 +3089,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_close(): cannot write dirty clusters "
                     "for file <%s>\n", inode->name );
@@ -3084,4 +3108,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_close(): cannot write dirty clusters "
                     "for directory <%s>\n", inode->parent->name );
@@ -3111,4 +3137,5 @@
     // release lock
     _spin_lock_release( &_fat.fat_lock );
+    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
 
     return GIET_FAT32_OK;
@@ -3161,7 +3188,11 @@
 
 /////////////////////////////////////////////////////////////////////////////////
-// The following function implements the "giet_fat_read()" system call.
-// It transfers "count" bytes from the File_Cache associated to the file
-// identified by "fd_id", to the user "buffer", from the current file offset.
+// The following function implements the "giet_fat_read()" system call,
+// but can also be used by the kernel in physical addressing mode.
+// It transfers <count> bytes from the File_Cache associated to the file
+// identified by <fd_id>, to the destination buffer defined by <vaddr>.
+// It uses the current file offset defined in the file descriptor.
+// If the <extend> 16 MSB bits are non zero, it uses physical addressing:
+// the physical  address is computed as extend[15:0] | vaddr[31:0]
 // In case of miss in the File_Cache, it loads all involved clusters into cache.
 /////////////////////////////////////////////////////////////////////////////////
@@ -3175,53 +3206,8 @@
 /////////////////////////////////////////////////////////////////////////////////
 int _fat_read( unsigned int fd_id,          // file descriptor index
-               paddr_t buffer,              // destination buffer
+               unsigned int vaddr,          // destination buffer vaddr
                unsigned int count,          // number of bytes to read
-               unsigned int phys )          // use physical_memcpy
-{
-    // checking FAT initialized
-    if( _fat.initialized != FAT_INITIALIZED )
-    {
-        _printf("\n[FAT ERROR] _fat_write(): FAT not initialized\n");
-        return GIET_FAT32_NOT_INITIALIZED;
-    }
-
-    // check fd_id overflow
-    if ( fd_id >= GIET_OPEN_FILES_MAX )
-    {
-        _printf("\n[FAT ERROR] _fat_read(): illegal file descriptor\n");
-        return GIET_FAT32_INVALID_FD;
-    }
-
-    // check file is open
-    if ( _fat.fd[fd_id].allocated == 0 )
-    {
-        _printf("\n[FAT ERROR] _fat_read(): file not open\n");
-        return GIET_FAT32_NOT_OPEN;
-    }
-
-    // takes lock
-    _spin_lock_acquire( &_fat.fat_lock );
-           
-    // get file inode pointer and offset
-    fat_inode_t* inode  = _fat.fd[fd_id].inode;
-    unsigned int seek   = _fat.fd[fd_id].seek;
-
-    // check count & seek versus file size
-    if ( count + seek > inode->size && !inode->is_dir )
-    {
-        _spin_lock_release( &_fat.fat_lock );
-        _printf("\n[FAT ERROR] _fat_read(): file too small"
-                " / seek = %x / count = %x / file_size = %x\n",
-                seek , count , inode->size );
-        return 0;
-    }
-
-    // compute first_cluster_id and first_byte_to_move 
-    unsigned int first_cluster_id   = seek >> 12;
-    unsigned int first_byte_to_move = seek & 0xFFF;   
-
-    // compute last_cluster and last_byte_to_move 
-    unsigned int last_cluster_id   = (seek + count - 1) >> 12;   
-    unsigned int last_byte_to_move = (seek + count - 1) & 0xFFF;
+               unsigned int extend )        // physical address extension
+{
 
 #if GIET_DEBUG_FAT
@@ -3231,9 +3217,68 @@
 unsigned int p       = procid & ((1<<P_WIDTH)-1);
 if ( _get_proctime() > GIET_DEBUG_FAT )
-_printf("\n[DEBUG FAT] _fat_read(): P[%d,%d,%d] enters for file <%s> "
-        " / bytes = %x / offset = %x\n"
-        "first_cluster_id = %x / first_byte_to_move = %x"
+_printf("\n[DEBUG FAT] _fat_read(): P[%d,%d,%d] enters at cycle %d\n"
+        "  fd = %d / vaddr = %x / bytes = %x / extend = %x\n",
+        x , y , p , _get_proctime(),
+        fd_id , vaddr , count , extend );
+#endif
+
+    // checking FAT initialized
+    if( _fat.initialized != FAT_INITIALIZED )
+    {
+        _printf("\n[FAT ERROR] _fat_read(): FAT not initialized\n");
+        return GIET_FAT32_NOT_INITIALIZED;
+    }
+
+    // check fd_id overflow
+    if ( fd_id >= GIET_OPEN_FILES_MAX )
+    {
+        _printf("\n[FAT ERROR] _fat_read(): illegal file descriptor\n");
+        return GIET_FAT32_INVALID_FD;
+    }
+
+    // check file is open
+    if ( _fat.fd[fd_id].allocated == 0 )
+    {
+        _printf("\n[FAT ERROR] _fat_read(): file not open\n");
+        return GIET_FAT32_NOT_OPEN;
+    }
+
+    // takes the FAT lock and register it in thread context
+    static_scheduler_t*  psched = _get_sched();
+    unsigned int         ltid   = _get_thread_ltid();
+    _spin_lock_acquire( &_fat.fat_lock );
+    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 
+
+           
+    // get file inode pointer and offset
+    fat_inode_t* inode  = _fat.fd[fd_id].inode;
+    unsigned int seek   = _fat.fd[fd_id].seek;
+
+    // check count & seek versus file size
+    if ( count + seek > inode->size && !inode->is_dir )
+    {
+        _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
+        _printf("\n[FAT ERROR] _fat_read(): file too small"
+                " / seek = %x / count = %x / file_size = %x\n",
+                seek , count , inode->size );
+        return 0;
+    }
+
+    // compute first_cluster_id and first_byte_to_move 
+    unsigned int first_cluster_id   = seek >> 12;
+    unsigned int first_byte_to_move = seek & 0xFFF;   
+
+    // compute last_cluster and last_byte_to_move 
+    unsigned int last_cluster_id   = (seek + count - 1) >> 12;   
+    unsigned int last_byte_to_move = (seek + count - 1) & 0xFFF;
+
+#if GIET_DEBUG_FAT
+if ( _get_proctime() > GIET_DEBUG_FAT )
+_printf("\n[DEBUG FAT] _fat_read(): P[%d,%d,%d] search file <%s> with seek = %x\n "
+        " first_cluster_id = %x / first_byte_to_move = %x"
         " / last_cluster_id = %x / last_byte_to_move = %x\n",
-        x , y , p , inode->name , count , seek ,
+        x , y , p , inode->name , seek ,
         first_cluster_id , first_byte_to_move , last_cluster_id , last_byte_to_move );
 #endif
@@ -3252,4 +3297,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_read(): cannot load file <%s>\n",
                     inode->name );
@@ -3289,18 +3336,16 @@
         }
 
-        // move data
-        if ( !phys )
-        {
-            void* dest = (void*)(unsigned int)buffer + done;
-
-            memcpy( dest, source, nbytes );
-        }
-        else
+        // move data 
+        if ( (extend & 0xFFFF0000) == 0 )         // no physical addressing
+        {
+            char* dest = (char*)(vaddr + done);
+            memcpy( dest , source , nbytes );
+        }
+        else                                      // physical addressing required
         {
             unsigned int flags;
-            paddr_t pdest = buffer + done;
+            paddr_t pdest    = (((paddr_t)(extend & 0x0000FFFF))<<32) + vaddr + done;
             paddr_t psource  = _v2p_translate( (unsigned int)source, &flags );
-
-            _physical_memcpy( pdest, psource, nbytes );
+            _physical_memcpy( pdest , psource , nbytes );
         }
 
@@ -3319,4 +3364,5 @@
     // release lock
     _spin_lock_release( &_fat.fat_lock );
+    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
 
     return done;
@@ -3327,7 +3373,11 @@
 
 /////////////////////////////////////////////////////////////////////////////////
-// The following function implements the "giet_fat_write()" system call.
-// It transfers "count" bytes to the fat_cache associated to the file
-// identified by "fd_id", from the user "buffer", using the current file offset.
+// The following function implements the "giet_fat_write()" system call,
+// but can also be used by the kernel in physical addressing mode.
+// It transfers <count> bytes to the File_Cache associated to the file
+// identified by <fd_id>, from the source buffer defined by <vaddr>.
+// It uses the current file offset defined in the file descriptor.
+// If the <extend> 16 MSB bits are non zero, it uses physical addressing:
+// the physical  address is computed as extend[15:0] | vaddr[31:0]
 // It increases the file size and allocate new clusters if (count + offset) 
 // is larger than the current file size. Then it loads and updates all 
@@ -3344,6 +3394,7 @@
 /////////////////////////////////////////////////////////////////////////////////
 int _fat_write( unsigned int fd_id,    // file descriptor index
-                void*        buffer,   // source buffer
-                unsigned int count )   // number of bytes to write
+                unsigned int vaddr,    // source buffer vaddr
+                unsigned int count,    // number of bytes to write
+                unsigned int extend )  // physical address extension
 {
     // checking FAT initialized
@@ -3354,6 +3405,10 @@
     }
 
-    // takes lock
+    // takes the FAT lock and register it in thread context
+    static_scheduler_t*  psched = _get_sched();
+    unsigned int         ltid   = _get_thread_ltid();
     _spin_lock_acquire( &_fat.fat_lock );
+    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 
+
            
     // check fd_id overflow
@@ -3361,4 +3416,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_write(): illegal file descriptor\n");
         return GIET_FAT32_INVALID_FD;
@@ -3369,4 +3426,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_write(): file not open\n" );
         return GIET_FAT32_NOT_OPEN;
@@ -3377,4 +3436,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_write(): file <%s> is read-only\n",
                 _fat.fd[fd_id].inode->name );
@@ -3429,4 +3490,6 @@
             {
                 _spin_lock_release( &_fat.fat_lock );
+                _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
                 _printf("\n[FAT ERROR] _fat_write(): no free clusters"
                         " for file <%s>\n", _fat.fd[fd_id].inode->name );
@@ -3439,4 +3502,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_write(): cannot update parent directory entry"
                     " for file <%s>\n", _fat.fd[fd_id].inode->name );
@@ -3483,4 +3548,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_write(): cannot load file <%s>\n",
                     inode->name );
@@ -3498,5 +3565,4 @@
 
         // compute memcpy arguments
-        unsigned char* source = (unsigned char*)buffer + done;
         unsigned char* dest;
         unsigned int   nbytes;
@@ -3522,6 +3588,18 @@
         }
 
-        //move date
-        memcpy( dest , source , nbytes ); 
+        // move data
+        if ( (extend & 0xFFFF0000) == 0 )     // no physical addressing
+        {
+            char* source = (char*)(vaddr + done);
+            memcpy( dest , source , nbytes ); 
+        }
+        else                                  // physical addressing required
+        {
+            unsigned int flags;
+            paddr_t      psource = (((paddr_t)(extend & 0x0000FFFF))<<32) + vaddr + done;
+            paddr_t      pdest   = _v2p_translate( (unsigned int)dest , &flags );
+            _physical_memcpy( pdest , psource , nbytes );
+        }
+
         done = done + nbytes;
 
@@ -3539,4 +3617,5 @@
     // release lock
     _spin_lock_release( &_fat.fat_lock );
+    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
 
     return done;
@@ -3577,6 +3656,10 @@
     }
 
-    // takes lock
+    // takes the FAT lock and register it in thread context
+    static_scheduler_t*  psched = _get_sched();
+    unsigned int         ltid   = _get_thread_ltid();
     _spin_lock_acquire( &_fat.fat_lock );
+    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 
+
 
     // check file open
@@ -3584,4 +3667,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_lseek(): file not open\n");
         return GIET_FAT32_NOT_OPEN;
@@ -3596,4 +3681,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_lseek(): illegal whence value\n");
         return GIET_FAT32_INVALID_ARG;
@@ -3615,4 +3702,5 @@
     // release lock
     _spin_lock_release( &_fat.fat_lock );
+    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
 
     return new_seek;
@@ -3665,6 +3753,10 @@
     }
 
-    // take the lock 
+    // takes the FAT lock and register it in thread context
+    static_scheduler_t*  psched = _get_sched();
+    unsigned int         ltid   = _get_thread_ltid();
     _spin_lock_acquire( &_fat.fat_lock );
+    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 
+
 
     // get searched file inode 
@@ -3680,4 +3772,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_remove(): file <%s> not found\n", 
                 pathname );
@@ -3687,4 +3781,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_remove(): name too long in <%s>\n",
                 pathname );
@@ -3696,4 +3792,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_remove(): <%s> is a directory\n",
                 pathname );
@@ -3703,4 +3801,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_remove(): <%s> is not a directory\n", 
                 pathname );
@@ -3718,4 +3818,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_remove(): file <%s> still referenced\n",
                 pathname );
@@ -3730,4 +3832,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_remove(): cannot scan directory <%s>\n", 
                     pathname );
@@ -3737,4 +3841,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_remove(): directory <%s> not empty\n", 
                     pathname );
@@ -3753,4 +3859,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_remove(): cannot remove <%s> from FS\n",
                 pathname );
@@ -3760,4 +3868,5 @@
     // release lock and return success
     _spin_lock_release( &_fat.fat_lock );
+    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
 
 #if GIET_DEBUG_FAT
@@ -3821,6 +3930,10 @@
     }
 
-    // take the lock 
+    // takes the FAT lock and register it in thread context
+    static_scheduler_t*  psched = _get_sched();
+    unsigned int         ltid   = _get_thread_ltid();
     _spin_lock_acquire( &_fat.fat_lock );
+    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 
+
 
     // get "old" and "old_parent" inode pointers
@@ -3828,4 +3941,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_rename(): <%s> not found\n", old_path );
         return GIET_FAT32_FILE_NOT_FOUND;
@@ -3845,4 +3960,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             return GIET_FAT32_OK;
         }
@@ -3859,4 +3976,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_rename(): <%s> not found\n", new_path );
         return GIET_FAT32_FILE_NOT_FOUND;
@@ -3867,5 +3986,7 @@
     {
         _spin_lock_release( &_fat.fat_lock );
-        _printf("\n[FAT ERROR] _fat_rename(): can't move %s into its own subdirectory\n", old_path );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
+        _printf("\n[FAT ERROR] _fat_rename(): can't move %s into  own directory\n", old_path );
         return GIET_FAT32_MOVE_INTO_SUBDIR;
     }
@@ -3894,4 +4015,6 @@
             {
                 _spin_lock_release( &_fat.fat_lock );
+                _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
                 _printf("\n[FAT ERROR] _fat_rename(): cannot scan directory <%s>\n", 
                         to_remove->name );
@@ -3901,4 +4024,6 @@
             {
                 _spin_lock_release( &_fat.fat_lock );
+                _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
                 _printf("\n[FAT ERROR] _fat_rename(): directory <%s> not empty\n", 
                         to_remove->name );
@@ -3911,4 +4036,6 @@
             {
                 _spin_lock_release( &_fat.fat_lock );
+                _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
                 _printf("\n[FAT ERROR] _fat_rename(): file <%s> still referenced\n", 
                         to_remove->name );
@@ -3945,4 +4072,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_rename(): cannot add <%s> into <%s>\n",
                 new->name , new_parent->name );
@@ -3959,4 +4088,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_rename(): cannot update <%s> on device\n",
                     new_parent->name );
@@ -3968,4 +4099,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_rename(): cannot remove <%s> from <%s>\n",
                 old->name , old_parent->name );
@@ -3985,4 +4118,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_rename(): cannot update <%s> on device\n",
                     old_parent->name );
@@ -3996,4 +4131,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_rename(): cannot remove <%s> from FS\n",
                     to_remove->name );
@@ -4004,4 +4141,5 @@
     // release lock
     _spin_lock_release( &_fat.fat_lock );
+    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
 
     return GIET_FAT32_OK;
@@ -4052,7 +4190,10 @@
     }
 
-    // takes the lock
+    // takes the FAT lock and register it in thread context
+    static_scheduler_t*  psched = _get_sched();
+    unsigned int         ltid   = _get_thread_ltid();
     _spin_lock_acquire( &_fat.fat_lock );
-    
+    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 
+
     // get inode
     unsigned int code = _get_inode_from_path( pathname , &inode );
@@ -4061,4 +4202,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_mkdir(): path to parent not found"
                 " for directory <%s>\n", pathname );
@@ -4068,4 +4211,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_mkdir(): one name in path too long"
                 " for directory  <%s>\n", pathname );
@@ -4075,4 +4220,6 @@
     {
         _spin_lock_release( &_fat.fat_lock );
+        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
         _printf("\n[FAT ERROR] _fat_mkdir(): directory <%s> already exist\n",
                 pathname );
@@ -4098,4 +4245,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_mkdir(): no free cluster"
                     " for directory <%s>\n" , pathname );
@@ -4127,4 +4276,6 @@
         { 
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_mkdir(): cannot update parent directory"
                     " for directory <%s>\n" , pathname );
@@ -4138,4 +4289,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_mkdir(): cannot update DATA region "
                     " for parent of directory <%s>\n", pathname );
@@ -4149,4 +4302,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_mkdir(): cannot update FAT region"
                     " for directory <%s>\n", pathname );
@@ -4158,4 +4313,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_mkdir(): cannot update FS-INFO"
                     " for directory <%s>\n", pathname );
@@ -4169,4 +4326,6 @@
         {
             _spin_lock_release( &_fat.fat_lock );
+            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
+
             _printf("\n[FAT ERROR] _fat_mkdir(): cannot update DATA region"
                     " for directory <%s>\n", pathname );
@@ -4177,4 +4336,5 @@
     // release lock
     _spin_lock_release( &_fat.fat_lock );
+    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
 
     return GIET_FAT32_OK;
@@ -4293,7 +4453,5 @@
         {
             // seek back to this entry
-            _spin_lock_acquire( &_fat.fat_lock );
-            _fat.fd[fd_id].seek -= DIR_ENTRY_SIZE;
-            _spin_lock_release( &_fat.fat_lock );
+            _atomic_increment( &_fat.fd[fd_id].seek , -DIR_ENTRY_SIZE );
 
             return GIET_FAT32_NO_MORE_ENTRIES;
