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

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