From cd2967803617cd0a0bb8611e7d41c33a451207a5 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Sun, 21 Aug 2011 16:17:22 +0200 Subject: sunbmac: use standard #defines from mii.h. Signed-off-by: Francois Romieu --- drivers/net/ethernet/sun/sunbmac.c | 31 ++++++++++++++++--------------- drivers/net/ethernet/sun/sunbmac.h | 17 ----------------- 2 files changed, 16 insertions(+), 32 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c index c94f5ef348d4..0d8cfd9ea053 100644 --- a/drivers/net/ethernet/sun/sunbmac.c +++ b/drivers/net/ethernet/sun/sunbmac.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -500,13 +501,13 @@ static int try_next_permutation(struct bigmac *bp, void __iomem *tregs) /* Reset the PHY. */ bp->sw_bmcr = (BMCR_ISOLATE | BMCR_PDOWN | BMCR_LOOPBACK); - bigmac_tcvr_write(bp, tregs, BIGMAC_BMCR, bp->sw_bmcr); + bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr); bp->sw_bmcr = (BMCR_RESET); - bigmac_tcvr_write(bp, tregs, BIGMAC_BMCR, bp->sw_bmcr); + bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr); timeout = 64; while (--timeout) { - bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, BIGMAC_BMCR); + bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR); if ((bp->sw_bmcr & BMCR_RESET) == 0) break; udelay(20); @@ -514,11 +515,11 @@ static int try_next_permutation(struct bigmac *bp, void __iomem *tregs) if (timeout == 0) printk(KERN_ERR "%s: PHY reset failed.\n", bp->dev->name); - bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, BIGMAC_BMCR); + bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR); /* Now we try 10baseT. */ bp->sw_bmcr &= ~(BMCR_SPEED100); - bigmac_tcvr_write(bp, tregs, BIGMAC_BMCR, bp->sw_bmcr); + bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr); return 0; } @@ -534,8 +535,8 @@ static void bigmac_timer(unsigned long data) bp->timer_ticks++; if (bp->timer_state == ltrywait) { - bp->sw_bmsr = bigmac_tcvr_read(bp, tregs, BIGMAC_BMSR); - bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, BIGMAC_BMCR); + bp->sw_bmsr = bigmac_tcvr_read(bp, tregs, MII_BMSR); + bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR); if (bp->sw_bmsr & BMSR_LSTATUS) { printk(KERN_INFO "%s: Link is now up at %s.\n", bp->dev->name, @@ -588,18 +589,18 @@ static void bigmac_begin_auto_negotiation(struct bigmac *bp) int timeout; /* Grab new software copies of PHY registers. */ - bp->sw_bmsr = bigmac_tcvr_read(bp, tregs, BIGMAC_BMSR); - bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, BIGMAC_BMCR); + bp->sw_bmsr = bigmac_tcvr_read(bp, tregs, MII_BMSR); + bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR); /* Reset the PHY. */ bp->sw_bmcr = (BMCR_ISOLATE | BMCR_PDOWN | BMCR_LOOPBACK); - bigmac_tcvr_write(bp, tregs, BIGMAC_BMCR, bp->sw_bmcr); + bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr); bp->sw_bmcr = (BMCR_RESET); - bigmac_tcvr_write(bp, tregs, BIGMAC_BMCR, bp->sw_bmcr); + bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr); timeout = 64; while (--timeout) { - bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, BIGMAC_BMCR); + bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR); if ((bp->sw_bmcr & BMCR_RESET) == 0) break; udelay(20); @@ -607,11 +608,11 @@ static void bigmac_begin_auto_negotiation(struct bigmac *bp) if (timeout == 0) printk(KERN_ERR "%s: PHY reset failed.\n", bp->dev->name); - bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, BIGMAC_BMCR); + bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR); /* First we try 100baseT. */ bp->sw_bmcr |= BMCR_SPEED100; - bigmac_tcvr_write(bp, tregs, BIGMAC_BMCR, bp->sw_bmcr); + bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr); bp->timer_state = ltrywait; bp->timer_ticks = 0; @@ -1054,7 +1055,7 @@ static u32 bigmac_get_link(struct net_device *dev) struct bigmac *bp = netdev_priv(dev); spin_lock_irq(&bp->lock); - bp->sw_bmsr = bigmac_tcvr_read(bp, bp->tregs, BIGMAC_BMSR); + bp->sw_bmsr = bigmac_tcvr_read(bp, bp->tregs, MII_BMSR); spin_unlock_irq(&bp->lock); return (bp->sw_bmsr & BMSR_LSTATUS); diff --git a/drivers/net/ethernet/sun/sunbmac.h b/drivers/net/ethernet/sun/sunbmac.h index 4943e975a731..06dd21707353 100644 --- a/drivers/net/ethernet/sun/sunbmac.h +++ b/drivers/net/ethernet/sun/sunbmac.h @@ -223,23 +223,6 @@ #define BIGMAC_PHY_EXTERNAL 0 /* External transceiver */ #define BIGMAC_PHY_INTERNAL 1 /* Internal transceiver */ -/* PHY registers */ -#define BIGMAC_BMCR 0x00 /* Basic mode control register */ -#define BIGMAC_BMSR 0x01 /* Basic mode status register */ - -/* BMCR bits */ -#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ -#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ -#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ -#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ -#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ -#define BMCR_RESET 0x8000 /* Reset the DP83840 */ - -/* BMSR bits */ -#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ -#define BMSR_JCD 0x0002 /* Jabber detected */ -#define BMSR_LSTATUS 0x0004 /* Link status */ - /* Ring descriptors and such, same as Quad Ethernet. */ struct be_rxd { u32 rx_flags; -- cgit v1.2.2 ity The LITMUS^RT kernel.Bjoern Brandenburg
aboutsummaryrefslogblamecommitdiffstats
blob: 1016b75b026ab61b7ef0ee233915c3b1adeaf64d (plain) (tree)
1
  
















                                                                             

                               
                               
                       
                           
                     
                        
                         


                          
                          



                           
                             





                              
                        

                               
                         
                        
                          
                        
                           
                            
                          
                         
                             
                         
                        
                         
                           
 




                                     












                                                                        
                                                                
                                                              

                                

                          


                                     


                                                  
                                                  
 
                                                                

                                                                 

                                                        
                                                                         




                                                          
                                                                           


                                          

                                                                     


                                                           

                                
                         

                               

 


                                                                      
                                    

 


                                                                     






                                                         
 















                                                                        






















                                                                              




                                                          

                                                                 

                                                                 

                                                   
                                                          




                                                                 

                                                          
      



                                  
                                                                        

      






                                                                               
 
                          
 



                                                                
         

                     

 
                                                               

                                                                              

                           

                                                                         
                                        
                                                              

                                        
                                                                            

                                               
                            
                                                                    

                                           
                                                                            

                                               
      
          
 

                                                                         
 
                                                      

                                                                          
                                                
                                                                           

                                            

                                                                          

                                                    
                            

                                                                  

                                               

                                                                          

                                               
      

                  




                                                                                
                               









                                 
                                        




















                                                                                
                 
         
 
                            










                                                                               
      


                                                  
                                        


                    

                                                              




                                                                  











                                                        
                               

         
                                                   
                    
 
                               
 
                                                        
                                            








                                                  
                               

                 
 
                                                           
 

                           
 


                                                                   

                                                                        
                                                    


                                  

                                                           

                                                                           



                                

 
                                              
 
                                 

 






                                                                  

                                                                



                                  
                                                                  

 

































                                                                               
                           
 
                                                           


                    





                                                                          
 






                                                               

                                                                       



                                                                        



                                                 
 

                       















                                                                       

                                                                       

                                                                       
                                                                       








                                                                       

                                                    
                           


                                                  
                

                                                   



                                                        
 
                                                         
                                               


























                                                                      
                                                  

                               
                         
 

                                                      










                                                                             











                                                               
                                                                             

                 
                              














                                                                              
                                                                             







                                                                     
                                                      


                                    
                                              


                   
                                                      
















                                                                  

                                                            
                                                                     









                                                                      

                                                             
 
                                                                    





                                                                 



                                                
                                        
                
 
                                  

















                                                                        







                                                      
                                                                         
                                    







                                                        
                                  

 

                                                              

                           
                                   

                            
                                                         





                                                                      









                                                                  






















                                                                         
                                      
                                                 


















                                                                          
                                    
                                                      
                              
                            

                                                              
                                 
                                  
                                                                                
                                                                               
                                        


                         
                                    

                               


                   
                                                                            












                                                                     











                                                     
 
                          
                                                            

                          
                         


                            
                                                                         

                                
                               
                                                                               
 
                                
                       
 

                                                                             
                                           
                         
                            





                                                            
                                                             


                                         
                                                   


                            


                                      
                                  

                                                               
 
                                                  
                                                                        


                                                                     
                                 



                          
                                 
                                                                            








                                                                       
                                                  
 
                                             
 
                              





                                                         



















                                                             
                                                      


                               


                                                   
                   





                           

                                               
                                                                    

                               
                                             

                                                                






                                                   
                         










                                                                               



                                                

                                                        







                                                                              



                                                              







                                                           
                                                                        
                                 
                                                            
                                                                          
                                 
         
 


                                                             




                                                            






                                                                 
 

                                                                    
                      

                                                                           

 


                                                                       
 



                                               






                                                       

                                                               










                                                                 

                                                                    






                                                                        



                                                                         

                             
                                        

                                 
                                             
                                                                                  


                                                   

                                                                             
                                   
         
                   

 



                                 
                                                     





                                                                   













                                         







                                                                    

                                                                 
                             





                                                                     






                                                                  
 

                                                           
                                             




                                                                   

                                                            





                                                             
                                  


                                          
                                            
                                 
                                                    




                                                                      
                                                    


                                                     










                                                                   
                                    








                                                                      
                                                 



                                       



























                                                                           
                                              










                                                                   



                                                                        


                                                            
                                               














                                                                      
                                            

                                                     
                                                   









                                                                               
                                                                             




















                                                                            
     
 







                                                                         








                                                                          
      
 

                                                

                                      
                                           


                      






                                                                         

                                                               

                                                                    
                                                          


                                                                                     



                     
                                                    



                                      



                                                           
                                                                

                                        
         
                                  
 
 
                                      

                
                             
 

                                                                     



                                  








                                                                             
                             
 





                                                                         
 
                                                      



                   
                                       




                                                       
                                                                               

                                
                               
         
 

                                                                
                                       
 

                                            
                                     
 
                                                   

                 

                                       
                  
                                      
          
                                      

                   












                                              


                                                  
                                         
                                       

                                            
                            












                                                                          
                                                                     

                                           

                               
                                       
                                                 
                                








                                    


                                             


                                             
                            
                                 
                        
                                         
      


                                                                 

                                                                      



                                        




                                      
                                        
 
                          


                                                            
                         
 
                                               


                                

                                                                           
                                                                 


                                                    
                       
                             







                                                                   
                            

                                                                   
      
          
 

                                                                        
                                                                              





                                                                               
                 

                 

 
                                                                       










                                                                        
                                         


















                                                                               

                                                                            
                                              

                                                              
                                      

                         











                                                                          
                                                                         









                                                                           







                                                                     
                                                   

                                                              


                 
                                                        



































                                                                         
                                                                           
                                         
                                                                               













                                                                      
                                                                            
                                         
                                                                               







                                                                  




                                                                
                                                  
                                                          
                                                                             

                                                                 




































                                                                               













                                                                  
 










                                                     
                      












                                                                  

                                                             
 


                                                                              
            

                                                                               




































                                                                          
                                                                             



                           























                                                                       
                                                         
                                                       


                                                           


                                               
                                               
                           
                           









                                                                       
                                                  
                                                




                                                                          
                               
                 




                                                                    










                                                                        


                       

                                            
                                            

                                               
                                               


                                                
 


                             
                








                                                                              







                                                             
                                                                             


                                  




                                                               

     


                                                                
                                                                
                                                              


                                                                  
 
                 
 
 

                                                   
                                                   

                                                      
                                                      


                                                            



                            
                                                                        
 




                                                                          
 
 













                                                                    






                                                                     
                                                                   







                                                                                
                                                              









                                                                            

                                                                      
                                                             





                                                           
                      


                                  
                                                               

                           
                                                          
                                                
 
                            









                                                                   
 






                                                                  
                                                      































                                                                           
                                                                      










                                                                         
                                                             








                                                                              



                                                                     
                                                      
                                                                 
                                                                 









                                                                           
                                                             

                                      
                                                                





                                                                          







                                                                               
                              


                                              

                              
 






                                                                 













                                                                       


                                                                       
                                      
                                                                         





                                                                         

                                                                      

                            
                                                         





                                                                      






                                       
                                                         






                                                                      





























                                                                                            
                                                            
 

                                                      




                               


                                                                   
                                                  

                                  
                                 
 


                                                                     




                                                                             
                                                  


                                                                        

                                                                
 

                                               
 





                                                                               

                                                                  

                                                                   












                                                                                
 
                            












                                                                          



                                                                        
 




                                                                  
      




                                                                    





                                                                           
      






                                                                            
                         


                                                                  
                            

                                                                  

                   

                                                                            

                                     
























                                                                               

                                         


                             
                                             


                                                                                

                                             
                                                               

                                                   
                                                                    


                                                           
 
                           
                                      

                                       

                                                                           

                                                              
         
 



                                                 

















                                                                             
                         
                                                                


                                                                         
                                                                   






                                                                           
 
                                                                           
                    
                            
 
                                                         
                    
                            
                                                               
                                                                



                                       

                               


                   
        


                                                               

                                 
                          


                                      
                                

                                 
           
      


                                           
                                                                            
             
                            

                    
                      

                   
                            






                                                           










                                            
                                         

                                                               




                                  
                                                         


                                                    
                                                         




                                            
                                            


                                    
                                           
                                    
 

                                                         
 
                          

                              
                                                 



                                                                      
                                    
                                

                                                                      


                                            
                                    

                           
                      


                                                                             



                                                
 
                                                                             
                                       
                            

                                                             
 


                                                                                      
                                  

                                     
                               


                                             
                                       
      



                                           
                                    















                                                                             
                                                     











                                                      
                                          
                                                                              
            


                                                                              
                                        




















                                                                                    



                                                             


                                                       

                                                                              
                                                     



                                                  

                           
                               
 
                          
                                                      

                                                    

                                                     

                                                                   

                 




                                                         
                         
                   

 



                                                                
                          
                                                      

                                                    




                                                                 
                                                             
                                         



                                 
                         


                       




                                                                         
                          
                                                      

                                                    





                                                                   
                                                                             
                                 
                                                                  
                                         



                                 
                         


                       

                                                                             


                           
                          
                                                      


                                                              
                                                                                

                                                                         
                                                                   
                                         
                                 


                                          
                         
                       






                                                                           

                                                                            











                                                           
                          





                                                             
                                                            


                                                                     
                         

                   


















                                                                             

                            
                                                        


                   


                                                
                                
                                                                  
                                        
                                                             
                                        
                                                    
                                        




                                                                              






                                                           






                                

















                                                                  


                                                                

                    
                              










                                                                  

                         
                                                             
 








                                                                      
                                                 





                          



















                                                                  


                                                                              


                                                     
                          
                                                      

                                            
 





                                                                         
                         

                                                                    
                                                                  


                 
  




                                                                        
   
                                          
 
                 
 
                          
                                             
                         
 
                   

 






                                                                    
                                                   


                           


                                                             
                                                    

                                                     


                                   
                                    
 




































                                                                            
                                         
 



                                     
                    
 
                                                  


                                                                              
                                                                   
                         

                                                                     


                     
                         





                                                                  



                                         
      
 













































                                                                            
/*
   Copyright (C) 2002 Richard Henderson
   Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.

    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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#include <linux/module.h>
#include <linux/moduleloader.h>
#include <linux/ftrace_event.h>
#include <linux/init.h>
#include <linux/kallsyms.h>
#include <linux/fs.h>
#include <linux/sysfs.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/elf.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/syscalls.h>
#include <linux/fcntl.h>
#include <linux/rcupdate.h>
#include <linux/capability.h>
#include <linux/cpu.h>
#include <linux/moduleparam.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/vermagic.h>
#include <linux/notifier.h>
#include <linux/sched.h>
#include <linux/stop_machine.h>
#include <linux/device.h>
#include <linux/string.h>
#include <linux/mutex.h>
#include <linux/rculist.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
#include <linux/license.h>
#include <asm/sections.h>
#include <linux/tracepoint.h>
#include <linux/ftrace.h>
#include <linux/async.h>
#include <linux/percpu.h>
#include <linux/kmemleak.h>

#define CREATE_TRACE_POINTS
#include <trace/events/module.h>

EXPORT_TRACEPOINT_SYMBOL(module_get);

#if 0
#define DEBUGP printk
#else
#define DEBUGP(fmt , a...)
#endif

#ifndef ARCH_SHF_SMALL
#define ARCH_SHF_SMALL 0
#endif

/* If this is set, the section belongs in the init part of the module */
#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))

/* List of modules, protected by module_mutex or preempt_disable
 * (delete uses stop_machine/add uses RCU list operations). */
DEFINE_MUTEX(module_mutex);
EXPORT_SYMBOL_GPL(module_mutex);
static LIST_HEAD(modules);

/* Block module loading/unloading? */
int modules_disabled = 0;

/* Waiting for a module to finish initializing? */
static DECLARE_WAIT_QUEUE_HEAD(module_wq);

static BLOCKING_NOTIFIER_HEAD(module_notify_list);

/* Bounds of module allocation, for speeding __module_address */
static unsigned long module_addr_min = -1UL, module_addr_max = 0;

int register_module_notifier(struct notifier_block * nb)
{
	return blocking_notifier_chain_register(&module_notify_list, nb);
}
EXPORT_SYMBOL(register_module_notifier);

int unregister_module_notifier(struct notifier_block * nb)
{
	return blocking_notifier_chain_unregister(&module_notify_list, nb);
}
EXPORT_SYMBOL(unregister_module_notifier);

/* We require a truly strong try_module_get(): 0 means failure due to
   ongoing or failed initialization etc. */
static inline int strong_try_module_get(struct module *mod)
{
	if (mod && mod->state == MODULE_STATE_COMING)
		return -EBUSY;
	if (try_module_get(mod))
		return 0;
	else
		return -ENOENT;
}

