int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, u_char *buffer) { int rval; size_t left_to_write = *length; size_t len_incl_bad; u_char *p_buffer = buffer; #if defined(CONFIG_MTD_NAND_YAFFS2)//add yaffs2 file system support if(nand->rw_oob==1) { size_t oobsize = nand->oobsize; size_t datasize = nand->writesize; int datapages = 0; if (((*length)%(nand->oobsize+nand->writesize)) != 0) { printf ("Attempt to write error length data!\n"); return -EINVAL; } datapages = *length/(datasize+oobsize); *length = datapages*datasize; left_to_write = *length; } #endif if ((offset & (nand->writesize - 1)) != 0 || (*length & (nand->writesize - 1)) != 0) { printf ("Attempt to write non page aligned data\n"); return -EINVAL; }
len_incl_bad = get_len_incl_bad (nand, offset, *length); if ((offset + len_incl_bad) >= nand->size) { printf ("Attempt to write outside the flash area\n"); return -EINVAL; } #if !defined(CONFIG_MTD_NAND_YAFFS2)//add yaffs2 file system support if (len_incl_bad == *length) { rval = nand_write (nand, offset, length, buffer); if (rval != 0) printf ("NAND write to offset %llx failed %d\n", offset, rval); return rval; } #endif while (left_to_write > 0) { size_t block_offset = offset & (nand->erasesize - 1); size_t write_size; WATCHDOG_RESET (); if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) { printf ("Skip bad block 0xllx\n", offset & ~(nand->erasesize - 1)); offset += nand->erasesize - block_offset; continue; } #if defined(CONFIG_MTD_NAND_YAFFS2)//add yaffs2 file system support if(nand->skipfirstblk==1) { nand->skipfirstblk=0; printf ("Skip the first good block %llx\n", offset & ~(nand->erasesize - 1)); offset += nand->erasesize - block_offset; continue; } #endif if (left_to_write < (nand->erasesize - block_offset)) write_size = left_to_write; else write_size = nand->erasesize - block_offset; printf("\rWriting at 0x%llx -- ",offset);//add yaffs2 file system support rval = nand_write (nand, offset, &write_size, p_buffer); if (rval != 0) { printf ("NAND write to offset %llx failed %d\n", offset, rval); *length -= left_to_write; return rval; } |