]> git.sur5r.net Git - u-boot/blobdiff - include/fat.h
cmd: CONFIG_CMD_LOG select CONFIG_LOG
[u-boot] / include / fat.h
index 59de3fbec55bd434798e8906b73ba798879529cb..fa956441c659504d247d0a9ff9860946c7fac479 100644 (file)
@@ -4,51 +4,34 @@
  * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6
  * 2003-03-10 - kharris@nexus-tech.net - ported to u-boot
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program 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; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #ifndef _FAT_H_
 #define _FAT_H_
 
 #include <asm/byteorder.h>
+#include <fs.h>
 
-#define CONFIG_SUPPORT_VFAT
-
-#define SECTOR_SIZE FS_BLOCK_SIZE
+/* Maximum Long File Name length supported here is 128 UTF-16 code units */
+#define VFAT_MAXLEN_BYTES      256 /* Maximum LFN buffer in bytes */
+#define VFAT_MAXSEQ            9   /* Up to 9 of 13 2-byte UTF-16 entries */
+#define PREFETCH_BLOCKS                2
 
-#define FS_BLOCK_SIZE 512
+#define MAX_CLUSTSIZE  CONFIG_FS_FAT_MAX_CLUSTSIZE
 
-#if FS_BLOCK_SIZE != SECTOR_SIZE
-#error FS_BLOCK_SIZE != SECTOR_SIZE - This code needs to be fixed!
-#endif
-
-#define MAX_CLUSTSIZE  65536
-#define DIRENTSPERBLOCK        (FS_BLOCK_SIZE/sizeof(dir_entry))
-#define DIRENTSPERCLUST        ((mydata->clust_size*SECTOR_SIZE)/sizeof(dir_entry))
+#define DIRENTSPERBLOCK        (mydata->sect_size / sizeof(dir_entry))
+#define DIRENTSPERCLUST        ((mydata->clust_size * mydata->sect_size) / \
+                        sizeof(dir_entry))
 
 #define FATBUFBLOCKS   6
-#define FATBUFSIZE     (FS_BLOCK_SIZE*FATBUFBLOCKS)
+#define FATBUFSIZE     (mydata->sect_size * FATBUFBLOCKS)
 #define FAT12BUFSIZE   ((FATBUFSIZE*2)/3)
 #define FAT16BUFSIZE   (FATBUFSIZE/2)
 #define FAT32BUFSIZE   (FATBUFSIZE/4)
 
+/* Maximum number of entry for long file name according to spec */
+#define MAX_LFN_SLOT   20
 
 /* Filesystem identifiers */
 #define FAT12_SIGN     "FAT12   "
 #define SIGNLEN                8
 
 /* File attributes */
-#define ATTR_RO      1
-#define ATTR_HIDDEN  2
-#define ATTR_SYS     4
-#define ATTR_VOLUME  8
-#define ATTR_DIR     16
-#define ATTR_ARCH    32
+#define ATTR_RO        1
+#define ATTR_HIDDEN    2
+#define ATTR_SYS       4
+#define ATTR_VOLUME    8
+#define ATTR_DIR       16
+#define ATTR_ARCH      32
 
-#define ATTR_VFAT     (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
+#define ATTR_VFAT      (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
 
 #define DELETED_FLAG   ((char)0xe5) /* Marks deleted files when in name[0] */
-#define aRING          0x05         /* Used to represent 'å' in name[0] */
+#define aRING          0x05         /* Used as special character in name[0] */
 
-/* Indicates that the entry is the last long entry in a set of long
+/*
+ * Indicates that the entry is the last long entry in a set of long
  * dir entries
  */
 #define LAST_LONG_ENTRY_MASK   0x40
 
-/* Flags telling whether we should read a file or list a directory */
-#define LS_NO  0
-#define LS_YES 1
-#define LS_DIR 1
-#define LS_ROOT        2
-
-#ifdef DEBUG
-#define FAT_DPRINT(args...)    printf(args)
-#else
-#define FAT_DPRINT(args...)
-#endif
-#define FAT_ERROR(arg)         printf(arg)
-
-#define ISDIRDELIM(c)   ((c) == '/' || (c) == '\\')
+#define ISDIRDELIM(c)  ((c) == '/' || (c) == '\\')
 
 #define FSTYPE_NONE    (-1)
 
 #endif
 #endif
 
-#define TOLOWER(c)     if((c) >= 'A' && (c) <= 'Z'){(c)+=('a' - 'A');}
 #define START(dent)    (FAT2CPU16((dent)->start) \
                        + (mydata->fatsize != 32 ? 0 : \
                          (FAT2CPU16((dent)->starthi) << 16)))
+#define IS_LAST_CLUST(x, fatsize) ((x) >= ((fatsize) != 32 ? \
+                                       ((fatsize) != 16 ? 0xff8 : 0xfff8) : \
+                                       0xffffff8))
 #define CHECK_CLUST(x, fatsize) ((x) <= 1 || \
-                               (x) >= ((fatsize) != 32 ? 0xfff0 : 0xffffff0))
+                               (x) >= ((fatsize) != 32 ? \
+                                       ((fatsize) != 16 ? 0xff0 : 0xfff0) : \
+                                       0xffffff0))
 
 typedef struct boot_sector {
        __u8    ignored[3];     /* Bootstrap code */
@@ -152,10 +127,14 @@ typedef struct volume_info
        /* Boot sign comes last, 2 bytes */
 } volume_info;
 
