These were in yaffs_params, but that was getting a bit cluttered.
Signed-off-by: Charles Manning <cdhmanning@gmail.com>
void yflash2_install_drv(struct yaffs_dev *dev)
{
struct yaffs_param *param = &dev->param;
-
- param->drv_write_chunk_fn = yflash2_WriteChunk;
- param->drv_read_chunk_fn = yflash2_ReadChunk;
- param->drv_erase_fn = yflash2_EraseBlock;
- param->drv_mark_bad_fn = yflash2_MarkBad;
- param->drv_check_bad_fn = yflash2_CheckBad;
- param->drv_initialise_fn = yflash2_Initialise;
+ struct yaffs_driver *drv = &dev->drv;
+
+ drv->drv_write_chunk_fn = yflash2_WriteChunk;
+ drv->drv_read_chunk_fn = yflash2_ReadChunk;
+ drv->drv_erase_fn = yflash2_EraseBlock;
+ drv->drv_mark_bad_fn = yflash2_MarkBad;
+ drv->drv_check_bad_fn = yflash2_CheckBad;
+ drv->drv_initialise_fn = yflash2_Initialise;
param->total_bytes_per_chunk = 2048;
void ynorif1_install_drv(struct yaffs_dev *dev)
{
struct yaffs_param *param = &dev->param;
+ struct yaffs_driver *drv = &dev->drv;
param->total_bytes_per_chunk = 1024;
param->chunks_per_block =248;
param->start_block = 0; // Can use block 0
param->end_block = 31; // Last block
param->use_nand_ecc = 0; // use YAFFS's ECC
- param->drv_write_chunk_fn = ynorif1_WriteChunkToNAND;
- param->drv_read_chunk_fn = ynorif1_ReadChunkFromNAND;
- param->drv_erase_fn = ynorif1_EraseBlockInNAND;
- param->drv_initialise_fn = ynorif1_InitialiseNAND;
- param->drv_deinitialise_fn = ynorif1_Deinitialise_flash_fn;
+ drv->drv_write_chunk_fn = ynorif1_WriteChunkToNAND;
+ drv->drv_read_chunk_fn = ynorif1_ReadChunkFromNAND;
+ drv->drv_erase_fn = ynorif1_EraseBlockInNAND;
+ drv->drv_initialise_fn = ynorif1_InitialiseNAND;
+ drv->drv_deinitialise_fn = ynorif1_Deinitialise_flash_fn;
}
{
int i;
- if (!dev->param.drv_erase_fn)
+ if (!dev->drv.drv_erase_fn)
return 0;
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
"checking blocks %d to %d",
dev->n_erasures++;
- result = dev->param.drv_erase_fn(dev, offset_i);
+ result = dev->drv.drv_erase_fn(dev, offset_i);
if(result) {
bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
dev->n_erased_blocks++;
dev->n_free_chunks +=
dev->param.chunks_per_block;
} else {
- dev->param.drv_mark_bad_fn(dev, offset_i);
+ dev->drv.drv_mark_bad_fn(dev, offset_i);
bi->block_state = YAFFS_BLOCK_STATE_DEAD;
}
}
enum yaffs_block_state state;
u32 seq;
- dev->param.read_chunk_tags_fn(dev,
+ dev->th.read_chunk_tags_fn(dev,
apply_chunk_offset(dev, chunk),
NULL, &tags);
yaffs_trace(YAFFS_TRACE_CHECKPOINT,
if (tags.seq_number != YAFFS_SEQUENCE_CHECKPOINT_DATA)
continue;
- dev->param.query_block_fn(dev,
+ dev->th.query_block_fn(dev,
apply_block_offset(dev, i),
&state, &seq);
if (state == YAFFS_BLOCK_STATE_DEAD)
dev->checkpt_open_write = writing;
/* Got the functions we need? */
- if (!dev->param.write_chunk_tags_fn ||
- !dev->param.read_chunk_tags_fn ||
- !dev->param.drv_erase_fn ||
- !dev->param.drv_mark_bad_fn)
+ if (!dev->th.write_chunk_tags_fn ||
+ !dev->th.read_chunk_tags_fn ||
+ !dev->drv.drv_erase_fn ||
+ !dev->drv.drv_mark_bad_fn)
return 0;
if (writing && !yaffs2_checkpt_space_ok(dev))
dev->n_page_writes++;
- dev->param.write_chunk_tags_fn(dev, offset_chunk,
+ dev->th.write_chunk_tags_fn(dev, offset_chunk,
dev->checkpt_buffer, &tags);
dev->checkpt_page_seq++;
dev->checkpt_cur_chunk++;
dev->n_page_reads++;
/* read in the next chunk */
- dev->param.read_chunk_tags_fn(dev,
+ dev->th.read_chunk_tags_fn(dev,
offset_chunk,
dev->checkpt_buffer,
&tags);
memset(buffer, 0xff, dev->data_bytes_per_chunk);
memset(&tags, 0, sizeof(tags));
tags.seq_number = YAFFS_SEQUENCE_BAD_BLOCK;
- if (dev->param.write_chunk_tags_fn(dev, chunk_id -
- dev->chunk_offset,
- buffer,
- &tags) != YAFFS_OK)
+ if (dev->th.write_chunk_tags_fn(dev, chunk_id -
+ dev->chunk_offset,
+ buffer,
+ &tags) != YAFFS_OK)
yaffs_trace(YAFFS_TRACE_ALWAYS,
"yaffs: Failed to write bad block marker to block %d",
flash_block);
static int yaffs_check_dev_fns(struct yaffs_dev *dev)
{
- struct yaffs_param *param = &dev->param;
+ struct yaffs_driver *drv = &dev->drv;
+ struct yaffs_tags_handler *th = &dev->th;
/* Common functions, gotta have */
- if (!param->drv_read_chunk_fn ||
- !param->drv_write_chunk_fn ||
- !param->drv_erase_fn)
+ if (!drv->drv_read_chunk_fn ||
+ !drv->drv_write_chunk_fn ||
+ !drv->drv_erase_fn)
return 0;
- if (param->is_yaffs2 &&
- (!param->drv_mark_bad_fn || !param->drv_check_bad_fn))
+ if (dev->param.is_yaffs2 &&
+ (!drv->drv_mark_bad_fn || !drv->drv_check_bad_fn))
return 0;
/* Install the default tags marshalling functions if needed. */
yaffs_tags_marshall_install(dev);
/* Check we now have the marshalling functions required. */
- if (!param->write_chunk_tags_fn ||
- !param->read_chunk_tags_fn ||
- !param->query_block_fn ||
- !param->mark_bad_fn)
+ if (!th->write_chunk_tags_fn ||
+ !th->read_chunk_tags_fn ||
+ !th->query_block_fn ||
+ !th->mark_bad_fn)
return 0;
return 1;
int enable_xattr; /* Enable xattribs */
- /* Tags marshalling functions.
- * If these are not set then defaults will be assigned.
- */
- int (*write_chunk_tags_fn) (struct yaffs_dev *dev,
- int nand_chunk, const u8 *data,
- const struct yaffs_ext_tags *tags);
- int (*read_chunk_tags_fn) (struct yaffs_dev *dev,
- int nand_chunk, u8 *data,
- struct yaffs_ext_tags *tags);
-
- int (*query_block_fn) (struct yaffs_dev *dev, int block_no,
- enum yaffs_block_state *state,
- u32 *seq_number);
- int (*mark_bad_fn) (struct yaffs_dev *dev, int block_no);
-
- /* NAND driver access functions All required except
- * the deinitialise function which is optional.
- */
-
- int (*drv_write_chunk_fn) (struct yaffs_dev *dev, int nand_chunk,
- const u8 *data, int data_len,
- const u8 *oob, int oob_len);
- int (*drv_read_chunk_fn) (struct yaffs_dev *dev, int nand_chunk,
- u8 *data, int data_len,
- u8 *oob, int oob_len,
- enum yaffs_ecc_result *ecc_result);
- int (*drv_erase_fn) (struct yaffs_dev *dev, int block_no);
- int (*drv_mark_bad_fn) (struct yaffs_dev *dev, int block_no);
- int (*drv_check_bad_fn) (struct yaffs_dev *dev, int block_no);
- int (*drv_initialise_fn) (struct yaffs_dev *dev);
- int (*drv_deinitialise_fn) (struct yaffs_dev *dev);
-
-
int max_objects; /*
* Set to limit the number of objects created.
* 0 = no limit.
};
+struct yaffs_driver {
+ int (*drv_write_chunk_fn) (struct yaffs_dev *dev, int nand_chunk,
+ const u8 *data, int data_len,
+ const u8 *oob, int oob_len);
+ int (*drv_read_chunk_fn) (struct yaffs_dev *dev, int nand_chunk,
+ u8 *data, int data_len,
+ u8 *oob, int oob_len,
+ enum yaffs_ecc_result *ecc_result);
+ int (*drv_erase_fn) (struct yaffs_dev *dev, int block_no);
+ int (*drv_mark_bad_fn) (struct yaffs_dev *dev, int block_no);
+ int (*drv_check_bad_fn) (struct yaffs_dev *dev, int block_no);
+ int (*drv_initialise_fn) (struct yaffs_dev *dev);
+ int (*drv_deinitialise_fn) (struct yaffs_dev *dev);
+};
+
+struct yaffs_tags_handler {
+ int (*write_chunk_tags_fn) (struct yaffs_dev *dev,
+ int nand_chunk, const u8 *data,
+ const struct yaffs_ext_tags *tags);
+ int (*read_chunk_tags_fn) (struct yaffs_dev *dev,
+ int nand_chunk, u8 *data,
+ struct yaffs_ext_tags *tags);
+
+ int (*query_block_fn) (struct yaffs_dev *dev, int block_no,
+ enum yaffs_block_state *state,
+ u32 *seq_number);
+ int (*mark_bad_fn) (struct yaffs_dev *dev, int block_no);
+};
+
struct yaffs_dev {
struct yaffs_param param;
+ struct yaffs_driver drv;
+ struct yaffs_tags_handler th;
/* Context storage. Holds extra OS specific data for this device */
void yaffs_mtd_drv_install(struct yaffs_dev *dev)
{
- struct yaffs_param *param = &dev->param;
-
- param->drv_write_chunk_fn = yaffs_mtd_write;
- param->drv_read_chunk_fn = yaffs_mtd_read;
- param->drv_erase_fn = yaffs_mtd_erase;
- param->drv_mark_bad_fn = yaffs_mtd_mark_bad;
- param->drv_check_bad_fn = yaffs_mtd_check_bad;
- param->drv_initialise_fn = yaffs_mtd_initialise;
- param->drv_deinitialise_fn = yaffs_mtd_deinitialise;
+ struct yaffs_driver *drv = &dev->drv;
+
+ drv->drv_write_chunk_fn = yaffs_mtd_write;
+ drv->drv_read_chunk_fn = yaffs_mtd_read;
+ drv->drv_erase_fn = yaffs_mtd_erase;
+ drv->drv_mark_bad_fn = yaffs_mtd_mark_bad;
+ drv->drv_check_bad_fn = yaffs_mtd_check_bad;
+ drv->drv_initialise_fn = yaffs_mtd_initialise;
+ drv->drv_deinitialise_fn = yaffs_mtd_deinitialise;
}
if (!tags)
tags = &local_tags;
- result = dev->param.read_chunk_tags_fn(dev, flash_chunk, buffer, tags);
+ result = dev->th.read_chunk_tags_fn(dev, flash_chunk, buffer, tags);
if (tags && tags->ecc_result > YAFFS_ECC_RESULT_NO_ERROR) {
struct yaffs_block_info *bi;
"Writing chunk %d tags %d %d",
nand_chunk, tags->obj_id, tags->chunk_id);
- result = dev->param.write_chunk_tags_fn(dev, flash_chunk,
+ result = dev->th.write_chunk_tags_fn(dev, flash_chunk,
buffer, tags);
yaffs_summary_add(dev, tags, nand_chunk);
{
block_no -= dev->block_offset;
dev->n_bad_markings++;
- return dev->param.mark_bad_fn(dev, block_no);
+ return dev->th.mark_bad_fn(dev, block_no);
}
u32 *seq_number)
{
block_no -= dev->block_offset;
- return dev->param.query_block_fn(dev, block_no, state, seq_number);
+ return dev->th.query_block_fn(dev, block_no, state, seq_number);
}
int yaffs_erase_block(struct yaffs_dev *dev, int block_no)
block_no -= dev->block_offset;
dev->n_erasures++;
- result = dev->param.drv_erase_fn(dev, block_no);
+ result = dev->drv.drv_erase_fn(dev, block_no);
return result;
}
int yaffs_init_nand(struct yaffs_dev *dev)
{
- if (dev->param.drv_initialise_fn)
- return dev->param.drv_initialise_fn(dev);
+ if (dev->drv.drv_initialise_fn)
+ return dev->drv.drv_initialise_fn(dev);
return YAFFS_OK;
}
int yaffs_deinit_nand(struct yaffs_dev *dev)
{
- if (dev->param.drv_deinitialise_fn)
- return dev->param.drv_deinitialise_fn(dev);
+ if (dev->drv.drv_deinitialise_fn)
+ return dev->drv.drv_deinitialise_fn(dev);
return YAFFS_OK;
}
{
int data_size = dev->data_bytes_per_chunk;
- return dev->param.drv_write_chunk_fn(dev, nand_chunk,
+ return dev->drv.drv_write_chunk_fn(dev, nand_chunk,
data, data_size,
(u8 *) spare, sizeof(*spare));
}
spare_size = sizeof(struct yaffs_spare);
if (dev->param.use_nand_ecc)
- return dev->param.drv_read_chunk_fn(dev, nand_chunk,
+ return dev->drv.drv_read_chunk_fn(dev, nand_chunk,
data, data_size,
(u8 *) spare, spare_size,
ecc_result);
/* Handle the ECC at this level. */
- ret_val = dev->param.drv_read_chunk_fn(dev, nand_chunk,
+ ret_val = dev->drv.drv_read_chunk_fn(dev, nand_chunk,
data, data_size,
(u8 *)spare, spare_size,
NULL);
{
if(dev->param.is_yaffs2)
return;
- if(!dev->param.write_chunk_tags_fn)
- dev->param.write_chunk_tags_fn = yaffs_tags_compat_wr;
- if(!dev->param.read_chunk_tags_fn)
- dev->param.read_chunk_tags_fn = yaffs_tags_compat_rd;
- if(!dev->param.query_block_fn)
- dev->param.query_block_fn = yaffs_tags_compat_query_block;
- if(!dev->param.mark_bad_fn)
- dev->param.mark_bad_fn = yaffs_tags_compat_mark_bad;
+ if(!dev->th.write_chunk_tags_fn)
+ dev->th.write_chunk_tags_fn = yaffs_tags_compat_wr;
+ if(!dev->th.read_chunk_tags_fn)
+ dev->th.read_chunk_tags_fn = yaffs_tags_compat_rd;
+ if(!dev->th.query_block_fn)
+ dev->th.query_block_fn = yaffs_tags_compat_query_block;
+ if(!dev->th.mark_bad_fn)
+ dev->th.mark_bad_fn = yaffs_tags_compat_mark_bad;
}
yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
}
- retval = dev->param.drv_write_chunk_fn(dev, nand_chunk,
+ retval = dev->drv.drv_write_chunk_fn(dev, nand_chunk,
data, dev->param.total_bytes_per_chunk,
(dev->param.inband_tags) ? NULL : packed_tags_ptr,
(dev->param.inband_tags) ? 0 : packed_tags_size);
}
if (dev->param.inband_tags || (data && !tags))
- retval = dev->param.drv_read_chunk_fn(dev, nand_chunk,
+ retval = dev->drv.drv_read_chunk_fn(dev, nand_chunk,
data, dev->param.total_bytes_per_chunk,
NULL, 0,
&ecc_result);
else if (tags)
- retval = dev->param.drv_read_chunk_fn(dev, nand_chunk,
+ retval = dev->drv.drv_read_chunk_fn(dev, nand_chunk,
data, dev->param.total_bytes_per_chunk,
spare_buffer, packed_tags_size,
&ecc_result);
yaffs_trace(YAFFS_TRACE_MTD, "yaffs_tags_marshall_query_block %d",
block_no);
- retval = dev->param.drv_check_bad_fn(dev, block_no);
+ retval = dev->drv.drv_check_bad_fn(dev, block_no);
if (retval== YAFFS_FAIL) {
yaffs_trace(YAFFS_TRACE_MTD, "block is bad");
static int yaffs_tags_marshall_mark_bad(struct yaffs_dev *dev, int block_no)
{
- return dev->param.drv_mark_bad_fn(dev, block_no);
+ return dev->drv.drv_mark_bad_fn(dev, block_no);
}
if (!dev->param.is_yaffs2)
return;
- if (!dev->param.write_chunk_tags_fn)
- dev->param.write_chunk_tags_fn = yaffs_tags_marshall_write;
+ if (!dev->th.write_chunk_tags_fn)
+ dev->th.write_chunk_tags_fn = yaffs_tags_marshall_write;
- if (!dev->param.read_chunk_tags_fn)
- dev->param.read_chunk_tags_fn = yaffs_tags_marshall_read;
+ if (!dev->th.read_chunk_tags_fn)
+ dev->th.read_chunk_tags_fn = yaffs_tags_marshall_read;
- if (!dev->param.query_block_fn)
- dev->param.query_block_fn = yaffs_tags_marshall_query_block;
+ if (!dev->th.query_block_fn)
+ dev->th.query_block_fn = yaffs_tags_marshall_query_block;
- if (!dev->param.mark_bad_fn)
- dev->param.mark_bad_fn = yaffs_tags_marshall_mark_bad;
+ if (!dev->th.mark_bad_fn)
+ dev->th.mark_bad_fn = yaffs_tags_marshall_mark_bad;
}