Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: Zlib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include "../zlib_inflate/inflate.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include "dfltcc_util.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include "dfltcc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/zutil.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Expand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) int dfltcc_can_inflate(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)     z_streamp strm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)     struct inflate_state *state = (struct inflate_state *)strm->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)     struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)     /* Check for kernel dfltcc command line parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)     if (zlib_dfltcc_support == ZLIB_DFLTCC_DISABLED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)             zlib_dfltcc_support == ZLIB_DFLTCC_DEFLATE_ONLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)     /* Unsupported compression settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)     if (state->wbits != HB_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)     /* Unsupported hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)     return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)                is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) EXPORT_SYMBOL(dfltcc_can_inflate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static int dfltcc_was_inflate_used(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)     z_streamp strm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)     struct inflate_state *state = (struct inflate_state *)strm->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)     struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)     return !param->nt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) static int dfltcc_inflate_disable(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)     z_streamp strm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)     struct inflate_state *state = (struct inflate_state *)strm->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)     struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)     if (!dfltcc_can_inflate(strm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)     if (dfltcc_was_inflate_used(strm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)         /* DFLTCC has already decompressed some data. Since there is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)          * enough information to resume decompression in software, the call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)          * must fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)          */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)         return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)     /* DFLTCC was not used yet - decompress in software */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)     memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) static dfltcc_cc dfltcc_xpnd(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)     z_streamp strm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)     struct inflate_state *state = (struct inflate_state *)strm->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)     struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)     size_t avail_in = strm->avail_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)     size_t avail_out = strm->avail_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)     dfltcc_cc cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)     cc = dfltcc(DFLTCC_XPND | HBT_CIRCULAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)                 param, &strm->next_out, &avail_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)                 &strm->next_in, &avail_in, state->window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)     strm->avail_in = avail_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)     strm->avail_out = avail_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)     return cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) dfltcc_inflate_action dfltcc_inflate(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)     z_streamp strm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)     int flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)     int *ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)     struct inflate_state *state = (struct inflate_state *)strm->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)     struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)     struct dfltcc_param_v0 *param = &dfltcc_state->param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)     dfltcc_cc cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)     if (flush == Z_BLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)         /* DFLTCC does not support stopping on block boundaries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)         if (dfltcc_inflate_disable(strm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)             *ret = Z_STREAM_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)             return DFLTCC_INFLATE_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)         } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)             return DFLTCC_INFLATE_SOFTWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)     if (state->last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)         if (state->bits != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)             strm->next_in++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)             strm->avail_in--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)             state->bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)         state->mode = CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)         return DFLTCC_INFLATE_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)     if (strm->avail_in == 0 && !param->cf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)         return DFLTCC_INFLATE_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)     if (!state->window || state->wsize == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)         state->mode = MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)         return DFLTCC_INFLATE_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)     /* Translate stream to parameter block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)     param->cvt = CVT_ADLER32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)     param->sbb = state->bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)     param->hl = state->whave; /* Software and hardware history formats match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)     param->ho = (state->write - state->whave) & ((1 << HB_BITS) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)     if (param->hl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)         param->nt = 0; /* Honor history for the first block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)     param->cv = state->check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)     /* Inflate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)     do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)         cc = dfltcc_xpnd(strm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)     } while (cc == DFLTCC_CC_AGAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)     /* Translate parameter block to stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)     strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)     state->last = cc == DFLTCC_CC_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)     state->bits = param->sbb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)     state->whave = param->hl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)     state->write = (param->ho + param->hl) & ((1 << HB_BITS) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)     state->check = param->cv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)     if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)         /* Report an error if stream is corrupted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)         state->mode = BAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)         return DFLTCC_INFLATE_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)     state->mode = TYPEDO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)     /* Break if operands are exhausted, otherwise continue looping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)     return (cc == DFLTCC_CC_OP1_TOO_SHORT || cc == DFLTCC_CC_OP2_TOO_SHORT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)         DFLTCC_INFLATE_BREAK : DFLTCC_INFLATE_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) EXPORT_SYMBOL(dfltcc_inflate);