patch-2.2.0-pre2 linux/drivers/scsi/fdomain.c
Next file: linux/drivers/scsi/ibmmca.c
Previous file: linux/drivers/scsi/eata_pio_proc.c
Back to the patch index
Back to the overall index
- Lines: 577
- Date:
Tue Dec 29 11:44:53 1998
- Orig file:
v2.2.0-pre1/linux/drivers/scsi/fdomain.c
- Orig date:
Fri Oct 23 22:01:21 1998
diff -u --recursive --new-file v2.2.0-pre1/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
@@ -1,10 +1,8 @@
/* fdomain.c -- Future Domain TMC-16x0 SCSI driver
* Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu
- * Revised: Wed Oct 2 11:10:55 1996 by faith@acm.org
+ * Revised: Mon Dec 28 21:59:02 1998 by faith@acm.org
* Author: Rickard E. Faith, faith@cs.unc.edu
- * Copyright 1992, 1993, 1994, 1995, 1996 Rickard E. Faith
- *
- * Version 5.46 (23-04-1998)
+ * Copyright 1992-1996, 1998 Rickard E. Faith (faith@acm.org)
* 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
@@ -32,13 +30,34 @@
Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX
Future Domain TMC-3260 (PCI)
Quantum ISA-200S, ISA-250MG
- Adaptec AHA-2920 (PCI)
+ Adaptec AHA-2920A (PCI) [BUT *NOT* AHA-2920C -- use aic7xxx instead]
IBM ?
- LILO command-line options:
+ LILO/INSMOD command-line options:
fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]
+
+ NOTE:
+
+ The Adaptec AHA-2920C has an Adaptec AIC-7850 chip on it.
+ Use the aic7xxx driver for this board.
+
+ The Adaptec AHA-2920A has a Future Domain chip on it, so this is the right
+ driver for that card. Unfortunately, the boxes will probably just say
+ "2920", so you'll have to look on the card for a Future Domain logo, or a
+ letter after the 2920.
+
+
+
+ THANKS:
+
+ Thanks to Adaptec for providing PCI boards for testing. This finally
+ enabled me to test the PCI detection and correct it for PCI boards that do
+ not have a BIOS at a standard ISA location. For PCI boards, LILO/INSMOD
+ command-line options should no longer be needed. --RF 18Nov98
+
+
DESCRIPTION:
This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
@@ -70,7 +89,7 @@
your board. Please refer to the Seagate driver for more information and
possible support.
-
+
HISTORY:
@@ -108,7 +127,8 @@
2.1.1 5.45 2 Oct 1996 Update ROM accesses for 2.1.x
2.1.97 5.46 23 Apr 1998 Rewritten PCI detection routines [mj]
2.1.11x 5.47 9 Aug 1998 Touched for 8 SCSI disk majors support
-
+ 5.48 18 Nov 1998 BIOS no longer needed for PCI detection
+ 2.2.0 5.50 28 Dec 1998 Support insmod parameters
REFERENCES USED:
@@ -207,6 +227,9 @@
patches.
New PCI detection code written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+
+ Insmod parameter code based on patches from Daniel Graham
+ <graham@balance.uoregon.edu>.
All of the alpha testers deserve much thanks.
@@ -282,7 +305,7 @@
S_IFDIR | S_IRUGO | S_IXUGO, 2
};
-#define VERSION "$Revision: 5.45 $"
+#define VERSION "$Revision: 5.50 $"
/* START OF USER DEFINABLE OPTIONS */
@@ -406,6 +429,15 @@
extern void do_fdomain_16x0_intr( int irq, void *dev_id,
struct pt_regs * regs );
+#ifdef MODULE
+ /* Allow insmod parameters to be like LILO
+ parameters. For example:
+ insmod fdomain fdomain=0x140,11
+ */
+static int fdomain[]={ 0, 0, 0 };
+MODULE_PARM(fdomain, "2-3i");
+#endif
+
static unsigned long addresses[] = {
0xc8000,
0xca000,
@@ -504,10 +536,10 @@
if (!shpnt) return; /* This won't ever happen */
if (bios_major < 0 && bios_minor < 0) {
- printk( "scsi%d <fdomain>: No BIOS; using scsi id %d\n",
+ printk( "scsi%d: <fdomain> No BIOS; using scsi id %d\n",
shpnt->host_no, shpnt->this_id );
} else {
- printk( "scsi%d <fdomain>: BIOS version ", shpnt->host_no );
+ printk( "scsi%d: <fdomain> BIOS version ", shpnt->host_no );
if (bios_major >= 0) printk( "%d.", bios_major );
else printk( "?." );
@@ -523,7 +555,7 @@
boards, we will have to modify banner
for additional PCI cards, but for now if
it's PCI it's a TMC-3260 - JTM */
- printk( "scsi%d <fdomain>: %s chip at 0x%x irq ",
+ printk( "scsi%d: <fdomain> %s chip at 0x%x irq ",
shpnt->host_no,
chip == tmc1800 ? "TMC-1800"
: (chip == tmc18c50 ? "TMC-18C50"
@@ -541,8 +573,9 @@
void fdomain_setup( char *str, int *ints )
{
if (setup_called++ || ints[0] < 2 || ints[0] > 3) {
- printk( "fdomain: usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n" );
- printk( "fdomain: bad LILO parameters?\n" );
+ printk( "scsi: <fdomain>"
+ " Usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n" );
+ printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
}
port_base = ints[0] >= 1 ? ints[1] : 0;
@@ -591,8 +624,6 @@
if (inb( port + MSB_ID_Code ) != 0x60) return 0;
chip = tmc18c50;
-#if 1
-
/* Try to toggle 32-bit mode. This only
works on an 18c30 chip. (User reports
say this works, so we should switch to
@@ -606,17 +637,6 @@
FIFO_Size = 0x800; /* 2k FIFO */
}
}
-#else
-
- /* That should have worked, but appears to
- have problems. Let's assume it is an
- 18c30 if the RAM is disabled. */
-
- if (inb( port + Configuration2 ) & 0x02) {
- chip = tmc18c30;
- FIFO_Size = 0x800; /* 2k FIFO */
- }
-#endif
/* If that failed, we are an 18c50. */
}
@@ -656,7 +676,7 @@
int options = inb( base + Configuration1 );
#if DEBUG_DETECT
- printk( " Options = %x\n", options );
+ printk( "scsi: <fdomain> Options = %x\n", options );
#endif
/* Check for board with lowest bios_base --
@@ -673,10 +693,31 @@
static int fdomain_isa_detect( int *irq, int *iobase )
{
- int i;
+ int i, j;
int base;
int flag = 0;
+#if DEBUG_DETECT
+ printk( "scsi: <fdomain> fdomain_isa_detect:" );
+#endif
+
+ for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) {
+#if DEBUG_DETECT
+ printk( " %lx(%lx),", addresses[i], bios_base );
+#endif
+ for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) {
+ if (check_signature(addresses[i] + signatures[j].sig_offset,
+ signatures[j].signature,
+ signatures[j].sig_length )) {
+ bios_major = signatures[j].major_bios_version;
+ bios_minor = signatures[j].minor_bios_version;
+ PCI_bus = (signatures[j].flag == 1);
+ Quantum = (signatures[j].flag > 1) ? signatures[j].flag : 0;
+ bios_base = addresses[i];
+ }
+ }
+ }
+
if (bios_major == 2) {
/* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
Assuming the ROM is enabled (otherwise we wouldn't have been
@@ -746,6 +787,11 @@
if ((flag = fdomain_is_valid_port( base ))) break;
}
+#if DEBUG_DETECT
+ if (flag) printk( " SUCCESS\n" );
+ else printk( " FAILURE\n" );
+#endif
+
if (!flag) return 0; /* iobase not found */
*irq = fdomain_get_irq( base );
@@ -771,18 +817,21 @@
/* 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: 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",
+ printk( "scsi: <fdomain> INFO: use lspci -v to see list of PCI devices\n" );
+ printk( "scsi: <fdomain> TMC-3260 detect:"
+ " Using Vendor ID: 0x%x and Device ID: 0x%x\n",
PCI_VENDOR_ID_FD,
PCI_DEVICE_ID_FD_36C70 );
#endif
- if ((pdev = pci_find_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL)
+ if ((pdev = pci_find_device(PCI_VENDOR_ID_FD,
+ PCI_DEVICE_ID_FD_36C70,
+ pdev)) == NULL)
return 0;
#if DEBUG_DETECT
- printk( "Future Domain 36C70 : at PCI bus %u, device %u, function %u\n",
+ printk( "scsi: <fdomain> TMC-3260 detect:"
+ " PCI bus %u, device %u, function %u\n",
pdev->bus->number,
PCI_SLOT(pdev->devfn),
PCI_FUNC(pdev->devfn));
@@ -793,10 +842,6 @@
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. */
@@ -805,18 +850,28 @@
*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( "scsi: <fdomain> TMC-3260 detect:"
+ " IRQ = %d, I/O base = 0x%x [0x%lx]\n", *irq, *iobase, pci_base );
#endif
- if (!fdomain_is_valid_port( *iobase )) return 0;
+ if (!fdomain_is_valid_port( *iobase )) {
+ printk( "scsi: <fdomain>"
+ " PCI card detected, but driver not loaded (invalid port)\n" );
+ return 0;
+ }
+
+ /* Fill in a few global variables. Ugh. */
+ bios_major = bios_minor = -1;
+ PCI_bus = 1;
+ Quantum = 0;
+ bios_base = 0;
+
return 1;
}
#endif
int fdomain_16x0_detect( Scsi_Host_Template *tpnt )
{
- int i, j;
int retcode;
struct Scsi_Host *shpnt;
#if DO_DETECT
@@ -829,68 +884,44 @@
unsigned char buf[buflen];
#endif
-#if DEBUG_DETECT
- printk( "fdomain_16x0_detect()," );
-#endif
tpnt->proc_dir = &proc_scsi_fdomain;
+#ifdef MODULE
+ if (fdomain[0] || fdomain[1] || fdomain[2]) {
+ port_base = fdomain[0];
+ interrupt_level = fdomain[1];
+ this_id = fdomain[2];
+ bios_major = bios_minor = -1;
+ ++setup_called;
+ }
+#endif
+
if (setup_called) {
#if DEBUG_DETECT
- printk( "no BIOS, using port_base = 0x%x, irq = %d\n",
+ printk( "scsi: <fdomain> No BIOS, using port_base = 0x%x, irq = %d\n",
port_base, interrupt_level );
#endif
if (!fdomain_is_valid_port( port_base )) {
- printk( "fdomain: cannot locate chip at port base 0x%x\n",
+ printk( "scsi: <fdomain> Cannot locate chip at port base 0x%x\n",
port_base );
- printk( "fdomain: bad LILO parameters?\n" );
+ printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
return 0;
}
} else {
int flag = 0;
-
- for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) {
-#if DEBUG_DETECT
- printk( " %lx(%lx),", addresses[i], bios_base );
-#endif
- for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) {
- if (check_signature(addresses[i] + signatures[j].sig_offset,
- signatures[j].signature,
- signatures[j].sig_length )) {
- bios_major = signatures[j].major_bios_version;
- bios_minor = signatures[j].minor_bios_version;
- PCI_bus = (signatures[j].flag == 1);
- Quantum = (signatures[j].flag > 1) ? signatures[j].flag : 0;
- bios_base = addresses[i];
- }
- }
- }
-
- if (!bios_base) {
-#if DEBUG_DETECT
- printk( " FAILED: NO BIOS\n" );
-#endif
- return 0;
- }
- if (!PCI_bus) {
- flag = fdomain_isa_detect( &interrupt_level, &port_base );
- } else {
#ifdef CONFIG_PCI
- flag = fdomain_pci_bios_detect( &interrupt_level, &port_base );
-#else
- printk(KERN_ERR "No PCI support in this kernel, giving up.\n");
- flag = 0;
+ /* Try PCI detection first */
+ flag = fdomain_pci_bios_detect( &interrupt_level, &port_base );
#endif
- }
-
if (!flag) {
-#if DEBUG_DETECT
- printk( " FAILED: NO PORT\n" );
-#endif
-#ifdef CONFIG_PCI
- printk( "\nTMC-3260 36C70 PCI scsi chip detection failed.\n" );
-#endif
- return 0; /* Cannot find valid set of ports */
+ /* Then try ISA bus detection */
+ flag = fdomain_isa_detect( &interrupt_level, &port_base );
+
+ if (!flag) {
+ printk( "scsi: <fdomain> Detection failed (no card)\n" );
+ return 0;
+ }
}
}
@@ -911,13 +942,10 @@
fdomain_16x0_reset( NULL, 0 );
if (fdomain_test_loopback()) {
-#if DEBUG_DETECT
- printk( "fdomain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
-#endif
+ printk( "scsi: <fdomain> Detection failed"
+ " (loopback test failed at port base 0x%x)\n", port_base );
if (setup_called) {
- printk( "fdomain: loopback test failed at port base 0x%x\n",
- port_base );
- printk( "fdomain: bad LILO parameters?\n" );
+ printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
}
return 0;
}
@@ -946,7 +974,9 @@
/* Log IRQ with kernel */
if (!interrupt_level) {
- panic( "fdomain: *NO* interrupt level selected!\n" );
+ printk( "scsi: <fdomain>"
+ " Card Detected, but driver not loaded (no IRQ)\n" );
+ return 0;
} else {
/* Register the IRQ with the kernel */
@@ -955,18 +985,21 @@
if (retcode < 0) {
if (retcode == -EINVAL) {
- printk( "fdomain: IRQ %d is bad!\n", interrupt_level );
- printk( " This shouldn't happen!\n" );
- printk( " Send mail to faith@acm.org\n" );
+ printk( "scsi: <fdomain> IRQ %d is bad!\n", interrupt_level );
+ printk( " This shouldn't happen!\n" );
+ printk( " Send mail to faith@acm.org\n" );
} else if (retcode == -EBUSY) {
- printk( "fdomain: IRQ %d is already in use!\n", interrupt_level );
- printk( " Please use another IRQ!\n" );
+ printk( "scsi: <fdomain> IRQ %d is already in use!\n",
+ interrupt_level );
+ printk( " Please use another IRQ!\n" );
} else {
- printk( "fdomain: Error getting IRQ %d\n", interrupt_level );
- printk( " This shouldn't happen!\n" );
- printk( " Send mail to faith@acm.org\n" );
+ printk( "scsi: <fdomain> Error getting IRQ %d\n",
+ interrupt_level );
+ printk( " This shouldn't happen!\n" );
+ printk( " Send mail to faith@acm.org\n" );
}
- panic( "fdomain: Driver requires interruptions\n" );
+ printk( "scsi: <fdomain> Detected, but driver not loaded (IRQ)\n" );
+ return 0;
}
}
@@ -987,7 +1020,7 @@
SCinit.use_sg = 0;
SCinit.lun = 0;
- printk( "fdomain: detection routine scanning for devices:\n" );
+ printk( "scsi: <fdomain> detection routine scanning for devices:\n" );
for (i = 0; i < 8; i++) {
SCinit.target = i;
if (i == tpnt->this_id) /* Skip host adapter */
@@ -1031,10 +1064,10 @@
const char *fdomain_16x0_info( struct Scsi_Host *ignore )
{
- static char buffer[80];
+ static char buffer[128];
char *pt;
- strcpy( buffer, "Future Domain TMC-16x0 SCSI driver, version" );
+ strcpy( buffer, "Future Domain 16-bit SCSI Driver Version" );
if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */
strcat( buffer, strchr( VERSION, ':' ) + 1 );
pt = strrchr( buffer, '$') - 1;
@@ -1118,7 +1151,7 @@
printk( "Arbitration failed, status = %x\n", status );
#endif
#if ERRORS_ONLY
- printk( "fdomain: Arbitration failed, status = %x\n", status );
+ printk( "scsi: <fdomain> Arbitration failed, status = %x\n", status );
#endif
return 1;
}
@@ -1158,7 +1191,7 @@
if (!flag) /* Skip first failure for all chips. */
++flag;
else
- printk( "fdomain: Selection failed\n" );
+ printk( "scsi: <fdomain> Selection failed\n" );
}
#endif
return 1;
@@ -1173,9 +1206,9 @@
current_SC->result = error;
if (current_SC->scsi_done)
current_SC->scsi_done( current_SC );
- else panic( "fdomain: current_SC->scsi_done() == NULL" );
+ else panic( "scsi: <fdomain> current_SC->scsi_done() == NULL" );
} else {
- panic( "fdomain: my_done() called outside of command\n" );
+ panic( "scsi: <fdomain> my_done() called outside of command\n" );
}
#if DEBUG_RACE
in_interrupt_flag = 0;
@@ -1211,7 +1244,7 @@
/* Abort calls my_done, so we do nothing here. */
if (current_SC->SCp.phase & aborted) {
#if DEBUG_ABORT
- printk( "Interrupt after abort, ignoring\n" );
+ printk( "scsi: <fdomain> Interrupt after abort, ignoring\n" );
#endif
/*
return; */
@@ -1311,7 +1344,7 @@
if (current_SC->SCp.Status
&& current_SC->SCp.Status != 2
&& current_SC->SCp.Status != 8) {
- printk( "fdomain: target = %d, command = %x, status = %x\n",
+ printk( "scsi: <fdomain> target = %d, command = %x, status = %x\n",
current_SC->target,
current_SC->cmnd[0],
current_SC->SCp.Status );
@@ -1329,7 +1362,8 @@
if (!current_SC->SCp.Message) ++done;
#if DEBUG_MESSAGES || EVERY_ACCESS
if (current_SC->SCp.Message) {
- printk( "fdomain: message = %x\n", current_SC->SCp.Message );
+ printk( "scsi: <fdomain> message = %x\n",
+ current_SC->SCp.Message );
}
#endif
break;
@@ -1590,8 +1624,8 @@
|| code == 0x24
|| !code)))
- printk( "fdomain: REQUEST SENSE "
- "Key = %x, Code = %x, Qualifier = %x\n",
+ printk( "scsi: <fdomain> REQUEST SENSE"
+ " Key = %x, Code = %x, Qualifier = %x\n",
key, code, qualifier );
}
}
@@ -1624,7 +1658,7 @@
int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
{
if (in_command) {
- panic( "fdomain: fdomain_16x0_queue() NOT REENTRANT!\n" );
+ panic( "scsi: <fdomain> fdomain_16x0_queue() NOT REENTRANT!\n" );
}
#if EVERY_ACCESS
printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
@@ -1704,7 +1738,8 @@
unsigned int isr;
if (!SCpnt || !SCpnt->host) {
- printk( "fdomain: cannot provide detailed information\n" );
+ printk( "scsi: <fdomain> Cannot provide detailed information\n" );
+ return;
}
printk( "%s\n", fdomain_16x0_info( SCpnt->host ) );
@@ -1770,7 +1805,7 @@
{
unsigned long flags;
#if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
- printk( "fdomain: abort " );
+ printk( "scsi: <fdomain> abort " );
#endif
save_flags( flags );
@@ -1808,7 +1843,7 @@
#endif
#if ERRORS_ONLY
- if (SCpnt) printk( "fdomain: SCSI Bus Reset\n" );
+ if (SCpnt) printk( "scsi: <fdomain> SCSI Bus Reset\n" );
#endif
#if DEBUG_RESET
@@ -1893,7 +1928,7 @@
*/
if (MAJOR(dev) != SCSI_DISK0_MAJOR) {
- printk("fdomain_16x0_biosparam: too many disks");
+ printk("scsi: <fdomain> fdomain_16x0_biosparam: too many disks");
return 0;
}
drive = MINOR(dev) >> 4;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov