Commit 8336793baf962163c9fab5a3f39614295fdbab27

Authored by Denys Vlasenko
Committed by David S. Miller
1 parent b3448b0bde

[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

... ... @@ -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 }
lib/zlib_inflate/inflate_syms.c
... ... @@ -16,5 +16,6 @@
16 16 EXPORT_SYMBOL(zlib_inflateEnd);
17 17 EXPORT_SYMBOL(zlib_inflateReset);
18 18 EXPORT_SYMBOL(zlib_inflateIncomp);
  19 +EXPORT_SYMBOL(zlib_inflate_blob);
19 20 MODULE_LICENSE("GPL");