复制代码- int nand_write_skip_bad(nand_info_t *nand, size_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;
-
- [u]if(nand->writeoob==1)
- {
- size_t oobsize = nand->oobsize;
- size_t datasize = nand->writesize;
-
- int datapages = 0;
-
- if(((*length)%(nand->oobsize + nand->writesize)) != 0)
- {
- printf("*length=%d,pagesize=%d\n",*length,nand->oobsize+nand->writesize);
- printf("Attempt to write error length data!\n");
- return -EINVAL;
- }
-
- datapages = *length/(datasize + oobsize);
- printf("datasize+oobsize=%d,datapages=%d\n",datasize+oobsize,datapages);
- *length = datapages * datasize;
- left_to_write = *length;
- nand->skipfirstblock=1;
- }
- /* Reject writes, which are not page aligned */
- /* if ((offset & (nand->writesize - 1)) != 0 ||
- (*length & (nand->writesize - 1)) != 0) {
- printf ("Attempt to write non page aligned data\n");
- return -EINVAL;
- }
- */[/u] 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 (len_incl_bad == *length) {
- rval = nand_write (nand, offset, length, buffer);
- if (rval != 0) {
- printf ("NAND write to offset %x failed %d\n",
- offset, rval);
- return rval;
- }
- }
- while (left_to_write > 0) {
- size_t block_offset = offset & (nand->erasesize - 1);
- size_t write_size;
- if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
- printf ("Skip bad block 0x%08x\n",
- offset & ~(nand->erasesize - 1));
- offset += nand->erasesize - block_offset;
- continue;
- }
- /*added */
- [u]if(nand->skipfirstblock==1)
- {
- nand->skipfirstblock=0;
- printf("skip the first blcok!\n");
- offset+=nand->erasesize - block_offset;
- continue;
- }[/u] /*end add*/
- if (left_to_write < (nand->erasesize - block_offset))
- write_size = left_to_write;
- else
- write_size = nand->erasesize - block_offset;
- rval = nand_write (nand, offset, &write_size, p_buffer);
- if (rval != 0) {
- printf ("NAND write to offset %x failed %d\n",
- offset, rval);
- *length -= left_to_write;
- return rval;
- }
- left_to_write -= write_size;
- offset += write_size;
- [u]// p_buffer += write_size;
- if(nand->writeoob==1)
- p_buffer += write_size + (write_size/nand->writesize*nand->oobsize);
- else
- p_buffer += write_size;[/u]
- }
- return 0;
- }
- /**
- * nand_read_skip_bad:
- *
- * Read image from NAND flash.
- * Blocks that are marked bad are skipped and the next block is readen
- * instead as long as the image is short enough to fit even after skipping the
- * bad blocks.
- *
- * @param nand NAND device
- * @param offset offset in flash
- * @param length buffer length, on return holds remaining bytes to read
- * @param buffer buffer to write to
- * @return 0 in case of success
- */
- int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
- u_char *buffer)
- {
- int rval;
- size_t left_to_read = *length;
- size_t len_incl_bad;
- u_char *p_buffer = buffer;
- len_incl_bad = get_len_incl_bad (nand, offset, *length);
- if ((offset + len_incl_bad) >= nand->size) {
- printf ("Attempt to read outside the flash area\n");
- return -EINVAL;
- }
- if (len_incl_bad == *length) {
- rval = nand_read (nand, offset, length, buffer);
- if (rval != 0) {
- printf ("NAND read from offset %x failed %d\n",
- offset, rval);
- return rval;
- }
- }
- while (left_to_read > 0) {
- size_t block_offset = offset & (nand->erasesize - 1);
- size_t read_length;
- if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
- printf ("Skipping bad block 0x%08x\n",
- offset & ~(nand->erasesize - 1));
- offset += nand->erasesize - block_offset;
- continue;
- }
- if (left_to_read < (nand->erasesize - block_offset))
- read_length = left_to_read;
- else
- read_length = nand->erasesize - block_offset;
- rval = nand_read (nand, offset, &read_length, p_buffer);
- if (rval != 0) {
- printf ("NAND read from offset %x failed %d\n",
- offset, rval);
- *length -= left_to_read;
- return rval;
- }
- left_to_read -= read_length;
- offset += read_length;
- p_buffer += read_length;
- }
- return 0;
- }
|