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