root/drivers/scsi/fdomain.c

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

DEFINITIONS

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

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