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: Tue Jan  4 20:43:57 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.8 1994/01/05 01:44:16 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.8 $"
 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) 1992 V3.00.004/02/92",       5, 44,  3,  0 },
 309    { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93",       5, 44,  3,  2 },
 310    { "FUTURE DOMAIN TMC-18XX",                             5, 22, -1, -1 },
 311 
 312    /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGANTURE
 313     Also, fix the disk geometry code for your signature and send your
 314     changes for faith@cs.unc.edu.  Above all, do *NOT* change any old
 315     signatures!
 316 
 317     Note that the last line will match a "generic" 18XX bios.  Because
 318     Future Domain has changed the host SCSI ID and/or the location of the
 319     geometry information in the on-board RAM area for each of the first
 320     three BIOS's, it is still important to enter a fully qualified
 321     signature in the table for any new BIOS's (after the host SCSI ID and
 322     geometry location are verified.) */
 323 };
 324 
 325 #define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
 326 
 327 static void print_banner( void )
 328 {
 329    printk( "%s", fdomain_16x0_info() );
 330    printk( "Future Domain: BIOS version %d.%d, %s\n",
 331            bios_major, bios_minor,
 332            chip == tmc1800 ? "TMC-1800"
 333            : (chip == tmc18c50 ? "TMC-18C50" : "Unknown") );
 334    
 335    if (interrupt_level) {
 336       printk( "Future Domain: BIOS at %x; port base at %x; using IRQ %d\n",
 337               (unsigned)bios_base, port_base, interrupt_level );
 338    } else {
 339       printk( "Future Domain: BIOS at %x; port base at %x; *NO* IRQ\n",
 340               (unsigned)bios_base, port_base );
 341    }
 342 }
 343 
 344 static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */
     /* [previous][next][first][last][top][bottom][index][help] */
 345 {
 346    unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */
 347 
 348    while (jiffies < the_time);
 349 }
 350 
 351 inline static void fdomain_make_bus_idle( void )
     /* [previous][next][first][last][top][bottom][index][help] */
 352 {
 353    outb( 0, SCSI_Cntl_port );
 354    outb( 0, SCSI_Mode_Cntl_port );
 355    if (chip == tmc18c50)
 356          outb( 0x21 | PARITY_MASK, TMC_Cntl_port ); /* Clear forced intr. */
 357    else
 358          outb( 0x01 | PARITY_MASK, TMC_Cntl_port );
 359 }
 360 
 361 static int fdomain_is_valid_port( int port )
     /* [previous][next][first][last][top][bottom][index][help] */
 362 {
 363    int options;
 364 
 365 #if DEBUG_DETECT 
 366    printk( " (%x%x),",
 367            inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
 368 #endif
 369 
 370    /* The MCA ID is a unique id for each MCA compatible board.  We
 371       are using ISA boards, but Future Domain provides the MCA ID
 372       anyway.  We can use this ID to ensure that this is a Future
 373       Domain TMC-1660/TMC-1680.
 374     */
 375 
 376    if (inb( port + LSB_ID_Code ) != 0xe9) { /* test for 0x6127 id */
 377       if (inb( port + LSB_ID_Code ) != 0x27) return 0;
 378       if (inb( port + MSB_ID_Code ) != 0x61) return 0;
 379       chip = tmc1800;
 380    } else {                                 /* test for 0xe960 id */
 381       if (inb( port + MSB_ID_Code ) != 0x60) return 0;
 382       chip = tmc18c50;
 383    }
 384 
 385    /* We have a valid MCA ID for a TMC-1660/TMC-1680 Future Domain board.
 386       Now, check to be sure the bios_base matches these ports.  If someone
 387       was unlucky enough to have purchased more than one Future Domain
 388       board, then they will have to modify this code, as we only detect one
 389       board here.  [The one with the lowest bios_base.]  */
 390 
 391    options = inb( port + Configuration1 );
 392 
 393 #if DEBUG_DETECT
 394    printk( " Options = %x\n", options );
 395 #endif
 396 
 397                                 /* Check for board with lowest bios_base. */
 398    if (addresses[ (options & 0xc0) >> 6 ] != bios_base)
 399          return 0;
 400    interrupt_level = ints[ (options & 0x0e) >> 1 ];
 401 
 402    return 1;
 403 }
 404 
 405 static int fdomain_test_loopback( void )
     /* [previous][next][first][last][top][bottom][index][help] */
 406 {
 407    int i;
 408    int result;
 409 
 410    for (i = 0; i < 255; i++) {
 411       outb( i, port_base + Write_Loopback );
 412       result = inb( port_base + Read_Loopback );
 413       if (i != result)
 414             return 1;
 415    }
 416    return 0;
 417 }
 418 
 419 int fdomain_16x0_detect( int hostnum )
     /* [previous][next][first][last][top][bottom][index][help] */
 420 {
 421    int              i, j;
 422    int              flag = 0;
 423    struct sigaction sa;
 424    int              retcode;
 425 #if DO_DETECT
 426    const int        buflen = 255;
 427    Scsi_Cmnd        SCinit;
 428    unsigned char    do_inquiry[] =       { INQUIRY, 0, 0, 0, buflen, 0 };
 429    unsigned char    do_request_sense[] = { REQUEST_SENSE, 0, 0, 0, buflen, 0 };
 430    unsigned char    do_read_capacity[] = { READ_CAPACITY,
 431                                            0, 0, 0, 0, 0, 0, 0, 0, 0 };
 432    unsigned char    buf[buflen];
 433 #endif
 434 
 435 #if DEBUG_DETECT
 436    printk( "fdomain_16x0_detect()," );
 437 #endif
 438 
 439    for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) {
 440 #if DEBUG_DETECT
 441       printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base );
 442 #endif
 443       for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) {
 444          if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset),
 445                       signatures[j].signature, signatures[j].sig_length )) {
 446             bios_major = signatures[j].major_bios_version;
 447             bios_minor = signatures[j].minor_bios_version;
 448             bios_base = addresses[i];
 449          }
 450       }
 451    }
 452 
 453    if (!bios_base) {
 454 #if DEBUG_DETECT
 455       printk( " FAILED: NO BIOS\n" );
 456 #endif
 457       return 0;
 458    }
 459 
 460    if (bios_major == 2) {
 461       /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
 462          Assuming the ROM is enabled (otherwise we wouldn't have been
 463          able to read the ROM signature :-), then the ROM sets up the
 464          RAM area with some magic numbers, such as a list of port
 465          base addresses and a list of the disk "geometry" reported to
 466          DOS (this geometry has nothing to do with physical geometry).
 467        */
 468 
 469       port_base = *((char *)bios_base + 0x1fcc)
 470             + (*((char *)bios_base + 0x1fcd) << 8);
 471    
 472 #if DEBUG_DETECT
 473       printk( " %x,", port_base );
 474 #endif
 475 
 476       for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) {
 477          if (port_base == ports[i])
 478                ++flag;
 479       }
 480 
 481       if (flag)
 482             flag = fdomain_is_valid_port( port_base );
 483    }
 484 
 485    if (!flag) {                 /* Cannot get port base from BIOS RAM */
 486       
 487       /* This is a bad sign.  It usually means that someone patched the
 488          BIOS signature list (the signatures variable) to contain a BIOS
 489          signature for a board *OTHER THAN* the TMC-1660/TMC-1680.  It
 490          also means that we don't have a Version 2.0 BIOS :-)
 491        */
 492       
 493 #if DEBUG_DETECT
 494       if (bios_major != 2) printk( " RAM FAILED, " );
 495 #endif
 496 
 497       /* Anyway, the alternative to finding the address in the RAM is
 498          to just search through every possible port address for one
 499          that is attached to the Future Domain card.  Don't panic,
 500          though, about reading all these random port addresses--there
 501          are rumors that the Future Domain BIOS does something very
 502          similar.
 503 
 504          Do not, however, check ports which the kernel knows are being used
 505          by another driver.
 506        */
 507 
 508       for (i = 0; !flag && i < PORT_COUNT; i++) {
 509          port_base = ports[i];
 510          if (check_region( port_base, 0x10 )) {
 511 #if DEBUG_DETECT
 512             printf( " (%x inuse),", port_base );
 513 #endif
 514             continue;
 515          }
 516 #if DEBUG_DETECT
 517          printk( " %x,", port_base );
 518 #endif
 519          flag = fdomain_is_valid_port( port_base );
 520       }
 521    }
 522 
 523    if (!flag) {
 524 #if DEBUG_DETECT
 525       printk( " FAILED: NO PORT\n" );
 526 #endif
 527       return 0;         /* Cannot find valid set of ports */
 528    }
 529 
 530    print_banner();
 531 
 532    SCSI_Mode_Cntl_port   = port_base + SCSI_Mode_Cntl;
 533    FIFO_Data_Count_port  = port_base + FIFO_Data_Count;
 534    Interrupt_Cntl_port   = port_base + Interrupt_Cntl;
 535    Interrupt_Status_port = port_base + Interrupt_Status;
 536    Read_FIFO_port        = port_base + Read_FIFO;
 537    Read_SCSI_Data_port   = port_base + Read_SCSI_Data;
 538    SCSI_Cntl_port        = port_base + SCSI_Cntl;
 539    SCSI_Data_NoACK_port  = port_base + SCSI_Data_NoACK;
 540    SCSI_Status_port      = port_base + SCSI_Status;
 541    TMC_Cntl_port         = port_base + TMC_Cntl;
 542    TMC_Status_port       = port_base + TMC_Status;
 543    Write_FIFO_port       = port_base + Write_FIFO;
 544    Write_SCSI_Data_port  = port_base + Write_SCSI_Data;
 545 
 546    fdomain_16x0_reset( NULL );
 547 
 548    if (fdomain_test_loopback()) {
 549 #if DEBUG_DETECT
 550       printk( "Future Domain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
 551 #endif
 552       return 0;
 553    }
 554 
 555    this_host = hostnum;
 556 
 557                                 /* Log IRQ with kernel */
 558    
 559    if (!interrupt_level) {
 560       panic( "Future Domain: *NO* interrupt level selected!\n" );
 561    } else {
 562       /* Register the IRQ with the kernel */
 563 
 564       sa.sa_handler  = fdomain_16x0_intr;
 565       sa.sa_flags    = SA_INTERRUPT;
 566       sa.sa_mask     = 0;
 567       sa.sa_restorer = NULL;
 568       
 569       retcode = irqaction( interrupt_level, &sa );
 570 
 571       if (retcode < 0) {
 572          if (retcode == -EINVAL) {
 573             printk( "Future Domain: IRQ %d is bad!\n", interrupt_level );
 574             printk( "               This shouldn't happen!\n" );
 575             printk( "               Send mail to faith@cs.unc.edu\n" );
 576          } else if (retcode == -EBUSY) {
 577             printk( "Future Domain: IRQ %d is already in use!\n",
 578                     interrupt_level );
 579             printk( "               Please use another IRQ!\n" );
 580          } else {
 581             printk( "Future Domain: Error getting IRQ %d\n", interrupt_level );
 582             printk( "               This shouldn't happen!\n" );
 583             printk( "               Send mail to faith@cs.unc.edu\n" );
 584          }
 585          panic( "Future Domain: Driver requires interruptions\n" );
 586       } else {
 587          printk( "Future Domain: IRQ %d requested from kernel\n",
 588                  interrupt_level );
 589       }
 590    }
 591 
 592                                 /* Log I/O ports with kernel */
 593 
 594    snarf_region( port_base, 0x10 );
 595 
 596    if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
 597       adapter_mask = 0x80;
 598       scsi_hosts[this_host].this_id = 7;
 599    }
 600    
 601 #if DO_DETECT
 602 
 603    /* These routines are here because of the way the SCSI bus behaves after
 604       a reset.  This appropriate behavior was not handled correctly by the
 605       higher level SCSI routines when I first wrote this driver.  Now,
 606       however, correct scan routines are part of scsi.c and these routines
 607       are no longer needed.  However, this code is still good for
 608       debugging.  */
 609 
 610    SCinit.request_buffer  = SCinit.buffer = buf;
 611    SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
 612    SCinit.use_sg          = 0;
 613    SCinit.lun             = 0;
 614 
 615    printk( "Future Domain detection routine scanning for devices:\n" );
 616    for (i = 0; i < 8; i++) {
 617       SCinit.target = i;
 618       if (i == scsi_hosts[this_host].this_id) /* Skip host adapter */
 619             continue;
 620       memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
 621       retcode = fdomain_16x0_command(&SCinit);
 622       if (!retcode) {
 623          memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
 624          retcode = fdomain_16x0_command(&SCinit);
 625          if (!retcode) {
 626             printk( "     SCSI ID %d: ", i );
 627             for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
 628                   printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
 629             memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
 630             retcode = fdomain_16x0_command(&SCinit);
 631             if (!retcode) {
 632                unsigned long blocks, size, capacity;
 633                
 634                blocks = (buf[0] << 24) | (buf[1] << 16)
 635                      | (buf[2] << 8) | buf[3];
 636                size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
 637                capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
 638                
 639                printk( "%lu MB (%lu byte blocks)",
 640                        ((capacity + 5L) / 10L), size );
 641             } else {
 642                memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
 643                retcode = fdomain_16x0_command(&SCinit);
 644             }
 645             printk ("\n" );
 646          } else {
 647             memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
 648             retcode = fdomain_16x0_command(&SCinit);
 649          }
 650       }
 651    }
 652 #endif
 653 
 654    return 1;
 655 }
 656 
 657 const char *fdomain_16x0_info(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 658 {
 659    static char buffer[80];
 660    char        *pt;
 661    
 662    strcpy( buffer, "Future Domain: TMC-16x0 SCSI driver, version" );
 663    if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */
 664       strcat( buffer, strchr( VERSION, ':' ) + 1 );
 665       pt = strrchr( buffer, '$') - 1;
 666       if (!pt)                  /* Stripped RCS Revision string? */
 667             pt = buffer + strlen( buffer ) - 1;
 668       if (*pt != ' ')
 669             ++pt;
 670       *pt++ = '\n';
 671       *pt = '\0';
 672    } else {                     /* Assume VERSION is a number */
 673       strcat( buffer, " " VERSION "\n" );
 674    }
 675       
 676    return buffer;
 677 }
 678 
 679 #if 0
 680 static int fdomain_arbitrate( void )
     /* [previous][next][first][last][top][bottom][index][help] */
 681 {
 682    int           status = 0;
 683    unsigned long timeout;
 684 
 685 #if EVERY_ACCESS
 686    printk( "fdomain_arbitrate()\n" );
 687 #endif
 688    
 689    outb( 0x00, SCSI_Cntl_port );              /* Disable data drivers */
 690    outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */
 691    outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
 692 
 693    timeout = jiffies + 50;                    /* 500 mS */
 694    while (jiffies < timeout) {
 695       status = inb( TMC_Status_port );        /* Read adapter status */
 696       if (status & 0x02)                      /* Arbitration complete */
 697             return 0;   
 698    }
 699 
 700    /* Make bus idle */
 701    fdomain_make_bus_idle();
 702 
 703 #if EVERY_ACCESS
 704    printk( "Arbitration failed, status = %x\n", status );
 705 #endif
 706 #if ERRORS_ONLY
 707    printk( "Future Domain: Arbitration failed, status = %x", status );
 708 #endif
 709    return 1;
 710 }
 711 #endif
 712 
 713 static int fdomain_select( int target )
     /* [previous][next][first][last][top][bottom][index][help] */
 714 {
 715    int           status;
 716    unsigned long timeout;
 717 
 718 
 719    outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
 720    outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );
 721 
 722    /* Stop arbitration and enable parity */
 723    outb( PARITY_MASK, TMC_Cntl_port ); 
 724 
 725    timeout = jiffies + 25;              /* 250mS */
 726    while (jiffies < timeout) {
 727       status = inb( SCSI_Status_port ); /* Read adapter status */
 728       if (status & 1) {                 /* Busy asserted */
 729          /* Enable SCSI Bus (on error, should make bus idle with 0) */
 730          outb( 0x80, SCSI_Cntl_port );
 731          return 0;
 732       }
 733    }
 734    /* Make bus idle */
 735    fdomain_make_bus_idle();
 736 #if EVERY_ACCESS
 737    if (!target) printk( "Selection failed\n" );
 738 #endif
 739 #if ERRORS_ONLY
 740    if (!target) printk( "Future Domain: Selection failed" );
 741 #endif
 742    return 1;
 743 }
 744 
 745 void my_done( int error )
     /* [previous][next][first][last][top][bottom][index][help] */
 746 {
 747    if (in_command) {
 748       in_command = 0;
 749       outb( 0x00, Interrupt_Cntl_port );
 750       fdomain_make_bus_idle();
 751       current_SC->result = error;
 752       if (current_SC->scsi_done)
 753             current_SC->scsi_done( current_SC );
 754       else panic( "Future Domain: current_SC->scsi_done() == NULL" );
 755    } else {
 756       panic( "Future Domain: my_done() called outside of command\n" );
 757    }
 758 #if DEBUG_RACE
 759    in_interrupt_flag = 0;
 760 #endif
 761 }
 762 
 763 void fdomain_16x0_intr( int unused )
     /* [previous][next][first][last][top][bottom][index][help] */
 764 {
 765    int      status;
 766    int      done = 0;
 767    unsigned data_count;
 768 
 769    sti();
 770    
 771    outb( 0x00, Interrupt_Cntl_port );
 772 
 773    /* We usually have one spurious interrupt after each command.  Ignore it. */
 774    if (!in_command || !current_SC) {    /* Spurious interrupt */
 775 #if EVERY_ACCESS
 776       printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
 777               in_command, current_SC );
 778 #endif
 779       return;
 780    }
 781 
 782    /* Abort calls my_done, so we do nothing here. */
 783    if (current_SC->SCp.phase & aborted) {
 784 #if DEBUG_ABORT
 785       printk( "Interrupt after abort, ignoring\n" );
 786 #endif
 787       /*
 788       return; */
 789    }
 790 
 791 #if DEBUG_RACE
 792    ++in_interrupt_flag;
 793 #endif
 794 
 795    if (current_SC->SCp.phase & in_arbitration) {
 796       status = inb( TMC_Status_port );        /* Read adapter status */
 797       if (!(status & 0x02)) {
 798 #if EVERY_ACCESS
 799          printk( " AFAIL " );
 800 #endif
 801          my_done( DID_BUS_BUSY << 16 );
 802          return;
 803       }
 804       current_SC->SCp.phase = in_selection;
 805       
 806       outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
 807 
 808       outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
 809       outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
 810       
 811       /* Stop arbitration and enable parity */
 812       outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
 813 #if DEBUG_RACE
 814       in_interrupt_flag = 0;
 815 #endif
 816       return;
 817    } else if (current_SC->SCp.phase & in_selection) {
 818       status = inb( SCSI_Status_port );
 819       if (!(status & 0x01)) {
 820          /* Try again, for slow devices */
 821          if (fdomain_select( current_SC->target )) {
 822 #if EVERY_ACCESS
 823             printk( " SFAIL " );
 824 #endif
 825             my_done( DID_NO_CONNECT << 16 );
 826             return;
 827          } else {
 828 #if EVERY_ACCESS
 829             printk( " AltSel " );
 830 #endif
 831             /* Stop arbitration and enable parity */
 832             outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
 833          }
 834       }
 835       current_SC->SCp.phase = in_other;
 836       outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
 837       outb( 0x80, SCSI_Cntl_port );
 838 #if DEBUG_RACE
 839       in_interrupt_flag = 0;
 840 #endif
 841       return;
 842    }
 843    
 844    /* current_SC->SCp.phase == in_other: this is the body of the routine */
 845    
 846    status = inb( SCSI_Status_port );
 847    
 848    if (status & 0x10) { /* REQ */
 849       
 850       switch (status & 0x0e) {
 851        
 852       case 0x08:                /* COMMAND OUT */
 853          outb( current_SC->cmnd[current_SC->SCp.sent_command++],
 854                Write_SCSI_Data_port );
 855 #if EVERY_ACCESS
 856          printk( "CMD = %x,",
 857                  current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
 858 #endif
 859          break;
 860       case 0x00:                /* DATA OUT -- tmc18c50 only */
 861          if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
 862             current_SC->SCp.have_data_in = -1;
 863             outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
 864          }
 865          break;
 866       case 0x04:                /* DATA IN -- tmc18c50 only */
 867          if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
 868             current_SC->SCp.have_data_in = 1;
 869             outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
 870          }
 871          break;
 872       case 0x0c:                /* STATUS IN */
 873          current_SC->SCp.Status = inb( Read_SCSI_Data_port );
 874 #if EVERY_ACCESS
 875          printk( "Status = %x, ", current_SC->SCp.Status );
 876 #endif
 877 #if ERRORS_ONLY
 878          if (current_SC->SCp.Status && current_SC->SCp.Status != 2) {
 879             printk( "Future Domain: target = %d, command = %x, "
 880                     "Status = %x\n",
 881                     current_SC->target, current_SC->cmnd[0],
 882                     current_SC->SCp.Status );
 883          }
 884 #endif
 885                break;
 886       case 0x0a:                /* MESSAGE OUT */
 887          outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */
 888          break;
 889       case 0x0e:                /* MESSAGE IN */
 890          current_SC->SCp.Message = inb( Read_SCSI_Data_port );
 891 #if EVERY_ACCESS
 892          printk( "Message = %x, ", current_SC->SCp.Message );
 893 #endif
 894          if (!current_SC->SCp.Message) ++done;
 895 #if DEBUG_MESSAGES || EVERY_ACCESS
 896          if (current_SC->SCp.Message) {
 897             printk( "Future Domain: Message = %x\n",
 898                     current_SC->SCp.Message );
 899          }
 900 #endif
 901          break;
 902       }
 903    }
 904 
 905    if (chip == tmc1800
 906        && !current_SC->SCp.have_data_in
 907        && (current_SC->SCp.sent_command
 908            >= COMMAND_SIZE( current_SC->cmnd[ 0 ] ))) {
 909                                 /* We have to get the FIFO direction
 910                                    correct, so I've made a table based
 911                                    on the SCSI Standard of which commands
 912                                    appear to require a DATA OUT phase.
 913                                  */
 914       /*
 915         p. 94: Command for all device types
 916         CHANGE DEFINITION            40 DATA OUT
 917         COMPARE                      39 DATA OUT
 918         COPY                         18 DATA OUT
 919         COPY AND VERIFY              3a DATA OUT
 920         INQUIRY                      12 
 921         LOG SELECT                   4c DATA OUT
 922         LOG SENSE                    4d
 923         MODE SELECT (6)              15 DATA OUT
 924         MODE SELECT (10)             55 DATA OUT
 925         MODE SENSE (6)               1a
 926         MODE SENSE (10)              5a
 927         READ BUFFER                  3c
 928         RECEIVE DIAGNOSTIC RESULTS   1c
 929         REQUEST SENSE                03
 930         SEND DIAGNOSTIC              1d DATA OUT
 931         TEST UNIT READY              00
 932         WRITE BUFFER                 3b DATA OUT
 933 
 934         p.178: Commands for direct-access devices (not listed on p. 94)
 935         FORMAT UNIT                  04 DATA OUT
 936         LOCK-UNLOCK CACHE            36
 937         PRE-FETCH                    34
 938         PREVENT-ALLOW MEDIUM REMOVAL 1e
 939         READ (6)/RECEIVE             08
 940         READ (10)                    3c
 941         READ CAPACITY                25
 942         READ DEFECT DATA (10)        37
 943         READ LONG                    3e
 944         REASSIGN BLOCKS              07 DATA OUT
 945         RELEASE                      17
 946         RESERVE                      16 DATA OUT
 947         REZERO UNIT/REWIND           01
 948         SEARCH DATA EQUAL (10)       31 DATA OUT
 949         SEARCH DATA HIGH (10)        30 DATA OUT
 950         SEARCH DATA LOW (10)         32 DATA OUT
 951         SEEK (6)                     0b
 952         SEEK (10)                    2b
 953         SET LIMITS (10)              33
 954         START STOP UNIT              1b
 955         SYNCHRONIZE CACHE            35
 956         VERIFY (10)                  2f
 957         WRITE (6)/PRINT/SEND         0a DATA OUT
 958         WRITE (10)/SEND              2a DATA OUT
 959         WRITE AND VERIFY (10)        2e DATA OUT
 960         WRITE LONG                   3f DATA OUT
 961         WRITE SAME                   41 DATA OUT ?
 962 
 963         p. 261: Commands for sequential-access devices (not previously listed)
 964         ERASE                        19
 965         LOAD UNLOAD                  1b
 966         LOCATE                       2b
 967         READ BLOCK LIMITS            05
 968         READ POSITION                34
 969         READ REVERSE                 0f
 970         RECOVER BUFFERED DATA        14
 971         SPACE                        11
 972         WRITE FILEMARKS              10 ?
 973 
 974         p. 298: Commands for printer devices (not previously listed)
 975         ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
 976         SLEW AND PRINT               0b DATA OUT  -- same as seek
 977         STOP PRINT                   1b
 978         SYNCHRONIZE BUFFER           10
 979 
 980         p. 315: Commands for processor devices (not previously listed)
 981         
 982         p. 321: Commands for write-once devices (not previously listed)
 983         MEDIUM SCAN                  38
 984         READ (12)                    a8
 985         SEARCH DATA EQUAL (12)       b1 DATA OUT
 986         SEARCH DATA HIGH (12)        b0 DATA OUT
 987         SEARCH DATA LOW (12)         b2 DATA OUT
 988         SET LIMITS (12)              b3
 989         VERIFY (12)                  af
 990         WRITE (12)                   aa DATA OUT
 991         WRITE AND VERIFY (12)        ae DATA OUT
 992 
 993         p. 332: Commands for CD-ROM devices (not previously listed)
 994         PAUSE/RESUME                 4b
 995         PLAY AUDIO (10)              45
 996         PLAY AUDIO (12)              a5
 997         PLAY AUDIO MSF               47
 998         PLAY TRACK RELATIVE (10)     49
 999         PLAY TRACK RELATIVE (12)     a9
1000         READ HEADER                  44
1001         READ SUB-CHANNEL             42
1002         READ TOC                     43
1003 
1004         p. 370: Commands for scanner devices (not previously listed)
1005         GET DATA BUFFER STATUS       34
1006         GET WINDOW                   25
1007         OBJECT POSITION              31
1008         SCAN                         1b
1009         SET WINDOW                   24 DATA OUT
1010 
1011         p. 391: Commands for optical memory devices (not listed)
1012         ERASE (10)                   2c
1013         ERASE (12)                   ac
1014         MEDIUM SCAN                  38 DATA OUT
1015         READ DEFECT DATA (12)        b7
1016         READ GENERATION              29
1017         READ UPDATED BLOCK           2d
1018         UPDATE BLOCK                 3d DATA OUT
1019 
1020         p. 419: Commands for medium changer devices (not listed)
1021         EXCHANGE MEDIUM              46
1022         INITIALIZE ELEMENT STATUS    07
1023         MOVE MEDIUM                  a5
1024         POSITION TO ELEMENT          2b
1025         READ ELEMENT STATUS          b8
1026         REQUEST VOL. ELEMENT ADDRESS b5
1027         SEND VOLUME TAG              b6 DATA OUT
1028 
1029         p. 454: Commands for communications devices (not listed previously)
1030         GET MESSAGE (6)              08
1031         GET MESSAGE (10)             28
1032         GET MESSAGE (12)             a8
1033       */
1034         
1035       switch (current_SC->cmnd[0]) {
1036       case CHANGE_DEFINITION: case COMPARE:         case COPY:
1037       case COPY_VERIFY:       case LOG_SELECT:      case MODE_SELECT:
1038       case MODE_SELECT_10:    case SEND_DIAGNOSTIC: case WRITE_BUFFER:
1039 
1040       case FORMAT_UNIT:       case REASSIGN_BLOCKS: case RESERVE:
1041       case SEARCH_EQUAL:      case SEARCH_HIGH:     case SEARCH_LOW:
1042       case WRITE_6:           case WRITE_10:        case WRITE_VERIFY:
1043       case 0x3f:              case 0x41:
1044 
1045       case 0xb1:              case 0xb0:            case 0xb2:
1046       case 0xaa:              case 0xae:
1047 
1048       case 0x24:
1049 
1050       case 0x38:              case 0x3d:
1051 
1052       case 0xb6:
1053          
1054       case 0xea:                /* alternate number for WRITE LONG */
1055          
1056          current_SC->SCp.have_data_in = -1;
1057          outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1058          break;
1059 
1060       case 0x00:
1061       default:
1062          
1063          current_SC->SCp.have_data_in = 1;
1064          outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1065          break;
1066       }
1067    }
1068 
1069    if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
1070       while ( (data_count = 0x2000 - inw( FIFO_Data_Count_port )) > 512 ) {
1071 #if EVERY_ACCESS
1072          printk( "DC=%d, ", data_count ) ;
1073 #endif
1074          if (data_count > current_SC->SCp.this_residual)
1075                data_count = current_SC->SCp.this_residual;
1076          if (data_count > 0) {
1077 #if EVERY_ACCESS
1078             printk( "%d OUT, ", data_count );
1079 #endif
1080             if (data_count == 1) {
1081                outb( *current_SC->SCp.ptr++, Write_FIFO_port );
1082                --current_SC->SCp.this_residual;
1083             } else {
1084                data_count >>= 1;
1085                outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count );
1086                current_SC->SCp.ptr += 2 * data_count;
1087                current_SC->SCp.this_residual -= 2 * data_count;
1088             }
1089          }
1090          if (!current_SC->SCp.this_residual) {
1091             if (current_SC->SCp.buffers_residual) {
1092                --current_SC->SCp.buffers_residual;
1093                ++current_SC->SCp.buffer;
1094                current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1095                current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1096             } else
1097                   break;
1098          }
1099       }
1100    }
1101    
1102    if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
1103       while ((data_count = inw( FIFO_Data_Count_port )) > 0) {
1104 #if EVERY_ACCESS
1105          printk( "DC=%d, ", data_count );
1106 #endif
1107          if (data_count > current_SC->SCp.this_residual)
1108                data_count = current_SC->SCp.this_residual;
1109          if (data_count) {
1110 #if EVERY_ACCESS
1111             printk( "%d IN, ", data_count );
1112 #endif
1113             if (data_count == 1) {
1114                *current_SC->SCp.ptr++ = inb( Read_FIFO_port );
1115                --current_SC->SCp.this_residual;
1116             } else {
1117                data_count >>= 1; /* Number of words */
1118                insw( Read_FIFO_port, current_SC->SCp.ptr, data_count );
1119                current_SC->SCp.ptr += 2 * data_count;
1120                current_SC->SCp.this_residual -= 2 * data_count;
1121             }
1122          }
1123          if (!current_SC->SCp.this_residual
1124              && current_SC->SCp.buffers_residual) {
1125             --current_SC->SCp.buffers_residual;
1126             ++current_SC->SCp.buffer;
1127             current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1128             current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1129          }
1130       }
1131    }
1132    
1133    if (done) {
1134 #if EVERY_ACCESS
1135       printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1136 #endif
1137 
1138 #if ERRORS_ONLY
1139       if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
1140          if ((unsigned char)(*((char *)current_SC->request_buffer+2)) & 0x0f) {
1141             unsigned char key;
1142             unsigned char code;
1143             unsigned char qualifier;
1144 
1145             key = (unsigned char)(*((char *)current_SC->request_buffer + 2))
1146                   & 0x0f;
1147             code = (unsigned char)(*((char *)current_SC->request_buffer + 12));
1148             qualifier = (unsigned char)(*((char *)current_SC->request_buffer
1149                                           + 13));
1150 
1151             if (!(key == UNIT_ATTENTION && (code == 0x29 || !code))
1152                 && !(key == NOT_READY
1153                      && code == 0x04
1154                      && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1155                 && !(key == ILLEGAL_REQUEST && (code == 0x25
1156                                                 || code == 0x24
1157                                                 || !code)))
1158                   
1159                   printk( "Future Domain: REQUEST SENSE "
1160                           "Key = %x, Code = %x, Qualifier = %x\n",
1161                           key, code, qualifier );
1162          }
1163       }
1164 #endif
1165 #if EVERY_ACCESS
1166       printk( "BEFORE MY_DONE. . ." );
1167 #endif
1168       my_done( (current_SC->SCp.Status & 0xff)
1169                | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1170 #if EVERY_ACCESS
1171       printk( "RETURNING.\n" );
1172 #endif
1173       
1174    } else {
1175       if (current_SC->SCp.phase & disconnect) {
1176          outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
1177          outb( 0x00, SCSI_Cntl_port );
1178       } else {
1179          outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1180       }
1181    }
1182 #if DEBUG_RACE
1183    in_interrupt_flag = 0;
1184 #endif
1185    return;
1186 }
1187 
1188 int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     /* [previous][next][first][last][top][bottom][index][help] */
1189 {
1190    if (in_command) {
1191       panic( "Future Domain: fdomain_16x0_queue() NOT REENTRANT!\n" );
1192    }
1193 #if EVERY_ACCESS
1194    printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1195            SCpnt->target,
1196            *(unsigned char *)SCpnt->cmnd,
1197            SCpnt->use_sg,
1198            SCpnt->request_bufflen );
1199 #endif
1200 
1201    fdomain_make_bus_idle();
1202 
1203    current_SC            = SCpnt; /* Save this for the done function */
1204    current_SC->scsi_done = done;
1205 
1206    /* Initialize static data */
1207 
1208    if (current_SC->use_sg) {
1209       current_SC->SCp.buffer =
1210             (struct scatterlist *)current_SC->request_buffer;
1211       current_SC->SCp.ptr              = current_SC->SCp.buffer->address;
1212       current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
1213       current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1214    } else {
1215       current_SC->SCp.ptr              = (char *)current_SC->request_buffer;
1216       current_SC->SCp.this_residual    = current_SC->request_bufflen;
1217       current_SC->SCp.buffer           = NULL;
1218       current_SC->SCp.buffers_residual = 0;
1219    }
1220          
1221    
1222    current_SC->SCp.Status              = 0;
1223    current_SC->SCp.Message             = 0;
1224    current_SC->SCp.have_data_in        = 0;
1225    current_SC->SCp.sent_command        = 0;
1226    current_SC->SCp.phase               = in_arbitration;
1227 
1228    /* Start arbitration */
1229    outb( 0x00, Interrupt_Cntl_port );
1230    outb( 0x00, SCSI_Cntl_port );              /* Disable data drivers */
1231    outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */
1232    ++in_command;
1233    outb( 0x20, Interrupt_Cntl_port );
1234    outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
1235 
1236    return 0;
1237 }
1238 
1239 /* The following code, which simulates the old-style command function, was
1240    taken from Tommy Thorn's aha1542.c file.  This code is Copyright (C)
1241    1992 Tommy Thorn. */
1242 
1243 static volatile int internal_done_flag    = 0;
1244 static volatile int internal_done_errcode = 0;
1245 
1246 static void internal_done( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1247 {
1248     internal_done_errcode = SCpnt->result;
1249     ++internal_done_flag;
1250 }
1251 
1252 int fdomain_16x0_command( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1253 {
1254     fdomain_16x0_queue( SCpnt, internal_done );
1255 
1256     while (!internal_done_flag)
1257           ;
1258     internal_done_flag = 0;
1259     return internal_done_errcode;
1260 }
1261 
1262 /* End of code derived from Tommy Thorn's work. */
1263 
1264 void print_info( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1265 {
1266    unsigned int imr;
1267    unsigned int irr;
1268    unsigned int isr;
1269    
1270    print_banner();
1271    switch (SCpnt->SCp.phase) {
1272    case in_arbitration: printk( "arbitration " ); break;
1273    case in_selection:   printk( "selection " );   break;
1274    case in_other:       printk( "other " );       break;
1275    default:             printk( "unknown " );     break;
1276    }
1277 
1278    printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1279            SCpnt->SCp.phase,
1280            SCpnt->target,
1281            *(unsigned char *)SCpnt->cmnd,
1282            SCpnt->use_sg,
1283            SCpnt->request_bufflen );
1284    printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1285            SCpnt->SCp.sent_command,
1286            SCpnt->SCp.have_data_in,
1287            SCpnt->timeout );
1288 #if DEBUG_RACE
1289    printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1290 #endif
1291 
1292    imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1293    outb( 0x0a, 0xa0 );
1294    irr = inb( 0xa0 ) << 8;
1295    outb( 0x0a, 0x20 );
1296    irr += inb( 0x20 );
1297    outb( 0x0b, 0xa0 );
1298    isr = inb( 0xa0 ) << 8;
1299    outb( 0x0b, 0x20 );
1300    isr += inb( 0x20 );
1301 
1302                                 /* Print out interesting information */
1303    printk( "IMR = 0x%04x", imr );
1304    if (imr & (1 << interrupt_level))
1305          printk( " (masked)" );
1306    printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1307 
1308    printk( "SCSI Status      = 0x%02x\n", inb( SCSI_Status_port ) );
1309    printk( "TMC Status       = 0x%02x", inb( TMC_Status_port ) );
1310    if (inb( TMC_Status_port & 1))
1311          printk( " (interrupt)" );
1312    printk( "\n" );
1313    printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
1314    if (inb( Interrupt_Status_port ) & 0x08)
1315          printk( " (enabled)" );
1316    printk( "\n" );
1317    if (chip == tmc18c50) {
1318       printk( "FIFO Status      = 0x%02x\n", inb( port_base + FIFO_Status ) );
1319       printk( "Int. Condition   = 0x%02x\n",
1320               inb( port_base + Interrupt_Cond ) );
1321    }
1322    printk( "Configuration 1  = 0x%02x\n", inb( port_base + Configuration1 ) );
1323    if (chip == tmc18c50)
1324          printk( "Configuration 2  = 0x%02x\n",
1325                  inb( port_base + Configuration2 ) );
1326 }
1327 
1328 int fdomain_16x0_abort( Scsi_Cmnd *SCpnt, int code )
     /* [previous][next][first][last][top][bottom][index][help] */
1329 {
1330 
1331 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1332    printk( "Future Domain: Abort " );
1333 #endif
1334 
1335    cli();
1336    if (!in_command) {
1337 #if EVERY_ACCESS || ERRORS_ONLY
1338       printk( " (not in command)\n" );
1339 #endif
1340       sti();
1341       return 0;
1342    } else {
1343 #if EVERY_ACCESS || ERRORS_ONLY
1344       printk( " code = %d\n", code );
1345 #endif
1346    }
1347 
1348 #if DEBUG_ABORT
1349    print_info( SCpnt );
1350 #endif
1351 
1352    fdomain_make_bus_idle();
1353 
1354    current_SC->SCp.phase |= aborted;
1355 
1356    current_SC->result = code ? code : DID_ABORT;
1357 
1358    sti();
1359    
1360    /* Aborts are not done well. . . */
1361    my_done( code << 16 );
1362 
1363    return 0;
1364 }
1365 
1366 int fdomain_16x0_reset( Scsi_Cmnd *SCpnt )
     /* [previous][next][first][last][top][bottom][index][help] */
1367 {
1368 #if DEBUG_RESET
1369    static int called_once = 0;
1370 #endif
1371 
1372 #if ERRORS_ONLY
1373    printk( "Future Domain: SCSI Bus Reset\n" );
1374 #endif
1375 
1376 #if DEBUG_RESET
1377    if (called_once) print_info( current_SC );
1378    called_once = 1;
1379 #endif
1380    
1381    outb( 1, SCSI_Cntl_port );
1382    do_pause( 2 );
1383    outb( 0, SCSI_Cntl_port );
1384    do_pause( 115 );
1385    outb( 0, SCSI_Mode_Cntl_port );
1386    outb( PARITY_MASK, TMC_Cntl_port );
1387 
1388    /* Unless this is the very first call (i.e., SCPnt == NULL), everything
1389       is probably hosed at this point.  We will, however, try to keep
1390       things going by informing the high-level code that we need help. */
1391 
1392    if (SCpnt)
1393          SCpnt->flags |= NEEDS_JUMPSTART;
1394    
1395    return 0;
1396 }
1397 
1398 int fdomain_16x0_biosparam( int size, int dev, int *info_array )
     /* [previous][next][first][last][top][bottom][index][help] */
1399 {
1400    int    drive;
1401    struct drive_info {
1402       unsigned short cylinders;
1403       unsigned char  heads;
1404       unsigned char  sectors;
1405    } *i;
1406    
1407    /* NOTES:
1408       The RAM area starts at 0x1f00 from the bios_base address.
1409 
1410       For BIOS Version 2.0:
1411       
1412       The drive parameter table seems to start at 0x1f30.
1413       The first byte's purpose is not known.
1414       Next is the cylinder, head, and sector information.
1415       The last 4 bytes appear to be the drive's size in sectors.
1416       The other bytes in the drive parameter table are unknown.
1417       If anyone figures them out, please send me mail, and I will
1418       update these notes.
1419 
1420       Tape drives do not get placed in this table.
1421 
1422       There is another table at 0x1fea:
1423       If the byte is 0x01, then the SCSI ID is not in use.
1424       If the byte is 0x18 or 0x48, then the SCSI ID is in use,
1425       although tapes don't seem to be in this table.  I haven't
1426       seen any other numbers (in a limited sample).
1427 
1428       0x1f2d is a drive count (i.e., not including tapes)
1429 
1430       The table at 0x1fcc are I/O ports addresses for the various
1431       operations.  I calculate these by hand in this driver code.
1432 
1433       For BIOS Version 3.2:
1434 
1435       The drive parameter table starts at 0x1f70.  Each entry is
1436       0x0a bytes long.  Heads are one less than we need to report.
1437     */
1438 
1439    drive = MINOR(dev) / 16;
1440 
1441    if (bios_major == 2) {
1442       i = (struct drive_info *)( (char *)bios_base + 0x1f31 + drive * 25 );
1443       info_array[0] = i->heads;
1444       info_array[1] = i->sectors;
1445       info_array[2] = i->cylinders;
1446    } else if (bios_major == 3) { /* Appears to be the same for 3.0 and 3.2 */
1447       i = (struct drive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
1448       info_array[0] = i->heads + 1;
1449       info_array[1] = i->sectors;
1450       info_array[2] = i->cylinders;
1451    } else {
1452       /* How the data is stored in the RAM area is very BIOS-dependent.
1453          Therefore, assume a version 3 layout, and check for validity. */
1454       
1455       i = (struct drive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
1456       info_array[0] = i->heads + 1;
1457       info_array[1] = i->sectors;
1458       info_array[2] = i->cylinders;
1459 
1460       if (!info_array[0]
1461           || !info_array[1]
1462           || !info_array[2]
1463           || info_array[2] > 1024 /* DOS uses only 10 bits.
1464                                      Should this be changed
1465                                      to support larger drives?
1466                                      I.e., will the controller
1467                                      "do the right thing"?
1468                                    */
1469           ) {
1470          
1471          info_array[0]
1472                = info_array[1]
1473                = info_array[2]
1474                = 0;
1475       }
1476    }
1477    
1478    return 0;
1479 }

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