summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c')
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c163
1 files changed, 85 insertions, 78 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c
index 2c11ab5340..0ce268ac30 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c
@@ -83,7 +83,7 @@ struct ftl_log_type
83 83
84 /* Pages that are still up to date in this block, i.e. need to be 84 /* Pages that are still up to date in this block, i.e. need to be
85 moved when this vBlock is deallocated. */ 85 moved when this vBlock is deallocated. */
86 uint16_t pagescurrent; 86 uint16_t pagescurrent;
87 87
88 /* A flag whether all pages are still sequential in this block. 88 /* A flag whether all pages are still sequential in this block.
89 Initialized to 1 on allocation, zeroed as soon as anything is 89 Initialized to 1 on allocation, zeroed as soon as anything is
@@ -112,9 +112,9 @@ struct ftl_cxt_type
112 112
113 /* Count of currently free pages in the block pool */ 113 /* Count of currently free pages in the block pool */
114 uint16_t freecount; 114 uint16_t freecount;
115 115
116 /* Index to the first free block in the blockpool ring buffer */ 116 /* Index to the first free block in the blockpool ring buffer */
117 uint16_t nextfreeidx; 117 uint16_t nextfreeidx;
118 118
119 /* This is a counter that is used to better distribute block 119 /* This is a counter that is used to better distribute block
120 wear. It is incremented on every block erase, and if it 120 wear. It is incremented on every block erase, and if it
@@ -129,7 +129,7 @@ struct ftl_cxt_type
129 uint16_t blockpool[0x14]; 129 uint16_t blockpool[0x14];
130 130
131 /* Alignment to 32 bits */ 131 /* Alignment to 32 bits */
132 uint16_t field_36; 132 uint16_t field_36;
133 133
134 /* vPages where the block map is stored */ 134 /* vPages where the block map is stored */
135 uint32_t ftl_map_pages[8]; 135 uint32_t ftl_map_pages[8];
@@ -138,23 +138,23 @@ struct ftl_cxt_type
138 uint8_t field_58[0x28]; 138 uint8_t field_58[0x28];
139 139
140 /* vPages where the erase counters are stored */ 140 /* vPages where the erase counters are stored */
141 uint32_t ftl_erasectr_pages[8]; 141 uint32_t ftl_erasectr_pages[8];
142 142
143 /* Seems to be padding */ 143 /* Seems to be padding */
144 uint8_t field_A0[0x70]; 144 uint8_t field_A0[0x70];
145 145
146 /* Pointer to ftl_map used by Whimory, not used by us */ 146 /* Pointer to ftl_map used by Whimory, not used by us */
147 uint32_t ftl_map_ptr; 147 uint32_t ftl_map_ptr;
148 148
149 /* Pointer to ftl_erasectr used by Whimory, not used by us */ 149 /* Pointer to ftl_erasectr used by Whimory, not used by us */
150 uint32_t ftl_erasectr_ptr; 150 uint32_t ftl_erasectr_ptr;
151 151
152 /* Pointer to ftl_log used by Whimory, not used by us */ 152 /* Pointer to ftl_log used by Whimory, not used by us */
153 uint32_t ftl_log_ptr; 153 uint32_t ftl_log_ptr;
154 154
155 /* Flag used to indicate that some erase counter pages should be committed 155 /* Flag used to indicate that some erase counter pages should be committed
156 as they were changed more than 100 times since the last commit. */ 156 as they were changed more than 100 times since the last commit. */
157 uint32_t erasedirty; 157 uint32_t erasedirty;
158 158
159 /* Seems to be unused */ 159 /* Seems to be unused */
160 uint16_t field_120; 160 uint16_t field_120;
@@ -163,7 +163,7 @@ struct ftl_cxt_type
163 counter pages. This is also a ring buffer, and the oldest 163 counter pages. This is also a ring buffer, and the oldest
164 page gets swapped with the least used page from the block 164 page gets swapped with the least used page from the block
165 pool ring buffer when a new one is allocated. */ 165 pool ring buffer when a new one is allocated. */
166 uint16_t ftlctrlblocks[3]; 166 uint16_t ftlctrlblocks[3];
167 167
168 /* The last used vPage number from ftlctrlblocks */ 168 /* The last used vPage number from ftlctrlblocks */
169 uint32_t ftlctrlpage; 169 uint32_t ftlctrlpage;
@@ -173,7 +173,7 @@ struct ftl_cxt_type
173 uint32_t clean_flag; 173 uint32_t clean_flag;
174 174
175 /* Seems to be unused, but gets loaded from flash by Whimory. */ 175 /* Seems to be unused, but gets loaded from flash by Whimory. */
176 uint8_t field_130[0x15C]; 176 uint8_t field_130[0x15C];
177 177
178} __attribute__((packed)) FTLCxtType; 178} __attribute__((packed)) FTLCxtType;
179 179
@@ -185,7 +185,7 @@ typedef struct ftl_vfl_cxt_type
185 185
186 /* Cross-bank update sequence number, incremented on every VFL 186 /* Cross-bank update sequence number, incremented on every VFL
187 context commit on any bank. */ 187 context commit on any bank. */
188 uint32_t usn; 188 uint32_t usn;
189 189
190 /* See ftl_cxt.ftlctrlblocks. This is stored to the VFL contexts 190 /* See ftl_cxt.ftlctrlblocks. This is stored to the VFL contexts
191 in order to be able to find the most recent FTL context copy 191 in order to be able to find the most recent FTL context copy
@@ -194,14 +194,14 @@ typedef struct ftl_vfl_cxt_type
194 uint16_t ftlctrlblocks[3]; 194 uint16_t ftlctrlblocks[3];
195 195
196 /* Alignment to 32 bits */ 196 /* Alignment to 32 bits */
197 uint8_t field_A[2]; 197 uint8_t field_A[2];
198 198
199 /* Decrementing update counter for VFL context commits per bank */ 199 /* Decrementing update counter for VFL context commits per bank */
200 uint32_t updatecount; 200 uint32_t updatecount;
201 201
202 /* Number of the currently active VFL context block, it's an index 202 /* Number of the currently active VFL context block, it's an index
203 into vflcxtblocks. */ 203 into vflcxtblocks. */
204 uint16_t activecxtblock; 204 uint16_t activecxtblock;
205 205
206 /* Number of the first free page in the active FTL context block */ 206 /* Number of the first free page in the active FTL context block */
207 uint16_t nextcxtpage; 207 uint16_t nextcxtpage;
@@ -217,31 +217,31 @@ typedef struct ftl_vfl_cxt_type
217 uint16_t spareused; 217 uint16_t spareused;
218 218
219 /* pBlock number of the first spare block */ 219 /* pBlock number of the first spare block */
220 uint16_t firstspare; 220 uint16_t firstspare;
221 221
222 /* Total number of spare blocks */ 222 /* Total number of spare blocks */
223 uint16_t sparecount; 223 uint16_t sparecount;
224 224
225 /* Block remap table. Contains the vBlock number the n-th spare 225 /* Block remap table. Contains the vBlock number the n-th spare
226 block is used as a replacement for. 0 = unused, 0xFFFF = bad. */ 226 block is used as a replacement for. 0 = unused, 0xFFFF = bad. */
227 uint16_t remaptable[0x334]; 227 uint16_t remaptable[0x334];
228 228
229 /* Bad block table. Each bit represents 8 blocks. 1 = OK, 0 = Bad. 229 /* Bad block table. Each bit represents 8 blocks. 1 = OK, 0 = Bad.
230 If the entry is zero, you should look at the remap table to see 230 If the entry is zero, you should look at the remap table to see
231 if the block is remapped, and if yes, where the replacement is. */ 231 if the block is remapped, and if yes, where the replacement is. */
232 uint8_t bbt[0x11A]; 232 uint8_t bbt[0x11A];
233 233
234 /* pBlock numbers used to store the VFL context. This is a ring 234 /* pBlock numbers used to store the VFL context. This is a ring
235 buffer. On a VFL context write, always 8 pages are written, 235 buffer. On a VFL context write, always 8 pages are written,
236 and it passes if at least 4 of them can be read back. */ 236 and it passes if at least 4 of them can be read back. */
237 uint16_t vflcxtblocks[4]; 237 uint16_t vflcxtblocks[4];
238 238
239 /* Blocks scheduled for remapping are stored at the end of the 239 /* Blocks scheduled for remapping are stored at the end of the
240 remap table. This is the first index used for them. */ 240 remap table. This is the first index used for them. */
241 uint16_t scheduledstart; 241 uint16_t scheduledstart;
242 242
243 /* Probably padding */ 243 /* Probably padding */
244 uint8_t field_7AC[0x4C]; 244 uint8_t field_7AC[0x4C];
245 245
246 /* First checksum (addition) */ 246 /* First checksum (addition) */
247 uint32_t checksum1; 247 uint32_t checksum1;
@@ -265,17 +265,17 @@ union ftl_spare_data_type
265 265
266 /* The update sequence number of that page, 266 /* The update sequence number of that page,
267 copied from ftl_cxt.nextblockusn on write */ 267 copied from ftl_cxt.nextblockusn on write */
268 uint32_t usn; 268 uint32_t usn;
269 269
270 /* Seems to be unused */ 270 /* Seems to be unused */
271 uint8_t field_8; 271 uint8_t field_8;
272 272
273 /* Type field, 0x40 (data page) or 0x41 (last data page of block) */ 273 /* Type field, 0x40 (data page) or 0x41 (last data page of block) */
274 uint8_t type; 274 uint8_t type;
275 275
276 /* ECC mark, usually 0xFF. If an error occurred while reading the 276 /* ECC mark, usually 0xFF. If an error occurred while reading the
277 page during a copying operation earlier, this will be 0x55. */ 277 page during a copying operation earlier, this will be 0x55. */
278 uint8_t eccmark; 278 uint8_t eccmark;
279 279
280 /* Seems to be unused */ 280 /* Seems to be unused */
281 uint8_t field_B; 281 uint8_t field_B;
@@ -297,10 +297,10 @@ union ftl_spare_data_type
297 297
298 /* Index of the thing inside the page, 298 /* Index of the thing inside the page,
299 for example number / index of the map or erase counter page */ 299 for example number / index of the map or erase counter page */
300 uint16_t idx; 300 uint16_t idx;
301 301
302 /* Seems to be unused */ 302 /* Seems to be unused */
303 uint8_t field_6; 303 uint8_t field_6;
304 304
305 /* Seems to be unused */ 305 /* Seems to be unused */
306 uint8_t field_7; 306 uint8_t field_7;
@@ -318,7 +318,7 @@ union ftl_spare_data_type
318 318
319 /* ECC mark, usually 0xFF. If an error occurred while reading the 319 /* ECC mark, usually 0xFF. If an error occurred while reading the
320 page during a copying operation earlier, this will be 0x55. */ 320 page during a copying operation earlier, this will be 0x55. */
321 uint8_t eccmark; 321 uint8_t eccmark;
322 322
323 /* Seems to be unused */ 323 /* Seems to be unused */
324 uint8_t field_B; 324 uint8_t field_B;
@@ -339,14 +339,14 @@ struct ftl_trouble_type
339{ 339{
340 340
341 /* vBlock number of the block giving trouble */ 341 /* vBlock number of the block giving trouble */
342 uint16_t block; 342 uint16_t block;
343 343
344 /* Bank of the block giving trouble */ 344 /* Bank of the block giving trouble */
345 uint8_t bank; 345 uint8_t bank;
346 346
347 /* Error counter, incremented by 3 on error, decremented by 1 on erase, 347 /* Error counter, incremented by 3 on error, decremented by 1 on erase,
348 remaping will be done when it reaches 6. */ 348 remaping will be done when it reaches 6. */
349 uint8_t errors; 349 uint8_t errors;
350 350
351} __attribute__((packed)); 351} __attribute__((packed));
352 352
@@ -359,47 +359,57 @@ const struct nand_device_info_type* ftl_nand_type;
359uint32_t ftl_banks; 359uint32_t ftl_banks;
360 360
361/* Block map, used vor pBlock to vBlock mapping */ 361/* Block map, used vor pBlock to vBlock mapping */
362uint16_t ftl_map[0x2000]; 362uint16_t ftl_map[0x2000];
363 363
364/* VFL context for each bank */ 364/* VFL context for each bank */
365struct ftl_vfl_cxt_type ftl_vfl_cxt[4]; 365struct ftl_vfl_cxt_type ftl_vfl_cxt[4];
366 366
367/* FTL context */ 367/* FTL context */
368struct ftl_cxt_type ftl_cxt; 368struct ftl_cxt_type ftl_cxt;
369 369
370/* Temporary data buffer for internal use by the FTL */ 370/* Temporary data buffers for internal use by the FTL */
371uint8_t ftl_buffer[0x800] __attribute__((aligned(16))); 371uint8_t ftl_buffer[0x800] __attribute__((aligned(16)));
372 372
373/* Temporary spare byte buffer for internal use by the FTL */ 373/* Temporary spare byte buffer for internal use by the FTL */
374union ftl_spare_data_type ftl_sparebuffer __attribute__((aligned(16))); 374union ftl_spare_data_type ftl_sparebuffer __attribute__((aligned(16)));
375 375
376 376
377#ifndef FTL_READONLY 377#ifndef FTL_READONLY
378 378
379/* Lowlevel BBT for each bank */ 379/* Lowlevel BBT for each bank */
380uint8_t ftl_bbt[4][0x410]; 380uint8_t ftl_bbt[4][0x410];
381 381
382/* Erase countes for the vBlocks */ 382/* Erase countes for the vBlocks */
383uint16_t ftl_erasectr[0x2000]; 383uint16_t ftl_erasectr[0x2000];
384 384
385/* Used by ftl_log */ 385/* Used by ftl_log */
386uint16_t ftl_offsets[0x11][0x200]; 386uint16_t ftl_offsets[0x11][0x200];
387 387
388/* Structs keeping record of scattered page blocks */ 388/* Structs keeping record of scattered page blocks */
389struct ftl_log_type ftl_log[0x11]; 389struct ftl_log_type ftl_log[0x11];
390 390
391/* Global cross-bank update sequence number of the VFL context */ 391/* Global cross-bank update sequence number of the VFL context */
392uint32_t ftl_vfl_usn; 392uint32_t ftl_vfl_usn;
393 393
394/* Keeps track (temporarily) of troublesome blocks */ 394/* Keeps track (temporarily) of troublesome blocks */
395struct ftl_trouble_type ftl_troublelog[5]; 395struct ftl_trouble_type ftl_troublelog[5];
396 396
397/* Counts erase counter page changes, after 100 of them the affected 397/* Counts erase counter page changes, after 100 of them the affected
398 page will be committed to the flash. */ 398 page will be committed to the flash. */
399uint8_t ftl_erasectr_dirt[8]; 399uint8_t ftl_erasectr_dirt[8];
400 400
401/* Buffer needed for copying pages around while moving or committing blocks.
402 This can't be shared with ftl_buffer, because this one could be overwritten
403 during the copying operation in order to e.g. commit a CXT. */
404uint8_t ftl_copybuffer[0x800] __attribute__((aligned(16)));
405
406/* Needed to store the old scattered page offsets in order to be able to roll
407 back if something fails while compacting a scattered page block. */
408uint16_t ftl_offsets_backup[0x200] __attribute__((aligned(16)));
409
401#endif 410#endif
402 411
412
403static struct mutex ftl_mtx; 413static struct mutex ftl_mtx;
404 414
405 415
@@ -413,28 +423,28 @@ uint32_t ftl_find_devinfo(uint32_t bank)
413 - ((*ftl_nand_type).blocks / 10); 423 - ((*ftl_nand_type).blocks / 10);
414 uint32_t block, page, pagenum; 424 uint32_t block, page, pagenum;
415 for (block = (*ftl_nand_type).blocks - 1; block >= lowestBlock; block--) 425 for (block = (*ftl_nand_type).blocks - 1; block >= lowestBlock; block--)
416 { 426 {
417 page = (*ftl_nand_type).pagesperblock - 8; 427 page = (*ftl_nand_type).pagesperblock - 8;
418 for (; page < (*ftl_nand_type).pagesperblock; page++) 428 for (; page < (*ftl_nand_type).pagesperblock; page++)
419 { 429 {
420 pagenum = block * (*ftl_nand_type).pagesperblock + page; 430 pagenum = block * (*ftl_nand_type).pagesperblock + page;
421 if ((nand_read_page(bank, pagenum, ftl_buffer, 431 if ((nand_read_page(bank, pagenum, ftl_buffer,
422 &ftl_sparebuffer, 1, 0) & 0x11F) != 0) 432 &ftl_sparebuffer, 1, 0) & 0x11F) != 0)
423 continue; 433 continue;
424 if (memcmp(ftl_buffer, "DEVICEINFOSIGN\0", 0x10) == 0) 434 if (memcmp(ftl_buffer, "DEVICEINFOSIGN\0", 0x10) == 0)
425 return pagenum; 435 return pagenum;
426 } 436 }
427 } 437 }
428 return 0; 438 return 0;
429} 439}
430 440
431 441
432/* Checks if all banks have proper device info pages */ 442/* Checks if all banks have proper device info pages */
433uint32_t ftl_has_devinfo(void) 443uint32_t ftl_has_devinfo(void)
434{ 444{
435 uint32_t i; 445 uint32_t i;
436 for (i = 0; i < ftl_banks; i++) if (ftl_find_devinfo(i) == 0) return 0; 446 for (i = 0; i < ftl_banks; i++) if (ftl_find_devinfo(i) == 0) return 0;
437 return 1; 447 return 1;
438} 448}
439 449
440 450
@@ -442,33 +452,33 @@ uint32_t ftl_has_devinfo(void)
442 This is based on some cryptic disassembly and not fully understood yet. */ 452 This is based on some cryptic disassembly and not fully understood yet. */
443uint32_t ftl_load_bbt(uint32_t bank, uint8_t* bbt) 453uint32_t ftl_load_bbt(uint32_t bank, uint8_t* bbt)
444{ 454{
445 uint32_t i, j; 455 uint32_t i, j;
446 uint32_t pagebase, page = ftl_find_devinfo(bank), page2; 456 uint32_t pagebase, page = ftl_find_devinfo(bank), page2;
447 uint32_t unk1, unk2, unk3; 457 uint32_t unk1, unk2, unk3;
448 if (page == 0) return 1; 458 if (page == 0) return 1;
449 pagebase = page & ~((*ftl_nand_type).pagesperblock - 1); 459 pagebase = page & ~((*ftl_nand_type).pagesperblock - 1);
450 if ((nand_read_page(bank, page, ftl_buffer, 460 if ((nand_read_page(bank, page, ftl_buffer,
451 (uint32_t*)0, 1, 0) & 0x11F) != 0) return 1; 461 (uint32_t*)0, 1, 0) & 0x11F) != 0) return 1;
452 if (memcmp(&ftl_buffer[0x18], "BBT", 4) != 0) return 1; 462 if (memcmp(&ftl_buffer[0x18], "BBT", 4) != 0) return 1;
453 unk1 = ((uint16_t*)ftl_buffer)[0x10]; 463 unk1 = ((uint16_t*)ftl_buffer)[0x10];
454 unk2 = ((uint16_t*)ftl_buffer)[0x11]; 464 unk2 = ((uint16_t*)ftl_buffer)[0x11];
455 unk3 = ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 0xC + 10] 465 unk3 = ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 0xC + 10]
456 + ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 0xC + 11]; 466 + ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 0xC + 11];
457 for (i = 0; i < unk1; i++) 467 for (i = 0; i < unk1; i++)
458 { 468 {
459 for (j = 0; ; j++) 469 for (j = 0; ; j++)
460 { 470 {
461 page2 = unk2 + i + unk3 * j; 471 page2 = unk2 + i + unk3 * j;
462 if (page2 >= (uint32_t)((*ftl_nand_type).pagesperblock - 8)) 472 if (page2 >= (uint32_t)((*ftl_nand_type).pagesperblock - 8))
463 break; 473 break;
464 if ((nand_read_page(bank, pagebase + page2, ftl_buffer, 474 if ((nand_read_page(bank, pagebase + page2, ftl_buffer,
465 (void*)0, 1, 0) & 0x11F) == 0) 475 (void*)0, 1, 0) & 0x11F) == 0)
466 { 476 {
467 memcpy(bbt, ftl_buffer, 0x410); 477 memcpy(bbt, ftl_buffer, 0x410);
468 return 0; 478 return 0;
469 } 479 }
470 } 480 }
471 } 481 }
472 return 1; 482 return 1;
473} 483}
474 484
@@ -929,7 +939,7 @@ uint32_t ftl_vfl_open(void)
929 { 939 {
930 if (ftl_vfl_read_page(i, vflcxtblock[vflcxtidx], 940 if (ftl_vfl_read_page(i, vflcxtblock[vflcxtidx],
931 k, ftl_buffer, 941 k, ftl_buffer,
932 &ftl_sparebuffer) != 0) 942 &ftl_sparebuffer) != 0)
933 break; 943 break;
934 last = k; 944 last = k;
935 } 945 }
@@ -1306,19 +1316,18 @@ uint32_t ftl_next_ctrl_pool_page(void)
1306uint32_t ftl_copy_page(uint32_t source, uint32_t destination, 1316uint32_t ftl_copy_page(uint32_t source, uint32_t destination,
1307 uint32_t lpn, uint32_t type) 1317 uint32_t lpn, uint32_t type)
1308{ 1318{
1309 uint8_t buffer[0x800];
1310 uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks; 1319 uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks;
1311 uint32_t rc = ftl_vfl_read(source, buffer, 1320 uint32_t rc = ftl_vfl_read(source, ftl_copybuffer,
1312 &ftl_sparebuffer, 1, 1) & 0x11F; 1321 &ftl_sparebuffer, 1, 1) & 0x11F;
1313 memset(&ftl_sparebuffer, 0xFF, 0x40); 1322 memset(&ftl_sparebuffer, 0xFF, 0x40);
1314 ftl_sparebuffer.user.lpn = lpn; 1323 ftl_sparebuffer.user.lpn = lpn;
1315 ftl_sparebuffer.user.usn = ++ftl_cxt.nextblockusn; 1324 ftl_sparebuffer.user.usn = ++ftl_cxt.nextblockusn;
1316 ftl_sparebuffer.user.type = 0x40; 1325 ftl_sparebuffer.user.type = 0x40;
1317 if ((rc & 2) != 0) memset(buffer, 0, 0x800); 1326 if ((rc & 2) != 0) memset(ftl_copybuffer, 0, 0x800);
1318 else if (rc != 0) ftl_sparebuffer.user.eccmark = 0x55; 1327 else if (rc != 0) ftl_sparebuffer.user.eccmark = 0x55;
1319 if (type == 1 && destination % ppb == ppb - 1) 1328 if (type == 1 && destination % ppb == ppb - 1)
1320 ftl_sparebuffer.user.type = 0x41; 1329 ftl_sparebuffer.user.type = 0x41;
1321 return ftl_vfl_write(destination, buffer, &ftl_sparebuffer); 1330 return ftl_vfl_write(destination, ftl_copybuffer, &ftl_sparebuffer);
1322} 1331}
1323#endif 1332#endif
1324 1333
@@ -1330,11 +1339,10 @@ uint32_t ftl_copy_block(uint32_t source, uint32_t destination)
1330 uint32_t i; 1339 uint32_t i;
1331 uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks; 1340 uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks;
1332 uint32_t error = 0; 1341 uint32_t error = 0;
1333 uint8_t buffer[0x800];
1334 ftl_cxt.nextblockusn++; 1342 ftl_cxt.nextblockusn++;
1335 for (i = 0; i < ppb; i++) 1343 for (i = 0; i < ppb; i++)
1336 { 1344 {
1337 uint32_t rc = ftl_read(source * ppb + i, 1, buffer); 1345 uint32_t rc = ftl_read(source * ppb + i, 1, ftl_copybuffer);
1338 memset(&ftl_sparebuffer, 0xFF, 0x40); 1346 memset(&ftl_sparebuffer, 0xFF, 0x40);
1339 ftl_sparebuffer.user.lpn = source * ppb + i; 1347 ftl_sparebuffer.user.lpn = source * ppb + i;
1340 ftl_sparebuffer.user.usn = ftl_cxt.nextblockusn; 1348 ftl_sparebuffer.user.usn = ftl_cxt.nextblockusn;
@@ -1342,7 +1350,7 @@ uint32_t ftl_copy_block(uint32_t source, uint32_t destination)
1342 if (rc != 0) ftl_sparebuffer.user.eccmark = 0x55; 1350 if (rc != 0) ftl_sparebuffer.user.eccmark = 0x55;
1343 if (i == ppb - 1) ftl_sparebuffer.user.type = 0x41; 1351 if (i == ppb - 1) ftl_sparebuffer.user.type = 0x41;
1344 if (ftl_vfl_write(destination * ppb + i, 1352 if (ftl_vfl_write(destination * ppb + i,
1345 buffer, &ftl_sparebuffer) != 0) 1353 ftl_copybuffer, &ftl_sparebuffer) != 0)
1346 { 1354 {
1347 error = 1; 1355 error = 1;
1348 break; 1356 break;
@@ -1383,7 +1391,6 @@ uint32_t ftl_compact_scattered(struct ftl_log_type* entry)
1383 uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks; 1391 uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks;
1384 uint32_t error; 1392 uint32_t error;
1385 struct ftl_log_type backup; 1393 struct ftl_log_type backup;
1386 uint16_t backup_pageoffsets[0x200];
1387 if ((*entry).pagescurrent == 0) 1394 if ((*entry).pagescurrent == 0)
1388 { 1395 {
1389 ftl_release_pool_block((*entry).scatteredvblock); 1396 ftl_release_pool_block((*entry).scatteredvblock);
@@ -1391,7 +1398,7 @@ uint32_t ftl_compact_scattered(struct ftl_log_type* entry)
1391 return 0; 1398 return 0;
1392 } 1399 }
1393 backup = *entry; 1400 backup = *entry;
1394 memcpy(backup_pageoffsets, (*entry).pageoffsets, 0x400); 1401 memcpy(ftl_offsets_backup, (*entry).pageoffsets, 0x400);
1395 for (i = 0; i < 4; i++) 1402 for (i = 0; i < 4; i++)
1396 { 1403 {
1397 uint32_t block = ftl_allocate_pool_block(); 1404 uint32_t block = ftl_allocate_pool_block();
@@ -1425,7 +1432,7 @@ uint32_t ftl_compact_scattered(struct ftl_log_type* entry)
1425 break; 1432 break;
1426 } 1433 }
1427 *entry = backup; 1434 *entry = backup;
1428 memcpy((*entry).pageoffsets, backup_pageoffsets, 0x400); 1435 memcpy((*entry).pageoffsets, ftl_offsets_backup, 0x400);
1429 } 1436 }
1430 return error; 1437 return error;
1431} 1438}
@@ -1850,7 +1857,7 @@ uint32_t ftl_init(void)
1850{ 1857{
1851 mutex_init(&ftl_mtx); 1858 mutex_init(&ftl_mtx);
1852 uint32_t i; 1859 uint32_t i;
1853 uint32_t result = 0; 1860 uint32_t result = 0;
1854 uint32_t foundsignature, founddevinfo, blockwiped, repaired, skip; 1861 uint32_t foundsignature, founddevinfo, blockwiped, repaired, skip;
1855 if (nand_device_init() != 0) //return 1; 1862 if (nand_device_init() != 0) //return 1;
1856 panicf("FTL: Lowlevel NAND driver init failed!"); 1863 panicf("FTL: Lowlevel NAND driver init failed!");
@@ -1874,7 +1881,7 @@ uint32_t ftl_init(void)
1874 else if ((result & 2) != 2) blockwiped = 0; 1881 else if ((result & 2) != 2) blockwiped = 0;
1875 } 1882 }
1876 1883
1877 founddevinfo = ftl_has_devinfo(); 1884 founddevinfo = ftl_has_devinfo();
1878 1885
1879 repaired = 0; 1886 repaired = 0;
1880 skip = 0; 1887 skip = 0;
@@ -1904,7 +1911,7 @@ uint32_t ftl_init(void)
1904 (However there is curently no point in this, as iLoader would already 1911 (However there is curently no point in this, as iLoader would already
1905 fail if this would be the case.) 1912 fail if this would be the case.)
1906 1913
1907 nand_block_erase(0, 0); 1914 nand_block_erase(0, 0);
1908*/ 1915*/
1909 1916
1910 1917