Subversion Repositories freemyipod

Rev

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

Rev 155 Rev 166
Line 480... Line 480...
480
    uint32_t pagebase, page = ftl_find_devinfo(bank), page2;
480
    uint32_t pagebase, page = ftl_find_devinfo(bank), page2;
481
    uint32_t unk1, unk2, unk3;
481
    uint32_t unk1, unk2, unk3;
482
    if (page == 0) return 1;
482
    if (page == 0) return 1;
483
    pagebase = page & ~(ftl_nand_type->pagesperblock - 1);
483
    pagebase = page & ~(ftl_nand_type->pagesperblock - 1);
484
    if ((nand_read_page(bank, page, ftl_buffer,
484
    if ((nand_read_page(bank, page, ftl_buffer,
485
                        (uint32_t*)0, 1, 0) & 0x11F) != 0) return 1;
485
                        NULL, 1, 0) & 0x11F) != 0) return 1;
486
    if (memcmp(&ftl_buffer[0x18], "BBT", 4) != 0) return 1;
486
    if (memcmp(&ftl_buffer[0x18], "BBT", 4) != 0) return 1;
487
    unk1 = ((uint16_t*)ftl_buffer)[0x10];
487
    unk1 = ((uint16_t*)ftl_buffer)[0x10];
488
    unk2 = ((uint16_t*)ftl_buffer)[0x11];
488
    unk2 = ((uint16_t*)ftl_buffer)[0x11];
489
    unk3 = ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 6 + 10]
489
    unk3 = ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 6 + 10]
490
         + ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 6 + 11];
490
         + ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 6 + 11];
Line 494... Line 494...
494
        {
494
        {
495
            page2 = unk2 + i + unk3 * j;
495
            page2 = unk2 + i + unk3 * j;
496
            if (page2 >= (uint32_t)(ftl_nand_type->pagesperblock - 8))
496
            if (page2 >= (uint32_t)(ftl_nand_type->pagesperblock - 8))
497
                break;
497
                break;
498
            if ((nand_read_page(bank, pagebase + page2, ftl_buffer,
498
            if ((nand_read_page(bank, pagebase + page2, ftl_buffer,
499
                                (void*)0, 1, 0) & 0x11F) == 0)
499
                                NULL, 1, 0) & 0x11F) == 0)
500
            {
500
            {
501
                memcpy(bbt, ftl_buffer, 0x410);
501
                memcpy(bbt, ftl_buffer, 0x410);
502
                return 0;
502
                return 0;
503
            }
503
            }
504
        }
504
        }
