xref: /openbmc/linux/drivers/scsi/fdomain.c (revision 64c70b1c)
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 <linux/io.h>
282 #include <scsi/scsicam.h>
283 
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 struct pci_dev	*PCI_dev;
391 static int               Quantum;	/* Quantum board variant */
392 static int               interrupt_level;
393 static volatile int      in_command;
394 static struct scsi_cmnd  *current_SC;
395 static enum chip_type    chip              = unknown;
396 static int               adapter_mask;
397 static int               this_id;
398 static int               setup_called;
399 
400 #if DEBUG_RACE
401 static volatile int      in_interrupt_flag;
402 #endif
403 
404 static int               FIFO_Size = 0x2000; /* 8k FIFO for
405 						pre-tmc18c30 chips */
406 
407 static irqreturn_t       do_fdomain_16x0_intr( int irq, void *dev_id );
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_get_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL)
817 		return 0;
818    if (pci_enable_device(pdev))
819    	goto fail;
820 
821 #if DEBUG_DETECT
822    printk( "scsi: <fdomain> TMC-3260 detect:"
823 	   " PCI bus %u, device %u, function %u\n",
824 	   pdev->bus->number,
825 	   PCI_SLOT(pdev->devfn),
826 	   PCI_FUNC(pdev->devfn));
827 #endif
828 
829    /* We now have the appropriate device function for the FD board so we
830       just read the PCI config info from the registers.  */
831 
832    pci_base = pci_resource_start(pdev, 0);
833    pci_irq = pdev->irq;
834 
835    if (!request_region( pci_base, 0x10, "fdomain" ))
836    	goto fail;
837 
838    /* Now we have the I/O base address and interrupt from the PCI
839       configuration registers. */
840 
841    *irq    = pci_irq;
842    *iobase = pci_base;
843    *ret_pdev = pdev;
844 
845 #if DEBUG_DETECT
846    printk( "scsi: <fdomain> TMC-3260 detect:"
847 	   " IRQ = %d, I/O base = 0x%x [0x%lx]\n", *irq, *iobase, pci_base );
848 #endif
849 
850    if (!fdomain_is_valid_port(pci_base)) {
851       printk(KERN_ERR "scsi: <fdomain> PCI card detected, but driver not loaded (invalid port)\n" );
852       release_region(pci_base, 0x10);
853       goto fail;
854    }
855 
856 				/* Fill in a few global variables.  Ugh. */
857    bios_major = bios_minor = -1;
858    PCI_bus    = 1;
859    PCI_dev    = pdev;
860    Quantum    = 0;
861    bios_base  = 0;
862 
863    return 1;
864 fail:
865    pci_dev_put(pdev);
866    return 0;
867 }
868 
869 #endif
870 
871 struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt )
872 {
873    int              retcode;
874    struct Scsi_Host *shpnt;
875    struct pci_dev *pdev = NULL;
876 
877    if (setup_called) {
878 #if DEBUG_DETECT
879       printk( "scsi: <fdomain> No BIOS, using port_base = 0x%x, irq = %d\n",
880 	      port_base, interrupt_level );
881 #endif
882       if (!request_region(port_base, 0x10, "fdomain")) {
883 	 printk( "scsi: <fdomain> port 0x%x is busy\n", port_base );
884 	 printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
885 	 return NULL;
886       }
887       if (!fdomain_is_valid_port( port_base )) {
888 	 printk( "scsi: <fdomain> Cannot locate chip at port base 0x%x\n",
889 		 port_base );
890 	 printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
891 	 release_region(port_base, 0x10);
892 	 return NULL;
893       }
894    } else {
895       int flag = 0;
896 
897 #ifdef CONFIG_PCI
898 				/* Try PCI detection first */
899       flag = fdomain_pci_bios_detect( &interrupt_level, &port_base, &pdev );
900 #endif
901       if (!flag) {
902 				/* Then try ISA bus detection */
903 	 flag = fdomain_isa_detect( &interrupt_level, &port_base );
904 
905 	 if (!flag) {
906 	    printk( "scsi: <fdomain> Detection failed (no card)\n" );
907 	    return NULL;
908 	 }
909       }
910    }
911 
912    fdomain_16x0_bus_reset(NULL);
913 
914    if (fdomain_test_loopback()) {
915       printk(KERN_ERR  "scsi: <fdomain> Detection failed (loopback test failed at port base 0x%x)\n", port_base);
916       if (setup_called) {
917 	 printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n");
918       }
919       goto fail;
920    }
921 
922    if (this_id) {
923       tpnt->this_id = (this_id & 0x07);
924       adapter_mask  = (1 << tpnt->this_id);
925    } else {
926       if (PCI_bus || (bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
927 	 tpnt->this_id = 7;
928 	 adapter_mask  = 0x80;
929       } else {
930 	 tpnt->this_id = 6;
931 	 adapter_mask  = 0x40;
932       }
933    }
934 
935 /* Print out a banner here in case we can't
936    get resources.  */
937 
938    shpnt = scsi_register( tpnt, 0 );
939    if(shpnt == NULL) {
940 	release_region(port_base, 0x10);
941    	return NULL;
942    }
943    shpnt->irq = interrupt_level;
944    shpnt->io_port = port_base;
945    shpnt->n_io_port = 0x10;
946    print_banner( shpnt );
947 
948    /* Log IRQ with kernel */
949    if (!interrupt_level) {
950       printk(KERN_ERR "scsi: <fdomain> Card Detected, but driver not loaded (no IRQ)\n" );
951       goto fail;
952    } else {
953       /* Register the IRQ with the kernel */
954 
955       retcode = request_irq( interrupt_level,
956 			     do_fdomain_16x0_intr, pdev?IRQF_SHARED:0, "fdomain", shpnt);
957 
958       if (retcode < 0) {
959 	 if (retcode == -EINVAL) {
960 	    printk(KERN_ERR "scsi: <fdomain> IRQ %d is bad!\n", interrupt_level );
961 	    printk(KERN_ERR "                This shouldn't happen!\n" );
962 	    printk(KERN_ERR "                Send mail to faith@acm.org\n" );
963 	 } else if (retcode == -EBUSY) {
964 	    printk(KERN_ERR "scsi: <fdomain> IRQ %d is already in use!\n", interrupt_level );
965 	    printk(KERN_ERR "                Please use another IRQ!\n" );
966 	 } else {
967 	    printk(KERN_ERR "scsi: <fdomain> Error getting IRQ %d\n", interrupt_level );
968 	    printk(KERN_ERR "                This shouldn't happen!\n" );
969 	    printk(KERN_ERR "                Send mail to faith@acm.org\n" );
970 	 }
971 	 printk(KERN_ERR "scsi: <fdomain> Detected, but driver not loaded (IRQ)\n" );
972 	 goto fail;
973       }
974    }
975    return shpnt;
976 fail:
977    pci_dev_put(pdev);
978    release_region(port_base, 0x10);
979    return NULL;
980 }
981 
982 static int fdomain_16x0_detect(struct scsi_host_template *tpnt)
983 {
984 	if (fdomain)
985 		fdomain_setup(fdomain);
986 	return (__fdomain_16x0_detect(tpnt) != NULL);
987 }
988 
989 static const char *fdomain_16x0_info( struct Scsi_Host *ignore )
990 {
991    static char buffer[128];
992    char        *pt;
993 
994    strcpy( buffer, "Future Domain 16-bit SCSI Driver Version" );
995    if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */
996       strcat( buffer, strchr( VERSION, ':' ) + 1 );
997       pt = strrchr( buffer, '$') - 1;
998       if (!pt)  		/* Stripped RCS Revision string? */
999 	    pt = buffer + strlen( buffer ) - 1;
1000       if (*pt != ' ')
1001 	    ++pt;
1002       *pt = '\0';
1003    } else {			/* Assume VERSION is a number */
1004       strcat( buffer, " " VERSION );
1005    }
1006 
1007    return buffer;
1008 }
1009 
1010 #if 0
1011 static int fdomain_arbitrate( void )
1012 {
1013    int           status = 0;
1014    unsigned long timeout;
1015 
1016 #if EVERY_ACCESS
1017    printk( "fdomain_arbitrate()\n" );
1018 #endif
1019 
1020    outb(0x00, port_base + SCSI_Cntl);              /* Disable data drivers */
1021    outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */
1022    outb(0x04 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */
1023 
1024    timeout = 500;
1025    do {
1026       status = inb(port_base + TMC_Status);        /* Read adapter status */
1027       if (status & 0x02)		      /* Arbitration complete */
1028 	    return 0;
1029       mdelay(1);			/* Wait one millisecond */
1030    } while (--timeout);
1031 
1032    /* Make bus idle */
1033    fdomain_make_bus_idle();
1034 
1035 #if EVERY_ACCESS
1036    printk( "Arbitration failed, status = %x\n", status );
1037 #endif
1038 #if ERRORS_ONLY
1039    printk( "scsi: <fdomain> Arbitration failed, status = %x\n", status );
1040 #endif
1041    return 1;
1042 }
1043 #endif
1044 
1045 static int fdomain_select( int target )
1046 {
1047    int           status;
1048    unsigned long timeout;
1049 #if ERRORS_ONLY
1050    static int    flag = 0;
1051 #endif
1052 
1053    outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */
1054    outb(adapter_mask | (1 << target), port_base + SCSI_Data_NoACK);
1055 
1056    /* Stop arbitration and enable parity */
1057    outb(PARITY_MASK, port_base + TMC_Cntl);
1058 
1059    timeout = 350;			/* 350 msec */
1060 
1061    do {
1062       status = inb(port_base + SCSI_Status); /* Read adapter status */
1063       if (status & 1) {			/* Busy asserted */
1064 	 /* Enable SCSI Bus (on error, should make bus idle with 0) */
1065 	 outb(0x80, port_base + SCSI_Cntl);
1066 	 return 0;
1067       }
1068       mdelay(1);			/* wait one msec */
1069    } while (--timeout);
1070    /* Make bus idle */
1071    fdomain_make_bus_idle();
1072 #if EVERY_ACCESS
1073    if (!target) printk( "Selection failed\n" );
1074 #endif
1075 #if ERRORS_ONLY
1076    if (!target) {
1077       if (!flag) /* Skip first failure for all chips. */
1078 	    ++flag;
1079       else
1080 	    printk( "scsi: <fdomain> Selection failed\n" );
1081    }
1082 #endif
1083    return 1;
1084 }
1085 
1086 static void my_done(int error)
1087 {
1088    if (in_command) {
1089       in_command = 0;
1090       outb(0x00, port_base + Interrupt_Cntl);
1091       fdomain_make_bus_idle();
1092       current_SC->result = error;
1093       if (current_SC->scsi_done)
1094 	    current_SC->scsi_done( current_SC );
1095       else panic( "scsi: <fdomain> current_SC->scsi_done() == NULL" );
1096    } else {
1097       panic( "scsi: <fdomain> my_done() called outside of command\n" );
1098    }
1099 #if DEBUG_RACE
1100    in_interrupt_flag = 0;
1101 #endif
1102 }
1103 
1104 static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
1105 {
1106    unsigned long flags;
1107    int      status;
1108    int      done = 0;
1109    unsigned data_count;
1110 
1111 				/* The fdomain_16x0_intr is only called via
1112 				   the interrupt handler.  The goal of the
1113 				   sti() here is to allow other
1114 				   interruptions while this routine is
1115 				   running. */
1116 
1117    /* Check for other IRQ sources */
1118    if ((inb(port_base + TMC_Status) & 0x01) == 0)
1119    	return IRQ_NONE;
1120 
1121    /* It is our IRQ */
1122    outb(0x00, port_base + Interrupt_Cntl);
1123 
1124    /* We usually have one spurious interrupt after each command.  Ignore it. */
1125    if (!in_command || !current_SC) {	/* Spurious interrupt */
1126 #if EVERY_ACCESS
1127       printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
1128 	      in_command, current_SC );
1129 #endif
1130       return IRQ_NONE;
1131    }
1132 
1133    /* Abort calls my_done, so we do nothing here. */
1134    if (current_SC->SCp.phase & aborted) {
1135 #if DEBUG_ABORT
1136       printk( "scsi: <fdomain> Interrupt after abort, ignoring\n" );
1137 #endif
1138       /*
1139       return IRQ_HANDLED; */
1140    }
1141 
1142 #if DEBUG_RACE
1143    ++in_interrupt_flag;
1144 #endif
1145 
1146    if (current_SC->SCp.phase & in_arbitration) {
1147       status = inb(port_base + TMC_Status);        /* Read adapter status */
1148       if (!(status & 0x02)) {
1149 #if EVERY_ACCESS
1150 	 printk( " AFAIL " );
1151 #endif
1152          spin_lock_irqsave(current_SC->device->host->host_lock, flags);
1153 	 my_done( DID_BUS_BUSY << 16 );
1154          spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
1155 	 return IRQ_HANDLED;
1156       }
1157       current_SC->SCp.phase = in_selection;
1158 
1159       outb(0x40 | FIFO_COUNT, port_base + Interrupt_Cntl);
1160 
1161       outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */
1162       outb(adapter_mask | (1 << scmd_id(current_SC)), port_base + SCSI_Data_NoACK);
1163 
1164       /* Stop arbitration and enable parity */
1165       outb(0x10 | PARITY_MASK, port_base + TMC_Cntl);
1166 #if DEBUG_RACE
1167       in_interrupt_flag = 0;
1168 #endif
1169       return IRQ_HANDLED;
1170    } else if (current_SC->SCp.phase & in_selection) {
1171       status = inb(port_base + SCSI_Status);
1172       if (!(status & 0x01)) {
1173 	 /* Try again, for slow devices */
1174 	 if (fdomain_select( scmd_id(current_SC) )) {
1175 #if EVERY_ACCESS
1176 	    printk( " SFAIL " );
1177 #endif
1178             spin_lock_irqsave(current_SC->device->host->host_lock, flags);
1179 	    my_done( DID_NO_CONNECT << 16 );
1180             spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
1181 	    return IRQ_HANDLED;
1182 	 } else {
1183 #if EVERY_ACCESS
1184 	    printk( " AltSel " );
1185 #endif
1186 	    /* Stop arbitration and enable parity */
1187 	    outb(0x10 | PARITY_MASK, port_base + TMC_Cntl);
1188 	 }
1189       }
1190       current_SC->SCp.phase = in_other;
1191       outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl);
1192       outb(0x80, port_base + SCSI_Cntl);
1193 #if DEBUG_RACE
1194       in_interrupt_flag = 0;
1195 #endif
1196       return IRQ_HANDLED;
1197    }
1198 
1199    /* current_SC->SCp.phase == in_other: this is the body of the routine */
1200 
1201    status = inb(port_base + SCSI_Status);
1202 
1203    if (status & 0x10) {	/* REQ */
1204 
1205       switch (status & 0x0e) {
1206 
1207       case 0x08:		/* COMMAND OUT */
1208 	 outb(current_SC->cmnd[current_SC->SCp.sent_command++],
1209 	      port_base + Write_SCSI_Data);
1210 #if EVERY_ACCESS
1211 	 printk( "CMD = %x,",
1212 		 current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
1213 #endif
1214 	 break;
1215       case 0x00:		/* DATA OUT -- tmc18c50/tmc18c30 only */
1216 	 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1217 	    current_SC->SCp.have_data_in = -1;
1218 	    outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl);
1219 	 }
1220 	 break;
1221       case 0x04:		/* DATA IN -- tmc18c50/tmc18c30 only */
1222 	 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1223 	    current_SC->SCp.have_data_in = 1;
1224 	    outb(0x90 | PARITY_MASK, port_base + TMC_Cntl);
1225 	 }
1226 	 break;
1227       case 0x0c:		/* STATUS IN */
1228 	 current_SC->SCp.Status = inb(port_base + Read_SCSI_Data);
1229 #if EVERY_ACCESS
1230 	 printk( "Status = %x, ", current_SC->SCp.Status );
1231 #endif
1232 #if ERRORS_ONLY
1233 	 if (current_SC->SCp.Status
1234 	     && current_SC->SCp.Status != 2
1235 	     && current_SC->SCp.Status != 8) {
1236 	    printk( "scsi: <fdomain> target = %d, command = %x, status = %x\n",
1237 		    current_SC->device->id,
1238 		    current_SC->cmnd[0],
1239 		    current_SC->SCp.Status );
1240 	 }
1241 #endif
1242 	       break;
1243       case 0x0a:		/* MESSAGE OUT */
1244 	 outb(MESSAGE_REJECT, port_base + Write_SCSI_Data); /* Reject */
1245 	 break;
1246       case 0x0e:		/* MESSAGE IN */
1247 	 current_SC->SCp.Message = inb(port_base + Read_SCSI_Data);
1248 #if EVERY_ACCESS
1249 	 printk( "Message = %x, ", current_SC->SCp.Message );
1250 #endif
1251 	 if (!current_SC->SCp.Message) ++done;
1252 #if DEBUG_MESSAGES || EVERY_ACCESS
1253 	 if (current_SC->SCp.Message) {
1254 	    printk( "scsi: <fdomain> message = %x\n",
1255 		    current_SC->SCp.Message );
1256 	 }
1257 #endif
1258 	 break;
1259       }
1260    }
1261 
1262    if (chip == tmc1800 && !current_SC->SCp.have_data_in
1263        && (current_SC->SCp.sent_command >= current_SC->cmd_len)) {
1264 
1265       if(current_SC->sc_data_direction == DMA_TO_DEVICE)
1266       {
1267 	 current_SC->SCp.have_data_in = -1;
1268 	 outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl);
1269       }
1270       else
1271       {
1272 	 current_SC->SCp.have_data_in = 1;
1273 	 outb(0x90 | PARITY_MASK, port_base + TMC_Cntl);
1274       }
1275    }
1276 
1277    if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
1278       while ((data_count = FIFO_Size - inw(port_base + FIFO_Data_Count)) > 512) {
1279 #if EVERY_ACCESS
1280 	 printk( "DC=%d, ", data_count ) ;
1281 #endif
1282 	 if (data_count > current_SC->SCp.this_residual)
1283 	       data_count = current_SC->SCp.this_residual;
1284 	 if (data_count > 0) {
1285 #if EVERY_ACCESS
1286 	    printk( "%d OUT, ", data_count );
1287 #endif
1288 	    if (data_count == 1) {
1289 	       outb(*current_SC->SCp.ptr++, port_base + Write_FIFO);
1290 	       --current_SC->SCp.this_residual;
1291 	    } else {
1292 	       data_count >>= 1;
1293 	       outsw(port_base + Write_FIFO, current_SC->SCp.ptr, data_count);
1294 	       current_SC->SCp.ptr += 2 * data_count;
1295 	       current_SC->SCp.this_residual -= 2 * data_count;
1296 	    }
1297 	 }
1298 	 if (!current_SC->SCp.this_residual) {
1299 	    if (current_SC->SCp.buffers_residual) {
1300 	       --current_SC->SCp.buffers_residual;
1301 	       ++current_SC->SCp.buffer;
1302 	       current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
1303 	       current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1304 	    } else
1305 		  break;
1306 	 }
1307       }
1308    }
1309 
1310    if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
1311       while ((data_count = inw(port_base + FIFO_Data_Count)) > 0) {
1312 #if EVERY_ACCESS
1313 	 printk( "DC=%d, ", data_count );
1314 #endif
1315 	 if (data_count > current_SC->SCp.this_residual)
1316 	       data_count = current_SC->SCp.this_residual;
1317 	 if (data_count) {
1318 #if EVERY_ACCESS
1319 	    printk( "%d IN, ", data_count );
1320 #endif
1321 	    if (data_count == 1) {
1322 	       *current_SC->SCp.ptr++ = inb(port_base + Read_FIFO);
1323 	       --current_SC->SCp.this_residual;
1324 	    } else {
1325 	       data_count >>= 1; /* Number of words */
1326 	       insw(port_base + Read_FIFO, current_SC->SCp.ptr, data_count);
1327 	       current_SC->SCp.ptr += 2 * data_count;
1328 	       current_SC->SCp.this_residual -= 2 * data_count;
1329 	    }
1330 	 }
1331 	 if (!current_SC->SCp.this_residual
1332 	     && current_SC->SCp.buffers_residual) {
1333 	    --current_SC->SCp.buffers_residual;
1334 	    ++current_SC->SCp.buffer;
1335 	    current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
1336 	    current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1337 	 }
1338       }
1339    }
1340 
1341    if (done) {
1342 #if EVERY_ACCESS
1343       printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1344 #endif
1345 
1346 #if ERRORS_ONLY
1347       if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
1348 	 if ((unsigned char)(*((char *)current_SC->request_buffer+2)) & 0x0f) {
1349 	    unsigned char key;
1350 	    unsigned char code;
1351 	    unsigned char qualifier;
1352 
1353 	    key = (unsigned char)(*((char *)current_SC->request_buffer + 2))
1354 		  & 0x0f;
1355 	    code = (unsigned char)(*((char *)current_SC->request_buffer + 12));
1356 	    qualifier = (unsigned char)(*((char *)current_SC->request_buffer
1357 					  + 13));
1358 
1359 	    if (key != UNIT_ATTENTION
1360 		&& !(key == NOT_READY
1361 		     && code == 0x04
1362 		     && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1363 		&& !(key == ILLEGAL_REQUEST && (code == 0x25
1364 						|| code == 0x24
1365 						|| !code)))
1366 
1367 		  printk( "scsi: <fdomain> REQUEST SENSE"
1368 			  " Key = %x, Code = %x, Qualifier = %x\n",
1369 			  key, code, qualifier );
1370 	 }
1371       }
1372 #endif
1373 #if EVERY_ACCESS
1374       printk( "BEFORE MY_DONE. . ." );
1375 #endif
1376       spin_lock_irqsave(current_SC->device->host->host_lock, flags);
1377       my_done( (current_SC->SCp.Status & 0xff)
1378 	       | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1379       spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
1380 #if EVERY_ACCESS
1381       printk( "RETURNING.\n" );
1382 #endif
1383 
1384    } else {
1385       if (current_SC->SCp.phase & disconnect) {
1386 	 outb(0xd0 | FIFO_COUNT, port_base + Interrupt_Cntl);
1387 	 outb(0x00, port_base + SCSI_Cntl);
1388       } else {
1389 	 outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl);
1390       }
1391    }
1392 #if DEBUG_RACE
1393    in_interrupt_flag = 0;
1394 #endif
1395    return IRQ_HANDLED;
1396 }
1397 
1398 static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
1399 		void (*done)(struct scsi_cmnd *))
1400 {
1401    if (in_command) {
1402       panic( "scsi: <fdomain> fdomain_16x0_queue() NOT REENTRANT!\n" );
1403    }
1404 #if EVERY_ACCESS
1405    printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1406 	   SCpnt->target,
1407 	   *(unsigned char *)SCpnt->cmnd,
1408 	   SCpnt->use_sg,
1409 	   SCpnt->request_bufflen );
1410 #endif
1411 
1412    fdomain_make_bus_idle();
1413 
1414    current_SC            = SCpnt; /* Save this for the done function */
1415    current_SC->scsi_done = done;
1416 
1417    /* Initialize static data */
1418 
1419    if (current_SC->use_sg) {
1420       current_SC->SCp.buffer =
1421 	    (struct scatterlist *)current_SC->request_buffer;
1422       current_SC->SCp.ptr              = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
1423       current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
1424       current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1425    } else {
1426       current_SC->SCp.ptr              = (char *)current_SC->request_buffer;
1427       current_SC->SCp.this_residual    = current_SC->request_bufflen;
1428       current_SC->SCp.buffer           = NULL;
1429       current_SC->SCp.buffers_residual = 0;
1430    }
1431 
1432 
1433    current_SC->SCp.Status              = 0;
1434    current_SC->SCp.Message             = 0;
1435    current_SC->SCp.have_data_in        = 0;
1436    current_SC->SCp.sent_command        = 0;
1437    current_SC->SCp.phase               = in_arbitration;
1438 
1439    /* Start arbitration */
1440    outb(0x00, port_base + Interrupt_Cntl);
1441    outb(0x00, port_base + SCSI_Cntl);              /* Disable data drivers */
1442    outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */
1443    ++in_command;
1444    outb(0x20, port_base + Interrupt_Cntl);
1445    outb(0x14 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */
1446 
1447    return 0;
1448 }
1449 
1450 #if DEBUG_ABORT
1451 static void print_info(struct scsi_cmnd *SCpnt)
1452 {
1453    unsigned int imr;
1454    unsigned int irr;
1455    unsigned int isr;
1456 
1457    if (!SCpnt || !SCpnt->device || !SCpnt->device->host) {
1458       printk(KERN_WARNING "scsi: <fdomain> Cannot provide detailed information\n");
1459       return;
1460    }
1461 
1462    printk(KERN_INFO "%s\n", fdomain_16x0_info( SCpnt->device->host ) );
1463    print_banner(SCpnt->device->host);
1464    switch (SCpnt->SCp.phase) {
1465    case in_arbitration: printk("arbitration"); break;
1466    case in_selection:   printk("selection");   break;
1467    case in_other:       printk("other");       break;
1468    default:             printk("unknown");     break;
1469    }
1470 
1471    printk( " (%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1472 	   SCpnt->SCp.phase,
1473 	   SCpnt->device->id,
1474 	   *(unsigned char *)SCpnt->cmnd,
1475 	   SCpnt->use_sg,
1476 	   SCpnt->request_bufflen );
1477    printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1478 	   SCpnt->SCp.sent_command,
1479 	   SCpnt->SCp.have_data_in,
1480 	   SCpnt->timeout );
1481 #if DEBUG_RACE
1482    printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1483 #endif
1484 
1485    imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1486    outb( 0x0a, 0xa0 );
1487    irr = inb( 0xa0 ) << 8;
1488    outb( 0x0a, 0x20 );
1489    irr += inb( 0x20 );
1490    outb( 0x0b, 0xa0 );
1491    isr = inb( 0xa0 ) << 8;
1492    outb( 0x0b, 0x20 );
1493    isr += inb( 0x20 );
1494 
1495 				/* Print out interesting information */
1496    printk( "IMR = 0x%04x", imr );
1497    if (imr & (1 << interrupt_level))
1498 	 printk( " (masked)" );
1499    printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1500 
1501    printk( "SCSI Status      = 0x%02x\n", inb(port_base + SCSI_Status));
1502    printk( "TMC Status       = 0x%02x", inb(port_base + TMC_Status));
1503    if (inb((port_base + TMC_Status) & 1))
1504 	 printk( " (interrupt)" );
1505    printk( "\n" );
1506    printk("Interrupt Status = 0x%02x", inb(port_base + Interrupt_Status));
1507    if (inb(port_base + Interrupt_Status) & 0x08)
1508 	 printk( " (enabled)" );
1509    printk( "\n" );
1510    if (chip == tmc18c50 || chip == tmc18c30) {
1511       printk("FIFO Status      = 0x%02x\n", inb(port_base + FIFO_Status));
1512       printk( "Int. Condition   = 0x%02x\n",
1513 	      inb( port_base + Interrupt_Cond ) );
1514    }
1515    printk( "Configuration 1  = 0x%02x\n", inb( port_base + Configuration1 ) );
1516    if (chip == tmc18c50 || chip == tmc18c30)
1517 	 printk( "Configuration 2  = 0x%02x\n",
1518 		 inb( port_base + Configuration2 ) );
1519 }
1520 #endif
1521 
1522 static int fdomain_16x0_abort(struct scsi_cmnd *SCpnt)
1523 {
1524 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1525    printk( "scsi: <fdomain> abort " );
1526 #endif
1527 
1528    if (!in_command) {
1529 #if EVERY_ACCESS || ERRORS_ONLY
1530       printk( " (not in command)\n" );
1531 #endif
1532       return FAILED;
1533    } else printk( "\n" );
1534 
1535 #if DEBUG_ABORT
1536    print_info( SCpnt );
1537 #endif
1538 
1539    fdomain_make_bus_idle();
1540    current_SC->SCp.phase |= aborted;
1541    current_SC->result = DID_ABORT << 16;
1542 
1543    /* Aborts are not done well. . . */
1544    my_done(DID_ABORT << 16);
1545    return SUCCESS;
1546 }
1547 
1548 int fdomain_16x0_bus_reset(struct scsi_cmnd *SCpnt)
1549 {
1550    unsigned long flags;
1551 
1552    local_irq_save(flags);
1553 
1554    outb(1, port_base + SCSI_Cntl);
1555    do_pause( 2 );
1556    outb(0, port_base + SCSI_Cntl);
1557    do_pause( 115 );
1558    outb(0, port_base + SCSI_Mode_Cntl);
1559    outb(PARITY_MASK, port_base + TMC_Cntl);
1560 
1561    local_irq_restore(flags);
1562    return SUCCESS;
1563 }
1564 
1565 static int fdomain_16x0_biosparam(struct scsi_device *sdev,
1566 		struct block_device *bdev,
1567 		sector_t capacity, int *info_array)
1568 {
1569    int              drive;
1570    int		    size      = capacity;
1571    unsigned long    offset;
1572    struct drive_info {
1573       unsigned short cylinders;
1574       unsigned char  heads;
1575       unsigned char  sectors;
1576    } i;
1577 
1578    /* NOTES:
1579       The RAM area starts at 0x1f00 from the bios_base address.
1580 
1581       For BIOS Version 2.0:
1582 
1583       The drive parameter table seems to start at 0x1f30.
1584       The first byte's purpose is not known.
1585       Next is the cylinder, head, and sector information.
1586       The last 4 bytes appear to be the drive's size in sectors.
1587       The other bytes in the drive parameter table are unknown.
1588       If anyone figures them out, please send me mail, and I will
1589       update these notes.
1590 
1591       Tape drives do not get placed in this table.
1592 
1593       There is another table at 0x1fea:
1594       If the byte is 0x01, then the SCSI ID is not in use.
1595       If the byte is 0x18 or 0x48, then the SCSI ID is in use,
1596       although tapes don't seem to be in this table.  I haven't
1597       seen any other numbers (in a limited sample).
1598 
1599       0x1f2d is a drive count (i.e., not including tapes)
1600 
1601       The table at 0x1fcc are I/O ports addresses for the various
1602       operations.  I calculate these by hand in this driver code.
1603 
1604 
1605 
1606       For the ISA-200S version of BIOS Version 2.0:
1607 
1608       The drive parameter table starts at 0x1f33.
1609 
1610       WARNING: Assume that the table entry is 25 bytes long.  Someone needs
1611       to check this for the Quantum ISA-200S card.
1612 
1613 
1614 
1615       For BIOS Version 3.2:
1616 
1617       The drive parameter table starts at 0x1f70.  Each entry is
1618       0x0a bytes long.  Heads are one less than we need to report.
1619     */
1620 
1621    if (MAJOR(bdev->bd_dev) != SCSI_DISK0_MAJOR) {
1622       printk("scsi: <fdomain> fdomain_16x0_biosparam: too many disks");
1623       return 0;
1624    }
1625    drive = MINOR(bdev->bd_dev) >> 4;
1626 
1627    if (bios_major == 2) {
1628       switch (Quantum) {
1629       case 2:			/* ISA_200S */
1630 				/* The value of 25 has never been verified.
1631 				   It should probably be 15. */
1632 	 offset = 0x1f33 + drive * 25;
1633 	 break;
1634       case 3:			/* ISA_250MG */
1635 	 offset = 0x1f36 + drive * 15;
1636 	 break;
1637       case 4:			/* ISA_200S (another one) */
1638 	 offset = 0x1f34 + drive * 15;
1639 	 break;
1640       default:
1641 	 offset = 0x1f31 + drive * 25;
1642 	 break;
1643       }
1644       memcpy_fromio( &i, bios_mem + offset, sizeof( struct drive_info ) );
1645       info_array[0] = i.heads;
1646       info_array[1] = i.sectors;
1647       info_array[2] = i.cylinders;
1648    } else if (bios_major == 3
1649 	      && bios_minor >= 0
1650 	      && bios_minor < 4) { /* 3.0 and 3.2 BIOS */
1651       memcpy_fromio( &i, bios_mem + 0x1f71 + drive * 10,
1652 		     sizeof( struct drive_info ) );
1653       info_array[0] = i.heads + 1;
1654       info_array[1] = i.sectors;
1655       info_array[2] = i.cylinders;
1656    } else {			/* 3.4 BIOS (and up?) */
1657       /* This algorithm was provided by Future Domain (much thanks!). */
1658       unsigned char *p = scsi_bios_ptable(bdev);
1659 
1660       if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */
1661 	  && p[4]) {			    /* Partition type */
1662 
1663 	 /* The partition table layout is as follows:
1664 
1665 	    Start: 0x1b3h
1666 	    Offset: 0 = partition status
1667 		    1 = starting head
1668 		    2 = starting sector and cylinder (word, encoded)
1669 		    4 = partition type
1670 		    5 = ending head
1671 		    6 = ending sector and cylinder (word, encoded)
1672 		    8 = starting absolute sector (double word)
1673 		    c = number of sectors (double word)
1674 	    Signature: 0x1fe = 0x55aa
1675 
1676 	    So, this algorithm assumes:
1677 	    1) the first partition table is in use,
1678 	    2) the data in the first entry is correct, and
1679 	    3) partitions never divide cylinders
1680 
1681 	    Note that (1) may be FALSE for NetBSD (and other BSD flavors),
1682 	    as well as for Linux.  Note also, that Linux doesn't pay any
1683 	    attention to the fields that are used by this algorithm -- it
1684 	    only uses the absolute sector data.  Recent versions of Linux's
1685 	    fdisk(1) will fill this data in correctly, and forthcoming
1686 	    versions will check for consistency.
1687 
1688 	    Checking for a non-zero partition type is not part of the
1689 	    Future Domain algorithm, but it seemed to be a reasonable thing
1690 	    to do, especially in the Linux and BSD worlds. */
1691 
1692 	 info_array[0] = p[5] + 1;	    /* heads */
1693 	 info_array[1] = p[6] & 0x3f;	    /* sectors */
1694       } else {
1695 
1696  	 /* Note that this new method guarantees that there will always be
1697 	    less than 1024 cylinders on a platter.  This is good for drives
1698 	    up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
1699 
1700 	 if ((unsigned int)size >= 0x7e0000U) {
1701 	    info_array[0] = 0xff; /* heads   = 255 */
1702 	    info_array[1] = 0x3f; /* sectors =  63 */
1703 	 } else if ((unsigned int)size >= 0x200000U) {
1704 	    info_array[0] = 0x80; /* heads   = 128 */
1705 	    info_array[1] = 0x3f; /* sectors =  63 */
1706 	 } else {
1707 	    info_array[0] = 0x40; /* heads   =  64 */
1708 	    info_array[1] = 0x20; /* sectors =  32 */
1709 	 }
1710       }
1711 				/* For both methods, compute the cylinders */
1712       info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] );
1713       kfree(p);
1714    }
1715 
1716    return 0;
1717 }
1718 
1719 static int fdomain_16x0_release(struct Scsi_Host *shpnt)
1720 {
1721 	if (shpnt->irq)
1722 		free_irq(shpnt->irq, shpnt);
1723 	if (shpnt->io_port && shpnt->n_io_port)
1724 		release_region(shpnt->io_port, shpnt->n_io_port);
1725 	if (PCI_bus)
1726 		pci_dev_put(PCI_dev);
1727 	return 0;
1728 }
1729 
1730 struct scsi_host_template fdomain_driver_template = {
1731 	.module			= THIS_MODULE,
1732 	.name			= "fdomain",
1733 	.proc_name		= "fdomain",
1734 	.detect			= fdomain_16x0_detect,
1735 	.info			= fdomain_16x0_info,
1736 	.queuecommand		= fdomain_16x0_queue,
1737 	.eh_abort_handler	= fdomain_16x0_abort,
1738 	.eh_bus_reset_handler	= fdomain_16x0_bus_reset,
1739 	.bios_param		= fdomain_16x0_biosparam,
1740 	.release		= fdomain_16x0_release,
1741 	.can_queue		= 1,
1742 	.this_id		= 6,
1743 	.sg_tablesize		= 64,
1744 	.cmd_per_lun		= 1,
1745 	.use_clustering		= DISABLE_CLUSTERING,
1746 };
1747 
1748 #ifndef PCMCIA
1749 
1750 static struct pci_device_id fdomain_pci_tbl[] __devinitdata = {
1751 	{ PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70,
1752 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
1753 	{ }
1754 };
1755 MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl);
1756 
1757 #define driver_template fdomain_driver_template
1758 #include "scsi_module.c"
1759 
1760 #endif
1761