Subversion Repositories freemyipod

Rev

Rev 227 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 227 Rev 249
Line 613... Line 613...
613
        if (j == 4) continue;
613
        if (j == 4) continue;
614
        ftl_vfl_cxt[bank].activecxtblock = i;
614
        ftl_vfl_cxt[bank].activecxtblock = i;
615
        ftl_vfl_cxt[bank].nextcxtpage = 0;
615
        ftl_vfl_cxt[bank].nextcxtpage = 0;
616
        if (ftl_vfl_store_cxt(bank) == 0) return 0;
616
        if (ftl_vfl_store_cxt(bank) == 0) return 0;
617
    }
617
    }
-
 
618
    ftl_initialized = false;
618
    panicf(PANIC_FATAL, "VFL: Failed to commit VFL CXT!");
619
    panicf(PANIC_KILLTHREAD, "VFL: Failed to commit VFL CXT!");
619
    return 1;
620
    return 1;
620
}
621
}
621
#endif
622
#endif
622
 
623
 
623
 
624
 
Line 727... Line 728...
727
#ifndef FTL_READONLY
728
#ifndef FTL_READONLY
728
/* Schedules remapping for the specified bank and vBlock */
729
/* Schedules remapping for the specified bank and vBlock */
729
static void ftl_vfl_schedule_block_for_remap(uint32_t bank, uint32_t block)
730
static void ftl_vfl_schedule_block_for_remap(uint32_t bank, uint32_t block)
730
{
731
{
731
    if (ftl_vfl_check_remap_scheduled(bank, block) == 1) return;
732
    if (ftl_vfl_check_remap_scheduled(bank, block) == 1) return;
-
 
733
    ftl_initialized = false;
732
    panicf(PANIC_FATAL, "FTL: Scheduling bank %u block %u for remap!",
734
    panicf(PANIC_KILLTHREAD, "FTL: Scheduling bank %u block %u for remap!",
733
           (unsigned)bank, (unsigned)block);
735
           (unsigned)bank, (unsigned)block);
734
    if (ftl_vfl_cxt[bank].scheduledstart == ftl_vfl_cxt[bank].spareused)
736
    if (ftl_vfl_cxt[bank].scheduledstart == ftl_vfl_cxt[bank].spareused)
735
        return;
737
        return;
736
    ftl_vfl_cxt[bank].remaptable[--ftl_vfl_cxt[bank].scheduledstart] = block;
738
    ftl_vfl_cxt[bank].remaptable[--ftl_vfl_cxt[bank].scheduledstart] = block;
737
    ftl_vfl_commit_cxt(bank);
739
    ftl_vfl_commit_cxt(bank);
Line 814... Line 816...
814
   if not (no more spare blocks available), it will return zero. */
816
   if not (no more spare blocks available), it will return zero. */
815
static uint32_t ftl_vfl_remap_block(uint32_t bank, uint32_t block)
817
static uint32_t ftl_vfl_remap_block(uint32_t bank, uint32_t block)
816
{
818
{
817
    uint32_t i;
819
    uint32_t i;
818
    uint32_t newblock = 0, newidx;
820
    uint32_t newblock = 0, newidx;
-
 
821
    ftl_initialized = false;
819
    panicf(PANIC_FATAL, "FTL: Remapping bank %u block %u!",
822
    panicf(PANIC_KILLTHREAD, "FTL: Remapping bank %u block %u!",
820
           (unsigned)bank, (unsigned)block);
823
           (unsigned)bank, (unsigned)block);
821
    if (bank >= ftl_banks || block >= ftl_nand_type->blocks) return 0;
824
    if (bank >= ftl_banks || block >= ftl_nand_type->blocks) return 0;
822
    for (i = 0; i < ftl_vfl_cxt[bank].sparecount; i++)
825
    for (i = 0; i < ftl_vfl_cxt[bank].sparecount; i++)
823
        if (ftl_vfl_cxt[bank].remaptable[i] == 0)
826
        if (ftl_vfl_cxt[bank].remaptable[i] == 0)
824
        {
827
        {
Line 1007... Line 1010...
1007
        if (i >= ftl_banks)
1010
        if (i >= ftl_banks)
1008
            if (nand_write_page_collect(bank[ftl_banks]))
1011
            if (nand_write_page_collect(bank[ftl_banks]))
1009
                if (nand_read_page(bank[ftl_banks], physpage[ftl_banks],
1012
                if (nand_read_page(bank[ftl_banks], physpage[ftl_banks],
1010
                                   ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F)
1013
                                   ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F)
1011
                {
1014
                {
-
 
1015
                    ftl_initialized = false;
1012
                    panicf(PANIC_FATAL, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
1016
                    panicf(PANIC_KILLTHREAD, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
1013
                           (unsigned)(vpage + i - ftl_banks),
1017
                           (unsigned)(vpage + i - ftl_banks),
1014
                           (unsigned)bank[ftl_banks],
1018
                           (unsigned)bank[ftl_banks],
1015
                           (unsigned)physpage[ftl_banks]);
1019
                           (unsigned)physpage[ftl_banks]);
1016
                    ftl_vfl_log_trouble(bank[ftl_banks], block[ftl_banks]);
1020
                    ftl_vfl_log_trouble(bank[ftl_banks], block[ftl_banks]);
1017
                }
1021
                }
Line 1019... Line 1023...
1019
                                  (void*)((uint32_t)buffer + 0x800 * i),
1023
                                  (void*)((uint32_t)buffer + 0x800 * i),
1020
                                  (void*)((uint32_t)sparebuffer + 0x40 * i), 1))
1024
                                  (void*)((uint32_t)sparebuffer + 0x40 * i), 1))
1021
            if (nand_read_page(bank[0], physpage[0], ftl_buffer,
1025
            if (nand_read_page(bank[0], physpage[0], ftl_buffer,
1022
                               &ftl_sparebuffer[0], 1, 1) & 0x11F)
1026
                               &ftl_sparebuffer[0], 1, 1) & 0x11F)
1023
            {
1027
            {
-
 
1028
                ftl_initialized = false;
1024
                panicf(PANIC_FATAL, "FTL: write error (1) on vPage %u, bank %u, pPage %u",
1029
                panicf(PANIC_KILLTHREAD, "FTL: write error (1) on vPage %u, bank %u, pPage %u",
1025
                       (unsigned)(vpage + i), (unsigned)bank[0], (unsigned)physpage[0]);
1030
                       (unsigned)(vpage + i), (unsigned)bank[0], (unsigned)physpage[0]);
1026
                ftl_vfl_log_trouble(bank[0], block[0]);
1031
                ftl_vfl_log_trouble(bank[0], block[0]);
1027
            }
1032
            }
1028
    }
1033
    }
1029
 
1034
 
1030
    for (i = count < ftl_banks ? count : ftl_banks; i > 0; i--)
1035
    for (i = count < ftl_banks ? count : ftl_banks; i > 0; i--)
1031
        if (nand_write_page_collect(bank[i - 1]))
1036
        if (nand_write_page_collect(bank[i - 1]))
1032
            if (nand_read_page(bank[i - 1], physpage[i - 1],
1037
            if (nand_read_page(bank[i - 1], physpage[i - 1],
1033
                               ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F)
1038
                               ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F)
1034
            {
1039
            {
-
 
1040
                ftl_initialized = false;
1035
                panicf(PANIC_FATAL, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
1041
                panicf(PANIC_KILLTHREAD, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
1036
                       (unsigned)(vpage + count - i),
1042
                       (unsigned)(vpage + count - i),
1037
                       (unsigned)bank[i - 1], (unsigned)physpage[i - 1]);
1043
                       (unsigned)bank[i - 1], (unsigned)physpage[i - 1]);
1038
                ftl_vfl_log_trouble(bank[i - 1], block[i - 1]);
1044
                ftl_vfl_log_trouble(bank[i - 1], block[i - 1]);
1039
            }
1045
            }
1040
 
1046
 
Line 1111... Line 1117...
1111
                            last = k;
1117
                            last = k;
1112
                        }
1118
                        }
1113
                        if (ftl_vfl_read_page(i, vflcxtblock[vflcxtidx],
1119
                        if (ftl_vfl_read_page(i, vflcxtblock[vflcxtidx],
1114
                                              last, ftl_buffer,
1120
                                              last, ftl_buffer,
1115
                                              &ftl_sparebuffer[0]) != 0)
1121
                                              &ftl_sparebuffer[0]) != 0)
-
 
1122
                        {
-
 
1123
                            ftl_initialized = false;
1116
                            panicf(PANIC_FATAL, "FTL: Re-reading VFL CXT block "
1124
                            panicf(PANIC_KILLTHREAD, "FTL: Re-reading VFL CXT block "
1117
                                        "on bank %u failed!?", (unsigned)i);
1125
                                                     "on bank %u failed!?", (unsigned)i);
1118
                            //return 1;
1126
                            //return 1;
-
 
1127
                        }
1119
                        memcpy(&ftl_vfl_cxt[i], ftl_buffer, 0x800);
1128
                        memcpy(&ftl_vfl_cxt[i], ftl_buffer, 0x800);
1120
                        if (ftl_vfl_verify_checksum(i) != 0) return 1;
1129
                        if (ftl_vfl_verify_checksum(i) != 0) return 1;
1121
#ifndef FTL_READONLY
1130
#ifndef FTL_READONLY
1122
                        if (ftl_vfl_usn < ftl_vfl_cxt[i].usn)
1131
                        if (ftl_vfl_usn < ftl_vfl_cxt[i].usn)
1123
                            ftl_vfl_usn = ftl_vfl_cxt[i].usn;
1132
                            ftl_vfl_usn = ftl_vfl_cxt[i].usn;
Line 1327... Line 1336...
1327
        return -2;
1336
        return -2;
1328
    }
1337
    }
