2003-05-17 17:31:59

by David Woodhouse

[permalink] [raw]
Subject: [PATCH] Shared crc32 for 2.4.

This has been needed for a long time... please pull from
master.kernel.org:/home/dwmw2/BK/crc32-2.4 or apply the GNU patch below.

I can resend for 2.4.22-pre1 if you prefer, but it's been working in 2.5
and in various other 2.4 trees for a while now so I'm sending it now
anyway.

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1209 -> 1.1210
# drivers/usb/usbnet.c 1.21 -> 1.22
# fs/jffs2/readinode.c 1.5 -> 1.6
# lib/Makefile 1.9 -> 1.10
# fs/jffs2/erase.c 1.3 -> 1.4
# net/bluetooth/bnep/crc32.c 1.1 -> (deleted)
# net/bluetooth/bnep/crc32.h 1.1 -> (deleted)
# fs/jffs2/Makefile 1.4 -> 1.5
# fs/jffs2/dir.c 1.5 -> 1.6
# fs/jffs2/gc.c 1.5 -> 1.6
# fs/jffs2/crc32.c 1.1 -> (deleted)
# fs/jffs2/read.c 1.2 -> 1.3
# include/linux/crc32.h 1.1 -> 1.2
# fs/jffs2/scan.c 1.4 -> 1.5
# fs/jffs2/crc32.h 1.1 -> (deleted)
# drivers/usb/catc.c 1.8 -> 1.9
# fs/jffs2/write.c 1.4 -> 1.5
# fs/jffs2/file.c 1.5 -> 1.6
# fs/partitions/efi.c 1.2 -> 1.3
# net/bluetooth/bnep/Makefile 1.2 -> 1.3
# lib/Config.in 1.1 -> 1.2
# net/bluetooth/bnep/bnep.h 1.3 -> 1.4
# net/bluetooth/bnep/core.c 1.7 -> 1.8
# (new) -> 1.1 fs/Makefile.lib
# (new) -> 1.1 drivers/net/Makefile.lib
# (new) -> 1.1 lib/gen_crc32table
# (new) -> 1.1 lib/crc32defs.h
# (new) -> 1.1 lib/crc32table.h
# (new) -> 1.1 lib/gen_crc32table.c
# (new) -> 1.1 lib/crc32.c
# (new) -> 1.1 net/bluetooth/bnep/Makefile.lib
# (new) -> 1.1 drivers/usb/Makefile.lib
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/05/17 [email protected] 1.1210
# Backport optimised and shared CRC32 functions from 2.5
# --------------------------------------------
#
diff -Nru a/drivers/net/Makefile.lib b/drivers/net/Makefile.lib
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/net/Makefile.lib Sat May 17 18:11:24 2003
@@ -0,0 +1,74 @@
+# These drivers all require crc32.o
+obj-$(CONFIG_8139CP) += crc32.o
+obj-$(CONFIG_8139TOO) += crc32.o
+obj-$(CONFIG_A2065) += crc32.o
+obj-$(CONFIG_ADAPTEC_STARFIRE) += crc32.o
+obj-$(CONFIG_AMD8111_ETH) += crc32.o
+obj-$(CONFIG_ARM_AM79C961A) += crc32.o
+obj-$(CONFIG_AT1700) += crc32.o
+obj-$(CONFIG_ATP) += crc32.o
+obj-$(CONFIG_BMAC) += crc32.o
+obj-$(CONFIG_DE4X5) += crc32.o
+obj-$(CONFIG_DECLANCE) += crc32.o
+obj-$(CONFIG_DEPCA) += crc32.o
+obj-$(CONFIG_DL2K) += crc32.o
+obj-$(CONFIG_DM9102) += crc32.o
+obj-$(CONFIG_EPIC100) += crc32.o
+obj-$(CONFIG_EWRK3) += crc32.o
+obj-$(CONFIG_FEALNX) += crc32.o
+obj-$(CONFIG_GMAC) += crc32.o
+obj-$(CONFIG_HAPPYMEAL) += crc32.o
+obj-$(CONFIG_MACE) += crc32.o
+obj-$(CONFIG_MACMACE) += crc32.o
+obj-$(CONFIG_PCNET32) += crc32.o
+obj-$(CONFIG_R8169) += crc32.o
+obj-$(CONFIG_SGI_IOC3_ETH) += crc32.o
+obj-$(CONFIG_SIS900) += crc32.o
+obj-$(CONFIG_SMC9194) += crc32.o
+obj-$(CONFIG_SUNBMAC) += crc32.o
+obj-$(CONFIG_SUNDANCE) += crc32.o
+obj-$(CONFIG_SUNGEM) += crc32.o
+obj-$(CONFIG_SUNLANCE) += crc32.o
+obj-$(CONFIG_SUNQE) += crc32.o
+obj-$(CONFIG_TYPHOON) += crc32.o
+obj-$(CONFIG_VIA_RHINE) += crc32.o
+obj-$(CONFIG_WINBOND_840) += crc32.o
+obj-$(CONFIG_YELLOWFIN) += crc32.o
+
+# These rely on drivers/net/7990.o which requires crc32.o
+obj-$(CONFIG_HPLANCE) += crc32.o
+obj-$(CONFIG_MVME147_NET) += crc32.o
+
+# These rely on drivers/net/8390.o which requires crc32.o
+obj-$(CONFIG_OAKNET) += crc32.o
+obj-$(CONFIG_NE2K_PCI) += crc32.o
+obj-$(CONFIG_STNIC) += crc32.o
+obj-$(CONFIG_MAC8390) += crc32.o
+obj-$(CONFIG_APNE) += crc32.o
+obj-$(CONFIG_PCMCIA_PCNET) += crc32.o
+obj-$(CONFIG_ARM_ETHERH) += crc32.o
+obj-$(CONFIG_WD80x3) += crc32.o
+obj-$(CONFIG_EL2) += crc32.o
+obj-$(CONFIG_NE2000) += crc32.o
+obj-$(CONFIG_NE2_MCA) += crc32.o
+obj-$(CONFIG_HPLAN) += crc32.o
+obj-$(CONFIG_HPLAN_PLUS) += crc32.o
+obj-$(CONFIG_ULTRA) += crc32.o
+obj-$(CONFIG_ULTRAMCA) += crc32.o
+obj-$(CONFIG_ULTRA32) += crc32.o
+obj-$(CONFIG_E2100) += crc32.o
+obj-$(CONFIG_ES3210) += crc32.o
+obj-$(CONFIG_LNE390) += crc32.o
+obj-$(CONFIG_NE3210) += crc32.o
+obj-$(CONFIG_AC3200) += crc32.o
+obj-$(CONFIG_ARIADNE2) += crc32.o
+obj-$(CONFIG_HYDRA) += crc32.o
+
+# drivers/net/pcmcia
+obj-$(CONFIG_PCMCIA_FMVJ18X) += crc32.o
+obj-$(CONFIG_PCMCIA_SMC91C92) += crc32.o
+obj-$(CONFIG_PCMCIA_XIRTULIP) += crc32.o
+
+# drivers/net/tulip
+obj-$(CONFIG_TULIP) += crc32.o
+
diff -Nru a/drivers/usb/Makefile.lib b/drivers/usb/Makefile.lib
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/Makefile.lib Sat May 17 18:11:24 2003
@@ -0,0 +1,3 @@
+obj-$(CONFIG_USB_USBNET) += crc32.o
+obj-$(CONFIG_USB_CATC) += crc32.o
+
diff -Nru a/drivers/usb/catc.c b/drivers/usb/catc.c
--- a/drivers/usb/catc.c Sat May 17 18:11:24 2003
+++ b/drivers/usb/catc.c Sat May 17 18:11:24 2003
@@ -42,6 +42,7 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
+#include <linux/crc32.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>

@@ -596,20 +597,9 @@
* Receive modes. Broadcast, Multicast, Promisc.
*/

-static inline u32 ether_crc_le(int cnt, unsigned char *addr)
-{
- unsigned int crc = 0xffffffff;
- u8 byte, idx, bit;
-
- for (idx = 0; idx < cnt; idx++)
- for (byte = *addr++, bit = 0; bit < 8; bit++, byte >>= 1)
- crc = (crc >> 1) ^ (((crc ^ byte) & 1) ? 0xedb88320U : 0);
- return crc;
-}
-
static void catc_multicast(unsigned char *addr, u8 *multicast)
{
- unsigned int crc = ether_crc_le(6, addr);
+ u32 crc = ether_crc_le(6, addr);
multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7);
}

diff -Nru a/drivers/usb/usbnet.c b/drivers/usb/usbnet.c
--- a/drivers/usb/usbnet.c Sat May 17 18:11:24 2003
+++ b/drivers/usb/usbnet.c Sat May 17 18:11:24 2003
@@ -1306,6 +1306,8 @@

#ifdef CONFIG_USB_ZAURUS

+#include <linux/crc32.h>
+
/*-------------------------------------------------------------------------
*
* Zaurus is also a SA-1110 based PDA, but one using a different driver
@@ -1318,57 +1320,6 @@
*
*-------------------------------------------------------------------------*/

