/*
 * fatfs.h - FATFS file system API definition.
 *
 * Author    Mohamed Lamine Karaoui (2015)
 *           Alain Greiner (2016)
 *
 * Copyright (c) UPMC Sorbonne Universites
 *
 * This file is part of ALMOS-MKH.
 *
 * ALMOS-MKH is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2.0 of the License.
 *
 * ALMOS-MKH is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _FATFS_H_
#define _FATFS_H_

#include <hal_types.h>
#include <rwlock.h>

/****  Forward declarations  ****/

struct mapper_s;
struct device_s;
struct vfs_inode_s;
struct page_s;

/*****************************************************************************************
 * This structure defines a FATFS context descriptor 
 ****************************************************************************************/

typedef struct fatfs_ctx_s
{
    xptr_t            dev_xp;                /*! extended pointer on remote IOC device  */ 
    rwlock_t          lock;                  /*! TODO protect what ???                  */
    uint32_t          fat_begin_lba;
    uint32_t          fat_sectors_count;
    uint32_t          bytes_per_sector;
    uint32_t          bytes_per_cluster;
    uint32_t          cluster_begin_lba;
    uint32_t          sectors_per_cluster;
    uint32_t          rootdir_first_cluster;
    uint32_t          last_allocated_sector;
    uint32_t          last_allocated_index;  /*! TODO last allocated cluster ???        */
    struct mapper_s * mapper;                /*! mapper for the FAT itself              */ 
}
fatfs_ctx_t;

/*****************************************************************************************
 * This structure defines the FAT specific inode extension (versus the VFS inode).
 ****************************************************************************************/

typedef struct fatfs_inode_s
{
    struct fatfs_ctx_s * ctx;                /*! local pointer on the FATFS context     */ 
	uint32_t             first_cluster;      /*! first cluster on device                */ 
}
fatfs_inode_t;

/*****************************************************************************************
 * This structure defines a FAT specific extension to the generic vfs_dentry_t.
 * TODO a-ton vraiment besoin de cette structure [AG]
 ****************************************************************************************/

struct fat_dentry_s
{
	uint32_t          entry_index;           /*! TODO ???                               */  
	uint32_t          first_cluster;         /*! TODO ???                               */
}
fat_dentry_t;





/*****************************************************************************************
 * This function allocates memory for a FATFS inode, initializes it,
 * and link it to the VFS inode.
 * TODO [AG] : faut-il rechercher le fichier correspondant sur le disque,
 * ou faut-il allouer un nouveau cluster?
 *****************************************************************************************
 * @ inode   : local pointer on vfs_inode.
 * @ return 0 if success / return ENOMEM if error. 
 ****************************************************************************************/
error_t fatfs_inode_create( struct vfs_inode_s * inode );

/*****************************************************************************************
 * This function releases memory allocated for a FATFS inode.
 *****************************************************************************************
 * @ inode   : local pointer on vfs_inode.
 ****************************************************************************************/
void fatfs_inode_destroy( struct vfs_inode_s * inode );

/*****************************************************************************************
 * This function allocates memory for a FATFS context, initialises it, 
 * and link it to the local VFS context.
 *****************************************************************************************
 * @ inode   : local pointer on VFS context.
 * @ return 0 if success / return ENOMEM if error. 
 ****************************************************************************************/
error_t fatfs_context_create( struct vfs_ctx_s * ctx );

/*****************************************************************************************
 * This function releases memory allocated for a FATFS context.
 *****************************************************************************************
 * @ ctx   : local pointer on VFS context.
 ****************************************************************************************/
void fatfs_inode_destroy( struct vfs_ctx_s * ctx );

/*****************************************************************************************
 * This function moves a page from the mapper to the FATFS file system.
 * It must be called by a thread running in cluster containing the mapper.
 * The pointer on the mapper and the page index in file are supposed to be registered
 * in the page descriptor. 
 *****************************************************************************************
 * @ page    : local pointer on page descriptor.
 * @ return 0 if success / return EIO if error. 
 ****************************************************************************************/
error_t fatfs_write_page( struct page_s * page );

/*****************************************************************************************
 * This function moves a page from the FATFS file system on device to the mapper.
 * It must be called by a thread running in cluster containing the mapper.
 * The pointer on the mapper and the page index in file are supposed to be registered
 * in the page descriptor. 
 *****************************************************************************************
 * @ page    : local pointer on page descriptor.
 * @ return 0 if success / return EIO if error. 
 ****************************************************************************************/
error_t fatfs_read_page( struct page_s * page );


#endif	/* _FATFS_H_ */
