linux/drivers/staging/cxt1e1/sbecrc.c
<<
>>
Prefs
   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
  29static      u_int32_t crcTableInit;
  30
  31#ifdef STATIC_CRC_TABLE
  32static 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
  46static void
  47genCrcTable(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                crc = ii;
  54                for (jj = 8; jj > 0; jj--) {
  55                        if (crc & 1)
  56                                crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
  57                        else
  58                                crc >>= 1;
  59                }
  60                CRCTable[ii] = crc;
  61        }
  62
  63        crcTableInit++;
  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
  85void
  86sbeCrc(u_int8_t *buffer,          /* data buffer to crc */
  87        u_int32_t count,           /* length of block in bytes */
  88        u_int32_t initialCrc,      /* starting CRC */
  89        u_int32_t *result)
  90{
  91        u_int32_t     *tbl = 0;
  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        */
  99        if (!crcTableInit) {
 100#ifdef STATIC_CRC_TABLE
 101                tbl = &CRCTable;
 102                genCrcTable(tbl);
 103#else
 104                tbl = (u_int32_t *) OS_kmalloc(CRC_TABLE_ENTRIES * sizeof(u_int32_t));
 105                if (tbl == 0) {
 106                        *result = 0;   /* dummy up return value due to malloc
 107                                        * failure */
 108                        return;
 109                }
 110                genCrcTable(tbl);
 111#endif
 112        }
 113        /* inverting bits makes ZMODEM & PKZIP compatible */
 114        crc = initialCrc ^ 0xFFFFFFFFL;
 115
 116        while (count-- != 0) {
 117                temp1 = (crc >> 8) & 0x00FFFFFFL;
 118                temp2 = tbl[((int) crc ^ *buffer++) & 0xff];
 119                crc = temp1 ^ temp2;
 120        }
 121
 122        crc ^= 0xFFFFFFFFL;
 123
 124        *result = crc;
 125
 126#ifndef STATIC_CRC_TABLE
 127        crcTableInit = 0;
 128        OS_kfree(tbl);
 129#endif
 130}
 131
 132/*** End-of-File ***/
 133