root/opal/util/crc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. opal_bcopy_csum_partial
  2. opal_bcopy_uicsum_partial
  3. opal_csum_partial
  4. opal_uicsum_partial
  5. opal_initialize_crc_table
  6. opal_bcopy_uicrc_partial
  7. opal_uicrc_partial

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2006 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2014      Intel, Inc. All rights reserved.
  13  * $COPYRIGHT$
  14  *
  15  * Additional copyrights may follow
  16  *
  17  * $HEADER$
  18  */
  19 
  20 
  21 #include "opal_config.h"
  22 #ifdef HAVE_STDIO_H
  23 #include <stdio.h>
  24 #endif /* HAVE_STDIO_H */
  25 #include <stdlib.h>
  26 #ifdef HAVE_STRINGS_H
  27 #include <strings.h>
  28 #endif  /* HAVE_STRINGS_H */
  29 #include <string.h>
  30 #ifdef HAVE_UNISTD_H
  31 #include <unistd.h>
  32 #endif  /* HAVE_UNISTD_H */
  33 #include "opal/util/crc.h"
  34 
  35 
  36 #if (OPAL_ALIGNMENT_LONG == 8)
  37 #define OPAL_CRC_WORD_MASK_ 0x7
  38 #elif (OPAL_ALIGNMENT_LONG == 4)
  39 #define OPAL_CRC_WORD_MASK_ 0x3
  40 #else
  41 #define OPAL_CRC_WORD_MASK_ 0xFFFF
  42 #endif
  43 
  44 
  45 #define WORDALIGNED(v) \
  46     (((intptr_t)v & OPAL_CRC_WORD_MASK_) ? false : true)
  47 
  48 
  49 #define INTALIGNED(v) \
  50     (((intptr_t)v & 3) ? false : true)
  51 
  52 /*
  53  * this version of bcopy_csum() looks a little too long, but it
  54  * handles cumulative checksumming for arbitrary lengths and address
  55  * alignments as best as it can; the contents of lastPartialLong and
  56  * lastPartialLength are updated to reflected the last partial word's
  57  * value and length (in bytes) -- this should allow proper handling of
  58  * checksumming contiguous or noncontiguous buffers via multiple calls
  59  * of bcopy_csum() - Mitch
  60  */
  61 
  62 unsigned long
  63 opal_bcopy_csum_partial (
  64     const void *  source,
  65     void *  destination,
  66     size_t copylen,
  67     size_t csumlen,
  68     unsigned long *  lastPartialLong,
  69     size_t*  lastPartialLength
  70     )
  71 {
  72     unsigned long *  src = (unsigned long *) source;
  73     unsigned long *  dest = (unsigned long *) destination;
  74     unsigned long csum = 0;
  75     size_t csumlenresidue;
  76     unsigned long i, temp;
  77 
  78     csumlenresidue = (csumlen > copylen) ? (csumlen - copylen) : 0;
  79     temp = *lastPartialLong;
  80 
  81     if (WORDALIGNED(source) && WORDALIGNED(dest)) {
  82         if (*lastPartialLength) {
  83             /* do we have enough data to fill out the partial word? */
  84             if (copylen >= (sizeof(unsigned long) - *lastPartialLength)) { /* YES, we do... */
  85                 memcpy(((char *)&temp + *lastPartialLength), src,
  86                        (sizeof(unsigned long) - *lastPartialLength));
  87                 memcpy(dest, ((char *)&temp + *lastPartialLength),
  88                        (sizeof(unsigned long) - *lastPartialLength));
  89                 src = (unsigned long *)((char *)src + sizeof(unsigned long) - *lastPartialLength);
  90                 dest = (unsigned long *)((char *)dest + sizeof(unsigned long) - *lastPartialLength);
  91                 csum += (temp - *lastPartialLong);
  92                 copylen -= sizeof(unsigned long) - *lastPartialLength;
  93                 /* now we have an unaligned source and an unaligned destination */
  94                 for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
  95                     memcpy(&temp, src, sizeof(temp));
  96                     src++;
  97                     csum += temp;
  98                     memcpy(dest, &temp, sizeof(temp));
  99                     dest++;
 100                 }
 101                 *lastPartialLength = 0;
 102                 *lastPartialLong = 0;
 103             }
 104             else { /* NO, we don't... */
 105                 memcpy(((char *)&temp + *lastPartialLength), src, copylen);
 106                 memcpy(dest, ((char *)&temp + *lastPartialLength), copylen);
 107                 src = (unsigned long *)((char *)src + copylen);
 108                 dest = (unsigned long *)((char *)dest + copylen);
 109                 csum += (temp - *lastPartialLong);
 110                 *lastPartialLong = temp;
 111                 *lastPartialLength += copylen;
 112                 copylen = 0;
 113             }
 114         }
 115         else { /* fast path... */
 116             size_t numLongs = copylen/sizeof(unsigned long);
 117             for(i = 0; i < numLongs; i++) {
 118                     csum += *src;
 119                     *dest++ = *src++;
 120             }
 121             *lastPartialLong = 0;
 122             *lastPartialLength = 0;
 123             if (WORDALIGNED(copylen) && (csumlenresidue == 0)) {
 124                     return(csum);
 125             }
 126             else {
 127                     copylen -= i * sizeof(unsigned long);
 128             }
 129         }
 130     } else if (WORDALIGNED(source)) {
 131         if (*lastPartialLength) {
 132             /* do we have enough data to fill out the partial word? */
 133             if (copylen >= (sizeof(unsigned long) - *lastPartialLength)) { /* YES, we do... */
 134                 memcpy(((char *)&temp + *lastPartialLength), src,
 135                        (sizeof(unsigned long) - *lastPartialLength));
 136                 memcpy(dest, ((char *)&temp + *lastPartialLength),
 137                        (sizeof(unsigned long) - *lastPartialLength));
 138                 src = (unsigned long *)((char *)src + sizeof(unsigned long) - *lastPartialLength);
 139                 dest = (unsigned long *)((char *)dest + sizeof(unsigned long) - *lastPartialLength);
 140                 csum += (temp - *lastPartialLong);
 141                 copylen -= sizeof(unsigned long) - *lastPartialLength;
 142                 /* now we have an unaligned source and an unknown alignment for our destination */
 143                 if (WORDALIGNED(dest)) {
 144                     size_t numLongs = copylen/sizeof(unsigned long);
 145                     for(i = 0; i < numLongs; i++) {
 146                             memcpy(&temp, src, sizeof(temp));
 147                             src++;
 148                             csum += temp;
 149                             *dest++ = temp;
 150                     }
 151                     copylen -= i * sizeof(unsigned long);
 152                 }
 153                 else {
 154                     for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 155                             memcpy(&temp, src, sizeof(temp));
 156                             src++;
 157                             csum += temp;
 158                             memcpy(dest, &temp, sizeof(temp));
 159                             dest++;
 160                     }
 161                 }
 162                 *lastPartialLong = 0;
 163                 *lastPartialLength = 0;
 164             }
 165             else { /* NO, we don't... */
 166                     memcpy(((char *)&temp + *lastPartialLength), src, copylen);
 167                     memcpy(dest, ((char *)&temp + *lastPartialLength), copylen);
 168                     src = (unsigned long *)((char *)src + copylen);
 169                     dest = (unsigned long *)((char *)dest + copylen);
 170                     csum += (temp - *lastPartialLong);
 171                     *lastPartialLong = temp;
 172                     *lastPartialLength += copylen;
 173                     copylen = 0;
 174             }
 175         }
 176         else {
 177             for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 178                 temp = *src++;
 179                 csum += temp;
 180                 memcpy(dest, &temp, sizeof(temp));
 181                 dest++;
 182             }
 183             *lastPartialLong = 0;
 184             *lastPartialLength = 0;
 185         }
 186     } else if (WORDALIGNED(dest)) {
 187         if (*lastPartialLength) {
 188             /* do we have enough data to fill out the partial word? */
 189             if (copylen >= (sizeof(unsigned long) - *lastPartialLength)) { /* YES, we do... */
 190                 memcpy(((char *)&temp + *lastPartialLength), src,
 191                        (sizeof(unsigned long) - *lastPartialLength));
 192                 memcpy(dest, ((char *)&temp + *lastPartialLength),
 193                        (sizeof(unsigned long) - *lastPartialLength));
 194                 src = (unsigned long *)((char *)src + sizeof(unsigned long) - *lastPartialLength);
 195                 dest = (unsigned long *)((char *)dest + sizeof(unsigned long) - *lastPartialLength);
 196                 csum += (temp - *lastPartialLong);
 197                 copylen -= sizeof(unsigned long) - *lastPartialLength;
 198                 /* now we have a source of unknown alignment and a unaligned destination */
 199                 if (WORDALIGNED(src)) {
 200                     for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 201                         temp = *src++;
 202                         csum += temp;
 203                         memcpy(dest, &temp, sizeof(temp));
 204                         dest++;
 205                     }
 206                     *lastPartialLong = 0;
 207                     *lastPartialLength = 0;
 208                 }
 209                 else {
 210                     for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 211                         memcpy(&temp, src, sizeof(temp));
 212                         src++;
 213                         csum += temp;
 214                         memcpy(dest, &temp, sizeof(temp));
 215                         dest++;
 216                     }
 217                     *lastPartialLength = 0;
 218                     *lastPartialLong = 0;
 219                 }
 220             }
 221             else { /* NO, we don't... */
 222                 memcpy(((char *)&temp + *lastPartialLength), src, copylen);
 223                 memcpy(dest, ((char *)&temp + *lastPartialLength), copylen);
 224                 src = (unsigned long *)((char *)src + copylen);
 225                 dest = (unsigned long *)((char *)dest + copylen);
 226                 csum += (temp - *lastPartialLong);
 227                 *lastPartialLong = temp;
 228                 *lastPartialLength += copylen;
 229                 copylen = 0;
 230             }
 231         }
 232         else {
 233             for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 234                 memcpy(&temp, src, sizeof(temp));
 235                 src++;
 236                 csum += temp;
 237                 *dest++ = temp;
 238             }
 239             *lastPartialLength = 0;
 240             *lastPartialLong = 0;
 241         }
 242     } else {
 243         if (*lastPartialLength) {
 244             /* do we have enough data to fill out the partial word? */
 245             if (copylen >= (sizeof(unsigned long) - *lastPartialLength)) { /* YES, we do... */
 246                 memcpy(((char *)&temp + *lastPartialLength), src,
 247                        (sizeof(unsigned long) - *lastPartialLength));
 248                 memcpy(dest, ((char *)&temp + *lastPartialLength),
 249                        (sizeof(unsigned long) - *lastPartialLength));
 250                 src = (unsigned long *)((char *)src + sizeof(unsigned long) - *lastPartialLength);
 251                 dest = (unsigned long *)((char *)dest + sizeof(unsigned long) - *lastPartialLength);
 252                 csum += (temp - *lastPartialLong);
 253                 copylen -= sizeof(unsigned long) - *lastPartialLength;
 254                 /* now we have an unknown alignment for our source and destination */
 255                 if (WORDALIGNED(src) && WORDALIGNED(dest)) {
 256                     size_t numLongs = copylen/sizeof(unsigned long);
 257                     for(i = 0; i < numLongs; i++) {
 258                             csum += *src;
 259                             *dest++ = *src++;
 260                     }
 261                     copylen -= i * sizeof(unsigned long);
 262                 }
 263                 else { /* safe but slower for all other alignments */
 264                     for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 265                             memcpy(&temp, src, sizeof(temp));
 266                             src++;
 267                             csum += temp;
 268                             memcpy(dest, &temp, sizeof(temp));
 269                             dest++;
 270                     }
 271                 }
 272                 *lastPartialLong = 0;
 273                 *lastPartialLength = 0;
 274             }
 275             else { /* NO, we don't... */
 276                 memcpy(((char *)&temp + *lastPartialLength), src, copylen);
 277                 memcpy(dest, ((char *)&temp + *lastPartialLength), copylen);
 278                 src = (unsigned long *)((char *)src + copylen);
 279                 dest = (unsigned long *)((char *)dest + copylen);
 280                 csum += (temp - *lastPartialLong);
 281                 *lastPartialLong = temp;
 282                 *lastPartialLength += copylen;
 283                 copylen = 0;
 284             }
 285         }
 286         else {
 287             for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 288                 memcpy(&temp, src, sizeof(temp));
 289                 src++;
 290                 csum += temp;
 291                 memcpy(dest, &temp, sizeof(temp));
 292                 dest++;
 293             }
 294             *lastPartialLength = 0;
 295             *lastPartialLong = 0;
 296         }
 297     }
 298 
 299     /* if copylen is non-zero there was a bit left, less than an unsigned long's worth */
 300     if ((copylen != 0) && (csumlenresidue == 0)) {
 301         temp = *lastPartialLong;
 302         if (*lastPartialLength) {
 303             if (copylen >= (sizeof(unsigned long) - *lastPartialLength)) {
 304                 /* copy all remaining bytes from src to dest */
 305                 unsigned long copytemp = 0;
 306                 memcpy(&copytemp, src, copylen);
 307                 memcpy(dest, &copytemp, copylen);
 308                 /* fill out rest of partial word and add to checksum */
 309                 memcpy(((char *)&temp + *lastPartialLength), src,
 310                        (sizeof(unsigned long) - *lastPartialLength));
 311                 /* avoid unsigned arithmetic overflow by subtracting the old partial
 312                  * word from the new one before adding to the checksum...
 313         */
 314                 csum += (temp - *lastPartialLong);
 315                 copylen -= sizeof(unsigned long) - *lastPartialLength;
 316                 src = (unsigned long *)((char *)src + sizeof(unsigned long) - *lastPartialLength);
 317                 *lastPartialLength = copylen;
 318                 /* reset temp, and calculate next partial word */
 319                 temp = 0;
 320                 if (copylen) {
 321                     memcpy(&temp, src, copylen);
 322                 }
 323                 /* add it to the the checksum */
 324                 csum += temp;
 325                 *lastPartialLong = temp;
 326             }
 327             else {
 328                 /* copy all remaining bytes from src to dest */
 329                 unsigned long copytemp = 0;
 330                 memcpy(&copytemp, src, copylen);
 331                 memcpy(dest, &copytemp, copylen);
 332                 /* fill out rest of partial word and add to checksum */
 333                 memcpy(((char *)&temp + *lastPartialLength), src,
 334                        copylen);
 335                 /* avoid unsigned arithmetic overflow by subtracting the old partial
 336                  * word from the new one before adding to the checksum...
 337         */
 338                 csum += temp - *lastPartialLong;
 339                 *lastPartialLong = temp;
 340                 *lastPartialLength += copylen;
 341             }
 342         }
 343         else { /* fast path... */
 344             /* temp and *lastPartialLong are 0 if *lastPartialLength is 0... */
 345             memcpy(&temp, src, copylen);
 346             csum += temp;
 347             memcpy(dest, &temp, copylen);
 348             *lastPartialLong = temp;
 349             *lastPartialLength = copylen;
 350             /* done...return the checksum */
 351         }
 352     }
 353     else if (csumlenresidue != 0) {
 354         if (copylen != 0) {
 355             temp = 0;
 356             memcpy(&temp, src, copylen);
 357             memcpy(dest, &temp, copylen);
 358         }
 359         if (csumlenresidue < (sizeof(unsigned long) - copylen - *lastPartialLength)) {
 360             temp = *lastPartialLong;
 361             memcpy(((char *)&temp + *lastPartialLength), src, (copylen + csumlenresidue));
 362             /* avoid unsigned arithmetic overflow by subtracting the old partial */
 363             /* word from the new one before adding to the checksum... */
 364             csum += temp - *lastPartialLong;
 365             src++;
 366             *lastPartialLong = temp;
 367             *lastPartialLength += copylen + csumlenresidue;
 368             csumlenresidue = 0;
 369         }
 370         else {
 371             /* we have enough chksum data to fill out our last partial */
 372             /* word */
 373             temp = *lastPartialLong;
 374             memcpy(((char *)&temp + *lastPartialLength), src,
 375                    (sizeof(unsigned long) - *lastPartialLength));
 376             /* avoid unsigned arithmetic overflow by subtracting the old partial */
 377             /* word from the new one before adding to the checksum... */
 378             csum += temp - *lastPartialLong;
 379             src = (unsigned long *)((char *)src + sizeof(unsigned long) - *lastPartialLength);
 380             csumlenresidue -= sizeof(unsigned long) - *lastPartialLength - copylen;
 381             *lastPartialLength = 0;
 382             *lastPartialLong = 0;
 383         }
 384         if (WORDALIGNED(src)) {
 385             for (i = 0; i < csumlenresidue/sizeof(unsigned long); i++) {
 386                 csum += *src++;
 387             }
 388         }
 389         else {
 390             for (i = 0; i < csumlenresidue/sizeof(unsigned long); i++) {
 391                 memcpy(&temp, src, sizeof(temp));
 392                 csum += temp;
 393                 src++;
 394             }
 395         }
 396         csumlenresidue -= i * sizeof(unsigned long);
 397         if (csumlenresidue) {
 398             temp = 0;
 399             memcpy(&temp, src, csumlenresidue);
 400             csum += temp;
 401             *lastPartialLong = temp;
 402             *lastPartialLength = csumlenresidue;
 403         }
 404     } /* end else if (csumlenresidue != 0) */
 405 
 406     return csum;
 407 }
 408 
 409 unsigned int
 410 opal_bcopy_uicsum_partial (
 411     const void *  source,
 412     void *  destination,
 413     size_t copylen,
 414     size_t csumlen,
 415     unsigned int*  lastPartialInt,
 416     size_t*  lastPartialLength
 417     )
 418 {
 419     unsigned int *  src = (unsigned int *) source;
 420     unsigned int *  dest = (unsigned int *) destination;
 421     unsigned int csum = 0;
 422     size_t csumlenresidue;
 423     unsigned long i;
 424     unsigned int temp;
 425 
 426     csumlenresidue = (csumlen > copylen) ? (csumlen - copylen) : 0;
 427     temp = *lastPartialInt;
 428 
 429     if (INTALIGNED(source) && INTALIGNED(dest)) {
 430         if (*lastPartialLength) {
 431             /* do we have enough data to fill out the partial word? */
 432             if (copylen >= (sizeof(unsigned int) - *lastPartialLength)) { /* YES, we do... */
 433                 memcpy(((char *)&temp + *lastPartialLength), src,
 434                        (sizeof(unsigned int) - *lastPartialLength));
 435                 memcpy(dest, ((char *)&temp + *lastPartialLength),
 436                        (sizeof(unsigned int) - *lastPartialLength));
 437                 src = (unsigned int *)((char *)src + sizeof(unsigned int) - *lastPartialLength);
 438                 dest = (unsigned int *)((char *)dest + sizeof(unsigned int) - *lastPartialLength);
 439                 csum += (temp - *lastPartialInt);
 440                 copylen -= sizeof(unsigned int) - *lastPartialLength;
 441                 /* now we have an unaligned source and an unaligned destination */
 442                 for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 443                     memcpy(&temp, src, sizeof(temp));
 444                     src++;
 445                     csum += temp;
 446                     memcpy(dest, &temp, sizeof(temp));
 447                     dest++;
 448                 }
 449                 *lastPartialLength = 0;
 450                 *lastPartialInt = 0;
 451             }
 452             else { /* NO, we don't... */
 453                 memcpy(((char *)&temp + *lastPartialLength), src, copylen);
 454                 memcpy(dest, ((char *)&temp + *lastPartialLength), copylen);
 455                 src = (unsigned int *)((char *)src + copylen);
 456                 dest = (unsigned int *)((char *)dest + copylen);
 457                 csum += (temp - *lastPartialInt);
 458                 *lastPartialInt = temp;
 459                 *lastPartialLength += copylen;
 460                 copylen = 0;
 461             }
 462         }
 463         else { /* fast path... */
 464             size_t numLongs = copylen/sizeof(unsigned int);
 465             for(i = 0; i < numLongs; i++) {
 466                     csum += *src;
 467                     *dest++ = *src++;
 468             }
 469             *lastPartialInt = 0;
 470             *lastPartialLength = 0;
 471             if (INTALIGNED(copylen) && (csumlenresidue == 0)) {
 472                     return(csum);
 473             }
 474             else {
 475                     copylen -= i * sizeof(unsigned int);
 476             }
 477         }
 478     } else if (INTALIGNED(source)) {
 479         if (*lastPartialLength) {
 480             /* do we have enough data to fill out the partial word? */
 481             if (copylen >= (sizeof(unsigned int) - *lastPartialLength)) { /* YES, we do... */
 482                 memcpy(((char *)&temp + *lastPartialLength), src,
 483                        (sizeof(unsigned int) - *lastPartialLength));
 484                 memcpy(dest, ((char *)&temp + *lastPartialLength),
 485                        (sizeof(unsigned int) - *lastPartialLength));
 486                 src = (unsigned int *)((char *)src + sizeof(unsigned int) - *lastPartialLength);
 487                 dest = (unsigned int *)((char *)dest + sizeof(unsigned int) - *lastPartialLength);
 488                 csum += (temp - *lastPartialInt);
 489                 copylen -= sizeof(unsigned int) - *lastPartialLength;
 490                 /* now we have an unaligned source and an unknown alignment for our destination */
 491                 if (INTALIGNED(dest)) {
 492                     size_t numLongs = copylen/sizeof(unsigned int);
 493                     for(i = 0; i < numLongs; i++) {
 494                         memcpy(&temp, src, sizeof(temp));
 495                         src++;
 496                         csum += temp;
 497                         *dest++ = temp;
 498                     }
 499                     copylen -= i * sizeof(unsigned int);
 500                 }
 501                 else {
 502                     for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 503                         memcpy(&temp, src, sizeof(temp));
 504                         src++;
 505                         csum += temp;
 506                         memcpy(dest, &temp, sizeof(temp));
 507                         dest++;
 508                     }
 509                 }
 510                 *lastPartialInt = 0;
 511                 *lastPartialLength = 0;
 512             }
 513             else { /* NO, we don't... */
 514                 memcpy(((char *)&temp + *lastPartialLength), src, copylen);
 515                 memcpy(dest, ((char *)&temp + *lastPartialLength), copylen);
 516                 src = (unsigned int *)((char *)src + copylen);
 517                 dest = (unsigned int *)((char *)dest + copylen);
 518                 csum += (temp - *lastPartialInt);
 519                 *lastPartialInt = temp;
 520                 *lastPartialLength += copylen;
 521                 copylen = 0;
 522             }
 523         }
 524         else {
 525             for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 526                 temp = *src++;
 527                 csum += temp;
 528                 memcpy(dest, &temp, sizeof(temp));
 529                 dest++;
 530             }
 531             *lastPartialInt = 0;
 532             *lastPartialLength = 0;
 533         }
 534     } else if (INTALIGNED(dest)) {
 535         if (*lastPartialLength) {
 536             /* do we have enough data to fill out the partial word? */
 537             if (copylen >= (sizeof(unsigned int) - *lastPartialLength)) { /* YES, we do... */
 538                 memcpy(((char *)&temp + *lastPartialLength), src,
 539                        (sizeof(unsigned int) - *lastPartialLength));
 540                 memcpy(dest, ((char *)&temp + *lastPartialLength),
 541                        (sizeof(unsigned int) - *lastPartialLength));
 542                 src = (unsigned int *)((char *)src + sizeof(unsigned int) - *lastPartialLength);
 543                 dest = (unsigned int *)((char *)dest + sizeof(unsigned int) - *lastPartialLength);
 544                 csum += (temp - *lastPartialInt);
 545                 copylen -= sizeof(unsigned int) - *lastPartialLength;
 546                 /* now we have a source of unknown alignment and a unaligned destination */
 547                 if (INTALIGNED(src)) {
 548                     for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 549                         temp = *src++;
 550                         csum += temp;
 551                         memcpy(dest, &temp, sizeof(temp));
 552                         dest++;
 553                     }
 554                     *lastPartialInt = 0;
 555                     *lastPartialLength = 0;
 556                 }
 557                 else {
 558                     for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 559                         memcpy(&temp, src, sizeof(temp));
 560                         src++;
 561                         csum += temp;
 562                         memcpy(dest, &temp, sizeof(temp));
 563                         dest++;
 564                     }
 565                     *lastPartialLength = 0;
 566                     *lastPartialInt = 0;
 567                 }
 568             }
 569             else { /* NO, we don't... */
 570                 memcpy(((char *)&temp + *lastPartialLength), src, copylen);
 571                 memcpy(dest, ((char *)&temp + *lastPartialLength), copylen);
 572                 src = (unsigned int *)((char *)src + copylen);
 573                 dest = (unsigned int *)((char *)dest + copylen);
 574                 csum += (temp - *lastPartialInt);
 575                 *lastPartialInt = temp;
 576                 *lastPartialLength += copylen;
 577                 copylen = 0;
 578             }
 579         }
 580         else {
 581             for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 582                 memcpy(&temp, src, sizeof(temp));
 583                 src++;
 584                 csum += temp;
 585                 *dest++ = temp;
 586             }
 587             *lastPartialLength = 0;
 588             *lastPartialInt = 0;
 589         }
 590     } else {
 591         if (*lastPartialLength) {
 592             /* do we have enough data to fill out the partial word? */
 593             if (copylen >= (sizeof(unsigned int) - *lastPartialLength)) { /* YES, we do... */
 594                 memcpy(((char *)&temp + *lastPartialLength), src,
 595                        (sizeof(unsigned int) - *lastPartialLength));
 596                 memcpy(dest, ((char *)&temp + *lastPartialLength),
 597                        (sizeof(unsigned int) - *lastPartialLength));
 598                 src = (unsigned int *)((char *)src + sizeof(unsigned int) - *lastPartialLength);
 599                 dest = (unsigned int *)((char *)dest + sizeof(unsigned int) - *lastPartialLength);
 600                 csum += (temp - *lastPartialInt);
 601                 copylen -= sizeof(unsigned int) - *lastPartialLength;
 602                 /* now we have an unknown alignment for our source and destination */
 603                 if (INTALIGNED(src) && INTALIGNED(dest)) {
 604                     size_t numLongs = copylen/sizeof(unsigned int);
 605                     for(i = 0; i < numLongs; i++) {
 606                         csum += *src;
 607                         *dest++ = *src++;
 608                     }
 609                     copylen -= i * sizeof(unsigned int);
 610                 }
 611                 else { /* safe but slower for all other alignments */
 612                     for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 613                         memcpy(&temp, src, sizeof(temp));
 614                         src++;
 615                         csum += temp;
 616                         memcpy(dest, &temp, sizeof(temp));
 617                         dest++;
 618                     }
 619                 }
 620                 *lastPartialInt = 0;
 621                 *lastPartialLength = 0;
 622             }
 623             else { /* NO, we don't... */
 624                 memcpy(((char *)&temp + *lastPartialLength), src, copylen);
 625                 memcpy(dest, ((char *)&temp + *lastPartialLength), copylen);
 626                 src = (unsigned int *)((char *)src + copylen);
 627                 dest = (unsigned int *)((char *)dest + copylen);
 628                 csum += (temp - *lastPartialInt);
 629                 *lastPartialInt = temp;
 630                 *lastPartialLength += copylen;
 631                 copylen = 0;
 632             }
 633         }
 634         else {
 635             for( ;copylen >= sizeof(*src); copylen -= sizeof(*src)) {
 636                 memcpy(&temp, src, sizeof(temp));
 637                 src++;
 638                 csum += temp;
 639                 memcpy(dest, &temp, sizeof(temp));
 640                 dest++;
 641             }
 642             *lastPartialLength = 0;
 643             *lastPartialInt = 0;
 644         }
 645     }
 646 
 647     /* if copylen is non-zero there was a bit left, less than an unsigned int's worth */
 648     if ((copylen != 0) && (csumlenresidue == 0)) {
 649         temp = *lastPartialInt;
 650         if (*lastPartialLength) {
 651             if (copylen >= (sizeof(unsigned int) - *lastPartialLength)) {
 652                 /* copy all remaining bytes from src to dest */
 653                 unsigned int copytemp = 0;
 654                 memcpy(&copytemp, src, copylen);
 655                 memcpy(dest, &copytemp, copylen);
 656                 /* fill out rest of partial word and add to checksum */
 657                 memcpy(((char *)&temp + *lastPartialLength), src,
 658                        (sizeof(unsigned int) - *lastPartialLength));
 659                 /* avoid unsigned arithmetic overflow by subtracting the old partial
 660                  * word from the new one before adding to the checksum...
 661         */
 662                 csum += (temp - *lastPartialInt);
 663                 copylen -= sizeof(unsigned int) - *lastPartialLength;
 664                 src = (unsigned int *)((char *)src + sizeof(unsigned int) - *lastPartialLength);
 665                 *lastPartialLength = copylen;
 666                 /* reset temp, and calculate next partial word */
 667                 temp = 0;
 668                 if (copylen) {
 669                     memcpy(&temp, src, copylen);
 670                 }
 671                 /* add it to the the checksum */
 672                 csum += temp;
 673                 *lastPartialInt = temp;
 674             }
 675             else {
 676                 /* copy all remaining bytes from src to dest */
 677                 unsigned int copytemp = 0;
 678                 memcpy(&copytemp, src, copylen);
 679                 memcpy(dest, &copytemp, copylen);
 680                 /* fill out rest of partial word and add to checksum */
 681                 memcpy(((char *)&temp + *lastPartialLength), src,
 682                        copylen);
 683                 /* avoid unsigned arithmetic overflow by subtracting the old partial
 684                  * word from the new one before adding to the checksum...
 685         */
 686                 csum += temp - *lastPartialInt;
 687                 *lastPartialInt = temp;
 688                 *lastPartialLength += copylen;
 689             }
 690         }
 691         else { /* fast path... */
 692             /* temp and *lastPartialInt are 0 if *lastPartialLength is 0... */
 693             memcpy(&temp, src, copylen);
 694             csum += temp;
 695             memcpy(dest, &temp, copylen);
 696             *lastPartialInt = temp;
 697             *lastPartialLength = copylen;
 698             /* done...return the checksum */
 699         }
 700     }
 701     else if (csumlenresidue != 0) {
 702         if (copylen != 0) {
 703             temp = 0;
 704             memcpy(&temp, src, copylen);
 705             memcpy(dest, &temp, copylen);
 706         }
 707         if (csumlenresidue < (sizeof(unsigned int) - copylen - *lastPartialLength)) {
 708             temp = *lastPartialInt;
 709             memcpy(((char *)&temp + *lastPartialLength), src, (copylen + csumlenresidue));
 710             /* avoid unsigned arithmetic overflow by subtracting the old partial
 711              * word from the new one before adding to the checksum...
 712         */
 713             csum += temp - *lastPartialInt;
 714             src++;
 715             *lastPartialInt = temp;
 716             *lastPartialLength += copylen + csumlenresidue;
 717             csumlenresidue = 0;
 718         }
 719         else {
 720             /* we have enough chksum data to fill out our last partial
 721              * word
 722         */
 723             temp = *lastPartialInt;
 724             memcpy(((char *)&temp + *lastPartialLength), src,
 725                    (sizeof(unsigned int) - *lastPartialLength));
 726             /* avoid unsigned arithmetic overflow by subtracting the old partial
 727              * word from the new one before adding to the checksum...
 728         */
 729             csum += temp - *lastPartialInt;
 730             src = (unsigned int *)((char *)src + sizeof(unsigned int) - *lastPartialLength);
 731             csumlenresidue -= sizeof(unsigned int) - *lastPartialLength - copylen;
 732             *lastPartialLength = 0;
 733             *lastPartialInt = 0;
 734         }
 735         if (INTALIGNED(src)) {
 736             for (i = 0; i < csumlenresidue/sizeof(unsigned int); i++) {
 737                 csum += *src++;
 738             }
 739         }
 740         else {
 741             for (i = 0; i < csumlenresidue/sizeof(unsigned int); i++) {
 742                 memcpy(&temp, src, sizeof(temp));
 743                 csum += temp;
 744                 src++;
 745             }
 746         }
 747         csumlenresidue -= i * sizeof(unsigned int);
 748         if (csumlenresidue) {
 749             temp = 0;
 750             memcpy(&temp, src, csumlenresidue);
 751             csum += temp;
 752             *lastPartialInt = temp;
 753             *lastPartialLength = csumlenresidue;
 754         }
 755     } /* end else if (csumlenresidue != 0) */
 756 
 757     return csum;
 758 }
 759 
 760 
 761 /*
 762  * csum() generates a bcopy_csum() - compatible checksum that can be
 763  * called multiple times
 764  */
 765 
 766 unsigned long
 767 opal_csum_partial (
 768     const void *  source,
 769     size_t csumlen,
 770     unsigned long*  lastPartialLong,
 771     size_t* lastPartialLength
 772     )
 773 {
 774     unsigned long *  src = (unsigned long *) source;
 775     unsigned long csum = 0;
 776     unsigned long i, temp;
 777 
 778 
 779 
 780     temp = *lastPartialLong;
 781 
 782     if (WORDALIGNED(source))  {
 783         if (*lastPartialLength) {
 784             /* do we have enough data to fill out the partial word? */
 785             if (csumlen >= (sizeof(unsigned long) - *lastPartialLength)) { /* YES, we do... */
 786                 memcpy(((char *)&temp + *lastPartialLength), src,
 787                        (sizeof(unsigned long) - *lastPartialLength));
 788                 src = (unsigned long *)((char *)src + sizeof(unsigned long) - *lastPartialLength);
 789                 csum += (temp - *lastPartialLong);
 790                 csumlen -= sizeof(unsigned long) - *lastPartialLength;
 791                 /* now we have an unaligned source */
 792                 for(i = 0; i < csumlen/sizeof(unsigned long); i++) {
 793                     memcpy(&temp, src, sizeof(temp));
 794                     csum += temp;
 795                     src++;
 796                 }
 797                 csumlen -= i * sizeof(unsigned long);
 798                 *lastPartialLong = 0;
 799                 *lastPartialLength = 0;
 800             }
 801             else { /* NO, we don't... */
 802                 memcpy(((char *)&temp + *lastPartialLength), src, csumlen);
 803                 src = (unsigned long *)((char *)src + csumlen);
 804                 csum += (temp - *lastPartialLong);
 805                 *lastPartialLong = temp;
 806                 *lastPartialLength += csumlen;
 807                 csumlen = 0;
 808             }
 809         }
 810         else { /* fast path... */
 811             size_t numLongs = csumlen/sizeof(unsigned long);
 812             for(i = 0; i < numLongs; i++) {
 813                     csum += *src++;
 814             }
 815             *lastPartialLong = 0;
 816             *lastPartialLength = 0;
 817             if (WORDALIGNED(csumlen)) {
 818                     return(csum);
 819             }
 820             else {
 821                     csumlen -= i * sizeof(unsigned long);
 822             }
 823         }
 824     } else {
 825         if (*lastPartialLength) {
 826             /* do we have enough data to fill out the partial word? */
 827             if (csumlen >= (sizeof(unsigned long) - *lastPartialLength)) { /* YES, we do... */
 828                 memcpy(((char *)&temp + *lastPartialLength), src,
 829                        (sizeof(unsigned long) - *lastPartialLength));
 830                 src = (unsigned long *)((char *)src + sizeof(unsigned long) - *lastPartialLength);
 831                 csum += (temp - *lastPartialLong);
 832                 csumlen -= sizeof(unsigned long) - *lastPartialLength;
 833                 /* now we have a source of unknown alignment */
 834                 if (WORDALIGNED(src)) {
 835                     for(i = 0; i < csumlen/sizeof(unsigned long); i++) {
 836                         csum += *src++;
 837                     }
 838                     csumlen -= i * sizeof(unsigned long);
 839                     *lastPartialLong = 0;
 840                     *lastPartialLength = 0;
 841                 }
 842                 else {
 843                     for(i = 0; i < csumlen/sizeof(unsigned long); i++) {
 844                         memcpy(&temp, src, sizeof(temp));
 845                         csum += temp;
 846                         src++;
 847                     }
 848                     csumlen -= i * sizeof(unsigned long);
 849                     *lastPartialLong = 0;
 850                     *lastPartialLength = 0;
 851                 }
 852             }
 853             else { /* NO, we don't... */
 854                 memcpy(((char *)&temp + *lastPartialLength), src, csumlen);
 855                 src = (unsigned long *)((char *)src + csumlen);
 856                 csum += (temp - *lastPartialLong);
 857                 *lastPartialLong = temp;
 858                 *lastPartialLength += csumlen;
 859                 csumlen = 0;
 860             }
 861         }
 862         else {
 863             for( ;csumlen >= sizeof(*src); csumlen -= sizeof(*src)) {
 864                 memcpy(&temp, src, sizeof(temp));
 865                 src++;
 866                 csum += temp;
 867             }
 868             *lastPartialLength = 0;
 869             *lastPartialLong = 0;
 870         }
 871     }
 872 
 873     /* if csumlen is non-zero there was a bit left, less than an unsigned long's worth */
 874     if (csumlen != 0) {
 875         temp = *lastPartialLong;
 876         if (*lastPartialLength) {
 877             if (csumlen >= (sizeof(unsigned long) - *lastPartialLength)) {
 878                 /* fill out rest of partial word and add to checksum */
 879                 memcpy(((char *)&temp + *lastPartialLength), src,
 880                        (sizeof(unsigned long) - *lastPartialLength));
 881                 csum += (temp - *lastPartialLong);
 882                 csumlen -= sizeof(unsigned long) - *lastPartialLength;
 883                 src = (unsigned long *)((char *)src + sizeof(unsigned long) - *lastPartialLength);
 884                 *lastPartialLength = csumlen;
 885                 /* reset temp, and calculate next partial word */
 886                 temp = 0;
 887                 if (csumlen) {
 888                     memcpy(&temp, src, csumlen);
 889                 }
 890                 /* add it to the the checksum */
 891                 csum += temp;
 892                 *lastPartialLong = temp;
 893             }
 894             else {
 895                 /* fill out rest of partial word and add to checksum */
 896                 memcpy(((char *)&temp + *lastPartialLength), src,
 897                        csumlen);
 898                 csum += (temp - *lastPartialLong);
 899                 *lastPartialLong = temp;
 900                 *lastPartialLength += csumlen;
 901             }
 902         }
 903         else { /* fast path... */
 904             /* temp and *lastPartialLong are 0 if *lastPartialLength is 0... */
 905             memcpy(&temp, src, csumlen);
 906             csum += temp;
 907             *lastPartialLong = temp;
 908             *lastPartialLength = csumlen;
 909             /* done...return the checksum */
 910         }
 911     }
 912 
 913     return csum;
 914 }
 915 
 916 unsigned int
 917 opal_uicsum_partial (
 918     const void *  source,
 919     size_t csumlen,
 920     unsigned int*  lastPartialInt,
 921     size_t*  lastPartialLength
 922     )
 923 {
 924     unsigned int *  src = (unsigned int *) source;
 925     unsigned int csum = 0;
 926     unsigned int temp;
 927     unsigned long i;
 928 
 929 
 930     temp = *lastPartialInt;
 931 
 932     if (INTALIGNED(source))  {
 933         if (*lastPartialLength) {
 934             /* do we have enough data to fill out the partial word? */
 935             if (csumlen >= (sizeof(unsigned int) - *lastPartialLength)) { /* YES, we do... */
 936                 memcpy(((char *)&temp + *lastPartialLength), src,
 937                        (sizeof(unsigned int) - *lastPartialLength));
 938                 src = (unsigned int *)((char *)src + sizeof(unsigned int) - *lastPartialLength);
 939                 csum += (temp - *lastPartialInt);
 940                 csumlen -= sizeof(unsigned int) - *lastPartialLength;
 941                 /* now we have an unaligned source */
 942                 for(i = 0; i < csumlen/sizeof(unsigned int); i++) {
 943                     memcpy(&temp, src, sizeof(temp));
 944                     csum += temp;
 945                     src++;
 946                 }
 947                 csumlen -= i * sizeof(unsigned int);
 948                 *lastPartialInt = 0;
 949                 *lastPartialLength = 0;
 950             }
 951             else { /* NO, we don't... */
 952                 memcpy(((char *)&temp + *lastPartialLength), src, csumlen);
 953                 src = (unsigned int *)((char *)src + csumlen);
 954                 csum += (temp - *lastPartialInt);
 955                 *lastPartialInt = temp;
 956                 *lastPartialLength += csumlen;
 957                 csumlen = 0;
 958             }
 959         }
 960         else { /* fast path... */
 961             size_t numLongs = csumlen/sizeof(unsigned int);
 962             for(i = 0; i < numLongs; i++) {
 963                     csum += *src++;
 964             }
 965             *lastPartialInt = 0;
 966             *lastPartialLength = 0;
 967             if (INTALIGNED(csumlen)) {
 968                     return(csum);
 969             }
 970             else {
 971                     csumlen -= i * sizeof(unsigned int);
 972             }
 973         }
 974     } else {
 975         if (*lastPartialLength) {
 976             /* do we have enough data to fill out the partial word? */
 977             if (csumlen >= (sizeof(unsigned int) - *lastPartialLength)) { /* YES, we do... */
 978                 memcpy(((char *)&temp + *lastPartialLength), src,
 979                        (sizeof(unsigned int) - *lastPartialLength));
 980                 src = (unsigned int *)((char *)src + sizeof(unsigned int) - *lastPartialLength);
 981                 csum += (temp - *lastPartialInt);
 982                 csumlen -= sizeof(unsigned int) - *lastPartialLength;
 983                 /* now we have a source of unknown alignment */
 984                 if (INTALIGNED(src)) {
 985                     for(i = 0; i < csumlen/sizeof(unsigned int); i++) {
 986                         csum += *src++;
 987                     }
 988                     csumlen -= i * sizeof(unsigned int);
 989                     *lastPartialInt = 0;
 990                     *lastPartialLength = 0;
 991                 }
 992                 else {
 993                     for(i = 0; i < csumlen/sizeof(unsigned int); i++) {
 994                         memcpy(&temp, src, sizeof(temp));
 995                         csum += temp;
 996                         src++;
 997                     }
 998                     csumlen -= i * sizeof(unsigned int);
 999                     *lastPartialInt = 0;
1000                     *lastPartialLength = 0;
1001                 }
1002             }
1003             else { /* NO, we don't... */
1004                 memcpy(((char *)&temp + *lastPartialLength), src, csumlen);
1005                 src = (unsigned int *)((char *)src + csumlen);
1006                 csum += (temp - *lastPartialInt);
1007                 *lastPartialInt = temp;
1008                 *lastPartialLength += csumlen;
1009                 csumlen = 0;
1010             }
1011         }
1012         else {
1013             for( ;csumlen >= sizeof(*src); csumlen -= sizeof(*src)) {
1014                 memcpy(&temp, src, sizeof(temp));
1015                 src++;
1016                 csum += temp;
1017             }
1018             *lastPartialLength = 0;
1019             *lastPartialInt = 0;
1020         }
1021     }
1022 
1023     /* if csumlen is non-zero there was a bit left, less than an unsigned int's worth */
1024     if (csumlen != 0) {
1025         temp = *lastPartialInt;
1026         if (*lastPartialLength) {
1027             if (csumlen >= (sizeof(unsigned int) - *lastPartialLength)) {
1028                 /* fill out rest of partial word and add to checksum */
1029                 memcpy(((char *)&temp + *lastPartialLength), src,
1030                        (sizeof(unsigned int) - *lastPartialLength));
1031                 csum += (temp - *lastPartialInt);
1032                 csumlen -= sizeof(unsigned int) - *lastPartialLength;
1033                 src = (unsigned int *)((char *)src + sizeof(unsigned int) - *lastPartialLength);
1034                 *lastPartialLength = csumlen;
1035                 /* reset temp, and calculate next partial word */
1036                 temp = 0;
1037                 if (csumlen) {
1038                     memcpy(&temp, src, csumlen);
1039                 }
1040                 /* add it to the the checksum */
1041                 csum += temp;
1042                 *lastPartialInt = temp;
1043             }
1044             else {
1045                 /* fill out rest of partial word and add to checksum */
1046                 memcpy(((char *)&temp + *lastPartialLength), src,
1047                        csumlen);
1048                 csum += (temp - *lastPartialInt);
1049                 *lastPartialInt = temp;
1050                 *lastPartialLength += csumlen;
1051             }
1052         }
1053         else { /* fast path... */
1054             /* temp and *lastPartialInt are 0 if *lastPartialLength is 0... */
1055             memcpy(&temp, src, csumlen);
1056             csum += temp;
1057             *lastPartialInt = temp;
1058             *lastPartialLength = csumlen;
1059             /* done...return the checksum */
1060         }
1061     }
1062 
1063     return csum;
1064 }
1065 
1066 /* globals for CRC32 bcopy and calculation routines */
1067 
1068 static bool _opal_crc_table_initialized = false;
1069 static unsigned int _opal_crc_table[256];
1070 
1071 /* CRC32 table generation routine - thanks to Charles Michael Heard for his
1072  * optimized CRC32 code...
1073  */
1074 
1075 void opal_initialize_crc_table(void)
1076 {
1077     register int i,j;
1078     register unsigned int crc_accum;
1079 
1080     for (i = 0; i < 256; i++) {
1081         crc_accum = (i << 24);
1082         for (j = 0; j < 8; j++) {
1083             if (crc_accum & 0x80000000)
1084                 crc_accum = (crc_accum << 1) ^ CRC_POLYNOMIAL;
1085             else
1086                 crc_accum = (crc_accum << 1);
1087         }
1088         _opal_crc_table[i] = crc_accum;
1089     }
1090 
1091     /* set global bool to true to do this work once! */
1092     _opal_crc_table_initialized = true;
1093     return;
1094 }
1095 
1096 unsigned int opal_bcopy_uicrc_partial(
1097     const void *  source,
1098     void *  destination,
1099     size_t copylen,
1100     size_t crclen,
1101     unsigned int partial_crc)
1102 {
1103     size_t crclenresidue = (crclen > copylen) ? (crclen - copylen) : 0;
1104     register int i, j;
1105     register unsigned char t;
1106     unsigned int tmp;
1107 
1108     if (!_opal_crc_table_initialized) {
1109         opal_initialize_crc_table();
1110     }
1111 
1112     if (INTALIGNED(source) && INTALIGNED(destination)) {
1113         register unsigned int *  src = (unsigned int *)source;
1114         register unsigned int *  dst = (unsigned int *)destination;
1115         register unsigned char *ts, *td;
1116         /* copy whole integers */
1117         while (copylen >= sizeof(unsigned int)) {
1118             tmp = *src++;
1119             *dst++ = tmp;
1120             ts = (unsigned char *)&tmp;
1121             for (j = 0; j < (int)sizeof(unsigned int); j++) {
1122                 i = ((partial_crc >> 24) ^ *ts++) & 0xff;
1123                 partial_crc = (partial_crc << 8) ^ _opal_crc_table[i];
1124             }
1125             copylen -= sizeof(unsigned int);
1126         }
1127         ts = (unsigned char *)src;
1128         td = (unsigned char *)dst;
1129         /* copy partial integer */
1130         while (copylen--) {
1131             t = *ts++;
1132             *td++ = t;
1133             i = ((partial_crc >> 24) ^ t) & 0xff;
1134             partial_crc = (partial_crc << 8) ^ _opal_crc_table[i];
1135         }
1136         /* calculate CRC over remaining bytes... */
1137         while (crclenresidue--) {
1138             i = ((partial_crc >> 24) ^ *ts++) & 0xff;
1139             partial_crc = (partial_crc << 8) ^ _opal_crc_table[i];
1140         }
1141     }
1142     else {
1143         register unsigned char *  src = (unsigned char *)source;
1144         register unsigned char *  dst = (unsigned char *)destination;
1145         while (copylen--) {
1146             t = *src++;
1147             *dst++ = t;
1148             i = ((partial_crc >> 24) ^ t) & 0xff;
1149             partial_crc = (partial_crc << 8) ^ _opal_crc_table[i];
1150         }
1151         while (crclenresidue--) {
1152             i = ((partial_crc >> 24) ^ *src++) & 0xff;
1153             partial_crc = (partial_crc << 8) ^ _opal_crc_table[i];
1154         }
1155     }
1156 
1157     return partial_crc;
1158 }
1159 
1160 
1161 unsigned int opal_uicrc_partial(
1162     const void *  source, size_t crclen, unsigned int partial_crc)
1163 {
1164     register int i, j;
1165     register unsigned char * t;
1166     unsigned int tmp;
1167 
1168     if (!_opal_crc_table_initialized) {
1169         opal_initialize_crc_table();
1170     }
1171 
1172     if (INTALIGNED(source)) {
1173         register unsigned int *  src = (unsigned int *)source;
1174         while (crclen >= sizeof(unsigned int)) {
1175             tmp = *src++;
1176             t = (unsigned char *)&tmp;
1177             for (j = 0; j < (int)sizeof(unsigned int); j++) {
1178                 i = ((partial_crc >> 24) ^ *t++) & 0xff;
1179                 partial_crc = (partial_crc << 8) ^ _opal_crc_table[i];
1180             }
1181             crclen -= sizeof(unsigned int);
1182         }
1183         t = (unsigned char *)src;
1184         while (crclen--) {
1185             i = ((partial_crc >> 24) ^ *t++) & 0xff;
1186             partial_crc = (partial_crc << 8) ^ _opal_crc_table[i];
1187         }
1188     }
1189     else {
1190         register unsigned char *  src = (unsigned char *)source;
1191         while (crclen--) {
1192             i = ((partial_crc >> 24) ^ *src++) & 0xff;
1193             partial_crc = (partial_crc << 8) ^ _opal_crc_table[i];
1194         }
1195     }
1196 
1197     return partial_crc;
1198 }
1199 

/* [<][>][^][v][top][bottom][index][help] */