1329
    if (count == 0) return 0;
1338
    if (count == 0) return 0;
1330
 
1339
 
1331
    mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
1340
    mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
-
 
1341
    if (!ftl_initialized)
-
 
1342
    {
-
 
1343
        mutex_unlock(&ftl_mtx);
-
 
1344
        return -1;
-
 
1345
    }
1332
 
1346
 
1333
    for (i = 0; i < count; i++)
1347
    for (i = 0; i < count; i++)
1334
    {
1348
    {
1335
        uint32_t block = (sector + i) / ppb;
1349
        uint32_t block = (sector + i) / ppb;
1336
        uint32_t page = (sector + i) % ppb;
1350
        uint32_t page = (sector + i) % ppb;
Line 1420... Line 1434...
1420
            rc = nand_block_erase(i, pblock * ftl_nand_type->pagesperblock);
1434
            rc = nand_block_erase(i, pblock * ftl_nand_type->pagesperblock);
1421
            if (rc == 0) break;
1435
            if (rc == 0) break;
1422
        }
1436
        }
1423
        if (rc != 0)
1437
        if (rc != 0)
1424
        {
1438
        {
-
 
1439
            ftl_initialized = false;
1425
            panicf(PANIC_FATAL, "FTL: Block erase failed on bank %u block %u",
1440
            panicf(PANIC_KILLTHREAD, "FTL: Block erase failed on bank %u block %u",
1426
                   (unsigned)i, (unsigned)block);
1441
                   (unsigned)i, (unsigned)block);
1427
            if (pblock != block)
1442
            if (pblock != block)
1428
            {
1443
            {
1429
                uint32_t spareindex = pblock - ftl_vfl_cxt[i].firstspare;
1444
                uint32_t spareindex = pblock - ftl_vfl_cxt[i].firstspare;
1430
                ftl_vfl_cxt[i].remaptable[spareindex] = 0xFFFF;
1445
                ftl_vfl_cxt[i].remaptable[spareindex] = 0xFFFF;
Line 1469... Line 1484...
1469
        {
1484
        {
1470
            erasectr = ftl_erasectr[ftl_cxt.blockpool[idx]];
1485
            erasectr = ftl_erasectr[ftl_cxt.blockpool[idx]];
1471
            bestidx = idx;
1486
            bestidx = idx;
1472
        }
1487
        }
1473
    }
1488
    }
-
 
1489
    if (bestidx == 0xFFFFFFFF0)
-
 
1490
    {
-
 
1491
        ftl_initialized = false;
1474
    if (bestidx == 0xFFFFFFFF) panicf(PANIC_FATAL, "FTL: Out of pool blocks!");
1492
        panicf(PANIC_KILLTHREAD, "FTL: Out of pool blocks!");
-
 
1493
    }
1475
    block = ftl_cxt.blockpool[bestidx];
1494
    block = ftl_cxt.blockpool[bestidx];
1476
    if (bestidx != ftl_cxt.nextfreeidx)
1495
    if (bestidx != ftl_cxt.nextfreeidx)
1477
    {
1496
    {
1478
        ftl_cxt.blockpool[bestidx] = ftl_cxt.blockpool[ftl_cxt.nextfreeidx];
1497
        ftl_cxt.blockpool[bestidx] = ftl_cxt.blockpool[ftl_cxt.nextfreeidx];
1479
        ftl_cxt.blockpool[ftl_cxt.nextfreeidx] = block;
1498
        ftl_cxt.blockpool[ftl_cxt.nextfreeidx] = block;
1480
    }
1499
    }
1481
    if (block > (uint32_t)ftl_nand_type->userblocks + 0x17)
1500
    if (block > (uint32_t)ftl_nand_type->userblocks + 0x17)
-
 
1501
    {
-
 
1502
        ftl_initialized = false;
1482
        panicf(PANIC_FATAL, "FTL: Bad block number in pool: %u", (unsigned)block);
1503
        panicf(PANIC_KILLTHREAD, "FTL: Bad block number in pool: %u", (unsigned)block);
-
 
1504
    }
1483
    if (ftl_erase_block(block) != 0) return 0xFFFFFFFF;
1505
    if (ftl_erase_block(block) != 0) return 0xFFFFFFFF;
1484
    if (++ftl_cxt.nextfreeidx == 0x14) ftl_cxt.nextfreeidx = 0;
1506
    if (++ftl_cxt.nextfreeidx == 0x14) ftl_cxt.nextfreeidx = 0;
1485
    ftl_cxt.freecount--;
1507
    ftl_cxt.freecount--;
1486
    return block;
1508
    return block;
1487
}
1509
}
Line 1491... Line 1513...
1491
#ifndef FTL_READONLY
1513
#ifndef FTL_READONLY
1492
/* Releases a vBlock back into the pool */
1514
/* Releases a vBlock back into the pool */
1493
static void ftl_release_pool_block(uint32_t block)
1515
static void ftl_release_pool_block(uint32_t block)
1494
{
1516
{
1495
    if (block >= (uint32_t)ftl_nand_type->userblocks + 0x17)
1517
    if (block >= (uint32_t)ftl_nand_type->userblocks + 0x17)
-
 
1518
    {
-
 
1519
        ftl_initialized = false;
1496
        panicf(PANIC_FATAL, "FTL: Tried to release block %u", (unsigned)block);
1520
        panicf(PANIC_KILLTHREAD, "FTL: Tried to release block %u", (unsigned)block);
-
 
1521
    }
1497
    uint32_t idx = ftl_cxt.nextfreeidx + ftl_cxt.freecount++;
1522
    uint32_t idx = ftl_cxt.nextfreeidx + ftl_cxt.freecount++;
1498
    if (idx >= 0x14) idx -= 0x14;
1523
    if (idx >= 0x14) idx -= 0x14;
1499
    ftl_cxt.blockpool[idx] = block;
1524
    ftl_cxt.blockpool[idx] = block;
1500
}
1525
}
1501
#endif
1526
#endif
Line 1861... Line 1886...
1861
        }
