xref: /linux/drivers/scsi/fdomain.c (revision 14b42963f64b98ab61fa9723c03d71aa5ef4f862)
1 /* fdomain.c -- Future Domain TMC-16x0 SCSI driver
2  * Created: Sun May  3 18:53:19 1992 by faith@cs.unc.edu
3  * Revised: Mon Dec 28 21:59:02 1998 by faith@acm.org
4  * Author: Rickard E. Faith, faith@cs.unc.edu
5  * Copyright 1992-1996, 1998 Rickard E. Faith (faith@acm.org)
6  * Shared IRQ supported added 7/7/2001  Alan Cox <alan@redhat.com>
7 
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2, or (at your option) any
11  * later version.
12 
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17 
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 675 Mass Ave, Cambridge, MA 02139, USA.
21 
22  **************************************************************************
23 
24  SUMMARY:
25 
26  Future Domain BIOS versions supported for autodetect:
27     2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61
28  Chips are supported:
29     TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70
30  Boards supported:
31     Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX
32     Future Domain TMC-3260 (PCI)
33     Quantum ISA-200S, ISA-250MG
34     Adaptec AHA-2920A (PCI) [BUT *NOT* AHA-2920C -- use aic7xxx instead]
35     IBM ?
36  LILO/INSMOD command-line options:
37     fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]
38 
39 
40 
41  NOTE:
42 
43  The Adaptec AHA-2920C has an Adaptec AIC-7850 chip on it.
44  Use the aic7xxx driver for this board.
45 
46  The Adaptec AHA-2920A has a Future Domain chip on it, so this is the right
47  driver for that card.  Unfortunately, the boxes will probably just say
48  "2920", so you'll have to look on the card for a Future Domain logo, or a
49  letter after the 2920.
50 
51 
52 
53  THANKS:
54 
55  Thanks to Adaptec for providing PCI boards for testing.  This finally
56  enabled me to test the PCI detection and correct it for PCI boards that do
57  not have a BIOS at a standard ISA location.  For PCI boards, LILO/INSMOD
58  command-line options should no longer be needed.  --RF 18Nov98
59 
60 
61 
62  DESCRIPTION:
63 
64  This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
65  TMC-1650/1670, and TMC-3260 SCSI host adapters.  The 1650 and 1670 have a
66  25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
67  high-density external connector.  The 1670 and 1680 have floppy disk
68  controllers built in.  The TMC-3260 is a PCI bus card.
69 
70  Future Domain's older boards are based on the TMC-1800 chip, and this
71  driver was originally written for a TMC-1680 board with the TMC-1800 chip.
72  More recently, boards are being produced with the TMC-18C50 and TMC-18C30
73  chips.  The latest and greatest board may not work with this driver.  If
74  you have to patch this driver so that it will recognize your board's BIOS
75  signature, then the driver may fail to function after the board is
76  detected.
77 
78  Please note that the drive ordering that Future Domain implemented in BIOS
79  versions 3.4 and 3.5 is the opposite of the order (currently) used by the
80  rest of the SCSI industry.  If you have BIOS version 3.4 or 3.5, and have
81  more than one drive, then the drive ordering will be the reverse of that
82  which you see under DOS.  For example, under DOS SCSI ID 0 will be D: and
83  SCSI ID 1 will be C: (the boot device).  Under Linux, SCSI ID 0 will be
84  /dev/sda and SCSI ID 1 will be /dev/sdb.  The Linux ordering is consistent
85  with that provided by all the other SCSI drivers for Linux.  If you want
86  this changed, you will probably have to patch the higher level SCSI code.
87  If you do so, please send me patches that are protected by #ifdefs.
88 
89  If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
90  your board.  Please refer to the Seagate driver for more information and
91  possible support.
92 
93 
94 
95  HISTORY:
96 
97  Linux       Driver      Driver
98  Version     Version     Date         Support/Notes
99 
100              0.0          3 May 1992  V2.0 BIOS; 1800 chip
101  0.97        1.9         28 Jul 1992
102  0.98.6      3.1         27 Nov 1992
103  0.99        3.2          9 Dec 1992
104 
105  0.99.3      3.3         10 Jan 1993  V3.0 BIOS
106  0.99.5      3.5         18 Feb 1993
107  0.99.10     3.6         15 May 1993  V3.2 BIOS; 18C50 chip
108  0.99.11     3.17         3 Jul 1993  (now under RCS)
109  0.99.12     3.18        13 Aug 1993
110  0.99.14     5.6         31 Oct 1993  (reselection code removed)
111 
112  0.99.15     5.9         23 Jan 1994  V3.4 BIOS (preliminary)
113  1.0.8/1.1.1 5.15         1 Apr 1994  V3.4 BIOS; 18C30 chip (preliminary)
114  1.0.9/1.1.3 5.16         7 Apr 1994  V3.4 BIOS; 18C30 chip
115  1.1.38      5.18        30 Jul 1994  36C70 chip (PCI version of 18C30)
116  1.1.62      5.20         2 Nov 1994  V3.5 BIOS
117  1.1.73      5.22         7 Dec 1994  Quantum ISA-200S board; V2.0 BIOS
118 
119  1.1.82      5.26        14 Jan 1995  V3.5 BIOS; TMC-1610M/MER/MEX board
120  1.2.10      5.28         5 Jun 1995  Quantum ISA-250MG board; V2.0, V2.01 BIOS
121  1.3.4       5.31        23 Jun 1995  PCI BIOS-32 detection (preliminary)
122  1.3.7       5.33         4 Jul 1995  PCI BIOS-32 detection
123  1.3.28      5.36        17 Sep 1995  V3.61 BIOS; LILO command-line support
124  1.3.34      5.39        12 Oct 1995  V3.60 BIOS; /proc
125  1.3.72      5.39         8 Feb 1996  Adaptec AHA-2920 board
126  1.3.85      5.41         4 Apr 1996
127  2.0.12      5.44         8 Aug 1996  Use ID 7 for all PCI cards
128  2.1.1       5.45         2 Oct 1996  Update ROM accesses for 2.1.x
129  2.1.97      5.46	 23 Apr 1998  Rewritten PCI detection routines [mj]
130  2.1.11x     5.47	  9 Aug 1998  Touched for 8 SCSI disk majors support
131              5.48        18 Nov 1998  BIOS no longer needed for PCI detection
132  2.2.0       5.50        28 Dec 1998  Support insmod parameters
133 
134 
135  REFERENCES USED:
136 
137  "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
138  1990.
139 
140  "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain
141  Corporation, January 1992.
142 
143  "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
144  B/September 1991)", Maxtor Corporation, 1991.
145 
146  "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
147 
148  "Draft Proposed American National Standard: Small Computer System
149  Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109,
150  revision 10h, October 17, 1991)
151 
152  Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric
153  Youngdale (ericy@cais.com), 1992.
154 
155  Private communication, Tuong Le (Future Domain Engineering department),
156  1994. (Disk geometry computations for Future Domain BIOS version 3.4, and
157  TMC-18C30 detection.)
158 
159  Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page
160  60 (2.39: Disk Partition Table Layout).
161 
162  "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page
163  6-1.
164 
165 
166 
167  NOTES ON REFERENCES:
168 
169  The Maxtor manuals were free.  Maxtor telephone technical support is
170  great!
171 
172  The Future Domain manuals were $25 and $35.  They document the chip, not
173  the TMC-16x0 boards, so some information I had to guess at.  In 1992,
174  Future Domain sold DOS BIOS source for $250 and the UN*X driver source was
175  $750, but these required a non-disclosure agreement, so even if I could
176  have afforded them, they would *not* have been useful for writing this
177  publically distributable driver.  Future Domain technical support has
178  provided some information on the phone and have sent a few useful FAXs.
179  They have been much more helpful since they started to recognize that the
180  word "Linux" refers to an operating system :-).
181 
182 
183 
184  ALPHA TESTERS:
185 
186  There are many other alpha testers that come and go as the driver
187  develops.  The people listed here were most helpful in times of greatest
188  need (mostly early on -- I've probably left out a few worthy people in
189  more recent times):
190 
191  Todd Carrico (todd@wutc.wustl.edu), Dan Poirier (poirier@cs.unc.edu ), Ken
192  Corey (kenc@sol.acs.unt.edu), C. de Bruin (bruin@bruin@sterbbs.nl), Sakari
193  Aaltonen (sakaria@vipunen.hit.fi), John Rice (rice@xanth.cs.odu.edu), Brad
194  Yearwood (brad@optilink.com), and Ray Toy (toy@soho.crd.ge.com).
195 
196  Special thanks to Tien-Wan Yang (twyang@cs.uh.edu), who graciously lent me
197  his 18C50-based card for debugging.  He is the sole reason that this
198  driver works with the 18C50 chip.
199 
200  Thanks to Dave Newman (dnewman@crl.com) for providing initial patches for
201  the version 3.4 BIOS.
202 
203  Thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for providing
204  patches that support the TMC-3260, a PCI bus card with the 36C70 chip.
205  The 36C70 chip appears to be "completely compatible" with the 18C30 chip.
206 
207  Thanks to Eric Kasten (tigger@petroglyph.cl.msu.edu) for providing the
208  patch for the version 3.5 BIOS.
209 
210  Thanks for Stephen Henson (shenson@nyx10.cs.du.edu) for providing the
211  patch for the Quantum ISA-200S SCSI adapter.
212 
213  Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, to
214  Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to some
215  random TMC-1680 repackaged by IBM; and to Mintak Ng (mintak@panix.com) for
216  the version 3.61 BIOS signature.
217 
218  Thanks for Mark Singer (elf@netcom.com) and Richard Simpson
219  (rsimpson@ewrcsdra.demon.co.uk) for more Quantum signatures and detective
220  work on the Quantum RAM layout.
221 
222  Special thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for
223  providing patches for proper PCI BIOS32-mediated detection of the TMC-3260
224  card (a PCI bus card with the 36C70 chip).  Please send James PCI-related
225  bug reports.
226 
227  Thanks to Tom Cavin (tec@usa1.com) for preliminary command-line option
228  patches.
229 
230  New PCI detection code written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
231 
232  Insmod parameter code based on patches from Daniel Graham
233  <graham@balance.uoregon.edu>.
234 
235  All of the alpha testers deserve much thanks.
236 
237 
238 
239  NOTES ON USER DEFINABLE OPTIONS:
240 
241  DEBUG: This turns on the printing of various debug information.
242 
243  ENABLE_PARITY: This turns on SCSI parity checking.  With the current
244  driver, all attached devices must support SCSI parity.  If none of your
245  devices support parity, then you can probably get the driver to work by
246  turning this option off.  I have no way of testing this, however, and it
247  would appear that no one ever uses this option.
248 
249  FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the
250  18C30 chip have a 2k cache).  When this many 512 byte blocks are filled by
251  the SCSI device, an interrupt will be raised.  Therefore, this could be as
252  low as 0, or as high as 16.  Note, however, that values which are too high
253  or too low seem to prevent any interrupts from occurring, and thereby lock
254  up the machine.  I have found that 2 is a good number, but throughput may
255  be increased by changing this value to values which are close to 2.
256  Please let me know if you try any different values.
257 
258  RESELECTION: This is no longer an option, since I gave up trying to
259  implement it in version 4.x of this driver.  It did not improve
260  performance at all and made the driver unstable (because I never found one
261  of the two race conditions which were introduced by the multiple
262  outstanding command code).  The instability seems a very high price to pay
263  just so that you don't have to wait for the tape to rewind.  If you want
264  this feature implemented, send me patches.  I'll be happy to send a copy
265  of my (broken) driver to anyone who would like to see a copy.
266 
267  **************************************************************************/
268 
269 #include <linux/module.h>
270 #include <linux/init.h>
271 #include <linux/interrupt.h>
272 #include <linux/blkdev.h>
273 #include <linux/spinlock.h>
274 #include <linux/errno.h>
275 #include <linux/string.h>
276 #include <linux/ioport.h>
277 #include <linux/proc_fs.h>
278 #include <linux/pci.h>
279 #include <linux/stat.h>
280 #include <linux/delay.h>
281 #include <scsi/scsicam.h>
282 
283 #include <asm/io.h>
284 #include <asm/system.h>
285 
286 #include <scsi/scsi.h>
287 #include <scsi/scsi_cmnd.h>
288 #include <scsi/scsi_device.h>
289 #include <scsi/scsi_host.h>
290 #include <scsi/scsi_ioctl.h>
291 #include "fdomain.h"
292 
293 MODULE_AUTHOR("Rickard E. Faith");
294 MODULE_DESCRIPTION("Future domain SCSI driver");
295 MODULE_LICENSE("GPL");
296 
297 
298 #define VERSION          "$Revision: 5.51 $"
299 
300 /* START OF USER DEFINABLE OPTIONS */
301 
302 #define DEBUG            0	/* Enable debugging output */
303 #define ENABLE_PARITY    1	/* Enable SCSI Parity */
304 #define FIFO_COUNT       2	/* Number of 512 byte blocks before INTR */
305 
306 /* END OF USER DEFINABLE OPTIONS */
307 
308 #if DEBUG
309 #define EVERY_ACCESS     0	/* Write a line on every scsi access */
310 #define ERRORS_ONLY      1	/* Only write a line if there is an error */
311 #define DEBUG_DETECT     0	/* Debug fdomain_16x0_detect() */
312 #define DEBUG_MESSAGES   1	/* Debug MESSAGE IN phase */
313 #define DEBUG_ABORT      1	/* Debug abort() routine */
314 #define DEBUG_RESET      1	/* Debug reset() routine */
315 #define DEBUG_RACE       1      /* Debug interrupt-driven race condition */
316 #else
317 #define EVERY_ACCESS     0	/* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
318 #define ERRORS_ONLY      0
319 #define DEBUG_DETECT     0
320 #define DEBUG_MESSAGES   0
321 #define DEBUG_ABORT      0
322 #define DEBUG_RESET      0
323 #define DEBUG_RACE       0
324 #endif
325 
326 /* Errors are reported on the line, so we don't need to report them again */
327 #if EVERY_ACCESS
328 #undef ERRORS_ONLY
329 #define ERRORS_ONLY      0
330 #endif
331 
332 #if ENABLE_PARITY
333 #define PARITY_MASK      0x08
334 #else
335 #define PARITY_MASK      0x00
336 #endif
337 
338 enum chip_type {
339    unknown          = 0x00,
340    tmc1800          = 0x01,
341    tmc18c50         = 0x02,
342    tmc18c30         = 0x03,
343 };
344 
345 enum {
346    in_arbitration   = 0x02,
347    in_selection     = 0x04,
348    in_other         = 0x08,
349    disconnect       = 0x10,
350    aborted          = 0x20,
351    sent_ident       = 0x40,
352 };
353 
354 enum in_port_type {
355    Read_SCSI_Data   =  0,
356    SCSI_Status      =  1,
357    TMC_Status       =  2,
358    FIFO_Status      =  3,	/* tmc18c50/tmc18c30 only */
359    Interrupt_Cond   =  4,	/* tmc18c50/tmc18c30 only */
360    LSB_ID_Code      =  5,
361    MSB_ID_Code      =  6,
362    Read_Loopback    =  7,
363    SCSI_Data_NoACK  =  8,
364    Interrupt_Status =  9,
365    Configuration1   = 10,
366    Configuration2   = 11,	/* tmc18c50/tmc18c30 only */
367    Read_FIFO        = 12,
368    FIFO_Data_Count  = 14
369 };
370 
371 enum out_port_type {
372    Write_SCSI_Data  =  0,
373    SCSI_Cntl        =  1,
374    Interrupt_Cntl   =  2,
375    SCSI_Mode_Cntl   =  3,
376    TMC_Cntl         =  4,
377    Memory_Cntl      =  5,	/* tmc18c50/tmc18c30 only */
378    Write_Loopback   =  7,
379    IO_Control       = 11,	/* tmc18c30 only */
380    Write_FIFO       = 12
381 };
382 
383 /* .bss will zero all the static variables below */
384 static int               port_base;
385 static unsigned long     bios_base;
386 static void __iomem *    bios_mem;
387 static int               bios_major;
388 static int               bios_minor;
389 static int               PCI_bus;
390 static int               Quantum;	/* Quantum board variant */
391 static int               interrupt_level;
392 static volatile int      in_command;
393 static struct scsi_cmnd  *current_SC;
394 static enum chip_type    chip              = unknown;
395 static int               adapter_mask;
396 static int               this_id;
397 static int               setup_called;
398 
399 #if DEBUG_RACE
400 static volatile int      in_interrupt_flag;
401 #endif
402 
403 static int               FIFO_Size = 0x2000; /* 8k FIFO for
404 						pre-tmc18c30 chips */
405 
406 static irqreturn_t       do_fdomain_16x0_intr( int irq, void *dev_id,
407 					    struct pt_regs * regs );
408 /* Allow insmod parameters to be like LILO parameters.  For example:
409    insmod fdomain fdomain=0x140,11 */
410 static char * fdomain = NULL;
411 module_param(fdomain, charp, 0);
412 
413 static unsigned long addresses[] = {
414    0xc8000,
415    0xca000,
416    0xce000,
417    0xde000,
418    0xcc000,		/* Extra addresses for PCI boards */
419    0xd0000,
420    0xe0000,
421 };
422 #define ADDRESS_COUNT ARRAY_SIZE(addresses)
423 
424 static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
425 #define PORT_COUNT ARRAY_SIZE(ports)
426 
427 static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
428 
429 /*
430 
431   READ THIS BEFORE YOU ADD A SIGNATURE!
432 
433   READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME!
434 
435   READ EVERY WORD, ESPECIALLY THE WORD *NOT*
436 
437   This driver works *ONLY* for Future Domain cards using the TMC-1800,
438   TMC-18C50, or TMC-18C30 chip.  This includes models TMC-1650, 1660, 1670,
439   and 1680.  These are all 16-bit cards.
440 
441   The following BIOS signature signatures are for boards which do *NOT*
442   work with this driver (these TMC-8xx and TMC-9xx boards may work with the
443   Seagate driver):
444 
445   FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88
446   FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89
447   FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89
448   FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90
449   FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
450   FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
451   FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92
452 
453   (The cards which do *NOT* work are all 8-bit cards -- although some of
454   them have a 16-bit form-factor, the upper 8-bits are used only for IRQs
455   and are *NOT* used for data.  You can tell the difference by following
456   the tracings on the circuit board -- if only the IRQ lines are involved,
457   you have a "8-bit" card, and should *NOT* use this driver.)
458 
459 */
460 
461 static struct signature {
462    const char *signature;
463    int  sig_offset;
464    int  sig_length;
465    int  major_bios_version;
466    int  minor_bios_version;
467    int  flag; /* 1 == PCI_bus, 2 == ISA_200S, 3 == ISA_250MG, 4 == ISA_200S */
468 } signatures[] = {
469    /*          1         2         3         4         5         6 */
470    /* 123456789012345678901234567890123456789012345678901234567890 */
471    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89",  5, 50,  2,  0, 0 },
472    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89",  5, 50,  2,  0, 0 },
473    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50,  2,  0, 2 },
474    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0",        73, 43,  2,  0, 3 },
475    { "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.",            72, 39,  2,  0, 4 },
476    { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92",        5, 44,  3,  0, 0 },
477    { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93",        5, 44,  3,  2, 0 },
478    { "IBM F1 P2 BIOS v1.0104/29/93",                        5, 28,  3, -1, 0 },
479    { "Future Domain Corp. V1.0008/18/93",                   5, 33,  3,  4, 0 },
480    { "Future Domain Corp. V1.0008/18/93",                  26, 33,  3,  4, 1 },
481    { "Adaptec AHA-2920 PCI-SCSI Card",                     42, 31,  3, -1, 1 },
482    { "IBM F1 P264/32",                                      5, 14,  3, -1, 1 },
483 				/* This next signature may not be a 3.5 bios */
484    { "Future Domain Corp. V2.0108/18/93",                   5, 33,  3,  5, 0 },
485    { "FUTURE DOMAIN CORP.  V3.5008/18/93",                  5, 34,  3,  5, 0 },
486    { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5",        5, 44,  3,  5, 0 },
487    { "FUTURE DOMAIN CORP.  V3.6008/18/93",                  5, 34,  3,  6, 0 },
488    { "FUTURE DOMAIN CORP.  V3.6108/18/93",                  5, 34,  3,  6, 0 },
489    { "FUTURE DOMAIN TMC-18XX",                              5, 22, -1, -1, 0 },
490 
491    /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE
492     Also, fix the disk geometry code for your signature and send your
493     changes for faith@cs.unc.edu.  Above all, do *NOT* change any old
494     signatures!
495 
496     Note that the last line will match a "generic" 18XX bios.  Because
497     Future Domain has changed the host SCSI ID and/or the location of the
498     geometry information in the on-board RAM area for each of the first
499     three BIOS's, it is still important to enter a fully qualified
500     signature in the table for any new BIOS's (after the host SCSI ID and
501     geometry location are verified). */
502 };
503 
504 #define SIGNATURE_COUNT ARRAY_SIZE(signatures)
505 
506 static void print_banner( struct Scsi_Host *shpnt )
507 {
508    if (!shpnt) return;		/* This won't ever happen */
509 
510    if (bios_major < 0 && bios_minor < 0) {
511       printk(KERN_INFO "scsi%d: <fdomain> No BIOS; using scsi id %d\n",
512 	      shpnt->host_no, shpnt->this_id);
513    } else {
514       printk(KERN_INFO "scsi%d: <fdomain> BIOS version ", shpnt->host_no);
515 
516       if (bios_major >= 0) printk("%d.", bios_major);
517       else                 printk("?.");
518 
519       if (bios_minor >= 0) printk("%d", bios_minor);
520       else                 printk("?.");
521 
522       printk( " at 0x%lx using scsi id %d\n",
523 	      bios_base, shpnt->this_id );
524    }
525 
526 				/* If this driver works for later FD PCI
527 				   boards, we will have to modify banner
528 				   for additional PCI cards, but for now if
529 				   it's PCI it's a TMC-3260 - JTM */
530    printk(KERN_INFO "scsi%d: <fdomain> %s chip at 0x%x irq ",
531 	   shpnt->host_no,
532 	   chip == tmc1800 ? "TMC-1800" : (chip == tmc18c50 ? "TMC-18C50" : (chip == tmc18c30 ? (PCI_bus ? "TMC-36C70 (PCI bus)" : "TMC-18C30") : "Unknown")),
533 	   port_base);
534 
535    if (interrupt_level)
536    	printk("%d", interrupt_level);
537    else
538         printk("<none>");
539 
540    printk( "\n" );
541 }
542 
543 int fdomain_setup(char *str)
544 {
545 	int ints[4];
546 
547 	(void)get_options(str, ARRAY_SIZE(ints), ints);
548 
549 	if (setup_called++ || ints[0] < 2 || ints[0] > 3) {
550 		printk(KERN_INFO "scsi: <fdomain> Usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n");
551 		printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n");
552 		return 0;
553 	}
554 
555 	port_base       = ints[0] >= 1 ? ints[1] : 0;
556 	interrupt_level = ints[0] >= 2 ? ints[2] : 0;
557 	this_id         = ints[0] >= 3 ? ints[3] : 0;
558 
559 	bios_major = bios_minor = -1; /* Use geometry for BIOS version >= 3.4 */
560 	++setup_called;
561 	return 1;
562 }
563 
564 __setup("fdomain=", fdomain_setup);
565 
566 
567 static void do_pause(unsigned amount)	/* Pause for amount*10 milliseconds */
568 {
569 	mdelay(10*amount);
570 }
571 
572 static inline void fdomain_make_bus_idle( void )
573 {
574    outb(0, port_base + SCSI_Cntl);
575    outb(0, port_base + SCSI_Mode_Cntl);
576    if (chip == tmc18c50 || chip == tmc18c30)
577 	 outb(0x21 | PARITY_MASK, port_base + TMC_Cntl); /* Clear forced intr. */
578    else
579 	 outb(0x01 | PARITY_MASK, port_base + TMC_Cntl);
580 }
581 
582 static int fdomain_is_valid_port( int port )
583 {
584 #if DEBUG_DETECT
585    printk( " (%x%x),",
586 	   inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
587 #endif
588 
589    /* The MCA ID is a unique id for each MCA compatible board.  We
590       are using ISA boards, but Future Domain provides the MCA ID
591       anyway.  We can use this ID to ensure that this is a Future
592       Domain TMC-1660/TMC-1680.
593     */
594 
595    if (inb( port + LSB_ID_Code ) != 0xe9) { /* test for 0x6127 id */
596       if (inb( port + LSB_ID_Code ) != 0x27) return 0;
597       if (inb( port + MSB_ID_Code ) != 0x61) return 0;
598       chip = tmc1800;
599    } else {				    /* test for 0xe960 id */
600       if (inb( port + MSB_ID_Code ) != 0x60) return 0;
601       chip = tmc18c50;
602 
603 				/* Try to toggle 32-bit mode.  This only
604 				   works on an 18c30 chip.  (User reports
605 				   say this works, so we should switch to
606 				   it in the near future.) */
607 
608       outb( 0x80, port + IO_Control );
609       if ((inb( port + Configuration2 ) & 0x80) == 0x80) {
610 	 outb( 0x00, port + IO_Control );
611 	 if ((inb( port + Configuration2 ) & 0x80) == 0x00) {
612 	    chip = tmc18c30;
613 	    FIFO_Size = 0x800;	/* 2k FIFO */
614 	 }
615       }
616 				/* If that failed, we are an 18c50. */
617    }
618 
619    return 1;
620 }
621 
622 static int fdomain_test_loopback( void )
623 {
624    int i;
625    int result;
626 
627    for (i = 0; i < 255; i++) {
628       outb( i, port_base + Write_Loopback );
629       result = inb( port_base + Read_Loopback );
630       if (i != result)
631 	    return 1;
632    }
633    return 0;
634 }
635 
636 /* fdomain_get_irq assumes that we have a valid MCA ID for a
637    TMC-1660/TMC-1680 Future Domain board.  Now, check to be sure the
638    bios_base matches these ports.  If someone was unlucky enough to have
639    purchased more than one Future Domain board, then they will have to
640    modify this code, as we only detect one board here.  [The one with the
641    lowest bios_base.]
642 
643    Note that this routine is only used for systems without a PCI BIOS32
644    (e.g., ISA bus).  For PCI bus systems, this routine will likely fail
645    unless one of the IRQs listed in the ints array is used by the board.
646    Sometimes it is possible to use the computer's BIOS setup screen to
647    configure a PCI system so that one of these IRQs will be used by the
648    Future Domain card. */
649 
650 static int fdomain_get_irq( int base )
651 {
652    int options = inb(base + Configuration1);
653 
654 #if DEBUG_DETECT
655    printk("scsi: <fdomain> Options = %x\n", options);
656 #endif
657 
658    /* Check for board with lowest bios_base --
659       this isn't valid for the 18c30 or for
660       boards on the PCI bus, so just assume we
661       have the right board. */
662 
663    if (chip != tmc18c30 && !PCI_bus && addresses[(options & 0xc0) >> 6 ] != bios_base)
664    	return 0;
665    return ints[(options & 0x0e) >> 1];
666 }
667 
668 static int fdomain_isa_detect( int *irq, int *iobase )
669 {
670 #ifndef PCMCIA
671    int i, j;
672    int base = 0xdeadbeef;
673    int flag = 0;
674 
675 #if DEBUG_DETECT
676    printk( "scsi: <fdomain> fdomain_isa_detect:" );
677 #endif
678 
679    for (i = 0; i < ADDRESS_COUNT; i++) {
680       void __iomem *p = ioremap(addresses[i], 0x2000);
681       if (!p)
682 	continue;
683 #if DEBUG_DETECT
684       printk( " %lx(%lx),", addresses[i], bios_base );
685 #endif
686       for (j = 0; j < SIGNATURE_COUNT; j++) {
687 	 if (check_signature(p + signatures[j].sig_offset,
688 			     signatures[j].signature,
689 			     signatures[j].sig_length )) {
690 	    bios_major = signatures[j].major_bios_version;
691 	    bios_minor = signatures[j].minor_bios_version;
692 	    PCI_bus    = (signatures[j].flag == 1);
693 	    Quantum    = (signatures[j].flag > 1) ? signatures[j].flag : 0;
694 	    bios_base  = addresses[i];
695 	    bios_mem   = p;
696 	    goto found;
697 	 }
698       }
699       iounmap(p);
700    }
701 
702 found:
703    if (bios_major == 2) {
704       /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
705 	 Assuming the ROM is enabled (otherwise we wouldn't have been
706 	 able to read the ROM signature :-), then the ROM sets up the
707 	 RAM area with some magic numbers, such as a list of port
708 	 base addresses and a list of the disk "geometry" reported to
709 	 DOS (this geometry has nothing to do with physical geometry).
710        */
711 
712       switch (Quantum) {
713       case 2:			/* ISA_200S */
714       case 3:			/* ISA_250MG */
715 	 base = readb(bios_mem + 0x1fa2) + (readb(bios_mem + 0x1fa3) << 8);
716 	 break;
717       case 4:			/* ISA_200S (another one) */
718 	 base = readb(bios_mem + 0x1fa3) + (readb(bios_mem + 0x1fa4) << 8);
719 	 break;
720       default:
721 	 base = readb(bios_mem + 0x1fcc) + (readb(bios_mem + 0x1fcd) << 8);
722 	 break;
723       }
724 
725 #if DEBUG_DETECT
726       printk( " %x,", base );
727 #endif
728 
729       for (i = 0; i < PORT_COUNT; i++) {
730 	if (base == ports[i]) {
731 		if (!request_region(base, 0x10, "fdomain"))
732 			break;
733 		if (!fdomain_is_valid_port(base)) {
734 			release_region(base, 0x10);
735 			break;
736 		}
737 		*irq    = fdomain_get_irq( base );
738 		*iobase = base;
739 		return 1;
740 	}
741       }
742 
743       /* This is a bad sign.  It usually means that someone patched the
744 	 BIOS signature list (the signatures variable) to contain a BIOS
745 	 signature for a board *OTHER THAN* the TMC-1660/TMC-1680. */
746 
747 #if DEBUG_DETECT
748       printk( " RAM FAILED, " );
749 #endif
750    }
751 
752    /* Anyway, the alternative to finding the address in the RAM is to just
753       search through every possible port address for one that is attached
754       to the Future Domain card.  Don't panic, though, about reading all
755       these random port addresses -- there are rumors that the Future
756       Domain BIOS does something very similar.
757 
758       Do not, however, check ports which the kernel knows are being used by
759       another driver. */
760 
761    for (i = 0; i < PORT_COUNT; i++) {
762       base = ports[i];
763       if (!request_region(base, 0x10, "fdomain")) {
764 #if DEBUG_DETECT
765 	 printk( " (%x inuse),", base );
766 #endif
767 	 continue;
768       }
769 #if DEBUG_DETECT
770       printk( " %x,", base );
771 #endif
772       flag = fdomain_is_valid_port(base);
773       if (flag)
774 	break;
775       release_region(base, 0x10);
776    }
777 
778 #if DEBUG_DETECT
779    if (flag) printk( " SUCCESS\n" );
780    else      printk( " FAILURE\n" );
781 #endif
782 
783    if (!flag) return 0;		/* iobase not found */
784 
785    *irq    = fdomain_get_irq( base );
786    *iobase = base;
787 
788    return 1;			/* success */
789 #else
790    return 0;
791 #endif
792 }
793 
794 /* PCI detection function: int fdomain_pci_bios_detect(int* irq, int*
795    iobase) This function gets the Interrupt Level and I/O base address from
796    the PCI configuration registers. */
797 
798 #ifdef CONFIG_PCI
799 static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_pdev )
800 {
801    unsigned int     pci_irq;                /* PCI interrupt line */
802    unsigned long    pci_base;               /* PCI I/O base address */
803    struct pci_dev   *pdev = NULL;
804 
805 #if DEBUG_DETECT
806    /* Tell how to print a list of the known PCI devices from bios32 and
807       list vendor and device IDs being used if in debug mode.  */
808 
809    printk( "scsi: <fdomain> INFO: use lspci -v to see list of PCI devices\n" );
810    printk( "scsi: <fdomain> TMC-3260 detect:"
811 	   " Using Vendor ID: 0x%x and Device ID: 0x%x\n",
812 	   PCI_VENDOR_ID_FD,
813 	   PCI_DEVICE_ID_FD_36C70 );
814 #endif
815 
816    if ((pdev = pci_find_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL)
817 		return 0;
818    if (pci_enable_device(pdev)) return 0;
819 
820 #if DEBUG_DETECT
821    printk( "scsi: <fdomain> TMC-3260 detect:"
822 	   " PCI bus %u, device %u, function %u\n",
823 	   pdev->bus->number,
824 	   PCI_SLOT(pdev->devfn),
825 	   PCI_FUNC(pdev->devfn));
826 #endif
827 
828    /* We now have the appropriate device function for the FD board so we
829       just read the PCI config info from the registers.  */
830 
831    pci_base = pci_resource_start(pdev, 0);
832    pci_irq = pdev->irq;
833 
834    if (!request_region( pci_base, 0x10, "fdomain" ))
835 	return 0;
836 
837    /* Now we have the I/O base address and interrupt from the PCI
838       configuration registers. */
839 
840    *irq    = pci_irq;
841    *iobase = pci_base;
842    *ret_pdev = pdev;
843 
844 #if DEBUG_DETECT
845    printk( "scsi: <fdomain> TMC-3260 detect:"
846 	   " IRQ = %d, I/O base = 0x%x [0x%lx]\n", *irq, *iobase, pci_base );
847 #endif
848 
849    if (!fdomain_is_valid_port(pci_base)) {
850       printk(KERN_ERR "scsi: <fdomain> PCI card detected, but driver not loaded (invalid port)\n" );
851       release_region(pci_base, 0x10);
852       return 0;
853    }
854 
855 				/* Fill in a few global variables.  Ugh. */
856    bios_major = bios_minor = -1;
857    PCI_bus    = 1;
858    Quantum    = 0;
859    bios_base  = 0;
860 
861    return 1;
862 }
863 #endif
864 
865 struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt )
866 {
867    int              retcode;
868    struct Scsi_Host *shpnt;
869    struct pci_dev *pdev = NULL;
870 
871    if (setup_called) {
872 #if DEBUG_DETECT
873       printk( "scsi: <fdomain> No BIOS, using port_base = 0x%x, irq = %d\n",
874 	      port_base, interrupt_level );
875 #endif
876       if (!request_region(port_base, 0x10, "fdomain")) {
877 	 printk( "scsi: <fdomain> port 0x%x is busy\n", port_base );
878 	 printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
879 	 return NULL;
880       }
881       if (!fdomain_is_valid_port( port_base )) {
882 	 printk( "scsi: <fdomain> Cannot locate chip at port base 0x%x\n",
883 		 port_base );
884 	 printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
885 	 release_region(port_base, 0x10);
886 	 return NULL;
887       }
888    } else {
889       int flag = 0;
890 
891 #ifdef CONFIG_PCI
892 				/* Try PCI detection first */
893       flag = fdomain_pci_bios_detect( &interrupt_level, &port_base, &pdev );
894 #endif
895       if (!flag) {
896 				/* Then try ISA bus detection */
897 	 flag = fdomain_isa_detect( &interrupt_level, &port_base );
898 
899 	 if (!flag) {
900 	    printk( "scsi: <fdomain> Detection failed (no card)\n" );
901 	    return NULL;
902 	 }
903       }
904    }
905 
906    fdomain_16x0_bus_reset(NULL);
907 
908    if (fdomain_test_loopback()) {
909       printk(KERN_ERR  "scsi: <fdomain> Detection failed (loopback test failed at port base 0x%x)\n", port_base);
910       if (setup_called) {
911 	 printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n");
912       }
913       release_region(port_base, 0x10);
914       return NULL;
915    }
916 
917    if (this_id) {
918       tpnt->this_id = (this_id & 0x07);
919       adapter_mask  = (1 << tpnt->this_id);
920    } else {
921       if (PCI_bus || (bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
922 	 tpnt->this_id = 7;
923 	 adapter_mask  = 0x80;
924       } else {
925 	 tpnt->this_id = 6;
926 	 adapter_mask  = 0x40;
927       }
928    }
929 
930 /* Print out a banner here in case we can't
931    get resources.  */
932 
933    shpnt = scsi_register( tpnt, 0 );
934    if(shpnt == NULL) {
935 	release_region(port_base, 0x10);
936    	return NULL;
937    }
938    shpnt->irq = interrupt_level;
939    shpnt->io_port = port_base;
940    shpnt->n_io_port = 0x10;
941    print_banner( shpnt );
942 
943    /* Log IRQ with kernel */
944    if (!interrupt_level) {
945       printk(KERN_ERR "scsi: <fdomain> Card Detected, but driver not loaded (no IRQ)\n" );
946       release_region(port_base, 0x10);
947       return NULL;
948    } else {
949       /* Register the IRQ with the kernel */
950 
951       retcode = request_irq( interrupt_level,
952 			     do_fdomain_16x0_intr, pdev?IRQF_SHARED:0, "fdomain", shpnt);
953 
954       if (retcode < 0) {
955 	 if (retcode == -EINVAL) {
956 	    printk(KERN_ERR "scsi: <fdomain> IRQ %d is bad!\n", interrupt_level );
957 	    printk(KERN_ERR "                This shouldn't happen!\n" );
958 	    printk(KERN_ERR "                Send mail to faith@acm.org\n" );
959 	 } else if (retcode == -EBUSY) {
960 	    printk(KERN_ERR "scsi: <fdomain> IRQ %d is already in use!\n", interrupt_level );
961 	    printk(KERN_ERR "                Please use another IRQ!\n" );
962 	 } else {
963 	    printk(KERN_ERR "scsi: <fdomain> Error getting IRQ %d\n", interrupt_level );
964 	    printk(KERN_ERR "                This shouldn't happen!\n" );
965 	    printk(KERN_ERR "                Send mail to faith@acm.org\n" );
966 	 }
967 	 printk(KERN_ERR "scsi: <fdomain> Detected, but driver not loaded (IRQ)\n" );
968          release_region(port_base, 0x10);
969 	 return NULL;
970       }
971    }
972    return shpnt;
973 }
974 
975 static int fdomain_16x0_detect(struct scsi_host_template *tpnt)
976 {
977 	if (fdomain)
978 		fdomain_setup(fdomain);
979 	return (__fdomain_16x0_detect(tpnt) != NULL);
980 }
981 
982 static const char *fdomain_16x0_info( struct Scsi_Host *ignore )
983 {
984    static char buffer[128];
985    char        *pt;
986 
987    strcpy( buffer, "Future Domain 16-bit SCSI Driver Version" );
988    if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */
989       strcat( buffer, strchr( VERSION, ':' ) + 1 );
990       pt = strrchr( buffer, '$') - 1;
991       if (!pt)  		/* Stripped RCS Revision string? */
992 	    pt = buffer + strlen( buffer ) - 1;
993       if (*pt != ' ')
994 	    ++pt;
995       *pt = '\0';
996    } else {			/* Assume VERSION is a number */
997       strcat( buffer, " " VERSION );
998    }
999 
1000    return buffer;
1001 }
1002 
1003 #if 0
1004 static int fdomain_arbitrate( void )
1005 {
1006    int           status = 0;
1007    unsigned long timeout;
1008 
1009 #if EVERY_ACCESS
1010    printk( "fdomain_arbitrate()\n" );
1011 #endif
1012 
1013    outb(0x00, port_base + SCSI_Cntl);              /* Disable data drivers */
1014    outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */
1015    outb(0x04 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */
1016 
1017    timeout = 500;
1018    do {
1019       status = inb(port_base + TMC_Status);        /* Read adapter status */
1020       if (status & 0x02)		      /* Arbitration complete */
1021 	    return 0;
1022       mdelay(1);			/* Wait one millisecond */
1023    } while (--timeout);
1024 
1025    /* Make bus idle */
1026    fdomain_make_bus_idle();
1027 
1028 #if EVERY_ACCESS
1029    printk( "Arbitration failed, status = %x\n", status );
1030 #endif
1031 #if ERRORS_ONLY
1032    printk( "scsi: <fdomain> Arbitration failed, status = %x\n", status );
1033 #endif
1034    return 1;
1035 }
1036 #endif
1037 
1038 static int fdomain_select( int target )
1039 {
1040    int           status;
1041    unsigned long timeout;
1042 #if ERRORS_ONLY
1043    static int    flag = 0;
1044 #endif
1045 
1046    outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */
1047    outb(adapter_mask | (1 << target), port_base + SCSI_Data_NoACK);
1048 
1049    /* Stop arbitration and enable parity */
1050    outb(PARITY_MASK, port_base + TMC_Cntl);
1051 
1052    timeout = 350;			/* 350 msec */
1053 
1054    do {
1055       status = inb(port_base + SCSI_Status); /* Read adapter status */
1056       if (status & 1) {			/* Busy asserted */
1057 	 /* Enable SCSI Bus (on error, should make bus idle with 0) */
1058 	 outb(0x80, port_base + SCSI_Cntl);
1059 	 return 0;
1060       }
1061       mdelay(1);			/* wait one msec */
1062    } while (--timeout);
1063    /* Make bus idle */
1064    fdomain_make_bus_idle();
1065 #if EVERY_ACCESS
1066    if (!target) printk( "Selection failed\n" );
1067 #endif
1068 #if ERRORS_ONLY
1069    if (!target) {
1070       if (!flag) /* Skip first failure for all chips. */
1071 	    ++flag;
1072       else
1073 	    printk( "scsi: <fdomain> Selection failed\n" );
1074    }
1075 #endif
1076    return 1;
1077 }
1078 
1079 static void my_done(int error)
1080 {
1081    if (in_command) {
1082       in_command = 0;
1083       outb(0x00, port_base + Interrupt_Cntl);
1084       fdomain_make_bus_idle();
1085       current_SC->result = error;
1086       if (current_SC->scsi_done)
1087 	    current_SC->scsi_done( current_SC );
1088       else panic( "scsi: <fdomain> current_SC->scsi_done() == NULL" );
1089    } else {
1090       panic( "scsi: <fdomain> my_done() called outside of command\n" );
1091    }
1092 #if DEBUG_RACE
1093    in_interrupt_flag = 0;
1094 #endif
1095 }
1096 
1097 static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id,
1098 					struct pt_regs * regs )
1099 {
1100    unsigned long flags;
1101    int      status;
1102    int      done = 0;
1103    unsigned data_count;
1104 
1105 				/* The fdomain_16x0_intr is only called via
1106 				   the interrupt handler.  The goal of the
1107 				   sti() here is to allow other
1108 				   interruptions while this routine is
1109 				   running. */
1110 
1111    /* Check for other IRQ sources */
1112    if ((inb(port_base + TMC_Status) & 0x01) == 0)
1113    	return IRQ_NONE;
1114 
1115    /* It is our IRQ */
1116    outb(0x00, port_base + Interrupt_Cntl);
1117 
1118    /* We usually have one spurious interrupt after each command.  Ignore it. */
1119    if (!in_command || !current_SC) {	/* Spurious interrupt */
1120 #if EVERY_ACCESS
1121       printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
1122 	      in_command, current_SC );
1123 #endif
1124       return IRQ_NONE;
1125    }
1126 
1127    /* Abort calls my_done, so we do nothing here. */
1128    if (current_SC->SCp.phase & aborted) {
1129 #if DEBUG_ABORT
1130       printk( "scsi: <fdomain> Interrupt after abort, ignoring\n" );
1131 #endif
1132       /*
1133       return IRQ_HANDLED; */
1134    }
1135 
1136 #if DEBUG_RACE
1137    ++in_interrupt_flag;
1138 #endif
1139 
1140    if (current_SC->SCp.phase & in_arbitration) {
1141       status = inb(port_base + TMC_Status);        /* Read adapter status */
1142       if (!(status & 0x02)) {
1143 #if EVERY_ACCESS
1144 	 printk( " AFAIL " );
1145 #endif
1146          spin_lock_irqsave(current_SC->device->host->host_lock, flags);
1147 	 my_done( DID_BUS_BUSY << 16 );
1148          spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
1149 	 return IRQ_HANDLED;
1150       }
1151       current_SC->SCp.phase = in_selection;
1152 
1153       outb(0x40 | FIFO_COUNT, port_base + Interrupt_Cntl);
1154 
1155       outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */
1156       outb(adapter_mask | (1 << scmd_id(current_SC)), port_base + SCSI_Data_NoACK);
1157 
1158       /* Stop arbitration and enable parity */
1159       outb(0x10 | PARITY_MASK, port_base + TMC_Cntl);
1160 #if DEBUG_RACE
1161       in_interrupt_flag = 0;
1162 #endif
1163       return IRQ_HANDLED;
1164    } else if (current_SC->SCp.phase & in_selection) {
1165       status = inb(port_base + SCSI_Status);
1166       if (!(status & 0x01)) {
1167 	 /* Try again, for slow devices */
1168 	 if (fdomain_select( scmd_id(current_SC) )) {
1169 #if EVERY_ACCESS
1170 	    printk( " SFAIL " );
1171 #endif
1172             spin_lock_irqsave(current_SC->device->host->host_lock, flags);
1173 	    my_done( DID_NO_CONNECT << 16 );
1174             spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
1175 	    return IRQ_HANDLED;
1176 	 } else {
1177 #if EVERY_ACCESS
1178 	    printk( " AltSel " );
1179 #endif
1180 	    /* Stop arbitration and enable parity */
1181 	    outb(0x10 | PARITY_MASK, port_base + TMC_Cntl);
1182 	 }
1183       }
1184       current_SC->SCp.phase = in_other;
1185       outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl);
1186       outb(0x80, port_base + SCSI_Cntl);
1187 #if DEBUG_RACE
1188       in_interrupt_flag = 0;
1189 #endif
1190       return IRQ_HANDLED;
1191    }
1192 
1193    /* current_SC->SCp.phase == in_other: this is the body of the routine */
1194 
1195    status = inb(port_base + SCSI_Status);
1196 
1197    if (status & 0x10) {	/* REQ */
1198 
1199       switch (status & 0x0e) {
1200 
1201       case 0x08:		/* COMMAND OUT */
1202 	 outb(current_SC->cmnd[current_SC->SCp.sent_command++],
1203 	      port_base + Write_SCSI_Data);
1204 #if EVERY_ACCESS
1205 	 printk( "CMD = %x,",
1206 		 current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
1207 #endif
1208 	 break;
1209       case 0x00:		/* DATA OUT -- tmc18c50/tmc18c30 only */
1210 	 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1211 	    current_SC->SCp.have_data_in = -1;
1212 	    outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl);
1213 	 }
1214 	 break;
1215       case 0x04:		/* DATA IN -- tmc18c50/tmc18c30 only */
1216 	 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1217 	    current_SC->SCp.have_data_in = 1;
1218 	    outb(0x90 | PARITY_MASK, port_base + TMC_Cntl);
1219 	 }
1220 	 break;
1221       case 0x0c:		/* STATUS IN */
1222 	 current_SC->SCp.Status = inb(port_base + Read_SCSI_Data);
1223 #if EVERY_ACCESS
1224 	 printk( "Status = %x, ", current_SC->SCp.Status );
1225 #endif
1226 #if ERRORS_ONLY
1227 	 if (current_SC->SCp.Status
1228 	     && current_SC->SCp.Status != 2
1229 	     && current_SC->SCp.Status != 8) {
1230 	    printk( "scsi: <fdomain> target = %d, command = %x, status = %x\n",
1231 		    current_SC->device->id,
1232 		    current_SC->cmnd[0],
1233 		    current_SC->SCp.Status );
1234 	 }
1235 #endif
1236 	       break;
1237       case 0x0a:		/* MESSAGE OUT */
1238 	 outb(MESSAGE_REJECT, port_base + Write_SCSI_Data); /* Reject */
1239 	 break;
1240       case 0x0e:		/* MESSAGE IN */
1241 	 current_SC->SCp.Message = inb(port_base + Read_SCSI_Data);
1242 #if EVERY_ACCESS
1243 	 printk( "Message = %x, ", current_SC->SCp.Message );
1244 #endif
1245 	 if (!current_SC->SCp.Message) ++done;
1246 #if DEBUG_MESSAGES || EVERY_ACCESS
1247 	 if (current_SC->SCp.Message) {
1248 	    printk( "scsi: <fdomain> message = %x\n",
1249 		    current_SC->SCp.Message );
1250 	 }
1251 #endif
1252 	 break;
1253       }
1254    }
1255 
1256    if (chip == tmc1800 && !current_SC->SCp.have_data_in
1257        && (current_SC->SCp.sent_command >= current_SC->cmd_len)) {
1258 
1259       if(current_SC->sc_data_direction == DMA_TO_DEVICE)
1260       {
1261 	 current_SC->SCp.have_data_in = -1;
1262 	 outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl);
1263       }
1264       else
1265       {
1266 	 current_SC->SCp.have_data_in = 1;
1267 	 outb(0x90 | PARITY_MASK, port_base + TMC_Cntl);
1268       }
1269    }
1270 
1271    if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
1272       while ((data_count = FIFO_Size - inw(port_base + FIFO_Data_Count)) > 512) {
1273 #if EVERY_ACCESS
1274 	 printk( "DC=%d, ", data_count ) ;
1275 #endif
1276 	 if (data_count > current_SC->SCp.this_residual)
1277 	       data_count = current_SC->SCp.this_residual;
1278 	 if (data_count > 0) {
1279 #if EVERY_ACCESS
1280 	    printk( "%d OUT, ", data_count );
1281 #endif
1282 	    if (data_count == 1) {
1283 	       outb(*current_SC->SCp.ptr++, port_base + Write_FIFO);
1284 	       --current_SC->SCp.this_residual;
1285 	    } else {
1286 	       data_count >>= 1;
1287 	       outsw(port_base + Write_FIFO, current_SC->SCp.ptr, data_count);
1288 	       current_SC->SCp.ptr += 2 * data_count;
1289 	       current_SC->SCp.this_residual -= 2 * data_count;
1290 	    }
1291 	 }
1292 	 if (!current_SC->SCp.this_residual) {
1293 	    if (current_SC->SCp.buffers_residual) {
1294 	       --current_SC->SCp.buffers_residual;
1295 	       ++current_SC->SCp.buffer;
1296 	       current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
1297 	       current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1298 	    } else
1299 		  break;
1300 	 }
1301       }
1302    }
1303 
1304    if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
1305       while ((data_count = inw(port_base + FIFO_Data_Count)) > 0) {
1306 #if EVERY_ACCESS
1307 	 printk( "DC=%d, ", data_count );
1308 #endif
1309 	 if (data_count > current_SC->SCp.this_residual)
1310 	       data_count = current_SC->SCp.this_residual;
1311 	 if (data_count) {
1312 #if EVERY_ACCESS
1313 	    printk( "%d IN, ", data_count );
1314 #endif
1315 	    if (data_count == 1) {
1316 	       *current_SC->SCp.ptr++ = inb(port_base + Read_FIFO);
1317 	       --current_SC->SCp.this_residual;
1318 	    } else {
1319 	       data_count >>= 1; /* Number of words */
1320 	       insw(port_base + Read_FIFO, current_SC->SCp.ptr, data_count);
1321 	       current_SC->SCp.ptr += 2 * data_count;
1322 	       current_SC->SCp.this_residual -= 2 * data_count;
1323 	    }
1324 	 }
1325 	 if (!current_SC->SCp.this_residual
1326 	     && current_SC->SCp.buffers_residual) {
1327 	    --current_SC->SCp.buffers_residual;
1328 	    ++current_SC->SCp.buffer;
1329 	    current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
1330 	    current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1331 	 }
1332       }
1333    }
1334 
1335    if (done) {
1336 #if EVERY_ACCESS
1337       printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1338 #endif
1339 
1340 #if ERRORS_ONLY
1341       if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
1342 	 if ((unsigned char)(*((char *)current_SC->request_buffer+2)) & 0x0f) {
1343 	    unsigned char key;
1344 	    unsigned char code;
1345 	    unsigned char qualifier;
1346 
1347 	    key = (unsigned char)(*((char *)current_SC->request_buffer + 2))
1348 		  & 0x0f;
1349 	    code = (unsigned char)(*((char *)current_SC->request_buffer + 12));
1350 	    qualifier = (unsigned char)(*((char *)current_SC->request_buffer
1351 					  + 13));
1352 
1353 	    if (key != UNIT_ATTENTION
1354 		&& !(key == NOT_READY
1355 		     && code == 0x04
1356 		     && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1357 		&& !(key == ILLEGAL_REQUEST && (code == 0x25
1358 						|| code == 0x24
1359 						|| !code)))
1360 
1361 		  printk( "scsi: <fdomain> REQUEST SENSE"
1362 			  " Key = %x, Code = %x, Qualifier = %x\n",
1363 			  key, code, qualifier );
1364 	 }
1365       }
1366 #endif
1367 #if EVERY_ACCESS
1368       printk( "BEFORE MY_DONE. . ." );
1369 #endif
1370       spin_lock_irqsave(current_SC->device->host->host_lock, flags);
1371       my_done( (current_SC->SCp.Status & 0xff)
1372 	       | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1373       spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
1374 #if EVERY_ACCESS
1375       printk( "RETURNING.\n" );
1376 #endif
1377 
1378    } else {
1379       if (current_SC->SCp.phase & disconnect) {
1380 	 outb(0xd0 | FIFO_COUNT, port_base + Interrupt_Cntl);
1381 	 outb(0x00, port_base + SCSI_Cntl);
1382       } else {
1383 	 outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl);
1384       }
1385    }
1386 #if DEBUG_RACE
1387    in_interrupt_flag = 0;
1388 #endif
1389    return IRQ_HANDLED;
1390 }
1391 
1392 static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
1393 		void (*done)(struct scsi_cmnd *))
1394 {
1395    if (in_command) {
1396       panic( "scsi: <fdomain> fdomain_16x0_queue() NOT REENTRANT!\n" );
1397    }
1398 #if EVERY_ACCESS
1399    printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1400 	   SCpnt->target,
1401 	   *(unsigned char *)SCpnt->cmnd,
1402 	   SCpnt->use_sg,
1403 	   SCpnt->request_bufflen );
1404 #endif
1405 
1406    fdomain_make_bus_idle();
1407 
1408    current_SC            = SCpnt; /* Save this for the done function */
1409    current_SC->scsi_done = done;
1410 
1411    /* Initialize static data */
1412 
1413    if (current_SC->use_sg) {
1414       current_SC->SCp.buffer =
1415 	    (struct scatterlist *)current_SC->request_buffer;
1416       current_SC->SCp.ptr              = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
1417       current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
1418       current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1419    } else {
1420       current_SC->SCp.ptr              = (char *)current_SC->request_buffer;
1421       current_SC->SCp.this_residual    = current_SC->request_bufflen;
1422       current_SC->SCp.buffer           = NULL;
1423       current_SC->SCp.buffers_residual = 0;
1424    }
1425 
1426 
1427    current_SC->SCp.Status              = 0;
1428    current_SC->SCp.Message             = 0;
1429    current_SC->SCp.have_data_in        = 0;
1430    current_SC->SCp.sent_command        = 0;
1431    current_SC->SCp.phase               = in_arbitration;
1432 
1433    /* Start arbitration */
1434    outb(0x00, port_base + Interrupt_Cntl);
1435    outb(0x00, port_base + SCSI_Cntl);              /* Disable data drivers */
1436    outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */
1437    ++in_command;
1438    outb(0x20, port_base + Interrupt_Cntl);
1439    outb(0x14 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */
1440 
1441    return 0;
1442 }
1443 
1444 #if DEBUG_ABORT
1445 static void print_info(struct scsi_cmnd *SCpnt)
1446 {
1447    unsigned int imr;
1448    unsigned int irr;
1449    unsigned int isr;
1450 
1451    if (!SCpnt || !SCpnt->device || !SCpnt->device->host) {
1452       printk(KERN_WARNING "scsi: <fdomain> Cannot provide detailed information\n");
1453       return;
1454    }
1455 
1456    printk(KERN_INFO "%s\n", fdomain_16x0_info( SCpnt->device->host ) );
1457    print_banner(SCpnt->device->host);
1458    switch (SCpnt->SCp.phase) {
1459    case in_arbitration: printk("arbitration"); break;
1460    case in_selection:   printk("selection");   break;
1461    case in_other:       printk("other");       break;
1462    default:             printk("unknown");     break;
1463    }
1464 
1465    printk( " (%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1466 	   SCpnt->SCp.phase,
1467 	   SCpnt->device->id,
1468 	   *(unsigned char *)SCpnt->cmnd,
1469 	   SCpnt->use_sg,
1470 	   SCpnt->request_bufflen );
1471    printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1472 	   SCpnt->SCp.sent_command,
1473 	   SCpnt->SCp.have_data_in,
1474 	   SCpnt->timeout );
1475 #if DEBUG_RACE
1476    printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1477 #endif
1478 
1479    imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1480    outb( 0x0a, 0xa0 );
1481    irr = inb( 0xa0 ) << 8;
1482    outb( 0x0a, 0x20 );
1483    irr += inb( 0x20 );
1484    outb( 0x0b, 0xa0 );
1485    isr = inb( 0xa0 ) << 8;
1486    outb( 0x0b, 0x20 );
1487    isr += inb( 0x20 );
1488 
1489 				/* Print out interesting information */
1490    printk( "IMR = 0x%04x", imr );
1491    if (imr & (1 << interrupt_level))
1492 	 printk( " (masked)" );
1493    printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1494 
1495    printk( "SCSI Status      = 0x%02x\n", inb(port_base + SCSI_Status));
1496    printk( "TMC Status       = 0x%02x", inb(port_base + TMC_Status));
1497    if (inb((port_base + TMC_Status) & 1))
1498 	 printk( " (interrupt)" );
1499    printk( "\n" );
1500    printk("Interrupt Status = 0x%02x", inb(port_base + Interrupt_Status));
1501    if (inb(port_base + Interrupt_Status) & 0x08)
1502 	 printk( " (enabled)" );
1503    printk( "\n" );
1504    if (chip == tmc18c50 || chip == tmc18c30) {
1505       printk("FIFO Status      = 0x%02x\n", inb(port_base + FIFO_Status));
1506       printk( "Int. Condition   = 0x%02x\n",
1507 	      inb( port_base + Interrupt_Cond ) );
1508    }
1509    printk( "Configuration 1  = 0x%02x\n", inb( port_base + Configuration1 ) );
1510    if (chip == tmc18c50 || chip == tmc18c30)
1511 	 printk( "Configuration 2  = 0x%02x\n",
1512 		 inb( port_base + Configuration2 ) );
1513 }
1514 #endif
1515 
1516 static int fdomain_16x0_abort(struct scsi_cmnd *SCpnt)
1517 {
1518 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1519    printk( "scsi: <fdomain> abort " );
1520 #endif
1521 
1522    if (!in_command) {
1523 #if EVERY_ACCESS || ERRORS_ONLY
1524       printk( " (not in command)\n" );
1525 #endif
1526       return FAILED;
1527    } else printk( "\n" );
1528 
1529 #if DEBUG_ABORT
1530    print_info( SCpnt );
1531 #endif
1532 
1533    fdomain_make_bus_idle();
1534    current_SC->SCp.phase |= aborted;
1535    current_SC->result = DID_ABORT << 16;
1536 
1537    /* Aborts are not done well. . . */
1538    my_done(DID_ABORT << 16);
1539    return SUCCESS;
1540 }
1541 
1542 int fdomain_16x0_bus_reset(struct scsi_cmnd *SCpnt)
1543 {
1544    unsigned long flags;
1545 
1546    local_irq_save(flags);
1547 
1548    outb(1, port_base + SCSI_Cntl);
1549    do_pause( 2 );
1550    outb(0, port_base + SCSI_Cntl);
1551    do_pause( 115 );
1552    outb(0, port_base + SCSI_Mode_Cntl);
1553    outb(PARITY_MASK, port_base + TMC_Cntl);
1554 
1555    local_irq_restore(flags);
1556    return SUCCESS;
1557 }
1558 
1559 static int fdomain_16x0_biosparam(struct scsi_device *sdev,
1560 		struct block_device *bdev,
1561 		sector_t capacity, int *info_array)
1562 {
1563    int              drive;
1564    int		    size      = capacity;
1565    unsigned long    offset;
1566    struct drive_info {
1567       unsigned short cylinders;
1568       unsigned char  heads;
1569       unsigned char  sectors;
1570    } i;
1571 
1572    /* NOTES:
1573       The RAM area starts at 0x1f00 from the bios_base address.
1574 
1575       For BIOS Version 2.0:
1576 
1577       The drive parameter table seems to start at 0x1f30.
1578       The first byte's purpose is not known.
1579       Next is the cylinder, head, and sector information.
1580       The last 4 bytes appear to be the drive's size in sectors.
1581       The other bytes in the drive parameter table are unknown.
1582       If anyone figures them out, please send me mail, and I will
1583       update these notes.
1584 
1585       Tape drives do not get placed in this table.
1586 
1587       There is another table at 0x1fea:
1588       If the byte is 0x01, then the SCSI ID is not in use.
1589       If the byte is 0x18 or 0x48, then the SCSI ID is in use,
1590       although tapes don't seem to be in this table.  I haven't
1591       seen any other numbers (in a limited sample).
1592 
1593       0x1f2d is a drive count (i.e., not including tapes)
1594 
1595       The table at 0x1fcc are I/O ports addresses for the various
1596       operations.  I calculate these by hand in this driver code.
1597 
1598 
1599 
1600       For the ISA-200S version of BIOS Version 2.0:
1601 
1602       The drive parameter table starts at 0x1f33.
1603 
1604       WARNING: Assume that the table entry is 25 bytes long.  Someone needs
1605       to check this for the Quantum ISA-200S card.
1606 
1607 
1608 
1609       For BIOS Version 3.2:
1610 
1611       The drive parameter table starts at 0x1f70.  Each entry is
1612       0x0a bytes long.  Heads are one less than we need to report.
1613     */
1614 
1615    if (MAJOR(bdev->bd_dev) != SCSI_DISK0_MAJOR) {
1616       printk("scsi: <fdomain> fdomain_16x0_biosparam: too many disks");
1617       return 0;
1618    }
1619    drive = MINOR(bdev->bd_dev) >> 4;
1620 
1621    if (bios_major == 2) {
1622       switch (Quantum) {
1623       case 2:			/* ISA_200S */
1624 				/* The value of 25 has never been verified.
1625 				   It should probably be 15. */
1626 	 offset = 0x1f33 + drive * 25;
1627 	 break;
1628       case 3:			/* ISA_250MG */
1629 	 offset = 0x1f36 + drive * 15;
1630 	 break;
1631       case 4:			/* ISA_200S (another one) */
1632 	 offset = 0x1f34 + drive * 15;
1633 	 break;
1634       default:
1635 	 offset = 0x1f31 + drive * 25;
1636 	 break;
1637       }
1638       memcpy_fromio( &i, bios_mem + offset, sizeof( struct drive_info ) );
1639       info_array[0] = i.heads;
1640       info_array[1] = i.sectors;
1641       info_array[2] = i.cylinders;
1642    } else if (bios_major == 3
1643 	      && bios_minor >= 0
1644 	      && bios_minor < 4) { /* 3.0 and 3.2 BIOS */
1645       memcpy_fromio( &i, bios_mem + 0x1f71 + drive * 10,
1646 		     sizeof( struct drive_info ) );
1647       info_array[0] = i.heads + 1;
1648       info_array[1] = i.sectors;
1649       info_array[2] = i.cylinders;
1650    } else {			/* 3.4 BIOS (and up?) */
1651       /* This algorithm was provided by Future Domain (much thanks!). */
1652       unsigned char *p = scsi_bios_ptable(bdev);
1653 
1654       if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */
1655 	  && p[4]) {			    /* Partition type */
1656 
1657 	 /* The partition table layout is as follows:
1658 
1659 	    Start: 0x1b3h
1660 	    Offset: 0 = partition status
1661 		    1 = starting head
1662 		    2 = starting sector and cylinder (word, encoded)
1663 		    4 = partition type
1664 		    5 = ending head
1665 		    6 = ending sector and cylinder (word, encoded)
1666 		    8 = starting absolute sector (double word)
1667 		    c = number of sectors (double word)
1668 	    Signature: 0x1fe = 0x55aa
1669 
1670 	    So, this algorithm assumes:
1671 	    1) the first partition table is in use,
1672 	    2) the data in the first entry is correct, and
1673 	    3) partitions never divide cylinders
1674 
1675 	    Note that (1) may be FALSE for NetBSD (and other BSD flavors),
1676 	    as well as for Linux.  Note also, that Linux doesn't pay any
1677 	    attention to the fields that are used by this algorithm -- it
1678 	    only uses the absolute sector data.  Recent versions of Linux's
1679 	    fdisk(1) will fill this data in correctly, and forthcoming
1680 	    versions will check for consistency.
1681 
1682 	    Checking for a non-zero partition type is not part of the
1683 	    Future Domain algorithm, but it seemed to be a reasonable thing
1684 	    to do, especially in the Linux and BSD worlds. */
1685 
1686 	 info_array[0] = p[5] + 1;	    /* heads */
1687 	 info_array[1] = p[6] & 0x3f;	    /* sectors */
1688       } else {
1689 
1690  	 /* Note that this new method guarantees that there will always be
1691 	    less than 1024 cylinders on a platter.  This is good for drives
1692 	    up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
1693 
1694 	 if ((unsigned int)size >= 0x7e0000U) {
1695 	    info_array[0] = 0xff; /* heads   = 255 */
1696 	    info_array[1] = 0x3f; /* sectors =  63 */
1697 	 } else if ((unsigned int)size >= 0x200000U) {
1698 	    info_array[0] = 0x80; /* heads   = 128 */
1699 	    info_array[1] = 0x3f; /* sectors =  63 */
1700 	 } else {
1701 	    info_array[0] = 0x40; /* heads   =  64 */
1702 	    info_array[1] = 0x20; /* sectors =  32 */
1703 	 }
1704       }
1705 				/* For both methods, compute the cylinders */
1706       info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] );
1707       kfree(p);
1708    }
1709 
1710    return 0;
1711 }
1712 
1713 static int fdomain_16x0_release(struct Scsi_Host *shpnt)
1714 {
1715 	if (shpnt->irq)
1716 		free_irq(shpnt->irq, shpnt);
1717 	if (shpnt->io_port && shpnt->n_io_port)
1718 		release_region(shpnt->io_port, shpnt->n_io_port);
1719 	return 0;
1720 }
1721 
1722 struct scsi_host_template fdomain_driver_template = {
1723 	.module			= THIS_MODULE,
1724 	.name			= "fdomain",
1725 	.proc_name		= "fdomain",
1726 	.detect			= fdomain_16x0_detect,
1727 	.info			= fdomain_16x0_info,
1728 	.queuecommand		= fdomain_16x0_queue,
1729 	.eh_abort_handler	= fdomain_16x0_abort,
1730 	.eh_bus_reset_handler	= fdomain_16x0_bus_reset,
1731 	.bios_param		= fdomain_16x0_biosparam,
1732 	.release		= fdomain_16x0_release,
1733 	.can_queue		= 1,
1734 	.this_id		= 6,
1735 	.sg_tablesize		= 64,
1736 	.cmd_per_lun		= 1,
1737 	.use_clustering		= DISABLE_CLUSTERING,
1738 };
1739 
1740 #ifndef PCMCIA
1741 #define driver_template fdomain_driver_template
1742 #include "scsi_module.c"
1743 #endif
1744