static inline void add_taint_module(struct module *mod, unsigned flag)
{
	add_taint(flag);
	mod->taints |= (1U << flag);
}

/*
 * A thread that wants to hold a reference to a module only while it
 * is running can call this to safely exit.  nfsd and lockd use this.
 */
void __module_put_and_exit(struct module *mod, long code)
{
	module_put(mod);
	do_exit(code);
}
EXPORT_SYMBOL(__module_put_and_exit);

/* Find a module section: 0 means not found. */
static unsigned int find_sec(Elf_Ehdr *hdr,
			     Elf_Shdr *sechdrs,
			     const char *secstrings,
			     const char *name)
{
	unsigned int i;

	for (i = 1; i < hdr->e_shnum; i++)
		/* Alloc bit cleared means "ignore it." */
		if ((sechdrs[i].sh_flags & SHF_ALLOC)
		    && strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
			return i;
	return 0;
}

/* Find a module section, or NULL. */
static void *section_addr(Elf_Ehdr *hdr, Elf_Shdr *shdrs,
			  const char *secstrings, const char *name)
{
	/* Section 0 has sh_addr 0. */
	return (void *)shdrs[find_sec(hdr, shdrs, secstrings, name)].sh_addr;
}

/* Find a module section, or NULL.  Fill in number of "objects" in section. */
static void *section_objs(Elf_Ehdr *hdr,
			  Elf_Shdr *sechdrs,
			  const char *secstrings,
			  const char *name,
			  size_t object_size,
			  unsigned int *num)
{
	unsigned int sec = find_sec(hdr, sechdrs, secstrings, name);

	/* Section 0 has sh_addr 0 and sh_size 0. */
	*num = sechdrs[sec].sh_size / object_size;
	return (void *)sechdrs[sec].sh_addr;
}

/* Provided by the linker */
extern const struct kernel_symbol __start___ksymtab[];
extern const struct kernel_symbol __stop___ksymtab[];
extern const struct kernel_symbol __start___ksymtab_gpl[];
extern const struct kernel_symbol __stop___ksymtab_gpl[];
extern const struct kernel_symbol __start___ksymtab_gpl_future[];
extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
extern const struct kernel_symbol __start___ksymtab_gpl_future[];
extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
extern const unsigned long __start___kcrctab[];
extern const unsigned long __start___kcrctab_gpl[];
extern const unsigned long __start___kcrctab_gpl_future[];
#ifdef CONFIG_UNUSED_SYMBOLS
extern const struct kernel_symbol __start___ksymtab_unused[];
extern const struct kernel_symbol __stop___ksymtab_unused[];
extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
extern const unsigned long __start___kcrctab_unused[];
extern const unsigned long __start___kcrctab_unused_gpl[];
#endif

#ifndef CONFIG_MODVERSIONS
#define symversion(base, idx) NULL
#else
#define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
#endif

static bool each_symbol_in_section(const struct symsearch *arr,
				   unsigned int arrsize,
				   struct module *owner,
				   bool (*fn)(const struct symsearch *syms,
					      struct module *owner,
					      unsigned int symnum, void *data),
				   void *data)
{
	unsigned int i, j;

	for (j = 0; j < arrsize; j++) {
		for (i = 0; i < arr[j].stop - arr[j].start; i++)
			if (fn(&arr[j], owner, i, data))
				return true;
	}

	return false;
}

/* Returns true as soon as fn returns true, otherwise false. */
bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
			    unsigned int symnum, void *data), void *data)
{
	struct module *mod;
	const struct symsearch arr[] = {
		{ __start___ksymtab, __stop___ksymtab, __start___kcrctab,
		  NOT_GPL_ONLY, false },
		{ __start___ksymtab_gpl, __stop___ksymtab_gpl,
		  __start___kcrctab_gpl,
		  GPL_ONLY, false },
		{ __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future,
		  __start___kcrctab_gpl_future,
		  WILL_BE_GPL_ONLY, false },
#ifdef CONFIG_UNUSED_SYMBOLS
		{ __start___ksymtab_unused, __stop___ksymtab_unused,
		  __start___kcrctab_unused,
		  NOT_GPL_ONLY, true },
		{ __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl,
		  __start___kcrctab_unused_gpl,
		  GPL_ONLY, true },
#endif
	};

	if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data))
		return true;

	list_for_each_entry_rcu(mod, &modules, list) {
		struct symsearch arr[] = {
			{ mod->syms, mod->syms + mod->num_syms, mod->crcs,
			  NOT_GPL_ONLY, false },
			{ mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
			  mod->gpl_crcs,
			  GPL_ONLY, false },
			{ mod->gpl_future_syms,
			  mod->gpl_future_syms + mod->num_gpl_future_syms,
			  mod->gpl_future_crcs,
			  WILL_BE_GPL_ONLY, false },
#ifdef CONFIG_UNUSED_SYMBOLS
			{ mod->unused_syms,
			  mod->unused_syms + mod->num_unused_syms,
			  mod->unused_crcs,
			  NOT_GPL_ONLY, true },
			{ mod->unused_gpl_syms,
			  mod->unused_gpl_syms + mod->num_unused_gpl_syms,
			  mod->unused_gpl_crcs,
			  GPL_ONLY, true },
#endif
		};

		if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
			return true;
	}
	return false;
}
EXPORT_SYMBOL_GPL(each_symbol);

