• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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