Line 626... Line 626...
626
   (planetbeing's "maxthing") */
626
   (planetbeing's "maxthing") */
627
static struct ftl_vfl_cxt_type* ftl_vfl_get_newest_cxt(void) INITCODE_ATTR;
627
static struct ftl_vfl_cxt_type* ftl_vfl_get_newest_cxt(void) INITCODE_ATTR;
628
static struct ftl_vfl_cxt_type* ftl_vfl_get_newest_cxt(void)
628
static struct ftl_vfl_cxt_type* ftl_vfl_get_newest_cxt(void)
629
{
629
{
630
    uint32_t i, maxusn;
630
    uint32_t i, maxusn;
631
    struct ftl_vfl_cxt_type* cxt = (struct ftl_vfl_cxt_type*)0;
631
    struct ftl_vfl_cxt_type* cxt = NULL;
632
    maxusn = 0;
632
    maxusn = 0;
633
    for (i = 0; i < ftl_banks; i++)
633
    for (i = 0; i < ftl_banks; i++)
634
        if (ftl_vfl_cxt[i].usn >= maxusn)
634
        if (ftl_vfl_cxt[i].usn >= maxusn)
635
        {
635
        {
636
            cxt = &ftl_vfl_cxt[i];
636
            cxt = &ftl_vfl_cxt[i];
Line 918... Line 918...
918
            remapped = 1;
918
            remapped = 1;
919
    if (bank || remapped)
919
    if (bank || remapped)
920
    {
920
    {
921
        for (i = 0; i < ftl_banks; i++)
921
        for (i = 0; i < ftl_banks; i++)
922
        {
922
        {
923
            void* databuf = (void*)0;
923
            void* databuf = NULL;
924
            void* sparebuf = (void*)0;
924
            void* sparebuf = NULL;
925
            if (buffer) databuf = (void*)((uint32_t)buffer + 0x800 * i);
925
            if (buffer) databuf = (void*)((uint32_t)buffer + 0x800 * i);
926
            if (sparebuffer) sparebuf = (void*)((uint32_t)sparebuffer + 0x40 * i);
926
            if (sparebuffer) sparebuf = (void*)((uint32_t)sparebuffer + 0x40 * i);
927
            uint32_t ret = ftl_vfl_read(vpage + i, databuf, sparebuf, checkempty, remaponfail);
927
            uint32_t ret = ftl_vfl_read(vpage + i, databuf, sparebuf, checkempty, remaponfail);
928
            if (ret & 1) rc |= 1 << (i << 2);
928
            if (ret & 1) rc |= 1 << (i << 2);
929
            if (ret & 2) rc |= 2 << (i << 2);
929
            if (ret & 2) rc |= 2 << (i << 2);
Line 1297... Line 1297...
1297
    for (i = 0; i < 0x11; i++)
1297
    for (i = 0; i < 0x11; i++)
1298
    {
1298
    {
1299
        if (ftl_log[i].scatteredvblock == 0xFFFF) continue;
1299
        if (ftl_log[i].scatteredvblock == 0xFFFF) continue;
1300
        if (ftl_log[i].logicalvblock == block) return &ftl_log[i];
1300
        if (ftl_log[i].logicalvblock == block) return &ftl_log[i];
1301
    }
1301
    }
1302
    return (struct ftl_log_type*)0;
1302
    return NULL;
1303
}
1303
}
1304
#endif
1304
#endif
1305
 
1305
 
1306
/* Exposed function: Read highlevel sectors */
1306
/* Exposed function: Read highlevel sectors */
1307
uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer)
1307
uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer)
Line 1336... Line 1336...
1336
        uint32_t page = (sector + i) % ppb;
1336
        uint32_t page = (sector + i) % ppb;
1337
 
1337
 
1338
        uint32_t abspage = ftl_map[block] * ppb + page;
1338
        uint32_t abspage = ftl_map[block] * ppb + page;
1339
#ifndef FTL_READONLY
1339
#ifndef FTL_READONLY
1340
        struct ftl_log_type* logentry = ftl_get_log_entry(block);
1340
        struct ftl_log_type* logentry = ftl_get_log_entry(block);
1341
        if (logentry != (struct ftl_log_type*)0)
1341
        if (logentry != NULL)
1342
        {
1342
        {
1343
#ifdef FTL_TRACE
1343
#ifdef FTL_TRACE
1344
	        DEBUGF("FTL: Block %d has a log entry", block);
1344
	        DEBUGF("FTL: Block %d has a log entry", block);
1345
#endif
1345
#endif
1346
            if (logentry->scatteredvblock != 0xFFFF
1346
            if (logentry->scatteredvblock != 0xFFFF
Line 1356... Line 1356...
1356
        }
1356
        }
1357
#endif
1357
#endif
1358
 
1358
 
1359
#ifndef FTL_READONLY
1359
#ifndef FTL_READONLY
1360
        if (count >= i + ftl_banks && !(page & (ftl_banks - 1))
1360
        if (count >= i + ftl_banks && !(page & (ftl_banks - 1))
1361
         && logentry == (struct ftl_log_type*)0)
1361
         && logentry == NULL)
1362
#else
1362
#else
1363
        if (count >= i + ftl_banks && !(page & (ftl_banks - 1)))
1363
        if (count >= i + ftl_banks && !(page & (ftl_banks - 1)))
1364
#endif
1364
#endif
1365
        {
1365
        {
1366
            uint32_t ret = ftl_vfl_read_fast(abspage, &((uint8_t*)buffer)[i << 11],
1366
            uint32_t ret = ftl_vfl_read_fast(abspage, &((uint8_t*)buffer)[i << 11],
Line 1795... Line 1795...
1795
static uint32_t ftl_remove_scattered_block(struct ftl_log_type* entry)
1795
static uint32_t ftl_remove_scattered_block(struct ftl_log_type* entry)
1796
{
1796
{
1797
    uint32_t i;
1797
    uint32_t i;
1798
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
1798
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
1799
    uint32_t age = 0xFFFFFFFF, used = 0;
1799
    uint32_t age = 0xFFFFFFFF, used = 0;
1800
    if (entry == (struct ftl_log_type*)0)
1800
    if (entry == NULL)
1801
    {
1801
    {
1802
        for (i = 0; i < 0x11; i++)
1802
        for (i = 0; i < 0x11; i++)
1803
        {
1803
        {
1804
            if (ftl_log[i].scatteredvblock == 0xFFFF) continue;
1804
            if (ftl_log[i].scatteredvblock == 0xFFFF) continue;
1805
            if (ftl_log[i].pagesused == 0 || ftl_log[i].pagescurrent == 0)
1805
            if (ftl_log[i].pagesused == 0 || ftl_log[i].pagescurrent == 0)
Line 1810... Line 1810...
1810
                age = ftl_log[i].usn;
1810
                age = ftl_log[i].usn;
1811
                used = ftl_log[i].pagescurrent;
1811
                used = ftl_log[i].pagescurrent;
1812
                entry = &ftl_log[i];
1812
                entry = &ftl_log[i];
1813
            }
1813
            }
1814
        }
1814
        }
1815
        if (entry == (struct ftl_log_type*)0) return 1;
1815
        if (entry == NULL) return 1;
1816
    }
1816
    }
1817
    else if (entry->pagescurrent < ppb / 2)
1817
    else if (entry->pagescurrent < ppb / 2)
1818
    {
1818
    {
1819
        ftl_cxt.swapcounter++;
1819
        ftl_cxt.swapcounter++;
1820
        return ftl_compact_scattered(entry);
1820
        return ftl_compact_scattered(entry);
Line 1843... Line 1843...
1843
   first making space, if neccessary. */
1843
   first making space, if neccessary. */
1844
static struct ftl_log_type* ftl_allocate_log_entry(uint32_t block)
1844
static struct ftl_log_type* ftl_allocate_log_entry(uint32_t block)
1845
{
1845
{
1846
    uint32_t i;
1846
    uint32_t i;
1847
    struct ftl_log_type* entry = ftl_get_log_entry(block);
1847
    struct ftl_log_type* entry = ftl_get_log_entry(block);
1848
    if (entry != (struct ftl_log_type*)0)
1848
    if (entry != NULL)
1849
    {
1849
    {
1850
        entry->usn = ftl_cxt.nextblockusn - 1;
1850
        entry->usn = ftl_cxt.nextblockusn - 1;
1851
        return entry;
1851
        return entry;
1852
    }
1852
    }
1853
 
1853
 
Line 1859... Line 1859...
1859
            entry = &ftl_log[i];
1859
            entry = &ftl_log[i];
1860
            break;
1860
            break;
1861
        }
1861
        }
1862
    }
1862
    }
1863
 
1863
 
1864
    if (entry == (struct ftl_log_type*)0)
1864
    if (entry == NULL)
1865
    {
1865
    {
1866
        if (ftl_cxt.freecount < 3) panicf(PANIC_FATAL, "FTL: Detected a pool block leak!");
1866
        if (ftl_cxt.freecount < 3) panicf(PANIC_FATAL, "FTL: Detected a pool block leak!");
1867
        else if (ftl_cxt.freecount == 3)
1867
        else if (ftl_cxt.freecount == 3)
1868
            if (ftl_remove_scattered_block((struct ftl_log_type*)0) != 0)
1868
            if (ftl_remove_scattered_block(NULL) != 0)
1869
                return (struct ftl_log_type*)0;
1869
                return NULL;
1870
        entry = ftl_log;
1870
        entry = ftl_log;
1871
        while (entry->scatteredvblock != 0xFFFF) entry = &entry[1];
1871
        while (entry->scatteredvblock != 0xFFFF) entry = &entry[1];
1872
        entry->scatteredvblock = ftl_allocate_pool_block();
1872
        entry->scatteredvblock = ftl_allocate_pool_block();
1873
        if (entry->scatteredvblock == 0xFFFF)
1873
        if (entry->scatteredvblock == 0xFFFF)
1874
            return (struct ftl_log_type*)0;
1874
            return NULL;
1875
    }
1875
    }
1876
 
1876
 
1877
    ftl_init_log_entry(entry);
1877
    ftl_init_log_entry(entry);
1878
    entry->logicalvblock = block;
1878
    entry->logicalvblock = block;
1879
    entry->usn = ftl_cxt.nextblockusn - 1;
1879
    entry->usn = ftl_cxt.nextblockusn - 1;
Line 1947... Line 1947...
1947
    }
1947
    }
1948
    if (maxidx == 0x14) return 0;
1948
    if (maxidx == 0x14) return 0;
1949
    for (i = 0; i < ftl_nand_type->userblocks; i++)
1949
    for (i = 0; i < ftl_nand_type->userblocks; i++)
1950
    {
1950
    {
1951
        if (ftl_erasectr[ftl_map[i]] > max) max = ftl_erasectr[ftl_map[i]];
1951
        if (ftl_erasectr[ftl_map[i]] > max) max = ftl_erasectr[ftl_map[i]];
1952
        if (ftl_get_log_entry(i) != (struct ftl_log_type*)0) continue;
1952
        if (ftl_get_log_entry(i) != NULL) continue;
1953
        if (ftl_erasectr[ftl_map[i]] < min)
1953
        if (ftl_erasectr[ftl_map[i]] < min)
1954
        {
1954
        {
1955
            minidx = i;
1955
            minidx = i;
1956
            minvb = ftl_map[i];
1956
            minvb = ftl_map[i];
1957
            min = ftl_erasectr[minidx];
1957
            min = ftl_erasectr[minidx];
Line 2026... Line 2026...
2026
    {
2026
    {
2027
        uint32_t block = (sector + i) / ppb;
2027
        uint32_t block = (sector + i) / ppb;
2028
        uint32_t page = (sector + i) % ppb;
2028
        uint32_t page = (sector + i) % ppb;
2029
 
2029
 
2030
        struct ftl_log_type* logentry = ftl_allocate_log_entry(block);
2030
        struct ftl_log_type* logentry = ftl_allocate_log_entry(block);
2031
        if (logentry == (struct ftl_log_type*)0)
2031
        if (logentry == NULL)
2032
        {
2032
        {
2033
            mutex_unlock(&ftl_mtx);
2033
            mutex_unlock(&ftl_mtx);
2034
            return -5;
2034
            return -5;
2035
        }
2035
        }
2036
        if (page == 0 && count - i >= ppb)
2036
        if (page == 0 && count - i >= ppb)
Line 2087... Line 2087...
2087
#ifdef FTL_TRACE
2087
#ifdef FTL_TRACE
2088
    			DEBUGF("FTL: Scattered block is full, committing");
2088
    			DEBUGF("FTL: Scattered block is full, committing");
2089
#endif
2089
#endif
2090
                ftl_remove_scattered_block(logentry);
2090
                ftl_remove_scattered_block(logentry);
2091
                logentry = ftl_allocate_log_entry(block);
2091
                logentry = ftl_allocate_log_entry(block);
2092
                if (logentry == (struct ftl_log_type*)0)
2092
                if (logentry == NULL)
2093
                {
2093
                {
2094
                    mutex_unlock(&ftl_mtx);
2094
                    mutex_unlock(&ftl_mtx);
2095
                    return -7;
2095
                    return -7;
2096
                }
2096
                }
2097
            }
2097
            }
Line 2530... Line 2530...
2530
    ftl_nand_type = nand_get_device_type(0);
2530
    ftl_nand_type = nand_get_device_type(0);
2531
    foundsignature = 0;
2531
    foundsignature = 0;
2532
    blockwiped = 1;
2532
    blockwiped = 1;
2533
    for (i = 0; i < ftl_nand_type->pagesperblock; i++)
2533
    for (i = 0; i < ftl_nand_type->pagesperblock; i++)
2534
    {
2534
    {
2535
        result = nand_read_page(0, i, ftl_buffer, (uint32_t*)0, 1, 1);
2535
        result = nand_read_page(0, i, ftl_buffer, NULL, 1, 1);
2536
        if ((result & 0x11F) == 0)
2536
        if ((result & 0x11F) == 0)
2537
        {
2537
        {
2538
            blockwiped = 0;
2538
            blockwiped = 0;
2539
            if (((uint32_t*)ftl_buffer)[0] != 0x41303034) continue;
2539
            if (((uint32_t*)ftl_buffer)[0] != 0x41303034) continue;
2540
            foundsignature = 1;
2540
            foundsignature = 1;