Index: soft/giet_vm/giet_fat32/fat32.c
===================================================================
--- soft/giet_vm/giet_fat32/fat32.c	(revision 503)
+++ soft/giet_vm/giet_fat32/fat32.c	(revision 530)
@@ -5,8 +5,7 @@
 // Copyright (c) UPMC-LIP6
 //////////////////////////////////////////////////////////////////////////////////
-// The fat32.h and fat32.c files define a library of access functions
+// The fat.h and fat_common.c files define a library of access functions
 // to a FAT32 disk on a block device. It is intended to be used
 // by the GIET_VM nano-kernel for both the boot code and the kernel code.
-// This code uses functions defined in the utils.c and drivers.c files.
 //////////////////////////////////////////////////////////////////////////////////
 // Implementation notes:
@@ -15,15 +14,19 @@
 // 2. the "cluster" variable is actually a cluster index. A cluster contains
 //    typically 8 sectors (4K bytes) and the cluster index is a 32 bits word.
-// 2. This FAT32 library uses a FAT cache whose storage capacity is one
-//    sector (512 bytes, or 128 cluster indexes in FAT)
-// 3. This FAT32 library can be used in 3 modes: BOOT/BOOT/KERNEL/USER
-//    defining different behaviours for the IOC driver.
+// 3. This FAT32 library uses a FAT cache whose storage capacity is one
+//    sector (512 bytes = 128 cluster indexes in FAT)
 //////////////////////////////////////////////////////////////////////////////////
 
 #include <giet_config.h>
+#include <hard_config.h>
 #include <fat32.h>
+#include <utils.h>
+#include <vmem.h>
+#include <bdv_driver.h>
+#include <hba_driver.h>
+#include <sdc_driver.h>
+#include <rdk_driver.h>
+#include <mmc_driver.h>
 #include <tty0.h>
-#include <ioc_driver.h>
-#include <utils.h>
 
 //////////////////////////////////////////////////////////////////////////////////
@@ -31,9 +34,86 @@
 //////////////////////////////////////////////////////////////////////////////////
 
-extern fat32_fs_t fat __attribute__((aligned(512)));
+extern fat32_fs_t _fat;
+
+extern unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE];
+  
+//////////////////////////////////////////////////////////////////////////////
+// This function computes the memory buffer physical address, and calls 
+// the proper IOC driver depending on the subtype (BDV / HBA / SDC /RDK). 
+// The use_irq argument allows to activate the descheduling mode, if it 
+// supported by the IOC driver subtype
+//////////////////////////////////////////////////////////////////////////////
+// Return 0 in case of success, return -1 in case of error
+//////////////////////////////////////////////////////////////////////////////
+static
+int _fat_ioc_access( unsigned int use_irq,
+                     unsigned int to_mem,
+                     unsigned int lba,
+                     unsigned int buf_vaddr,
+                     unsigned int count ) 
+{
+    // compute memory buffer physical address
+    unsigned int       flags;         // for _v2p_translate
+    unsigned long long buf_paddr;     // buffer physical address 
+
+    if ( ((_get_mmu_mode() & 0x4) == 0 ) || USE_IOC_RDK )  // identity
+    {
+        buf_paddr = (unsigned long long)buf_vaddr;
+    }
+    else                                // V2P translation required
+    {
+        buf_paddr = _v2p_translate( buf_vaddr , &flags );
+    }
+
+#if (GIET_DEBUG_FAT > 1)
+unsigned int procid  = _get_procid();
+unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
+unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int p       = procid & ((1<<P_WIDTH)-1);
+_printf("\n[DEBUG FAT] P[%d,%d,%d] enters _fat_ioc_access() at cycle %d\n"
+        "  to_mem = %d / vaddr = %x / paddr = %l / sectors = %d / lba = %x\n",
+        x, y , p, _get_proctime(), to_mem, buf_vaddr, buf_paddr, count, lba );
+#endif
+
+    // cache coherence for both L1 & L2 caches
+    if ( to_mem ) // memory write  
+    {
+        // L1 cache (only if L1 cache coherence not guaranteed by hardware)
+        if ( GIET_NO_HARD_CC ) _dcache_buf_invalidate( buf_vaddr, count<<9 );
+
+        // L2 cache (only if we use an IO-Bridge component in architecture))
+        if ( USE_IOB ) _mmc_inval( buf_paddr, count<<9 );
+    }
+    else         // memory read 
+    {
+        // L1 cache : nothing to do for L1 write-through
+
+        // L2 cache (only if we use an IO-Bridge component in architecture))
+        if ( USE_IOB ) _mmc_sync( buf_paddr, count<<9 );
+    }
+
+    // call the proper descheduling physical device driver 
+  
+#if   ( USE_IOC_BDV )
+    return( _bdv_access( use_irq , to_mem , lba , buf_paddr , count ) ); 
+#elif ( USE_IOC_HBA )
+    return( _hba_access( use_irq , to_mem , lba , buf_paddr , count ) );
+#elif ( USE_IOC_SPI )
+    return( _sdc_access( use_irq , to_mem , lba , buf_paddr , count ) );
+#elif ( USE_IOC_RDK )
+    return( _rdk_access( use_irq , to_mem , lba , buf_paddr , count ) );
+#else
+    _printf("\n[FAT ERROR] in _fat_ioc_access() : no IOC driver\n");
+    _exit();
+#endif
+
+}  // end _fat_ioc_access()
+
 
 //////////////////////////////////////////////////////////////////////////////////
 // This function displays the content of the FAT cache
 //////////////////////////////////////////////////////////////////////////////////
+#if (GIET_DEBUG_FAT > 1)
+static
 void _display_fat_cache()
 {
@@ -45,5 +125,5 @@
 
     _puts("\n*********************** fat_cache_lba = ");
-    _putx( fat.cache_lba );
+    _putx( _fat.cache_lba );
     _puts(" *****************************\n");
 
@@ -58,16 +138,16 @@
         {
             unsigned int byte  = (line<<5) + (word<<2);
-            unsigned int hexa  = (fat.fat_cache[byte  ]<<24) |
-                                 (fat.fat_cache[byte+1]<<16) |
-                                 (fat.fat_cache[byte+2]<< 8) |
-                                 (fat.fat_cache[byte+3]);
+            unsigned int hexa  = (_fat.fat_cache[byte  ]<<24) |
+                                 (_fat.fat_cache[byte+1]<<16) |
+                                 (_fat.fat_cache[byte+2]<< 8) |
+                                 (_fat.fat_cache[byte+3]);
             _putx( hexa );
             _puts(" | ");
 
             // prepare display ascii
-            temp[word] = fat.fat_cache[byte]         |
-                         (fat.fat_cache[byte+1]<<8)  |
-                         (fat.fat_cache[byte+2]<<16) |
-                         (fat.fat_cache[byte+3]<<24) ;
+            temp[word] = _fat.fat_cache[byte]         |
+                         (_fat.fat_cache[byte+1]<<8)  |
+                         (_fat.fat_cache[byte+2]<<16) |
+                         (_fat.fat_cache[byte+3]<<24) ;
         }
         
@@ -79,4 +159,33 @@
 
 } // end _display_fat_cache()  
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function displays the FAT descriptor.
+//////////////////////////////////////////////////////////////////////////////////
+#if GIET_DEBUG_FAT
+static
+void _fat_print()
+{
+    _printf("\n########################## FAT32 ################################"  
+            "\nFAT initialised                  %x"
+            "\nSector Size  (bytes)             %x"
+            "\nSectors per cluster              %x"
+            "\nFAT region first lba             %x"
+            "\nData region first lba            %x"
+            "\nNumber of sectors for one FAT    %x"
+            "\nNumber of free clusters          %x"
+            "\nLast allocated cluster           %x" 
+            "\n#################################################################\n",
+            _fat.initialised,
+            _fat.sector_size,
+            _fat.sectors_per_cluster,
+            _fat.fat_lba,
+            _fat.data_lba,
+            _fat.fat_sectors,
+            _fat.number_free_cluster,
+            _fat.last_cluster_allocated );
+} // end _fat_print()
+#endif
 
 //////////////////////////////////////////////////////////////////////////////////
@@ -84,6 +193,7 @@
 // by an (offset,length) mnemonic defined in fat32.h file.
 //////////////////////////////////////////////////////////////////////////////////
