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