-// NOTE: so far on 2.4 <linux/crc32.h> isn't for "bulk data" like this.
-// On 2.5 crc32_le() handles this for us.
-
-static const u32 crc32_table [256] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
- 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
- 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
- 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
- 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
- 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
- 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
- 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
- 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
- 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
- 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
- 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
- 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
- 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
- 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
- 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
- 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
- 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
-};
-
-#define CRC32_INITFCS 0xffffffff // Initial FCS value
-#define CRC32_FCS(fcs, c) (((fcs) >> 8) ^ crc32_table[((fcs) ^ (c)) & 0xff])
-
-/* fcs_compute32 - memcpy and calculate fcs
- * Perform a memcpy and calculate fcs using ppp 32bit CRC algorithm.
- */
-static inline u32 fcs_compute32 (unsigned char *sp, int len, u32 fcs)
-{
- for (;len-- > 0; fcs = CRC32_FCS (fcs, *sp++))
- continue;
- return fcs;
-}
-
static struct sk_buff *
zaurus_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags)
{
@@ -1387,7 +1338,7 @@
if (skb) {
u32 fcs;
done:
- fcs = fcs_compute32 (skb->data, skb->len, CRC32_INITFCS);
+ fcs = crc32_le (~0, skb->data, skb->len);
fcs = ~fcs;

*skb_put (skb, 1) = fcs & 0xff;
diff -Nru a/fs/Makefile.lib b/fs/Makefile.lib
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/fs/Makefile.lib Sat May 17 18:11:24 2003
@@ -0,0 +1,2 @@
+obj-$(CONFIG_JFFS2_FS) += crc32.o
+obj-$(CONFIG_EFI_PARTITION) += crc32.o
diff -Nru a/fs/jffs2/Makefile b/fs/jffs2/Makefile
--- a/fs/jffs2/Makefile Sat May 17 18:11:24 2003
+++ b/fs/jffs2/Makefile Sat May 17 18:11:24 2003
@@ -12,7 +12,7 @@

COMPR_OBJS := compr.o compr_rubin.o compr_rtime.o pushpull.o \
compr_zlib.o
-JFFS2_OBJS := crc32.o dir.o file.o ioctl.o nodelist.o malloc.o \
+JFFS2_OBJS := dir.o file.o ioctl.o nodelist.o malloc.o \
read.o nodemgmt.o readinode.o super.o write.o scan.o gc.o \
symlink.o build.o erase.o background.o

diff -Nru a/fs/jffs2/crc32.c b/fs/jffs2/crc32.c
--- a/fs/jffs2/crc32.c Sat May 17 18:11:24 2003
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,97 +0,0 @@
-/*
- * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
- * code or tables extracted from it, as desired without restriction.
- *
- * First, the polynomial itself and its table of feedback terms. The
- * polynomial is
- * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
- *
- * Note that we take it "backwards" and put the highest-order term in
- * the lowest-order bit. The X^32 term is "implied"; the LSB is the
- * X^31 term, etc. The X^0 term (usually shown as "+1") results in
- * the MSB being 1
- *
- * Note that the usual hardware shift register implementation, which
- * is what we're using (we're merely optimizing it by doing eight-bit
- * chunks at a time) shifts bits into the lowest-order term. In our
- * implementation, that means shifting towards the right. Why do we
- * do it this way? Because the calculated CRC must be transmitted in
- * order from highest-order term to lowest-order term. UARTs transmit
- * characters in order from LSB to MSB. By storing the CRC this way
- * we hand it to the UART in the order low-byte to high-byte; the UART
- * sends each low-bit to hight-bit; and the result is transmission bit
- * by bit from highest- to lowest-order term without requiring any bit
- * shuffling on our part. Reception works similarly
- *
- * The feedback terms table consists of 256, 32-bit entries. Notes
- *
- * The table can be generated at runtime if desired; code to do so
- * is shown later. It might not be obvious, but the feedback
- * terms simply represent the results of eight shift/xor opera
- * tions for all combinations of data and CRC register values
- *
- * The values must be right-shifted by eight bits by the "updcrc
- * logic; the shift must be unsigned (bring in zeroes). On some
- * hardware you could probably optimize the shift in assembler by
- * using byte-swap instructions
- * polynomial $edb88320
- */
-
-/* $Id: crc32.c,v 1.3 2001/02/07 16:45:32 dwmw2 Exp $ */
-
-#include "crc32.h"
-
-const __u32 crc32_table[256] = {
- 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
- 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
- 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
- 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
- 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
- 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
- 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
- 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
- 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
- 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
- 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
- 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
- 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
- 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
- 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
- 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
- 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
- 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
- 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
- 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
- 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
- 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
- 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
- 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
- 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
- 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
- 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
- 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
- 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
- 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
- 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
- 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
- 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
- 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
- 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
- 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
- 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
- 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
- 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
- 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
- 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
- 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
- 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
- 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
- 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
- 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
- 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
- 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
- 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
- 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
- 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
- 0x2d02ef8dL
-};
diff -Nru a/fs/jffs2/crc32.h b/fs/jffs2/crc32.h
--- a/fs/jffs2/crc32.h Sat May 17 18:11:24 2003
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,21 +0,0 @@
-#ifndef CRC32_H
-#define CRC32_H
-
-/* $Id: crc32.h,v 1.3 2001/02/26 14:44:37 dwmw2 Exp $ */
-
-#include <linux/types.h>
-
-extern const __u32 crc32_table[256];
-
-/* Return a 32-bit CRC of the contents of the buffer. */
-
-static inline __u32
-crc32(__u32 val, const void *ss, int len)
-{
- const unsigned char *s = ss;
- while (--len >= 0)
- val = crc32_table[(val ^ *s++) & 0xff] ^ (val >> 8);
- return val;
-}
-
-#endif
diff -Nru a/fs/jffs2/dir.c b/fs/jffs2/dir.c
--- a/fs/jffs2/dir.c Sat May 17 18:11:24 2003
+++ b/fs/jffs2/dir.c Sat May 17 18:11:24 2003
@@ -43,7 +43,7 @@
#include <linux/jffs2_fs_i.h>
#include <linux/jffs2_fs_sb.h>
#include "nodelist.h"
-#include "crc32.h"
+#include <linux/crc32.h>

static int jffs2_readdir (struct file *, void *, filldir_t);

diff -Nru a/fs/jffs2/erase.c b/fs/jffs2/erase.c
--- a/fs/jffs2/erase.c Sat May 17 18:11:24 2003
+++ b/fs/jffs2/erase.c Sat May 17 18:11:24 2003
@@ -40,7 +40,7 @@
#include <linux/jffs2.h>
#include <linux/interrupt.h>
#include "nodelist.h"
-#include "crc32.h"
+#include <linux/crc32.h>

struct erase_priv_struct {
struct jffs2_eraseblock *jeb;
diff -Nru a/fs/jffs2/file.c b/fs/jffs2/file.c
--- a/fs/jffs2/file.c Sat May 17 18:11:24 2003
+++ b/fs/jffs2/file.c Sat May 17 18:11:24 2003
@@ -42,7 +42,7 @@
#include <linux/pagemap.h>
#include <linux/jffs2.h>
#include "nodelist.h"
-#include "crc32.h"
+#include <linux/crc32.h>

extern int generic_file_open(struct inode *, struct file *) __attribute__((weak));
extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) __attribute__((weak));
diff -Nru a/fs/jffs2/gc.c b/fs/jffs2/gc.c
--- a/fs/jffs2/gc.c Sat May 17 18:11:24 2003
+++ b/fs/jffs2/gc.c Sat May 17 18:11:24 2003
@@ -43,7 +43,7 @@
#include <linux/interrupt.h>
#include <linux/pagemap.h>
#include "nodelist.h"
-#include "crc32.h"
+#include <linux/crc32.h>

static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
struct inode *inode, struct jffs2_full_dnode *fd);
diff -Nru a/fs/jffs2/read.c b/fs/jffs2/read.c
--- a/fs/jffs2/read.c Sat May 17 18:11:24 2003
+++ b/fs/jffs2/read.c Sat May 17 18:11:24 2003
@@ -40,7 +40,7 @@
#include <linux/jffs2.h>
#include <linux/mtd/mtd.h>
#include "nodelist.h"
-#include "crc32.h"
+#include <linux/crc32.h>

int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_full_dnode *fd, unsigned char *buf, int ofs, int len)
{
diff -Nru a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
--- a/fs/jffs2/readinode.c Sat May 17 18:11:24 2003
+++ b/fs/jffs2/readinode.c Sat May 17 18:11:24 2003
@@ -44,7 +44,7 @@
#include <linux/mtd/mtd.h>
#include <linux/jffs2.h>
#include "nodelist.h"
-#include "crc32.h"
+#include <linux/crc32.h>


D1(void jffs2_print_frag_list(struct jffs2_inode_info *f)
diff -Nru a/fs/jffs2/scan.c b/fs/jffs2/scan.c
--- a/fs/jffs2/scan.c Sat May 17 18:11:24 2003
+++ b/fs/jffs2/scan.c Sat May 17 18:11:24 2003
@@ -40,7 +40,7 @@
#include <linux/mtd/mtd.h>
#include <linux/pagemap.h>
#include "nodelist.h"
-#include "crc32.h"
+#include <linux/crc32.h>


#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
diff -Nru a/fs/jffs2/write.c b/fs/jffs2/write.c
--- a/fs/jffs2/write.c Sat May 17 18:11:24 2003
+++ b/fs/jffs2/write.c Sat May 17 18:11:24 2003
@@ -40,7 +40,7 @@
#include <linux/jffs2.h>
#include <linux/mtd/mtd.h>
#include "nodelist.h"
-#include "crc32.h"
+#include <linux/crc32.h>

/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
fill in the raw_inode while you're at it. */
diff -Nru a/fs/partitions/efi.c b/fs/partitions/efi.c
--- a/fs/partitions/efi.c Sat May 17 18:11:24 2003
+++ b/fs/partitions/efi.c Sat May 17 18:11:24 2003
@@ -99,6 +99,7 @@
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
+#include <linux/crc32.h>
#include <asm/system.h>
#include <asm/byteorder.h>
#include "check.h"
@@ -138,73 +139,6 @@
}
__setup("gpt", force_gpt_fn);

-
-/*
- * There are multiple 16-bit CRC polynomials in common use, but this is
- * *the* standard CRC-32 polynomial, first popularized by Ethernet.
- * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0
- */
-#define CRCPOLY_LE 0xedb88320
-/* How many bits at a time to use. Requires a table of 4<<CRC_xx_BITS bytes. */
-/* For less performance-sensitive, use 4 */
-#define CRC_LE_BITS 8
-static u32 *crc32table_le;
-
-/**
- * crc32init_le() - allocate and initialize LE table data
- *
- * crc is the crc of the byte i; other entries are filled in based on the
- * fact that crctable[i^j] = crctable[i] ^ crctable[j].
- *
- */
-static int __init crc32init_le(void)
-{
- unsigned i, j;
- u32 crc = 1;
-
- crc32table_le =
- kmalloc((1 << CRC_LE_BITS) * sizeof(u32), GFP_KERNEL);
- if (!crc32table_le)
- return 1;
- crc32table_le[0] = 0;
-
- for (i = 1 << (CRC_LE_BITS - 1); i; i >>= 1) {
- crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
- for (j = 0; j < 1 << CRC_LE_BITS; j += 2 * i)
- crc32table_le[i + j] = crc ^ crc32table_le[j];
- }
- return 0;
-}
-
-/**
- * crc32cleanup_le(): free LE table data
- */
-static void __exit crc32cleanup_le(void)
-{
- if (crc32table_le) kfree(crc32table_le);
- crc32table_le = NULL;
-}
-
-__initcall(crc32init_le);
-__exitcall(crc32cleanup_le);
-
-/**
- * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
- * @crc - seed value for computation. ~0 for Ethernet, sometimes 0 for
- * other uses, or the previous crc32 value if computing incrementally.
- * @p - pointer to buffer over which CRC is run
- * @len - length of buffer @p
- *
- */
-static u32 crc32_le(u32 crc, unsigned char const *p, size_t len)
-{
- while (len--) {
- crc = (crc >> 8) ^ crc32table_le[(crc ^ *p++) & 255];
- }
- return crc;
-}
-
-
/**
* efi_crc32() - EFI version of crc32 function
* @buf: buffer to calculate crc32 of
@@ -220,7 +154,7 @@
static inline u32
efi_crc32(const void *buf, unsigned long len)
{
- return (crc32_le(~0L, buf, len) ^ ~0L);
+ return (crc32(~0L, buf, len) ^ ~0L);
}

/**
diff -Nru a/include/linux/crc32.h b/include/linux/crc32.h
--- a/include/linux/crc32.h Sat May 17 18:11:24 2003
+++ b/include/linux/crc32.h Sat May 17 18:11:24 2003
@@ -1,49 +1,27 @@
/*
- * crc32.h for early Linux 2.4.19pre kernel inclusion
- * This defines ether_crc_le() and ether_crc() as inline functions
- * This is slated to change to using the library crc32 functions
- * as kernel 2.5.2 included at some future date.
+ * crc32.h
+ * See linux/lib/crc32.c for license and changes
*/
#ifndef _LINUX_CRC32_H
#define _LINUX_CRC32_H

#include <linux/types.h>

-/* The little-endian AUTODIN II ethernet CRC calculation.
- N.B. Do not use for bulk data, use a table-based routine instead.
- This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline unsigned ether_crc_le(int length, unsigned char *data)
-{
- unsigned int crc = 0xffffffff; /* Initial value. */
- while(--length >= 0) {
- unsigned char current_octet = *data++;
- int bit;
- for (bit = 8; --bit >= 0; current_octet >>= 1) {
- if ((crc ^ current_octet) & 1) {
- crc >>= 1;
- crc ^= ethernet_polynomial_le;
- } else
- crc >>= 1;
- }
- }
- return crc;
-}
+extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len);
+extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len);
+extern u32 bitreverse(u32 in);

