root/drivers/misc/altera-stapl/altera-comp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. altera_bits_req
  2. altera_read_packed
  3. altera_shrink

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * altera-comp.c
   4  *
   5  * altera FPGA driver
   6  *
   7  * Copyright (C) Altera Corporation 1998-2001
   8  * Copyright (C) 2010 NetUP Inc.
   9  * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
  10  */
  11 
  12 #include <linux/kernel.h>
  13 #include "altera-exprt.h"
  14 
  15 #define SHORT_BITS              16
  16 #define CHAR_BITS               8
  17 #define DATA_BLOB_LENGTH        3
  18 #define MATCH_DATA_LENGTH       8192
  19 #define ALTERA_REQUEST_SIZE     1024
  20 #define ALTERA_BUFFER_SIZE      (MATCH_DATA_LENGTH + ALTERA_REQUEST_SIZE)
  21 
  22 static u32 altera_bits_req(u32 n)
  23 {
  24         u32 result = SHORT_BITS;
  25 
  26         if (n == 0)
  27                 result = 1;
  28         else {
  29                 /* Look for the highest non-zero bit position */
  30                 while ((n & (1 << (SHORT_BITS - 1))) == 0) {
  31                         n <<= 1;
  32                         --result;
  33                 }
  34         }
  35 
  36         return result;
  37 }
  38 
  39 static u32 altera_read_packed(u8 *buffer, u32 bits, u32 *bits_avail,
  40                                                         u32 *in_index)
  41 {
  42         u32 result = 0;
  43         u32 shift = 0;
  44         u32 databyte = 0;
  45 
  46         while (bits > 0) {
  47                 databyte = buffer[*in_index];
  48                 result |= (((databyte >> (CHAR_BITS - *bits_avail))
  49                         & (0xff >> (CHAR_BITS - *bits_avail))) << shift);
  50 
  51                 if (bits <= *bits_avail) {
  52                         result &= (0xffff >> (SHORT_BITS - (bits + shift)));
  53                         *bits_avail -= bits;
  54                         bits = 0;
  55                 } else {
  56                         ++(*in_index);
  57                         shift += *bits_avail;
  58                         bits -= *bits_avail;
  59                         *bits_avail = CHAR_BITS;
  60                 }
  61         }
  62 
  63         return result;
  64 }
  65 
  66 u32 altera_shrink(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version)
  67 {
  68         u32 i, j, data_length = 0L;
  69         u32 offset, length;
  70         u32 match_data_length = MATCH_DATA_LENGTH;
  71         u32 bits_avail = CHAR_BITS;
  72         u32 in_index = 0L;
  73 
  74         if (version > 0)
  75                 --match_data_length;
  76 
  77         for (i = 0; i < out_length; ++i)
  78                 out[i] = 0;
  79 
  80         /* Read number of bytes in data. */
  81         for (i = 0; i < sizeof(in_length); ++i) {
  82                 data_length = data_length | (
  83                         altera_read_packed(in,
  84                                         CHAR_BITS,
  85                                         &bits_avail,
  86                                         &in_index) << (i * CHAR_BITS));
  87         }
  88 
  89         if (data_length > out_length) {
  90                 data_length = 0L;
  91                 return data_length;
  92         }
  93 
  94         i = 0;
  95         while (i < data_length) {
  96                 /* A 0 bit indicates literal data. */
  97                 if (altera_read_packed(in, 1, &bits_avail,
  98                                                 &in_index) == 0) {
  99                         for (j = 0; j < DATA_BLOB_LENGTH; ++j) {
 100                                 if (i < data_length) {
 101                                         out[i] = (u8)altera_read_packed(in,
 102                                                         CHAR_BITS,
 103                                                         &bits_avail,
 104                                                         &in_index);
 105                                         i++;
 106                                 }
 107                         }
 108                 } else {
 109                         /* A 1 bit indicates offset/length to follow. */
 110                         offset = altera_read_packed(in, altera_bits_req((s16)
 111                                         (i > match_data_length ?
 112                                                 match_data_length : i)),
 113                                         &bits_avail,
 114                                         &in_index);
 115                         length = altera_read_packed(in, CHAR_BITS,
 116                                         &bits_avail,
 117                                         &in_index);
 118                         for (j = 0; j < length; ++j) {
 119                                 if (i < data_length) {
 120                                         out[i] = out[i - offset];
 121                                         i++;
 122                                 }
 123                         }
 124                 }
 125         }
 126 
 127         return data_length;
 128 }

/* [<][>][^][v][top][bottom][index][help] */