• 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 static
pn(DWORD pns)14 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 < _MAX_SS + 4) {
54         printf("Insufficient work area to run 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 1 ****\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(" Data matched.\n");
149         } else {
150             printf("Failed: Read data differs from the data written.\n");
151             return 10;
152         }
153         pns++;
154 
155         printf("**** Multiple sector write test ****\n");
156         lba = 1; ns = sz_buff / sz_sect;
157         if (ns > 4) ns = 4;
158         for (n = 0, pn(pns); n < (UINT)(sz_sect * ns); n++) pbuff[n] = (BYTE)pn(0);
159         printf(" disk_write(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns);
160         dr = disk_write(pdrv, pbuff, lba, ns);
161         if (dr == RES_OK) {
162             printf(" - ok.\n");
163         } else {
164             printf(" - failed.\n");
165             return 11;
166         }
167         printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
168         dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
169         if (dr == RES_OK) {
170             printf(" - ok.\n");
171         } else {
172             printf(" - failed.\n");
173             return 12;
174         }
175         memset(pbuff, 0, sz_sect * ns);
176         printf(" disk_read(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns);
177         dr = disk_read(pdrv, pbuff, lba, ns);
178         if (dr == RES_OK) {
179             printf(" - ok.\n");
180         } else {
181             printf(" - failed.\n");
182             return 13;
183         }
184         for (n = 0, pn(pns); n < (UINT)(sz_sect * ns) && pbuff[n] == (BYTE)pn(0); n++) ;
185         if (n == (UINT)(sz_sect * ns)) {
186             printf(" Data matched.\n");
187         } else {
188             printf("Failed: Read data differs from the data written.\n");
189             return 14;
190         }
191         pns++;
192 
193         printf("**** Single sector write test (misaligned address) ****\n");
194         lba = 5;
195         for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n+3] = (BYTE)pn(0);
196         printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+3), lba);
197         dr = disk_write(pdrv, pbuff+3, lba, 1);
198         if (dr == RES_OK) {
199             printf(" - ok.\n");
200         } else {
201             printf(" - failed.\n");
202             return 15;
203         }
204         printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
205         dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
206         if (dr == RES_OK) {
207             printf(" - ok.\n");
208         } else {
209             printf(" - failed.\n");
210             return 16;
211         }
212         memset(pbuff+5, 0, sz_sect);
213         printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+5), lba);
214         dr = disk_read(pdrv, pbuff+5, lba, 1);
215         if (dr == RES_OK) {
216             printf(" - ok.\n");
217         } else {
218             printf(" - failed.\n");
219             return 17;
220         }
221         for (n = 0, pn(pns); n < sz_sect && pbuff[n+5] == (BYTE)pn(0); n++) ;
222         if (n == sz_sect) {
223             printf(" Data matched.\n");
224         } else {
225             printf("Failed: Read data differs from the data written.\n");
226             return 18;
227         }
228         pns++;
229 
230         printf("**** 4GB barrier test ****\n");
231         if (sz_drv >= 128 + 0x80000000 / (sz_sect / 2)) {
232             lba = 6; lba2 = lba + 0x80000000 / (sz_sect / 2);
233             for (n = 0, pn(pns); n < (UINT)(sz_sect * 2); n++) pbuff[n] = (BYTE)pn(0);
234             printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
235             dr = disk_write(pdrv, pbuff, lba, 1);
236             if (dr == RES_OK) {
237                 printf(" - ok.\n");
238             } else {
239                 printf(" - failed.\n");
240                 return 19;
241             }
242             printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2);
243             dr = disk_write(pdrv, pbuff+sz_sect, lba2, 1);
244             if (dr == RES_OK) {
245                 printf(" - ok.\n");
246             } else {
247                 printf(" - failed.\n");
248                 return 20;
249             }
250             printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
251             dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
252             if (dr == RES_OK) {
253             printf(" - ok.\n");
254             } else {
255                 printf(" - failed.\n");
256                 return 21;
257             }
258             memset(pbuff, 0, sz_sect * 2);
259             printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
260             dr = disk_read(pdrv, pbuff, lba, 1);
261             if (dr == RES_OK) {
262                 printf(" - ok.\n");
263             } else {
264                 printf(" - failed.\n");
265                 return 22;
266             }
267             printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2);
268             dr = disk_read(pdrv, pbuff+sz_sect, lba2, 1);
269             if (dr == RES_OK) {
270                 printf(" - ok.\n");
271             } else {
272                 printf(" - failed.\n");
273                 return 23;
274             }
275             for (n = 0, pn(pns); pbuff[n] == (BYTE)pn(0) && n < (UINT)(sz_sect * 2); n++) ;
276             if (n == (UINT)(sz_sect * 2)) {
277                 printf(" Data matched.\n");
278             } else {
279                 printf("Failed: Read data differs from the data written.\n");
280                 return 24;
281             }
282         } else {
283             printf(" Test skipped.\n");
284         }
285         pns++;
286 
287         printf("**** Test cycle %u of %u completed ****\n\n", cc, ncyc);
288     }
289 
290     return 0;
291 }
292 
293 
294 
main(int argc,char * argv[])295 int main (int argc, char* argv[])
296 {
297     int rc;
298     DWORD buff[FF_MAX_SS];  /* Working buffer (4 sector in size) */
299 
300     /* Check function/compatibility of the physical drive #0 */
301     rc = test_diskio(0, 3, buff, sizeof buff);
302 
303     if (rc) {
304         printf("Sorry the function/compatibility test failed. (rc=%d)\nFatFs will not work with this disk driver.\n", rc);
305     } else {
306         printf("Congratulations! The disk driver works well.\n");
307     }
308 
309     return rc;
310 }
311 
312