summaryrefslogtreecommitdiffstats
path: root/lib/reed_solomon/reed_solomon.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/reed_solomon/reed_solomon.c')
-rw-r--r--lib/reed_solomon/reed_solomon.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/reed_solomon/reed_solomon.c b/lib/reed_solomon/reed_solomon.c
index cb21e8b5a4e0e..dfcf54242fb92 100644
--- a/lib/reed_solomon/reed_solomon.c
+++ b/lib/reed_solomon/reed_solomon.c
@@ -37,6 +37,18 @@
#include <linux/slab.h>
#include <linux/mutex.h>
+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
+};
+
/* This list holds all currently allocated rs codec structures */
static LIST_HEAD(codec_list);
/* Protection for the list */
@@ -204,6 +216,7 @@ static struct rs_control *init_rs_internal(int symsize, int gfpoly,
{
struct list_head *tmp;
struct rs_control *rs;
+ unsigned int bsize;
/* Sanity checks */
if (symsize < 1)
@@ -215,7 +228,13 @@ static struct rs_control *init_rs_internal(int symsize, int gfpoly,
if (nroots < 0 || nroots >= (1<<symsize))
return NULL;
- rs = kzalloc(sizeof(*rs), GFP_KERNEL);
+ /*
+ * 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);
if (!rs)
return NULL;
@@ -330,6 +349,11 @@ EXPORT_SYMBOL_GPL(encode_rs8);
* 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.
+ *
+ * Note: The rs_control struct @rsc contains buffers which are used for
+ * decoding, so the caller has to ensure that decoder invocations are
+ * serialized.
+ *
* Returns the number of corrected bits or -EBADMSG for uncorrectable errors.
*/
int decode_rs8(struct rs_control *rsc, uint8_t *data, uint16_t *par, int len,
@@ -374,6 +398,11 @@ EXPORT_SYMBOL_GPL(encode_rs16);
* @corr: buffer to store correction bitmask on eras_pos
*
* Each field in the data array contains up to symbol size bits of valid data.
+ *
+ * Note: The rc_control struct @rsc contains buffers which are used for
+ * decoding, so the caller has to ensure that decoder invocations are
+ * serialized.
+ *
* Returns the number of corrected bits or -EBADMSG for uncorrectable errors.
*/
int decode_rs16(struct rs_control *rsc, uint16_t *data, uint16_t *par, int len,