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
- Lines: 218
- Date:
Thu Apr 2 09:12:25 1998
- Orig file:
v2.1.92/linux/drivers/scsi/fdomain.c
- Orig date:
Fri Nov 7 10:16:36 1997
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