#include "yaffs_guts.h"
#include "yaffs_getblockinfo.h"
#include "yaffs_tagscompat.h"
+#include "yaffs_tagsmarshall.h"
#include "yaffs_nand.h"
#include "yaffs_yaffs1.h"
#include "yaffs_yaffs2.h"
static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk,
const u8 *buffer, int n_bytes, int use_reserve);
-
+static void yaffs_fix_null_name(struct yaffs_obj *obj, YCHAR *name,
+ int buffer_size);
/* Function to calculate chunk and offset */
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->tagger.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);
return sum;
}
+
void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR * name)
{
memset(obj->short_name, 0, sizeof(obj->short_name));
- if (name &&
+
+ if (name && !name[0]) {
+ yaffs_fix_null_name(obj, obj->short_name,
+ YAFFS_SHORT_NAME_LENGTH);
+ name = obj->short_name;
+ } else if (name &&
strnlen(name, YAFFS_SHORT_NAME_LENGTH + 1) <=
- YAFFS_SHORT_NAME_LENGTH)
+ YAFFS_SHORT_NAME_LENGTH) {
strcpy(obj->short_name, name);
- else
- obj->short_name[0] = _Y('\0');
+ }
+
obj->sum = yaffs_calc_name_sum(name);
}
int erased_chunks;
int checkpt_block_adjust;
- if (dev->param.gc_control && (dev->param.gc_control(dev) & 1) == 0)
+ if (dev->param.gc_control_fn &&
+ (dev->param.gc_control_fn(dev) & 1) == 0)
return YAFFS_OK;
if (dev->gc_disable)
/*--------------------------- Initialisation code -------------------------- */
-static int yaffs_check_dev_fns(const struct yaffs_dev *dev)
+static int yaffs_check_dev_fns(struct yaffs_dev *dev)
{
+ struct yaffs_driver *drv = &dev->drv;
+ struct yaffs_tags_handler *tagger = &dev->tagger;
+
/* Common functions, gotta have */
- if (!dev->param.erase_fn || !dev->param.initialise_flash_fn)
+ if (!drv->drv_read_chunk_fn ||
+ !drv->drv_write_chunk_fn ||
+ !drv->drv_erase_fn)
return 0;
- /* Can use the "with tags" style interface for yaffs1 or yaffs2 */
- if (dev->param.write_chunk_tags_fn &&
- dev->param.read_chunk_tags_fn &&
- !dev->param.write_chunk_fn &&
- !dev->param.read_chunk_fn &&
- dev->param.bad_block_fn && dev->param.query_block_fn)
- return 1;
+ if (dev->param.is_yaffs2 &&
+ (!drv->drv_mark_bad_fn || !drv->drv_check_bad_fn))
+ return 0;
- /* Can use the "spare" style interface for yaffs1 */
- if (!dev->param.is_yaffs2 &&
- !dev->param.write_chunk_tags_fn &&
- !dev->param.read_chunk_tags_fn &&
- dev->param.write_chunk_fn &&
- dev->param.read_chunk_fn &&
- !dev->param.bad_block_fn && !dev->param.query_block_fn)
- return 1;
+ /* Install the default tags marshalling functions if needed. */
+ yaffs_tags_compat_install(dev);
+ yaffs_tags_marshall_install(dev);
- return 0; /* bad */
+ /* Check we now have the marshalling functions required. */
+ if (!tagger->write_chunk_tags_fn ||
+ !tagger->read_chunk_tags_fn ||
+ !tagger->query_block_fn ||
+ !tagger->mark_bad_fn)
+ return 0;
+
+ return 1;
}
static int yaffs_create_initial_dir(struct yaffs_dev *dev)
dev->is_mounted = 0;
- if (dev->param.deinitialise_flash_fn)
- dev->param.deinitialise_flash_fn(dev);
+ yaffs_deinit_nand(dev);
}
}
return n_free;
}
+
+int yaffs_format_dev(struct yaffs_dev *dev)
+{
+ int i;
+ enum yaffs_block_state state;
+ u32 dummy;
+
+ if(dev->is_mounted)
+ return YAFFS_FAIL;
+
+ /*
+ * The runtime variables might not have been set up,
+ * so set up what we need.
+ */
+ dev->internal_start_block = dev->param.start_block;
+ dev->internal_end_block = dev->param.end_block;
+ dev->block_offset = 0;
+ dev->chunk_offset = 0;
+
+ if (dev->param.start_block == 0) {
+ dev->internal_start_block = dev->param.start_block + 1;
+ dev->internal_end_block = dev->param.end_block + 1;
+ dev->block_offset = 1;
+ dev->chunk_offset = dev->param.chunks_per_block;
+ }
+
+ for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
+ yaffs_query_init_block_state(dev, i, &state, &dummy);
+ if (state != YAFFS_BLOCK_STATE_DEAD)
+ yaffs_erase_block(dev, i);
+ }
+
+ return YAFFS_OK;
+}
+
+
/*
* Marshalling functions to get loff_t file sizes into and out of
* object headers.