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

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