xref: /third_party/FatFs/documents/res/app4.c (revision e6865dcd)
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
14static 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
36int 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
299int 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