mirror of
https://github.com/torvalds/linux.git
synced 2025-04-09 14:45:27 +00:00

This CRC64 variant comes from the NVME NVM Command Set Specification (https://nvmexpress.org/wp-content/uploads/NVM-Express-NVM-Command-Set-Specification-1.0e-2024.07.29-Ratified.pdf). The "Rocksoft Model CRC Algorithm", published in 1993 and available at https://www.zlib.net/crc_v3.txt, is a generalized CRC algorithm that can calculate any variant of CRC, given a list of parameters such as polynomial, bit order, etc. It is not a CRC variant. The NVME NVM Command Set Specification has a table that gives the "Rocksoft Model Parameters" for the CRC variant it uses. When support for this CRC variant was added to Linux, this table seems to have been misinterpreted as naming the CRC variant the "Rocksoft" CRC. In fact, the table names the CRC variant as the "NVM Express 64b CRC". Most implementations of this CRC variant outside Linux have been calling it CRC64-NVME. Therefore, update Linux to match. While at it, remove the superfluous "update" from the function name, so crc64_rocksoft_update() is now just crc64_nvme(), matching most of the other CRC library functions. Reviewed-by: Ard Biesheuvel <ardb@kernel.org> Reviewed-by: "Martin K. Petersen" <martin.petersen@oracle.com> Acked-by: Keith Busch <kbusch@kernel.org> Link: https://lore.kernel.org/r/20250130035130.180676-4-ebiggers@kernel.org Signed-off-by: Eric Biggers <ebiggers@google.com>
96 lines
2.1 KiB
C
96 lines
2.1 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Generate lookup table for the table-driven CRC64 calculation.
|
|
*
|
|
* gen_crc64table is executed in kernel build time and generates
|
|
* lib/crc64table.h. This header is included by lib/crc64.c for
|
|
* the table-driven CRC64 calculation.
|
|
*
|
|
* See lib/crc64.c for more information about which specification
|
|
* and polynomial arithmetic that gen_crc64table.c follows to
|
|
* generate the lookup table.
|
|
*
|
|
* Copyright 2018 SUSE Linux.
|
|
* Author: Coly Li <colyli@suse.de>
|
|
*/
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
|
|
#define CRC64_ECMA182_POLY 0x42F0E1EBA9EA3693ULL
|
|
#define CRC64_NVME_POLY 0x9A6C9329AC4BC9B5ULL
|
|
|
|
static uint64_t crc64_table[256] = {0};
|
|
static uint64_t crc64_nvme_table[256] = {0};
|
|
|
|
static void generate_reflected_crc64_table(uint64_t table[256], uint64_t poly)
|
|
{
|
|
uint64_t i, j, c, crc;
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
crc = 0ULL;
|
|
c = i;
|
|
|
|
for (j = 0; j < 8; j++) {
|
|
if ((crc ^ (c >> j)) & 1)
|
|
crc = (crc >> 1) ^ poly;
|
|
else
|
|
crc >>= 1;
|
|
}
|
|
table[i] = crc;
|
|
}
|
|
}
|
|
|
|
static void generate_crc64_table(uint64_t table[256], uint64_t poly)
|
|
{
|
|
uint64_t i, j, c, crc;
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
crc = 0;
|
|
c = i << 56;
|
|
|
|
for (j = 0; j < 8; j++) {
|
|
if ((crc ^ c) & 0x8000000000000000ULL)
|
|
crc = (crc << 1) ^ poly;
|
|
else
|
|
crc <<= 1;
|
|
c <<= 1;
|
|
}
|
|
|
|
table[i] = crc;
|
|
}
|
|
}
|
|
|
|
static void output_table(uint64_t table[256])
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
printf("\t0x%016" PRIx64 "ULL", table[i]);
|
|
if (i & 0x1)
|
|
printf(",\n");
|
|
else
|
|
printf(", ");
|
|
}
|
|
printf("};\n");
|
|
}
|
|
|
|
static void print_crc64_tables(void)
|
|
{
|
|
printf("/* this file is generated - do not edit */\n\n");
|
|
printf("#include <linux/types.h>\n");
|
|
printf("#include <linux/cache.h>\n\n");
|
|
printf("static const u64 ____cacheline_aligned crc64table[256] = {\n");
|
|
output_table(crc64_table);
|
|
|
|
printf("\nstatic const u64 ____cacheline_aligned crc64nvmetable[256] = {\n");
|
|
output_table(crc64_nvme_table);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
generate_crc64_table(crc64_table, CRC64_ECMA182_POLY);
|
|
generate_reflected_crc64_table(crc64_nvme_table, CRC64_NVME_POLY);
|
|
print_crc64_tables();
|
|
return 0;
|
|
}
|