struct find_symbol_arg {
	/* Input */
	const char *name;
	bool gplok;
	bool warn;

	/* Output */
	struct module *owner;
	const unsigned long *crc;
	const struct kernel_symbol *sym;
};

static bool find_symbol_in_section(const struct symsearch *syms,
				   struct module *owner,
				   unsigned int symnum, void *data)
{
	struct find_symbol_arg *fsa = data;

	if (strcmp(syms->start[symnum].name, fsa->name) != 0)
		return false;

	if (!fsa->gplok) {
		if (syms->licence == GPL_ONLY)
			return false;
		if (syms->licence == WILL_BE_GPL_ONLY && fsa->warn) {
			printk(KERN_WARNING "Symbol %s is being used "
			       "by a non-GPL module, which will not "
			       "be allowed in the future\n", fsa->name);
			printk(KERN_WARNING "Please see the file "
			       "Documentation/feature-removal-schedule.txt "
			       "in the kernel source tree for more details.\n");
		}
	}

#ifdef CONFIG_UNUSED_SYMBOLS
	if (syms->unused && fsa->warn) {
		printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
		       "however this module is using it.\n", fsa->name);
		printk(KERN_WARNING
		       "This symbol will go away in the future.\n");
		printk(KERN_WARNING
		       "Please evalute if this is the right api to use and if "
		       "it really is, submit a report the linux kernel "
		       "mailinglist together with submitting your code for "
		       "inclusion.\n");
	}
