summaryrefslogtreecommitdiff
path: root/yaffs_bitmap.c
diff options
context:
space:
mode:
authorCharles Manning <cdhmanning@gmail.com>2010-06-30 16:06:45 +1200
committerCharles Manning <cdhmanning@gmail.com>2010-07-01 16:19:59 +1200
commit780469359d1051ab37ab281b0520137d73fee2e9 (patch)
treed94612d14879624dd120b3d6aacb718ebc2a2c6c /yaffs_bitmap.c
parent29e2dccbc8145ce3fd337a91a266d29e9b0f3f60 (diff)
yaffs Reactoring WIP
Signed-off-by: Charles Manning <cdhmanning@gmail.com>
Diffstat (limited to 'yaffs_bitmap.c')
-rw-r--r--yaffs_bitmap.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/yaffs_bitmap.c b/yaffs_bitmap.c
new file mode 100644
index 0000000..c7e9e8c
--- /dev/null
+++ b/yaffs_bitmap.c
@@ -0,0 +1,105 @@
+/*
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2010 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 Y_INLINE __u8 *yaffs_BlockBits(yaffs_Device *dev, int blk)
+{
+ if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
+ T(YAFFS_TRACE_ERROR,
+ (TSTR("**>> yaffs: BlockBits block %d is not valid" TENDSTR),
+ blk));
+ YBUG();
+ }
+ return dev->chunkBits +
+ (dev->chunkBitmapStride * (blk - dev->internalStartBlock));
+}
+
+void yaffs_VerifyChunkBitId(yaffs_Device *dev, int blk, int chunk)
+{
+ if (blk < dev->internalStartBlock || blk > dev->internalEndBlock ||
+ chunk < 0 || chunk >= dev->param.nChunksPerBlock) {
+ T(YAFFS_TRACE_ERROR,
+ (TSTR("**>> yaffs: Chunk Id (%d:%d) invalid"TENDSTR),
+ blk, chunk));
+ YBUG();
+ }
+}
+
+void yaffs_ClearChunkBits(yaffs_Device *dev, int blk)
+{
+ __u8 *blkBits = yaffs_BlockBits(dev, blk);
+
+ memset(blkBits, 0, dev->chunkBitmapStride);
+}
+
+void yaffs_ClearChunkBit(yaffs_Device *dev, int blk, int chunk)
+{
+ __u8 *blkBits = yaffs_BlockBits(dev, blk);
+
+ yaffs_VerifyChunkBitId(dev, blk, chunk);
+
+ blkBits[chunk / 8] &= ~(1 << (chunk & 7));
+}
+
+void yaffs_SetChunkBit(yaffs_Device *dev, int blk, int chunk)
+{
+ __u8 *blkBits = yaffs_BlockBits(dev, blk);
+
+ yaffs_VerifyChunkBitId(dev, blk, chunk);
+
+ blkBits[chunk / 8] |= (1 << (chunk & 7));
+}
+
+int yaffs_CheckChunkBit(yaffs_Device *dev, int blk, int chunk)
+{
+ __u8 *blkBits = yaffs_BlockBits(dev, blk);
+ yaffs_VerifyChunkBitId(dev, blk, chunk);
+
+ return (blkBits[chunk / 8] & (1 << (chunk & 7))) ? 1 : 0;
+}
+
+int yaffs_StillSomeChunkBits(yaffs_Device *dev, int blk)
+{
+ __u8 *blkBits = yaffs_BlockBits(dev, blk);
+ int i;
+ for (i = 0; i < dev->chunkBitmapStride; i++) {
+ if (*blkBits)
+ return 1;
+ blkBits++;
+ }
+ return 0;
+}
+
+int yaffs_CountChunkBits(yaffs_Device *dev, int blk)
+{
+ __u8 *blkBits = yaffs_BlockBits(dev, blk);
+ int i;
+ int n = 0;
+ for (i = 0; i < dev->chunkBitmapStride; i++) {
+ __u8 x = *blkBits;
+ while (x) {
+ if (x & 1)
+ n++;
+ x >>= 1;
+ }
+
+ blkBits++;
+ }
+ return n;
+}
+