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