Subversion Repositories freemyipod

Rev

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

Rev 58 Rev 61
Line 574... Line 574...
574
#ifndef FTL_READONLY
574
#ifndef FTL_READONLY
575
/* Commits the VFL context of the specified bank to flash,
575
/* Commits the VFL context of the specified bank to flash,
576
   retries until it works or all available pages have been tried */
576
   retries until it works or all available pages have been tried */
577
uint32_t ftl_vfl_commit_cxt(uint32_t bank)
577
uint32_t ftl_vfl_commit_cxt(uint32_t bank)
578
{
578
{
579
    DEBUGF("FTL: VFL: Committing context on bank %d\n", bank);
579
    DEBUGF("FTL: VFL: Committing context on bank %d", bank);
580
    if (ftl_vfl_cxt[bank].nextcxtpage + 8 <= ftl_nand_type->pagesperblock)
580
    if (ftl_vfl_cxt[bank].nextcxtpage + 8 <= ftl_nand_type->pagesperblock)
581
        if (ftl_vfl_store_cxt(bank) == 0) return 0;
581
        if (ftl_vfl_store_cxt(bank) == 0) return 0;
582
    uint32_t current = ftl_vfl_cxt[bank].activecxtblock;
582
    uint32_t current = ftl_vfl_cxt[bank].activecxtblock;
583
    uint32_t i = current, j;
583
    uint32_t i = current, j;
584
    while (1)
584
    while (1)
Line 593... Line 593...
593
        if (j == 4) continue;
593
        if (j == 4) continue;
594
        ftl_vfl_cxt[bank].activecxtblock = i;
594
        ftl_vfl_cxt[bank].activecxtblock = i;
595
        ftl_vfl_cxt[bank].nextcxtpage = 0;
595
        ftl_vfl_cxt[bank].nextcxtpage = 0;
596
        if (ftl_vfl_store_cxt(bank) == 0) return 0;
596
        if (ftl_vfl_store_cxt(bank) == 0) return 0;
597
    }
597
    }
598
    panicf(PANIC_FATAL, "VFL: Failed to commit VFL CXT!\n");
598
    panicf(PANIC_FATAL, "VFL: Failed to commit VFL CXT!");
599
    return 1;
599
    return 1;
600
}
600
}
601
#endif
601
#endif
602
 
602
 
603
 
603
 
Line 677... Line 677...
677
    uint32_t spareindex;
677
    uint32_t spareindex;
678
    uint32_t spareused = ftl_vfl_cxt[bank].spareused;
678
    uint32_t spareused = ftl_vfl_cxt[bank].spareused;
679
    for (spareindex = 0; spareindex < spareused; spareindex++)
679
    for (spareindex = 0; spareindex < spareused; spareindex++)
680
        if (ftl_vfl_cxt[bank].remaptable[spareindex] == block)
680
        if (ftl_vfl_cxt[bank].remaptable[spareindex] == block)
681
		{
681
		{
682
            DEBUGF("FTL: VFL: Following remapped block: %d => %d\n",
682
            DEBUGF("FTL: VFL: Following remapped block: %d => %d",
683
                   block, ftl_vfl_cxt[bank].firstspare + spareindex);
683
                   block, ftl_vfl_cxt[bank].firstspare + spareindex);
684
            return ftl_vfl_cxt[bank].firstspare + spareindex;
684
            return ftl_vfl_cxt[bank].firstspare + spareindex;
685
		}
685
		}
686
    return block;
686
    return block;
687
}
687
}
Line 820... Line 820...
820
/* Reads the specified vPage, dealing with all kinds of trouble */
820
/* Reads the specified vPage, dealing with all kinds of trouble */
821
uint32_t ftl_vfl_read(uint32_t vpage, void* buffer, void* sparebuffer,
821
uint32_t ftl_vfl_read(uint32_t vpage, void* buffer, void* sparebuffer,
822
                      uint32_t checkempty, uint32_t remaponfail)
822
                      uint32_t checkempty, uint32_t remaponfail)