#endif

	fsa->owner = owner;
	fsa->crc = symversion(syms->crcs, symnum);
	fsa->sym = &syms->start[symnum];
	return true;
}

/* Find a symbol and return it, along with, (optional) crc and
 * (optional) module which owns it */
const struct kernel_symbol *find_symbol(const char *name,
					struct module **owner,
					const unsigned long **crc,
					bool gplok,
					bool warn)
{
	struct find_symbol_arg fsa;

	fsa.name = name;
	fsa.gplok = gplok;
	fsa.warn = warn;

	if (each_symbol(find_symbol_in_section, &fsa)) {
		if (owner)
			*owner = fsa.owner;
		if (crc)
			*crc = fsa.crc;
		return fsa.sym;
	}

	DEBUGP("Failed to find symbol %s\n", name);
	return NULL;
}
EXPORT_SYMBOL_GPL(find_symbol);

/* Search for module by name: must hold module_mutex. */
struct module *find_module(const char *name)
{
	struct module *mod;

	list_for_each_entry(mod, &modules, list) {
		if (strcmp(mod->name, name) == 0)
			return mod;
	}
	return NULL;
}
EXPORT_SYMBOL_GPL(find_module);

#ifdef CONFIG_SMP

static inline void __percpu *mod_percpu(struct module *mod)
{
	return mod->percpu;
}