-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc(int length, unsigned char *data)
-{
- int crc = -1;
- while (--length >= 0) {
- unsigned char current_octet = *data++;
- int bit;
- for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
- crc = (crc << 1) ^
- ((crc < 0) ^ (current_octet & 1) ?
- ethernet_polynomial : 0);
- }
- }
- return crc;
-}
+#define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)data, length)
+
+/*
+ * Helpers for hash table generation of ethernet nics:
+ *
+ * Ethernet sends the least significant bit of a byte first, thus crc32_le
+ * is used. The output of crc32_le is bit reversed [most significant bit
+ * is in bit nr 0], thus it must be reversed before use. Except for
+ * nics that bit swap the result internally...
+ */
+#define ether_crc(length, data) bitreverse(crc32_le(~0, data, length))
+#define ether_crc_le(length, data) crc32_le(~0, data, length)

#endif /* _LINUX_CRC32_H */
diff -Nru a/lib/Config.in b/lib/Config.in
--- a/lib/Config.in Sat May 17 18:11:24 2003
+++ b/lib/Config.in Sat May 17 18:11:24 2003
@@ -4,6 +4,8 @@
mainmenu_option next_comment
comment 'Library routines'

+tristate 'CRC32 functions' CONFIG_CRC32
+
#
# Do we need the compression support?
#
diff -Nru a/lib/Makefile b/lib/Makefile
--- a/lib/Makefile Sat May 17 18:11:24 2003
+++ b/lib/Makefile Sat May 17 18:11:24 2003
@@ -1,4 +1,4 @@
-#
+ #
# Makefile for some libs needed in the kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
@@ -8,7 +8,7 @@

L_TARGET := lib.a

-export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o
+export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o crc32.o

obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o \
bust_spinlocks.o rbtree.o dump_stack.o
@@ -20,10 +20,26 @@
obj-y += dec_and_lock.o
endif

+obj-$(CONFIG_CRC32) += crc32.o
+
subdir-$(CONFIG_ZLIB_INFLATE) += zlib_inflate
subdir-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate

+include $(TOPDIR)/drivers/net/Makefile.lib
+include $(TOPDIR)/drivers/usb/Makefile.lib
+include $(TOPDIR)/fs/Makefile.lib
+include $(TOPDIR)/net/bluetooth/bnep/Makefile.lib
+
# Include the subdirs, if necessary.
obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))

