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

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