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

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

added first readtest version (does not compile)

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