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