823
{
823
{
824
#ifdef VFL_TRACE
824
#ifdef VFL_TRACE
825
    DEBUGF("FTL: VFL: Reading page %d\n", vpage);
825
    DEBUGF("FTL: VFL: Reading page %d", vpage);
826
#endif
826
#endif
827
 
827
 
828
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
828
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
829
    uint32_t syshyperblocks = ftl_nand_type->blocks
829
    uint32_t syshyperblocks = ftl_nand_type->blocks
830
                            - ftl_nand_type->userblocks - 0x17;
830
                            - ftl_nand_type->userblocks - 0x17;
Line 852... Line 852...
852
#ifdef FTL_READONLY
852
#ifdef FTL_READONLY
853
        (void)remaponfail;
853
        (void)remaponfail;
854
#else
854
#else
855
        if (remaponfail == 1 &&(ret & 0x11D) != 0 && (ret & 2) == 0)
855
        if (remaponfail == 1 &&(ret & 0x11D) != 0 && (ret & 2) == 0)
856
        {
856
        {
857
            DEBUGF("FTL: VFL: Scheduling vBlock %d for remapping!\n", block);
857
            DEBUGF("FTL: VFL: Scheduling vBlock %d for remapping!", block);
858
            ftl_vfl_schedule_block_for_remap(bank, block);
858
            ftl_vfl_schedule_block_for_remap(bank, block);
859
        }
859
        }
860
#endif
860
#endif
861
        return ret;
861
        return ret;
862
    }
862
    }
Line 868... Line 868...
868
/* Multi-bank version of ftl_vfl_read, will read ftl_banks pages in parallel */
868
/* Multi-bank version of ftl_vfl_read, will read ftl_banks pages in parallel */
869
uint32_t ftl_vfl_read_fast(uint32_t vpage, void* buffer, void* sparebuffer,
869
uint32_t ftl_vfl_read_fast(uint32_t vpage, void* buffer, void* sparebuffer,
870
                           uint32_t checkempty, uint32_t remaponfail)
870
                           uint32_t checkempty, uint32_t remaponfail)
871
{
871
{
872
#ifdef VFL_TRACE
872
#ifdef VFL_TRACE
873
    DEBUGF("FTL: VFL: Fast reading page %d on all banks\n", vpage);
873
    DEBUGF("FTL: VFL: Fast reading page %d on all banks", vpage);
874
#endif
874
#endif
875
 
875
 
876
    uint32_t i, rc = 0;
876
    uint32_t i, rc = 0;
877
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
877
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
878
    uint32_t syshyperblocks = ftl_nand_type->blocks
878
    uint32_t syshyperblocks = ftl_nand_type->blocks
Line 945... Line 945...
945
uint32_t ftl_vfl_write(uint32_t vpage, uint32_t count,
945
uint32_t ftl_vfl_write(uint32_t vpage, uint32_t count,
946
                       void* buffer, void* sparebuffer)
946
                       void* buffer, void* sparebuffer)
947
{
947
{
948
    uint32_t i, j;
948
    uint32_t i, j;
949
#ifdef VFL_TRACE
949
#ifdef VFL_TRACE
950
    DEBUGF("FTL: VFL: Writing page %d\n", vpage);
950
    DEBUGF("FTL: VFL: Writing page %d", vpage);
951
#endif
951
#endif
952
 
952
 
953
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
953
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
954
    uint32_t syshyperblocks = ftl_nand_type->blocks
954
    uint32_t syshyperblocks = ftl_nand_type->blocks
955
                            - ftl_nand_type->userblocks - 0x17;
955
                            - ftl_nand_type->userblocks - 0x17;
Line 1137... Line 1137...
1137
    {
1137
    {
1138
        DEBUGF("FTL: Couldn't find readable FTL CXT block!");
1138
        DEBUGF("FTL: Couldn't find readable FTL CXT block!");
1139
        return 1;
1139
        return 1;
1140
    }
1140
    }
1141
 
1141
 
1142
    DEBUGF("FTL: Found FTL context block: vBlock %d\n", ftlcxtblock);
1142
    DEBUGF("FTL: Found FTL context block: vBlock %d", ftlcxtblock);
1143
    uint32_t ftlcxtfound = 0;
1143
    uint32_t ftlcxtfound = 0;
1144
    for (i = ftl_nand_type->pagesperblock * ftl_banks - 1; i > 0; i--)
1144
    for (i = ftl_nand_type->pagesperblock * ftl_banks - 1; i > 0; i--)
1145
    {
1145
    {
1146
        ret = ftl_vfl_read(ppb * ftlcxtblock + i,
1146
        ret = ftl_vfl_read(ppb * ftlcxtblock + i,
1147
                           ftl_buffer, &ftl_sparebuffer[0], 1, 0);
1147
                           ftl_buffer, &ftl_sparebuffer[0], 1, 0);
Line 1153... Line 1153...
1153
            break;
1153
            break;
1154
        }
1154
        }
1155
        else
1155
        else
1156
        {
1156
        {
1157
            /* This will trip if there was an unclean unmount before. */
1157
            /* This will trip if there was an unclean unmount before. */
1158
            DEBUGF("FTL: Unclean shutdown before!\n");
1158
            DEBUGF("FTL: Unclean shutdown before!");
1159
#ifdef FTL_FORCEMOUNT
1159
#ifdef FTL_FORCEMOUNT
1160
            DEBUGF("FTL: Forcing mount nevertheless...\n");
1160
            DEBUGF("FTL: Forcing mount nevertheless...");
1161
#else
1161
#else
1162
            break;
1162
            break;
1163
#endif
1163
#endif
1164
        }
1164
        }
1165
    }
1165
    }
Line 1168... Line 1168...
1168
	{
1168
	{
1169
        DEBUGF("FTL: Couldn't find FTL CXT page!");
1169
        DEBUGF("FTL: Couldn't find FTL CXT page!");
1170
	    return 1;
1170
	    return 1;
1171
	}
1171
	}
1172
 
1172
 
1173
    DEBUGF("FTL: Successfully read FTL context block\n");
1173
    DEBUGF("FTL: Successfully read FTL context block");
1174
    uint32_t pagestoread = ftl_nand_type->userblocks >> 10;
1174
    uint32_t pagestoread = ftl_nand_type->userblocks >> 10;
1175
    if ((ftl_nand_type->userblocks & 0x1FF) != 0) pagestoread++;
1175
    if ((ftl_nand_type->userblocks & 0x1FF) != 0) pagestoread++;
1176
 
1176
 
1177
    for (i = 0; i < pagestoread; i++)
1177
    for (i = 0; i < pagestoread; i++)
1178
    {
1178
    {
Line 1230... Line 1230...
1230
        for (j = 0; j < (*ftl_nand_type).blocks >> 3; j++)
1230
        for (j = 0; j < (*ftl_nand_type).blocks >> 3; j++)
1231
        {
1231
        {
1232
            uint8_t bbtentry = ftl_bbt[i][j];
1232
            uint8_t bbtentry = ftl_bbt[i][j];
1233
            for (k = 0; k < 8; k++) if ((bbtentry & (1 << k)) == 0) badblocks++;
1233
            for (k = 0; k < 8; k++) if ((bbtentry & (1 << k)) == 0) badblocks++;
1234
        }
1234
        }
1235
        DEBUGF("FTL: BBT for bank %d: %d bad blocks\n", i, badblocks);
1235
        DEBUGF("FTL: BBT for bank %d: %d bad blocks", i, badblocks);
1236
        badblocks = 0;
1236
        badblocks = 0;
1237
#endif
1237
#endif
1238
        for (j = 0; j < ftl_vfl_cxt[i].sparecount; j++)
1238
        for (j = 0; j < ftl_vfl_cxt[i].sparecount; j++)
1239
            if (ftl_vfl_cxt[i].remaptable[j] == 0xFFFF) badblocks++;
1239
            if (ftl_vfl_cxt[i].remaptable[j] == 0xFFFF) badblocks++;
1240
        DEBUGF("FTL: VFL: Bank %d: %d of %d spare blocks are bad\n",
1240
        DEBUGF("FTL: VFL: Bank %d: %d of %d spare blocks are bad",
1241
               i, badblocks, ftl_vfl_cxt[i].sparecount);
1241
               i, badblocks, ftl_vfl_cxt[i].sparecount);
1242
        DEBUGF("FTL: VFL: Bank %d: %d blocks remapped\n",
1242
        DEBUGF("FTL: VFL: Bank %d: %d blocks remapped",
1243
               i, ftl_vfl_cxt[i].spareused);
1243
               i, ftl_vfl_cxt[i].spareused);
1244
        DEBUGF("FTL: VFL: Bank %d: %d blocks scheduled for remapping\n",
1244
        DEBUGF("FTL: VFL: Bank %d: %d blocks scheduled for remapping",
1245
               i, 0x334 - ftl_vfl_cxt[i].scheduledstart);
1245
               i, 0x334 - ftl_vfl_cxt[i].scheduledstart);
1246
    }
1246
    }
1247
#ifndef FTL_READONLY
1247
#ifndef FTL_READONLY
1248
    uint32_t min = 0xFFFFFFFF, max = 0, total = 0;
1248
    uint32_t min = 0xFFFFFFFF, max = 0, total = 0;
1249
    for (i = 0; i < (*ftl_nand_type).userBlocks + 23; i++)
1249
    for (i = 0; i < (*ftl_nand_type).userblocks + 23; i++)
1250
    {
1250
    {
1251
        if (ftl_erasectr[i] > max) max = ftl_erasectr[i];
1251
        if (ftl_erasectr[i] > max) max = ftl_erasectr[i];
1252
        if (ftl_erasectr[i] < min) min = ftl_erasectr[i];
1252
        if (ftl_erasectr[i] < min) min = ftl_erasectr[i];
1253
        total += ftl_erasectr[i];
1253
        total += ftl_erasectr[i];
1254
    }
1254
    }
1255
    DEBUGF("FTL: Erase counters: Minimum: %d, maximum %d, average: %d, total: %d\n",
1255
    DEBUGF("FTL: Erase counters: Minimum: %d, maximum %d, average: %d, total: %d",
1256
           min, max, total / ((*ftl_nand_type).userBlocks + 23), total);
1256
           min, max, total / ((*ftl_nand_type).userblocks + 23), total);
1257
#endif
1257
#endif
1258
#endif
1258
#endif
1259
 
1259
 
1260
    return 0;
1260
    return 0;
1261
}
1261
}
Line 1282... Line 1282...
1282
    uint32_t i, j;
