linux/drivers/scsi/fdomain.c
<<
>>
Prefs
   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
 293MODULE_AUTHOR("Rickard E. Faith");
 294MODULE_DESCRIPTION("Future domain SCSI driver");
 295MODULE_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
 338enum chip_type {
 339   unknown          = 0x00,
 340   tmc1800          = 0x01,
 341   tmc18c50         = 0x02,
 342   tmc18c30         = 0x03,
 343};
 344
 345enum {
 346   in_arbitration   = 0x02,
 347   in_selection     = 0x04,
 348   in_other         = 0x08,
 349   disconnect       = 0x10,
 350   aborted          = 0x20,
 351   sent_ident       = 0x40,
 352};
 353
 354enum 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
 371enum 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 */
 384static int               port_base;
 385static unsigned long     bios_base;
 386static void __iomem *    bios_mem;
 387static int               bios_major;
 388static int               bios_minor;
 389static int               PCI_bus;
 390#ifdef CONFIG_PCI
 391static struct pci_dev   *PCI_dev;
 392#endif
 393static int               Quantum;       /* Quantum board variant */
 394static int               interrupt_level;
 395static volatile int      in_command;
 396static struct scsi_cmnd  *current_SC;
 397static enum chip_type    chip              = unknown;
 398static int               adapter_mask;
 399static int               this_id;
 400static int               setup_called;
 401
 402#if DEBUG_RACE
 403static volatile int      in_interrupt_flag;
 404#endif
 405
 406static int               FIFO_Size = 0x2000; /* 8k FIFO for
 407                                                pre-tmc18c30 chips */
 408
 409static irqreturn_t       do_fdomain_16x0_intr( int irq, void *dev_id );
 410/* Allow insmod parameters to be like LILO parameters.  For example:
 411   insmod fdomain fdomain=0x140,11 */
 412static char * fdomain = NULL;
 413module_param(fdomain, charp, 0);
 414
 415#ifndef PCMCIA
 416
 417static unsigned long addresses[] = {
 418   0xc8000,
 419   0xca000,
 420   0xce000,
 421   0xde000,
 422   0xcc000,             /* Extra addresses for PCI boards */
 423   0xd0000,
 424   0xe0000,
 425};
 426#define ADDRESS_COUNT ARRAY_SIZE(addresses)
 427
 428static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
 429#define PORT_COUNT ARRAY_SIZE(ports)
 430
 431static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
 432
 433#endif /* !PCMCIA */
 434
 435/*
 436
 437  READ THIS BEFORE YOU ADD A SIGNATURE!
 438
 439  READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME!
 440
 441  READ EVERY WORD, ESPECIALLY THE WORD *NOT*
 442
 443  This driver works *ONLY* for Future Domain cards using the TMC-1800,
 444  TMC-18C50, or TMC-18C30 chip.  This includes models TMC-1650, 1660, 1670,
 445  and 1680.  These are all 16-bit cards.
 446
 447  The following BIOS signature signatures are for boards which do *NOT*
 448  work with this driver (these TMC-8xx and TMC-9xx boards may work with the
 449  Seagate driver):
 450
 451  FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88
 452  FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89
 453  FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89
 454  FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90
 455  FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
 456  FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
 457  FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92
 458
 459  (The cards which do *NOT* work are all 8-bit cards -- although some of
 460  them have a 16-bit form-factor, the upper 8-bits are used only for IRQs
 461  and are *NOT* used for data.  You can tell the difference by following
 462  the tracings on the circuit board -- if only the IRQ lines are involved,
 463  you have a "8-bit" card, and should *NOT* use this driver.)
 464
 465*/
 466
 467#ifndef PCMCIA
 468
 469static struct signature {
 470   const char *signature;
 471   int  sig_offset;
 472   int  sig_length;
 473   int  major_bios_version;
 474   int  minor_bios_version;
 475   int  flag; /* 1 == PCI_bus, 2 == ISA_200S, 3 == ISA_250MG, 4 == ISA_200S */
 476} signatures[] = {
 477   /*          1         2         3         4         5         6 */
 478   /* 123456789012345678901234567890123456789012345678901234567890 */
 479   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89",  5, 50,  2,  0, 0 },
 480   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89",  5, 50,  2,  0, 0 },
 481   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50,  2,  0, 2 },
 482   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0",        73, 43,  2,  0, 3 },
 483   { "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.",            72, 39,  2,  0, 4 },
 484   { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92",        5, 44,  3,  0, 0 },
 485   { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93",        5, 44,  3,  2, 0 },
 486   { "IBM F1 P2 BIOS v1.0104/29/93",                        5, 28,  3, -1, 0 },
 487   { "Future Domain Corp. V1.0008/18/93",                   5, 33,  3,  4, 0 },
 488   { "Future Domain Corp. V1.0008/18/93",                  26, 33,  3,  4, 1 },
 489   { "Adaptec AHA-2920 PCI-SCSI Card",                     42, 31,  3, -1, 1 },
 490   { "IBM F1 P264/32",                                      5, 14,  3, -1, 1 },
 491                                /* This next signature may not be a 3.5 bios */
 492   { "Future Domain Corp. V2.0108/18/93",                   5, 33,  3,  5, 0 },
 493   { "FUTURE DOMAIN CORP.  V3.5008/18/93",                  5, 34,  3,  5, 0 },
 494   { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5",        5, 44,  3,  5, 0 },
 495   { "FUTURE DOMAIN CORP.  V3.6008/18/93",                  5, 34,  3,  6, 0 },
 496   { "FUTURE DOMAIN CORP.  V3.6108/18/93",                  5, 34,  3,  6, 0 },
 497   { "FUTURE DOMAIN TMC-18XX",                              5, 22, -1, -1, 0 },
 498
 499   /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE
 500    Also, fix the disk geometry code for your signature and send your
 501    changes for faith@cs.unc.edu.  Above all, do *NOT* change any old
 502    signatures!
 503
 504    Note that the last line will match a "generic" 18XX bios.  Because
 505    Future Domain has changed the host SCSI ID and/or the location of the
 506    geometry information in the on-board RAM area for each of the first
 507    three BIOS's, it is still important to enter a fully qualified
 508    signature in the table for any new BIOS's (after the host SCSI ID and
 509    geometry location are verified). */
 510};
 511
 512#define SIGNATURE_COUNT ARRAY_SIZE(signatures)
 513
 514#endif /* !PCMCIA */
 515
 516static void print_banner( struct Scsi_Host *shpnt )
 517{
 518   if (!shpnt) return;          /* This won't ever happen */
 519
 520   if (bios_major < 0 && bios_minor < 0) {
 521      printk(KERN_INFO "scsi%d: <fdomain> No BIOS; using scsi id %d\n",
 522              shpnt->host_no, shpnt->this_id);
 523   } else {
 524      printk(KERN_INFO "scsi%d: <fdomain> BIOS version ", shpnt->host_no);
 525
 526      if (bios_major >= 0) printk("%d.", bios_major);
 527      else                 printk("?.");
 528
 529      if (bios_minor >= 0) printk("%d", bios_minor);
 530      else                 printk("?.");
 531
 532      printk( " at 0x%lx using scsi id %d\n",
 533              bios_base, shpnt->this_id );
 534   }
 535
 536                                /* If this driver works for later FD PCI
 537                                   boards, we will have to modify banner
 538                                   for additional PCI cards, but for now if
 539                                   it's PCI it's a TMC-3260 - JTM */
 540   printk(KERN_INFO "scsi%d: <fdomain> %s chip at 0x%x irq ",
 541           shpnt->host_no,
 542           chip == tmc1800 ? "TMC-1800" : (chip == tmc18c50 ? "TMC-18C50" : (chip == tmc18c30 ? (PCI_bus ? "TMC-36C70 (PCI bus)" : "TMC-18C30") : "Unknown")),
 543           port_base);
 544
 545   if (interrupt_level)
 546        printk("%d", interrupt_level);
 547   else
 548        printk("<none>");
 549
 550   printk( "\n" );
 551}
 552
 553int fdomain_setup(char *str)
 554{
 555        int ints[4];
 556
 557        (void)get_options(str, ARRAY_SIZE(ints), ints);
 558
 559        if (setup_called++ || ints[0] < 2 || ints[0] > 3) {
 560                printk(KERN_INFO "scsi: <fdomain> Usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n");
 561                printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n");
 562                return 0;
 563        }
 564
 565        port_base       = ints[0] >= 1 ? ints[1] : 0;
 566        interrupt_level = ints[0] >= 2 ? ints[2] : 0;
 567        this_id         = ints[0] >= 3 ? ints[3] : 0;
 568   
 569        bios_major = bios_minor = -1; /* Use geometry for BIOS version >= 3.4 */
 570        ++setup_called;
 571        return 1;
 572}
 573
 574__setup("fdomain=", fdomain_setup);
 575
 576
 577static void do_pause(unsigned amount)   /* Pause for amount*10 milliseconds */
 578{
 579        mdelay(10*amount);
 580}
 581
 582static inline void fdomain_make_bus_idle( void )
 583{
 584   outb(0, port_base + SCSI_Cntl);
 585   outb(0, port_base + SCSI_Mode_Cntl);
 586   if (chip == tmc18c50 || chip == tmc18c30)
 587         outb(0x21 | PARITY_MASK, port_base + TMC_Cntl); /* Clear forced intr. */
 588   else
 589         outb(0x01 | PARITY_MASK, port_base + TMC_Cntl);
 590}
 591
 592static int fdomain_is_valid_port( int port )
 593{
 594#if DEBUG_DETECT 
 595   printk( " (%x%x),",
 596           inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
 597#endif
 598
 599   /* The MCA ID is a unique id for each MCA compatible board.  We
 600      are using ISA boards, but Future Domain provides the MCA ID
 601      anyway.  We can use this ID to ensure that this is a Future
 602      Domain TMC-1660/TMC-1680.
 603    */
 604
 605   if (inb( port + LSB_ID_Code ) != 0xe9) { /* test for 0x6127 id */
 606      if (inb( port + LSB_ID_Code ) != 0x27) return 0;
 607      if (inb( port + MSB_ID_Code ) != 0x61) return 0;
 608      chip = tmc1800;
 609   } else {                                 /* test for 0xe960 id */
 610      if (inb( port + MSB_ID_Code ) != 0x60) return 0;
 611      chip = tmc18c50;
 612
 613                                /* Try to toggle 32-bit mode.  This only
 614                                   works on an 18c30 chip.  (User reports
 615                                   say this works, so we should switch to
 616                                   it in the near future.) */
 617
 618      outb( 0x80, port + IO_Control );
 619      if ((inb( port + Configuration2 ) & 0x80) == 0x80) {
 620         outb( 0x00, port + IO_Control );
 621         if ((inb( port + Configuration2 ) & 0x80) == 0x00) {
 622            chip = tmc18c30;
 623            FIFO_Size = 0x800;  /* 2k FIFO */
 624         }
 625      }
 626                                /* If that failed, we are an 18c50. */
 627   }
 628
 629   return 1;
 630}
 631
 632static int fdomain_test_loopback( void )
 633{
 634   int i;
 635   int result;
 636
 637   for (i = 0; i < 255; i++) {
 638      outb( i, port_base + Write_Loopback );
 639      result = inb( port_base + Read_Loopback );
 640      if (i != result)
 641            return 1;
 642   }
 643   return 0;
 644}
 645
 646#ifndef PCMCIA
 647
 648/* fdomain_get_irq assumes that we have a valid MCA ID for a
 649   TMC-1660/TMC-1680 Future Domain board.  Now, check to be sure the
 650   bios_base matches these ports.  If someone was unlucky enough to have
 651   purchased more than one Future Domain board, then they will have to
 652   modify this code, as we only detect one board here.  [The one with the
 653   lowest bios_base.]
 654
 655   Note that this routine is only used for systems without a PCI BIOS32
 656   (e.g., ISA bus).  For PCI bus systems, this routine will likely fail
 657   unless one of the IRQs listed in the ints array is used by the board.
 658   Sometimes it is possible to use the computer's BIOS setup screen to
 659   configure a PCI system so that one of these IRQs will be used by the
 660   Future Domain card. */
 661
 662static int fdomain_get_irq( int base )
 663{
 664   int options = inb(base + Configuration1);
 665
 666#if DEBUG_DETECT
 667   printk("scsi: <fdomain> Options = %x\n", options);
 668#endif
 669 
 670   /* Check for board with lowest bios_base --
 671      this isn't valid for the 18c30 or for
 672      boards on the PCI bus, so just assume we
 673      have the right board. */
 674
 675   if (chip != tmc18c30 && !PCI_bus && addresses[(options & 0xc0) >> 6 ] != bios_base)
 676        return 0;
 677   return ints[(options & 0x0e) >> 1];
 678}
 679
 680static int fdomain_isa_detect( int *irq, int *iobase )
 681{
 682   int i, j;
 683   int base = 0xdeadbeef;
 684   int flag = 0;
 685
 686#if DEBUG_DETECT
 687   printk( "scsi: <fdomain> fdomain_isa_detect:" );
 688#endif
 689
 690   for (i = 0; i < ADDRESS_COUNT; i++) {
 691      void __iomem *p = ioremap(addresses[i], 0x2000);
 692      if (!p)
 693        continue;
 694#if DEBUG_DETECT
 695      printk( " %lx(%lx),", addresses[i], bios_base );
 696#endif
 697      for (j = 0; j < SIGNATURE_COUNT; j++) {
 698         if (check_signature(p + signatures[j].sig_offset,
 699                             signatures[j].signature,
 700                             signatures[j].sig_length )) {
 701            bios_major = signatures[j].major_bios_version;
 702            bios_minor = signatures[j].minor_bios_version;
 703            PCI_bus    = (signatures[j].flag == 1);
 704            Quantum    = (signatures[j].flag > 1) ? signatures[j].flag : 0;
 705            bios_base  = addresses[i];
 706            bios_mem   = p;
 707            goto found;
 708         }
 709      }
 710      iounmap(p);
 711   }
 712 
 713found:
 714   if (bios_major == 2) {
 715      /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
 716         Assuming the ROM is enabled (otherwise we wouldn't have been
 717         able to read the ROM signature :-), then the ROM sets up the
 718         RAM area with some magic numbers, such as a list of port
 719         base addresses and a list of the disk "geometry" reported to
 720         DOS (this geometry has nothing to do with physical geometry).
 721       */
 722
 723      switch (Quantum) {
 724      case 2:                   /* ISA_200S */
 725      case 3:                   /* ISA_250MG */
 726         base = readb(bios_mem + 0x1fa2) + (readb(bios_mem + 0x1fa3) << 8);
 727         break;
 728      case 4:                   /* ISA_200S (another one) */
 729         base = readb(bios_mem + 0x1fa3) + (readb(bios_mem + 0x1fa4) << 8);
 730         break;
 731      default:
 732         base = readb(bios_mem + 0x1fcc) + (readb(bios_mem + 0x1fcd) << 8);
 733         break;
 734      }
 735   
 736#if DEBUG_DETECT
 737      printk( " %x,", base );
 738#endif
 739
 740      for (i = 0; i < PORT_COUNT; i++) {
 741        if (base == ports[i]) {
 742                if (!request_region(base, 0x10, "fdomain"))
 743                        break;
 744                if (!fdomain_is_valid_port(base)) {
 745                        release_region(base, 0x10);
 746                        break;
 747                }
 748                *irq    = fdomain_get_irq( base );
 749                *iobase = base;
 750                return 1;
 751        }
 752      }
 753
 754      /* This is a bad sign.  It usually means that someone patched the
 755         BIOS signature list (the signatures variable) to contain a BIOS
 756         signature for a board *OTHER THAN* the TMC-1660/TMC-1680. */
 757      
 758#if DEBUG_DETECT
 759      printk( " RAM FAILED, " );
 760#endif
 761   }
 762
 763   /* Anyway, the alternative to finding the address in the RAM is to just
 764      search through every possible port address for one that is attached
 765      to the Future Domain card.  Don't panic, though, about reading all
 766      these random port addresses -- there are rumors that the Future
 767      Domain BIOS does something very similar.
 768
 769      Do not, however, check ports which the kernel knows are being used by
 770      another driver. */
 771
 772   for (i = 0; i < PORT_COUNT; i++) {
 773      base = ports[i];
 774      if (!request_region(base, 0x10, "fdomain")) {
 775#if DEBUG_DETECT
 776         printk( " (%x inuse),", base );
 777#endif
 778         continue;
 779      }
 780#if DEBUG_DETECT
 781      printk( " %x,", base );
 782#endif
 783      flag = fdomain_is_valid_port(base);
 784      if (flag)
 785        break;
 786      release_region(base, 0x10);
 787   }
 788
 789#if DEBUG_DETECT
 790   if (flag) printk( " SUCCESS\n" );
 791   else      printk( " FAILURE\n" );
 792#endif
 793
 794   if (!flag) return 0;         /* iobase not found */
 795
 796   *irq    = fdomain_get_irq( base );
 797   *iobase = base;
 798
 799   return 1;                    /* success */
 800}
 801
 802#else /* PCMCIA */
 803
 804static int fdomain_isa_detect( int *irq, int *iobase )
 805{
 806        if (irq)
 807                *irq = 0;
 808        if (iobase)
 809                *iobase = 0;
 810        return 0;
 811}
 812
 813#endif /* !PCMCIA */
 814
 815
 816/* PCI detection function: int fdomain_pci_bios_detect(int* irq, int*
 817   iobase) This function gets the Interrupt Level and I/O base address from
 818   the PCI configuration registers. */
 819
 820#ifdef CONFIG_PCI
 821static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_pdev )
 822{
 823   unsigned int     pci_irq;                /* PCI interrupt line */
 824   unsigned long    pci_base;               /* PCI I/O base address */
 825   struct pci_dev   *pdev = NULL;
 826
 827#if DEBUG_DETECT
 828   /* Tell how to print a list of the known PCI devices from bios32 and
 829      list vendor and device IDs being used if in debug mode.  */
 830      
 831   printk( "scsi: <fdomain> INFO: use lspci -v to see list of PCI devices\n" );
 832   printk( "scsi: <fdomain> TMC-3260 detect:"
 833           " Using Vendor ID: 0x%x and Device ID: 0x%x\n",
 834           PCI_VENDOR_ID_FD, 
 835           PCI_DEVICE_ID_FD_36C70 );
 836#endif 
 837
 838   if ((pdev = pci_get_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL)
 839                return 0;
 840   if (pci_enable_device(pdev))
 841        goto fail;
 842       
 843#if DEBUG_DETECT
 844   printk( "scsi: <fdomain> TMC-3260 detect:"
 845           " PCI bus %u, device %u, function %u\n",
 846           pdev->bus->number,
 847           PCI_SLOT(pdev->devfn),
 848           PCI_FUNC(pdev->devfn));
 849#endif
 850
 851   /* We now have the appropriate device function for the FD board so we
 852      just read the PCI config info from the registers.  */
 853
 854   pci_base = pci_resource_start(pdev, 0);
 855   pci_irq = pdev->irq;
 856
 857   if (!request_region( pci_base, 0x10, "fdomain" ))
 858        goto fail;
 859
 860   /* Now we have the I/O base address and interrupt from the PCI
 861      configuration registers. */
 862
 863   *irq    = pci_irq;
 864   *iobase = pci_base;
 865   *ret_pdev = pdev;
 866
 867#if DEBUG_DETECT
 868   printk( "scsi: <fdomain> TMC-3260 detect:"
 869           " IRQ = %d, I/O base = 0x%x [0x%lx]\n", *irq, *iobase, pci_base );
 870#endif
 871
 872   if (!fdomain_is_valid_port(pci_base)) {
 873      printk(KERN_ERR "scsi: <fdomain> PCI card detected, but driver not loaded (invalid port)\n" );
 874      release_region(pci_base, 0x10);
 875      goto fail;
 876   }
 877
 878                                /* Fill in a few global variables.  Ugh. */
 879   bios_major = bios_minor = -1;
 880   PCI_bus    = 1;
 881   PCI_dev    = pdev;
 882   Quantum    = 0;
 883   bios_base  = 0;
 884   
 885   return 1;
 886fail:
 887   pci_dev_put(pdev);
 888   return 0;
 889}
 890
 891#endif
 892
 893struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt )
 894{
 895   int              retcode;
 896   struct Scsi_Host *shpnt;
 897   struct pci_dev *pdev = NULL;
 898
 899   if (setup_called) {
 900#if DEBUG_DETECT
 901      printk( "scsi: <fdomain> No BIOS, using port_base = 0x%x, irq = %d\n",
 902              port_base, interrupt_level );
 903#endif
 904      if (!request_region(port_base, 0x10, "fdomain")) {
 905         printk( "scsi: <fdomain> port 0x%x is busy\n", port_base );
 906         printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
 907         return NULL;
 908      }
 909      if (!fdomain_is_valid_port( port_base )) {
 910         printk( "scsi: <fdomain> Cannot locate chip at port base 0x%x\n",
 911                 port_base );
 912         printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
 913         release_region(port_base, 0x10);
 914         return NULL;
 915      }
 916   } else {
 917      int flag = 0;
 918
 919#ifdef CONFIG_PCI
 920                                /* Try PCI detection first */
 921      flag = fdomain_pci_bios_detect( &interrupt_level, &port_base, &pdev );
 922#endif
 923      if (!flag) {
 924                                /* Then try ISA bus detection */
 925         flag = fdomain_isa_detect( &interrupt_level, &port_base );
 926
 927         if (!flag) {
 928            printk( "scsi: <fdomain> Detection failed (no card)\n" );
 929            return NULL;
 930         }
 931      }
 932   }
 933
 934   fdomain_16x0_bus_reset(NULL);
 935
 936   if (fdomain_test_loopback()) {
 937      printk(KERN_ERR  "scsi: <fdomain> Detection failed (loopback test failed at port base 0x%x)\n", port_base);
 938      if (setup_called) {
 939         printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n");
 940      }
 941      goto fail;
 942   }
 943
 944   if (this_id) {
 945      tpnt->this_id = (this_id & 0x07);
 946      adapter_mask  = (1 << tpnt->this_id);
 947   } else {
 948      if (PCI_bus || (bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
 949         tpnt->this_id = 7;
 950         adapter_mask  = 0x80;
 951      } else {
 952         tpnt->this_id = 6;
 953         adapter_mask  = 0x40;
 954      }
 955   }
 956
 957/* Print out a banner here in case we can't
 958   get resources.  */
 959
 960   shpnt = scsi_register( tpnt, 0 );
 961   if(shpnt == NULL) {
 962        release_region(port_base, 0x10);
 963        return NULL;
 964   }
 965   shpnt->irq = interrupt_level;
 966   shpnt->io_port = port_base;
 967   shpnt->n_io_port = 0x10;
 968   print_banner( shpnt );
 969
 970   /* Log IRQ with kernel */   
 971   if (!interrupt_level) {
 972      printk(KERN_ERR "scsi: <fdomain> Card Detected, but driver not loaded (no IRQ)\n" );
 973      goto fail;
 974   } else {
 975      /* Register the IRQ with the kernel */
 976
 977      retcode = request_irq( interrupt_level,
 978                             do_fdomain_16x0_intr, pdev?IRQF_SHARED:0, "fdomain", shpnt);
 979
 980      if (retcode < 0) {
 981         if (retcode == -EINVAL) {
 982            printk(KERN_ERR "scsi: <fdomain> IRQ %d is bad!\n", interrupt_level );
 983            printk(KERN_ERR "                This shouldn't happen!\n" );
 984            printk(KERN_ERR "                Send mail to faith@acm.org\n" );
 985         } else if (retcode == -EBUSY) {
 986            printk(KERN_ERR "scsi: <fdomain> IRQ %d is already in use!\n", interrupt_level );
 987            printk(KERN_ERR "                Please use another IRQ!\n" );
 988         } else {
 989            printk(KERN_ERR "scsi: <fdomain> Error getting IRQ %d\n", interrupt_level );
 990            printk(KERN_ERR "                This shouldn't happen!\n" );
 991            printk(KERN_ERR "                Send mail to faith@acm.org\n" );
 992         }
 993         printk(KERN_ERR "scsi: <fdomain> Detected, but driver not loaded (IRQ)\n" );
 994         goto fail;
 995      }
 996   }
 997   return shpnt;
 998fail:
 999   pci_dev_put(pdev);
1000   release_region(port_base, 0x10);
1001   return NULL;
1002}
1003
1004static int fdomain_16x0_detect(struct scsi_host_template *tpnt)
1005{
1006        if (fdomain)
1007                fdomain_setup(fdomain);
1008        return (__fdomain_16x0_detect(tpnt) != NULL);
1009}
1010
1011static const char *fdomain_16x0_info( struct Scsi_Host *ignore )
1012{
1013   static char buffer[128];
1014   char        *pt;
1015   
1016   strcpy( buffer, "Future Domain 16-bit SCSI Driver Version" );
1017   if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */
1018      strcat( buffer, strchr( VERSION, ':' ) + 1 );
1019      pt = strrchr( buffer, '$') - 1;
1020      if (!pt)                  /* Stripped RCS Revision string? */
1021            pt = buffer + strlen( buffer ) - 1;
1022      if (*pt != ' ')
1023            ++pt;
1024      *pt = '\0';
1025   } else {                     /* Assume VERSION is a number */
1026      strcat( buffer, " " VERSION );
1027   }
1028      
1029   return buffer;
1030}
1031
1032#if 0
1033static int fdomain_arbitrate( void )
1034{
1035   int           status = 0;
1036   unsigned long timeout;
1037
1038#if EVERY_ACCESS
1039   printk( "fdomain_arbitrate()\n" );
1040#endif
1041   
1042   outb(0x00, port_base + SCSI_Cntl);              /* Disable data drivers */
1043   outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */
1044   outb(0x04 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */
1045
1046   timeout = 500;
1047   do {
1048      status = inb(port_base + TMC_Status);        /* Read adapter status */
1049      if (status & 0x02)                      /* Arbitration complete */
1050            return 0;
1051      mdelay(1);                        /* Wait one millisecond */
1052   } while (--timeout);
1053
1054   /* Make bus idle */
1055   fdomain_make_bus_idle();
1056
1057#if EVERY_ACCESS
1058   printk( "Arbitration failed, status = %x\n", status );
1059#endif
1060#if ERRORS_ONLY
1061   printk( "scsi: <fdomain> Arbitration failed, status = %x\n", status );
1062#endif
1063   return 1;
1064}
1065#endif
1066
1067static int fdomain_select( int target )
1068{
1069   int           status;
1070   unsigned long timeout;
1071#if ERRORS_ONLY
1072   static int    flag = 0;
1073#endif
1074
1075   outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */
1076   outb(adapter_mask | (1 << target), port_base + SCSI_Data_NoACK);
1077
1078   /* Stop arbitration and enable parity */
1079   outb(PARITY_MASK, port_base + TMC_Cntl); 
1080
1081   timeout = 350;                       /* 350 msec */
1082
1083   do {
1084      status = inb(port_base + SCSI_Status); /* Read adapter status */
1085      if (status & 1) {                 /* Busy asserted */
1086         /* Enable SCSI Bus (on error, should make bus idle with 0) */
1087         outb(0x80, port_base + SCSI_Cntl);
1088         return 0;
1089      }
1090      mdelay(1);                        /* wait one msec */
1091   } while (--timeout);
1092   /* Make bus idle */
1093   fdomain_make_bus_idle();
1094#if EVERY_ACCESS
1095   if (!target) printk( "Selection failed\n" );
1096#endif
1097#if ERRORS_ONLY
1098   if (!target) {
1099      if (!flag) /* Skip first failure for all chips. */
1100            ++flag;
1101      else
1102            printk( "scsi: <fdomain> Selection failed\n" );
1103   }
1104#endif
1105   return 1;
1106}
1107
1108static void my_done(int error)
1109{
1110   if (in_command) {
1111      in_command = 0;
1112      outb(0x00, port_base + Interrupt_Cntl);
1113      fdomain_make_bus_idle();
1114      current_SC->result = error;
1115      if (current_SC->scsi_done)
1116            current_SC->scsi_done( current_SC );
1117      else panic( "scsi: <fdomain> current_SC->scsi_done() == NULL" );
1118   } else {
1119      panic( "scsi: <fdomain> my_done() called outside of command\n" );
1120   }
1121#if DEBUG_RACE
1122   in_interrupt_flag = 0;
1123#endif
1124}
1125
1126static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
1127{
1128   unsigned long flags;
1129   int      status;
1130   int      done = 0;
1131   unsigned data_count;
1132
1133                                /* The fdomain_16x0_intr is only called via
1134                                   the interrupt handler.  The goal of the
1135                                   sti() here is to allow other
1136                                   interruptions while this routine is
1137                                   running. */
1138
1139   /* Check for other IRQ sources */
1140   if ((inb(port_base + TMC_Status) & 0x01) == 0)
1141        return IRQ_NONE;
1142
1143   /* It is our IRQ */          
1144   outb(0x00, port_base + Interrupt_Cntl);
1145
1146   /* We usually have one spurious interrupt after each command.  Ignore it. */
1147   if (!in_command || !current_SC) {    /* Spurious interrupt */
1148#if EVERY_ACCESS
1149      printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
1150              in_command, current_SC );
1151#endif
1152      return IRQ_NONE;
1153   }
1154
1155   /* Abort calls my_done, so we do nothing here. */
1156   if (current_SC->SCp.phase & aborted) {
1157#if DEBUG_ABORT
1158      printk( "scsi: <fdomain> Interrupt after abort, ignoring\n" );
1159#endif
1160      /*
1161      return IRQ_HANDLED; */
1162   }
1163
1164#if DEBUG_RACE
1165   ++in_interrupt_flag;
1166#endif
1167
1168   if (current_SC->SCp.phase & in_arbitration) {
1169      status = inb(port_base + TMC_Status);        /* Read adapter status */
1170      if (!(status & 0x02)) {
1171#if EVERY_ACCESS
1172         printk( " AFAIL " );
1173#endif
1174         spin_lock_irqsave(current_SC->device->host->host_lock, flags);
1175         my_done( DID_BUS_BUSY << 16 );
1176         spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
1177         return IRQ_HANDLED;
1178      }
1179      current_SC->SCp.phase = in_selection;
1180      
1181      outb(0x40 | FIFO_COUNT, port_base + Interrupt_Cntl);
1182
1183      outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */
1184      outb(adapter_mask | (1 << scmd_id(current_SC)), port_base + SCSI_Data_NoACK);
1185      
1186      /* Stop arbitration and enable parity */
1187      outb(0x10 | PARITY_MASK, port_base + TMC_Cntl);
1188#if DEBUG_RACE
1189      in_interrupt_flag = 0;
1190#endif
1191      return IRQ_HANDLED;
1192   } else if (current_SC->SCp.phase & in_selection) {
1193      status = inb(port_base + SCSI_Status);
1194      if (!(status & 0x01)) {
1195         /* Try again, for slow devices */
1196         if (fdomain_select( scmd_id(current_SC) )) {
1197#if EVERY_ACCESS
1198            printk( " SFAIL " );
1199#endif
1200            spin_lock_irqsave(current_SC->device->host->host_lock, flags);
1201            my_done( DID_NO_CONNECT << 16 );
1202            spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
1203            return IRQ_HANDLED;
1204         } else {
1205#if EVERY_ACCESS
1206            printk( " AltSel " );
1207#endif
1208            /* Stop arbitration and enable parity */
1209            outb(0x10 | PARITY_MASK, port_base + TMC_Cntl);
1210         }
1211      }
1212      current_SC->SCp.phase = in_other;
1213      outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl);
1214      outb(0x80, port_base + SCSI_Cntl);
1215#if DEBUG_RACE
1216      in_interrupt_flag = 0;
1217#endif
1218      return IRQ_HANDLED;
1219   }
1220   
1221   /* current_SC->SCp.phase == in_other: this is the body of the routine */
1222   
1223   status = inb(port_base + SCSI_Status);
1224   
1225   if (status & 0x10) { /* REQ */
1226      
1227      switch (status & 0x0e) {
1228       
1229      case 0x08:                /* COMMAND OUT */
1230         outb(current_SC->cmnd[current_SC->SCp.sent_command++],
1231              port_base + Write_SCSI_Data);
1232#if EVERY_ACCESS
1233         printk( "CMD = %x,",
1234                 current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
1235#endif
1236         break;
1237      case 0x00:                /* DATA OUT -- tmc18c50/tmc18c30 only */
1238         if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1239            current_SC->SCp.have_data_in = -1;
1240            outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl);
1241         }
1242         break;
1243      case 0x04:                /* DATA IN -- tmc18c50/tmc18c30 only */
1244         if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1245            current_SC->SCp.have_data_in = 1;
1246            outb(0x90 | PARITY_MASK, port_base + TMC_Cntl);
1247         }
1248         break;
1249      case 0x0c:                /* STATUS IN */
1250         current_SC->SCp.Status = inb(port_base + Read_SCSI_Data);
1251#if EVERY_ACCESS
1252         printk( "Status = %x, ", current_SC->SCp.Status );
1253#endif
1254#if ERRORS_ONLY
1255         if (current_SC->SCp.Status
1256             && current_SC->SCp.Status != 2
1257             && current_SC->SCp.Status != 8) {
1258            printk( "scsi: <fdomain> target = %d, command = %x, status = %x\n",
1259                    current_SC->device->id,
1260                    current_SC->cmnd[0],
1261                    current_SC->SCp.Status );
1262         }
1263#endif
1264               break;
1265      case 0x0a:                /* MESSAGE OUT */
1266         outb(MESSAGE_REJECT, port_base + Write_SCSI_Data); /* Reject */
1267         break;
1268      case 0x0e:                /* MESSAGE IN */
1269         current_SC->SCp.Message = inb(port_base + Read_SCSI_Data);
1270#if EVERY_ACCESS
1271         printk( "Message = %x, ", current_SC->SCp.Message );
1272#endif
1273         if (!current_SC->SCp.Message) ++done;
1274#if DEBUG_MESSAGES || EVERY_ACCESS
1275         if (current_SC->SCp.Message) {
1276            printk( "scsi: <fdomain> message = %x\n",
1277                    current_SC->SCp.Message );
1278         }
1279#endif
1280         break;
1281      }
1282   }
1283
1284   if (chip == tmc1800 && !current_SC->SCp.have_data_in
1285       && (current_SC->SCp.sent_command >= current_SC->cmd_len)) {
1286      
1287      if(current_SC->sc_data_direction == DMA_TO_DEVICE)
1288      {
1289         current_SC->SCp.have_data_in = -1;
1290         outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl);
1291      }
1292      else
1293      {
1294         current_SC->SCp.have_data_in = 1;
1295         outb(0x90 | PARITY_MASK, port_base + TMC_Cntl);
1296      }
1297   }
1298
1299   if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
1300      while ((data_count = FIFO_Size - inw(port_base + FIFO_Data_Count)) > 512) {
1301#if EVERY_ACCESS
1302         printk( "DC=%d, ", data_count ) ;
1303#endif
1304         if (data_count > current_SC->SCp.this_residual)
1305               data_count = current_SC->SCp.this_residual;
1306         if (data_count > 0) {
1307#if EVERY_ACCESS
1308            printk( "%d OUT, ", data_count );
1309#endif
1310            if (data_count == 1) {
1311               outb(*current_SC->SCp.ptr++, port_base + Write_FIFO);
1312               --current_SC->SCp.this_residual;
1313            } else {
1314               data_count >>= 1;
1315               outsw(port_base + Write_FIFO, current_SC->SCp.ptr, data_count);
1316               current_SC->SCp.ptr += 2 * data_count;
1317               current_SC->SCp.this_residual -= 2 * data_count;
1318            }
1319         }
1320         if (!current_SC->SCp.this_residual) {
1321            if (current_SC->SCp.buffers_residual) {
1322               --current_SC->SCp.buffers_residual;
1323               ++current_SC->SCp.buffer;
1324               current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
1325               current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1326            } else
1327                  break;
1328         }
1329      }
1330   }
1331   
1332   if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
1333      while ((data_count = inw(port_base + FIFO_Data_Count)) > 0) {
1334#if EVERY_ACCESS
1335         printk( "DC=%d, ", data_count );
1336#endif
1337         if (data_count > current_SC->SCp.this_residual)
1338               data_count = current_SC->SCp.this_residual;
1339         if (data_count) {
1340#if EVERY_ACCESS
1341            printk( "%d IN, ", data_count );
1342#endif
1343            if (data_count == 1) {
1344               *current_SC->SCp.ptr++ = inb(port_base + Read_FIFO);
1345               --current_SC->SCp.this_residual;
1346            } else {
1347               data_count >>= 1; /* Number of words */
1348               insw(port_base + Read_FIFO, current_SC->SCp.ptr, data_count);
1349               current_SC->SCp.ptr += 2 * data_count;
1350               current_SC->SCp.this_residual -= 2 * data_count;
1351            }
1352         }
1353         if (!current_SC->SCp.this_residual
1354             && current_SC->SCp.buffers_residual) {
1355            --current_SC->SCp.buffers_residual;
1356            ++current_SC->SCp.buffer;
1357            current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
1358            current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1359         }
1360      }
1361   }
1362   
1363   if (done) {
1364#if EVERY_ACCESS
1365      printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1366#endif
1367
1368#if ERRORS_ONLY
1369      if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
1370              char *buf = scsi_sglist(current_SC);
1371         if ((unsigned char)(*(buf + 2)) & 0x0f) {
1372            unsigned char key;
1373            unsigned char code;
1374            unsigned char qualifier;
1375
1376            key = (unsigned char)(*(buf + 2)) & 0x0f;
1377            code = (unsigned char)(*(buf + 12));
1378            qualifier = (unsigned char)(*(buf + 13));
1379
1380            if (key != UNIT_ATTENTION
1381                && !(key == NOT_READY
1382                     && code == 0x04
1383                     && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1384                && !(key == ILLEGAL_REQUEST && (code == 0x25
1385                                                || code == 0x24
1386                                                || !code)))
1387                  
1388                  printk( "scsi: <fdomain> REQUEST SENSE"
1389                          " Key = %x, Code = %x, Qualifier = %x\n",
1390                          key, code, qualifier );
1391         }
1392      }
1393#endif
1394#if EVERY_ACCESS
1395      printk( "BEFORE MY_DONE. . ." );
1396#endif
1397      spin_lock_irqsave(current_SC->device->host->host_lock, flags);
1398      my_done( (current_SC->SCp.Status & 0xff)
1399               | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1400      spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
1401#if EVERY_ACCESS
1402      printk( "RETURNING.\n" );
1403#endif
1404      
1405   } else {
1406      if (current_SC->SCp.phase & disconnect) {
1407         outb(0xd0 | FIFO_COUNT, port_base + Interrupt_Cntl);
1408         outb(0x00, port_base + SCSI_Cntl);
1409      } else {
1410         outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl);
1411      }
1412   }
1413#if DEBUG_RACE
1414   in_interrupt_flag = 0;
1415#endif
1416   return IRQ_HANDLED;
1417}
1418
1419static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
1420                void (*done)(struct scsi_cmnd *))
1421{
1422   if (in_command) {
1423      panic( "scsi: <fdomain> fdomain_16x0_queue() NOT REENTRANT!\n" );
1424   }
1425#if EVERY_ACCESS
1426   printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1427           SCpnt->target,
1428           *(unsigned char *)SCpnt->cmnd,
1429           scsi_sg_count(SCpnt),
1430           scsi_bufflen(SCpnt));
1431#endif
1432
1433   fdomain_make_bus_idle();
1434
1435   current_SC            = SCpnt; /* Save this for the done function */
1436   current_SC->scsi_done = done;
1437
1438   /* Initialize static data */
1439
1440   if (scsi_sg_count(current_SC)) {
1441           current_SC->SCp.buffer = scsi_sglist(current_SC);
1442           current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
1443           current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
1444           current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
1445   } else {
1446           current_SC->SCp.ptr              = 0;
1447           current_SC->SCp.this_residual    = 0;
1448           current_SC->SCp.buffer           = NULL;
1449           current_SC->SCp.buffers_residual = 0;
1450   }
1451
1452   current_SC->SCp.Status              = 0;
1453   current_SC->SCp.Message             = 0;
1454   current_SC->SCp.have_data_in        = 0;
1455   current_SC->SCp.sent_command        = 0;
1456   current_SC->SCp.phase               = in_arbitration;
1457
1458   /* Start arbitration */
1459   outb(0x00, port_base + Interrupt_Cntl);
1460   outb(0x00, port_base + SCSI_Cntl);              /* Disable data drivers */
1461   outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */
1462   ++in_command;
1463   outb(0x20, port_base + Interrupt_Cntl);
1464   outb(0x14 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */
1465
1466   return 0;
1467}
1468
1469#if DEBUG_ABORT
1470static void print_info(struct scsi_cmnd *SCpnt)
1471{
1472   unsigned int imr;
1473   unsigned int irr;
1474   unsigned int isr;
1475
1476   if (!SCpnt || !SCpnt->device || !SCpnt->device->host) {
1477      printk(KERN_WARNING "scsi: <fdomain> Cannot provide detailed information\n");
1478      return;
1479   }
1480   
1481   printk(KERN_INFO "%s\n", fdomain_16x0_info( SCpnt->device->host ) );
1482   print_banner(SCpnt->device->host);
1483   switch (SCpnt->SCp.phase) {
1484   case in_arbitration: printk("arbitration"); break;
1485   case in_selection:   printk("selection");   break;
1486   case in_other:       printk("other");       break;
1487   default:             printk("unknown");     break;
1488   }
1489
1490   printk( " (%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1491           SCpnt->SCp.phase,
1492           SCpnt->device->id,
1493           *(unsigned char *)SCpnt->cmnd,
1494           scsi_sg_count(SCpnt),
1495           scsi_bufflen(SCpnt));
1496   printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1497           SCpnt->SCp.sent_command,
1498           SCpnt->SCp.have_data_in,
1499           SCpnt->timeout );
1500#if DEBUG_RACE
1501   printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1502#endif
1503
1504   imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1505   outb( 0x0a, 0xa0 );
1506   irr = inb( 0xa0 ) << 8;
1507   outb( 0x0a, 0x20 );
1508   irr += inb( 0x20 );
1509   outb( 0x0b, 0xa0 );
1510   isr = inb( 0xa0 ) << 8;
1511   outb( 0x0b, 0x20 );
1512   isr += inb( 0x20 );
1513
1514                                /* Print out interesting information */
1515   printk( "IMR = 0x%04x", imr );
1516   if (imr & (1 << interrupt_level))
1517         printk( " (masked)" );
1518   printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1519
1520   printk( "SCSI Status      = 0x%02x\n", inb(port_base + SCSI_Status));
1521   printk( "TMC Status       = 0x%02x", inb(port_base + TMC_Status));
1522   if (inb((port_base + TMC_Status) & 1))
1523         printk( " (interrupt)" );
1524   printk( "\n" );
1525   printk("Interrupt Status = 0x%02x", inb(port_base + Interrupt_Status));
1526   if (inb(port_base + Interrupt_Status) & 0x08)
1527         printk( " (enabled)" );
1528   printk( "\n" );
1529   if (chip == tmc18c50 || chip == tmc18c30) {
1530      printk("FIFO Status      = 0x%02x\n", inb(port_base + FIFO_Status));
1531      printk( "Int. Condition   = 0x%02x\n",
1532              inb( port_base + Interrupt_Cond ) );
1533   }
1534   printk( "Configuration 1  = 0x%02x\n", inb( port_base + Configuration1 ) );
1535   if (chip == tmc18c50 || chip == tmc18c30)
1536         printk( "Configuration 2  = 0x%02x\n",
1537                 inb( port_base + Configuration2 ) );
1538}
1539#endif
1540
1541static int fdomain_16x0_abort(struct scsi_cmnd *SCpnt)
1542{
1543#if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1544   printk( "scsi: <fdomain> abort " );
1545#endif
1546
1547   if (!in_command) {
1548#if EVERY_ACCESS || ERRORS_ONLY
1549      printk( " (not in command)\n" );
1550#endif
1551      return FAILED;
1552   } else printk( "\n" );
1553
1554#if DEBUG_ABORT
1555   print_info( SCpnt );
1556#endif
1557
1558   fdomain_make_bus_idle();
1559   current_SC->SCp.phase |= aborted;
1560   current_SC->result = DID_ABORT << 16;
1561   
1562   /* Aborts are not done well. . . */
1563   my_done(DID_ABORT << 16);
1564   return SUCCESS;
1565}
1566
1567int fdomain_16x0_bus_reset(struct scsi_cmnd *SCpnt)
1568{
1569   unsigned long flags;
1570
1571   local_irq_save(flags);
1572
1573   outb(1, port_base + SCSI_Cntl);
1574   do_pause( 2 );
1575   outb(0, port_base + SCSI_Cntl);
1576   do_pause( 115 );
1577   outb(0, port_base + SCSI_Mode_Cntl);
1578   outb(PARITY_MASK, port_base + TMC_Cntl);
1579
1580   local_irq_restore(flags);
1581   return SUCCESS;
1582}
1583
1584static int fdomain_16x0_biosparam(struct scsi_device *sdev,
1585                struct block_device *bdev,
1586                sector_t capacity, int *info_array)
1587{
1588   int              drive;
1589   int              size      = capacity;
1590   unsigned long    offset;
1591   struct drive_info {
1592      unsigned short cylinders;
1593      unsigned char  heads;
1594      unsigned char  sectors;
1595   } i;
1596   
1597   /* NOTES:
1598      The RAM area starts at 0x1f00 from the bios_base address.
1599
1600      For BIOS Version 2.0:
1601      
1602      The drive parameter table seems to start at 0x1f30.
1603      The first byte's purpose is not known.
1604      Next is the cylinder, head, and sector information.
1605      The last 4 bytes appear to be the drive's size in sectors.
1606      The other bytes in the drive parameter table are unknown.
1607      If anyone figures them out, please send me mail, and I will
1608      update these notes.
1609
1610      Tape drives do not get placed in this table.
1611
1612      There is another table at 0x1fea:
1613      If the byte is 0x01, then the SCSI ID is not in use.
1614      If the byte is 0x18 or 0x48, then the SCSI ID is in use,
1615      although tapes don't seem to be in this table.  I haven't
1616      seen any other numbers (in a limited sample).
1617
1618      0x1f2d is a drive count (i.e., not including tapes)
1619
1620      The table at 0x1fcc are I/O ports addresses for the various
1621      operations.  I calculate these by hand in this driver code.
1622
1623      
1624      
1625      For the ISA-200S version of BIOS Version 2.0:
1626
1627      The drive parameter table starts at 0x1f33.
1628
1629      WARNING: Assume that the table entry is 25 bytes long.  Someone needs
1630      to check this for the Quantum ISA-200S card.
1631
1632      
1633      
1634      For BIOS Version 3.2:
1635
1636      The drive parameter table starts at 0x1f70.  Each entry is
1637      0x0a bytes long.  Heads are one less than we need to report.
1638    */
1639
1640   if (MAJOR(bdev->bd_dev) != SCSI_DISK0_MAJOR) {
1641      printk("scsi: <fdomain> fdomain_16x0_biosparam: too many disks");
1642      return 0;
1643   }
1644   drive = MINOR(bdev->bd_dev) >> 4;
1645
1646   if (bios_major == 2) {
1647      switch (Quantum) {
1648      case 2:                   /* ISA_200S */
1649                                /* The value of 25 has never been verified.
1650                                   It should probably be 15. */
1651         offset = 0x1f33 + drive * 25;
1652         break;
1653      case 3:                   /* ISA_250MG */
1654         offset = 0x1f36 + drive * 15;
1655         break;
1656      case 4:                   /* ISA_200S (another one) */
1657         offset = 0x1f34 + drive * 15;
1658         break;
1659      default:
1660         offset = 0x1f31 + drive * 25;
1661         break;
1662      }
1663      memcpy_fromio( &i, bios_mem + offset, sizeof( struct drive_info ) );
1664      info_array[0] = i.heads;
1665      info_array[1] = i.sectors;
1666      info_array[2] = i.cylinders;
1667   } else if (bios_major == 3
1668              && bios_minor >= 0
1669              && bios_minor < 4) { /* 3.0 and 3.2 BIOS */
1670      memcpy_fromio( &i, bios_mem + 0x1f71 + drive * 10,
1671                     sizeof( struct drive_info ) );
1672      info_array[0] = i.heads + 1;
1673      info_array[1] = i.sectors;
1674      info_array[2] = i.cylinders;
1675   } else {                     /* 3.4 BIOS (and up?) */
1676      /* This algorithm was provided by Future Domain (much thanks!). */
1677      unsigned char *p = scsi_bios_ptable(bdev);
1678
1679      if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */
1680          && p[4]) {                        /* Partition type */
1681
1682         /* The partition table layout is as follows:
1683
1684            Start: 0x1b3h
1685            Offset: 0 = partition status
1686                    1 = starting head
1687                    2 = starting sector and cylinder (word, encoded)
1688                    4 = partition type
1689                    5 = ending head
1690                    6 = ending sector and cylinder (word, encoded)
1691                    8 = starting absolute sector (double word)
1692                    c = number of sectors (double word)
1693            Signature: 0x1fe = 0x55aa
1694
1695            So, this algorithm assumes:
1696            1) the first partition table is in use,
1697            2) the data in the first entry is correct, and
1698            3) partitions never divide cylinders
1699
1700            Note that (1) may be FALSE for NetBSD (and other BSD flavors),
1701            as well as for Linux.  Note also, that Linux doesn't pay any
1702            attention to the fields that are used by this algorithm -- it
1703            only uses the absolute sector data.  Recent versions of Linux's
1704            fdisk(1) will fill this data in correctly, and forthcoming
1705            versions will check for consistency.
1706
1707            Checking for a non-zero partition type is not part of the
1708            Future Domain algorithm, but it seemed to be a reasonable thing
1709            to do, especially in the Linux and BSD worlds. */
1710
1711         info_array[0] = p[5] + 1;          /* heads */
1712         info_array[1] = p[6] & 0x3f;       /* sectors */
1713      } else {
1714
1715         /* Note that this new method guarantees that there will always be
1716            less than 1024 cylinders on a platter.  This is good for drives
1717            up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
1718
1719         if ((unsigned int)size >= 0x7e0000U) {
1720            info_array[0] = 0xff; /* heads   = 255 */
1721            info_array[1] = 0x3f; /* sectors =  63 */
1722         } else if ((unsigned int)size >= 0x200000U) {
1723            info_array[0] = 0x80; /* heads   = 128 */
1724            info_array[1] = 0x3f; /* sectors =  63 */
1725         } else {
1726            info_array[0] = 0x40; /* heads   =  64 */
1727            info_array[1] = 0x20; /* sectors =  32 */
1728         }
1729      }
1730                                /* For both methods, compute the cylinders */
1731      info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] );
1732      kfree(p);
1733   }
1734   
1735   return 0;
1736}
1737
1738static int fdomain_16x0_release(struct Scsi_Host *shpnt)
1739{
1740        if (shpnt->irq)
1741                free_irq(shpnt->irq, shpnt);
1742        if (shpnt->io_port && shpnt->n_io_port)
1743                release_region(shpnt->io_port, shpnt->n_io_port);
1744        if (PCI_bus)
1745                pci_dev_put(PCI_dev);
1746        return 0;
1747}
1748
1749struct scsi_host_template fdomain_driver_template = {
1750        .module                 = THIS_MODULE,
1751        .name                   = "fdomain",
1752        .proc_name              = "fdomain",
1753        .detect                 = fdomain_16x0_detect,
1754        .info                   = fdomain_16x0_info,
1755        .queuecommand           = fdomain_16x0_queue,
1756        .eh_abort_handler       = fdomain_16x0_abort,
1757        .eh_bus_reset_handler   = fdomain_16x0_bus_reset,
1758        .bios_param             = fdomain_16x0_biosparam,
1759        .release                = fdomain_16x0_release,
1760        .can_queue              = 1,
1761        .this_id                = 6,
1762        .sg_tablesize           = 64,
1763        .cmd_per_lun            = 1,
1764        .use_clustering         = DISABLE_CLUSTERING,
1765};
1766
1767#ifndef PCMCIA
1768#ifdef CONFIG_PCI
1769
1770static struct pci_device_id fdomain_pci_tbl[] __devinitdata = {
1771        { PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70,
1772          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
1773        { }
1774};
1775MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl);
1776#endif
1777#define driver_template fdomain_driver_template
1778#include "scsi_module.c"
1779
1780#endif
1781