1886
        }
1862
    }
1887
    }
1863
 
1888
 
1864
    if (entry == NULL)
1889
    if (entry == NULL)
1865
    {
1890
    {
-
 
1891
        if (ftl_cxt.freecount < 3)
-
 
1892
        {
-
 
1893
            ftl_initialized = false;
1866
        if (ftl_cxt.freecount < 3) panicf(PANIC_FATAL, "FTL: Detected a pool block leak!");
1894
            panicf(PANIC_KILLTHREAD, "FTL: Detected a pool block leak!");
-
 
1895
        }
1867
        else if (ftl_cxt.freecount == 3)
1896
        else if (ftl_cxt.freecount == 3)
1868
            if (ftl_remove_scattered_block(NULL) != 0)
1897
            if (ftl_remove_scattered_block(NULL) != 0)
1869
                return NULL;
1898
                return NULL;
1870
        entry = ftl_log;
1899
        entry = ftl_log;
1871
        while (entry->scatteredvblock != 0xFFFF) entry = &entry[1];
1900
        while (entry->scatteredvblock != 0xFFFF) entry = &entry[1];
Line 1992... Line 2021...
1992
        return -2;
2021
        return -2;
1993
    }
2022
    }
1994
    if (count == 0) return 0;
2023
    if (count == 0) return 0;
