Home | History | Annotate | Download | only in yaffs2
      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 (at) 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