2005-04-16 15:20:36 -07:00
# include <linux/bitops.h>
# include <linux/module.h>
/**
* find_next_bit - find the first set bit in a memory region
* @ addr : The address to base the search on
* @ offset : The bitnumber to start searching at
* @ size : The maximum size to search
*/
int find_next_bit ( const unsigned long * addr , int size , int offset )
{
const unsigned long * p = addr + ( offset > > 5 ) ;
int set = 0 , bit = offset & 31 , res ;
if ( bit ) {
/*
* Look for nonzero in the first 32 bits :
*/
__asm__ ( " bsfl %1,%0 \n \t "
" jne 1f \n \t "
" movl $32, %0 \n "
" 1: "
: " =r " ( set )
: " r " ( * p > > bit ) ) ;
if ( set < ( 32 - bit ) )
return set + offset ;
set = 32 - bit ;
p + + ;
}
/*
* No set bit yet , search remaining full words for a bit
*/
res = find_first_bit ( p , size - 32 * ( p - addr ) ) ;
return ( offset + set + res ) ;
}
EXPORT_SYMBOL ( find_next_bit ) ;
/**
* find_next_zero_bit - find the first zero bit in a memory region
* @ addr : The address to base the search on
* @ offset : The bitnumber to start searching at
* @ size : The maximum size to search
*/
int find_next_zero_bit ( const unsigned long * addr , int size , int offset )
{
2007-05-02 19:27:08 +02:00
const unsigned long * p = addr + ( offset > > 5 ) ;
2005-04-16 15:20:36 -07:00
int set = 0 , bit = offset & 31 , res ;
if ( bit ) {
/*
* Look for zero in the first 32 bits .
*/
__asm__ ( " bsfl %1,%0 \n \t "
" jne 1f \n \t "
" movl $32, %0 \n "
" 1: "
: " =r " ( set )
: " r " ( ~ ( * p > > bit ) ) ) ;
if ( set < ( 32 - bit ) )
return set + offset ;
set = 32 - bit ;
p + + ;
}
/*
* No zero yet , search remaining full bytes for a zero
*/
2007-05-02 19:27:08 +02:00
res = find_first_zero_bit ( p , size - 32 * ( p - addr ) ) ;
2005-04-16 15:20:36 -07:00
return ( offset + set + res ) ;
}
EXPORT_SYMBOL ( find_next_zero_bit ) ;