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