summaryrefslogtreecommitdiff
path: root/arch/m68k/include/asm/bitops_mm.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-19 16:27:21 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-19 16:27:21 -0700
commite1f2084ed200eb31f2c9d1efe70569c76889c980 (patch)
tree06b185bb7a13f4ac5862a8dbc05e8dd3453b27b8 /arch/m68k/include/asm/bitops_mm.h
parente33ab8f275cf6e0e0bf6c9c44149de46222b36cc (diff)
parent659e6ed55ff8d617c895c10288644e3e6107834e (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k: input/atari: Fix mouse movement and button mapping input/atari: Fix atarimouse init input/atari: Use the correct mouse interrupt hook m68k/atari: Do not use "/" in interrupt names m68k: unistd - Comment out definitions for unimplemented syscalls m68k: Really wire up sys_pselect6 and sys_ppoll m68k: Merge mmu and non-mmu versions of sys_call_table MAINTAINERS: Roman Zippel has been MIA for several years. m68k: bitops - Never step beyond the end of the bitmap m68k: bitops - offset == ((long)p - (long)vaddr) * 8
Diffstat (limited to 'arch/m68k/include/asm/bitops_mm.h')
-rw-r--r--arch/m68k/include/asm/bitops_mm.h87
1 files changed, 57 insertions, 30 deletions
diff --git a/arch/m68k/include/asm/bitops_mm.h b/arch/m68k/include/asm/bitops_mm.h
index 9d69f6e62365..e9020f88a748 100644
--- a/arch/m68k/include/asm/bitops_mm.h
+++ b/arch/m68k/include/asm/bitops_mm.h
@@ -181,14 +181,15 @@ static inline int find_first_zero_bit(const unsigned long *vaddr,
{
const unsigned long *p = vaddr;
int res = 32;
+ unsigned int words;
unsigned long num;
if (!size)
return 0;
- size = (size + 31) >> 5;
+ words = (size + 31) >> 5;
while (!(num = ~*p++)) {
- if (!--size)
+ if (!--words)
goto out;
}
@@ -196,7 +197,8 @@ static inline int find_first_zero_bit(const unsigned long *vaddr,
: "=d" (res) : "d" (num & -num));
res ^= 31;
out:
- return ((long)p - (long)vaddr - 4) * 8 + res;
+ res += ((long)p - (long)vaddr - 4) * 8;
+ return res < size ? res : size;
}
static inline int find_next_zero_bit(const unsigned long *vaddr, int size,
@@ -215,27 +217,32 @@ static inline int find_next_zero_bit(const unsigned long *vaddr, int size,
/* Look for zero in first longword */
__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
: "=d" (res) : "d" (num & -num));
- if (res < 32)
- return offset + (res ^ 31);
+ if (res < 32) {
+ offset += res ^ 31;
+ return offset < size ? offset : size;
+ }
offset += 32;
+
+ if (offset >= size)
+ return size;
}
/* No zero yet, search remaining full bytes for a zero */
- res = find_first_zero_bit(p, size - ((long)p - (long)vaddr) * 8);
- return offset + res;
+ return offset + find_first_zero_bit(p, size - offset);
}
static inline int find_first_bit(const unsigned long *vaddr, unsigned size)
{
const unsigned long *p = vaddr;
int res = 32;
+ unsigned int words;
unsigned long num;
if (!size)
return 0;
- size = (size + 31) >> 5;
+ words = (size + 31) >> 5;
while (!(num = *p++)) {
- if (!--size)
+ if (!--words)
goto out;
}
@@ -243,7 +250,8 @@ static inline int find_first_bit(const unsigned long *vaddr, unsigned size)
: "=d" (res) : "d" (num & -num));
res ^= 31;
out:
- return ((long)p - (long)vaddr - 4) * 8 + res;
+ res += ((long)p - (long)vaddr - 4) * 8;
+ return res < size ? res : size;
}
static inline int find_next_bit(const unsigned long *vaddr, int size,
@@ -262,13 +270,17 @@ static inline int find_next_bit(const unsigned long *vaddr, int size,
/* Look for one in first longword */
__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
: "=d" (res) : "d" (num & -num));
- if (res < 32)
- return offset + (res ^ 31);
+ if (res < 32) {
+ offset += res ^ 31;
+ return offset < size ? offset : size;
+ }
offset += 32;
+
+ if (offset >= size)
+ return size;
}
/* No one yet, search remaining full bytes for a one */
- res = find_first_bit(p, size - ((long)p - (long)vaddr) * 8);
- return offset + res;
+ return offset + find_first_bit(p, size - offset);
}
/*
@@ -366,23 +378,25 @@ static inline int test_bit_le(int nr, const void *vaddr)
static inline int find_first_zero_bit_le(const void *vaddr, unsigned size)
{
const unsigned long *p = vaddr, *addr = vaddr;
- int res;
+ int res = 0;
+ unsigned int words;
if (!size)
return 0;
- size = (size >> 5) + ((size & 31) > 0);
- while (*p++ == ~0UL)
- {
- if (--size == 0)
- return (p - addr) << 5;
+ words = (size >> 5) + ((size & 31) > 0);
+ while (*p++ == ~0UL) {
+ if (--words == 0)
+ goto out;
}
--p;
for (res = 0; res < 32; res++)
if (!test_bit_le(res, p))
break;
- return (p - addr) * 32 + res;
+out:
+ res += (p - addr) * 32;
+ return res < size ? res : size;
}
static inline unsigned long find_next_zero_bit_le(const void *addr,
@@ -400,10 +414,15 @@ static inline unsigned long find_next_zero_bit_le(const void *addr,
offset -= bit;
/* Look for zero in first longword */
for (res = bit; res < 32; res++)
- if (!test_bit_le(res, p))
- return offset + res;
+ if (!test_bit_le(res, p)) {
+ offset += res;
+ return offset < size ? offset : size;
+ }
p++;
offset += 32;
+
+ if (offset >= size)
+ return size;
}
/* No zero yet, search remaining full bytes for a zero */
return offset + find_first_zero_bit_le(p, size - offset);
@@ -412,22 +431,25 @@ static inline unsigned long find_next_zero_bit_le(const void *addr,
static inline int find_first_bit_le(const void *vaddr, unsigned size)
{
const unsigned long *p = vaddr, *addr = vaddr;
- int res;
+ int res = 0;
+ unsigned int words;
if (!size)
return 0;
- size = (size >> 5) + ((size & 31) > 0);
+ words = (size >> 5) + ((size & 31) > 0);
while (*p++ == 0UL) {
- if (--size == 0)
- return (p - addr) << 5;
+ if (--words == 0)
+ goto out;
}
--p;
for (res = 0; res < 32; res++)
if (test_bit_le(res, p))
break;
- return (p - addr) * 32 + res;
+out:
+ res += (p - addr) * 32;
+ return res < size ? res : size;
}
static inline unsigned long find_next_bit_le(const void *addr,
@@ -445,10 +467,15 @@ static inline unsigned long find_next_bit_le(const void *addr,
offset -= bit;
/* Look for one in first longword */
for (res = bit; res < 32; res++)
- if (test_bit_le(res, p))
- return offset + res;
+ if (test_bit_le(res, p)) {
+ offset += res;
+ return offset < size ? offset : size;
+ }
p++;
offset += 32;
+
+ if (offset >= size)
+ return size;
}
/* No set bit yet, search remaining full bytes for a set bit */
return offset + find_first_bit_le(p, size - offset);