+/* see dir_entry::lcase: */
+#define CASE_LOWER_BASE        8       /* base (name) is lower case */
+#define CASE_LOWER_EXT 16      /* extension is lower case */
+
 typedef struct dir_entry {
        char    name[8],ext[3]; /* Name and extension */
        __u8    attr;           /* Attribute bits */
-       __u8    lcase;          /* Case for base and extension */
+       __u8    lcase;          /* Case for name and ext (CASE_LOWER_x) */
        __u8    ctime_ms;       /* Creation time, milliseconds */
        __u16   ctime;          /* Creation time */
        __u16   cdate;          /* Creation date */
@@ -166,55 +145,62 @@ typedef struct dir_entry {
 } dir_entry;
 
 typedef struct dir_slot {
-       __u8    id;             /* Sequence number for slot */
-       __u8    name0_4[10];    /* First 5 characters in name */
-       __u8    attr;           /* Attribute byte */
-       __u8    reserved;       /* Unused */
-       __u8    alias_checksum;/* Checksum for 8.3 alias */
-       __u8    name5_10[12];   /* 6 more characters in name */
-       __u16   start;          /* Unused */
-       __u8    name11_12[4];   /* Last 2 characters in name */
+       __u8    id;             /* Sequence number for slot */
+       __u8    name0_4[10];    /* First 5 characters in name */
+       __u8    attr;           /* Attribute byte */
+       __u8    reserved;       /* Unused */
+       __u8    alias_checksum;/* Checksum for 8.3 alias */
+       __u8    name5_10[12];   /* 6 more characters in name */
+       __u16   start;          /* Unused */
+       __u8    name11_12[4];   /* Last 2 characters in name */
 } dir_slot;
 
-/* Private filesystem parameters
+/*
+ * Private filesystem parameters
  *
  * Note: FAT buffer has to be 32 bit aligned
  * (see FAT32 accesses)
  */
 typedef struct {
-       __u8    fatbuf[FATBUFSIZE]; /* Current FAT buffer */
+       __u8    *fatbuf;        /* Current FAT buffer */
        int     fatsize;        /* Size of FAT in bits */
-       __u16   fatlength;      /* Length of FAT in sectors */
+       __u32   fatlength;      /* Length of FAT in sectors */
        __u16   fat_sect;       /* Starting sector of the FAT */
-       __u16   rootdir_sect;   /* Start sector of root directory */
+       __u8    fat_dirty;      /* Set if fatbuf has been modified */
+       __u32   rootdir_sect;   /* Start sector of root directory */
+       __u16   sect_size;      /* Size of sectors in bytes */
        __u16   clust_size;     /* Size of clusters in sectors */
-       short   data_begin;     /* The sector of the first cluster, can be negative */
+       int     data_begin;     /* The sector of the first cluster, can be negative */
        int     fatbufnum;      /* Used by get_fatent, init to -1 */
+       int     rootdir_size;   /* Size of root dir for non-FAT32 */
+       __u32   root_cluster;   /* First cluster of root dir for FAT32 */
 } fsdata;
 
-typedef int    (file_detectfs_func)(void);
-typedef int    (file_ls_func)(const char *dir);
-typedef long   (file_read_func)(const char *filename, void *buffer,
-                                unsigned long maxsize);
-
-struct filesystem {
-       file_detectfs_func *detect;
-       file_ls_func       *ls;
-       file_read_func     *read;
-       const char          name[12];
-};
-
-/* FAT tables */
-file_detectfs_func     file_fat_detectfs;
-file_ls_func           file_fat_ls;
-file_read_func         file_fat_read;
-
-/* Currently this doesn't check if the dir exists or is valid... */
-int file_cd(const char *path);
-int file_fat_detectfs(void);
-int file_fat_ls(const char *dir);
-long file_fat_read(const char *filename, void *buffer, unsigned long maxsize);
-const char *file_getfsname(int idx);
-int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
+static inline u32 clust_to_sect(fsdata *fsdata, u32 clust)
+{
+       return fsdata->data_begin + clust * fsdata->clust_size;
+}
+
+static inline u32 sect_to_clust(fsdata *fsdata, u32 sect)
+{
+       return (sect - fsdata->data_begin) / fsdata->clust_size;
+}
 
+int file_fat_detectfs(void);
+int fat_exists(const char *filename);
+int fat_size(const char *filename, loff_t *size);
+int file_fat_read_at(const char *filename, loff_t pos, void *buffer,
+                    loff_t maxsize, loff_t *actread);
+int file_fat_read(const char *filename, void *buffer, int maxsize);
+int fat_set_blk_dev(struct blk_desc *rbdd, disk_partition_t *info);
+int fat_register_device(struct blk_desc *dev_desc, int part_no);
+
+int file_fat_write(const char *filename, void *buf, loff_t offset, loff_t len,
+                  loff_t *actwrite);
+int fat_read_file(const char *filename, void *buf, loff_t offset, loff_t len,
+                 loff_t *actread);
+int fat_opendir(const char *filename, struct fs_dir_stream **dirsp);
+int fat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp);
+void fat_closedir(struct fs_dir_stream *dirs);
+void fat_close(void);
 #endif /* _FAT_H_ */