+
include $(TOPDIR)/Rules.make
+
+crc32.o: crc32table.h
+
+gen_crc32table: gen_crc32table.c
+ $(HOSTCC) $(HOSTCCFLAGS) -o $@ $<
+
+crc32table.h: gen_crc32table
+ ./$< > $@
diff -Nru a/lib/crc32.c b/lib/crc32.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/lib/crc32.c Sat May 17 18:11:24 2003
@@ -0,0 +1,536 @@
+/*
+ * Oct 15, 2000 Matt Domsch <[email protected]>
+ * Nicer crc32 functions/docs submitted by [email protected]. Thanks!
+ *
+ * Oct 12, 2000 Matt Domsch <[email protected]>
+ * Same crc32 function was used in 5 other places in the kernel.
+ * I made one version, and deleted the others.
+ * There are various incantations of crc32(). Some use a seed of 0 or ~0.
+ * Some xor at the end with ~0. The generic crc32() function takes
+ * seed as an argument, and doesn't xor at the end. Then individual
+ * users can do whatever they need.
+ * drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0.
+ * fs/jffs2 uses seed 0, doesn't xor with ~0.
+ * fs/partitions/efi.c uses seed ~0, xor's with ~0.
+ *
+ */
+
+#include <linux/crc32.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <asm/atomic.h>
+#include "crc32defs.h"
+#if CRC_LE_BITS == 8
+#define tole(x) __constant_cpu_to_le32(x)
+#define tobe(x) __constant_cpu_to_be32(x)
+#else
+#define tole(x) (x)
+#define tobe(x) (x)
+#endif
+#include "crc32table.h"
+
+#if __GNUC__ >= 3 /* 2.x has "attribute", but only 3.0 has "pure */
+#define attribute(x) __attribute__(x)
+#else
+#define attribute(x)
+#endif
+
+/*
+ * This code is in the public domain; copyright abandoned.
+ * Liability for non-performance of this code is limited to the amount
+ * you paid for it. Since it is distributed for free, your refund will
+ * be very very small. If it breaks, you get to keep both pieces.
+ */
+
+MODULE_AUTHOR("Matt Domsch <[email protected]>");
+MODULE_DESCRIPTION("Ethernet CRC32 calculations");
+MODULE_LICENSE("GPL and additional rights");
+
+#if CRC_LE_BITS == 1
+/*
+ * In fact, the table-based code will work in this case, but it can be
+ * simplified by inlining the table in ?: form.
+ */
+
+/**
+ * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
+ * @crc - seed value for computation. ~0 for Ethernet, sometimes 0 for
+ * other uses, or the previous crc32 value if computing incrementally.
+ * @p - pointer to buffer over which CRC is run
+ * @len - length of buffer @p
+ *
+ */
+u32 attribute((pure)) crc32_le(u32 crc, unsigned char const *p, size_t len)
+{
+ int i;
+ while (len--) {
+ crc ^= *p++;
+ for (i = 0; i < 8; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+ }
+ return crc;
+}
+#else /* Table-based approach */
+
+/**
+ * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
+ * @crc - seed value for computation. ~0 for Ethernet, sometimes 0 for
+ * other uses, or the previous crc32 value if computing incrementally.
+ * @p - pointer to buffer over which CRC is run
+ * @len - length of buffer @p
+ *
+ */
+u32 attribute((pure)) crc32_le(u32 crc, unsigned char const *p, size_t len)
+{
+# if CRC_LE_BITS == 8
+ const u32 *b =(u32 *)p;
+ const u32 *tab = crc32table_le;
+
+# ifdef __LITTLE_ENDIAN
+# define DO_CRC crc = (crc>>8) ^ tab[ crc & 255 ]
+# define ENDIAN_SHIFT 0
+# else
+# define DO_CRC crc = (crc<<8) ^ tab[ crc >> 24 ]
+# define ENDIAN_SHIFT 24
+# endif
+
+ crc = __cpu_to_le32(crc);
+ /* Align it */
+ if( ((u32)b)&3 && len){
+ do {
+ crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
+ DO_CRC;
+ } while ((--len) && ((u32)b)&3 );
+ }
+ if(len >= 4){
+ /* load data 32 bits wide, xor data 32 bits wide. */
+ size_t save_len = len & 3;
+ len = len >> 2;
+ --b; /* use pre increment below(*++b) for speed */
+ do {
+ crc ^= *++b;
+ DO_CRC;
+ DO_CRC;
+ DO_CRC;
+ DO_CRC;
+ } while (--len);
+ b++; /* point to next byte(s) */
+ len = save_len;
+ }
+ /* And the last few bytes */
+ if(len){
+ do {
+ crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
+ DO_CRC;
+ } while (--len);
+ }
+
+ return __le32_to_cpu(crc);
+#undef ENDIAN_SHIFT
+#undef DO_CRC
+
+# elif CRC_LE_BITS == 4
+ while (len--) {
+ crc ^= *p++;
+ crc = (crc >> 4) ^ crc32table_le[crc & 15];
+ crc = (crc >> 4) ^ crc32table_le[crc & 15];
+ }
+ return crc;
+# elif CRC_LE_BITS == 2
+ while (len--) {
+ crc ^= *p++;
+ crc = (crc >> 2) ^ crc32table_le[crc & 3];
+ crc = (crc >> 2) ^ crc32table_le[crc & 3];
+ crc = (crc >> 2) ^ crc32table_le[crc & 3];
+ crc = (crc >> 2) ^ crc32table_le[crc & 3];
+ }
+ return crc;
+# endif
+}
+#endif
+
+#if CRC_BE_BITS == 1
+/*
+ * In fact, the table-based code will work in this case, but it can be
+ * simplified by inlining the table in ?: form.
+ */
+
+/**
+ * crc32_be() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
+ * @crc - seed value for computation. ~0 for Ethernet, sometimes 0 for
+ * other uses, or the previous crc32 value if computing incrementally.
+ * @p - pointer to buffer over which CRC is run
+ * @len - length of buffer @p
+ *
+ */
+u32 attribute((pure)) crc32_be(u32 crc, unsigned char const *p, size_t len)
+{
+ int i;
+ while (len--) {
+ crc ^= *p++ << 24;
+ for (i = 0; i < 8; i++)
+ crc =
+ (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE :
+ 0);
+ }
+ return crc;
+}
+
+#else /* Table-based approach */
+/**
+ * crc32_be() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
+ * @crc - seed value for computation. ~0 for Ethernet, sometimes 0 for
+ * other uses, or the previous crc32 value if computing incrementally.
+ * @p - pointer to buffer over which CRC is run
+ * @len - length of buffer @p
+ *
+ */
+u32 attribute((pure)) crc32_be(u32 crc, unsigned char const *p, size_t len)
+{
+# if CRC_BE_BITS == 8
+ const u32 *b =(u32 *)p;
+ const u32 *tab = crc32table_be;
+
+# ifdef __LITTLE_ENDIAN
+# define DO_CRC crc = (crc>>8) ^ tab[ crc & 255 ]
+# define ENDIAN_SHIFT 24
+# else
+# define DO_CRC crc = (crc<<8) ^ tab[ crc >> 24 ]
+# define ENDIAN_SHIFT 0
+# endif
+
+ crc = __cpu_to_be32(crc);
+ /* Align it */
+ if( ((u32)b)&3 && len){
+ do {
+ crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
+ DO_CRC;
+ } while ((--len) && ((u32)b)&3 );
+ }
+ if(len >= 4){
+ /* load data 32 bits wide, xor data 32 bits wide. */
+ size_t save_len = len & 3;
+ len = len >> 2;
+ --b; /* use pre increment below(*++b) for speed */
+ do {
+ crc ^= *++b;
+ DO_CRC;
+ DO_CRC;
+ DO_CRC;
+ DO_CRC;
+ } while (--len);
+ b++; /* point to next byte(s) */
+ len = save_len;
+ }
+ /* And the last few bytes */
+ if(len){
+ do {
+ crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
+ DO_CRC;
+ } while (--len);
+ }
+ return __be32_to_cpu(crc);
+#undef ENDIAN_SHIFT
+#undef DO_CRC
+
+# elif CRC_BE_BITS == 4
+ while (len--) {
+ crc ^= *p++ << 24;
+ crc = (crc << 4) ^ crc32table_be[crc >> 28];
+ crc = (crc << 4) ^ crc32table_be[crc >> 28];
+ }
+ return crc;
+# elif CRC_BE_BITS == 2
+ while (len--) {
+ crc ^= *p++ << 24;
+ crc = (crc << 2) ^ crc32table_be[crc >> 30];
+ crc = (crc << 2) ^ crc32table_be[crc >> 30];
+ crc = (crc << 2) ^ crc32table_be[crc >> 30];
+ crc = (crc << 2) ^ crc32table_be[crc >> 30];
+ }
+ return crc;
+# endif
+}
+#endif
+
+u32 bitreverse(u32 x)
+{
+ x = (x >> 16) | (x << 16);
+ x = (x >> 8 & 0x00ff00ff) | (x << 8 & 0xff00ff00);
+ x = (x >> 4 & 0x0f0f0f0f) | (x << 4 & 0xf0f0f0f0);
+ x = (x >> 2 & 0x33333333) | (x << 2 & 0xcccccccc);
+ x = (x >> 1 & 0x55555555) | (x << 1 & 0xaaaaaaaa);
+ return x;
+}
+
+EXPORT_SYMBOL(crc32_le);
+EXPORT_SYMBOL(crc32_be);
+EXPORT_SYMBOL(bitreverse);
+
+/*
+ * A brief CRC tutorial.
+ *
+ * A CRC is a long-division remainder. You add the CRC to the message,
+ * and the whole thing (message+CRC) is a multiple of the given
+ * CRC polynomial. To check the CRC, you can either check that the
+ * CRC matches the recomputed value, *or* you can check that the
+ * remainder computed on the message+CRC is 0. This latter approach
+ * is used by a lot of hardware implementations, and is why so many
+ * protocols put the end-of-frame flag after the CRC.
+ *
+ * It's actually the same long division you learned in school, except that
+ * - We're working in binary, so the digits are only 0 and 1, and
+ * - When dividing polynomials, there are no carries. Rather than add and
+ * subtract, we just xor. Thus, we tend to get a bit sloppy about
+ * the difference between adding and subtracting.
+ *
+ * A 32-bit CRC polynomial is actually 33 bits long. But since it's
+ * 33 bits long, bit 32 is always going to be set, so usually the CRC
+ * is written in hex with the most significant bit omitted. (If you're
+ * familiar with the IEEE 754 floating-point format, it's the same idea.)
+ *
+ * Note that a CRC is computed over a string of *bits*, so you have
+ * to decide on the endianness of the bits within each byte. To get
+ * the best error-detecting properties, this should correspond to the
+ * order they're actually sent. For example, standard RS-232 serial is
+ * little-endian; the most significant bit (sometimes used for parity)
+ * is sent last. And when appending a CRC word to a message, you should
+ * do it in the right order, matching the endianness.
+ *
+ * Just like with ordinary division, the remainder is always smaller than
+ * the divisor (the CRC polynomial) you're dividing by. Each step of the
+ * division, you take one more digit (bit) of the dividend and append it
+ * to the current remainder. Then you figure out the appropriate multiple
+ * of the divisor to subtract to being the remainder back into range.
+ * In binary, it's easy - it has to be either 0 or 1, and to make the
+ * XOR cancel, it's just a copy of bit 32 of the remainder.
+ *
+ * When computing a CRC, we don't care about the quotient, so we can
+ * throw the quotient bit away, but subtract the appropriate multiple of
+ * the polynomial from the remainder and we're back to where we started,
+ * ready to process the next bit.
+ *
+ * A big-endian CRC written this way would be coded like:
+ * for (i = 0; i < input_bits; i++) {
+ * multiple = remainder & 0x80000000 ? CRCPOLY : 0;
+ * remainder = (remainder << 1 | next_input_bit()) ^ multiple;
+ * }
+ * Notice how, to get at bit 32 of the shifted remainder, we look
+ * at bit 31 of the remainder *before* shifting it.
+ *
+ * But also notice how the next_input_bit() bits we're shifting into
+ * the remainder don't actually affect any decision-making until
+ * 32 bits later. Thus, the first 32 cycles of this are pretty boring.
+ * Also, to add the CRC to a message, we need a 32-bit-long hole for it at
+ * the end, so we have to add 32 extra cycles shifting in zeros at the
+ * end of every message,
+ *
+ * So the standard trick is to rearrage merging in the next_input_bit()
+ * until the moment it's needed. Then the first 32 cycles can be precomputed,
+ * and merging in the final 32 zero bits to make room for the CRC can be
+ * skipped entirely.
+ * This changes the code to:
+ * for (i = 0; i < input_bits; i++) {
+ * remainder ^= next_input_bit() << 31;
+ * multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
+ * remainder = (remainder << 1) ^ multiple;
+ * }
+ * With this optimization, the little-endian code is simpler:
+ * for (i = 0; i < input_bits; i++) {
+ * remainder ^= next_input_bit();
+ * multiple = (remainder & 1) ? CRCPOLY : 0;
+ * remainder = (remainder >> 1) ^ multiple;
+ * }
+ *
+ * Note that the other details of endianness have been hidden in CRCPOLY
+ * (which must be bit-reversed) and next_input_bit().
+ *
+ * However, as long as next_input_bit is returning the bits in a sensible
+ * order, we can actually do the merging 8 or more bits at a time rather
+ * than one bit at a time:
+ * for (i = 0; i < input_bytes; i++) {
+ * remainder ^= next_input_byte() << 24;
+ * for (j = 0; j < 8; j++) {
+ * multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
+ * remainder = (remainder << 1) ^ multiple;
+ * }
+ * }
+ * Or in little-endian:
+ * for (i = 0; i < input_bytes; i++) {
+ * remainder ^= next_input_byte();
+ * for (j = 0; j < 8; j++) {
+ * multiple = (remainder & 1) ? CRCPOLY : 0;
+ * remainder = (remainder << 1) ^ multiple;
+ * }
+ * }
+ * If the input is a multiple of 32 bits, you can even XOR in a 32-bit
+ * word at a time and increase the inner loop count to 32.
+ *
+ * You can also mix and match the two loop styles, for example doing the
+ * bulk of a message byte-at-a-time and adding bit-at-a-time processing
+ * for any fractional bytes at the end.
+ *
+ * The only remaining optimization is to the byte-at-a-time table method.
+ * Here, rather than just shifting one bit of the remainder to decide
+ * in the correct multiple to subtract, we can shift a byte at a time.
+ * This produces a 40-bit (rather than a 33-bit) intermediate remainder,
+ * but again the multiple of the polynomial to subtract depends only on
+ * the high bits, the high 8 bits in this case.
+ *
+ * The multile we need in that case is the low 32 bits of a 40-bit
+ * value whose high 8 bits are given, and which is a multiple of the
+ * generator polynomial. This is simply the CRC-32 of the given
+ * one-byte message.
+ *
+ * Two more details: normally, appending zero bits to a message which
+ * is already a multiple of a polynomial produces a larger multiple of that
+ * polynomial. To enable a CRC to detect this condition, it's common to
+ * invert the CRC before appending it. This makes the remainder of the
+ * message+crc come out not as zero, but some fixed non-zero value.
+ *
+ * The same problem applies to zero bits prepended to the message, and
+ * a similar solution is used. Instead of starting with a remainder of
+ * 0, an initial remainder of all ones is used. As long as you start
+ * the same way on decoding, it doesn't make a difference.
+ */
+
+#if UNITTEST
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#if 0 /*Not used at present */
+static void
+buf_dump(char const *prefix, unsigned char const *buf, size_t len)
+{
+ fputs(prefix, stdout);
+ while (len--)
+ printf(" %02x", *buf++);
+ putchar('\n');
+
+}
+#endif
+
+static void bytereverse(unsigned char *buf, size_t len)
+{
+ while (len--) {
+ unsigned char x = *buf;
+ x = (x >> 4) | (x << 4);
+ x = (x >> 2 & 0x33) | (x << 2 & 0xcc);
+ x = (x >> 1 & 0x55) | (x << 1 & 0xaa);
+ *buf++ = x;
+ }
+}
+
+static void random_garbage(unsigned char *buf, size_t len)
+{
+ while (len--)
+ *buf++ = (unsigned char) random();
+}
+
+#if 0 /* Not used at present */
+static void store_le(u32 x, unsigned char *buf)
+{
+ buf[0] = (unsigned char) x;
+ buf[1] = (unsigned char) (x >> 8);
+ buf[2] = (unsigned char) (x >> 16);
+ buf[3] = (unsigned char) (x >> 24);
+}
+#endif
+
+static void store_be(u32 x, unsigned char *buf)
+{
+ buf[0] = (unsigned char) (x >> 24);
+ buf[1] = (unsigned char) (x >> 16);
+ buf[2] = (unsigned char) (x >> 8);
+ buf[3] = (unsigned char) x;
+}
+
+/*
+ * This checks that CRC(buf + CRC(buf)) = 0, and that
+ * CRC commutes with bit-reversal. This has the side effect
+ * of bytewise bit-reversing the input buffer, and returns
+ * the CRC of the reversed buffer.
+ */
+static u32 test_step(u32 init, unsigned char *buf, size_t len)
+{
+ u32 crc1, crc2;
+ size_t i;
+
+ crc1 = crc32_be(init, buf, len);
+ store_be(crc1, buf + len);
+ crc2 = crc32_be(init, buf, len + 4);
+ if (crc2)
+ printf("\nCRC cancellation fail: 0x%08x should be 0\n",
+ crc2);
+
+ for (i = 0; i <= len + 4; i++) {
+ crc2 = crc32_be(init, buf, i);
+ crc2 = crc32_be(crc2, buf + i, len + 4 - i);
+ if (crc2)
+ printf("\nCRC split fail: 0x%08x\n", crc2);
+ }
+
+ /* Now swap it around for the other test */
+
+ bytereverse(buf, len + 4);
+ init = bitreverse(init);
+ crc2 = bitreverse(crc1);
+ if (crc1 != bitreverse(crc2))
+ printf("\nBit reversal fail: 0x%08x -> %0x08x -> 0x%08x\n",
+ crc1, crc2, bitreverse(crc2));
+ crc1 = crc32_le(init, buf, len);
+ if (crc1 != crc2)
+ printf("\nCRC endianness fail: 0x%08x != 0x%08x\n", crc1,
+ crc2);
+ crc2 = crc32_le(init, buf, len + 4);
+ if (crc2)
+ printf("\nCRC cancellation fail: 0x%08x should be 0\n",
+ crc2);
+
+ for (i = 0; i <= len + 4; i++) {
+ crc2 = crc32_le(init, buf, i);
+ crc2 = crc32_le(crc2, buf + i, len + 4 - i);
+ if (crc2)
+ printf("\nCRC split fail: 0x%08x\n", crc2);
+ }
+
+ return crc1;
+}
+
+#define SIZE 64
+#define INIT1 0
+#define INIT2 0
+
+int main(void)
+{
+ unsigned char buf1[SIZE + 4];
+ unsigned char buf2[SIZE + 4];
+ unsigned char buf3[SIZE + 4];
+ int i, j;
+ u32 crc1, crc2, crc3;
+
+ for (i = 0; i <= SIZE; i++) {
+ printf("\rTesting length %d...", i);
+ fflush(stdout);
+ random_garbage(buf1, i);
+ random_garbage(buf2, i);
+ for (j = 0; j < i; j++)
+ buf3[j] = buf1[j] ^ buf2[j];
+
+ crc1 = test_step(INIT1, buf1, i);
+ crc2 = test_step(INIT2, buf2, i);
+ /* Now check that CRC(buf1 ^ buf2) = CRC(buf1) ^ CRC(buf2) */
+ crc3 = test_step(INIT1 ^ INIT2, buf3, i);
+ if (crc3 != (crc1 ^ crc2))
+ printf("CRC XOR fail: 0x%08x != 0x%08x ^ 0x%08x\n",
+ crc3, crc1, crc2);
+ }
+ printf("\nAll test complete. No failures expected.\n");
+ return 0;
+}
+
+#endif /* UNITTEST */
diff -Nru a/lib/crc32defs.h b/lib/crc32defs.h
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/lib/crc32defs.h Sat May 17 18:11:24 2003
@@ -0,0 +1,28 @@
+/*
+ * There are multiple 16-bit CRC polynomials in common use, but this is
+ * *the* standard CRC-32 polynomial, first popularized by Ethernet.
+ * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0
+ */
+#define CRCPOLY_LE 0xedb88320
+#define CRCPOLY_BE 0x04c11db7
+
+/* How many bits at a time to use. Requires a table of 4<<CRC_xx_BITS bytes. */
+/* For less performance-sensitive, use 4 */
+#define CRC_LE_BITS 8
+#define CRC_BE_BITS 8
+
+/*
+ * Little-endian CRC computation. Used with serial bit streams sent
+ * lsbit-first. Be sure to use cpu_to_le32() to append the computed CRC.
+ */
+#if CRC_LE_BITS > 8 || CRC_LE_BITS < 1 || CRC_LE_BITS & CRC_LE_BITS-1
+# error CRC_LE_BITS must be a power of 2 between 1 and 8
+#endif
+
+/*
+ * Big-endian CRC computation. Used with serial bit streams sent
+ * msbit-first. Be sure to use cpu_to_be32() to append the computed CRC.
+ */
+#if CRC_BE_BITS > 8 || CRC_BE_BITS < 1 || CRC_BE_BITS & CRC_BE_BITS-1
+# error CRC_BE_BITS must be a power of 2 between 1 and 8
+#endif
diff -Nru a/lib/crc32table.h b/lib/crc32table.h
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/lib/crc32table.h Sat May 17 18:11:24 2003
@@ -0,0 +1,134 @@
+/* this file is generated - do not edit */
+
+static const u32 crc32table_le[] = {
+tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL),
+tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L),
+tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L),
+tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L),
+tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL),
+tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L),
+tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL),
+tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L),
+tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L),
+tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL),
+tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L),
+tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L),
+tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L),
+tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL),
+tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L),
+tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL),
+tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL),
+tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L),
+tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L),
+tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L),
+tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL),
+tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L),
+tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL),
+tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L),
+tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L),
+tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL),
+tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L),
+tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L),
+tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L),
+tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL),
+tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L),
+tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL),
+tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL),
+tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L),
+tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L),
+tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L),
+tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL),
+tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L),
+tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL),
+tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L),
+tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L),
+tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL),
+tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L),
+tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L),
+tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L),
+tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL),
+tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L),
+tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL),
+tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL),
+tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L),
+tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L),
+tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L),
+tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL),
+tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L),
+tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL),
+tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L),
+tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L),
+tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL),
+tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L),
+tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L),
+tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L),
+tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL),
+tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L),
+tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL)
+};
+static const u32 crc32table_be[] = {
+tobe(0x00000000L), tobe(0x04c11db7L), tobe(0x09823b6eL), tobe(0x0d4326d9L),
+tobe(0x130476dcL), tobe(0x17c56b6bL), tobe(0x1a864db2L), tobe(0x1e475005L),
+tobe(0x2608edb8L), tobe(0x22c9f00fL), tobe(0x2f8ad6d6L), tobe(0x2b4bcb61L),
+tobe(0x350c9b64L), tobe(0x31cd86d3L), tobe(0x3c8ea00aL), tobe(0x384fbdbdL),
+tobe(0x4c11db70L), tobe(0x48d0c6c7L), tobe(0x4593e01eL), tobe(0x4152fda9L),
+tobe(0x5f15adacL), tobe(0x5bd4b01bL), tobe(0x569796c2L), tobe(0x52568b75L),
+tobe(0x6a1936c8L), tobe(0x6ed82b7fL), tobe(0x639b0da6L), tobe(0x675a1011L),
+tobe(0x791d4014L), tobe(0x7ddc5da3L), tobe(0x709f7b7aL), tobe(0x745e66cdL),
+tobe(0x9823b6e0L), tobe(0x9ce2ab57L), tobe(0x91a18d8eL), tobe(0x95609039L),
+tobe(0x8b27c03cL), tobe(0x8fe6dd8bL), tobe(0x82a5fb52L), tobe(0x8664e6e5L),
+tobe(0xbe2b5b58L), tobe(0xbaea46efL), tobe(0xb7a96036L), tobe(0xb3687d81L),
+tobe(0xad2f2d84L), tobe(0xa9ee3033L), tobe(0xa4ad16eaL), tobe(0xa06c0b5dL),
+tobe(0xd4326d90L), tobe(0xd0f37027L), tobe(0xddb056feL), tobe(0xd9714b49L),
+tobe(0xc7361b4cL), tobe(0xc3f706fbL), tobe(0xceb42022L), tobe(0xca753d95L),
+tobe(0xf23a8028L), tobe(0xf6fb9d9fL), tobe(0xfbb8bb46L), tobe(0xff79a6f1L),
+tobe(0xe13ef6f4L), tobe(0xe5ffeb43L), tobe(0xe8bccd9aL), tobe(0xec7dd02dL),
+tobe(0x34867077L), tobe(0x30476dc0L), tobe(0x3d044b19L), tobe(0x39c556aeL),
+tobe(0x278206abL), tobe(0x23431b1cL), tobe(0x2e003dc5L), tobe(0x2ac12072L),
+tobe(0x128e9dcfL), tobe(0x164f8078L), tobe(0x1b0ca6a1L), tobe(0x1fcdbb16L),
+tobe(0x018aeb13L), tobe(0x054bf6a4L), tobe(0x0808d07dL), tobe(0x0cc9cdcaL),
+tobe(0x7897ab07L), tobe(0x7c56b6b0L), tobe(0x71159069L), tobe(0x75d48ddeL),
+tobe(0x6b93dddbL), tobe(0x6f52c06cL), tobe(0x6211e6b5L), tobe(0x66d0fb02L),
+tobe(0x5e9f46bfL), tobe(0x5a5e5b08L), tobe(0x571d7dd1L), tobe(0x53dc6066L),
+tobe(0x4d9b3063L), tobe(0x495a2dd4L), tobe(0x44190b0dL), tobe(0x40d816baL),
+tobe(0xaca5c697L), tobe(0xa864db20L), tobe(0xa527fdf9L), tobe(0xa1e6e04eL),
+tobe(0xbfa1b04bL), tobe(0xbb60adfcL), tobe(0xb6238b25L), tobe(0xb2e29692L),
+tobe(0x8aad2b2fL), tobe(0x8e6c3698L), tobe(0x832f1041L), tobe(0x87ee0df6L),
+tobe(0x99a95df3L), tobe(0x9d684044L), tobe(0x902b669dL), tobe(0x94ea7b2aL),
+tobe(0xe0b41de7L), tobe(0xe4750050L), tobe(0xe9362689L), tobe(0xedf73b3eL),
+tobe(0xf3b06b3bL), tobe(0xf771768cL), tobe(0xfa325055L), tobe(0xfef34de2L),
+tobe(0xc6bcf05fL), tobe(0xc27dede8L), tobe(0xcf3ecb31L), tobe(0xcbffd686L),
+tobe(0xd5b88683L), tobe(0xd1799b34L), tobe(0xdc3abdedL), tobe(0xd8fba05aL),
+tobe(0x690ce0eeL), tobe(0x6dcdfd59L), tobe(0x608edb80L), tobe(0x644fc637L),
+tobe(0x7a089632L), tobe(0x7ec98b85L), tobe(0x738aad5cL), tobe(0x774bb0ebL),
+tobe(0x4f040d56L), tobe(0x4bc510e1L), tobe(0x46863638L), tobe(0x42472b8fL),
+tobe(0x5c007b8aL), tobe(0x58c1663dL), tobe(0x558240e4L), tobe(0x51435d53L),
+tobe(0x251d3b9eL), tobe(0x21dc2629L), tobe(0x2c9f00f0L), tobe(0x285e1d47L),
+tobe(0x36194d42L), tobe(0x32d850f5L), tobe(0x3f9b762cL), tobe(0x3b5a6b9bL),
+tobe(0x0315d626L), tobe(0x07d4cb91L), tobe(0x0a97ed48L), tobe(0x0e56f0ffL),
+tobe(0x1011a0faL), tobe(0x14d0bd4dL), tobe(0x19939b94L), tobe(0x1d528623L),
+tobe(0xf12f560eL), tobe(0xf5ee4bb9L), tobe(0xf8ad6d60L), tobe(0xfc6c70d7L),
+tobe(0xe22b20d2L), tobe(0xe6ea3d65L), tobe(0xeba91bbcL), tobe(0xef68060bL),
+tobe(0xd727bbb6L), tobe(0xd3e6a601L), tobe(0xdea580d8L), tobe(0xda649d6fL),
+tobe(0xc423cd6aL), tobe(0xc0e2d0ddL), tobe(0xcda1f604L), tobe(0xc960ebb3L),
+tobe(0xbd3e8d7eL), tobe(0xb9ff90c9L), tobe(0xb4bcb610L), tobe(0xb07daba7L),
+tobe(0xae3afba2L), tobe(0xaafbe615L), tobe(0xa7b8c0ccL), tobe(0xa379dd7bL),
+tobe(0x9b3660c6L), tobe(0x9ff77d71L), tobe(0x92b45ba8L), tobe(0x9675461fL),
+tobe(0x8832161aL), tobe(0x8cf30badL), tobe(0x81b02d74L), tobe(0x857130c3L),
+tobe(0x5d8a9099L), tobe(0x594b8d2eL), tobe(0x5408abf7L), tobe(0x50c9b640L),
+tobe(0x4e8ee645L), tobe(0x4a4ffbf2L), tobe(0x470cdd2bL), tobe(0x43cdc09cL),
+tobe(0x7b827d21L), tobe(0x7f436096L), tobe(0x7200464fL), tobe(0x76c15bf8L),
+tobe(0x68860bfdL), tobe(0x6c47164aL), tobe(0x61043093L), tobe(0x65c52d24L),
+tobe(0x119b4be9L), tobe(0x155a565eL), tobe(0x18197087L), tobe(0x1cd86d30L),
+tobe(0x029f3d35L), tobe(0x065e2082L), tobe(0x0b1d065bL), tobe(0x0fdc1becL),
+tobe(0x3793a651L), tobe(0x3352bbe6L), tobe(0x3e119d3fL), tobe(0x3ad08088L),
+tobe(0x2497d08dL), tobe(0x2056cd3aL), tobe(0x2d15ebe3L), tobe(0x29d4f654L),
+tobe(0xc5a92679L), tobe(0xc1683bceL), tobe(0xcc2b1d17L), tobe(0xc8ea00a0L),
+tobe(0xd6ad50a5L), tobe(0xd26c4d12L), tobe(0xdf2f6bcbL), tobe(0xdbee767cL),
+tobe(0xe3a1cbc1L), tobe(0xe760d676L), tobe(0xea23f0afL), tobe(0xeee2ed18L),
+tobe(0xf0a5bd1dL), tobe(0xf464a0aaL), tobe(0xf9278673L), tobe(0xfde69bc4L),
+tobe(0x89b8fd09L), tobe(0x8d79e0beL), tobe(0x803ac667L), tobe(0x84fbdbd0L),
+tobe(0x9abc8bd5L), tobe(0x9e7d9662L), tobe(0x933eb0bbL), tobe(0x97ffad0cL),
+tobe(0xafb010b1L), tobe(0xab710d06L), tobe(0xa6322bdfL), tobe(0xa2f33668L),
+tobe(0xbcb4666dL), tobe(0xb8757bdaL), tobe(0xb5365d03L), tobe(0xb1f740b4L)
+};
Binary files a/lib/gen_crc32table and b/lib/gen_crc32table differ
diff -Nru a/lib/gen_crc32table.c b/lib/gen_crc32table.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/lib/gen_crc32table.c Sat May 17 18:11:24 2003
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include "crc32defs.h"
+#include <sys/types.h>
+
+#define ENTRIES_PER_LINE 4
+
+#define LE_TABLE_SIZE (1 << CRC_LE_BITS)
+#define BE_TABLE_SIZE (1 << CRC_BE_BITS)
+
+static u_int32_t crc32table_le[LE_TABLE_SIZE];
+static u_int32_t crc32table_be[BE_TABLE_SIZE];
+
+/**
+ * crc32init_le() - allocate and initialize LE table data
+ *
+ * crc is the crc of the byte i; other entries are filled in based on the
+ * fact that crctable[i^j] = crctable[i] ^ crctable[j].
+ *
+ */
+static void crc32init_le(void)
+{
+ unsigned i, j;
+ u_int32_t crc = 1;
+
+ crc32table_le[0] = 0;
+
+ for (i = 1 << (CRC_LE_BITS - 1); i; i >>= 1) {
+ crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+ for (j = 0; j < LE_TABLE_SIZE; j += 2 * i)
+ crc32table_le[i + j] = crc ^ crc32table_le[j];
+ }
+}
+
+/**
+ * crc32init_be() - allocate and initialize BE table data
+ */
+static void crc32init_be(void)
+{
+ unsigned i, j;
+ u_int32_t crc = 0x80000000;
+
+ crc32table_be[0] = 0;
+
+ for (i = 1; i < BE_TABLE_SIZE; i <<= 1) {
+ crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
+ for (j = 0; j < i; j++)
+ crc32table_be[i + j] = crc ^ crc32table_be[j];
+ }
+}
+
+static void output_table(u_int32_t table[], int len, char *trans)
+{
+ int i;
+
+ for (i = 0; i < len - 1; i++) {
+ if (i % ENTRIES_PER_LINE == 0)
+ printf("\n");
+ printf("%s(0x%8.8xL), ", trans, table[i]);
+ }
+ printf("%s(0x%8.8xL)\n", trans, table[len - 1]);
+}
+
+int main(int argc, char** argv)
+{
+ printf("/* this file is generated - do not edit */\n\n");
+
+ if (CRC_LE_BITS > 1) {
+ crc32init_le();
+ printf("static const u32 crc32table_le[] = {");
+ output_table(crc32table_le, LE_TABLE_SIZE, "tole");
+ printf("};\n");
+ }
+
+ if (CRC_BE_BITS > 1) {
+ crc32init_be();
+ printf("static const u32 crc32table_be[] = {");
+ output_table(crc32table_be, BE_TABLE_SIZE, "tobe");
+ printf("};\n");
+ }
+
+ return 0;
+}
diff -Nru a/net/bluetooth/bnep/Makefile b/net/bluetooth/bnep/Makefile
--- a/net/bluetooth/bnep/Makefile Sat May 17 18:11:24 2003
+++ b/net/bluetooth/bnep/Makefile Sat May 17 18:11:24 2003
@@ -4,7 +4,7 @@