1282
    uint32_t i, j;
1283
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
1283
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
1284
    uint32_t error = 0;
1284
    uint32_t error = 0;
1285
 
1285
 
1286
#ifdef FTL_TRACE
1286
#ifdef FTL_TRACE
1287
    DEBUGF("FTL: Reading %d sectors starting at %d\n", count, sector);
1287
    DEBUGF("FTL: Reading %d sectors starting at %d", count, sector);
1288
#endif
1288
#endif
1289
 
1289
 
1290
    if (sector + count > ftl_nand_type->userblocks * ppb)
1290
    if (sector + count > ftl_nand_type->userblocks * ppb)
1291
    {
1291
    {
1292
        DEBUGF("FTL: Sector %d is out of range!\n", sector + count - 1);
1292
        DEBUGF("FTL: Sector %d is out of range!", sector + count - 1);
1293
        return 1;
1293
        return 1;
1294
    }
1294
    }
1295
    if (count == 0) return 0;
1295
    if (count == 0) return 0;
1296
 
1296
 
1297
    mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
1297
    mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
Line 1305... Line 1305...
1305
#ifndef FTL_READONLY
1305
#ifndef FTL_READONLY
1306
        struct ftl_log_type* logentry = ftl_get_log_entry(block);
1306
        struct ftl_log_type* logentry = ftl_get_log_entry(block);
1307
        if (logentry != (struct ftl_log_type*)0)
1307
        if (logentry != (struct ftl_log_type*)0)
