diff options
Diffstat (limited to 'fs/yaffs2/yaffs_bitmap.c')
| -rw-r--r-- | fs/yaffs2/yaffs_bitmap.c | 97 | 
1 files changed, 97 insertions, 0 deletions
| diff --git a/fs/yaffs2/yaffs_bitmap.c b/fs/yaffs2/yaffs_bitmap.c new file mode 100644 index 000000000..4440e930d --- /dev/null +++ b/fs/yaffs2/yaffs_bitmap.c @@ -0,0 +1,97 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2011 Aleph One Ltd. + *   for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning <charles@aleph1.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "yaffs_bitmap.h" +#include "yaffs_trace.h" +/* + * Chunk bitmap manipulations + */ + +static inline u8 *yaffs_block_bits(struct yaffs_dev *dev, int blk) +{ +	if (blk < dev->internal_start_block || blk > dev->internal_end_block) { +		yaffs_trace(YAFFS_TRACE_ERROR, +			"BlockBits block %d is not valid", +			blk); +		BUG(); +	} +	return dev->chunk_bits + +	    (dev->chunk_bit_stride * (blk - dev->internal_start_block)); +} + +void yaffs_verify_chunk_bit_id(struct yaffs_dev *dev, int blk, int chunk) +{ +	if (blk < dev->internal_start_block || blk > dev->internal_end_block || +	    chunk < 0 || chunk >= dev->param.chunks_per_block) { +		yaffs_trace(YAFFS_TRACE_ERROR, +			"Chunk Id (%d:%d) invalid", +			blk, chunk); +		BUG(); +	} +} + +void yaffs_clear_chunk_bits(struct yaffs_dev *dev, int blk) +{ +	u8 *blk_bits = yaffs_block_bits(dev, blk); + +	memset(blk_bits, 0, dev->chunk_bit_stride); +} + +void yaffs_clear_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) +{ +	u8 *blk_bits = yaffs_block_bits(dev, blk); + +	yaffs_verify_chunk_bit_id(dev, blk, chunk); +	blk_bits[chunk / 8] &= ~(1 << (chunk & 7)); +} + +void yaffs_set_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) +{ +	u8 *blk_bits = yaffs_block_bits(dev, blk); + +	yaffs_verify_chunk_bit_id(dev, blk, chunk); +	blk_bits[chunk / 8] |= (1 << (chunk & 7)); +} + +int yaffs_check_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) +{ +	u8 *blk_bits = yaffs_block_bits(dev, blk); + +	yaffs_verify_chunk_bit_id(dev, blk, chunk); +	return (blk_bits[chunk / 8] & (1 << (chunk & 7))) ? 1 : 0; +} + +int yaffs_still_some_chunks(struct yaffs_dev *dev, int blk) +{ +	u8 *blk_bits = yaffs_block_bits(dev, blk); +	int i; + +	for (i = 0; i < dev->chunk_bit_stride; i++) { +		if (*blk_bits) +			return 1; +		blk_bits++; +	} +	return 0; +} + +int yaffs_count_chunk_bits(struct yaffs_dev *dev, int blk) +{ +	u8 *blk_bits = yaffs_block_bits(dev, blk); +	int i; +	int n = 0; + +	for (i = 0; i < dev->chunk_bit_stride; i++, blk_bits++) +		n += hweight8(*blk_bits); + +	return n; +} |