]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - fs/fat/fat_write.c
mmc: omap_hsmmc: enable 8bit interface for eMMC for AM43xx
[karo-tx-uboot.git] / fs / fat / fat_write.c
index 24ed5d371502e651f2c5a3a41b0cb90e1ffc11b2..98b88add83c507116bfa05a7927983c785a13a2c 100644 (file)
@@ -13,6 +13,8 @@
 #include <asm/byteorder.h>
 #include <part.h>
 #include <linux/ctype.h>
+#include <div64.h>
+#include <linux/math64.h>
 #include "fat.c"
 
 static void uppercase(char *str, int len)
@@ -660,24 +662,26 @@ static int clear_fatent(fsdata *mydata, __u32 entry)
 /*
  * Write at most 'maxsize' bytes from 'buffer' into
  * the file associated with 'dentptr'
- * Return the number of bytes read or -1 on fatal errors.
+ * Update the number of bytes written in *gotsize and return 0
+ * or return -1 on fatal errors.
  */
 static int
 set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
-             unsigned long maxsize)
+             loff_t maxsize, loff_t *gotsize)
 {
-       unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;
+       loff_t filesize = FAT2CPU32(dentptr->size);
        unsigned int bytesperclust = mydata->clust_size * mydata->sect_size;
        __u32 curclust = START(dentptr);
        __u32 endclust = 0, newclust = 0;
-       unsigned long actsize;
+       loff_t actsize;
 
-       debug("Filesize: %ld bytes\n", filesize);
+       *gotsize = 0;
+       debug("Filesize: %llu bytes\n", filesize);
 
        if (maxsize > 0 && filesize > maxsize)
                filesize = maxsize;
 
-       debug("%ld bytes\n", filesize);
+       debug("%llu bytes\n", filesize);
 
        actsize = bytesperclust;
        endclust = curclust;
@@ -692,7 +696,7 @@ set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
                        if (CHECK_CLUST(newclust, mydata->fatsize)) {
                                debug("curclust: 0x%x\n", newclust);
                                debug("Invalid FAT entry\n");
-                               return gotsize;
+                               return 0;
                        }
                        endclust = newclust;
                        actsize += bytesperclust;
@@ -706,7 +710,7 @@ set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
                }
 
                /* set remaining bytes */
-               gotsize += (int)actsize;
+               *gotsize += actsize;
                filesize -= actsize;
                buffer += actsize;
                actsize = filesize;
@@ -715,7 +719,7 @@ set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
                        debug("error: writing cluster\n");
                        return -1;
                }
-               gotsize += actsize;
+               *gotsize += actsize;
 
                /* Mark end of file in FAT */
                if (mydata->fatsize == 16)
@@ -724,20 +728,20 @@ set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
                        newclust = 0xfffffff;
                set_fatent_value(mydata, endclust, newclust);
 
-               return gotsize;
+               return 0;
 getit:
                if (set_cluster(mydata, curclust, buffer, (int)actsize) != 0) {
                        debug("error: writing cluster\n");
                        return -1;
                }
-               gotsize += (int)actsize;
+               *gotsize += actsize;
                filesize -= actsize;
                buffer += actsize;
 
                if (CHECK_CLUST(curclust, mydata->fatsize)) {
                        debug("curclust: 0x%x\n", curclust);
                        debug("Invalid FAT entry\n");
-                       return gotsize;
+                       return 0;
                }
                actsize = bytesperclust;
                curclust = endclust = newclust;
@@ -766,9 +770,9 @@ static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
  * exceed the size of the block device
  * Return -1 when overflow occurs, otherwise return 0
  */
