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 | |
47 | genCrcTable (u_int32_t *CRCTable) | |
48 | { | |
49 | int ii, jj; | |
50 | u_int32_t crc; | |
51 | ||
52 | for (ii = 0; ii < CRC_TABLE_ENTRIES; ii++) | |
53 | { | |
54 | crc = ii; | |
55 | for (jj = 8; jj > 0; jj--) | |
56 | { | |
57 | if (crc & 1) | |
58 | crc = (crc >> 1) ^ CRC32_POLYNOMIAL; | |
59 | else | |
60 | crc >>= 1; | |
61 | } | |
62 | CRCTable[ii] = crc; | |
63 | } | |
64 | ||
65 | crcTableInit++; | |
66 | } | |
67 | ||
68 | ||
69 | /*************************************************************************** | |
70 | * | |
71 | * sbeCrc - generates a CRC on a given buffer, and initial CRC | |
72 | * | |
73 | * This routine calculates the CRC for a buffer of data using the | |
74 | * table lookup method. It accepts an original value for the crc, | |
75 | * and returns the updated value. This permits "catenation" of | |
76 | * discontiguous buffers. An original value of 0 for the "first" | |
77 | * buffer is the norm. | |
78 | * | |
79 | * Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobb's | |
80 | * Journal, May 1992, pp. 64-67. This algorithm generates the same CRC | |
81 | * values as ZMODEM and PKZIP. | |
82 | * | |
83 | * RETURNS: calculated crc of block | |
84 | * | |
85 | */ | |
86 | ||
87 | void | |
88 | sbeCrc (u_int8_t *buffer, /* data buffer to crc */ | |
89 | u_int32_t count, /* length of block in bytes */ | |
90 | u_int32_t initialCrc, /* starting CRC */ | |
91 | u_int32_t *result) | |
92 | { | |
93 | u_int32_t *tbl = 0; | |
94 | u_int32_t temp1, temp2, crc; | |
95 | ||
96 | /* | |
97 | * if table not yet created, do so. Don't care about "extra" time | |
25985edc | 98 | * checking this every time sbeCrc() is called, since CRC calculations are |
50ee11fe BB |
99 | * already time consuming |
100 | */ | |
101 | if (!crcTableInit) | |
102 | { | |
103 | #ifdef STATIC_CRC_TABLE | |
104 | tbl = &CRCTable; | |
105 | genCrcTable (tbl); | |
106 | #else | |
107 | tbl = (u_int32_t *) OS_kmalloc (CRC_TABLE_ENTRIES * sizeof (u_int32_t)); | |
108 | if (tbl == 0) | |
109 | { | |
110 | *result = 0; /* dummy up return value due to malloc | |
111 | * failure */ | |
112 | return; | |
113 | } | |
114 | genCrcTable (tbl); | |
115 | #endif | |
116 | } | |
117 | /* inverting bits makes ZMODEM & PKZIP compatible */ | |
118 | crc = initialCrc ^ 0xFFFFFFFFL; | |
119 | ||
120 | while (count-- != 0) | |
121 | { | |
122 | temp1 = (crc >> 8) & 0x00FFFFFFL; | |
123 | temp2 = tbl[((int) crc ^ *buffer++) & 0xff]; | |
124 | crc = temp1 ^ temp2; | |
125 | } | |
126 | ||
127 | crc ^= 0xFFFFFFFFL; | |
128 | ||
129 | *result = crc; | |
130 | ||
131 | #ifndef STATIC_CRC_TABLE | |
132 | crcTableInit = 0; | |
133 | OS_kfree (tbl); | |
134 | #endif | |
135 | } | |
136 | ||
137 | /*** End-of-File ***/ |