1995
 
2024
 
1996
    mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
2025
    mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
-
 
2026
    if (!ftl_initialized)
-
 
2027
    {
-
 
2028
        mutex_unlock(&ftl_mtx);
-
 
2029
        return -1;
-
 
2030
    }
1997
 
2031
 
1998
    if (ftl_cxt.clean_flag == 1)
2032
    if (ftl_cxt.clean_flag == 1)
1999
    {
2033
    {
2000
        for (i = 0; i < 3; i++)
2034
        for (i = 0; i < 3; i++)
2001
        {
2035
        {
Line 2123... Line 2157...
2123
                     || logentry->pageoffsets[page + j] != page + j)
2157
                     || logentry->pageoffsets[page + j] != page + j)
2124
                        logentry->issequential = 0;
2158
                        logentry->issequential = 0;
2125
                }
2159
                }
2126
                i += cnt;
2160
                i += cnt;
2127
            }
2161
            }
-
 
2162
            else
-
 
2163
            {
-
 
2164
                ftl_initialized = false;
2128
            else panicf(PANIC_FATAL, "FTL: Write error: %u %u %u!",
2165
                panicf(PANIC_KILLTHREAD, "FTL: Write error: %u %u %u!",
2129
                        (unsigned)sector, (unsigned)count, (unsigned)i);
2166
                       (unsigned)sector, (unsigned)count, (unsigned)i);
-
 
2167
            }