static int percpu_modalloc(struct module *mod,
			   unsigned long size, unsigned long align)
{
	if (align > PAGE_SIZE) {
		printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
		       mod->name, align, PAGE_SIZE);
		align = PAGE_SIZE;
	}

	mod->percpu = __alloc_reserved_percpu(size, align);
	if (!mod->percpu) {
		printk(KERN_WARNING
		       "Could not allocate %lu bytes percpu data\n", size);
		return -ENOMEM;
	}
	mod->percpu_size = size;
	return 0;
}

static void percpu_modfree(struct module *mod)
{
	free_percpu(mod->percpu);
}

static unsigned int find_pcpusec(Elf_Ehdr *hdr,
				 Elf_Shdr *sechdrs,
				 const char *secstrings)
{
	return find_sec(hdr, sechdrs, secstrings, ".data.percpu");
}

static void percpu_modcopy(struct module *mod,
			   const void *from, unsigned long size)
{
	int cpu;

	for_each_possible_cpu(cpu)
		memcpy(per_cpu_ptr(mod->percpu, cpu), from, size);
}

/**
 * is_module_percpu_address - test whether address is from module static percpu
 * @addr: address to test
 *
 * Test whether @addr belongs to module static percpu area.
 *
 * RETURNS:
 * %true if @addr is from module static percpu area
 */
bool is_module_percpu_address(unsigned long addr)
{
	struct module *mod;
	unsigned int cpu;

	preempt_disable();

	list_for_each_entry_rcu(mod, &modules, list) {
		if (!mod->percpu_size)
			continue;
		for_each_possible_cpu(cpu) {
			void *start = per_cpu_ptr(mod->percpu, cpu);

			if ((void *)addr >= start &&
			    (void *)addr < start + mod->percpu_size) {
				preempt_enable();
				return true;
			}
		}
	}

	preempt_enable();
	return false;
}

#else /* ... !CONFIG_SMP */

static inline void __percpu *mod_percpu(struct module *mod)
{
	return NULL;
}
static inline int percpu_modalloc(struct module *mod,
				  unsigned long size, unsigned long align)
{
	return -ENOMEM;
}
static inline void percpu_modfree(struct module *mod)
{
}
static inline unsigned int find_pcpusec(Elf_Ehdr *hdr,
					Elf_Shdr *sechdrs,
					const char *secstrings)
{
	return 0;
}
static inline void percpu_modcopy(struct module *mod,
				  const void *from, unsigned long size)
{
	/* pcpusec should be 0, and size of that section should be 0. */
	BUG_ON(size != 0);
}
bool is_module_percpu_address(unsigned long addr)
{
	return false;
}

#endif /* CONFIG_SMP */