O_TARGET := bnep.o

-obj-y := core.o sock.o netdev.o crc32.o
+obj-y := core.o sock.o netdev.o
obj-m += $(O_TARGET)

include $(TOPDIR)/Rules.make
diff -Nru a/net/bluetooth/bnep/Makefile.lib b/net/bluetooth/bnep/Makefile.lib
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/net/bluetooth/bnep/Makefile.lib Sat May 17 18:11:24 2003
@@ -0,0 +1 @@
+obj-$(CONFIG_BLUEZ_BNEP) += crc32.o
diff -Nru a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h
--- a/net/bluetooth/bnep/bnep.h Sat May 17 18:11:24 2003
+++ b/net/bluetooth/bnep/bnep.h Sat May 17 18:11:24 2003
@@ -26,7 +26,7 @@
#include <linux/types.h>
#include <net/bluetooth/bluetooth.h>

-#include "crc32.h"
+#include <linux/crc32.h>

// Limits
#define BNEP_MAX_PROTO_FILTERS 5
@@ -179,7 +179,7 @@

static inline int bnep_mc_hash(__u8 *addr)
{
- return (bnep_crc32(~0, addr, ETH_ALEN) >> 26);
+ return (crc32_be(~0, addr, ETH_ALEN) >> 26);
}

#endif
diff -Nru a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
--- a/net/bluetooth/bnep/core.c Sat May 17 18:11:24 2003
+++ b/net/bluetooth/bnep/core.c Sat May 17 18:11:24 2003
@@ -680,7 +680,6 @@

