gpio: Add Turris Omnia MCU driver
[platform/kernel/u-boot.git] / lib / gunzip.c
index d86aa87..a8e498d 100644 (file)
@@ -1,18 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2000-2006
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
-#include <watchdog.h>
+#include <blk.h>
 #include <command.h>
 #include <console.h>
+#include <div64.h>
+#include <gzip.h>
 #include <image.h>
 #include <malloc.h>
+#include <memalign.h>
+#include <u-boot/crc.h>
+#include <watchdog.h>
 #include <u-boot/zlib.h>
-#include <div64.h>
 
 #define HEADER0                        '\x1f'
 #define HEADER1                        '\x8b'
@@ -41,7 +44,7 @@ void gzfree(void *x, void *addr, unsigned nb)
        free (addr);
 }
 
-int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp)
+int gzip_parse_header(const unsigned char *src, unsigned long len)
 {
        int i, flags;
 
@@ -62,41 +65,51 @@ int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp)
                        ;
        if ((flags & HEAD_CRC) != 0)
                i += 2;
-       if (i >= *lenp) {
+       if (i >= len) {
                puts ("Error: gunzip out of data in header\n");
                return (-1);
        }
+       return i;
+}
+
+int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp)
+{
+       int offset = gzip_parse_header(src, *lenp);
+
+       if (offset < 0)
+               return offset;
 
-       return zunzip(dst, dstlen, src, lenp, 1, i);
+       return zunzip(dst, dstlen, src, lenp, 1, offset);
 }
 
+#ifdef CONFIG_CMD_UNZIP
 __weak
-void gzwrite_progress_init(u64 expectedsize)
+void gzwrite_progress_init(ulong expectedsize)
 {
        putc('\n');
 }
 
 __weak
 void gzwrite_progress(int iteration,
-                    u64 bytes_written,
-                    u64 total_bytes)
+                    ulong bytes_written,
+                    ulong total_bytes)
 {
        if (0 == (iteration & 3))
-               printf("%llu/%llu\r", bytes_written, total_bytes);
+               printf("%lu/%lu\r", bytes_written, total_bytes);
 }
 
 __weak
 void gzwrite_progress_finish(int returnval,
-                            u64 bytes_written,
-                            u64 total_bytes,
+                            ulong bytes_written,
+                            ulong total_bytes,
                             u32 expected_crc,
                             u32 calculated_crc)
 {
        if (0 == returnval) {
-               printf("\n\t%llu bytes, crc 0x%08x\n",
+               printf("\n\t%lu bytes, crc 0x%08x\n",
                       total_bytes, calculated_crc);
        } else {
-               printf("\n\tuncompressed %llu of %llu\n"
+               printf("\n\tuncompressed %lu of %lu\n"
                       "\tcrcs == 0x%08x/0x%08x\n",
                       bytes_written, total_bytes,
                       expected_crc, calculated_crc);
@@ -104,17 +117,17 @@ void gzwrite_progress_finish(int returnval,
 }
 
 int gzwrite(unsigned char *src, int len,
-           struct block_dev_desc *dev,
+           struct blk_desc *dev,
            unsigned long szwritebuf,
-           u64 startoffs,
-           u64 szexpected)
+           ulong startoffs,
+           ulong szexpected)
 {
        int i, flags;
        z_stream s;
        int r = 0;
        unsigned char *writebuf;
        unsigned crc = 0;
-       u64 totalfilled = 0;
+       ulong totalfilled = 0;
        lbaint_t blksperbuf, outblock;
        u32 expected_crc;
        u32 payload_size;
@@ -129,7 +142,7 @@ int gzwrite(unsigned char *src, int len,
        }
 
        if (startoffs & (dev->blksz-1)) {
-               printf("%s: start offset %llu not a multiple of %lu\n",
+               printf("%s: start offset %lu not a multiple of %lu\n",
                       __func__, startoffs, dev->blksz);
                return -1;
        }
@@ -169,12 +182,12 @@ int gzwrite(unsigned char *src, int len,
        if (szexpected == 0) {
                szexpected = le32_to_cpu(szuncompressed);
        } else if (szuncompressed != (u32)szexpected) {
-               printf("size of %llx doesn't match trailer low bits %x\n",
+               printf("size of %lx doesn't match trailer low bits %x\n",
                       szexpected, szuncompressed);
                return -1;
        }
        if (lldiv(szexpected, dev->blksz) > (dev->lba - outblock)) {
-               printf("%s: uncompressed size %llu exceeds device size\n",
+               printf("%s: uncompressed size %lu exceeds device size\n",
                       __func__, szexpected);
                return -1;
        }
@@ -192,7 +205,7 @@ int gzwrite(unsigned char *src, int len,
 
        s.next_in = src + i;
        s.avail_in = payload_size+8;
-       writebuf = (unsigned char *)malloc(szwritebuf);
+       writebuf = (unsigned char *)malloc_cache_aligned(szwritebuf);
 
        /* decompress until deflate stream ends or end of file */
        do {
@@ -231,9 +244,8 @@ int gzwrite(unsigned char *src, int len,
                        gzwrite_progress(iteration++,
                                         totalfilled,
                                         szexpected);
-                       blocks_written = dev->block_write(dev, outblock,
-                                                         writeblocks,
-                                                         writebuf);
+                       blocks_written = blk_dwrite(dev, outblock,
+                                                   writeblocks, writebuf);
                        outblock += blocks_written;
                        if (ctrlc()) {
                                puts("abort\n");
@@ -258,6 +270,7 @@ out:
 
        return r;
 }
+#endif
 
 /*
  * Uncompress blocks compressed with zlib without headers
@@ -284,12 +297,11 @@ int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp,
        do {
                r = inflate(&s, Z_FINISH);
                if (stoponerr == 1 && r != Z_STREAM_END &&
-                   (s.avail_out == 0 || r != Z_BUF_ERROR)) {
+                   (s.avail_in == 0 || s.avail_out == 0 || r != Z_BUF_ERROR)) {
                        printf("Error: inflate() returned %d\n", r);
                        err = -1;
                        break;
                }
-               s.avail_in = *lenp - offset - (int)(s.next_out - (unsigned char*)dst);
        } while (r == Z_BUF_ERROR);
        *lenp = s.next_out - (unsigned char *) dst;
        inflateEnd(&s);