Index: trunk/kernel/fs/fatfs.c
===================================================================
--- trunk/kernel/fs/fatfs.c	(revision 611)
+++ trunk/kernel/fs/fatfs.c	(revision 612)
@@ -1359,6 +1359,6 @@
 }  // end fatfs_remove_dentry
 
-////////////////////////////////////////////////////////////////
-error_t fatfs_child_init( vfs_inode_t * parent_inode,
+/////////////////////////////////////////////////////
+error_t fatfs_get_dentry( vfs_inode_t * parent_inode,
                           char        * name,
                           xptr_t        child_inode_xp )
@@ -1368,10 +1368,10 @@
     // - scan the directory entries in each 4 Kbytes page
 
-#if DEBUG_FATFS_CHILD_INIT
+#if DEBUG_FATFS_GET_DENTRY
 char       parent_name[CONFIG_VFS_MAX_NAME_LENGTH];
 uint32_t   cycle = (uint32_t)hal_get_cycles();
 thread_t * this  = CURRENT_THREAD;
 vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name );
-if( DEBUG_FATFS_CHILD_INIT < cycle )
+if( DEBUG_FATFS_GET_DENTRY < cycle )
 printk("\n[%s]  thread[%x,%x] enter for child <%s> in parent <%s> / cycle %d\n",
 __FUNCTION__, this->process->pid, this->trdid, name , parent_name , cycle );
@@ -1420,18 +1420,7 @@
         base    = (uint8_t *)GET_PTR( base_xp );
 
-#if (DEBUG_FATFS_CHILD_INIT & 0x1)
-if( DEBUG_FATFS_CHILD_INIT < cycle )
-{
-    uint32_t * buf = (uint32_t *)base;
-    uint32_t line , word;
-    printk("\n[%s] First 16 dentries for <%s>\n",
-    __FUNCTION__ , parent_name );
-    for( line = 0 ; line < 16 ; line++ )
-    {
-        printk("%X : ", line );
-        for( word = 0 ; word < 8 ; word++ ) printk("%X ", buf[(line<<4) + word] );
-        printk("\n");
-    }
-}
+#if (DEBUG_FATFS_GET_DENTRY & 0x1)
+if( DEBUG_FATFS_GET_DENTRY < cycle )
+mapper_display_page( mapper_xp , page_id , 256 , parent_name );
 #endif
         // scan this page until end of directory, end of page, or name found
@@ -1506,7 +1495,7 @@
     {
 
-#if DEBUG_FATFS_CHILD_INIT
+#if DEBUG_FATFS_GET_DENTRY
 cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_FATFS_CHILD_INIT < cycle )
+if( DEBUG_FATFS_GET_DENTRY < cycle )
 printk("\n[%s]  thread[%x,%x] exit / child <%s> not found / cycle %d\n",
 __FUNCTION__, this->process->pid, this->trdid, name, cycle );
@@ -1544,7 +1533,7 @@
     dentry_ptr->extend = (void *)(intptr_t)dentry_id;
 
-#if DEBUG_FATFS_CHILD_INIT
+#if DEBUG_FATFS_GET_DENTRY
 cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_FATFS_CHILD_INIT < cycle )
+if( DEBUG_FATFS_GET_DENTRY < cycle )
 printk("\n[%s]  thread[%x,%x] exit / child <%s> loaded in <%s> / cycle %d\n",
 __FUNCTION__, this->process->pid, this->trdid, name, parent_name, cycle );
@@ -1553,5 +1542,161 @@
     return 0;
 
-}  // end fatfs_child_init()
+}  // end fatfs_get_dentry()
+
+///////////////////////////////////////////////////////
+error_t fatfs_get_user_dir( struct vfs_inode_s * inode,
+                            struct dirent      * array, 
+                            uint32_t             max_dirent,
+                            uint32_t             min_dentry,
+                            bool_t               detailed,
+                            uint32_t           * entries,
+                            bool_t             * done )
+{
+    // Two embedded loops to scan the directory mapper:
+    // - scan the parent directory mapper pages starting always from page 0
+    // - scan the 32 bytes NORMAL/LFN directory entries in each page
+    // Only valid dentries are copied : dentry_id >= min_dentry && dirent_id < dirent_max
+
+#if DEBUG_FATFS_GET_USER_DIR
+char       inode_name[CONFIG_VFS_MAX_NAME_LENGTH];
+uint32_t   cycle = (uint32_t)hal_get_cycles();
+thread_t * this  = CURRENT_THREAD;
+vfs_inode_get_name( XPTR( local_cxy , inode ) , inode_name );
+if( DEBUG_FATFS_GET_USER_DIR < cycle )
+printk("\n[%s]  thread[%x,%x] enter for inode <%s> / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, inode_name , cycle );
+#endif
+
+    mapper_t * mapper    = inode->mapper;
+    xptr_t     mapper_xp = XPTR( local_cxy , mapper );
+
+// check mapper pointer
+assert( (mapper != NULL) , "mapper is NULL\n");
+    
+// TODO handle the detailed flag
+assert( (detailed == false), "detailed argument not supported/n");
+
+    char       cname[CONFIG_VFS_MAX_NAME_LENGTH];  // name extracter from each directory entry
+
+    char       lfn1[16];           // buffer for one partial cname
+    char       lfn2[16];           // buffer for one partial cname
+    char       lfn3[16];           // buffer for one partial cname
+    xptr_t     page_xp;            // extended pointer on page descriptor
+    xptr_t     base_xp;            // extended pointer on page base
+    uint8_t  * base;               // local pointer on page base
+    uint32_t   attr;               // directory entry ATTR field
+    uint32_t   ord;                // directory entry ORD field
+    uint32_t   seq;                // sequence index
+    uint32_t   lfn       = 0;      // LFN entries number
+    uint32_t   offset    = 0;      // byte offset in page
+    uint32_t   page_id   = 0;      // page index in mapper
+    uint32_t   dentry_id = 0;      // valid (i.e. copied) dentry index in mapper 
+    uint32_t   dirent_id = 0;      // slot index in dirent array to initialize
+    bool_t     end       = false;  // true if end of directory found
+
+    // loop on mapper pages
+    while ( (end == false) && (dirent_id < max_dirent) )
+    {
+        // get one page from mapper
+        page_xp = mapper_remote_get_page( mapper_xp , page_id );
+
+        if( page_xp == XPTR_NULL) return -1;
+
+        // get page base
+        base_xp = ppm_page2base( page_xp );
+        base    = (uint8_t *)GET_PTR( base_xp );
+
+#if (DEBUG_FATFS_GET_USER_DIR & 0x1)
+if( DEBUG_FATFS_GET_USER_DIR < cycle )
+mapper_display_page( mapper_xp , page_id , 256 , inode_name );
+#endif 
+        // loop on NORMAL/LFN (32 bytes) directory entries in this page
+        while( (end == false) && (offset < 4096) )
+        {
+            // compute condition to copy one dentry to dirent array
+            bool_t valid = (dentry_id >= min_dentry) && (dirent_id <  max_dirent );
+
+            attr = fatfs_get_record( DIR_ATTR , base + offset , 0 );   
+            ord  = fatfs_get_record( LDIR_ORD , base + offset , 0 );   
+
+            if (ord == NO_MORE_ENTRY)                 // no more entry => break
+            {
+                end = true;
+            }
+            else if ( ord == FREE_ENTRY )             // free entry => skip
+            {
+                offset = offset + 32;
+            }
+            else if ( attr == ATTR_LONG_NAME_MASK )   // LFN entry
+            {
+                if( valid )
+                {
+                    // get partial cname
+                    seq = ord & 0x3;
+                    lfn = (seq > lfn) ? seq : lfn;   
+                    if      ( seq == 1 ) fatfs_get_name_from_long( base + offset, lfn1 );
+                    else if ( seq == 2 ) fatfs_get_name_from_long( base + offset, lfn2 );
+                    else if ( seq == 3 ) fatfs_get_name_from_long( base + offset, lfn3 );
+                }
+                offset = offset + 32;
+            }
+            else                                     // NORMAL entry
+            {
+                // increment dentry_id
+                dentry_id++;
+
+                if( valid )
+                {
+                    // build the complete cname
+                    if      ( lfn == 0 )
+                    {
+                        fatfs_get_name_from_short( base + offset , cname );
+                    }
+                    else if ( lfn == 1 )
+                    {
+                        strcpy( cname      , lfn1 );
+                    }   
+                    else if ( lfn == 2 ) 
+                    {
+                        strcpy( cname      , lfn1 );
+                        strcpy( cname + 13 , lfn2 );
+                    }
+                    else if ( lfn == 3 ) 
+                    {
+                        strcpy( cname      , lfn1 );
+                        strcpy( cname + 13 , lfn2 );
+                        strcpy( cname + 26 , lfn3 );
+                    }
+                    
+                    // copy cname into dirent array
+                    strcpy( array[dirent_id].d_name , cname ); 
+
+                    // increment dirent_id
+                    dirent_id++;
+                }
+                offset = offset + 32;
+                lfn    = 0;
+            }
+        }  // end loop on directory entries in page
+
+        page_id++;
+        offset = 0;
+
+    }  // end loop on pages
+
+    // return result of scan
+    *done    = end;
+    *entries = dirent_id;
+
+#if DEBUG_FATFS_GET_USER_DIR
+cycle = (uint32_t)hal_get_cycles();
+if( DEBUG_FATFS_GET_USER_DIR < cycle )
+printk("\n[%s]  thread[%x,%x] exit for inode <%s> / %d entries / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, inode_name, entries, cycle );
+#endif
+
+    return 0;
+
+}  // end fatfs_get_user_dir()
 
 ///////////////////////////////////////////////
