diff options
author | Greg Watson <jarrah@users.sourceforge.net> | 2004-03-17 17:03:02 +0000 |
---|---|---|
committer | Greg Watson <jarrah@users.sourceforge.net> | 2004-03-17 17:03:02 +0000 |
commit | 582231ed01d56381d0ac714a1157ffe739edcac4 (patch) | |
tree | 977da037e2c8f1954c2a2da941cf711a7758ba64 | |
parent | f6d05f501ec6a28fdc53e3876cab872c11e0ab73 (diff) |
FAT big endian changes
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1419 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
-rw-r--r-- | src/include/fs/fat.h | 42 | ||||
-rw-r--r-- | src/stream/fs/fat.c | 60 |
2 files changed, 61 insertions, 41 deletions
diff --git a/src/include/fs/fat.h b/src/include/fs/fat.h index 7fed6bacb3..d445ce84b1 100644 --- a/src/include/fs/fat.h +++ b/src/include/fs/fat.h @@ -42,25 +42,27 @@ struct fat_bpb { __u8 reserved_sects[2]; /* reserved sectors */ __u8 num_fats; /* number of FATs */ __u8 dir_entries[2]; /* root directory entries */ - __u8 short_sectors[2]; /* number of sectors */ + __u8 short_sectors[2];/* number of sectors */ __u8 media; /* media code (unused) */ - __u16 fat_length; /* sectors/FAT */ - __u16 secs_track; /* sectors per track */ - __u16 heads; /* number of heads */ - __u32 hidden; /* hidden sectors (unused) */ - __u32 long_sectors; /* number of sectors (if short_sectors == 0) */ + __u8 fat_length[2]; /* sectors/FAT */ + __u8 secs_track[2]; /* sectors per track */ + __u8 heads[2]; /* number of heads */ + __u8 hidden[2]; /* hidden sectors (unused) */ + __u8 long_sectors[2];/* number of sectors (if short_sectors == 0) */ /* The following fields are only used by FAT32 */ - __u32 fat32_length; /* sectors/FAT */ - __u16 flags; /* bit 8: fat mirroring, low 4: active fat */ + __u8 fat32_length[2];/* sectors/FAT */ + __u8 flags[2]; /* bit 8: fat mirroring, low 4: active fat */ __u8 version[2]; /* major, minor filesystem version */ - __u32 root_cluster; /* first cluster in root directory */ - __u16 info_sector; /* filesystem info sector */ - __u16 backup_boot; /* backup boot sector */ - __u16 reserved2[6]; /* Unused */ + __u8 root_cluster[4];/* first cluster in root directory */ + __u8 info_sector[2]; /* filesystem info sector */ + __u8 backup_boot[2]; /* backup boot sector */ + __u8 reserved2[12]; /* Unused */ }; -#define FAT_CVT_U16(bytarr) (* (__u16*)(bytarr)) +#define FAT_CVT_U8(byte) (* (__u8*)(byte)) +#define FAT_CVT_U16(bytarr) le16_to_cpu(* (__u16*)(bytarr)) +#define FAT_CVT_U32(bytarr) le32_to_cpu(* (__u32*)(bytarr)) /* * Defines how to differentiate a 12-bit and 16-bit FAT. @@ -84,17 +86,17 @@ struct fat_bpb { #define FAT_DIRENTRY_LENGTH 32 #define FAT_DIRENTRY_ATTRIB(entry) \ - (*((unsigned char *) (entry+11))) + FAT_CVT_U8(entry+11) #define FAT_DIRENTRY_VALID(entry) \ - ( ((*((unsigned char *) entry)) != 0) \ - && ((*((unsigned char *) entry)) != 0xE5) \ + ( (FAT_CVT_U8(entry) != 0) \ + && (FAT_CVT_U8(entry) != 0xE5) \ && !(FAT_DIRENTRY_ATTRIB(entry) & FAT_ATTRIB_NOT_OK_MASK) ) #define FAT_DIRENTRY_FIRST_CLUSTER(entry) \ - ((*((unsigned short *) (entry+26)))+(*((unsigned short *) (entry+20)) << 16)) + (FAT_CVT_U16(entry+26)+(FAT_CVT_U16(entry+20) << 16)) #define FAT_DIRENTRY_FILELENGTH(entry) \ - (*((unsigned long *) (entry+28))) + FAT_CVT_U32(entry+28) #define FAT_LONGDIR_ID(entry) \ - (*((unsigned char *) (entry))) + FAT_CVT_U8(entry) #define FAT_LONGDIR_ALIASCHECKSUM(entry) \ - (*((unsigned char *) (entry+13))) + FAT_CVT_U8(entry+13) diff --git a/src/stream/fs/fat.c b/src/stream/fs/fat.c index b657bfa3f6..aa64e584d6 100644 --- a/src/stream/fs/fat.c +++ b/src/stream/fs/fat.c @@ -17,8 +17,11 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <console/console.h> +#include <string.h> #include <fs/fs.h> #include <fs/fat.h> +#include <arch/byteorder.h> struct fat_superblock { @@ -72,8 +75,6 @@ __ilog2(unsigned long x) static __inline__ unsigned long log2(unsigned long x) { - if ((x = ~x) == 0) - return 32; return __ilog2(x & -x); } #endif @@ -98,24 +99,36 @@ fat_mount (void) zero division. */ if (bpb.sects_per_clust == 0) return 0; - - FAT_SUPER->sectsize_bits = log2 (FAT_CVT_U16 (bpb.bytes_per_sect)); + + FAT_SUPER->sectsize_bits = log2(FAT_CVT_U16(bpb.bytes_per_sect)); FAT_SUPER->clustsize_bits - = FAT_SUPER->sectsize_bits + log2 (bpb.sects_per_clust); + = FAT_SUPER->sectsize_bits + log2(bpb.sects_per_clust); + +printk_debug("BytsPerSec = %d\n", FAT_CVT_U16(bpb.bytes_per_sect)); +printk_debug("SecPerClus = %d\n", bpb.sects_per_clust); /* Fill in info about super block */ - FAT_SUPER->num_sectors = FAT_CVT_U16 (bpb.short_sectors) - ? FAT_CVT_U16 (bpb.short_sectors) : bpb.long_sectors; + FAT_SUPER->num_sectors = FAT_CVT_U16(bpb.short_sectors) + ? FAT_CVT_U16(bpb.short_sectors) : FAT_CVT_U32(bpb.long_sectors); + +printk_debug("TotSec16 = %d\n", FAT_CVT_U16(bpb.short_sectors)); +printk_debug("TotSec32 = %d\n", FAT_CVT_U32(bpb.long_sectors)); /* FAT offset and length */ - FAT_SUPER->fat_offset = FAT_CVT_U16 (bpb.reserved_sects); - FAT_SUPER->fat_length = - bpb.fat_length ? bpb.fat_length : bpb.fat32_length; + FAT_SUPER->fat_offset = FAT_CVT_U16(bpb.reserved_sects); + FAT_SUPER->fat_length = FAT_CVT_U16(bpb.fat_length) + ? FAT_CVT_U16(bpb.fat_length) : FAT_CVT_U32(bpb.fat32_length); + +printk_debug("RsvdSecCnt = %d\n", FAT_CVT_U16(bpb.reserved_sects)); +printk_debug("FATSx16 = %d\n", FAT_CVT_U16(bpb.fat_length)); +printk_debug("FATSx32 = %d\n", FAT_CVT_U32(bpb.fat32_length)); /* Rootdir offset and length for FAT12/16 */ FAT_SUPER->root_offset = FAT_SUPER->fat_offset + bpb.num_fats * FAT_SUPER->fat_length; FAT_SUPER->root_max = FAT_DIRENTRY_LENGTH * FAT_CVT_U16(bpb.dir_entries); + +printk_debug("RootEntCnt = %d\n", FAT_CVT_U16(bpb.dir_entries)); /* Data offset and number of clusters */ FAT_SUPER->data_offset = @@ -125,24 +138,27 @@ fat_mount (void) 2 + ((FAT_SUPER->num_sectors - FAT_SUPER->data_offset) / bpb.sects_per_clust); FAT_SUPER->sects_per_clust = bpb.sects_per_clust; - + if (!bpb.fat_length) { /* This is a FAT32 */ if (FAT_CVT_U16(bpb.dir_entries)) return 0; - if (bpb.flags & 0x0080) +printk_debug("We seem to be FAT32\n"); +printk_debug("ExtFlags = 0x%x\n", FAT_CVT_U16(bpb.flags)); +printk_debug("RootClus = %d\n", FAT_CVT_U32(bpb.root_cluster)); + if (FAT_CVT_U16(bpb.flags) & 0x0080) { /* FAT mirroring is disabled, get active FAT */ - int active_fat = bpb.flags & 0x000f; + int active_fat = FAT_CVT_U16(bpb.flags) & 0x000f; if (active_fat >= bpb.num_fats) return 0; FAT_SUPER->fat_offset += active_fat * FAT_SUPER->fat_length; } FAT_SUPER->fat_size = 8; - FAT_SUPER->root_cluster = bpb.root_cluster; + FAT_SUPER->root_cluster = FAT_CVT_U32(bpb.root_cluster); /* Yes the following is correct. FAT32 should be called FAT28 :) */ FAT_SUPER->clust_eof_marker = 0xffffff8; @@ -152,6 +168,7 @@ fat_mount (void) if (!FAT_SUPER->root_max) return 0; +printk_debug("We seem to be FAT12/16\n"); FAT_SUPER->root_cluster = -1; if (FAT_SUPER->num_clust > FAT_MAX_12BIT_CLUST) { @@ -165,7 +182,6 @@ fat_mount (void) } } - /* Now do some sanity checks */ if (FAT_CVT_U16(bpb.bytes_per_sect) != (1 << FAT_SUPER->sectsize_bits) @@ -183,19 +199,21 @@ fat_mount (void) sizeof(first_fat), (char *)&first_fat)) return 0; +printk_debug("Media = 0x%x\n", bpb.media); + if (FAT_SUPER->fat_size == 8) { - first_fat &= 0x0fffffff; + first_fat = le32_to_cpu(first_fat) & 0x0fffffff; magic = 0x0fffff00; } else if (FAT_SUPER->fat_size == 4) { - first_fat &= 0x0000ffff; + first_fat = le32_to_cpu(first_fat) & 0x0000ffff; magic = 0xff00; } else { - first_fat &= 0x00000fff; + first_fat = le32_to_cpu(first_fat) & 0x00000fff; magic = 0x0f00; } @@ -255,7 +273,7 @@ fat_read (char *buf, int len) if (!devread (sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF)) return 0; } - next_cluster = * (unsigned long *) (FAT_BUF + (cached_pos >> 1)); + next_cluster = FAT_CVT_U32(FAT_BUF + (cached_pos >> 1)); if (FAT_SUPER->fat_size == 3) { if (cached_pos & 1) @@ -288,7 +306,7 @@ fat_read (char *buf, int len) devread(sector, offset, size, buf); - disk_read_func = NULL; + disk_read_func = 0; len -= size; buf += size; @@ -317,7 +335,7 @@ fat_dir (char *dirname) { 1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30 }; int slot = -2; int alias_checksum = -1; - + FAT_SUPER->file_cluster = FAT_SUPER->root_cluster; filepos = 0; FAT_SUPER->current_cluster_num = MAXINT; |