#define MODINFO_ATTR(field)	\
static void setup_modinfo_##field(struct module *mod, const char *s)  \
{                                                                     \
	mod->field = kstrdup(s, GFP_KERNEL);                          \
}                                                                     \
static ssize_t show_modinfo_##field(struct module_attribute *mattr,   \
	                struct module *mod, char *buffer)             \
{                                                                     \
	return sprintf(buffer, "%s\n", mod->field);                   \
}                                                                     \
static int modinfo_##field##_exists(struct module *mod)               \
{                                                                     \
	return mod->field != NULL;                                    \
}                                                                     \
static void free_modinfo_##field(struct module *mod)                  \
{                                                                     \
	kfree(mod->field);                                            \
	mod->field = NULL;                                            \
}                                                                     \
static struct module_attribute modinfo_##field = {                    \
	.attr = { .name = __stringify(field), .mode = 0444 },         \
	.show = show_modinfo_##field,                                 \
	.setup = setup_modinfo_##field,                               \
	.test = modinfo_##field##_exists,                             \
	.free = free_modinfo_##field,                                 \
};

MODINFO_ATTR(version);
MODINFO_ATTR(srcversion);

static char last_unloaded_module[MODULE_NAME_LEN+1];

#ifdef CONFIG_MODULE_UNLOAD
/* Init the unload section of the module. */
static void module_unload_init(struct module *mod)
{
	int cpu;

	INIT_LIST_HEAD(&mod->modules_which_use_me);
	for_each_possible_cpu(cpu) {
		per_cpu_ptr(mod->refptr, cpu)->incs = 0;
		per_cpu_ptr(mod->refptr, cpu)->decs = 0;
	}

	/* Hold reference count during initialization. */
	__this_cpu_write(mod->refptr->incs, 1);
	/* Backwards compatibility macros put refcount during init. */
	mod->waiter = current;
}

/* modules using other modules */
struct module_use
{
	struct list_head list;
	struct module *module_which_uses;
};

/* Does a already use b? */
static int already_uses(struct module *a, struct module *b)
{
	struct module_use *use;

	list_for_each_entry(use, &b->modules_which_use_me, list) {
		if (use->module_which_uses == a) {
			DEBUGP("%s uses %s!\n", a->name, b->name);
			return 1;
		}
	}
	DEBUGP("%s does not use %s!\n", a->name, b->name);
	return 0;
}

/* Module a uses b */
int use_module(struct module *a, struct module *b)
{
	struct module_use *use;
	int no_warn, err;

	if (b == NULL || already_uses(a, b)) return 1;

	/* If we're interrupted or time out, we fail. */
	if (wait_event_interruptible_timeout(
		    module_wq, (err = strong_try_module_get(b)) != -EBUSY,
		    30 * HZ) <= 0) {
		printk("%s: gave up waiting for init of module %s.\n",
		       a->name, b->name);
		return 0;
	}

	/* If strong_try_module_get() returned a different error, we fail. */
	if (err)
		return 0;

	DEBUGP("Allocating new usage for %s.\n", a->name);
	use = kmalloc(sizeof(*use), GFP_ATOMIC);
	if (!use) {
		printk("%s: out of memory loading\n", a->name);
		module_put(b);
		return 0;
	}

	use->module_which_uses = a;
	list_add(&use->list, &b->modules_which_use_me);
	no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
	return 1;
}
EXPORT_SYMBOL_GPL(use_module);

/* Clear the unload stuff of the module. */
static void module_unload_free(struct module *mod)
{
	struct module *i;

	list_for_each_entry(i, &modules, list) {
		struct module_use *use;

		list_for_each_entry(use, &i->modules_which_use_me, list) {
			if (use->module_which_uses == mod) {
				DEBUGP("%s unusing %s\n", mod->name, i->name);
				module_put(i);
				list_del(&use->list);
				kfree(use);
				sysfs_remove_link(i->holders_dir, mod->name);
				/* There can be at most one match. */
				break;
			}
		}
	}
}

#ifdef CONFIG_MODULE_FORCE_UNLOAD
static inline int try_force_unload(unsigned int flags)
{
	int ret = (flags & O_TRUNC);
	if (ret)
		add_taint(TAINT_FORCED_RMMOD);
	return ret;
}
#else
static inline int try_force_unload(unsigned int flags)
{
	return 0;
}
#endif /* CONFIG_MODULE_FORCE_UNLOAD */

struct stopref
{
	struct module *mod;
	int flags;
	int *forced;
};

/* Whole machine is stopped with interrupts off when this runs. */
static int __try_stop_module(void *_sref)
{
	struct stopref *sref = _sref;

	/* If it's not unused, quit unless we're forcing. */
	if (module_refcount(sref->mod) != 0) {
		if (!(*sref->forced = try_force_unload(sref->flags)))
			return -EWOULDBLOCK;
	}

	/* Mark it as dying. */
	sref->mod->state = MODULE_STATE_GOING;
	return 0;
}

