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;
 }