patch-2.1.93 linux/drivers/scsi/fdomain.c

Next file: linux/drivers/scsi/gdth.c
Previous file: linux/drivers/scsi/eata_pio.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.92/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
@@ -20,6 +20,8 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 675 Mass Ave, Cambridge, MA 02139, USA.
 
+ * PCI detection rewritten by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+
  **************************************************************************
 
  SUMMARY:
@@ -266,7 +268,6 @@
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/proc_fs.h>
-#include <linux/bios32.h>
 #include <linux/pci.h>
 #include <linux/stat.h>
 
@@ -749,168 +750,63 @@
    return 1;			/* success */
 }
 
-static int fdomain_pci_nobios_detect( int *irq, int *iobase )
-{
-   int i;
-   int flag = 0;
-
-   /* The proper way of doing this is to use ask the PCI bus for the device
-      IRQ and interrupt level.  But we can't do that if PCI BIOS32 support
-      isn't compiled into the kernel, or if a PCI BIOS32 isn't present.
-
-      Instead, we scan down a bunch of addresses (Future Domain tech
-      support says we will probably find the address before we get to
-      0xf800).  This works fine on some systems -- other systems may have
-      to scan more addresses.  If you have to modify this section for your
-      installation, please send mail to faith@cs.unc.edu. */
-
-   for (i = 0xfff8; i > 0xe000; i -= 8) {
-      if (check_region( i, 0x10 )) {
-#if DEBUG_DETECT
-	 printk( " (%x inuse)," , i );
-#endif
-	 continue;
-      }
-      if ((flag = fdomain_is_valid_port( i ))) break;
-   }
-
-   if (!flag) return 0;		/* iobase not found */
-
-   *irq    = fdomain_get_irq( i );
-   *iobase = i;
-
-   return 1;			/* success */
-}
-
 /* PCI detection function: int fdomain_pci_bios_detect(int* irq, int*
    iobase) This function gets the Interrupt Level and I/O base address from
-   the PCI configuration registers.  The I/O base address is masked with
-   0xfff8 since on my card the address read from the PCI config registers
-   is off by one from the actual I/O base address necessary for accessing
-   the status and control registers on the card (PCI config register gives
-   0xf801, actual address is 0xf800).  This is likely a bug in the FD
-   config code that writes to the PCI registers, however using a mask
-   should be safe since I think the scan done by the card to determine the
-   I/O base is done in increments of 8 (i.e., 0xf800, 0xf808, ...), at
-   least the old scan code we used to use to get the I/O base did...  Also,
-   the device ID from the PCI config registers is 0x0 and should be 0x60e9
-   as it is in the status registers (offset 5 from I/O base).  If this is
-   changed in future hardware/BIOS changes it will need to be fixed in this
-   detection function.  Comments, bug reports, etc... on this function
-   should be sent to mckinley@msupa.pa.msu.edu - James T. McKinley.  */
+   the PCI configuration registers. */
 
 #ifdef CONFIG_PCI
 static int fdomain_pci_bios_detect( int *irq, int *iobase )
 {
-   int              error;
-   unsigned char    pci_bus, pci_dev_fn;    /* PCI bus & device function */
-   unsigned char    pci_irq;                /* PCI interrupt line */
-   unsigned int     pci_base;               /* PCI I/O base address */
-   unsigned short   pci_vendor, pci_device; /* PCI vendor & device IDs */
-
-   /* If the PCI BIOS doesn't exist, use the old-style detection routines.
-      Otherwise, get the I/O base address and interrupt from the PCI config
-      registers. */
-   
-   if (!pcibios_present()) return fdomain_pci_nobios_detect( irq, iobase );
+   unsigned int     pci_irq;                /* PCI interrupt line */
+   unsigned long    pci_base;               /* PCI I/O base address */
+   struct pci_dev   *pdev = NULL;
+
+   if (!pci_present()) return 0;
 
 #if DEBUG_DETECT
    /* Tell how to print a list of the known PCI devices from bios32 and
       list vendor and device IDs being used if in debug mode.  */
       
-   printk( "\nINFO: cat /proc/pci to see list of PCI devices from bios32\n" );
+   printk( "\nINFO: use lspci -v to see list of PCI devices\n" );
    printk( "\nTMC-3260 detect:"
 	   " Using PCI Vendor ID: 0x%x, PCI Device ID: 0x%x\n",
 	   PCI_VENDOR_ID_FD, 
 	   PCI_DEVICE_ID_FD_36C70 );
 #endif 
 
-   /* We will have to change this if more than 1 PCI bus is present and the
-      FD scsi host is not on the first bus (i.e., a PCI to PCI bridge,
-      which is not supported by bios32 right now anyway).  This should
-      probably be done by a call to pcibios_find_device but I can't get it
-      to work...  Also the device ID reported from the PCI config registers
-      does not match the device ID quoted in the tech manual or available
-      from offset 5 from the I/O base address.  It should be 0x60E9, but it
-      is 0x0 if read from the PCI config registers.  I guess the FD folks
-      neglected to write it to the PCI registers...  This loop is necessary
-      to get the device function (at least until someone can get
-      pcibios_find_device to work, I cannot but 53c7,8xx.c uses it...). */
-    
-   pci_bus = 0;
-
-   for (pci_dev_fn = 0x0; pci_dev_fn < 0xff; pci_dev_fn++) {
-      pcibios_read_config_word( pci_bus,
-				pci_dev_fn,
-				PCI_VENDOR_ID,
-				&pci_vendor );
-
-      if (pci_vendor == PCI_VENDOR_ID_FD) {
-	 pcibios_read_config_word( pci_bus,
-				   pci_dev_fn,
-				   PCI_DEVICE_ID,
-				   &pci_device );
-
-	 if (pci_device == PCI_DEVICE_ID_FD_36C70) {
-	    /* Break out once we have the correct device.  If other FD
-	       PCI devices are added to this driver we will need to add
-	       an or of the other PCI_DEVICE_ID_FD_XXXXX's here. */
-	    break;
-	 } else {
-	    /* If we can't find an FD scsi card we give up. */
-	    return 0;
-	 }
-      }
-   }
+   if ((pdev = pci_find_device(PCI_VENDOR_ID, PCI_DEVICE_ID, pdev)) == NULL)
+     return 0;
        
 #if DEBUG_DETECT
    printk( "Future Domain 36C70 : at PCI bus %u, device %u, function %u\n",
-	   pci_bus,
-	   (pci_dev_fn & 0xf8) >> 3, 
-	   pci_dev_fn & 7 );
+	   pdev->bus->number,
+	   PCI_SLOT(pdev->devfn),
+	   PCI_FUNC(pdev->devfn));
 #endif
 
    /* We now have the appropriate device function for the FD board so we
       just read the PCI config info from the registers.  */
 
