/*
 * 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;
}
