root/kernel/blk_drv/scsi/fdomain.c

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

DEFINITIONS

This source file includes following definitions.
  1. outw
  2. print_banner
  3. do_pause
  4. fdomain_make_bus_idle
  5. fdomain_is_valid_port
  6. fdomain_test_loopback
  7. fdomain_16x0_detect
  8. fdomain_16x0_info
  9. fdomain_arbitrate
  10. fdomain_select
  11. my_done
  12. fdomain_16x0_intr
  13. fdomain_16x0_queue
  14. internal_done
  15. fdomain_16x0_command
  16. print_info
  17. fdomain_16x0_abort
  18. fdomain_16x0_reset
  19. fdomain_16x0_biosparam

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

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