root/drivers/scsi/fdomain.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fdomain_setup
  2. do_pause
  3. fdomain_make_bus_idle
  4. fdomain_is_valid_port
  5. fdomain_test_loopback
  6. fdomain_get_irq
  7. fdomain_isa_detect
  8. fdomain_pci_nobios_detect
  9. fdomain_pci_bios_detect
  10. fdomain_16x0_detect
  11. fdomain_16x0_info
  12. fdomain_16x0_proc_info
  13. fdomain_arbitrate
  14. fdomain_select
  15. my_done
  16. fdomain_16x0_intr
  17. fdomain_16x0_queue
  18. internal_done
  19. fdomain_16x0_command
  20. print_info
  21. fdomain_16x0_abort
  22. fdomain_16x0_reset
  23. fdomain_16x0_biosparam

   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: Sun Sep 17 00:23:26 1995 by r.faith@ieee.org
   4  * Author: Rickard E. Faith, faith@cs.unc.edu
   5  * Copyright 1992, 1993, 1994, 1995 Rickard E. Faith
   6  *
   7  * $Id: fdomain.c,v 5.36 1995/09/17 04:23:42 root Exp $
   8 
   9  * This program is free software; you can redistribute it and/or modify it
  10  * under the terms of the GNU General Public License as published by the
  11  * Free Software Foundation; either version 2, or (at your option) any
  12  * later version.
  13 
  14  * This program is distributed in the hope that it will be useful, but
  15  * WITHOUT ANY WARRANTY; without even the implied warranty of
  16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17  * General Public License for more details.
  18 
  19  * You should have received a copy of the GNU General Public License along
  20  * with this program; if not, write to the Free Software Foundation, Inc.,
  21  * 675 Mass Ave, Cambridge, MA 02139, USA.
  22 
  23  **************************************************************************
  24  
  25  DESCRIPTION:
  26 
  27  This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
  28  TMC-1650/1670, and TMC-3260 SCSI host adapters.  The 1650 and 1670 have a
  29  25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
  30  high-density external connector.  The 1670 and 1680 have floppy disk
  31  controllers built in.  The TMC-3260 is a PCI bus card.
  32 
  33  Future Domain's older boards are based on the TMC-1800 chip, and this
  34  driver was originally written for a TMC-1680 board with the TMC-1800 chip.
  35  More recently, boards are being produced with the TMC-18C50 and TMC-18C30
  36  chips.  The latest and greatest board may not work with this driver.  If
  37  you have to patch this driver so that it will recognize your board's BIOS
  38  signature, then the driver may fail to function after the board is
  39  detected.
  40 
  41  The following BIOS versions are supported: 2.0, 3.0, 3.2, 3.4, and 3.5.
  42  The following chips are supported: TMC-1800, TMC-18C50, TMC-18C30.
  43  Reports suggest that the driver will also work with the 36C70 chip and
  44  with the Quantum ISA-200S and ISA-250MG SCSI adapters.
  45 
  46  Please note that the drive ordering that Future Domain implemented in BIOS
  47  versions 3.4 and 3.5 is the opposite of the order (currently) used by the
  48  rest of the SCSI industry.  If you have BIOS version 3.4 or 3.5, and have
  49  more then one drive, then the drive ordering will be the reverse of that
  50  which you see under DOS.  For example, under DOS SCSI ID 0 will be D: and
  51  SCSI ID 1 will be C: (the boot device).  Under Linux, SCSI ID 0 will be
  52  /dev/sda and SCSI ID 1 will be /dev/sdb.  The Linux ordering is consistent
  53  with that provided by all the other SCSI drivers for Linux.  If you want
  54  this changed, send me patches that are protected by #ifdefs.
  55 
  56  If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
  57  your board.  Please refer to the Seagate driver for more information and
  58  possible support.
  59 
  60  
  61 
  62  REFERENCES USED:
  63 
  64  "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
  65  1990.
  66 
  67  "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain
  68  Corporation, January 1992.
  69 
  70  "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
  71  B/September 1991)", Maxtor Corporation, 1991.
  72 
  73  "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
  74 
  75  "Draft Proposed American National Standard: Small Computer System
  76  Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109,
  77  revision 10h, October 17, 1991)
  78 
  79  Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric
  80  Youngdale (ericy@cais.com), 1992.
  81 
  82  Private communication, Tuong Le (Future Domain Engineering department),
  83  1994. (Disk geometry computations for Future Domain BIOS version 3.4, and
  84  TMC-18C30 detection.)
  85 
  86  Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page
  87  60 (2.39: Disk Partition Table Layout).
  88 
  89  "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page
  90  6-1.
  91 
  92 
  93  
  94  NOTES ON REFERENCES:
  95 
  96  The Maxtor manuals were free.  Maxtor telephone technical support is
  97  great!
  98 
  99  The Future Domain manuals were $25 and $35.  They document the chip, not
 100  the TMC-16x0 boards, so some information I had to guess at.  In 1992,
 101  Future Domain sold DOS BIOS source for $250 and the UN*X driver source was
 102  $750, but these required a non-disclosure agreement, so even if I could
 103  have afforded them, they would *not* have been useful for writing this
 104  publically distributable driver.  Future Domain technical support has
 105  provided some information on the phone and have sent a few useful FAXs.
 106  They have been much more helpful since they started to recognize that the
 107  word "Linux" refers to an operating system :-).
 108 
 109  
 110 
 111  ALPHA TESTERS:
 112 
 113  There are many other alpha testers that come and go as the driver
 114  develops.  The people listed here were most helpful in times of greatest
 115  need (mostly early on -- I've probably left out a few worthy people in
 116  more recent times):
 117 
 118  Todd Carrico (todd@wutc.wustl.edu), Dan Poirier (poirier@cs.unc.edu ), Ken
 119  Corey (kenc@sol.acs.unt.edu), C. de Bruin (bruin@bruin@sterbbs.nl), Sakari
 120  Aaltonen (sakaria@vipunen.hit.fi), John Rice (rice@xanth.cs.odu.edu), Brad
 121  Yearwood (brad@optilink.com), and Ray Toy (toy@soho.crd.ge.com).
 122 
 123  Special thanks to Tien-Wan Yang (twyang@cs.uh.edu), who graciously lent me
 124  his 18C50-based card for debugging.  He is the sole reason that this
 125  driver works with the 18C50 chip.
 126 
 127  Thanks to Dave Newman (dnewman@crl.com) for providing initial patches for
 128  the version 3.4 BIOS.
 129 
 130  Thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for providing
 131  patches that support the TMC-3260, a PCI bus card with the 36C70 chip.
 132  The 36C70 chip appears to be "completely compatible" with the 18C30 chip.
 133 
 134  Thanks to Eric Kasten (tigger@petroglyph.cl.msu.edu) for providing the
 135  patch for the version 3.5 BIOS.
 136 
 137  Thanks for Stephen Henson (shenson@nyx10.cs.du.edu) for providing the
 138  patch for the Quantum ISA-200S SCSI adapter.
 139  
 140  Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, to
 141  Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to some
 142  random TMC-1680 repackaged by IBM; and to Mintak Ng (mintak@panix.com) for
 143  the version 3.61 BIOS siganture.
 144 
 145  Thanks for Mark Singer (elf@netcom.com) and Richard Simpson
 146  (rsimpson@ewrcsdra.demon.co.uk) for more Quantum signatures and detective
 147  work on the Quantum RAM layout.
 148 
 149  Special thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for
 150  providing patches for proper PCI BIOS32-mediated detection of the TMC-3260
 151  card (a PCI bus card with the 36C70 chip).  Please send James PCI-related
 152  bug reports.
 153 
 154  Thanks to Tom Cavin (tec@usa1.com) for preliminary command-line option
 155  patches.
 156  
 157  All of the alpha testers deserve much thanks.
 158 
 159 
 160 
 161  NOTES ON USER DEFINABLE OPTIONS:
 162 
 163  DEBUG: This turns on the printing of various debug information.
 164 
 165  ENABLE_PARITY: This turns on SCSI parity checking.  With the current
 166  driver, all attached devices must support SCSI parity.  If none of your
 167  devices support parity, then you can probably get the driver to work by
 168  turning this option off.  I have no way of testing this, however.
 169 
 170  FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the
 171  18C30 chip have a 2k cache).  When this many 512 byte blocks are filled by
 172  the SCSI device, an interrupt will be raised.  Therefore, this could be as
 173  low as 0, or as high as 16.  Note, however, that values which are too high
 174  or too low seem to prevent any interrupts from occurring, and thereby lock
 175  up the machine.  I have found that 2 is a good number, but throughput may
 176  be increased by changing this value to values which are close to 2.
 177  Please let me know if you try any different values.
 178 
 179  DO_DETECT: This activates some old scan code which was needed before the
 180  high level drivers got fixed.  If you are having trouble with the driver,
 181  turning this on should not hurt, and might help.  Please let me know if
 182  this is the case, since this code will be removed from future drivers.
 183 
 184  RESELECTION: This is no longer an option, since I gave up trying to
 185  implement it in version 4.x of this driver.  It did not improve
 186  performance at all and made the driver unstable (because I never found one
 187  of the two race conditions which were introduced by the multiple
 188  outstanding command code).  The instability seems a very high price to pay
 189  just so that you don't have to wait for the tape to rewind.  If you want
 190  this feature implemented, send me patches.  I'll be happy to send a copy
 191  of my (broken) driver to anyone who would like to see a copy.
 192 
 193  **************************************************************************/
 194 
 195 #ifdef MODULE
 196 #include <linux/module.h>
 197 #endif
 198 
 199 #include <linux/sched.h>
 200 #include <asm/io.h>
 201 #include "../block/blk.h"
 202 #include "scsi.h"
 203 #include "hosts.h"
 204 #include "fdomain.h"
 205 #include <asm/system.h>
 206 #include <linux/errno.h>
 207 #include <linux/string.h>
 208 #include <linux/ioport.h>
 209 #include <linux/proc_fs.h>
 210 #include <linux/bios32.h>
 211 #include <linux/pci.h>
 212 #include<linux/stat.h>
 213 
 214 struct proc_dir_entry proc_scsi_fdomain = {
 215     PROC_SCSI_FDOMAIN, 7, "fdomain",
 216     S_IFDIR | S_IRUGO | S_IXUGO, 2
 217 };
 218   
 219 #define VERSION          "$Revision: 5.36 $"
 220 
 221 /* START OF USER DEFINABLE OPTIONS */
 222 
 223 #define DEBUG            1      /* Enable debugging output */
 224 #define ENABLE_PARITY    1      /* Enable SCSI Parity */
 225 #define FIFO_COUNT       2      /* Number of 512 byte blocks before INTR */
 226 #define DO_DETECT        0      /* Do device detection here (see scsi.c) */
 227 
 228 /* END OF USER DEFINABLE OPTIONS */
 229 
 230 #if DEBUG
 231 #define EVERY_ACCESS     0      /* Write a line on every scsi access */
 232 #define ERRORS_ONLY      1      /* Only write a line if there is an error */
 233 #define DEBUG_DETECT     0      /* Debug fdomain_16x0_detect() */
 234 #define DEBUG_MESSAGES   1      /* Debug MESSAGE IN phase */
 235 #define DEBUG_ABORT      1      /* Debug abort() routine */
 236 #define DEBUG_RESET      1      /* Debug reset() routine */
 237 #define DEBUG_RACE       1      /* Debug interrupt-driven race condition */
 238 #else
 239 #define EVERY_ACCESS     0      /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
 240 #define ERRORS_ONLY      0
 241 #define DEBUG_DETECT     0
 242 #define DEBUG_MESSAGES   0
 243 #define DEBUG_ABORT      0
 244 #define DEBUG_RESET      0
 245 #define DEBUG_RACE       0
 246 #endif
 247 
 248 /* Errors are reported on the line, so we don't need to report them again */
 249 #if EVERY_ACCESS
 250 #undef ERRORS_ONLY
 251 #define ERRORS_ONLY      0
 252 #endif
 253 
 254 #if ENABLE_PARITY
 255 #define PARITY_MASK      0x08
 256 #else
 257 #define PARITY_MASK      0x00
 258 #endif
 259 
 260 enum chip_type {
 261    unknown          = 0x00,
 262    tmc1800          = 0x01,
 263    tmc18c50         = 0x02,
 264    tmc18c30         = 0x03,
 265 };
 266 
 267 enum {
 268    in_arbitration   = 0x02,
 269    in_selection     = 0x04,
 270    in_other         = 0x08,
 271    disconnect       = 0x10,
 272    aborted          = 0x20,
 273    sent_ident       = 0x40,
 274 };
 275 
 276 enum in_port_type {
 277    Read_SCSI_Data   =  0,
 278    SCSI_Status      =  1,
 279    TMC_Status       =  2,
 280    FIFO_Status      =  3,       /* tmc18c50/tmc18c30 only */
 281    Interrupt_Cond   =  4,       /* tmc18c50/tmc18c30 only */
 282    LSB_ID_Code      =  5,
 283    MSB_ID_Code      =  6,
 284    Read_Loopback    =  7,
 285    SCSI_Data_NoACK  =  8,
 286    Interrupt_Status =  9,
 287    Configuration1   = 10,
 288    Configuration2   = 11,       /* tmc18c50/tmc18c30 only */
 289    Read_FIFO        = 12,
 290    FIFO_Data_Count  = 14
 291 };
 292 
 293 enum out_port_type {
 294    Write_SCSI_Data  =  0,
 295    SCSI_Cntl        =  1,
 296    Interrupt_Cntl   =  2,
 297    SCSI_Mode_Cntl   =  3,
 298    TMC_Cntl         =  4,
 299    Memory_Cntl      =  5,       /* tmc18c50/tmc18c30 only */
 300    Write_Loopback   =  7,
 301    IO_Control       = 11,       /* tmc18c30 only */
 302    Write_FIFO       = 12
 303 };
 304 
 305 static int               port_base         = 0;
 306 static void              *bios_base        = NULL;
 307 static int               bios_major        = 0;
 308 static int               bios_minor        = 0;
 309 static int               PCI_bus           = 0;
 310 static int               Quantum           = 0; /* Quantum board variant */
 311 static int               interrupt_level   = 0;
 312 static volatile int      in_command        = 0;
 313 static Scsi_Cmnd         *current_SC       = NULL;
 314 static enum chip_type    chip              = unknown;
 315 static int               adapter_mask      = 0;
 316 static int               this_id           = 0;
 317 static int               setup_called      = 0;
 318 
 319 #if DEBUG_RACE
 320 static volatile int      in_interrupt_flag = 0;
 321 #endif
 322 
 323 static int               SCSI_Mode_Cntl_port;
 324 static int               FIFO_Data_Count_port;
 325 static int               Interrupt_Cntl_port;
 326 static int               Interrupt_Status_port;
 327 static int               Read_FIFO_port;
 328 static int               Read_SCSI_Data_port;
 329 static int               SCSI_Cntl_port;
 330 static int               SCSI_Data_NoACK_port;
 331 static int               SCSI_Status_port;
 332 static int               TMC_Cntl_port;
 333 static int               TMC_Status_port;
 334 static int               Write_FIFO_port;
 335 static int               Write_SCSI_Data_port;
 336 
 337 static int               FIFO_Size = 0x2000; /* 8k FIFO for
 338                                                 pre-tmc18c30 chips */
 339 
 340 extern void              fdomain_16x0_intr( int irq, struct pt_regs * regs );
 341 
 342 static void *addresses[] = {
 343    (void *)0xc8000,
 344    (void *)0xca000,
 345    (void *)0xce000,
 346    (void *)0xde000,
 347    (void *)0xd0000,             /* Extra addresses for PCI boards */
 348    (void *)0xe0000,
 349 };
 350 #define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
 351                        
 352 static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
 353 #define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
 354 
 355 static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
 356 
 357 /*
 358 
 359   READ THIS BEFORE YOU ADD A SIGNATURE!
 360 
 361   READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME!
 362 
 363   READ EVERY WORD, ESPECIALLY THE WORD *NOT*
 364 
 365   This driver works *ONLY* for Future Domain cards using the TMC-1800,
 366   TMC-18C50, or TMC-18C30 chip.  This includes models TMC-1650, 1660, 1670,
 367   and 1680.
 368 
 369   The following BIOS signature signatures are for boards which do *NOT*
 370   work with this driver (these TMC-8xx and TMC-9xx boards may work with the
 371   Seagate driver):
 372 
 373   FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88
 374   FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89
 375   FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89
 376   FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90
 377   FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
 378   FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
 379   FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92
 380 
 381 */
 382 
 383 struct signature {
 384    const char *signature;
 385    int  sig_offset;
 386    int  sig_length;
 387    int  major_bios_version;
 388    int  minor_bios_version;
 389    int  flag; /* 1 == PCI_bus, 2 == ISA_200S, 3 == ISA_250MG, 4 == ISA_200S */
 390 } signatures[] = {
 391    /*          1         2         3         4         5         6 */
 392    /* 123456789012345678901234567890123456789012345678901234567890 */
 393    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89",  5, 50,  2,  0, 0 },
 394    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89",  5, 50,  2,  0, 0 },
 395    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50,  2,  0, 2 },
 396    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0",        73, 43,  2,  0, 3 },
 397    { "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.",            72, 39,  2,  0, 4 },
 398    { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92",        5, 44,  3,  0, 0 },
 399    { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93",        5, 44,  3,  2, 0 },
 400    { "IBM F1 P2 BIOS v1.0104/29/93",                        5, 28,  3, -1, 0 },
 401    { "Future Domain Corp. V1.0008/18/93",                   5, 33,  3,  4, 0 },
 402    { "Future Domain Corp. V1.0008/18/93",                  26, 33,  3,  4, 1 },
 403                                 /* This next signature may not be a 3.5 bios */
 404    { "Future Domain Corp. V2.0108/18/93",                   5, 33,  3,  5, 0 },
 405    { "FUTURE DOMAIN CORP.  V3.5008/18/93",                  5, 34,  3,  5, 0 },
 406    { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5",        5, 44,  3,  5, 0 },
 407    { "FUTURE DOMAIN CORP.  V3.6108/18/93",                  5, 34,  3,  6, 0 },
 408    { "FUTURE DOMAIN TMC-18XX",                              5, 22, -1, -1, 0 },
 409 
 410    /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE
 411     Also, fix the disk geometry code for your signature and send your
 412     changes for faith@cs.unc.edu.  Above all, do *NOT* change any old
 413     signatures!
 414 
 415     Note that the last line will match a "generic" 18XX bios.  Because
 416     Future Domain has changed the host SCSI ID and/or the location of the
 417     geometry information in the on-board RAM area for each of the first
 418     three BIOS's, it is still important to enter a fully qualified
 419     signature in the table for any new BIOS's (after the host SCSI ID and
 420     geometry location are verified). */
 421 };
 422 
 423 #define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
 424 
 425 static void print_banner( struct Scsi_Host *shpnt )
 426 {
 427    if (!shpnt) return;          /* This won't ever happen */
 428 
 429    if (bios_major < 0 && bios_minor < 0) {
 430       printk( "scsi%d <fdomain>: No BIOS; using scsi id %d\n",
 431               shpnt->host_no, shpnt->this_id );
 432    } else {
 433       printk( "scsi%d <fdomain>: BIOS version ", shpnt->host_no );
 434 
 435       if (bios_major >= 0) printk( "%d.", bios_major );
 436       else                 printk( "?." );
 437 
 438       if (bios_minor >= 0) printk( "%d", bios_minor );
 439       else                 printk( "?." );
 440    
 441       printk( " at 0x%x using scsi id %d\n",
 442               (unsigned)bios_base, shpnt->this_id );
 443    }
 444 
 445                                 /* If this driver works for later FD PCI
 446                                    boards, we will have to modify banner
 447                                    for additional PCI cards, but for now if
 448                                    it's PCI it's a TMC-3260 - JTM */
 449    printk( "scsi%d <fdomain>: %s chip at 0x%x irq ",
 450            shpnt->host_no,
 451            chip == tmc1800 ? "TMC-1800"
 452            : (chip == tmc18c50 ? "TMC-18C50"
 453               : (chip == tmc18c30 ?
 454                  (PCI_bus ? "TMC-36C70 (PCI bus)" : "TMC-18C30")
 455                  : "Unknown")),
 456            port_base );
 457 
 458    if (interrupt_level) printk( "%d", interrupt_level );
 459    else                 printk( "<none>" );
 460 
 461    printk( "\n" );
 462 }
 463 
 464 void fdomain_setup( char *str, int *ints )
     /* [previous][next][first][last][top][bottom][index][help] */
 465 {
 466    if (setup_called++ || ints[0] < 2 || ints[0] > 3) {
 467       printk( "fdomain: usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n" );
 468       printk( "fdomain: bad LILO parameters?\n" );
 469    }
 470 
 471    port_base       = ints[0] >= 1 ? ints[1]        : 0;
 472    interrupt_level = ints[0] >= 2 ? ints[2]        : 0;
 473    adapter_mask    = ints[0] >= 3 ? (1 << ints[3]) : 0;
 474    
 475    bios_major = bios_minor = -1; /* Use geometry for BIOS version >= 3.4 */
 476 }
 477 
 478 
 479 static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */
     /* [previous][next][first][last][top][bottom][index][help] */
 480 {
 481    unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */
 482 
 483    while (jiffies < the_time);
 484 }
 485 
 486 inline static void fdomain_make_bus_idle( void )
     /* [previous][next][first][last][top][bottom][index][help] */
 487 {
 488    outb( 0, SCSI_Cntl_port );
 489    outb( 0, SCSI_Mode_Cntl_port );
 490    if (chip == tmc18c50 || chip == tmc18c30)
 491          outb( 0x21 | PARITY_MASK, TMC_Cntl_port ); /* Clear forced intr. */
 492    else
 493          outb( 0x01 | PARITY_MASK, TMC_Cntl_port );
 494 }
 495 
 496 static int fdomain_is_valid_port( int port )
     /* [previous][next][first][last][top][bottom][index][help] */
 497 {
 498 #if DEBUG_DETECT 
 499    printk( " (%x%x),",
 500            inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
 501 #endif
 502 
 503    /* The MCA ID is a unique id for each MCA compatible board.  We
 504       are using ISA boards, but Future Domain provides the MCA ID
 505       anyway.  We can use this ID to ensure that this is a Future
 506       Domain TMC-1660/TMC-1680.
 507     */
 508 
 509    if (inb( port + LSB_ID_Code ) != 0xe9) { /* test for 0x6127 id */
 510       if (inb( port + LSB_ID_Code ) != 0x27) return 0;
 511       if (inb( port + MSB_ID_Code ) != 0x61) return 0;
 512       chip = tmc1800;
 513    } else {                                 /* test for 0xe960 id */
 514       if (inb( port + MSB_ID_Code ) != 0x60) return 0;
 515       chip = tmc18c50;
 516 
 517 #if 0
 518 
 519                                 /* Try to toggle 32-bit mode.  This only
 520                                    works on an 18c30 chip.  (User reports
 521                                    say that this doesn't work at all, so
 522                                    we'll use the other method.) */
 523 
 524       outb( 0x80, port + IO_Control );
 525       if ((inb( port + Configuration2 ) & 0x80) == 0x80) {
 526          outb( 0x00, port + IO_Control );
 527          if ((inb( port + Configuration2 ) & 0x80) == 0x00) {
 528             chip = tmc18c30;
 529             FIFO_Size = 0x800;  /* 2k FIFO */
 530          }
 531       }
 532 #else
 533 
 534                                 /* That should have worked, but appears to
 535                                    have problems.  Lets assume it is an
 536                                    18c30 if the RAM is disabled. */
 537 
 538       if (inb( port + Configuration2 ) & 0x02) {
 539          chip      = tmc18c30;
 540          FIFO_Size = 0x800;     /* 2k FIFO */
 541       }
 542 #endif
 543                                 /* If that failed, we are an 18c50. */
 544    }
 545 
 546    return 1;
 547 }
 548 
 549 static int fdomain_test_loopback( void )
     /* [previous][next][first][last][top][bottom][index][help] */
 550 {
 551    int i;
 552    int result;
 553 
 554    for (i = 0; i < 255; i++) {
 555       outb( i, port_base + Write_Loopback );
 556       result = inb( port_base + Read_Loopback );
 557       if (i != result)
 558             return 1;
 559    }
 560    return 0;
 561 }
 562 
 563 /* fdomain_get_irq assumes that we have a valid MCA ID for a
 564    TMC-1660/TMC-1680 Future Domain board.  Now, check to be sure the
 565    bios_base matches these ports.  If someone was unlucky enough to have
 566    purchased more than one Future Domain board, then they will have to
 567    modify this code, as we only detect one board here.  [The one with the
 568    lowest bios_base.]
 569 
 570    Note that this routine is only used for systems without a PCI BIOS32
 571    (e.g., ISA bus).  For PCI bus systems, this routine will likely fail
 572    unless one of the IRQs listed in the ints array is used by the board.
 573    Sometimes it is possible to use the computer's BIOS setup screen to
 574    configure a PCI system so that one of these IRQs will be used by the
 575    Future Domain card. */
 576 
 577 static int fdomain_get_irq( int base )
     /* [previous][next][first][last][top][bottom][index][help] */
 578 {
 579    int options = inb( base + Configuration1 );
 580 
 581 #if DEBUG_DETECT
 582    printk( " Options = %x\n", options );
 583 #endif
 584    
 585                                 /* Check for board with lowest bios_base --
 586                                    this isn't valid for the 18c30 or for
 587                                    boards on the PCI bus, so just assume we
 588                                    have the right board. */
 589 
 590    if (chip != tmc18c30
 591        && !PCI_bus
 592        && addresses[ (options & 0xc0) >> 6 ] != bios_base) return 0;
 593 
 594    return ints[ (options & 0x0e) >> 1 ];
 595 }
 596 
 597 static int fdomain_isa_detect( int *irq, int *iobase )
     /* [previous][next][first][last][top][bottom][index][help] */
 598 {
 599    int i;
 600    int base;
 601    int flag = 0;
 602 
 603    if (bios_major == 2) {
 604       /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
 605          Assuming the ROM is enabled (otherwise we wouldn't have been
 606          able to read the ROM signature :-), then the ROM sets up the
 607          RAM area with some magic numbers, such as a list of port
 608          base addresses and a list of the disk "geometry" reported to
 609          DOS (this geometry has nothing to do with physical geometry).
 610        */
 611 
 612       switch (Quantum) {
 613       case 2:                   /* ISA_200S */
 614       case 3:                   /* ISA_250MG */
 615          base = *((char *)bios_base + 0x1fa2)
 616                + (*((char *)bios_base + 0x1fa3) << 8);
 617          break;
 618       case 4:                   /* ISA_200S (another one) */
 619          base = *((char *)bios_base + 0x1fa3)
 620                + (*((char *)bios_base + 0x1fa4) << 8);
 621          break;
 622       default:
 623          base = *((char *)bios_base + 0x1fcc)
 624                + (*((char *)bios_base + 0x1fcd) << 8);
 625          break;
 626       }
 627    
 628 #if DEBUG_DETECT
 629       printk( " %x,", base );
 630 #endif
 631 
 632       for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) {
 633          if (base == ports[i])
 634                ++flag;
 635       }
 636 
 637       if (flag && fdomain_is_valid_port( base )) {
 638          *irq    = fdomain_get_irq( base );
 639          *iobase = base;
 640          return 1;
 641       }
 642       
 643       /* This is a bad sign.  It usually means that someone patched the
 644          BIOS signature list (the signatures variable) to contain a BIOS
 645          signature for a board *OTHER THAN* the TMC-1660/TMC-1680. */
 646       
 647 #if DEBUG_DETECT
 648       printk( " RAM FAILED, " );
 649 #endif
 650    }
 651 
 652    /* Anyway, the alternative to finding the address in the RAM is to just
 653       search through every possible port address for one that is attached
 654       to the Future Domain card.  Don't panic, though, about reading all
 655       these random port addresses -- there are rumors that the Future
 656       Domain BIOS does something very similar.
 657 
 658       Do not, however, check ports which the kernel knows are being used by
 659       another driver. */
 660 
 661    for (i = 0; i < PORT_COUNT; i++) {
 662       base = ports[i];
 663       if (check_region( base, 0x10 )) {
 664 #if DEBUG_DETECT
 665          printk( " (%x inuse),", base );
 666 #endif
 667          continue;
 668       }
 669 #if DEBUG_DETECT
 670       printk( " %x,", base );
 671 #endif
 672       if ((flag = fdomain_is_valid_port( base ))) break;
 673    }
 674 
 675    if (!flag) return 0;         /* iobase not found */
 676 
 677    *irq    = fdomain_get_irq( base );
 678    *iobase = base;
 679 
 680    return 1;                    /* success */
 681 }
 682 
 683 static int fdomain_pci_nobios_detect( int *irq, int *iobase )
     /* [previous][next][first][last][top][bottom][index][help] */
 684 {
 685    int i;
 686    int flag = 0;
 687 
 688    /* The proper way of doing this is to use ask the PCI bus for the device
 689       IRQ and interrupt level.  But we can't do that if PCI BIOS32 support
 690       isn't compiled into the kernel, or if a PCI BIOS32 isn't present.
 691 
 692       Instead, we scan down a bunch of addresses (Future Domain tech
 693       support says we will probably find the address before we get to
 694       0xf800).  This works fine on some systems -- other systems may have
 695       to scan more addresses.  If you have to modify this section for your
 696       installation, please send mail to faith@cs.unc.edu. */
 697 
 698    for (i = 0xfff8; i > 0xe000; i -= 8) {
 699       if (check_region( i, 0x10 )) {
 700 #if DEBUG_DETECT
 701          printk( " (%x inuse)," , i );
 702 #endif
 703          continue;
 704       }
 705       if ((flag = fdomain_is_valid_port( i ))) break;
 706    }
 707 
 708    if (!flag) return 0;         /* iobase not found */
 709 
 710    *irq    = fdomain_get_irq( i );
 711    *iobase = i;
 712 
 713    return 1;                    /* success */
 714 }
 715 
 716 /* PCI detection function: int fdomain_pci_bios_detect(int* irq, int*
 717    iobase) This function gets the Interrupt Level and I/O base address from
 718    the PCI configuration registers.  The I/O base address is masked with
 719    0xfff8 since on my card the address read from the PCI config registers
 720    is off by one from the actual I/O base address necessary for accessing
 721    the status and control registers on the card (PCI config register gives
 722    0xf801, actual address is 0xf800).  This is likely a bug in the FD
 723    config code that writes to the PCI registers, however using a mask
 724    should be safe since I think the scan done by the card to determine the
 725    I/O base is done in increments of 8 (i.e., 0xf800, 0xf808, ...), at
 726    least the old scan code we used to use to get the I/O base did...  Also,
 727    the device ID from the PCI config registers is 0x0 and should be 0x60e9
 728    as it is in the status registers (offset 5 from I/O base).  If this is
 729    changed in future hardware/BIOS changes it will need to be fixed in this
 730    detection function.  Comments, bug reports, etc... on this function
 731    should be sent to mckinley@msupa.pa.msu.edu - James T. McKinley.  */
 732 
 733 #ifdef CONFIG_PCI
 734 static int fdomain_pci_bios_detect( int *irq, int *iobase )
     /* [previous][next][first][last][top][bottom][index][help] */
 735 {
 736    int              error;
 737    unsigned char    pci_bus, pci_dev_fn;    /* PCI bus & device function */
 738    unsigned char    pci_irq;                /* PCI interrupt line */
 739    unsigned int     pci_base;               /* PCI I/O base address */
 740    unsigned short   pci_vendor, pci_device; /* PCI vendor & device IDs */
 741 
 742    /* If the PCI BIOS doesn't exist, use the old-style detection routines.
 743       Otherwise, get the I/O base address and interrupt from the PCI config
 744       registers. */
 745    
 746    if (!pcibios_present()) return fdomain_pci_nobios_detect( irq, iobase );
 747 
 748 #if DEBUG_DETECT
 749    /* Tell how to print a list of the known PCI devices from bios32 and
 750       list vendor and device IDs being used if in debug mode.  */
 751       
 752    printk( "\nINFO: cat /proc/pci to see list of PCI devices from bios32\n" );
 753    printk( "\nTMC-3260 detect:"
 754            " Using PCI Vendor ID: 0x%x, PCI Device ID: 0x%x\n",
 755            PCI_VENDOR_ID_FD, 
 756            PCI_DEVICE_ID_FD_36C70 );
 757 #endif 
 758 
 759    /* We will have to change this if more than 1 PCI bus is present and the
 760       FD scsi host is not on the first bus (i.e., a PCI to PCI bridge,
 761       which is not supported by bios32 right now anyway).  This should
 762       probably be done by a call to pcibios_find_device but I can't get it
 763       to work...  Also the device ID reported from the PCI config registers
 764       does not match the device ID quoted in the tech manual or available
 765       from offset 5 from the I/O base address.  It should be 0x60E9, but it
 766       is 0x0 if read from the PCI config registers.  I guess the FD folks
 767       neglected to write it to the PCI registers...  This loop is necessary
 768       to get the device function (at least until someone can get
 769       pcibios_find_device to work, I cannot but 53c7,8xx.c uses it...). */
 770     
 771    pci_bus = 0;
 772 
 773    for (pci_dev_fn = 0x0; pci_dev_fn < 0xff; pci_dev_fn++) {
 774       pcibios_read_config_word( pci_bus,
 775                                 pci_dev_fn,
 776                                 PCI_VENDOR_ID,
 777                                 &pci_vendor );
 778 
 779       if (pci_vendor == PCI_VENDOR_ID_FD) {
 780          pcibios_read_config_word( pci_bus,
 781                                    pci_dev_fn,
 782                                    PCI_DEVICE_ID,
 783                                    &pci_device );
 784 
 785          if (pci_device == PCI_DEVICE_ID_FD_36C70) {
 786             /* Break out once we have the correct device.  If other FD
 787                PCI devices are added to this driver we will need to add
 788                an or of the other PCI_DEVICE_ID_FD_XXXXX's here. */
 789             break;
 790          } else {
 791             /* If we can't find an FD scsi card we give up. */
 792             return 0;
 793          }
 794       }
 795    }
 796        
 797 #if DEBUG_DETECT
 798    printk( "Future Domain 36C70 : at PCI bus %u, device %u, function %u\n",
 799            pci_bus,
 800            (pci_dev_fn & 0xf8) >> 3, 
 801            pci_dev_fn & 7 );
 802 #endif
 803 
 804    /* We now have the appropriate device function for the FD board so we
 805       just read the PCI config info from the registers.  */
 806 
 807    if ((error = pcibios_read_config_dword( pci_bus,
 808                                            pci_dev_fn, 
 809                                            PCI_BASE_ADDRESS_0,
 810                                            &pci_base ))
 811        || (error = pcibios_read_config_byte( pci_bus,
 812                                              pci_dev_fn, 
 813                                              PCI_INTERRUPT_LINE,
 814                                              &pci_irq ))) {
 815       printk ( "PCI ERROR: Future Domain 36C70 not initializing"
 816                " due to error reading configuration space\n" );
 817       return 0;
 818    } else {
 819 #if DEBUG_DETECT
 820       printk( "TMC-3260 PCI: IRQ = %u, I/O base = 0x%lx\n", 
 821               pci_irq, pci_base );
 822 #endif
 823 
 824       /* Now we have the I/O base address and interrupt from the PCI
 825          configuration registers.  Unfortunately it seems that the I/O base
 826          address is off by one on my card so I mask it with 0xfff8.  This
 827          must be some kind of goof in the FD code that does the autoconfig
 828          and writes to the PCI registers (or maybe I just don't understand
 829          something).  If they fix it in later versions of the card or BIOS
 830          we may have to adjust the address based on the signature or
 831          something...  */
 832 
 833       *irq    = pci_irq;
 834       *iobase = (pci_base & 0xfff8);
 835 
 836 #if DEBUG_DETECT
 837       printk( "TMC-3260 fix: Masking I/O base address with 0xff00.\n" ); 
 838       printk( "TMC-3260: IRQ = %d, I/O base = 0x%x\n", *irq, *iobase );
 839 #endif
 840 
 841       if (!fdomain_is_valid_port( *iobase )) return 0;
 842       return 1;
 843    }
 844    return 0;
 845 }
 846 #endif
 847 
 848 int fdomain_16x0_detect( Scsi_Host_Template *tpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
 849 {
 850    int              i, j;
 851    int              retcode;
 852    struct Scsi_Host *shpnt;
 853 #if DO_DETECT
 854    const int        buflen = 255;
 855    Scsi_Cmnd        SCinit;
 856    unsigned char    do_inquiry[] =       { INQUIRY, 0, 0, 0, buflen, 0 };
 857    unsigned char    do_request_sense[] = { REQUEST_SENSE, 0, 0, 0, buflen, 0 };
 858    unsigned char    do_read_capacity[] = { READ_CAPACITY,
 859                                            0, 0, 0, 0, 0, 0, 0, 0, 0 };
 860    unsigned char    buf[buflen];
 861 #endif
 862 
 863 #if DEBUG_DETECT
 864    printk( "fdomain_16x0_detect()," );
 865 #endif
 866    tpnt->proc_dir = &proc_scsi_fdomain;
 867 
 868    if (setup_called) {
 869 #if DEBUG_DETECT
 870       printk( "no BIOS, using port_base = 0x%x, irq = %d\n",
 871               port_base, interrupt_level );
 872 #endif
 873       if (!fdomain_is_valid_port( port_base )) {
 874          printk( "fdomain: cannot locate chip at port base 0x%x\n",
 875                  port_base );
 876          printk( "fdomain: bad LILO parameters?\n" );
 877          return 0;
 878       }
 879    } else {
 880       int flag = 0;
 881       
 882       for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) {
 883 #if DEBUG_DETECT
 884          printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base );
 885 #endif
 886          for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) {
 887             if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset),
 888                          signatures[j].signature, signatures[j].sig_length )) {
 889                bios_major = signatures[j].major_bios_version;
 890                bios_minor = signatures[j].minor_bios_version;
 891                PCI_bus    = (signatures[j].flag == 1);
 892                Quantum    = (signatures[j].flag > 1) ? signatures[j].flag : 0;
 893                bios_base  = addresses[i];
 894             }
 895          }
 896       }
 897 
 898       if (!bios_base) {
 899 #if DEBUG_DETECT
 900          printk( " FAILED: NO BIOS\n" );
 901 #endif
 902          return 0;
 903       }
 904 
 905       if (!PCI_bus) {
 906          flag = fdomain_isa_detect( &interrupt_level, &port_base );
 907       } else {
 908 #ifdef CONFIG_PCI
 909          flag = fdomain_pci_bios_detect( &interrupt_level, &port_base );
 910 #else
 911          flag = fdomain_pci_nobios_detect( &interrupt_level, &port_base );
 912 #endif
 913       }
 914          
 915       if (!flag) {
 916 #if DEBUG_DETECT
 917          printk( " FAILED: NO PORT\n" );
 918 #endif
 919 #ifdef CONFIG_PCI
 920          printk( "\nTMC-3260 36C70 PCI scsi chip detection failed.\n" );
 921          printk( "Send mail to mckinley@msupa.pa.msu.edu.\n" );
 922 #endif
 923          return 0;              /* Cannot find valid set of ports */
 924       }
 925    }
 926 
 927    SCSI_Mode_Cntl_port   = port_base + SCSI_Mode_Cntl;
 928    FIFO_Data_Count_port  = port_base + FIFO_Data_Count;
 929    Interrupt_Cntl_port   = port_base + Interrupt_Cntl;
 930    Interrupt_Status_port = port_base + Interrupt_Status;
 931    Read_FIFO_port        = port_base + Read_FIFO;
 932    Read_SCSI_Data_port   = port_base + Read_SCSI_Data;
 933    SCSI_Cntl_port        = port_base + SCSI_Cntl;
 934    SCSI_Data_NoACK_port  = port_base + SCSI_Data_NoACK;
 935    SCSI_Status_port      = port_base + SCSI_Status;
 936    TMC_Cntl_port         = port_base + TMC_Cntl;
 937    TMC_Status_port       = port_base + TMC_Status;
 938    Write_FIFO_port       = port_base + Write_FIFO;
 939    Write_SCSI_Data_port  = port_base + Write_SCSI_Data;
 940 
 941    fdomain_16x0_reset( NULL );
 942 
 943    if (fdomain_test_loopback()) {
 944 #if DEBUG_DETECT
 945       printk( "fdomain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
 946 #endif
 947       if (setup_called) {
 948          printk( "fdomain: loopback test failed at port base 0x%x\n",
 949                  port_base );
 950          printk( "fdomain: bad LILO parameters?\n" );
 951       }
 952       return 0;
 953    }
 954 
 955    if (this_id) {
 956       tpnt->this_id = (this_id & 0x7);
 957       adapter_mask  = (1 << tpnt->this_id);
 958    } else {
 959       if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
 960          tpnt->this_id = 7;
 961          adapter_mask  = 0x80;
 962       } else {
 963          tpnt->this_id = 6;
 964          adapter_mask  = 0x40;
 965       }
 966    }
 967 
 968                                 /* Print out a banner here in case we can't
 969                                    get resources.  */
 970 
 971    shpnt = scsi_register( tpnt, 0 );
 972    print_banner( shpnt );
 973 
 974                                 /* Log IRQ with kernel */   
 975    if (!interrupt_level) {
 976       panic( "fdomain: *NO* interrupt level selected!\n" );
 977    } else {
 978       /* Register the IRQ with the kernel */
 979 
 980       retcode = request_irq( interrupt_level,
 981                              fdomain_16x0_intr, SA_INTERRUPT, "fdomain" );
 982 
 983       if (retcode < 0) {
 984          if (retcode == -EINVAL) {
 985             printk( "fdomain: IRQ %d is bad!\n", interrupt_level );
 986             printk( "         This shouldn't happen!\n" );
 987             printk( "         Send mail to faith@cs.unc.edu\n" );
 988          } else if (retcode == -EBUSY) {
 989             printk( "fdomain: IRQ %d is already in use!\n", interrupt_level );
 990             printk( "         Please use another IRQ!\n" );
 991          } else {
 992             printk( "fdomain: Error getting IRQ %d\n", interrupt_level );
 993             printk( "         This shouldn't happen!\n" );
 994             printk( "         Send mail to faith@cs.unc.edu\n" );
 995          }
 996          panic( "fdomain: Driver requires interruptions\n" );
 997       }
 998    }
 999 