static int __init bnep_init_module(void)
{
- bnep_crc32_init();
bnep_sock_init();

BT_INFO("BlueZ BNEP ver %s", VERSION);
@@ -695,7 +694,6 @@
static void __exit bnep_cleanup_module(void)
{
bnep_sock_cleanup();
- bnep_crc32_cleanup();
}

module_init(bnep_init_module);
diff -Nru a/net/bluetooth/bnep/crc32.c b/net/bluetooth/bnep/crc32.c
--- a/net/bluetooth/bnep/crc32.c Sat May 17 18:11:24 2003
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,59 +0,0 @@
-/*
- * Based on linux-2.5/lib/crc32 by Matt Domsch <[email protected]>
- *
- * FIXME: Remove in 2.5
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <asm/atomic.h>
-
-#include "crc32.h"
-
-#define CRCPOLY_BE 0x04c11db7
-#define CRC_BE_BITS 8
-
-static u32 *bnep_crc32_table;
-
-/*
- * This code is in the public domain; copyright abandoned.
- * Liability for non-performance of this code is limited to the amount
- * you paid for it. Since it is distributed for free, your refund will
- * be very very small. If it breaks, you get to keep both pieces.
- */
-u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len)
-{
- while (len--)
- crc = (crc << 8) ^ bnep_crc32_table[(crc >> 24) ^ *p++];
-
- return crc;
-}
-
-int __init bnep_crc32_init(void)
-{
- unsigned i, j;
- u32 crc = 0x80000000;
-
- bnep_crc32_table = kmalloc((1 << CRC_BE_BITS) * sizeof(u32), GFP_KERNEL);
- if (!bnep_crc32_table)
- return -ENOMEM;
-
- bnep_crc32_table[0] = 0;
-
- for (i = 1; i < 1 << CRC_BE_BITS; i <<= 1) {
- crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
- for (j = 0; j < i; j++)
- bnep_crc32_table[i + j] = crc ^ bnep_crc32_table[j];
- }
- return 0;
-}
-
-void __exit bnep_crc32_cleanup(void)
-{
- if (bnep_crc32_table)
- kfree(bnep_crc32_table);
- bnep_crc32_table = NULL;
-}
diff -Nru a/net/bluetooth/bnep/crc32.h b/net/bluetooth/bnep/crc32.h
--- a/net/bluetooth/bnep/crc32.h Sat May 17 18:11:24 2003
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,10 +0,0 @@
-/*
- * crc32.h
- * See crc32.c for license and changes
- *
- * FIXME: Remove in 2.5
- */
-
-int bnep_crc32_init(void);
-void bnep_crc32_cleanup(void);
-u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len);



