Skip to contentSkip to conversation

Remove non-ascii characters from fat code

PATCH New Remy Bohmer 2 participants 4 messages Nov 27, 2008 – Dec 7, 2008 1 message not in the archive

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#3 lore raw

PATCH 2/2 Cleanup patch Fat on non standard sector sizedevices

Dear Remy,

I have checked patches and I think there are OK.

Also, I have aplied [patch 1/2] and [patch 2/2] on git u-boot version. Then I have copied patched files (fat.h and fat.c) on our customized u-boot-1.1.6 version. Finally I have built and installed u-boot on our custom board.

I have executed fatls and fatload commands with our 2048 bytes sector USB pendrive and IT WORKS !!!!

Thanks a lot for your help.

El jue, 27-11-2008 a las 22:30 +0100, Remy Bohmer escribi?:

Quoted 348 lines

documento de texto sencillo adjunto (fat-on-non-standard-sector-size-devices.patch)
The patch below is a patch originally posted by Igor Luri. However, the patch posted on the mailinglist was not readable (base64) and thus not mergable or testable. Also tabs/spaces were malformed.

So, I merged the whole patch by hand and posted it again.

Igor can you please check if I did this cleanup properly.

Notice that the code that is being modified here does not match _any_ coding rule standard and is actually a big mess. So, I did not focus on the Coding Rules too much for this patch.
I will post a seperate patch to fix this for the complete files also.
----------------
There are USB devices with sector size different than 512 bytes. In fact, I have one with 2048 bytes per sector:

scsi0 : SCSI emulation for USB Mass Storage devices
Vendor: ChipsBnk Model: Flash Disk Rev: 4.00
Type: Direct-Access ANSI SCSI revision: 02
Attached scsi removable disk sda at scsi0, channel 0, id 0, lun 0 SCSI device sda: 129124 2048-byte hdwr sectors (264 MB)
sda: Write Protect is off
Partition check:
sda: sda1 sda2 sda3 sda4

U-boot FAT filesystem code supposes that sector size is always 512 bytes, consecuently fatload and fatls commands ends up with a segmentation fault.

Attached patches adds FAT support on devices with sector size up to 8192 bytes.

---
 fs/fat/fat.c  |   89 ++++++++++++++++++++++++++++++++++++++++------------------
 include/fat.h |   18 +++--------
 2 files changed, 68 insertions(+), 39 deletions(-)

Index: u-boot-usb.new/fs/fat/fat.c
===================================================================

fs/fat/fat.c +62 -27
@@ -30,6 +30,7 @@
 #include <fat.h>
 #include <asm/byteorder.h>
 #include <part.h>
+#include <malloc.h>
 
 /*
  * Convert a string to lowercase.
@@ -67,12 +68,17 @@ int disk_read (__u32 startblock, __u32 g
 int
 fat_register_device(block_dev_desc_t *dev_desc, int part_no)
 {
-	unsigned char buffer[SECTOR_SIZE];
+	unsigned char *buffer;
 	disk_partition_t info;
 
 	if (!dev_desc->block_read)
 		return -1;
 	cur_dev = dev_desc;
+
+	buffer = malloc(cur_dev->blksz);
+	if (!buffer)
+		return -1;
+
 	/* check if we have a MBR (on floppies we have only a PBR) */
 	if (dev_desc->block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) {
 		printf ("** Can't read from device %d **\n", dev_desc->dev);
@@ -118,6 +124,7 @@ fat_register_device(block_dev_desc_t *de
 		cur_part = 1;
 	}
 #endif
+	free(buffer);
 	return 0;
 }
 
