Commit | Line | Data |
---|---|---|
50ee11fe BB |
1 | /* Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobbs' |
2 | * Journal, May 1992, pp. 64-67. This algorithm generates the same CRC | |
3 | * values as ZMODEM and PKZIP | |
4 | * | |
5 | * Copyright (C) 2002-2005 SBE, Inc. | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | */ | |
17 | ||
18 | #include <linux/types.h> | |
19 | #include "pmcc4_sysdep.h" | |
20 | #include "sbecom_inline_linux.h" | |
21 | #include "sbe_promformat.h" | |
22 | ||
23 | /* defines */ | |
24 | #define CRC32_POLYNOMIAL 0xEDB88320L | |
25 | #define CRC_TABLE_ENTRIES 256 | |
26 | ||
27 | ||
28 | ||
29 | static u_int32_t crcTableInit; | |
30 | ||
31 | #ifdef STATIC_CRC_TABLE | |
32 | static u_int32_t CRCTable[CRC_TABLE_ENTRIES]; | |
33 | ||
34 | #endif | |
35 | ||
36 | ||
37 | /*************************************************************************** | |
38 | * | |
39 | * genCrcTable - fills in CRCTable, as used by sbeCrc() | |
40 | * | |
41 | * RETURNS: N/A | |
42 | * | |
43 | * ERRNO: N/A | |
44 | ***************************************************************************/ | |
45 | ||
46 | static void | |
477953e1 | 47 | genCrcTable(u_int32_t *CRCTable) |
50ee11fe | 48 | { |
0b7ccbed JM |
49 | int ii, jj; |
50 | u_int32_t crc; | |
51 | ||
3effcd06 | 52 | for (ii = 0; ii < CRC_TABLE_ENTRIES; ii++) { |
0b7ccbed | 53 | crc = ii; |
3effcd06 | 54 | for (jj = 8; jj > 0; jj--) { |
0b7ccbed JM |
55 | if (crc & 1) |
56 | crc = (crc >> 1) ^ CRC32_POLYNOMIAL; | |
57 | else | |
58 | crc >>= 1; | |
59 | } | |
60 | CRCTable[ii] = crc; | |
61 | } | |
62 | ||
63 | crcTableInit++; | |
50ee11fe BB |
64 | } |
65 | ||
66 | ||
67 | /*************************************************************************** | |
68 | * | |
69 | * sbeCrc - generates a CRC on a given buffer, and initial CRC | |
70 | * | |
71 | * This routine calculates the CRC for a buffer of data using the | |
72 | * table lookup method. It accepts an original value for the crc, | |
73 | * and returns the updated value. This permits "catenation" of | |
74 | * discontiguous buffers. An original value of 0 for the "first" | |
75 | * buffer is the norm. | |
76 | * | |
77 | * Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobb's | |
78 | * Journal, May 1992, pp. 64-67. This algorithm generates the same CRC | |
79 | * values as ZMODEM and PKZIP. | |
80 | * | |
81 | * RETURNS: calculated crc of block | |
82 | * | |
83 | */ | |
84 | ||
85 | void | |
477953e1 | 86 | sbeCrc(u_int8_t *buffer, /* data buffer to crc */ |
0b7ccbed JM |
87 | u_int32_t count, /* length of block in bytes */ |
88 | u_int32_t initialCrc, /* starting CRC */ | |
89 | u_int32_t *result) | |
50ee11fe | 90 | { |
c11afaae | 91 | u_int32_t *tbl = NULL; |
0b7ccbed JM |
92 | u_int32_t temp1, temp2, crc; |
93 | ||
94 | /* | |
95 | * if table not yet created, do so. Don't care about "extra" time | |
96 | * checking this every time sbeCrc() is called, since CRC calculations | |
97 | * are already time consuming | |
98 | */ | |
3effcd06 | 99 | if (!crcTableInit) { |
50ee11fe | 100 | #ifdef STATIC_CRC_TABLE |
0b7ccbed | 101 | tbl = &CRCTable; |
477953e1 | 102 | genCrcTable(tbl); |
50ee11fe | 103 | #else |
477953e1 | 104 | tbl = (u_int32_t *) OS_kmalloc(CRC_TABLE_ENTRIES * sizeof(u_int32_t)); |
c11afaae | 105 | if (!tbl) { |
0b7ccbed JM |
106 | *result = 0; /* dummy up return value due to malloc |
107 | * failure */ | |
108 | return; | |
109 | } | |
477953e1 | 110 | genCrcTable(tbl); |
50ee11fe | 111 | #endif |
0b7ccbed JM |
112 | } |
113 | /* inverting bits makes ZMODEM & PKZIP compatible */ | |
114 | crc = initialCrc ^ 0xFFFFFFFFL; | |
50ee11fe | 115 | |
3effcd06 | 116 | while (count-- != 0) { |
0b7ccbed JM |
117 | temp1 = (crc >> 8) & 0x00FFFFFFL; |
118 | temp2 = tbl[((int) crc ^ *buffer++) & 0xff]; | |
119 | crc = temp1 ^ temp2; | |
120 | } | |
50ee11fe | 121 | |
0b7ccbed | 122 | crc ^= 0xFFFFFFFFL; |
50ee11fe | 123 | |
0b7ccbed | 124 | *result = crc; |
50ee11fe BB |
125 | |
126 | #ifndef STATIC_CRC_TABLE | |
0b7ccbed | 127 | crcTableInit = 0; |
477953e1 | 128 | OS_kfree(tbl); |
50ee11fe BB |
129 | #endif |
130 | } | |
131 | ||
132 | /*** End-of-File ***/ |