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_16x0_detect
  6. fdomain_16x0_info
  7. fdomain_arbitrate
  8. fdomain_select
  9. my_done
  10. fdomain_16x0_intr
  11. fdomain_16x0_queue
  12. internal_done
  13. fdomain_16x0_command
  14. print_info
  15. fdomain_16x0_abort
  16. fdomain_16x0_reset
  17. 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 Jan 23 08:59:04 1994 by faith@cs.unc.edu
   4  * Author: Rickard E. Faith, faith@cs.unc.edu
   5  * Copyright 1992, 1993, 1994 Rickard E. Faith
   6  *
   7  * $Id: fdomain.c,v 5.9 1994/01/23 13:59:14 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  **************************************************************************
  20  
  21  DESCRIPTION:
  22 
  23  This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
  24  and TMC-1650/1670 SCSI host adapters.  The 1650 and 1670 have a 25-pin
  25  external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
  26  high-density external connector.  The 1670 and 1680 have floppy disk
  27  controllers built in.
  28 
  29  Future Domain's older boards are based on the TMC-1800 chip, and the
  30  driver was originally written for a TMC-1680 board with the TMC-1800
  31  chip.  More recently, boards are being produced with the TMC-18C50 chip.
  32  The latest and greatest board may not work with this driver.  If you have
  33  to patch this driver so that it will recognize your board's BIOS
  34  signature, then the driver may fail to function after the board is
  35  detected.
  36 
  37  If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
  38  your board.  Please refer to the Seagate driver for more information and
  39  possible support.
  40 
  41  
  42 
  43  REFERENCES USED:
  44 
  45  "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
  46  1990.
  47 
  48  "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain
  49  Corporation, January 1992.
  50 
  51  "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
  52  B/September 1991)", Maxtor Corporation, 1991.
  53 
  54  "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
  55 
  56  "Draft Proposed American National Standard: Small Computer System
  57  Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109,
  58  revision 10h, October 17, 1991)
  59 
  60  Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric
  61  Youngdale (eric@tantalus.nrl.navy.mil), 1992.
  62 
  63 
  64  
  65  NOTES ON REFERENCES:
  66 
  67  The Maxtor manuals were free.  Maxtor telephone technical support is
  68  great!
  69 
  70  The Future Domain manuals were $25 and $35.  They document the chip, not
  71  the TMC-16x0 boards, so some information I had to guess at.  In 1992,
  72  Future Domain sold DOS BIOS source for $250 and the UN*X driver source was
  73  $750, but these required a non-disclosure agreement, so even if I could
  74  have afforded them, they would *not* have been useful for writing this
  75  publically distributable driver.  Future Domain technical support has
  76  provided some information on the phone and have sent a few useful FAXs.
  77  They have been much more helpful since they started to recognize that the
  78  word "Linux" refers to an operating system :-).
  79 
  80  
  81 
  82  ALPHA TESTERS:
  83 
  84  There are many other alpha testers that come and go as the driver
  85  develops.  The people listed here were most helpful in times of greatest
  86  need (mostly early on -- I've probably left out a few worthy people in
  87  more recent times):
  88 
  89  Todd Carrico (todd@wutc.wustl.edu), Dan Poirier (poirier@cs.unc.edu ), Ken
  90  Corey (kenc@sol.acs.unt.edu), C. de Bruin (bruin@bruin@sterbbs.nl), Sakari
  91  Aaltonen (sakaria@vipunen.hit.fi), John Rice (rice@xanth.cs.odu.edu), Brad
  92  Yearwood (brad@optilink.com), and Ray Toy (toy@soho.crd.ge.com).
  93 
  94  Special thanks to Tien-Wan Yang (twyang@cs.uh.edu), who graciously lent me
  95  his 18C50-based card for debugging.  He is the sole reason that this
  96  driver works with the 18C50 chip.
  97 
  98  All of the alpha testers deserve much thanks.
  99  
 100 
 101  
 102  NOTES ON USER DEFINABLE OPTIONS:
 103 
 104  DEBUG: This turns on the printing of various debug informaiton.
 105 
 106  ENABLE_PARITY: This turns on SCSI parity checking.  With the current
 107  driver, all attached devices must support SCSI parity.  If none of your
 108  devices support parity, then you can probably get the driver to work by
 109  turning this option off.  I have no way of testing this, however.
 110 
 111  FIFO_COUNT: The host adapter has an 8K cache.  When this many 512 byte
 112  blocks are filled by the SCSI device, an interrupt will be raised.
 113  Therefore, this could be as low as 0, or as high as 16.  Note, however,
 114  that values which are too high or too low seem to prevent any interrupts
 115  from occuring, and thereby lock up the machine.  I have found that 2 is a
 116  good number, but throughput may be increased by changing this value to
 117  values which are close to 2.  Please let me know if you try any different
 118  values.
 119 
 120  DO_DETECT: This activates some old scan code which was needed before the
 121  high level drivers got fixed.  If you are having toruble with the driver,
 122  turning this on should not hurt, and might help.  Please let me know if
 123  this is the case, since this code will be removed from future drivers.
 124 
 125  RESELECTION: This is no longer an option, since I gave up trying to
 126  implement it in version 4.x of this driver.  It did not improve
 127  performance at all and made the driver unstable (because I never found one
 128  of the two race conditions which were introduced by multiple outstanding
 129  commands).  The instability seems a very high price to pay just so that
 130  you don't have to wait for the tape to rewind.  When I have time, I will
 131  work on this again.  In the interim, if anyone want to work on the code, I
 132  can give them my latest version.
 133 
 134  **************************************************************************/
 135 
 136 #include <linux/sched.h>
 137 #include <asm/io.h>
 138 #include "../block/blk.h"
 139 #include "scsi.h"
 140 #include "hosts.h"
 141 #include "fdomain.h"
 142 #include <asm/system.h>
 143 #include <linux/errno.h>
 144 #include <linux/string.h>
 145 #include <linux/ioport.h>
 146 
 147 #define VERSION          "$Revision: 5.9 $"
 148 
 149 /* START OF USER DEFINABLE OPTIONS */
 150 
 151 #define DEBUG            1      /* Enable debugging output */
 152 #define ENABLE_PARITY    1      /* Enable SCSI Parity */
 153 #define FIFO_COUNT       2      /* Number of 512 byte blocks before INTR */
 154 #define DO_DETECT        0      /* Do device detection here (see scsi.c) */
 155 
 156 /* END OF USER DEFINABLE OPTIONS */
 157 
 158 #if DEBUG
 159 #define EVERY_ACCESS     0      /* Write a line on every scsi access */
 160 #define ERRORS_ONLY      1      /* Only write a line if there is an error */
 161 #define DEBUG_DETECT     0      /* Debug fdomain_16x0_detect() */
 162 #define DEBUG_MESSAGES   1      /* Debug MESSAGE IN phase */
 163 #define DEBUG_ABORT      1      /* Debug abort() routine */
 164 #define DEBUG_RESET      1      /* Debug reset() routine */
 165 #define DEBUG_RACE       1      /* Debug interrupt-driven race condition */
 166 #else
 167 #define EVERY_ACCESS     0      /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
 168 #define ERRORS_ONLY      0
 169 #define DEBUG_DETECT     0
 170 #define DEBUG_MESSAGES   0
 171 #define DEBUG_ABORT      0
 172 #define DEBUG_RESET      0
 173 #define DEBUG_RACE       0
 174 #endif
 175 
 176 /* Errors are reported on the line, so we don't need to report them again */
 177 #if EVERY_ACCESS
 178 #undef ERRORS_ONLY
 179 #define ERRORS_ONLY      0
 180 #endif
 181 
 182 #if ENABLE_PARITY
 183 #define PARITY_MASK      0x08
 184 #else
 185 #define PARITY_MASK      0x00
 186 #endif
 187 
 188 enum chip_type {
 189    unknown          = 0x00,
 190    tmc1800          = 0x01,
 191    tmc18c50         = 0x02,
 192 };
 193 
 194 enum {
 195    in_arbitration   = 0x02,
 196    in_selection     = 0x04,
 197    in_other         = 0x08,
 198    disconnect       = 0x10,
 199    aborted          = 0x20,
 200    sent_ident       = 0x40,
 201 };
 202 
 203 enum in_port_type {
 204    Read_SCSI_Data   =  0,
 205    SCSI_Status      =  1,
 206    TMC_Status       =  2,
 207    FIFO_Status      =  3,       /* tmc18c50 only */
 208    Interrupt_Cond   =  4,       /* tmc18c50 only */
 209    LSB_ID_Code      =  5,
 210    MSB_ID_Code      =  6,
 211    Read_Loopback    =  7,
 212    SCSI_Data_NoACK  =  8,
 213    Interrupt_Status =  9,
 214    Configuration1   = 10,
 215    Configuration2   = 11,       /* tmc18c50 only */
 216    Read_FIFO        = 12,
 217    FIFO_Data_Count  = 14
 218 };
 219 
 220 enum out_port_type {
 221    Write_SCSI_Data  =  0,
 222    SCSI_Cntl        =  1,
 223    Interrupt_Cntl   =  2,
 224    SCSI_Mode_Cntl   =  3,
 225    TMC_Cntl         =  4,
 226    Memory_Cntl      =  5,       /* tmc18c50 only */
 227    Write_Loopback   =  7,
 228    Write_FIFO       = 12
 229 };
 230 
 231 static int               port_base         = 0;
 232 static void              *bios_base        = NULL;
 233 static int               bios_major        = 0;
 234 static int               bios_minor        = 0;
 235 static int               interrupt_level   = 0;
 236 static int               this_host         = 0;
 237 static volatile int      in_command        = 0;
 238 static Scsi_Cmnd         *current_SC       = NULL;
 239 static enum chip_type    chip              = unknown;
 240 static int               adapter_mask      = 0x40;
 241 #if DEBUG_RACE
 242 static volatile int      in_interrupt_flag = 0;
 243 #endif
 244 
 245 static int               SCSI_Mode_Cntl_port;
 246 static int               FIFO_Data_Count_port;
 247 static int               Interrupt_Cntl_port;
 248 static int               Interrupt_Status_port;
 249 static int               Read_FIFO_port;
 250 static int               Read_SCSI_Data_port;
 251 static int               SCSI_Cntl_port;
 252 static int               SCSI_Data_NoACK_port;
 253 static int               SCSI_Status_port;
 254 static int               TMC_Cntl_port;
 255 static int               TMC_Status_port;
 256 static int               Write_FIFO_port;
 257 static int               Write_SCSI_Data_port;
 258 
 259 extern void              fdomain_16x0_intr( int unused );
 260 
 261 static void *addresses[] = {
 262    (void *)0xc8000,
 263    (void *)0xca000,
 264    (void *)0xce000,
 265    (void *)0xde000 };
 266 #define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
 267                        
 268 static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
 269 #define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
 270 
 271 static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
 272 
 273 /*
 274 
 275   READ THIS BEFORE YOU ADD A SIGNATURE!
 276 
 277   READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME!
 278 
 279   READ EVERY WORD, ESPECIALLY THE WORD *NOT*
 280 
 281   This driver works *ONLY* for Future Domain cards using the TMC-1800 or
 282   the TMC-18C50 chip.  This includes models TMC-1650, 1660, 1670, and 1680.
 283 
 284   The following BIOS signature signatures are for boards which do *NOT*
 285   work with this driver (these TMC-8xx and TMC-9xx boards may work with the
 286   Seagate driver):
 287 
 288   FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88
 289   FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89
 290   FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89
 291   FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90
 292   FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
 293   FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
 294   FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92
 295 
 296 */
 297 
 298 struct signature {
 299    char *signature;
 300    int  sig_offset;
 301    int  sig_length;
 302    int  major_bios_version;
 303    int  minor_bios_version;
 304 } signatures[] = {
 305    /*          1         2         3         4         5         6 */
 306    /* 123456789012345678901234567890123456789012345678901234567890 */
 307    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50,  2,  0 },
 308    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89", 5, 50,  2,  0 },
 309    { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92",       5, 44,  3,  0 },
 310    { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93",       5, 44,  3,  2 },
 311    { "FUTURE DOMAIN TMC-18XX",                             5, 22, -1, -1 },
 312 
 313    /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGANTURE
 314     Also, fix the disk geometry code for your signature and send your
 315     changes for faith@cs.unc.edu.  Above all, do *NOT* change any old
 316     signatures!
 317 
 318     Note that the last line will match a "generic" 18XX bios.  Because
 319     Future Domain has changed the host SCSI ID and/or the location of the
 320     geometry information in the on-board RAM area for each of the first
 321     three BIOS's, it is still important to enter a fully qualified
 322     signature in the table for any new BIOS's (after the host SCSI ID and
 323     geometry location are verified.) */
 324 };
 325 
 326 #define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
 327 
 328 static void print_banner( void )
 329 {
 330    printk( "%s", fdomain_16x0_info() );
 331    printk( "Future Domain: BIOS version %d.%d, %s\n",
 332            bios_major, bios_minor,
 333            chip == tmc1800 ? "TMC-1800"
 334            : (chip == tmc18c50 ? "TMC-18C50" : "Unknown") );
 335    
 336    if (interrupt_level) {
 337       printk( "Future Domain: BIOS at %x; port base at %x; using IRQ %d\n",
 338               (unsigned)bios_base, port_base, interrupt_level );
 339    } else {
 340       printk( "Future Domain: BIOS at %x; port base at %x; *NO* IRQ\n",
 341               (unsigned)bios_base, port_base );
 342    }
 343 }
 344 
 345 static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */
     /* [previous][next][first][last][top][bottom][index][help] */
 346 {
 347    unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */
 348 
 349    while (jiffies < the_time);
 350 }
 351 
 352 inline static void fdomain_make_bus_idle( void )
     /* [previous][next][first][last][top][bottom][index][help] */
 353 {
 354    outb( 0, SCSI_Cntl_port );
 355    outb( 0, SCSI_Mode_Cntl_port );
 356    if (chip == tmc18c50)
 357          outb( 0x21 | PARITY_MASK, TMC_Cntl_port ); /* Clear forced intr. */
 358    else
 359          outb( 0x01 | PARITY_MASK, TMC_Cntl_port );
 360 }
 361 
 362 static int fdomain_is_valid_port( int port )
     /* [previous][next][first][last][top][bottom][index][help] */
 363 {
 364    int options;
 365 
 366 #if DEBUG_DETECT 
 367    printk( " (%x%x),",
 368            inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
 369 #endif
 370 
 371    /* The MCA ID is a unique id for each MCA compatible board.  We
 372       are using ISA boards, but Future Domain provides the MCA ID
 373       anyway.  We can use this ID to ensure that this is a Future
 374       Domain TMC-1660/TMC-1680.
 375     */
 376 
 377    if (inb( port + LSB_ID_Code ) != 0xe9) { /* test for 0x6127 id */
 378       if (inb( port + LSB_ID_Code ) != 0x27) return 0;
 379       if (inb( port + MSB_ID_Code ) != 0x61) return 0;
 380       chip = tmc1800;
 381    } else {                                 /* test for 0xe960 id */
 382       if (inb( port + MSB_ID_Code ) != 0x60) return 0;
 383       chip = tmc18c50;
 384    }
 385 
 386    /* We have a valid MCA ID for a TMC-1660/TMC-1680 Future Domain board.
 387       Now, check to be sure the bios_base matches these ports.  If someone
 388       was unlucky enough to have purchased more than one Future Domain
 389       board, then they will have to modify this code, as we only detect one
 390       board here.  [The one with the lowest bios_base.]  */
 391 
 392    options = inb( port + Configuration1 );
 393 
 394 #if DEBUG_DETECT
 395    printk( " Options = %x\n", options );
 396 #endif
 397 
 398                                 /* Check for board with lowest bios_base. */
 399    if (addresses[ (options & 0xc0) >> 6 ] != bios_base)
 400          return 0;
 401    interrupt_level = ints[ (options & 0x0e) >> 1 ];
 402 
 403    return 1;
 404 }
 405 
 406 static int fdomain_test_loopback( void )
     /* [previous][next][first][last][top][bottom][index][help] */
 407 {
 408    int i;
 409    int result;
 410 
 411    for (i = 0; i < 255; i++) {
 412       outb( i, port_base + Write_Loopback );
 413       result = inb( port_base + Read_Loopback );
 414       if (i != result)
 415             return 1;
 416    }
 417    return 0;
 418 }
 419 
 420 int fdomain_16x0_detect( int hostnum )
     /* [previous][next][first][last][top][bottom][index][help] */
 421 {
 422    int              i, j;
 423    int              flag = 0;
 424    struct sigaction sa;
 425    int              retcode;
 426 #if DO_DETECT
 427    const int        buflen = 255;
 428    Scsi_Cmnd        SCinit;
 429    unsigned char    do_inquiry[] =       { INQUIRY, 0, 0, 0, buflen, 0 };
 430    unsigned char    do_request_sense[] = { REQUEST_SENSE, 0, 0, 0, buflen, 0 };
 431    unsigned char    do_read_capacity[] = { READ_CAPACITY,
 432                                            0, 0, 0, 0, 0, 0, 0, 0, 0 };
 433    unsigned char    buf[buflen];
 434 #endif
 435 
 436 #if DEBUG_DETECT
 437    printk( "fdomain_16x0_detect()," );
 438 #endif
 439 
 440    for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) {
 441 #if DEBUG_DETECT
 442       printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base );
 443 #endif
 444       for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) {
 445          if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset),
 446                       signatures[j].signature, signatures[j].sig_length )) {
 447             bios_major = signatures[j].major_bios_version;
 448             bios_minor = signatures[j].minor_bios_version;
 449             bios_base = addresses[i];
 450          }
 451       }
 452    }
 453 
 454    if (!bios_base) {
 455 #if DEBUG_DETECT
 456       printk( " FAILED: NO BIOS\n" );
 457 #endif
 458       return 0;
 459    }
 460 
 461    if (bios_major == 2) {
 462       /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
 463          Assuming the ROM is enabled (otherwise we wouldn't have been
 464          able to read the ROM signature :-), then the ROM sets up the
 465          RAM area with some magic numbers, such as a list of port
 466          base addresses and a list of the disk "geometry" reported to
 467          DOS (this geometry has nothing to do with physical geometry).
 468        */
 469 
 470       port_base = *((char *)bios_base + 0x1fcc)
 471             + (*((char *)bios_base + 0x1fcd) << 8);
 472    
 473 #if DEBUG_DETECT
 474       printk( " %x,", port_base );
 475 #endif
 476 
 477       for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) {
 478          if (port_base == ports[i])
 479                ++flag;
 480       }
 481 
 482       if (flag)
 483             flag = fdomain_is_valid_port( port_base );
 484    }
 485 
 486    if (!flag) {                 /* Cannot get port base from BIOS RAM */
 487       
 488       /* This is a bad sign.  It usually means that someone patched the
 489          BIOS signature list (the signatures variable) to contain a BIOS
 490          signature for a board *OTHER THAN* the TMC-1660/TMC-1680.  It
 491          also means that we don't have a Version 2.0 BIOS :-)
 492        */
 493       
 494 #if DEBUG_DETECT
 495       if (bios_major != 2) printk( " RAM FAILED, " );
 496 #endif
 497 
 498       /* Anyway, the alternative to finding the address in the RAM is
 499          to just search through every possible port address for one
 500          that is attached to the Future Domain card.  Don't panic,
 501          though, about reading all these random port addresses--there
 502          are rumors that the Future Domain BIOS does something very
 503          similar.
 504 
 505          Do not, however, check ports which the kernel knows are being used
 506          by another driver.
 507        */
 508 
 509       for (i = 0; !flag && i < PORT_COUNT; i++) {
 510          port_base = ports[i];
 511          if (check_region( port_base, 0x10 )) {
 512 #if DEBUG_DETECT
 513             printf( " (%x inuse),", port_base );
 514 #endif
 515             continue;
 516          }
 517 #if DEBUG_DETECT
 518          printk( " %x,", port_base );
 519 #endif
 520          flag = fdomain_is_valid_port( port_base );
 521       }
 522    }
 523 
 524    if (!flag) {
 525 #if DEBUG_DETECT
 526       printk( " FAILED: NO PORT\n" );
 527 #endif
 528       return 0;         /* Cannot find valid set of ports */
 529    }
 530 
 531    print_banner();
 532 
 533    SCSI_Mode_Cntl_port   = port_base + SCSI_Mode_Cntl;
 534    FIFO_Data_Count_port  = port_base + FIFO_Data_Count;
 535    Interrupt_Cntl_port   = port_base + Interrupt_Cntl;
 536    Interrupt_Status_port = port_base + Interrupt_Status;
 537    Read_FIFO_port        = port_base + Read_FIFO;
 538    Read_SCSI_Data_port   = port_base + Read_SCSI_Data;
 539    SCSI_Cntl_port        = port_base + SCSI_Cntl;
 540    SCSI_Data_NoACK_port  = port_base + SCSI_Data_NoACK;
 541    SCSI_Status_port      = port_base + SCSI_Status;
 542    TMC_Cntl_port         = port_base + TMC_Cntl;
 543    TMC_Status_port       = port_base + TMC_Status;
 544    Write_FIFO_port       = port_base + Write_FIFO;
 545    Write_SCSI_Data_port  = port_base + Write_SCSI_Data;
 546 
 547    fdomain_16x0_reset( NULL );
 548 
 549    if (fdomain_test_loopback()) {
 550 #if DEBUG_DETECT
 551       printk( "Future Domain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
 552 #endif
 553       return 0;
 554    }
 555 
 556    this_host = hostnum;
 557 
 558                                 /* Log IRQ with kernel */
 559    
 560    if (!interrupt_level) {
 561       panic( "Future Domain: *NO* interrupt level selected!\n" );
 562    } else {
 563       /* Register the IRQ with the kernel */
 564 
 565       sa.sa_handler  = fdomain_16x0_intr;
 566       sa.sa_flags    = SA_INTERRUPT;
 567       sa.sa_mask     = 0;
 568       sa.sa_restorer = NULL;
 569       
 570       retcode = irqaction( interrupt_level, &sa );
 571 
 572       if (retcode < 0) {
 573          if (retcode == -EINVAL) {
 574             printk( "Future Domain: IRQ %d is bad!\n", interrupt_level );
 575             printk( "               This shouldn't happen!\n" );
 576             printk( "               Send mail to faith@cs.unc.edu\n" );
 577          } else if (retcode == -EBUSY) {
 578             printk( "Future Domain: IRQ %d is already in use!\n",
 579                     interrupt_level );
 580             printk( "               Please use another IRQ!\n" );
 581          } else {
 582             printk( "Future Domain: Error getting IRQ %d\n", interrupt_level );
 583             printk( "               This shouldn't happen!\n" );
 584             printk( "               Send mail to faith@cs.unc.edu\n" );
 585          }
 586          panic( "Future Domain: Driver requires interruptions\n" );
 587       } else {
 588          printk( "Future Domain: IRQ %d requested from kernel\n",
 589                  interrupt_level );
 590       }
 591    }
 592 
 593                                 /* Log I/O ports with kernel */
 594 
 595    snarf_region( port_base, 0x10 );
 596 
 597    if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
 598       adapter_mask = 0x80;
 599       scsi_hosts[this_host].this_id = 7;
 600    }
 601    
 602 #if DO_DETECT
 603 
 604    /* These routines are here because of the way the SCSI bus behaves after
 605       a reset.  This appropriate behavior was not handled correctly by the
 606       higher level SCSI routines when I first wrote this driver.  Now,
 607       however, correct scan routines are part of scsi.c and these routines
 608       are no longer needed.  However, this code is still good for
 609       debugging.  */
 610 
 611    SCinit.request_buffer  = SCinit.buffer = buf;
 612    SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
 613    SCinit.use_sg          = 0;
 614    SCinit.lun             = 0;
 615 
 616    printk( "Future Domain detection routine scanning for devices:\n" );
 617    for (i = 0; i < 8; i++) {
 618       SCinit.target = i;
 619       if (i == scsi_hosts[this_host].this_id) /* Skip host adapter */
 620             continue;
 621       memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
 622       retcode = fdomain_16x0_command(&SCinit);
 623       if (!retcode) {
 624          memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
 625          retcode = fdomain_16x0_command(&SCinit);
 626          if (!retcode) {
 627             printk( "     SCSI ID %d: ", i );
 628             for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
 629                   printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
 630             memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
 631             retcode = fdomain_16x0_command(&SCinit);
 632             if (!retcode) {
 633                unsigned long blocks, size, capacity;
 634                
 635                blocks = (buf[0] << 24) | (buf[1] << 16)
 636                      | (buf[2] << 8) | buf[3];
 637                size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
 638                capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
 639                
 640                printk( "%lu MB (%lu byte blocks)",
 641                        ((capacity + 5L) / 10L), size );
 642             } else {
 643                memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
 644                retcode = fdomain_16x0_command(&SCinit);
 645             }
 646             printk ("\n" );
 647          } else {
 648             memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
 649             retcode = fdomain_16x0_command(&SCinit);
 650          }
 651       }
 652    }
 653 #endif
 654 
 655    return 1;
 656 }
 657 
 658 const char *fdomain_16x0_info(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 659 {
 660    static char buffer[80];
 661    char        *pt;
 662    
 663    strcpy( buffer, "Future Domain: TMC-16x0 SCSI driver, version" );
 664    if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */
 665       strcat( buffer, strchr( VERSION, ':' ) + 1 );
 666       pt = strrchr( buffer, '$') - 1;
 667       if (!pt)                  /* Stripped RCS Revision string? */
 668             pt = buffer + strlen( buffer ) - 1;
 669       if (*pt != ' ')
 670             ++pt;
 671       *pt++ = '\n';
 672       *pt = '\0';
 673    } else {                     /* Assume VERSION is a number */
 674       strcat( buffer, " " VERSION "\n" );
 675    }
 676       
 677    return buffer;
 678 }
 679 
 680 #if 0
 681 static int fdomain_arbitrate( void )
     /* [previous][next][first][last][top][bottom][index][help] */
 682 {
 683    int           status = 0;
 684    unsigned long timeout;
 685 
 686 #if EVERY_ACCESS
 687    printk( "fdomain_arbitrate()\n" );
 688 #endif
 689    
 690    outb( 0x00, SCSI_Cntl_port );              /* Disable data drivers */
 691    outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */
 692    outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
 693 
 694    timeout = jiffies + 50;                    /* 500 mS */
 695    while (jiffies < timeout) {
 696       status = inb( TMC_Status_port );        /* Read adapter status */
 697       if (status & 0x02)                      /* Arbitration complete */
 698             return 0;   
 699    }
 700 
 701    /* Make bus idle */
 702    fdomain_make_bus_idle();
 703 
 704 #if EVERY_ACCESS
 705    printk( "Arbitration failed, status = %x\n", status );
 706 #endif
 707 #if ERRORS_ONLY
 708    printk( "Future Domain: Arbitration failed, status = %x", status );
 709 #endif
 710    return 1;
 711 }
 712 #endif
 713 
 714 static int fdomain_select( int target )
     /* [previous][next][first][last][top][bottom][index][help] */
 715 {
 716    int           status;
 717    unsigned long timeout;
 718 
 719 
 720    outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
 721    outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );
 722 
 723    /* Stop arbitration and enable parity */
 724    outb( PARITY_MASK, TMC_Cntl_port ); 
 725 
 726    timeout = jiffies + 25;              /* 250mS */
 727    while (jiffies < timeout) {
 728       status = inb( SCSI_Status_port ); /* Read adapter status */
 729       if (status & 1) {                 /* Busy asserted */
 730          /* Enable SCSI Bus (on error, should make bus idle with 0) */
 731          outb( 0x80, SCSI_Cntl_port );
 732          return 0;
 733       }
 734    }
 735    /* Make bus idle */
 736    fdomain_make_bus_idle();
 737 #if EVERY_ACCESS
 738    if (!target) printk( "Selection failed\n" );
 739 #endif
 740 #if ERRORS_ONLY
 741    if (!target) printk( "Future Domain: Selection failed" );
 742 #endif
 743    return 1;
 744 }
 745 
 746 void my_done( int error )
     /* [previous][next][first][last][top][bottom][index][help] */
 747 {
 748    if (in_command) {
 749       in_command = 0;
 750       outb( 0x00, Interrupt_Cntl_port );
 751       fdomain_make_bus_idle();
 752       current_SC->result = error;
 753       if (current_SC->scsi_done)
 754             current_SC->scsi_done( current_SC );
 755       else panic( "Future Domain: current_SC->scsi_done() == NULL" );
 756    } else {
 757       panic( "Future Domain: my_done() called outside of command\n" );
 758    }
 759 #if DEBUG_RACE
 760    in_interrupt_flag = 0;
 761 #endif
 762 }
 763 
 764 void fdomain_16x0_intr( int unused )
     /* [previous][next][first][last][top][bottom][index][help] */
 765 {
 766    int      status;
 767    int      done = 0;
 768    unsigned data_count;
 769 
 770    sti();
 771    
 772    outb( 0x00, Interrupt_Cntl_port );
 773 
 774    /* We usually have one spurious interrupt after each command.  Ignore it. */
 775    if (!in_command || !current_SC) {    /* Spurious interrupt */
 776 #if EVERY_ACCESS
 777       printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
 778               in_command, current_SC );
 779 #endif
 780       return;
 781    }
 782 
 783    /* Abort calls my_done, so we do nothing here. */
 784    if (current_SC->SCp.phase & aborted) {
 785 #if DEBUG_ABORT
 786       printk( "Interrupt after abort, ignoring\n" );
 787 #endif
 788       /*
 789       return; */
 790    }
 791 
 792 #if DEBUG_RACE
 793    ++in_interrupt_flag;
 794 #endif
 795 
 796    if (current_SC->SCp.phase & in_arbitration) {
 797       status = inb( TMC_Status_port );        /* Read adapter status */
 798       if (!(status & 0x02)) {
 799 #if EVERY_ACCESS
 800          printk( " AFAIL " );
 801 #endif
 802          my_done( DID_BUS_BUSY << 16 );
 803          return;
 804       }
 805       current_SC->SCp.phase = in_selection;
 806       
 807       outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
 808 
 809       outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
 810       outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
 811       
 812       /* Stop arbitration and enable parity */
 813       outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
 814 #if DEBUG_RACE
 815       in_interrupt_flag = 0;
 816 #endif
 817       return;
 818    } else if (current_SC->SCp.phase & in_selection) {
 819       status = inb( SCSI_Status_port );
 820       if (!(status & 0x01)) {
 821          /* Try again, for slow devices */
 822          if (fdomain_select( current_SC->target )) {
 823 #if EVERY_ACCESS
 824             printk( " SFAIL " );
 825 #endif
 826             my_done( DID_NO_CONNECT << 16 );
 827             return;
 828          } else {
 829 #if EVERY_ACCESS
 830             printk( " AltSel " );
 831 #endif
 832             /* Stop arbitration and enable parity */
 833             outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
 834          }
 835       }
 836       current_SC->SCp.phase = in_other;
 837       outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
 838       outb( 0x80, SCSI_Cntl_port );
 839 #if DEBUG_RACE
 840       in_interrupt_flag = 0;
 841 #endif
 842       return;
 843    }
 844    
 845    /* current_SC->SCp.phase == in_other: this is the body of the routine */
 846    
 847    status = inb( SCSI_Status_port );
 848    
 849    if (status & 0x10) { /* REQ */
 850       
 851       switch (status & 0x0e) {
 852        
 853       case 0x08:                /* COMMAND OUT */
 854          outb( current_SC->cmnd[current_SC->SCp.sent_command++],
 855                Write_SCSI_Data_port );
 856 #if EVERY_ACCESS
 857          printk( "CMD = %x,",
 858                  current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
 859 #endif
 860          break;
 861       case 0x00:                /* DATA OUT -- tmc18c50 only */
 862          if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
 863             current_SC->SCp.have_data_in = -1;
 864             outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
 865          }
 866          break;
 867       case 0x04:                /* DATA IN -- tmc18c50 only */
 868          if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
 869             current_SC->SCp.have_data_in = 1;
 870             outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
 871          }
 872          break;
 873       case 0x0c:                /* STATUS IN */
 874          current_SC->SCp.Status = inb( Read_SCSI_Data_port );
 875 #if EVERY_ACCESS
 876          printk( "Status = %x, ", current_SC->SCp.Status );
 877 #endif
 878 #if ERRORS_ONLY
 879          if (current_SC->SCp.Status && current_SC->SCp.Status != 2) {
 880             printk( "Future Domain: target = %d, command = %x, "
 881                     "Status = %x\n",
 882                     current_SC->target, current_SC->cmnd[0],
 883                     current_SC->SCp.Status );
 884          }
 885 #endif
 886                break;
 887       case 0x0a:                /* MESSAGE OUT */
 888          outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */
 889          break;
 890       case 0x0e:                /* MESSAGE IN */
 891          current_SC->SCp.Message = inb( Read_SCSI_Data_port );
 892 #if EVERY_ACCESS
 893          printk( "Message = %x, ", current_SC->SCp.Message );
 894 #endif
 895          if (!current_SC->SCp.Message) ++done;
 896 #if DEBUG_MESSAGES || EVERY_ACCESS
 897          if (current_SC->SCp.Message) {
 898             printk( "Future Domain: Message = %x\n",
 899                     current_SC->SCp.Message );
 900          }
 901 #endif
 902          break;
 903       }
 904    }
 905 
 906    if (chip == tmc1800
 907        && !current_SC->SCp.have_data_in
 908        && (current_SC->SCp.sent_command
 909            >= COMMAND_SIZE( current_SC->cmnd[ 0 ] ))) {
 910                                 /* We have to get the FIFO direction
 911                                    correct, so I've made a table based
 912                                    on the SCSI Standard of which commands
 913                                    appear to require a DATA OUT phase.
 914                                  */
 915       /*
 916         p. 94: Command for all device types
 917         CHANGE DEFINITION            40 DATA OUT
 918         COMPARE                      39 DATA OUT
 919         COPY                         18 DATA OUT
 920         COPY AND VERIFY              3a DATA OUT
 921         INQUIRY                      12 
 922         LOG SELECT                   4c DATA OUT
 923         LOG SENSE                    4d
 924         MODE SELECT (6)              15 DATA OUT
 925         MODE SELECT (10)             55 DATA OUT
 926         MODE SENSE (6)               1a
 927         MODE SENSE (10)              5a
 928         READ BUFFER                  3c
 929         RECEIVE DIAGNOSTIC RESULTS   1c
 930         REQUEST SENSE                03
 931         SEND DIAGNOSTIC              1d DATA OUT
 932         TEST UNIT READY              00
 933         WRITE BUFFER                 3b DATA OUT
 934 
 935         p.178: Commands for direct-access devices (not listed on p. 94)
 936         FORMAT UNIT                  04 DATA OUT
 937         LOCK-UNLOCK CACHE            36
 938         PRE-FETCH                    34
 939         PREVENT-ALLOW MEDIUM REMOVAL 1e
 940         READ (6)/RECEIVE             08
 941         READ (10)                    3c
 942         READ CAPACITY                25
 943         READ DEFECT DATA (10)        37
 944         READ LONG                    3e
 945         REASSIGN BLOCKS              07 DATA OUT
 946         RELEASE                      17
 947         RESERVE                      16 DATA OUT
 948         REZERO UNIT/REWIND           01
 949         SEARCH DATA EQUAL (10)       31 DATA OUT
 950         SEARCH DATA HIGH (10)        30 DATA OUT
 951         SEARCH DATA LOW (10)         32 DATA OUT
 952         SEEK (6)                     0b
 953         SEEK (10)                    2b
 954         SET LIMITS (10)              33
 955         START STOP UNIT              1b
 956         SYNCHRONIZE CACHE            35
 957         VERIFY (10)                  2f
 958         WRITE (6)/PRINT/SEND         0a DATA OUT
 959         WRITE (10)/SEND              2a DATA OUT
 960         WRITE AND VERIFY (10)        2e DATA OUT
 961         WRITE LONG                   3f DATA OUT
 962         WRITE SAME                   41 DATA OUT ?
 963 
 964         p. 261: Commands for sequential-access devices (not previously listed)
 965         ERASE                        19
 966         LOAD UNLOAD                  1b
 967         LOCATE                       2b
 968         READ BLOCK LIMITS            05
 969         READ POSITION                34
 970         READ REVERSE                 0f
 971         RECOVER BUFFERED DATA        14
 972         SPACE                        11
 973         WRITE FILEMARKS              10 ?
 974 
 975         p. 298: Commands for printer devices (not previously listed)
 976         ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
 977         SLEW AND PRINT               0b DATA OUT  -- same as seek
 978         STOP PRINT                   1b
 979         SYNCHRONIZE BUFFER           10
 980 
 981         p. 315: Commands for processor devices (not previously listed)
 982         
 983         p. 321: Commands for write-once devices (not previously listed)
 984         MEDIUM SCAN                  38
 985         READ (12)                    a8
 986         SEARCH DATA EQUAL (12)       b1 DATA OUT
 987         SEARCH DATA HIGH (12)        b0 DATA OUT
 988         SEARCH DATA LOW (12)         b2 DATA OUT
 989         SET LIMITS (12)              b3
 990         VERIFY (12)                  af
 991         WRITE (12)                   aa DATA OUT
 992         WRITE AND VERIFY (12)        ae DATA OUT
 993 
 994         p. 332: Commands for CD-ROM devices (not previously listed)
 995         PAUSE/RESUME                 4b
 996         PLAY AUDIO (10)              45
 997         PLAY AUDIO (12)              a5
 998         PLAY AUDIO MSF               47
 999         PLAY TRACK RELATIVE (10)     49
1000         PLAY TRACK RELATIVE (12)     a9
1001         READ HEADER                  44
1002         READ SUB-CHANNEL             42
1003         READ TOC                     43
1004 
1005         p. 370: Commands for scanner devices (not previously listed)
1006         GET DATA BUFFER STATUS       34
1007         GET WINDOW                   25
1008         OBJECT POSITION              31
1009         SCAN                         1b
1010         SET WINDOW                   24 DATA OUT
1011 
1012         p. 391: Commands for optical memory devices (not listed)
1013         ERASE (10)                   2c
1014         ERASE (12)                   ac
1015         MEDIUM SCAN                  38 DATA OUT
1016         READ DEFECT DATA (12)        b7
1017         READ GENERATION              29
1018         READ UPDATED BLOCK           2d
1019         UPDATE BLOCK                 3d DATA OUT
1020 
1021         p. 419: Commands for medium changer devices (not listed)
1022         EXCHANGE MEDIUM              46
1023         INITIALIZE ELEMENT STATUS    07
1024         MOVE MEDIUM                  a5
1025         POSITION TO ELEMENT          2b
1026         READ ELEMENT STATUS          b8
1027         REQUEST VOL. ELEMENT ADDRESS b5
1028         SEND VOLUME TAG              b6 DATA OUT
1029 
1030         p. 454: Commands for communications devices (not listed previously)
1031         GET MESSAGE (6)              08
1032         GET MESSAGE (10)             28
1033         GET MESSAGE (12)             a8
1034       */
1035         
1036       switch (current_SC->cmnd[0]) {
1037       case CHANGE_DEFINITION: case COMPARE:         case COPY:
1038       case COPY_VERIFY:       case LOG_SELECT:      case MODE_SELECT:
1039       case MODE_SELECT_10:    case SEND_DIAGNOSTIC: case WRITE_BUFFER:
1040 
1041       case FORMAT_UNIT:       case REASSIGN_BLOCKS: case RESERVE:
1042       case SEARCH_EQUAL:      case SEARCH_HIGH:     case SEARCH_LOW:
1043       case WRITE_6:           case WRITE_10:        case WRITE_VERIFY:
1044       case 0x3f:              case 0x41:
1045 
1046       case 0xb1:              case 0xb0:            case 0xb2:
1047       case 0xaa:              case 0xae:
1048 
1049       case 0x24:
1050 
1051       case 0x38:              case 0x3d:
1052 
1053       case 0xb6:
1054          
1055       case 0xea:                /* alternate number for WRITE LONG */
1056          
1057          current_SC->SCp.have_data_in = -1;
1058          outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1059          break;
1060 
1061       case 0x00:
1062       default:
1063          
1064          current_SC->SCp.have_data_in = 1;
1065          outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1066          break;
1067       }
1068    }
1069 
1070    if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
1071       while ( (data_count = 0x2000 - inw( FIFO_Data_Count_port )) > 512 ) {
1072 #if EVERY_ACCESS
1073          printk( "DC=%d, ", data_count ) ;
1074 #endif
1075          if (data_count > current_SC->SCp.this_residual)
1076                data_count = current_SC->SCp.this_residual;
1077          if (data_count > 0) {
1078 #if EVERY_ACCESS
1079             printk( "%d OUT, ", data_count );
1080 #endif
1081             if (data_count == 1) {
1082                outb( *current_SC->SCp.ptr++, Write_FIFO_port );
1083                --current_SC->SCp.this_residual;
1084             } else {
1085                data_count >>= 1;
1086                outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count );
1087                current_SC->SCp.ptr += 2 * data_count;
1088                current_SC->SCp.this_residual -= 2 * data_count;
1089             }
1090          }
1091          if (!current_SC->SCp.this_residual) {
1092             if (current_SC->SCp.buffers_residual) {
1093                --current_SC->SCp.buffers_residual;
1094                ++current_SC->SCp.buffer;
1095                current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1096                current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1097             } else
1098                   break;
1099          }
1100       }
1101    }
1102    
1103    if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
1104       while ((data_count = inw( FIFO_Data_Count_port )) > 0) {
1105 #if EVERY_ACCESS
1106          printk( "DC=%d, ", data_count );
1107 #endif
1108          if (data_count > current_SC->SCp.this_residual)
1109                data_count = current_SC->SCp.this_residual;
1110          if (data_count) {
1111 #if EVERY_ACCESS
1112             printk( "%d IN, ", data_count );
1113 #endif
1114             if (data_count == 1) {
1115                *current_SC->SCp.ptr++ = inb( Read_FIFO_port );
1116                --current_SC->SCp.this_residual;
1117             } else {
1118                data_count >>= 1; /* Number of words */
1119                insw( Read_FIFO_port, current_SC->SCp.ptr, data_count );
1120                current_SC->SCp.ptr += 2 * data_count;
1121                current_SC->SCp.this_residual -= 2 * data_count;
1122             }
1123          }
1124          if (!current_SC->SCp.this_residual
1125              && current_SC->SCp.buffers_residual) {
1126             --current_SC->SCp.buffers_residual;
1127             ++current_SC->SCp.buffer;
1128             current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1129             current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1130          }
1131       }
1132    }
1133    
1134    if (done) {
1135 #if EVERY_ACCESS
1136       printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1137 #endif
1138 
1139 #if ERRORS_ONLY
1140       if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
1141          if ((unsigned char)(*((char *)current_SC->request_buffer+2)) & 0x0f) {
1142             unsigned char key;
1143             unsigned char code;
1144             unsigned char qualifier;
1145 
1146             key = (unsigned char)(*((char *)current_SC->request_buffer + 2))
1147                   & 0x0f;
1148             code = (unsigned char)(*((char *)current_SC->request_buffer + 12));
1149             qualifier = (unsigned char)(*((char *)current_SC->request_buffer
1150                                           + 13));
1151 
1152             if (!(key == UNIT_ATTENTION && (code == 0x29 || !code))
1153                 && !(key == NOT_READY
1154                      && code == 0x04
1155                      && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1156                 && !(key == ILLEGAL_REQUEST && (code == 0x25
1157                                                 || code == 0x24
1158                                                 || !code)))
1159                   
1160                   printk( "Future Domain: REQUEST SENSE "
1161                           "Key = %x, Code = %x, Qualifier = %x\n",
1162                           key, code, qualifier );
1163          }
1164       }
1165 #endif
1166 #if EVERY_ACCESS
1167       printk( "BEFORE MY_DONE. . ." );
1168 #endif
1169       my_done( (current_SC->SCp.Status & 0xff)
1170                | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1171 #if EVERY_ACCESS
1172       printk( "RETURNING.\n" );
1173 #endif
1174       
1175    } else {
1176       if (current_SC->SCp.phase & disconnect) {
1177          outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
1178          outb( 0x00, SCSI_Cntl_port );
1179       } else {
1180          outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1181       }
1182    }
1183 #if DEBUG_RACE
1184    in_interrupt_flag = 0;
1185 #endif
1186    return;
1187 }
1188 
1189 int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     /* [previous][next][first][last][top][bottom][index][help] */
1190 {
1191    if (in_command) {
1192       panic( "Future Domain: fdomain_16x0_queue() NOT REENTRANT!\n" );
1193    }
1194 #if EVERY_ACCESS
1195    printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1196            SCpnt->target,
1197            *(unsigned char *)SCpnt->cmnd,
1198            SCpnt->use_sg,
1199            SCpnt->request_bufflen );
1200 #endif
1201 
1202    fdomain_make_bus_idle();
1203 
1204    current_SC            = SCpnt; /* Save this for the done function */
1205    current_SC->scsi_done = done;
1206 
1207    /* Initialize static data */
1208 
1209    if (current_SC->use_sg) {
1210       current_SC->SCp.buffer =
1211             (struct scatterlist *)current_SC->request_buffer;
1212       current_SC->SCp.ptr              = current_SC->SCp.buffer->address;
1213       current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
1214       current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1215    } else {
1216       current_SC->SCp.ptr              = (char *)current_SC->request_buffer;
1217       current_SC->SCp.this_residual    = current_SC->request_bufflen;
1218       current_SC->SCp.buffer           = NULL;
1219       current_SC->SCp.buffers_residual = 0;
1220    }
1221          
1222    
1223    current_SC->SCp.Status              = 0;
1224    current_SC->SCp.Message             = 0;
1225    current_SC->SCp.have_data_in        = 0;
1226    current_SC->SCp.sent_command        = 0;
1227    current_SC->SCp.phase               = in_arbitration;
1228 
1229    /* Start arbitration */
1230    outb( 0x00, Interrupt_Cntl_port );
1231    outb( 0x00, SCSI_Cntl_port );              /* Disable data drivers */
1232    outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */
1233    ++in_command;
1234    outb( 0x20, Interrupt_Cntl_port );
1235    outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
1236 
1237    return 0;
1238 }
1239 
1240 /* The following code, which simulates the old-style command function, was
1241    taken from Tommy Thorn's aha1542.c file.  This code is Copyright (C)
1242    1992 Tommy Thorn. */
1243 
1244 static volatile int internal_done_flag    = 0;
1245 static volatile int internal_done_errcode = 0;
1246 
1247 static void internal_done( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1248 {
1249     internal_done_errcode = SCpnt->result;
1250     ++internal_done_flag;
1251 }
1252 
1253 int fdomain_16x0_command( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1254 {
1255     fdomain_16x0_queue( SCpnt, internal_done );
1256 
1257     while (!internal_done_flag)
1258           ;
1259     internal_done_flag = 0;
1260     return internal_done_errcode;
1261 }
1262 
1263 /* End of code derived from Tommy Thorn's work. */
1264 
1265 void print_info( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1266 {
1267    unsigned int imr;
1268    unsigned int irr;
1269    unsigned int isr;
1270    
1271    print_banner();
1272    switch (SCpnt->SCp.phase) {
1273    case in_arbitration: printk( "arbitration " ); break;
1274    case in_selection:   printk( "selection " );   break;
1275    case in_other:       printk( "other " );       break;
1276    default:             printk( "unknown " );     break;
1277    }
1278 
1279    printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1280            SCpnt->SCp.phase,
1281            SCpnt->target,
1282            *(unsigned char *)SCpnt->cmnd,
1283            SCpnt->use_sg,
1284            SCpnt->request_bufflen );
1285    printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1286            SCpnt->SCp.sent_command,
1287            SCpnt->SCp.have_data_in,
1288            SCpnt->timeout );
1289 #if DEBUG_RACE
1290    printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1291 #endif
1292 
1293    imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1294    outb( 0x0a, 0xa0 );
1295    irr = inb( 0xa0 ) << 8;
1296    outb( 0x0a, 0x20 );
1297    irr += inb( 0x20 );
1298    outb( 0x0b, 0xa0 );
1299    isr = inb( 0xa0 ) << 8;
1300    outb( 0x0b, 0x20 );
1301    isr += inb( 0x20 );
1302 
1303                                 /* Print out interesting information */
1304    printk( "IMR = 0x%04x", imr );
1305    if (imr & (1 << interrupt_level))
1306          printk( " (masked)" );
1307    printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1308 
1309    printk( "SCSI Status      = 0x%02x\n", inb( SCSI_Status_port ) );
1310    printk( "TMC Status       = 0x%02x", inb( TMC_Status_port ) );
1311    if (inb( TMC_Status_port & 1))
1312          printk( " (interrupt)" );
1313    printk( "\n" );
1314    printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
1315    if (inb( Interrupt_Status_port ) & 0x08)
1316          printk( " (enabled)" );
1317    printk( "\n" );
1318    if (chip == tmc18c50) {
1319       printk( "FIFO Status      = 0x%02x\n", inb( port_base + FIFO_Status ) );
1320       printk( "Int. Condition   = 0x%02x\n",
1321               inb( port_base + Interrupt_Cond ) );
1322    }
1323    printk( "Configuration 1  = 0x%02x\n", inb( port_base + Configuration1 ) );
1324    if (chip == tmc18c50)
1325          printk( "Configuration 2  = 0x%02x\n",
1326                  inb( port_base + Configuration2 ) );
1327 }
1328 
1329 int fdomain_16x0_abort( Scsi_Cmnd *SCpnt, int code )
     /* [previous][next][first][last][top][bottom][index][help] */
1330 {
1331 
1332 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1333    printk( "Future Domain: Abort " );
1334 #endif
1335 
1336    cli();
1337    if (!in_command) {
1338 #if EVERY_ACCESS || ERRORS_ONLY
1339       printk( " (not in command)\n" );
1340 #endif
1341       sti();
1342       return 0;
1343    } else {
1344 #if EVERY_ACCESS || ERRORS_ONLY
1345       printk( " code = %d\n", code );
1346 #endif
1347    }
1348 
1349 #if DEBUG_ABORT
1350    print_info( SCpnt );
1351 #endif
1352 
1353    fdomain_make_bus_idle();
1354 
1355    current_SC->SCp.phase |= aborted;
1356 
1357    current_SC->result = code ? code : DID_ABORT;
1358 
1359    sti();
1360    
1361    /* Aborts are not done well. . . */
1362    my_done( code << 16 );
1363 
1364    return 0;
1365 }
1366 
1367 int fdomain_16x0_reset( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1368 {
1369 #if DEBUG_RESET
1370    static int called_once = 0;
1371 #endif
1372 
1373 #if ERRORS_ONLY
1374    printk( "Future Domain: SCSI Bus Reset\n" );
1375 #endif
1376 
1377 #if DEBUG_RESET
1378    if (called_once) print_info( current_SC );
1379    called_once = 1;
1380 #endif
1381    
1382    outb( 1, SCSI_Cntl_port );
1383    do_pause( 2 );
1384    outb( 0, SCSI_Cntl_port );
1385    do_pause( 115 );
1386    outb( 0, SCSI_Mode_Cntl_port );
1387    outb( PARITY_MASK, TMC_Cntl_port );
1388 
1389    /* Unless this is the very first call (i.e., SCPnt == NULL), everything
1390       is probably hosed at this point.  We will, however, try to keep
1391       things going by informing the high-level code that we need help. */
1392 
1393    if (SCpnt)
1394          SCpnt->flags |= NEEDS_JUMPSTART;
1395    
1396    return 0;
1397 }
1398 
1399 int fdomain_16x0_biosparam( int size, int dev, int *info_array )
     /* [previous][next][first][last][top][bottom][index][help] */
1400 {
1401    int    drive;
1402    struct drive_info {
1403       unsigned short cylinders;
1404       unsigned char  heads;
1405       unsigned char  sectors;
1406    } *i;
1407    
1408    /* NOTES:
1409       The RAM area starts at 0x1f00 from the bios_base address.
1410 
1411       For BIOS Version 2.0:
1412       
1413       The drive parameter table seems to start at 0x1f30.
1414       The first byte's purpose is not known.
1415       Next is the cylinder, head, and sector information.
1416       The last 4 bytes appear to be the drive's size in sectors.
1417       The other bytes in the drive parameter table are unknown.
1418       If anyone figures them out, please send me mail, and I will
1419       update these notes.
1420 
1421       Tape drives do not get placed in this table.
1422 
1423       There is another table at 0x1fea:
1424       If the byte is 0x01, then the SCSI ID is not in use.
1425       If the byte is 0x18 or 0x48, then the SCSI ID is in use,
1426       although tapes don't seem to be in this table.  I haven't
1427       seen any other numbers (in a limited sample).
1428 
1429       0x1f2d is a drive count (i.e., not including tapes)
1430 
1431       The table at 0x1fcc are I/O ports addresses for the various
1432       operations.  I calculate these by hand in this driver code.
1433 
1434       For BIOS Version 3.2:
1435 
1436       The drive parameter table starts at 0x1f70.  Each entry is
1437       0x0a bytes long.  Heads are one less than we need to report.
1438     */
1439 
1440    drive = MINOR(dev) / 16;
1441 
1442    if (bios_major == 2) {
1443       i = (struct drive_info *)( (char *)bios_base + 0x1f31 + drive * 25 );
1444       info_array[0] = i->heads;
1445       info_array[1] = i->sectors;
1446       info_array[2] = i->cylinders;
1447    } else if (bios_major == 3) { /* Appears to be the same for 3.0 and 3.2 */
1448       i = (struct drive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
1449       info_array[0] = i->heads + 1;
1450       info_array[1] = i->sectors;
1451       info_array[2] = i->cylinders;
1452    } else {
1453       /* How the data is stored in the RAM area is very BIOS-dependent.
1454          Therefore, assume a version 3 layout, and check for validity. */
1455       
1456       i = (struct drive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
1457       info_array[0] = i->heads + 1;
1458       info_array[1] = i->sectors;
1459       info_array[2] = i->cylinders;
1460 
1461       if (!info_array[0]
1462           || !info_array[1]
1463           || !info_array[2]
1464           || info_array[2] > 1024 /* DOS uses only 10 bits.
1465                                      Should this be changed
1466                                      to support larger drives?
1467                                      I.e., will the controller
1468                                      "do the right thing"?
1469                                    */
1470           ) {
1471          
1472          info_array[0]
1473                = info_array[1]
1474                = info_array[2]
1475                = 0;
1476       }
1477    }
1478    
1479    return 0;
1480 }

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