2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/* 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Driver  for  Intel  I82092AA  PCI - PCMCIA  bridge . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  ( C )  2001  Red  Hat ,  Inc . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Author :  Arjan  Van  De  Ven  < arjanv @ redhat . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Loosly  based  on  i82365 . c  from  the  pcmcia - cs  package 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/kernel.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/module.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/pci.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/init.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/workqueue.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/interrupt.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/device.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pcmcia/ss.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <asm/io.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "i82092aa.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "i82365.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								MODULE_LICENSE ( " GPL " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* PCI core routines */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-27 16:17:46 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  DEFINE_PCI_DEVICE_TABLE ( i82092aa_pci_ids )  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  PCI_DEVICE ( PCI_VENDOR_ID_INTEL ,  PCI_DEVICE_ID_INTEL_82092AA_0 )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  } 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								MODULE_DEVICE_TABLE ( pci ,  i82092aa_pci_ids ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 04:34:51 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  struct  pci_driver  i82092aa_pci_driver  =  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									. name            =  " i82092aa " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. id_table        =  i82092aa_pci_ids , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. probe           =  i82092aa_pci_probe , 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-19 13:20:38 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									. remove          =  i82092aa_pci_remove , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* the pccard structure and its functions */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  struct  pccard_operations  i82092aa_operations  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. init  		 	=  i82092aa_init , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. get_status 		=  i82092aa_get_status , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. set_socket 		=  i82092aa_set_socket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. set_io_map 		=  i82092aa_set_io_map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. set_mem_map 		=  i82092aa_set_mem_map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-30 22:57:33 -03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* The card can do up to 4 sockets, allocate a structure for each of them */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  socket_info  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int 	number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int 	card_state ;  	/*  0 = no socket,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												    1  =  empty  socket ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												    2  =  card  but  not  initialized , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												    3  =  operational  card  */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-04 22:27:35 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									unsigned  int  io_base ;  	/* base io address of the socket */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  pcmcia_socket  socket ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  pci_dev  * dev ; 	/* The PCI device for the socket */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define MAX_SOCKETS 4 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  struct  socket_info  sockets [ MAX_SOCKETS ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  socket_count ;   /* shortcut */                                   	                                	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-19 13:23:12 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  i82092aa_pci_probe ( struct  pci_dev  * dev ,  const  struct  pci_device_id  * id ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  configbyte ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  i ,  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enter ( " i82092aa_pci_probe " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( ret  =  pci_enable_device ( dev ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pci_read_config_byte ( dev ,  0x40 ,  & configbyte ) ;   /* PCI Configuration Control */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch ( configbyte & 6 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											socket_count  =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											socket_count  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  4 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  6 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											socket_count  =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											printk ( KERN_ERR  " i82092aa: Oops, you did something we didn't think of. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ret  =  - EIO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											goto  err_out_disable ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									printk ( KERN_INFO  " i82092aa: configured as a %d socket device. \n " ,  socket_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! request_region ( pci_resource_start ( dev ,  0 ) ,  2 ,  " i82092aa " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ret  =  - EBUSY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  err_out_disable ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ; i < socket_count ; i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sockets [ i ] . card_state  =  1 ;  /* 1 = present but empty */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sockets [ i ] . io_base  =  pci_resource_start ( dev ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sockets [ i ] . socket . features  | =  SS_CAP_PCCARD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sockets [ i ] . socket . map_size  =  0x1000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sockets [ i ] . socket . irq_mask  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sockets [ i ] . socket . pci_irq   =  dev - > irq ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 17:42:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										sockets [ i ] . socket . cb_dev   =  dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										sockets [ i ] . socket . owner  =  THIS_MODULE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sockets [ i ] . number  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( card_present ( i ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											sockets [ i ] . card_state  =  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											dprintk ( KERN_DEBUG  " i82092aa: slot %i is occupied \n " , i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											dprintk ( KERN_DEBUG  " i82092aa: slot %i is vacant \n " , i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Now, specifiy that all interrupts are to be done as PCI interrupts */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									configbyte  =  0xFF ;  /* bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pci_write_config_byte ( dev ,  0x50 ,  configbyte ) ;  /* PCI Interrupt Routing Register */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Register the interrupt handler */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dprintk ( KERN_DEBUG  " Requesting interrupt %i  \n " , dev - > irq ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-01 19:29:38 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( ret  =  request_irq ( dev - > irq ,  i82092aa_interrupt ,  IRQF_SHARED ,  " i82092aa " ,  i82092aa_interrupt ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										printk ( KERN_ERR  " i82092aa: Failed to register IRQ %d, aborting \n " ,  dev - > irq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  err_out_free_res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ;  i < socket_count ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-12 17:00:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										sockets [ i ] . socket . dev . parent  =  & dev - > dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										sockets [ i ] . socket . ops  =  & i82092aa_operations ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sockets [ i ] . socket . resource_ops  =  & pccard_nonstatic_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ret  =  pcmcia_register_socket ( & sockets [ i ] . socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ret )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											goto  err_out_free_sockets ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									leave ( " i82092aa_pci_probe " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								err_out_free_sockets : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  ( i - - ; i > = 0 ; i - - )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											pcmcia_unregister_socket ( & sockets [ i ] . socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									free_irq ( dev - > irq ,  i82092aa_interrupt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								err_out_free_res : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									release_region ( pci_resource_start ( dev ,  0 ) ,  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								err_out_disable : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pci_disable_device ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ret ; 			
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-19 13:26:05 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  i82092aa_pci_remove ( struct  pci_dev  * dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-14 18:01:08 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enter ( " i82092aa_pci_remove " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									free_irq ( dev - > irq ,  i82092aa_interrupt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-12-14 18:01:08 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ;  i  <  socket_count ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pcmcia_unregister_socket ( & sockets [ i ] . socket ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									leave ( " i82092aa_pci_remove " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  DEFINE_SPINLOCK ( port_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* basic value read/write functions */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  unsigned  char  indirect_read ( int  socket ,  unsigned  short  reg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  short  int  port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  long  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_lock_irqsave ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reg  + =  socket  *  0x40 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									port  =  sockets [ socket ] . io_base ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( reg , port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									val  =  inb ( port + 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_unlock_irqrestore ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#if 0 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  unsigned  short  indirect_read16 ( int  socket ,  unsigned  short  reg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  short  int  port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  short  tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  long  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_lock_irqsave ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reg   =  reg  +  socket  *  0x40 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									port  =  sockets [ socket ] . io_base ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( reg , port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									tmp  =  inb ( port + 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reg + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( reg , port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									tmp  =  tmp  |  ( inb ( port + 1 ) < < 8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_unlock_irqrestore ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  indirect_write ( int  socket ,  unsigned  short  reg ,  unsigned  char  value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  short  int  port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  long  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_lock_irqsave ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reg  =  reg  +  socket  *  0x40 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									port  =  sockets [ socket ] . io_base ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( reg , port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( value , port + 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_unlock_irqrestore ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  indirect_setbit ( int  socket ,  unsigned  short  reg ,  unsigned  char  mask ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  short  int  port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  long  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_lock_irqsave ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reg  =  reg  +  socket  *  0x40 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									port  =  sockets [ socket ] . io_base ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( reg , port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									val  =  inb ( port + 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									val  | =  mask ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( reg , port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( val , port + 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_unlock_irqrestore ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  indirect_resetbit ( int  socket ,  unsigned  short  reg ,  unsigned  char  mask ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  short  int  port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  long  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_lock_irqsave ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reg  =  reg  +  socket  *  0x40 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									port  =  sockets [ socket ] . io_base ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( reg , port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									val  =  inb ( port + 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									val  & =  ~ mask ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( reg , port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( val , port + 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_unlock_irqrestore ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  indirect_write16 ( int  socket ,  unsigned  short  reg ,  unsigned  short  value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  short  int  port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  long  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_lock_irqsave ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reg  =  reg  +  socket  *  0x40 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									port  =  sockets [ socket ] . io_base ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( reg , port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									val  =  value  &  255 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( val , port + 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reg + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( reg , port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									val  =  value > > 8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									outb ( val , port + 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spin_unlock_irqrestore ( & port_lock , flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* simple helper functions */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* External clock time, in nanoseconds.  120 ns = 8.33 MHz */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  cycle_time  =  120 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  to_cycles ( int  ns ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( cycle_time ! = 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ns / cycle_time ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Interrupt handler functionality */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												IRQ: Maintain regs pointer globally rather than passing to IRQ handlers
Maintain a per-CPU global "struct pt_regs *" variable which can be used instead
of passing regs around manually through all ~1800 interrupt handlers in the
Linux kernel.
The regs pointer is used in few places, but it potentially costs both stack
space and code to pass it around.  On the FRV arch, removing the regs parameter
from all the genirq function results in a 20% speed up of the IRQ exit path
(ie: from leaving timer_interrupt() to leaving do_IRQ()).
Where appropriate, an arch may override the generic storage facility and do
something different with the variable.  On FRV, for instance, the address is
maintained in GR28 at all times inside the kernel as part of general exception
handling.
Having looked over the code, it appears that the parameter may be handed down
through up to twenty or so layers of functions.  Consider a USB character
device attached to a USB hub, attached to a USB controller that posts its
interrupts through a cascaded auxiliary interrupt controller.  A character
device driver may want to pass regs to the sysrq handler through the input
layer which adds another few layers of parameter passing.
I've build this code with allyesconfig for x86_64 and i386.  I've runtested the
main part of the code on FRV and i386, though I can't test most of the drivers.
I've also done partial conversion for powerpc and MIPS - these at least compile
with minimal configurations.
This will affect all archs.  Mostly the changes should be relatively easy.
Take do_IRQ(), store the regs pointer at the beginning, saving the old one:
	struct pt_regs *old_regs = set_irq_regs(regs);
And put the old one back at the end:
	set_irq_regs(old_regs);
Don't pass regs through to generic_handle_irq() or __do_IRQ().
In timer_interrupt(), this sort of change will be necessary:
	-	update_process_times(user_mode(regs));
	-	profile_tick(CPU_PROFILING, regs);
	+	update_process_times(user_mode(get_irq_regs()));
	+	profile_tick(CPU_PROFILING);
I'd like to move update_process_times()'s use of get_irq_regs() into itself,
except that i386, alone of the archs, uses something other than user_mode().
Some notes on the interrupt handling in the drivers:
 (*) input_dev() is now gone entirely.  The regs pointer is no longer stored in
     the input_dev struct.
 (*) finish_unlinks() in drivers/usb/host/ohci-q.c needs checking.  It does
     something different depending on whether it's been supplied with a regs
     pointer or not.
 (*) Various IRQ handler function pointers have been moved to type
     irq_handler_t.
Signed-Off-By: David Howells <dhowells@redhat.com>
(cherry picked from 1b16e7ac850969f38b375e511e3fa2f474a33867 commit)
											 
										 
										
											2006-10-05 14:55:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  irqreturn_t  i82092aa_interrupt ( int  irq ,  void  * dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  loopcount  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  handled  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  events ,  active = 0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*	enter("i82092aa_interrupt");*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									while  ( 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										loopcount + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( loopcount > 20 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											printk ( KERN_ERR  " i82092aa: infinite eventloop in interrupt  \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										active  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  ( i = 0 ; i < socket_count ; i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											int  csc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( sockets [ i ] . card_state = = 0 )  /* Inactive socket, should not happen */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											csc  =  indirect_read ( i , I365_CSC ) ;  /* card status change register */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( csc = = 0 )   /* no events on this socket */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											   	continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											handled  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											events  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( csc  &  I365_CSC_DETECT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												events  | =  SS_DETECT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												printk ( " Card detected in socket %i! \n " , i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( indirect_read ( i , I365_INTCTL )  &  I365_PC_IOCARD )  {  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* For IO/CARDS, bit 0 means "read the card" */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												events  | =  ( csc  &  I365_CSC_STSCHG )  ?  SS_STSCHG  :  0 ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* Check for battery/ready events */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												events  | =  ( csc  &  I365_CSC_BVD1 )  ?  SS_BATDEAD  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												events  | =  ( csc  &  I365_CSC_BVD2 )  ?  SS_BATWARN  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												events  | =  ( csc  &  I365_CSC_READY )  ?  SS_READY  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( events )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												pcmcia_parse_events ( & sockets [ i ] . socket ,  events ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											active  | =  events ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( active = = 0 )  /* no more events to handle */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 				
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  IRQ_RETVAL ( handled ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*	leave("i82092aa_interrupt");*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* socket functions */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  card_present ( int  socketno ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enter ( " card_present " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( socketno < 0 )  | |  ( socketno  > =  MAX_SOCKETS ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( sockets [ socketno ] . io_base  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									val  =  indirect_read ( socketno ,  1 ) ;  /* Interface status register */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( val & 12 ) = = 12 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										leave ( " card_present 1 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									leave ( " card_present 0 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  set_bridge_state ( int  sock ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enter ( " set_bridge_state " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									indirect_write ( sock ,  I365_GBLCTL , 0x00 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									indirect_write ( sock ,  I365_GENCTL , 0x00 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									indirect_setbit ( sock ,  I365_INTCTL , 0x08 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									leave ( " set_bridge_state " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  i82092aa_init ( struct  pcmcia_socket  * sock ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  resource  res  =  {  . start  =  0 ,  . end  =  0x0fff  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pccard_io_map  io  =  {  0 ,  0 ,  0 ,  0 ,  1  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pccard_mem_map  mem  =  {  . res  =  & res ,  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        enter ( " i82092aa_init " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        for  ( i  =  0 ;  i  <  2 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        	io . map  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                i82092aa_set_io_map ( sock ,  & io ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        for  ( i  =  0 ;  i  <  5 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        	mem . map  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                i82092aa_set_mem_map ( sock ,  & mem ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									leave ( " i82092aa_init " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                                                                                                                                                                                                                              
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  i82092aa_get_status ( struct  pcmcia_socket  * socket ,  u_int  * value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  sock  =  container_of ( socket ,  struct  socket_info ,  socket ) - > number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  status ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enter ( " i82092aa_get_status " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									status  =  indirect_read ( sock , I365_STATUS ) ;  /* Interface Status Register */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									* value  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( status  &  I365_CS_DETECT )  = =  I365_CS_DETECT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* value  | =  SS_DETECT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* IO cards have a different meaning of bits 0,1 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Also notice the inverse-logic on the bits */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 if  ( indirect_read ( sock ,  I365_INTCTL )  &  I365_PC_IOCARD ) 	{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 	/* IO card */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 	if  ( ! ( status  &  I365_CS_STSCHG ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 		* value  | =  SS_STSCHG ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 }  else  {  /* non I/O card */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 	if  ( ! ( status  &  I365_CS_BVD1 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 		* value  | =  SS_BATDEAD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 	if  ( ! ( status  &  I365_CS_BVD2 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 		* value  | =  SS_BATWARN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 		
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 if  ( status  &  I365_CS_WRPROT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 	( * value )  | =  SS_WRPROT ; 	/* card is write protected */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 if  ( status  &  I365_CS_READY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 	( * value )  | =  SS_READY ;     /* card is not busy */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 if  ( status  &  I365_CS_POWERON ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 	( * value )  | =  SS_POWERON ;   /* power is applied to the card */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									leave ( " i82092aa_get_status " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  i82092aa_set_socket ( struct  pcmcia_socket  * socket ,  socket_state_t  * state )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  sock  =  container_of ( socket ,  struct  socket_info ,  socket ) - > number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  reg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enter ( " i82092aa_set_socket " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* First, set the global controller options */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									set_bridge_state ( sock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Values for the IGENC register */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reg  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ( state - > flags  &  SS_RESET ) )  	/* The reset bit has "inverse" logic */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										reg  =  reg  |  I365_PC_RESET ;   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( state - > flags  &  SS_IOCARD )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										reg  =  reg  |  I365_PC_IOCARD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									indirect_write ( sock , I365_INTCTL , reg ) ;  /* IGENC, Interrupt and General Control Register */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Power registers */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reg  =  I365_PWR_NORESET ;  /* default: disable resetdrv on resume */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( state - > flags  &  SS_PWR_AUTO )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										printk ( " Auto power \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										reg  | =  I365_PWR_AUTO ; 	/* automatic power mngmnt */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( state - > flags  &  SS_OUTPUT_ENA )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										printk ( " Power Enabled  \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										reg  | =  I365_PWR_OUT ; 	/* enable power */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( state - > Vcc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  0 : 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  50 :  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											printk ( " setting voltage to Vcc to 5V on socket %i \n " , sock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											reg  | =  I365_VCC_5V ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											printk ( " i82092aa: i82092aa_set_socket called with invalid VCC power value: %i  " ,  state - > Vcc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											leave ( " i82092aa_set_socket " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( state - > Vpp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  0 : 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											printk ( " not setting Vpp on socket %i \n " , sock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  50 :  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											printk ( " setting Vpp to 5.0 for socket %i \n " , sock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											reg  | =  I365_VPP1_5V  |  I365_VPP2_5V ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  120 :  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											printk ( " setting Vpp to 12.0 \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											reg  | =  I365_VPP1_12V  |  I365_VPP2_12V ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											printk ( " i82092aa: i82092aa_set_socket called with invalid VPP power value: %i  " ,  state - > Vcc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											leave ( " i82092aa_set_socket " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( reg  ! =  indirect_read ( sock , I365_POWER ) )  /* only write if changed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										indirect_write ( sock , I365_POWER , reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Enable specific interrupt events */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reg  =  0x00 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( state - > csc_mask  &  SS_DETECT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										reg  | =  I365_CSC_DETECT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( state - > flags  &  SS_IOCARD )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( state - > csc_mask  &  SS_STSCHG ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											reg  | =  I365_CSC_STSCHG ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( state - > csc_mask  &  SS_BATDEAD )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											reg  | =  I365_CSC_BVD1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( state - > csc_mask  &  SS_BATWARN )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											reg  | =  I365_CSC_BVD2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( state - > csc_mask  &  SS_READY )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											reg  | =  I365_CSC_READY ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										                        
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* now write the value and clear the (probably bogus) pending stuff by doing a dummy read*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									indirect_write ( sock , I365_CSCINT , reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									( void ) indirect_read ( sock , I365_CSC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									leave ( " i82092aa_set_socket " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  i82092aa_set_io_map ( struct  pcmcia_socket  * socket ,  struct  pccard_io_map  * io ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  sock  =  container_of ( socket ,  struct  socket_info ,  socket ) - > number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  map ,  ioctl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enter ( " i82092aa_set_io_map " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									map  =  io - > map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Check error conditions */ 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( map  >  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										leave ( " i82092aa_set_io_map with invalid map " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( io - > start  >  0xffff )  | |  ( io - > stop  >  0xffff )  | |  ( io - > stop  <  io - > start ) ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										leave ( " i82092aa_set_io_map with invalid io " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Turn off the window before changing anything */  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( indirect_read ( sock ,  I365_ADDRWIN )  &  I365_ENA_IO ( map ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										indirect_resetbit ( sock ,  I365_ADDRWIN ,  I365_ENA_IO ( map ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*	printk("set_io_map: Setting range to %x - %x \n",io->start,io->stop);  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* write the new values */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									indirect_write16 ( sock , I365_IO ( map ) + I365_W_START , io - > start ) ;             	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									indirect_write16 ( sock , I365_IO ( map ) + I365_W_STOP , io - > stop ) ;             	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									            	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ioctl  =  indirect_read ( sock , I365_IOCTL )  &  ~ I365_IOCTL_MASK ( map ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( io - > flags  &  ( MAP_16BIT | MAP_AUTOSZ ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ioctl  | =  I365_IOCTL_16BIT ( map ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									indirect_write ( sock , I365_IOCTL , ioctl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Turn the window back on if needed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( io - > flags  &  MAP_ACTIVE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										indirect_setbit ( sock , I365_ADDRWIN , I365_ENA_IO ( map ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									leave ( " i82092aa_set_io_map " ) ; 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  i82092aa_set_mem_map ( struct  pcmcia_socket  * socket ,  struct  pccard_mem_map  * mem ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  socket_info  * sock_info  =  container_of ( socket ,  struct  socket_info ,  socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  sock  =  sock_info - > number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  pci_bus_region  region ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  short  base ,  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enter ( " i82092aa_set_mem_map " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												PCI: Convert pcibios_resource_to_bus() to take a pci_bus, not a pci_dev
These interfaces:
  pcibios_resource_to_bus(struct pci_dev *dev, *bus_region, *resource)
  pcibios_bus_to_resource(struct pci_dev *dev, *resource, *bus_region)
took a pci_dev, but they really depend only on the pci_bus.  And we want to
use them in resource allocation paths where we have the bus but not a
device, so this patch converts them to take the pci_bus instead of the
pci_dev:
  pcibios_resource_to_bus(struct pci_bus *bus, *bus_region, *resource)
  pcibios_bus_to_resource(struct pci_bus *bus, *resource, *bus_region)
In fact, with standard PCI-PCI bridges, they only depend on the host
bridge, because that's the only place address translation occurs, but
we aren't going that far yet.
[bhelgaas: changelog]
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
											 
										 
										
											2013-12-09 22:54:40 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pcibios_resource_to_bus ( sock_info - > dev - > bus ,  & region ,  mem - > res ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									map  =  mem - > map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( map  >  4 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										leave ( " i82092aa_set_mem_map: invalid map " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  (  ( mem - > card_start  >  0x3ffffff )  | |  ( region . start  >  region . end )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									     ( mem - > speed  >  1000 )  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										leave ( " i82092aa_set_mem_map: invalid address / speed " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-04 23:35:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										printk ( " invalid mem map for socket %i: %llx to %llx with a  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" start of %x \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											sock , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											( unsigned  long  long ) region . start , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											( unsigned  long  long ) region . end , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											mem - > card_start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Turn off the window before changing anything */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( indirect_read ( sock ,  I365_ADDRWIN )  &  I365_ENA_MEM ( map ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									              indirect_resetbit ( sock ,  I365_ADDRWIN ,  I365_ENA_MEM ( map ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									                 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									                 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* 	printk("set_mem_map: Setting map %i range to %x - %x on socket %i, speed is %i, active = %i \n",map, region.start,region.end,sock,mem->speed,mem->flags & MAP_ACTIVE);  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* write the start address */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									base  =  I365_MEM ( map ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									i  =  ( region . start  > >  12 )  &  0x0fff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( mem - > flags  &  MAP_16BIT )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										i  | =  I365_MEM_16BIT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( mem - > flags  &  MAP_0WS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										i  | =  I365_MEM_0WS ; 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									indirect_write16 ( sock , base + I365_W_START , i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										               
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* write the stop address */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									i =  ( region . end  > >  12 )  &  0x0fff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( to_cycles ( mem - > speed ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											i  | =  I365_MEM_WS0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											i  | =  I365_MEM_WS1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											i  | =  I365_MEM_WS1  |  I365_MEM_WS0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									indirect_write16 ( sock , base + I365_W_STOP , i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* card start */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									i  =  ( ( mem - > card_start  -  region . start )  > >  12 )  &  0x3fff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( mem - > flags  &  MAP_WRPROT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										i  | =  I365_MEM_WRPROT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( mem - > flags  &  MAP_ATTRIB )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*		printk("requesting attribute memory for socket %i\n",sock);*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										i  | =  I365_MEM_REG ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*		printk("requesting normal memory for socket %i\n",sock);*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									indirect_write16 ( sock , base + I365_W_OFF , i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Enable the window if necessary */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( mem - > flags  &  MAP_ACTIVE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										indirect_setbit ( sock ,  I365_ADDRWIN ,  I365_ENA_MEM ( map ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									            
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									leave ( " i82092aa_set_mem_map " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  i82092aa_module_init ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 04:34:51 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  pci_register_driver ( & i82092aa_pci_driver ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  i82092aa_module_exit ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enter ( " i82092aa_module_exit " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 04:34:51 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pci_unregister_driver ( & i82092aa_pci_driver ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ( sockets [ 0 ] . io_base > 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 release_region ( sockets [ 0 ] . io_base ,  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									leave ( " i82092aa_module_exit " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								module_init ( i82092aa_module_init ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								module_exit ( i82092aa_module_exit ) ;