home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / drivers / scsi / fdomain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-24  |  45.4 KB  |  1,481 lines

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