2010-08-26 13:57:58 -04:00
# include <linux/dma-mapping.h>
# include <asm/iommu_table.h>
# include <linux/string.h>
# include <linux/kallsyms.h>
# define DEBUG 1
static struct iommu_table_entry * __init
find_dependents_of ( struct iommu_table_entry * start ,
struct iommu_table_entry * finish ,
struct iommu_table_entry * q )
{
struct iommu_table_entry * p ;
if ( ! q )
return NULL ;
for ( p = start ; p < finish ; p + + )
if ( p - > detect = = q - > depend )
return p ;
return NULL ;
}
void __init sort_iommu_table ( struct iommu_table_entry * start ,
struct iommu_table_entry * finish ) {
struct iommu_table_entry * p , * q , tmp ;
for ( p = start ; p < finish ; p + + ) {
again :
q = find_dependents_of ( start , finish , p ) ;
/* We are bit sneaky here. We use the memory address to figure
* out if the node we depend on is past our point , if so , swap .
*/
if ( q > p ) {
tmp = * p ;
memmove ( p , q , sizeof ( * p ) ) ;
* q = tmp ;
goto again ;
}
}
}
# ifdef DEBUG
void __init check_iommu_entries ( struct iommu_table_entry * start ,
struct iommu_table_entry * finish )
{
struct iommu_table_entry * p , * q , * x ;
/* Simple cyclic dependency checker. */
for ( p = start ; p < finish ; p + + ) {
q = find_dependents_of ( start , finish , p ) ;
x = find_dependents_of ( start , finish , q ) ;
if ( p = = x ) {
2010-11-05 16:12:35 -07:00
printk ( KERN_ERR " CYCLIC DEPENDENCY FOUND! %pS depends on %pS and vice-versa. BREAKING IT. \n " ,
p - > detect , q - > detect ) ;
2010-08-26 13:57:58 -04:00
/* Heavy handed way..*/
x - > depend = 0 ;
}
}
for ( p = start ; p < finish ; p + + ) {
q = find_dependents_of ( p , finish , p ) ;
if ( q & & q > p ) {
2010-11-05 16:12:35 -07:00
printk ( KERN_ERR " EXECUTION ORDER INVALID! %pS should be called before %pS! \n " ,
p - > detect , q - > detect ) ;
2010-08-26 13:57:58 -04:00
}
}
}
# else
inline void check_iommu_entries ( struct iommu_table_entry * start ,
struct iommu_table_entry * finish )
{
}
# endif