-   if ((error = pcibios_read_config_dword( pci_bus,
-					   pci_dev_fn, 
-					   PCI_BASE_ADDRESS_0,
-					   &pci_base ))
-       || (error = pcibios_read_config_byte( pci_bus,
-					     pci_dev_fn, 
-					     PCI_INTERRUPT_LINE,
-					     &pci_irq ))) {
-      printk ( "PCI ERROR: Future Domain 36C70 not initializing"
-	       " due to error reading configuration space\n" );
-      return 0;
-   } else {
+   pci_base = pdev->base_address[0];
+   pci_irq = pdev->irq;
 #if DEBUG_DETECT
       printk( "TMC-3260 PCI: IRQ = %u, I/O base = 0x%lx\n", 
 	      pci_irq, pci_base );
 #endif
 
-      /* Now we have the I/O base address and interrupt from the PCI
-	 configuration registers.  Unfortunately it seems that the I/O base
-	 address is off by one on my card so I mask it with 0xfff8.  This
-	 must be some kind of goof in the FD code that does the autoconfig
-	 and writes to the PCI registers (or maybe I just don't understand
-	 something).  If they fix it in later versions of the card or BIOS
-	 we may have to adjust the address based on the signature or
-	 something...  */
+   /* Now we have the I/O base address and interrupt from the PCI
+      configuration registers. */
 
-      *irq    = pci_irq;
-      *iobase = (pci_base & 0xfff8);
+   *irq    = pci_irq;
+   *iobase = (pci_base & PCI_BASE_ADDRESS_IO_MASK);
 
 #if DEBUG_DETECT
-      printk( "TMC-3260 fix: Masking I/O base address with 0xff00.\n" ); 
-      printk( "TMC-3260: IRQ = %d, I/O base = 0x%x\n", *irq, *iobase );
+   printk( "TMC-3260 fix: Masking I/O base address with 0xff00.\n" ); 
+   printk( "TMC-3260: IRQ = %d, I/O base = 0x%x\n", *irq, *iobase );
 #endif
 
-      if (!fdomain_is_valid_port( *iobase )) return 0;
-      return 1;
-   }
-   return 0;
+   if (!fdomain_is_valid_port( *iobase )) return 0;
+   return 1;
 }
 #endif
 
@@ -978,7 +874,8 @@
 #ifdef CONFIG_PCI
 	 flag = fdomain_pci_bios_detect( &interrupt_level, &port_base );
 #else
-	 flag = fdomain_pci_nobios_detect( &interrupt_level, &port_base );
+	 printk(KERN_ERR "No PCI support in this kernel, giving up.\n");
+	 flag = 0;
 #endif
       }
 	 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov