Changeset 773 for soft


Ignore:
Timestamp:
Feb 4, 2016, 4:55:22 PM (8 years ago)
Author:
alain
Message:

Fix several bugs related to new files or directories creation:

  • The first_free_cluster computation in _fat_init has been corrected.
  • The generation of SFN 8-3 names has been modified to pass the fsck_msdos check.
  • The number of clusters occupied by a directory is now stored in the <is_dir> field of inode.
Location:
soft/giet_vm/giet_fat32
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_fat32/fat32.c

    r772 r773  
    1 //////////////////////////////////////////////////////////////////////////////////
     1/////////////////////////////////////////////////////////////////////////////////
    22// Date     : 01/06/2015
    33// Authors  : Alain Greiner
     
    7878
    7979
    80 ///////////////////////////////////////////////////////////////////////////////////
    81 // This debug function displays the content of a 512 bytes buffer "buf",
    82 // with an identifier defined by the "string" and "block_id" arguments.
    83 ///////////////////////////////////////////////////////////////////////////////////
    84 
    85 #if GIET_DEBUG_FAT
    86 static void _display_one_block( unsigned char* buf,
    87                                 char*          string,
    88                                 unsigned int   block_id );
    89 #endif
    90 
    91 //////////////////////////////////////////////////////////////////////////////////
    92 // This debug function displays the FAT descriptor.
    93 //////////////////////////////////////////////////////////////////////////////////
    94 
    95 #if GIET_DEBUG_FAT
     80#if GIET_DEBUG_FAT
     81
    9682static void _display_fat_descriptor();
    97 #endif
    98 
    99 /////////////////////////////////////////////////////////////////////////////////
    100 // The following function transfers one or several blocks between the device
    101 // and a memory buffer identified by a virtual address.
    102 // It computes the memory buffer physical address, and calls the proper
    103 // IOC driver depending on the subtype (BDV / HBA / SDC / SPI / RDK).
    104 // The use_irq argument allows to activate the descheduling mode,
    105 // if it supported by the IOC driver subtype
    106 // It returns 0 on success.
    107 // It returns -1 on error.
    108 /////////////////////////////////////////////////////////////////////////////////
    109 
    110 static int _fat_ioc_access( unsigned int use_irq,
    111                             unsigned int to_mem,
    112                             unsigned int lba,
    113                             unsigned int buf_vaddr,
    114                             unsigned int count );
    115 
    116 ////////////////////////////////////////////////////////////////////////////////
    117 // This function extract a (partial) name from a LFN directory entry.
    118 ////////////////////////////////////////////////////////////////////////////////
     83
     84static void _display_clusters_list();
     85
     86#endif
    11987
    12088static void _get_name_from_long( unsigned char* buffer,
    12189                                 char*          name );
    12290
    123 ////////////////////////////////////////////////////////////////////////////////
    124 // The following function extract a name from a NORMAL directory entry.
    125 ////////////////////////////////////////////////////////////////////////////////
    126 
    12791static void _get_name_from_short( unsigned char* buffer,
    12892                                  char*          name );
    12993
    130 //////////////////////////////////////////////////////////////////////////////////
    131 // This function returns the number of levels of a File-Cache (or Fat-Cache)
    132 // from the size of the file (or FAT).
    133 //////////////////////////////////////////////////////////////////////////////////
    134 
    13594static inline unsigned int _get_levels_from_size( unsigned int size );
    136 
    137 ///////////////////////////////////////////////////////////////////////////////////
    138 // The following function analyses the "pathname" argument, from the character
    139 // defined by the "nb_read" argument.
    140 // It copies the found name in the "name" buffer (without '/'),
    141 // and updates the "nb_read" argument.
    142 // It returns 0 on success.
    143 // It returns 1 if one name length > NAME_MAX_SIZE characters
    144 ///////////////////////////////////////////////////////////////////////////////////
    14595
    14696static unsigned int _get_name_from_path( char*          pathname,
     
    14898                                         unsigned int*  nb_read );
    14999
    150 ////////////////////////////////////////////////////////////////////////////////
    151 // The following function scan the "pathname" argument, and copies in the
    152 // "name" buffer the last name in path (leaf name).
    153 // It returns 0 on success.
    154 // It returns 1 if one name length > NAME_MAX_SIZE characters
    155 ////////////////////////////////////////////////////////////////////////////////
    156100static unsigned int _get_last_name( char*   pathname,
    157101                                    char*   name );
    158102
    159 //////////////////////////////////////////////////////////////////////////////////
    160 // The following function accesses the Fat-Cache and returns in the "value"
    161 // argument the content of the FAT slot identified by the "cluster" argument.
    162 // It loads the missing cluster from block device into cache in case of miss.
    163 // It returns 0 on success.
    164 // It returns 1 on error.
    165 //////////////////////////////////////////////////////////////////////////////////
    166 
    167103static unsigned int _get_fat_entry( unsigned int  cluster,
    168104                                    unsigned int* value );
    169105
    170 //////////////////////////////////////////////////////////////////////////////////
    171 // The following function writes a new "value" in the Fat-Cache, in the slot
    172 // identified by the "cluster" argument. 
    173 // It loads the missing cluster from block device into cache in case of miss.
    174 // It returns 0 on success,
    175 // It returns 1 on error.
    176 //////////////////////////////////////////////////////////////////////////////////
    177 
    178106static unsigned int _set_fat_entry( unsigned int  cluster,
    179107                                    unsigned int  value );
    180108
    181 //////////////////////////////////////////////////////////////////////////////////
    182 // The following function introduces the inode identified by the <child> argument,
    183 // as a new child of the <parent> inode in the Inode-Tree.
    184 // All checking are supposed to be done by the caller.
    185 // Nor the File-Cache, neither the block device are modified.
    186 //////////////////////////////////////////////////////////////////////////////////
    187 
    188109static void _add_inode_in_tree( fat_inode_t*  child,
    189110                                fat_inode_t*  parent );
    190111
    191 //////////////////////////////////////////////////////////////////////////////////
    192 // The following function removes one inode identified by the <inode> argument
    193 // from the Inode-Tree. All checking are supposed to be done by the caller.
    194 // Nor the File-Cache, neither the block device are modified.
    195 //////////////////////////////////////////////////////////////////////////////////
    196 
    197112static void _remove_inode_from_tree( fat_inode_t* inode );
    198 
    199 //////////////////////////////////////////////////////////////////////////////////
    200 // This recursive function scan one File-Cache (or Fat-Cache) from root to leaves,
    201 // to writes all dirty clusters to block device, and reset the dirty bits.
    202 // The cache is identified by the <root> an <levels> arguments.
    203 // The <string> argument is only used for debug : inode name or Fat.
    204 // It returns 0 on success.
    205 // It returns 1 on error.
    206 //////////////////////////////////////////////////////////////////////////////////
    207113
    208114static unsigned int _update_device_from_cache( unsigned int      levels,
     
    210116                                               char*             string );
    211117
    212 //////////////////////////////////////////////////////////////////////////////////
    213 // The following function accesses directly the FS_INFO block on the block device,
    214 // to update the "first_free_cluster" and "free_clusters_number" values,
    215 // using only the Fat-Descriptor single block buffer.
    216 // It return 0 on success.
    217 // It return 1 on error.
    218 //////////////////////////////////////////////////////////////////////////////////
    219 
    220118static unsigned int _update_fs_info();
    221 
    222 //////////////////////////////////////////////////////////////////////////////
    223 // The following function read a data field (from one to four bytes)
    224 // from an unsigned char[] buffer, taking endianness into account.
    225 // The analysed field is defined by the <offset> and <size> arguments.
    226 //////////////////////////////////////////////////////////////////////////////
    227119
    228120static unsigned int _read_entry( unsigned int    offset,
     
    231123                                 unsigned int    little_indian );
    232124
    233 //////////////////////////////////////////////////////////////////////////////////
    234 // The following function returns the lba of first sector in DATA region
    235 // from the cluster index. The cluster index must be larger than 2.
    236 //////////////////////////////////////////////////////////////////////////////////
    237 
    238125static unsigned int _cluster_to_lba( unsigned int cluster );
    239 
    240 //////////////////////////////////////////////////////////////////////////////////
    241 // The following function returns in the "nb_entries" argument the number of files
    242 // (or directories) contained in a directory identified by the "inode " pointer.
    243 // It returns 0 on success.
    244 // It returns 1 on error.
    245 //////////////////////////////////////////////////////////////////////////////////
    246126
    247127static unsigned int _get_nb_entries( fat_inode_t*   inode,
    248128                                     unsigned int*  nb_entries );
    249 
    250 //////////////////////////////////////////////////////////////////////////////////
    251 // The following function search in the directory identified by the <parent>
    252 // inode pointer a child (file or directory) identified by its <name>.
    253 // It returns in the <inode> argument the searched child inode pointer.
    254 // If the searched name is not found in the Inode-Tree, the function accesses
    255 // the File-cache associated to the parent directory.
    256 // If the child exists on block device, the Inode-Tree is updated, and
    257 // a success code is returned.
    258 // If the file/dir does not exist on block device, a error code is returned.
    259 // It returns 0 if inode found.
    260 // It returns 1 if inode not found.
    261 // It returns 2 on error in cache access.
    262 //////////////////////////////////////////////////////////////////////////////////
    263129
    264130static unsigned int _get_child_from_parent( fat_inode_t*   parent,
     
    266132                                            fat_inode_t**  inode );
    267133
    268 /////////////////////////////////////////////////////////////////////////////////
    269 // For a file (or a directory) identified by the "pathname" argument, the
    270 // following function returns in the "inode" argument the inode pointer
    271 // associated to the searched file (or directory), with code (0).
    272 // If the searched file (or directory) is not found, but the parent directory
    273 // is found, it returns in the "inode" argument the pointer on the parent inode,
    274 // with code (1).  Finally, code (2) and code (3) are error codes.
    275 // Both the Inode-Tree and the involved Cache-Files are updated from the block
    276 // device in case of miss on one inode during the search in path.
    277 // Neither the Fat-Cache, nor the block device are updated.
    278 // It returns 0 if searched inode found
    279 // It returns 1 if searched inode not found but parent directory found
    280 // It returns 2 if searched inode not found and parent directory not found
    281 // It returns 3 if one name too long
    282 /////////////////////////////////////////////////////////////////////////////////
    283 
    284134static unsigned int _get_inode_from_path( char*          pathname,
    285135                                          fat_inode_t**  inode );
    286136
    287 //////////////////////////////////////////////////////////////////////////////////
    288 // The following function checks if node "a" is an ancestor of inode "b".
    289 // It returns 0 on failure.
    290 // It returns 1 otherwise.
    291 //////////////////////////////////////////////////////////////////////////////////
    292 
    293137static unsigned int _is_ancestor( fat_inode_t* a,
    294138                                  fat_inode_t* b);
    295139
    296 //////////////////////////////////////////////////////////////////////////////////
    297 // This function computes the length and the number of LFN entries required
    298 // to store a node name in the "length" and "nb_lfn" arguments.
    299 // Short name (less than 13 characters) require 1 LFN entry.
    300 // Medium names (from 14 to 26 characters require 2 LFN entries.
    301 // Large names (up to 31 characters) require 3 LFN entries.
    302 // It returns 0 on success.
    303 // It returns 1 if length larger than 31 characters.
    304 //////////////////////////////////////////////////////////////////////////////////
    305 
    306 static unsigned int _check_name_length( char* name,
    307                                         unsigned int* length,
    308                                         unsigned int* nb_lfn );
    309 
    310 //////////////////////////////////////////////////////////////////////////////////
    311 // For a node identified by the "inode" argument, this function updates the
    312 // "size" and "cluster" values in the entry of the parent directory File-Cache.
    313 // It set the dirty bit in the modified buffer of the parent directory File-Cache.
    314 //////////////////////////////////////////////////////////////////////////////////
     140static unsigned int _get_sfn_name( char*          name,
     141                                   unsigned int*  length,
     142                                   unsigned int*  nb_lfn,
     143                                   char*          sfn,
     144                                   unsigned char* checksum );
    315145
    316146static unsigned int _update_dir_entry( fat_inode_t*  inode );
    317 
    318 //////////////////////////////////////////////////////////////////////////////////
    319 // The following function add new "child" in Cache-File of "parent" directory.
    320 // It accesses the File_Cache associated to the parent directory, and scan the
    321 // clusters allocated to this directory to find the NO_MORE entry.
    322 // This entry will be the first modified entry in the directory.
    323 // Regarding the name storage, it uses LFN entries for all names.
    324 // Therefore, it writes 1, 2, or 3 LFN entries (depending on the child name
    325 // actual length, it writes one NORMAL entry, and writes the new NOMORE entry.
    326 // It updates the dentry field in the child inode.
    327 // It set the dirty bit for all modified File-Cache buffers.
    328 // The block device is not modified by this function.
    329 //////////////////////////////////////////////////////////////////////////////////
    330147
    331148static unsigned int _add_dir_entry( fat_inode_t* child,
    332149                                    fat_inode_t* parent );
    333150
    334 //////////////////////////////////////////////////////////////////////////////////
    335 // The following function invalidates all dir_entries associated to the "inode"
    336 // argument from its parent directory.
    337 // It set the dirty bit for all modified buffers in parent directory Cache-File.
    338 // The inode itself is not modified by this function.
    339 // The block device is not modified by this function.
    340 //////////////////////////////////////////////////////////////////////////////////
    341 
    342151static unsigned int _remove_dir_entry( fat_inode_t*  inode );
    343 
    344 //////////////////////////////////////////////////////////////////////////////////
    345 // The following function add the special entries "." and ".." in the File-Cache
    346 // of the directory identified by the "child" argument.
    347 // The parent directory is defined by the "parent" argument.
    348 // The child directory File-Cache is supposed to be empty.
    349 // We use two NORMAL entries for these "." and ".." entries.
    350 // The block device is not modified by this function.
    351 //////////////////////////////////////////////////////////////////////////////////
    352152
    353153static void _add_special_directories( fat_inode_t* child,
    354154                                      fat_inode_t* parent );
    355155
    356 //////////////////////////////////////////////////////////////////////////////////
    357 // The following function releases all clusters allocated to a file or directory,
    358 // from the cluster index defined by the <cluster> argument, until the end
    359 // of the FAT linked list.
    360 // It calls _get_fat_entry() and _set_fat_entry() functions to scan the FAT,
    361 // and to update the clusters chaining.
    362 // The FAT region on block device is updated.
    363 // It returns 0 on success.
    364 // It returns 1 on error.
    365 //////////////////////////////////////////////////////////////////////////////////
    366 
    367 static unsigned int _clusters_release( unsigned int cluster );
    368 
    369 //////////////////////////////////////////////////////////////////////////////////
    370 // This function allocate one cluster in FAT to a file (or directory) identified
    371 // by the <inode> pointer. The allocated cluster index is returned in the
    372 // <cluster> argument.
    373 // It allocates also the associated buffers and buffer descriptors in Cache-File.
    374 // It calls _get_fat_entry() and _set_fat_entry() functions to update the
    375 // clusters chaining in the Cache-Fat. The FAT region on block device is updated.
    376 // It returns 0 on success.
    377 // It returns 1 on error.
    378 //////////////////////////////////////////////////////////////////////////////////
     156static unsigned int _clusters_release( fat_inode_t* inode );
    379157
    380158static unsigned int _cluster_allocate( fat_inode_t*   inode,
    381159                                       unsigned int*  cluster );
    382160
    383 //////////////////////////////////////////////////////////////////////////////////
    384 // This recursive function scans one File-Cache (or Fat-Cache) from root to
    385 // leaves. All memory allocated for 4KB buffers, and buffer descriptors (in
    386 // leaves) is released, along with the 64-Tree structure (root node is kept).
    387 // The cache is identified by the "root" and "levels" arguments.
    388 // It should not contain any dirty clusters.
    389 //////////////////////////////////////////////////////////////////////////////////
    390 
    391161static void _release_cache_memory( fat_cache_node_t*  root,
    392162                                   unsigned int       levels );
    393163
    394 //////////////////////////////////////////////////////////////////////////////////
    395 // The following function allocates and initializes a new cache node.
    396 // Its first child can be specified (used when adding a cache level).
    397 // The 63 other children are set to NULL.
    398 // It returns a pointer to a new Fat-Cache node.
    399 //////////////////////////////////////////////////////////////////////////////////
    400 
    401164static fat_cache_node_t* _allocate_one_cache_node( fat_cache_node_t* first_child );
    402 
    403 //////////////////////////////////////////////////////////////////////////////////
    404 // The following function allocates and initializes a new inode,
    405 // using the values defined by the arguments.
    406 // If the "cache_allocate" argument is true, an empty cache is allocated.
    407 // It returns a pointer on the new inode.
    408 //////////////////////////////////////////////////////////////////////////////////
    409165
    410166static fat_inode_t* _allocate_one_inode( char*        name,
     
    416172                                         unsigned int cache_allocate );
    417173
    418 //////////////////////////////////////////////////////////////////////////////////
    419 // The following function allocates a 4 Kbytes buffer and the associated cluster
    420 // descriptor for the file (or directory) identified by the <inode> argument,
    421 // and updates the Cache_File slot identified by the <cluster_id> argument.
    422 // The File-Cache slot must be empty.
    423 // It updates the buffer descriptor, using the <cluster> argument, that is
    424 // the cluster index in FAT.  The cluster descriptor dirty field is set.
    425 // It traverse the 64-tree Cache-file from top to bottom to find the last level.
    426 //////////////////////////////////////////////////////////////////////////////////
    427 
    428174static void _allocate_one_buffer( fat_inode_t*    inode,
    429175                                  unsigned int    cluster_id,
    430176                                  unsigned int    cluster );
    431177
    432 //////////////////////////////////////////////////////////////////////////////////
    433 // The following function allocates one free cluster from the FAT 
    434 // and returns the cluster index in the <cluster> argument.
    435 // It updates the FAT slot, and the two FAT global variables: first_free_cluster,
    436 // and free_clusters_number.
    437 // It returns 0 on success.
    438 // It returns 1 on error.
    439 //////////////////////////////////////////////////////////////////////////////////
    440 
    441178static unsigned int _allocate_one_cluster( unsigned int*  cluster );
    442179
    443 /////////////////////////////////////////////////////////////////////////////
    444 // This function remove from the file system a file or a directory
    445 // identified by the <inode> argument.
    446 // The remove condition must be checked by the caller.
    447 // The relevant lock(s) must have been taken by te caller.
    448 // It returns 0 on success.
    449 // It returns 1 on error.
    450 /////////////////////////////////////////////////////////////////////////////
    451 
    452180static unsigned int _remove_node_from_fs( fat_inode_t* inode );
    453 
    454 /////////////////////////////////////////////////////////////////////////////
    455 // This function return the cluster index and the size for a file
    456 // identified by the "pathname" argument, scanning directly the block
    457 // device DATA region.
    458 // It is intended to be called only by the _fat_load_no_cache() function,
    459 // it does not use the dynamically allocated File Caches, but uses only
    460 // the 4 Kbytes _fat_buffer_data.
    461 // It returns 0 on success.
    462 // It returns 1 on error.
    463 /////////////////////////////////////////////////////////////////////////////
    464181
    465182static unsigned int _file_info_no_cache( char*          pathname,
     
    467184                                         unsigned int*  file_size );
    468185
    469 /////////////////////////////////////////////////////////////////////////////
    470 // This function scan directly the FAT region on the block device,
    471 // and returns in the "next" argument the value stored in the fat slot
    472 // identified by the "cluster" argument.
    473 // It is intended to be called only by the _fat_load_no_cache() function,
    474 // as it does not use the dynamically allocated Fat-Cache, but uses only
    475 // the 4 Kbytes _fat_buffer_fat.
    476 // It returns 0 on success.
    477 // It returns 1 on error.
    478 /////////////////////////////////////////////////////////////////////////////
    479 
    480186static unsigned int _next_cluster_no_cache( unsigned int   cluster,
    481187                                            unsigned int*  next );
    482188
    483 
    484 //////////////////////////////////////////////////////////////////////////////////
    485 // The following functions return the the size (bytes) of a FAT field,
    486 // identified by an (offset,length) mnemonic defined in the fat32.h file.
    487 //////////////////////////////////////////////////////////////////////////////////
    488 
    489189static inline int get_length( int offset , int length ) { return length; }
    490190
    491191static inline int get_offset( int offset , int length ) { return offset; }
    492 
    493 //////////////////////////////////////////////////////////////////////////////////
    494 // The following function returns in the <desc> argument a pointer on a buffer
    495 // descriptor contained in the Fat_Cache.
    496 // The <cluster_id> argument is the buffer index in the FAT_Cache.
    497 // In case of miss, a 4 Kbytesbuffer and a buffer descriptor are allocated
    498 // from the local heap, and the missing cluster is loaded in the Fat_Cache.
    499 // It returns 0 on success.
    500 // It returns 1 on error.
    501 //////////////////////////////////////////////////////////////////////////////////
    502 
    503 static unsigned int _get_fat_cache_buffer( unsigned int        cluster_id,
    504                                            fat_cache_desc_t**  desc );
    505 
    506192
    507193
     
    512198//////////////////////////////////////////////////////////////////////////////////
    513199//////////////////////////////////////////////////////////////////////////////////
    514 
    515 #if GIET_DEBUG_FAT
    516 ///////////////////////////////////////////////////
    517 static void _display_one_block( unsigned char* buf,
    518                                 char*          string,
    519                                 unsigned int   block_id )
    520 {
    521     unsigned int line;
    522     unsigned int word;
    523 
    524     _printf("\n***  <%s>  block %x  ***********************************\n",
    525             string , block_id );
    526 
    527     for ( line = 0 ; line < 16 ; line++ )
    528     {
    529         // display line index
    530         _printf("%x : ", line );
    531 
    532         // display 8*4 bytes hexa
    533         for ( word=0 ; word<8 ; word++ )
    534         {
    535             unsigned int byte  = (line<<5) + (word<<2);
    536             unsigned int hexa  = (buf[byte  ]<<24) |
    537                                  (buf[byte+1]<<16) |
    538                                  (buf[byte+2]<< 8) |
    539                                  (buf[byte+3]      );
    540             _printf(" %X |", hexa );
    541         }
    542         _printf("\n");
    543     }
    544     _printf("*******************************************************************\n");
    545 } // end _display_one_block() 
    546 #endif
    547 
    548200
    549201
     
    579231
    580232
    581 
    582 #if 0
     233#if GIET_DEBUG_FAT
    583234////////////////////////////////////////////////////////
    584235static void _display_clusters_list( fat_inode_t* inode )
    585236{
    586     _printf("\n**************** clusters for <%s> ***********************\n", inode->name );
    587     unsigned int next;
    588     unsigned int n       = 0;
    589     unsigned int current = inode->cluster;
    590     while( (current < END_OF_CHAIN_CLUSTER_MIN) && (n < 1024) )
    591     {
     237    unsigned int next        = 0;
     238    unsigned int cluster_id  = 0;
     239    unsigned int current     = inode->cluster;
     240
     241    _printf("\n --- clusters for <%s> ---\n",
     242            inode->name );
     243
     244    while( current < END_OF_CHAIN_CLUSTER_MIN )
     245    {
     246        if ( (current < 2) || (cluster_id >= 1024) )
     247        {
     248            _printf("\n[FAT ERROR] in _display_clusters_list()\n");
     249            _exit();
     250        }
     251
    592252        _get_fat_entry( current , &next );
    593253        _printf(" > %X", current );
    594         n++;
    595         if ( (n & 0x7) == 0 ) _printf("\n");
     254        cluster_id++;
     255        if ( (cluster_id & 0x7) == 0 ) _printf("\n");
    596256        current = next;
    597257    }
     
    599259}  // end _display_clusters_list()
    600260#endif
    601 
    602 
    603 
    604 /////////////////////////////////////////////////////////////////////////////////
    605 static int _fat_ioc_access( unsigned int use_irq,       // descheduling if non zero
    606                             unsigned int to_mem,        // read / write
    607                             unsigned int lba,           // first sector on device
    608                             unsigned int buf_vaddr,     // memory buffer vaddr
    609                             unsigned int count )        // number of sectors
    610 {
    611     // compute memory buffer physical address
    612     unsigned int       flags;         // for _v2p_translate
    613     unsigned long long buf_paddr;     // buffer physical address
    614 
    615     if ( ((_get_mmu_mode() & 0x4) == 0 ) || USE_IOC_RDK )  // identity
    616     {
    617         buf_paddr = (unsigned long long)buf_vaddr;
    618     }
    619     else                                // V2P translation required
    620     {
    621         buf_paddr = _v2p_translate( buf_vaddr , &flags );
    622     }
    623 
    624 #if (GIET_DEBUG_FAT & 1)
    625 if ( _get_proctime() > GIET_DEBUG_FAT )
    626 _printf("\n[DEBUG FAT] _fat_ioc_access(): enters at cycle %d\n"
    627         "  to_mem = %d / vaddr = %x / paddr = %l / sectors = %d / lba = %x\n",
    628         _get_proctime(), to_mem, buf_vaddr, buf_paddr, count, lba );
    629 #endif
    630 
    631 
    632 #if GIET_NO_HARD_CC     // L1 cache inval (virtual addresses)
    633     if ( to_mem ) _dcache_buf_invalidate( buf_vaddr, count<<9 );
    634 #endif
    635 
    636 
    637 #if   ( USE_IOC_BDV )   // call the proper driver
    638     return( _bdv_access( use_irq , to_mem , lba , buf_paddr , count ) );
    639 #elif ( USE_IOC_HBA )
    640     return( _hba_access( use_irq , to_mem , lba , buf_paddr , count ) );
    641 #elif ( USE_IOC_SDC )
    642     return( _sdc_access( use_irq , to_mem , lba , buf_paddr , count ) );
    643 #elif ( USE_IOC_SPI )
    644     return( _spi_access( use_irq , to_mem , lba , buf_paddr , count ) );
    645 #elif ( USE_IOC_RDK )
    646     return( _rdk_access( use_irq , to_mem , lba , buf_paddr , count ) );
    647 #else
    648     _printf("\n[FAT ERROR] _fat_ioc_access(): no IOC driver\n");
    649     _exit();
    650 #endif
    651 
    652 }  // end _fat_ioc_access()
    653 
    654261
    655262
     
    956563
    957564
    958 
    959 
    960 
    961 
    962 
    963565/////////////////////////////////////
    964566static unsigned int _update_fs_info()
     
    998600    }
    999601
    1000 #if (GIET_DEBUG_FAT & 1)
     602#if GIET_DEBUG_FAT
    1001603if ( _get_proctime() > GIET_DEBUG_FAT )
    1002604_printf("\n[DEBUG FAT] _update_fs_info(): nb_free = %x / first_free = %x\n",
     
    1006608    return 0;
    1007609}  // end _update_fs_info()
    1008 
    1009610
    1010611
     
    1013614                                           unsigned int* value )
    1014615{
    1015     // compute cluster_id & entry_id in FAT
    1016     // a FAT cluster is an array of 1024 unsigned int entries
     616    // compute cluster_id & entry_id in FAT from cluster index
     617    // a FAT buffer is an array of 1024 unsigned int entries
    1017618    unsigned int       cluster_id = cluster >> 10;       
    1018619    unsigned int       entry_id   = cluster & 0x3FF;
     
    1037638                                           unsigned int value  )
    1038639{
    1039     // compute cluster_id & entry_id in FAT
     640    // compute cluster_id & entry_id in FAT from cluster index
    1040641    // a FAT cluster is an array of 1024 unsigned int entries
    1041642    unsigned int cluster_id = cluster >> 10;
     
    1064665{
    1065666
    1066 #if (GIET_DEBUG_FAT & 1)
     667#if GIET_DEBUG_FAT
    1067668if ( _get_proctime() > GIET_DEBUG_FAT )
    1068669_printf("\n[DEBUG FAT] _allocate_one_buffer(): in cache <%s> for cluster_id %d\n",
     
    1074675    {
    1075676
    1076 #if (GIET_DEBUG_FAT & 1)
     677#if GIET_DEBUG_FAT
    1077678if ( _get_proctime() > GIET_DEBUG_FAT )
    1078679_printf("\n[DEBUG FAT] _allocate_one_buffer(): adding a cache level\n" );
     
    1105706            }
    1106707
    1107 #if (GIET_DEBUG_FAT & 1)
     708#if GIET_DEBUG_FAT
    1108709if ( _get_proctime() > GIET_DEBUG_FAT )
    1109710_printf("\n[DEBUG FAT] _allocate_one_buffer(): buffer allocated to <%s> for cluster_id %d\n",
     
    1155756        // get FAT entry indexed by current
    1156757        if ( _get_fat_entry( current , &value ) ) return 1;
     758
    1157759        // test if free
    1158760        if ( value == FREE_CLUSTER ) found = 1;
     
    1174776    _fat.first_free_cluster   = current;
    1175777
    1176 #if (GIET_DEBUG_FAT & 1)
     778#if GIET_DEBUG_FAT
    1177779if ( _get_proctime() > GIET_DEBUG_FAT )
    1178780_printf("\n[DEBUG FAT] _allocate_one_cluster(): allocated cluster = %x / first_free = %x\n",
     
    1221823                        pdesc->dirty = 0;
    1222824
    1223 #if (GIET_DEBUG_FAT & 1)
     825#if GIET_DEBUG_FAT
    1224826if ( _get_proctime() > GIET_DEBUG_FAT )
    1225827_printf("\n[DEBUG FAT] _update_device_from_cache(): cluster_id = %d for <%s>\n",
     
    1347949    }
    1348950
    1349     // update the FAT on block device
     951    // update the FAT on device
    1350952    if ( _update_device_from_cache( _fat.fat_cache_levels,
    1351953                                    _fat.fat_cache_root,
    1352954                                    "FAT" ) )              return 1;
    1353 #if (GIET_DEBUG_FAT & 1)
    1354 if ( _get_proctime() > GIET_DEBUG_FAT )
    1355 _printf("\n[DEBUG FAT] _cluster_allocate(): for <%s> / current_clusters = %d"
    1356         " / last_cluster = %x / new_cluster = %x\n",
     955
     956    // update FS-INFO sector on device
     957    if ( _update_fs_info() )  return 1;
     958
     959#if GIET_DEBUG_FAT
     960if ( _get_proctime() > GIET_DEBUG_FAT )
     961_printf("\n[DEBUG FAT] _cluster_allocate(): for <%s>\n"
     962        " nb_clusters = %d / last_cluster = %x / new_cluster = %x\n",
    1357963        inode->name , nb_current_clusters , last , new );
    1358964#endif
     
    1366972
    1367973
    1368 //////////////////////////////////////////////////////////////
    1369 static unsigned int _clusters_release( unsigned int cluster )
     974///////////////////////////////////////////////////////////
     975static unsigned int _clusters_release( fat_inode_t* inode )
    1370976{
    1371977    // scan the FAT
    1372     unsigned int current = cluster;
     978    unsigned int current = inode->cluster;
    1373979    unsigned int next;
    1374980    do
     
    1393999                                    _fat.fat_cache_root,
    13941000                                    "FAT" ) )                return 1;
     1001
     1002    // update FS-INFO sector on device
     1003    if ( _update_fs_info() )  return 1;
     1004
     1005#if GIET_DEBUG_FAT
     1006if ( _get_proctime() > GIET_DEBUG_FAT )
     1007_printf("\n[DEBUG FAT] _clusters_release(): for file <%s>\n", inode->name );
     1008#endif
     1009
    13951010    return 0;
    13961011}  // end _clusters_release()
     
    14731088
    14741089////////////////////////////////////////////////////////////
    1475 static unsigned int _check_name_length( char* name,
    1476                                         unsigned int* length,
    1477                                         unsigned int* nb_lfn )
    1478 {
    1479     unsigned int len = _strlen( name );
    1480     if      ( len <= 13 )
    1481     {
    1482         *length  = len;
     1090static unsigned int _get_sfn_name( char*           name,
     1091                                   unsigned int*   length,
     1092                                   unsigned int*   nb_lfn,
     1093                                   char*           sfn,
     1094                                   unsigned char*  checksum )
     1095{
     1096    // compute name length
     1097    unsigned int name_length = _strlen( name );
     1098
     1099    // compute prefix and suffix length
     1100    // only the last '.' is taken into account
     1101    unsigned int suffix_length = 0;
     1102    unsigned int prefix_length = 0;
     1103    unsigned int dot_found     = 0;
     1104    unsigned int i;
     1105    for ( i=0 ; i<name_length ; i++ )
     1106    {
     1107        if (name[i] == '.' )
     1108        {
     1109            if ( dot_found )
     1110            {
     1111                prefix_length += suffix_length + 1;
     1112                suffix_length =  0;
     1113            }
     1114            else
     1115            {
     1116                dot_found = 1;
     1117            }
     1118        }
     1119        else
     1120        {
     1121            if ( dot_found)
     1122            {
     1123                suffix_length++;
     1124            }
     1125            else
     1126            {
     1127                prefix_length++;
     1128            }
     1129        }
     1130    }
     1131
     1132    // build SFN prefix (8bits)
     1133    if (prefix_length <= 8)
     1134    {
     1135        for( i=0 ; i<8 ; i++)
     1136        {
     1137            if ( i<prefix_length ) sfn[i] = _to_upper( name[i] );
     1138            else                   sfn[i] = 0x20;
     1139        }
     1140    }
     1141    else
     1142    {
     1143        for( i=0 ; i<6 ; i++)
     1144        {
     1145            sfn[i] = _to_upper( name[i] );
     1146        }
     1147        sfn[6] = 0x7E;
     1148        sfn[7] = 0x31;
     1149    }
     1150
     1151    // build SFN suffix (3 bits)
     1152    if ( suffix_length == 0 )
     1153    {
     1154        sfn[8]  = 0x20;
     1155        sfn[9]  = 0x20;
     1156        sfn[10] = 0x20;
     1157    }
     1158    else if ( suffix_length == 1 )
     1159    {
     1160        sfn[8]  = _to_upper( name[name_length-1] );
     1161        sfn[9]  = 0x20;
     1162        sfn[10] = 0x20;
     1163    }
     1164    else if ( suffix_length == 2 )
     1165    {
     1166        sfn[8]  = _to_upper( name[name_length-2] );
     1167        sfn[9]  = _to_upper( name[name_length-1] );
     1168        sfn[10] = 0x20;
     1169    }
     1170    else
     1171    {
     1172        sfn[8]  = _to_upper( name[name_length-suffix_length] );
     1173        sfn[9]  = _to_upper( name[name_length-suffix_length+1] );
     1174        sfn[10] = _to_upper( name[name_length-suffix_length+2] );
     1175    }
     1176
     1177    // compute 8 bits checksum
     1178    unsigned char sum = 0;
     1179    for ( i=0 ; i<11 ; i++ )
     1180    {
     1181        sum = (((sum & 0x01)<<7) | ((sum & 0xFE)>>1)) + sfn[i];
     1182    }
     1183    *checksum = sum;
     1184
     1185    // set nb_lfn and length values
     1186    if      ( name_length <= 13 )
     1187    {
     1188        *length  = name_length;
    14831189        *nb_lfn  = 1;
    14841190        return 0;
    14851191    }
    1486     else if ( len <= 26 )
    1487     {
    1488         *length  = len;
     1192    else if ( name_length <= 26 )
     1193    {
     1194        *length  = name_length;
    14891195        *nb_lfn  = 2;
    14901196        return 0;
    14911197    }
    1492     else if ( len <= 31 )
    1493     {
    1494         *length  = len;
     1198    else if ( name_length <= 31 )
     1199    {
     1200        *length  = name_length;
    14951201        *nb_lfn  = 3;
    14961202        return 0;
     
    15001206        return 1;
    15011207    }
    1502 }  // _check_name_length()
     1208}  // _get_sfn_name()
    15031209
    15041210
     
    15651271   
    15661272    return 0;
    1567 }  // end dir_not_empty()
     1273}  // end _get_nb_entries()
     1274
     1275
     1276
     1277////////////////////////////////////////////////////////////
     1278static unsigned int _update_dir_entry( fat_inode_t*  inode )
     1279
     1280    // get Cache-File buffer containing the parent directory entry
     1281    // 128 directories entries in one 4 Kbytes buffer
     1282    fat_cache_desc_t*  pdesc;
     1283    unsigned char*     buffer;   
     1284    unsigned int       cluster_id = inode->dentry>>7;
     1285    unsigned int       offset     = (inode->dentry & 0x7F)<<5;
     1286
     1287    if ( _get_file_cache_buffer( inode->parent,
     1288                                 cluster_id,
     1289                                 0,
     1290                                 &pdesc ) )    return 1;
     1291    buffer       = pdesc->buffer;
     1292    pdesc->dirty = 1;
     1293
     1294    // update size field
     1295    buffer[offset + 28] = inode->size>>0;       // size.B0
     1296    buffer[offset + 29] = inode->size>>8;       // size.B1
     1297    buffer[offset + 30] = inode->size>>16;      // size.B2
     1298    buffer[offset + 31] = inode->size>>24;      // size.B3
     1299
     1300    // update cluster field
     1301    buffer[offset + 26] = inode->cluster>>0;    // cluster.B0
     1302    buffer[offset + 27] = inode->cluster>>8;    // cluster.B1
     1303    buffer[offset + 20] = inode->cluster>>16;   // cluster.B2
     1304    buffer[offset + 21] = inode->cluster>>24;   // cluster.B3
     1305   
     1306    return 0;
     1307} // end _update_dir_entry()
     1308
    15681309
    15691310
     
    15781319    unsigned int      cluster = child->cluster;
    15791320
    1580     // compute number of required entries to store child->name
    1581     // - Short name (less than 13 characters) require 3 entries:
    1582     //   one LFN entry / one NORMAL entry / one NO_MORE_ENTRY entry.
    1583     // - Longer names (up to 31 characters) can require 4 or 5 entries:
    1584     //   2 or 3 LFN entries / one NORMAL entry / one NO_MORE entry.
    1585     unsigned int length;
    1586     unsigned int nb_lfn;
    1587     if ( _check_name_length( child->name,
     1321    // compute number of required 32 bytes entries to store
     1322    // the complete child name and a legal 8.3 SFN name.
     1323    unsigned int    length;
     1324    unsigned int    nb_lfn;
     1325    char            sfn[11];
     1326    unsigned char   checksum;
     1327    if ( _get_sfn_name( child->name,
    15881328                             &length,
    1589                              &nb_lfn ) )  return 1;
    1590 
    1591 #if (GIET_DEBUG_FAT & 1)
     1329                             &nb_lfn,
     1330                             sfn,
     1331                             &checksum ) )  return 1;
     1332
     1333#if GIET_DEBUG_FAT
    15921334if ( _get_proctime() > GIET_DEBUG_FAT )
    15931335_printf("\n[DEBUG FAT] _add_dir_entry(): try to add <%s> in <%s> / nb_lfn = %d\n",
     
    16071349    while ( found == 0 )
    16081350    {
    1609         // get one 4 Kytes buffer from File_Cache 
     1351        // get the 4 Kytes buffer from File_Cache 
    16101352        if ( _get_file_cache_buffer( parent,
    16111353                                     cluster_id,
     
    16281370            }
    16291371        }  // end loop on entries
     1372
    16301373        if ( found == 0 )
    16311374        {
     
    16351378    }  // end loop on clusters
    16361379
    1637 #if (GIET_DEBUG_FAT & 1)
     1380#if GIET_DEBUG_FAT
    16381381if ( _get_proctime() > GIET_DEBUG_FAT )
    16391382_printf("\n[DEBUG FAT] _add_dir_entry(): get NO_MORE directory entry : "
     
    16791422        entry = buffer + offset;
    16801423
    1681 #if (GIET_DEBUG_FAT & 1)
     1424#if GIET_DEBUG_FAT
    16821425if ( _get_proctime() > GIET_DEBUG_FAT )
    16831426_printf("\n[DEBUG FAT] _add_dir_entry(): FSM step = %d /"
     
    17081451                    }
    17091452                    else if (i == 11)     entry[i] = 0x0F;
    1710                     else if (i == 12)     entry[i] = 0xCA;
     1453                    else if (i == 13)     entry[i] = checksum;
    17111454                    else                  entry[i] = 0x00;
    17121455                }
     
    17341477                    }
    17351478                    else if (i == 11)     entry[i] = 0x0F;
    1736                     else if (i == 12)     entry[i] = 0xCA;
     1479                    else if (i == 13)     entry[i] = checksum;
    17371480                    else                  entry[i] = 0x00;
    17381481                }
     
    17601503                    }
    17611504                    else if (i == 11)     entry[i] = 0x0F;
    1762                     else if (i == 12)     entry[i] = 0xCA;
     1505                    else if (i == 13)     entry[i] = checksum;
    17631506                    else                  entry[i] = 0x00;
    17641507                }
     
    17681511            case 2:   // write NORMAL entry     
    17691512            {
    1770                 c = 0;
    17711513                // scan the 32 bytes in dir_entry
    17721514                for ( i = 0 ; i < 32 ; i++ )
    17731515                {
    1774                     if      ( (i < 8) && (c < length) )             // SFN
     1516                    if      ( i < 11 )                              // 8.3 SFN
    17751517                    {
    1776                                           entry[i] = _to_upper( name[c] );
    1777                                           c++;
     1518                                          entry[i] = sfn[i];
    17781519                    }
    1779                     else if (i <  11)     entry[i] = 0x20;          // EXT
    17801520                    else if (i == 11)                               // ATTR
    17811521                    {
     
    18101550    } // exit while => exit FSM   
    18111551
    1812 #if (GIET_DEBUG_FAT & 1)
     1552#if GIET_DEBUG_FAT
    18131553if ( _get_proctime() > GIET_DEBUG_FAT )
    18141554{
     
    18271567{
    18281568    // compute number of LFN entries
    1829     unsigned int length;
    18301569    unsigned int nb_lfn;
    1831     if ( _check_name_length( inode->name,
    1832                              &length,
    1833                              &nb_lfn ) )  return 1;
     1570    unsigned int name_length = _strlen( inode->name );
     1571    if      ( name_length <= 13 ) nb_lfn  = 1;
     1572    else if ( name_length <= 26 ) nb_lfn  = 2;
     1573    else                          nb_lfn  = 3;
    18341574
    18351575    // get cluster_id and offset in parent directory cache
     
    18871627
    18881628
    1889 ////////////////////////////////////////////////////////////
    1890 static unsigned int _update_dir_entry( fat_inode_t*  inode )
    1891 
    1892     // get Cache-File buffer containing the parent directory entry
    1893     // 128 directories entries in one 4 Kbytes buffer
    1894     fat_cache_desc_t*  pdesc;
    1895     unsigned char*     buffer;   
    1896     unsigned int       cluster_id = inode->dentry>>7;
    1897     unsigned int       offset     = (inode->dentry & 0x7F)<<5;
    1898 
    1899     if ( _get_file_cache_buffer( inode->parent,
    1900                                  cluster_id,
    1901                                  0,
    1902                                  &pdesc ) )    return 1;
    1903     buffer       = pdesc->buffer;
    1904     pdesc->dirty = 1;
    1905 
    1906     // update size field
    1907     buffer[offset + 28] = inode->size>>0;       // size.B0
    1908     buffer[offset + 29] = inode->size>>8;       // size.B1
    1909     buffer[offset + 30] = inode->size>>16;      // size.B2
    1910     buffer[offset + 31] = inode->size>>24;      // size.B3
    1911 
    1912     // update cluster field
    1913     buffer[offset + 26] = inode->cluster>>0;    // cluster.B0
    1914     buffer[offset + 27] = inode->cluster>>8;    // cluster.B1
    1915     buffer[offset + 20] = inode->cluster>>16;   // cluster.B2
    1916     buffer[offset + 21] = inode->cluster>>24;   // cluster.B3
    1917    
    1918     return 0;
    1919 } // end _update_dir_entry()
    1920 
    1921 
    1922 
    1923 
    19241629//////////////////////////////////////////////////////////////////
    19251630static unsigned int _get_child_from_parent( fat_inode_t*   parent,
     
    19291634    fat_inode_t*   current;
    19301635
    1931 #if (GIET_DEBUG_FAT & 1)
     1636#if GIET_DEBUG_FAT
    19321637if ( _get_proctime() > GIET_DEBUG_FAT )
    19331638_printf("\n[DEBUG FAT] _get_child_from_parent(): search <%s> in directory <%s>\n",
     
    19411646        {
    19421647
    1943 #if (GIET_DEBUG_FAT & 1)
    1944 if ( _get_proctime() > GIET_DEBUG_FAT )
    1945 _printf("\n[DEBUG FAT] _get_child_from_parent(): found inode <%s> in directory <%s>\n",
     1648#if GIET_DEBUG_FAT
     1649if ( _get_proctime() > GIET_DEBUG_FAT )
     1650_printf("\n[DEBUG FAT] _get_child_from_parent(): found inode for <%s> in <%s>\n",
    19461651        name , parent->name );
    19471652#endif
     
    19721677    int               found      = 0;   // not found (0) / name found (1) / end of dir (-1)
    19731678
    1974 #if (GIET_DEBUG_FAT & 1)
    1975 if ( _get_proctime() > GIET_DEBUG_FAT )
    1976 _printf("\n[DEBUG FAT] _get_child_from_parent(): does not found inode <%s>"
    1977         " in directory <%s> => search in cache\n", name , parent->name );
     1679#if GIET_DEBUG_FAT
     1680if ( _get_proctime() > GIET_DEBUG_FAT )
     1681_printf("\n[DEBUG FAT] _get_child_from_parent(): child <%s> in <%s> not found in Inode-Tree\n"
     1682        " search in parent cache\n", name , parent->name );
    19781683#endif
    19791684
     
    20341739                    _strcpy( cname + 26 , lfn3 );
    20351740                }
    2036                    
    2037                 // get dir-entry arguments if extracted name == searched name
     1741
     1742                // get dentry arguments if extracted name == searched name
    20381743                if ( _strcmp( name , cname ) == 0 )
    20391744                {
     
    20441749                    size    = _read_entry( DIR_FILE_SIZE , buffer + offset , 1 );
    20451750                    found   = 1;
    2046 
    2047                     // adjust size for a directory :
    2048                     // size must be non-zero and rounded to a multiple of 4 Kbytes
    2049                     if ( is_dir )
    2050                     {
    2051                         if      ( size == 0 )    size = 4096;
    2052                         else if ( size & 0xFFF ) size = ((size>>12) + 1)<<12; 
    2053                     }
    20541751                }
    20551752                offset = offset + 32;
     
    20641761    {
    20651762
    2066 #if (GIET_DEBUG_FAT & 1)
     1763#if GIET_DEBUG_FAT
    20671764if ( _get_proctime() > GIET_DEBUG_FAT )
    20681765_printf("\n[DEBUG FAT] _get_child_from_parent(): found end of directory in <%s>\n",
     
    20861783        _add_inode_in_tree( *inode , parent );
    20871784
    2088 #if (GIET_DEBUG_FAT & 1)
     1785#if GIET_DEBUG_FAT
    20891786if ( _get_proctime() > GIET_DEBUG_FAT )
    20901787_printf("\n[DEBUG FAT] _get_child_from_parent(): found <%s> on device\n", name );
     
    21081805    unsigned int         code;             // return value
    21091806
    2110 #if (GIET_DEBUG_FAT & 1)
     1807#if GIET_DEBUG_FAT
    21111808if ( _get_proctime() > GIET_DEBUG_FAT )
    21121809_printf("\n[DEBUG FAT] _get_inode_from_path(): enters for path <%s>\n", pathname );
     
    21171814    {
    21181815
    2119 #if (GIET_DEBUG_FAT & 1)
     1816#if GIET_DEBUG_FAT
    21201817if ( _get_proctime() > GIET_DEBUG_FAT )
    21211818_printf("\n[DEBUG FAT] _get_inode_from_path(): found root inode for <%s>\n",
     
    21451842        last = (pathname[nb_read] == 0);
    21461843
    2147 #if (GIET_DEBUG_FAT & 1)
     1844#if GIET_DEBUG_FAT
    21481845if ( _get_proctime() > GIET_DEBUG_FAT )
    21491846_printf("\n[DEBUG FAT] _get_inode_from_path(): got name <%s>\n", name );
     
    21761873            {
    21771874
    2178     #if (GIET_DEBUG_FAT & 1)
     1875    #if GIET_DEBUG_FAT
    21791876    if ( _get_proctime() > GIET_DEBUG_FAT )
    21801877    _printf("\n[DEBUG FAT] _get_inode_from_path(): neither parent, nor child found for <%s>\n",
     
    21941891    {
    21951892
    2196 #if (GIET_DEBUG_FAT & 1)
     1893#if GIET_DEBUG_FAT
    21971894if ( _get_proctime() > GIET_DEBUG_FAT )
    21981895_printf("\n[DEBUG FAT] _get_inode_from_path(): found inode for <%s>\n",
     
    22041901    {
    22051902
    2206 #if (GIET_DEBUG_FAT & 1)
     1903#if GIET_DEBUG_FAT
    22071904if ( _get_proctime() > GIET_DEBUG_FAT )
    22081905_printf("\n[DEBUG FAT] _get_inode_from_path(): found only parent inode for <%s>\n",
     
    22341931
    22351932    // release clusters allocated to file/dir in DATA region
    2236     if ( _clusters_release( inode->cluster ) ) return 1;
     1933    if ( _clusters_release( inode ) ) return 1;
    22371934
    22381935    // release File-Cache
     
    22951992{
    22961993   
    2297 #if (GIET_DEBUG_FAT & 1)
     1994#if GIET_DEBUG_FAT
    22981995if ( _get_proctime() > GIET_DEBUG_FAT )
    22991996_printf("\n[DEBUG FAT] _file_info_no_cache(): enters for path <%s>\n", pathname );
     
    23322029        if ( _get_name_from_path( pathname, name, &nb_read ) ) return 1;
    23332030
    2334 #if (GIET_DEBUG_FAT & 1)
     2031#if GIET_DEBUG_FAT
    23352032if ( _get_proctime() > GIET_DEBUG_FAT )
    23362033_printf("\n[DEBUG FAT] _file_info_no_cache(): search name <%s>"
     
    24512148    }  // end loop on names
    24522149
    2453 #if (GIET_DEBUG_FAT & 1)
     2150#if GIET_DEBUG_FAT
    24542151if ( _get_proctime() > GIET_DEBUG_FAT )
    24552152_printf("\n[DEBUG FAT] _file_info_no_cache(): success for <%s> / "
     
    24652162
    24662163
    2467 //////////////////////////////////////////////////////////////////////////
    2468 static unsigned int _get_fat_cache_buffer( unsigned int        cluster_id,
    2469                                            fat_cache_desc_t**  desc )
    2470 {
    2471     // get cache pointer and number of levels
    2472     fat_cache_node_t*   node   = _fat.fat_cache_root;   
    2473     unsigned int        level  = _fat.fat_cache_levels; 
    2474 
    2475     if ( _get_levels_from_size( (cluster_id + 1) * 4096 ) > level )
    2476     {
    2477         _printf("\n[FAT ERROR] in _get_fat_cache_buffer() : "
    2478                 "cluster_id %d too large", cluster_id );
     2164
     2165/////////////////////////////
     2166unsigned int _set_fs_info()
     2167{
     2168
     2169#if GIET_DEBUG_FAT
     2170if ( _get_proctime() > GIET_DEBUG_FAT )
     2171_printf("\n[DEBUG FAT] _set_fs_info(): enters at cycle %d\n", _get_proctime() );
     2172#endif
     2173
     2174    // load FS_INFO sector into FAT buffer
     2175    if ( _fat_ioc_access( 0,                                // no descheduling
     2176                          1,                                // read
     2177                          _fat.fs_info_lba,                 // lba
     2178                          (unsigned int)_fat.block_buffer,
     2179                          1 ) )                             // one block
     2180    {
     2181        _printf("\n[FAT ERROR] _set_fs_info(): cannot load FS_INFO Sector\n");
    24792182        return 1;
    24802183    }
    24812184
    2482     // search the 64-tree cache from top to bottom
    2483     while ( level )
    2484     {
    2485         // compute child index at each level
    2486         unsigned int index = (cluster_id >> (6*(level-1))) & 0x3F;
    2487 
    2488         if ( level == 1 )        // last level => children are buffer descriptors
    2489         {
    2490             fat_cache_desc_t*   pdesc = (fat_cache_desc_t*)node->children[index];
    2491 
    2492             if ( pdesc == NULL )      // miss
     2185    _fat.block_buffer_lba = _fat.fs_info_lba;
     2186
     2187#if GIET_DEBUG_FAT
     2188if ( _get_proctime() > GIET_DEBUG_FAT )
     2189_printf("\n[DEBUG FAT] _set_fs_info(): FS-INFO sector loaded\n");
     2190#endif
     2191
     2192    // get general info from FAT descriptor
     2193    unsigned int  fat_blocks   = _fat.fat_sectors;
     2194    unsigned int  data_blocks  = _fat.data_sectors;
     2195    unsigned int  lba          = _fat.fat_lba;
     2196    unsigned int* buf          = (unsigned int*)_fat.block_buffer;
     2197
     2198    // initialise <free_clusters_number> from FS-INFO sector
     2199    unsigned int free_clusters = _read_entry( FS_FREE_CLUSTERS, _fat.block_buffer, 1);
     2200    if ( free_clusters >= (data_blocks>>3) )
     2201    {
     2202        _printf("\n[FAT ERROR] _set_fs_info(): illegal FS_FREE_CLUSTERS in FS-INFO\n"
     2203                "  fs_free_clusters = %x / total_clusters = %x\n",
     2204                free_clusters , (data_blocks>>3)  );
     2205        return 1;
     2206    }
     2207
     2208    _fat.free_clusters_number  = free_clusters;
     2209
     2210    // scan FAT on device from FS-FREE_CLUSTER_HINT to initialise <first_free_cluster>
     2211    unsigned int free_cluster_hint = _read_entry( FS_FREE_CLUSTER_HINT, _fat.block_buffer, 1);     
     2212    if ( free_cluster_hint > (data_blocks>>3) )
     2213    {
     2214        _printf("\n[FAT ERROR] _set_fs_info(): illegal FS_FREE_CLUSTER_HINT in FS-INFO\n"
     2215                "  fs_free_cluster_hint = %x / total_clusters = %x\n",
     2216                free_cluster_hint , (data_blocks>>3)  );
     2217        return 1;
     2218    }
     2219
     2220    unsigned int block_id    = free_cluster_hint>>7;
     2221    unsigned int first_entry = free_cluster_hint & 0x7F;
     2222    unsigned int  search     = 1;
     2223    unsigned int  first_free = 0;
     2224
     2225    // loop on the FAT blocks from free_cluster_hint
     2226    // until free cluster found or end of FAT region
     2227    while ( search && (block_id < fat_blocks) )
     2228    {
     2229        // read one FAT block from device
     2230        if ( _fat_ioc_access( 0,                   // no_irq
     2231                              1,                   // to_mem,
     2232                              lba + block_id,      // lba
     2233                              (unsigned int)buf,   // FAT local buffer
     2234                              1 ) )                // one block
     2235        {
     2236            _printf("\n[FAT_ERROR] _set_fs_info() : cannot read FAT block %d\n", block_id);
     2237            return 1;
     2238        }
     2239
     2240        _fat.block_buffer_lba = lba + block_id;
     2241
     2242        // scan the entries in block from first_entry to 128
     2243        unsigned int entry;
     2244        for ( entry = first_entry ; entry < 128 ; entry++ )
     2245        {
     2246            if ( buf[entry] == FREE_CLUSTER )
    24932247            {
     2248                first_free = (block_id<<7) + entry;
     2249                search = 0;
     2250                break;
     2251            }
     2252        }  // end loop on entries
     2253
     2254        block_id++;
     2255        first_entry = 0;
     2256    }  // end loop on blocks
     2257
     2258    if ( search )               // no free cluster 
     2259    {
     2260        _printf("\n[FAT_ERROR] _set_fs_info() : No free cluster found in FAT\n");
     2261        return 1;
     2262    }
     2263    else          // update fat descriptor
     2264    {
     2265        _fat.first_free_cluster = first_free;
     2266
     2267#if GIET_DEBUG_FAT
     2268if ( _get_proctime() > GIET_DEBUG_FAT )
     2269_printf("\n[DEBUG FAT] _set_fs_info() completes : free_clusters = %x / first_free = %x\n",
     2270        free_clusters , first_free );
     2271#endif
     2272
     2273        return 0;
     2274    }
     2275}  // end _set_fs_info()
     2276
     2277
     2278///////////////////////////////////////////////////////////////////////////////
     2279///////////////////////////////////////////////////////////////////////////////
     2280//             Extern functions                                               
     2281///////////////////////////////////////////////////////////////////////////////
     2282///////////////////////////////////////////////////////////////////////////////
     2283
     2284/////////////////////////////////////////////////////////////////////////////
     2285int _fat_ioc_access( unsigned int use_irq,       // descheduling if non zero
     2286                     unsigned int to_mem,        // read / write
     2287                     unsigned int lba,           // first sector on device
     2288                     unsigned int buf_vaddr,     // memory buffer vaddr
     2289                     unsigned int count )        // number of sectors
     2290{
     2291    // compute memory buffer physical address
     2292    unsigned int       flags;         // for _v2p_translate
     2293    unsigned long long buf_paddr;     // buffer physical address
     2294
     2295    if ( ((_get_mmu_mode() & 0x4) == 0 ) || USE_IOC_RDK )  // identity
     2296    {
     2297        buf_paddr = (unsigned long long)buf_vaddr;
     2298    }
     2299    else                                // V2P translation required
     2300    {
     2301        buf_paddr = _v2p_translate( buf_vaddr , &flags );
     2302    }
    24942303
    24952304#if (GIET_DEBUG_FAT & 1)
    24962305if ( _get_proctime() > GIET_DEBUG_FAT )
    2497 _printf("\n[DEBUG FAT] _get_fat_cache_buffer(): miss for cluster_id %d\n", cluster_id );
    2498 #endif
    2499                 // compute missing cluster lba
    2500                 unsigned int lba = _fat.fat_lba + (cluster_id << 3);
    2501 
    2502                 // allocate a 4 Kbytes buffer and a buffer descriptor
    2503                 void* buf      = _malloc( 4096 );
    2504                 pdesc          = _malloc( sizeof(fat_cache_desc_t) );
    2505                 pdesc->lba     = lba;
    2506                 pdesc->buffer  = buf;
    2507                 pdesc->dirty   = 0;
    2508                 node->children[index] = pdesc;
    2509 
    2510                 // load cluster from device
    2511                 if ( _fat_ioc_access( 1,         // descheduling
    2512                                       1,         // to memory
    2513                                       lba,
    2514                                       (unsigned int)buf,
    2515                                       8 ) )
    2516                 {
    2517                     _free( buf );
    2518                     _free( pdesc );
    2519                     _printf("\n[FAT ERROR] in _get_fat_cache_buffer() : "
    2520                             ": cannot access block device for lba = %x\n", lba );
    2521                     return 1;
    2522                 }
    2523 
    2524             }
    2525 
    2526 #if (GIET_DEBUG_FAT & 1)
    2527 if ( _get_proctime() > GIET_DEBUG_FAT )
    2528 _printf("\n[DEBUG FAT] _get_fat_cache_buffer() : found buffer = %x\n",
    2529         (unsigned int)pdesc->buffer );
    2530 #endif
    2531             // return pdesc pointer
    2532             *desc = pdesc;
    2533 
    2534             // prepare next iteration
    2535             level--;
    2536         }
    2537         else                      // not last level => children are 64-tree nodes
    2538         {
    2539             fat_cache_node_t* child = (fat_cache_node_t*)node->children[index];
    2540             if ( child == NULL )  // miss
    2541             {
    2542                 // allocate a cache node if miss
    2543                 child = _allocate_one_cache_node( NULL );
    2544                 node->children[index] = child;   
    2545             }
    2546 
    2547             // prepare next iteration
    2548             node = child;
    2549             level--;
    2550         }
    2551     } // end while
    2552 
    2553     return 0;
    2554 }  // end _get_fat_cache_buffer()
    2555 
    2556 
    2557 
    2558 /////////////////////////////////////////////////////////////////////////////
    2559 /////////////////////////////////////////////////////////////////////////////
    2560 //             Extern functions                                               
    2561 /////////////////////////////////////////////////////////////////////////////
    2562 /////////////////////////////////////////////////////////////////////////////
    2563 
    2564 
    2565 /////////////////////////////////////////////////////////////////////////////
    2566 // This function initializes the FAT structures.
    2567 // - The Fat-Descriptor is initialized in both boot and kernel modes.
    2568 // - The dynamically allocated structures (the Inode-Tre, the Fat_Cache,
    2569 //   and the File-Cache for the root directory) are only allocated
    2570 //   and initialized if the "kernel_mode" argument is set.
    2571 /////////////////////////////////////////////////////////////////////////////
    2572 // Implementation note:
    2573 // This function is called twice, by the boot-loader, and by the kernel_init.
    2574 // It does not use dynamic memory allocation from the distributed heap.
    2575 // It use informations found in the boot sector and FS-INFO sector.
    2576 // that are loaded in the Fat-Descriptor temporary block_buffer.
    2577 /////////////////////////////////////////////////////////////////////////////
    2578 // Returns GIET_FAT32_OK on success.
    2579 // Returns a negative value on error:
    2580 //   GIET_FAT32_IO_ERROR,
    2581 //   GIET_FAT32_INVALID_BOOT_SECTOR
    2582 /////////////////////////////////////////////////////////////////////////////
     2306_printf("\n[DEBUG FAT] _fat_ioc_access(): enters at cycle %d\n"
     2307        "  to_mem = %d / vaddr = %x / paddr = %l / sectors = %d / lba = %x\n",
     2308        _get_proctime(), to_mem, buf_vaddr, buf_paddr, count, lba );
     2309#endif
     2310
     2311
     2312#if GIET_NO_HARD_CC     // L1 cache inval (virtual addresses)
     2313    if ( to_mem ) _dcache_buf_invalidate( buf_vaddr, count<<9 );
     2314#endif
     2315
     2316
     2317#if   ( USE_IOC_BDV )   // call the proper driver
     2318    return( _bdv_access( use_irq , to_mem , lba , buf_paddr , count ) );
     2319#elif ( USE_IOC_HBA )
     2320    return( _hba_access( use_irq , to_mem , lba , buf_paddr , count ) );
     2321#elif ( USE_IOC_SDC )
     2322    return( _sdc_access( use_irq , to_mem , lba , buf_paddr , count ) );
     2323#elif ( USE_IOC_SPI )
     2324    return( _spi_access( use_irq , to_mem , lba , buf_paddr , count ) );
     2325#elif ( USE_IOC_RDK )
     2326    return( _rdk_access( use_irq , to_mem , lba , buf_paddr , count ) );
     2327#else
     2328    _printf("\n[FAT ERROR] _fat_ioc_access(): no IOC driver\n");
     2329    _exit();
     2330#endif
     2331
     2332}  // end _fat_ioc_access()
     2333
     2334
     2335
     2336/////////////////////////////////////////
    25832337int _fat_init( unsigned int kernel_mode ) 
    25842338{
     
    26132367{
    26142368    _printf("\n[DEBUG FAT] _fat_init(): Boot sector loaded\n");
    2615     _display_one_block( _fat.block_buffer, "block device", _fat.block_buffer_lba );
    26162369}
    26172370#endif
     
    26562409    _fat.initialized         = FAT_INITIALIZED;
    26572410
    2658     // load FS_INFO sector into FAT buffer
    2659     if ( _fat_ioc_access( 0,                                // no descheduling
    2660                           1,                                // read
    2661                           _fat.fs_info_lba,                 // lba
    2662                           (unsigned int)_fat.block_buffer,
    2663                           1 ) )                             // one block
    2664     {
    2665         _printf("\n[FAT ERROR] _fat_init(): cannot load FS_INFO Sector\n");
    2666         return GIET_FAT32_IO_ERROR;
    2667     }
    2668 
    2669     _fat.block_buffer_lba = _fat.fs_info_lba;
    2670 
    2671 #if GIET_DEBUG_FAT
    2672 if ( _get_proctime() > GIET_DEBUG_FAT )
    2673 {
    2674     _printf("\n[DEBUG FAT] _fat_init(): FS-INFO sector loaded\n");
    2675     _display_one_block( _fat.block_buffer, "block device", _fat.block_buffer_lba );
    2676 }
    2677 #endif
    2678 
    2679     // initialise Fat-Descriptor from FS_INFO
    2680     _fat.free_clusters_number   = _read_entry( FS_FREE_CLUSTERS    , _fat.block_buffer, 1);
    2681     _fat.first_free_cluster     = _read_entry( FS_FREE_CLUSTER_HINT, _fat.block_buffer, 1);
    2682 
     2411    /////////////////////////////////////////////////////////////////////
    26832412    // This is done only when the _fat_init() is called in kernel mode
    26842413
    26852414    if ( kernel_mode )
    26862415    {
    2687         unsigned int i;
     2416        // initialise <free_clusters_number> and <first_free_cluster in FAT descriptor
     2417        if ( _set_fs_info() ) return GIET_FAT32_IO_ERROR;
    26882418
    26892419        // create Inode-Tree root
     
    27002430
    27012431        // initialize File Descriptor Array
     2432        unsigned int i;
    27022433        for( i = 0 ; i < GIET_OPEN_FILES_MAX ; i++ ) _fat.fd[i].allocated = 0;
    27032434
     
    27182449
    27192450
    2720 ///////////////////////////////////////////////////////////////////////////////
    2721 // This function implements the giet_fat_open() system call.
    2722 // The semantic is similar to the UNIX open() function, with some limitations:
    2723 // - only the O_CREAT, O_RDONLY, and O_TRUNC flags are supported.
    2724 // - the UNIX access rights are not supported.
    2725 // If the file does not exist in the specified directory, it is created when
    2726 // the O_CREAT flag is set.
    2727 // If the specified directory does not exist, an error is returned.
    2728 // It allocates a file descriptor to the calling task, for the file identified
    2729 // by the <pathname> argument. If several tasks try to open the same file,
    2730 // each task obtains a private file descriptor.
    2731 // A node name (file or directory) cannot be larger than 31 characters.
    2732 ///////////////////////////////////////////////////////////////////////////////
    2733 // Returns a file descriptor index on success.
    2734 // Returns a negative value on error:
    2735 //   GIET_FAT32_NOT_INITIALIZED,
    2736 //   GIET_FAT32_FILE_NOT_FOUND,
    2737 //   GIET_FAT32_NAME_TOO_LONG,
    2738 //   GIET_FAT32_IO_ERROR,
    2739 //   GIET_FAT32_TOO_MANY_OPEN_FILES
    2740 ///////////////////////////////////////////////////////////////////////////////
     2451////////////////////////////////////////////////////////////////////
    27412452int _fat_open( char*        pathname,     // absolute path from root
    27422453               unsigned int flags )       // O_CREAT and O_RDONLY
     
    27592470unsigned int p       = procid & ((1<<P_WIDTH)-1);
    27602471if ( _get_proctime() > GIET_DEBUG_FAT )
    2761 _printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] enters for path <%s> / "
    2762         " create = %d / read_only = %d\n",
    2763         x, y, p, pathname , create , read_only );
     2472_printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] enters for path <%s>\n"
     2473        " create = %d / read_only = %d / truncate = %d\n",
     2474        x, y, p, pathname , create , read_only , truncate );
    27642475#endif
    27652476
     
    27982509        return GIET_FAT32_NAME_TOO_LONG;
    27992510    }
    2800     else if ( (code == 1) && (create == 0) )   // inode not found
     2511    else if ( (code == 1) && (create == 0) )   // child inode not found
    28012512    {
    28022513        _spin_lock_release( &_fat.fat_lock );
     
    28072518        return GIET_FAT32_FILE_NOT_FOUND;
    28082519    }
    2809     else if ( (code == 1) && (create != 0) )   // inode not found => create
     2520    else if ( (code == 1) && (create != 0) )   // child inode not found => create
    28102521    {
    28112522        // set parent inode pointer
     
    28712582        }
    28722583
    2873         // update FS_INFO sector
    2874         if ( _update_fs_info() )
    2875         {
    2876             _spin_lock_release( &_fat.fat_lock );
    2877             _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    2878 
    2879             _printf("\n[FAT ERROR] _fat_open(): cannot update FS-INFO"
    2880                     " for file <%s>\n", pathname );
    2881             return GIET_FAT32_IO_ERROR;
    2882         }
    2883 
    28842584        // no need to truncate a new file
    28852585        truncate = 0;
     
    29102610#if GIET_DEBUG_FAT
    29112611if ( _get_proctime() > GIET_DEBUG_FAT )
    2912 _printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] found file <%s> on device : inode = %x\n",
    2913         x , y , p , pathname , child );
    2914 #endif
     2612{
     2613    _printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] found file <%s>\n"
     2614            " inode = %x / size = %x\n",
     2615            x , y , p , pathname , (unsigned int)child , child->size );
     2616
     2617    _display_clusters_list( child );
     2618}
     2619#endif
     2620
    29152621    }
    29162622
     
    29522658
    29532659        // release clusters allocated to file/dir in DATA region
    2954         if ( _clusters_release( child->cluster ) )
     2660        if ( _clusters_release( child ) )
    29552661        {
    29562662            _spin_lock_release( &_fat.fat_lock );
     
    29742680#if GIET_DEBUG_FAT
    29752681if ( _get_proctime() > GIET_DEBUG_FAT )
    2976 _printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] got fd = %d for <%s> / "
    2977         "size = %x / read_only = %d\n",
    2978         x , y , p , fd_id , pathname , read_only );
     2682_printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] get fd = %d for <%s>\n"
     2683        " inode = %x / offset = %x / read_only = %d / size = %x / cluster = %x\n",
     2684        x , y , p , fd_id , pathname ,
     2685        (unsigned int)_fat.fd[fd_id].inode,
     2686        _fat.fd[fd_id].seek,
     2687        _fat.fd[fd_id].read_only,
     2688        _fat.fd[fd_id].inode->size,
     2689        _fat.fd[fd_id].inode->cluster );
    29792690#endif
    29802691
     
    29892700
    29902701
    2991 /////////////////////////////////////////////////////////////////////////////////
    2992 // This function implements the "giet_fat_close()" system call.
    2993 // It decrements the inode reference count, and release the fd_id entry
    2994 // in the file descriptors array.
    2995 // If the reference count is zero, it writes all dirty clusters on block device,
    2996 // and releases the memory allocated to the File_Cache.
    2997 /////////////////////////////////////////////////////////////////////////////////
    2998 // Returns GIET_FAT32_OK on success.
    2999 // Returns a negative value on error:
    3000 //   GIET_FAT32_NOT_INITIALIZED,
    3001 //   GIET_FAT32_INVALID_FD,
    3002 //   GIET_FAT32_NOT_OPEN,
    3003 //   GIET_FAT32_IO_ERROR
    3004 /////////////////////////////////////////////////////////////////////////////////
     2702////////////////////////////////////
    30052703int _fat_close( unsigned int fd_id )
    30062704{
     
    30962794#endif
    30972795
    3098     }
     2796    }  // end if (refcount == 0)
     2797
    30992798
    31002799    // release fd_id entry in file descriptor array
     
    31112810
    31122811
    3113 /////////////////////////////////////////////////////////////////////////////////
    3114 // This function implements the giet_fat_file_info() system call.
    3115 // It returns the size, the current offset and the directory info for a file
    3116 // identified by the "fd_id" argument.
    3117 /////////////////////////////////////////////////////////////////////////////////
    3118 // Returns GIET_FAT32_OK on success.
    3119 // Returns a negative value on error:
    3120 //   GIET_FAT32_NOT_INITIALIZED,
    3121 //   GIET_FAT32_INVALID_FD,
    3122 //   GIET_FAT32_NOT_OPEN
    3123 /////////////////////////////////////////////////////////////////////////////////
     2812////////////////////////////////////////////
    31242813int _fat_file_info( unsigned int     fd_id,
    31252814                    fat_file_info_t* info )
     
    31532842
    31542843
    3155 ///////////////////////////////////////////////////////////////////////////////////
    3156 // The following function implements the "giet_fat_read()" and "giet_fat_pread')"
    3157 // system calls, but can also be used by the kernel in physical addressing mode.
    3158 // It transfers <count> bytes from the File_Cache associated to the file
    3159 // identified by <fd_id>, to the destination buffer defined by <vaddr>.
    3160 // It uses the current file offset defined in the file descriptor.
    3161 // If the <extend> 16 MSB bits are non zero, it uses physical addressing:
    3162 // the physical  address is computed as extend[15:0] | vaddr[31:0]
    3163 // In case of miss in the File_Cache, it loads all involved clusters into cache.
    3164 ///////////////////////////////////////////////////////////////////////////////////
    3165 // Returns the number of bytes actually transfered on success.
    3166 // Returns a negative value on error:
    3167 //   GIET_FAT32_NOT_INITIALIZED,
    3168 //   GIET_FAT32_INVALID_FD,
    3169 //   GIET_FAT32_NOT_OPEN,
    3170 //   GIET_FAT32_IO_ERROR
    3171 /////////////////////////////////////////////////////////////////////////////////
     2844/////////////////////////////////////////////////////////////////////
    31722845int _fat_read( unsigned int fd_id,          // file descriptor index
    31732846               unsigned int vaddr,          // destination buffer vaddr
     
    33463019
    33473020
    3348 /////////////////////////////////////////////////////////////////////////////////
    3349 // The following function implements the "giet_fat_write()" system call,
    3350 // but can also be used by the kernel in physical addressing mode.
    3351 // It transfers <count> bytes to the File_Cache associated to the file
    3352 // identified by <fd_id>, from the source buffer defined by <vaddr>.
    3353 // It uses the current file offset defined in the file descriptor.
    3354 // If required by the <modes> argument, the physical  address is computed
    3355 // as extend[15:0] | vaddr[31:0]
    3356 // It increases the file size and allocate new clusters if (count + offset)
    3357 // is larger than the current file size. Then it loads and updates all
    3358 // involved clusters in the cache.
    3359 /////////////////////////////////////////////////////////////////////////////////
    3360 // Returns number of bytes actually written on success.
    3361 // Returns a negative value on error:
    3362 //   GIET_FAT32_NOT_INITIALIZED,
    3363 //   GIET_FAT32_INVALID_FD,
    3364 //   GIET_FAT32_NOT_OPEN,
    3365 //   GIET_FAT32_READ_ONLY,
    3366 //   GIET_FAT32_NO_FREE_SPACE,
    3367 //   GIET_FAT32_IO_ERROR
    3368 /////////////////////////////////////////////////////////////////////////////////
     3021////////////////////////////////////////////////////////////////
    33693022int _fat_write( unsigned int fd_id,    // file descriptor index
    33703023                unsigned int vaddr,    // source buffer vaddr
     
    34363089#endif
    34373090
    3438     // chek if file size must be incremented
     3091    // check if file size must be incremented
    34393092    // and allocate new clusters from FAT if required
    34403093    unsigned int old_size = inode->size;
     
    36073260
    36083261
    3609 /////////////////////////////////////////////////////////////////////////////////
    3610 // The following function implements the "giet_fat_lseek()" system call.
    3611 // It repositions the seek in the file descriptor "fd_id", according to
    3612 // the "seek" and "whence" arguments.
    3613 // It has the same semantic as the UNIX lseek() function.
    3614 // Accepted values for whence are SEEK_SET / SEEK_CUR / SEEK_END.
    3615 /////////////////////////////////////////////////////////////////////////////////
    3616 // Returns new seek value (in bytes) on success.
    3617 // Returns a negative value on error:
    3618 //   GIET_FAT32_NOT_INITIALIZED,
    3619 //   GIET_FAT32_INVALID_FD,
    3620 //   GIET_FAT32_NOT_OPEN,
    3621 //   GIET_FAT32_INVALID_ARG
    3622 /////////////////////////////////////////////////////////////////////////////////
     3262///////////////////////////////////
    36233263int _fat_lseek( unsigned int fd_id,
    36243264                unsigned int seek,
     
    36933333
    36943334
    3695 /////////////////////////////////////////////////////////////////////////////////
    3696 // The following function implements the giet_fat_remove() system call.
    3697 // It deletes the file/directory identified by the "pathname" argument from
    3698 // the file system, if the remove condition is fulfilled (directory empty,
    3699 // or file not referenced).
    3700 // All clusters allocated in the block device DATA region are released.
    3701 // The FAT region is updated on the block device.
    3702 // The Inode-Tree is updated.
    3703 // The associated File_Cache is released.
    3704 // The Fat_Cache is updated.
    3705 /////////////////////////////////////////////////////////////////////////////////
    3706 // Returns GIET_FAT32_OK on success.
    3707 // Returns a negative value on error:
    3708 //   GIET_FAT32_NOT_INITIALIZED,
    3709 //   GIET_FAT32_FILE_NOT_FOUND,
    3710 //   GIET_FAT32_NAME_TOO_LONG,
    3711 //   GIET_FAT32_IS_DIRECTORY,
    3712 //   GIET_FAT32_NOT_A_DIRECTORY,
    3713 //   GIET_FAT32_IS_OPEN,
    3714 //   GIET_FAT32_IO_ERROR,
    3715 //   GIET_FAT32_DIRECTORY_NOT_EMPTY
    3716 /////////////////////////////////////////////////////////////////////////////////
     3335///////////////////////////////////////
    37173336int _fat_remove( char*        pathname,
    37183337                 unsigned int should_be_dir )
     
    38683487
    38693488
    3870 /////////////////////////////////////////////////////////////////////////////////
    3871 // This function implements the giet_fat_rename() system call.
    3872 // It moves an existing file or directory from one node (defined by "old_path"
    3873 // argument) to another node (defined by "new_path" argument) in the FS tree.
    3874 // The type (file/directory) and content are not modified.
    3875 // If the new_path file/dir exist, it is removed from the file system, but only 
    3876 // if the remove condition is respected (directory empty / file not referenced).
    3877 // The removed entry is only removed after the new entry is actually created.
    3878 /////////////////////////////////////////////////////////////////////////////////
    3879 // Returns GIET_FAT32_OK on success.
    3880 // Returns a negative value on error:
    3881 //   GIET_FAT32_NOT_INITIALIZED,
    3882 //   GIET_FAT32_FILE_NOT_FOUND,
    3883 //   GIET_FAT32_MOVE_INTO_SUBDIR,
    3884 //   GIET_FAT32_IO_ERROR,
    3885 //   GIET_FAT32_DIRECTORY_NOT_EMPTY,
    3886 //   GIET_FAT32_IS_OPEN
    3887 /////////////////////////////////////////////////////////////////////////////////
     3489/////////////////////////////////
    38883490int _fat_rename( char*  old_path,
    38893491                 char*  new_path )
     
    41333735
    41343736
    4135 /////////////////////////////////////////////////////////////////////////////////
    4136 // The following function implements the giet_fat_mkdir() system call.
    4137 // It creates in file system the directory specified by the "pathname" argument.
    4138 // The Inode-Tree is updated.
    4139 // One cluster is allocated to the new directory.
    4140 // The associated File-Cache is created.
    4141 // The FAT region on block device is updated.
    4142 // The DATA region on block device is updated.
    4143 /////////////////////////////////////////////////////////////////////////////////
    4144 // Returns GIET_FAT32_OK on success.
    4145 // Returns a negative value on error:
    4146 //   GIET_FAT32_NOT_INITIALIZED,
    4147 //   GIET_FAT32_FILE_NOT_FOUND,
    4148 //   GIET_FAT32_NAME_TOO_LONG,
    4149 //   GIET_FAT32_FILE_EXISTS,
    4150 //   GIET_FAT32_NO_FREE_SPACE,
    4151 //   GIET_FAT32_IO_ERROR
    4152 /////////////////////////////////////////////////////////////////////////////////
     3737////////////////////////////////
    41533738int _fat_mkdir( char* pathname )
    41543739{
     
    42403825                                     1,           // it's a directory
    42413826                                     cluster, 
    4242                                      4096,        // one buffer for a directory
     3827                                     0,           // size = 0 for a directory
    42433828                                     0,           // count
    42443829                                     0,           // dentry set by _add_dir_entry()
     
    42933878        }
    42943879
    4295         // update FS_INFO sector
    4296         if ( _update_fs_info() )
    4297         {
    4298             _spin_lock_release( &_fat.fat_lock );
    4299             _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    4300 
    4301             _printf("\n[FAT ERROR] _fat_mkdir(): cannot update FS-INFO"
    4302                     " for directory <%s>\n", pathname );
    4303             return GIET_FAT32_IO_ERROR;
    4304         }
    4305 
    43063880        // update DATA region on block device for the new directory
    43073881        if ( _update_device_from_cache( child->levels,   
     
    43283902
    43293903
    4330 ///////////////////////////////////////////////////////////////////////////////
    4331 // This function implements the giet_fat_opendir() system call.
    4332 // The semantic is similar to the UNIX opendir() function.
    4333 // If the specified directory does not exist, an error is returned.
    4334 // It allocates a file descriptor to the calling task, for the directory
    4335 // identified by "pathname". If several tasks try to open the same directory,
    4336 // each task obtains a private file descriptor.
    4337 // A node name cannot be larger than 31 characters.
    4338 ///////////////////////////////////////////////////////////////////////////////
    4339 // Returns a file descriptor for the directory index on success
    4340 // Returns a negative value on error:
    4341 //   GIET_FAT32_NOT_INITIALIZED,
    4342 //   GIET_FAT32_NAME_TOO_LONG,
    4343 //   GIET_FAT32_FILE_NOT_FOUND,
    4344 //   GIET_FAT32_TOO_MANY_OPEN_FILES,
    4345 //   GIET_FAT32_NOT_A_DIRECTORY
    4346 ///////////////////////////////////////////////////////////////////////////////
     3904/////////////////////////////////////////
    43473905extern int _fat_opendir( char* pathname )
    43483906{
     
    43653923
    43663924
    4367 /////////////////////////////////////////////////////////////////////////////////
    4368 // This function implements the "giet_fat_closedir()" system call.
    4369 // Same behavior as _fat_close(), no check for directory.
    4370 /////////////////////////////////////////////////////////////////////////////////
    4371 // Returns GIET_FAT32_OK on success.
    4372 // Returns a negative value on error:
    4373 //   GIET_FAT32_NOT_INITIALIZED,
    4374 //   GIET_FAT32_INVALID_FD,
    4375 //   GIET_FAT32_NOT_OPEN,
    4376 //   GIET_FAT32_IO_ERROR
    4377 /////////////////////////////////////////////////////////////////////////////////
     3925//////////////////////////////////////////////
    43783926extern int _fat_closedir( unsigned int fd_id )
    43793927{
     
    43843932
    43853933
    4386 /////////////////////////////////////////////////////////////////////////////////
    4387 // This function implements the "giet_fat_readdir()" system call.
    4388 // It reads one directory entry from the file descriptor opened by
    4389 // "giet_fat_opendir()" and writes its info to the "entry" argument.
    4390 // This includes the cluster, size, is_dir and name info for each entry.
    4391 /////////////////////////////////////////////////////////////////////////////////
    4392 // Returns GIET_FAT32_OK on success.
    4393 // Returns a negative value on error:
    4394 //   GIET_FAT32_NOT_INITIALIZED,
    4395 //   GIET_FAT32_INVALID_FD,
    4396 //   GIET_FAT32_NOT_OPEN,
    4397 //   GIET_FAT32_NOT_A_DIRECTORY,
    4398 //   GIET_FAT32_IO_ERROR,
    4399 //   GIET_FAT32_NO_MORE_ENTRIES
    4400 /////////////////////////////////////////////////////////////////////////////////
     3934/////////////////////////////////////////////
    44013935extern int _fat_readdir( unsigned int  fd_id,
    44023936                         fat_dirent_t* entry )
     
    45064040
    45074041
    4508 ///////////////////////////////////////////////////////////////////////////////
    4509 // This function loads a file identified by the "pathname" argument into the
    4510 // memory buffer defined by the "buffer_vbase" and "buffer_size" arguments.
    4511 // It is intended to be called by the boot-loader, as it does not use the
    4512 // dynamically allocated FAT structures (Inode-Tree, Fat_Cache or File-Cache,
    4513 // File-Descriptor-Array).
    4514 // It uses only the 512 bytes buffer defined in the FAT descriptor.
    4515 ///////////////////////////////////////////////////////////////////////////////
    4516 // Returns GIET_FAT32_OK on success.
    4517 // Returns negative value on error:
    4518 //   GIET_FAT32_NOT_INITIALIZED
    4519 //   GIET_FAT32_FILE_NOT_FOUND
    4520 //   GIET_FAT32_BUFFER_TOO_SMALL
    4521 //   GIET_FAT32_IO_ERROR
    4522 ///////////////////////////////////////////////////////////////////////////////
     4042///////////////////////////////////////////////
    45234043int _fat_load_no_cache( char*        pathname,
    45244044                        unsigned int buffer_vbase, 
     
    46134133
    46144134
    4615 //////////////////////////////////////////////////////////////////////////////////
    4616 // The following function returns in the <desc> argument a pointer on a buffer
    4617 // descriptor contained in a File_Cache.
    4618 // The searched buffer is idenfified by the <inode> and <cluster_id> arguments.
    4619 // The <cluster_id> argument is the buffer index in the file.
    4620 // The <writable> argument define the behaviour in case of miss in File-Cache:
    4621 // - if [all clusters (from 0 to cluster_id) are already allocated in FAT]
    4622 //   we scan the FAT to find the cluster index on device, and we load the
    4623 //   missing cluster in the File-Cache, marked as dirty if writable is set.
    4624 // - else if [writable is not set]  we return an error.
    4625 // - else [writable set, but all clusters (from 0 to cluster_id) not allocated]
    4626 //   we allocate in FAT all required clusters, we update the size in the inode
    4627 //   and dentry, and we allocate a buffer descriptor for the missing cluster,
    4628 //   marked as dirty.
    4629 // This function can be called by the FAT functions, and by _sys_fat_mmap().
    4630 // It does not take the FAT lock, that must be taken by the caller.
    4631 //////////////////////////////////////////////////////////////////////////////////
    4632 // It returns 0 on success.
    4633 // It returns 1 on error.
    4634 //////////////////////////////////////////////////////////////////////////////////
     4135//////////////////////////////////////////////////////////
     4136int _get_fat_cache_buffer( unsigned int        cluster_id,
     4137                           fat_cache_desc_t**  desc )
     4138{
     4139    // get cache pointer and number of levels
     4140    fat_cache_node_t*   node   = _fat.fat_cache_root;   
     4141    unsigned int        level  = _fat.fat_cache_levels; 
     4142
     4143    if ( _get_levels_from_size( (cluster_id + 1) * 4096 ) > level )
     4144    {
     4145        _printf("\n[FAT ERROR] in _get_fat_cache_buffer() : "
     4146                "cluster_id %d too large", cluster_id );
     4147        return GIET_FAT32_IO_ERROR;
     4148    }
     4149
     4150    // search the 64-tree cache from top to bottom
     4151    while ( level )
     4152    {
     4153        // compute child index at each level
     4154        unsigned int index = (cluster_id >> (6*(level-1))) & 0x3F;
     4155
     4156        if ( level == 1 )        // last level => children are buffer descriptors
     4157        {
     4158            fat_cache_desc_t*   pdesc = (fat_cache_desc_t*)node->children[index];
     4159
     4160            if ( pdesc == NULL )      // miss
     4161            {
     4162
     4163#if GIET_DEBUG_FAT
     4164if ( _get_proctime() > GIET_DEBUG_FAT )
     4165_printf("\n[DEBUG FAT] _get_fat_cache_buffer(): miss for cluster_id %d\n", cluster_id );
     4166#endif
     4167                // compute missing cluster lba
     4168                unsigned int lba = _fat.fat_lba + (cluster_id << 3);
     4169
     4170                // allocate a 4 Kbytes buffer and a buffer descriptor
     4171                void* buf      = _malloc( 4096 );
     4172                pdesc          = _malloc( sizeof(fat_cache_desc_t) );
     4173                pdesc->lba     = lba;
     4174                pdesc->buffer  = buf;
     4175                pdesc->dirty   = 0;
     4176                node->children[index] = pdesc;
     4177
     4178                // load cluster from device
     4179                if ( _fat_ioc_access( 1,         // descheduling
     4180                                      1,         // to memory
     4181                                      lba,
     4182                                      (unsigned int)buf,
     4183                                      8 ) )
     4184                {
     4185                    _free( buf );
     4186                    _free( pdesc );
     4187                    _printf("\n[FAT ERROR] in _get_fat_cache_buffer() : "
     4188                            ": cannot access block device for lba = %x\n", lba );
     4189                    return GIET_FAT32_IO_ERROR;
     4190                }
     4191
     4192            }
     4193
     4194            // return pdesc pointer
     4195            *desc = pdesc;
     4196
     4197            // prepare next iteration
     4198            level--;
     4199        }
     4200        else                      // not last level => children are 64-tree nodes
     4201        {
     4202            fat_cache_node_t* child = (fat_cache_node_t*)node->children[index];
     4203            if ( child == NULL )  // miss
     4204            {
     4205                // allocate a cache node if miss
     4206                child = _allocate_one_cache_node( NULL );
     4207                node->children[index] = child;   
     4208            }
     4209
     4210            // prepare next iteration
     4211            node = child;
     4212            level--;
     4213        }
     4214    } // end while
     4215
     4216    return 0;
     4217}  // end _get_fat_cache_buffer()
     4218
     4219
     4220
     4221
     4222//////////////////////////////////////////////////////
    46354223int _get_file_cache_buffer( fat_inode_t*        inode,
    46364224                            unsigned int        cluster_id,
     
    46394227{
    46404228
    4641 #if (GIET_DEBUG_FAT & 1)
    4642 if ( _get_proctime() > GIET_DEBUG_FAT )
    4643 _printf("\n[DEBUG FAT] _get_file_cache_buffer(): enters in File-Cache <%s>"
     4229#if GIET_DEBUG_FAT
     4230if ( _get_proctime() > GIET_DEBUG_FAT )
     4231_printf("\n[DEBUG FAT] _get_file_cache_buffer() : enters in File-Cache <%s>"
    46444232        " for cluster_id = %d\n size = %x / cache = %x / desc[%d] = %x\n",
    46454233        inode->name , cluster_id ,
     
    46664254    {
    46674255
    4668 #if (GIET_DEBUG_FAT & 1)
     4256#if GIET_DEBUG_FAT
    46694257if ( _get_proctime() > GIET_DEBUG_FAT )
    46704258_printf("\n[DEBUG FAT] _get_file_cache_buffer() : add a File-Cache level\n" );
     
    46754263    }
    46764264
    4677     // get File-Cache
    4678     fat_cache_node_t*   node  = inode->cache; 
    4679     unsigned int        level = inode->levels;
    4680 
     4265    // get inode type, size, and File-Cache
     4266    unsigned int       size   = inode->size;
     4267    unsigned int       is_dir = inode->is_dir;
     4268    fat_cache_node_t*  node   = inode->cache; 
     4269    unsigned int       level  = inode->levels;
    46814270
    46824271    // search the 64-tree cache from top to bottom
     
    46884277        if ( level == 1 )        // last level => children are buffer descriptors
    46894278        {
    4690             fat_cache_desc_t*   pdesc = (fat_cache_desc_t*)node->children[index];
    4691             unsigned int        current = inode->cluster;
     4279            fat_cache_desc_t*   pdesc   = (fat_cache_desc_t*)node->children[index];
    46924280            unsigned int        next    = 0;
    46934281            unsigned int        prev    = 0;
     4282            unsigned int        current;
    46944283            unsigned int        cid;
    46954284            unsigned int        lba;
    4696 
    4697             if ( pdesc == NULL )      // miss in File-Cache
     4285            unsigned int        cluster_allocated;
     4286
     4287            // File-Cache miss handling:
     4288            // In case of miss, the missing buffer is allocated,
     4289            // and the missing cluster is loaded from block device.
     4290            // A new cluster is allocated from FAT if required, when
     4291            // the writable argument is set.
     4292            if ( pdesc == NULL )   
    46984293            {
    46994294
    4700 #if (GIET_DEBUG_FAT & 1)
    4701 if ( _get_proctime() > GIET_DEBUG_FAT )
    4702 _printf("\n[DEBUG FAT] _get_file_cache_buffer() : miss in cache <%s> for cluster_id = %d\n"
    4703         " cluster = %x / size = %x / cache = %x / desc[%d] = %x\n",
    4704         inode->name , cluster_id , inode-> cluster , inode->size ,
     4295#if GIET_DEBUG_FAT
     4296if ( _get_proctime() > GIET_DEBUG_FAT )
     4297_printf("\n[DEBUG FAT] _get_file_cache_buffer() : miss in File-Cache <%s> "
     4298        " for cluster_id = %d\n"
     4299        " cluster = %x / size = %x / is_dir = %d / cache = %x / desc[%d] = %x\n",
     4300        inode->name , cluster_id , inode->cluster , inode->size , inode->is_dir ,
    47054301        (unsigned int)inode->cache , cluster_id ,
    47064302        (unsigned int)inode->cache->children[cluster_id] );
    47074303#endif
    4708                 if ( inode->size > (cluster_id<<12) )  // all clusters allocated in FAT
     4304                // compute cluster_allocated condition, depending on file / dir type
     4305                if ( is_dir )  cluster_allocated = ( cluster_id < is_dir );
     4306                else           cluster_allocated = ( (cluster_id<<12) < size );
     4307
     4308                if ( cluster_allocated )  // cluster already allocated => allocate buffer
    47094309                {
    47104310                    // scan the FAT to find the cluster index for cluster_id
     4311                    current = inode->cluster;
    47114312                    for ( cid = 0 ; cid < cluster_id ; cid++ )
    47124313                    {
     
    47454346                    }
    47464347                }
    4747                 else if ( writable == 0 )
     4348                else if ( writable == 0 ) // not writable and cluster not allocated in FAT
    47484349                {
    47494350                    _printf("\n[FAT ERROR] in _get_file_cache_buffer() : "
     
    47534354                    return GIET_FAT32_IO_ERROR;
    47544355                }
    4755                 else   // writable and all clusters NOT allocated in FAT
     4356                else   // writable and cluster NOT allocated in FAT => allocate cluster & buffer
    47564357                {
    47574358                    // scan the FAT to allocate all required clusters
     4359                    current = inode->cluster;
    47584360                    for ( cid = 0 ; cid <= cluster_id ; cid++ )
    47594361                    {
     
    47824384                    }
    47834385
    4784                     // update size in inode and directory entry
    4785                     inode->size = (cluster_id + 1)<<12;
     4386                    // update size or is_dir attributes in inode
     4387                    if ( is_dir )    inode->is_dir = cluster_id;
     4388                    else             inode->size   = (cluster_id + 1)<<12;
     4389
     4390                    // update directory entry from inode
    47864391                    _update_dir_entry( inode );
    47874392
     
    48004405                    node->children[index] = pdesc;
    48014406                }
    4802             }
     4407            }  // end File-Cache miss handling
    48034408
    48044409            // return pdesc pointer
    48054410            *desc = pdesc;
    48064411
    4807 #if (GIET_DEBUG_FAT & 1)
    4808 if ( _get_proctime() > GIET_DEBUG_FAT )
    4809 _printf("\n[DEBUG FAT] _fat_buffer_from_cache(): found buffer = %x "
     4412#if GIET_DEBUG_FAT
     4413if ( _get_proctime() > GIET_DEBUG_FAT )
     4414_printf("\n[DEBUG FAT] _get_file_cache_buffer(): found buffer = %x "
    48104415        " in file <%s> for cluster_id %d\n",
    48114416        (unsigned int)pdesc->buffer , inode->name , cluster_id );
     
    48344439}  // end _get_file_cache_buffer()
    48354440
     4441
     4442
     4443
     4444
     4445
    48364446// Local Variables:
    48374447// tab-width: 4
  • soft/giet_vm/giet_fat32/fat32.h

    r772 r773  
    144144
    145145/********************************************************************************
    146   This struct defines a cluster descriptor, that is a leaf cell in a 64-tree.
    147   Each cluster descriptor contains a pointer on a 4K bytes buffer, and the
     146  This struct defines a buffer descriptor, that is a leaf cell in a 64-tree.
     147  Each buffer descriptor contains a pointer on a 4K bytes buffer, and the
    148148  lba on block device.
    149149********************************************************************************/
     
    225225*******************************************************************************/
    226226
     227extern int _fat_ioc_access( unsigned int use_irq,               // descheduling
     228                            unsigned int to_mem,                // read / write
     229                            unsigned int lba,                   // first sector
     230                            unsigned int buf_vaddr,             // memory buffer vaddr
     231                            unsigned int count );               // number of sectors
     232
    227233extern int _fat_init();         
    228234
     
    271277                               unsigned int buffer_size );      // buffer size
    272278
     279extern int _get_fat_cache_buffer( unsigned int    cluster_id,   // cluster index in FAT
     280                                  fat_cache_desc_t**  desc );   // buffer descriptor
     281
    273282extern int _get_file_cache_buffer( fat_inode_t*    inode,       // inode pointer
    274                                    unsigned int    cluster_id,  // cluster index
    275                                    unsigned int     writable,   // writable mmap
     283                                   unsigned int    cluster_id,  // cluster index in file
     284                                   unsigned int    writable,    // behaviour if miss
    276285                                   fat_cache_desc_t** desc );   // buffer descriptor
    277286#endif
  • soft/giet_vm/giet_fat32/fat32_shared.h

    r772 r773  
    4949
    5050/********************************************************************************
     51  _fat_dump_block() types.
     52********************************************************************************/
     53
     54#define DUMP_BS                 0
     55#define DUMP_FS                 1
     56#define DUMP_FAT                2
     57#define DUMP_FILE               3
     58#define DUMP_DIR                4
     59
     60/********************************************************************************
    5161  Error codes map.
    5262********************************************************************************/
Note: See TracChangeset for help on using the changeset viewer.