1 /*----------------------------------------------------------------------/
2 / Low level disk I/O module function checker /
3 /-----------------------------------------------------------------------/
4 / WARNING: The data on the target drive will be lost!
5 */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include "ff.h" /* Declarations of sector size */
10 #include "diskio.h" /* Declarations of disk functions */
11
12
13
pn(DWORD pns)14 static DWORD pn ( /* Pseudo random number generator */
15 DWORD pns /* 0:Initialize, !0:Read */
16 )
17 {
18 static DWORD lfsr;
19 UINT n;
20
21
22 if (pns) {
23 lfsr = pns;
24 for (n = 0; n < 32; n++) pn(0);
25 }
26 if (lfsr & 1) {
27 lfsr >>= 1;
28 lfsr ^= 0x80200003;
29 } else {
30 lfsr >>= 1;
31 }
32 return lfsr;
33 }
34
35
test_diskio(BYTE pdrv,UINT ncyc,DWORD * buff,UINT sz_buff)36 int test_diskio (
37 BYTE pdrv, /* Physical drive number to be checked (all data on the drive will be lost) */
38 UINT ncyc, /* Number of test cycles */
39 DWORD* buff, /* Pointer to the working buffer */
40 UINT sz_buff /* Size of the working buffer in unit of byte */
41 )
42 {
43 UINT n, cc, ns;
44 DWORD sz_drv, lba, lba2, sz_eblk, pns = 1;
45 WORD sz_sect;
46 BYTE *pbuff = (BYTE*)buff;
47 DSTATUS ds;
48 DRESULT dr;
49
50
51 printf("test_diskio(%u, %u, 0x%08X, 0x%08X)\n", pdrv, ncyc, (UINT)buff, sz_buff);
52
53 if (sz_buff < FF_MAX_SS + 8) {
54 printf("Insufficient work area to run the program.\n");
55 return 1;
56 }
57
58 for (cc = 1; cc <= ncyc; cc++) {
59 printf("**** Test cycle %u of %u start ****\n", cc, ncyc);
60
61 printf(" disk_initalize(%u)", pdrv);
62 ds = disk_initialize(pdrv);
63 if (ds & STA_NOINIT) {
64 printf(" - failed.\n");
65 return 2;
66 } else {
67 printf(" - ok.\n");
68 }
69
70 printf("**** Get drive size ****\n");
71 printf(" disk_ioctl(%u, GET_SECTOR_COUNT, 0x%08X)", pdrv, (UINT)&sz_drv);
72 sz_drv = 0;
73 dr = disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_drv);
74 if (dr == RES_OK) {
75 printf(" - ok.\n");
76 } else {
77 printf(" - failed.\n");
78 return 3;
79 }
80 if (sz_drv < 128) {
81 printf("Failed: Insufficient drive size to test.\n");
82 return 4;
83 }
84 printf(" Number of sectors on the drive %u is %lu.\n", pdrv, sz_drv);
85
86 #if FF_MAX_SS != FF_MIN_SS
87 printf("**** Get sector size ****\n");
88 printf(" disk_ioctl(%u, GET_SECTOR_SIZE, 0x%X)", pdrv, (UINT)&sz_sect);
89 sz_sect = 0;
90 dr = disk_ioctl(pdrv, GET_SECTOR_SIZE, &sz_sect);
91 if (dr == RES_OK) {
92 printf(" - ok.\n");
93 } else {
94 printf(" - failed.\n");
95 return 5;
96 }
97 printf(" Size of sector is %u bytes.\n", sz_sect);
98 #else
99 sz_sect = FF_MAX_SS;
100 #endif
101
102 printf("**** Get block size ****\n");
103 printf(" disk_ioctl(%u, GET_BLOCK_SIZE, 0x%X)", pdrv, (UINT)&sz_eblk);
104 sz_eblk = 0;
105 dr = disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_eblk);
106 if (dr == RES_OK) {
107 printf(" - ok.\n");
108 } else {
109 printf(" - failed.\n");
110 }
111 if (dr == RES_OK || sz_eblk >= 2) {
112 printf(" Size of the erase block is %lu sectors.\n", sz_eblk);
113 } else {
114 printf(" Size of the erase block is unknown.\n");
115 }
116
117 /* Single sector write test */
118 printf("**** Single sector write test ****\n");
119 lba = 0;
120 for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n] = (BYTE)pn(0);
121 printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
122 dr = disk_write(pdrv, pbuff, lba, 1);
123 if (dr == RES_OK) {
124 printf(" - ok.\n");
125 } else {
126 printf(" - failed.\n");
127 return 6;
128 }
129 printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
130 dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
131 if (dr == RES_OK) {
132 printf(" - ok.\n");
133 } else {
134 printf(" - failed.\n");
135 return 7;
136 }
137 memset(pbuff, 0, sz_sect);
138 printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
139 dr = disk_read(pdrv, pbuff, lba, 1);
140 if (dr == RES_OK) {
141 printf(" - ok.\n");
142 } else {
143 printf(" - failed.\n");
144 return 8;
145 }
146 for (n = 0, pn(pns); n < sz_sect && pbuff[n] == (BYTE)pn(0); n++) ;
147 if (n == sz_sect) {
148 printf(" Read data matched.\n");
149 } else {
150 printf(" Read data differs from the data written.\n");
151 return 10;
152 }
153 pns++;
154
155 printf("**** Multiple sector write test ****\n");
156 lba = 5; ns = sz_buff / sz_sect;
157 if (ns > 4) ns = 4;
158 if (ns > 1) {
159 for (n = 0, pn(pns); n < (UINT)(sz_sect * ns); n++) pbuff[n] = (BYTE)pn(0);
160 printf(" disk_write(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns);
161 dr = disk_write(pdrv, pbuff, lba, ns);
162 if (dr == RES_OK) {
163 printf(" - ok.\n");
164 } else {
165 printf(" - failed.\n");
166 return 11;
167 }
168 printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
169 dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
170 if (dr == RES_OK) {
171 printf(" - ok.\n");
172 } else {
173 printf(" - failed.\n");
174 return 12;
175 }
176 memset(pbuff, 0, sz_sect * ns);
177 printf(" disk_read(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns);
178 dr = disk_read(pdrv, pbuff, lba, ns);
179 if (dr == RES_OK) {
180 printf(" - ok.\n");
181 } else {
182 printf(" - failed.\n");
183 return 13;
184 }
185 for (n = 0, pn(pns); n < (UINT)(sz_sect * ns) && pbuff[n] == (BYTE)pn(0); n++) ;
186 if (n == (UINT)(sz_sect * ns)) {
187 printf(" Read data matched.\n");
188 } else {
189 printf(" Read data differs from the data written.\n");
190 return 14;
191 }
192 } else {
193 printf(" Test skipped.\n");
194 }
195 pns++;
196
197 printf("**** Single sector write test (unaligned buffer address) ****\n");
198 lba = 5;
199 for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n+3] = (BYTE)pn(0);
200 printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+3), lba);
201 dr = disk_write(pdrv, pbuff+3, lba, 1);
202 if (dr == RES_OK) {
203 printf(" - ok.\n");
204 } else {
205 printf(" - failed.\n");
206 return 15;
207 }
208 printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
209 dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
210 if (dr == RES_OK) {
211 printf(" - ok.\n");
212 } else {
213 printf(" - failed.\n");
214 return 16;
215 }
216 memset(pbuff+5, 0, sz_sect);
217 printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+5), lba);
218 dr = disk_read(pdrv, pbuff+5, lba, 1);
219 if (dr == RES_OK) {
220 printf(" - ok.\n");
221 } else {
222 printf(" - failed.\n");
223 return 17;
224 }
225 for (n = 0, pn(pns); n < sz_sect && pbuff[n+5] == (BYTE)pn(0); n++) ;
226 if (n == sz_sect) {
227 printf(" Read data matched.\n");
228 } else {
229 printf(" Read data differs from the data written.\n");
230 return 18;
231 }
232 pns++;
233
234 printf("**** 4GB barrier test ****\n");
235 if (sz_drv >= 128 + 0x80000000 / (sz_sect / 2)) {
236 lba = 6; lba2 = lba + 0x80000000 / (sz_sect / 2);
237 for (n = 0, pn(pns); n < (UINT)(sz_sect * 2); n++) pbuff[n] = (BYTE)pn(0);
238 printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
239 dr = disk_write(pdrv, pbuff, lba, 1);
240 if (dr == RES_OK) {
241 printf(" - ok.\n");
242 } else {
243 printf(" - failed.\n");
244 return 19;
245 }
246 printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2);
247 dr = disk_write(pdrv, pbuff+sz_sect, lba2, 1);
248 if (dr == RES_OK) {
249 printf(" - ok.\n");
250 } else {
251 printf(" - failed.\n");
252 return 20;
253 }
254 printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
255 dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
256 if (dr == RES_OK) {
257 printf(" - ok.\n");
258 } else {
259 printf(" - failed.\n");
260 return 21;
261 }
262 memset(pbuff, 0, sz_sect * 2);
263 printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
264 dr = disk_read(pdrv, pbuff, lba, 1);
265 if (dr == RES_OK) {
266 printf(" - ok.\n");
267 } else {
268 printf(" - failed.\n");
269 return 22;
270 }
271 printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2);
272 dr = disk_read(pdrv, pbuff+sz_sect, lba2, 1);
273 if (dr == RES_OK) {
274 printf(" - ok.\n");
275 } else {
276 printf(" - failed.\n");
277 return 23;
278 }
279 for (n = 0, pn(pns); pbuff[n] == (BYTE)pn(0) && n < (UINT)(sz_sect * 2); n++) ;
280 if (n == (UINT)(sz_sect * 2)) {
281 printf(" Read data matched.\n");
282 } else {
283 printf(" Read data differs from the data written.\n");
284 return 24;
285 }
286 } else {
287 printf(" Test skipped.\n");
288 }
289 pns++;
290
291 printf("**** Test cycle %u of %u completed ****\n\n", cc, ncyc);
292 }
293
294 return 0;
295 }
296
297
298
main(int argc,char * argv[])299 int main (int argc, char* argv[])
300 {
301 int rc;
302 DWORD buff[FF_MAX_SS]; /* Working buffer (4 sector in size) */
303
304 /* Check function/compatibility of the physical drive #0 */
305 rc = test_diskio(0, 3, buff, sizeof buff);
306
307 if (rc) {
308 printf("Sorry the function/compatibility test failed. (rc=%d)\nFatFs will not work with this disk driver.\n", rc);
309 } else {
310 printf("Congratulations! The disk driver works well.\n");
311 }
312
313 return rc;
314 }
315
316