Ignore:
Timestamp:
Apr 29, 2019, 7:25:09 PM (5 years ago)
Author:
alain
Message:

This version has been tested on the sort multithreaded application
for TSAR_IOB architectures ranging from 1 to 8 clusters.
It fixes three bigs bugs:
1) the dev_ioc device API has been modified: the dev_ioc_sync_read()
and dev_ioc_sync_write() function use now extended pointers on the
kernel buffer to access a mapper stored in any cluster.
2) the hal_uspace API has been modified: the hal_copy_to_uspace()
and hal_copy_from_uspace() functions use now a (cxy,ptr) couple
to identify the target buffer (equivalent to an extended pointer.
3) an implementation bug has been fixed in the assembly code contained
in the hal_copy_to_uspace() and hal_copy_from_uspace() functions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/fs/fatfs.c

    r625 r626  
    3737#include <fatfs.h>
    3838
     39#define LITTLE_ENDIAN  1
    3940
    4041//////////////////////////////////////////////////////////////////////////////////////////
     
    7273
    7374//////////////////////////////////////////////////////////////////////////////////////////
    74 // This function return an integer record value (one, two, or four bytes)
    75 // from a memory buffer, taking into account endianness.
    76 //////////////////////////////////////////////////////////////////////////////////////////
    77 // @ offset        : first byte of record in buffer.
    78 // @ size          : record length in bytes (1/2/4).
    79 // @ buffer        : pointer on buffer base.
    80 // @ little endian : the most significant byte has the highest address when true.
     75// This function return an integer record value (one, two, or four bytes) from a local
     76// array of bytes, taking into account the global LITTLE_ENDIAN parameter:
     77// if LITTLE_ENDIAN is true, the most significant byte has the highest address.
     78//////////////////////////////////////////////////////////////////////////////////////////
     79// @ offset        : first byte in array.
     80// @ nbytes        : record length in bytes (1/2/4).
     81// @ buffer        : local pointer on byte array.
    8182// @ return the integer value in a 32 bits word.
    8283//////////////////////////////////////////////////////////////////////////////////////////
    8384static uint32_t fatfs_get_record( uint32_t    offset,
    84                                   uint32_t    size,
    85                                   uint8_t   * buffer,
    86                                   uint32_t    little_endian )
    87 {
    88     uint32_t n;
    89     uint32_t res  = 0;
    90 
    91     if ( little_endian )
    92     {
    93         for( n = size ; n > 0 ; n-- ) res = (res<<8) | buffer[offset+n-1];
    94     }
    95     else // big_endian
    96     {
    97         for( n = 0 ; n < size ; n++ ) res = (res<<8) | buffer[offset+n];
     85                                  uint32_t    nbytes,
     86                                  uint8_t   * buffer )
     87{
     88    uint32_t i;
     89    uint32_t res = 0;
     90
     91    if ( LITTLE_ENDIAN )
     92    {
     93        for( i = nbytes ; i > 0 ; i-- ) res = (res<<8) | buffer[offset+i-1];
     94    }
     95    else
     96    {
     97        for( i = 0 ; i < nbytes ; i++ ) res = (res<<8) | buffer[offset+i];
    9898    }
    9999    return res;
     
    102102
    103103//////////////////////////////////////////////////////////////////////////////////////////
    104 // This function writes one, two, or four bytes from a 32 bits integer to a memory buffer,
    105 // taking into account endianness.
    106 //////////////////////////////////////////////////////////////////////////////////////////
    107 // @ offset        : first byte of record in buffer.
    108 // @ size          : record length in bytes (1/2/4).
    109 // @ buffer        : pointer on buffer base.
    110 // @ little endian : the most significant byte has the highest address when true.
     104// This function return an integer record value (one, two, or four bytes) from a remote
     105// array of bytes, taking into account the global LITTLE_ENDIAN parameter:
     106// if LITTLE_ENDIAN is true, the most significant byte has the highest address.
     107//////////////////////////////////////////////////////////////////////////////////////////
     108// @ offset        : first byte in array.
     109// @ nbytes        : record length in bytes (1/2/4).
     110// @ buffer_xp     : extended pointer on byte array.
    111111// @ return the integer value in a 32 bits word.
    112112//////////////////////////////////////////////////////////////////////////////////////////
     113static uint32_t fatfs_get_remote_record( uint32_t   offset,
     114                                         uint32_t   nbytes,
     115                                         xptr_t     buffer_xp )
     116{
     117    uint32_t i;
     118    uint32_t res = 0;
     119
     120    if ( LITTLE_ENDIAN )
     121    {
     122        for( i = nbytes ; i > 0 ; i-- )
     123        {
     124            res = (res<<8) | hal_remote_lb( buffer_xp+offset+i-1 );
     125        }
     126    }
     127    else
     128    {
     129        for( i = 0 ; i < nbytes ; i++ )
     130        {
     131            res = (res<<8) | hal_remote_lb( buffer_xp+offset+i );
     132        }
     133    }
     134    return res;
     135
     136}  // end fatfs_get_remote_record()
     137
     138//////////////////////////////////////////////////////////////////////////////////////////
     139// This function writes one, two, or four bytes from a 32 bits integer to a local
     140// array of bytes, taking into account the global LITTLE_ENDIAN parameter:
     141// if LITTLE_ENDIAN is true, the most significant byte has the highest address.
     142//////////////////////////////////////////////////////////////////////////////////////////
     143// @ offset        : first byte in array.
     144// @ nbytes        : record length in bytes (1/2/4).
     145// @ buffer        : local pointer on byte array.
     146// @ value         : 32 bits integer value.
     147//////////////////////////////////////////////////////////////////////////////////////////
    113148static void fatfs_set_record( uint32_t    offset,
    114                               uint32_t    size,
     149                              uint32_t    nbytes,
    115150                              uint8_t   * buffer,
    116                               uint32_t    little_endian,
    117151                              uint32_t    value )
    118152{
    119     uint32_t n;
    120 
    121     if ( little_endian )
    122     {
    123         for( n = size ; n > 0 ; n-- ) buffer[offset+n-1] = (uint8_t)(value>>((n-1)<<3));
    124     }
    125     else // big_endian
    126     {
    127         for( n = 0 ; n < size ; n++ ) buffer[offset+n] = (uint8_t)(value>>((size-1-n)<<3));
     153    uint32_t i;
     154
     155    if ( LITTLE_ENDIAN )
     156    {
     157        for( i = nbytes ; i > 0 ; i-- ) buffer[offset+i-1] = (uint8_t)(value>>((i-1)<<3));
     158    }
     159    else
     160    {
     161        for( i = 0 ; i < nbytes ; i++ ) buffer[offset+i] = (uint8_t)(value>>((nbytes-1-i)<<3));
     162    }
     163
     164}  // end fatfs_set_record()
     165
     166//////////////////////////////////////////////////////////////////////////////////////////
     167// This function writes one, two, or four bytes from a 32 bits integer to a remote
     168// array of bytes, taking into account the global LITTLE_ENDIAN parameter:
     169// if LITTLE_ENDIAN is true, the most significant byte has the highest address.
     170//////////////////////////////////////////////////////////////////////////////////////////
     171// @ offset        : first byte in array.
     172// @ nbytes        : record length in bytes (1/2/4).
     173// @ buffer_xp     : extended pointer on byte array.
     174// @ value         : 32 bits integer value.
     175//////////////////////////////////////////////////////////////////////////////////////////
     176static void fatfs_set_remote_record( uint32_t    offset,
     177                                     uint32_t    nbytes,
     178                                     xptr_t      buffer_xp,
     179                                     uint32_t    value )
     180{
     181    uint32_t i;
     182
     183    if ( LITTLE_ENDIAN )
     184    {
     185        for( i = nbytes ; i > 0 ; i-- )
     186        {
     187            hal_remote_sb( (buffer_xp+offset+i-1) , (uint8_t)(value>>((i-1)<<3)) );
     188        }
     189    }
     190    else
     191    {
     192        for( i = 0 ; i < nbytes ; i++ )
     193        {
     194            hal_remote_sb( (buffer_xp+offset+i) , (uint8_t)(value>>((nbytes-1-i)<<3)) );
     195        }
    128196    }
    129197
     
    374442
    375443//////////////////////////////////////////////////////////////////////////////////////////
     444// This static function is called by both the fatfs_free_clusters_increment(),
     445// and the fatfs_free_cluster_decrement() functions defined below.
     446// It synchronously updates the  "free_clusters" and "free_cluster_hint" variables
     447// in FS_INFO sector on the IOC device, each times these variables are modified.
     448//////////////////////////////////////////////////////////////////////////////////////////
     449// @ fatfs_ctx_xp      : extended pointer on fatfs context in FAT cluster.
     450// @ free_clusters     : new free_clusters value.
     451// @ free_cluster_hint : new free_cluster_hint value.
     452// @ return 0 if success, return -1 if the FS_INFO sector cannot be updated.
     453//////////////////////////////////////////////////////////////////////////////////////////
     454static error_t fatfs_free_clusters_update_ioc( xptr_t    fatfs_ctx_xp,
     455                                               uint32_t  free_clusters,
     456                                               uint32_t  free_cluster_hint )
     457{
     458    cxy_t         fat_cxy;             // FAT cluster identifier
     459    fatfs_ctx_t * fatfs_ctx_ptr;       // local pointer on fatfs context in FAT cluster
     460    uint8_t     * fs_info_buffer_ptr;  // local pointer on FS_INFO buffer in FAT cluster
     461    xptr_t        fs_info_buffer_xp;   // extended pointer on FS_INFO buffer in FAT cluster
     462    uint32_t      fs_info_lba;         // FS_INFO sector lba on IOC device
     463
     464    // get cluster and local pointer on FAT cluster context
     465    fat_cxy       = GET_CXY( fatfs_ctx_xp );
     466    fatfs_ctx_ptr = GET_PTR( fatfs_ctx_xp );
     467
     468    // get pointers on FS_INFO buffer in FAT cluster
     469    fs_info_buffer_ptr = hal_remote_lpt( XPTR( fat_cxy , &fatfs_ctx_ptr->fs_info_buffer ) );
     470    fs_info_buffer_xp  = XPTR( fat_cxy , fs_info_buffer_ptr );
     471
     472    // get lba of FS_INFO sector on IOC device from fatfs context
     473    fs_info_lba = hal_remote_l32( XPTR( fat_cxy , &fatfs_ctx_ptr->fs_info_lba ) );
     474
     475    // update the FS_INFO buffer in FAT cluster
     476    fatfs_set_remote_record( FS_FREE_CLUSTERS     , fs_info_buffer_xp , free_clusters );
     477    fatfs_set_remote_record( FS_FREE_CLUSTER_HINT , fs_info_buffer_xp , free_cluster_hint );
     478   
     479    // update the FS_INFO sector on IOC device
     480    return dev_ioc_sync_write( fs_info_buffer_xp , fs_info_lba , 1 );
     481 
     482}  // fatfs_free_clusters_update_ioc()
     483
     484//////////////////////////////////////////////////////////////////////////////////////////
    376485// This static function decrements the  "free_clusters" variable, and updates the
    377 // "free_cluster_hint" variable in the FATFS context, identified by the <fat_ctx_cxy>
    378 // and <fat_ctx_ptr> arguments (cluster containing the FAT mapper).
     486// "free_cluster_hint" variable in the FATFS context in FAT cluster, identified
     487// by the <fat_ctx_xp> argument, when a new <cluster> has been allocated from FAT.
    379488// It scan all slots in the FAT mapper seen as an array of 32 bits words, looking for the
    380489// first free slot larger than the <cluster> argument, to update "free_cluster_hint".
     490// It calls the fatfs_free_clusters_update_ioc() function to synchronously update the
     491// FS_INFO sector on the IOC device. It can be called by a thead running in any cluster.
    381492//
    382493// WARNING : The free_lock protecting exclusive access to these variables
    383494//           must be taken by the calling function.
    384495//////////////////////////////////////////////////////////////////////////////////////////
    385 // @ fat_ctx_cxy  : FAT mapper cluster identifier.
    386 // @ fat_ctx_ptr  : local pointer on FATFS context.
    387 // @ cluster      : recently allocated cluster index in FAT.
    388 //////////////////////////////////////////////////////////////////////////////////////////
    389 static error_t fatfs_free_clusters_decrement( cxy_t         fat_ctx_cxy,
    390                                               fatfs_ctx_t * fat_ctx_ptr,
    391                                               uint32_t      cluster )
    392 {
     496// @ fatfs_ctx_xp  : extended pointer on FATFS context in FAT cluster.
     497// @ cluster       : recently allocated cluster index in FAT.
     498// @ return 0 if success, return -1 if the FS_INFO sector cannot be updated.
     499//////////////////////////////////////////////////////////////////////////////////////////
     500static error_t fatfs_free_clusters_decrement( xptr_t    fatfs_ctx_xp,
     501                                              uint32_t  cluster )
     502{
     503    error_t       error;
     504    cxy_t         fat_cxy;      // FAT cluster identifier
     505    fatfs_ctx_t * fat_ctx_ptr;  // local pointer on fatfs context in FAT cluster
    393506    xptr_t        mapper_xp;    // extended pointer on FAT mapper
    394507    xptr_t        hint_xp;      // extended pointer on "free_cluster_hint" shared variable
    395508    xptr_t        numb_xp;      // extended pointer on "free_clusters" shared variable
    396509    uint32_t      numb;         // "free_clusters" variable current value
     510    uint32_t      hint;         // "free_cluster_hint" variable current value
    397511    uint32_t      page_id;      // page index in FAT mapper
    398512    uint32_t      slot_id;      // slot index in one page of FAT (1024 slots per page)
     
    405519uint32_t   cycle = (uint32_t)hal_get_cycles();
    406520thread_t * this  = CURRENT_THREAD;
    407 if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() )
     521if( DEBUG_FATFS_FREE_CLUSTERS < cycle )
    408522printk("\n[%s] thread[%x,%x] enter for allocated cluster %x / cycle %d\n",
    409523__FUNCTION__, this->process->pid, this->trdid, cluster , cycle );
    410524#endif
    411525
    412     // build extended pointers on free_clusters, and free_cluster_hint
    413     hint_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_cluster_hint );
    414     numb_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_clusters );
    415 
    416     // update "free_clusters"
    417     numb = hal_remote_l32( numb_xp );
    418     hal_remote_s32( numb_xp , numb - 1 );
     526    // get FAT cluster an local pointer on fatfs context in FAT cluster
     527    fat_cxy      = GET_CXY( fatfs_ctx_xp );
     528    fat_ctx_ptr  = GET_PTR( fatfs_ctx_xp );
     529   
     530    // build extended pointers on free_clusters, and free_cluster_hint in fatfs context
     531    hint_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_cluster_hint );
     532    numb_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_clusters );
     533
     534    // update "free_clusters" value
     535    numb = hal_remote_l32( numb_xp ) - 1;
     536    hal_remote_s32( numb_xp , numb );
    419537
    420538    // get extended pointer on FAT mapper
    421     mapper_xp = hal_remote_l64( XPTR( fat_ctx_cxy , &fat_ctx_ptr->fat_mapper_xp ) );
     539    mapper_xp = hal_remote_l64( XPTR( fat_cxy , &fat_ctx_ptr->fat_mapper_xp ) );
    422540
    423541    // initialise variables to scan the FAT mapper
     
    425543    page_id  = (cluster + 1) >> 10;
    426544    slot_id  = (cluster + 1) & 0x3FF;
    427     page_max = hal_remote_l32( XPTR( fat_ctx_cxy, &fat_ctx_ptr->fat_sectors_count ) ) >> 3;
     545    page_max = hal_remote_l32( XPTR( fat_cxy, &fat_ctx_ptr->fat_sectors_count ) ) >> 3;
    428546
    429547    // scan FAT mapper / loop on pages
     
    451569            if ( hal_remote_l32( slot_xp ) == FREE_CLUSTER )
    452570            {
    453                 // update "free_cluster_hint"
    454                 hal_remote_s32( hint_xp , (page_id << 10) + slot_id - 1 );
     571                // update "free_cluster_hint" value
     572                hint = (page_id << 10) + slot_id - 1;
     573                hal_remote_s32( hint_xp , hint );
     574
     575                // update FS_INFO sector on IOC device
     576                error = fatfs_free_clusters_update_ioc( fatfs_ctx_xp , numb , hint );
     577
     578                if( error )
     579                {
     580                    printk("\n[ERROR] in %s : cannot update FS_INFO on IOC\n", __FUNCTION__ );
     581                    return -1;
     582                }
    455583
    456584#if DEBUG_FATFS_FREE_CLUSTERS
    457585cycle = (uint32_t)hal_get_cycles();
    458586if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() )
    459 printk("\n[%s] thread[%x,%x] exit / hint %x / free_clusters %x / cycle %d\n",
    460 __FUNCTION__, this->process->pid, this->trdid,
    461 hal_remote_l32(hint_xp), hal_remote_l32(numb_xp), cycle );
     587printk("\n[%s] thread[%x,%x] updated free cluster info  / hint %x / number %x\n",
     588__FUNCTION__, this->process->pid, this->trdid, 
     589hal_remote_l32(hint_xp), hal_remote_l32(numb_xp) );
    462590#endif
    463591                return 0;
     
    469597        }  // end loop on slots
    470598
    471         // update (page_id,slot_id) variables
     599        // update page_id & slot_id variables
    472600        page_id++;
    473601        slot_id = 0;
     
    483611//////////////////////////////////////////////////////////////////////////////////////////
    484612// This static function increments the "free_clusters" variable, and updates the
    485 // "free_cluster_hint" variables in the FATFS context, identified by the <fat_ctx_cxy>
    486 // and <fat_ctx_ptr> argument (cluster containing the FAT mapper).
     613// "free_cluster_hint" variables in the FATFS context in FAT cluster, identified
     614// by the <fat_ctx_xp> argument, when a cluster is released to FAT.
    487615// If the released cluster index is smaller than the current (hint) value,
    488616// it set "free_cluster_hint" <= cluster.
     617// It calls the fatfs_free_clusters_update_ioc() function to synchronously update the
     618// FS_INFO sector on the IOC device. It can be called by a thead running in any cluster.
    489619//
    490620// WARNING : The free_lock protecting exclusive access to these variables
    491621//           must be taken by the calling function.
    492622//////////////////////////////////////////////////////////////////////////////////////////
    493 // @ fat_ctx_cxy  : FAT mapper cluster identifier.
    494 // @ fat_ctx_ptr  : local pointer on FATFS context.
    495 // @ cluster     : recently released cluster index in FAT.
    496 //////////////////////////////////////////////////////////////////////////////////////////
    497 static void fatfs_free_clusters_increment( cxy_t         fat_ctx_cxy,
    498                                            fatfs_ctx_t * fat_ctx_ptr,
    499                                            uint32_t      cluster )
    500 {
     623// @ fatfs_ctx_xp  : extended pointer on FATFS context in FAT cluster.
     624// @ cluster       : recently released cluster index in FAT.
     625// @ return 0 if success, return -1 if the FS_INFO sector cannot be updated.
     626//////////////////////////////////////////////////////////////////////////////////////////
     627static error_t fatfs_free_clusters_increment( xptr_t   fatfs_ctx_xp,
     628                                              uint32_t cluster )
     629{
     630    error_t       error;
     631    cxy_t         fat_cxy;      // FAT cluster identifier
     632    fatfs_ctx_t * fat_ctx_ptr;  // local pointer on fatfs context in FAT cluster
    501633    xptr_t        hint_xp;      // extended pointer on "free_cluster_hint" shared variable
    502634    xptr_t        numb_xp;      // extended pointer on "free_clusters" shared variable
     
    504636    uint32_t      numb;         // "free_clusters" variable current value
    505637
     638#if DEBUG_FATFS_FREE_CLUSTERS
     639uint32_t   cycle = (uint32_t)hal_get_cycles();
     640thread_t * this  = CURRENT_THREAD;
     641if( DEBUG_FATFS_FREE_CLUSTERS < cycle )
     642printk("\n[%s] thread[%x,%x] enter for released cluster %x / cycle %d\n",
     643__FUNCTION__, this->process->pid, this->trdid, cluster , cycle );
     644#endif
     645
     646    // get FAT cluster an local pointer on fatfs context in FAT cluster
     647    fat_cxy      = GET_CXY( fatfs_ctx_xp );
     648    fat_ctx_ptr  = GET_PTR( fatfs_ctx_xp );
     649   
    506650    // build extended pointers on free_clusters, and free_cluster_hint
    507     hint_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_cluster_hint );
    508     numb_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_clusters );
     651    hint_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_cluster_hint );
     652    numb_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_clusters );
    509653
    510654    // get current value of free_cluster_hint and free_clusters
     
    512656    numb = hal_remote_l32( numb_xp );
    513657
    514     // update free_cluster_hint if required
    515     if ( (cluster - 1) < hint ) hal_remote_s32( hint_xp , (cluster - 1) );
     658    // update "numb" and "hint" variables as required
     659    numb++;
     660    if ( (cluster - 1) < hint ) hint = cluster - 1;
    516661
    517662    // update free_clusters
    518     hal_remote_s32( numb_xp , numb + 1 );
     663    hal_remote_s32( numb_xp , numb );
     664    hal_remote_s32( hint_xp , hint );
     665
     666    // update FS_INFO sector on IOC device
     667    error = fatfs_free_clusters_update_ioc( fatfs_ctx_xp , numb , hint );
     668
     669    if( error )
     670    {
     671        printk("\n[ERROR] in %s : cannot update FS_INFO on IOC\n", __FUNCTION__ );
     672        return -1;
     673    }
    519674
    520675#if DEBUG_FATFS_FREE_CLUSTERS
    521676thread_t * this = CURRENT_THREAD;
    522677if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() )
    523 printk("\n[%s] thread[%x,%x] updates free cluster info : hint %x / number %x\n",
     678printk("\n[%s] thread[%x,%x] updated free cluster info : hint %x / number %x\n",
    524679__FUNCTION__, this->process->pid, this->trdid,
    525680hal_remote_l32( hint_xp ), hal_remote_l32( numb_xp ) );
    526681#endif
     682
     683    return 0;
    527684
    528685}  // end fatfs_free_clusters_increment()
     
    576733                               FREE_CLUSTER ) ) return -1;
    577734
    578     // Update free_cluster_hint and free_clusters in FAT context
    579     fatfs_free_clusters_increment( mapper_cxy,
    580                                    fatfs_ctx,
    581                                    cluster );
    582 
    583     return 0;
     735    // Update free_cluster info in FATFS context and in FS_INFO sector
     736    return fatfs_free_clusters_increment( XPTR( mapper_cxy , fatfs_ctx ) , cluster );
    584737
    585738}  // end fatfs_recursive_release()
     
    590743//////////////////////////////////////////////////////////////////////////////////////////
    591744
    592 ///////////////////////////////////////////
    593 void fatfs_ctx_display( fatfs_ctx_t * ctx )
    594 {
    595     printk("\n*** FAT context ***\n"
     745///////////////////////////////////
     746void fatfs_display_ctx( cxy_t cxy )
     747{
     748    // get pointer on local FATFS context
     749    vfs_ctx_t   * vfs_ctx = &fs_context[FS_TYPE_FATFS];
     750        fatfs_ctx_t * ctx     = hal_remote_lpt( XPTR( cxy , &vfs_ctx->extend ) );
     751
     752    uint32_t fat_sectors       = hal_remote_l32( XPTR( cxy , &ctx->fat_sectors_count ) );
     753    uint32_t sector_size       = hal_remote_l32( XPTR( cxy , &ctx->bytes_per_sector ) );
     754    uint32_t sec_per_clus      = hal_remote_l32( XPTR( cxy , &ctx->sectors_per_cluster ) );
     755    uint32_t fat_lba           = hal_remote_l32( XPTR( cxy , &ctx->fat_begin_lba ) );
     756    uint32_t data_lba          = hal_remote_l32( XPTR( cxy , &ctx->cluster_begin_lba ) );
     757    uint32_t fsinfo_lba        = hal_remote_l32( XPTR( cxy , &ctx->fs_info_lba ) );
     758    uint32_t root_dir_clus     = hal_remote_l32( XPTR( cxy , &ctx->root_dir_cluster ) );
     759    uint32_t free_clusters     = hal_remote_l32( XPTR( cxy , &ctx->free_clusters ) );
     760    uint32_t free_cluster_hint = hal_remote_l32( XPTR( cxy , &ctx->free_cluster_hint ) );
     761    xptr_t   mapper_xp         = hal_remote_l64( XPTR( cxy , &ctx->fat_mapper_xp ) );
     762    void   * fs_info_buffer    = hal_remote_lpt( XPTR( cxy , &ctx->fs_info_buffer ) );
     763
     764    printk("\n*** FAT context in cluster %x\n"
    596765           "- fat_sectors       = %d\n"
    597766           "- sector size       = %d\n"
    598767           "- cluster size      = %d\n"
    599            "- fat_first_lba     = %d\n"
    600            "- data_first_lba    = %d\n"
    601            "- root_dir_cluster  = %d\n"
    602            "- free_clusters     = %d\n"
    603            "- free_cluster_hint = %d\n"
    604            "- fat_mapper_xp     = %l\n",
    605            ctx->fat_sectors_count,
    606            ctx->bytes_per_sector,
    607            ctx->sectors_per_cluster * ctx->bytes_per_sector,
    608            ctx->fat_begin_lba,
    609            ctx->cluster_begin_lba,
    610            ctx->root_dir_cluster,
    611            ctx->free_clusters,
    612            ctx->free_cluster_hint,
    613            ctx->fat_mapper_xp );
    614 
    615 }  // end ctx_display()
     768           "- fat_lba           = %x\n"
     769           "- data_lba          = %x\n"
     770           "- fsinfo_lba        = %x\n"
     771           "- root_dir_cluster  = %x\n"
     772           "- free_clusters     = %x\n"
     773           "- free_cluster_hint = %x\n"
     774           "- fat_mapper_ptr    = %x\n"
     775           "- fs_info_buffer    = %x\n",
     776           cxy,
     777           fat_sectors,
     778           sector_size,
     779           sector_size * sec_per_clus,
     780           fat_lba,
     781           data_lba,
     782           fsinfo_lba,
     783           root_dir_clus,
     784           free_clusters,
     785           free_cluster_hint,
     786           GET_PTR( mapper_xp ),
     787           fs_info_buffer );
     788
     789}  // end fatfs_ctx_display()
    616790
    617791//////////////////////////////////////////
     
    622796    uint32_t maxline;
    623797
    624     // copute numner of lines to display
     798    // compute number of lines to display
    625799    maxline = nentries >> 3;
    626800    if( nentries & 0x7 ) maxline++;
    627801
    628802    // get pointer on local FATFS context
    629     vfs_ctx_t   * vfs_ctx   = &fs_context[FS_TYPE_FATFS];
    630     fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;
     803    vfs_ctx_t   * vfs_ctx       = &fs_context[FS_TYPE_FATFS];
     804    fatfs_ctx_t * loc_fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;
    631805
    632806    // get extended pointer on FAT mapper
    633     xptr_t fat_mapper_xp = fatfs_ctx->fat_mapper_xp;
    634 
    635     // get extended pointer and cluster of FAT mapper requested page
     807    xptr_t fat_mapper_xp  = loc_fatfs_ctx->fat_mapper_xp;
     808
     809    // get FAT cluster identifier
     810    cxy_t  fat_cxy = GET_CXY( fat_mapper_xp );
     811
     812    // get pointer on FATFS context in FAT cluster
     813    fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) );
     814 
     815    // get current value of hint and free_clusters
     816    uint32_t hint = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint ) );
     817    uint32_t free = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters ) );
     818 
     819    // get extended pointer on requested page in FAT mapper
    636820    xptr_t     page_xp  = mapper_remote_get_page( fat_mapper_xp , page_id );
    637821
    638822    // get extended pointer on requested page base
    639823    xptr_t     base_xp  = ppm_page2base( page_xp );
    640 
    641     printk("\n***** FAT content / page %d *****\n", page_id );
     824    void     * base     = GET_PTR( base_xp );
     825
     826    printk("\n***** FAT mapper / cxy %x / page_id %d / base %x / free_clusters %x / hint %x\n",
     827    fat_cxy, page_id, base, free, hint );
     828
    642829    for( line = 0 ; line < maxline ; line++ )
    643830    {
     
    766953    kmem_req_t    req;
    767954    uint8_t     * buffer;
     955    xptr_t        buffer_xp;
    768956
    769957#if DEBUG_FATFS_CTX_INIT
     
    778966assert( (fatfs_ctx != NULL) , "pointer on FATFS context is NULL" );
    779967
    780 // check only cluster 0 does FATFS init
     968// check only cluster 0 does FATFS initialization
    781969assert( (local_cxy == 0) , "only cluster 0 can initialize FATFS");
    782970
    783     // allocate a 512 bytes buffer to store the boot record
     971    // allocate a permanent 512 bytes buffer to store
     972    // - temporarily the BOOT sector
     973    // - permanently the FS_INFO sector
    784974        req.type    = KMEM_512_BYTES;
    785975    req.flags   = AF_KERNEL | AF_ZERO;
    786976        buffer      = (uint8_t *)kmem_alloc( &req );
     977    buffer_xp   = XPTR( local_cxy , buffer );
    787978
    788979    if( buffer == NULL )
     
    793984     
    794985    // load the BOOT record from device
    795     error = dev_ioc_sync_read( buffer , 0 , 1 );
     986    error = dev_ioc_sync_read( buffer_xp , 0 , 1 );
    796987
    797988    if ( error )
     
    807998
    808999    // get sector size from boot record
    809     uint32_t sector_size = fatfs_get_record( BPB_BYTSPERSEC , buffer , 1 );
     1000    uint32_t sector_size = fatfs_get_record( BPB_BYTSPERSEC , buffer );
    8101001    if ( sector_size != 512 )
    8111002    {
     
    8151006
    8161007    // get cluster size from boot record
    817     uint32_t nb_sectors = fatfs_get_record( BPB_SECPERCLUS , buffer , 1 );
     1008    uint32_t nb_sectors = fatfs_get_record( BPB_SECPERCLUS , buffer );
    8181009    if ( nb_sectors != 8 )
    8191010    {
     
    8231014
    8241015    // get number of FAT copies from boot record
    825     uint32_t nb_fats = fatfs_get_record( BPB_NUMFATS , buffer , 1 );
     1016    uint32_t nb_fats = fatfs_get_record( BPB_NUMFATS , buffer );
    8261017    if ( nb_fats != 1 )
    8271018    {
     
    8311022
    8321023    // get number of sectors in FAT from boot record
    833     uint32_t fat_sectors = fatfs_get_record( BPB_FAT32_FATSZ32 , buffer , 1 );
     1024    uint32_t fat_sectors = fatfs_get_record( BPB_FAT32_FATSZ32 , buffer );
    8341025    if ( (fat_sectors & 0xF) != 0 )
    8351026    {
     
    8391030
    8401031    // get root cluster from boot record
    841     uint32_t root_cluster = fatfs_get_record( BPB_FAT32_ROOTCLUS , buffer , 1 );
     1032    uint32_t root_cluster = fatfs_get_record( BPB_FAT32_ROOTCLUS , buffer );
    8421033    if ( root_cluster != 2 )
    8431034    {
     
    8471038
    8481039    // get FAT lba from boot record
    849     uint32_t fat_lba = fatfs_get_record( BPB_RSVDSECCNT , buffer , 1 );
     1040    uint32_t fat_lba = fatfs_get_record( BPB_RSVDSECCNT , buffer );
    8501041
    8511042    // get FS_INFO sector lba from boot record
    852     uint32_t fs_info_lba = fatfs_get_record( BPB_FAT32_FSINFO , buffer , 1 );
     1043    uint32_t fs_info_lba = fatfs_get_record( BPB_FAT32_FSINFO , buffer );
    8531044
    8541045    // load the FS_INFO record from device
    855     error = dev_ioc_sync_read( buffer , fs_info_lba , 1 );
     1046    error = dev_ioc_sync_read( buffer_xp , fs_info_lba , 1 );
    8561047
    8571048    if ( error )
     
    8611052    }
    8621053
    863     // get free clusters number from FS_INFO record
    864     uint32_t free_clusters = fatfs_get_record( FS_FREE_CLUSTERS , buffer , 1 );
     1054    // get free_clusters number from FS_INFO record
     1055    uint32_t free_clusters = fatfs_get_record( FS_FREE_CLUSTERS , buffer );
    8651056    if ( free_clusters >= fat_sectors << 7 )
    8661057    {
     
    8691060    }
    8701061
    871     // get cluster hint from FS_INFO record
    872     uint32_t free_cluster_hint = fatfs_get_record( FS_FREE_CLUSTER_HINT , buffer , 1 );
     1062    // get free_cluster_hint from FS_INFO record
     1063    uint32_t free_cluster_hint = fatfs_get_record( FS_FREE_CLUSTER_HINT , buffer );
     1064
    8731065    if ( free_cluster_hint >= fat_sectors << 7 )
    8741066    {
     
    8761068        hal_core_sleep();
    8771069    }
    878 
    879     // release the 512 bytes buffer
    880     req.type = KMEM_512_BYTES;
    881     req.ptr  = buffer;
    882     kmem_free( &req );
    8831070
    8841071    // allocate a mapper for the FAT itself
     
    8901077    }
    8911078
    892     // WARNING : the inode field MUST be NULL for the FAT mapper
     1079    // the inode field is NULL for the FAT mapper
    8931080    fat_mapper->inode = NULL;
    894 
    8951081
    8961082    // initialize the FATFS context
     
    9021088    fatfs_ctx->root_dir_cluster      = 2;
    9031089    fatfs_ctx->fat_mapper_xp         = XPTR( local_cxy , fat_mapper );
     1090    fatfs_ctx->fs_info_lba           = fs_info_lba;
    9041091    fatfs_ctx->free_clusters         = free_clusters;
    9051092    fatfs_ctx->free_cluster_hint     = free_cluster_hint;
     1093    fatfs_ctx->fs_info_buffer        = buffer;
    9061094
    9071095    remote_queuelock_init( XPTR( local_cxy , &fatfs_ctx->free_lock ) , LOCK_FATFS_FREE );
     
    10191207        while ( (offset < 4096) && (found == 0) )
    10201208        {
    1021             if ( fatfs_get_record( LDIR_ORD, (base + offset), 0 ) == NO_MORE_ENTRY )
     1209            if ( fatfs_get_record( LDIR_ORD, (base + offset) ) == NO_MORE_ENTRY )
    10221210            {
    10231211                found = 1;
     
    13351523
    13361524// check for LFN entry
    1337 assert( (fatfs_get_record( DIR_ATTR, base + offset, 0 ) == ATTR_LONG_NAME_MASK ),
     1525assert( (fatfs_get_record( DIR_ATTR, base + offset ) == ATTR_LONG_NAME_MASK ),
    13381526"this directory entry must be a LFN\n");
    13391527
     
    14391627        while( (offset < 4096) && (found == 0) )
    14401628        {
    1441             attr = fatfs_get_record( DIR_ATTR , base + offset , 0 );   
    1442             ord  = fatfs_get_record( LDIR_ORD , base + offset , 0 );   
     1629            attr = fatfs_get_record( DIR_ATTR , base + offset );   
     1630            ord  = fatfs_get_record( LDIR_ORD , base + offset );   
    14431631
    14441632            if (ord == NO_MORE_ENTRY)                 // no more entry => break
     
    15591747
    15601748// check arguments
    1561 assert( (parent_inode != NULL)         , "parent_inode is NULL\n" );
    1562 assert( (name         != NULL)         , "name is NULL\n" );
    1563 assert( (child_inode_xp != XPTR_NULL ) , "child_inode is XPTR_NULL\n" );
     1749assert( (parent_inode   != NULL)       , "parent_inode is NULL\n" );
     1750assert( (name           != NULL)       , "name is NULL\n" );
     1751assert( (child_inode_xp != XPTR_NULL ) , "child_inode is NULL\n" );
     1752
     1753    // get child inode cluster and local pointer
     1754    child_inode_cxy = GET_CXY( child_inode_xp );
     1755    child_inode_ptr = GET_PTR( child_inode_xp );
     1756
     1757    // build extended pointer on root of list of parent dentries
     1758    root_xp = XPTR( child_inode_cxy , &child_inode_ptr->parents );
     1759
     1760// check child inode has at least one parent
     1761assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n");
    15641762
    15651763#if DEBUG_FATFS_GET_DENTRY
     
    15781776    error  = fatfs_scan_directory( mapper, name , &entry , &index );
    15791777
    1580     if( error )
    1581     {
    1582         vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , dir_name );
    1583         printk("\n[ERROR] in %s : cannot find <%s> in parent mapper <%s>\n",
    1584         __FUNCTION__, name , dir_name );
    1585         return -1;
    1586     }
     1778    // return non fatal error if not found
     1779    if( error ) return -1;
    15871780
    15881781    // get relevant infos from FAT32 directory entry
    1589     cluster = (fatfs_get_record( DIR_FST_CLUS_HI , entry , 1 ) << 16) |
    1590               (fatfs_get_record( DIR_FST_CLUS_LO , entry , 1 )      ) ;
    1591     is_dir  = (fatfs_get_record( DIR_ATTR        , entry , 1 ) & ATTR_DIRECTORY);
    1592     size    =  fatfs_get_record( DIR_FILE_SIZE   , entry , 1 );
    1593 
    1594     // get child inode cluster and local pointer
    1595     child_inode_cxy = GET_CXY( child_inode_xp );
    1596     child_inode_ptr = GET_PTR( child_inode_xp );
    1597 
    1598     // build extended pointer on root of list of parent dentries
    1599     root_xp = XPTR( child_inode_cxy , &child_inode_ptr->parents );
    1600 
    1601 // check child inode has at least one parent
    1602 assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n");
     1782    cluster = (fatfs_get_record( DIR_FST_CLUS_HI , entry ) << 16) |
     1783              (fatfs_get_record( DIR_FST_CLUS_LO , entry )      ) ;
     1784    is_dir  = (fatfs_get_record( DIR_ATTR        , entry ) & ATTR_DIRECTORY);
     1785    size    =  fatfs_get_record( DIR_FILE_SIZE   , entry );
    16031786
    16041787    // scan list of parent dentries to search the parent_inode
     
    16921875
    16931876    // set size in FAT32 directory entry
    1694     fatfs_set_record( DIR_FILE_SIZE , entry , 1 , size );
     1877    fatfs_set_record( DIR_FILE_SIZE , entry , size );
    16951878
    16961879    // get local pointer on modified page base
     
    17951978            bool_t valid = (dentry_id >= min_dentry) && (dirent_id <  max_dirent );
    17961979
    1797             attr = fatfs_get_record( DIR_ATTR , base + offset , 0 );   
    1798             ord  = fatfs_get_record( LDIR_ORD , base + offset , 0 );   
     1980            attr = fatfs_get_record( DIR_ATTR , base + offset );   
     1981            ord  = fatfs_get_record( LDIR_ORD , base + offset );   
    17991982
    18001983            if (ord == NO_MORE_ENTRY)                 // no more entry => break
     
    20332216error_t fatfs_sync_free_info( void )
    20342217{
     2218    error_t       error;
     2219    fatfs_ctx_t * fatfs_ctx_ptr;              // local pointer on fatfs context in cluster 0
     2220    uint32_t      ctx_free_clusters;          // number of free clusters from fatfs context
     2221    uint32_t      ctx_free_cluster_hint;      // free cluster hint from fatfs context
     2222    uint32_t      ioc_free_clusters;          // number of free clusters from fatfs context
     2223    uint32_t      ioc_free_cluster_hint;      // free cluster hint from fatfs context
     2224    uint32_t      fs_info_lba;                // lba of FS_INFO sector on IOC device
     2225    uint8_t     * fs_info_buffer;             // local pointer on FS_INFO buffer in cluster 0
     2226    xptr_t        fs_info_buffer_xp;          // extended pointer on FS_INFO buffer in cluster 0
     2227    uint8_t       tmp_buf[512];               // 512 bytes temporary buffer
     2228    xptr_t        tmp_buf_xp;                 // extended pointer on temporary buffer
    20352229
    20362230#if DEBUG_FATFS_SYNC_FSINFO
     
    20422236#endif
    20432237
    2044     uint8_t     * buffer;   // dynamically allocated aligned 512 bytes buffer
    2045     kmem_req_t    req;
    2046     error_t       error;
    2047 
    2048     // get FS_INFO lba, free_ from FATFS context
    2049     fatfs_ctx_t * fatfs_ctx  = fs_context[FS_TYPE_FATFS].extend;
    2050     uint32_t      lba        = fatfs_ctx->fs_info_lba;
    2051     uint32_t      hint       = fatfs_ctx->free_cluster_hint;
    2052     uint32_t      number     = fatfs_ctx->free_clusters;
    2053 
    2054     // allocate buffer to store the FS_INFO sector
    2055         req.type    = KMEM_512_BYTES;
    2056     req.flags   = AF_KERNEL | AF_ZERO;
    2057         buffer      = (uint8_t *)kmem_alloc( &req );
    2058     if( buffer == NULL )
    2059     {
    2060         printk("\n[PANIC] in %s : cannot allocate buffer\n", __FUNCTION__ );
    2061         return ENOMEM;
    2062     }
    2063      
    2064     // load the FS_INFO sector from device to buffer
    2065     error = dev_ioc_read( buffer , lba , 1 );
     2238    // get pointer on fatfs context in cluster 0
     2239    fatfs_ctx_ptr = hal_remote_lpt( XPTR( 0 , &fs_context[FS_TYPE_FATFS].extend ) );
     2240
     2241    // get "free_clusters" and "free_cluster_hint" from fatfs context in cluster 0
     2242    ctx_free_clusters     = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_clusters ) );
     2243    ctx_free_cluster_hint = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_cluster_hint ) );
     2244
     2245    // get fs_info_lba
     2246    fs_info_lba = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->fs_info_lba ) );
     2247
     2248    // build extended pointer on temporary buffer
     2249    tmp_buf_xp = XPTR( local_cxy , tmp_buf );
     2250
     2251    // copy FS_INFO sector from IOC to local buffer
     2252    error = dev_ioc_sync_read( tmp_buf_xp , fs_info_lba , 1 );
     2253
    20662254    if ( error )
    20672255    {
    2068         printk("\n[PANIC] in %s : cannot read FS_INFO record\n", __FUNCTION__ );
    2069         return EIO;
    2070     }
    2071 
    2072     // update buffer
    2073     fatfs_set_record( FS_FREE_CLUSTERS     , buffer , 1 , number );
    2074     fatfs_set_record( FS_FREE_CLUSTER_HINT , buffer , 1 , hint );
    2075 
    2076     // write modified FS_INFO sector from buffer to device
    2077     error = dev_ioc_write( buffer , lba , 1 );
    2078     if ( error )
    2079     {
    2080         printk("\n[PANIC] in %s : cannot write FS_INFO record\n", __FUNCTION__ );
    2081         return EIO;
    2082     }
    2083 
    2084     // release the 512 bytes buffer
    2085     req.type = KMEM_512_BYTES;
    2086     req.ptr  = buffer;
    2087     kmem_free( &req );
     2256        printk("\n[ERROR] in %s : cannot access FS_INFO on IOC device\n", __FUNCTION__ );
     2257        return -1;
     2258    }
     2259
     2260    // get current values of "free_clusters" and "free_cluster_hint" from FS_INFO on IOC
     2261    ioc_free_clusters     = fatfs_get_remote_record( FS_FREE_CLUSTERS     , tmp_buf_xp );
     2262    ioc_free_cluster_hint = fatfs_get_remote_record( FS_FREE_CLUSTER_HINT , tmp_buf_xp );
     2263
     2264    // check values
     2265    if( (ioc_free_clusters     != ctx_free_clusters) ||
     2266        (ioc_free_cluster_hint != ctx_free_cluster_hint) )
     2267    {
     2268        printk("\n[WARNING] in %s : unconsistent free clusters info\n"
     2269        " ioc_free %x / ctx_free %x / ioc_hint %x / ctx_hint %x\n",
     2270        __FUNCTION__, ioc_free_clusters, ctx_free_clusters,
     2271        ioc_free_cluster_hint, ctx_free_cluster_hint );
     2272
     2273        // get pointers on FS_INFO buffer in cluster 0
     2274        fs_info_buffer    = hal_remote_lpt( XPTR( 0 , &fatfs_ctx_ptr->fs_info_buffer ) );
     2275        fs_info_buffer_xp = XPTR( 0 , fs_info_buffer );
     2276
     2277        // update FS_INFO buffer in cluster 0
     2278        fatfs_set_remote_record(FS_FREE_CLUSTERS    ,fs_info_buffer_xp,ctx_free_clusters );
     2279        fatfs_set_remote_record(FS_FREE_CLUSTER_HINT,fs_info_buffer_xp,ctx_free_cluster_hint);
     2280
     2281        // update the FS_INFO sector on IOC device
     2282        error = dev_ioc_sync_write( fs_info_buffer_xp , fs_info_lba , 1 );
     2283
     2284        if ( error )
     2285        {
     2286            printk("\n[ERROR] in %s : cannot update FS_INFO on IOC device\n", __FUNCTION__ );
     2287            return -1;
     2288        }
     2289    }
    20882290
    20892291#if DEBUG_FATFS_SYNC_FSINFO
     
    20962298    return 0;
    20972299
    2098 }  // end fatfs_sync_fs_info()
     2300}  // end fatfs_sync_free_info()
    20992301
    21002302//////////////////////////////////////////////////////////
    21012303error_t fatfs_cluster_alloc( uint32_t * searched_cluster )
    21022304{
     2305    error_t       error;
    21032306    uint32_t      page_id;        // page index in FAT mapper
    21042307    uint32_t      slot_id;        // slot index in page (1024 slots per page)
     
    21092312    fatfs_ctx_t * fat_fatfs_ctx;  // local pointer on FATFS context in FAT cluster
    21102313    xptr_t        mapper_xp;      // extended pointer on FAT mapper
    2111     cxy_t         mapper_cxy;     // Fat mapper cluster identifier
     2314    cxy_t         fat_cxy;        // Fat mapper cluster identifier
    21122315    xptr_t        page_xp;        // extended pointer on current page descriptor in mapper
    21132316    xptr_t        slot_xp;        // extended pointer on FAT slot defined by hint
    21142317    xptr_t        lock_xp;        // extended pointer on lock protecting free clusters info
    21152318    xptr_t        hint_xp;        // extended pointer on free_cluster_hint in FAT cluster
    2116     xptr_t        numb_xp;        // extended pointer on free_clusters_number in FAT cluster
     2319    xptr_t        free_xp;        // extended pointer on free_clusters_number in FAT cluster
    21172320
    21182321#if DEBUG_FATFS_CLUSTER_ALLOC
     
    21302333    loc_fatfs_ctx = vfs_ctx->extend;
    21312334
    2132     // get extended pointer and cluster on FAT mapper
     2335    // get extended pointer on FAT mapper
    21332336    mapper_xp  = loc_fatfs_ctx->fat_mapper_xp;
    2134     mapper_cxy = GET_CXY( mapper_xp );
     2337
     2338    // get FAT cluster
     2339    fat_cxy = GET_CXY( mapper_xp );
    21352340   
    21362341    // get local pointer on FATFS context in FAT cluster
    2137     fat_fatfs_ctx = hal_remote_lpt( XPTR( mapper_cxy , &vfs_ctx->extend ) );
     2342    fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) );
    21382343
    21392344    // build relevant extended pointers on free clusters info in mapper cluster
    2140     lock_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_lock );
    2141     hint_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_cluster_hint );
    2142     numb_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_clusters );
     2345    lock_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_lock );
     2346    hint_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint );
     2347    free_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters );
    21432348
    21442349    // take the lock protecting free clusters
    21452350    remote_queuelock_acquire( lock_xp );
    21462351
    2147     // get hint and free_clusters values from FATFS context
     2352    // get hint and free_clusters values from FATFS context in FAT cluster
    21482353    cluster       = hal_remote_l32( hint_xp ) + 1;
    2149     free_clusters = hal_remote_l32( numb_xp );
     2354    free_clusters = hal_remote_l32( free_xp );
    21502355       
    21512356#if (DEBUG_FATFS_CLUSTER_ALLOC & 1)
     
    21682373    }
    21692374
    2170 
    2171 
    21722375    // get page index & slot index for selected cluster
    21732376    page_id  = cluster >> 10;
    21742377    slot_id  = cluster & 0x3FF;
    21752378
    2176     // get relevant page descriptor from mapper
     2379    // get relevant page descriptor from FAT mapper
    21772380    page_xp = mapper_remote_get_page( mapper_xp , page_id );
    21782381
     
    21942397    }
    21952398
    2196     // update free cluster info in FATFS context
    2197     fatfs_free_clusters_decrement( mapper_cxy , fat_fatfs_ctx , cluster );
     2399    // update free cluster info in FATFS context and in FS_INFO sector
     2400    error = fatfs_free_clusters_decrement( XPTR( fat_cxy , fat_fatfs_ctx ) , cluster );
     2401
     2402    if( error )
     2403    {
     2404        printk("\n[ERROR] in %s : cannot update free cluster info\n", __FUNCTION__ );
     2405        remote_queuelock_acquire( lock_xp );
     2406        return -1;
     2407    }
     2408
     2409    // update FAT mapper
     2410    hal_remote_s32( slot_xp , END_OF_CHAIN_CLUSTER_MAX );
     2411
     2412    // synchronously update FAT on device
     2413    error = fatfs_move_page( page_xp , IOC_SYNC_WRITE );
     2414
     2415    if( error )
     2416    {
     2417        printk("\n[ERROR] in %s : cannot update FAT on IOC device\n", __FUNCTION__ );
     2418        remote_queuelock_acquire( lock_xp );
     2419        return -1;
     2420    }
    21982421
    21992422    // release free clusters busylock
    22002423    remote_queuelock_release( lock_xp );
    2201 
    2202     // update FAT mapper
    2203     hal_remote_s32( slot_xp , END_OF_CHAIN_CLUSTER_MAX );
    2204 
    2205     // synchronously update FAT on device
    2206     fatfs_move_page( page_xp , IOC_SYNC_WRITE );
    22072424
    22082425#if DEBUG_FATFS_CLUSTER_ALLOC
    22092426cycle = (uint32_t)hal_get_cycles();
    22102427if( DEBUG_FATFS_CLUSTER_ALLOC < cycle )
    2211 printk("\n[%s] thread[%x,%x] exit / updated cluster %x in FAT / cycle %d\n",
     2428printk("\n[%s] thread[%x,%x] exit / allocated cluster %x in FAT / cycle %d\n",
    22122429__FUNCTION__, this->process->pid, this->trdid, cluster, cycle );
    22132430#endif
     
    22302447    xptr_t        first_xp;       // extended pointer on inode extension
    22312448    uint32_t      first_cluster;  // first cluster index for released inode
    2232     vfs_inode_t * inode_ptr;
    2233     cxy_t         inode_cxy;
     2449    vfs_inode_t * inode_ptr;      // local pointer on target inode
     2450    cxy_t         inode_cxy;      // target inode cluster identifier
    22342451
    22352452// check inode pointer
     
    23572574
    23582575    // get page base address
    2359     xptr_t    base_xp = ppm_page2base( page_xp );
    2360     uint8_t * buffer  = (uint8_t *)GET_PTR( base_xp );
     2576    xptr_t    buffer_xp = ppm_page2base( page_xp );
     2577    uint8_t * buffer_ptr = (uint8_t *)GET_PTR( buffer_xp );
    23612578 
    23622579    // get inode pointer from mapper
    23632580    inode_ptr  = hal_remote_lpt( XPTR( page_cxy , &mapper_ptr->inode ) );
    23642581
    2365     ////////////////////////////// it is the FAT mapper
     2582#if DEBUG_FATFS_MOVE_PAGE
     2583if( DEBUG_FATFS_MOVE_PAGE < cycle )
     2584printk("\n[%s] thread[%x,%x] enters : %s / cxy %x / mapper %x / inode %x / page %x\n",
     2585__FUNCTION__, this->process->pid, this->trdid,
     2586dev_ioc_cmd_str( cmd_type ), page_cxy, mapper_ptr, inode_ptr, buffer_ptr );
     2587#endif
     2588
     2589    //////////////////////////////  FAT mapper
    23662590    if( inode_ptr == NULL )
    23672591    {
     
    23702594 
    23712595        // access device
    2372         if     ( cmd_type == IOC_SYNC_READ  ) error = dev_ioc_sync_read ( buffer , lba , 8 );
    2373         else if( cmd_type == IOC_SYNC_WRITE ) error = dev_ioc_sync_write( buffer , lba , 8 );
    2374         else if( cmd_type == IOC_READ       ) error = dev_ioc_read      ( buffer , lba , 8 );
    2375         else if( cmd_type == IOC_WRITE      ) error = dev_ioc_write     ( buffer , lba , 8 );
    2376         else                                  error = -1;
    2377 
    2378         if( error ) return EIO;
     2596        if     (cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer_xp  , lba , 8 );
     2597        else if(cmd_type == IOC_SYNC_WRITE) error = dev_ioc_sync_write( buffer_xp  , lba , 8 );
     2598        else if(cmd_type == IOC_READ      ) error = dev_ioc_read      ( buffer_ptr , lba , 8 );
     2599        else if(cmd_type == IOC_WRITE     ) error = dev_ioc_write     ( buffer_ptr , lba , 8 );
     2600        else                                error = -1;
     2601
     2602        if( error )
     2603        {
     2604            printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ );
     2605            return -1;
     2606        }
    23792607
    23802608#if DEBUG_FATFS_MOVE_PAGE
     
    23822610{
    23832611    if ( (cmd_type == IOC_READ) || (cmd_type == IOC_SYNC_READ) )
    2384          printk("\n[%s] thread[%x,%x] load page %d of FAT / cycle %d\n",
    2385          __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
     2612        printk("\n[%s] thread[%x,%x] load FAT mapper page %d from IOC / cycle %d\n",
     2613        __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
    23862614    else
    2387         printk("\n[%s] thread[%x,%x] sync page %d of FAT / cycle %d\n",
     2615        printk("\n[%s] thread[%x,%x] sync FAT mapper page %d to IOC / cycle %d\n",
    23882616        __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
    23892617}
     
    23912619
    23922620    }
    2393     ///////////////////////// it is an inode mapper
     2621    ///////////////////////// inode mapper
    23942622    else                       
    23952623    {
     
    24252653        }
    24262654
    2427         // get lba from searched_cluster
     2655        // get lba for searched_cluster
    24282656        uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , searched_cluster );
     2657
     2658        // access device
     2659        if     (cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer_xp  , lba , 8 );
     2660        else if(cmd_type == IOC_SYNC_WRITE) error = dev_ioc_sync_write( buffer_xp  , lba , 8 );
     2661        else if(cmd_type == IOC_READ      ) error = dev_ioc_read      ( buffer_ptr , lba , 8 );
     2662        else if(cmd_type == IOC_WRITE     ) error = dev_ioc_write     ( buffer_ptr , lba , 8 );
     2663        else                                error = -1;
     2664
     2665        if( error )
     2666        {
     2667            printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ );
     2668            return -1;
     2669        }
    24292670
    24302671#if DEBUG_FATFS_MOVE_PAGE
     
    24402681#endif
    24412682
    2442         // access device
    2443         if     ( cmd_type == IOC_SYNC_READ  ) error = dev_ioc_sync_read ( buffer , lba , 8 );
    2444         else if( cmd_type == IOC_SYNC_WRITE ) error = dev_ioc_sync_write( buffer , lba , 8 );
    2445         else if( cmd_type == IOC_READ       ) error = dev_ioc_read      ( buffer , lba , 8 );
    2446         else if( cmd_type == IOC_WRITE      ) error = dev_ioc_write     ( buffer , lba , 8 );
    2447         else                                  error = -1;
    2448 
    2449         if( error )
    2450         {
    2451             printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ );
    2452             return -1;
    2453         }
    24542683    }
    24552684
Note: See TracChangeset for help on using the changeset viewer.