--
dwmw2



2003-05-19 07:12:04

by Duncan Sands

[permalink] [raw]
Subject: Re: [PATCH] Shared crc32 for 2.4.

--- linux-2.4/Documentation/Configure.help.orig 2003-05-16 16:15:52.000000000 +0200
+++ linux-2.4/Documentation/Configure.help 2003-05-19 09:23:08.000000000 +0200
@@ -26525,6 +26525,13 @@

If unsure, say N.

+CRC32 functions
+CONFIG_CRC32
+ This option is provided for the case where no in-kernel-tree
+ modules require CRC32 functions, but a module built outside the
+ kernel tree does. Such modules that use library CRC32 functions
+ require M here.
+
#
# A couple of things I keep forgetting:
# capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,

2003-05-19 14:53:57

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] Shared crc32 for 2.4.

On Mon, 2003-05-19 at 08:24, Duncan Sands wrote:
> --- linux-2.4/Documentation/Configure.help.orig 2003-05-16 16:15:52.000000000 +0200
> +++ linux-2.4/Documentation/Configure.help 2003-05-19 09:23:08.000000000 +0200

Thanks; added to the BK tree which Marcelo was asked to pull from, and
I'm sure Alan has picked it up for himself.

--
dwmw2

2003-05-21 23:37:44

by J.A. Magallon

[permalink] [raw]
Subject: Re: [PATCH] Shared crc32 for 2.4.


On 05.17, David Woodhouse wrote:
> This has been needed for a long time... please pull from
> master.kernel.org:/home/dwmw2/BK/crc32-2.4 or apply the GNU patch below.
>
> I can resend for 2.4.22-pre1 if you prefer, but it's been working in 2.5
> and in various other 2.4 trees for a while now so I'm sending it now
> anyway.
>

This works if crc32.o is compiled as a module, but does not work if it is
built into the kernel. For example, crc32_le symbol does not appear
in System.map nor vmlinux.
For me, it failed with 8390.o ans 8139too.o. But just because they are the
only drivers needing crc32 that I build.

TIA

--
J.A. Magallon <[email protected]> \ Software is like sex:
werewolf.able.es \ It's better when it's free
Mandrake Linux release 9.2 (Cooker) for i586
Linux 2.4.21-rc2-jam1 (gcc 3.2.3 (Mandrake Linux 9.2 3.2.3-1mdk))

2003-05-22 20:12:25

by Marcelo Tosatti

[permalink] [raw]
Subject: Re: [PATCH] Shared crc32 for 2.4.


Lets wait for 2.4.22pre.

Danke

2003-05-22 20:58:50

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] Shared crc32 for 2.4.

On Thu, 2003-05-22 at 00:50, J.A. Magallon wrote:
> This works if crc32.o is compiled as a module, but does not work if it is
> built into the kernel. For example, crc32_le symbol does not appear
> in System.map nor vmlinux.

Oh bollocks; sorry I'd forgotten about that.

Added to the tree from which Marcelo will pull for 2.4.22-pre1...


# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1211 -> 1.1212
# lib/crc32.c 1.1 -> 1.2
# kernel/ksyms.c 1.67 -> 1.68
# lib/Makefile 1.10 -> 1.11
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/05/22 [email protected] 1.1212
# Fix CONFIG_CRC32=y when nothing in-kernel uses CRC32 functions
# by exporting the symbol from kernel/ksyms.c instead of lib/crc32.c,
# hence forcing lib/crc32.o to get pulled in during the final link.
# --------------------------------------------
#
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c Thu May 22 22:08:02 2003
+++ b/kernel/ksyms.c Thu May 22 22:08:02 2003
@@ -48,6 +48,7 @@
#include <linux/completion.h>
#include <linux/seq_file.h>
#include <linux/dnotify.h>
+#include <linux/crc32.h>
#include <asm/checksum.h>

