source: trunk/src/lbatest/readtest.c@ 55

Last change on this file since 55 was 55, checked in by markus, 15 years ago

fixed readtest to run under OS/2 Ring3 above 2GB; commented out ADD read sector dump code

File size: 6.6 KB
Line 
1/******************************************************************************
2
3 readtest.c - simple (dumb) read test program for os2ahci
4
5 Reads each sector of a logical drive under OS/2 and verifies that the
6 sector number (LBA) written (by lbatest) in the first 4 bytes of each sector
7 matches its real LBA.
8
9 To run the test, run lbatest under Linux, then attach the drive to an OS/2
10 system an create a single primary partition that stretches the entire drive.
11 Then run readtest.exe with the drive letter as a parameter.
12
13
14 Author: Markus Thielen
15
16 Compilation (Watcom): wcl386 -bt=os2 readtest.c
17
18 Copyright (c) 2010 by thi.guten Software development, www.thiguten.de
19
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of the GNU General Public License as published by
22 the Free Software Foundation; either version 2 of the License, or
23 (at your option) any later version.
24
25 This program is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 GNU General Public License for more details.
29
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33
34******************************************************************************/
35
36/*---- includes -------------------------------------------------------------*/
37
38#define INCL_DOS
39#define INCL_ERRORS
40#define INCL_DOSDEVICES
41#define INCL_DOSDEVIOCTL
42#include <os2.h>
43#include <stdio.h>
44#include <stddef.h>
45#include <stdlib.h>
46#include <ctype.h>
47#include <string.h>
48#include <signal.h>
49
50#define SECTOR_SIZE 512
51#define SECTORS_PER_READ 200
52
53
54/*--- function prototypes ---------------------------------------------------*/
55
56void usage (void);
57
58int read_test (char *drv);
59
60void signal_handler (int sig_no);
61
62/*--- global data -----------------------------------------------------------*/
63
64unsigned long lba_pos;
65unsigned long first_wrong_sector = 0xffffffff;
66
67
68/*--- start of code ---------------------------------------------------------*/
69
70/******************************************************************************
71 * main()
72 */
73int main(int argc, char **argv)
74{
75 HFILE hf;
76 char drv[50];
77
78 if (argc < 2) {
79 usage();
80 return -1;
81 }
82
83 if (isalpha(argv[1][0])) {
84 sprintf(drv, "\\\\.\\%c", toupper(argv[1][0]));
85 } else if (isdigit(argv[1][0])) {
86 sprintf(drv, "\\\\.\\Physical_Disk%c", argv[1][0]);
87 } else {
88 usage();
89 return -1;
90 }
91
92 return read_test(drv);
93
94}
95
96/******************************************************************************
97 * read_test() - read each sector's first 4 bytes and compare to its LBA
98 */
99int read_test(char *drv)
100{
101 unsigned long ret;
102 HFILE hf_disk;
103 unsigned long action;
104 unsigned long cb_read;
105 char *buf;
106 int rc = 0;
107 unsigned long cb_take = SECTOR_SIZE * SECTORS_PER_READ;
108 unsigned long err_cnt = 0;
109 float gbf = 1024.0 * 1024.0 * 1024.0 / 512.0;
110 LONGLONG cbfile = {0};
111 int s;
112 unsigned long sectors;
113 unsigned long val;
114
115 buf = calloc(SECTOR_SIZE, SECTORS_PER_READ);
116
117 /* open drive */
118 ret = DosOpen(drv, &hf_disk, &action, 0, 0,
119 OPEN_ACTION_OPEN_IF_EXISTS,
120/* OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR | */
121/* OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_NO_CACHE | */
122/* OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYREADWRITE | */
123 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
124 NULL);
125 if (ret != NO_ERROR) {
126 fprintf(stderr, "Failed to open disk %s for reading: %d\n", drv, ret);
127 return -1;
128 }
129
130 /* lock disk */
131/* ret = DosDevIOCtl(hf_disk, IOCTL_DISK, DSK_LOCKDRIVE, NULL, 0, */
132/* &action, NULL, 0, &cb_read); */
133/* if (ret != NO_ERROR) { */
134/* fprintf(stderr, "Failed to lock drive, code %d\n", ret); */
135/* rc = -1; */
136/* goto cleanup; */
137/* } */
138
139 /* catch Ctrl+C */
140 signal(SIGINT, signal_handler);
141
142 /* go... */
143 memset(buf, 0x00, sizeof(buf));
144 for (lba_pos = 0; ; lba_pos += SECTORS_PER_READ) {
145 ret = DosRead(hf_disk, buf, cb_take, &cb_read);
146 if (ret != NO_ERROR) {
147 fprintf(stderr, "\nFailed to read from disk %s, code %d\n", drv, ret);
148 rc = -1;
149 goto cleanup;
150 }
151
152 if (cb_read == 0) {
153 goto cleanup;
154 }
155
156 sectors = cb_read / SECTOR_SIZE;
157
158 for (s = 0; s < sectors; s++) {
159
160 if (lba_pos + s < 64) {
161 continue;
162 }
163
164 val = *((unsigned long*) (buf + s * SECTOR_SIZE));
165 if (val == 0xf6f6f6f6) {
166 /* appearantly, this is the funny first partition sector
167 * created by LVM - skip it */
168 continue;
169 }
170
171 if (val != lba_pos + s) {
172 printf("\nWrong sector number: read 0x%08x from sector 0x%08x",
173 val, lba_pos + s);
174 err_cnt++;
175 if (first_wrong_sector == 0xffffffff) {
176 first_wrong_sector = lba_pos + s;
177 }
178 }
179 }
180
181 /* progress */
182 printf("\r%dk sectors read (%0.02f GB)", lba_pos / 1000,
183 (float) lba_pos / gbf);
184 }
185
186cleanup:
187 /* unlock drive */
188 DosDevIOCtl(hf_disk, IOCTL_DISK, DSK_UNLOCKDRIVE, NULL, 0, &action,
189 NULL, 0, &cb_read);
190 DosClose(hf_disk);
191 free(buf);
192
193 /* print summary */
194 printf("Found %d logical errors\n", err_cnt);
195 if (first_wrong_sector != 0xffffffff) {
196 printf("First wrong sector was %u.\n", err_cnt, first_wrong_sector);
197 }
198
199 return rc;
200}
201
202/******************************************************************************
203 * usage() - print usage summary to STDOUT
204 */
205void usage(void)
206{
207 printf("LBA (read sector number) test for os2ahci.add\n"
208 "Call with a drive letter (for logical drive) or 1-based disk number (for\n"
209 "physical drive)\n\n"
210 "Usage:\n\n"
211 "lbatest <drive letter|drive number>\n\n");
212}
213
214
215/******************************************************************************
216 * signal_handler for SIGINT - prints summary to STDOUT
217 */
218void signal_handler(int sig_no)
219{
220
221 if (sig_no == SIGINT) {
222 /* read mode interrupted; show summary */
223 printf("\n\nLast block read: 0x%08x\n", lba_pos);
224 if (first_wrong_sector != 0xffffffff) {
225 printf("First wrong sector: 0x%08x\n", first_wrong_sector);
226 } else {
227 printf("All sectors read ok\n");
228 }
229 }
230
231 exit(0);
232
233}
Note: See TracBrowser for help on using the repository browser.