1000                                 /* Log I/O ports with kernel */
1001    request_region( port_base, 0x10, "fdomain" );
1002 
1003 #if DO_DETECT
1004 
1005    /* These routines are here because of the way the SCSI bus behaves after
1006       a reset.  This appropriate behavior was not handled correctly by the
1007       higher level SCSI routines when I first wrote this driver.  Now,
1008       however, correct scan routines are part of scsi.c and these routines
1009       are no longer needed.  However, this code is still good for
1010       debugging.  */
1011 
1012    SCinit.request_buffer  = SCinit.buffer = buf;
1013    SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
1014    SCinit.use_sg          = 0;
1015    SCinit.lun             = 0;
1016 
1017    printk( "fdomain: detection routine scanning for devices:\n" );
1018    for (i = 0; i < 8; i++) {
1019       SCinit.target = i;
1020       if (i == tpnt->this_id)   /* Skip host adapter */
1021             continue;
1022       memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1023       retcode = fdomain_16x0_command(&SCinit);
1024       if (!retcode) {
1025          memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
1026          retcode = fdomain_16x0_command(&SCinit);
1027          if (!retcode) {
1028             printk( "     SCSI ID %d: ", i );
1029             for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
1030                   printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
1031             memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
1032             retcode = fdomain_16x0_command(&SCinit);
1033             if (!retcode) {
1034                unsigned long blocks, size, capacity;
1035                
1036                blocks = (buf[0] << 24) | (buf[1] << 16)
1037                      | (buf[2] << 8) | buf[3];
1038                size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
1039                capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
1040                
1041                printk( "%lu MB (%lu byte blocks)",
1042                        ((capacity + 5L) / 10L), size );
1043             } else {
1044                memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1045                retcode = fdomain_16x0_command(&SCinit);
1046             }
1047             printk ("\n" );
1048          } else {
1049             memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1050             retcode = fdomain_16x0_command(&SCinit);
1051          }
1052       }
1053    }
1054 #endif
1055 
1056    return 1;                    /* Maximum of one adapter will be detected. */
1057 }
1058 
1059 const char *fdomain_16x0_info( struct Scsi_Host *ignore )
     /* [previous][next][first][last][top][bottom][index][help] */