#if defined(CONFIG_PROC_FS)
@@ -557,6 +558,12 @@
EXPORT_SYMBOL(strnicmp);
EXPORT_SYMBOL(strspn);
EXPORT_SYMBOL(strsep);
+
+#ifdef CONFIG_CRC32
+EXPORT_SYMBOL(crc32_le);
+EXPORT_SYMBOL(crc32_be);
+EXPORT_SYMBOL(bitreverse);
+#endif

/* software interrupts */
EXPORT_SYMBOL(tasklet_hi_vec);
diff -Nru a/lib/Makefile b/lib/Makefile
--- a/lib/Makefile Thu May 22 22:08:02 2003
+++ b/lib/Makefile Thu May 22 22:08:02 2003
@@ -8,7 +8,7 @@

L_TARGET := lib.a

-export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o crc32.o
+export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o

obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o \
bust_spinlocks.o rbtree.o dump_stack.o
diff -Nru a/lib/crc32.c b/lib/crc32.c
--- a/lib/crc32.c Thu May 22 22:08:02 2003
+++ b/lib/crc32.c Thu May 22 22:08:02 2003
@@ -266,10 +266,6 @@
return x;
}

-EXPORT_SYMBOL(crc32_le);
-EXPORT_SYMBOL(crc32_be);
-EXPORT_SYMBOL(bitreverse);
-
/*
* A brief CRC tutorial.
*

--
dwmw2


2003-05-23 06:31:50

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] Shared crc32 for 2.4.

On Thu, 2003-05-22 at 21:23, Marcelo Tosatti wrote:
> Lets wait for 2.4.22pre.

OK. It currently looks like this...

[email protected], 2003-05-22 22:07:44+01:00, [email protected]
Fix CONFIG_CRC32=y when nothing in-kernel uses CRC32 functions
by exporting the symbol from kernel/ksyms.c instead of lib/crc32.c,
hence forcing lib/crc32.o to get pulled in during the final link.

[email protected], 2003-05-19 14:31:55+01:00, [email protected]
Add config help for CONFIG_CRC32 (Duncan Sands <[email protected]>)

[email protected], 2003-05-17 18:34:20+01:00, [email protected]
Switch to shared optimised CRC32 functions.

--
dwmw2


2003-05-23 09:15:10

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] Shared crc32 for 2.4.

On Thu, 2003-05-22 at 22:11, David Woodhouse wrote:
> On Thu, 2003-05-22 at 00:50, J.A. Magallon wrote:
> > This works if crc32.o is compiled as a module, but does not work if it is
> > built into the kernel. For example, crc32_le symbol does not appear
> > in System.map nor vmlinux.
>
> Oh bollocks; sorry I'd forgotten about that.
>
> Added to the tree from which Marcelo will pull for 2.4.22-pre1...

I hereby declare myself to be Today's Official Mr Fuck All Good.

On top of that patch which fixes CONFIG_CRC32=y, you'll need this patch
which fixes CONFIG_CRC32=m, newly broken (at least with new modutils) by
the removal of the EXPORT_SYMBOL()s from crc32.o...ยท

Full patch against 2.4.21-rc3 is in
ftp://ftp.??.kernel.org/pub/linux/kernel/people/dwmw2/crc32/

(and in master.kernel.org:~dwmw2/BK/crc32-2.4 still)

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1216 -> 1.1217
# lib/crc32.c 1.2 -> 1.3
# lib/Makefile 1.11 -> 1.12
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/05/23 [email protected] 1.1217
# Fix CONFIG_CRC32=m by make crc32.o export its own symbols again in that case.
# --------------------------------------------
#
diff -Nru a/lib/Makefile b/lib/Makefile
--- a/lib/Makefile Fri May 23 10:09:17 2003
+++ b/lib/Makefile Fri May 23 10:09:17 2003
@@ -8,7 +8,8 @@

L_TARGET := lib.a

-export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o
+export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \
+ rbtree.o crc32.o

obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o \
bust_spinlocks.o rbtree.o dump_stack.o
diff -Nru a/lib/crc32.c b/lib/crc32.c
--- a/lib/crc32.c Fri May 23 10:09:17 2003
+++ b/lib/crc32.c Fri May 23 10:09:17 2003
@@ -266,6 +266,13 @@
return x;
}

+#ifdef MODULE /* These are exported from kernel/ksyms.c in the non-module
+ case, to ensure that this file is pulled in from lib/lib.a */
+EXPORT_SYMBOL(crc32_le);
+EXPORT_SYMBOL(crc32_be);
+EXPORT_SYMBOL(bitreverse);
+#endif
+
/*
* A brief CRC tutorial.
*




--
dwmw2

2003-05-27 11:13:29

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH] Shared crc32 for 2.4.

On Thu, 2003-05-22 at 23:51, Joakim Tjernlund wrote:
> David, please use my latest crc32 mods in the 2.5 tree.
> I think I sent them to you too.
> It is a cleanup and optimization for x86.

Oops, sorry I thought I had, but in fact I'd used a slightly older
version. BK tree (and linux-2.4.21-rc4-shared-crc32.patch on
ftp.kernel.org) updated accordingly...

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or
higher.
# This patch includes the following deltas:
# ChangeSet 1.1226.1.1 -> 1.1226.1.2
# lib/crc32.c 1.3 -> 1.4
# lib/crc32defs.h 1.1 -> 1.2
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/05/27 [email protected] 1.1226.1.2
# Back-port Jocke's CRC32 optimisations from 2.5.
# --------------------------------------------
#
diff -Nru a/lib/crc32.c b/lib/crc32.c
--- a/lib/crc32.c Tue May 27 11:45:55 2003
+++ b/lib/crc32.c Tue May 27 11:45:55 2003
@@ -90,32 +90,29 @@
const u32 *tab = crc32table_le;

# ifdef __LITTLE_ENDIAN
-# define DO_CRC crc = (crc>>8) ^ tab[ crc & 255 ]
-# define ENDIAN_SHIFT 0
+# define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8)
# else
-# define DO_CRC crc = (crc<<8) ^ tab[ crc >> 24 ]
-# define ENDIAN_SHIFT 24
+# define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8)
# endif

crc = __cpu_to_le32(crc);
/* Align it */
- if( ((u32)b)&3 && len){
+ if(unlikely(((long)b)&3 && len)){
do {
- crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
- DO_CRC;
- } while ((--len) && ((u32)b)&3 );
+ DO_CRC(*((u8 *)b)++);
+ } while ((--len) && ((long)b)&3 );
}
- if(len >= 4){
+ if(likely(len >= 4)){
/* load data 32 bits wide, xor data 32 bits wide. */
size_t save_len = len & 3;
len = len >> 2;
--b; /* use pre increment below(*++b) for speed */
do {
crc ^= *++b;
- DO_CRC;
- DO_CRC;
- DO_CRC;
- DO_CRC;
+ DO_CRC(0);
+ DO_CRC(0);
+ DO_CRC(0);
+ DO_CRC(0);
} while (--len);
b++; /* point to next byte(s) */
len = save_len;
@@ -123,8 +120,7 @@
/* And the last few bytes */
if(len){
do {
- crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
- DO_CRC;
+ DO_CRC(*((u8 *)b)++);
} while (--len);
}

@@ -195,32 +191,29 @@
const u32 *tab = crc32table_be;

# ifdef __LITTLE_ENDIAN
-# define DO_CRC crc = (crc>>8) ^ tab[ crc & 255 ]
-# define ENDIAN_SHIFT 24
+# define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8)
# else
-# define DO_CRC crc = (crc<<8) ^ tab[ crc >> 24 ]
-# define ENDIAN_SHIFT 0
+# define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8)
# endif

crc = __cpu_to_be32(crc);
/* Align it */
- if( ((u32)b)&3 && len){
+ if(unlikely(((long)b)&3 && len)){
do {
- crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
- DO_CRC;
- } while ((--len) && ((u32)b)&3 );
+ DO_CRC(*((u8 *)b)++);
+ } while ((--len) && ((long)b)&3 );
}
- if(len >= 4){
+ if(likely(len >= 4)){
/* load data 32 bits wide, xor data 32 bits wide. */
size_t save_len = len & 3;
len = len >> 2;
--b; /* use pre increment below(*++b) for speed */
do {
crc ^= *++b;
- DO_CRC;
- DO_CRC;
- DO_CRC;
- DO_CRC;
+ DO_CRC(0);
+ DO_CRC(0);
+ DO_CRC(0);
+ DO_CRC(0);
} while (--len);
b++; /* point to next byte(s) */
len = save_len;
@@ -228,8 +221,7 @@
/* And the last few bytes */
if(len){
do {
- crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
- DO_CRC;
+ DO_CRC(*((u8 *)b)++);
} while (--len);
}
return __be32_to_cpu(crc);
diff -Nru a/lib/crc32defs.h b/lib/crc32defs.h
--- a/lib/crc32defs.h Tue May 27 11:45:55 2003
+++ b/lib/crc32defs.h Tue May 27 11:45:55 2003
@@ -8,8 +8,12 @@

/* How many bits at a time to use. Requires a table of 4<<CRC_xx_BITS
bytes. */
/* For less performance-sensitive, use 4 */
-#define CRC_LE_BITS 8
-#define CRC_BE_BITS 8
+#ifndef CRC_LE_BITS
+# define CRC_LE_BITS 8
+#endif
+#ifndef CRC_BE_BITS
+# define CRC_BE_BITS 8
+#endif

/*
* Little-endian CRC computation. Used with serial bit streams sent



--
dwmw2