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

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