1060 {
1061    static char buffer[80];
1062    char        *pt;
1063    
1064    strcpy( buffer, "Future Domain TMC-16x0 SCSI driver, version" );
1065    if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */
1066       strcat( buffer, strchr( VERSION, ':' ) + 1 );
1067       pt = strrchr( buffer, '$') - 1;
1068       if (!pt)                  /* Stripped RCS Revision string? */
1069             pt = buffer + strlen( buffer ) - 1;
1070       if (*pt != ' ')
1071             ++pt;
1072       *pt = '\0';
1073    } else {                     /* Assume VERSION is a number */
1074       strcat( buffer, " " VERSION );
1075    }
1076       
1077    return buffer;
1078 }
1079 
1080 #if 0
1081                                 /* First pass at /proc information routine. */
1082 /*
1083  * inout : decides on the direction of the dataflow and the meaning of the 
1084  *         variables
1085  * buffer: If inout==FALSE data is beeing written to it else read from it
1086  * *start: If inout==FALSE start of the valid data in the buffer
1087  * offset: If inout==FALSE offset from the beginning of the imaginary file 
1088  *         from which we start writing into the buffer
1089  * length: If inout==FALSE max number of bytes to be written into the buffer 
1090  *         else number of bytes in the buffer
1091  */
1092 int fdomain_16x0_proc_info( char *buffer, char **start, off_t offset,
     /* [previous][next][first][last][top][bottom][index][help] */
1093                             int length, int hostno, int inout )
1094 {
1095    int        len   = 0;
1096    const char *info = fdomain_16x0_info( NULL );
1097    
1098    if (inout) return -ENOSYS;
1099 
1100    strcpy( buffer, info );
1101    len += strlen( info );
1102 
1103    return( len );
1104 }
1105 #endif
1106    
1107 #if 0
1108 static int fdomain_arbitrate( void )
     /* [previous][next][first][last][top][bottom][index][help] */
