yaffs_nand.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  3. *
  4. * Copyright (C) 2002-2011 Aleph One Ltd.
  5. * for Toby Churchill Ltd and Brightstar Engineering
  6. *
  7. * Created by Charles Manning <charles@aleph1.co.uk>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. */
  13. #include "yaffs_nand.h"
  14. #include "yaffs_tagscompat.h"
  15. #include "yaffs_getblockinfo.h"
  16. #include "yaffs_summary.h"
  17. int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk,
  18. u8 *buffer, struct yaffs_ext_tags *tags)
  19. {
  20. int result;
  21. struct yaffs_ext_tags local_tags;
  22. int flash_chunk = nand_chunk - dev->chunk_offset;
  23. dev->n_page_reads++;
  24. /* If there are no tags provided use local tags. */
  25. if (!tags)
  26. tags = &local_tags;
  27. if (dev->param.read_chunk_tags_fn)
  28. result =
  29. dev->param.read_chunk_tags_fn(dev, flash_chunk, buffer,
  30. tags);
  31. else
  32. result = yaffs_tags_compat_rd(dev,
  33. flash_chunk, buffer, tags);
  34. if (tags && tags->ecc_result > YAFFS_ECC_RESULT_NO_ERROR) {
  35. struct yaffs_block_info *bi;
  36. bi = yaffs_get_block_info(dev,
  37. nand_chunk /
  38. dev->param.chunks_per_block);
  39. yaffs_handle_chunk_error(dev, bi);
  40. }
  41. return result;
  42. }
  43. int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev,
  44. int nand_chunk,
  45. const u8 *buffer, struct yaffs_ext_tags *tags)
  46. {
  47. int result;
  48. int flash_chunk = nand_chunk - dev->chunk_offset;
  49. dev->n_page_writes++;
  50. if (tags) {
  51. tags->seq_number = dev->seq_number;
  52. tags->chunk_used = 1;
  53. yaffs_trace(YAFFS_TRACE_WRITE,
  54. "Writing chunk %d tags %d %d",
  55. nand_chunk, tags->obj_id, tags->chunk_id);
  56. } else {
  57. yaffs_trace(YAFFS_TRACE_ERROR, "Writing with no tags");
  58. BUG();
  59. return YAFFS_FAIL;
  60. }
  61. if (dev->param.write_chunk_tags_fn)
  62. result = dev->param.write_chunk_tags_fn(dev, flash_chunk,
  63. buffer, tags);
  64. else
  65. result = yaffs_tags_compat_wr(dev, flash_chunk, buffer, tags);
  66. yaffs_summary_add(dev, tags, nand_chunk);
  67. return result;
  68. }
  69. int yaffs_mark_bad(struct yaffs_dev *dev, int block_no)
  70. {
  71. block_no -= dev->block_offset;
  72. if (dev->param.bad_block_fn)
  73. return dev->param.bad_block_fn(dev, block_no);
  74. return yaffs_tags_compat_mark_bad(dev, block_no);
  75. }
  76. int yaffs_query_init_block_state(struct yaffs_dev *dev,
  77. int block_no,
  78. enum yaffs_block_state *state,
  79. u32 *seq_number)
  80. {
  81. block_no -= dev->block_offset;
  82. if (dev->param.query_block_fn)
  83. return dev->param.query_block_fn(dev, block_no, state,
  84. seq_number);
  85. return yaffs_tags_compat_query_block(dev, block_no, state, seq_number);
  86. }
  87. int yaffs_erase_block(struct yaffs_dev *dev, int flash_block)
  88. {
  89. int result;
  90. flash_block -= dev->block_offset;
  91. dev->n_erasures++;
  92. result = dev->param.erase_fn(dev, flash_block);
  93. return result;
  94. }
  95. int yaffs_init_nand(struct yaffs_dev *dev)
  96. {
  97. if (dev->param.initialise_flash_fn)
  98. return dev->param.initialise_flash_fn(dev);
  99. return YAFFS_OK;
  100. }