-static int check_overflow(fsdata *mydata, __u32 clustnum, unsigned long size)
+static int check_overflow(fsdata *mydata, __u32 clustnum, loff_t size)
 {
-       __u32 startsect, sect_num;
+       __u32 startsect, sect_num, offset;
 
        if (clustnum > 0) {
                startsect = mydata->data_begin +
@@ -777,13 +781,13 @@ static int check_overflow(fsdata *mydata, __u32 clustnum, unsigned long size)
                startsect = mydata->rootdir_sect;
        }
 
-       sect_num = size / mydata->sect_size;
-       if (size % mydata->sect_size)
+       sect_num = div_u64_rem(size, mydata->sect_size, &offset);
+
+       if (offset != 0)
                sect_num++;
 
        if (startsect + sect_num > cur_part_info.start + total_sector)
                return -1;
-
        return 0;
 }
 
@@ -923,8 +927,8 @@ static dir_entry *find_directory_entry(fsdata *mydata, int startsect,
        return NULL;
 }
 
-static int do_fat_write(const char *filename, void *buffer,
-       unsigned long size)
+static int do_fat_write(const char *filename, void *buffer, loff_t size,
+                       loff_t *actwrite)
 {
        dir_entry *dentptr, *retdent;
        __u32 startsect;
@@ -936,8 +940,8 @@ static int do_fat_write(const char *filename, void *buffer,
        int cursect;
        int ret = -1, name_len;
        char l_filename[VFAT_MAXLEN_BYTES];
-       int write_size = size;
 
+       *actwrite = size;
        dir_curclust = 0;
 
        if (read_bootsectandvi(&bs, &volinfo, &mydata->fatsize)) {
@@ -1015,7 +1019,7 @@ static int do_fat_write(const char *filename, void *buffer,
 
                ret = check_overflow(mydata, start_cluster, size);
                if (ret) {
-                       printf("Error: %ld overflow\n", size);
+                       printf("Error: %llu overflow\n", size);
                        goto exit;
                }
 
@@ -1025,13 +1029,12 @@ static int do_fat_write(const char *filename, void *buffer,
                        goto exit;
                }
 
-               ret = set_contents(mydata, retdent, buffer, size);
+               ret = set_contents(mydata, retdent, buffer, size, actwrite);
                if (ret < 0) {
                        printf("Error: writing contents\n");
                        goto exit;
                }
-               write_size = ret;
-               debug("attempt to write 0x%x bytes\n", write_size);
+               debug("attempt to write 0x%llx bytes\n", *actwrite);
 
                /* Flush fat buffer */
                ret = flush_fat_buffer(mydata);
@@ -1061,7 +1064,7 @@ static int do_fat_write(const char *filename, void *buffer,
 
                ret = check_overflow(mydata, start_cluster, size);
                if (ret) {
-                       printf("Error: %ld overflow\n", size);
+                       printf("Error: %llu overflow\n", size);
                        goto exit;
                }
 
@@ -1069,13 +1072,13 @@ static int do_fat_write(const char *filename, void *buffer,
                fill_dentry(mydata, empty_dentptr, filename,
                        start_cluster, size, 0x20);
 
-               ret = set_contents(mydata, empty_dentptr, buffer, size);
+               ret = set_contents(mydata, empty_dentptr, buffer, size,
+                                  actwrite);
                if (ret < 0) {
                        printf("Error: writing contents\n");
                        goto exit;
                }
-               write_size = ret;
-               debug("attempt to write 0x%x bytes\n", write_size);
+               debug("attempt to write 0x%llx bytes\n", *actwrite);
 
                /* Flush fat buffer */
                ret = flush_fat_buffer(mydata);
@@ -1096,11 +1099,17 @@ static int do_fat_write(const char *filename, void *buffer,
 
 exit:
        free(mydata->fatbuf);
-       return ret < 0 ? ret : write_size;
+       return ret;
 }
 
-int file_fat_write(const char *filename, void *buffer, unsigned long maxsize)
+int file_fat_write(const char *filename, void *buffer, loff_t offset,
+                  loff_t maxsize, loff_t *actwrite)
 {
+       if (offset != 0) {
+               printf("Error: non zero offset is currently not suported.\n");
+               return -1;
+       }
+
        printf("writing %s\n", filename);
-       return do_fat_write(filename, buffer, maxsize);
+       return do_fat_write(filename, buffer, maxsize, actwrite);
 }