1109 {
1110    int           status = 0;
1111    unsigned long timeout;
1112 
1113 #if EVERY_ACCESS
1114    printk( "fdomain_arbitrate()\n" );
1115 #endif
1116    
1117    outb( 0x00, SCSI_Cntl_port );              /* Disable data drivers */
1118    outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */
1119    outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
1120 
1121    timeout = jiffies + 50;                    /* 500 mS */
1122    while (jiffies < timeout) {
1123       status = inb( TMC_Status_port );        /* Read adapter status */
1124       if (status & 0x02)                      /* Arbitration complete */
1125             return 0;   
1126    }
1127 
1128    /* Make bus idle */
1129    fdomain_make_bus_idle();
1130 
1131 #if EVERY_ACCESS
1132    printk( "Arbitration failed, status = %x\n", status );
1133 #endif
1134 #if ERRORS_ONLY
1135    printk( "fdomain: Arbitration failed, status = %x\n", status );
1136 #endif
1137    return 1;
1138 }
1139 #endif
1140 
1141 static int fdomain_select( int target )
     /* [previous][next][first][last][top][bottom][index][help] */
1142 {
1143    int           status;
1144    unsigned long timeout;
1145    static int    flag = 0;
1146 
1147 
1148    outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
1149    outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );
1150 
1151    /* Stop arbitration and enable parity */
1152    outb( PARITY_MASK, TMC_Cntl_port ); 
1153 
1154    timeout = jiffies + 35;              /* 350mS -- because of timeouts
1155                                            (was 250mS) */
1156 
1157    while (jiffies < timeout) {
1158       status = inb( SCSI_Status_port ); /* Read adapter status */
1159       if (status & 1) {                 /* Busy asserted */
1160          /* Enable SCSI Bus (on error, should make bus idle with 0) */
1161          outb( 0x80, SCSI_Cntl_port );
1162          return 0;
1163       }
1164    }
1165    /* Make bus idle */
1166    fdomain_make_bus_idle();
1167 #if EVERY_ACCESS
1168    if (!target) printk( "Selection failed\n" );
1169 #endif
1170 #if ERRORS_ONLY
1171    if (!target) {
1172       if (chip == tmc18c30 && !flag) /* Skip first failure for 18C30 chips. */
1173             ++flag;
1174       else
1175             printk( "fdomain: Selection failed\n" );
1176    }
1177 #endif
1178    return 1;
1179 }
1180 
1181 void my_done( int error )
     /* [previous][next][first][last][top][bottom][index][help] */
