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