1308
        {
1308
        {
1309
#ifdef FTL_TRACE
1309
#ifdef FTL_TRACE
1310
	        DEBUGF("FTL: Block %d has a log entry\n", block);
1310
	        DEBUGF("FTL: Block %d has a log entry", block);
1311
#endif
1311
#endif
1312
            if (logentry->scatteredvblock != 0xFFFF
1312
            if (logentry->scatteredvblock != 0xFFFF
1313
             && logentry->pageoffsets[page] != 0xFFFF)
1313
             && logentry->pageoffsets[page] != 0xFFFF)
1314
            {
1314
            {
1315
#ifdef FTL_TRACE
1315
#ifdef FTL_TRACE
1316
   		     DEBUGF("FTL: Found page %d at block %d, page %d\n", page,
1316
   		     DEBUGF("FTL: Found page %d at block %d, page %d", page,
1317
          		    (*logentry).scatteredvblock, (*logentry).pageoffsets[page]);
1317
          		    (*logentry).scatteredvblock, (*logentry).pageoffsets[page]);
1318
#endif
1318
#endif
1319
                abspage = logentry->scatteredvblock * ppb
1319
                abspage = logentry->scatteredvblock * ppb
1320
                        + logentry->pageoffsets[page];
1320
                        + logentry->pageoffsets[page];
1321
            }
1321
            }
Line 1334... Line 1334...
1334
            for (j = 0; j < ftl_banks; j++)
1334
            for (j = 0; j < ftl_banks; j++)
1335
                if (ret & (2 << (j << 2)))
1335
                if (ret & (2 << (j << 2)))
1336
                    memset(&((uint8_t*)buffer)[(i + j) << 11], 0, 0x800);
1336
                    memset(&((uint8_t*)buffer)[(i + j) << 11], 0, 0x800);
1337
                else if ((ret & (0xd << (j << 2))) || ftl_sparebuffer[j].user.eccmark != 0xFF)
1337
                else if ((ret & (0xd << (j << 2))) || ftl_sparebuffer[j].user.eccmark != 0xFF)
1338
                {
1338
                {
1339
		            DEBUGF("FTL: Error while reading sector %d!\n", (sector + i));
1339
		            DEBUGF("FTL: Error while reading sector %d!", (sector + i));
1340
                    error = 1;
1340
                    error = 1;
1341
                    memset(&((uint8_t*)buffer)[(i + j) << 11], 0, 0x800);
1341
                    memset(&((uint8_t*)buffer)[(i + j) << 11], 0, 0x800);
1342
                }
1342
                }
1343
            i += ftl_banks - 1;
1343
            i += ftl_banks - 1;
1344
        }
1344
        }
Line 1347... Line 1347...
1347
            uint32_t ret = ftl_vfl_read(abspage, &((uint8_t*)buffer)[i << 11],
1347
            uint32_t ret = ftl_vfl_read(abspage, &((uint8_t*)buffer)[i << 11],
1348
                                        &ftl_sparebuffer[0], 1, 1);
1348
                                        &ftl_sparebuffer[0], 1, 1);
1349
            if (ret & 2) memset(&((uint8_t*)buffer)[i << 11], 0, 0x800);
1349
            if (ret & 2) memset(&((uint8_t*)buffer)[i << 11], 0, 0x800);
1350
            else if ((ret & 0x11D) != 0 || ftl_sparebuffer[0].user.eccmark != 0xFF)
1350
            else if ((ret & 0x11D) != 0 || ftl_sparebuffer[0].user.eccmark != 0xFF)
1351
            {
1351
            {
1352
	            DEBUGF("FTL: Error while reading sector %d!\n", (sector + i));
1352
	            DEBUGF("FTL: Error while reading sector %d!", (sector + i));
1353
                error = 1;
1353
                error = 1;
1354
                memset(&((uint8_t*)buffer)[i << 11], 0, 0x800);
1354
                memset(&((uint8_t*)buffer)[i << 11], 0, 0x800);
1355
            }
1355
            }
1356
        }
1356
        }
1357
    }
1357
    }
Line 1521... Line 1521...
1521
    uint32_t oldblock = ftl_cxt.ftlctrlblocks[i];
