1/*
2 *  GRUB  --  GRand Unified Bootloader
3 *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
4 *
5 *  This program is free software; you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation; either version 2 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program; if not, write to the Free Software
17 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19/*
20 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
21 * Use is subject to license terms.
22 */
23
24#pragma ident	"%Z%%M%	%I%	%E% SMI"
25
26#include "fsys_zfs.h"
27
28
29void
30fletcher_2_native(const void *buf, uint64_t size, zio_cksum_t *zcp)
31{
32	const uint64_t *ip = buf;
33	const uint64_t *ipend = ip + (size / sizeof (uint64_t));
34	uint64_t a0, b0, a1, b1;
35
36	for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
37		a0 += ip[0];
38		a1 += ip[1];
39		b0 += a0;
40		b1 += a1;
41	}
42
43	ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
44}
45
46void
47fletcher_2_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)
48{
49	const uint64_t *ip = buf;
50	const uint64_t *ipend = ip + (size / sizeof (uint64_t));
51	uint64_t a0, b0, a1, b1;
52
53	for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
54		a0 += BSWAP_64(ip[0]);
55		a1 += BSWAP_64(ip[1]);
56		b0 += a0;
57		b1 += a1;
58	}
59
60	ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
61}
62
63void
64fletcher_4_native(const void *buf, uint64_t size, zio_cksum_t *zcp)
65{
66	const uint32_t *ip = buf;
67	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
68	uint64_t a, b, c, d;
69
70	for (a = b = c = d = 0; ip < ipend; ip++) {
71		a += ip[0];
72		b += a;
73		c += b;
74		d += c;
75	}
76
77	ZIO_SET_CHECKSUM(zcp, a, b, c, d);
78}
79
80void
81fletcher_4_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)
82{
83	const uint32_t *ip = buf;
84	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
85	uint64_t a, b, c, d;
86
87	for (a = b = c = d = 0; ip < ipend; ip++) {
88		a += BSWAP_32(ip[0]);
89		b += a;
90		c += b;
91		d += c;
92	}
93
94	ZIO_SET_CHECKSUM(zcp, a, b, c, d);
95}
96