2018-04-22 19:23:50 +03:00
// SPDX-License-Identifier: GPL-2.0
2005-11-07 14:15:37 +03:00
/*
2018-04-22 19:23:49 +03:00
* Generic Reed Solomon encoder / decoder library
2005-11-07 14:15:37 +03:00
*
2005-04-17 02:20:36 +04:00
* Copyright ( C ) 2004 Thomas Gleixner ( tglx @ linutronix . de )
*
* Reed Solomon code lifted from reed solomon library written by Phil Karn
* Copyright 2002 Phil Karn , KA9Q
*
* Description :
2005-11-07 14:15:37 +03:00
*
2005-04-17 02:20:36 +04:00
* The generic Reed Solomon library provides runtime configurable
* encoding / decoding of RS codes .
2018-04-22 19:23:53 +03:00
*
* Each user must call init_rs to get a pointer to a rs_control structure
* for the given rs parameters . The control struct is unique per instance .
* It points to a codec which can be shared by multiple control structures .
* If a codec is newly allocated then the polynomial arrays for fast
* encoding / decoding are built . This can take some time so make sure not
* to call this function from a time critical path . Usually a module /
* driver should initialize the necessary rs_control structure on module /
* driver init and release it on exit .
*
* The encoding puts the calculated syndrome into a given syndrome buffer .
*
* The decoding is a two step process . The first step calculates the
* syndrome over the received ( data + syndrome ) and calls the second stage ,
* which does the decoding / error correction itself . Many hw encoders
* provide a syndrome calculation over the received data + syndrome and can
* call the second stage directly .
2005-04-17 02:20:36 +04:00
*/
# include <linux/errno.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/module.h>
# include <linux/rslib.h>
# include <linux/slab.h>
2006-03-23 14:00:24 +03:00
# include <linux/mutex.h>
2005-04-17 02:20:36 +04:00
2018-04-22 19:23:55 +03:00
enum {
RS_DECODE_LAMBDA ,
RS_DECODE_SYN ,
RS_DECODE_B ,
RS_DECODE_T ,
RS_DECODE_OMEGA ,
RS_DECODE_ROOT ,
RS_DECODE_REG ,
RS_DECODE_LOC ,
RS_DECODE_NUM_BUFFERS
} ;
2018-04-22 19:23:53 +03:00
/* This list holds all currently allocated rs codec structures */
static LIST_HEAD ( codec_list ) ;
2005-04-17 02:20:36 +04:00
/* Protection for the list */
2006-03-23 14:00:24 +03:00
static DEFINE_MUTEX ( rslistlock ) ;
2005-04-17 02:20:36 +04:00
2005-11-07 14:15:37 +03:00
/**
2018-04-22 19:23:53 +03:00
* codec_init - Initialize a Reed - Solomon codec
2005-04-17 02:20:36 +04:00
* @ symsize : symbol size , bits ( 1 - 8 )
* @ gfpoly : Field generator polynomial coefficients
2007-05-02 14:18:41 +04:00
* @ gffunc : Field generator function
2005-04-17 02:20:36 +04:00
* @ fcr : first root of RS code generator polynomial , index form
* @ prim : primitive element to generate polynomial roots
* @ nroots : RS code generator polynomial degree ( number of roots )
2018-04-22 19:23:46 +03:00
* @ gfp : GFP_ flags for allocations
2005-04-17 02:20:36 +04:00
*
2018-04-22 19:23:53 +03:00
* Allocate a codec structure and the polynom arrays for faster
2006-06-25 16:49:14 +04:00
* en / decoding . Fill the arrays according to the given parameters .
2005-04-17 02:20:36 +04:00
*/
2018-04-22 19:23:53 +03:00
static struct rs_codec * codec_init ( int symsize , int gfpoly , int ( * gffunc ) ( int ) ,
int fcr , int prim , int nroots , gfp_t gfp )
2005-04-17 02:20:36 +04:00
{
int i , j , sr , root , iprim ;
2018-04-22 19:23:53 +03:00
struct rs_codec * rs ;
2005-04-17 02:20:36 +04:00
2018-04-22 19:23:52 +03:00
rs = kzalloc ( sizeof ( * rs ) , gfp ) ;
2018-04-22 19:23:46 +03:00
if ( ! rs )
2005-04-17 02:20:36 +04:00
return NULL ;
INIT_LIST_HEAD ( & rs - > list ) ;
rs - > mm = symsize ;
rs - > nn = ( 1 < < symsize ) - 1 ;
rs - > fcr = fcr ;
rs - > prim = prim ;
rs - > nroots = nroots ;
rs - > gfpoly = gfpoly ;
2007-05-02 14:18:41 +04:00
rs - > gffunc = gffunc ;
2005-04-17 02:20:36 +04:00
/* Allocate the arrays */
treewide: kmalloc() -> kmalloc_array()
The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
patch replaces cases of:
kmalloc(a * b, gfp)
with:
kmalloc_array(a * b, gfp)
as well as handling cases of:
kmalloc(a * b * c, gfp)
with:
kmalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kmalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kmalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The tools/ directory was manually excluded, since it has its own
implementation of kmalloc().
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kmalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kmalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kmalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kmalloc
+ kmalloc_array
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kmalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kmalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kmalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kmalloc(sizeof(THING) * C2, ...)
|
kmalloc(sizeof(TYPE) * C2, ...)
|
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(C1 * C2, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * E2
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 23:55:00 +03:00
rs - > alpha_to = kmalloc_array ( rs - > nn + 1 , sizeof ( uint16_t ) , gfp ) ;
2005-04-17 02:20:36 +04:00
if ( rs - > alpha_to = = NULL )
2018-04-22 19:23:52 +03:00
goto err ;
2005-04-17 02:20:36 +04:00
treewide: kmalloc() -> kmalloc_array()
The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
patch replaces cases of:
kmalloc(a * b, gfp)
with:
kmalloc_array(a * b, gfp)
as well as handling cases of:
kmalloc(a * b * c, gfp)
with:
kmalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kmalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kmalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The tools/ directory was manually excluded, since it has its own
implementation of kmalloc().
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kmalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kmalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kmalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kmalloc
+ kmalloc_array
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kmalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kmalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kmalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kmalloc(sizeof(THING) * C2, ...)
|
kmalloc(sizeof(TYPE) * C2, ...)
|
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(C1 * C2, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * E2
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 23:55:00 +03:00
rs - > index_of = kmalloc_array ( rs - > nn + 1 , sizeof ( uint16_t ) , gfp ) ;
2005-04-17 02:20:36 +04:00
if ( rs - > index_of = = NULL )
2018-04-22 19:23:52 +03:00
goto err ;
2005-04-17 02:20:36 +04:00
treewide: kmalloc() -> kmalloc_array()
The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
patch replaces cases of:
kmalloc(a * b, gfp)
with:
kmalloc_array(a * b, gfp)
as well as handling cases of:
kmalloc(a * b * c, gfp)
with:
kmalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kmalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kmalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The tools/ directory was manually excluded, since it has its own
implementation of kmalloc().
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kmalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kmalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kmalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kmalloc
+ kmalloc_array
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kmalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kmalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kmalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kmalloc(sizeof(THING) * C2, ...)
|
kmalloc(sizeof(TYPE) * C2, ...)
|
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(C1 * C2, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * E2
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 23:55:00 +03:00
rs - > genpoly = kmalloc_array ( rs - > nroots + 1 , sizeof ( uint16_t ) , gfp ) ;
2005-04-17 02:20:36 +04:00
if ( rs - > genpoly = = NULL )
2018-04-22 19:23:52 +03:00
goto err ;
2005-04-17 02:20:36 +04:00
/* Generate Galois field lookup tables */
rs - > index_of [ 0 ] = rs - > nn ; /* log(zero) = -inf */
rs - > alpha_to [ rs - > nn ] = 0 ; /* alpha**-inf = 0 */
2007-05-02 14:18:41 +04:00
if ( gfpoly ) {
sr = 1 ;
for ( i = 0 ; i < rs - > nn ; i + + ) {
rs - > index_of [ sr ] = i ;
rs - > alpha_to [ i ] = sr ;
sr < < = 1 ;
if ( sr & ( 1 < < symsize ) )
sr ^ = gfpoly ;
sr & = rs - > nn ;
}
} else {
sr = gffunc ( 0 ) ;
for ( i = 0 ; i < rs - > nn ; i + + ) {
rs - > index_of [ sr ] = i ;
rs - > alpha_to [ i ] = sr ;
sr = gffunc ( sr ) ;
}
2005-04-17 02:20:36 +04:00
}
/* If it's not primitive, exit */
2007-05-02 14:18:41 +04:00
if ( sr ! = rs - > alpha_to [ 0 ] )
2018-04-22 19:23:52 +03:00
goto err ;
2005-04-17 02:20:36 +04:00
/* Find prim-th root of 1, used in decoding */
for ( iprim = 1 ; ( iprim % prim ) ! = 0 ; iprim + = rs - > nn ) ;
/* prim-th root of 1, index form */
rs - > iprim = iprim / prim ;
/* Form RS code generator polynomial from its roots */
rs - > genpoly [ 0 ] = 1 ;
for ( i = 0 , root = fcr * prim ; i < nroots ; i + + , root + = prim ) {
rs - > genpoly [ i + 1 ] = 1 ;
/* Multiply rs->genpoly[] by @**(root + x) */
for ( j = i ; j > 0 ; j - - ) {
if ( rs - > genpoly [ j ] ! = 0 ) {
2005-11-07 14:15:37 +03:00
rs - > genpoly [ j ] = rs - > genpoly [ j - 1 ] ^
rs - > alpha_to [ rs_modnn ( rs ,
2005-04-17 02:20:36 +04:00
rs - > index_of [ rs - > genpoly [ j ] ] + root ) ] ;
} else
rs - > genpoly [ j ] = rs - > genpoly [ j - 1 ] ;
}
/* rs->genpoly[0] can never be zero */
2005-11-07 14:15:37 +03:00
rs - > genpoly [ 0 ] =
rs - > alpha_to [ rs_modnn ( rs ,
2005-04-17 02:20:36 +04:00
rs - > index_of [ rs - > genpoly [ 0 ] ] + root ) ] ;
}
/* convert rs->genpoly[] to index form for quicker encoding */
for ( i = 0 ; i < = nroots ; i + + )
rs - > genpoly [ i ] = rs - > index_of [ rs - > genpoly [ i ] ] ;
2018-04-22 19:23:53 +03:00
rs - > users = 1 ;
list_add ( & rs - > list , & codec_list ) ;
2005-04-17 02:20:36 +04:00
return rs ;
2018-04-22 19:23:52 +03:00
err :
2005-04-17 02:20:36 +04:00
kfree ( rs - > genpoly ) ;
kfree ( rs - > index_of ) ;
kfree ( rs - > alpha_to ) ;
kfree ( rs ) ;
return NULL ;
}
2005-11-07 14:15:37 +03:00
/**
2018-04-22 19:23:53 +03:00
* free_rs - Free the rs control structure
* @ rs : The control structure which is not longer used by the
2005-04-17 02:20:36 +04:00
* caller
2018-04-22 19:23:53 +03:00
*
* Free the control structure . If @ rs is the last user of the associated
* codec , free the codec as well .
2005-04-17 02:20:36 +04:00
*/
void free_rs ( struct rs_control * rs )
{
2018-04-22 19:23:53 +03:00
struct rs_codec * cd ;
if ( ! rs )
return ;
cd = rs - > codec ;
2006-03-23 14:00:24 +03:00
mutex_lock ( & rslistlock ) ;
2018-04-22 19:23:53 +03:00
cd - > users - - ;
if ( ! cd - > users ) {
list_del ( & cd - > list ) ;
kfree ( cd - > alpha_to ) ;
kfree ( cd - > index_of ) ;
kfree ( cd - > genpoly ) ;
kfree ( cd ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-23 14:00:24 +03:00
mutex_unlock ( & rslistlock ) ;
2018-04-22 19:23:53 +03:00
kfree ( rs ) ;
2005-04-17 02:20:36 +04:00
}
2018-04-22 19:23:46 +03:00
EXPORT_SYMBOL_GPL ( free_rs ) ;
2005-04-17 02:20:36 +04:00
2005-11-07 14:15:37 +03:00
/**
2018-04-22 19:23:53 +03:00
* init_rs_internal - Allocate rs control , find a matching codec or allocate a new one
2005-04-17 02:20:36 +04:00
* @ symsize : the symbol size ( number of bits )
* @ gfpoly : the extended Galois field generator polynomial coefficients ,
* with the 0 th coefficient in the low order bit . The polynomial
* must be primitive ;
2007-05-02 14:18:41 +04:00
* @ gffunc : pointer to function to generate the next field element ,
* or the multiplicative identity element if given 0. Used
* instead of gfpoly if gfpoly is 0
2018-04-22 19:23:48 +03:00
* @ fcr : the first consecutive root of the rs code generator polynomial
2005-04-17 02:20:36 +04:00
* in index form
* @ prim : primitive element to generate polynomial roots
* @ nroots : RS code generator polynomial degree ( number of roots )
2018-04-22 19:23:46 +03:00
* @ gfp : GFP_ flags for allocations
2005-04-17 02:20:36 +04:00
*/
2007-05-02 14:18:41 +04:00
static struct rs_control * init_rs_internal ( int symsize , int gfpoly ,
2018-04-22 19:23:46 +03:00
int ( * gffunc ) ( int ) , int fcr ,
int prim , int nroots , gfp_t gfp )
2005-04-17 02:20:36 +04:00
{
2018-04-22 19:23:46 +03:00
struct list_head * tmp ;
struct rs_control * rs ;
2018-04-22 19:23:55 +03:00
unsigned int bsize ;
2005-04-17 02:20:36 +04:00
/* Sanity checks */
if ( symsize < 1 )
return NULL ;
if ( fcr < 0 | | fcr > = ( 1 < < symsize ) )
2018-04-22 19:23:48 +03:00
return NULL ;
2005-04-17 02:20:36 +04:00
if ( prim < = 0 | | prim > = ( 1 < < symsize ) )
2018-04-22 19:23:48 +03:00
return NULL ;
2005-11-07 14:15:37 +03:00
if ( nroots < 0 | | nroots > = ( 1 < < symsize ) )
2005-04-17 02:20:36 +04:00
return NULL ;
2005-11-07 14:15:37 +03:00
2018-04-22 19:23:55 +03:00
/*
* The decoder needs buffers in each control struct instance to
* avoid variable size or large fixed size allocations on
* stack . Size the buffers to arrays of [ nroots + 1 ] .
*/
bsize = sizeof ( uint16_t ) * RS_DECODE_NUM_BUFFERS * ( nroots + 1 ) ;
rs = kzalloc ( sizeof ( * rs ) + bsize , gfp ) ;
2018-04-22 19:23:53 +03:00
if ( ! rs )
return NULL ;
2006-03-23 14:00:24 +03:00
mutex_lock ( & rslistlock ) ;
2005-04-17 02:20:36 +04:00
/* Walk through the list and look for a matching entry */
2018-04-22 19:23:53 +03:00
list_for_each ( tmp , & codec_list ) {
struct rs_codec * cd = list_entry ( tmp , struct rs_codec , list ) ;
if ( symsize ! = cd - > mm )
2005-04-17 02:20:36 +04:00
continue ;
2018-04-22 19:23:53 +03:00
if ( gfpoly ! = cd - > gfpoly )
2005-04-17 02:20:36 +04:00
continue ;
2018-04-22 19:23:53 +03:00
if ( gffunc ! = cd - > gffunc )
2007-05-02 14:18:41 +04:00
continue ;
2018-04-22 19:23:53 +03:00
if ( fcr ! = cd - > fcr )
2005-11-07 14:15:37 +03:00
continue ;
2018-04-22 19:23:53 +03:00
if ( prim ! = cd - > prim )
2005-11-07 14:15:37 +03:00
continue ;
2018-04-22 19:23:53 +03:00
if ( nroots ! = cd - > nroots )
2005-04-17 02:20:36 +04:00
continue ;
/* We have a matching one already */
2018-04-22 19:23:53 +03:00
cd - > users + + ;
rs - > codec = cd ;
2005-04-17 02:20:36 +04:00
goto out ;
}
/* Create a new one */
2018-04-22 19:23:53 +03:00
rs - > codec = codec_init ( symsize , gfpoly , gffunc , fcr , prim , nroots , gfp ) ;
if ( ! rs - > codec ) {
kfree ( rs ) ;
rs = NULL ;
2005-04-17 02:20:36 +04:00
}
2005-11-07 14:15:37 +03:00
out :
2006-03-23 14:00:24 +03:00
mutex_unlock ( & rslistlock ) ;
2005-04-17 02:20:36 +04:00
return rs ;
}
2007-05-02 14:18:41 +04:00
/**
2018-04-22 19:23:53 +03:00
* init_rs_gfp - Create a RS control struct and initialize it
2007-05-02 14:18:41 +04:00
* @ symsize : the symbol size ( number of bits )
* @ gfpoly : the extended Galois field generator polynomial coefficients ,
* with the 0 th coefficient in the low order bit . The polynomial
* must be primitive ;
2018-04-22 19:23:48 +03:00
* @ fcr : the first consecutive root of the rs code generator polynomial
2007-05-02 14:18:41 +04:00
* in index form
* @ prim : primitive element to generate polynomial roots
* @ nroots : RS code generator polynomial degree ( number of roots )
2018-07-03 22:43:54 +03:00
* @ gfp : Memory allocation flags .
2007-05-02 14:18:41 +04:00
*/
2018-04-22 19:23:46 +03:00
struct rs_control * init_rs_gfp ( int symsize , int gfpoly , int fcr , int prim ,
int nroots , gfp_t gfp )
2007-05-02 14:18:41 +04:00
{
2018-04-22 19:23:46 +03:00
return init_rs_internal ( symsize , gfpoly , NULL , fcr , prim , nroots , gfp ) ;
2007-05-02 14:18:41 +04:00
}
2018-04-22 19:23:46 +03:00
EXPORT_SYMBOL_GPL ( init_rs_gfp ) ;
2007-05-02 14:18:41 +04:00
/**
2018-04-22 19:23:53 +03:00
* init_rs_non_canonical - Allocate rs control struct for fields with
* non - canonical representation
2007-05-02 14:18:41 +04:00
* @ symsize : the symbol size ( number of bits )
* @ gffunc : pointer to function to generate the next field element ,
* or the multiplicative identity element if given 0. Used
* instead of gfpoly if gfpoly is 0
2018-04-22 19:23:48 +03:00
* @ fcr : the first consecutive root of the rs code generator polynomial
2007-05-02 14:18:41 +04:00
* in index form
* @ prim : primitive element to generate polynomial roots
* @ nroots : RS code generator polynomial degree ( number of roots )
*/
struct rs_control * init_rs_non_canonical ( int symsize , int ( * gffunc ) ( int ) ,
2018-04-22 19:23:48 +03:00
int fcr , int prim , int nroots )
2007-05-02 14:18:41 +04:00
{
2018-04-22 19:23:46 +03:00
return init_rs_internal ( symsize , 0 , gffunc , fcr , prim , nroots ,
GFP_KERNEL ) ;
2007-05-02 14:18:41 +04:00
}
2018-04-22 19:23:46 +03:00
EXPORT_SYMBOL_GPL ( init_rs_non_canonical ) ;
2007-05-02 14:18:41 +04:00
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_REED_SOLOMON_ENC8
2005-11-07 14:15:37 +03:00
/**
2005-04-17 02:20:36 +04:00
* encode_rs8 - Calculate the parity for data values ( 8 bit data width )
2018-04-22 19:23:53 +03:00
* @ rsc : the rs control structure
2005-04-17 02:20:36 +04:00
* @ data : data field of a given type
2005-11-07 14:15:37 +03:00
* @ len : data length
2005-04-17 02:20:36 +04:00
* @ par : parity data , must be initialized by caller ( usually all 0 )
* @ invmsk : invert data mask ( will be xored on data )
*
* The parity uses a uint16_t data type to enable
* symbol size > 8. The calling code must take care of encoding of the
* syndrome result for storage itself .
*/
2018-04-22 19:23:53 +03:00
int encode_rs8 ( struct rs_control * rsc , uint8_t * data , int len , uint16_t * par ,
2005-04-17 02:20:36 +04:00
uint16_t invmsk )
{
# include "encode_rs.c"
}
EXPORT_SYMBOL_GPL ( encode_rs8 ) ;
# endif
# ifdef CONFIG_REED_SOLOMON_DEC8
2005-11-07 14:15:37 +03:00
/**
2005-04-17 02:20:36 +04:00
* decode_rs8 - Decode codeword ( 8 bit data width )
2018-04-22 19:23:53 +03:00
* @ rsc : the rs control structure
2005-04-17 02:20:36 +04:00
* @ data : data field of a given type
* @ par : received parity data field
* @ len : data length
* @ s : syndrome data field ( if NULL , syndrome is calculated )
* @ no_eras : number of erasures
* @ eras_pos : position of erasures , can be NULL
* @ invmsk : invert data mask ( will be xored on data , not on parity ! )
* @ corr : buffer to store correction bitmask on eras_pos
*
* The syndrome and parity uses a uint16_t data type to enable
* symbol size > 8. The calling code must take care of decoding of the
* syndrome result and the received parity before calling this code .
2018-04-22 19:23:55 +03:00
*
* Note : The rs_control struct @ rsc contains buffers which are used for
* decoding , so the caller has to ensure that decoder invocations are
* serialized .
*
2007-10-21 01:16:32 +04:00
* Returns the number of corrected bits or - EBADMSG for uncorrectable errors .
2005-04-17 02:20:36 +04:00
*/
2018-04-22 19:23:53 +03:00
int decode_rs8 ( struct rs_control * rsc , uint8_t * data , uint16_t * par , int len ,
2005-11-07 14:15:37 +03:00
uint16_t * s , int no_eras , int * eras_pos , uint16_t invmsk ,
2005-04-17 02:20:36 +04:00
uint16_t * corr )
{
# include "decode_rs.c"
}
EXPORT_SYMBOL_GPL ( decode_rs8 ) ;
# endif
# ifdef CONFIG_REED_SOLOMON_ENC16
/**
* encode_rs16 - Calculate the parity for data values ( 16 bit data width )
2018-04-22 19:23:53 +03:00
* @ rsc : the rs control structure
2005-04-17 02:20:36 +04:00
* @ data : data field of a given type
2005-11-07 14:15:37 +03:00
* @ len : data length
2005-04-17 02:20:36 +04:00
* @ par : parity data , must be initialized by caller ( usually all 0 )
* @ invmsk : invert data mask ( will be xored on data , not on parity ! )
*
* Each field in the data array contains up to symbol size bits of valid data .
*/
2018-04-22 19:23:53 +03:00
int encode_rs16 ( struct rs_control * rsc , uint16_t * data , int len , uint16_t * par ,
2005-04-17 02:20:36 +04:00
uint16_t invmsk )
{
# include "encode_rs.c"
}
EXPORT_SYMBOL_GPL ( encode_rs16 ) ;
# endif
# ifdef CONFIG_REED_SOLOMON_DEC16
2005-11-07 14:15:37 +03:00
/**
2005-04-17 02:20:36 +04:00
* decode_rs16 - Decode codeword ( 16 bit data width )
2018-04-22 19:23:53 +03:00
* @ rsc : the rs control structure
2005-04-17 02:20:36 +04:00
* @ data : data field of a given type
* @ par : received parity data field
* @ len : data length
* @ s : syndrome data field ( if NULL , syndrome is calculated )
* @ no_eras : number of erasures
* @ eras_pos : position of erasures , can be NULL
2005-11-07 14:15:37 +03:00
* @ invmsk : invert data mask ( will be xored on data , not on parity ! )
2005-04-17 02:20:36 +04:00
* @ corr : buffer to store correction bitmask on eras_pos
*
* Each field in the data array contains up to symbol size bits of valid data .
2018-04-22 19:23:55 +03:00
*
* Note : The rc_control struct @ rsc contains buffers which are used for
* decoding , so the caller has to ensure that decoder invocations are
* serialized .
*
2007-10-21 01:16:32 +04:00
* Returns the number of corrected bits or - EBADMSG for uncorrectable errors .
2005-04-17 02:20:36 +04:00
*/
2018-04-22 19:23:53 +03:00
int decode_rs16 ( struct rs_control * rsc , uint16_t * data , uint16_t * par , int len ,
2005-11-07 14:15:37 +03:00
uint16_t * s , int no_eras , int * eras_pos , uint16_t invmsk ,
2005-04-17 02:20:36 +04:00
uint16_t * corr )
{
# include "decode_rs.c"
}
EXPORT_SYMBOL_GPL ( decode_rs16 ) ;
# endif
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " Reed Solomon encoder/decoder " ) ;
MODULE_AUTHOR ( " Phil Karn, Thomas Gleixner " ) ;