rsk.struct_version = 2;
rsk.uid = ROLLBACK_SPACE_KERNEL_UID;
rsk.kernel_versions = 0;
- rsk.crc8 = crc8((unsigned char *)&rsk,
+ rsk.crc8 = crc8(0, (unsigned char *)&rsk,
offsetof(struct rollback_space_kernel,
crc8));
memcpy(data, &rsk, sizeof(rsk));
* This uses an x^8 + x^2 + x + 1 polynomial. A table-based algorithm would
* be faster, but for only a few bytes it isn't worth the code size
*
+ * @crc_start: CRC8 start value
* @vptr: Buffer to checksum
* @len: Length of buffer in bytes
* @return CRC8 checksum
*/
-unsigned int crc8(const unsigned char *vptr, int len);
+unsigned int crc8(unsigned int crc_start, const unsigned char *vptr, int len);
#endif
#include "linux/crc8.h"
-unsigned int crc8(const unsigned char *vptr, int len)
+#define POLY (0x1070U << 3)
+
+static unsigned char _crc8(unsigned short data)
{
- const unsigned char *data = vptr;
- unsigned int crc = 0;
- int i, j;
-
- for (j = len; j; j--, data++) {
- crc ^= (*data << 8);
- for (i = 8; i; i--) {
- if (crc & 0x8000)
- crc ^= (0x1070 << 3);
- crc <<= 1;
- }
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if (data & 0x8000)
+ data = data ^ POLY;
+ data = data << 1;
}
- return (crc >> 8) & 0xff;
+ return (unsigned char)(data >> 8);
+}
+
+unsigned int crc8(unsigned int crc, const unsigned char *vptr, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ crc = _crc8((crc ^ vptr[i]) << 8);
+
+ return crc;
}