 db85eaeb52
			
		
	
	
	db85eaeb52
	
	
	
		
			
			Fix some numbers in the comments describing the layout of the bit maps. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
		
			
				
	
	
		
			77 lines
		
	
	
	
		
			1.9 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
	
		
			1.9 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * MSB0 numbered special bitops handling.
 | |
|  *
 | |
|  * On s390x the bits are numbered:
 | |
|  *   |0..............63|64............127|128...........191|192...........255|
 | |
|  * and on s390:
 | |
|  *   |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255|
 | |
|  *
 | |
|  * The reason for this bit numbering is the fact that the hardware sets bits
 | |
|  * in a bitmap starting at bit 0 (MSB) and we don't want to scan the bitmap
 | |
|  * from the 'wrong end'.
 | |
|  */
 | |
| 
 | |
| #include <linux/compiler.h>
 | |
| #include <linux/bitops.h>
 | |
| #include <linux/export.h>
 | |
| 
 | |
| unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size)
 | |
| {
 | |
| 	const unsigned long *p = addr;
 | |
| 	unsigned long result = 0;
 | |
| 	unsigned long tmp;
 | |
| 
 | |
| 	while (size & ~(BITS_PER_LONG - 1)) {
 | |
| 		if ((tmp = *(p++)))
 | |
| 			goto found;
 | |
| 		result += BITS_PER_LONG;
 | |
| 		size -= BITS_PER_LONG;
 | |
| 	}
 | |
| 	if (!size)
 | |
| 		return result;
 | |
| 	tmp = (*p) & (~0UL << (BITS_PER_LONG - size));
 | |
| 	if (!tmp)		/* Are any bits set? */
 | |
| 		return result + size;	/* Nope. */
 | |
| found:
 | |
| 	return result + (__fls(tmp) ^ (BITS_PER_LONG - 1));
 | |
| }
 | |
| EXPORT_SYMBOL(find_first_bit_inv);
 | |
| 
 | |
| unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size,
 | |
| 				unsigned long offset)
 | |
| {
 | |
| 	const unsigned long *p = addr + (offset / BITS_PER_LONG);
 | |
| 	unsigned long result = offset & ~(BITS_PER_LONG - 1);
 | |
| 	unsigned long tmp;
 | |
| 
 | |
| 	if (offset >= size)
 | |
| 		return size;
 | |
| 	size -= result;
 | |
| 	offset %= BITS_PER_LONG;
 | |
| 	if (offset) {
 | |
| 		tmp = *(p++);
 | |
| 		tmp &= (~0UL >> offset);
 | |
| 		if (size < BITS_PER_LONG)
 | |
| 			goto found_first;
 | |
| 		if (tmp)
 | |
| 			goto found_middle;
 | |
| 		size -= BITS_PER_LONG;
 | |
| 		result += BITS_PER_LONG;
 | |
| 	}
 | |
| 	while (size & ~(BITS_PER_LONG-1)) {
 | |
| 		if ((tmp = *(p++)))
 | |
| 			goto found_middle;
 | |
| 		result += BITS_PER_LONG;
 | |
| 		size -= BITS_PER_LONG;
 | |
| 	}
 | |
| 	if (!size)
 | |
| 		return result;
 | |
| 	tmp = *p;
 | |
| found_first:
 | |
| 	tmp &= (~0UL << (BITS_PER_LONG - size));
 | |
| 	if (!tmp)		/* Are any bits set? */
 | |
| 		return result + size;	/* Nope. */
 | |
| found_middle:
 | |
| 	return result + (__fls(tmp) ^ (BITS_PER_LONG - 1));
 | |
| }
 | |
| EXPORT_SYMBOL(find_next_bit_inv);
 |