1182 {
1183    if (in_command) {
1184       in_command = 0;
1185       outb( 0x00, Interrupt_Cntl_port );
1186       fdomain_make_bus_idle();
1187       current_SC->result = error;
1188       if (current_SC->scsi_done)
1189             current_SC->scsi_done( current_SC );
1190       else panic( "fdomain: current_SC->scsi_done() == NULL" );
1191    } else {
1192       panic( "fdomain: my_done() called outside of command\n" );
1193    }
1194 #if DEBUG_RACE
1195    in_interrupt_flag = 0;
1196 #endif
1197 }
1198 
1199 void fdomain_16x0_intr( int irq, struct pt_regs * regs )
     /* [previous][next][first][last][top][bottom][index][help] */
1200 {
1201    int      status;
1202    int      done = 0;
1203    unsigned data_count;
1204 
1205                                 /* The fdomain_16x0_intr is only called via
1206                                    the interrupt handler.  The goal of the
1207                                    sti() here is to allow other
1208                                    interruptions while this routine is
1209                                    running. */
1210 
1211    sti();                       /* Yes, we really want sti() here */
1212    
1213    outb( 0x00, Interrupt_Cntl_port );
1214 
1215    /* We usually have one spurious interrupt after each command.  Ignore it. */
1216    if (!in_command || !current_SC) {    /* Spurious interrupt */
1217 #if EVERY_ACCESS
1218       printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
1219               in_command, current_SC );
1220 #endif
1221       return;
1222    }
1223 
1224    /* Abort calls my_done, so we do nothing here. */
1225    if (current_SC->SCp.phase & aborted) {
1226 #if DEBUG_ABORT
1227       printk( "Interrupt after abort, ignoring\n" );
1228 #endif
1229       /*
1230       return; */
1231    }
1232 
1233 #if DEBUG_RACE
1234    ++in_interrupt_flag;
1235 #endif
1236 
1237    if (current_SC->SCp.phase & in_arbitration) {
1238       status = inb( TMC_Status_port );        /* Read adapter status */
1239       if (!(status & 0x02)) {
1240 #if EVERY_ACCESS
1241          printk( " AFAIL " );
1242 #endif
1243          my_done( DID_BUS_BUSY << 16 );
1244          return;
1245       }
1246       current_SC->SCp.phase = in_selection;
1247       
1248       outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
1249 
1250       outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
1251       outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
1252       
1253       /* Stop arbitration and enable parity */
1254       outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
1255 #if DEBUG_RACE
1256       in_interrupt_flag = 0;
1257 #endif
1258       return;
1259    } else if (current_SC->SCp.phase & in_selection) {
1260       status = inb( SCSI_Status_port );
1261       if (!(status & 0x01)) {
1262          /* Try again, for slow devices */
1263          if (fdomain_select( current_SC->target )) {
1264 #if EVERY_ACCESS
1265             printk( " SFAIL " );
1266 #endif
1267             my_done( DID_NO_CONNECT << 16 );
1268             return;
1269          } else {
1270 #if EVERY_ACCESS
1271             printk( " AltSel " );
1272 #endif
1273             /* Stop arbitration and enable parity */
1274             outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
1275          }
1276       }
1277       current_SC->SCp.phase = in_other;
1278       outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1279       outb( 0x80, SCSI_Cntl_port );
1280 #if DEBUG_RACE
1281       in_interrupt_flag = 0;
1282 #endif
1283       return;
1284    }
1285    
1286    /* current_SC->SCp.phase == in_other: this is the body of the routine */
1287    
1288    status = inb( SCSI_Status_port );
1289    
1290    if (status & 0x10) { /* REQ */
1291       
1292       switch (status & 0x0e) {
1293        
1294       case 0x08:                /* COMMAND OUT */
1295          outb( current_SC->cmnd[current_SC->SCp.sent_command++],
1296                Write_SCSI_Data_port );
1297 #if EVERY_ACCESS
1298          printk( "CMD = %x,",
1299                  current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
1300 #endif
1301          break;
1302       case 0x00:                /* DATA OUT -- tmc18c50/tmc18c30 only */
1303          if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1304             current_SC->SCp.have_data_in = -1;
1305             outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1306          }
1307          break;
1308       case 0x04:                /* DATA IN -- tmc18c50/tmc18c30 only */
1309          if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1310             current_SC->SCp.have_data_in = 1;
1311             outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1312          }
1313          break;
1314       case 0x0c:                /* STATUS IN */
1315          current_SC->SCp.Status = inb( Read_SCSI_Data_port );
1316 #if EVERY_ACCESS
1317          printk( "Status = %x, ", current_SC->SCp.Status );
1318 #endif
1319 #if ERRORS_ONLY
1320          if (current_SC->SCp.Status && current_SC->SCp.Status != 2) {
1321             printk( "fdomain: target = %d, command = %x, status = %x\n",
1322                     current_SC->target,
1323                     current_SC->cmnd[0],
1324                     current_SC->SCp.Status );
1325          }
1326 #endif
1327                break;
1328       case 0x0a:                /* MESSAGE OUT */
1329          outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */
1330          break;
1331       case 0x0e:                /* MESSAGE IN */
1332          current_SC->SCp.Message = inb( Read_SCSI_Data_port );
1333 #if EVERY_ACCESS
1334          printk( "Message = %x, ", current_SC->SCp.Message );
1335 #endif
1336          if (!current_SC->SCp.Message) ++done;
1337 #if DEBUG_MESSAGES || EVERY_ACCESS
1338          if (current_SC->SCp.Message) {
1339             printk( "fdomain: message = %x\n", current_SC->SCp.Message );
1340          }
1341 #endif
1342          break;
1343       }
1344    }
1345 
1346    if (chip == tmc1800
1347        && !current_SC->SCp.have_data_in
1348        && (current_SC->SCp.sent_command
1349            >= current_SC->cmd_len)) {
1350                                 /* We have to get the FIFO direction
1351                                    correct, so I've made a table based
1352                                    on the SCSI Standard of which commands
1353                                    appear to require a DATA OUT phase.
1354                                  */
1355       /*
1356         p. 94: Command for all device types
1357         CHANGE DEFINITION            40 DATA OUT
1358         COMPARE                      39 DATA OUT
1359         COPY                         18 DATA OUT
1360         COPY AND VERIFY              3a DATA OUT
1361         INQUIRY                      12 
1362         LOG SELECT                   4c DATA OUT
1363         LOG SENSE                    4d
1364         MODE SELECT (6)              15 DATA OUT
1365         MODE SELECT (10)             55 DATA OUT
1366         MODE SENSE (6)               1a
1367         MODE SENSE (10)              5a
1368         READ BUFFER                  3c
1369         RECEIVE DIAGNOSTIC RESULTS   1c
1370         REQUEST SENSE                03
1371         SEND DIAGNOSTIC              1d DATA OUT
1372         TEST UNIT READY              00
1373         WRITE BUFFER                 3b DATA OUT
1374 
1375         p.178: Commands for direct-access devices (not listed on p. 94)
1376         FORMAT UNIT                  04 DATA OUT
1377         LOCK-UNLOCK CACHE            36
1378         PRE-FETCH                    34
1379         PREVENT-ALLOW MEDIUM REMOVAL 1e
1380         READ (6)/RECEIVE             08
1381         READ (10)                    3c
1382         READ CAPACITY                25
1383         READ DEFECT DATA (10)        37
1384         READ LONG                    3e
1385         REASSIGN BLOCKS              07 DATA OUT
1386         RELEASE                      17
1387         RESERVE                      16 DATA OUT
1388         REZERO UNIT/REWIND           01
1389         SEARCH DATA EQUAL (10)       31 DATA OUT
1390         SEARCH DATA HIGH (10)        30 DATA OUT
1391         SEARCH DATA LOW (10)         32 DATA OUT
1392         SEEK (6)                     0b
1393         SEEK (10)                    2b
1394         SET LIMITS (10)              33
1395         START STOP UNIT              1b
1396         SYNCHRONIZE CACHE            35
1397         VERIFY (10)                  2f
1398         WRITE (6)/PRINT/SEND         0a DATA OUT
1399         WRITE (10)/SEND              2a DATA OUT
1400         WRITE AND VERIFY (10)        2e DATA OUT
1401         WRITE LONG                   3f DATA OUT
1402         WRITE SAME                   41 DATA OUT ?
1403 
1404         p. 261: Commands for sequential-access devices (not previously listed)
1405         ERASE                        19
1406         LOAD UNLOAD                  1b
1407         LOCATE                       2b
1408         READ BLOCK LIMITS            05
1409         READ POSITION                34
1410         READ REVERSE                 0f
1411         RECOVER BUFFERED DATA        14
1412         SPACE                        11
1413         WRITE FILEMARKS              10 ?
1414 
1415         p. 298: Commands for printer devices (not previously listed)
1416         ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
1417         SLEW AND PRINT               0b DATA OUT  -- same as seek
1418         STOP PRINT                   1b
1419         SYNCHRONIZE BUFFER           10
1420 
1421         p. 315: Commands for processor devices (not previously listed)
1422         
1423         p. 321: Commands for write-once devices (not previously listed)
1424         MEDIUM SCAN                  38
1425         READ (12)                    a8
1426         SEARCH DATA EQUAL (12)       b1 DATA OUT
1427         SEARCH DATA HIGH (12)        b0 DATA OUT
1428         SEARCH DATA LOW (12)         b2 DATA OUT
1429         SET LIMITS (12)              b3
1430         VERIFY (12)                  af
1431         WRITE (12)                   aa DATA OUT
1432         WRITE AND VERIFY (12)        ae DATA OUT
1433 
1434         p. 332: Commands for CD-ROM devices (not previously listed)
1435         PAUSE/RESUME                 4b
1436         PLAY AUDIO (10)              45
1437         PLAY AUDIO (12)              a5
1438         PLAY AUDIO MSF               47
1439         PLAY TRACK RELATIVE (10)     49
1440         PLAY TRACK RELATIVE (12)     a9
1441         READ HEADER                  44
1442         READ SUB-CHANNEL             42
1443         READ TOC                     43
1444 
1445         p. 370: Commands for scanner devices (not previously listed)
1446         GET DATA BUFFER STATUS       34
1447         GET WINDOW                   25
1448         OBJECT POSITION              31
1449         SCAN                         1b
1450         SET WINDOW                   24 DATA OUT
1451 
1452         p. 391: Commands for optical memory devices (not listed)
1453         ERASE (10)                   2c
1454         ERASE (12)                   ac
1455         MEDIUM SCAN                  38 DATA OUT
1456         READ DEFECT DATA (12)        b7
1457         READ GENERATION              29
1458         READ UPDATED BLOCK           2d
1459         UPDATE BLOCK                 3d DATA OUT
1460 
1461         p. 419: Commands for medium changer devices (not listed)
1462         EXCHANGE MEDIUM              46
1463         INITIALIZE ELEMENT STATUS    07
1464         MOVE MEDIUM                  a5
1465         POSITION TO ELEMENT          2b
1466         READ ELEMENT STATUS          b8
1467         REQUEST VOL. ELEMENT ADDRESS b5
1468         SEND VOLUME TAG              b6 DATA OUT
1469 
1470         p. 454: Commands for communications devices (not listed previously)
1471         GET MESSAGE (6)              08
1472         GET MESSAGE (10)             28
1473         GET MESSAGE (12)             a8
1474       */
1475         
1476       switch (current_SC->cmnd[0]) {
1477       case CHANGE_DEFINITION: case COMPARE:         case COPY:
1478       case COPY_VERIFY:       case LOG_SELECT:      case MODE_SELECT:
1479       case MODE_SELECT_10:    case SEND_DIAGNOSTIC: case WRITE_BUFFER:
1480 
1481       case FORMAT_UNIT:       case REASSIGN_BLOCKS: case RESERVE:
1482       case SEARCH_EQUAL:      case SEARCH_HIGH:     case SEARCH_LOW:
1483       case WRITE_6:           case WRITE_10:        case WRITE_VERIFY:
1484       case 0x3f:              case 0x41:
1485 
1486       case 0xb1:              case 0xb0:            case 0xb2:
1487       case 0xaa:              case 0xae:
1488 
1489       case 0x24:
1490 
1491       case 0x38:              case 0x3d:
1492 
1493       case 0xb6:
1494          
1495       case 0xea:                /* alternate number for WRITE LONG */
1496          
1497          current_SC->SCp.have_data_in = -1;
1498          outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1499          break;
1500 
1501       case 0x00:
1502       default:
1503          
1504          current_SC->SCp.have_data_in = 1;
1505          outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1506          break;
1507       }
1508    }
1509 
1510    if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
1511       while ( (data_count = FIFO_Size - inw( FIFO_Data_Count_port )) > 512 ) {
1512 #if EVERY_ACCESS
1513          printk( "DC=%d, ", data_count ) ;
1514 #endif
1515          if (data_count > current_SC->SCp.this_residual)
1516                data_count = current_SC->SCp.this_residual;
1517          if (data_count > 0) {
1518 #if EVERY_ACCESS
1519             printk( "%d OUT, ", data_count );
1520 #endif
1521             if (data_count == 1) {
1522                outb( *current_SC->SCp.ptr++, Write_FIFO_port );
1523                --current_SC->SCp.this_residual;
1524             } else {
1525                data_count >>= 1;
1526                outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count );
1527                current_SC->SCp.ptr += 2 * data_count;
1528                current_SC->SCp.this_residual -= 2 * data_count;
1529             }
1530          }
1531          if (!current_SC->SCp.this_residual) {
1532             if (current_SC->SCp.buffers_residual) {
1533                --current_SC->SCp.buffers_residual;
1534                ++current_SC->SCp.buffer;
1535                current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1536                current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1537             } else
1538                   break;
1539          }
1540       }
1541    }
1542    
1543    if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
1544       while ((data_count = inw( FIFO_Data_Count_port )) > 0) {
1545 #if EVERY_ACCESS
1546          printk( "DC=%d, ", data_count );
1547 #endif
1548          if (data_count > current_SC->SCp.this_residual)
1549                data_count = current_SC->SCp.this_residual;
1550          if (data_count) {
1551 #if EVERY_ACCESS
1552             printk( "%d IN, ", data_count );
1553 #endif
1554             if (data_count == 1) {
1555                *current_SC->SCp.ptr++ = inb( Read_FIFO_port );
1556                --current_SC->SCp.this_residual;
1557             } else {
1558                data_count >>= 1; /* Number of words */
1559                insw( Read_FIFO_port, current_SC->SCp.ptr, data_count );
1560                current_SC->SCp.ptr += 2 * data_count;
1561                current_SC->SCp.this_residual -= 2 * data_count;
1562             }
1563          }
1564          if (!current_SC->SCp.this_residual
1565              && current_SC->SCp.buffers_residual) {
1566             --current_SC->SCp.buffers_residual;
1567             ++current_SC->SCp.buffer;
1568             current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1569             current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1570          }
1571       }
1572    }
1573    
1574    if (done) {
1575 #if EVERY_ACCESS
1576       printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1577 #endif
1578 
1579 #if ERRORS_ONLY
1580       if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
1581          if ((unsigned char)(*((char *)current_SC->request_buffer+2)) & 0x0f) {
1582             unsigned char key;
1583             unsigned char code;
1584             unsigned char qualifier;
1585 
1586             key = (unsigned char)(*((char *)current_SC->request_buffer + 2))
1587                   & 0x0f;
1588             code = (unsigned char)(*((char *)current_SC->request_buffer + 12));
1589             qualifier = (unsigned char)(*((char *)current_SC->request_buffer
1590                                           + 13));
1591 
1592             if (!(key == UNIT_ATTENTION && (code == 0x29 || !code))
1593                 && !(key == NOT_READY
1594                      && code == 0x04
1595                      && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1596                 && !(key == ILLEGAL_REQUEST && (code == 0x25
1597                                                 || code == 0x24
1598                                                 || !code)))
1599                   
1600                   printk( "fdomain: REQUEST SENSE "
1601                           "Key = %x, Code = %x, Qualifier = %x\n",
1602                           key, code, qualifier );
1603          }
1604       }
1605 #endif
1606 #if EVERY_ACCESS
1607       printk( "BEFORE MY_DONE. . ." );
1608 #endif
1609       my_done( (current_SC->SCp.Status & 0xff)
1610                | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1611 #if EVERY_ACCESS
1612       printk( "RETURNING.\n" );
1613 #endif
1614       
1615    } else {
1616       if (current_SC->SCp.phase & disconnect) {
1617          outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
1618          outb( 0x00, SCSI_Cntl_port );
1619       } else {
1620          outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1621       }
1622    }
1623 #if DEBUG_RACE
1624    in_interrupt_flag = 0;
1625 #endif
1626    return;
1627 }
1628 
1629 int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     /* [previous][next][first][last][top][bottom][index][help] */
1630 {
1631    if (in_command) {
1632       panic( "fdomain: fdomain_16x0_queue() NOT REENTRANT!\n" );
1633    }
1634 #if EVERY_ACCESS
1635    printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1636            SCpnt->target,
1637            *(unsigned char *)SCpnt->cmnd,
1638            SCpnt->use_sg,
1639            SCpnt->request_bufflen );
1640 #endif
1641 
1642    fdomain_make_bus_idle();
1643 
1644    current_SC            = SCpnt; /* Save this for the done function */
1645    current_SC->scsi_done = done;
1646 
1647    /* Initialize static data */
1648 
1649    if (current_SC->use_sg) {
1650       current_SC->SCp.buffer =
1651             (struct scatterlist *)current_SC->request_buffer;
1652       current_SC->SCp.ptr              = current_SC->SCp.buffer->address;
1653       current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
1654       current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1655    } else {
1656       current_SC->SCp.ptr              = (char *)current_SC->request_buffer;
1657       current_SC->SCp.this_residual    = current_SC->request_bufflen;
1658       current_SC->SCp.buffer           = NULL;
1659       current_SC->SCp.buffers_residual = 0;
1660    }
1661          
1662    
1663    current_SC->SCp.Status              = 0;
1664    current_SC->SCp.Message             = 0;
1665    current_SC->SCp.have_data_in        = 0;
1666    current_SC->SCp.sent_command        = 0;
1667    current_SC->SCp.phase               = in_arbitration;
1668 
1669    /* Start arbitration */
1670    outb( 0x00, Interrupt_Cntl_port );
1671    outb( 0x00, SCSI_Cntl_port );              /* Disable data drivers */
1672    outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */
1673    ++in_command;
1674    outb( 0x20, Interrupt_Cntl_port );
1675    outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
1676 
1677    return 0;
1678 }
1679 
1680 /* The following code, which simulates the old-style command function, was
1681    taken from Tommy Thorn's aha1542.c file.  This code is Copyright (C)
1682    1992 Tommy Thorn. */
1683 
1684 static volatile int internal_done_flag    = 0;
1685 static volatile int internal_done_errcode = 0;
1686 
1687 static void internal_done( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1688 {
1689     internal_done_errcode = SCpnt->result;
1690     ++internal_done_flag;
1691 }
1692 
1693 int fdomain_16x0_command( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1694 {
1695     fdomain_16x0_queue( SCpnt, internal_done );
1696 
1697     while (!internal_done_flag)
1698           ;
1699     internal_done_flag = 0;
1700     return internal_done_errcode;
1701 }
1702 
1703 /* End of code derived from Tommy Thorn's work. */
1704 
1705 void print_info( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1706 {
1707    unsigned int imr;
1708    unsigned int irr;
1709    unsigned int isr;
1710 
1711    if (!SCpnt || !SCpnt->host) {
1712       printk( "fdomain: cannot provide detailed information\n" );
1713    }
1714    
1715    printk( "%s\n", fdomain_16x0_info( SCpnt->host ) );
1716    print_banner( SCpnt->host );
1717    switch (SCpnt->SCp.phase) {
1718    case in_arbitration: printk( "arbitration " ); break;
1719    case in_selection:   printk( "selection " );   break;
1720    case in_other:       printk( "other " );       break;
1721    default:             printk( "unknown " );     break;
1722    }
1723 
1724    printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1725            SCpnt->SCp.phase,
1726            SCpnt->target,
1727            *(unsigned char *)SCpnt->cmnd,
1728            SCpnt->use_sg,
1729            SCpnt->request_bufflen );
1730    printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1731            SCpnt->SCp.sent_command,
1732            SCpnt->SCp.have_data_in,
1733            SCpnt->timeout );
1734 #if DEBUG_RACE
1735    printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1736 #endif
1737 
1738    imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1739    outb( 0x0a, 0xa0 );
1740    irr = inb( 0xa0 ) << 8;
1741    outb( 0x0a, 0x20 );
1742    irr += inb( 0x20 );
1743    outb( 0x0b, 0xa0 );
1744    isr = inb( 0xa0 ) << 8;
1745    outb( 0x0b, 0x20 );
1746    isr += inb( 0x20 );
1747 
1748                                 /* Print out interesting information */
1749    printk( "IMR = 0x%04x", imr );
1750    if (imr & (1 << interrupt_level))
1751          printk( " (masked)" );
1752    printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1753 
1754    printk( "SCSI Status      = 0x%02x\n", inb( SCSI_Status_port ) );
1755    printk( "TMC Status       = 0x%02x", inb( TMC_Status_port ) );
1756    if (inb( TMC_Status_port & 1))
1757          printk( " (interrupt)" );
1758    printk( "\n" );
1759    printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
1760    if (inb( Interrupt_Status_port ) & 0x08)
1761          printk( " (enabled)" );
1762    printk( "\n" );
1763    if (chip == tmc18c50 || chip == tmc18c30) {
1764       printk( "FIFO Status      = 0x%02x\n", inb( port_base + FIFO_Status ) );
1765       printk( "Int. Condition   = 0x%02x\n",
1766               inb( port_base + Interrupt_Cond ) );
1767    }
1768    printk( "Configuration 1  = 0x%02x\n", inb( port_base + Configuration1 ) );
1769    if (chip == tmc18c50 || chip == tmc18c30)
1770          printk( "Configuration 2  = 0x%02x\n",
1771                  inb( port_base + Configuration2 ) );
1772 }
1773 
1774 int fdomain_16x0_abort( Scsi_Cmnd *SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
1775 {
1776    unsigned long flags;
1777 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1778    printk( "fdomain: abort " );
1779 #endif
1780 
1781    save_flags( flags );
1782    cli();
1783    if (!in_command) {
1784 #if EVERY_ACCESS || ERRORS_ONLY
1785       printk( " (not in command)\n" );
1786 #endif
1787       restore_flags( flags );
1788       return SCSI_ABORT_NOT_RUNNING;
1789    } else printk( "\n" );
1790 
1791 #if DEBUG_ABORT
1792    print_info( SCpnt );
1793 #endif
1794 
1795    fdomain_make_bus_idle();
1796 
1797    current_SC->SCp.phase |= aborted;
1798 
1799    current_SC->result = DID_ABORT << 16;
1800 
1801    restore_flags( flags );
1802    
1803    /* Aborts are not done well. . . */
1804    my_done( DID_ABORT << 16 );
1805 
1806    return SCSI_ABORT_SUCCESS;
1807 }
1808 
1809 int fdomain_16x0_reset( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1810 {
1811 #if DEBUG_RESET
1812    static int called_once = 0;
1813 #endif
1814 
1815 #if ERRORS_ONLY
1816    if (SCpnt) printk( "fdomain: SCSI Bus Reset\n" );
1817 #endif
1818 
1819 #if DEBUG_RESET
1820    if (called_once) print_info( current_SC );
1821    called_once = 1;
1822 #endif
1823    
1824    outb( 1, SCSI_Cntl_port );
1825    do_pause( 2 );
1826    outb( 0, SCSI_Cntl_port );
1827    do_pause( 115 );
1828    outb( 0, SCSI_Mode_Cntl_port );
1829    outb( PARITY_MASK, TMC_Cntl_port );
1830 
1831    /* Unless this is the very first call (i.e., SCPnt == NULL), everything
1832       is probably hosed at this point.  We will, however, try to keep
1833       things going by informing the high-level code that we need help. */
1834 
1835    return SCSI_RESET_WAKEUP;
1836 }
1837 
1838 #include "sd.h"
1839 #include "scsi_ioctl.h"
1840 
1841 int fdomain_16x0_biosparam( Scsi_Disk *disk, kdev_t dev, int *info_array )
     /* [previous][next][first][last][top][bottom][index][help] */
1842 {
1843    int              drive;
1844    unsigned char    buf[512 + sizeof( int ) * 2];
1845    int              size      = disk->capacity;
1846    int              *sizes    = (int *)buf;
1847    unsigned char    *data     = (unsigned char *)(sizes + 2);
1848    unsigned char    do_read[] = { READ_6, 0, 0, 0, 1, 0 };
1849    int              retcode;
1850    struct drive_info {
1851       unsigned short cylinders;
1852       unsigned char  heads;
1853       unsigned char  sectors;
1854    } *i;
1855    
1856    /* NOTES:
1857       The RAM area starts at 0x1f00 from the bios_base address.
1858 
1859       For BIOS Version 2.0:
1860       
1861       The drive parameter table seems to start at 0x1f30.
1862       The first byte's purpose is not known.
1863       Next is the cylinder, head, and sector information.
1864       The last 4 bytes appear to be the drive's size in sectors.
1865       The other bytes in the drive parameter table are unknown.
1866       If anyone figures them out, please send me mail, and I will
1867       update these notes.
1868 
1869       Tape drives do not get placed in this table.
1870 
1871       There is another table at 0x1fea:
1872       If the byte is 0x01, then the SCSI ID is not in use.
1873       If the byte is 0x18 or 0x48, then the SCSI ID is in use,
1874       although tapes don't seem to be in this table.  I haven't
1875       seen any other numbers (in a limited sample).
1876 
1877       0x1f2d is a drive count (i.e., not including tapes)
1878 
1879       The table at 0x1fcc are I/O ports addresses for the various
1880       operations.  I calculate these by hand in this driver code.
1881 
1882       
1883       
1884       For the ISA-200S version of BIOS Version 2.0:
1885 
1886       The drive parameter table starts at 0x1f33.
1887 
1888       WARNING: Assume that the table entry is 25 bytes long.  Someone needs
1889       to check this for the Quantum ISA-200S card.
1890 
1891       
1892       
1893       For BIOS Version 3.2:
1894 
1895       The drive parameter table starts at 0x1f70.  Each entry is
1896       0x0a bytes long.  Heads are one less than we need to report.
1897     */
1898 
1899    drive = MINOR(dev) / 16;
1900 
1901    if (bios_major == 2) {
1902       switch (Quantum) {
1903       case 2:                   /* ISA_200S */
1904                                 /* The value of 25 has never been verified.
1905                                    It should probably be 15. */
1906          i = (struct drive_info *)( (char *)bios_base + 0x1f33 + drive * 25 );
1907          break;
1908       case 3:                   /* ISA_250MG */
1909          i = (struct drive_info *)( (char *)bios_base + 0x1f36 + drive * 15 );
1910          break;
1911       case 4:                   /* ISA_200S (another one) */
1912          i = (struct drive_info *)( (char *)bios_base + 0x1f34 + drive * 15 );
1913          break;
1914       default:
1915          i = (struct drive_info *)( (char *)bios_base + 0x1f31 + drive * 25 );
1916          break;
1917       }
1918       info_array[0] = i->heads;
1919       info_array[1] = i->sectors;
1920       info_array[2] = i->cylinders;
1921    } else if (bios_major == 3
1922               && bios_minor >= 0
1923               && bios_minor < 4) { /* 3.0 and 3.2 BIOS */
1924       i = (struct drive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
1925       info_array[0] = i->heads + 1;
1926       info_array[1] = i->sectors;
1927       info_array[2] = i->cylinders;
1928    } else {                     /* 3.4 BIOS (and up?) */
1929       /* This algorithm was provided by Future Domain (much thanks!). */
1930 
1931       sizes[0] = 0;             /* zero bytes out */
1932       sizes[1] = 512;           /* one sector in */
1933       memcpy( data, do_read, sizeof( do_read ) );
1934       retcode = kernel_scsi_ioctl( disk->device,
1935                                    SCSI_IOCTL_SEND_COMMAND,
1936                                    (void *)buf );
1937       if (!retcode                                  /* SCSI command ok */
1938           && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */
1939           && data[0x1c2]) {                         /* Partition type */
1940 
1941          /* The partition table layout is as follows:
1942 
1943             Start: 0x1b3h
1944             Offset: 0 = partition status
1945                     1 = starting head
1946                     2 = starting sector and cylinder (word, encoded)
1947                     4 = partition type
1948                     5 = ending head
1949                     6 = ending sector and cylinder (word, encoded)
1950                     8 = starting absolute sector (double word)
1951                     c = number of sectors (double word)
1952             Signature: 0x1fe = 0x55aa
1953 
1954             So, this algorithm assumes:
1955             1) the first partition table is in use,
1956             2) the data in the first entry is correct, and
1957             3) partitions never divide cylinders
1958 
1959             Note that (1) may be FALSE for NetBSD (and other BSD flavors),
1960             as well as for Linux.  Note also, that Linux doesn't pay any
1961             attention to the fields that are used by this algorithm -- it
1962             only uses the absolute sector data.  Recent versions of Linux's
1963             fdisk(1) will fill this data in correctly, and forthcoming
1964             versions will check for consistency.
1965 
1966             Checking for a non-zero partition type is not part of the
1967             Future Domain algorithm, but it seemed to be a reasonable thing
1968             to do, especially in the Linux and BSD worlds. */
1969 
1970          info_array[0] = data[0x1c3] + 1;           /* heads */
1971          info_array[1] = data[0x1c4] & 0x3f;        /* sectors */
1972       } else {
1973 
1974          /* Note that this new method guarantees that there will always be
1975             less than 1024 cylinders on a platter.  This is good for drives
1976             up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
1977 
1978          if ((unsigned int)size >= 0x7e0000U) {
1979             info_array[0] = 0xff; /* heads   = 255 */
1980             info_array[1] = 0x3f; /* sectors =  63 */
1981          } else if ((unsigned int)size >= 0x200000U) {
1982             info_array[0] = 0x80; /* heads   = 128 */
1983             info_array[1] = 0x3f; /* sectors =  63 */
1984          } else {
1985             info_array[0] = 0x40; /* heads   =  64 */
1986             info_array[1] = 0x20; /* sectors =  32 */
1987          }
1988       }
1989                                 /* For both methods, compute the cylinders */
1990       info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] );
1991    }
1992    
1993    return 0;
1994 }
1995 
1996 #ifdef MODULE
1997 /* Eventually this will go into an include file, but this will be later */
1998 Scsi_Host_Template driver_template = FDOMAIN_16X0;
1999 
2000 #include "scsi_module.c"
2001 #endif

/* [previous][next][first][last][top][bottom][index][help] */