2 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 int verbose; /* print lots of debugging info */
23 void usage(char *progname);
24 void writeblks(int fd, long filesize, int blocksize,
25 int interleave, int base, int rev);
26 int readblks(int fd, long filesize, int blocksize,
27 int interleave, int count);
32 fprintf(stderr, "usage: %s [-l filesize] [-b blocksize] [-i interleave]\n"
33 "\t\t[-c count] [-r(everse)] [-v(erbose)] filename\n",
39 main(int argc, char *argv[])
41 int interleave, blocksize, count, rev, i, ch, fd;
43 char *filename = NULL;
48 count = interleave = 4;
50 while ((ch = getopt(argc, argv, "b:l:i:c:rv")) != EOF) {
52 case 'b': blocksize = atoi(optarg); break;
53 case 'c': count = atoi(optarg); break;
54 case 'i': interleave = atoi(optarg); break;
55 case 'l': filesize = atol(optarg); break;
56 case 'v': verbose++; break;
57 case 'r': rev++; break;
58 default: usage(argv[0]); break;
62 filename = argv[optind];
65 if ((filesize % (blocksize*interleave)) != 0) {
66 filesize -= filesize % (blocksize * interleave);
67 printf("filesize not a multiple of blocksize*interleave,\n");
68 printf("reducing filesize to %ld\n", filesize);
70 if (count > interleave) {
72 printf("count of passes is too large, setting to %d\n", count);
73 } else if (count < 1) {
75 printf("count of passes is too small, setting to %d\n", count);
78 if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) {
82 for (i = 0; i < count; i++) {
83 writeblks(fd, filesize, blocksize, interleave, i, rev);
85 errs=readblks(fd, filesize, blocksize, interleave, count);
91 printf("%d errors detected during readback\n", errs);
98 writeblks(int fd, long filesize, int blocksize, int interleave, int base, int rev)
103 if ((buffer = calloc(1, blocksize)) == NULL) {
109 offset = (filesize-blocksize) - (base * blocksize);
111 offset = base * blocksize;
114 if (lseek(fd, offset, SEEK_SET) < 0) {
118 *(long *)buffer = *(long *)(buffer+256) = offset;
119 if (write(fd, buffer, blocksize) < blocksize) {
124 printf("writing data at offset=%ld, delta=%d, value 0x%lx and 0x%lx\n",
125 offset-base*blocksize, base,
127 *(long *)(buffer+256));
131 offset -= interleave*blocksize;
135 offset += interleave*blocksize;
136 if (offset >= filesize)
142 /* pad file out to full length */
144 if (lseek(fd, filesize-1, SEEK_SET)<0) {
148 if (write(fd, zero, 1)!=1) {
158 readblks(int fd, long filesize, int blocksize, int interleave, int count)
165 if ((buffer = calloc(interleave, blocksize)) == NULL) {
169 xfer = interleave * blocksize;
171 if (lseek(fd, (long)0, SEEK_SET) < 0) {
175 for (offset = 0; offset < filesize; offset += xfer) {
176 if ((i = read(fd, buffer, xfer) < xfer)) {
181 printf("short read: %d of %d bytes read\n", i, xfer);
185 for (tmp = buffer, i = 0; i < count; i++, tmp += blocksize) {
186 if ( (*(long *)tmp != (offset+i*blocksize)) ||
187 (*(long *)(tmp+256) != (offset+i*blocksize)) ) {
188 printf("mismatched data at offset=%ld, delta=%d, expected 0x%lx, got 0x%lx and 0x%lx\n",