2130
        }
2168
        }
2131
        if (logentry->pagesused == ppb) ftl_remove_scattered_block(logentry);
2169
        if (logentry->pagesused == ppb) ftl_remove_scattered_block(logentry);
2132
    }
2170
    }
2133
    if (ftl_cxt.swapcounter >= 300)
2171
    if (ftl_cxt.swapcounter >= 300)
2134
    {
2172
    {
Line 2164... Line 2202...
2164
    if (!ftl_initialized) return 0;
2202
    if (!ftl_initialized) return 0;
2165
 
2203
 
2166
    if (ftl_cxt.clean_flag == 1) return 0;
2204
    if (ftl_cxt.clean_flag == 1) return 0;
2167
 
2205
 
2168
    mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
2206
    mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
-
 
2207
    if (!ftl_initialized)
-
 
2208
    {
-
 
2209
        mutex_unlock(&ftl_mtx);
-
 
2210
        return -1;
-
 
2211
    }
2169
    
2212
    
2170
#ifdef FTL_TRACE
2213
#ifdef FTL_TRACE
2171
    DEBUGF("FTL: Syncing");
2214
    DEBUGF("FTL: Syncing");
2172
#endif
2215
#endif
2173
 
2216
 
Line 2541... Line 2584...
2541
    if (ftl_initialized) return 0;
2584
    if (ftl_initialized) return 0;
2542
    mutex_init(&ftl_mtx);
2585
    mutex_init(&ftl_mtx);
2543
    uint32_t i;
2586
    uint32_t i;
2544
    int rc;
2587
    int rc;
2545
    if ((rc = nand_device_init()) != 0)
2588
    if ((rc = nand_device_init()) != 0)
2546
        panicf(PANIC_FATAL, "FTL: Lowlevel NAND driver init failed: %d", rc);
2589
        panicf(PANIC_KILLTHREAD, "FTL: Lowlevel NAND driver init failed: %d", rc);
2547
    ftl_banks = 0;
2590
    ftl_banks = 0;
2548
    for (i = 0; i < 4; i++)
2591
    for (i = 0; i < 4; i++)
2549
        if (nand_get_device_type(i) != 0) ftl_banks = i + 1;
2592
        if (nand_get_device_type(i) != 0) ftl_banks = i + 1;
2550
    ftl_nand_type = nand_get_device_type(0);
2593
    ftl_nand_type = nand_get_device_type(0);
2551
 
2594
 
Line 2559... Line 2602...
2559
        if (ftl_open() == 0)
2602
        if (ftl_open() == 0)
2560
        {
2603
        {
2561
            ftl_initialized = true;
2604
            ftl_initialized = true;
2562
            return 0;
2605
            return 0;
2563
        }
2606
        }
2564
        cputs(CONSOLE_BOOT, "The FTL seems to be damaged. Forcing check.\n");
2607
        cputs(CONSOLE_BOOT, "The FTL seems to be unclean. Forcing check.\n");
2565
        if (ftl_repair() != 0)
2608
        if (ftl_repair() != 0)
2566
            cputs(CONSOLE_BOOT, "FTL recovery failed. Use disk mode to recover.\n");
2609
            cputs(CONSOLE_BOOT, "FTL recovery failed. Use disk mode to recover.\n");
2567
        else
2610
        else
2568
        {
2611
        {
2569
            cputs(CONSOLE_BOOT, "FTL recovery finished. Trying to mount again...\n");
2612
            cputs(CONSOLE_BOOT, "FTL recovery finished. Trying to mount again...\n");