lib/bch.c

Source file repositories/reference/linux-study-clean/lib/bch.c

File Facts

System
Linux kernel
Corpus path
lib/bch.c
Extension
.c
Size
37575 bytes
Lines
1403
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

struct gf_poly {
	unsigned int deg;    /* polynomial degree */
	unsigned int c[];   /* polynomial terms */
};

/* given its degree, compute a polynomial size in bytes */
#define GF_POLY_SZ(_d) (sizeof(struct gf_poly)+((_d)+1)*sizeof(unsigned int))

/* polynomial of degree 1 */
struct gf_poly_deg1 {
	struct gf_poly poly;
	unsigned int   c[2];
};

static u8 swap_bits(struct bch_control *bch, u8 in)
{
	if (!bch->swap_bits)
		return in;

	return bitrev8(in);
}

/*
 * same as bch_encode(), but process input data one byte at a time
 */
static void bch_encode_unaligned(struct bch_control *bch,
				 const unsigned char *data, unsigned int len,
				 uint32_t *ecc)
{
	int i;
	const uint32_t *p;
	const int l = BCH_ECC_WORDS(bch)-1;

	while (len--) {
		u8 tmp = swap_bits(bch, *data++);

		p = bch->mod8_tab + (l+1)*(((ecc[0] >> 24)^(tmp)) & 0xff);

		for (i = 0; i < l; i++)
			ecc[i] = ((ecc[i] << 8)|(ecc[i+1] >> 24))^(*p++);

		ecc[l] = (ecc[l] << 8)^(*p);
	}
}

/*
 * convert ecc bytes to aligned, zero-padded 32-bit ecc words
 */
static void load_ecc8(struct bch_control *bch, uint32_t *dst,
		      const uint8_t *src)
{
	uint8_t pad[4] = {0, 0, 0, 0};
	unsigned int i, nwords = BCH_ECC_WORDS(bch)-1;

	for (i = 0; i < nwords; i++, src += 4)
		dst[i] = ((u32)swap_bits(bch, src[0]) << 24) |
			((u32)swap_bits(bch, src[1]) << 16) |
			((u32)swap_bits(bch, src[2]) << 8) |
			swap_bits(bch, src[3]);

	memcpy(pad, src, BCH_ECC_BYTES(bch)-4*nwords);
	dst[nwords] = ((u32)swap_bits(bch, pad[0]) << 24) |
		((u32)swap_bits(bch, pad[1]) << 16) |
		((u32)swap_bits(bch, pad[2]) << 8) |
		swap_bits(bch, pad[3]);
}

/*
 * convert 32-bit ecc words to ecc bytes
 */
static void store_ecc8(struct bch_control *bch, uint8_t *dst,
		       const uint32_t *src)
{
	uint8_t pad[4];
	unsigned int i, nwords = BCH_ECC_WORDS(bch)-1;

	for (i = 0; i < nwords; i++) {
		*dst++ = swap_bits(bch, src[i] >> 24);
		*dst++ = swap_bits(bch, src[i] >> 16);
		*dst++ = swap_bits(bch, src[i] >> 8);
		*dst++ = swap_bits(bch, src[i]);
	}
	pad[0] = swap_bits(bch, src[nwords] >> 24);
	pad[1] = swap_bits(bch, src[nwords] >> 16);
	pad[2] = swap_bits(bch, src[nwords] >> 8);
	pad[3] = swap_bits(bch, src[nwords]);
	memcpy(dst, pad, BCH_ECC_BYTES(bch)-4*nwords);
}

/**

Annotation

Implementation Notes