| .. | .. |
|---|
| 52 | 52 | #include <linux/zutil.h> |
|---|
| 53 | 53 | #include "defutil.h" |
|---|
| 54 | 54 | |
|---|
| 55 | +/* architecture-specific bits */ |
|---|
| 56 | +#ifdef CONFIG_ZLIB_DFLTCC |
|---|
| 57 | +# include "../zlib_dfltcc/dfltcc.h" |
|---|
| 58 | +#else |
|---|
| 59 | +#define DEFLATE_RESET_HOOK(strm) do {} while (0) |
|---|
| 60 | +#define DEFLATE_HOOK(strm, flush, bstate) 0 |
|---|
| 61 | +#define DEFLATE_NEED_CHECKSUM(strm) 1 |
|---|
| 62 | +#define DEFLATE_DFLTCC_ENABLED() 0 |
|---|
| 63 | +#endif |
|---|
| 55 | 64 | |
|---|
| 56 | 65 | /* =========================================================================== |
|---|
| 57 | 66 | * Function prototypes. |
|---|
| 58 | 67 | */ |
|---|
| 59 | | -typedef enum { |
|---|
| 60 | | - need_more, /* block not completed, need more input or more output */ |
|---|
| 61 | | - block_done, /* block flush performed */ |
|---|
| 62 | | - finish_started, /* finish started, need only more output at next deflate */ |
|---|
| 63 | | - finish_done /* finish done, accept no more input or output */ |
|---|
| 64 | | -} block_state; |
|---|
| 65 | 68 | |
|---|
| 66 | 69 | typedef block_state (*compress_func) (deflate_state *s, int flush); |
|---|
| 67 | 70 | /* Compression function. Returns the block state after the call. */ |
|---|
| .. | .. |
|---|
| 72 | 75 | static block_state deflate_slow (deflate_state *s, int flush); |
|---|
| 73 | 76 | static void lm_init (deflate_state *s); |
|---|
| 74 | 77 | static void putShortMSB (deflate_state *s, uInt b); |
|---|
| 75 | | -static void flush_pending (z_streamp strm); |
|---|
| 76 | 78 | static int read_buf (z_streamp strm, Byte *buf, unsigned size); |
|---|
| 77 | 79 | static uInt longest_match (deflate_state *s, IPos cur_match); |
|---|
| 78 | 80 | |
|---|
| .. | .. |
|---|
| 97 | 99 | /* Minimum amount of lookahead, except at the end of the input file. |
|---|
| 98 | 100 | * See deflate.c for comments about the MIN_MATCH+1. |
|---|
| 99 | 101 | */ |
|---|
| 102 | + |
|---|
| 103 | +/* Workspace to be allocated for deflate processing */ |
|---|
| 104 | +typedef struct deflate_workspace { |
|---|
| 105 | + /* State memory for the deflator */ |
|---|
| 106 | + deflate_state deflate_memory; |
|---|
| 107 | +#ifdef CONFIG_ZLIB_DFLTCC |
|---|
| 108 | + /* State memory for s390 hardware deflate */ |
|---|
| 109 | + struct dfltcc_state dfltcc_memory; |
|---|
| 110 | +#endif |
|---|
| 111 | + Byte *window_memory; |
|---|
| 112 | + Pos *prev_memory; |
|---|
| 113 | + Pos *head_memory; |
|---|
| 114 | + char *overlay_memory; |
|---|
| 115 | +} deflate_workspace; |
|---|
| 116 | + |
|---|
| 117 | +#ifdef CONFIG_ZLIB_DFLTCC |
|---|
| 118 | +/* dfltcc_state must be doubleword aligned for DFLTCC call */ |
|---|
| 119 | +static_assert(offsetof(struct deflate_workspace, dfltcc_memory) % 8 == 0); |
|---|
| 120 | +#endif |
|---|
| 100 | 121 | |
|---|
| 101 | 122 | /* Values for max_lazy_match, good_match and max_chain_length, depending on |
|---|
| 102 | 123 | * the desired pack level (0..9). The values given below have been tuned to |
|---|
| .. | .. |
|---|
| 207 | 228 | */ |
|---|
| 208 | 229 | next = (char *) mem; |
|---|
| 209 | 230 | next += sizeof(*mem); |
|---|
| 231 | +#ifdef CONFIG_ZLIB_DFLTCC |
|---|
| 232 | + /* |
|---|
| 233 | + * DFLTCC requires the window to be page aligned. |
|---|
| 234 | + * Thus, we overallocate and take the aligned portion of the buffer. |
|---|
| 235 | + */ |
|---|
| 236 | + mem->window_memory = (Byte *) PTR_ALIGN(next, PAGE_SIZE); |
|---|
| 237 | +#else |
|---|
| 210 | 238 | mem->window_memory = (Byte *) next; |
|---|
| 239 | +#endif |
|---|
| 211 | 240 | next += zlib_deflate_window_memsize(windowBits); |
|---|
| 212 | 241 | mem->prev_memory = (Pos *) next; |
|---|
| 213 | 242 | next += zlib_deflate_prev_memsize(windowBits); |
|---|
| .. | .. |
|---|
| 277 | 306 | zlib_tr_init(s); |
|---|
| 278 | 307 | lm_init(s); |
|---|
| 279 | 308 | |
|---|
| 309 | + DEFLATE_RESET_HOOK(strm); |
|---|
| 310 | + |
|---|
| 280 | 311 | return Z_OK; |
|---|
| 281 | 312 | } |
|---|
| 282 | 313 | |
|---|
| .. | .. |
|---|
| 293 | 324 | put_byte(s, (Byte)(b >> 8)); |
|---|
| 294 | 325 | put_byte(s, (Byte)(b & 0xff)); |
|---|
| 295 | 326 | } |
|---|
| 296 | | - |
|---|
| 297 | | -/* ========================================================================= |
|---|
| 298 | | - * Flush as much pending output as possible. All deflate() output goes |
|---|
| 299 | | - * through this function so some applications may wish to modify it |
|---|
| 300 | | - * to avoid allocating a large strm->next_out buffer and copying into it. |
|---|
| 301 | | - * (See also read_buf()). |
|---|
| 302 | | - */ |
|---|
| 303 | | -static void flush_pending( |
|---|
| 304 | | - z_streamp strm |
|---|
| 305 | | -) |
|---|
| 306 | | -{ |
|---|
| 307 | | - deflate_state *s = (deflate_state *) strm->state; |
|---|
| 308 | | - unsigned len = s->pending; |
|---|
| 309 | | - |
|---|
| 310 | | - if (len > strm->avail_out) len = strm->avail_out; |
|---|
| 311 | | - if (len == 0) return; |
|---|
| 312 | | - |
|---|
| 313 | | - if (strm->next_out != NULL) { |
|---|
| 314 | | - memcpy(strm->next_out, s->pending_out, len); |
|---|
| 315 | | - strm->next_out += len; |
|---|
| 316 | | - } |
|---|
| 317 | | - s->pending_out += len; |
|---|
| 318 | | - strm->total_out += len; |
|---|
| 319 | | - strm->avail_out -= len; |
|---|
| 320 | | - s->pending -= len; |
|---|
| 321 | | - if (s->pending == 0) { |
|---|
| 322 | | - s->pending_out = s->pending_buf; |
|---|
| 323 | | - } |
|---|
| 324 | | -} |
|---|
| 325 | 327 | |
|---|
| 326 | 328 | /* ========================================================================= */ |
|---|
| 327 | 329 | int zlib_deflate( |
|---|
| .. | .. |
|---|
| 404 | 406 | (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { |
|---|
| 405 | 407 | block_state bstate; |
|---|
| 406 | 408 | |
|---|
| 407 | | - bstate = (*(configuration_table[s->level].func))(s, flush); |
|---|
| 409 | + bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate : |
|---|
| 410 | + (*(configuration_table[s->level].func))(s, flush); |
|---|
| 408 | 411 | |
|---|
| 409 | 412 | if (bstate == finish_started || bstate == finish_done) { |
|---|
| 410 | 413 | s->status = FINISH_STATE; |
|---|
| .. | .. |
|---|
| 503 | 506 | |
|---|
| 504 | 507 | strm->avail_in -= len; |
|---|
| 505 | 508 | |
|---|
| 506 | | - if (!((deflate_state *)(strm->state))->noheader) { |
|---|
| 509 | + if (!DEFLATE_NEED_CHECKSUM(strm)) {} |
|---|
| 510 | + else if (!((deflate_state *)(strm->state))->noheader) { |
|---|
| 507 | 511 | strm->adler = zlib_adler32(strm->adler, strm->next_in, len); |
|---|
| 508 | 512 | } |
|---|
| 509 | 513 | memcpy(buf, strm->next_in, len); |
|---|
| .. | .. |
|---|
| 1135 | 1139 | + zlib_deflate_head_memsize(memLevel) |
|---|
| 1136 | 1140 | + zlib_deflate_overlay_memsize(memLevel); |
|---|
| 1137 | 1141 | } |
|---|
| 1142 | + |
|---|
| 1143 | +int zlib_deflate_dfltcc_enabled(void) |
|---|
| 1144 | +{ |
|---|
| 1145 | + return DEFLATE_DFLTCC_ENABLED(); |
|---|
| 1146 | +} |
|---|