static int try_stop_module(struct module *mod, int flags, int *forced)
{
	if (flags & O_NONBLOCK) {
		struct stopref sref = { mod, flags, forced };

		return stop_machine(__try_stop_module, &sref, NULL);
	} else {
		/* We don't need to stop the machine for this. */
		mod->state = MODULE_STATE_GOING;
		synchronize_sched();
		return 0;
	}
}

unsigned int module_refcount(struct module *mod)
{
	unsigned int incs = 0, decs = 0;
	int cpu;

	for_each_possible_cpu(cpu)
		decs += per_cpu_ptr(mod->refptr, cpu)->decs;
	/*
	 * ensure the incs are added up after the decs.
	 * module_put ensures incs are visible before decs with smp_wmb.
	 *
	 * This 2-count scheme avoids the situation where the refcount
	 * for CPU0 is read, then CPU0 increments the module refcount,
	 * then CPU1 drops that refcount, then the refcount for CPU1 is
	 * read. We would record a decrement but not its corresponding
	 * increment so we would see a low count (disaster).
	 *
	 * Rare situation? But module_refcount can be preempted, and we
	 * might be tallying up 4096+ CPUs. So it is not impossible.
	 */
	smp_rmb();
	for_each_possible_cpu(cpu)
		incs += per_cpu_ptr(mod->refptr, cpu)->incs;
	return incs - decs;
}
EXPORT_SYMBOL(module_refcount);

/* This exists whether we can unload or not */
static void free_module(struct module *mod);

static void wait_for_zero_refcount(struct module *mod)
{
	/* Since we might sleep for some time, release the mutex first */
	mutex_unlock(&module_mutex);
	for (;;) {
		DEBUGP("Looking at refcount...\n");
		set_current_state(TASK_UNINTERRUPTIBLE);
		if (module_refcount(mod) == 0)
			break;
		schedule();
	}
	current->state = TASK_RUNNING;
	mutex_lock(&module_mutex);
}

SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
		unsigned int, flags)
{
	struct module *mod;
	char name[MODULE_NAME_LEN];
	int ret, forced = 0;

	if (!capable(CAP_SYS_MODULE) || modules_disabled)
		return -EPERM;

	if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
		return -EFAULT;
	name[MODULE_NAME_LEN-1] = '\0';

	/* Create stop_machine threads since free_module relies on
	 * a non-failing stop_machine call. */
	ret = stop_machine_create();
	if (ret)
		return ret;

	if (mutex_lock_interruptible(&module_mutex) != 0) {
		ret = -EINTR;
		goto out_stop;
	}

	mod = find_module(name);
	if (!mod) {
		ret = -ENOENT;
		goto out;
	}

	if (!list_empty(&mod->modules_which_use_me)) {
		/* Other modules depend on us: get rid of them first. */
		ret = -EWOULDBLOCK;
		goto out;
	}

	/* Doing init or already dying? */
	if (mod->state != MODULE_STATE_LIVE) {
		/* FIXME: if (force), slam module count and wake up
                   waiter --RR */
		DEBUGP("%s already dying\n", mod->name);
		ret = -EBUSY;
		goto out;
	}

	/* If it has an init func, it must have an exit func to unload */
	if (mod->init && !mod->exit) {
		forced = try_force_unload(flags);
		if (!forced) {
			/* This module can't be removed */
			ret = -EBUSY;
			goto out;
		}
	}

	/* Set this up before setting mod->state */
	mod->waiter = current;

	/* Stop the machine so refcounts can't move and disable module. */
	ret = try_stop_module(mod, flags, &forced);
	if (ret != 0)
		goto out;

	/* Never wait if forced. */
	if (!forced && module_refcount(mod) != 0)
		wait_for_zero_refcount(mod);

	mutex_unlock(&module_mutex);
	/* Final destruction now noone is using it. */
	if (mod->exit != NULL)
		mod->exit();
	blocking_notifier_call_chain(&module_notify_list,
				     MODULE_STATE_GOING, mod);
	async_synchronize_full();
	mutex_lock(&module_mutex);
	/* Store the name of the last unloaded module for diagnostic purposes */
	strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
	ddebug_remove_module(mod->name);
	free_module(mod);

 out:
	mutex_unlock(&module_mutex);
out_stop:
	stop_machine_destroy();
	return ret;
}

static inline void print_unload_info(struct seq_file *m, struct module *mod)
{
	struct module_use *use;
	int printed_something = 0;

	seq_printf(m, " %u ", module_refcount(mod));

	/* Always include a trailing , so userspace can differentiate
           between this and the old multi-field proc format. */
	list_for_each_entry(use, &mod->modules_which_use_me, list) {
		printed_something = 1;
		seq_printf(m, "%s,", use->module_which_uses->name);
	}

	if (mod->init != NULL && mod->exit == NULL) {
		printed_something = 1;
		seq_printf(m, "[permanent],");
	}

	if (!printed_something)
		seq_printf(m, "-");
}

void __symbol_put(const char *symbol)
{
	struct module *owner;