1 /* 2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. 3 * 4 * Copyright (C) 2002-2011 Aleph One Ltd. 5 * for Toby Churchill Ltd and Brightstar Engineering 6 * 7 * Created by Charles Manning <charles@aleph1.co.uk> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13 14 #include "yaffs_bitmap.h" 15 #include "yaffs_trace.h" 16 /* 17 * Chunk bitmap manipulations 18 */ 19 20 static inline u8 *yaffs_block_bits(struct yaffs_dev *dev, int blk) 21 { 22 if (blk < dev->internal_start_block || blk > dev->internal_end_block) { 23 yaffs_trace(YAFFS_TRACE_ERROR, 24 "BlockBits block %d is not valid", 25 blk); 26 BUG(); 27 } 28 return dev->chunk_bits + 29 (dev->chunk_bit_stride * (blk - dev->internal_start_block)); 30 } 31 32 void yaffs_verify_chunk_bit_id(struct yaffs_dev *dev, int blk, int chunk) 33 { 34 if (blk < dev->internal_start_block || blk > dev->internal_end_block || 35 chunk < 0 || chunk >= dev->param.chunks_per_block) { 36 yaffs_trace(YAFFS_TRACE_ERROR, 37 "Chunk Id (%d:%d) invalid", 38 blk, chunk); 39 BUG(); 40 } 41 } 42 43 void yaffs_clear_chunk_bits(struct yaffs_dev *dev, int blk) 44 { 45 u8 *blk_bits = yaffs_block_bits(dev, blk); 46 47 memset(blk_bits, 0, dev->chunk_bit_stride); 48 } 49 50 void yaffs_clear_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) 51 { 52 u8 *blk_bits = yaffs_block_bits(dev, blk); 53 54 yaffs_verify_chunk_bit_id(dev, blk, chunk); 55 blk_bits[chunk / 8] &= ~(1 << (chunk & 7)); 56 } 57 58 void yaffs_set_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) 59 { 60 u8 *blk_bits = yaffs_block_bits(dev, blk); 61 62 yaffs_verify_chunk_bit_id(dev, blk, chunk); 63 blk_bits[chunk / 8] |= (1 << (chunk & 7)); 64 } 65 66 int yaffs_check_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) 67 { 68 u8 *blk_bits = yaffs_block_bits(dev, blk); 69 70 yaffs_verify_chunk_bit_id(dev, blk, chunk); 71 return (blk_bits[chunk / 8] & (1 << (chunk & 7))) ? 1 : 0; 72 } 73 74 int yaffs_still_some_chunks(struct yaffs_dev *dev, int blk) 75 { 76 u8 *blk_bits = yaffs_block_bits(dev, blk); 77 int i; 78 79 for (i = 0; i < dev->chunk_bit_stride; i++) { 80 if (*blk_bits) 81 return 1; 82 blk_bits++; 83 } 84 return 0; 85 } 86 87 int yaffs_count_chunk_bits(struct yaffs_dev *dev, int blk) 88 { 89 u8 *blk_bits = yaffs_block_bits(dev, blk); 90 int i; 91 int n = 0; 92 93 for (i = 0; i < dev->chunk_bit_stride; i++, blk_bits++) 94 n += hweight8(*blk_bits); 95 96 return n; 97 } 98