1521
    uint32_t oldblock = ftl_cxt.ftlctrlblocks[i];
1522
    uint32_t newblock = ftl_allocate_pool_block();
1522
    uint32_t newblock = ftl_allocate_pool_block();
1523
    if (newblock == 0xFFFFFFFF) return 1;
1523
    if (newblock == 0xFFFFFFFF) return 1;
1524
    ftl_cxt.ftlctrlblocks[i] = newblock;
1524
    ftl_cxt.ftlctrlblocks[i] = newblock;
1525
    ftl_cxt.ftlctrlpage = newblock * ppb;
1525
    ftl_cxt.ftlctrlpage = newblock * ppb;
1526
    DEBUGF("Starting new FTL control block at %d\n", ftl_cxt.ftlctrlpage);
1526
    DEBUGF("Starting new FTL control block at %d", ftl_cxt.ftlctrlpage);
1527
    uint32_t pagestoread = (ftl_nand_type->userblocks + 23) >> 10;
1527
    uint32_t pagestoread = (ftl_nand_type->userblocks + 23) >> 10;
1528
    if (((ftl_nand_type->userblocks + 23) & 0x1FF) != 0) pagestoread++;
1528
    if (((ftl_nand_type->userblocks + 23) & 0x1FF) != 0) pagestoread++;
1529
    for (i = 0; i < pagestoread; i++)
1529
    for (i = 0; i < pagestoread; i++)
1530
        if (oldblock * ppb <= ftl_cxt.ftl_erasectr_pages[i]
1530
        if (oldblock * ppb <= ftl_cxt.ftl_erasectr_pages[i]
1531
         && (oldblock + 1) * ppb > ftl_cxt.ftl_erasectr_pages[i])
1531
         && (oldblock + 1) * ppb > ftl_cxt.ftl_erasectr_pages[i])
Line 1853... Line 1853...
1853
    uint32_t i;
1853
    uint32_t i;
1854
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
1854
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
1855
    uint32_t mappages = (ftl_nand_type->userblocks + 0x3ff) >> 10;
1855
    uint32_t mappages = (ftl_nand_type->userblocks + 0x3ff) >> 10;
1856
    uint32_t ctrpages = (ftl_nand_type->userblocks + 23 + 0x3ff) >> 10;
1856
    uint32_t ctrpages = (ftl_nand_type->userblocks + 23 + 0x3ff) >> 10;
1857
    uint32_t endpage = ftl_cxt.ftlctrlpage + mappages + ctrpages + 1;
1857
    uint32_t endpage = ftl_cxt.ftlctrlpage + mappages + ctrpages + 1;
1858
    DEBUGF("FTL: Committing context\n");
1858
    DEBUGF("FTL: Committing context");
1859
    if (endpage >= (ftl_cxt.ftlctrlpage / ppb + 1) * ppb)
1859
    if (endpage >= (ftl_cxt.ftlctrlpage / ppb + 1) * ppb)
1860
        ftl_cxt.ftlctrlpage |= ppb - 1;
1860
        ftl_cxt.ftlctrlpage |= ppb - 1;
1861
    for (i = 0; i < ctrpages; i++)
1861
    for (i = 0; i < ctrpages; i++)
1862
    {
1862
    {
1863
        if (ftl_next_ctrl_pool_page() != 0) return 1;
1863
        if (ftl_next_ctrl_pool_page() != 0) return 1;
Line 1880... Line 1880...
1880
    memset(&ftl_sparebuffer[0], 0xFF, 0x40);
1880
    memset(&ftl_sparebuffer[0], 0xFF, 0x40);
1881
    ftl_sparebuffer[0].meta.usn = ftl_cxt.usn;
1881
    ftl_sparebuffer[0].meta.usn = ftl_cxt.usn;
1882
    ftl_sparebuffer[0].meta.type = 0x43;
1882
    ftl_sparebuffer[0].meta.type = 0x43;
1883
    if (ftl_vfl_write(ftl_cxt.ftlctrlpage, 1, &ftl_cxt, &ftl_sparebuffer[0]) != 0)
1883
    if (ftl_vfl_write(ftl_cxt.ftlctrlpage, 1, &ftl_cxt, &ftl_sparebuffer[0]) != 0)
1884
        return 1;
1884
        return 1;
1885
    DEBUGF("FTL: Wrote context to page %d\n", ftl_cxt.ftlctrlpage);
1885
    DEBUGF("FTL: Wrote context to page %d", ftl_cxt.ftlctrlpage);
1886
    return 0;
1886
    return 0;
1887
}
1887
}
1888
#endif
1888
#endif
1889
 
