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

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