int VFL_Init(void) { nand_setup(); NANDGeometry = nand_get_geometry(); FTLData = nand_get_ftl_data(); memset(&VFLData1, 0, sizeof(VFLData1)); if(pstVFLCxt == NULL) { pstVFLCxt = kmalloc(NANDGeometry->banksTotal * sizeof(VFLCxt), GFP_KERNEL | GFP_DMA); if(pstVFLCxt == NULL) return -1; } if(pstBBTArea == NULL) { pstBBTArea = (u8*) kmalloc((NANDGeometry->blocksPerBank + 7) / 8, GFP_KERNEL | GFP_DMA); if(pstBBTArea == NULL) return -1; } if(ScatteredPageNumberBuffer == NULL && ScatteredBankNumberBuffer == NULL) { ScatteredPageNumberBuffer = (u32*) kmalloc(NANDGeometry->pagesPerSuBlk * 4, GFP_KERNEL | GFP_DMA); ScatteredBankNumberBuffer = (u16*) kmalloc(NANDGeometry->pagesPerSuBlk * 4, GFP_KERNEL | GFP_DMA); if(ScatteredPageNumberBuffer == NULL || ScatteredBankNumberBuffer == NULL) return -1; } PageBuffer = (u8*) kmalloc(NANDGeometry->bytesPerPage, GFP_KERNEL | GFP_DMA); SpareBuffer = (u8*) kmalloc(NANDGeometry->bytesPerSpare, GFP_KERNEL | GFP_DMA); curVFLusnInc = 0; return 0; }
void cmd_nand_read_spare(int argc, char** argv) { if(argc < 4) { bufferPrintf("Usage: %s <address> <bank> <page> [pages]\r\n", argv[0]); return; } uint32_t address = parseNumber(argv[1]); uint32_t bank = parseNumber(argv[2]); uint32_t page = parseNumber(argv[3]); uint32_t pages = 1; if(argc >= 5) { pages = parseNumber(argv[4]); } bufferPrintf("reading bank %d, pages %d - %d spare into %x\r\n", bank, page, page + pages - 1, address); NANDData* Data = nand_get_geometry(); while(pages > 0) { int ret = nand_read(bank, page, NULL, (uint8_t*) address, FALSE, FALSE); if(ret != 0) bufferPrintf("nand_read: %x\r\n", ret); pages--; page++; address += Data->bytesPerSpare; } bufferPrintf("done!\r\n"); }
int bdev_setup() { if(HasBDevInit) return 0; ftl_setup(); NANDData* Data = nand_get_geometry(); BLOCK_SIZE = Data->bytesPerPage; ftl_read(&MBRData, 0, sizeof(MBRData)); MBRPartitionRecord* record = MBRData.partitions; int id = 0; while(record->type != 0) { bufferPrintf("bdev: partition id: %d, type: %x, sectors: %d - %d\r\n", id, record->type, record->beginLBA, record->beginLBA + record->numSectors); record++; id++; } HasBDevInit = TRUE; return 0; }
int ftl_setup() { if(HasFTLInit) return 0; nand_setup(); Data = nand_get_geometry(); Data2 = nand_get_data(); if(VFL_Init() != 0) { bufferPrintf("ftl: VFL_Init failed\r\n"); return -1; } if(FTL_Init() != 0) { bufferPrintf("ftl: FTL_Init failed\r\n"); return -1; } int i; int foundSignature = FALSE; DebugPrintf("ftl: Attempting to read %d pages from first block of first bank.\r\n", Data->pagesPerBlock); uint8_t* buffer = malloc(Data->bytesPerPage); for(i = 0; i < Data->pagesPerBlock; i++) { int ret; if((ret = nand_read_alternate_ecc(0, i, buffer)) == 0) { uint32_t id = *((uint32_t*) buffer); if(id == FTL_ID_V1 || id == FTL_ID_V2) { bufferPrintf("ftl: Found production format: %x\r\n", id); foundSignature = TRUE; break; } else { DebugPrintf("ftl: Found non-matching signature: %x\r\n", ((uint32_t*) buffer)); } } else { DebugPrintf("ftl: page %d of first bank is unreadable: %x!\r\n", i, ret); } } free(buffer); if(!foundSignature || !hasDeviceInfoBBT()) { bufferPrintf("ftl: no signature or production format.\r\n"); return -1; } if(VFL_Open() != 0) { bufferPrintf("ftl: VFL_Open failed\r\n"); return -1; } int pagesAvailable; int bytesPerPage; if(FTL_Open(&pagesAvailable, &bytesPerPage) != 0) { bufferPrintf("ftl: FTL_Open failed\r\n"); return -1; } HasFTLInit = TRUE; return 0; }