xref: /openbmc/u-boot/fs/yaffs2/yaffs_bitmap.c (revision 753ac610880e6e563d0384bb114f8b41df89e520)
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  
yaffs_block_bits(struct yaffs_dev * dev,int blk)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  
yaffs_verify_chunk_bit_id(struct yaffs_dev * dev,int blk,int chunk)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  
yaffs_clear_chunk_bits(struct yaffs_dev * dev,int blk)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  
yaffs_clear_chunk_bit(struct yaffs_dev * dev,int blk,int chunk)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  
yaffs_set_chunk_bit(struct yaffs_dev * dev,int blk,int chunk)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  
yaffs_check_chunk_bit(struct yaffs_dev * dev,int blk,int chunk)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  
yaffs_still_some_chunks(struct yaffs_dev * dev,int blk)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  
yaffs_count_chunk_bits(struct yaffs_dev * dev,int blk)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