@@ -220,12 +227,12 @@ get_fatent(fsdata *mydata, __u32 entry)
 
 	/* Read a new block of FAT entries into the cache. */
 	if (bufnum != mydata->fatbufnum) {
-		int getsize = FATBUFSIZE/FS_BLOCK_SIZE;
+		int getsize = FATBUFSIZE / mydata->sector_size;
 		__u8 *bufptr = mydata->fatbuf;
 		__u32 fatlength = mydata->fatlength;
 		__u32 startblock = bufnum * FATBUFBLOCKS;
 
-		fatlength *= SECTOR_SIZE;	/* We want it in bytes now */
+		fatlength *= mydata->sector_size; /* We want it in bytes now */
 		startblock += mydata->fat_sect;	/* Offset from start of disk */
 
 		if (getsize > fatlength) getsize = fatlength;
@@ -300,20 +307,25 @@ get_cluster(fsdata *mydata, __u32 clustn
 	}
 
 	FAT_DPRINT("gc - clustnum: %d, startsect: %d\n", clustnum, startsect);
-	if (disk_read(startsect, size/FS_BLOCK_SIZE , buffer) < 0) {
+	if (disk_read(startsect, size / mydata->sector_size, buffer) < 0) {
 		FAT_DPRINT("Error reading data\n");
 		return -1;
 	}
-	if(size % FS_BLOCK_SIZE) {
-		__u8 tmpbuf[FS_BLOCK_SIZE];
-		idx= size/FS_BLOCK_SIZE;
+	if (size % mydata->sector_size) {
+		__u8 *tmpbuf;
+
+		tmpbuf = (__u8 *) malloc(mydata->sector_size);
+		if (!tmpbuf)
+			return -1;
+		idx = size / mydata->sector_size;
 		if (disk_read(startsect + idx, 1, tmpbuf) < 0) {
 			FAT_DPRINT("Error reading data\n");
 			return -1;
 		}
-		buffer += idx*FS_BLOCK_SIZE;
+		buffer += idx * mydata->sector_size;
 
-		memcpy(buffer, tmpbuf, size % FS_BLOCK_SIZE);
+		memcpy(buffer, tmpbuf, size % mydata->sector_size);
+		free(tmpbuf);
 		return 0;
 	}
 
@@ -331,7 +343,7 @@ get_contents(fsdata *mydata, dir_entry *
 	     unsigned long maxsize)
 {
 	unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;
-	unsigned int bytesperclust = mydata->clust_size * SECTOR_SIZE;
+	unsigned int bytesperclust = mydata->clust_size * mydata->sector_size;
 	__u32 curclust = START(dentptr);
 	__u32 endclust, newclust;
 	unsigned long actsize;
@@ -440,7 +452,8 @@ get_vfatname(fsdata *mydata, int curclus
 {
 	dir_entry *realdent;
 	dir_slot  *slotptr = (dir_slot*) retdent;
-	__u8	  *nextclust = cluster + mydata->clust_size * SECTOR_SIZE;
+	__u8      *nextclust = cluster +
+			       mydata->clust_size * mydata->sector_size;
 	__u8	   counter = (slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff;
 	int idx = 0;
 
@@ -463,7 +476,7 @@ get_vfatname(fsdata *mydata, int curclus
 			return -1;
 		}
 		if (get_cluster(mydata, curclust, get_vfatname_block,
-				mydata->clust_size * SECTOR_SIZE) != 0) {
+			   mydata->clust_size * mydata->sector_size) != 0) {
 			FAT_DPRINT("Error: reading directory block\n");
 			return -1;
 		}
@@ -533,8 +546,8 @@ static dir_entry *get_dentfromdir (fsdat
 	dir_entry *dentptr;
 	int i;
 
-	if (get_cluster (mydata, curclust, get_dentfromdir_block,
-		 mydata->clust_size * SECTOR_SIZE) != 0) {
+	if (get_cluster(mydata, curclust, get_dentfromdir_block,
+			mydata->clust_size * mydata->sector_size) != 0) {
 	    FAT_DPRINT ("Error: reading directory block\n");
 	    return NULL;
 	}
@@ -667,9 +680,16 @@ static dir_entry *get_dentfromdir (fsdat
 static int
 read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize)
 {
-	__u8 block[FS_BLOCK_SIZE];
+	__u8 *block;
 	volume_info *vistart;
 
+	if (!cur_dev)
+		return -1;
+
+	block = (__u8 *)malloc(cur_dev->blksz);
+	if (!block)
+		return -1;
+
 	if (disk_read(0, 1, block) < 0) {
 		FAT_DPRINT("Error: reading block\n");
 		return -1;
@@ -680,6 +700,7 @@ read_bootsectandvi(boot_sector *bs, volu
 	bs->fat_length	= FAT2CPU16(bs->fat_length);
 	bs->secs_track	= FAT2CPU16(bs->secs_track);
 	bs->heads	= FAT2CPU16(bs->heads);
+	*(__u16 *)bs->sector_size = FAT2CPU16(*(__u16 *)bs->sector_size);
 #if 0 /* UNUSED */
 	bs->hidden	= FAT2CPU32(bs->hidden);
 #endif
@@ -704,7 +725,7 @@ read_bootsectandvi(boot_sector *bs, volu
 	/* Terminate fs_type string. Writing past the end of vistart
 	   is ok - it's just the buffer. */
 	vistart->fs_type[8] = '\0';
-
+	free(block);
 	if (*fatsize == 32) {
 		if (compare_sign(FAT32_SIGN, vistart->fs_type) == 0) {
 			return 0;
@@ -757,6 +778,7 @@ do_fat_read (const char *filename, void 
 	mydata->fatlength = bs.fat_length;
     }
     mydata->fat_sect = bs.reserved;
+    mydata->sector_size = *(__u16 *)bs.sector_size;
     cursect = mydata->rootdir_sect
 	    = mydata->fat_sect + mydata->fatlength * bs.fats;
     mydata->clust_size = bs.cluster_size;
@@ -766,17 +788,21 @@ do_fat_read (const char *filename, void 
 		- (mydata->clust_size * 2);
     } else {
 	rootdir_size = ((bs.dir_entries[1] * (int) 256 + bs.dir_entries[0])
-			* sizeof (dir_entry)) / SECTOR_SIZE;
+			* sizeof (dir_entry)) / mydata->sector_size;
 	mydata->data_begin = mydata->rootdir_sect + rootdir_size
 		- (mydata->clust_size * 2);
     }
     mydata->fatbufnum = -1;
+    mydata->fatbuf = (__u8 *) malloc(FATBUFSIZE);
+    if (!mydata->fatbuf)
+	return -1;
 
     FAT_DPRINT ("FAT%d, fatlength: %d\n", mydata->fatsize,
 		mydata->fatlength);
     FAT_DPRINT ("Rootdir begins at sector: %d, offset: %x, size: %d\n"
 		"Data begins at: %d\n",
-		mydata->rootdir_sect, mydata->rootdir_sect * SECTOR_SIZE,
+		mydata->rootdir_sect,
+		mydata->rootdir_sect * mydata->sector_size,
 		rootdir_size, mydata->data_begin);
     FAT_DPRINT ("Cluster size: %d\n", mydata->clust_size);
 
@@ -787,8 +813,10 @@ do_fat_read (const char *filename, void 
     strcpy (fnamecopy, filename);
     downcase (fnamecopy);
     if (*fnamecopy == '\0') {
-	if (!dols)
-	    return -1;
+	if (!dols) {
+		free(mydata->fatbuf);
+		return -1;
+	}
 	dols = LS_ROOT;
     } else if ((idx = dirdelim (fnamecopy)) >= 0) {
 	isdir = 1;
@@ -805,8 +833,9 @@ do_fat_read (const char *filename, void 
 	int i;
 
 	if (disk_read (cursect, mydata->clust_size, do_fat_read_block) < 0) {
-	    FAT_DPRINT ("Error: reading rootdir block\n");
-	    return -1;
+		FAT_DPRINT ("Error: reading rootdir block\n");
+		free(mydata->fatbuf);
+		return -1;
 	}
 	dentptr = (dir_entry *) do_fat_read_block;
 	for (i = 0; i < DIRENTSPERBLOCK; i++) {
@@ -856,6 +885,7 @@ do_fat_read (const char *filename, void 
 		    continue;
 		}
 	    } else if (dentptr->name[0] == 0) {
+		free(mydata->fatbuf);
 		FAT_DPRINT ("RootDentname == NULL - %d\n", i);
 		if (dols == LS_ROOT) {
 		    printf ("\n%d file(s), %d dir(s)\n\n", files, dirs);
@@ -906,9 +936,10 @@ do_fat_read (const char *filename, void 
 		dentptr++;
 		continue;
 	    }
-	    if (isdir && !(dentptr->attr & ATTR_DIR))
+	    if (isdir && !(dentptr->attr & ATTR_DIR)) {
+		free(mydata->fatbuf);
 		return -1;
-
+	    }
 	    FAT_DPRINT ("RootName: %s", s_name);
 	    FAT_DPRINT (", start: 0x%x", START (dentptr));
 	    FAT_DPRINT (", size:  0x%x %s\n",
@@ -949,20 +980,24 @@ do_fat_read (const char *filename, void 
 
 	if (get_dentfromdir (mydata, startsect, subname, dentptr,
 			     isdir ? 0 : dols) == NULL) {
+	    free(mydata->fatbuf);
 	    if (dols && !isdir)
 		return 0;
 	    return -1;
 	}
 
 	if (idx >= 0) {
-	    if (!(dentptr->attr & ATTR_DIR))
-		return -1;
-	    subname = nextname;
+		if (!(dentptr->attr & ATTR_DIR)) {
+			free(mydata->fatbuf);
+			return -1;
+		}
+		subname = nextname;
 	}
     }
     ret = get_contents (mydata, dentptr, buffer, maxsize);
     FAT_DPRINT ("Size: %d, got: %ld\n", FAT2CPU32 (dentptr->size), ret);
 
+    free(mydata->fatbuf);
     return ret;
 }
 

Index: u-boot-usb.new/include/fat.h
===================================================================

include/fat.h +6 -12
@@ -31,20 +31,13 @@
 
 #define CONFIG_SUPPORT_VFAT
 
-#define SECTOR_SIZE FS_BLOCK_SIZE
-
-#define FS_BLOCK_SIZE 512
-
-#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->sector_size / sizeof(dir_entry))
+#define DIRENTSPERCLUST ((mydata->clust_size * mydata->sector_size) / \
+							     sizeof(dir_entry))
 
 #define FATBUFBLOCKS	6
-#define FATBUFSIZE	(FS_BLOCK_SIZE*FATBUFBLOCKS)
+#define FATBUFSIZE      (mydata->sector_size * FATBUFBLOCKS)
 #define FAT12BUFSIZE	((FATBUFSIZE*2)/3)
 #define FAT16BUFSIZE	(FATBUFSIZE/2)
 #define FAT32BUFSIZE	(FATBUFSIZE/4)
@@ -182,8 +175,9 @@ typedef struct dir_slot {
  * (see FAT32 accesses)
  */
 typedef struct {
-	__u8	fatbuf[FATBUFSIZE]; /* Current FAT buffer */
+	__u8    *fatbuf;	/* Current FAT buffer */
 	int	fatsize;	/* Size of FAT in bits */
+	__u16   sector_size;	/* Sector size */
 	__u16	fatlength;	/* Length of FAT in sectors */
 	__u16	fat_sect;	/* Starting sector of the FAT */
 	__u16	rootdir_sect;	/* Start sector of root directory */
Signature · 9 lines
Igor Luri
R&D Software Department
Fagor Aotek S. Coop.
P. O. Box 144
E-20500 Mondrag?n-Arrasate
Tel.    ++34 943 71 92 00 
        ++34 943 71 92 01 (Ext. 44268)
Fax.    ++34 943 79 92 03
www.aotek.es
#4 lore raw

PATCH 2/2 Cleanup patch Fat on non standard sector sizedevices

Hello Igor,

2008/11/28 Igor Luri <[email protected]>:

Quoted 9 lines

Dear Remy,

I have checked patches and I think there are OK.
Also, I have aplied [patch 1/2] and [patch 2/2] on git u-boot version. Then I have copied patched files (fat.h and fat.c) on our customized u-boot-1.1.6 version. Finally I have built and installed u-boot on our custom board.
I have executed fatls and fatload commands with our 2048 bytes sector USB pendrive and IT WORKS !!!!

Status update:
I have put this patch in the u-boot-usb 'debug' branch.
It is pending there because I found a regression problem on some boards with 512 bytes sector sized USB sticks, which work without this patch. I did not found the time yet to debug this problem, because of debugging another problem...
I hope you can find some time to look into this patch and see what is going wrong here.
You can use the debug branch of the u-boot-usb tree.

Please let me know...

Kind Regards,

Remy

Quoted 365 lines

Thanks a lot for your help.

El jue, 27-11-2008 a las 22:30 +0100, Remy Bohmer escribi?:

Quoted 338 lines

documento de texto sencillo adjunto (fat-on-non-standard-sector-size-devices.patch)
The patch below is a patch originally posted by Igor Luri. However, the patch posted on the mailinglist was not readable (base64) and thus not mergable or testable. Also tabs/spaces were malformed.

So, I merged the whole patch by hand and posted it again.

Igor can you please check if I did this cleanup properly.

Notice that the code that is being modified here does not match _any_ coding rule standard and is actually a big mess. So, I did not focus on the Coding Rules too much for this patch.
I will post a seperate patch to fix this for the complete files also.
----------------
There are USB devices with sector size different than 512 bytes. In fact, I have one with 2048 bytes per sector:

scsi0 : SCSI emulation for USB Mass Storage devices
Vendor: ChipsBnk Model: Flash Disk Rev: 4.00
Type: Direct-Access ANSI SCSI revision: 02
Attached scsi removable disk sda at scsi0, channel 0, id 0, lun 0 SCSI device sda: 129124 2048-byte hdwr sectors (264 MB)
sda: Write Protect is off
Partition check:
sda: sda1 sda2 sda3 sda4

U-boot FAT filesystem code supposes that sector size is always 512 bytes, consecuently fatload and fatls commands ends up with a segmentation fault.

Attached patches adds FAT support on devices with sector size up to 8192 bytes.

---
 fs/fat/fat.c  |   89 ++++++++++++++++++++++++++++++++++++++++------------------
 include/fat.h |   18 +++--------
 2 files changed, 68 insertions(+), 39 deletions(-)

Index: u-boot-usb.new/fs/fat/fat.c
===================================================================

fs/fat/fat.c 2008-11-27 22:10:40.000000000 +0100 renamed from fs/fat/fat.c 2008-11-27 21:40:25.000000000 +0100 +62 -27
@@ -30,6 +30,7 @@
 #include <fat.h>
 #include <asm/byteorder.h>
 #include <part.h>
+#include <malloc.h>
 
 /*
  * Convert a string to lowercase.
@@ -67,12 +68,17 @@ int disk_read (__u32 startblock, __u32 g
 int
 fat_register_device(block_dev_desc_t *dev_desc, int part_no)
 {
-     unsigned char buffer[SECTOR_SIZE];
+     unsigned char *buffer;
      disk_partition_t info;
 
      if (!dev_desc->block_read)
              return -1;
      cur_dev = dev_desc;
+
+     buffer = malloc(cur_dev->blksz);
+     if (!buffer)
+             return -1;
+
      /* check if we have a MBR (on floppies we have only a PBR) */
      if (dev_desc->block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) {
              printf ("** Can't read from device %d **\n", dev_desc->dev);
@@ -118,6 +124,7 @@ fat_register_device(block_dev_desc_t *de
              cur_part = 1;
      }
 #endif
+     free(buffer);
      return 0;
 }
 
@@ -220,12 +227,12 @@ get_fatent(fsdata *mydata, __u32 entry)
 
      /* Read a new block of FAT entries into the cache. */
      if (bufnum != mydata->fatbufnum) {
-             int getsize = FATBUFSIZE/FS_BLOCK_SIZE;
+             int getsize = FATBUFSIZE / mydata->sector_size;
              __u8 *bufptr = mydata->fatbuf;
              __u32 fatlength = mydata->fatlength;
              __u32 startblock = bufnum * FATBUFBLOCKS;
 
-             fatlength *= SECTOR_SIZE;       /* We want it in bytes now */
+             fatlength *= mydata->sector_size; /* We want it in bytes now */
              startblock += mydata->fat_sect; /* Offset from start of disk */
 
              if (getsize > fatlength) getsize = fatlength;
@@ -300,20 +307,25 @@ get_cluster(fsdata *mydata, __u32 clustn
      }
 
      FAT_DPRINT("gc - clustnum: %d, startsect: %d\n", clustnum, startsect);
-     if (disk_read(startsect, size/FS_BLOCK_SIZE , buffer) < 0) {
+     if (disk_read(startsect, size / mydata->sector_size, buffer) < 0) {
              FAT_DPRINT("Error reading data\n");
              return -1;
      }
-     if(size % FS_BLOCK_SIZE) {
-             __u8 tmpbuf[FS_BLOCK_SIZE];
-             idx= size/FS_BLOCK_SIZE;
+     if (size % mydata->sector_size) {
+             __u8 *tmpbuf;
+
+             tmpbuf = (__u8 *) malloc(mydata->sector_size);
+             if (!tmpbuf)
+                     return -1;
+             idx = size / mydata->sector_size;
              if (disk_read(startsect + idx, 1, tmpbuf) < 0) {
                      FAT_DPRINT("Error reading data\n");
                      return -1;
              }
-             buffer += idx*FS_BLOCK_SIZE;
+             buffer += idx * mydata->sector_size;
 
-             memcpy(buffer, tmpbuf, size % FS_BLOCK_SIZE);
+             memcpy(buffer, tmpbuf, size % mydata->sector_size);
+             free(tmpbuf);
              return 0;
      }
 
@@ -331,7 +343,7 @@ get_contents(fsdata *mydata, dir_entry *
           unsigned long maxsize)
 {
      unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;
-     unsigned int bytesperclust = mydata->clust_size * SECTOR_SIZE;
+     unsigned int bytesperclust = mydata->clust_size * mydata->sector_size;
      __u32 curclust = START(dentptr);
      __u32 endclust, newclust;
      unsigned long actsize;
@@ -440,7 +452,8 @@ get_vfatname(fsdata *mydata, int curclus
 {
      dir_entry *realdent;
      dir_slot  *slotptr = (dir_slot*) retdent;
-     __u8      *nextclust = cluster + mydata->clust_size * SECTOR_SIZE;
+     __u8      *nextclust = cluster +
+                            mydata->clust_size * mydata->sector_size;
      __u8       counter = (slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff;
      int idx = 0;
 
@@ -463,7 +476,7 @@ get_vfatname(fsdata *mydata, int curclus
                      return -1;
              }
              if (get_cluster(mydata, curclust, get_vfatname_block,
-                             mydata->clust_size * SECTOR_SIZE) != 0) {
+                        mydata->clust_size * mydata->sector_size) != 0) {
                      FAT_DPRINT("Error: reading directory block\n");
                      return -1;
              }
@@ -533,8 +546,8 @@ static dir_entry *get_dentfromdir (fsdat
      dir_entry *dentptr;
      int i;
 
-     if (get_cluster (mydata, curclust, get_dentfromdir_block,
-              mydata->clust_size * SECTOR_SIZE) != 0) {
+     if (get_cluster(mydata, curclust, get_dentfromdir_block,
+                     mydata->clust_size * mydata->sector_size) != 0) {
          FAT_DPRINT ("Error: reading directory block\n");
          return NULL;
      }
@@ -667,9 +680,16 @@ static dir_entry *get_dentfromdir (fsdat
 static int
 read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize)
 {
-     __u8 block[FS_BLOCK_SIZE];
+     __u8 *block;
      volume_info *vistart;
 
+     if (!cur_dev)
+             return -1;
+
+     block = (__u8 *)malloc(cur_dev->blksz);
+     if (!block)
+             return -1;
+
      if (disk_read(0, 1, block) < 0) {
              FAT_DPRINT("Error: reading block\n");
              return -1;
@@ -680,6 +700,7 @@ read_bootsectandvi(boot_sector *bs, volu
      bs->fat_length  = FAT2CPU16(bs->fat_length);
      bs->secs_track  = FAT2CPU16(bs->secs_track);
      bs->heads       = FAT2CPU16(bs->heads);
+     *(__u16 *)bs->sector_size = FAT2CPU16(*(__u16 *)bs->sector_size);
 #if 0 /* UNUSED */
      bs->hidden      = FAT2CPU32(bs->hidden);
 #endif
@@ -704,7 +725,7 @@ read_bootsectandvi(boot_sector *bs, volu
      /* Terminate fs_type string. Writing past the end of vistart
         is ok - it's just the buffer. */
      vistart->fs_type[8] = '\0';
-
+     free(block);
      if (*fatsize == 32) {
              if (compare_sign(FAT32_SIGN, vistart->fs_type) == 0) {
                      return 0;
@@ -757,6 +778,7 @@ do_fat_read (const char *filename, void
      mydata->fatlength = bs.fat_length;
     }
     mydata->fat_sect = bs.reserved;
+    mydata->sector_size = *(__u16 *)bs.sector_size;
     cursect = mydata->rootdir_sect
          = mydata->fat_sect + mydata->fatlength * bs.fats;
     mydata->clust_size = bs.cluster_size;
@@ -766,17 +788,21 @@ do_fat_read (const char *filename, void
              - (mydata->clust_size * 2);
     } else {
      rootdir_size = ((bs.dir_entries[1] * (int) 256 + bs.dir_entries[0])
-                     * sizeof (dir_entry)) / SECTOR_SIZE;
+                     * sizeof (dir_entry)) / mydata->sector_size;
      mydata->data_begin = mydata->rootdir_sect + rootdir_size
              - (mydata->clust_size * 2);
     }
     mydata->fatbufnum = -1;
+    mydata->fatbuf = (__u8 *) malloc(FATBUFSIZE);
+    if (!mydata->fatbuf)
+     return -1;
 
     FAT_DPRINT ("FAT%d, fatlength: %d\n", mydata->fatsize,
              mydata->fatlength);
     FAT_DPRINT ("Rootdir begins at sector: %d, offset: %x, size: %d\n"
              "Data begins at: %d\n",
-             mydata->rootdir_sect, mydata->rootdir_sect * SECTOR_SIZE,
+             mydata->rootdir_sect,
+             mydata->rootdir_sect * mydata->sector_size,
              rootdir_size, mydata->data_begin);
     FAT_DPRINT ("Cluster size: %d\n", mydata->clust_size);
 
@@ -787,8 +813,10 @@ do_fat_read (const char *filename, void
     strcpy (fnamecopy, filename);
     downcase (fnamecopy);
     if (*fnamecopy == '\0') {
-     if (!dols)
-         return -1;
+     if (!dols) {
+             free(mydata->fatbuf);
+             return -1;
+     }
      dols = LS_ROOT;
     } else if ((idx = dirdelim (fnamecopy)) >= 0) {
      isdir = 1;
@@ -805,8 +833,9 @@ do_fat_read (const char *filename, void
      int i;
 
      if (disk_read (cursect, mydata->clust_size, do_fat_read_block) < 0) {
-         FAT_DPRINT ("Error: reading rootdir block\n");
-         return -1;
+             FAT_DPRINT ("Error: reading rootdir block\n");
+             free(mydata->fatbuf);
+             return -1;
      }
      dentptr = (dir_entry *) do_fat_read_block;
      for (i = 0; i < DIRENTSPERBLOCK; i++) {
@@ -856,6 +885,7 @@ do_fat_read (const char *filename, void
                  continue;
              }
          } else if (dentptr->name[0] == 0) {
+             free(mydata->fatbuf);
              FAT_DPRINT ("RootDentname == NULL - %d\n", i);
              if (dols == LS_ROOT) {
                  printf ("\n%d file(s), %d dir(s)\n\n", files, dirs);
@@ -906,9 +936,10 @@ do_fat_read (const char *filename, void
              dentptr++;
              continue;
          }
-         if (isdir && !(dentptr->attr & ATTR_DIR))
+         if (isdir && !(dentptr->attr & ATTR_DIR)) {
+             free(mydata->fatbuf);
              return -1;
-
+         }
          FAT_DPRINT ("RootName: %s", s_name);
          FAT_DPRINT (", start: 0x%x", START (dentptr));
          FAT_DPRINT (", size:  0x%x %s\n",
@@ -949,20 +980,24 @@ do_fat_read (const char *filename, void
 
      if (get_dentfromdir (mydata, startsect, subname, dentptr,
                           isdir ? 0 : dols) == NULL) {
+         free(mydata->fatbuf);
          if (dols && !isdir)
              return 0;
          return -1;
      }
 
      if (idx >= 0) {
-         if (!(dentptr->attr & ATTR_DIR))
-             return -1;
-         subname = nextname;
+             if (!(dentptr->attr & ATTR_DIR)) {
+                     free(mydata->fatbuf);
+                     return -1;
+             }
+             subname = nextname;
      }
     }
     ret = get_contents (mydata, dentptr, buffer, maxsize);
     FAT_DPRINT ("Size: %d, got: %ld\n", FAT2CPU32 (dentptr->size), ret);
 
+    free(mydata->fatbuf);
     return ret;
 }
 

Index: u-boot-usb.new/include/fat.h
===================================================================

include/fat.h 2008-11-27 21:45:13.000000000 +0100 renamed from include/fat.h 2008-11-27 21:40:17.000000000 +0100 +4 -11
@@ -31,20 +31,13 @@
 
 #define CONFIG_SUPPORT_VFAT
 
-#define SECTOR_SIZE FS_BLOCK_SIZE
-
-#define FS_BLOCK_SIZE 512
-
-#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->sector_size / sizeof(dir_entry))
+#define DIRENTSPERCLUST ((mydata->clust_size * mydata->sector_size) / \
+                                                          sizeof(dir_entry))
 
 #define FATBUFBLOCKS 6
-#define FATBUFSIZE   (FS_BLOCK_SIZE*FATBUFBLOCKS)
+#define FATBUFSIZE      (mydata->sector_size * FATBUFBLOCKS)
 #define FAT12BUFSIZE ((FATBUFSIZE*2)/3)
 #define FAT16BUFSIZE (FATBUFSIZE/2)
 #define FAT32BUFSIZE (FATBUFSIZE/4)

include/fat.h 2008-11-27 21:45:13.000000000 +0100 typedef struct dir_slot { · line 183

Quoted 10 lines
include/fat.h 2008-11-27 21:45:13.000000000 +0100 renamed from include/fat.h 2008-11-27 21:40:17.000000000 +0100 +2 -1
@@ -182,8 +175,9 @@ typedef struct dir_slot {
  * (see FAT32 accesses)
  */
 typedef struct {
-     __u8    fatbuf[FATBUFSIZE]; /* Current FAT buffer */
+     __u8    *fatbuf;        /* Current FAT buffer */
      int     fatsize;        /* Size of FAT in bits */
+     __u16   sector_size;    /* Sector size */
      __u16   fatlength;      /* Length of FAT in sectors */
      __u16   fat_sect;       /* Starting sector of the FAT */
      __u16   rootdir_sect;   /* Start sector of root directory */

--
Igor Luri
R&D Software Department
Fagor Aotek S. Coop.
P. O. Box 144
E-20500 Mondrag?n-Arrasate
Tel. ++34 943 71 92 00

       ++34 943 71 92 01 (Ext. 44268)

Fax. ++34 943 79 92 03
www.aotek.es