static int checkECC(int setting, uint8_t* data, uint8_t* ecc) { int eccSize = 0; if(setting == 4) { eccSize = 15; } else if(setting == 8) { eccSize = 20; } else if(setting == 0) { eccSize = 10; } else { return ERROR_ECC; } uint8_t* dataPtr = data; uint8_t* eccPtr = ecc; int sectorsLeft = Data.sectorsPerPage; while(sectorsLeft > 0) { int toCheck; if(sectorsLeft > 4) toCheck = 4; else toCheck = sectorsLeft; if(LargePages) { // If there are more than 4 sectors in a page... int i; for(i = 0; i < toCheck; i++) { // loop through each sector that we have to check this time's ECC uint8_t* x = &eccPtr[eccSize * i]; // first byte of ECC uint8_t* y = x + eccSize - 1; // last byte of ECC while(x < y) { // swap the byte order of them uint8_t t = *y; *y = *x; *x = t; x++; y--; } } } ecc_perform(setting, toCheck, dataPtr, eccPtr); if(ecc_finish() != 0) return ERROR_ECC; dataPtr += toCheck * SECTOR_SIZE; eccPtr += toCheck * eccSize; sectorsLeft -= toCheck; } return 0; }
static int ecc_generate(int setting, int sectors, u8* sectorData, u8* eccData) { dma_addr_t sectorDMA = dma_map_single(nand_dev, sectorData, sectors * SECTOR_SIZE, DMA_BIDIRECTIONAL); dma_addr_t eccDMA = dma_map_single(nand_dev, eccData, sectors * 20, DMA_BIDIRECTIONAL); writel(1, NANDECC + NANDECC_CLEARINT); writel(((sectors - 1) & 0x3) | setting, NANDECC + NANDECC_SETUP); writel(virt_to_phys(sectorData), NANDECC + NANDECC_DATA); writel(virt_to_phys(eccData), NANDECC + NANDECC_ECC); writel(2, NANDECC + NANDECC_START); return ecc_finish(sectorDMA, eccDMA, sectors); }