]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - fs/fat/fat_write.c
Merge branch 'master' of git://git.denx.de/u-boot-tegra
[karo-tx-uboot.git] / fs / fat / fat_write.c
index b4022aa29054abae1ae22d19e0015d18883c9545..24ed5d371502e651f2c5a3a41b0cb90e1ffc11b2 100644 (file)
@@ -3,23 +3,7 @@
  *
  * R/W (V)FAT 12/16/32 filesystem implementation by Donggeun Kim
  *
- * 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+
  */
 
 #include <common.h>
@@ -73,7 +57,7 @@ static void set_name(dir_entry *dirent, const char *filename)
        if (len == 0)
                return;
 
-       memcpy(s_name, filename, len);
+       strcpy(s_name, filename);
        uppercase(s_name, len);
 
        period = strchr(s_name, '.');
@@ -120,7 +104,6 @@ static int flush_fat_buffer(fsdata *mydata)
        __u8 *bufptr = mydata->fatbuf;
        __u32 startblock = mydata->fatbufnum * FATBUFBLOCKS;
 
-       fatlength *= mydata->sect_size;
        startblock += mydata->fat_sect;
 
        if (getsize > fatlength)
@@ -156,6 +139,11 @@ static __u32 get_fatent_value(fsdata *mydata, __u32 entry)
        __u32 ret = 0x00;
        __u16 val1, val2;
 
+       if (CHECK_CLUST(entry, mydata->fatsize)) {
+               printf("Error: Invalid FAT entry: 0x%08x\n", entry);
+               return ret;
+       }
+
        switch (mydata->fatsize) {
        case 32:
                bufnum = entry / FAT32BUFSIZE;
@@ -569,9 +557,11 @@ set_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer,
 
        debug("clustnum: %d, startsect: %d\n", clustnum, startsect);
 
-       if (disk_write(startsect, size / mydata->sect_size, buffer) < 0) {
-               debug("Error writing data\n");
-               return -1;
+       if ((size / mydata->sect_size) > 0) {
+               if (disk_write(startsect, size / mydata->sect_size, buffer) < 0) {
+                       debug("Error writing data\n");
+                       return -1;
+               }
        }
 
        if (size % mydata->sect_size) {
@@ -896,8 +886,30 @@ static dir_entry *find_directory_entry(fsdata *mydata, int startsect,
                        return dentptr;
                }
 
+               /*
+                * In FAT16/12, the root dir is locate before data area, shows
+                * in following:
+                * -------------------------------------------------------------
+                * | Boot | FAT1 & 2 | Root dir | Data (start from cluster #2) |
+                * -------------------------------------------------------------
+                *
+                * As a result if curclust is in Root dir, it is a negative
+                * number or 0, 1.
+                *
+                */
+               if (mydata->fatsize != 32 && (int)curclust <= 1) {
+                       /* Current clust is in root dir, set to next clust */
+                       curclust++;
+                       if ((int)curclust <= 1)
+                               continue;       /* continue to find */
+
+                       /* Reach the end of root dir */
+                       empty_dentptr = dentptr;
+                       return NULL;
+               }
+
                curclust = get_fatent_value(mydata, dir_curclust);
-               if ((curclust >= 0xffffff8) || (curclust >= 0xfff8)) {
+               if (IS_LAST_CLUST(curclust, mydata->fatsize)) {
                        empty_dentptr = dentptr;
                        return NULL;
                }
@@ -935,7 +947,7 @@ static int do_fat_write(const char *filename, void *buffer,
 
        total_sector = bs.total_sect;
        if (total_sector == 0)
-               total_sector = cur_part_info.size;
+               total_sector = (int)cur_part_info.size; /* cast of lbaint_t */
 
        if (mydata->fatsize == 32)
                mydata->fatlength = bs.fat32_length;
@@ -967,7 +979,7 @@ static int do_fat_write(const char *filename, void *buffer,
        }
 
        mydata->fatbufnum = -1;
-       mydata->fatbuf = malloc(FATBUFSIZE);
+       mydata->fatbuf = memalign(ARCH_DMA_MINALIGN, FATBUFSIZE);
        if (mydata->fatbuf == NULL) {
                debug("Error: allocating memory\n");
                return -1;