2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
35 int verbose; /* print lots of debugging info */
37 void usage(char *progname);
38 void writeblks(int fd, long filesize, int blocksize,
39 int interleave, int base, int rev);
40 int readblks(int fd, long filesize, int blocksize,
41 int interleave, int count);
46 fprintf(stderr, "usage: %s [-l filesize] [-b blocksize] [-i interleave]\n"
47 "\t\t[-c count] [-r(everse)] [-v(erbose)] filename\n",
53 main(int argc, char *argv[])
55 int interleave, blocksize, count, rev, i, ch, fd;
57 char *filename = NULL;
62 count = interleave = 4;
64 while ((ch = getopt(argc, argv, "b:l:i:c:rv")) != EOF) {
66 case 'b': blocksize = atoi(optarg); break;
67 case 'c': count = atoi(optarg); break;
68 case 'i': interleave = atoi(optarg); break;
69 case 'l': filesize = atol(optarg); break;
70 case 'v': verbose++; break;
71 case 'r': rev++; break;
72 default: usage(argv[0]); break;
76 filename = argv[optind];
79 if ((filesize % (blocksize*interleave)) != 0) {
80 filesize -= filesize % (blocksize * interleave);
81 printf("filesize not a multiple of blocksize*interleave,\n");
82 printf("reducing filesize to %ld\n", filesize);
84 if (count > interleave) {
86 printf("count of passes is too large, setting to %d\n", count);
87 } else if (count < 1) {
89 printf("count of passes is too small, setting to %d\n", count);
92 if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) {
96 for (i = 0; i < count; i++) {
97 writeblks(fd, filesize, blocksize, interleave, i, rev);
99 errs=readblks(fd, filesize, blocksize, interleave, count);
105 printf("%d errors detected during readback\n", errs);
112 writeblks(int fd, long filesize, int blocksize, int interleave, int base, int rev)
117 if ((buffer = calloc(1, blocksize)) == NULL) {
123 offset = (filesize-blocksize) - (base * blocksize);
125 offset = base * blocksize;
128 if (lseek(fd, offset, SEEK_SET) < 0) {
132 *(long *)buffer = *(long *)(buffer+256) = offset;
133 if (write(fd, buffer, blocksize) < blocksize) {
138 printf("writing data at offset=%ld, delta=%d, value 0x%lx and 0x%lx\n",
139 offset-base*blocksize, base,
141 *(long *)(buffer+256));
145 offset -= interleave*blocksize;
149 offset += interleave*blocksize;
150 if (offset >= filesize)
156 /* pad file out to full length */
158 if (lseek(fd, filesize-1, SEEK_SET)<0) {
162 if (write(fd, zero, 1)!=1) {
172 readblks(int fd, long filesize, int blocksize, int interleave, int count)
179 if ((buffer = calloc(interleave, blocksize)) == NULL) {
183 xfer = interleave * blocksize;
185 if (lseek(fd, (long)0, SEEK_SET) < 0) {
189 for (offset = 0; offset < filesize; offset += xfer) {
190 if ((i = read(fd, buffer, xfer) < xfer)) {
195 printf("short read: %d of %d bytes read\n", i, xfer);
199 for (tmp = buffer, i = 0; i < count; i++, tmp += blocksize) {
200 if ( (*(long *)tmp != (offset+i*blocksize)) ||
201 (*(long *)(tmp+256) != (offset+i*blocksize)) ) {
202 printf("mismatched data at offset=%ld, delta=%d, expected 0x%lx, got 0x%lx and 0x%lx\n",