0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0020
0021 #include <linux/kernel.h>
0022 #include <linux/errno.h>
0023 #include <linux/vmalloc.h>
0024 #include <linux/zlib.h>
0025 #include "internal.h"
0026
0027 static z_stream stream;
0028 static int initialized;
0029
0030
0031 int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen)
0032 {
0033 int err;
0034
0035 stream.next_in = src;
0036 stream.avail_in = srclen;
0037
0038 stream.next_out = dst;
0039 stream.avail_out = dstlen;
0040
0041 err = zlib_inflateReset(&stream);
0042 if (err != Z_OK) {
0043 pr_err("zlib_inflateReset error %d\n", err);
0044 zlib_inflateEnd(&stream);
0045 zlib_inflateInit(&stream);
0046 }
0047
0048 err = zlib_inflate(&stream, Z_FINISH);
0049 if (err != Z_STREAM_END)
0050 goto err;
0051 return stream.total_out;
0052
0053 err:
0054 pr_err("Error %d while decompressing!\n", err);
0055 pr_err("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen);
0056 return -EIO;
0057 }
0058
0059 int cramfs_uncompress_init(void)
0060 {
0061 if (!initialized++) {
0062 stream.workspace = vmalloc(zlib_inflate_workspacesize());
0063 if (!stream.workspace) {
0064 initialized = 0;
0065 return -ENOMEM;
0066 }
0067 stream.next_in = NULL;
0068 stream.avail_in = 0;
0069 zlib_inflateInit(&stream);
0070 }
0071 return 0;
0072 }
0073
0074 void cramfs_uncompress_exit(void)
0075 {
0076 if (!--initialized) {
0077 zlib_inflateEnd(&stream);
0078 vfree(stream.workspace);
0079 }
0080 }