
From: David Howells <dhowells@redhat.com>

The attached patch provides an out-of-line implementation of find_next_bit()
and rearranges linux/bitops.h to avoid a dependency loop between inline
functions in there and in asm/bitops.h trying to include one another.

Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/include/linux/bitops.h |    7 ++++-
 25-akpm/lib/Makefile           |    1 
 25-akpm/lib/find_next_bit.c    |   55 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 1 deletion(-)

diff -puN include/linux/bitops.h~out-of-line-implementation-of-find_next_bit include/linux/bitops.h
--- 25/include/linux/bitops.h~out-of-line-implementation-of-find_next_bit	2004-11-11 01:14:03.000000000 -0800
+++ 25-akpm/include/linux/bitops.h	2004-11-11 12:30:16.684071840 -0800
@@ -1,7 +1,6 @@
 #ifndef _LINUX_BITOPS_H
 #define _LINUX_BITOPS_H
 #include <asm/types.h>
-#include <asm/bitops.h>
 
 /*
  * ffs: find first bit set. This is defined the same way as
@@ -71,6 +70,12 @@ static __inline__ int generic_fls(int x)
 	return r;
 }
 
+/*
+ * Include this here because some architectures need generic_ffs/fls in
+ * scope
+ */
+#include <asm/bitops.h>
+
 static __inline__ int get_bitmask_order(unsigned int count)
 {
 	int order;
diff -puN /dev/null lib/find_next_bit.c
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/lib/find_next_bit.c	2004-11-11 01:14:03.000000000 -0800
@@ -0,0 +1,55 @@
+/* find_next_bit.c: fallback find next bit implementation
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/bitops.h>
+
+int find_next_bit(const unsigned long *addr, int size, int offset)
+{
+	const unsigned long *base;
+	const int NBITS = sizeof(*addr) * 8;
+	unsigned long tmp;
+
+	base = addr;
+	if (offset) {
+		int suboffset;
+
+		addr += offset / NBITS;
+
+		suboffset = offset % NBITS;
+		if (suboffset) {
+			tmp = *addr;
+			tmp >>= suboffset;
+			if (tmp)
+				goto finish;
+		}
+
+		addr++;
+	}
+
+	while ((tmp = *addr) == 0)
+		addr++;
+
+	offset = (addr - base) * NBITS;
+
+ finish:
+	/* count the remaining bits without using __ffs() since that takes a 32-bit arg */
+	while (!(tmp & 0xff)) {
+		offset += 8;
+		tmp >>= 8;
+	}
+
+	while (!(tmp & 1)) {
+		offset++;
+		tmp >>= 1;
+	}
+
+	return offset;
+}
diff -puN lib/Makefile~out-of-line-implementation-of-find_next_bit lib/Makefile
--- 25/lib/Makefile~out-of-line-implementation-of-find_next_bit	2004-11-11 01:14:03.000000000 -0800
+++ 25-akpm/lib/Makefile	2004-11-11 01:14:03.000000000 -0800
@@ -14,6 +14,7 @@ endif
 
 lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
+lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
 obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
 
 ifneq ($(CONFIG_HAVE_DEC_LOCK),y) 
_