-static inline int get_length( int offset, 
-                              int length )
+static inline 
+int get_length( int offset, 
+                int length )
 {
     return length;
@@ -94,8 +204,9 @@
 // The modified field in buffer is defined by the offset and size arguments.
 //////////////////////////////////////////////////////////////////////////////
-static void _write_entry( unsigned int   offset,
-                         unsigned int   size,
-                         char*          buffer,
-                         unsigned int   value )
+static 
+void _write_entry( unsigned int   offset,
+                   unsigned int   size,
+                   char*          buffer,
+                   unsigned int   value )
 {
     unsigned int turn = 0;
@@ -116,8 +227,9 @@
 // The analysed field in buffer is defined by the offset and size arguments.
 //////////////////////////////////////////////////////////////////////////////
-static unsigned int _read_entry( unsigned int   offset,
-                                 unsigned int   size,
-                                 char*          buffer,
-                                 unsigned int   little_indian )
+static 
+unsigned int _read_entry( unsigned int   offset,
+                          unsigned int   size,
+                          char*          buffer,
+                          unsigned int   little_indian )
 {
     unsigned int turn;
@@ -156,9 +268,10 @@
 // The DATA region indexing starts a cluster 2.
 //////////////////////////////////////////////////////////////////////////////////
-static inline unsigned int lba_to_cluster( unsigned int lba )                   
-{
-   if (lba < fat.data_lba ) return 0;
-
-   return ( (lba - fat.data_lba) / fat.sectors_per_cluster) + 2; 
+static inline 
+unsigned int lba_to_cluster( unsigned int lba )                   
+{
+   if (lba < _fat.data_lba ) return 0;
+
+   return ( (lba - _fat.data_lba) / _fat.sectors_per_cluster) + 2; 
 }
 
@@ -167,9 +280,10 @@
 // from the cluster index. The cluster index must be larger than 2. 
 //////////////////////////////////////////////////////////////////////////////////
-static inline unsigned int cluster_to_lba( unsigned int cluster )       
+static inline 
+unsigned int cluster_to_lba( unsigned int cluster )       
 {
    if ( cluster < 2 ) return 0; 
 
-   return  (fat.sectors_per_cluster * (cluster - 2)) + fat.data_lba;
+   return  (_fat.sectors_per_cluster * (cluster - 2)) + _fat.data_lba;
 }
 
@@ -179,49 +293,39 @@
 // remark: a sector of FAT contains 128 cluster indexes.
 /////////////////////////////////////////////////////////////////////////////////
-static unsigned int _get_next_cluster( unsigned int mode,
-                                       unsigned int cluster )
+static 
+unsigned int _get_next_cluster( unsigned int use_irq,
+                                unsigned int cluster )
 {
     // compute lba of the sector containing the cluster index
-    unsigned int lba = fat.fat_lba + (cluster / 128);
-
-#if GIET_DEBUG_FAT
+    unsigned int lba = _fat.fat_lba + (cluster / 128);
+
+    if ( lba != _fat.cache_lba )      // miss in fat_cache
+    {
+        // access fat
+        if( _fat_ioc_access( use_irq,
+                             1,               // read
+                             lba, 
+                             (unsigned int)_fat.fat_cache,
+                             1 ) )            // one sector
+        {
+            _printf("[FAT_ERROR] in get_next_cluster_id() : cannot read block %x", 
+                    lba );
+            return 1;
+        }
+        _fat.cache_lba = lba;
+    }
+
+    unsigned int next = _read_entry( ((cluster % 128) * 4), 
+                                     4, 
+                                     _fat.fat_cache,
+                                     1 );
+#if (GIET_DEBUG_FAT > 1)
 unsigned int procid  = _get_procid();
 unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
 unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
 unsigned int p       = procid & ((1<<P_WIDTH)-1);
-
-_printf("\n[FAT DEBUG] _get_next_cluster() : P[%d,%d,%d] enters for cluster %x\n",
-      x , y , p , cluster );
-#endif
-
-    if ( lba != fat.cache_lba )      // miss in fat_cache
-    {
-        // we cannot access fat in user mode
-        if( mode == IOC_USER_MODE ) mode = IOC_KERNEL_MODE;
-        
-        // access fat
-        if( _ioc_read( 0,                 // channel
-                       mode,              // mode for IOC driver
-                       lba,               // sector index 
-                       fat.fat_cache,     // fat cache
-                       1 ) )              // one sector
-        {
-            _printf("[FAT_ERROR] in get_next cluster_id() : cannot read block %x", lba );
-            return 1;
-        }
-        fat.cache_lba = lba;
-    
-#if (GIET_DEBUG_FAT > 1)
+_printf("\n[DEBUG FAT] P[%d,%d,%d] in _get_next_cluster() :  next = %x\n",
+        x , y , p , next );
 _display_fat_cache();
-#endif
-
-    }
-    unsigned int next = _read_entry( ((cluster % 128) * 4), 
-                                     4, 
-                                     fat.fat_cache,
-                                     1 );
-
-#if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _get_next_cluster() : P[%d,%d,%d] next cluster = %x\n", next );
 #endif
 
@@ -241,5 +345,6 @@
 // Return the '_' character if c is illegal
 ////////////////////////////////////////////////////////////////
-static unsigned char illegal_short(unsigned char c)
+static 
+unsigned char illegal_short(unsigned char c)
 {
    const unsigned char illegal_char [] =";+=[]â,\"*\\<>/?:|\0";
@@ -265,6 +370,7 @@
 // Return 0 if not legal SFN
 /////////////////////////////////////////////////////////////////////////////////
-static int is_short( char* string, 
-                     char* sfn_string)
+static 
+int is_short( char* string, 
+              char* sfn_string)
 {
     int s_size   = 0;
@@ -340,7 +446,8 @@
 // Return 1 if name found, Return 0 if NUL character found, 
 ///////////////////////////////////////////////////////////////////////
-static int get_name_from_path( char*          pathname,
-                               char*          name,
-                               unsigned int*  nb_read )	
+static 
+int get_name_from_path( char*          pathname,
+                        char*          name,
+                        unsigned int*  nb_read )	
 {
     if ( pathname[*nb_read] == 0 ) return 0;
@@ -452,15 +559,17 @@
 } // end get_name_from_long()
 
-//////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////
 // This function update a DIR_ENTRY, write a new value into a specific field 
 // (ex : DIR_FILE_SIZE, when we want update the file size after a fat_write)
 // Return 0 in case of success, > 0 if failure.
-//////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////
 // TODO : make this function less complex
-//////////////////////////////////////////////////////////////////////////////////////
-static inline unsigned int update_entry( unsigned int fd_id, 
-                                         unsigned int field,
-                                         unsigned int size,
-                                         unsigned int value )
+///////////////////////////////////////////////////////////////////////////////////
+static inline 
+unsigned int _update_entry( unsigned int use_irq,
+                            unsigned int fd_id, 
+                            unsigned int field,
+                            unsigned int size,
+                            unsigned int value )
 {
     char dir_entry[32];   // buffer to store a full directory_entry
@@ -468,11 +577,11 @@
     char file_name[256];  // buffer to store the name (not pathname) of the file
 
-    char sfn_string[12]  = {[0 ... 10] = ' ', '\0'};       // buffer for a Short File Name
-    unsigned int lba     = fat.fd[fd_id].lba_dir_entry;    // Lba of file dir_entry
+    char sfn_string[12]  = {[0 ... 10] = ' ', '\0'};     // buffer Short File Name
+    unsigned int lba     = _fat.fd[fd_id].lba_dir_entry;  // Lba of file dir_entry
     unsigned int is_sfn;         
-    unsigned int attr    = 0;                              // directory entry attribute
-    unsigned int ord     = 0;                              // directory entry sequence
-    unsigned int found   = 0;                              // name found
-    unsigned int offset  = 0;                              // offset in fat_cache
+    unsigned int attr    = 0;                            // dir entry attribute
+    unsigned int ord     = 0;                            // dir entry sequence
+    unsigned int found   = 0;                            // name found
+    unsigned int offset  = 0;                            // offset in fat_cache
     unsigned int i       = 0;
     unsigned int nb_read = 0;
@@ -482,5 +591,5 @@
     
     // Get the name of the file.
-    while ( get_name_from_path( fat.fd[fd_id].name, file_name, &nb_read ) )
+    while ( get_name_from_path( _fat.fd[fd_id].name, file_name, &nb_read ) )
     {
     }
@@ -489,14 +598,16 @@
     is_sfn = is_short( file_name, sfn_string );
 
-    if ( _ioc_read( 0,               // channel
-                    IOC_KERNEL_MODE, // mode for IOC driver
-                    lba,             // sector index 
-                    fat.fat_cache,   // buffer address
-                    1 ) )            // one sector
-    {
-        _printf("\n[FAT ERROR] in update_entry() cannot read sector %x\n", lba );
+    // access FAT
+    if ( _fat_ioc_access( use_irq,
+                          1,               // read
+                          lba, 
+                          (unsigned int)_fat.fat_cache,
+                          1 ) )            // one sector
+    {
+        _printf("\n[FAT ERROR] in _update_entry() cannot read sector %x\n", 
+                lba );
         return 1;
     }
-    fat.cache_lba = lba;
+    _fat.cache_lba = lba;
 
     // - the offset increment is an integer number of directory entry (32 bytes)
@@ -504,6 +615,6 @@
     while ( !found )
     {
-        attr = _read_entry( DIR_ATTR, fat.fat_cache + offset, 0 );
-        ord  = _read_entry( LDIR_ORD, fat.fat_cache + offset, 0 );
+        attr = _read_entry( DIR_ATTR, _fat.fat_cache + offset, 0 );
+        ord  = _read_entry( LDIR_ORD, _fat.fat_cache + offset, 0 );
 
         if ( is_sfn == 1 )		                       // searched name is short
@@ -520,9 +631,9 @@
                     (ord  != NO_MORE_ENTRY ) )         // SFN entry : checked
             {
-                memcpy( dir_entry, fat.fat_cache + offset, DIR_ENTRY_SIZE );    
+                memcpy( dir_entry, _fat.fat_cache + offset, DIR_ENTRY_SIZE );    
             }
             else if (ord == NO_MORE_ENTRY )            // end of directory : return
             {
-                _printf("\n[FAT ERROR] in update_entry() : reaches end of directory\n");
+                _printf("\n[FAT ERROR] in _update_entry() : reaches end\n");
                 return 1;
             }
@@ -539,5 +650,5 @@
                     (ord != NO_MORE_ENTRY) )           // LFN entry : checked
             {
-                memcpy( dir_entry, fat.fat_cache + offset, DIR_ENTRY_SIZE );    
+                memcpy( dir_entry, _fat.fat_cache + offset, DIR_ENTRY_SIZE );    
             }
             else if ( (attr != ATTR_LONG_NAME_MASK) && 
@@ -550,5 +661,5 @@
             else if (ord == NO_MORE_ENTRY )			   // end of directory : return
             {
-                _printf("\n[FAT ERROR] in update_entry() reaches end of directory\n");
+                _printf("\n[FAT ERROR] in _update_entry() reaches end\n");
                 return 1;
             }
@@ -568,5 +679,5 @@
             if ( _strncmp( (char*)sfn_string, (char*)name_entry, 13 ) == 0 )
             {
-                _write_entry(offset + field, size, fat.fat_cache, value);
+                _write_entry(offset + field, size, _fat.fat_cache, value);
                 found = 1;
             }
@@ -581,10 +692,11 @@
 
             unsigned shift = ((ord & 0xf) - 1) * 13;
-            if ( _strncmp( (char*)(file_name + shift), (char*)name_entry, 13 ) == 0 )
+            if ( _strncmp( (char*)(file_name + shift), 
+                           (char*)name_entry, 13 ) == 0 )
             {
                 if ( (ord & 0xf) == 1 )
                 {
                     offset = offset + DIR_ENTRY_SIZE;
-                    _write_entry(offset + field, size, fat.fat_cache, value);
+                    _write_entry(offset + field, size, _fat.fat_cache, value);
                     found = 1;
                 }
@@ -599,49 +711,65 @@
     }
 
-    return _ioc_write( 0,                // channel
-                       IOC_KERNEL_MODE,  // mode
-                       lba,              // sector index
-                       fat.fat_cache,    // source buffer
-                       1 );              // one sector
-}
-//////////////////////////////////////////////////////////////////////////////////
-// This function update FS_INFO:
+    // write block to FAT
+    if ( _fat_ioc_access( use_irq,
+                          0,                // write
+                          lba, 
+                          (unsigned int)_fat.fat_cache, 
+                          1 ) )             // one sector
+    {
+        _printf("\n[FAT ERROR] in _update_entry() cannot write sector %x\n", 
+                lba );
+        return 1;
+    }
+
+    return 0;
+} // end _update_entry()
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function update the FS_INFO block:
 // last cluster allocated and number of free cluster. 
 // Return 0 in case of success, > 0 if failure.
 //////////////////////////////////////////////////////////////////////////////////
-static inline unsigned int _update_fs_info( )
-{
-    unsigned int lba = fat.fs_info_lba;
-
-#if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _update_fs_info() : enters\n");
-#endif
-
-    if ( lba == fat.cache_lba )            // hit cache
-    {
-        _write_entry( FS_FREE_CLUSTER     , fat.fat_cache, fat.number_free_cluster );
-        _write_entry( FS_FREE_CLUSTER_HINT, fat.fat_cache, fat.last_cluster_allocated );
-    }
-    else                                   // miss cache
-    {
-        if ( _ioc_read( 0,                 // channel
-                        IOC_KERNEL_MODE,   // mode for IOC driver
-                        lba,               // sector index 
-                        fat.fat_cache,     // source buffer
-                        1 ) )              // one sector
-        {
-            _printf("\n[FAT_ERROR] in _update_fat() cannot read block %x\n", lba );
+static inline 
+unsigned int _update_fs_info( unsigned int use_irq )
+{
+    unsigned int lba = _fat.fs_info_lba;
+
+#if GIET_DEBUG_FAT
+_printf("\n[DEBUG FAT] _update_fs_info()\n");
+#endif
+
+    // update FAT cache in case of miss
+    if ( lba != _fat.cache_lba )
+    {
+        if ( _fat_ioc_access( use_irq,
+                              1,                 // read
+                              lba, 
+                              (unsigned int)_fat.fat_cache, 
+                              1 ) )              // one sector
+        {
+            _printf("\n[FAT_ERROR] in _update_fs_info() cannot read block\n");
             return 1;
         }
-        fat.cache_lba = lba;
-        _write_entry( FS_FREE_CLUSTER     , fat.fat_cache, fat.number_free_cluster );
-        _write_entry( FS_FREE_CLUSTER_HINT, fat.fat_cache, fat.last_cluster_allocated );
-    }
-    return _ioc_write( 0,                // channel
-                       IOC_KERNEL_MODE,  // mode    
-                       lba,              // sector index
-                       fat.fat_cache,    // source buffer
-                       1 );              // one sector
-}
+        _fat.cache_lba = lba;
+    }
+
+    _write_entry( FS_FREE_CLUSTER     , _fat.fat_cache, _fat.number_free_cluster );
+    _write_entry( FS_FREE_CLUSTER_HINT, _fat.fat_cache, _fat.last_cluster_allocated );
+   
+    // write bloc to FAT
+    if ( _fat_ioc_access( use_irq,
+                          0,                // write
+                          lba,
+                          (unsigned int)_fat.fat_cache, 
+                          1 ) )             // one sector
+    {
+        _printf("\n[FAT_ERROR] in _update_fs_info() cannot write block\n");
+        return 1;
+    }
+
+    return 0;
+}  // end _update_fs_info()
 
 //////////////////////////////////////////////////////////////////////////////////
@@ -650,36 +778,47 @@
 // Return 0 in case of success, > 0 if failure.
 //////////////////////////////////////////////////////////////////////////////////
-static inline unsigned int _update_fat( unsigned int cluster, 
-                                        unsigned int value  )
-{
-    unsigned int lba = fat.fat_lba + (cluster / 128);
-
-#if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _update_fat() : cluster = %x / value = %x\n", cluster, value );
-#endif
-
-    if ( lba == fat.cache_lba )            // hit cache
-    {
-        _write_entry( ((cluster % 128) << 2), 4, fat.fat_cache, value );
-    }
-    else                                   // miss cache
-    {
-        if ( _ioc_read( 0,                 // channel
-                        IOC_KERNEL_MODE,   // mode for IOC driver
-                        lba,               // sector index 
-                        fat.fat_cache,     // source buffer
-                        1 ) )              // one sector
-        {
-            _printf("\n[FAT_ERROR] in _update_fat() cannot read block %x\n", lba );
+static inline 
+unsigned int _update_fat( unsigned int use_irq,
+                          unsigned int cluster, 
+                          unsigned int value  )
+{
+    unsigned int lba = _fat.fat_lba + (cluster / 128);
+
+#if GIET_DEBUG_FAT
+_printf("\n[DEBUG FAT] _update_fat() : cluster = %x / value = %x\n", 
+        cluster, value );
+#endif
+
+    // update FAT cache in case of miss
+    if ( lba != _fat.cache_lba )  
+    {
+        if ( _fat_ioc_access( use_irq,
+                              1,                 // read
+                              lba, 
+                              (unsigned int)_fat.fat_cache, 
+                              1 ) )              // one sector
+        {
+            _printf("\n[FAT_ERROR] in _update_fat() cannot read block %x\n",
+                    lba );
             return 1;
         }
-        fat.cache_lba = lba;
-        _write_entry( ((cluster % 128) << 2), 4, fat.fat_cache, value );
-    }
-    return _ioc_write( 0,                // channel
-                       IOC_KERNEL_MODE,  // mode      
-                       lba,              // sector indexs
-                       fat.fat_cache,    // source buffer 
-                       1 );              // one sector
+        _fat.cache_lba = lba;
+    }
+
+    _write_entry( ((cluster % 128) << 2), 4, _fat.fat_cache, value );
+
+    // write bloc to FAT
+    if ( _fat_ioc_access( use_irq,
+                          0,                // write
+                          lba,
+                          (unsigned int)_fat.fat_cache,
+                          1 ) )             // one sector
+    {
+        _printf("\n[FAT_ERROR] in _update_fat() cannot write block %x\n",
+                lba );
+        return 1;
+    }
+
+    return 0;
 } // end update_fat()
 
@@ -689,14 +828,16 @@
 // return 0 if success, -1 if failure
 //////////////////////////////////////////////////////////////////////////////////
-static inline int _fat_allocate( unsigned int fd_id, 
-                                 unsigned int count )
-{
-    unsigned int next_cluster = fat.fd[fd_id].first_cluster;    // get first cluster
-    unsigned int cluster_to_allocate = count;                   // clusters to allocate
-    unsigned int last_cluster_file;                             // Last cluster (EOC)
-    unsigned int free_cluster = fat.last_cluster_allocated + 1; // First free cluster
+static inline 
+int _fat_allocate( unsigned int use_irq,
+                   unsigned int fd_id, 
+                   unsigned int count )
+{
+    unsigned int next_cluster = _fat.fd[fd_id].first_cluster;    // first cluster
+    unsigned int cluster_to_allocate = count;                   // to allocate
+    unsigned int last_cluster_file;                             // Last cluster 
+    unsigned int free_cluster = _fat.last_cluster_allocated + 1; // First free 
 
     // Check if free_cluster is really free (must be true)
-    if ( _get_next_cluster( IOC_KERNEL_MODE, free_cluster ) != FREE_CLUSTER)
+    if ( _get_next_cluster( use_irq , free_cluster ) != FREE_CLUSTER)
     {
         _printf("\n[FAT ERROR] in _fat_allocate() : first free cluster not free\n");
@@ -704,5 +845,5 @@
     }
     // Check if FAT contains enough cluster free for this allocation
-    if ( count > fat.number_free_cluster )
+    if ( count > _fat.number_free_cluster )
     {
         _printf("\n[FAT ERROR] in _fat_allocate() : Not enough free cluster(s)\n");
@@ -711,5 +852,5 @@
 
 #if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _fat_allocate() for fd = %d\n" fd_id );
+_printf("\n[DEBUG FAT] _fat_allocate() for fd = %d\n", fd_id );
 #endif
 
@@ -718,5 +859,5 @@
     {
         last_cluster_file = next_cluster;
-        next_cluster      = _get_next_cluster( IOC_KERNEL_MODE, next_cluster );
+        next_cluster      = _get_next_cluster( use_irq , next_cluster );
     }
     while ( next_cluster < END_OF_CHAIN_CLUSTER );
@@ -727,5 +868,5 @@
 
 #if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] cluster to update = %x / free cluster = %x / nb_clusters %d\n",
+_printf("\n[DEBUG FAT] cluster to update = %x / free cluster = %x / count = %d\n",
         last_cluster_file , free_cluster , cluster_to_allocate );
 #endif
@@ -733,5 +874,5 @@
         // update, in the FAT, the value of last cluster allocated by the index
         // of free cluster.
-        if ( _update_fat( last_cluster_file, free_cluster ) )
+        if ( _update_fat( use_irq , last_cluster_file , free_cluster ) )
         {
             _printf("\n[FAT ERROR] in _fat_allocate() : update fat failed\n");
@@ -748,5 +889,5 @@
             // update, in the FAT, the value of the last cluster allocated by
             // END_OF_CHAIN_CLUSTER
-            if ( _update_fat( last_cluster_file, END_OF_CHAIN_CLUSTER ) )
+            if ( _update_fat( use_irq , last_cluster_file , END_OF_CHAIN_CLUSTER ) )
             {
                 _printf("\n[FAT ERROR] in _fat_allocate() : update fat failed\n");
@@ -758,5 +899,5 @@
 
         // Check if free_cluster is really free (must be true)
-        if ( _get_next_cluster( IOC_KERNEL_MODE, free_cluster ) != FREE_CLUSTER)
+        if ( _get_next_cluster( use_irq , free_cluster ) != FREE_CLUSTER)
         {
             _printf("\n[FAT ERROR] in _fat_allocate() : free_cluster not free\n");
@@ -767,8 +908,8 @@
     // Update field number_free_cluster and last_cluster_allocated 
     // of structure fat for next fat_allocate
-    fat.last_cluster_allocated = last_cluster_file;
-    fat.number_free_cluster    = fat.number_free_cluster - count;
-
-    if ( _update_fs_info() )
+    _fat.last_cluster_allocated = last_cluster_file;
+    _fat.number_free_cluster    = _fat.number_free_cluster - count;
+
+    if ( _update_fs_info( use_irq ) )
     {
         _printf("\n[FAT ERROR] in _fat_allocate() : update fs_info failed\n");
@@ -779,5 +920,5 @@
 }  // end _fat_allocate()
 
-////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 // This function read the blocks defined by the cluster index argument, in a data 
 // region containing a directory to search the name of a file/firectory. 
@@ -790,24 +931,25 @@
 // The cluster index is always stored in a SFN or LFN entry.
 // Return cluster index if name found / Return -1 if not found.
-////////////////////////////////////////////////////////////////////////////////////////
-static int _scan_directory( unsigned int   mode,            // mode for IOC driver
-                            unsigned int   cluster,         // cluster containing dir_entry 
-                            char*          file_name,       // searched file/directory name
-                            unsigned int*  file_size,       // file size
-                            unsigned int*  lba_dir_entry )  // lba of dir_entry
+//////////////////////////////////////////////////////////////////////////////////
+static 
+int _scan_directory( unsigned int   use_irq,         // use descheduling mode 
+                     unsigned int   cluster,         // cluster of dir_entry 
+                     char*          file_name,       // searched file/dir name
+                     unsigned int*  file_size,       // file size
+                     unsigned int*  lba_dir_entry )  // lba of dir_entry
 {
     char dir_entry[32];   // buffer to store a full directory_entry
     char name_entry[14];  // buffer to store a 13 characters (partial) name
 
-    char sfn_string[12]    = {[0 ... 10] = ' ', '\0'};        // buffer for Short File Name
-    unsigned int  is_sfn   = is_short(file_name, sfn_string); // if file_name is short
-    unsigned int  offset   = 0;                               // byte offset in block
-    unsigned int  block_id = fat.sectors_per_cluster;         // sector index initialisation
-    unsigned int  lba      = cluster_to_lba(cluster);         // lba of cluster containing dir
-    unsigned int  attr     = 0;                               // directory entry attribute
-    unsigned int  ord      = 0;                               // directory entry sequence
-    unsigned int  found    = 0;                               // searched name found
-    unsigned int  long_name_found = 0;                        // a matching XTN has been found
-    unsigned int  searched_cluster;                           // searched cluster index
+    char sfn_string[12]    = {[0 ... 10] = ' ', '\0'};  // buffer Short File Name
+    unsigned int  is_sfn   = is_short(file_name, sfn_string); // file_name is short
+    unsigned int  offset   = 0;                         // byte offset in block
+    unsigned int  block_id = _fat.sectors_per_cluster;   // sector index 
+    unsigned int  lba      = cluster_to_lba(cluster);   // lba of cluster 
+    unsigned int  attr     = 0;                         // dir entry attribute
+    unsigned int  ord      = 0;                         // dir entry sequence
+    unsigned int  found    = 0;                         // searched name found
+    unsigned int  long_name_found = 0;                  // matching XTN found
+    unsigned int  searched_cluster;                     // searched cluster index
 
 #if GIET_DEBUG_FAT
@@ -817,5 +959,5 @@
 unsigned int p       = procid & ((1<<P_WIDTH)-1);
 
-_printf("\n[FAT DEBUG] _scan_directory() : P[%d,%d,%d] enters for %s\n",
+_printf("\n[DEBUG FAT] P[%d,%d,%d] enters _scan_directory() for %s\n",
       x, y, p, file_name );
 #endif
@@ -827,15 +969,15 @@
     // load first sector from DATA region into FAT cache
     // other sectors will be loaded inside loop as required
-    if( _ioc_read( 0,               // channel
-                   mode,            // mode for IOC driver
-                   lba,             // sector index 
-                   fat.fat_cache,   // buffer address
-                   1 ) )            // one sector
-    {
-        _printf("[\nFAT ERROR] in _scan_directory() : cannot read sector %x\n", lba );
+    if( _fat_ioc_access( use_irq,
+                         1,               // read
+                         lba,
+                         (unsigned int)_fat.fat_cache,
+                         1 ) )            // one sector
+    {
+        _printf("[\nFAT ERROR] in _scan_directory() : cannot read sector %x\n",
+                lba );
         return -1;
     }
-
-    fat.cache_lba = lba;
+    _fat.cache_lba = lba;
 
 #if ( GIET_DEBUG_FAT > 1 )
@@ -858,21 +1000,22 @@
             else					  // get next cluster
             {
-                cluster = _get_next_cluster( mode, cluster );
+                cluster = _get_next_cluster( use_irq , cluster );
 
                 if ( cluster >= END_OF_CHAIN_CLUSTER  ) return END_OF_CHAIN_CLUSTER;
 
                 lba      = cluster_to_lba(cluster);
-                block_id = fat.sectors_per_cluster;
-            }
-            if( _ioc_read( 0,               // channel
-                           mode,            // mode for IOC driver
-                           lba,             // sector index 
-                           fat.fat_cache,   // buffer address
-                           1 ) )            // one sector
-            {
-                _printf("\n[FAT ERROR] in _scan_directory() : cannot read sector %x\n", lba);
+                block_id = _fat.sectors_per_cluster;
+            }
+            if( _fat_ioc_access( use_irq,
+                                 1,               // read
+                                 lba, 
+                                 (unsigned int)_fat.fat_cache,
+                                 1 ) )            // one sector
+            {
+                _printf("\n[FAT ERROR] in _scan_directory() : cannot read sector %x\n",
+                        lba);
                 return -1;
             }
-            fat.cache_lba = lba;
+            _fat.cache_lba = lba;
             block_id--;
             offset = offset % 512;
@@ -882,6 +1025,6 @@
         // if it a possible candidate for the searched name
 
-        attr = _read_entry( DIR_ATTR, fat.fat_cache + offset, 0);   
-        ord  = _read_entry( LDIR_ORD, fat.fat_cache + offset, 0);
+        attr = _read_entry( DIR_ATTR, _fat.fat_cache + offset, 0);   
+        ord  = _read_entry( LDIR_ORD, _fat.fat_cache + offset, 0);
 
         if ( is_sfn == 1 )		                  // searched name is short
@@ -897,5 +1040,5 @@
                       (ord  != NO_MORE_ENTRY ) )         // SFN entry : to be checked
             {
-                memcpy( dir_entry, fat.fat_cache + offset, DIR_ENTRY_SIZE );    
+                memcpy( dir_entry, _fat.fat_cache + offset, DIR_ENTRY_SIZE );    
 
                 get_name_from_short( dir_entry, name_entry );
@@ -922,5 +1065,5 @@
                 (ord != NO_MORE_ENTRY) )                 // EXT entry : to be checked
             {
-                memcpy( dir_entry, fat.fat_cache + offset, DIR_ENTRY_SIZE );
+                memcpy( dir_entry, _fat.fat_cache + offset, DIR_ENTRY_SIZE );
 
                 get_name_from_long( dir_entry, name_entry );
@@ -943,5 +1086,5 @@
                 if ( long_name_found )                   // LFN entry
                 {
-                    memcpy( dir_entry, fat.fat_cache + offset, DIR_ENTRY_SIZE );
+                    memcpy( dir_entry, _fat.fat_cache + offset, DIR_ENTRY_SIZE );
                     found = 1;
                 }
@@ -965,5 +1108,5 @@
 
 #if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _scan_directory() : P[%d,%d,%d] found %s"
+_printf("\n[DEBUG FAT] _scan_directory() : P[%d,%d,%d] found %s"
         " : cluster = %x\n", x, y, p, file_name, searched_cluster );
 #endif
@@ -999,7 +1142,6 @@
 // Return 0 if success, exit if failure 
 //////////////////////////////////////////////////////////////////////////
-int _fat_init( unsigned int mode )   // mode for IOC driver
-{
-    unsigned int   n;
+int _fat_init( unsigned int use_irq )  
+{
 
 #if GIET_DEBUG_FAT
@@ -1008,54 +1150,48 @@
 unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
 unsigned int p       = procid & ((1<<P_WIDTH)-1);
-
-if ( mode == IOC_BOOT_MODE ) 
-_printf("\n[FAT DEBUG] _fat_init() : P[%d,%d,%d] enters in BOOT_MODE\n",x,y,p);
-if ( mode == IOC_KERNEL_MODE )
-_printf("\n[FAT DEBUG] _fat_init() : P[%d,%d,%d] enters in KERNEL_MODE\n",x,y,p);
-if ( mode == IOC_USER_MODE )
-_printf("\n[FAT DEBUG] _fat_init() : P[%d,%d,%d] enters in USER_MODE\n",x,y,p);
+_printf("\n[DEBUG FAT] P[%d,%d,%d] enters _fat_init\n",x,y,p);
 #endif
 
     // FAT initialisation should be done only once
-    if ( fat.initialised == FAT_INITIALISED )
-    {
-        _printf("\n[FAT WARNING] Strange, FAT already initialised...\n");
+    if ( _fat.initialised == FAT_INITIALISED )
+    {
+        _printf("\n[FAT ERROR] Strange, FAT already initialised...\n");
         _exit();
     }
 
     // load Boot Record (VBR) into fat cache
-    if ( _ioc_read( 0,                   // channel
-                    mode,                // mode for IOC driver
-                    0,                   // sector index
-                    fat.fat_cache,       // buffer address
-                    1 ) )                // one sector
+    if ( _fat_ioc_access( use_irq,
+                          1,                   // read
+                          0,                   // sector index
+                          (unsigned int)_fat.fat_cache,
+                          1 ) )                // one sector
     {
         _printf("\n[FAT ERROR] in _fat_init() cannot load VBR\n");
         _exit();
     }
-    fat.cache_lba = 0;
+    _fat.cache_lba = 0;
 
 #if GIET_DEBUG_FAT > 1
-_printf("\n[FAT DEBUG] _fat_init() : Boot Sector Loaded\n");
+_printf("\n[DEBUG FAT] _fat_init() : Boot Sector Loaded\n");
 _display_fat_cache();
 #endif
 
     // checking various FAT32 assuptions from boot sector
-    if( _read_entry( BPB_BYTSPERSEC, fat.fat_cache, 1 ) != 512 )
+    if( _read_entry( BPB_BYTSPERSEC, _fat.fat_cache, 1 ) != 512 )
     {
         _printf("\n[FAT ERROR] The sector size must be 512 bytes\n");
         _exit();
     }
-    if( _read_entry( BPB_NUMFATS, fat.fat_cache, 1 ) != 1 )
+    if( _read_entry( BPB_NUMFATS, _fat.fat_cache, 1 ) != 1 )
     {
         _printf("\n[FAT ERROR] The number of FAT copies in FAT region must be 1\n");
         _exit();
     }
-    if( (_read_entry( BPB_FAT32_FATSZ32, fat.fat_cache, 1 ) & 0xF) != 0 )
-    {
-        _printf("\n[FAT ERROR] The FAT region in FAT32 must be multiple of 32 sectors\n");
+    if( (_read_entry( BPB_FAT32_FATSZ32, _fat.fat_cache, 1 ) & 0xF) != 0 )
+    {
+        _printf("\n[FAT ERROR] The FAT region must be multiple of 32 sectors\n");
         _exit();
     }
-    if( _read_entry( BPB_FAT32_ROOTCLUS, fat.fat_cache, 1 ) != 2 )
+    if( _read_entry( BPB_FAT32_ROOTCLUS, _fat.fat_cache, 1 ) != 2 )
     {
         _printf("\n[FAT ERROR] The first cluster index must be 2\n");
@@ -1063,71 +1199,48 @@
     }
     // FS Info always in sector 1
-    fat.fs_info_lba         = _read_entry( BPB_FAT32_FSINFO, fat.fat_cache, 1 );
+    _fat.fs_info_lba         = _read_entry( BPB_FAT32_FSINFO, _fat.fat_cache, 1 );
 
     // initialise fat descriptor from VBR
-    fat.sectors_per_cluster = _read_entry( BPB_SECPERCLUS, fat.fat_cache, 1 );
-    fat.sector_size         = _read_entry( BPB_BYTSPERSEC, fat.fat_cache, 1 );
-    fat.cluster_size        = fat.sectors_per_cluster * 512;
-    fat.fat_sectors         = _read_entry( BPB_FAT32_FATSZ32, fat.fat_cache, 1 );
-    fat.fat_lba             = _read_entry( BPB_RSVDSECCNT, fat.fat_cache, 1 );
-    fat.data_lba            = fat.fat_lba + fat.fat_sectors;
-    fat.initialised         = FAT_INITIALISED;
+    _fat.sectors_per_cluster = _read_entry( BPB_SECPERCLUS, _fat.fat_cache, 1 );
+    _fat.sector_size         = _read_entry( BPB_BYTSPERSEC, _fat.fat_cache, 1 );
+    _fat.cluster_size        = _fat.sectors_per_cluster * 512;
+    _fat.fat_sectors         = _read_entry( BPB_FAT32_FATSZ32, _fat.fat_cache, 1 );
+    _fat.fat_lba             = _read_entry( BPB_RSVDSECCNT, _fat.fat_cache, 1 );
+    _fat.data_lba            = _fat.fat_lba + _fat.fat_sectors;
+    _fat.initialised         = FAT_INITIALISED;
 
     // initalise the lock protecting the FAT
-    _spin_lock_init( &fat.fat_lock );
+    _spin_lock_init( &_fat.fat_lock );
 
     // initialise file descriptor array
-    for( n = 0 ; n < GIET_OPEN_FILES_MAX ; n++ ) fat.fd[n].used = 0;
-
-#if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _fat_init() : FS_INFO Sector = %x\n", fat.fs_info_lba );
+    unsigned int   n;
+    for( n = 0 ; n < GIET_OPEN_FILES_MAX ; n++ ) _fat.fd[n].used = 0;
+
+#if GIET_DEBUG_FAT
+_printf("\n[DEBUG FAT] _fat_init() : FS_INFO Sector = %x\n", _fat.fs_info_lba );
 #endif
 
     // load FS_INFO into fat cache
-    if ( _ioc_read( 0,                  // channel
-                    mode,               // mode for IOC driver
-                    fat.fs_info_lba,    // sector index 
-                    fat.fat_cache,      // buffer address
-                    1 ) )               // one sector
+    if ( _fat_ioc_access( use_irq,
+                          1,                  // read
+                          _fat.fs_info_lba,    
+                          (unsigned int)_fat.fat_cache,
+                          1 ) )               // one sector
     { 
         _printf("\n[FAT ERROR] in _fat_init() cannot load FS_INFO Sector\n"); 
         _exit();
     }
-    fat.cache_lba = fat.fs_info_lba;
-
-    fat.number_free_cluster    = _read_entry( FS_FREE_CLUSTER     , fat.fat_cache, 1);
-    fat.last_cluster_allocated = _read_entry( FS_FREE_CLUSTER_HINT, fat.fat_cache, 1);
-
+    _fat.cache_lba = _fat.fs_info_lba;
+
+    _fat.number_free_cluster    = _read_entry( FS_FREE_CLUSTER     , _fat.fat_cache, 1);
+    _fat.last_cluster_allocated = _read_entry( FS_FREE_CLUSTER_HINT, _fat.fat_cache, 1);
 
 #if GIET_DEBUG_FAT
 _fat_print();
-_printf("\n[FAT DEBUG] P[%d,%d,%d] exit _fat_init()\n" );
+_printf("\n[DEBUG FAT] P[%d,%d,%d] exit _fat_init()\n", x,y,p );
 #endif
 
     return 0;
 }  // end _fat_init()
-
-/////////////////
-void _fat_print()
-{
-    _printf("\n########################## FAT32 ################################"  
-            "\nFAT initialised                  %x"
-            "\nSector Size  (bytes)             %x"
-            "\nSectors per cluster              %x"
-            "\nFAT region first lba             %x"
-            "\nData region first lba            %x"
-            "\nNumber of sectors for one FAT    %x"
-            "\nNumber of free clusters          %x"
-            "\nLast allocated cluster           %x" 
-            "\n#################################################################\n",
-            fat.initialised,
-            fat.sector_size,
-            fat.sectors_per_cluster,
-            fat.fat_lba,
-            fat.data_lba,
-            fat.fat_sectors,
-            fat.number_free_cluster,
-            fat.last_cluster_allocated );
-}
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1142,5 +1255,5 @@
 // Returns file descriptor index if success, returns -1 if error.
 ///////////////////////////////////////////////////////////////////////////////
-int _fat_open( unsigned     mode,
+int _fat_open( unsigned int use_irq,       // use descheduling mode if possible
                char*        pathname,
                unsigned int creat )
@@ -1160,6 +1273,5 @@
 unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
 unsigned int p       = procid & ((1<<P_WIDTH)-1);
-
-_printf("\n[FAT DEBUG] P[%d,%d,%d] enters _fat_open() for path %s\n",
+_printf("\n[DEBUG FAT] P[%d,%d,%d] enters _fat_open() for path %s\n",
         x, y, p, pathname );
 #endif
@@ -1173,5 +1285,5 @@
 
     // checking FAT initialised
-    if( fat.initialised != FAT_INITIALISED )
+    if( _fat.initialised != FAT_INITIALISED )
     {
         _printf("\n[FAT ERROR] in _fat_open() : FAT not initialised\n");
@@ -1179,8 +1291,8 @@
     }
     // takes the FAT lock for exclusive access
-    _spin_lock_acquire( &fat.fat_lock );
-
-#if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _fat_open() : P[%d,%d,%d] takes the FAT lock\n",
+    _spin_lock_acquire( &_fat.fat_lock );
+
+#if GIET_DEBUG_FAT
+_printf("\n[DEBUG FAT] _fat_open() : P[%d,%d,%d] takes the FAT lock\n",
         x, y, p );
 #endif
@@ -1199,5 +1311,5 @@
 
 #if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _fat_open() : P[%d,%d,%d] search file/dir %s\n",
+_printf("\n[DEBUG FAT] _fat_open() : P[%d,%d,%d] search file/dir %s\n",
         x, y, p, name );
 #endif
@@ -1211,5 +1323,5 @@
 
         // scan current directory
-        cluster  = _scan_directory( mode, cluster, name, &file_size, &lba );
+        cluster = _scan_directory( use_irq , cluster , name , &file_size , &lba );
 
         if( cluster == END_OF_CHAIN_CLUSTER && last_name && creat )
@@ -1220,5 +1332,5 @@
         {
             _printf("\n[FAT ERROR] in _fat_open() cannot found %s\n", name );
-            _spin_lock_release( &fat.fat_lock );
+            _spin_lock_release( &_fat.fat_lock );
             return -1;
         }
@@ -1226,10 +1338,10 @@
 
 #if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _fat_open() : P[%d,%d,%d] cluster for %s = %x\n",
+_printf("\n[DEBUG FAT] P[%d,%d,%d] in _fat_open() : cluster for %s = %x\n",
        x, y, p, pathname, cluster );
 #endif
 
     // check the next value for cluster index found
-    unsigned next = _get_next_cluster( mode, cluster );
+    unsigned next = _get_next_cluster( use_irq , cluster );
 
     if ( (next != BAD_CLUSTER) && (next != FREE_CLUSTER) )
@@ -1237,5 +1349,5 @@
         // Search an empty slot scanning open file descriptors array
         fd_id = 0;
-        while ( fat.fd[fd_id].used != 0 && fd_id < GIET_OPEN_FILES_MAX )
+        while ( _fat.fd[fd_id].used != 0 && fd_id < GIET_OPEN_FILES_MAX )
         {
             fd_id++;
@@ -1245,17 +1357,17 @@
         if ( fd_id < GIET_OPEN_FILES_MAX )
         {
-            fat.fd[fd_id].used          = 1;
-            fat.fd[fd_id].first_cluster = cluster;
-            fat.fd[fd_id].file_size     = file_size;
-            fat.fd[fd_id].lba_dir_entry = lba;
-            _strcpy( fat.fd[fd_id].name, pathname );
-
-#if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _fat_open() : P[%d,%d,%d] exit : fd = %d for file %s\n",
+            _fat.fd[fd_id].used          = 1;
+            _fat.fd[fd_id].first_cluster = cluster;
+            _fat.fd[fd_id].file_size     = file_size;
+            _fat.fd[fd_id].lba_dir_entry = lba;
+            _strcpy( _fat.fd[fd_id].name, pathname );
+
+#if GIET_DEBUG_FAT
+_printf("\n[DEBUG FAT] _fat_open() : P[%d,%d,%d] exit : fd = %d for file %s\n",
         x, y, p, fd_id, pathname );
 #endif
 
             // release FAT lock
-            _spin_lock_release( &fat.fat_lock );
+            _spin_lock_release( &_fat.fat_lock );
 
             return fd_id;
@@ -1265,5 +1377,5 @@
             _printf("\n[FAT ERROR] in _fat_open() for file %s : fd array full\n", 
                     pathname );
-            _spin_lock_release( &fat.fat_lock );
+            _spin_lock_release( &_fat.fat_lock );
             return -1;
         }
@@ -1273,5 +1385,5 @@
         _printf("\n[FAT ERROR] in _fat_open() for file %s : bad cluster\n",
                 pathname );
-        _spin_lock_release( &fat.fat_lock );
+        _spin_lock_release( &_fat.fat_lock );
         return -1;
     }
@@ -1285,5 +1397,5 @@
 // Returns number of sectors transfered if success, < 0 if error.
 ///////////////////////////////////////////////////////////////////////////////
-int _fat_read( unsigned int mode,       // mode for IOC driver
+int _fat_read( unsigned int use_irq,    // use descheduling mode if possible
                unsigned int fd_id,      // file descriptor
                void*        buffer,     // target buffer base address
@@ -1291,5 +1403,5 @@
                unsigned int offset )    // nuber of sectors to skip in file
 {
-    unsigned int spc = fat.sectors_per_cluster;
+    unsigned int spc = _fat.sectors_per_cluster;
 
     unsigned int file_size;         // number of bytes in file
@@ -1306,5 +1418,5 @@
         return -1;
     }
-    if ( fat.fd[fd_id].used != 1 )
+    if ( _fat.fd[fd_id].used != 1 )
     {
         _printf("\n[FAT ERROR] in _fat_read() : file not open\n");
@@ -1318,5 +1430,5 @@
 
     // compute file size as a number of sectors 
-    file_size    = fat.fd[fd_id].file_size;
+    file_size    = _fat.fd[fd_id].file_size;
     if ( file_size & 0x1FF ) file_sectors = (file_size >> 9) + 1;
     else                     file_sectors = (file_size >> 9); 
@@ -1337,5 +1449,5 @@
     
     // get first cluster index 
-    cluster = fat.fd[fd_id].first_cluster;
+    cluster = _fat.fd[fd_id].first_cluster;
 
 #if GIET_DEBUG_FAT
@@ -1344,5 +1456,5 @@
 unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
 unsigned int p       = procid & ((1<<P_WIDTH)-1);
-_printf("\n[FAT DEBUG] _fat_read() : P[%d,%d,%d] enters for file %s\n"
+_printf("\n[DEBUG FAT] _fat_read() : P[%d,%d,%d] enters for file %s\n"
         " - buffer vbase     = %x\n"
         " - skipped sectors  = %x\n"
@@ -1350,18 +1462,12 @@
         " - first cluster    = %x\n"
         " - skipped clusters = %x\n",
-        x, y, p, 
-        fat.fd[fd_id].name,
-        (unsigned int)buffer,
-        offset,
-        count,
-        cluster,
-        clusters_to_skip );
+        x, y, p, _fat.fd[fd_id].name, (unsigned int)buffer,
+        offset, count, cluster, clusters_to_skip );
 #endif
 
     // compute index of first cluster to be loaded
-    // as we may need to scan the FAT, we use the kernel mode
     while ( clusters_to_skip )
     {
-        cluster = _get_next_cluster( IOC_KERNEL_MODE, cluster );
+        cluster = _get_next_cluster( use_irq , cluster );
         clusters_to_skip--;
     }
@@ -1371,9 +1477,9 @@
     unsigned int    lba;            // first sector index on device
     unsigned int    iter_sectors;   // number of sectors to load in iteration
-    char*           dst;            // pointer on target buffer
+    unsigned int    dst;            // pointer on target buffer
 
     // initialize these variables for the first iteration 
     todo_sectors  = total_sectors;
-    dst           = (char*)buffer;
+    dst           = (unsigned int)buffer;
     lba           = cluster_to_lba(cluster) + sectors_to_skip;
     if( total_sectors < (spc - sectors_to_skip) ) iter_sectors = total_sectors;
@@ -1385,21 +1491,14 @@
 
 #if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _fat_read() : P[%d,%d,%d] makes an IOC read\n"
-        " - cluster = %x\n"
-        " - buffer  = %x\n"
-        " - lba     = %x\n"
-        " - sectors = %x\n",
-        x, y, p,
-        cluster,
-        (unsigned int)dst,
-        lba,
-        iter_sectors );
-#endif
-
-        if( _ioc_read( 0,                 // channel
-                       mode,              // mode for IOC driver
-                       lba,               // first sector index 
-                       dst,               // buffer address
-                       iter_sectors ) )   // number of sectors
+_printf("\n[DEBUG FAT] _fat_read() : P[%d,%d,%d] makes an IOC read\n"
+        "  cluster = %x / buffer = %x / lba = %x / sectors = %d\n",
+        x, y, p, cluster, dst, lba, iter_sectors );
+#endif
+
+        if( _fat_ioc_access( use_irq,
+                             1,                 // read
+                             lba, 
+                             dst,               // buffer address
+                             iter_sectors ) )   // number of sectors
         {
             _printf("\n[FAT ERROR] in _fat_read() cannot load block %x", lba );
@@ -1408,5 +1507,5 @@
          
         // update variables for next iteration
-        cluster      = _get_next_cluster( mode, cluster );
+        cluster      = _get_next_cluster( use_irq , cluster );
         todo_sectors = todo_sectors - iter_sectors;
         dst          = dst + (iter_sectors << 9);
@@ -1426,14 +1525,8 @@
 // Allocate new clusters if the offset+count larger than current file size,
 // but the offset should be smaller than the current file size...
-// - fat    : pointer on FAT 
-// - mode   : mode for the IOC driver
-// - fd_id  : open file descriptor index  
-// - buffer : base address of the memory buffer (must be sector aligned)
-// - offset : number of sectors to skip in file
-// - count  : number of sectors to be written.
 ///////////////////////////////////////////////////////////////////////////////
 // Returns number of sectors written if success, < 0 if error.
 ///////////////////////////////////////////////////////////////////////////////
-int _fat_write( unsigned int mode,       // mode for IOC driver
+int _fat_write( unsigned int use_irq,    // use descheduling mode if possible
                 unsigned int fd_id,      // file descriptor
                 void*        buffer,     // target buffer base address
@@ -1442,5 +1535,5 @@
 {
 
-    unsigned int spc = fat.sectors_per_cluster;
+    unsigned int spc = _fat.sectors_per_cluster;
 
     unsigned int file_size;         // number of bytes in file
@@ -1454,5 +1547,5 @@
 
     // compute file size as a number of sectors 
-    file_size    = fat.fd[fd_id].file_size;
+    file_size    = _fat.fd[fd_id].file_size;
     if ( file_size & 0x1FF ) file_sectors = (file_size >> 9) + 1;
     else                     file_sectors = (file_size >> 9); 
@@ -1473,5 +1566,5 @@
 unsigned int p       = procid & ((1<<P_WIDTH)-1);
 
-_printf("\n[FAT DEBUG] _fat_write() : P[%d,%d,%d] enters for file %s\n"
+_printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] enters for file %s\n"
         " - buffer vbase    = %x\n"
         " - skipped sectors = %x\n"
@@ -1479,11 +1572,6 @@
         " - file sectors    = %x\n"
         " - need_allocate   = %d\n",
-        x, y, p,
-        fat.fd[fd_id].name
-        (unsigned int)buffer,
-        offset,
-        count,
-        file_sectors,
-        allocate );
+        x, y, p, _fat.fd[fd_id].name, (unsigned int)buffer,
+        offset, count, file_sectors, allocate );
 #endif
 
@@ -1494,5 +1582,5 @@
         return -1;
     }
-    if ( fat.fd[fd_id].used != 1 )
+    if ( _fat.fd[fd_id].used != 1 )
     {
         _printf("\n[FAT ERROR] in _fat_write() : file not open\n");
@@ -1507,5 +1595,5 @@
     if ( allocate  )
     {
-        if ( _fat_allocate( fd_id, (required_cluster - current_cluster) ) < 0 )
+        if ( _fat_allocate( use_irq , fd_id, (required_cluster-current_cluster) ) )
         {
             _printf("\n[FAT ERROR] in _fat_write() : fat_allocate failed\n");
@@ -1519,16 +1607,15 @@
     
     // get first cluster index 
-    cluster = fat.fd[fd_id].first_cluster;
-
-#if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _fat_write() : P[%d,%d,%d] get cluster %x\n",
+    cluster = _fat.fd[fd_id].first_cluster;
+
+#if GIET_DEBUG_FAT
+_printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] get cluster %x\n",
         x, y, p, cluster );
 #endif
 
     // compute index of first cluster to be loaded
-    // as we may need to scan the FAT, we use the kernel mode
     while ( clusters_to_skip )
     {
-        cluster = _get_next_cluster( IOC_KERNEL_MODE, cluster );
+        cluster = _get_next_cluster( use_irq , cluster );
         clusters_to_skip--;
     }
@@ -1538,9 +1625,9 @@
     unsigned int    lba;            // first sector index on device
     unsigned int    iter_sectors;   // number of sectors to load in iteration
-    char*           src;            // pointer on target buffer
+    unsigned int    src;            // pointer on target buffer
 
     // initialize these variables for the first iteration 
     todo_sectors  = count;
-    src           = (char*)buffer;
+    src           = (unsigned int)buffer;
     lba           = cluster_to_lba(cluster) + sectors_to_skip;
     if( count < (spc - sectors_to_skip) ) iter_sectors = count;
@@ -1552,21 +1639,14 @@
 
 #if GIET_DEBUG_FAT
-_printf("\n[FAT DEBUG] _fat_write() : P[%d,%d,%d] makes an IOC write"
-        " - cluster  = %x\n"
-        " - buffer   = %x\n"
-        " - lba      = %x\n"
-        " - sectors  = %x\n",
-        x, y, p, 
-        cluster,
-        (unsigned int) src,
-        lba,
-        iter_sectors );
-#endif
-
-        if( _ioc_write( 0,                 // channel
-                        mode,              // mode for IOC driver
-                        lba,               // first sector index 
-                        src,               // source buffer address
-                        iter_sectors ) )   // number of sectors
+_printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] makes an IOC write"
+        "  cluster = %x / buffer = %x / lba = %x / sectors = %d\n",
+        x, y, p, cluster, src, lba, iter_sectors );
+#endif
+
+        if( _fat_ioc_access( use_irq,
+                             0,                 // write
+                             lba, 
+                             src,               // source buffer address
+                             iter_sectors ) )   // number of sectors
         {
             _printf("\n[FAT ERROR] in _fat_write() cannot write block %x\n", lba );
@@ -1575,5 +1655,5 @@
          
         // update variables for next iteration
-        cluster      = _get_next_cluster( mode, cluster );
+        cluster      = _get_next_cluster( use_irq , cluster );
         todo_sectors = todo_sectors - iter_sectors;
         src          = src + (iter_sectors << 9);
@@ -1587,13 +1667,13 @@
     if ( ( offset + count ) > file_sectors )
     {
-        fat.fd[fd_id].file_size = (count + offset) << 9;
+        _fat.fd[fd_id].file_size = (count + offset) << 9;
     }
 
     // Update entry of directory with the new value 
     // of file size (Field : DIR_FILE_SIZE)
-    if ( update_entry(fd_id, DIR_FILE_SIZE, fat.fd[fd_id].file_size) )
-    {
-            _printf("\n[FAT ERROR] in _fat_write() update entry failed\n");
-            return -1;
+    if ( _update_entry( use_irq, fd_id , DIR_FILE_SIZE , _fat.fd[fd_id].file_size ) )
+    {
+        _printf("\n[FAT ERROR] in _fat_write() update entry failed\n");
+        return -1;
     }
          
@@ -1615,5 +1695,5 @@
     if( (fd_id < GIET_OPEN_FILES_MAX) )
     {
-        file_size = fat.fd[fd_id].file_size;
+        file_size = _fat.fd[fd_id].file_size;
 
         if ( file_size & 0x1FF ) file_sectors = (file_size >> 9) + 1;
@@ -1638,5 +1718,5 @@
     if( (fd_id < GIET_OPEN_FILES_MAX) )
     {
-        fat.fd[fd_id].used = 0;
+        _fat.fd[fd_id].used = 0;
         return 0;
     }
@@ -1648,24 +1728,24 @@
 } // end fat_close()
 
-/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
 // The following function implement the user_level system call.
 // The flags argument is not used, as file access modes are not implemented yet.
-/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
 // Return the file descriptor index if success / return -1 if failure
-/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
 int _fat_user_open( char*  pathname,         // absolute pathname from root
                     unsigned int flags )     // unused: TODO
 {
-    return _fat_open( IOC_KERNEL_MODE,       // we use KERNEL_MODE, because
-                      pathname,              // we need to write into FAT cache
-                      0 );                   // no creation if not found
+    return _fat_open( 1,        // use descheduling mode if possible
+                      pathname, 
+                      0 );      // no creation if not found
 }
 
-/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
 // The following function implement the user_level system call.
-// This function should be modified to respect the UNIX specification 
-/////////////////////////////////////////////////////////////////////////////////////
+// This function should be modified to respect the UNIX specification.
+/////////////////////////////////////////////////////////////////////////////////
 // Return number of sectors actually transfered if success / return -1 if failure
-/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
 int _fat_user_read( unsigned int fd,        // file descriptor index
                     void*        buffer,    // destination buffer
@@ -1673,5 +1753,5 @@
                     unsigned int offset )   // number of sectors to skip
 {
-    return _fat_read( IOC_USER_MODE,
+    return _fat_read( 1,        // use descheduling mode if possible
                       fd,
                       buffer,  
@@ -1680,10 +1760,10 @@
 }
 
-/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
 // The following function implement the user_level system call.
 // This function should be modified to respect the UNIX specification. 
-/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
 // Return number of sectors actually transfered if success / return -1 if failure
-/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
 int _fat_user_write( unsigned int fd,       // file descriptor
                      void*        buffer,   // source buffer
@@ -1691,5 +1771,5 @@
                      unsigned int offset )  // number of sectors to skip on file
 {
-    return _fat_write( IOC_USER_MODE,
+    return _fat_write( 1,       // use descheduling mode if possible
                        fd,
                        buffer,  
@@ -1698,5 +1778,5 @@
 }
 
-/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
 int _fat_user_lseek( unsigned int fd_id,
                      unsigned int offset,