1889
 
1890
 
1890
 
Line 1937... Line 1937...
1937
{
1937
{
1938
    uint32_t i, j, k;
1938
    uint32_t i, j, k;
1939
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
1939
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
1940
 
1940
 
1941
#ifdef FTL_TRACE
1941
#ifdef FTL_TRACE
1942
    DEBUGF("FTL: Writing %d sectors starting at %d\n", count, sector);
1942
    DEBUGF("FTL: Writing %d sectors starting at %d", count, sector);
1943
#endif
1943
#endif
1944
 
1944
 
1945
    if (sector + count > ftl_nand_type->userblocks * ppb)
1945
    if (sector + count > ftl_nand_type->userblocks * ppb)
1946
    {
1946
    {
1947
        DEBUGF("FTL: Sector %d is out of range!\n", sector + count - 1);
1947
        DEBUGF("FTL: Sector %d is out of range!", sector + count - 1);
1948
        return 1;
1948
        return 1;
1949
    }
1949
    }
1950
    if (count == 0) return 0;
1950
    if (count == 0) return 0;
1951
 
1951
 
1952
    mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
1952
    mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
1953
 
1953
 
1954
    if (ftl_cxt.clean_flag == 1)
1954
    if (ftl_cxt.clean_flag == 1)
1955
    {
1955
    {
1956
        for (i = 0; i < 3; i++)
1956
        for (i = 0; i < 3; i++)
1957
        {
1957
        {
1958
		    DEBUGF("FTL: Marking dirty, try %d\n", i);
1958
		    DEBUGF("FTL: Marking dirty, try %d", i);
1959
            if (ftl_next_ctrl_pool_page() != 0)
1959
            if (ftl_next_ctrl_pool_page() != 0)
1960
            {
1960
            {
1961
                mutex_unlock(&ftl_mtx);
1961
                mutex_unlock(&ftl_mtx);
1962
                return 1;
1962
                return 1;
1963
            }
1963
            }
Line 1972... Line 1972...
1972
        if (i == 3)
1972
        if (i == 3)
1973
        {
1973
        {
1974
            mutex_unlock(&ftl_mtx);
1974
            mutex_unlock(&ftl_mtx);
1975
            return 1;
1975
            return 1;
1976
        }
1976
        }
1977
    	DEBUGF("FTL: Wrote dirty mark to %d\n", ftl_cxt.ftlctrlpage);
1977
    	DEBUGF("FTL: Wrote dirty mark to %d", ftl_cxt.ftlctrlpage);
1978
        ftl_cxt.clean_flag = 0;
1978
        ftl_cxt.clean_flag = 0;
1979
    }
1979
    }
1980
 
1980
 
1981
    for (i = 0; i < count; )
1981
    for (i = 0; i < count; )
1982
    {
1982
    {
Line 1990... Line 1990...
1990
            return 1;
1990
            return 1;
1991
        }
1991
        }
1992
        if (page == 0 && count - i >= ppb)
1992
        if (page == 0 && count - i >= ppb)
1993
        {
1993
        {
1994
#ifdef FTL_TRACE
1994
#ifdef FTL_TRACE
1995
		    DEBUGF("FTL: Going to write a full hyperblock in one shot\n");
1995
		    DEBUGF("FTL: Going to write a full hyperblock in one shot");
1996
#endif
1996
#endif
1997
            uint32_t vblock = logentry->scatteredvblock;
1997
            uint32_t vblock = logentry->scatteredvblock;
1998
            logentry->scatteredvblock = 0xFFFF;
1998
            logentry->scatteredvblock = 0xFFFF;
1999
            if (logentry->pagesused != 0)
1999
            if (logentry->pagesused != 0)
2000
            {
2000
            {
2001
#ifdef FTL_TRACE
2001
#ifdef FTL_TRACE
2002
    			DEBUGF("FTL: Scattered block had some pages already used, committing\n");
2002
    			DEBUGF("FTL: Scattered block had some pages already used, committing");
2003
#endif
2003
#endif
2004
                ftl_release_pool_block(vblock);
2004
                ftl_release_pool_block(vblock);
2005
                vblock = ftl_allocate_pool_block();
2005
                vblock = ftl_allocate_pool_block();
2006
                if (vblock == 0xFFFFFFFF)
2006
                if (vblock == 0xFFFFFFFF)
2007
                {
2007
                {
Line 2039... Line 2039...
2039
        else
2039
        else
2040
        {
2040
        {
2041
            if (logentry->pagesused == ppb)
2041
            if (logentry->pagesused == ppb)
2042
            {
2042
            {
2043
#ifdef FTL_TRACE
2043
#ifdef FTL_TRACE
2044
    			DEBUGF("FTL: Scattered block is full, committing\n");
2044
    			DEBUGF("FTL: Scattered block is full, committing");
2045
#endif
2045
#endif
2046
                ftl_remove_scattered_block(logentry);
2046
                ftl_remove_scattered_block(logentry);
2047
                logentry = ftl_allocate_log_entry(block);
2047
                logentry = ftl_allocate_log_entry(block);
2048
                if (logentry == (struct ftl_log_type*)0)
2048
                if (logentry == (struct ftl_log_type*)0)
2049
                {
2049
                {
Line 2117... Line 2117...
2117
    uint32_t rc = 0;
2117
    uint32_t rc = 0;
2118
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
2118
    uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
2119
    if (ftl_cxt.clean_flag == 1) return 0;
2119
    if (ftl_cxt.clean_flag == 1) return 0;
2120
 
2120
 
2121
#ifdef FTL_TRACE
2121
#ifdef FTL_TRACE
2122
    DEBUGF("FTL: Syncing\n");
2122
    DEBUGF("FTL: Syncing");
2123
#endif
2123
#endif
2124
 
2124
 
2125
    if (ftl_cxt.swapcounter >= 20)
2125
    if (ftl_cxt.swapcounter >= 20)
2126
        for (i = 0; i < 4; i++)
2126
        for (i = 0; i < 4; i++)
2127
            if (ftl_swap_blocks() == 0)
2127
            if (ftl_swap_blocks() == 0)
Line 2163... Line 2163...
2163
{
2163
{
2164
    mutex_init(&ftl_mtx);
2164
    mutex_init(&ftl_mtx);
2165
    uint32_t i;
2165
    uint32_t i;
2166
    uint32_t result = 0;
2166
    uint32_t result = 0;
2167
    uint32_t foundsignature, founddevinfo, blockwiped, repaired, skip;
2167
    uint32_t foundsignature, founddevinfo, blockwiped, repaired, skip;
-
 
2168
    int rc;
2168
    if (nand_device_init() != 0) //return 1;
2169
    if ((rc = nand_device_init()) != 0) //return 1;
2169
        panicf(PANIC_FATAL, "FTL: Lowlevel NAND driver init failed!");
2170
        panicf(PANIC_FATAL, "FTL: Lowlevel NAND driver init failed: %d", rc);
2170
    ftl_banks = 0;
2171
    ftl_banks = 0;
2171
    for (i = 0; i < 4; i++)
2172
    for (i = 0; i < 4; i++)
2172
        if (nand_get_device_type(i) != 0) ftl_banks = i + 1;
2173
        if (nand_get_device_type(i) != 0) ftl_banks = i + 1;
2173
    ftl_nand_type = nand_get_device_type(0);
2174
    ftl_nand_type = nand_get_device_type(0);
2174
    foundsignature = 0;
2175
    foundsignature = 0;