2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/************************************************************
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *                                                           * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *                Linux  EATA  SCSI  PIO  driver                  * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *                                                           * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   based  on  the  CAM  document  CAM / 89 - 004  rev .  2.0 c ,          * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   DPT ' s  driver  kit ,  some  internal  documents  and  source ,    * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   and  several  other  Linux  scsi  drivers  and  kernel  docs .    * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *                                                           * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   The  driver  currently :                                    * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *       - supports  all  EATA - PIO  boards                        * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *       - only  supports  DASD  devices                          * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *                                                           * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   ( c ) 1993 - 96  Michael  Neuffer ,  Alfred  Arnold                * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *              neuffer @ goofy . zdv . uni - mainz . de                * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *              a . arnold @ kfa - juelich . de                       *  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *                                                           * 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-27 15:16:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *   Updated  2002  by  Alan  Cox  < alan @ lxorguk . ukuu . org . uk >  for  * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *    Linux  2.5 . x  and  the  newer  locking  and  error  handling    * 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *                                                           * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   This  program  is  free  software ;  you  can  redistribute  it   * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   and / or  modify  it  under  the  terms  of  the  GNU  General      * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   Public  License  as  published  by  the  Free  Software         * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   Foundation ;  either  version  2  of  the  License ,  or          * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   ( at  your  option )  any  later  version .                      * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *                                                           * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   This  program  is  distributed  in  the  hope  that  it  will  be  * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   useful ,  but  WITHOUT  ANY  WARRANTY ;  without  even  the       * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   implied  warranty  of  MERCHANTABILITY  or  FITNESS  FOR  A     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   PARTICULAR  PURPOSE .   See  the  GNU  General  Public  License  * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   for  more  details .                                        * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *                                                           * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   You  should  have  received  a  copy  of  the  GNU  General       * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   Public  License  along  with  this  kernel ;  if  not ,  write  to  * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   the  Free  Software  Foundation ,  Inc . ,  675  Mass  Ave ,        * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   Cambridge ,  MA  0213 9 ,  USA .                                * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 							    * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   For  the  avoidance  of  doubt  the  " preferred form "  of  this  * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   code  is  one  which  is  in  an  open  non  patent  encumbered    * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   format .  Where  cryptographic  key  signing  forms  part  of    * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   the  process  of  creating  an  executable  the  information    * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   including  keys  needed  to  generate  an  equivalently        * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   functional  executable  are  deemed  to  be  part  of  the  	    * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   source  code  are  deemed  to  be  part  of  the  source  code .    * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *                                                           * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   last  change :  2002 / 11 / 02                OS :  Linux  2.5 .45   * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/module.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/kernel.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/string.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/ioport.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/in.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/pci.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/proc_fs.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/interrupt.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/blkdev.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/spinlock.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/delay.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <asm/io.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <scsi/scsi.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <scsi/scsi_cmnd.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <scsi/scsi_device.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <scsi/scsi_host.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "eata_generic.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "eata_pio.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  unsigned  int  ISAbases [ MAXISA ]  = 	{  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 0x1F0 ,  0x170 ,  0x330 ,  0x230 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  unsigned  int  ISAirqs [ MAXISA ]  =  {  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									14 ,  12 ,  15 ,  11 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  unsigned  char  EISAbases [ ]  =  {   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  unsigned  int  registered_HBAs ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  struct  Scsi_Host  * last_HBA ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  Scsi_Host  * first_HBA ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  unsigned  char  reg_IRQ [ 16 ] ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  unsigned  char  reg_IRQL [ 16 ] ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  unsigned  long  int_counter ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  unsigned  long  queue_counter ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  scsi_host_template  driver_template ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-31 03:18:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  eata_pio_show_info ( struct  seq_file  * m ,  struct  Scsi_Host  * shost )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2013-03-31 03:18:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seq_printf ( m ,  " EATA (Extended Attachment) PIO driver version:  " 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										   " %d.%d%s \n " , VER_MAJOR ,  VER_MINOR ,  VER_SUB ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-31 03:18:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seq_printf ( m ,  " queued commands:     %10ld \n " 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										   " processed interrupts:%10ld \n " ,  queue_counter ,  int_counter ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-31 03:18:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seq_printf ( m ,  " \n scsi%-2d: HBA %.10s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										   shost - > host_no ,  SD ( shost ) - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-31 03:18:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seq_printf ( m ,  " Firmware revision: v%s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										   SD ( shost ) - > revision ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-31 03:18:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seq_printf ( m ,  " IO: PIO \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									seq_printf ( m ,  " Base IO : %#.4x \n " ,  ( u32 )  shost - > base ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									seq_printf ( m ,  " Host Bus: %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										   ( SD ( shost ) - > bustype  = =  ' P ' ) ? " PCI  " : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   ( SD ( shost ) - > bustype  = =  ' E ' ) ? " EISA " : " ISA  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-31 03:18:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  eata_pio_release ( struct  Scsi_Host  * sh )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hostdata  * hd  =  SD ( sh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( sh - > irq  & &  reg_IRQ [ sh - > irq ]  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										free_irq ( sh - > irq ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reg_IRQ [ sh - > irq ] - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( SD ( sh ) - > channel  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( sh - > io_port  & &  sh - > n_io_port ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											release_region ( sh - > io_port ,  sh - > n_io_port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* At this point the PCI reference can go */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hd - > pdev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pci_dev_put ( hd - > pdev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  IncStat ( struct  scsi_pointer  * SCp ,  unsigned  int  Increment )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SCp - > ptr  + =  Increment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( SCp - > this_residual  - =  Increment )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( - - SCp - > buffers_residual )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											SCp - > Status  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											SCp - > buffer + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-22 21:19:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											SCp - > ptr  =  sg_virt ( SCp - > buffer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											SCp - > this_residual  =  SCp - > buffer - > length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												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  eata_pio_int_handler ( int  irq ,  void  * dev_id ) ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												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  do_eata_pio_int_handler ( int  irq ,  void  * dev_id )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  long  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  Scsi_Host  * dev  =  dev_id ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									irqreturn_t  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									spin_lock_irqsave ( dev - > host_lock ,  flags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-10-19 23:28:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ret  =  eata_pio_int_handler ( irq ,  dev_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									spin_unlock_irqrestore ( dev - > host_lock ,  flags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												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  eata_pio_int_handler ( int  irq ,  void  * dev_id )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  int  eata_stat  =  0xfffff ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  scsi_cmnd  * cmd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hostdata  * hd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  eata_ccb  * cp ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  long  base ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  x ,  z ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  Scsi_Host  * sh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  short  zwickel  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  stat ,  odd ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									irqreturn_t  ret  =  IRQ_NONE ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( x  =  1 ,  sh  =  first_HBA ;  x  < =  registered_HBAs ;  x + + ,  sh  =  SD ( sh ) - > prev )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( sh - > irq  ! =  irq ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( inb ( sh - > base  +  HA_RSTATUS )  &  HA_SBUSY ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int_counter + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ret  =  IRQ_HANDLED ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hd  =  SD ( sh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cp  =  & hd - > ccb [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cmd  =  cp - > cmd ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										base  =  cmd - > device - > host - > base ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											stat  =  inb ( base  +  HA_RSTATUS ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( stat  &  HA_SDRQ )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( cp - > DataIn )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													z  =  256 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													odd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													while  ( ( cmd - > SCp . Status )  & &  ( ( z  >  0 )  | |  ( odd ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( odd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															* ( cmd - > SCp . ptr )  =  zwickel  > >  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															IncStat ( & cmd - > SCp ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															odd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														x  =  min_t ( unsigned  int ,  z ,  cmd - > SCp . this_residual  /  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														insw ( base  +  HA_RDATA ,  cmd - > SCp . ptr ,  x ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														z  - =  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														IncStat ( & cmd - > SCp ,  2  *  x ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( ( z  >  0 )  & &  ( cmd - > SCp . this_residual  = =  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															zwickel  =  inw ( base  +  HA_RDATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															* ( cmd - > SCp . ptr )  =  zwickel  &  0xff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															IncStat ( & cmd - > SCp ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															z - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															odd  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													while  ( z  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														zwickel  =  inw ( base  +  HA_RDATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														z - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 	/* cp->DataOut */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													odd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													z  =  256 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													while  ( ( cmd - > SCp . Status )  & &  ( ( z  >  0 )  | |  ( odd ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( odd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															zwickel  + =  * ( cmd - > SCp . ptr )  < <  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															IncStat ( & cmd - > SCp ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															outw ( zwickel ,  base  +  HA_RDATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															z - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															odd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														x  =  min_t ( unsigned  int ,  z ,  cmd - > SCp . this_residual  /  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														outsw ( base  +  HA_RDATA ,  cmd - > SCp . ptr ,  x ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														z  - =  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														IncStat ( & cmd - > SCp ,  2  *  x ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( ( z  >  0 )  & &  ( cmd - > SCp . this_residual  = =  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															zwickel  =  * ( cmd - > SCp . ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															zwickel  & =  0xff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															IncStat ( & cmd - > SCp ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															odd  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													while  ( z  >  0  | |  odd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														outw ( zwickel ,  base  +  HA_RDATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														z - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														odd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( ( stat  &  HA_SDRQ )  | |  ( ( stat  &  HA_SMORE )  & &  hd - > moresupport ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* terminate handler if HBA goes busy again, i.e. transfers
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  more  data  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( stat  &  HA_SBUSY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* OK, this is quite stupid, but I haven't found any correct
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  way  to  get  HBA & SCSI  status  so  far  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( inb ( base  +  HA_RSTATUS )  &  HA_SERROR ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cmd - > result  =  ( DID_OK  < <  16 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hd - > devflags  | =  ( 1  < <  cp - > cp_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( hd - > devflags  &  ( 1  < <  cp - > cp_id ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											cmd - > result  =  ( DID_OK  < <  16 )  +  0x02 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cmd - > result  =  ( DID_NO_CONNECT  < <  16 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( cp - > status  = =  LOCKED )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cp - > status  =  FREE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											eata_stat  =  inb ( base  +  HA_RSTATUS ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											printk ( KERN_CRIT  " eata_pio: int_handler, freeing locked  "  " queueslot \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# if DBG_INTR2 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( stat  ! =  0x50 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											printk ( KERN_DEBUG  " stat: %#.2x, result: %#.8x \n " ,  stat ,  cmd - > result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cp - > status  =  FREE ; 	/* now we can release the slot  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cmd - > scsi_done ( cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  unsigned  int  eata_pio_send_command ( unsigned  long  base ,  unsigned  char  command )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  int  loop  =  50 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( inb ( base  +  HA_RSTATUS )  &  HA_SBUSY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( - - loop  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Enable interrupts for HBA.  It is not the best way to do it at this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  place ,  but  I  hope  that  it  doesn ' t  interfere  with  the  IDE  driver  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  initialization  this  way  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									outb ( HA_CTRL_8HEADS ,  base  +  HA_CTRLREG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									outb ( command ,  base  +  HA_WCOMMAND ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 02:10:29 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  eata_pio_queue_lck ( struct  scsi_cmnd  * cmd ,  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										void  ( * done ) ( struct  scsi_cmnd  * ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  int  x ,  y ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  long  base ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hostdata  * hd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  Scsi_Host  * sh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  eata_ccb  * cp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queue_counter + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hd  =  HD ( cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh  =  cmd - > device - > host ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									base  =  sh - > base ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* use only slot 0, as 2001 can handle only one cmd at a time */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									y  =  x  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hd - > ccb [ y ] . status  ! =  FREE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DBG ( DBG_QUEUE ,  printk ( KERN_EMERG  " can_queue %d, x %d, y %d \n " ,  sh - > can_queue ,  x ,  y ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# if DEBUG_EATA 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( KERN_EMERG  " eata_pio: run out of queue slots cmdno:%ld  "  " intrno: %ld \n " ,  queue_counter ,  int_counter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( KERN_EMERG  " eata_pio: run out of queue slots.... \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp  =  & hd - > ccb [ y ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( cp ,  0 ,  sizeof ( struct  eata_ccb ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp - > status  =  USED ; 	/* claim free slot */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-24 18:04:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DBG ( DBG_QUEUE ,  scmd_printk ( KERN_DEBUG ,  cmd , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-04 09:42:14 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" eata_pio_queue 0x%p, y %d \n " ,  cmd ,  y ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cmd - > scsi_done  =  ( void  * )  done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( cmd - > sc_data_direction  = =  DMA_TO_DEVICE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cp - > DataOut  =  1 ; 	/* Output mode */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cp - > DataIn  =  0 ; 	/* Input mode  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp - > Interpret  =  ( cmd - > device - > id  = =  hd - > hostid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-09 21:10:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cp - > cp_datalen  =  cpu_to_be32 ( scsi_bufflen ( cmd ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									cp - > Auto_Req_Sen  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cp - > cp_reqDMA  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									cp - > reqlen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp - > cp_id  =  cmd - > device - > id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp - > cp_lun  =  cmd - > device - > lun ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp - > cp_dispri  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp - > cp_identify  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memcpy ( cp - > cp_cdb ,  cmd - > cmnd ,  COMMAND_SIZE ( * cmd - > cmnd ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cp - > cp_statDMA  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp - > cp_viraddr  =  cp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp - > cmd  =  cmd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cmd - > host_scribble  =  ( char  * )  & hd - > ccb [ y ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-09-09 21:10:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! scsi_bufflen ( cmd ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										cmd - > SCp . buffers_residual  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-09 21:10:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cmd - > SCp . ptr  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cmd - > SCp . this_residual  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										cmd - > SCp . buffer  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-09 21:10:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cmd - > SCp . buffer  =  scsi_sglist ( cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cmd - > SCp . buffers_residual  =  scsi_sg_count ( cmd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-22 21:19:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cmd - > SCp . ptr  =  sg_virt ( cmd - > SCp . buffer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										cmd - > SCp . this_residual  =  cmd - > SCp . buffer - > length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cmd - > SCp . Status  =  ( cmd - > SCp . this_residual  ! =  0 ) ; 	/* TRUE as long as bytes 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																 *  are  to  transfer  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( eata_pio_send_command ( base ,  EATA_CMD_PIO_SEND_CP ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cmd - > result  =  DID_BUS_BUSY  < <  16 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-24 18:04:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										scmd_printk ( KERN_NOTICE ,  cmd , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-04 09:42:14 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											" eata_pio_queue pid 0x%p, HBA busy,  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" returning DID_BUS_BUSY, done. \n " ,  cmd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										done ( cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cp - > status  =  FREE ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-20 15:15:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* FIXME: timeout */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ! ( inb ( base  +  HA_RSTATUS )  &  HA_SDRQ ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cpu_relax ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									outsw ( base  +  HA_RDATA ,  cp ,  hd - > cplen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									outb ( EATA_CMD_PIO_TRUNC ,  base  +  HA_WCOMMAND ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  hd - > cppadlen ;  x + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										outw ( 0 ,  base  +  HA_RDATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-24 18:04:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DBG ( DBG_QUEUE ,  scmd_printk ( KERN_DEBUG ,  cmd , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-04 09:42:14 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" Queued base %#.4lx cmd: 0x%p  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" slot %d irq %d \n " ,  sh - > base ,  cmd ,  y ,  sh - > irq ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-09-20 15:15:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 02:10:29 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  DEF_SCSI_QCMD ( eata_pio_queue )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  eata_pio_abort ( struct  scsi_cmnd  * cmd )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  int  loop  =  100 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-24 18:04:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DBG ( DBG_ABNORM ,  scmd_printk ( KERN_WARNING ,  cmd , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-04 09:42:14 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" eata_pio_abort called pid: 0x%p \n " ,  cmd ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( inb ( cmd - > device - > host - > base  +  HA_RAUXSTAT )  &  HA_ABUSY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( - - loop  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											printk ( KERN_WARNING  " eata_pio: abort, timeout error. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( CD ( cmd ) - > status  = =  FREE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DBG ( DBG_ABNORM ,  printk ( KERN_WARNING  " Returning: SCSI_ABORT_NOT_RUNNING \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( CD ( cmd ) - > status  = =  USED )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DBG ( DBG_ABNORM ,  printk ( KERN_WARNING  " Returning: SCSI_ABORT_BUSY \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* We want to sleep a bit more here */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  FAILED ; 		/* SNOOZE */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( CD ( cmd ) - > status  = =  RESET )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										printk ( KERN_WARNING  " eata_pio: abort, command reset error. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( CD ( cmd ) - > status  = =  LOCKED )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DBG ( DBG_ABNORM ,  printk ( KERN_WARNING  " eata_pio: abort, queue slot  "  " locked. \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									panic ( " eata_pio: abort: invalid slot status \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  eata_pio_host_reset ( struct  scsi_cmnd  * cmd )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  int  x ,  limit  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									unsigned  char  success  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  scsi_cmnd  * sp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  Scsi_Host  * host  =  cmd - > device - > host ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-24 18:04:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DBG ( DBG_ABNORM ,  scmd_printk ( KERN_WARNING ,  cmd , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-04 09:42:14 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" eata_pio_reset called \n " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-05-28 07:57:14 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									spin_lock_irq ( host - > host_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( HD ( cmd ) - > state  = =  RESET )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										printk ( KERN_WARNING  " eata_pio_reset: exit, already in reset. \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-28 07:57:14 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										spin_unlock_irq ( host - > host_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* force all slots to be free */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  cmd - > device - > host - > can_queue ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( HD ( cmd ) - > ccb [ x ] . status  = =  FREE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sp  =  HD ( cmd ) - > ccb [ x ] . cmd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										HD ( cmd ) - > ccb [ x ] . status  =  RESET ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-04 09:42:14 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										printk ( KERN_WARNING  " eata_pio_reset: slot %d in reset. \n " ,  x ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( sp  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											panic ( " eata_pio_reset: slot %d, sp==NULL. \n " ,  x ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* hard reset the HBA  */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									outb ( EATA_CMD_RESET ,  cmd - > device - > host - > base  +  HA_WCOMMAND ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DBG ( DBG_ABNORM ,  printk ( KERN_WARNING  " eata_pio_reset: board reset done. \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HD ( cmd ) - > state  =  RESET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									spin_unlock_irq ( host - > host_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msleep ( 3000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									spin_lock_irq ( host - > host_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DBG ( DBG_ABNORM ,  printk ( KERN_WARNING  " eata_pio_reset: interrupts disabled,  "  " loops %d. \n " ,  limit ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  cmd - > device - > host - > can_queue ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Skip slots already set free by interrupt */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( HD ( cmd ) - > ccb [ x ] . status  ! =  RESET ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sp  =  HD ( cmd ) - > ccb [ x ] . cmd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sp - > result  =  DID_RESET  < <  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* This mailbox is terminated */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										printk ( KERN_WARNING  " eata_pio_reset: reset ccb %d. \n " ,  x ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										HD ( cmd ) - > ccb [ x ] . status  =  FREE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sp - > scsi_done ( sp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HD ( cmd ) - > state  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-05-28 07:57:14 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									spin_unlock_irq ( host - > host_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( success )  { 		/* hmmm... */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DBG ( DBG_ABNORM ,  printk ( KERN_WARNING  " eata_pio_reset: exit, success. \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DBG ( DBG_ABNORM ,  printk ( KERN_WARNING  " eata_pio_reset: exit, wakeup. \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * get_pio_board_data ( unsigned  long  base ,  unsigned  int  irq ,  unsigned  int  id ,  unsigned  long  cplen ,  unsigned  short  cppadlen )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  eata_ccb  cp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  char  buff [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  z ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( & cp ,  0 ,  sizeof ( struct  eata_ccb ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( buff ,  0 ,  sizeof ( buff ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp . DataIn  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp . Interpret  =  1 ; 	/* Interpret command */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cp . cp_datalen  =  cpu_to_be32 ( 254 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp . cp_dataDMA  =  cpu_to_be32 ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp . cp_id  =  id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp . cp_lun  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp . cp_cdb [ 0 ]  =  INQUIRY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp . cp_cdb [ 1 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp . cp_cdb [ 2 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp . cp_cdb [ 3 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp . cp_cdb [ 4 ]  =  254 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp . cp_cdb [ 5 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( eata_pio_send_command ( base ,  EATA_CMD_PIO_SEND_CP ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-20 15:15:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ! ( inb ( base  +  HA_RSTATUS )  &  HA_SDRQ ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cpu_relax ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									outsw ( base  +  HA_RDATA ,  & cp ,  cplen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									outb ( EATA_CMD_PIO_TRUNC ,  base  +  HA_WCOMMAND ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( z  =  0 ;  z  <  cppadlen ;  z + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										outw ( 0 ,  base  +  HA_RDATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-09-20 15:15:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( inb ( base  +  HA_RSTATUS )  &  HA_SBUSY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cpu_relax ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( inb ( base  +  HA_RSTATUS )  &  HA_SERROR ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-20 15:15:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									else  if  ( ! ( inb ( base  +  HA_RSTATUS )  &  HA_SDRQ ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-20 15:15:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										insw ( base  +  HA_RDATA ,  & buff ,  127 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( inb ( base  +  HA_RSTATUS )  &  HA_SDRQ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											inw ( base  +  HA_RDATA ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-20 15:15:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  buff ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  get_pio_conf_PIO ( unsigned  long  base ,  struct  get_conf  * buf )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  long  loop  =  HZ  /  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  z ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  short  * p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! request_region ( base ,  9 ,  " eata_pio " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( buf ,  0 ,  sizeof ( struct  get_conf ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( inb ( base  +  HA_RSTATUS )  &  HA_SBUSY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( - - loop  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DBG ( DBG_PIO  & &  DBG_PROBE ,  printk ( KERN_DEBUG  " Issuing PIO READ CONFIG to HBA at %#lx \n " ,  base ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									eata_pio_send_command ( base ,  EATA_CMD_PIO_READ_CONFIG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									loop  =  50 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  ( p  =  ( unsigned  short  * )  buf ;  ( long )  p  < =  ( ( long )  buf  +  ( sizeof ( struct  get_conf )  /  2 ) ) ;  p + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( ! ( inb ( base  +  HA_RSTATUS )  &  HA_SDRQ ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( - - loop  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										loop  =  50 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										* p  =  inw ( base  +  HA_RDATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( inb ( base  +  HA_RSTATUS )  &  HA_SERROR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DBG ( DBG_PROBE ,  printk ( " eata_dma: get_conf_PIO, error during  " 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													" transfer for HBA at %lx \n " ,  base ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( cpu_to_be32 ( EATA_SIGNATURE )  ! =  buf - > signature ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DBG ( DBG_PIO  & &  DBG_PROBE ,  printk ( KERN_NOTICE  " EATA Controller found  " 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												" at %#4lx EATA Level: %x \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												base ,  ( unsigned  int )  ( buf - > version ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( inb ( base  +  HA_RSTATUS )  &  HA_SDRQ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										inw ( base  +  HA_RDATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ALLOW_DMA_BOARDS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( z  =  0 ;  z  <  MAXISA ;  z + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( base  = =  ISAbases [ z ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												buf - > IRQ  =  ISAirqs [ z ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 fail : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									release_region ( base ,  9 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  print_pio_config ( struct  get_conf  * gc )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									printk ( " Please check values: (read config data) \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									printk ( " LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d \n " ,  be32_to_cpu ( gc - > len ) ,  gc - > version ,  gc - > OCS_enabled ,  gc - > TAR_support ,  gc - > TRNXFR ,  gc - > MORE_support ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									printk ( " HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d \n " ,  gc - > HAA_valid ,  gc - > scsi_id [ 3 ] ,  gc - > scsi_id [ 2 ] ,  gc - > scsi_id [ 1 ] ,  be16_to_cpu ( gc - > queuesiz ) ,  be16_to_cpu ( gc - > SGsiz ) ,  gc - > SECOND ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									printk ( " IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d \n " ,  gc - > IRQ ,  gc - > IRQ_TR ,  gc - > FORCADR ,  gc - > MAX_CHAN ,  gc - > ID_qest ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  unsigned  int  print_selftest ( unsigned  int  base )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  buffer [ 512 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef VERBOSE_SETUP 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  z ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									printk ( " eata_pio: executing controller self test & setup... \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( inb ( base  +  HA_RSTATUS )  &  HA_SBUSY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									outb ( EATA_CMD_PIO_SETUPTEST ,  base  +  HA_WCOMMAND ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( inb ( base  +  HA_RSTATUS )  &  HA_SBUSY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* nothing */  ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( inb ( base  +  HA_RSTATUS )  &  HA_SDRQ )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											insw ( base  +  HA_RDATA ,  & buffer ,  256 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef VERBOSE_SETUP 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* no beeps please... */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( z  =  0 ;  z  <  511  & &  buffer [ z ] ;  z + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( buffer [ z ]  ! =  7 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													printk ( " %c " ,  buffer [ z ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  while  ( inb ( base  +  HA_RSTATUS )  &  ( HA_SBUSY  |  HA_SDRQ ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ( ! ( inb ( base  +  HA_RSTATUS )  &  HA_SERROR ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  register_pio_HBA ( long  base ,  struct  get_conf  * gc ,  struct  pci_dev  * pdev )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  long  size  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * buff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  long  cplen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  short  cppadlen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  Scsi_Host  * sh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hostdata  * hd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DBG ( DBG_REGISTER ,  print_pio_config ( gc ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( gc - > DMA_support )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										printk ( " HBA at %#.4lx supports DMA. Please use EATA-DMA driver. \n " ,  base ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ALLOW_DMA_BOARDS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( buff  =  get_pio_board_data ( base ,  gc - > IRQ ,  gc - > scsi_id [ 3 ] ,  cplen  =  ( cpu_to_be32 ( gc - > cplen )  +  1 )  /  2 ,  cppadlen  =  ( cpu_to_be16 ( gc - > cppadlen )  +  1 )  /  2 ) )  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										printk ( " HBA at %#lx didn't react on INQUIRY. Sorry. \n " ,  base ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! print_selftest ( base )  & &  ! ALLOW_DMA_BOARDS )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										printk ( " HBA at %#lx failed while performing self test & setup. \n " ,  base ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									size  =  sizeof ( hostdata )  +  ( sizeof ( struct  eata_ccb )  *  be16_to_cpu ( gc - > queuesiz ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh  =  scsi_register ( & driver_template ,  size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sh  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! reg_IRQ [ gc - > IRQ ] )  { 	/* Interrupt already registered ? */ 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-05 06:09:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! request_irq ( gc - > IRQ ,  do_eata_pio_int_handler ,  0 ,  " EATA-PIO " ,  sh ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											reg_IRQ [ gc - > IRQ ] + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! gc - > IRQ_TR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reg_IRQL [ gc - > IRQ ]  =  1 ; 	/* IRQ is edge triggered */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											printk ( " Couldn't allocate IRQ %d, Sorry. \n " ,  gc - > IRQ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 		/* More than one HBA on this IRQ */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( reg_IRQL [ gc - > IRQ ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											printk ( " Can't support more than one HBA on this IRQ, \n "  "   if the IRQ is edge triggered. Sorry. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reg_IRQ [ gc - > IRQ ] + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hd  =  SD ( sh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									memset ( hd - > ccb ,  0 ,  ( sizeof ( struct  eata_ccb )  *  be16_to_cpu ( gc - > queuesiz ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( hd - > reads ,  0 ,  sizeof ( hd - > reads ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strlcpy ( SD ( sh ) - > vendor ,  & buff [ 8 ] ,  sizeof ( SD ( sh ) - > vendor ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strlcpy ( SD ( sh ) - > name ,  & buff [ 16 ] ,  sizeof ( SD ( sh ) - > name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SD ( sh ) - > revision [ 0 ]  =  buff [ 32 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SD ( sh ) - > revision [ 1 ]  =  buff [ 33 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SD ( sh ) - > revision [ 2 ]  =  buff [ 34 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SD ( sh ) - > revision [ 3 ]  =  ' . ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SD ( sh ) - > revision [ 4 ]  =  buff [ 35 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SD ( sh ) - > revision [ 5 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  ( be32_to_cpu ( gc - > len ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  0x1c : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SD ( sh ) - > EATA_revision  =  ' a ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  0x1e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SD ( sh ) - > EATA_revision  =  ' b ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  0x22 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SD ( sh ) - > EATA_revision  =  ' c ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  0x24 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SD ( sh ) - > EATA_revision  =  ' z ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SD ( sh ) - > EATA_revision  =  ' ? ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( be32_to_cpu ( gc - > len )  > =  0x22 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( gc - > is_PCI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hd - > bustype  =  IS_PCI ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else  if  ( gc - > is_EISA ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hd - > bustype  =  IS_EISA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hd - > bustype  =  IS_ISA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( buff [ 21 ]  = =  ' 4 ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hd - > bustype  =  IS_PCI ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else  if  ( buff [ 21 ]  = =  ' 2 ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hd - > bustype  =  IS_EISA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hd - > bustype  =  IS_ISA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SD ( sh ) - > cplen  =  cplen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SD ( sh ) - > cppadlen  =  cppadlen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SD ( sh ) - > hostid  =  gc - > scsi_id [ 3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SD ( sh ) - > devflags  =  1  < <  gc - > scsi_id [ 3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SD ( sh ) - > moresupport  =  gc - > MORE_support ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh - > unique_id  =  base ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh - > base  =  base ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh - > io_port  =  base ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh - > n_io_port  =  9 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh - > irq  =  gc - > IRQ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh - > dma_channel  =  PIO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh - > this_id  =  gc - > scsi_id [ 3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh - > can_queue  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh - > cmd_per_lun  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh - > sg_tablesize  =  SG_ALL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hd - > channel  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hd - > pdev  =  pci_dev_get ( pdev ) ; 	/* Keep a PCI reference */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									sh - > max_id  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sh - > max_lun  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( gc - > SECOND ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hd - > primary  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hd - > primary  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hd - > next  =  NULL ; 	/* build a linked list of all HBAs */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hd - > prev  =  last_HBA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hd - > prev  ! =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SD ( hd - > prev ) - > next  =  sh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									last_HBA  =  sh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( first_HBA  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										first_HBA  =  sh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									registered_HBAs + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  find_pio_ISA ( struct  get_conf  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  MAXISA ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ISAbases [ i ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! get_pio_conf_PIO ( ISAbases [ i ] ,  buf ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! register_pio_HBA ( ISAbases [ i ] ,  buf ,  NULL ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											release_region ( ISAbases [ i ] ,  9 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ISAbases [ i ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  find_pio_EISA ( struct  get_conf  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u32  base ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef CHECKPAL 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u8  pal1 ,  pal2 ,  pal3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  MAXEISA ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( EISAbases [ i ] )  { 	/* Still a possibility ?          */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											base  =  0x1c88  +  ( i  *  0x1000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef CHECKPAL 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pal1  =  inb ( ( u16 )  base  -  8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pal2  =  inb ( ( u16 )  base  -  7 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pal3  =  inb ( ( u16 )  base  -  6 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( ( pal1  = =  0x12 )  & &  ( pal2  = =  0x14 ) )  | |  ( ( pal1  = =  0x38 )  & &  ( pal2  = =  0xa3 )  & &  ( pal3  = =  0x82 ) )  | |  ( ( pal1  = =  0x06 )  & &  ( pal2  = =  0x94 )  & &  ( pal3  = =  0x24 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												DBG ( DBG_PROBE ,  printk ( KERN_NOTICE  " EISA EATA id tags found:  "  " %x %x %x  \n " ,  ( int )  pal1 ,  ( int )  pal2 ,  ( int )  pal3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( get_pio_conf_PIO ( base ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													DBG ( DBG_PROBE  & &  DBG_EISA ,  print_pio_config ( buf ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( buf - > IRQ )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( ! register_pio_HBA ( base ,  buf ,  NULL ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															release_region ( base ,  9 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														printk ( KERN_NOTICE  " eata_dma: No valid IRQ. HBA  "  " removed from list \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														release_region ( base ,  9 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Nothing found here so we take it from the list */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												EISAbases [ i ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef CHECKPAL 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  find_pio_PCI ( struct  get_conf  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef CONFIG_PCI 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									printk ( " eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  pci_dev  * dev  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  long  base ,  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( ( dev  =  pci_get_device ( PCI_VENDOR_ID_DPT ,  PCI_DEVICE_ID_DPT ,  dev ) )  ! =  NULL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										DBG ( DBG_PROBE  & &  DBG_PCI ,  printk ( " eata_pio: find_PCI, HBA at %s \n " ,  pci_name ( dev ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pci_enable_device ( dev ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pci_set_master ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										base  =  pci_resource_flags ( dev ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( base  &  IORESOURCE_MEM )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											printk ( " eata_pio: invalid base address of device %s \n " ,  pci_name ( dev ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										base  =  pci_resource_start ( dev ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* EISA tag there ? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( inb ( base )  = =  0x12 )  & &  ( inb ( base  +  1 )  = =  0x14 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 	/* Jep, it's forced, so move on  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										base  + =  0x10 ; 	/* Now, THIS is the real address */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( base  ! =  0x1f8 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* We didn't find it in the primary search */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( get_pio_conf_PIO ( base ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( buf - > FORCADR )  { 	/* If the address is forced */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													release_region ( base ,  9 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue ; 	/* we'll find it later      */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* OK. We made it till here, so we can go now  
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  and  register  it .  We   only  have  to  check  and  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  eventually  remove  it  from  the  EISA  and  ISA  list  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! register_pio_HBA ( base ,  buf ,  dev ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													release_region ( base ,  9 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( base  <  0x1000 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													for  ( x  =  0 ;  x  <  MAXISA ;  + + x )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( ISAbases [ x ]  = =  base )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ISAbases [ x ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ( base  &  0x0fff )  = =  0x0c88 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													x  =  ( base  > >  12 )  &  0x0f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													EISAbases [ x ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef CHECK_BLINK 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else  if  ( check_blink_state ( base ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												printk ( " eata_pio: HBA is in BLINK state. \n "  " Consult your HBAs manual to correct this. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif				 /* #ifndef CONFIG_PCI */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  eata_pio_detect ( struct  scsi_host_template  * tpnt )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  Scsi_Host  * HBA_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  get_conf  gc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									find_pio_PCI ( & gc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									find_pio_EISA ( & gc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									find_pio_ISA ( & gc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-23 15:11:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  MAXIRQ ;  i + + ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( reg_IRQ [ i ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-05 06:09:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											request_irq ( i ,  do_eata_pio_int_handler ,  0 ,  " EATA-PIO " ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HBA_ptr  =  first_HBA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( registered_HBAs  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										printk ( " EATA (Extended Attachment) PIO driver version: %d.%d%s \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       " (c) 1993-95 Michael Neuffer, neuffer@goofy.zdv.uni-mainz.de \n "  "             Alfred Arnold,   a.arnold@kfa-juelich.de \n "  " This release only supports DASD devices (harddisks) \n " ,  VER_MAJOR ,  VER_MINOR ,  VER_SUB ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										printk ( " Registered HBAs: \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										printk ( " HBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: Ch: ID: Pr: "  "  QS: SG: CPL: \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( i  =  1 ;  i  < =  registered_HBAs ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											printk ( " scsi%-2d: %.10s v%s 2.0%c  %s %#.4lx   %2d   %d   %d   %c " 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											       "   %2d  %2d  %2d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       HBA_ptr - > host_no ,  SD ( HBA_ptr ) - > name ,  SD ( HBA_ptr ) - > revision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       SD ( HBA_ptr ) - > EATA_revision ,  ( SD ( HBA_ptr ) - > bustype  = =  ' P ' )  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       " PCI  "  :  ( SD ( HBA_ptr ) - > bustype  = =  ' E ' )  ?  " EISA "  :  " ISA  " , 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:18:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       HBA_ptr - > base ,  HBA_ptr - > irq ,  SD ( HBA_ptr ) - > channel ,  HBA_ptr - > this_id , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											       SD ( HBA_ptr ) - > primary  ?  ' Y '  :  ' N ' ,  HBA_ptr - > can_queue , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       HBA_ptr - > sg_tablesize ,  HBA_ptr - > cmd_per_lun ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HBA_ptr  =  SD ( HBA_ptr ) - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ( registered_HBAs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  scsi_host_template  driver_template  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. proc_name 		=  " eata_pio " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. name               	=  " EATA (Extended Attachment) PIO driver " , 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-31 03:18:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. show_info          	=  eata_pio_show_info , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									. detect             	=  eata_pio_detect , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. release            	=  eata_pio_release , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. queuecommand       	=  eata_pio_queue , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. eh_abort_handler   	=  eata_pio_abort , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. eh_host_reset_handler 	=  eata_pio_host_reset , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. use_clustering     	=  ENABLE_CLUSTERING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_AUTHOR ( " Michael Neuffer, Alfred Arnold " ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_DESCRIPTION ( " EATA SCSI PIO driver " ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_LICENSE ( " GPL " ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "scsi_module.c"