Commit 8336793baf962163c9fab5a3f39614295fdbab27
Committed by
David S. Miller
1 parent
b3448b0bde
Exists in
master
and in
4 other branches
[ZLIB]: Move bnx2 driver gzip unpacker into zlib.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> Acked-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 5 changed files with 69 additions and 59 deletions Side-by-side Diff
drivers/net/bnx2.c
... | ... | @@ -2761,48 +2761,6 @@ |
2761 | 2761 | spin_unlock_bh(&bp->phy_lock); |
2762 | 2762 | } |
2763 | 2763 | |
2764 | -/* To be moved to generic lib/ */ | |
2765 | -static int | |
2766 | -bnx2_gunzip(void *gunzip_buf, unsigned sz, u8 *zbuf, int len) | |
2767 | -{ | |
2768 | - struct z_stream_s *strm; | |
2769 | - int rc; | |
2770 | - | |
2771 | - /* gzip header (1f,8b,08... 10 bytes total + possible asciz filename) | |
2772 | - * is stripped */ | |
2773 | - | |
2774 | - rc = -ENOMEM; | |
2775 | - strm = kmalloc(sizeof(*strm), GFP_KERNEL); | |
2776 | - if (strm == NULL) | |
2777 | - goto gunzip_nomem2; | |
2778 | - strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); | |
2779 | - if (strm->workspace == NULL) | |
2780 | - goto gunzip_nomem3; | |
2781 | - | |
2782 | - strm->next_in = zbuf; | |
2783 | - strm->avail_in = len; | |
2784 | - strm->next_out = gunzip_buf; | |
2785 | - strm->avail_out = sz; | |
2786 | - | |
2787 | - rc = zlib_inflateInit2(strm, -MAX_WBITS); | |
2788 | - if (rc == Z_OK) { | |
2789 | - rc = zlib_inflate(strm, Z_FINISH); | |
2790 | - /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */ | |
2791 | - if (rc == Z_STREAM_END) | |
2792 | - rc = sz - strm->avail_out; | |
2793 | - else | |
2794 | - rc = -EINVAL; | |
2795 | - zlib_inflateEnd(strm); | |
2796 | - } else | |
2797 | - rc = -EINVAL; | |
2798 | - | |
2799 | - kfree(strm->workspace); | |
2800 | -gunzip_nomem3: | |
2801 | - kfree(strm); | |
2802 | -gunzip_nomem2: | |
2803 | - return rc; | |
2804 | -} | |
2805 | - | |
2806 | 2764 | static void |
2807 | 2765 | load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len, |
2808 | 2766 | u32 rv2p_proc) |
... | ... | @@ -2858,7 +2816,7 @@ |
2858 | 2816 | text = vmalloc(FW_BUF_SIZE); |
2859 | 2817 | if (!text) |
2860 | 2818 | return -ENOMEM; |
2861 | - rc = bnx2_gunzip(text, FW_BUF_SIZE, fw->gz_text, fw->gz_text_len); | |
2819 | + rc = zlib_inflate_blob(text, FW_BUF_SIZE, fw->gz_text, fw->gz_text_len); | |
2862 | 2820 | if (rc < 0) { |
2863 | 2821 | vfree(text); |
2864 | 2822 | return rc; |
2865 | 2823 | |
... | ... | @@ -2935,14 +2893,14 @@ |
2935 | 2893 | text = vmalloc(FW_BUF_SIZE); |
2936 | 2894 | if (!text) |
2937 | 2895 | return -ENOMEM; |
2938 | - rc = bnx2_gunzip(text, FW_BUF_SIZE, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1)); | |
2896 | + rc = zlib_inflate_blob(text, FW_BUF_SIZE, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1)); | |
2939 | 2897 | if (rc < 0) { |
2940 | 2898 | vfree(text); |
2941 | 2899 | goto init_cpu_err; |
2942 | 2900 | } |
2943 | 2901 | load_rv2p_fw(bp, text, rc /* == len */, RV2P_PROC1); |
2944 | 2902 | |
2945 | - rc = bnx2_gunzip(text, FW_BUF_SIZE, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2)); | |
2903 | + rc = zlib_inflate_blob(text, FW_BUF_SIZE, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2)); | |
2946 | 2904 | if (rc < 0) { |
2947 | 2905 | vfree(text); |
2948 | 2906 | goto init_cpu_err; |
include/linux/zlib.h
... | ... | @@ -82,7 +82,7 @@ |
82 | 82 | struct internal_state; |
83 | 83 | |
84 | 84 | typedef struct z_stream_s { |
85 | - Byte *next_in; /* next input byte */ | |
85 | + const Byte *next_in; /* next input byte */ | |
86 | 86 | uInt avail_in; /* number of bytes available at next_in */ |
87 | 87 | uLong total_in; /* total nb of input bytes read so far */ |
88 | 88 | |
... | ... | @@ -698,6 +698,10 @@ |
698 | 698 | #if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) |
699 | 699 | struct internal_state {int dummy;}; /* hack for buggy compilers */ |
700 | 700 | #endif |
701 | + | |
702 | +/* Utility function: initialize zlib, unpack binary blob, clean up zlib, | |
703 | + * return len or negative error code. */ | |
704 | +extern int zlib_inflate_blob(void *dst, unsigned dst_sz, const void *src, unsigned src_sz); | |
701 | 705 | |
702 | 706 | #endif /* _ZLIB_H */ |
lib/zlib_inflate/inffast.c
... | ... | @@ -69,22 +69,22 @@ |
69 | 69 | void inflate_fast(z_streamp strm, unsigned start) |
70 | 70 | { |
71 | 71 | struct inflate_state *state; |
72 | - unsigned char *in; /* local strm->next_in */ | |
73 | - unsigned char *last; /* while in < last, enough input available */ | |
74 | - unsigned char *out; /* local strm->next_out */ | |
75 | - unsigned char *beg; /* inflate()'s initial strm->next_out */ | |
76 | - unsigned char *end; /* while out < end, enough space available */ | |
72 | + const unsigned char *in; /* local strm->next_in */ | |
73 | + const unsigned char *last; /* while in < last, enough input available */ | |
74 | + unsigned char *out; /* local strm->next_out */ | |
75 | + unsigned char *beg; /* inflate()'s initial strm->next_out */ | |
76 | + unsigned char *end; /* while out < end, enough space available */ | |
77 | 77 | #ifdef INFLATE_STRICT |
78 | 78 | unsigned dmax; /* maximum distance from zlib header */ |
79 | 79 | #endif |
80 | 80 | unsigned wsize; /* window size or zero if not using window */ |
81 | 81 | unsigned whave; /* valid bytes in the window */ |
82 | 82 | unsigned write; /* window write index */ |
83 | - unsigned char *window; /* allocated sliding window, if wsize != 0 */ | |
83 | + unsigned char *window; /* allocated sliding window, if wsize != 0 */ | |
84 | 84 | unsigned long hold; /* local strm->hold */ |
85 | 85 | unsigned bits; /* local strm->bits */ |
86 | - code const *lcode; /* local strm->lencode */ | |
87 | - code const *dcode; /* local strm->distcode */ | |
86 | + code const *lcode; /* local strm->lencode */ | |
87 | + code const *dcode; /* local strm->distcode */ | |
88 | 88 | unsigned lmask; /* mask for first level of length codes */ |
89 | 89 | unsigned dmask; /* mask for first level of distance codes */ |
90 | 90 | code this; /* retrieved table entry */ |
... | ... | @@ -92,7 +92,7 @@ |
92 | 92 | /* window position, window bytes to copy */ |
93 | 93 | unsigned len; /* match length, unused bytes */ |
94 | 94 | unsigned dist; /* match distance */ |
95 | - unsigned char *from; /* where to copy match from */ | |
95 | + unsigned char *from; /* where to copy match from */ | |
96 | 96 | |
97 | 97 | /* copy state to local variables */ |
98 | 98 | state = (struct inflate_state *)strm->state; |
lib/zlib_inflate/inflate.c
... | ... | @@ -332,14 +332,14 @@ |
332 | 332 | int zlib_inflate(z_streamp strm, int flush) |
333 | 333 | { |
334 | 334 | struct inflate_state *state; |
335 | - unsigned char *next; /* next input */ | |
336 | - unsigned char *put; /* next output */ | |
335 | + const unsigned char *next; /* next input */ | |
336 | + unsigned char *put; /* next output */ | |
337 | 337 | unsigned have, left; /* available input and output */ |
338 | 338 | unsigned long hold; /* bit buffer */ |
339 | 339 | unsigned bits; /* bits in bit buffer */ |
340 | 340 | unsigned in, out; /* save starting available input and output */ |
341 | 341 | unsigned copy; /* number of stored or match bytes to copy */ |
342 | - unsigned char *from; /* where to copy match bytes from */ | |
342 | + unsigned char *from; /* where to copy match bytes from */ | |
343 | 343 | code this; /* current decoding table entry */ |
344 | 344 | code last; /* parent table entry */ |
345 | 345 | unsigned len; /* length to copy for repeats, bits to drop */ |
... | ... | @@ -897,7 +897,7 @@ |
897 | 897 | |
898 | 898 | /* Setup some variables to allow misuse of updateWindow */ |
899 | 899 | z->avail_out = 0; |
900 | - z->next_out = z->next_in + z->avail_in; | |
900 | + z->next_out = (unsigned char*)z->next_in + z->avail_in; | |
901 | 901 | |
902 | 902 | zlib_updatewindow(z, z->avail_in); |
903 | 903 | |
... | ... | @@ -915,5 +915,52 @@ |
915 | 915 | z->avail_in = 0; |
916 | 916 | |
917 | 917 | return Z_OK; |
918 | +} | |
919 | + | |
920 | +#include <linux/errno.h> | |
921 | +#include <linux/slab.h> | |
922 | +#include <linux/vmalloc.h> | |
923 | + | |
924 | +/* Utility function: initialize zlib, unpack binary blob, clean up zlib, | |
925 | + * return len or negative error code. */ | |
926 | +int zlib_inflate_blob(void *gunzip_buf, unsigned sz, const void *buf, unsigned len) | |
927 | +{ | |
928 | + const u8 *zbuf = buf; | |
929 | + struct z_stream_s *strm; | |
930 | + int rc; | |
931 | + | |
932 | + rc = -ENOMEM; | |
933 | + strm = kmalloc(sizeof(*strm), GFP_KERNEL); | |
934 | + if (strm == NULL) | |
935 | + goto gunzip_nomem1; | |
936 | + strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); | |
937 | + if (strm->workspace == NULL) | |
938 | + goto gunzip_nomem2; | |
939 | + | |
940 | + /* gzip header (1f,8b,08... 10 bytes total + possible asciz filename) | |
941 | + * expected to be stripped from input */ | |
942 | + | |
943 | + strm->next_in = zbuf; | |
944 | + strm->avail_in = len; | |
945 | + strm->next_out = gunzip_buf; | |
946 | + strm->avail_out = sz; | |
947 | + | |
948 | + rc = zlib_inflateInit2(strm, -MAX_WBITS); | |
949 | + if (rc == Z_OK) { | |
950 | + rc = zlib_inflate(strm, Z_FINISH); | |
951 | + /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */ | |
952 | + if (rc == Z_STREAM_END) | |
953 | + rc = sz - strm->avail_out; | |
954 | + else | |
955 | + rc = -EINVAL; | |
956 | + zlib_inflateEnd(strm); | |
957 | + } else | |
958 | + rc = -EINVAL; | |
959 | + | |
960 | + kfree(strm->workspace); | |
961 | +gunzip_nomem2: | |
962 | + kfree(strm); | |
963 | +gunzip_nomem1: | |
964 | + return rc; /* returns Z_OK (0) if successful */ | |
918 | 965 | } |