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

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